]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Add support for RISC-V architecture.
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
6f2750fe 2 Copyright (C) 1998-2016 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 46#include <zlib.h>
3bfcb652 47#ifdef HAVE_WCHAR_H
7bfd842d 48#include <wchar.h>
3bfcb652 49#endif
252b5132 50
a952a375 51#if __GNUC__ >= 2
19936277 52/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 53 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 54 Only do this if we believe that the compiler can support a 64 bit
a952a375 55 data type. For now we only rely on GCC being able to do this. */
19936277 56#define BFD64
a952a375
NC
57#endif
58
3db64b00
AM
59#include "bfd.h"
60#include "bucomm.h"
3284fe0c 61#include "elfcomm.h"
19e6b90e 62#include "dwarf.h"
252b5132
RH
63
64#include "elf/common.h"
65#include "elf/external.h"
66#include "elf/internal.h"
252b5132 67
4b78141a
NC
68
69/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
70 we can obtain the H8 reloc numbers. We need these for the
71 get_reloc_size() function. We include h8.h again after defining
72 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
73
74#include "elf/h8.h"
75#undef _ELF_H8_H
76
77/* Undo the effects of #including reloc-macros.h. */
78
79#undef START_RELOC_NUMBERS
80#undef RELOC_NUMBER
81#undef FAKE_RELOC
82#undef EMPTY_RELOC
83#undef END_RELOC_NUMBERS
84#undef _RELOC_MACROS_H
85
252b5132
RH
86/* The following headers use the elf/reloc-macros.h file to
87 automatically generate relocation recognition functions
88 such as elf_mips_reloc_type() */
89
90#define RELOC_MACROS_GEN_FUNC
91
a06ea964 92#include "elf/aarch64.h"
252b5132 93#include "elf/alpha.h"
3b16e843 94#include "elf/arc.h"
252b5132 95#include "elf/arm.h"
3b16e843 96#include "elf/avr.h"
1d65ded4 97#include "elf/bfin.h"
60bca95a 98#include "elf/cr16.h"
3b16e843 99#include "elf/cris.h"
1c0d3aa6 100#include "elf/crx.h"
252b5132
RH
101#include "elf/d10v.h"
102#include "elf/d30v.h"
d172d4ba 103#include "elf/dlx.h"
cfb8c092 104#include "elf/epiphany.h"
252b5132 105#include "elf/fr30.h"
5c70f934 106#include "elf/frv.h"
3f8107ab 107#include "elf/ft32.h"
3b16e843
NC
108#include "elf/h8.h"
109#include "elf/hppa.h"
110#include "elf/i386.h"
35b1837e 111#include "elf/i370.h"
3b16e843
NC
112#include "elf/i860.h"
113#include "elf/i960.h"
114#include "elf/ia64.h"
1e4cf259 115#include "elf/ip2k.h"
84e94c90 116#include "elf/lm32.h"
1c0d3aa6 117#include "elf/iq2000.h"
49f58d10 118#include "elf/m32c.h"
3b16e843
NC
119#include "elf/m32r.h"
120#include "elf/m68k.h"
75751cd9 121#include "elf/m68hc11.h"
252b5132 122#include "elf/mcore.h"
15ab5209 123#include "elf/mep.h"
a3c62988 124#include "elf/metag.h"
7ba29e2a 125#include "elf/microblaze.h"
3b16e843 126#include "elf/mips.h"
e23eba97 127#include "elf/riscv.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"
619ed720 152#include "elf/visium.h"
3b16e843 153#include "elf/x86-64.h"
c29aca4a 154#include "elf/xc16x.h"
f6c1a2d5 155#include "elf/xgate.h"
93fbbb04 156#include "elf/xstormy16.h"
88da6820 157#include "elf/xtensa.h"
252b5132 158
252b5132 159#include "getopt.h"
566b0d53 160#include "libiberty.h"
09c11c86 161#include "safe-ctype.h"
2cf0635d 162#include "filenames.h"
252b5132 163
15b42fb0
AM
164#ifndef offsetof
165#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
166#endif
167
6a40cf0c
NC
168typedef struct elf_section_list
169{
170 Elf_Internal_Shdr * hdr;
171 struct elf_section_list * next;
172} elf_section_list;
173
2cf0635d 174char * program_name = "readelf";
c9c1d674 175static unsigned long archive_file_offset;
85b1c36d 176static unsigned long archive_file_size;
f54498b4 177static bfd_size_type current_file_size;
85b1c36d
BE
178static unsigned long dynamic_addr;
179static bfd_size_type dynamic_size;
8b73c356 180static size_t dynamic_nent;
2cf0635d 181static char * dynamic_strings;
85b1c36d 182static unsigned long dynamic_strings_length;
2cf0635d 183static char * string_table;
85b1c36d
BE
184static unsigned long string_table_length;
185static unsigned long num_dynamic_syms;
2cf0635d
NC
186static Elf_Internal_Sym * dynamic_symbols;
187static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
188static unsigned long dynamic_syminfo_offset;
189static unsigned int dynamic_syminfo_nent;
f8eae8b2 190static char program_interpreter[PATH_MAX];
bb8a0291 191static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 192static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
193static bfd_vma version_info[16];
194static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
195static Elf_Internal_Shdr * section_headers;
196static Elf_Internal_Phdr * program_headers;
197static Elf_Internal_Dyn * dynamic_section;
6a40cf0c 198static elf_section_list * symtab_shndx_list;
85b1c36d
BE
199static int show_name;
200static int do_dynamic;
201static int do_syms;
2c610e4b 202static int do_dyn_syms;
85b1c36d
BE
203static int do_reloc;
204static int do_sections;
205static int do_section_groups;
5477e8a0 206static int do_section_details;
85b1c36d
BE
207static int do_segments;
208static int do_unwind;
209static int do_using_dynamic;
210static int do_header;
211static int do_dump;
212static int do_version;
85b1c36d
BE
213static int do_histogram;
214static int do_debugging;
85b1c36d
BE
215static int do_arch;
216static int do_notes;
4145f1d5 217static int do_archive_index;
85b1c36d 218static int is_32bit_elf;
0e602686 219static int decompress_dumps;
252b5132 220
e4b17d5c
L
221struct group_list
222{
2cf0635d 223 struct group_list * next;
e4b17d5c
L
224 unsigned int section_index;
225};
226
227struct group
228{
2cf0635d 229 struct group_list * root;
e4b17d5c
L
230 unsigned int group_index;
231};
232
85b1c36d 233static size_t group_count;
2cf0635d
NC
234static struct group * section_groups;
235static struct group ** section_headers_groups;
e4b17d5c 236
09c11c86
NC
237
238/* Flag bits indicating particular types of dump. */
239#define HEX_DUMP (1 << 0) /* The -x command line switch. */
240#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
241#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
242#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 243#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
244
245typedef unsigned char dump_type;
246
247/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
248struct dump_list_entry
249{
2cf0635d 250 char * name;
09c11c86 251 dump_type type;
2cf0635d 252 struct dump_list_entry * next;
aef1f6d0 253};
2cf0635d 254static struct dump_list_entry * dump_sects_byname;
aef1f6d0 255
09c11c86
NC
256/* A dynamic array of flags indicating for which sections a dump
257 has been requested via command line switches. */
258static dump_type * cmdline_dump_sects = NULL;
259static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
260
261/* A dynamic array of flags indicating for which sections a dump of
262 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
263 basis and then initialised from the cmdline_dump_sects array,
264 the results of interpreting the -w switch, and the
265 dump_sects_byname list. */
09c11c86
NC
266static dump_type * dump_sects = NULL;
267static unsigned int num_dump_sects = 0;
252b5132 268
252b5132 269
c256ffe7 270/* How to print a vma value. */
843dd992
NC
271typedef enum print_mode
272{
273 HEX,
274 DEC,
275 DEC_5,
276 UNSIGNED,
277 PREFIX_HEX,
278 FULL_HEX,
279 LONG_HEX
280}
281print_mode;
282
bb4d2ac2
L
283/* Versioned symbol info. */
284enum versioned_symbol_info
285{
286 symbol_undefined,
287 symbol_hidden,
288 symbol_public
289};
290
15f205b1 291static const char *get_symbol_version_string
bb4d2ac2
L
292 (FILE *file, int is_dynsym, const char *strtab,
293 unsigned long int strtab_size, unsigned int si,
294 Elf_Internal_Sym *psym, enum versioned_symbol_info *sym_info,
295 unsigned short *vna_other);
296
9c19a809
NC
297#define UNKNOWN -1
298
2b692964
NC
299#define SECTION_NAME(X) \
300 ((X) == NULL ? _("<none>") \
301 : string_table == NULL ? _("<no-name>") \
302 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 303 : string_table + (X)->sh_name))
252b5132 304
ee42cf8c 305#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 306
ba5cdace
NC
307#define GET_ELF_SYMBOLS(file, section, sym_count) \
308 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
309 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 310
d79b3d50
NC
311#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
312/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
313 already been called and verified that the string exists. */
314#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 315
61865e30
NC
316#define REMOVE_ARCH_BITS(ADDR) \
317 do \
318 { \
319 if (elf_header.e_machine == EM_ARM) \
320 (ADDR) &= ~1; \
321 } \
322 while (0)
d79b3d50 323\f
c9c1d674
EG
324/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET +
325 the offset of the current archive member, if we are examining an archive.
59245841
NC
326 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
327 using malloc and fill that. In either case return the pointer to the start of
328 the retrieved data or NULL if something went wrong. If something does go wrong
c9c1d674
EG
329 and REASON is not NULL then emit an error message using REASON as part of the
330 context. */
59245841 331
c256ffe7 332static void *
57028622
NC
333get_data (void * var, FILE * file, unsigned long offset, bfd_size_type size,
334 bfd_size_type nmemb, const char * reason)
a6e9f9df 335{
2cf0635d 336 void * mvar;
57028622 337 bfd_size_type amt = size * nmemb;
a6e9f9df 338
c256ffe7 339 if (size == 0 || nmemb == 0)
a6e9f9df
AM
340 return NULL;
341
57028622
NC
342 /* If the size_t type is smaller than the bfd_size_type, eg because
343 you are building a 32-bit tool on a 64-bit host, then make sure
344 that when the sizes are cast to (size_t) no information is lost. */
345 if (sizeof (size_t) < sizeof (bfd_size_type)
346 && ( (bfd_size_type) ((size_t) size) != size
347 || (bfd_size_type) ((size_t) nmemb) != nmemb))
348 {
349 if (reason)
ed754a13
AM
350 error (_("Size truncation prevents reading 0x%" BFD_VMA_FMT "x"
351 " elements of size 0x%" BFD_VMA_FMT "x for %s\n"),
352 nmemb, size, reason);
57028622
NC
353 return NULL;
354 }
355
356 /* Check for size overflow. */
357 if (amt < nmemb)
358 {
359 if (reason)
ed754a13
AM
360 error (_("Size overflow prevents reading 0x%" BFD_VMA_FMT "x"
361 " elements of size 0x%" BFD_VMA_FMT "x for %s\n"),
362 nmemb, size, reason);
57028622
NC
363 return NULL;
364 }
365
c9c1d674
EG
366 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
367 attempting to allocate memory when the read is bound to fail. */
368 if (amt > current_file_size
369 || offset + archive_file_offset + amt > current_file_size)
a6e9f9df 370 {
049b0c3a 371 if (reason)
ed754a13
AM
372 error (_("Reading 0x%" BFD_VMA_FMT "x"
373 " bytes extends past end of file for %s\n"),
374 amt, reason);
a6e9f9df
AM
375 return NULL;
376 }
377
c9c1d674 378 if (fseek (file, archive_file_offset + offset, SEEK_SET))
071436c6
NC
379 {
380 if (reason)
c9c1d674 381 error (_("Unable to seek to 0x%lx for %s\n"),
ed754a13 382 archive_file_offset + offset, reason);
071436c6
NC
383 return NULL;
384 }
385
a6e9f9df
AM
386 mvar = var;
387 if (mvar == NULL)
388 {
c256ffe7 389 /* Check for overflow. */
57028622 390 if (nmemb < (~(bfd_size_type) 0 - 1) / size)
c256ffe7 391 /* + 1 so that we can '\0' terminate invalid string table sections. */
57028622 392 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
393
394 if (mvar == NULL)
395 {
049b0c3a 396 if (reason)
ed754a13
AM
397 error (_("Out of memory allocating 0x%" BFD_VMA_FMT "x"
398 " bytes for %s\n"),
399 amt, reason);
a6e9f9df
AM
400 return NULL;
401 }
c256ffe7 402
c9c1d674 403 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
404 }
405
57028622 406 if (fread (mvar, (size_t) size, (size_t) nmemb, file) != nmemb)
a6e9f9df 407 {
049b0c3a 408 if (reason)
ed754a13
AM
409 error (_("Unable to read in 0x%" BFD_VMA_FMT "x bytes of %s\n"),
410 amt, reason);
a6e9f9df
AM
411 if (mvar != var)
412 free (mvar);
413 return NULL;
414 }
415
416 return mvar;
417}
418
14a91970 419/* Print a VMA value. */
cb8f3167 420
66543521 421static int
14a91970 422print_vma (bfd_vma vma, print_mode mode)
66543521 423{
66543521
AM
424 int nc = 0;
425
14a91970 426 switch (mode)
66543521 427 {
14a91970
AM
428 case FULL_HEX:
429 nc = printf ("0x");
1a0670f3 430 /* Fall through. */
66543521 431
14a91970 432 case LONG_HEX:
f7a99963 433#ifdef BFD64
14a91970 434 if (is_32bit_elf)
437c2fb7 435 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 436#endif
14a91970
AM
437 printf_vma (vma);
438 return nc + 16;
b19aac67 439
14a91970
AM
440 case DEC_5:
441 if (vma <= 99999)
442 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 443 /* Fall through. */
66543521 444
14a91970
AM
445 case PREFIX_HEX:
446 nc = printf ("0x");
1a0670f3 447 /* Fall through. */
66543521 448
14a91970
AM
449 case HEX:
450 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 451
14a91970
AM
452 case DEC:
453 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 454
14a91970
AM
455 case UNSIGNED:
456 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 457 }
66543521 458 return 0;
f7a99963
NC
459}
460
7bfd842d 461/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 462 multibye characters (assuming the host environment supports them).
31104126 463
7bfd842d
NC
464 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
465
466 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
467 padding as necessary.
171191ba
NC
468
469 Returns the number of emitted characters. */
470
471static unsigned int
7a88bc9c 472print_symbol (int width, const char *symbol)
31104126 473{
171191ba 474 bfd_boolean extra_padding = FALSE;
7bfd842d 475 int num_printed = 0;
3bfcb652 476#ifdef HAVE_MBSTATE_T
7bfd842d 477 mbstate_t state;
3bfcb652 478#endif
7bfd842d 479 int width_remaining;
961c521f 480
7bfd842d 481 if (width < 0)
961c521f 482 {
961c521f
NC
483 /* Keep the width positive. This also helps. */
484 width = - width;
171191ba 485 extra_padding = TRUE;
0b4362b0 486 }
74e1a04b 487 assert (width != 0);
961c521f 488
7bfd842d
NC
489 if (do_wide)
490 /* Set the remaining width to a very large value.
491 This simplifies the code below. */
492 width_remaining = INT_MAX;
493 else
494 width_remaining = width;
cb8f3167 495
3bfcb652 496#ifdef HAVE_MBSTATE_T
7bfd842d
NC
497 /* Initialise the multibyte conversion state. */
498 memset (& state, 0, sizeof (state));
3bfcb652 499#endif
961c521f 500
7bfd842d
NC
501 while (width_remaining)
502 {
503 size_t n;
7bfd842d 504 const char c = *symbol++;
961c521f 505
7bfd842d 506 if (c == 0)
961c521f
NC
507 break;
508
7bfd842d
NC
509 /* Do not print control characters directly as they can affect terminal
510 settings. Such characters usually appear in the names generated
511 by the assembler for local labels. */
512 if (ISCNTRL (c))
961c521f 513 {
7bfd842d 514 if (width_remaining < 2)
961c521f
NC
515 break;
516
7bfd842d
NC
517 printf ("^%c", c + 0x40);
518 width_remaining -= 2;
171191ba 519 num_printed += 2;
961c521f 520 }
7bfd842d
NC
521 else if (ISPRINT (c))
522 {
523 putchar (c);
524 width_remaining --;
525 num_printed ++;
526 }
961c521f
NC
527 else
528 {
3bfcb652
NC
529#ifdef HAVE_MBSTATE_T
530 wchar_t w;
531#endif
7bfd842d
NC
532 /* Let printf do the hard work of displaying multibyte characters. */
533 printf ("%.1s", symbol - 1);
534 width_remaining --;
535 num_printed ++;
536
3bfcb652 537#ifdef HAVE_MBSTATE_T
7bfd842d
NC
538 /* Try to find out how many bytes made up the character that was
539 just printed. Advance the symbol pointer past the bytes that
540 were displayed. */
541 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
542#else
543 n = 1;
544#endif
7bfd842d
NC
545 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
546 symbol += (n - 1);
961c521f 547 }
961c521f 548 }
171191ba 549
7bfd842d 550 if (extra_padding && num_printed < width)
171191ba
NC
551 {
552 /* Fill in the remaining spaces. */
7bfd842d
NC
553 printf ("%-*s", width - num_printed, " ");
554 num_printed = width;
171191ba
NC
555 }
556
557 return num_printed;
31104126
NC
558}
559
1449284b 560/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
561 the given section's name. Like print_symbol, except that it does not try
562 to print multibyte characters, it just interprets them as hex values. */
563
564static const char *
0d2a7a93 565printable_section_name (const Elf_Internal_Shdr * sec)
74e1a04b
NC
566{
567#define MAX_PRINT_SEC_NAME_LEN 128
568 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
569 const char * name = SECTION_NAME (sec);
570 char * buf = sec_name_buf;
571 char c;
572 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
573
574 while ((c = * name ++) != 0)
575 {
576 if (ISCNTRL (c))
577 {
578 if (remaining < 2)
579 break;
948f632f 580
74e1a04b
NC
581 * buf ++ = '^';
582 * buf ++ = c + 0x40;
583 remaining -= 2;
584 }
585 else if (ISPRINT (c))
586 {
587 * buf ++ = c;
588 remaining -= 1;
589 }
590 else
591 {
592 static char hex[17] = "0123456789ABCDEF";
593
594 if (remaining < 4)
595 break;
596 * buf ++ = '<';
597 * buf ++ = hex[(c & 0xf0) >> 4];
598 * buf ++ = hex[c & 0x0f];
599 * buf ++ = '>';
600 remaining -= 4;
601 }
602
603 if (remaining == 0)
604 break;
605 }
606
607 * buf = 0;
608 return sec_name_buf;
609}
610
611static const char *
612printable_section_name_from_index (unsigned long ndx)
613{
614 if (ndx >= elf_header.e_shnum)
615 return _("<corrupt>");
616
617 return printable_section_name (section_headers + ndx);
618}
619
89fac5e3
RS
620/* Return a pointer to section NAME, or NULL if no such section exists. */
621
622static Elf_Internal_Shdr *
2cf0635d 623find_section (const char * name)
89fac5e3
RS
624{
625 unsigned int i;
626
627 for (i = 0; i < elf_header.e_shnum; i++)
628 if (streq (SECTION_NAME (section_headers + i), name))
629 return section_headers + i;
630
631 return NULL;
632}
633
0b6ae522
DJ
634/* Return a pointer to a section containing ADDR, or NULL if no such
635 section exists. */
636
637static Elf_Internal_Shdr *
638find_section_by_address (bfd_vma addr)
639{
640 unsigned int i;
641
642 for (i = 0; i < elf_header.e_shnum; i++)
643 {
644 Elf_Internal_Shdr *sec = section_headers + i;
645 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
646 return sec;
647 }
648
649 return NULL;
650}
651
071436c6
NC
652static Elf_Internal_Shdr *
653find_section_by_type (unsigned int type)
654{
655 unsigned int i;
656
657 for (i = 0; i < elf_header.e_shnum; i++)
658 {
659 Elf_Internal_Shdr *sec = section_headers + i;
660 if (sec->sh_type == type)
661 return sec;
662 }
663
664 return NULL;
665}
666
657d0d47
CC
667/* Return a pointer to section NAME, or NULL if no such section exists,
668 restricted to the list of sections given in SET. */
669
670static Elf_Internal_Shdr *
671find_section_in_set (const char * name, unsigned int * set)
672{
673 unsigned int i;
674
675 if (set != NULL)
676 {
677 while ((i = *set++) > 0)
678 if (streq (SECTION_NAME (section_headers + i), name))
679 return section_headers + i;
680 }
681
682 return find_section (name);
683}
684
0b6ae522
DJ
685/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
686 bytes read. */
687
f6f0e17b
NC
688static inline unsigned long
689read_uleb128 (unsigned char *data,
690 unsigned int *length_return,
691 const unsigned char * const end)
0b6ae522 692{
f6f0e17b 693 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
694}
695
28f997cf
TG
696/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
697 This OS has so many departures from the ELF standard that we test it at
698 many places. */
699
700static inline int
701is_ia64_vms (void)
702{
703 return elf_header.e_machine == EM_IA_64
704 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
705}
706
bcedfee6 707/* Guess the relocation size commonly used by the specific machines. */
252b5132 708
252b5132 709static int
2dc4cec1 710guess_is_rela (unsigned int e_machine)
252b5132 711{
9c19a809 712 switch (e_machine)
252b5132
RH
713 {
714 /* Targets that use REL relocations. */
252b5132 715 case EM_386:
22abe556 716 case EM_IAMCU:
63fcb9e9 717 case EM_960:
e9f53129 718 case EM_ARM:
2b0337b0 719 case EM_D10V:
252b5132 720 case EM_CYGNUS_D10V:
e9f53129 721 case EM_DLX:
252b5132 722 case EM_MIPS:
4fe85591 723 case EM_MIPS_RS3_LE:
e9f53129 724 case EM_CYGNUS_M32R:
1c0d3aa6 725 case EM_SCORE:
f6c1a2d5 726 case EM_XGATE:
9c19a809 727 return FALSE;
103f02d3 728
252b5132
RH
729 /* Targets that use RELA relocations. */
730 case EM_68K:
e9f53129 731 case EM_860:
a06ea964 732 case EM_AARCH64:
cfb8c092 733 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
734 case EM_ALPHA:
735 case EM_ALTERA_NIOS2:
886a2506
NC
736 case EM_ARC:
737 case EM_ARC_COMPACT:
738 case EM_ARC_COMPACT2:
e9f53129
AM
739 case EM_AVR:
740 case EM_AVR_OLD:
741 case EM_BLACKFIN:
60bca95a 742 case EM_CR16:
e9f53129
AM
743 case EM_CRIS:
744 case EM_CRX:
2b0337b0 745 case EM_D30V:
252b5132 746 case EM_CYGNUS_D30V:
2b0337b0 747 case EM_FR30:
3f8107ab 748 case EM_FT32:
252b5132 749 case EM_CYGNUS_FR30:
5c70f934 750 case EM_CYGNUS_FRV:
e9f53129
AM
751 case EM_H8S:
752 case EM_H8_300:
753 case EM_H8_300H:
800eeca4 754 case EM_IA_64:
1e4cf259
NC
755 case EM_IP2K:
756 case EM_IP2K_OLD:
3b36097d 757 case EM_IQ2000:
84e94c90 758 case EM_LATTICEMICO32:
ff7eeb89 759 case EM_M32C_OLD:
49f58d10 760 case EM_M32C:
e9f53129
AM
761 case EM_M32R:
762 case EM_MCORE:
15ab5209 763 case EM_CYGNUS_MEP:
a3c62988 764 case EM_METAG:
e9f53129
AM
765 case EM_MMIX:
766 case EM_MN10200:
767 case EM_CYGNUS_MN10200:
768 case EM_MN10300:
769 case EM_CYGNUS_MN10300:
5506d11a 770 case EM_MOXIE:
e9f53129
AM
771 case EM_MSP430:
772 case EM_MSP430_OLD:
d031aafb 773 case EM_MT:
35c08157 774 case EM_NDS32:
64fd6348 775 case EM_NIOS32:
73589c9d 776 case EM_OR1K:
e9f53129
AM
777 case EM_PPC64:
778 case EM_PPC:
e23eba97 779 case EM_RISCV:
99c513f6 780 case EM_RL78:
c7927a3c 781 case EM_RX:
e9f53129
AM
782 case EM_S390:
783 case EM_S390_OLD:
784 case EM_SH:
785 case EM_SPARC:
786 case EM_SPARC32PLUS:
787 case EM_SPARCV9:
788 case EM_SPU:
40b36596 789 case EM_TI_C6000:
aa137e4d
NC
790 case EM_TILEGX:
791 case EM_TILEPRO:
708e2187 792 case EM_V800:
e9f53129
AM
793 case EM_V850:
794 case EM_CYGNUS_V850:
795 case EM_VAX:
619ed720 796 case EM_VISIUM:
e9f53129 797 case EM_X86_64:
8a9036a4 798 case EM_L1OM:
7a9068fe 799 case EM_K1OM:
e9f53129
AM
800 case EM_XSTORMY16:
801 case EM_XTENSA:
802 case EM_XTENSA_OLD:
7ba29e2a
NC
803 case EM_MICROBLAZE:
804 case EM_MICROBLAZE_OLD:
9c19a809 805 return TRUE;
103f02d3 806
e9f53129
AM
807 case EM_68HC05:
808 case EM_68HC08:
809 case EM_68HC11:
810 case EM_68HC16:
811 case EM_FX66:
812 case EM_ME16:
d1133906 813 case EM_MMA:
d1133906
NC
814 case EM_NCPU:
815 case EM_NDR1:
e9f53129 816 case EM_PCP:
d1133906 817 case EM_ST100:
e9f53129 818 case EM_ST19:
d1133906 819 case EM_ST7:
e9f53129
AM
820 case EM_ST9PLUS:
821 case EM_STARCORE:
d1133906 822 case EM_SVX:
e9f53129 823 case EM_TINYJ:
9c19a809
NC
824 default:
825 warn (_("Don't know about relocations on this machine architecture\n"));
826 return FALSE;
827 }
828}
252b5132 829
9c19a809 830static int
2cf0635d 831slurp_rela_relocs (FILE * file,
d3ba0551
AM
832 unsigned long rel_offset,
833 unsigned long rel_size,
2cf0635d
NC
834 Elf_Internal_Rela ** relasp,
835 unsigned long * nrelasp)
9c19a809 836{
2cf0635d 837 Elf_Internal_Rela * relas;
8b73c356 838 size_t nrelas;
4d6ed7c8 839 unsigned int i;
252b5132 840
4d6ed7c8
NC
841 if (is_32bit_elf)
842 {
2cf0635d 843 Elf32_External_Rela * erelas;
103f02d3 844
3f5e193b 845 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 846 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
847 if (!erelas)
848 return 0;
252b5132 849
4d6ed7c8 850 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 851
3f5e193b
NC
852 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
853 sizeof (Elf_Internal_Rela));
103f02d3 854
4d6ed7c8
NC
855 if (relas == NULL)
856 {
c256ffe7 857 free (erelas);
591a748a 858 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
859 return 0;
860 }
103f02d3 861
4d6ed7c8
NC
862 for (i = 0; i < nrelas; i++)
863 {
864 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
865 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 866 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 867 }
103f02d3 868
4d6ed7c8
NC
869 free (erelas);
870 }
871 else
872 {
2cf0635d 873 Elf64_External_Rela * erelas;
103f02d3 874
3f5e193b 875 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 876 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
877 if (!erelas)
878 return 0;
4d6ed7c8
NC
879
880 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 881
3f5e193b
NC
882 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
883 sizeof (Elf_Internal_Rela));
103f02d3 884
4d6ed7c8
NC
885 if (relas == NULL)
886 {
c256ffe7 887 free (erelas);
591a748a 888 error (_("out of memory parsing relocs\n"));
4d6ed7c8 889 return 0;
9c19a809 890 }
4d6ed7c8
NC
891
892 for (i = 0; i < nrelas; i++)
9c19a809 893 {
66543521
AM
894 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
895 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 896 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
897
898 /* The #ifdef BFD64 below is to prevent a compile time
899 warning. We know that if we do not have a 64 bit data
900 type that we will never execute this code anyway. */
901#ifdef BFD64
902 if (elf_header.e_machine == EM_MIPS
903 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
904 {
905 /* In little-endian objects, r_info isn't really a
906 64-bit little-endian value: it has a 32-bit
907 little-endian symbol index followed by four
908 individual byte fields. Reorder INFO
909 accordingly. */
91d6fa6a
NC
910 bfd_vma inf = relas[i].r_info;
911 inf = (((inf & 0xffffffff) << 32)
912 | ((inf >> 56) & 0xff)
913 | ((inf >> 40) & 0xff00)
914 | ((inf >> 24) & 0xff0000)
915 | ((inf >> 8) & 0xff000000));
916 relas[i].r_info = inf;
861fb55a
DJ
917 }
918#endif /* BFD64 */
4d6ed7c8 919 }
103f02d3 920
4d6ed7c8
NC
921 free (erelas);
922 }
923 *relasp = relas;
924 *nrelasp = nrelas;
925 return 1;
926}
103f02d3 927
4d6ed7c8 928static int
2cf0635d 929slurp_rel_relocs (FILE * file,
d3ba0551
AM
930 unsigned long rel_offset,
931 unsigned long rel_size,
2cf0635d
NC
932 Elf_Internal_Rela ** relsp,
933 unsigned long * nrelsp)
4d6ed7c8 934{
2cf0635d 935 Elf_Internal_Rela * rels;
8b73c356 936 size_t nrels;
4d6ed7c8 937 unsigned int i;
103f02d3 938
4d6ed7c8
NC
939 if (is_32bit_elf)
940 {
2cf0635d 941 Elf32_External_Rel * erels;
103f02d3 942
3f5e193b 943 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 944 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
945 if (!erels)
946 return 0;
103f02d3 947
4d6ed7c8 948 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 949
3f5e193b 950 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 951
4d6ed7c8
NC
952 if (rels == NULL)
953 {
c256ffe7 954 free (erels);
591a748a 955 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
956 return 0;
957 }
958
959 for (i = 0; i < nrels; i++)
960 {
961 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
962 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 963 rels[i].r_addend = 0;
9ea033b2 964 }
4d6ed7c8
NC
965
966 free (erels);
9c19a809
NC
967 }
968 else
969 {
2cf0635d 970 Elf64_External_Rel * erels;
9ea033b2 971
3f5e193b 972 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 973 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
974 if (!erels)
975 return 0;
103f02d3 976
4d6ed7c8 977 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 978
3f5e193b 979 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 980
4d6ed7c8 981 if (rels == NULL)
9c19a809 982 {
c256ffe7 983 free (erels);
591a748a 984 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
985 return 0;
986 }
103f02d3 987
4d6ed7c8
NC
988 for (i = 0; i < nrels; i++)
989 {
66543521
AM
990 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
991 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 992 rels[i].r_addend = 0;
861fb55a
DJ
993
994 /* The #ifdef BFD64 below is to prevent a compile time
995 warning. We know that if we do not have a 64 bit data
996 type that we will never execute this code anyway. */
997#ifdef BFD64
998 if (elf_header.e_machine == EM_MIPS
999 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
1000 {
1001 /* In little-endian objects, r_info isn't really a
1002 64-bit little-endian value: it has a 32-bit
1003 little-endian symbol index followed by four
1004 individual byte fields. Reorder INFO
1005 accordingly. */
91d6fa6a
NC
1006 bfd_vma inf = rels[i].r_info;
1007 inf = (((inf & 0xffffffff) << 32)
1008 | ((inf >> 56) & 0xff)
1009 | ((inf >> 40) & 0xff00)
1010 | ((inf >> 24) & 0xff0000)
1011 | ((inf >> 8) & 0xff000000));
1012 rels[i].r_info = inf;
861fb55a
DJ
1013 }
1014#endif /* BFD64 */
4d6ed7c8 1015 }
103f02d3 1016
4d6ed7c8
NC
1017 free (erels);
1018 }
1019 *relsp = rels;
1020 *nrelsp = nrels;
1021 return 1;
1022}
103f02d3 1023
aca88567
NC
1024/* Returns the reloc type extracted from the reloc info field. */
1025
1026static unsigned int
1027get_reloc_type (bfd_vma reloc_info)
1028{
1029 if (is_32bit_elf)
1030 return ELF32_R_TYPE (reloc_info);
1031
1032 switch (elf_header.e_machine)
1033 {
1034 case EM_MIPS:
1035 /* Note: We assume that reloc_info has already been adjusted for us. */
1036 return ELF64_MIPS_R_TYPE (reloc_info);
1037
1038 case EM_SPARCV9:
1039 return ELF64_R_TYPE_ID (reloc_info);
1040
1041 default:
1042 return ELF64_R_TYPE (reloc_info);
1043 }
1044}
1045
1046/* Return the symbol index extracted from the reloc info field. */
1047
1048static bfd_vma
1049get_reloc_symindex (bfd_vma reloc_info)
1050{
1051 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1052}
1053
13761a11
NC
1054static inline bfd_boolean
1055uses_msp430x_relocs (void)
1056{
1057 return
1058 elf_header.e_machine == EM_MSP430 /* Paranoia. */
1059 /* GCC uses osabi == ELFOSBI_STANDALONE. */
1060 && (((elf_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
1061 /* TI compiler uses ELFOSABI_NONE. */
1062 || (elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
1063}
1064
d3ba0551
AM
1065/* Display the contents of the relocation data found at the specified
1066 offset. */
ee42cf8c 1067
41e92641 1068static void
2cf0635d 1069dump_relocations (FILE * file,
d3ba0551
AM
1070 unsigned long rel_offset,
1071 unsigned long rel_size,
2cf0635d 1072 Elf_Internal_Sym * symtab,
d3ba0551 1073 unsigned long nsyms,
2cf0635d 1074 char * strtab,
d79b3d50 1075 unsigned long strtablen,
bb4d2ac2
L
1076 int is_rela,
1077 int is_dynsym)
4d6ed7c8 1078{
b34976b6 1079 unsigned int i;
2cf0635d 1080 Elf_Internal_Rela * rels;
103f02d3 1081
4d6ed7c8
NC
1082 if (is_rela == UNKNOWN)
1083 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 1084
4d6ed7c8
NC
1085 if (is_rela)
1086 {
c8286bd1 1087 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 1088 return;
4d6ed7c8
NC
1089 }
1090 else
1091 {
1092 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 1093 return;
252b5132
RH
1094 }
1095
410f7a12
L
1096 if (is_32bit_elf)
1097 {
1098 if (is_rela)
2c71103e
NC
1099 {
1100 if (do_wide)
1101 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1102 else
1103 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1104 }
410f7a12 1105 else
2c71103e
NC
1106 {
1107 if (do_wide)
1108 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1109 else
1110 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1111 }
410f7a12 1112 }
252b5132 1113 else
410f7a12
L
1114 {
1115 if (is_rela)
2c71103e
NC
1116 {
1117 if (do_wide)
8beeaeb7 1118 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1119 else
1120 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1121 }
410f7a12 1122 else
2c71103e
NC
1123 {
1124 if (do_wide)
8beeaeb7 1125 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1126 else
1127 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1128 }
410f7a12 1129 }
252b5132
RH
1130
1131 for (i = 0; i < rel_size; i++)
1132 {
2cf0635d 1133 const char * rtype;
b34976b6 1134 bfd_vma offset;
91d6fa6a 1135 bfd_vma inf;
b34976b6
AM
1136 bfd_vma symtab_index;
1137 bfd_vma type;
103f02d3 1138
b34976b6 1139 offset = rels[i].r_offset;
91d6fa6a 1140 inf = rels[i].r_info;
103f02d3 1141
91d6fa6a
NC
1142 type = get_reloc_type (inf);
1143 symtab_index = get_reloc_symindex (inf);
252b5132 1144
410f7a12
L
1145 if (is_32bit_elf)
1146 {
39dbeff8
AM
1147 printf ("%8.8lx %8.8lx ",
1148 (unsigned long) offset & 0xffffffff,
91d6fa6a 1149 (unsigned long) inf & 0xffffffff);
410f7a12
L
1150 }
1151 else
1152 {
39dbeff8
AM
1153#if BFD_HOST_64BIT_LONG
1154 printf (do_wide
1155 ? "%16.16lx %16.16lx "
1156 : "%12.12lx %12.12lx ",
91d6fa6a 1157 offset, inf);
39dbeff8 1158#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1159#ifndef __MSVCRT__
39dbeff8
AM
1160 printf (do_wide
1161 ? "%16.16llx %16.16llx "
1162 : "%12.12llx %12.12llx ",
91d6fa6a 1163 offset, inf);
6e3d6dc1
NC
1164#else
1165 printf (do_wide
1166 ? "%16.16I64x %16.16I64x "
1167 : "%12.12I64x %12.12I64x ",
91d6fa6a 1168 offset, inf);
6e3d6dc1 1169#endif
39dbeff8 1170#else
2c71103e
NC
1171 printf (do_wide
1172 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1173 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1174 _bfd_int64_high (offset),
1175 _bfd_int64_low (offset),
91d6fa6a
NC
1176 _bfd_int64_high (inf),
1177 _bfd_int64_low (inf));
9ea033b2 1178#endif
410f7a12 1179 }
103f02d3 1180
252b5132
RH
1181 switch (elf_header.e_machine)
1182 {
1183 default:
1184 rtype = NULL;
1185 break;
1186
a06ea964
NC
1187 case EM_AARCH64:
1188 rtype = elf_aarch64_reloc_type (type);
1189 break;
1190
2b0337b0 1191 case EM_M32R:
252b5132 1192 case EM_CYGNUS_M32R:
9ea033b2 1193 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1194 break;
1195
1196 case EM_386:
22abe556 1197 case EM_IAMCU:
9ea033b2 1198 rtype = elf_i386_reloc_type (type);
252b5132
RH
1199 break;
1200
ba2685cc
AM
1201 case EM_68HC11:
1202 case EM_68HC12:
1203 rtype = elf_m68hc11_reloc_type (type);
1204 break;
75751cd9 1205
252b5132 1206 case EM_68K:
9ea033b2 1207 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1208 break;
1209
63fcb9e9 1210 case EM_960:
9ea033b2 1211 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1212 break;
1213
adde6300 1214 case EM_AVR:
2b0337b0 1215 case EM_AVR_OLD:
adde6300
AM
1216 rtype = elf_avr_reloc_type (type);
1217 break;
1218
9ea033b2
NC
1219 case EM_OLD_SPARCV9:
1220 case EM_SPARC32PLUS:
1221 case EM_SPARCV9:
252b5132 1222 case EM_SPARC:
9ea033b2 1223 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1224 break;
1225
e9f53129
AM
1226 case EM_SPU:
1227 rtype = elf_spu_reloc_type (type);
1228 break;
1229
708e2187
NC
1230 case EM_V800:
1231 rtype = v800_reloc_type (type);
1232 break;
2b0337b0 1233 case EM_V850:
252b5132 1234 case EM_CYGNUS_V850:
9ea033b2 1235 rtype = v850_reloc_type (type);
252b5132
RH
1236 break;
1237
2b0337b0 1238 case EM_D10V:
252b5132 1239 case EM_CYGNUS_D10V:
9ea033b2 1240 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1241 break;
1242
2b0337b0 1243 case EM_D30V:
252b5132 1244 case EM_CYGNUS_D30V:
9ea033b2 1245 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1246 break;
1247
d172d4ba
NC
1248 case EM_DLX:
1249 rtype = elf_dlx_reloc_type (type);
1250 break;
1251
252b5132 1252 case EM_SH:
9ea033b2 1253 rtype = elf_sh_reloc_type (type);
252b5132
RH
1254 break;
1255
2b0337b0 1256 case EM_MN10300:
252b5132 1257 case EM_CYGNUS_MN10300:
9ea033b2 1258 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1259 break;
1260
2b0337b0 1261 case EM_MN10200:
252b5132 1262 case EM_CYGNUS_MN10200:
9ea033b2 1263 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1264 break;
1265
2b0337b0 1266 case EM_FR30:
252b5132 1267 case EM_CYGNUS_FR30:
9ea033b2 1268 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1269 break;
1270
ba2685cc
AM
1271 case EM_CYGNUS_FRV:
1272 rtype = elf_frv_reloc_type (type);
1273 break;
5c70f934 1274
3f8107ab
AM
1275 case EM_FT32:
1276 rtype = elf_ft32_reloc_type (type);
1277 break;
1278
252b5132 1279 case EM_MCORE:
9ea033b2 1280 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1281 break;
1282
3c3bdf30
NC
1283 case EM_MMIX:
1284 rtype = elf_mmix_reloc_type (type);
1285 break;
1286
5506d11a
AM
1287 case EM_MOXIE:
1288 rtype = elf_moxie_reloc_type (type);
1289 break;
1290
2469cfa2 1291 case EM_MSP430:
13761a11
NC
1292 if (uses_msp430x_relocs ())
1293 {
1294 rtype = elf_msp430x_reloc_type (type);
1295 break;
1296 }
1a0670f3 1297 /* Fall through. */
2469cfa2
NC
1298 case EM_MSP430_OLD:
1299 rtype = elf_msp430_reloc_type (type);
1300 break;
1301
35c08157
KLC
1302 case EM_NDS32:
1303 rtype = elf_nds32_reloc_type (type);
1304 break;
1305
252b5132 1306 case EM_PPC:
9ea033b2 1307 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1308 break;
1309
c833c019
AM
1310 case EM_PPC64:
1311 rtype = elf_ppc64_reloc_type (type);
1312 break;
1313
252b5132 1314 case EM_MIPS:
4fe85591 1315 case EM_MIPS_RS3_LE:
9ea033b2 1316 rtype = elf_mips_reloc_type (type);
252b5132
RH
1317 break;
1318
e23eba97
NC
1319 case EM_RISCV:
1320 rtype = elf_riscv_reloc_type (type);
1321 break;
1322
252b5132 1323 case EM_ALPHA:
9ea033b2 1324 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1325 break;
1326
1327 case EM_ARM:
9ea033b2 1328 rtype = elf_arm_reloc_type (type);
252b5132
RH
1329 break;
1330
584da044 1331 case EM_ARC:
886a2506
NC
1332 case EM_ARC_COMPACT:
1333 case EM_ARC_COMPACT2:
9ea033b2 1334 rtype = elf_arc_reloc_type (type);
252b5132
RH
1335 break;
1336
1337 case EM_PARISC:
69e617ca 1338 rtype = elf_hppa_reloc_type (type);
252b5132 1339 break;
7d466069 1340
b8720f9d
JL
1341 case EM_H8_300:
1342 case EM_H8_300H:
1343 case EM_H8S:
1344 rtype = elf_h8_reloc_type (type);
1345 break;
1346
73589c9d
CS
1347 case EM_OR1K:
1348 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1349 break;
1350
7d466069 1351 case EM_PJ:
2b0337b0 1352 case EM_PJ_OLD:
7d466069
ILT
1353 rtype = elf_pj_reloc_type (type);
1354 break;
800eeca4
JW
1355 case EM_IA_64:
1356 rtype = elf_ia64_reloc_type (type);
1357 break;
1b61cf92
HPN
1358
1359 case EM_CRIS:
1360 rtype = elf_cris_reloc_type (type);
1361 break;
535c37ff
JE
1362
1363 case EM_860:
1364 rtype = elf_i860_reloc_type (type);
1365 break;
bcedfee6
NC
1366
1367 case EM_X86_64:
8a9036a4 1368 case EM_L1OM:
7a9068fe 1369 case EM_K1OM:
bcedfee6
NC
1370 rtype = elf_x86_64_reloc_type (type);
1371 break;
a85d7ed0 1372
35b1837e
AM
1373 case EM_S370:
1374 rtype = i370_reloc_type (type);
1375 break;
1376
53c7db4b
KH
1377 case EM_S390_OLD:
1378 case EM_S390:
1379 rtype = elf_s390_reloc_type (type);
1380 break;
93fbbb04 1381
1c0d3aa6
NC
1382 case EM_SCORE:
1383 rtype = elf_score_reloc_type (type);
1384 break;
1385
93fbbb04
GK
1386 case EM_XSTORMY16:
1387 rtype = elf_xstormy16_reloc_type (type);
1388 break;
179d3252 1389
1fe1f39c
NC
1390 case EM_CRX:
1391 rtype = elf_crx_reloc_type (type);
1392 break;
1393
179d3252
JT
1394 case EM_VAX:
1395 rtype = elf_vax_reloc_type (type);
1396 break;
1e4cf259 1397
619ed720
EB
1398 case EM_VISIUM:
1399 rtype = elf_visium_reloc_type (type);
1400 break;
1401
cfb8c092
NC
1402 case EM_ADAPTEVA_EPIPHANY:
1403 rtype = elf_epiphany_reloc_type (type);
1404 break;
1405
1e4cf259
NC
1406 case EM_IP2K:
1407 case EM_IP2K_OLD:
1408 rtype = elf_ip2k_reloc_type (type);
1409 break;
3b36097d
SC
1410
1411 case EM_IQ2000:
1412 rtype = elf_iq2000_reloc_type (type);
1413 break;
88da6820
NC
1414
1415 case EM_XTENSA_OLD:
1416 case EM_XTENSA:
1417 rtype = elf_xtensa_reloc_type (type);
1418 break;
a34e3ecb 1419
84e94c90
NC
1420 case EM_LATTICEMICO32:
1421 rtype = elf_lm32_reloc_type (type);
1422 break;
1423
ff7eeb89 1424 case EM_M32C_OLD:
49f58d10
JB
1425 case EM_M32C:
1426 rtype = elf_m32c_reloc_type (type);
1427 break;
1428
d031aafb
NS
1429 case EM_MT:
1430 rtype = elf_mt_reloc_type (type);
a34e3ecb 1431 break;
1d65ded4
CM
1432
1433 case EM_BLACKFIN:
1434 rtype = elf_bfin_reloc_type (type);
1435 break;
15ab5209
DB
1436
1437 case EM_CYGNUS_MEP:
1438 rtype = elf_mep_reloc_type (type);
1439 break;
60bca95a
NC
1440
1441 case EM_CR16:
1442 rtype = elf_cr16_reloc_type (type);
1443 break;
dd24e3da 1444
7ba29e2a
NC
1445 case EM_MICROBLAZE:
1446 case EM_MICROBLAZE_OLD:
1447 rtype = elf_microblaze_reloc_type (type);
1448 break;
c7927a3c 1449
99c513f6
DD
1450 case EM_RL78:
1451 rtype = elf_rl78_reloc_type (type);
1452 break;
1453
c7927a3c
NC
1454 case EM_RX:
1455 rtype = elf_rx_reloc_type (type);
1456 break;
c29aca4a 1457
a3c62988
NC
1458 case EM_METAG:
1459 rtype = elf_metag_reloc_type (type);
1460 break;
1461
c29aca4a
NC
1462 case EM_XC16X:
1463 case EM_C166:
1464 rtype = elf_xc16x_reloc_type (type);
1465 break;
40b36596
JM
1466
1467 case EM_TI_C6000:
1468 rtype = elf_tic6x_reloc_type (type);
1469 break;
aa137e4d
NC
1470
1471 case EM_TILEGX:
1472 rtype = elf_tilegx_reloc_type (type);
1473 break;
1474
1475 case EM_TILEPRO:
1476 rtype = elf_tilepro_reloc_type (type);
1477 break;
f6c1a2d5
NC
1478
1479 case EM_XGATE:
1480 rtype = elf_xgate_reloc_type (type);
1481 break;
36591ba1
SL
1482
1483 case EM_ALTERA_NIOS2:
1484 rtype = elf_nios2_reloc_type (type);
1485 break;
252b5132
RH
1486 }
1487
1488 if (rtype == NULL)
39dbeff8 1489 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1490 else
8beeaeb7 1491 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1492
7ace3541 1493 if (elf_header.e_machine == EM_ALPHA
157c2599 1494 && rtype != NULL
7ace3541
RH
1495 && streq (rtype, "R_ALPHA_LITUSE")
1496 && is_rela)
1497 {
1498 switch (rels[i].r_addend)
1499 {
1500 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1501 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1502 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1503 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1504 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1505 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1506 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1507 default: rtype = NULL;
1508 }
1509 if (rtype)
1510 printf (" (%s)", rtype);
1511 else
1512 {
1513 putchar (' ');
1514 printf (_("<unknown addend: %lx>"),
1515 (unsigned long) rels[i].r_addend);
1516 }
1517 }
1518 else if (symtab_index)
252b5132 1519 {
af3fc3bc 1520 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1521 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1522 else
19936277 1523 {
2cf0635d 1524 Elf_Internal_Sym * psym;
bb4d2ac2
L
1525 const char * version_string;
1526 enum versioned_symbol_info sym_info;
1527 unsigned short vna_other;
19936277 1528
af3fc3bc 1529 psym = symtab + symtab_index;
103f02d3 1530
bb4d2ac2
L
1531 version_string
1532 = get_symbol_version_string (file, is_dynsym,
1533 strtab, strtablen,
1534 symtab_index,
1535 psym,
1536 &sym_info,
1537 &vna_other);
1538
af3fc3bc 1539 printf (" ");
171191ba 1540
d8045f23
NC
1541 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1542 {
1543 const char * name;
1544 unsigned int len;
1545 unsigned int width = is_32bit_elf ? 8 : 14;
1546
1547 /* Relocations against GNU_IFUNC symbols do not use the value
1548 of the symbol as the address to relocate against. Instead
1549 they invoke the function named by the symbol and use its
1550 result as the address for relocation.
1551
1552 To indicate this to the user, do not display the value of
1553 the symbol in the "Symbols's Value" field. Instead show
1554 its name followed by () as a hint that the symbol is
1555 invoked. */
1556
1557 if (strtab == NULL
1558 || psym->st_name == 0
1559 || psym->st_name >= strtablen)
1560 name = "??";
1561 else
1562 name = strtab + psym->st_name;
1563
1564 len = print_symbol (width, name);
bb4d2ac2
L
1565 if (version_string)
1566 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1567 version_string);
d8045f23
NC
1568 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1569 }
1570 else
1571 {
1572 print_vma (psym->st_value, LONG_HEX);
171191ba 1573
d8045f23
NC
1574 printf (is_32bit_elf ? " " : " ");
1575 }
103f02d3 1576
af3fc3bc 1577 if (psym->st_name == 0)
f1ef08cb 1578 {
2cf0635d 1579 const char * sec_name = "<null>";
f1ef08cb
AM
1580 char name_buf[40];
1581
1582 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1583 {
4fbb74a6 1584 if (psym->st_shndx < elf_header.e_shnum)
74e1a04b 1585 sec_name = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1586 else if (psym->st_shndx == SHN_ABS)
1587 sec_name = "ABS";
1588 else if (psym->st_shndx == SHN_COMMON)
1589 sec_name = "COMMON";
ac145307
BS
1590 else if ((elf_header.e_machine == EM_MIPS
1591 && psym->st_shndx == SHN_MIPS_SCOMMON)
1592 || (elf_header.e_machine == EM_TI_C6000
1593 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1594 sec_name = "SCOMMON";
1595 else if (elf_header.e_machine == EM_MIPS
1596 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1597 sec_name = "SUNDEF";
8a9036a4 1598 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1599 || elf_header.e_machine == EM_L1OM
1600 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1601 && psym->st_shndx == SHN_X86_64_LCOMMON)
1602 sec_name = "LARGE_COMMON";
9ce701e2
L
1603 else if (elf_header.e_machine == EM_IA_64
1604 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1605 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1606 sec_name = "ANSI_COM";
28f997cf 1607 else if (is_ia64_vms ()
148b93f2
NC
1608 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1609 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1610 else
1611 {
1612 sprintf (name_buf, "<section 0x%x>",
1613 (unsigned int) psym->st_shndx);
1614 sec_name = name_buf;
1615 }
1616 }
1617 print_symbol (22, sec_name);
1618 }
af3fc3bc 1619 else if (strtab == NULL)
d79b3d50 1620 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1621 else if (psym->st_name >= strtablen)
d79b3d50 1622 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1623 else
bb4d2ac2
L
1624 {
1625 print_symbol (22, strtab + psym->st_name);
1626 if (version_string)
1627 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1628 version_string);
1629 }
103f02d3 1630
af3fc3bc 1631 if (is_rela)
171191ba 1632 {
7360e63f 1633 bfd_vma off = rels[i].r_addend;
171191ba 1634
7360e63f 1635 if ((bfd_signed_vma) off < 0)
598aaa76 1636 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1637 else
598aaa76 1638 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1639 }
19936277 1640 }
252b5132 1641 }
1b228002 1642 else if (is_rela)
f7a99963 1643 {
7360e63f 1644 bfd_vma off = rels[i].r_addend;
e04d7088
L
1645
1646 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1647 if ((bfd_signed_vma) off < 0)
e04d7088
L
1648 printf ("-%" BFD_VMA_FMT "x", - off);
1649 else
1650 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1651 }
252b5132 1652
157c2599
NC
1653 if (elf_header.e_machine == EM_SPARCV9
1654 && rtype != NULL
1655 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1656 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1657
252b5132 1658 putchar ('\n');
2c71103e 1659
aca88567 1660#ifdef BFD64
53c7db4b 1661 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1662 {
91d6fa6a
NC
1663 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1664 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1665 const char * rtype2 = elf_mips_reloc_type (type2);
1666 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1667
2c71103e
NC
1668 printf (" Type2: ");
1669
1670 if (rtype2 == NULL)
39dbeff8
AM
1671 printf (_("unrecognized: %-7lx"),
1672 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1673 else
1674 printf ("%-17.17s", rtype2);
1675
18bd398b 1676 printf ("\n Type3: ");
2c71103e
NC
1677
1678 if (rtype3 == NULL)
39dbeff8
AM
1679 printf (_("unrecognized: %-7lx"),
1680 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1681 else
1682 printf ("%-17.17s", rtype3);
1683
53c7db4b 1684 putchar ('\n');
2c71103e 1685 }
aca88567 1686#endif /* BFD64 */
252b5132
RH
1687 }
1688
c8286bd1 1689 free (rels);
252b5132
RH
1690}
1691
1692static const char *
d3ba0551 1693get_mips_dynamic_type (unsigned long type)
252b5132
RH
1694{
1695 switch (type)
1696 {
1697 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1698 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1699 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1700 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1701 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1702 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1703 case DT_MIPS_MSYM: return "MIPS_MSYM";
1704 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1705 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1706 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1707 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1708 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1709 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1710 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1711 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1712 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1713 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1714 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1715 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1716 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1717 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1718 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1719 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1720 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1721 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1722 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1723 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1724 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1725 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1726 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1727 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1728 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1729 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1730 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1731 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1732 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1733 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1734 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1735 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1736 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1737 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1738 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1739 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1740 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1741 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1742 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1743 default:
1744 return NULL;
1745 }
1746}
1747
9a097730 1748static const char *
d3ba0551 1749get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1750{
1751 switch (type)
1752 {
1753 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1754 default:
1755 return NULL;
1756 }
103f02d3
UD
1757}
1758
7490d522
AM
1759static const char *
1760get_ppc_dynamic_type (unsigned long type)
1761{
1762 switch (type)
1763 {
a7f2871e 1764 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1765 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1766 default:
1767 return NULL;
1768 }
1769}
1770
f1cb7e17 1771static const char *
d3ba0551 1772get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1773{
1774 switch (type)
1775 {
a7f2871e
AM
1776 case DT_PPC64_GLINK: return "PPC64_GLINK";
1777 case DT_PPC64_OPD: return "PPC64_OPD";
1778 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1779 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1780 default:
1781 return NULL;
1782 }
1783}
1784
103f02d3 1785static const char *
d3ba0551 1786get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1787{
1788 switch (type)
1789 {
1790 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1791 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1792 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1793 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1794 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1795 case DT_HP_PREINIT: return "HP_PREINIT";
1796 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1797 case DT_HP_NEEDED: return "HP_NEEDED";
1798 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1799 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1800 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1801 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1802 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1803 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1804 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1805 case DT_HP_FILTERED: return "HP_FILTERED";
1806 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1807 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1808 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1809 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1810 case DT_PLT: return "PLT";
1811 case DT_PLT_SIZE: return "PLT_SIZE";
1812 case DT_DLT: return "DLT";
1813 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1814 default:
1815 return NULL;
1816 }
1817}
9a097730 1818
ecc51f48 1819static const char *
d3ba0551 1820get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1821{
1822 switch (type)
1823 {
148b93f2
NC
1824 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1825 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1826 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1827 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1828 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1829 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1830 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1831 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1832 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1833 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1834 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1835 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1836 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1837 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1838 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1839 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1840 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1841 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1842 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1843 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1844 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1845 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1846 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1847 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1848 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1849 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1850 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1851 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1852 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1853 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1854 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1855 default:
1856 return NULL;
1857 }
1858}
1859
fd85a6a1
NC
1860static const char *
1861get_solaris_section_type (unsigned long type)
1862{
1863 switch (type)
1864 {
1865 case 0x6fffffee: return "SUNW_ancillary";
1866 case 0x6fffffef: return "SUNW_capchain";
1867 case 0x6ffffff0: return "SUNW_capinfo";
1868 case 0x6ffffff1: return "SUNW_symsort";
1869 case 0x6ffffff2: return "SUNW_tlssort";
1870 case 0x6ffffff3: return "SUNW_LDYNSYM";
1871 case 0x6ffffff4: return "SUNW_dof";
1872 case 0x6ffffff5: return "SUNW_cap";
1873 case 0x6ffffff6: return "SUNW_SIGNATURE";
1874 case 0x6ffffff7: return "SUNW_ANNOTATE";
1875 case 0x6ffffff8: return "SUNW_DEBUGSTR";
1876 case 0x6ffffff9: return "SUNW_DEBUG";
1877 case 0x6ffffffa: return "SUNW_move";
1878 case 0x6ffffffb: return "SUNW_COMDAT";
1879 case 0x6ffffffc: return "SUNW_syminfo";
1880 case 0x6ffffffd: return "SUNW_verdef";
1881 case 0x6ffffffe: return "SUNW_verneed";
1882 case 0x6fffffff: return "SUNW_versym";
1883 case 0x70000000: return "SPARC_GOTDATA";
1884 default: return NULL;
1885 }
1886}
1887
fabcb361
RH
1888static const char *
1889get_alpha_dynamic_type (unsigned long type)
1890{
1891 switch (type)
1892 {
1893 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1894 default:
1895 return NULL;
1896 }
1897}
1898
1c0d3aa6
NC
1899static const char *
1900get_score_dynamic_type (unsigned long type)
1901{
1902 switch (type)
1903 {
1904 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1905 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1906 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1907 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1908 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1909 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1910 default:
1911 return NULL;
1912 }
1913}
1914
40b36596
JM
1915static const char *
1916get_tic6x_dynamic_type (unsigned long type)
1917{
1918 switch (type)
1919 {
1920 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1921 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1922 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1923 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1924 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1925 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1926 default:
1927 return NULL;
1928 }
1929}
1c0d3aa6 1930
36591ba1
SL
1931static const char *
1932get_nios2_dynamic_type (unsigned long type)
1933{
1934 switch (type)
1935 {
1936 case DT_NIOS2_GP: return "NIOS2_GP";
1937 default:
1938 return NULL;
1939 }
1940}
1941
fd85a6a1
NC
1942static const char *
1943get_solaris_dynamic_type (unsigned long type)
1944{
1945 switch (type)
1946 {
1947 case 0x6000000d: return "SUNW_AUXILIARY";
1948 case 0x6000000e: return "SUNW_RTLDINF";
1949 case 0x6000000f: return "SUNW_FILTER";
1950 case 0x60000010: return "SUNW_CAP";
1951 case 0x60000011: return "SUNW_SYMTAB";
1952 case 0x60000012: return "SUNW_SYMSZ";
1953 case 0x60000013: return "SUNW_SORTENT";
1954 case 0x60000014: return "SUNW_SYMSORT";
1955 case 0x60000015: return "SUNW_SYMSORTSZ";
1956 case 0x60000016: return "SUNW_TLSSORT";
1957 case 0x60000017: return "SUNW_TLSSORTSZ";
1958 case 0x60000018: return "SUNW_CAPINFO";
1959 case 0x60000019: return "SUNW_STRPAD";
1960 case 0x6000001a: return "SUNW_CAPCHAIN";
1961 case 0x6000001b: return "SUNW_LDMACH";
1962 case 0x6000001d: return "SUNW_CAPCHAINENT";
1963 case 0x6000001f: return "SUNW_CAPCHAINSZ";
1964 case 0x60000021: return "SUNW_PARENT";
1965 case 0x60000023: return "SUNW_ASLR";
1966 case 0x60000025: return "SUNW_RELAX";
1967 case 0x60000029: return "SUNW_NXHEAP";
1968 case 0x6000002b: return "SUNW_NXSTACK";
1969
1970 case 0x70000001: return "SPARC_REGISTER";
1971 case 0x7ffffffd: return "AUXILIARY";
1972 case 0x7ffffffe: return "USED";
1973 case 0x7fffffff: return "FILTER";
1974
15f205b1 1975 default: return NULL;
fd85a6a1
NC
1976 }
1977}
1978
252b5132 1979static const char *
d3ba0551 1980get_dynamic_type (unsigned long type)
252b5132 1981{
e9e44622 1982 static char buff[64];
252b5132
RH
1983
1984 switch (type)
1985 {
1986 case DT_NULL: return "NULL";
1987 case DT_NEEDED: return "NEEDED";
1988 case DT_PLTRELSZ: return "PLTRELSZ";
1989 case DT_PLTGOT: return "PLTGOT";
1990 case DT_HASH: return "HASH";
1991 case DT_STRTAB: return "STRTAB";
1992 case DT_SYMTAB: return "SYMTAB";
1993 case DT_RELA: return "RELA";
1994 case DT_RELASZ: return "RELASZ";
1995 case DT_RELAENT: return "RELAENT";
1996 case DT_STRSZ: return "STRSZ";
1997 case DT_SYMENT: return "SYMENT";
1998 case DT_INIT: return "INIT";
1999 case DT_FINI: return "FINI";
2000 case DT_SONAME: return "SONAME";
2001 case DT_RPATH: return "RPATH";
2002 case DT_SYMBOLIC: return "SYMBOLIC";
2003 case DT_REL: return "REL";
2004 case DT_RELSZ: return "RELSZ";
2005 case DT_RELENT: return "RELENT";
2006 case DT_PLTREL: return "PLTREL";
2007 case DT_DEBUG: return "DEBUG";
2008 case DT_TEXTREL: return "TEXTREL";
2009 case DT_JMPREL: return "JMPREL";
2010 case DT_BIND_NOW: return "BIND_NOW";
2011 case DT_INIT_ARRAY: return "INIT_ARRAY";
2012 case DT_FINI_ARRAY: return "FINI_ARRAY";
2013 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2014 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2015 case DT_RUNPATH: return "RUNPATH";
2016 case DT_FLAGS: return "FLAGS";
2d0e6f43 2017
d1133906
NC
2018 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2019 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2020 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2021
05107a46 2022 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2023 case DT_PLTPADSZ: return "PLTPADSZ";
2024 case DT_MOVEENT: return "MOVEENT";
2025 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2026 case DT_FEATURE: return "FEATURE";
252b5132
RH
2027 case DT_POSFLAG_1: return "POSFLAG_1";
2028 case DT_SYMINSZ: return "SYMINSZ";
2029 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2030
252b5132 2031 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2032 case DT_CONFIG: return "CONFIG";
2033 case DT_DEPAUDIT: return "DEPAUDIT";
2034 case DT_AUDIT: return "AUDIT";
2035 case DT_PLTPAD: return "PLTPAD";
2036 case DT_MOVETAB: return "MOVETAB";
252b5132 2037 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2038
252b5132 2039 case DT_VERSYM: return "VERSYM";
103f02d3 2040
67a4f2b7
AO
2041 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2042 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2043 case DT_RELACOUNT: return "RELACOUNT";
2044 case DT_RELCOUNT: return "RELCOUNT";
2045 case DT_FLAGS_1: return "FLAGS_1";
2046 case DT_VERDEF: return "VERDEF";
2047 case DT_VERDEFNUM: return "VERDEFNUM";
2048 case DT_VERNEED: return "VERNEED";
2049 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2050
019148e4 2051 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2052 case DT_USED: return "USED";
2053 case DT_FILTER: return "FILTER";
103f02d3 2054
047b2264
JJ
2055 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2056 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2057 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2058 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2059 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2060 case DT_GNU_HASH: return "GNU_HASH";
047b2264 2061
252b5132
RH
2062 default:
2063 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2064 {
2cf0635d 2065 const char * result;
103f02d3 2066
252b5132
RH
2067 switch (elf_header.e_machine)
2068 {
2069 case EM_MIPS:
4fe85591 2070 case EM_MIPS_RS3_LE:
252b5132
RH
2071 result = get_mips_dynamic_type (type);
2072 break;
9a097730
RH
2073 case EM_SPARCV9:
2074 result = get_sparc64_dynamic_type (type);
2075 break;
7490d522
AM
2076 case EM_PPC:
2077 result = get_ppc_dynamic_type (type);
2078 break;
f1cb7e17
AM
2079 case EM_PPC64:
2080 result = get_ppc64_dynamic_type (type);
2081 break;
ecc51f48
NC
2082 case EM_IA_64:
2083 result = get_ia64_dynamic_type (type);
2084 break;
fabcb361
RH
2085 case EM_ALPHA:
2086 result = get_alpha_dynamic_type (type);
2087 break;
1c0d3aa6
NC
2088 case EM_SCORE:
2089 result = get_score_dynamic_type (type);
2090 break;
40b36596
JM
2091 case EM_TI_C6000:
2092 result = get_tic6x_dynamic_type (type);
2093 break;
36591ba1
SL
2094 case EM_ALTERA_NIOS2:
2095 result = get_nios2_dynamic_type (type);
2096 break;
252b5132 2097 default:
fd85a6a1
NC
2098 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
2099 result = get_solaris_dynamic_type (type);
2100 else
2101 result = NULL;
252b5132
RH
2102 break;
2103 }
2104
2105 if (result != NULL)
2106 return result;
2107
e9e44622 2108 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2109 }
eec8f817
DA
2110 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
2111 || (elf_header.e_machine == EM_PARISC
2112 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2113 {
2cf0635d 2114 const char * result;
103f02d3
UD
2115
2116 switch (elf_header.e_machine)
2117 {
2118 case EM_PARISC:
2119 result = get_parisc_dynamic_type (type);
2120 break;
148b93f2
NC
2121 case EM_IA_64:
2122 result = get_ia64_dynamic_type (type);
2123 break;
103f02d3 2124 default:
fd85a6a1
NC
2125 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
2126 result = get_solaris_dynamic_type (type);
2127 else
2128 result = NULL;
103f02d3
UD
2129 break;
2130 }
2131
2132 if (result != NULL)
2133 return result;
2134
e9e44622
JJ
2135 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2136 type);
103f02d3 2137 }
252b5132 2138 else
e9e44622 2139 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2140
252b5132
RH
2141 return buff;
2142 }
2143}
2144
2145static char *
d3ba0551 2146get_file_type (unsigned e_type)
252b5132 2147{
b34976b6 2148 static char buff[32];
252b5132
RH
2149
2150 switch (e_type)
2151 {
2152 case ET_NONE: return _("NONE (None)");
2153 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
2154 case ET_EXEC: return _("EXEC (Executable file)");
2155 case ET_DYN: return _("DYN (Shared object file)");
2156 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2157
2158 default:
2159 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2160 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2161 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2162 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2163 else
e9e44622 2164 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2165 return buff;
2166 }
2167}
2168
2169static char *
d3ba0551 2170get_machine_name (unsigned e_machine)
252b5132 2171{
b34976b6 2172 static char buff[64]; /* XXX */
252b5132
RH
2173
2174 switch (e_machine)
2175 {
c45021f2 2176 case EM_NONE: return _("None");
a06ea964 2177 case EM_AARCH64: return "AArch64";
c45021f2
NC
2178 case EM_M32: return "WE32100";
2179 case EM_SPARC: return "Sparc";
e9f53129 2180 case EM_SPU: return "SPU";
c45021f2
NC
2181 case EM_386: return "Intel 80386";
2182 case EM_68K: return "MC68000";
2183 case EM_88K: return "MC88000";
22abe556 2184 case EM_IAMCU: return "Intel MCU";
c45021f2
NC
2185 case EM_860: return "Intel 80860";
2186 case EM_MIPS: return "MIPS R3000";
2187 case EM_S370: return "IBM System/370";
7036c0e1 2188 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2189 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2190 case EM_PARISC: return "HPPA";
252b5132 2191 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 2192 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
2193 case EM_960: return "Intel 90860";
2194 case EM_PPC: return "PowerPC";
285d1771 2195 case EM_PPC64: return "PowerPC64";
c45021f2 2196 case EM_FR20: return "Fujitsu FR20";
3f8107ab 2197 case EM_FT32: return "FTDI FT32";
c45021f2 2198 case EM_RH32: return "TRW RH32";
b34976b6 2199 case EM_MCORE: return "MCORE";
7036c0e1
AJ
2200 case EM_ARM: return "ARM";
2201 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2202 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2203 case EM_SPARCV9: return "Sparc v9";
2204 case EM_TRICORE: return "Siemens Tricore";
584da044 2205 case EM_ARC: return "ARC";
886a2506
NC
2206 case EM_ARC_COMPACT: return "ARCompact";
2207 case EM_ARC_COMPACT2: return "ARCv2";
c2dcd04e
NC
2208 case EM_H8_300: return "Renesas H8/300";
2209 case EM_H8_300H: return "Renesas H8/300H";
2210 case EM_H8S: return "Renesas H8S";
2211 case EM_H8_500: return "Renesas H8/500";
30800947 2212 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2213 case EM_MIPS_X: return "Stanford MIPS-X";
2214 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 2215 case EM_ALPHA: return "Alpha";
2b0337b0
AO
2216 case EM_CYGNUS_D10V:
2217 case EM_D10V: return "d10v";
2218 case EM_CYGNUS_D30V:
b34976b6 2219 case EM_D30V: return "d30v";
2b0337b0 2220 case EM_CYGNUS_M32R:
26597c86 2221 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 2222 case EM_CYGNUS_V850:
708e2187 2223 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 2224 case EM_V850: return "Renesas V850";
2b0337b0
AO
2225 case EM_CYGNUS_MN10300:
2226 case EM_MN10300: return "mn10300";
2227 case EM_CYGNUS_MN10200:
2228 case EM_MN10200: return "mn10200";
5506d11a 2229 case EM_MOXIE: return "Moxie";
2b0337b0
AO
2230 case EM_CYGNUS_FR30:
2231 case EM_FR30: return "Fujitsu FR30";
b34976b6 2232 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 2233 case EM_PJ_OLD:
b34976b6 2234 case EM_PJ: return "picoJava";
7036c0e1
AJ
2235 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2236 case EM_PCP: return "Siemens PCP";
2237 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2238 case EM_NDR1: return "Denso NDR1 microprocesspr";
2239 case EM_STARCORE: return "Motorola Star*Core processor";
2240 case EM_ME16: return "Toyota ME16 processor";
2241 case EM_ST100: return "STMicroelectronics ST100 processor";
2242 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
2243 case EM_PDSP: return "Sony DSP processor";
2244 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2245 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2246 case EM_FX66: return "Siemens FX66 microcontroller";
2247 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2248 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2249 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 2250 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2251 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2252 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2253 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2254 case EM_SVX: return "Silicon Graphics SVx";
2255 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2256 case EM_VAX: return "Digital VAX";
619ed720 2257 case EM_VISIUM: return "CDS VISIUMcore processor";
2b0337b0 2258 case EM_AVR_OLD:
b34976b6 2259 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 2260 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2261 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2262 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2263 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 2264 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2265 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2266 case EM_PRISM: return "Vitesse Prism";
bcedfee6 2267 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 2268 case EM_L1OM: return "Intel L1OM";
7a9068fe 2269 case EM_K1OM: return "Intel K1OM";
b7498e0e 2270 case EM_S390_OLD:
b34976b6 2271 case EM_S390: return "IBM S/390";
1c0d3aa6 2272 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 2273 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
73589c9d 2274 case EM_OR1K: return "OpenRISC 1000";
1fe1f39c 2275 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 2276 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 2277 case EM_DLX: return "OpenDLX";
1e4cf259 2278 case EM_IP2K_OLD:
b34976b6 2279 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 2280 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
2281 case EM_XTENSA_OLD:
2282 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2283 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2284 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2285 case EM_NS32K: return "National Semiconductor 32000 series";
2286 case EM_TPC: return "Tenor Network TPC processor";
2287 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2288 case EM_MAX: return "MAX Processor";
2289 case EM_CR: return "National Semiconductor CompactRISC";
2290 case EM_F2MC16: return "Fujitsu F2MC16";
2291 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 2292 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 2293 case EM_M32C_OLD:
49f58d10 2294 case EM_M32C: return "Renesas M32c";
d031aafb 2295 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 2296 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2297 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2298 case EM_SEP: return "Sharp embedded microprocessor";
2299 case EM_ARCA: return "Arca RISC microprocessor";
2300 case EM_UNICORE: return "Unicore";
2301 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2302 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
2303 case EM_NIOS32: return "Altera Nios";
2304 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 2305 case EM_C166:
d70c5fc7 2306 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2307 case EM_M16C: return "Renesas M16C series microprocessors";
2308 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2309 case EM_CE: return "Freescale Communication Engine RISC core";
2310 case EM_TSK3000: return "Altium TSK3000 core";
2311 case EM_RS08: return "Freescale RS08 embedded processor";
2312 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2313 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2314 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2315 case EM_SE_C17: return "Seiko Epson C17 family";
2316 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2317 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2318 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2319 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2320 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2321 case EM_R32C: return "Renesas R32C series microprocessors";
2322 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2323 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2324 case EM_8051: return "Intel 8051 and variants";
2325 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2326 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2327 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2328 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2329 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2330 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2331 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2332 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2333 case EM_CR16:
f6c1a2d5 2334 case EM_MICROBLAZE:
7ba29e2a 2335 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
e23eba97 2336 case EM_RISCV: return "RISC-V";
99c513f6 2337 case EM_RL78: return "Renesas RL78";
c7927a3c 2338 case EM_RX: return "Renesas RX";
a3c62988 2339 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2340 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2341 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2342 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2343 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2344 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2345 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2346 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2347 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2348 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2349 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2350 case EM_XGATE: return "Motorola XGATE embedded processor";
6d913794
NC
2351 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2352 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2353 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
2354 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
2355 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
2356 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2357 case EM_BA1: return "Beyond BA1 CPU architecture";
2358 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2359 case EM_XCORE: return "XMOS xCORE processor family";
2360 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
2361 case EM_KM32: return "KM211 KM32 32-bit processor";
2362 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2363 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2364 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2365 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2366 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2367 case EM_COGE: return "Cognitive Smart Memory Processor";
2368 case EM_COOL: return "Bluechip Systems CoolEngine";
2369 case EM_NORC: return "Nanoradio Optimized RISC";
2370 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
15f205b1 2371 case EM_Z80: return "Zilog Z80";
6d913794 2372 case EM_AMDGPU: return "AMD GPU architecture";
252b5132 2373 default:
35d9dd2f 2374 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2375 return buff;
2376 }
2377}
2378
a9522a21
AB
2379static void
2380decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2381{
2382 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
2383 other compilers don't a specific architecture type in the e_flags, and
2384 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2385 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2386 architectures.
2387
2388 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2389 but also sets a specific architecture type in the e_flags field.
2390
2391 However, when decoding the flags we don't worry if we see an
2392 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2393 ARCEM architecture type. */
2394
2395 switch (e_flags & EF_ARC_MACH_MSK)
2396 {
2397 /* We only expect these to occur for EM_ARC_COMPACT2. */
2398 case EF_ARC_CPU_ARCV2EM:
2399 strcat (buf, ", ARC EM");
2400 break;
2401 case EF_ARC_CPU_ARCV2HS:
2402 strcat (buf, ", ARC HS");
2403 break;
2404
2405 /* We only expect these to occur for EM_ARC_COMPACT. */
2406 case E_ARC_MACH_ARC600:
2407 strcat (buf, ", ARC600");
2408 break;
2409 case E_ARC_MACH_ARC601:
2410 strcat (buf, ", ARC601");
2411 break;
2412 case E_ARC_MACH_ARC700:
2413 strcat (buf, ", ARC700");
2414 break;
2415
2416 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2417 new ELF with new architecture being read by an old version of
2418 readelf, or (c) An ELF built with non-GNU compiler that does not
2419 set the architecture in the e_flags. */
2420 default:
2421 if (e_machine == EM_ARC_COMPACT)
2422 strcat (buf, ", Unknown ARCompact");
2423 else
2424 strcat (buf, ", Unknown ARC");
2425 break;
2426 }
2427
2428 switch (e_flags & EF_ARC_OSABI_MSK)
2429 {
2430 case E_ARC_OSABI_ORIG:
2431 strcat (buf, ", (ABI:legacy)");
2432 break;
2433 case E_ARC_OSABI_V2:
2434 strcat (buf, ", (ABI:v2)");
2435 break;
2436 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2437 case E_ARC_OSABI_V3:
2438 strcat (buf, ", v3 no-legacy-syscalls ABI");
2439 break;
2440 default:
2441 strcat (buf, ", unrecognised ARC OSABI flag");
2442 break;
2443 }
2444}
2445
f3485b74 2446static void
d3ba0551 2447decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2448{
2449 unsigned eabi;
2450 int unknown = 0;
2451
2452 eabi = EF_ARM_EABI_VERSION (e_flags);
2453 e_flags &= ~ EF_ARM_EABIMASK;
2454
2455 /* Handle "generic" ARM flags. */
2456 if (e_flags & EF_ARM_RELEXEC)
2457 {
2458 strcat (buf, ", relocatable executable");
2459 e_flags &= ~ EF_ARM_RELEXEC;
2460 }
76da6bbe 2461
f3485b74
NC
2462 /* Now handle EABI specific flags. */
2463 switch (eabi)
2464 {
2465 default:
2c71103e 2466 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2467 if (e_flags)
2468 unknown = 1;
2469 break;
2470
2471 case EF_ARM_EABI_VER1:
a5bcd848 2472 strcat (buf, ", Version1 EABI");
f3485b74
NC
2473 while (e_flags)
2474 {
2475 unsigned flag;
76da6bbe 2476
f3485b74
NC
2477 /* Process flags one bit at a time. */
2478 flag = e_flags & - e_flags;
2479 e_flags &= ~ flag;
76da6bbe 2480
f3485b74
NC
2481 switch (flag)
2482 {
a5bcd848 2483 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2484 strcat (buf, ", sorted symbol tables");
2485 break;
76da6bbe 2486
f3485b74
NC
2487 default:
2488 unknown = 1;
2489 break;
2490 }
2491 }
2492 break;
76da6bbe 2493
a5bcd848
PB
2494 case EF_ARM_EABI_VER2:
2495 strcat (buf, ", Version2 EABI");
2496 while (e_flags)
2497 {
2498 unsigned flag;
2499
2500 /* Process flags one bit at a time. */
2501 flag = e_flags & - e_flags;
2502 e_flags &= ~ flag;
2503
2504 switch (flag)
2505 {
2506 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2507 strcat (buf, ", sorted symbol tables");
2508 break;
2509
2510 case EF_ARM_DYNSYMSUSESEGIDX:
2511 strcat (buf, ", dynamic symbols use segment index");
2512 break;
2513
2514 case EF_ARM_MAPSYMSFIRST:
2515 strcat (buf, ", mapping symbols precede others");
2516 break;
2517
2518 default:
2519 unknown = 1;
2520 break;
2521 }
2522 }
2523 break;
2524
d507cf36
PB
2525 case EF_ARM_EABI_VER3:
2526 strcat (buf, ", Version3 EABI");
8cb51566
PB
2527 break;
2528
2529 case EF_ARM_EABI_VER4:
2530 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2531 while (e_flags)
2532 {
2533 unsigned flag;
2534
2535 /* Process flags one bit at a time. */
2536 flag = e_flags & - e_flags;
2537 e_flags &= ~ flag;
2538
2539 switch (flag)
2540 {
2541 case EF_ARM_BE8:
2542 strcat (buf, ", BE8");
2543 break;
2544
2545 case EF_ARM_LE8:
2546 strcat (buf, ", LE8");
2547 break;
2548
2549 default:
2550 unknown = 1;
2551 break;
2552 }
2553 break;
2554 }
2555 break;
3a4a14e9
PB
2556
2557 case EF_ARM_EABI_VER5:
2558 strcat (buf, ", Version5 EABI");
d507cf36
PB
2559 while (e_flags)
2560 {
2561 unsigned flag;
2562
2563 /* Process flags one bit at a time. */
2564 flag = e_flags & - e_flags;
2565 e_flags &= ~ flag;
2566
2567 switch (flag)
2568 {
2569 case EF_ARM_BE8:
2570 strcat (buf, ", BE8");
2571 break;
2572
2573 case EF_ARM_LE8:
2574 strcat (buf, ", LE8");
2575 break;
2576
3bfcb652
NC
2577 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2578 strcat (buf, ", soft-float ABI");
2579 break;
2580
2581 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2582 strcat (buf, ", hard-float ABI");
2583 break;
2584
d507cf36
PB
2585 default:
2586 unknown = 1;
2587 break;
2588 }
2589 }
2590 break;
2591
f3485b74 2592 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2593 strcat (buf, ", GNU EABI");
f3485b74
NC
2594 while (e_flags)
2595 {
2596 unsigned flag;
76da6bbe 2597
f3485b74
NC
2598 /* Process flags one bit at a time. */
2599 flag = e_flags & - e_flags;
2600 e_flags &= ~ flag;
76da6bbe 2601
f3485b74
NC
2602 switch (flag)
2603 {
a5bcd848 2604 case EF_ARM_INTERWORK:
f3485b74
NC
2605 strcat (buf, ", interworking enabled");
2606 break;
76da6bbe 2607
a5bcd848 2608 case EF_ARM_APCS_26:
f3485b74
NC
2609 strcat (buf, ", uses APCS/26");
2610 break;
76da6bbe 2611
a5bcd848 2612 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2613 strcat (buf, ", uses APCS/float");
2614 break;
76da6bbe 2615
a5bcd848 2616 case EF_ARM_PIC:
f3485b74
NC
2617 strcat (buf, ", position independent");
2618 break;
76da6bbe 2619
a5bcd848 2620 case EF_ARM_ALIGN8:
f3485b74
NC
2621 strcat (buf, ", 8 bit structure alignment");
2622 break;
76da6bbe 2623
a5bcd848 2624 case EF_ARM_NEW_ABI:
f3485b74
NC
2625 strcat (buf, ", uses new ABI");
2626 break;
76da6bbe 2627
a5bcd848 2628 case EF_ARM_OLD_ABI:
f3485b74
NC
2629 strcat (buf, ", uses old ABI");
2630 break;
76da6bbe 2631
a5bcd848 2632 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2633 strcat (buf, ", software FP");
2634 break;
76da6bbe 2635
90e01f86
ILT
2636 case EF_ARM_VFP_FLOAT:
2637 strcat (buf, ", VFP");
2638 break;
2639
fde78edd
NC
2640 case EF_ARM_MAVERICK_FLOAT:
2641 strcat (buf, ", Maverick FP");
2642 break;
2643
f3485b74
NC
2644 default:
2645 unknown = 1;
2646 break;
2647 }
2648 }
2649 }
f3485b74
NC
2650
2651 if (unknown)
2b692964 2652 strcat (buf,_(", <unknown>"));
f3485b74
NC
2653}
2654
343433df
AB
2655static void
2656decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2657{
2658 --size; /* Leave space for null terminator. */
2659
2660 switch (e_flags & EF_AVR_MACH)
2661 {
2662 case E_AVR_MACH_AVR1:
2663 strncat (buf, ", avr:1", size);
2664 break;
2665 case E_AVR_MACH_AVR2:
2666 strncat (buf, ", avr:2", size);
2667 break;
2668 case E_AVR_MACH_AVR25:
2669 strncat (buf, ", avr:25", size);
2670 break;
2671 case E_AVR_MACH_AVR3:
2672 strncat (buf, ", avr:3", size);
2673 break;
2674 case E_AVR_MACH_AVR31:
2675 strncat (buf, ", avr:31", size);
2676 break;
2677 case E_AVR_MACH_AVR35:
2678 strncat (buf, ", avr:35", size);
2679 break;
2680 case E_AVR_MACH_AVR4:
2681 strncat (buf, ", avr:4", size);
2682 break;
2683 case E_AVR_MACH_AVR5:
2684 strncat (buf, ", avr:5", size);
2685 break;
2686 case E_AVR_MACH_AVR51:
2687 strncat (buf, ", avr:51", size);
2688 break;
2689 case E_AVR_MACH_AVR6:
2690 strncat (buf, ", avr:6", size);
2691 break;
2692 case E_AVR_MACH_AVRTINY:
2693 strncat (buf, ", avr:100", size);
2694 break;
2695 case E_AVR_MACH_XMEGA1:
2696 strncat (buf, ", avr:101", size);
2697 break;
2698 case E_AVR_MACH_XMEGA2:
2699 strncat (buf, ", avr:102", size);
2700 break;
2701 case E_AVR_MACH_XMEGA3:
2702 strncat (buf, ", avr:103", size);
2703 break;
2704 case E_AVR_MACH_XMEGA4:
2705 strncat (buf, ", avr:104", size);
2706 break;
2707 case E_AVR_MACH_XMEGA5:
2708 strncat (buf, ", avr:105", size);
2709 break;
2710 case E_AVR_MACH_XMEGA6:
2711 strncat (buf, ", avr:106", size);
2712 break;
2713 case E_AVR_MACH_XMEGA7:
2714 strncat (buf, ", avr:107", size);
2715 break;
2716 default:
2717 strncat (buf, ", avr:<unknown>", size);
2718 break;
2719 }
2720
2721 size -= strlen (buf);
2722 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2723 strncat (buf, ", link-relax", size);
2724}
2725
35c08157
KLC
2726static void
2727decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2728{
2729 unsigned abi;
2730 unsigned arch;
2731 unsigned config;
2732 unsigned version;
2733 int has_fpu = 0;
2734 int r = 0;
2735
2736 static const char *ABI_STRINGS[] =
2737 {
2738 "ABI v0", /* use r5 as return register; only used in N1213HC */
2739 "ABI v1", /* use r0 as return register */
2740 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2741 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2742 "AABI",
2743 "ABI2 FP+"
35c08157
KLC
2744 };
2745 static const char *VER_STRINGS[] =
2746 {
2747 "Andes ELF V1.3 or older",
2748 "Andes ELF V1.3.1",
2749 "Andes ELF V1.4"
2750 };
2751 static const char *ARCH_STRINGS[] =
2752 {
2753 "",
2754 "Andes Star v1.0",
2755 "Andes Star v2.0",
2756 "Andes Star v3.0",
2757 "Andes Star v3.0m"
2758 };
2759
2760 abi = EF_NDS_ABI & e_flags;
2761 arch = EF_NDS_ARCH & e_flags;
2762 config = EF_NDS_INST & e_flags;
2763 version = EF_NDS32_ELF_VERSION & e_flags;
2764
2765 memset (buf, 0, size);
2766
2767 switch (abi)
2768 {
2769 case E_NDS_ABI_V0:
2770 case E_NDS_ABI_V1:
2771 case E_NDS_ABI_V2:
2772 case E_NDS_ABI_V2FP:
2773 case E_NDS_ABI_AABI:
40c7a7cb 2774 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2775 /* In case there are holes in the array. */
2776 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2777 break;
2778
2779 default:
2780 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2781 break;
2782 }
2783
2784 switch (version)
2785 {
2786 case E_NDS32_ELF_VER_1_2:
2787 case E_NDS32_ELF_VER_1_3:
2788 case E_NDS32_ELF_VER_1_4:
2789 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2790 break;
2791
2792 default:
2793 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2794 break;
2795 }
2796
2797 if (E_NDS_ABI_V0 == abi)
2798 {
2799 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2800 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2801 if (arch == E_NDS_ARCH_STAR_V1_0)
2802 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2803 return;
2804 }
2805
2806 switch (arch)
2807 {
2808 case E_NDS_ARCH_STAR_V1_0:
2809 case E_NDS_ARCH_STAR_V2_0:
2810 case E_NDS_ARCH_STAR_V3_0:
2811 case E_NDS_ARCH_STAR_V3_M:
2812 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
2813 break;
2814
2815 default:
2816 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
2817 /* ARCH version determines how the e_flags are interpreted.
2818 If it is unknown, we cannot proceed. */
2819 return;
2820 }
2821
2822 /* Newer ABI; Now handle architecture specific flags. */
2823 if (arch == E_NDS_ARCH_STAR_V1_0)
2824 {
2825 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2826 r += snprintf (buf + r, size -r, ", MFUSR_PC");
2827
2828 if (!(config & E_NDS32_HAS_NO_MAC_INST))
2829 r += snprintf (buf + r, size -r, ", MAC");
2830
2831 if (config & E_NDS32_HAS_DIV_INST)
2832 r += snprintf (buf + r, size -r, ", DIV");
2833
2834 if (config & E_NDS32_HAS_16BIT_INST)
2835 r += snprintf (buf + r, size -r, ", 16b");
2836 }
2837 else
2838 {
2839 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2840 {
2841 if (version <= E_NDS32_ELF_VER_1_3)
2842 r += snprintf (buf + r, size -r, ", [B8]");
2843 else
2844 r += snprintf (buf + r, size -r, ", EX9");
2845 }
2846
2847 if (config & E_NDS32_HAS_MAC_DX_INST)
2848 r += snprintf (buf + r, size -r, ", MAC_DX");
2849
2850 if (config & E_NDS32_HAS_DIV_DX_INST)
2851 r += snprintf (buf + r, size -r, ", DIV_DX");
2852
2853 if (config & E_NDS32_HAS_16BIT_INST)
2854 {
2855 if (version <= E_NDS32_ELF_VER_1_3)
2856 r += snprintf (buf + r, size -r, ", 16b");
2857 else
2858 r += snprintf (buf + r, size -r, ", IFC");
2859 }
2860 }
2861
2862 if (config & E_NDS32_HAS_EXT_INST)
2863 r += snprintf (buf + r, size -r, ", PERF1");
2864
2865 if (config & E_NDS32_HAS_EXT2_INST)
2866 r += snprintf (buf + r, size -r, ", PERF2");
2867
2868 if (config & E_NDS32_HAS_FPU_INST)
2869 {
2870 has_fpu = 1;
2871 r += snprintf (buf + r, size -r, ", FPU_SP");
2872 }
2873
2874 if (config & E_NDS32_HAS_FPU_DP_INST)
2875 {
2876 has_fpu = 1;
2877 r += snprintf (buf + r, size -r, ", FPU_DP");
2878 }
2879
2880 if (config & E_NDS32_HAS_FPU_MAC_INST)
2881 {
2882 has_fpu = 1;
2883 r += snprintf (buf + r, size -r, ", FPU_MAC");
2884 }
2885
2886 if (has_fpu)
2887 {
2888 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
2889 {
2890 case E_NDS32_FPU_REG_8SP_4DP:
2891 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
2892 break;
2893 case E_NDS32_FPU_REG_16SP_8DP:
2894 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
2895 break;
2896 case E_NDS32_FPU_REG_32SP_16DP:
2897 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
2898 break;
2899 case E_NDS32_FPU_REG_32SP_32DP:
2900 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
2901 break;
2902 }
2903 }
2904
2905 if (config & E_NDS32_HAS_AUDIO_INST)
2906 r += snprintf (buf + r, size -r, ", AUDIO");
2907
2908 if (config & E_NDS32_HAS_STRING_INST)
2909 r += snprintf (buf + r, size -r, ", STR");
2910
2911 if (config & E_NDS32_HAS_REDUCED_REGS)
2912 r += snprintf (buf + r, size -r, ", 16REG");
2913
2914 if (config & E_NDS32_HAS_VIDEO_INST)
2915 {
2916 if (version <= E_NDS32_ELF_VER_1_3)
2917 r += snprintf (buf + r, size -r, ", VIDEO");
2918 else
2919 r += snprintf (buf + r, size -r, ", SATURATION");
2920 }
2921
2922 if (config & E_NDS32_HAS_ENCRIPT_INST)
2923 r += snprintf (buf + r, size -r, ", ENCRP");
2924
2925 if (config & E_NDS32_HAS_L2C_INST)
2926 r += snprintf (buf + r, size -r, ", L2C");
2927}
2928
252b5132 2929static char *
d3ba0551 2930get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2931{
b34976b6 2932 static char buf[1024];
252b5132
RH
2933
2934 buf[0] = '\0';
76da6bbe 2935
252b5132
RH
2936 if (e_flags)
2937 {
2938 switch (e_machine)
2939 {
2940 default:
2941 break;
2942
886a2506 2943 case EM_ARC_COMPACT2:
886a2506 2944 case EM_ARC_COMPACT:
a9522a21
AB
2945 decode_ARC_machine_flags (e_flags, e_machine, buf);
2946 break;
886a2506 2947
f3485b74
NC
2948 case EM_ARM:
2949 decode_ARM_machine_flags (e_flags, buf);
2950 break;
76da6bbe 2951
343433df
AB
2952 case EM_AVR:
2953 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
2954 break;
2955
781303ce
MF
2956 case EM_BLACKFIN:
2957 if (e_flags & EF_BFIN_PIC)
2958 strcat (buf, ", PIC");
2959
2960 if (e_flags & EF_BFIN_FDPIC)
2961 strcat (buf, ", FDPIC");
2962
2963 if (e_flags & EF_BFIN_CODE_IN_L1)
2964 strcat (buf, ", code in L1");
2965
2966 if (e_flags & EF_BFIN_DATA_IN_L1)
2967 strcat (buf, ", data in L1");
2968
2969 break;
2970
ec2dfb42
AO
2971 case EM_CYGNUS_FRV:
2972 switch (e_flags & EF_FRV_CPU_MASK)
2973 {
2974 case EF_FRV_CPU_GENERIC:
2975 break;
2976
2977 default:
2978 strcat (buf, ", fr???");
2979 break;
57346661 2980
ec2dfb42
AO
2981 case EF_FRV_CPU_FR300:
2982 strcat (buf, ", fr300");
2983 break;
2984
2985 case EF_FRV_CPU_FR400:
2986 strcat (buf, ", fr400");
2987 break;
2988 case EF_FRV_CPU_FR405:
2989 strcat (buf, ", fr405");
2990 break;
2991
2992 case EF_FRV_CPU_FR450:
2993 strcat (buf, ", fr450");
2994 break;
2995
2996 case EF_FRV_CPU_FR500:
2997 strcat (buf, ", fr500");
2998 break;
2999 case EF_FRV_CPU_FR550:
3000 strcat (buf, ", fr550");
3001 break;
3002
3003 case EF_FRV_CPU_SIMPLE:
3004 strcat (buf, ", simple");
3005 break;
3006 case EF_FRV_CPU_TOMCAT:
3007 strcat (buf, ", tomcat");
3008 break;
3009 }
1c877e87 3010 break;
ec2dfb42 3011
53c7db4b 3012 case EM_68K:
425c6cb0 3013 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3014 strcat (buf, ", m68000");
425c6cb0 3015 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3016 strcat (buf, ", cpu32");
3017 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3018 strcat (buf, ", fido_a");
425c6cb0 3019 else
266abb8f 3020 {
2cf0635d
NC
3021 char const * isa = _("unknown");
3022 char const * mac = _("unknown mac");
3023 char const * additional = NULL;
0112cd26 3024
c694fd50 3025 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3026 {
c694fd50 3027 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3028 isa = "A";
3029 additional = ", nodiv";
3030 break;
c694fd50 3031 case EF_M68K_CF_ISA_A:
266abb8f
NS
3032 isa = "A";
3033 break;
c694fd50 3034 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3035 isa = "A+";
3036 break;
c694fd50 3037 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3038 isa = "B";
3039 additional = ", nousp";
3040 break;
c694fd50 3041 case EF_M68K_CF_ISA_B:
266abb8f
NS
3042 isa = "B";
3043 break;
f608cd77
NS
3044 case EF_M68K_CF_ISA_C:
3045 isa = "C";
3046 break;
3047 case EF_M68K_CF_ISA_C_NODIV:
3048 isa = "C";
3049 additional = ", nodiv";
3050 break;
266abb8f
NS
3051 }
3052 strcat (buf, ", cf, isa ");
3053 strcat (buf, isa);
0b2e31dc
NS
3054 if (additional)
3055 strcat (buf, additional);
c694fd50 3056 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3057 strcat (buf, ", float");
c694fd50 3058 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3059 {
3060 case 0:
3061 mac = NULL;
3062 break;
c694fd50 3063 case EF_M68K_CF_MAC:
266abb8f
NS
3064 mac = "mac";
3065 break;
c694fd50 3066 case EF_M68K_CF_EMAC:
266abb8f
NS
3067 mac = "emac";
3068 break;
f608cd77
NS
3069 case EF_M68K_CF_EMAC_B:
3070 mac = "emac_b";
3071 break;
266abb8f
NS
3072 }
3073 if (mac)
3074 {
3075 strcat (buf, ", ");
3076 strcat (buf, mac);
3077 }
266abb8f 3078 }
53c7db4b 3079 break;
33c63f9d 3080
153a2776
NC
3081 case EM_CYGNUS_MEP:
3082 switch (e_flags & EF_MEP_CPU_MASK)
3083 {
3084 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3085 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3086 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3087 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3088 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3089 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3090 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3091 }
3092
3093 switch (e_flags & EF_MEP_COP_MASK)
3094 {
3095 case EF_MEP_COP_NONE: break;
3096 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3097 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3098 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3099 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3100 default: strcat (buf, _("<unknown MeP copro type>")); break;
3101 }
3102
3103 if (e_flags & EF_MEP_LIBRARY)
3104 strcat (buf, ", Built for Library");
3105
3106 if (e_flags & EF_MEP_INDEX_MASK)
3107 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3108 e_flags & EF_MEP_INDEX_MASK);
3109
3110 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3111 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3112 e_flags & ~ EF_MEP_ALL_FLAGS);
3113 break;
3114
252b5132
RH
3115 case EM_PPC:
3116 if (e_flags & EF_PPC_EMB)
3117 strcat (buf, ", emb");
3118
3119 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3120 strcat (buf, _(", relocatable"));
252b5132
RH
3121
3122 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3123 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3124 break;
3125
ee67d69a
AM
3126 case EM_PPC64:
3127 if (e_flags & EF_PPC64_ABI)
3128 {
3129 char abi[] = ", abiv0";
3130
3131 abi[6] += e_flags & EF_PPC64_ABI;
3132 strcat (buf, abi);
3133 }
3134 break;
3135
708e2187
NC
3136 case EM_V800:
3137 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3138 strcat (buf, ", RH850 ABI");
0b4362b0 3139
708e2187
NC
3140 if (e_flags & EF_V800_850E3)
3141 strcat (buf, ", V3 architecture");
3142
3143 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3144 strcat (buf, ", FPU not used");
3145
3146 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3147 strcat (buf, ", regmode: COMMON");
3148
3149 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3150 strcat (buf, ", r4 not used");
3151
3152 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3153 strcat (buf, ", r30 not used");
3154
3155 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3156 strcat (buf, ", r5 not used");
3157
3158 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3159 strcat (buf, ", r2 not used");
3160
3161 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3162 {
3163 switch (e_flags & - e_flags)
3164 {
3165 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3166 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3167 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3168 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3169 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3170 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3171 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3172 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3173 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3174 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3175 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3176 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3177 default: break;
3178 }
3179 }
3180 break;
3181
2b0337b0 3182 case EM_V850:
252b5132
RH
3183 case EM_CYGNUS_V850:
3184 switch (e_flags & EF_V850_ARCH)
3185 {
78c8d46c
NC
3186 case E_V850E3V5_ARCH:
3187 strcat (buf, ", v850e3v5");
3188 break;
1cd986c5
NC
3189 case E_V850E2V3_ARCH:
3190 strcat (buf, ", v850e2v3");
3191 break;
3192 case E_V850E2_ARCH:
3193 strcat (buf, ", v850e2");
3194 break;
3195 case E_V850E1_ARCH:
3196 strcat (buf, ", v850e1");
8ad30312 3197 break;
252b5132
RH
3198 case E_V850E_ARCH:
3199 strcat (buf, ", v850e");
3200 break;
252b5132
RH
3201 case E_V850_ARCH:
3202 strcat (buf, ", v850");
3203 break;
3204 default:
2b692964 3205 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3206 break;
3207 }
3208 break;
3209
2b0337b0 3210 case EM_M32R:
252b5132
RH
3211 case EM_CYGNUS_M32R:
3212 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3213 strcat (buf, ", m32r");
252b5132
RH
3214 break;
3215
3216 case EM_MIPS:
4fe85591 3217 case EM_MIPS_RS3_LE:
252b5132
RH
3218 if (e_flags & EF_MIPS_NOREORDER)
3219 strcat (buf, ", noreorder");
3220
3221 if (e_flags & EF_MIPS_PIC)
3222 strcat (buf, ", pic");
3223
3224 if (e_flags & EF_MIPS_CPIC)
3225 strcat (buf, ", cpic");
3226
d1bdd336
TS
3227 if (e_flags & EF_MIPS_UCODE)
3228 strcat (buf, ", ugen_reserved");
3229
252b5132
RH
3230 if (e_flags & EF_MIPS_ABI2)
3231 strcat (buf, ", abi2");
3232
43521d43
TS
3233 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3234 strcat (buf, ", odk first");
3235
a5d22d2a
TS
3236 if (e_flags & EF_MIPS_32BITMODE)
3237 strcat (buf, ", 32bitmode");
3238
ba92f887
MR
3239 if (e_flags & EF_MIPS_NAN2008)
3240 strcat (buf, ", nan2008");
3241
fef1b0b3
SE
3242 if (e_flags & EF_MIPS_FP64)
3243 strcat (buf, ", fp64");
3244
156c2f8b
NC
3245 switch ((e_flags & EF_MIPS_MACH))
3246 {
3247 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3248 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3249 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3250 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3251 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3252 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3253 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3254 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 3255 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3256 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3257 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3258 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 3259 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 3260 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3261 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3262 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3263 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
3264 case 0:
3265 /* We simply ignore the field in this case to avoid confusion:
3266 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3267 extension. */
3268 break;
2b692964 3269 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3270 }
43521d43
TS
3271
3272 switch ((e_flags & EF_MIPS_ABI))
3273 {
3274 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3275 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3276 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3277 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3278 case 0:
3279 /* We simply ignore the field in this case to avoid confusion:
3280 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3281 This means it is likely to be an o32 file, but not for
3282 sure. */
3283 break;
2b692964 3284 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3285 }
3286
3287 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3288 strcat (buf, ", mdmx");
3289
3290 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3291 strcat (buf, ", mips16");
3292
df58fc94
RS
3293 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3294 strcat (buf, ", micromips");
3295
43521d43
TS
3296 switch ((e_flags & EF_MIPS_ARCH))
3297 {
3298 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3299 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3300 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3301 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3302 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3303 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3304 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3305 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3306 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3307 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3308 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3309 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3310 }
252b5132 3311 break;
351b4b40 3312
35c08157
KLC
3313 case EM_NDS32:
3314 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3315 break;
3316
e23eba97
NC
3317 case EM_RISCV:
3318 if (e_flags & EF_RISCV_RVC)
3319 strcat (buf, ", RVC");
3320 if (e_flags & EF_RISCV_SOFT_FLOAT)
3321 strcat (buf, ", soft-float ABI");
3322 break;
3323
ccde1100
AO
3324 case EM_SH:
3325 switch ((e_flags & EF_SH_MACH_MASK))
3326 {
3327 case EF_SH1: strcat (buf, ", sh1"); break;
3328 case EF_SH2: strcat (buf, ", sh2"); break;
3329 case EF_SH3: strcat (buf, ", sh3"); break;
3330 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3331 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3332 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3333 case EF_SH3E: strcat (buf, ", sh3e"); break;
3334 case EF_SH4: strcat (buf, ", sh4"); break;
3335 case EF_SH5: strcat (buf, ", sh5"); break;
3336 case EF_SH2E: strcat (buf, ", sh2e"); break;
3337 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3338 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3339 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3340 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3341 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3342 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3343 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3344 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3345 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3346 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3347 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3348 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3349 }
3350
cec6a5b8
MR
3351 if (e_flags & EF_SH_PIC)
3352 strcat (buf, ", pic");
3353
3354 if (e_flags & EF_SH_FDPIC)
3355 strcat (buf, ", fdpic");
ccde1100 3356 break;
948f632f 3357
73589c9d
CS
3358 case EM_OR1K:
3359 if (e_flags & EF_OR1K_NODELAY)
3360 strcat (buf, ", no delay");
3361 break;
57346661 3362
351b4b40
RH
3363 case EM_SPARCV9:
3364 if (e_flags & EF_SPARC_32PLUS)
3365 strcat (buf, ", v8+");
3366
3367 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3368 strcat (buf, ", ultrasparcI");
3369
3370 if (e_flags & EF_SPARC_SUN_US3)
3371 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3372
3373 if (e_flags & EF_SPARC_HAL_R1)
3374 strcat (buf, ", halr1");
3375
3376 if (e_flags & EF_SPARC_LEDATA)
3377 strcat (buf, ", ledata");
3378
3379 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3380 strcat (buf, ", tso");
3381
3382 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3383 strcat (buf, ", pso");
3384
3385 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3386 strcat (buf, ", rmo");
3387 break;
7d466069 3388
103f02d3
UD
3389 case EM_PARISC:
3390 switch (e_flags & EF_PARISC_ARCH)
3391 {
3392 case EFA_PARISC_1_0:
3393 strcpy (buf, ", PA-RISC 1.0");
3394 break;
3395 case EFA_PARISC_1_1:
3396 strcpy (buf, ", PA-RISC 1.1");
3397 break;
3398 case EFA_PARISC_2_0:
3399 strcpy (buf, ", PA-RISC 2.0");
3400 break;
3401 default:
3402 break;
3403 }
3404 if (e_flags & EF_PARISC_TRAPNIL)
3405 strcat (buf, ", trapnil");
3406 if (e_flags & EF_PARISC_EXT)
3407 strcat (buf, ", ext");
3408 if (e_flags & EF_PARISC_LSB)
3409 strcat (buf, ", lsb");
3410 if (e_flags & EF_PARISC_WIDE)
3411 strcat (buf, ", wide");
3412 if (e_flags & EF_PARISC_NO_KABP)
3413 strcat (buf, ", no kabp");
3414 if (e_flags & EF_PARISC_LAZYSWAP)
3415 strcat (buf, ", lazyswap");
30800947 3416 break;
76da6bbe 3417
7d466069 3418 case EM_PJ:
2b0337b0 3419 case EM_PJ_OLD:
7d466069
ILT
3420 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3421 strcat (buf, ", new calling convention");
3422
3423 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3424 strcat (buf, ", gnu calling convention");
3425 break;
4d6ed7c8
NC
3426
3427 case EM_IA_64:
3428 if ((e_flags & EF_IA_64_ABI64))
3429 strcat (buf, ", 64-bit");
3430 else
3431 strcat (buf, ", 32-bit");
3432 if ((e_flags & EF_IA_64_REDUCEDFP))
3433 strcat (buf, ", reduced fp model");
3434 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3435 strcat (buf, ", no function descriptors, constant gp");
3436 else if ((e_flags & EF_IA_64_CONS_GP))
3437 strcat (buf, ", constant gp");
3438 if ((e_flags & EF_IA_64_ABSOLUTE))
3439 strcat (buf, ", absolute");
28f997cf
TG
3440 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3441 {
3442 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3443 strcat (buf, ", vms_linkages");
3444 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3445 {
3446 case EF_IA_64_VMS_COMCOD_SUCCESS:
3447 break;
3448 case EF_IA_64_VMS_COMCOD_WARNING:
3449 strcat (buf, ", warning");
3450 break;
3451 case EF_IA_64_VMS_COMCOD_ERROR:
3452 strcat (buf, ", error");
3453 break;
3454 case EF_IA_64_VMS_COMCOD_ABORT:
3455 strcat (buf, ", abort");
3456 break;
3457 default:
bee0ee85
NC
3458 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3459 e_flags & EF_IA_64_VMS_COMCOD);
3460 strcat (buf, ", <unknown>");
28f997cf
TG
3461 }
3462 }
4d6ed7c8 3463 break;
179d3252
JT
3464
3465 case EM_VAX:
3466 if ((e_flags & EF_VAX_NONPIC))
3467 strcat (buf, ", non-PIC");
3468 if ((e_flags & EF_VAX_DFLOAT))
3469 strcat (buf, ", D-Float");
3470 if ((e_flags & EF_VAX_GFLOAT))
3471 strcat (buf, ", G-Float");
3472 break;
c7927a3c 3473
619ed720
EB
3474 case EM_VISIUM:
3475 if (e_flags & EF_VISIUM_ARCH_MCM)
3476 strcat (buf, ", mcm");
3477 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3478 strcat (buf, ", mcm24");
3479 if (e_flags & EF_VISIUM_ARCH_GR6)
3480 strcat (buf, ", gr6");
3481 break;
3482
4046d87a 3483 case EM_RL78:
1740ba0c
NC
3484 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3485 {
3486 case E_FLAG_RL78_ANY_CPU: break;
3487 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3488 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3489 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3490 }
856ea05c
KP
3491 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3492 strcat (buf, ", 64-bit doubles");
4046d87a 3493 break;
0b4362b0 3494
c7927a3c
NC
3495 case EM_RX:
3496 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3497 strcat (buf, ", 64-bit doubles");
3498 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3499 strcat (buf, ", dsp");
d4cb0ea0 3500 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3501 strcat (buf, ", pid");
708e2187
NC
3502 if (e_flags & E_FLAG_RX_ABI)
3503 strcat (buf, ", RX ABI");
3525236c
NC
3504 if (e_flags & E_FLAG_RX_SINSNS_SET)
3505 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3506 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3507 if (e_flags & E_FLAG_RX_V2)
3508 strcat (buf, ", V2");
d4cb0ea0 3509 break;
55786da2
AK
3510
3511 case EM_S390:
3512 if (e_flags & EF_S390_HIGH_GPRS)
3513 strcat (buf, ", highgprs");
d4cb0ea0 3514 break;
40b36596
JM
3515
3516 case EM_TI_C6000:
3517 if ((e_flags & EF_C6000_REL))
3518 strcat (buf, ", relocatable module");
d4cb0ea0 3519 break;
13761a11
NC
3520
3521 case EM_MSP430:
3522 strcat (buf, _(": architecture variant: "));
3523 switch (e_flags & EF_MSP430_MACH)
3524 {
3525 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3526 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3527 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3528 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3529 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3530 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3531 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3532 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3533 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3534 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3535 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3536 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3537 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3538 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3539 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3540 default:
3541 strcat (buf, _(": unknown")); break;
3542 }
3543
3544 if (e_flags & ~ EF_MSP430_MACH)
3545 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3546 }
3547 }
3548
3549 return buf;
3550}
3551
252b5132 3552static const char *
d3ba0551
AM
3553get_osabi_name (unsigned int osabi)
3554{
3555 static char buff[32];
3556
3557 switch (osabi)
3558 {
3559 case ELFOSABI_NONE: return "UNIX - System V";
3560 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3561 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3562 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3563 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3564 case ELFOSABI_AIX: return "UNIX - AIX";
3565 case ELFOSABI_IRIX: return "UNIX - IRIX";
3566 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3567 case ELFOSABI_TRU64: return "UNIX - TRU64";
3568 case ELFOSABI_MODESTO: return "Novell - Modesto";
3569 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3570 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3571 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3572 case ELFOSABI_AROS: return "AROS";
11636f9e 3573 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3574 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3575 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3576 default:
40b36596
JM
3577 if (osabi >= 64)
3578 switch (elf_header.e_machine)
3579 {
3580 case EM_ARM:
3581 switch (osabi)
3582 {
3583 case ELFOSABI_ARM: return "ARM";
3584 default:
3585 break;
3586 }
3587 break;
3588
3589 case EM_MSP430:
3590 case EM_MSP430_OLD:
619ed720 3591 case EM_VISIUM:
40b36596
JM
3592 switch (osabi)
3593 {
3594 case ELFOSABI_STANDALONE: return _("Standalone App");
3595 default:
3596 break;
3597 }
3598 break;
3599
3600 case EM_TI_C6000:
3601 switch (osabi)
3602 {
3603 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3604 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3605 default:
3606 break;
3607 }
3608 break;
3609
3610 default:
3611 break;
3612 }
e9e44622 3613 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3614 return buff;
3615 }
3616}
3617
a06ea964
NC
3618static const char *
3619get_aarch64_segment_type (unsigned long type)
3620{
3621 switch (type)
3622 {
3623 case PT_AARCH64_ARCHEXT:
3624 return "AARCH64_ARCHEXT";
3625 default:
3626 break;
3627 }
3628
3629 return NULL;
3630}
3631
b294bdf8
MM
3632static const char *
3633get_arm_segment_type (unsigned long type)
3634{
3635 switch (type)
3636 {
3637 case PT_ARM_EXIDX:
3638 return "EXIDX";
3639 default:
3640 break;
3641 }
3642
3643 return NULL;
3644}
3645
d3ba0551
AM
3646static const char *
3647get_mips_segment_type (unsigned long type)
252b5132
RH
3648{
3649 switch (type)
3650 {
3651 case PT_MIPS_REGINFO:
3652 return "REGINFO";
3653 case PT_MIPS_RTPROC:
3654 return "RTPROC";
3655 case PT_MIPS_OPTIONS:
3656 return "OPTIONS";
351cdf24
MF
3657 case PT_MIPS_ABIFLAGS:
3658 return "ABIFLAGS";
252b5132
RH
3659 default:
3660 break;
3661 }
3662
3663 return NULL;
3664}
3665
103f02d3 3666static const char *
d3ba0551 3667get_parisc_segment_type (unsigned long type)
103f02d3
UD
3668{
3669 switch (type)
3670 {
3671 case PT_HP_TLS: return "HP_TLS";
3672 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3673 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3674 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3675 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3676 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3677 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3678 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3679 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3680 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3681 case PT_HP_PARALLEL: return "HP_PARALLEL";
3682 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3683 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3684 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3685 case PT_HP_STACK: return "HP_STACK";
3686 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3687 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3688 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3689 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
3690 default:
3691 break;
3692 }
3693
3694 return NULL;
3695}
3696
4d6ed7c8 3697static const char *
d3ba0551 3698get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3699{
3700 switch (type)
3701 {
3702 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3703 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3704 case PT_HP_TLS: return "HP_TLS";
3705 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3706 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3707 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
3708 default:
3709 break;
3710 }
3711
3712 return NULL;
3713}
3714
40b36596
JM
3715static const char *
3716get_tic6x_segment_type (unsigned long type)
3717{
3718 switch (type)
3719 {
3720 case PT_C6000_PHATTR: return "C6000_PHATTR";
3721 default:
3722 break;
3723 }
3724
3725 return NULL;
3726}
3727
5522f910
NC
3728static const char *
3729get_solaris_segment_type (unsigned long type)
3730{
3731 switch (type)
3732 {
3733 case 0x6464e550: return "PT_SUNW_UNWIND";
3734 case 0x6474e550: return "PT_SUNW_EH_FRAME";
3735 case 0x6ffffff7: return "PT_LOSUNW";
3736 case 0x6ffffffa: return "PT_SUNWBSS";
3737 case 0x6ffffffb: return "PT_SUNWSTACK";
3738 case 0x6ffffffc: return "PT_SUNWDTRACE";
3739 case 0x6ffffffd: return "PT_SUNWCAP";
3740 case 0x6fffffff: return "PT_HISUNW";
3741 default: return NULL;
3742 }
3743}
3744
252b5132 3745static const char *
d3ba0551 3746get_segment_type (unsigned long p_type)
252b5132 3747{
b34976b6 3748 static char buff[32];
252b5132
RH
3749
3750 switch (p_type)
3751 {
b34976b6
AM
3752 case PT_NULL: return "NULL";
3753 case PT_LOAD: return "LOAD";
252b5132 3754 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3755 case PT_INTERP: return "INTERP";
3756 case PT_NOTE: return "NOTE";
3757 case PT_SHLIB: return "SHLIB";
3758 case PT_PHDR: return "PHDR";
13ae64f3 3759 case PT_TLS: return "TLS";
252b5132 3760
65765700
JJ
3761 case PT_GNU_EH_FRAME:
3762 return "GNU_EH_FRAME";
2b05f1b7 3763 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3764 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3765
252b5132
RH
3766 default:
3767 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
3768 {
2cf0635d 3769 const char * result;
103f02d3 3770
252b5132
RH
3771 switch (elf_header.e_machine)
3772 {
a06ea964
NC
3773 case EM_AARCH64:
3774 result = get_aarch64_segment_type (p_type);
3775 break;
b294bdf8
MM
3776 case EM_ARM:
3777 result = get_arm_segment_type (p_type);
3778 break;
252b5132 3779 case EM_MIPS:
4fe85591 3780 case EM_MIPS_RS3_LE:
252b5132
RH
3781 result = get_mips_segment_type (p_type);
3782 break;
103f02d3
UD
3783 case EM_PARISC:
3784 result = get_parisc_segment_type (p_type);
3785 break;
4d6ed7c8
NC
3786 case EM_IA_64:
3787 result = get_ia64_segment_type (p_type);
3788 break;
40b36596
JM
3789 case EM_TI_C6000:
3790 result = get_tic6x_segment_type (p_type);
3791 break;
252b5132
RH
3792 default:
3793 result = NULL;
3794 break;
3795 }
103f02d3 3796
252b5132
RH
3797 if (result != NULL)
3798 return result;
103f02d3 3799
252b5132
RH
3800 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3801 }
3802 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3803 {
2cf0635d 3804 const char * result;
103f02d3
UD
3805
3806 switch (elf_header.e_machine)
3807 {
3808 case EM_PARISC:
3809 result = get_parisc_segment_type (p_type);
3810 break;
00428cca
AM
3811 case EM_IA_64:
3812 result = get_ia64_segment_type (p_type);
3813 break;
103f02d3 3814 default:
5522f910
NC
3815 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
3816 result = get_solaris_segment_type (p_type);
3817 else
3818 result = NULL;
103f02d3
UD
3819 break;
3820 }
3821
3822 if (result != NULL)
3823 return result;
3824
3825 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3826 }
252b5132 3827 else
e9e44622 3828 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3829
3830 return buff;
3831 }
3832}
3833
3834static const char *
d3ba0551 3835get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3836{
3837 switch (sh_type)
3838 {
b34976b6
AM
3839 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3840 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3841 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3842 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3843 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3844 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3845 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3846 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3847 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3848 case SHT_MIPS_RELD: return "MIPS_RELD";
3849 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3850 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3851 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3852 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3853 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3854 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3855 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3856 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3857 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3858 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3859 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3860 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3861 case SHT_MIPS_LINE: return "MIPS_LINE";
3862 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3863 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3864 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3865 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3866 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3867 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3868 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3869 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3870 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3871 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3872 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3873 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3874 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3875 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3876 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 3877 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 3878 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
252b5132
RH
3879 default:
3880 break;
3881 }
3882 return NULL;
3883}
3884
103f02d3 3885static const char *
d3ba0551 3886get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3887{
3888 switch (sh_type)
3889 {
3890 case SHT_PARISC_EXT: return "PARISC_EXT";
3891 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3892 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3893 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3894 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3895 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3896 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3897 default:
3898 break;
3899 }
3900 return NULL;
3901}
3902
4d6ed7c8 3903static const char *
d3ba0551 3904get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3905{
18bd398b 3906 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3907 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3908 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3909
4d6ed7c8
NC
3910 switch (sh_type)
3911 {
148b93f2
NC
3912 case SHT_IA_64_EXT: return "IA_64_EXT";
3913 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3914 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3915 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3916 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3917 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3918 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3919 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3920 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3921 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3922 default:
3923 break;
3924 }
3925 return NULL;
3926}
3927
d2b2c203
DJ
3928static const char *
3929get_x86_64_section_type_name (unsigned int sh_type)
3930{
3931 switch (sh_type)
3932 {
3933 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3934 default:
3935 break;
3936 }
3937 return NULL;
3938}
3939
a06ea964
NC
3940static const char *
3941get_aarch64_section_type_name (unsigned int sh_type)
3942{
3943 switch (sh_type)
3944 {
3945 case SHT_AARCH64_ATTRIBUTES:
3946 return "AARCH64_ATTRIBUTES";
3947 default:
3948 break;
3949 }
3950 return NULL;
3951}
3952
40a18ebd
NC
3953static const char *
3954get_arm_section_type_name (unsigned int sh_type)
3955{
3956 switch (sh_type)
3957 {
7f6fed87
NC
3958 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3959 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3960 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3961 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3962 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3963 default:
3964 break;
3965 }
3966 return NULL;
3967}
3968
40b36596
JM
3969static const char *
3970get_tic6x_section_type_name (unsigned int sh_type)
3971{
3972 switch (sh_type)
3973 {
3974 case SHT_C6000_UNWIND:
3975 return "C6000_UNWIND";
3976 case SHT_C6000_PREEMPTMAP:
3977 return "C6000_PREEMPTMAP";
3978 case SHT_C6000_ATTRIBUTES:
3979 return "C6000_ATTRIBUTES";
3980 case SHT_TI_ICODE:
3981 return "TI_ICODE";
3982 case SHT_TI_XREF:
3983 return "TI_XREF";
3984 case SHT_TI_HANDLER:
3985 return "TI_HANDLER";
3986 case SHT_TI_INITINFO:
3987 return "TI_INITINFO";
3988 case SHT_TI_PHATTRS:
3989 return "TI_PHATTRS";
3990 default:
3991 break;
3992 }
3993 return NULL;
3994}
3995
13761a11
NC
3996static const char *
3997get_msp430x_section_type_name (unsigned int sh_type)
3998{
3999 switch (sh_type)
4000 {
4001 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4002 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4003 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4004 default: return NULL;
4005 }
4006}
4007
685080f2
NC
4008static const char *
4009get_v850_section_type_name (unsigned int sh_type)
4010{
4011 switch (sh_type)
4012 {
4013 case SHT_V850_SCOMMON: return "V850 Small Common";
4014 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4015 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4016 case SHT_RENESAS_IOP: return "RENESAS IOP";
4017 case SHT_RENESAS_INFO: return "RENESAS INFO";
4018 default: return NULL;
4019 }
4020}
4021
252b5132 4022static const char *
d3ba0551 4023get_section_type_name (unsigned int sh_type)
252b5132 4024{
b34976b6 4025 static char buff[32];
9fb71ee4 4026 const char * result;
252b5132
RH
4027
4028 switch (sh_type)
4029 {
4030 case SHT_NULL: return "NULL";
4031 case SHT_PROGBITS: return "PROGBITS";
4032 case SHT_SYMTAB: return "SYMTAB";
4033 case SHT_STRTAB: return "STRTAB";
4034 case SHT_RELA: return "RELA";
4035 case SHT_HASH: return "HASH";
4036 case SHT_DYNAMIC: return "DYNAMIC";
4037 case SHT_NOTE: return "NOTE";
4038 case SHT_NOBITS: return "NOBITS";
4039 case SHT_REL: return "REL";
4040 case SHT_SHLIB: return "SHLIB";
4041 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4042 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4043 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4044 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4045 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
4046 case SHT_GROUP: return "GROUP";
4047 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
4048 case SHT_GNU_verdef: return "VERDEF";
4049 case SHT_GNU_verneed: return "VERNEED";
4050 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4051 case 0x6ffffff0: return "VERSYM";
4052 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4053 case 0x7ffffffd: return "AUXILIARY";
4054 case 0x7fffffff: return "FILTER";
047b2264 4055 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4056
4057 default:
4058 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4059 {
252b5132
RH
4060 switch (elf_header.e_machine)
4061 {
4062 case EM_MIPS:
4fe85591 4063 case EM_MIPS_RS3_LE:
252b5132
RH
4064 result = get_mips_section_type_name (sh_type);
4065 break;
103f02d3
UD
4066 case EM_PARISC:
4067 result = get_parisc_section_type_name (sh_type);
4068 break;
4d6ed7c8
NC
4069 case EM_IA_64:
4070 result = get_ia64_section_type_name (sh_type);
4071 break;
d2b2c203 4072 case EM_X86_64:
8a9036a4 4073 case EM_L1OM:
7a9068fe 4074 case EM_K1OM:
d2b2c203
DJ
4075 result = get_x86_64_section_type_name (sh_type);
4076 break;
a06ea964
NC
4077 case EM_AARCH64:
4078 result = get_aarch64_section_type_name (sh_type);
4079 break;
40a18ebd
NC
4080 case EM_ARM:
4081 result = get_arm_section_type_name (sh_type);
4082 break;
40b36596
JM
4083 case EM_TI_C6000:
4084 result = get_tic6x_section_type_name (sh_type);
4085 break;
13761a11
NC
4086 case EM_MSP430:
4087 result = get_msp430x_section_type_name (sh_type);
4088 break;
685080f2
NC
4089 case EM_V800:
4090 case EM_V850:
4091 case EM_CYGNUS_V850:
4092 result = get_v850_section_type_name (sh_type);
4093 break;
252b5132
RH
4094 default:
4095 result = NULL;
4096 break;
4097 }
4098
4099 if (result != NULL)
4100 return result;
4101
9fb71ee4 4102 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4103 }
4104 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4105 {
148b93f2
NC
4106 switch (elf_header.e_machine)
4107 {
4108 case EM_IA_64:
4109 result = get_ia64_section_type_name (sh_type);
4110 break;
4111 default:
fd85a6a1
NC
4112 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
4113 result = get_solaris_section_type (sh_type);
4114 else
4115 result = NULL;
148b93f2
NC
4116 break;
4117 }
4118
4119 if (result != NULL)
4120 return result;
4121
9fb71ee4 4122 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4123 }
252b5132 4124 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2
NC
4125 {
4126 switch (elf_header.e_machine)
4127 {
4128 case EM_V800:
4129 case EM_V850:
4130 case EM_CYGNUS_V850:
9fb71ee4 4131 result = get_v850_section_type_name (sh_type);
a9fb83be 4132 break;
685080f2 4133 default:
9fb71ee4 4134 result = NULL;
685080f2
NC
4135 break;
4136 }
4137
9fb71ee4
NC
4138 if (result != NULL)
4139 return result;
4140
4141 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4142 }
252b5132 4143 else
a7dbfd1c
NC
4144 /* This message is probably going to be displayed in a 15
4145 character wide field, so put the hex value first. */
4146 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4147
252b5132
RH
4148 return buff;
4149 }
4150}
4151
2979dc34 4152#define OPTION_DEBUG_DUMP 512
2c610e4b 4153#define OPTION_DYN_SYMS 513
fd2f0033
TT
4154#define OPTION_DWARF_DEPTH 514
4155#define OPTION_DWARF_START 515
4723351a 4156#define OPTION_DWARF_CHECK 516
2979dc34 4157
85b1c36d 4158static struct option options[] =
252b5132 4159{
b34976b6 4160 {"all", no_argument, 0, 'a'},
252b5132
RH
4161 {"file-header", no_argument, 0, 'h'},
4162 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
4163 {"headers", no_argument, 0, 'e'},
4164 {"histogram", no_argument, 0, 'I'},
4165 {"segments", no_argument, 0, 'l'},
4166 {"sections", no_argument, 0, 'S'},
252b5132 4167 {"section-headers", no_argument, 0, 'S'},
f5842774 4168 {"section-groups", no_argument, 0, 'g'},
5477e8a0 4169 {"section-details", no_argument, 0, 't'},
595cf52e 4170 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
4171 {"symbols", no_argument, 0, 's'},
4172 {"syms", no_argument, 0, 's'},
2c610e4b 4173 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
4174 {"relocs", no_argument, 0, 'r'},
4175 {"notes", no_argument, 0, 'n'},
4176 {"dynamic", no_argument, 0, 'd'},
a952a375 4177 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
4178 {"version-info", no_argument, 0, 'V'},
4179 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 4180 {"unwind", no_argument, 0, 'u'},
4145f1d5 4181 {"archive-index", no_argument, 0, 'c'},
b34976b6 4182 {"hex-dump", required_argument, 0, 'x'},
cf13d699 4183 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 4184 {"string-dump", required_argument, 0, 'p'},
0e602686 4185 {"decompress", no_argument, 0, 'z'},
252b5132
RH
4186#ifdef SUPPORT_DISASSEMBLY
4187 {"instruction-dump", required_argument, 0, 'i'},
4188#endif
cf13d699 4189 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 4190
fd2f0033
TT
4191 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4192 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4193 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 4194
b34976b6
AM
4195 {"version", no_argument, 0, 'v'},
4196 {"wide", no_argument, 0, 'W'},
4197 {"help", no_argument, 0, 'H'},
4198 {0, no_argument, 0, 0}
252b5132
RH
4199};
4200
4201static void
2cf0635d 4202usage (FILE * stream)
252b5132 4203{
92f01d61
JM
4204 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4205 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4206 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4207 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4208 -h --file-header Display the ELF file header\n\
4209 -l --program-headers Display the program headers\n\
4210 --segments An alias for --program-headers\n\
4211 -S --section-headers Display the sections' header\n\
4212 --sections An alias for --section-headers\n\
f5842774 4213 -g --section-groups Display the section groups\n\
5477e8a0 4214 -t --section-details Display the section details\n\
8b53311e
NC
4215 -e --headers Equivalent to: -h -l -S\n\
4216 -s --syms Display the symbol table\n\
3f08eb35 4217 --symbols An alias for --syms\n\
2c610e4b 4218 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
4219 -n --notes Display the core notes (if present)\n\
4220 -r --relocs Display the relocations (if present)\n\
4221 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4222 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4223 -V --version-info Display the version sections (if present)\n\
1b31d05e 4224 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4225 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4226 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
4227 -x --hex-dump=<number|name>\n\
4228 Dump the contents of section <number|name> as bytes\n\
4229 -p --string-dump=<number|name>\n\
4230 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4231 -R --relocated-dump=<number|name>\n\
4232 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4233 -z --decompress Decompress section before dumping it\n\
f9f0e732 4234 -w[lLiaprmfFsoRt] or\n\
1ed06042 4235 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 4236 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
4237 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
4238 =addr,=cu_index]\n\
8b53311e 4239 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
4240 fprintf (stream, _("\
4241 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4242 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4243 or deeper\n"));
252b5132 4244#ifdef SUPPORT_DISASSEMBLY
92f01d61 4245 fprintf (stream, _("\
09c11c86
NC
4246 -i --instruction-dump=<number|name>\n\
4247 Disassemble the contents of section <number|name>\n"));
252b5132 4248#endif
92f01d61 4249 fprintf (stream, _("\
8b53311e
NC
4250 -I --histogram Display histogram of bucket list lengths\n\
4251 -W --wide Allow output width to exceed 80 characters\n\
07012eee 4252 @<file> Read options from <file>\n\
8b53311e
NC
4253 -H --help Display this information\n\
4254 -v --version Display the version number of readelf\n"));
1118d252 4255
92f01d61
JM
4256 if (REPORT_BUGS_TO[0] && stream == stdout)
4257 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4258
92f01d61 4259 exit (stream == stdout ? 0 : 1);
252b5132
RH
4260}
4261
18bd398b
NC
4262/* Record the fact that the user wants the contents of section number
4263 SECTION to be displayed using the method(s) encoded as flags bits
4264 in TYPE. Note, TYPE can be zero if we are creating the array for
4265 the first time. */
4266
252b5132 4267static void
09c11c86 4268request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
4269{
4270 if (section >= num_dump_sects)
4271 {
2cf0635d 4272 dump_type * new_dump_sects;
252b5132 4273
3f5e193b
NC
4274 new_dump_sects = (dump_type *) calloc (section + 1,
4275 sizeof (* dump_sects));
252b5132
RH
4276
4277 if (new_dump_sects == NULL)
591a748a 4278 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4279 else
4280 {
21b65bac
NC
4281 if (dump_sects)
4282 {
4283 /* Copy current flag settings. */
4284 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132 4285
21b65bac
NC
4286 free (dump_sects);
4287 }
252b5132
RH
4288
4289 dump_sects = new_dump_sects;
4290 num_dump_sects = section + 1;
4291 }
4292 }
4293
4294 if (dump_sects)
b34976b6 4295 dump_sects[section] |= type;
252b5132
RH
4296
4297 return;
4298}
4299
aef1f6d0
DJ
4300/* Request a dump by section name. */
4301
4302static void
2cf0635d 4303request_dump_byname (const char * section, dump_type type)
aef1f6d0 4304{
2cf0635d 4305 struct dump_list_entry * new_request;
aef1f6d0 4306
3f5e193b
NC
4307 new_request = (struct dump_list_entry *)
4308 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4309 if (!new_request)
591a748a 4310 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4311
4312 new_request->name = strdup (section);
4313 if (!new_request->name)
591a748a 4314 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4315
4316 new_request->type = type;
4317
4318 new_request->next = dump_sects_byname;
4319 dump_sects_byname = new_request;
4320}
4321
cf13d699
NC
4322static inline void
4323request_dump (dump_type type)
4324{
4325 int section;
4326 char * cp;
4327
4328 do_dump++;
4329 section = strtoul (optarg, & cp, 0);
4330
4331 if (! *cp && section >= 0)
4332 request_dump_bynumber (section, type);
4333 else
4334 request_dump_byname (optarg, type);
4335}
4336
4337
252b5132 4338static void
2cf0635d 4339parse_args (int argc, char ** argv)
252b5132
RH
4340{
4341 int c;
4342
4343 if (argc < 2)
92f01d61 4344 usage (stderr);
252b5132
RH
4345
4346 while ((c = getopt_long
0e602686 4347 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4348 {
252b5132
RH
4349 switch (c)
4350 {
4351 case 0:
4352 /* Long options. */
4353 break;
4354 case 'H':
92f01d61 4355 usage (stdout);
252b5132
RH
4356 break;
4357
4358 case 'a':
b34976b6
AM
4359 do_syms++;
4360 do_reloc++;
4361 do_unwind++;
4362 do_dynamic++;
4363 do_header++;
4364 do_sections++;
f5842774 4365 do_section_groups++;
b34976b6
AM
4366 do_segments++;
4367 do_version++;
4368 do_histogram++;
4369 do_arch++;
4370 do_notes++;
252b5132 4371 break;
f5842774
L
4372 case 'g':
4373 do_section_groups++;
4374 break;
5477e8a0 4375 case 't':
595cf52e 4376 case 'N':
5477e8a0
L
4377 do_sections++;
4378 do_section_details++;
595cf52e 4379 break;
252b5132 4380 case 'e':
b34976b6
AM
4381 do_header++;
4382 do_sections++;
4383 do_segments++;
252b5132 4384 break;
a952a375 4385 case 'A':
b34976b6 4386 do_arch++;
a952a375 4387 break;
252b5132 4388 case 'D':
b34976b6 4389 do_using_dynamic++;
252b5132
RH
4390 break;
4391 case 'r':
b34976b6 4392 do_reloc++;
252b5132 4393 break;
4d6ed7c8 4394 case 'u':
b34976b6 4395 do_unwind++;
4d6ed7c8 4396 break;
252b5132 4397 case 'h':
b34976b6 4398 do_header++;
252b5132
RH
4399 break;
4400 case 'l':
b34976b6 4401 do_segments++;
252b5132
RH
4402 break;
4403 case 's':
b34976b6 4404 do_syms++;
252b5132
RH
4405 break;
4406 case 'S':
b34976b6 4407 do_sections++;
252b5132
RH
4408 break;
4409 case 'd':
b34976b6 4410 do_dynamic++;
252b5132 4411 break;
a952a375 4412 case 'I':
b34976b6 4413 do_histogram++;
a952a375 4414 break;
779fe533 4415 case 'n':
b34976b6 4416 do_notes++;
779fe533 4417 break;
4145f1d5
NC
4418 case 'c':
4419 do_archive_index++;
4420 break;
252b5132 4421 case 'x':
cf13d699 4422 request_dump (HEX_DUMP);
aef1f6d0 4423 break;
09c11c86 4424 case 'p':
cf13d699
NC
4425 request_dump (STRING_DUMP);
4426 break;
4427 case 'R':
4428 request_dump (RELOC_DUMP);
09c11c86 4429 break;
0e602686
NC
4430 case 'z':
4431 decompress_dumps++;
4432 break;
252b5132 4433 case 'w':
b34976b6 4434 do_dump++;
252b5132 4435 if (optarg == 0)
613ff48b
CC
4436 {
4437 do_debugging = 1;
4438 dwarf_select_sections_all ();
4439 }
252b5132
RH
4440 else
4441 {
4442 do_debugging = 0;
4cb93e3b 4443 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4444 }
4445 break;
2979dc34 4446 case OPTION_DEBUG_DUMP:
b34976b6 4447 do_dump++;
2979dc34
JJ
4448 if (optarg == 0)
4449 do_debugging = 1;
4450 else
4451 {
2979dc34 4452 do_debugging = 0;
4cb93e3b 4453 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4454 }
4455 break;
fd2f0033
TT
4456 case OPTION_DWARF_DEPTH:
4457 {
4458 char *cp;
4459
4460 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4461 }
4462 break;
4463 case OPTION_DWARF_START:
4464 {
4465 char *cp;
4466
4467 dwarf_start_die = strtoul (optarg, & cp, 0);
4468 }
4469 break;
4723351a
CC
4470 case OPTION_DWARF_CHECK:
4471 dwarf_check = 1;
4472 break;
2c610e4b
L
4473 case OPTION_DYN_SYMS:
4474 do_dyn_syms++;
4475 break;
252b5132
RH
4476#ifdef SUPPORT_DISASSEMBLY
4477 case 'i':
cf13d699
NC
4478 request_dump (DISASS_DUMP);
4479 break;
252b5132
RH
4480#endif
4481 case 'v':
4482 print_version (program_name);
4483 break;
4484 case 'V':
b34976b6 4485 do_version++;
252b5132 4486 break;
d974e256 4487 case 'W':
b34976b6 4488 do_wide++;
d974e256 4489 break;
252b5132 4490 default:
252b5132
RH
4491 /* xgettext:c-format */
4492 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4493 /* Fall through. */
252b5132 4494 case '?':
92f01d61 4495 usage (stderr);
252b5132
RH
4496 }
4497 }
4498
4d6ed7c8 4499 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4500 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4501 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4502 && !do_section_groups && !do_archive_index
4503 && !do_dyn_syms)
92f01d61 4504 usage (stderr);
252b5132
RH
4505}
4506
4507static const char *
d3ba0551 4508get_elf_class (unsigned int elf_class)
252b5132 4509{
b34976b6 4510 static char buff[32];
103f02d3 4511
252b5132
RH
4512 switch (elf_class)
4513 {
4514 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4515 case ELFCLASS32: return "ELF32";
4516 case ELFCLASS64: return "ELF64";
ab5e7794 4517 default:
e9e44622 4518 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4519 return buff;
252b5132
RH
4520 }
4521}
4522
4523static const char *
d3ba0551 4524get_data_encoding (unsigned int encoding)
252b5132 4525{
b34976b6 4526 static char buff[32];
103f02d3 4527
252b5132
RH
4528 switch (encoding)
4529 {
4530 case ELFDATANONE: return _("none");
33c63f9d
CM
4531 case ELFDATA2LSB: return _("2's complement, little endian");
4532 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4533 default:
e9e44622 4534 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4535 return buff;
252b5132
RH
4536 }
4537}
4538
252b5132 4539/* Decode the data held in 'elf_header'. */
ee42cf8c 4540
252b5132 4541static int
d3ba0551 4542process_file_header (void)
252b5132 4543{
b34976b6
AM
4544 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
4545 || elf_header.e_ident[EI_MAG1] != ELFMAG1
4546 || elf_header.e_ident[EI_MAG2] != ELFMAG2
4547 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4548 {
4549 error
4550 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
4551 return 0;
4552 }
4553
2dc4cec1
L
4554 init_dwarf_regnames (elf_header.e_machine);
4555
252b5132
RH
4556 if (do_header)
4557 {
4558 int i;
4559
4560 printf (_("ELF Header:\n"));
4561 printf (_(" Magic: "));
b34976b6
AM
4562 for (i = 0; i < EI_NIDENT; i++)
4563 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
4564 printf ("\n");
4565 printf (_(" Class: %s\n"),
b34976b6 4566 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 4567 printf (_(" Data: %s\n"),
b34976b6 4568 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 4569 printf (_(" Version: %d %s\n"),
b34976b6
AM
4570 elf_header.e_ident[EI_VERSION],
4571 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 4572 ? "(current)"
b34976b6 4573 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 4574 ? _("<unknown: %lx>")
789be9f7 4575 : "")));
252b5132 4576 printf (_(" OS/ABI: %s\n"),
b34976b6 4577 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 4578 printf (_(" ABI Version: %d\n"),
b34976b6 4579 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
4580 printf (_(" Type: %s\n"),
4581 get_file_type (elf_header.e_type));
4582 printf (_(" Machine: %s\n"),
4583 get_machine_name (elf_header.e_machine));
4584 printf (_(" Version: 0x%lx\n"),
4585 (unsigned long) elf_header.e_version);
76da6bbe 4586
f7a99963
NC
4587 printf (_(" Entry point address: "));
4588 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4589 printf (_("\n Start of program headers: "));
4590 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4591 printf (_(" (bytes into file)\n Start of section headers: "));
4592 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
4593 printf (_(" (bytes into file)\n"));
76da6bbe 4594
252b5132
RH
4595 printf (_(" Flags: 0x%lx%s\n"),
4596 (unsigned long) elf_header.e_flags,
4597 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
4598 printf (_(" Size of this header: %ld (bytes)\n"),
4599 (long) elf_header.e_ehsize);
4600 printf (_(" Size of program headers: %ld (bytes)\n"),
4601 (long) elf_header.e_phentsize);
2046a35d 4602 printf (_(" Number of program headers: %ld"),
252b5132 4603 (long) elf_header.e_phnum);
2046a35d
AM
4604 if (section_headers != NULL
4605 && elf_header.e_phnum == PN_XNUM
4606 && section_headers[0].sh_info != 0)
cc5914eb 4607 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 4608 putc ('\n', stdout);
252b5132
RH
4609 printf (_(" Size of section headers: %ld (bytes)\n"),
4610 (long) elf_header.e_shentsize);
560f3c1c 4611 printf (_(" Number of section headers: %ld"),
252b5132 4612 (long) elf_header.e_shnum);
4fbb74a6 4613 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
4614 printf (" (%ld)", (long) section_headers[0].sh_size);
4615 putc ('\n', stdout);
4616 printf (_(" Section header string table index: %ld"),
252b5132 4617 (long) elf_header.e_shstrndx);
4fbb74a6
AM
4618 if (section_headers != NULL
4619 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 4620 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
4621 else if (elf_header.e_shstrndx != SHN_UNDEF
4622 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 4623 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
4624 putc ('\n', stdout);
4625 }
4626
4627 if (section_headers != NULL)
4628 {
2046a35d
AM
4629 if (elf_header.e_phnum == PN_XNUM
4630 && section_headers[0].sh_info != 0)
4631 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 4632 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 4633 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 4634 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 4635 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 4636 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 4637 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
4638 free (section_headers);
4639 section_headers = NULL;
252b5132 4640 }
103f02d3 4641
9ea033b2
NC
4642 return 1;
4643}
4644
e0a31db1 4645static bfd_boolean
91d6fa6a 4646get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4647{
2cf0635d
NC
4648 Elf32_External_Phdr * phdrs;
4649 Elf32_External_Phdr * external;
4650 Elf_Internal_Phdr * internal;
b34976b6 4651 unsigned int i;
e0a31db1
NC
4652 unsigned int size = elf_header.e_phentsize;
4653 unsigned int num = elf_header.e_phnum;
4654
4655 /* PR binutils/17531: Cope with unexpected section header sizes. */
4656 if (size == 0 || num == 0)
4657 return FALSE;
4658 if (size < sizeof * phdrs)
4659 {
4660 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4661 return FALSE;
4662 }
4663 if (size > sizeof * phdrs)
4664 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4665
3f5e193b 4666 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1
NC
4667 size, num, _("program headers"));
4668 if (phdrs == NULL)
4669 return FALSE;
9ea033b2 4670
91d6fa6a 4671 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4672 i < elf_header.e_phnum;
b34976b6 4673 i++, internal++, external++)
252b5132 4674 {
9ea033b2
NC
4675 internal->p_type = BYTE_GET (external->p_type);
4676 internal->p_offset = BYTE_GET (external->p_offset);
4677 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4678 internal->p_paddr = BYTE_GET (external->p_paddr);
4679 internal->p_filesz = BYTE_GET (external->p_filesz);
4680 internal->p_memsz = BYTE_GET (external->p_memsz);
4681 internal->p_flags = BYTE_GET (external->p_flags);
4682 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4683 }
4684
9ea033b2 4685 free (phdrs);
e0a31db1 4686 return TRUE;
252b5132
RH
4687}
4688
e0a31db1 4689static bfd_boolean
91d6fa6a 4690get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4691{
2cf0635d
NC
4692 Elf64_External_Phdr * phdrs;
4693 Elf64_External_Phdr * external;
4694 Elf_Internal_Phdr * internal;
b34976b6 4695 unsigned int i;
e0a31db1
NC
4696 unsigned int size = elf_header.e_phentsize;
4697 unsigned int num = elf_header.e_phnum;
4698
4699 /* PR binutils/17531: Cope with unexpected section header sizes. */
4700 if (size == 0 || num == 0)
4701 return FALSE;
4702 if (size < sizeof * phdrs)
4703 {
4704 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4705 return FALSE;
4706 }
4707 if (size > sizeof * phdrs)
4708 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4709
3f5e193b 4710 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1 4711 size, num, _("program headers"));
a6e9f9df 4712 if (!phdrs)
e0a31db1 4713 return FALSE;
9ea033b2 4714
91d6fa6a 4715 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4716 i < elf_header.e_phnum;
b34976b6 4717 i++, internal++, external++)
9ea033b2
NC
4718 {
4719 internal->p_type = BYTE_GET (external->p_type);
4720 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4721 internal->p_offset = BYTE_GET (external->p_offset);
4722 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4723 internal->p_paddr = BYTE_GET (external->p_paddr);
4724 internal->p_filesz = BYTE_GET (external->p_filesz);
4725 internal->p_memsz = BYTE_GET (external->p_memsz);
4726 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4727 }
4728
4729 free (phdrs);
e0a31db1 4730 return TRUE;
9ea033b2 4731}
252b5132 4732
d93f0186
NC
4733/* Returns 1 if the program headers were read into `program_headers'. */
4734
4735static int
2cf0635d 4736get_program_headers (FILE * file)
d93f0186 4737{
2cf0635d 4738 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4739
4740 /* Check cache of prior read. */
4741 if (program_headers != NULL)
4742 return 1;
4743
3f5e193b
NC
4744 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
4745 sizeof (Elf_Internal_Phdr));
d93f0186
NC
4746
4747 if (phdrs == NULL)
4748 {
8b73c356
NC
4749 error (_("Out of memory reading %u program headers\n"),
4750 elf_header.e_phnum);
d93f0186
NC
4751 return 0;
4752 }
4753
4754 if (is_32bit_elf
4755 ? get_32bit_program_headers (file, phdrs)
4756 : get_64bit_program_headers (file, phdrs))
4757 {
4758 program_headers = phdrs;
4759 return 1;
4760 }
4761
4762 free (phdrs);
4763 return 0;
4764}
4765
2f62977e
NC
4766/* Returns 1 if the program headers were loaded. */
4767
252b5132 4768static int
2cf0635d 4769process_program_headers (FILE * file)
252b5132 4770{
2cf0635d 4771 Elf_Internal_Phdr * segment;
b34976b6 4772 unsigned int i;
252b5132
RH
4773
4774 if (elf_header.e_phnum == 0)
4775 {
82f2dbf7
NC
4776 /* PR binutils/12467. */
4777 if (elf_header.e_phoff != 0)
4778 warn (_("possibly corrupt ELF header - it has a non-zero program"
9035ed51 4779 " header offset, but no program headers\n"));
82f2dbf7 4780 else if (do_segments)
252b5132 4781 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 4782 return 0;
252b5132
RH
4783 }
4784
4785 if (do_segments && !do_header)
4786 {
f7a99963
NC
4787 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
4788 printf (_("Entry point "));
4789 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4790 printf (_("\nThere are %d program headers, starting at offset "),
4791 elf_header.e_phnum);
4792 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4793 printf ("\n");
252b5132
RH
4794 }
4795
d93f0186 4796 if (! get_program_headers (file))
252b5132 4797 return 0;
103f02d3 4798
252b5132
RH
4799 if (do_segments)
4800 {
3a1a2036
NC
4801 if (elf_header.e_phnum > 1)
4802 printf (_("\nProgram Headers:\n"));
4803 else
4804 printf (_("\nProgram Headers:\n"));
76da6bbe 4805
f7a99963
NC
4806 if (is_32bit_elf)
4807 printf
4808 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4809 else if (do_wide)
4810 printf
4811 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4812 else
4813 {
4814 printf
4815 (_(" Type Offset VirtAddr PhysAddr\n"));
4816 printf
4817 (_(" FileSiz MemSiz Flags Align\n"));
4818 }
252b5132
RH
4819 }
4820
252b5132 4821 dynamic_addr = 0;
1b228002 4822 dynamic_size = 0;
252b5132
RH
4823
4824 for (i = 0, segment = program_headers;
4825 i < elf_header.e_phnum;
b34976b6 4826 i++, segment++)
252b5132
RH
4827 {
4828 if (do_segments)
4829 {
103f02d3 4830 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
4831
4832 if (is_32bit_elf)
4833 {
4834 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4835 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4836 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4837 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4838 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4839 printf ("%c%c%c ",
4840 (segment->p_flags & PF_R ? 'R' : ' '),
4841 (segment->p_flags & PF_W ? 'W' : ' '),
4842 (segment->p_flags & PF_X ? 'E' : ' '));
4843 printf ("%#lx", (unsigned long) segment->p_align);
4844 }
d974e256
JJ
4845 else if (do_wide)
4846 {
4847 if ((unsigned long) segment->p_offset == segment->p_offset)
4848 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4849 else
4850 {
4851 print_vma (segment->p_offset, FULL_HEX);
4852 putchar (' ');
4853 }
4854
4855 print_vma (segment->p_vaddr, FULL_HEX);
4856 putchar (' ');
4857 print_vma (segment->p_paddr, FULL_HEX);
4858 putchar (' ');
4859
4860 if ((unsigned long) segment->p_filesz == segment->p_filesz)
4861 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
4862 else
4863 {
4864 print_vma (segment->p_filesz, FULL_HEX);
4865 putchar (' ');
4866 }
4867
4868 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4869 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4870 else
4871 {
f48e6c45 4872 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4873 }
4874
4875 printf (" %c%c%c ",
4876 (segment->p_flags & PF_R ? 'R' : ' '),
4877 (segment->p_flags & PF_W ? 'W' : ' '),
4878 (segment->p_flags & PF_X ? 'E' : ' '));
4879
4880 if ((unsigned long) segment->p_align == segment->p_align)
4881 printf ("%#lx", (unsigned long) segment->p_align);
4882 else
4883 {
4884 print_vma (segment->p_align, PREFIX_HEX);
4885 }
4886 }
f7a99963
NC
4887 else
4888 {
4889 print_vma (segment->p_offset, FULL_HEX);
4890 putchar (' ');
4891 print_vma (segment->p_vaddr, FULL_HEX);
4892 putchar (' ');
4893 print_vma (segment->p_paddr, FULL_HEX);
4894 printf ("\n ");
4895 print_vma (segment->p_filesz, FULL_HEX);
4896 putchar (' ');
4897 print_vma (segment->p_memsz, FULL_HEX);
4898 printf (" %c%c%c ",
4899 (segment->p_flags & PF_R ? 'R' : ' '),
4900 (segment->p_flags & PF_W ? 'W' : ' '),
4901 (segment->p_flags & PF_X ? 'E' : ' '));
4902 print_vma (segment->p_align, HEX);
4903 }
252b5132
RH
4904 }
4905
f54498b4
NC
4906 if (do_segments)
4907 putc ('\n', stdout);
4908
252b5132
RH
4909 switch (segment->p_type)
4910 {
252b5132
RH
4911 case PT_DYNAMIC:
4912 if (dynamic_addr)
4913 error (_("more than one dynamic segment\n"));
4914
20737c13
AM
4915 /* By default, assume that the .dynamic section is the first
4916 section in the DYNAMIC segment. */
4917 dynamic_addr = segment->p_offset;
4918 dynamic_size = segment->p_filesz;
f54498b4
NC
4919 /* PR binutils/17512: Avoid corrupt dynamic section info in the segment. */
4920 if (dynamic_addr + dynamic_size >= current_file_size)
4921 {
4922 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
4923 dynamic_addr = dynamic_size = 0;
4924 }
20737c13 4925
b2d38a17
NC
4926 /* Try to locate the .dynamic section. If there is
4927 a section header table, we can easily locate it. */
4928 if (section_headers != NULL)
4929 {
2cf0635d 4930 Elf_Internal_Shdr * sec;
b2d38a17 4931
89fac5e3
RS
4932 sec = find_section (".dynamic");
4933 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4934 {
28f997cf
TG
4935 /* A corresponding .dynamic section is expected, but on
4936 IA-64/OpenVMS it is OK for it to be missing. */
4937 if (!is_ia64_vms ())
4938 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4939 break;
4940 }
4941
42bb2e33 4942 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4943 {
4944 dynamic_size = 0;
4945 break;
4946 }
42bb2e33 4947
b2d38a17
NC
4948 dynamic_addr = sec->sh_offset;
4949 dynamic_size = sec->sh_size;
4950
4951 if (dynamic_addr < segment->p_offset
4952 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4953 warn (_("the .dynamic section is not contained"
4954 " within the dynamic segment\n"));
b2d38a17 4955 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4956 warn (_("the .dynamic section is not the first section"
4957 " in the dynamic segment.\n"));
b2d38a17 4958 }
252b5132
RH
4959 break;
4960
4961 case PT_INTERP:
fb52b2f4
NC
4962 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4963 SEEK_SET))
252b5132
RH
4964 error (_("Unable to find program interpreter name\n"));
4965 else
4966 {
f8eae8b2 4967 char fmt [32];
9495b2e6 4968 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
4969
4970 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4971 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4972
252b5132 4973 program_interpreter[0] = 0;
7bd7b3ef
AM
4974 if (fscanf (file, fmt, program_interpreter) <= 0)
4975 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4976
4977 if (do_segments)
f54498b4 4978 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
4979 program_interpreter);
4980 }
4981 break;
4982 }
252b5132
RH
4983 }
4984
c256ffe7 4985 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4986 {
4987 printf (_("\n Section to Segment mapping:\n"));
4988 printf (_(" Segment Sections...\n"));
4989
252b5132
RH
4990 for (i = 0; i < elf_header.e_phnum; i++)
4991 {
9ad5cbcf 4992 unsigned int j;
2cf0635d 4993 Elf_Internal_Shdr * section;
252b5132
RH
4994
4995 segment = program_headers + i;
b391a3e3 4996 section = section_headers + 1;
252b5132
RH
4997
4998 printf (" %2.2d ", i);
4999
b34976b6 5000 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 5001 {
f4638467
AM
5002 if (!ELF_TBSS_SPECIAL (section, segment)
5003 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
74e1a04b 5004 printf ("%s ", printable_section_name (section));
252b5132
RH
5005 }
5006
5007 putc ('\n',stdout);
5008 }
5009 }
5010
252b5132
RH
5011 return 1;
5012}
5013
5014
d93f0186
NC
5015/* Find the file offset corresponding to VMA by using the program headers. */
5016
5017static long
2cf0635d 5018offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 5019{
2cf0635d 5020 Elf_Internal_Phdr * seg;
d93f0186
NC
5021
5022 if (! get_program_headers (file))
5023 {
5024 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5025 return (long) vma;
5026 }
5027
5028 for (seg = program_headers;
5029 seg < program_headers + elf_header.e_phnum;
5030 ++seg)
5031 {
5032 if (seg->p_type != PT_LOAD)
5033 continue;
5034
5035 if (vma >= (seg->p_vaddr & -seg->p_align)
5036 && vma + size <= seg->p_vaddr + seg->p_filesz)
5037 return vma - seg->p_vaddr + seg->p_offset;
5038 }
5039
5040 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5041 (unsigned long) vma);
d93f0186
NC
5042 return (long) vma;
5043}
5044
5045
049b0c3a
NC
5046/* Allocate memory and load the sections headers into the global pointer
5047 SECTION_HEADERS. If PROBE is true, this is just a probe and we do not
5048 generate any error messages if the load fails. */
5049
5050static bfd_boolean
5051get_32bit_section_headers (FILE * file, bfd_boolean probe)
252b5132 5052{
2cf0635d
NC
5053 Elf32_External_Shdr * shdrs;
5054 Elf_Internal_Shdr * internal;
b34976b6 5055 unsigned int i;
049b0c3a
NC
5056 unsigned int size = elf_header.e_shentsize;
5057 unsigned int num = probe ? 1 : elf_header.e_shnum;
5058
5059 /* PR binutils/17531: Cope with unexpected section header sizes. */
5060 if (size == 0 || num == 0)
5061 return FALSE;
5062 if (size < sizeof * shdrs)
5063 {
5064 if (! probe)
5065 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5066 return FALSE;
5067 }
5068 if (!probe && size > sizeof * shdrs)
5069 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5070
3f5e193b 5071 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
5072 size, num,
5073 probe ? NULL : _("section headers"));
5074 if (shdrs == NULL)
5075 return FALSE;
252b5132 5076
049b0c3a
NC
5077 if (section_headers != NULL)
5078 free (section_headers);
3f5e193b
NC
5079 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
5080 sizeof (Elf_Internal_Shdr));
252b5132
RH
5081 if (section_headers == NULL)
5082 {
049b0c3a 5083 if (!probe)
8b73c356 5084 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 5085 return FALSE;
252b5132
RH
5086 }
5087
5088 for (i = 0, internal = section_headers;
560f3c1c 5089 i < num;
b34976b6 5090 i++, internal++)
252b5132
RH
5091 {
5092 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5093 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5094 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5095 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5096 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5097 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5098 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5099 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5100 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5101 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5102 if (!probe && internal->sh_link > num)
5103 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5104 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5105 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5106 }
5107
5108 free (shdrs);
049b0c3a 5109 return TRUE;
252b5132
RH
5110}
5111
049b0c3a
NC
5112static bfd_boolean
5113get_64bit_section_headers (FILE * file, bfd_boolean probe)
9ea033b2 5114{
2cf0635d
NC
5115 Elf64_External_Shdr * shdrs;
5116 Elf_Internal_Shdr * internal;
b34976b6 5117 unsigned int i;
049b0c3a
NC
5118 unsigned int size = elf_header.e_shentsize;
5119 unsigned int num = probe ? 1 : elf_header.e_shnum;
5120
5121 /* PR binutils/17531: Cope with unexpected section header sizes. */
5122 if (size == 0 || num == 0)
5123 return FALSE;
5124 if (size < sizeof * shdrs)
5125 {
5126 if (! probe)
5127 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5128 return FALSE;
5129 }
5130 if (! probe && size > sizeof * shdrs)
5131 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5132
3f5e193b 5133 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
5134 size, num,
5135 probe ? NULL : _("section headers"));
5136 if (shdrs == NULL)
5137 return FALSE;
9ea033b2 5138
049b0c3a
NC
5139 if (section_headers != NULL)
5140 free (section_headers);
3f5e193b
NC
5141 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
5142 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
5143 if (section_headers == NULL)
5144 {
049b0c3a 5145 if (! probe)
8b73c356 5146 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 5147 return FALSE;
9ea033b2
NC
5148 }
5149
5150 for (i = 0, internal = section_headers;
560f3c1c 5151 i < num;
b34976b6 5152 i++, internal++)
9ea033b2
NC
5153 {
5154 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5155 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5156 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5157 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5158 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5159 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5160 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5161 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5162 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5163 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5164 if (!probe && internal->sh_link > num)
5165 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5166 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5167 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5168 }
5169
5170 free (shdrs);
049b0c3a 5171 return TRUE;
9ea033b2
NC
5172}
5173
252b5132 5174static Elf_Internal_Sym *
ba5cdace
NC
5175get_32bit_elf_symbols (FILE * file,
5176 Elf_Internal_Shdr * section,
5177 unsigned long * num_syms_return)
252b5132 5178{
ba5cdace 5179 unsigned long number = 0;
dd24e3da 5180 Elf32_External_Sym * esyms = NULL;
ba5cdace 5181 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5182 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5183 Elf_Internal_Sym * psym;
b34976b6 5184 unsigned int j;
252b5132 5185
c9c1d674
EG
5186 if (section->sh_size == 0)
5187 {
5188 if (num_syms_return != NULL)
5189 * num_syms_return = 0;
5190 return NULL;
5191 }
5192
dd24e3da 5193 /* Run some sanity checks first. */
c9c1d674 5194 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5195 {
c9c1d674
EG
5196 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
5197 printable_section_name (section), (unsigned long) section->sh_entsize);
ba5cdace 5198 goto exit_point;
dd24e3da
NC
5199 }
5200
f54498b4
NC
5201 if (section->sh_size > current_file_size)
5202 {
5203 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
74e1a04b 5204 printable_section_name (section), (unsigned long) section->sh_size);
f54498b4
NC
5205 goto exit_point;
5206 }
5207
dd24e3da
NC
5208 number = section->sh_size / section->sh_entsize;
5209
5210 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5211 {
c9c1d674 5212 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
5213 (unsigned long) section->sh_size,
5214 printable_section_name (section),
5215 (unsigned long) section->sh_entsize);
ba5cdace 5216 goto exit_point;
dd24e3da
NC
5217 }
5218
3f5e193b
NC
5219 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
5220 section->sh_size, _("symbols"));
dd24e3da 5221 if (esyms == NULL)
ba5cdace 5222 goto exit_point;
252b5132 5223
6a40cf0c
NC
5224 {
5225 elf_section_list * entry;
5226
5227 shndx = NULL;
5228 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
5229 if (entry->hdr->sh_link == (unsigned long) (section - section_headers))
c9c1d674 5230 {
6a40cf0c
NC
5231 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
5232 entry->hdr->sh_offset,
5233 1, entry->hdr->sh_size,
5234 _("symbol table section indicies"));
5235 if (shndx == NULL)
5236 goto exit_point;
5237 /* PR17531: file: heap-buffer-overflow */
5238 else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5239 {
5240 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5241 printable_section_name (entry->hdr),
5242 (unsigned long) entry->hdr->sh_size,
5243 (unsigned long) section->sh_size);
5244 goto exit_point;
5245 }
c9c1d674 5246 }
6a40cf0c 5247 }
9ad5cbcf 5248
3f5e193b 5249 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5250
5251 if (isyms == NULL)
5252 {
8b73c356
NC
5253 error (_("Out of memory reading %lu symbols\n"),
5254 (unsigned long) number);
dd24e3da 5255 goto exit_point;
252b5132
RH
5256 }
5257
dd24e3da 5258 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5259 {
5260 psym->st_name = BYTE_GET (esyms[j].st_name);
5261 psym->st_value = BYTE_GET (esyms[j].st_value);
5262 psym->st_size = BYTE_GET (esyms[j].st_size);
5263 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5264 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5265 psym->st_shndx
5266 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5267 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5268 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5269 psym->st_info = BYTE_GET (esyms[j].st_info);
5270 psym->st_other = BYTE_GET (esyms[j].st_other);
5271 }
5272
dd24e3da 5273 exit_point:
ba5cdace 5274 if (shndx != NULL)
9ad5cbcf 5275 free (shndx);
ba5cdace 5276 if (esyms != NULL)
dd24e3da 5277 free (esyms);
252b5132 5278
ba5cdace
NC
5279 if (num_syms_return != NULL)
5280 * num_syms_return = isyms == NULL ? 0 : number;
5281
252b5132
RH
5282 return isyms;
5283}
5284
9ea033b2 5285static Elf_Internal_Sym *
ba5cdace
NC
5286get_64bit_elf_symbols (FILE * file,
5287 Elf_Internal_Shdr * section,
5288 unsigned long * num_syms_return)
9ea033b2 5289{
ba5cdace
NC
5290 unsigned long number = 0;
5291 Elf64_External_Sym * esyms = NULL;
5292 Elf_External_Sym_Shndx * shndx = NULL;
5293 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5294 Elf_Internal_Sym * psym;
b34976b6 5295 unsigned int j;
9ea033b2 5296
c9c1d674
EG
5297 if (section->sh_size == 0)
5298 {
5299 if (num_syms_return != NULL)
5300 * num_syms_return = 0;
5301 return NULL;
5302 }
5303
dd24e3da 5304 /* Run some sanity checks first. */
c9c1d674 5305 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5306 {
c9c1d674 5307 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
8066deb1
AM
5308 printable_section_name (section),
5309 (unsigned long) section->sh_entsize);
ba5cdace 5310 goto exit_point;
dd24e3da
NC
5311 }
5312
f54498b4
NC
5313 if (section->sh_size > current_file_size)
5314 {
5315 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
8066deb1
AM
5316 printable_section_name (section),
5317 (unsigned long) section->sh_size);
f54498b4
NC
5318 goto exit_point;
5319 }
5320
dd24e3da
NC
5321 number = section->sh_size / section->sh_entsize;
5322
5323 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5324 {
c9c1d674 5325 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
5326 (unsigned long) section->sh_size,
5327 printable_section_name (section),
5328 (unsigned long) section->sh_entsize);
ba5cdace 5329 goto exit_point;
dd24e3da
NC
5330 }
5331
3f5e193b
NC
5332 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
5333 section->sh_size, _("symbols"));
a6e9f9df 5334 if (!esyms)
ba5cdace 5335 goto exit_point;
9ea033b2 5336
6a40cf0c
NC
5337 {
5338 elf_section_list * entry;
5339
5340 shndx = NULL;
5341 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
5342 if (entry->hdr->sh_link == (unsigned long) (section - section_headers))
c9c1d674 5343 {
6a40cf0c
NC
5344 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
5345 entry->hdr->sh_offset,
5346 1, entry->hdr->sh_size,
5347 _("symbol table section indicies"));
5348 if (shndx == NULL)
5349 goto exit_point;
5350 /* PR17531: file: heap-buffer-overflow */
5351 else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5352 {
5353 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5354 printable_section_name (entry->hdr),
5355 (unsigned long) entry->hdr->sh_size,
5356 (unsigned long) section->sh_size);
5357 goto exit_point;
5358 }
c9c1d674 5359 }
6a40cf0c 5360 }
9ad5cbcf 5361
3f5e193b 5362 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5363
5364 if (isyms == NULL)
5365 {
8b73c356
NC
5366 error (_("Out of memory reading %lu symbols\n"),
5367 (unsigned long) number);
ba5cdace 5368 goto exit_point;
9ea033b2
NC
5369 }
5370
ba5cdace 5371 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5372 {
5373 psym->st_name = BYTE_GET (esyms[j].st_name);
5374 psym->st_info = BYTE_GET (esyms[j].st_info);
5375 psym->st_other = BYTE_GET (esyms[j].st_other);
5376 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5377
4fbb74a6 5378 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5379 psym->st_shndx
5380 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5381 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5382 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5383
66543521
AM
5384 psym->st_value = BYTE_GET (esyms[j].st_value);
5385 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5386 }
5387
ba5cdace
NC
5388 exit_point:
5389 if (shndx != NULL)
9ad5cbcf 5390 free (shndx);
ba5cdace
NC
5391 if (esyms != NULL)
5392 free (esyms);
5393
5394 if (num_syms_return != NULL)
5395 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5396
5397 return isyms;
5398}
5399
d1133906 5400static const char *
d3ba0551 5401get_elf_section_flags (bfd_vma sh_flags)
d1133906 5402{
5477e8a0 5403 static char buff[1024];
2cf0635d 5404 char * p = buff;
8d5ff12c 5405 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
5406 int sindex;
5407 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5408 bfd_vma os_flags = 0;
5409 bfd_vma proc_flags = 0;
5410 bfd_vma unknown_flags = 0;
148b93f2 5411 static const struct
5477e8a0 5412 {
2cf0635d 5413 const char * str;
5477e8a0
L
5414 int len;
5415 }
5416 flags [] =
5417 {
cfcac11d
NC
5418 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5419 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5420 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5421 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5422 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5423 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5424 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5425 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5426 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5427 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5428 /* IA-64 specific. */
5429 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5430 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5431 /* IA-64 OpenVMS specific. */
5432 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5433 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5434 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5435 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5436 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5437 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5438 /* Generic. */
cfcac11d 5439 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5440 /* SPARC specific. */
77115a4a 5441 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5442 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5443 /* ARM specific. */
5444 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5445 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
ac4c9b04 5446 /* 23 */ { STRING_COMMA_LEN ("COMDEF") }
5477e8a0
L
5447 };
5448
5449 if (do_section_details)
5450 {
8d5ff12c
L
5451 sprintf (buff, "[%*.*lx]: ",
5452 field_size, field_size, (unsigned long) sh_flags);
5453 p += field_size + 4;
5477e8a0 5454 }
76da6bbe 5455
d1133906
NC
5456 while (sh_flags)
5457 {
5458 bfd_vma flag;
5459
5460 flag = sh_flags & - sh_flags;
5461 sh_flags &= ~ flag;
76da6bbe 5462
5477e8a0 5463 if (do_section_details)
d1133906 5464 {
5477e8a0
L
5465 switch (flag)
5466 {
91d6fa6a
NC
5467 case SHF_WRITE: sindex = 0; break;
5468 case SHF_ALLOC: sindex = 1; break;
5469 case SHF_EXECINSTR: sindex = 2; break;
5470 case SHF_MERGE: sindex = 3; break;
5471 case SHF_STRINGS: sindex = 4; break;
5472 case SHF_INFO_LINK: sindex = 5; break;
5473 case SHF_LINK_ORDER: sindex = 6; break;
5474 case SHF_OS_NONCONFORMING: sindex = 7; break;
5475 case SHF_GROUP: sindex = 8; break;
5476 case SHF_TLS: sindex = 9; break;
18ae9cc1 5477 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 5478 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 5479
5477e8a0 5480 default:
91d6fa6a 5481 sindex = -1;
cfcac11d 5482 switch (elf_header.e_machine)
148b93f2 5483 {
cfcac11d 5484 case EM_IA_64:
148b93f2 5485 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5486 sindex = 10;
148b93f2 5487 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5488 sindex = 11;
148b93f2
NC
5489#ifdef BFD64
5490 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
5491 switch (flag)
5492 {
91d6fa6a
NC
5493 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5494 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5495 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5496 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5497 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5498 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5499 default: break;
5500 }
5501#endif
cfcac11d
NC
5502 break;
5503
caa83f8b 5504 case EM_386:
22abe556 5505 case EM_IAMCU:
caa83f8b 5506 case EM_X86_64:
7f502d6c 5507 case EM_L1OM:
7a9068fe 5508 case EM_K1OM:
cfcac11d
NC
5509 case EM_OLD_SPARCV9:
5510 case EM_SPARC32PLUS:
5511 case EM_SPARCV9:
5512 case EM_SPARC:
18ae9cc1 5513 if (flag == SHF_ORDERED)
91d6fa6a 5514 sindex = 19;
cfcac11d 5515 break;
ac4c9b04
MG
5516
5517 case EM_ARM:
5518 switch (flag)
5519 {
5520 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 5521 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
5522 case SHF_COMDEF: sindex = 23; break;
5523 default: break;
5524 }
5525 break;
5526
cfcac11d
NC
5527 default:
5528 break;
148b93f2 5529 }
5477e8a0
L
5530 }
5531
91d6fa6a 5532 if (sindex != -1)
5477e8a0 5533 {
8d5ff12c
L
5534 if (p != buff + field_size + 4)
5535 {
5536 if (size < (10 + 2))
bee0ee85
NC
5537 {
5538 warn (_("Internal error: not enough buffer room for section flag info"));
5539 return _("<unknown>");
5540 }
8d5ff12c
L
5541 size -= 2;
5542 *p++ = ',';
5543 *p++ = ' ';
5544 }
5545
91d6fa6a
NC
5546 size -= flags [sindex].len;
5547 p = stpcpy (p, flags [sindex].str);
5477e8a0 5548 }
3b22753a 5549 else if (flag & SHF_MASKOS)
8d5ff12c 5550 os_flags |= flag;
d1133906 5551 else if (flag & SHF_MASKPROC)
8d5ff12c 5552 proc_flags |= flag;
d1133906 5553 else
8d5ff12c 5554 unknown_flags |= flag;
5477e8a0
L
5555 }
5556 else
5557 {
5558 switch (flag)
5559 {
5560 case SHF_WRITE: *p = 'W'; break;
5561 case SHF_ALLOC: *p = 'A'; break;
5562 case SHF_EXECINSTR: *p = 'X'; break;
5563 case SHF_MERGE: *p = 'M'; break;
5564 case SHF_STRINGS: *p = 'S'; break;
5565 case SHF_INFO_LINK: *p = 'I'; break;
5566 case SHF_LINK_ORDER: *p = 'L'; break;
5567 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5568 case SHF_GROUP: *p = 'G'; break;
5569 case SHF_TLS: *p = 'T'; break;
18ae9cc1 5570 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 5571 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
5572
5573 default:
8a9036a4 5574 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
5575 || elf_header.e_machine == EM_L1OM
5576 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
5577 && flag == SHF_X86_64_LARGE)
5578 *p = 'l';
91f68a68 5579 else if (elf_header.e_machine == EM_ARM
f0728ee3 5580 && flag == SHF_ARM_PURECODE)
91f68a68 5581 *p = 'y';
5477e8a0
L
5582 else if (flag & SHF_MASKOS)
5583 {
5584 *p = 'o';
5585 sh_flags &= ~ SHF_MASKOS;
5586 }
5587 else if (flag & SHF_MASKPROC)
5588 {
5589 *p = 'p';
5590 sh_flags &= ~ SHF_MASKPROC;
5591 }
5592 else
5593 *p = 'x';
5594 break;
5595 }
5596 p++;
d1133906
NC
5597 }
5598 }
76da6bbe 5599
8d5ff12c
L
5600 if (do_section_details)
5601 {
5602 if (os_flags)
5603 {
5604 size -= 5 + field_size;
5605 if (p != buff + field_size + 4)
5606 {
5607 if (size < (2 + 1))
bee0ee85
NC
5608 {
5609 warn (_("Internal error: not enough buffer room for section flag info"));
5610 return _("<unknown>");
5611 }
8d5ff12c
L
5612 size -= 2;
5613 *p++ = ',';
5614 *p++ = ' ';
5615 }
5616 sprintf (p, "OS (%*.*lx)", field_size, field_size,
5617 (unsigned long) os_flags);
5618 p += 5 + field_size;
5619 }
5620 if (proc_flags)
5621 {
5622 size -= 7 + field_size;
5623 if (p != buff + field_size + 4)
5624 {
5625 if (size < (2 + 1))
bee0ee85
NC
5626 {
5627 warn (_("Internal error: not enough buffer room for section flag info"));
5628 return _("<unknown>");
5629 }
8d5ff12c
L
5630 size -= 2;
5631 *p++ = ',';
5632 *p++ = ' ';
5633 }
5634 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
5635 (unsigned long) proc_flags);
5636 p += 7 + field_size;
5637 }
5638 if (unknown_flags)
5639 {
5640 size -= 10 + field_size;
5641 if (p != buff + field_size + 4)
5642 {
5643 if (size < (2 + 1))
bee0ee85
NC
5644 {
5645 warn (_("Internal error: not enough buffer room for section flag info"));
5646 return _("<unknown>");
5647 }
8d5ff12c
L
5648 size -= 2;
5649 *p++ = ',';
5650 *p++ = ' ';
5651 }
2b692964 5652 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
5653 (unsigned long) unknown_flags);
5654 p += 10 + field_size;
5655 }
5656 }
5657
e9e44622 5658 *p = '\0';
d1133906
NC
5659 return buff;
5660}
5661
77115a4a
L
5662static unsigned int
5663get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf)
5664{
5665 if (is_32bit_elf)
5666 {
5667 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 5668
77115a4a
L
5669 chdr->ch_type = BYTE_GET (echdr->ch_type);
5670 chdr->ch_size = BYTE_GET (echdr->ch_size);
5671 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
5672 return sizeof (*echdr);
5673 }
5674 else
5675 {
5676 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 5677
77115a4a
L
5678 chdr->ch_type = BYTE_GET (echdr->ch_type);
5679 chdr->ch_size = BYTE_GET (echdr->ch_size);
5680 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
5681 return sizeof (*echdr);
5682 }
5683}
5684
252b5132 5685static int
2cf0635d 5686process_section_headers (FILE * file)
252b5132 5687{
2cf0635d 5688 Elf_Internal_Shdr * section;
b34976b6 5689 unsigned int i;
252b5132
RH
5690
5691 section_headers = NULL;
5692
5693 if (elf_header.e_shnum == 0)
5694 {
82f2dbf7
NC
5695 /* PR binutils/12467. */
5696 if (elf_header.e_shoff != 0)
5697 warn (_("possibly corrupt ELF file header - it has a non-zero"
5698 " section header offset, but no section headers\n"));
5699 else if (do_sections)
252b5132
RH
5700 printf (_("\nThere are no sections in this file.\n"));
5701
5702 return 1;
5703 }
5704
5705 if (do_sections && !do_header)
9ea033b2 5706 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
5707 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
5708
9ea033b2
NC
5709 if (is_32bit_elf)
5710 {
049b0c3a 5711 if (! get_32bit_section_headers (file, FALSE))
9ea033b2
NC
5712 return 0;
5713 }
049b0c3a 5714 else if (! get_64bit_section_headers (file, FALSE))
252b5132
RH
5715 return 0;
5716
5717 /* Read in the string table, so that we have names to display. */
0b49d371 5718 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 5719 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 5720 {
4fbb74a6 5721 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 5722
c256ffe7
JJ
5723 if (section->sh_size != 0)
5724 {
3f5e193b
NC
5725 string_table = (char *) get_data (NULL, file, section->sh_offset,
5726 1, section->sh_size,
5727 _("string table"));
0de14b54 5728
c256ffe7
JJ
5729 string_table_length = string_table != NULL ? section->sh_size : 0;
5730 }
252b5132
RH
5731 }
5732
5733 /* Scan the sections for the dynamic symbol table
e3c8793a 5734 and dynamic string table and debug sections. */
252b5132
RH
5735 dynamic_symbols = NULL;
5736 dynamic_strings = NULL;
5737 dynamic_syminfo = NULL;
6a40cf0c 5738 symtab_shndx_list = NULL;
103f02d3 5739
89fac5e3
RS
5740 eh_addr_size = is_32bit_elf ? 4 : 8;
5741 switch (elf_header.e_machine)
5742 {
5743 case EM_MIPS:
5744 case EM_MIPS_RS3_LE:
5745 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
5746 FDE addresses. However, the ABI also has a semi-official ILP32
5747 variant for which the normal FDE address size rules apply.
5748
5749 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
5750 section, where XX is the size of longs in bits. Unfortunately,
5751 earlier compilers provided no way of distinguishing ILP32 objects
5752 from LP64 objects, so if there's any doubt, we should assume that
5753 the official LP64 form is being used. */
5754 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
5755 && find_section (".gcc_compiled_long32") == NULL)
5756 eh_addr_size = 8;
5757 break;
0f56a26a
DD
5758
5759 case EM_H8_300:
5760 case EM_H8_300H:
5761 switch (elf_header.e_flags & EF_H8_MACH)
5762 {
5763 case E_H8_MACH_H8300:
5764 case E_H8_MACH_H8300HN:
5765 case E_H8_MACH_H8300SN:
5766 case E_H8_MACH_H8300SXN:
5767 eh_addr_size = 2;
5768 break;
5769 case E_H8_MACH_H8300H:
5770 case E_H8_MACH_H8300S:
5771 case E_H8_MACH_H8300SX:
5772 eh_addr_size = 4;
5773 break;
5774 }
f4236fe4
DD
5775 break;
5776
ff7eeb89 5777 case EM_M32C_OLD:
f4236fe4
DD
5778 case EM_M32C:
5779 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
5780 {
5781 case EF_M32C_CPU_M16C:
5782 eh_addr_size = 2;
5783 break;
5784 }
5785 break;
89fac5e3
RS
5786 }
5787
76ca31c0
NC
5788#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
5789 do \
5790 { \
5791 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
5792 if (section->sh_entsize != expected_entsize) \
9dd3a467 5793 { \
76ca31c0
NC
5794 char buf[40]; \
5795 sprintf_vma (buf, section->sh_entsize); \
5796 /* Note: coded this way so that there is a single string for \
5797 translation. */ \
5798 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
5799 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
5800 (unsigned) expected_entsize); \
9dd3a467 5801 section->sh_entsize = expected_entsize; \
76ca31c0
NC
5802 } \
5803 } \
08d8fa11 5804 while (0)
9dd3a467
NC
5805
5806#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
5807 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
5808 sizeof (Elf64_External_##type))
5809
252b5132
RH
5810 for (i = 0, section = section_headers;
5811 i < elf_header.e_shnum;
b34976b6 5812 i++, section++)
252b5132 5813 {
2cf0635d 5814 char * name = SECTION_NAME (section);
252b5132
RH
5815
5816 if (section->sh_type == SHT_DYNSYM)
5817 {
5818 if (dynamic_symbols != NULL)
5819 {
5820 error (_("File contains multiple dynamic symbol tables\n"));
5821 continue;
5822 }
5823
08d8fa11 5824 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 5825 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
5826 }
5827 else if (section->sh_type == SHT_STRTAB
18bd398b 5828 && streq (name, ".dynstr"))
252b5132
RH
5829 {
5830 if (dynamic_strings != NULL)
5831 {
5832 error (_("File contains multiple dynamic string tables\n"));
5833 continue;
5834 }
5835
3f5e193b
NC
5836 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
5837 1, section->sh_size,
5838 _("dynamic strings"));
59245841 5839 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 5840 }
9ad5cbcf
AM
5841 else if (section->sh_type == SHT_SYMTAB_SHNDX)
5842 {
6a40cf0c
NC
5843 elf_section_list * entry = xmalloc (sizeof * entry);
5844 entry->hdr = section;
5845 entry->next = symtab_shndx_list;
5846 symtab_shndx_list = entry;
9ad5cbcf 5847 }
08d8fa11
JJ
5848 else if (section->sh_type == SHT_SYMTAB)
5849 CHECK_ENTSIZE (section, i, Sym);
5850 else if (section->sh_type == SHT_GROUP)
5851 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
5852 else if (section->sh_type == SHT_REL)
5853 CHECK_ENTSIZE (section, i, Rel);
5854 else if (section->sh_type == SHT_RELA)
5855 CHECK_ENTSIZE (section, i, Rela);
252b5132 5856 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 5857 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 5858 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
5859 || do_debug_str || do_debug_loc || do_debug_ranges
5860 || do_debug_addr || do_debug_cu_index)
1b315056
CS
5861 && (const_strneq (name, ".debug_")
5862 || const_strneq (name, ".zdebug_")))
252b5132 5863 {
1b315056
CS
5864 if (name[1] == 'z')
5865 name += sizeof (".zdebug_") - 1;
5866 else
5867 name += sizeof (".debug_") - 1;
252b5132
RH
5868
5869 if (do_debugging
4723351a
CC
5870 || (do_debug_info && const_strneq (name, "info"))
5871 || (do_debug_info && const_strneq (name, "types"))
5872 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
5873 || (do_debug_lines && strcmp (name, "line") == 0)
5874 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
5875 || (do_debug_pubnames && const_strneq (name, "pubnames"))
5876 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
5877 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
5878 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
5879 || (do_debug_aranges && const_strneq (name, "aranges"))
5880 || (do_debug_ranges && const_strneq (name, "ranges"))
5881 || (do_debug_frames && const_strneq (name, "frame"))
5882 || (do_debug_macinfo && const_strneq (name, "macinfo"))
5883 || (do_debug_macinfo && const_strneq (name, "macro"))
5884 || (do_debug_str && const_strneq (name, "str"))
5885 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
5886 || (do_debug_addr && const_strneq (name, "addr"))
5887 || (do_debug_cu_index && const_strneq (name, "cu_index"))
5888 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 5889 )
09c11c86 5890 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 5891 }
a262ae96 5892 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 5893 else if ((do_debugging || do_debug_info)
0112cd26 5894 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 5895 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 5896 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 5897 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
5898 else if (do_gdb_index && streq (name, ".gdb_index"))
5899 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
5900 /* Trace sections for Itanium VMS. */
5901 else if ((do_debugging || do_trace_info || do_trace_abbrevs
5902 || do_trace_aranges)
5903 && const_strneq (name, ".trace_"))
5904 {
5905 name += sizeof (".trace_") - 1;
5906
5907 if (do_debugging
5908 || (do_trace_info && streq (name, "info"))
5909 || (do_trace_abbrevs && streq (name, "abbrev"))
5910 || (do_trace_aranges && streq (name, "aranges"))
5911 )
5912 request_dump_bynumber (i, DEBUG_DUMP);
5913 }
252b5132
RH
5914 }
5915
5916 if (! do_sections)
5917 return 1;
5918
3a1a2036
NC
5919 if (elf_header.e_shnum > 1)
5920 printf (_("\nSection Headers:\n"));
5921 else
5922 printf (_("\nSection Header:\n"));
76da6bbe 5923
f7a99963 5924 if (is_32bit_elf)
595cf52e 5925 {
5477e8a0 5926 if (do_section_details)
595cf52e
L
5927 {
5928 printf (_(" [Nr] Name\n"));
5477e8a0 5929 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
5930 }
5931 else
5932 printf
5933 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
5934 }
d974e256 5935 else if (do_wide)
595cf52e 5936 {
5477e8a0 5937 if (do_section_details)
595cf52e
L
5938 {
5939 printf (_(" [Nr] Name\n"));
5477e8a0 5940 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
5941 }
5942 else
5943 printf
5944 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
5945 }
f7a99963
NC
5946 else
5947 {
5477e8a0 5948 if (do_section_details)
595cf52e
L
5949 {
5950 printf (_(" [Nr] Name\n"));
5477e8a0
L
5951 printf (_(" Type Address Offset Link\n"));
5952 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
5953 }
5954 else
5955 {
5956 printf (_(" [Nr] Name Type Address Offset\n"));
5957 printf (_(" Size EntSize Flags Link Info Align\n"));
5958 }
f7a99963 5959 }
252b5132 5960
5477e8a0
L
5961 if (do_section_details)
5962 printf (_(" Flags\n"));
5963
252b5132
RH
5964 for (i = 0, section = section_headers;
5965 i < elf_header.e_shnum;
b34976b6 5966 i++, section++)
252b5132 5967 {
dd905818
NC
5968 /* Run some sanity checks on the section header. */
5969
5970 /* Check the sh_link field. */
5971 switch (section->sh_type)
5972 {
5973 case SHT_SYMTAB_SHNDX:
5974 case SHT_GROUP:
5975 case SHT_HASH:
5976 case SHT_GNU_HASH:
5977 case SHT_GNU_versym:
5978 case SHT_REL:
5979 case SHT_RELA:
5980 if (section->sh_link < 1
5981 || section->sh_link > elf_header.e_shnum
5982 || (section_headers[section->sh_link].sh_type != SHT_SYMTAB
5983 && section_headers[section->sh_link].sh_type != SHT_DYNSYM))
5984 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
5985 i, section->sh_link);
5986 break;
5987
5988 case SHT_DYNAMIC:
5989 case SHT_SYMTAB:
5990 case SHT_DYNSYM:
5991 case SHT_GNU_verneed:
5992 case SHT_GNU_verdef:
5993 case SHT_GNU_LIBLIST:
5994 if (section->sh_link < 1
5995 || section->sh_link > elf_header.e_shnum
5996 || section_headers[section->sh_link].sh_type != SHT_STRTAB)
5997 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
5998 i, section->sh_link);
5999 break;
6000
6001 case SHT_INIT_ARRAY:
6002 case SHT_FINI_ARRAY:
6003 case SHT_PREINIT_ARRAY:
6004 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6005 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6006 i, section->sh_link);
6007 break;
6008
6009 default:
6010 /* FIXME: Add support for target specific section types. */
6011#if 0 /* Currently we do not check other section types as there are too
6012 many special cases. Stab sections for example have a type
6013 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6014 section. */
6015 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6016 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6017 i, section->sh_link);
6018#endif
6019 break;
6020 }
6021
6022 /* Check the sh_info field. */
6023 switch (section->sh_type)
6024 {
6025 case SHT_REL:
6026 case SHT_RELA:
6027 if (section->sh_info < 1
6028 || section->sh_info > elf_header.e_shnum
6029 || (section_headers[section->sh_info].sh_type != SHT_PROGBITS
6030 && section_headers[section->sh_info].sh_type != SHT_NOBITS
6031 && section_headers[section->sh_info].sh_type != SHT_NOTE
6032 && section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
6033 /* FIXME: Are other section types valid ? */
6034 && section_headers[section->sh_info].sh_type < SHT_LOOS))
6035 {
6036 if (section->sh_info == 0
6037 && (streq (SECTION_NAME (section), ".rel.dyn")
6038 || streq (SECTION_NAME (section), ".rela.dyn")))
6039 /* The .rel.dyn and .rela.dyn sections have an sh_info field
6040 of zero. No idea why. I would have expected the index
6041 of the .plt section. */
6042 ;
6043 else
6044 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6045 i, section->sh_info);
6046 }
6047 break;
6048
6049 case SHT_DYNAMIC:
6050 case SHT_HASH:
6051 case SHT_SYMTAB_SHNDX:
6052 case SHT_INIT_ARRAY:
6053 case SHT_FINI_ARRAY:
6054 case SHT_PREINIT_ARRAY:
6055 if (section->sh_info != 0)
6056 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6057 i, section->sh_info);
6058 break;
6059
6060 case SHT_GROUP:
6061 case SHT_SYMTAB:
6062 case SHT_DYNSYM:
6063 /* A symbol index - we assume that it is valid. */
6064 break;
6065
6066 default:
6067 /* FIXME: Add support for target specific section types. */
6068 if (section->sh_type == SHT_NOBITS)
6069 /* NOBITS section headers with non-zero sh_info fields can be
6070 created when a binary is stripped of everything but its debug
6071 information. The stripped sections have their headers preserved but their types set to SHT_NOBITS. so do not check this type of section. */
6072 ;
6073 else if (section->sh_flags & SHF_INFO_LINK)
6074 {
6075 if (section->sh_info < 1 || section->sh_info > elf_header.e_shnum)
6076 warn (_("[%2u]: Expected link to another section in info field"), i);
6077 }
6078 else if (section->sh_type < SHT_LOOS && section->sh_info != 0)
6079 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6080 i, section->sh_info);
6081 break;
6082 }
6083
7bfd842d 6084 printf (" [%2u] ", i);
5477e8a0 6085 if (do_section_details)
74e1a04b 6086 printf ("%s\n ", printable_section_name (section));
595cf52e 6087 else
74e1a04b 6088 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6089
ea52a088
NC
6090 printf (do_wide ? " %-15s " : " %-15.15s ",
6091 get_section_type_name (section->sh_type));
0b4362b0 6092
f7a99963
NC
6093 if (is_32bit_elf)
6094 {
cfcac11d
NC
6095 const char * link_too_big = NULL;
6096
f7a99963 6097 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6098
f7a99963
NC
6099 printf ( " %6.6lx %6.6lx %2.2lx",
6100 (unsigned long) section->sh_offset,
6101 (unsigned long) section->sh_size,
6102 (unsigned long) section->sh_entsize);
d1133906 6103
5477e8a0
L
6104 if (do_section_details)
6105 fputs (" ", stdout);
6106 else
6107 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 6108
cfcac11d
NC
6109 if (section->sh_link >= elf_header.e_shnum)
6110 {
6111 link_too_big = "";
6112 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6113 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
6114 switch (elf_header.e_machine)
6115 {
caa83f8b 6116 case EM_386:
22abe556 6117 case EM_IAMCU:
caa83f8b 6118 case EM_X86_64:
7f502d6c 6119 case EM_L1OM:
7a9068fe 6120 case EM_K1OM:
cfcac11d
NC
6121 case EM_OLD_SPARCV9:
6122 case EM_SPARC32PLUS:
6123 case EM_SPARCV9:
6124 case EM_SPARC:
6125 if (section->sh_link == (SHN_BEFORE & 0xffff))
6126 link_too_big = "BEFORE";
6127 else if (section->sh_link == (SHN_AFTER & 0xffff))
6128 link_too_big = "AFTER";
6129 break;
6130 default:
6131 break;
6132 }
6133 }
6134
6135 if (do_section_details)
6136 {
6137 if (link_too_big != NULL && * link_too_big)
6138 printf ("<%s> ", link_too_big);
6139 else
6140 printf ("%2u ", section->sh_link);
6141 printf ("%3u %2lu\n", section->sh_info,
6142 (unsigned long) section->sh_addralign);
6143 }
6144 else
6145 printf ("%2u %3u %2lu\n",
6146 section->sh_link,
6147 section->sh_info,
6148 (unsigned long) section->sh_addralign);
6149
6150 if (link_too_big && ! * link_too_big)
6151 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6152 i, section->sh_link);
f7a99963 6153 }
d974e256
JJ
6154 else if (do_wide)
6155 {
6156 print_vma (section->sh_addr, LONG_HEX);
6157
6158 if ((long) section->sh_offset == section->sh_offset)
6159 printf (" %6.6lx", (unsigned long) section->sh_offset);
6160 else
6161 {
6162 putchar (' ');
6163 print_vma (section->sh_offset, LONG_HEX);
6164 }
6165
6166 if ((unsigned long) section->sh_size == section->sh_size)
6167 printf (" %6.6lx", (unsigned long) section->sh_size);
6168 else
6169 {
6170 putchar (' ');
6171 print_vma (section->sh_size, LONG_HEX);
6172 }
6173
6174 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6175 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6176 else
6177 {
6178 putchar (' ');
6179 print_vma (section->sh_entsize, LONG_HEX);
6180 }
6181
5477e8a0
L
6182 if (do_section_details)
6183 fputs (" ", stdout);
6184 else
6185 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 6186
72de5009 6187 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6188
6189 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6190 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6191 else
6192 {
6193 print_vma (section->sh_addralign, DEC);
6194 putchar ('\n');
6195 }
6196 }
5477e8a0 6197 else if (do_section_details)
595cf52e 6198 {
5477e8a0 6199 printf (" %-15.15s ",
595cf52e 6200 get_section_type_name (section->sh_type));
595cf52e
L
6201 print_vma (section->sh_addr, LONG_HEX);
6202 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6203 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6204 else
6205 {
6206 printf (" ");
6207 print_vma (section->sh_offset, LONG_HEX);
6208 }
72de5009 6209 printf (" %u\n ", section->sh_link);
595cf52e 6210 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6211 putchar (' ');
595cf52e
L
6212 print_vma (section->sh_entsize, LONG_HEX);
6213
72de5009
AM
6214 printf (" %-16u %lu\n",
6215 section->sh_info,
595cf52e
L
6216 (unsigned long) section->sh_addralign);
6217 }
f7a99963
NC
6218 else
6219 {
6220 putchar (' ');
6221 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6222 if ((long) section->sh_offset == section->sh_offset)
6223 printf (" %8.8lx", (unsigned long) section->sh_offset);
6224 else
6225 {
6226 printf (" ");
6227 print_vma (section->sh_offset, LONG_HEX);
6228 }
f7a99963
NC
6229 printf ("\n ");
6230 print_vma (section->sh_size, LONG_HEX);
6231 printf (" ");
6232 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6233
d1133906 6234 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 6235
72de5009
AM
6236 printf (" %2u %3u %lu\n",
6237 section->sh_link,
6238 section->sh_info,
f7a99963
NC
6239 (unsigned long) section->sh_addralign);
6240 }
5477e8a0
L
6241
6242 if (do_section_details)
77115a4a
L
6243 {
6244 printf (" %s\n", get_elf_section_flags (section->sh_flags));
6245 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6246 {
6247 /* Minimum section size is 12 bytes for 32-bit compression
6248 header + 12 bytes for compressed data header. */
6249 unsigned char buf[24];
d8024a91 6250
77115a4a
L
6251 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
6252 if (get_data (&buf, (FILE *) file, section->sh_offset, 1,
6253 sizeof (buf), _("compression header")))
6254 {
6255 Elf_Internal_Chdr chdr;
d8024a91
NC
6256
6257 (void) get_compression_header (&chdr, buf);
6258
77115a4a
L
6259 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6260 printf (" ZLIB, ");
6261 else
6262 printf (_(" [<unknown>: 0x%x], "),
6263 chdr.ch_type);
6264 print_vma (chdr.ch_size, LONG_HEX);
6265 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6266 }
6267 }
6268 }
252b5132
RH
6269 }
6270
5477e8a0 6271 if (!do_section_details)
3dbcc61d 6272 {
9fb71ee4
NC
6273 /* The ordering of the letters shown here matches the ordering of the
6274 corresponding SHF_xxx values, and hence the order in which these
6275 letters will be displayed to the user. */
6276 printf (_("Key to Flags:\n\
6277 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6278 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6279 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
3dbcc61d 6280 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
6281 || elf_header.e_machine == EM_L1OM
6282 || elf_header.e_machine == EM_K1OM)
9fb71ee4 6283 printf (_("l (large), "));
91f68a68 6284 else if (elf_header.e_machine == EM_ARM)
f0728ee3 6285 printf (_("y (purecode), "));
9fb71ee4 6286 printf ("p (processor specific)\n");
0b4362b0 6287 }
d1133906 6288
252b5132
RH
6289 return 1;
6290}
6291
f5842774
L
6292static const char *
6293get_group_flags (unsigned int flags)
6294{
1449284b 6295 static char buff[128];
220453ec 6296
6d913794
NC
6297 if (flags == 0)
6298 return "";
6299 else if (flags == GRP_COMDAT)
6300 return "COMDAT ";
f5842774 6301
6d913794
NC
6302 snprintf (buff, 14, _("[0x%x: "), flags);
6303
6304 flags &= ~ GRP_COMDAT;
6305 if (flags & GRP_MASKOS)
6306 {
6307 strcat (buff, "<OS specific>");
6308 flags &= ~ GRP_MASKOS;
f5842774 6309 }
6d913794
NC
6310
6311 if (flags & GRP_MASKPROC)
6312 {
6313 strcat (buff, "<PROC specific>");
6314 flags &= ~ GRP_MASKPROC;
6315 }
6316
6317 if (flags)
6318 strcat (buff, "<unknown>");
6319
6320 strcat (buff, "]");
f5842774
L
6321 return buff;
6322}
6323
6324static int
2cf0635d 6325process_section_groups (FILE * file)
f5842774 6326{
2cf0635d 6327 Elf_Internal_Shdr * section;
f5842774 6328 unsigned int i;
2cf0635d
NC
6329 struct group * group;
6330 Elf_Internal_Shdr * symtab_sec;
6331 Elf_Internal_Shdr * strtab_sec;
6332 Elf_Internal_Sym * symtab;
ba5cdace 6333 unsigned long num_syms;
2cf0635d 6334 char * strtab;
c256ffe7 6335 size_t strtab_size;
d1f5c6e3
L
6336
6337 /* Don't process section groups unless needed. */
6338 if (!do_unwind && !do_section_groups)
6339 return 1;
f5842774
L
6340
6341 if (elf_header.e_shnum == 0)
6342 {
6343 if (do_section_groups)
82f2dbf7 6344 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
6345
6346 return 1;
6347 }
6348
6349 if (section_headers == NULL)
6350 {
6351 error (_("Section headers are not available!\n"));
fa1908fd
NC
6352 /* PR 13622: This can happen with a corrupt ELF header. */
6353 return 0;
f5842774
L
6354 }
6355
3f5e193b
NC
6356 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
6357 sizeof (struct group *));
e4b17d5c
L
6358
6359 if (section_headers_groups == NULL)
6360 {
8b73c356
NC
6361 error (_("Out of memory reading %u section group headers\n"),
6362 elf_header.e_shnum);
e4b17d5c
L
6363 return 0;
6364 }
6365
f5842774 6366 /* Scan the sections for the group section. */
d1f5c6e3 6367 group_count = 0;
f5842774
L
6368 for (i = 0, section = section_headers;
6369 i < elf_header.e_shnum;
6370 i++, section++)
e4b17d5c
L
6371 if (section->sh_type == SHT_GROUP)
6372 group_count++;
6373
d1f5c6e3
L
6374 if (group_count == 0)
6375 {
6376 if (do_section_groups)
6377 printf (_("\nThere are no section groups in this file.\n"));
6378
6379 return 1;
6380 }
6381
3f5e193b 6382 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
6383
6384 if (section_groups == NULL)
6385 {
8b73c356
NC
6386 error (_("Out of memory reading %lu groups\n"),
6387 (unsigned long) group_count);
e4b17d5c
L
6388 return 0;
6389 }
6390
d1f5c6e3
L
6391 symtab_sec = NULL;
6392 strtab_sec = NULL;
6393 symtab = NULL;
ba5cdace 6394 num_syms = 0;
d1f5c6e3 6395 strtab = NULL;
c256ffe7 6396 strtab_size = 0;
e4b17d5c
L
6397 for (i = 0, section = section_headers, group = section_groups;
6398 i < elf_header.e_shnum;
6399 i++, section++)
f5842774
L
6400 {
6401 if (section->sh_type == SHT_GROUP)
6402 {
74e1a04b
NC
6403 const char * name = printable_section_name (section);
6404 const char * group_name;
2cf0635d
NC
6405 unsigned char * start;
6406 unsigned char * indices;
f5842774 6407 unsigned int entry, j, size;
2cf0635d
NC
6408 Elf_Internal_Shdr * sec;
6409 Elf_Internal_Sym * sym;
f5842774
L
6410
6411 /* Get the symbol table. */
4fbb74a6
AM
6412 if (section->sh_link >= elf_header.e_shnum
6413 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 6414 != SHT_SYMTAB))
f5842774
L
6415 {
6416 error (_("Bad sh_link in group section `%s'\n"), name);
6417 continue;
6418 }
d1f5c6e3
L
6419
6420 if (symtab_sec != sec)
6421 {
6422 symtab_sec = sec;
6423 if (symtab)
6424 free (symtab);
ba5cdace 6425 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 6426 }
f5842774 6427
dd24e3da
NC
6428 if (symtab == NULL)
6429 {
6430 error (_("Corrupt header in group section `%s'\n"), name);
6431 continue;
6432 }
6433
ba5cdace
NC
6434 if (section->sh_info >= num_syms)
6435 {
6436 error (_("Bad sh_info in group section `%s'\n"), name);
6437 continue;
6438 }
6439
f5842774
L
6440 sym = symtab + section->sh_info;
6441
6442 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
6443 {
4fbb74a6
AM
6444 if (sym->st_shndx == 0
6445 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
6446 {
6447 error (_("Bad sh_info in group section `%s'\n"), name);
6448 continue;
6449 }
ba2685cc 6450
4fbb74a6 6451 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
6452 strtab_sec = NULL;
6453 if (strtab)
6454 free (strtab);
f5842774 6455 strtab = NULL;
c256ffe7 6456 strtab_size = 0;
f5842774
L
6457 }
6458 else
6459 {
6460 /* Get the string table. */
4fbb74a6 6461 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
6462 {
6463 strtab_sec = NULL;
6464 if (strtab)
6465 free (strtab);
6466 strtab = NULL;
6467 strtab_size = 0;
6468 }
6469 else if (strtab_sec
4fbb74a6 6470 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
6471 {
6472 strtab_sec = sec;
6473 if (strtab)
6474 free (strtab);
071436c6 6475
3f5e193b 6476 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
071436c6
NC
6477 1, strtab_sec->sh_size,
6478 _("string table"));
c256ffe7 6479 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 6480 }
c256ffe7 6481 group_name = sym->st_name < strtab_size
2b692964 6482 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
6483 }
6484
c9c1d674
EG
6485 /* PR 17531: file: loop. */
6486 if (section->sh_entsize > section->sh_size)
6487 {
6488 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
6489 printable_section_name (section),
8066deb1
AM
6490 (unsigned long) section->sh_entsize,
6491 (unsigned long) section->sh_size);
c9c1d674
EG
6492 break;
6493 }
6494
3f5e193b
NC
6495 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
6496 1, section->sh_size,
6497 _("section data"));
59245841
NC
6498 if (start == NULL)
6499 continue;
f5842774
L
6500
6501 indices = start;
6502 size = (section->sh_size / section->sh_entsize) - 1;
6503 entry = byte_get (indices, 4);
6504 indices += 4;
e4b17d5c
L
6505
6506 if (do_section_groups)
6507 {
2b692964 6508 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 6509 get_group_flags (entry), i, name, group_name, size);
ba2685cc 6510
e4b17d5c
L
6511 printf (_(" [Index] Name\n"));
6512 }
6513
6514 group->group_index = i;
6515
f5842774
L
6516 for (j = 0; j < size; j++)
6517 {
2cf0635d 6518 struct group_list * g;
e4b17d5c 6519
f5842774
L
6520 entry = byte_get (indices, 4);
6521 indices += 4;
6522
4fbb74a6 6523 if (entry >= elf_header.e_shnum)
391cb864 6524 {
57028622
NC
6525 static unsigned num_group_errors = 0;
6526
6527 if (num_group_errors ++ < 10)
6528 {
6529 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
6530 entry, i, elf_header.e_shnum - 1);
6531 if (num_group_errors == 10)
6532 warn (_("Futher error messages about overlarge group section indicies suppressed\n"));
6533 }
391cb864
L
6534 continue;
6535 }
391cb864 6536
4fbb74a6 6537 if (section_headers_groups [entry] != NULL)
e4b17d5c 6538 {
d1f5c6e3
L
6539 if (entry)
6540 {
57028622
NC
6541 static unsigned num_errs = 0;
6542
6543 if (num_errs ++ < 10)
6544 {
6545 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
6546 entry, i,
6547 section_headers_groups [entry]->group_index);
6548 if (num_errs == 10)
6549 warn (_("Further error messages about already contained group sections suppressed\n"));
6550 }
d1f5c6e3
L
6551 continue;
6552 }
6553 else
6554 {
6555 /* Intel C/C++ compiler may put section 0 in a
6556 section group. We just warn it the first time
6557 and ignore it afterwards. */
6558 static int warned = 0;
6559 if (!warned)
6560 {
6561 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 6562 section_headers_groups [entry]->group_index);
d1f5c6e3
L
6563 warned++;
6564 }
6565 }
e4b17d5c
L
6566 }
6567
4fbb74a6 6568 section_headers_groups [entry] = group;
e4b17d5c
L
6569
6570 if (do_section_groups)
6571 {
4fbb74a6 6572 sec = section_headers + entry;
74e1a04b 6573 printf (" [%5u] %s\n", entry, printable_section_name (sec));
ba2685cc
AM
6574 }
6575
3f5e193b 6576 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
6577 g->section_index = entry;
6578 g->next = group->root;
6579 group->root = g;
f5842774
L
6580 }
6581
f5842774
L
6582 if (start)
6583 free (start);
e4b17d5c
L
6584
6585 group++;
f5842774
L
6586 }
6587 }
6588
d1f5c6e3
L
6589 if (symtab)
6590 free (symtab);
6591 if (strtab)
6592 free (strtab);
f5842774
L
6593 return 1;
6594}
6595
28f997cf
TG
6596/* Data used to display dynamic fixups. */
6597
6598struct ia64_vms_dynfixup
6599{
6600 bfd_vma needed_ident; /* Library ident number. */
6601 bfd_vma needed; /* Index in the dstrtab of the library name. */
6602 bfd_vma fixup_needed; /* Index of the library. */
6603 bfd_vma fixup_rela_cnt; /* Number of fixups. */
6604 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
6605};
6606
6607/* Data used to display dynamic relocations. */
6608
6609struct ia64_vms_dynimgrela
6610{
6611 bfd_vma img_rela_cnt; /* Number of relocations. */
6612 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
6613};
6614
6615/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
6616 library). */
6617
6618static void
6619dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
6620 const char *strtab, unsigned int strtab_sz)
6621{
6622 Elf64_External_VMS_IMAGE_FIXUP *imfs;
6623 long i;
6624 const char *lib_name;
6625
6626 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
6627 1, fixup->fixup_rela_cnt * sizeof (*imfs),
6628 _("dynamic section image fixups"));
6629 if (!imfs)
6630 return;
6631
6632 if (fixup->needed < strtab_sz)
6633 lib_name = strtab + fixup->needed;
6634 else
6635 {
6636 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 6637 (unsigned long) fixup->needed);
28f997cf
TG
6638 lib_name = "???";
6639 }
6640 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
6641 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
6642 printf
6643 (_("Seg Offset Type SymVec DataType\n"));
6644
6645 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
6646 {
6647 unsigned int type;
6648 const char *rtype;
6649
6650 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
6651 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
6652 type = BYTE_GET (imfs [i].type);
6653 rtype = elf_ia64_reloc_type (type);
6654 if (rtype == NULL)
6655 printf (" 0x%08x ", type);
6656 else
6657 printf (" %-32s ", rtype);
6658 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
6659 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
6660 }
6661
6662 free (imfs);
6663}
6664
6665/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
6666
6667static void
6668dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
6669{
6670 Elf64_External_VMS_IMAGE_RELA *imrs;
6671 long i;
6672
6673 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
6674 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 6675 _("dynamic section image relocations"));
28f997cf
TG
6676 if (!imrs)
6677 return;
6678
6679 printf (_("\nImage relocs\n"));
6680 printf
6681 (_("Seg Offset Type Addend Seg Sym Off\n"));
6682
6683 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
6684 {
6685 unsigned int type;
6686 const char *rtype;
6687
6688 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
6689 printf ("%08" BFD_VMA_FMT "x ",
6690 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
6691 type = BYTE_GET (imrs [i].type);
6692 rtype = elf_ia64_reloc_type (type);
6693 if (rtype == NULL)
6694 printf ("0x%08x ", type);
6695 else
6696 printf ("%-31s ", rtype);
6697 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
6698 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
6699 printf ("%08" BFD_VMA_FMT "x\n",
6700 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
6701 }
6702
6703 free (imrs);
6704}
6705
6706/* Display IA-64 OpenVMS dynamic relocations and fixups. */
6707
6708static int
6709process_ia64_vms_dynamic_relocs (FILE *file)
6710{
6711 struct ia64_vms_dynfixup fixup;
6712 struct ia64_vms_dynimgrela imgrela;
6713 Elf_Internal_Dyn *entry;
6714 int res = 0;
6715 bfd_vma strtab_off = 0;
6716 bfd_vma strtab_sz = 0;
6717 char *strtab = NULL;
6718
6719 memset (&fixup, 0, sizeof (fixup));
6720 memset (&imgrela, 0, sizeof (imgrela));
6721
6722 /* Note: the order of the entries is specified by the OpenVMS specs. */
6723 for (entry = dynamic_section;
6724 entry < dynamic_section + dynamic_nent;
6725 entry++)
6726 {
6727 switch (entry->d_tag)
6728 {
6729 case DT_IA_64_VMS_STRTAB_OFFSET:
6730 strtab_off = entry->d_un.d_val;
6731 break;
6732 case DT_STRSZ:
6733 strtab_sz = entry->d_un.d_val;
6734 if (strtab == NULL)
6735 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
6736 1, strtab_sz, _("dynamic string section"));
6737 break;
6738
6739 case DT_IA_64_VMS_NEEDED_IDENT:
6740 fixup.needed_ident = entry->d_un.d_val;
6741 break;
6742 case DT_NEEDED:
6743 fixup.needed = entry->d_un.d_val;
6744 break;
6745 case DT_IA_64_VMS_FIXUP_NEEDED:
6746 fixup.fixup_needed = entry->d_un.d_val;
6747 break;
6748 case DT_IA_64_VMS_FIXUP_RELA_CNT:
6749 fixup.fixup_rela_cnt = entry->d_un.d_val;
6750 break;
6751 case DT_IA_64_VMS_FIXUP_RELA_OFF:
6752 fixup.fixup_rela_off = entry->d_un.d_val;
6753 res++;
6754 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
6755 break;
6756
6757 case DT_IA_64_VMS_IMG_RELA_CNT:
6758 imgrela.img_rela_cnt = entry->d_un.d_val;
6759 break;
6760 case DT_IA_64_VMS_IMG_RELA_OFF:
6761 imgrela.img_rela_off = entry->d_un.d_val;
6762 res++;
6763 dump_ia64_vms_dynamic_relocs (file, &imgrela);
6764 break;
6765
6766 default:
6767 break;
6768 }
6769 }
6770
6771 if (strtab != NULL)
6772 free (strtab);
6773
6774 return res;
6775}
6776
85b1c36d 6777static struct
566b0d53 6778{
2cf0635d 6779 const char * name;
566b0d53
L
6780 int reloc;
6781 int size;
6782 int rela;
6783} dynamic_relocations [] =
6784{
6785 { "REL", DT_REL, DT_RELSZ, FALSE },
6786 { "RELA", DT_RELA, DT_RELASZ, TRUE },
6787 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
6788};
6789
252b5132 6790/* Process the reloc section. */
18bd398b 6791
252b5132 6792static int
2cf0635d 6793process_relocs (FILE * file)
252b5132 6794{
b34976b6
AM
6795 unsigned long rel_size;
6796 unsigned long rel_offset;
252b5132
RH
6797
6798
6799 if (!do_reloc)
6800 return 1;
6801
6802 if (do_using_dynamic)
6803 {
566b0d53 6804 int is_rela;
2cf0635d 6805 const char * name;
566b0d53
L
6806 int has_dynamic_reloc;
6807 unsigned int i;
0de14b54 6808
566b0d53 6809 has_dynamic_reloc = 0;
252b5132 6810
566b0d53 6811 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 6812 {
566b0d53
L
6813 is_rela = dynamic_relocations [i].rela;
6814 name = dynamic_relocations [i].name;
6815 rel_size = dynamic_info [dynamic_relocations [i].size];
6816 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 6817
566b0d53
L
6818 has_dynamic_reloc |= rel_size;
6819
6820 if (is_rela == UNKNOWN)
aa903cfb 6821 {
566b0d53
L
6822 if (dynamic_relocations [i].reloc == DT_JMPREL)
6823 switch (dynamic_info[DT_PLTREL])
6824 {
6825 case DT_REL:
6826 is_rela = FALSE;
6827 break;
6828 case DT_RELA:
6829 is_rela = TRUE;
6830 break;
6831 }
aa903cfb 6832 }
252b5132 6833
566b0d53
L
6834 if (rel_size)
6835 {
6836 printf
6837 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
6838 name, rel_offset, rel_size);
252b5132 6839
d93f0186
NC
6840 dump_relocations (file,
6841 offset_from_vma (file, rel_offset, rel_size),
6842 rel_size,
566b0d53 6843 dynamic_symbols, num_dynamic_syms,
bb4d2ac2
L
6844 dynamic_strings, dynamic_strings_length,
6845 is_rela, 1);
566b0d53 6846 }
252b5132 6847 }
566b0d53 6848
28f997cf
TG
6849 if (is_ia64_vms ())
6850 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
6851
566b0d53 6852 if (! has_dynamic_reloc)
252b5132
RH
6853 printf (_("\nThere are no dynamic relocations in this file.\n"));
6854 }
6855 else
6856 {
2cf0635d 6857 Elf_Internal_Shdr * section;
b34976b6
AM
6858 unsigned long i;
6859 int found = 0;
252b5132
RH
6860
6861 for (i = 0, section = section_headers;
6862 i < elf_header.e_shnum;
b34976b6 6863 i++, section++)
252b5132
RH
6864 {
6865 if ( section->sh_type != SHT_RELA
6866 && section->sh_type != SHT_REL)
6867 continue;
6868
6869 rel_offset = section->sh_offset;
6870 rel_size = section->sh_size;
6871
6872 if (rel_size)
6873 {
2cf0635d 6874 Elf_Internal_Shdr * strsec;
b34976b6 6875 int is_rela;
103f02d3 6876
252b5132
RH
6877 printf (_("\nRelocation section "));
6878
6879 if (string_table == NULL)
19936277 6880 printf ("%d", section->sh_name);
252b5132 6881 else
74e1a04b 6882 printf ("'%s'", printable_section_name (section));
252b5132
RH
6883
6884 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6885 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
6886
d79b3d50
NC
6887 is_rela = section->sh_type == SHT_RELA;
6888
4fbb74a6
AM
6889 if (section->sh_link != 0
6890 && section->sh_link < elf_header.e_shnum)
af3fc3bc 6891 {
2cf0635d
NC
6892 Elf_Internal_Shdr * symsec;
6893 Elf_Internal_Sym * symtab;
d79b3d50 6894 unsigned long nsyms;
c256ffe7 6895 unsigned long strtablen = 0;
2cf0635d 6896 char * strtab = NULL;
57346661 6897
4fbb74a6 6898 symsec = section_headers + section->sh_link;
08d8fa11
JJ
6899 if (symsec->sh_type != SHT_SYMTAB
6900 && symsec->sh_type != SHT_DYNSYM)
6901 continue;
6902
ba5cdace 6903 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 6904
af3fc3bc
AM
6905 if (symtab == NULL)
6906 continue;
252b5132 6907
4fbb74a6
AM
6908 if (symsec->sh_link != 0
6909 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 6910 {
4fbb74a6 6911 strsec = section_headers + symsec->sh_link;
103f02d3 6912
3f5e193b 6913 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
071436c6
NC
6914 1, strsec->sh_size,
6915 _("string table"));
c256ffe7
JJ
6916 strtablen = strtab == NULL ? 0 : strsec->sh_size;
6917 }
252b5132 6918
d79b3d50 6919 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2
L
6920 symtab, nsyms, strtab, strtablen,
6921 is_rela,
6922 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
6923 if (strtab)
6924 free (strtab);
6925 free (symtab);
6926 }
6927 else
6928 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2 6929 NULL, 0, NULL, 0, is_rela, 0);
252b5132
RH
6930
6931 found = 1;
6932 }
6933 }
6934
6935 if (! found)
6936 printf (_("\nThere are no relocations in this file.\n"));
6937 }
6938
6939 return 1;
6940}
6941
4d6ed7c8
NC
6942/* An absolute address consists of a section and an offset. If the
6943 section is NULL, the offset itself is the address, otherwise, the
6944 address equals to LOAD_ADDRESS(section) + offset. */
6945
6946struct absaddr
948f632f
DA
6947{
6948 unsigned short section;
6949 bfd_vma offset;
6950};
4d6ed7c8 6951
1949de15
L
6952#define ABSADDR(a) \
6953 ((a).section \
6954 ? section_headers [(a).section].sh_addr + (a).offset \
6955 : (a).offset)
6956
948f632f
DA
6957/* Find the nearest symbol at or below ADDR. Returns the symbol
6958 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 6959
4d6ed7c8 6960static void
2cf0635d 6961find_symbol_for_address (Elf_Internal_Sym * symtab,
948f632f
DA
6962 unsigned long nsyms,
6963 const char * strtab,
6964 unsigned long strtab_size,
6965 struct absaddr addr,
6966 const char ** symname,
6967 bfd_vma * offset)
4d6ed7c8 6968{
d3ba0551 6969 bfd_vma dist = 0x100000;
2cf0635d 6970 Elf_Internal_Sym * sym;
948f632f
DA
6971 Elf_Internal_Sym * beg;
6972 Elf_Internal_Sym * end;
2cf0635d 6973 Elf_Internal_Sym * best = NULL;
4d6ed7c8 6974
0b6ae522 6975 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
6976 beg = symtab;
6977 end = symtab + nsyms;
0b6ae522 6978
948f632f 6979 while (beg < end)
4d6ed7c8 6980 {
948f632f
DA
6981 bfd_vma value;
6982
6983 sym = beg + (end - beg) / 2;
0b6ae522 6984
948f632f 6985 value = sym->st_value;
0b6ae522
DJ
6986 REMOVE_ARCH_BITS (value);
6987
948f632f 6988 if (sym->st_name != 0
4d6ed7c8 6989 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
6990 && addr.offset >= value
6991 && addr.offset - value < dist)
4d6ed7c8
NC
6992 {
6993 best = sym;
0b6ae522 6994 dist = addr.offset - value;
4d6ed7c8
NC
6995 if (!dist)
6996 break;
6997 }
948f632f
DA
6998
6999 if (addr.offset < value)
7000 end = sym;
7001 else
7002 beg = sym + 1;
4d6ed7c8 7003 }
1b31d05e 7004
4d6ed7c8
NC
7005 if (best)
7006 {
57346661 7007 *symname = (best->st_name >= strtab_size
2b692964 7008 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7009 *offset = dist;
7010 return;
7011 }
1b31d05e 7012
4d6ed7c8
NC
7013 *symname = NULL;
7014 *offset = addr.offset;
7015}
7016
948f632f
DA
7017static int
7018symcmp (const void *p, const void *q)
7019{
7020 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7021 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7022
7023 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7024}
7025
7026/* Process the unwind section. */
7027
7028#include "unwind-ia64.h"
7029
7030struct ia64_unw_table_entry
7031{
7032 struct absaddr start;
7033 struct absaddr end;
7034 struct absaddr info;
7035};
7036
7037struct ia64_unw_aux_info
7038{
7039 struct ia64_unw_table_entry *table; /* Unwind table. */
7040 unsigned long table_len; /* Length of unwind table. */
7041 unsigned char * info; /* Unwind info. */
7042 unsigned long info_size; /* Size of unwind info. */
7043 bfd_vma info_addr; /* Starting address of unwind info. */
7044 bfd_vma seg_base; /* Starting address of segment. */
7045 Elf_Internal_Sym * symtab; /* The symbol table. */
7046 unsigned long nsyms; /* Number of symbols. */
7047 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7048 unsigned long nfuns; /* Number of entries in funtab. */
7049 char * strtab; /* The string table. */
7050 unsigned long strtab_size; /* Size of string table. */
7051};
7052
4d6ed7c8 7053static void
2cf0635d 7054dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 7055{
2cf0635d 7056 struct ia64_unw_table_entry * tp;
948f632f 7057 unsigned long j, nfuns;
4d6ed7c8 7058 int in_body;
7036c0e1 7059
948f632f
DA
7060 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7061 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7062 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7063 aux->funtab[nfuns++] = aux->symtab[j];
7064 aux->nfuns = nfuns;
7065 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7066
4d6ed7c8
NC
7067 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7068 {
7069 bfd_vma stamp;
7070 bfd_vma offset;
2cf0635d
NC
7071 const unsigned char * dp;
7072 const unsigned char * head;
53774b7e 7073 const unsigned char * end;
2cf0635d 7074 const char * procname;
4d6ed7c8 7075
948f632f 7076 find_symbol_for_address (aux->funtab, aux->nfuns, aux->strtab,
57346661 7077 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7078
7079 fputs ("\n<", stdout);
7080
7081 if (procname)
7082 {
7083 fputs (procname, stdout);
7084
7085 if (offset)
7086 printf ("+%lx", (unsigned long) offset);
7087 }
7088
7089 fputs (">: [", stdout);
7090 print_vma (tp->start.offset, PREFIX_HEX);
7091 fputc ('-', stdout);
7092 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7093 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7094 (unsigned long) (tp->info.offset - aux->seg_base));
7095
53774b7e
NC
7096 /* PR 17531: file: 86232b32. */
7097 if (aux->info == NULL)
7098 continue;
7099
7100 /* PR 17531: file: 0997b4d1. */
7101 if ((ABSADDR (tp->info) - aux->info_addr) >= aux->info_size)
7102 {
7103 warn (_("Invalid offset %lx in table entry %ld\n"),
7104 (long) tp->info.offset, (long) (tp - aux->table));
7105 continue;
7106 }
7107
1949de15 7108 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 7109 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7110
86f55779 7111 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7112 (unsigned) UNW_VER (stamp),
7113 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7114 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7115 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7116 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7117
7118 if (UNW_VER (stamp) != 1)
7119 {
2b692964 7120 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7121 continue;
7122 }
7123
7124 in_body = 0;
53774b7e
NC
7125 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7126 /* PR 17531: file: 16ceda89. */
7127 if (end > aux->info + aux->info_size)
7128 end = aux->info + aux->info_size;
7129 for (dp = head + 8; dp < end;)
b4477bc8 7130 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7131 }
948f632f
DA
7132
7133 free (aux->funtab);
4d6ed7c8
NC
7134}
7135
53774b7e 7136static bfd_boolean
2cf0635d
NC
7137slurp_ia64_unwind_table (FILE * file,
7138 struct ia64_unw_aux_info * aux,
7139 Elf_Internal_Shdr * sec)
4d6ed7c8 7140{
89fac5e3 7141 unsigned long size, nrelas, i;
2cf0635d
NC
7142 Elf_Internal_Phdr * seg;
7143 struct ia64_unw_table_entry * tep;
7144 Elf_Internal_Shdr * relsec;
7145 Elf_Internal_Rela * rela;
7146 Elf_Internal_Rela * rp;
7147 unsigned char * table;
7148 unsigned char * tp;
7149 Elf_Internal_Sym * sym;
7150 const char * relname;
4d6ed7c8 7151
53774b7e
NC
7152 aux->table_len = 0;
7153
4d6ed7c8
NC
7154 /* First, find the starting address of the segment that includes
7155 this section: */
7156
7157 if (elf_header.e_phnum)
7158 {
d93f0186 7159 if (! get_program_headers (file))
53774b7e 7160 return FALSE;
4d6ed7c8 7161
d93f0186
NC
7162 for (seg = program_headers;
7163 seg < program_headers + elf_header.e_phnum;
7164 ++seg)
4d6ed7c8
NC
7165 {
7166 if (seg->p_type != PT_LOAD)
7167 continue;
7168
7169 if (sec->sh_addr >= seg->p_vaddr
7170 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7171 {
7172 aux->seg_base = seg->p_vaddr;
7173 break;
7174 }
7175 }
4d6ed7c8
NC
7176 }
7177
7178 /* Second, build the unwind table from the contents of the unwind section: */
7179 size = sec->sh_size;
3f5e193b
NC
7180 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
7181 _("unwind table"));
a6e9f9df 7182 if (!table)
53774b7e 7183 return FALSE;
4d6ed7c8 7184
53774b7e 7185 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7186 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7187 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7188 tep = aux->table;
53774b7e
NC
7189
7190 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7191 {
7192 tep->start.section = SHN_UNDEF;
7193 tep->end.section = SHN_UNDEF;
7194 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7195 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7196 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7197 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7198 tep->start.offset += aux->seg_base;
7199 tep->end.offset += aux->seg_base;
7200 tep->info.offset += aux->seg_base;
7201 }
7202 free (table);
7203
41e92641 7204 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
7205 for (relsec = section_headers;
7206 relsec < section_headers + elf_header.e_shnum;
7207 ++relsec)
7208 {
7209 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
7210 || relsec->sh_info >= elf_header.e_shnum
7211 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7212 continue;
7213
7214 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7215 & rela, & nrelas))
53774b7e
NC
7216 {
7217 free (aux->table);
7218 aux->table = NULL;
7219 aux->table_len = 0;
7220 return FALSE;
7221 }
4d6ed7c8
NC
7222
7223 for (rp = rela; rp < rela + nrelas; ++rp)
7224 {
aca88567
NC
7225 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
7226 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 7227
82b1b41b
NC
7228 /* PR 17531: file: 9fa67536. */
7229 if (relname == NULL)
7230 {
7231 warn (_("Skipping unknown relocation type: %u\n"), get_reloc_type (rp->r_info));
7232 continue;
7233 }
948f632f 7234
0112cd26 7235 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7236 {
82b1b41b 7237 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7238 continue;
7239 }
7240
89fac5e3 7241 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7242
53774b7e
NC
7243 /* PR 17531: file: 5bc8d9bf. */
7244 if (i >= aux->table_len)
7245 {
7246 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7247 continue;
7248 }
7249
7250 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7251 {
7252 case 0:
7253 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7254 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7255 break;
7256 case 1:
7257 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7258 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7259 break;
7260 case 2:
7261 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7262 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7263 break;
7264 default:
7265 break;
7266 }
7267 }
7268
7269 free (rela);
7270 }
7271
53774b7e 7272 return TRUE;
4d6ed7c8
NC
7273}
7274
1b31d05e 7275static void
2cf0635d 7276ia64_process_unwind (FILE * file)
4d6ed7c8 7277{
2cf0635d
NC
7278 Elf_Internal_Shdr * sec;
7279 Elf_Internal_Shdr * unwsec = NULL;
7280 Elf_Internal_Shdr * strsec;
89fac5e3 7281 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7282 struct ia64_unw_aux_info aux;
f1467e33 7283
4d6ed7c8
NC
7284 memset (& aux, 0, sizeof (aux));
7285
4d6ed7c8
NC
7286 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7287 {
c256ffe7 7288 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 7289 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 7290 {
ba5cdace 7291 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 7292
4fbb74a6 7293 strsec = section_headers + sec->sh_link;
4082ef84
NC
7294 if (aux.strtab != NULL)
7295 {
7296 error (_("Multiple auxillary string tables encountered\n"));
7297 free (aux.strtab);
7298 }
3f5e193b
NC
7299 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
7300 1, strsec->sh_size,
7301 _("string table"));
c256ffe7 7302 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
7303 }
7304 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
7305 unwcount++;
7306 }
7307
7308 if (!unwcount)
7309 printf (_("\nThere are no unwind sections in this file.\n"));
7310
7311 while (unwcount-- > 0)
7312 {
2cf0635d 7313 char * suffix;
579f31ac
JJ
7314 size_t len, len2;
7315
4082ef84 7316 for (i = unwstart, sec = section_headers + unwstart, unwsec = NULL;
579f31ac
JJ
7317 i < elf_header.e_shnum; ++i, ++sec)
7318 if (sec->sh_type == SHT_IA_64_UNWIND)
7319 {
7320 unwsec = sec;
7321 break;
7322 }
4082ef84
NC
7323 /* We have already counted the number of SHT_IA64_UNWIND
7324 sections so the loop above should never fail. */
7325 assert (unwsec != NULL);
579f31ac
JJ
7326
7327 unwstart = i + 1;
7328 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
7329
e4b17d5c
L
7330 if ((unwsec->sh_flags & SHF_GROUP) != 0)
7331 {
7332 /* We need to find which section group it is in. */
4082ef84 7333 struct group_list * g;
e4b17d5c 7334
4082ef84
NC
7335 if (section_headers_groups == NULL
7336 || section_headers_groups [i] == NULL)
7337 i = elf_header.e_shnum;
7338 else
e4b17d5c 7339 {
4082ef84 7340 g = section_headers_groups [i]->root;
18bd398b 7341
4082ef84
NC
7342 for (; g != NULL; g = g->next)
7343 {
7344 sec = section_headers + g->section_index;
e4b17d5c 7345
4082ef84
NC
7346 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
7347 break;
7348 }
7349
7350 if (g == NULL)
7351 i = elf_header.e_shnum;
7352 }
e4b17d5c 7353 }
18bd398b 7354 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 7355 {
18bd398b 7356 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
7357 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
7358 suffix = SECTION_NAME (unwsec) + len;
7359 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
7360 ++i, ++sec)
18bd398b
NC
7361 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
7362 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7363 break;
7364 }
7365 else
7366 {
7367 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 7368 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
7369 len = sizeof (ELF_STRING_ia64_unwind) - 1;
7370 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
7371 suffix = "";
18bd398b 7372 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
7373 suffix = SECTION_NAME (unwsec) + len;
7374 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
7375 ++i, ++sec)
18bd398b
NC
7376 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
7377 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7378 break;
7379 }
7380
7381 if (i == elf_header.e_shnum)
7382 {
7383 printf (_("\nCould not find unwind info section for "));
7384
7385 if (string_table == NULL)
7386 printf ("%d", unwsec->sh_name);
7387 else
74e1a04b 7388 printf ("'%s'", printable_section_name (unwsec));
579f31ac
JJ
7389 }
7390 else
4d6ed7c8 7391 {
4d6ed7c8 7392 aux.info_addr = sec->sh_addr;
3f5e193b 7393 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
4082ef84
NC
7394 sec->sh_size,
7395 _("unwind info"));
59245841 7396 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 7397
579f31ac 7398 printf (_("\nUnwind section "));
4d6ed7c8 7399
579f31ac
JJ
7400 if (string_table == NULL)
7401 printf ("%d", unwsec->sh_name);
7402 else
74e1a04b 7403 printf ("'%s'", printable_section_name (unwsec));
4d6ed7c8 7404
579f31ac 7405 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 7406 (unsigned long) unwsec->sh_offset,
89fac5e3 7407 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 7408
53774b7e
NC
7409 if (slurp_ia64_unwind_table (file, & aux, unwsec)
7410 && aux.table_len > 0)
579f31ac
JJ
7411 dump_ia64_unwind (& aux);
7412
7413 if (aux.table)
7414 free ((char *) aux.table);
7415 if (aux.info)
7416 free ((char *) aux.info);
7417 aux.table = NULL;
7418 aux.info = NULL;
7419 }
4d6ed7c8 7420 }
4d6ed7c8 7421
4d6ed7c8
NC
7422 if (aux.symtab)
7423 free (aux.symtab);
7424 if (aux.strtab)
7425 free ((char *) aux.strtab);
4d6ed7c8
NC
7426}
7427
3f5e193b
NC
7428struct hppa_unw_table_entry
7429 {
7430 struct absaddr start;
7431 struct absaddr end;
948f632f 7432 unsigned int Cannot_unwind:1; /* 0 */
3f5e193b
NC
7433 unsigned int Millicode:1; /* 1 */
7434 unsigned int Millicode_save_sr0:1; /* 2 */
7435 unsigned int Region_description:2; /* 3..4 */
7436 unsigned int reserved1:1; /* 5 */
7437 unsigned int Entry_SR:1; /* 6 */
7438 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
7439 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
7440 unsigned int Args_stored:1; /* 16 */
948f632f
DA
7441 unsigned int Variable_Frame:1; /* 17 */
7442 unsigned int Separate_Package_Body:1; /* 18 */
3f5e193b 7443 unsigned int Frame_Extension_Millicode:1; /* 19 */
948f632f
DA
7444 unsigned int Stack_Overflow_Check:1; /* 20 */
7445 unsigned int Two_Instruction_SP_Increment:1;/* 21 */
3f5e193b
NC
7446 unsigned int Ada_Region:1; /* 22 */
7447 unsigned int cxx_info:1; /* 23 */
948f632f
DA
7448 unsigned int cxx_try_catch:1; /* 24 */
7449 unsigned int sched_entry_seq:1; /* 25 */
3f5e193b 7450 unsigned int reserved2:1; /* 26 */
948f632f
DA
7451 unsigned int Save_SP:1; /* 27 */
7452 unsigned int Save_RP:1; /* 28 */
3f5e193b
NC
7453 unsigned int Save_MRP_in_frame:1; /* 29 */
7454 unsigned int extn_ptr_defined:1; /* 30 */
948f632f 7455 unsigned int Cleanup_defined:1; /* 31 */
3f5e193b 7456
948f632f
DA
7457 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
7458 unsigned int HP_UX_interrupt_marker:1; /* 1 */
3f5e193b 7459 unsigned int Large_frame:1; /* 2 */
948f632f 7460 unsigned int Pseudo_SP_Set:1; /* 3 */
3f5e193b
NC
7461 unsigned int reserved4:1; /* 4 */
7462 unsigned int Total_frame_size:27; /* 5..31 */
7463 };
7464
57346661 7465struct hppa_unw_aux_info
948f632f
DA
7466{
7467 struct hppa_unw_table_entry * table; /* Unwind table. */
7468 unsigned long table_len; /* Length of unwind table. */
7469 bfd_vma seg_base; /* Starting address of segment. */
7470 Elf_Internal_Sym * symtab; /* The symbol table. */
7471 unsigned long nsyms; /* Number of symbols. */
7472 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7473 unsigned long nfuns; /* Number of entries in funtab. */
7474 char * strtab; /* The string table. */
7475 unsigned long strtab_size; /* Size of string table. */
7476};
57346661
AM
7477
7478static void
2cf0635d 7479dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 7480{
2cf0635d 7481 struct hppa_unw_table_entry * tp;
948f632f
DA
7482 unsigned long j, nfuns;
7483
7484 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7485 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7486 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7487 aux->funtab[nfuns++] = aux->symtab[j];
7488 aux->nfuns = nfuns;
7489 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 7490
57346661
AM
7491 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7492 {
7493 bfd_vma offset;
2cf0635d 7494 const char * procname;
57346661 7495
948f632f 7496 find_symbol_for_address (aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
7497 aux->strtab_size, tp->start, &procname,
7498 &offset);
7499
7500 fputs ("\n<", stdout);
7501
7502 if (procname)
7503 {
7504 fputs (procname, stdout);
7505
7506 if (offset)
7507 printf ("+%lx", (unsigned long) offset);
7508 }
7509
7510 fputs (">: [", stdout);
7511 print_vma (tp->start.offset, PREFIX_HEX);
7512 fputc ('-', stdout);
7513 print_vma (tp->end.offset, PREFIX_HEX);
7514 printf ("]\n\t");
7515
18bd398b
NC
7516#define PF(_m) if (tp->_m) printf (#_m " ");
7517#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
7518 PF(Cannot_unwind);
7519 PF(Millicode);
7520 PF(Millicode_save_sr0);
18bd398b 7521 /* PV(Region_description); */
57346661
AM
7522 PF(Entry_SR);
7523 PV(Entry_FR);
7524 PV(Entry_GR);
7525 PF(Args_stored);
7526 PF(Variable_Frame);
7527 PF(Separate_Package_Body);
7528 PF(Frame_Extension_Millicode);
7529 PF(Stack_Overflow_Check);
7530 PF(Two_Instruction_SP_Increment);
7531 PF(Ada_Region);
7532 PF(cxx_info);
7533 PF(cxx_try_catch);
7534 PF(sched_entry_seq);
7535 PF(Save_SP);
7536 PF(Save_RP);
7537 PF(Save_MRP_in_frame);
7538 PF(extn_ptr_defined);
7539 PF(Cleanup_defined);
7540 PF(MPE_XL_interrupt_marker);
7541 PF(HP_UX_interrupt_marker);
7542 PF(Large_frame);
7543 PF(Pseudo_SP_Set);
7544 PV(Total_frame_size);
7545#undef PF
7546#undef PV
7547 }
7548
18bd398b 7549 printf ("\n");
948f632f
DA
7550
7551 free (aux->funtab);
57346661
AM
7552}
7553
7554static int
2cf0635d
NC
7555slurp_hppa_unwind_table (FILE * file,
7556 struct hppa_unw_aux_info * aux,
7557 Elf_Internal_Shdr * sec)
57346661 7558{
1c0751b2 7559 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
7560 Elf_Internal_Phdr * seg;
7561 struct hppa_unw_table_entry * tep;
7562 Elf_Internal_Shdr * relsec;
7563 Elf_Internal_Rela * rela;
7564 Elf_Internal_Rela * rp;
7565 unsigned char * table;
7566 unsigned char * tp;
7567 Elf_Internal_Sym * sym;
7568 const char * relname;
57346661 7569
57346661
AM
7570 /* First, find the starting address of the segment that includes
7571 this section. */
7572
7573 if (elf_header.e_phnum)
7574 {
7575 if (! get_program_headers (file))
7576 return 0;
7577
7578 for (seg = program_headers;
7579 seg < program_headers + elf_header.e_phnum;
7580 ++seg)
7581 {
7582 if (seg->p_type != PT_LOAD)
7583 continue;
7584
7585 if (sec->sh_addr >= seg->p_vaddr
7586 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7587 {
7588 aux->seg_base = seg->p_vaddr;
7589 break;
7590 }
7591 }
7592 }
7593
7594 /* Second, build the unwind table from the contents of the unwind
7595 section. */
7596 size = sec->sh_size;
3f5e193b
NC
7597 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
7598 _("unwind table"));
57346661
AM
7599 if (!table)
7600 return 0;
7601
1c0751b2
DA
7602 unw_ent_size = 16;
7603 nentries = size / unw_ent_size;
7604 size = unw_ent_size * nentries;
57346661 7605
3f5e193b
NC
7606 tep = aux->table = (struct hppa_unw_table_entry *)
7607 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 7608
1c0751b2 7609 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
7610 {
7611 unsigned int tmp1, tmp2;
7612
7613 tep->start.section = SHN_UNDEF;
7614 tep->end.section = SHN_UNDEF;
7615
1c0751b2
DA
7616 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
7617 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
7618 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
7619 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
7620
7621 tep->start.offset += aux->seg_base;
7622 tep->end.offset += aux->seg_base;
57346661
AM
7623
7624 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
7625 tep->Millicode = (tmp1 >> 30) & 0x1;
7626 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
7627 tep->Region_description = (tmp1 >> 27) & 0x3;
7628 tep->reserved1 = (tmp1 >> 26) & 0x1;
7629 tep->Entry_SR = (tmp1 >> 25) & 0x1;
7630 tep->Entry_FR = (tmp1 >> 21) & 0xf;
7631 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
7632 tep->Args_stored = (tmp1 >> 15) & 0x1;
7633 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
7634 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
7635 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
7636 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
7637 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
7638 tep->Ada_Region = (tmp1 >> 9) & 0x1;
7639 tep->cxx_info = (tmp1 >> 8) & 0x1;
7640 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
7641 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
7642 tep->reserved2 = (tmp1 >> 5) & 0x1;
7643 tep->Save_SP = (tmp1 >> 4) & 0x1;
7644 tep->Save_RP = (tmp1 >> 3) & 0x1;
7645 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
7646 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
7647 tep->Cleanup_defined = tmp1 & 0x1;
7648
7649 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
7650 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
7651 tep->Large_frame = (tmp2 >> 29) & 0x1;
7652 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
7653 tep->reserved4 = (tmp2 >> 27) & 0x1;
7654 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
7655 }
7656 free (table);
7657
7658 /* Third, apply any relocations to the unwind table. */
57346661
AM
7659 for (relsec = section_headers;
7660 relsec < section_headers + elf_header.e_shnum;
7661 ++relsec)
7662 {
7663 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
7664 || relsec->sh_info >= elf_header.e_shnum
7665 || section_headers + relsec->sh_info != sec)
57346661
AM
7666 continue;
7667
7668 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7669 & rela, & nrelas))
7670 return 0;
7671
7672 for (rp = rela; rp < rela + nrelas; ++rp)
7673 {
aca88567
NC
7674 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
7675 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
7676
7677 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 7678 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
7679 {
7680 warn (_("Skipping unexpected relocation type %s\n"), relname);
7681 continue;
7682 }
7683
7684 i = rp->r_offset / unw_ent_size;
7685
89fac5e3 7686 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
7687 {
7688 case 0:
7689 aux->table[i].start.section = sym->st_shndx;
1e456d54 7690 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
7691 break;
7692 case 1:
7693 aux->table[i].end.section = sym->st_shndx;
1e456d54 7694 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
7695 break;
7696 default:
7697 break;
7698 }
7699 }
7700
7701 free (rela);
7702 }
7703
1c0751b2 7704 aux->table_len = nentries;
57346661
AM
7705
7706 return 1;
7707}
7708
1b31d05e 7709static void
2cf0635d 7710hppa_process_unwind (FILE * file)
57346661 7711{
57346661 7712 struct hppa_unw_aux_info aux;
2cf0635d
NC
7713 Elf_Internal_Shdr * unwsec = NULL;
7714 Elf_Internal_Shdr * strsec;
7715 Elf_Internal_Shdr * sec;
18bd398b 7716 unsigned long i;
57346661 7717
c256ffe7 7718 if (string_table == NULL)
1b31d05e
NC
7719 return;
7720
7721 memset (& aux, 0, sizeof (aux));
57346661
AM
7722
7723 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7724 {
c256ffe7 7725 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 7726 && sec->sh_link < elf_header.e_shnum)
57346661 7727 {
ba5cdace 7728 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 7729
4fbb74a6 7730 strsec = section_headers + sec->sh_link;
4082ef84
NC
7731 if (aux.strtab != NULL)
7732 {
7733 error (_("Multiple auxillary string tables encountered\n"));
7734 free (aux.strtab);
7735 }
3f5e193b
NC
7736 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
7737 1, strsec->sh_size,
7738 _("string table"));
c256ffe7 7739 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 7740 }
18bd398b 7741 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
7742 unwsec = sec;
7743 }
7744
7745 if (!unwsec)
7746 printf (_("\nThere are no unwind sections in this file.\n"));
7747
7748 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7749 {
18bd398b 7750 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 7751 {
74e1a04b
NC
7752 printf (_("\nUnwind section '%s' at offset 0x%lx contains %lu entries:\n"),
7753 printable_section_name (sec),
57346661 7754 (unsigned long) sec->sh_offset,
89fac5e3 7755 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
7756
7757 slurp_hppa_unwind_table (file, &aux, sec);
7758 if (aux.table_len > 0)
7759 dump_hppa_unwind (&aux);
7760
7761 if (aux.table)
7762 free ((char *) aux.table);
7763 aux.table = NULL;
7764 }
7765 }
7766
7767 if (aux.symtab)
7768 free (aux.symtab);
7769 if (aux.strtab)
7770 free ((char *) aux.strtab);
57346661
AM
7771}
7772
0b6ae522
DJ
7773struct arm_section
7774{
a734115a
NC
7775 unsigned char * data; /* The unwind data. */
7776 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
7777 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
7778 unsigned long nrelas; /* The number of relocations. */
7779 unsigned int rel_type; /* REL or RELA ? */
7780 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
7781};
7782
7783struct arm_unw_aux_info
7784{
a734115a
NC
7785 FILE * file; /* The file containing the unwind sections. */
7786 Elf_Internal_Sym * symtab; /* The file's symbol table. */
7787 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
7788 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7789 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
7790 char * strtab; /* The file's string table. */
7791 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
7792};
7793
7794static const char *
7795arm_print_vma_and_name (struct arm_unw_aux_info *aux,
7796 bfd_vma fn, struct absaddr addr)
7797{
7798 const char *procname;
7799 bfd_vma sym_offset;
7800
7801 if (addr.section == SHN_UNDEF)
7802 addr.offset = fn;
7803
948f632f 7804 find_symbol_for_address (aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
7805 aux->strtab_size, addr, &procname,
7806 &sym_offset);
7807
7808 print_vma (fn, PREFIX_HEX);
7809
7810 if (procname)
7811 {
7812 fputs (" <", stdout);
7813 fputs (procname, stdout);
7814
7815 if (sym_offset)
7816 printf ("+0x%lx", (unsigned long) sym_offset);
7817 fputc ('>', stdout);
7818 }
7819
7820 return procname;
7821}
7822
7823static void
7824arm_free_section (struct arm_section *arm_sec)
7825{
7826 if (arm_sec->data != NULL)
7827 free (arm_sec->data);
7828
7829 if (arm_sec->rela != NULL)
7830 free (arm_sec->rela);
7831}
7832
a734115a
NC
7833/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
7834 cached section and install SEC instead.
7835 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
7836 and return its valued in * WORDP, relocating if necessary.
1b31d05e 7837 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 7838 relocation's offset in ADDR.
1b31d05e
NC
7839 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
7840 into the string table of the symbol associated with the reloc. If no
7841 reloc was applied store -1 there.
7842 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
7843
7844static bfd_boolean
1b31d05e
NC
7845get_unwind_section_word (struct arm_unw_aux_info * aux,
7846 struct arm_section * arm_sec,
7847 Elf_Internal_Shdr * sec,
7848 bfd_vma word_offset,
7849 unsigned int * wordp,
7850 struct absaddr * addr,
7851 bfd_vma * sym_name)
0b6ae522
DJ
7852{
7853 Elf_Internal_Rela *rp;
7854 Elf_Internal_Sym *sym;
7855 const char * relname;
7856 unsigned int word;
7857 bfd_boolean wrapped;
7858
e0a31db1
NC
7859 if (sec == NULL || arm_sec == NULL)
7860 return FALSE;
7861
0b6ae522
DJ
7862 addr->section = SHN_UNDEF;
7863 addr->offset = 0;
7864
1b31d05e
NC
7865 if (sym_name != NULL)
7866 *sym_name = (bfd_vma) -1;
7867
a734115a 7868 /* If necessary, update the section cache. */
0b6ae522
DJ
7869 if (sec != arm_sec->sec)
7870 {
7871 Elf_Internal_Shdr *relsec;
7872
7873 arm_free_section (arm_sec);
7874
7875 arm_sec->sec = sec;
7876 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
7877 sec->sh_size, _("unwind data"));
0b6ae522
DJ
7878 arm_sec->rela = NULL;
7879 arm_sec->nrelas = 0;
7880
7881 for (relsec = section_headers;
7882 relsec < section_headers + elf_header.e_shnum;
7883 ++relsec)
7884 {
7885 if (relsec->sh_info >= elf_header.e_shnum
1ae40aa4
NC
7886 || section_headers + relsec->sh_info != sec
7887 /* PR 15745: Check the section type as well. */
7888 || (relsec->sh_type != SHT_REL
7889 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
7890 continue;
7891
a734115a 7892 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
7893 if (relsec->sh_type == SHT_REL)
7894 {
7895 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
7896 relsec->sh_size,
7897 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7898 return FALSE;
0b6ae522 7899 }
1ae40aa4 7900 else /* relsec->sh_type == SHT_RELA */
0b6ae522
DJ
7901 {
7902 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
7903 relsec->sh_size,
7904 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7905 return FALSE;
0b6ae522 7906 }
1ae40aa4 7907 break;
0b6ae522
DJ
7908 }
7909
7910 arm_sec->next_rela = arm_sec->rela;
7911 }
7912
a734115a 7913 /* If there is no unwind data we can do nothing. */
0b6ae522 7914 if (arm_sec->data == NULL)
a734115a 7915 return FALSE;
0b6ae522 7916
e0a31db1 7917 /* If the offset is invalid then fail. */
1a915552
NC
7918 if (word_offset > (sec->sh_size - 4)
7919 /* PR 18879 */
7920 || (sec->sh_size < 5 && word_offset >= sec->sh_size)
7921 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
7922 return FALSE;
7923
a734115a 7924 /* Get the word at the required offset. */
0b6ae522
DJ
7925 word = byte_get (arm_sec->data + word_offset, 4);
7926
0eff7165
NC
7927 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
7928 if (arm_sec->rela == NULL)
7929 {
7930 * wordp = word;
7931 return TRUE;
7932 }
7933
a734115a 7934 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
7935 wrapped = FALSE;
7936 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
7937 {
7938 bfd_vma prelval, offset;
7939
7940 if (rp->r_offset > word_offset && !wrapped)
7941 {
7942 rp = arm_sec->rela;
7943 wrapped = TRUE;
7944 }
7945 if (rp->r_offset > word_offset)
7946 break;
7947
7948 if (rp->r_offset & 3)
7949 {
7950 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
7951 (unsigned long) rp->r_offset);
7952 continue;
7953 }
7954
7955 if (rp->r_offset < word_offset)
7956 continue;
7957
74e1a04b
NC
7958 /* PR 17531: file: 027-161405-0.004 */
7959 if (aux->symtab == NULL)
7960 continue;
7961
0b6ae522
DJ
7962 if (arm_sec->rel_type == SHT_REL)
7963 {
7964 offset = word & 0x7fffffff;
7965 if (offset & 0x40000000)
7966 offset |= ~ (bfd_vma) 0x7fffffff;
7967 }
a734115a 7968 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 7969 offset = rp->r_addend;
a734115a 7970 else
74e1a04b
NC
7971 {
7972 error (_("Unknown section relocation type %d encountered\n"),
7973 arm_sec->rel_type);
7974 break;
7975 }
0b6ae522 7976
071436c6
NC
7977 /* PR 17531 file: 027-1241568-0.004. */
7978 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
7979 {
7980 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
7981 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
7982 break;
7983 }
7984
7985 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
7986 offset += sym->st_value;
7987 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
7988
a734115a
NC
7989 /* Check that we are processing the expected reloc type. */
7990 if (elf_header.e_machine == EM_ARM)
7991 {
7992 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7993 if (relname == NULL)
7994 {
7995 warn (_("Skipping unknown ARM relocation type: %d\n"),
7996 (int) ELF32_R_TYPE (rp->r_info));
7997 continue;
7998 }
a734115a
NC
7999
8000 if (streq (relname, "R_ARM_NONE"))
8001 continue;
0b4362b0 8002
a734115a
NC
8003 if (! streq (relname, "R_ARM_PREL31"))
8004 {
071436c6 8005 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8006 continue;
8007 }
8008 }
8009 else if (elf_header.e_machine == EM_TI_C6000)
8010 {
8011 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8012 if (relname == NULL)
8013 {
8014 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8015 (int) ELF32_R_TYPE (rp->r_info));
8016 continue;
8017 }
0b4362b0 8018
a734115a
NC
8019 if (streq (relname, "R_C6000_NONE"))
8020 continue;
8021
8022 if (! streq (relname, "R_C6000_PREL31"))
8023 {
071436c6 8024 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8025 continue;
8026 }
8027
8028 prelval >>= 1;
8029 }
8030 else
74e1a04b
NC
8031 {
8032 /* This function currently only supports ARM and TI unwinders. */
8033 warn (_("Only TI and ARM unwinders are currently supported\n"));
8034 break;
8035 }
fa197c1c 8036
0b6ae522
DJ
8037 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8038 addr->section = sym->st_shndx;
8039 addr->offset = offset;
74e1a04b 8040
1b31d05e
NC
8041 if (sym_name)
8042 * sym_name = sym->st_name;
0b6ae522
DJ
8043 break;
8044 }
8045
8046 *wordp = word;
8047 arm_sec->next_rela = rp;
8048
a734115a 8049 return TRUE;
0b6ae522
DJ
8050}
8051
a734115a
NC
8052static const char *tic6x_unwind_regnames[16] =
8053{
0b4362b0
RM
8054 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8055 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8056 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8057};
fa197c1c 8058
0b6ae522 8059static void
fa197c1c 8060decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8061{
fa197c1c
PB
8062 int i;
8063
8064 for (i = 12; mask; mask >>= 1, i--)
8065 {
8066 if (mask & 1)
8067 {
8068 fputs (tic6x_unwind_regnames[i], stdout);
8069 if (mask > 1)
8070 fputs (", ", stdout);
8071 }
8072 }
8073}
0b6ae522
DJ
8074
8075#define ADVANCE \
8076 if (remaining == 0 && more_words) \
8077 { \
8078 data_offset += 4; \
1b31d05e
NC
8079 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
8080 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
8081 return; \
8082 remaining = 4; \
8083 more_words--; \
8084 } \
8085
8086#define GET_OP(OP) \
8087 ADVANCE; \
8088 if (remaining) \
8089 { \
8090 remaining--; \
8091 (OP) = word >> 24; \
8092 word <<= 8; \
8093 } \
8094 else \
8095 { \
2b692964 8096 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
8097 return; \
8098 } \
cc5914eb 8099 printf ("0x%02x ", OP)
0b6ae522 8100
fa197c1c 8101static void
948f632f
DA
8102decode_arm_unwind_bytecode (struct arm_unw_aux_info * aux,
8103 unsigned int word,
8104 unsigned int remaining,
8105 unsigned int more_words,
8106 bfd_vma data_offset,
8107 Elf_Internal_Shdr * data_sec,
8108 struct arm_section * data_arm_sec)
fa197c1c
PB
8109{
8110 struct absaddr addr;
0b6ae522
DJ
8111
8112 /* Decode the unwinding instructions. */
8113 while (1)
8114 {
8115 unsigned int op, op2;
8116
8117 ADVANCE;
8118 if (remaining == 0)
8119 break;
8120 remaining--;
8121 op = word >> 24;
8122 word <<= 8;
8123
cc5914eb 8124 printf (" 0x%02x ", op);
0b6ae522
DJ
8125
8126 if ((op & 0xc0) == 0x00)
8127 {
8128 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8129
cc5914eb 8130 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8131 }
8132 else if ((op & 0xc0) == 0x40)
8133 {
8134 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8135
cc5914eb 8136 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8137 }
8138 else if ((op & 0xf0) == 0x80)
8139 {
8140 GET_OP (op2);
8141 if (op == 0x80 && op2 == 0)
8142 printf (_("Refuse to unwind"));
8143 else
8144 {
8145 unsigned int mask = ((op & 0x0f) << 8) | op2;
8146 int first = 1;
8147 int i;
2b692964 8148
0b6ae522
DJ
8149 printf ("pop {");
8150 for (i = 0; i < 12; i++)
8151 if (mask & (1 << i))
8152 {
8153 if (first)
8154 first = 0;
8155 else
8156 printf (", ");
8157 printf ("r%d", 4 + i);
8158 }
8159 printf ("}");
8160 }
8161 }
8162 else if ((op & 0xf0) == 0x90)
8163 {
8164 if (op == 0x9d || op == 0x9f)
8165 printf (_(" [Reserved]"));
8166 else
cc5914eb 8167 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8168 }
8169 else if ((op & 0xf0) == 0xa0)
8170 {
8171 int end = 4 + (op & 0x07);
8172 int first = 1;
8173 int i;
61865e30 8174
0b6ae522
DJ
8175 printf (" pop {");
8176 for (i = 4; i <= end; i++)
8177 {
8178 if (first)
8179 first = 0;
8180 else
8181 printf (", ");
8182 printf ("r%d", i);
8183 }
8184 if (op & 0x08)
8185 {
1b31d05e 8186 if (!first)
0b6ae522
DJ
8187 printf (", ");
8188 printf ("r14");
8189 }
8190 printf ("}");
8191 }
8192 else if (op == 0xb0)
8193 printf (_(" finish"));
8194 else if (op == 0xb1)
8195 {
8196 GET_OP (op2);
8197 if (op2 == 0 || (op2 & 0xf0) != 0)
8198 printf (_("[Spare]"));
8199 else
8200 {
8201 unsigned int mask = op2 & 0x0f;
8202 int first = 1;
8203 int i;
61865e30 8204
0b6ae522
DJ
8205 printf ("pop {");
8206 for (i = 0; i < 12; i++)
8207 if (mask & (1 << i))
8208 {
8209 if (first)
8210 first = 0;
8211 else
8212 printf (", ");
8213 printf ("r%d", i);
8214 }
8215 printf ("}");
8216 }
8217 }
8218 else if (op == 0xb2)
8219 {
b115cf96 8220 unsigned char buf[9];
0b6ae522
DJ
8221 unsigned int i, len;
8222 unsigned long offset;
61865e30 8223
b115cf96 8224 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8225 {
8226 GET_OP (buf[i]);
8227 if ((buf[i] & 0x80) == 0)
8228 break;
8229 }
4082ef84
NC
8230 if (i == sizeof (buf))
8231 printf (_("corrupt change to vsp"));
8232 else
8233 {
8234 offset = read_uleb128 (buf, &len, buf + i + 1);
8235 assert (len == i + 1);
8236 offset = offset * 4 + 0x204;
8237 printf ("vsp = vsp + %ld", offset);
8238 }
0b6ae522 8239 }
61865e30 8240 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8241 {
61865e30
NC
8242 unsigned int first, last;
8243
8244 GET_OP (op2);
8245 first = op2 >> 4;
8246 last = op2 & 0x0f;
8247 if (op == 0xc8)
8248 first = first + 16;
8249 printf ("pop {D%d", first);
8250 if (last)
8251 printf ("-D%d", first + last);
8252 printf ("}");
8253 }
8254 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
8255 {
8256 unsigned int count = op & 0x07;
8257
8258 printf ("pop {D8");
8259 if (count)
8260 printf ("-D%d", 8 + count);
8261 printf ("}");
8262 }
8263 else if (op >= 0xc0 && op <= 0xc5)
8264 {
8265 unsigned int count = op & 0x07;
8266
8267 printf (" pop {wR10");
8268 if (count)
8269 printf ("-wR%d", 10 + count);
8270 printf ("}");
8271 }
8272 else if (op == 0xc6)
8273 {
8274 unsigned int first, last;
8275
8276 GET_OP (op2);
8277 first = op2 >> 4;
8278 last = op2 & 0x0f;
8279 printf ("pop {wR%d", first);
8280 if (last)
8281 printf ("-wR%d", first + last);
8282 printf ("}");
8283 }
8284 else if (op == 0xc7)
8285 {
8286 GET_OP (op2);
8287 if (op2 == 0 || (op2 & 0xf0) != 0)
8288 printf (_("[Spare]"));
0b6ae522
DJ
8289 else
8290 {
61865e30
NC
8291 unsigned int mask = op2 & 0x0f;
8292 int first = 1;
8293 int i;
8294
8295 printf ("pop {");
8296 for (i = 0; i < 4; i++)
8297 if (mask & (1 << i))
8298 {
8299 if (first)
8300 first = 0;
8301 else
8302 printf (", ");
8303 printf ("wCGR%d", i);
8304 }
8305 printf ("}");
0b6ae522
DJ
8306 }
8307 }
61865e30
NC
8308 else
8309 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
8310 printf ("\n");
8311 }
fa197c1c
PB
8312}
8313
8314static void
948f632f
DA
8315decode_tic6x_unwind_bytecode (struct arm_unw_aux_info * aux,
8316 unsigned int word,
8317 unsigned int remaining,
8318 unsigned int more_words,
8319 bfd_vma data_offset,
8320 Elf_Internal_Shdr * data_sec,
8321 struct arm_section * data_arm_sec)
fa197c1c
PB
8322{
8323 struct absaddr addr;
8324
8325 /* Decode the unwinding instructions. */
8326 while (1)
8327 {
8328 unsigned int op, op2;
8329
8330 ADVANCE;
8331 if (remaining == 0)
8332 break;
8333 remaining--;
8334 op = word >> 24;
8335 word <<= 8;
8336
9cf03b7e 8337 printf (" 0x%02x ", op);
fa197c1c
PB
8338
8339 if ((op & 0xc0) == 0x00)
8340 {
8341 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 8342 printf (" sp = sp + %d", offset);
fa197c1c
PB
8343 }
8344 else if ((op & 0xc0) == 0x80)
8345 {
8346 GET_OP (op2);
8347 if (op == 0x80 && op2 == 0)
8348 printf (_("Refuse to unwind"));
8349 else
8350 {
8351 unsigned int mask = ((op & 0x1f) << 8) | op2;
8352 if (op & 0x20)
8353 printf ("pop compact {");
8354 else
8355 printf ("pop {");
8356
8357 decode_tic6x_unwind_regmask (mask);
8358 printf("}");
8359 }
8360 }
8361 else if ((op & 0xf0) == 0xc0)
8362 {
8363 unsigned int reg;
8364 unsigned int nregs;
8365 unsigned int i;
8366 const char *name;
a734115a
NC
8367 struct
8368 {
fa197c1c
PB
8369 unsigned int offset;
8370 unsigned int reg;
8371 } regpos[16];
8372
8373 /* Scan entire instruction first so that GET_OP output is not
8374 interleaved with disassembly. */
8375 nregs = 0;
8376 for (i = 0; nregs < (op & 0xf); i++)
8377 {
8378 GET_OP (op2);
8379 reg = op2 >> 4;
8380 if (reg != 0xf)
8381 {
8382 regpos[nregs].offset = i * 2;
8383 regpos[nregs].reg = reg;
8384 nregs++;
8385 }
8386
8387 reg = op2 & 0xf;
8388 if (reg != 0xf)
8389 {
8390 regpos[nregs].offset = i * 2 + 1;
8391 regpos[nregs].reg = reg;
8392 nregs++;
8393 }
8394 }
8395
8396 printf (_("pop frame {"));
8397 reg = nregs - 1;
8398 for (i = i * 2; i > 0; i--)
8399 {
8400 if (regpos[reg].offset == i - 1)
8401 {
8402 name = tic6x_unwind_regnames[regpos[reg].reg];
8403 if (reg > 0)
8404 reg--;
8405 }
8406 else
8407 name = _("[pad]");
8408
8409 fputs (name, stdout);
8410 if (i > 1)
8411 printf (", ");
8412 }
8413
8414 printf ("}");
8415 }
8416 else if (op == 0xd0)
8417 printf (" MOV FP, SP");
8418 else if (op == 0xd1)
8419 printf (" __c6xabi_pop_rts");
8420 else if (op == 0xd2)
8421 {
8422 unsigned char buf[9];
8423 unsigned int i, len;
8424 unsigned long offset;
a734115a 8425
fa197c1c
PB
8426 for (i = 0; i < sizeof (buf); i++)
8427 {
8428 GET_OP (buf[i]);
8429 if ((buf[i] & 0x80) == 0)
8430 break;
8431 }
0eff7165
NC
8432 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
8433 if (i == sizeof (buf))
8434 {
8435 printf ("<corrupt sp adjust>\n");
8436 warn (_("Corrupt stack pointer adjustment detected\n"));
8437 return;
8438 }
948f632f 8439
f6f0e17b 8440 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
8441 assert (len == i + 1);
8442 offset = offset * 8 + 0x408;
8443 printf (_("sp = sp + %ld"), offset);
8444 }
8445 else if ((op & 0xf0) == 0xe0)
8446 {
8447 if ((op & 0x0f) == 7)
8448 printf (" RETURN");
8449 else
8450 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
8451 }
8452 else
8453 {
8454 printf (_(" [unsupported opcode]"));
8455 }
8456 putchar ('\n');
8457 }
8458}
8459
8460static bfd_vma
a734115a 8461arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
8462{
8463 bfd_vma offset;
8464
8465 offset = word & 0x7fffffff;
8466 if (offset & 0x40000000)
8467 offset |= ~ (bfd_vma) 0x7fffffff;
8468
8469 if (elf_header.e_machine == EM_TI_C6000)
8470 offset <<= 1;
8471
8472 return offset + where;
8473}
8474
8475static void
1b31d05e
NC
8476decode_arm_unwind (struct arm_unw_aux_info * aux,
8477 unsigned int word,
8478 unsigned int remaining,
8479 bfd_vma data_offset,
8480 Elf_Internal_Shdr * data_sec,
8481 struct arm_section * data_arm_sec)
fa197c1c
PB
8482{
8483 int per_index;
8484 unsigned int more_words = 0;
37e14bc3 8485 struct absaddr addr;
1b31d05e 8486 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
8487
8488 if (remaining == 0)
8489 {
1b31d05e
NC
8490 /* Fetch the first word.
8491 Note - when decoding an object file the address extracted
8492 here will always be 0. So we also pass in the sym_name
8493 parameter so that we can find the symbol associated with
8494 the personality routine. */
8495 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
8496 & word, & addr, & sym_name))
fa197c1c 8497 return;
1b31d05e 8498
fa197c1c
PB
8499 remaining = 4;
8500 }
8501
8502 if ((word & 0x80000000) == 0)
8503 {
8504 /* Expand prel31 for personality routine. */
8505 bfd_vma fn;
8506 const char *procname;
8507
a734115a 8508 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 8509 printf (_(" Personality routine: "));
1b31d05e
NC
8510 if (fn == 0
8511 && addr.section == SHN_UNDEF && addr.offset == 0
8512 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
8513 {
8514 procname = aux->strtab + sym_name;
8515 print_vma (fn, PREFIX_HEX);
8516 if (procname)
8517 {
8518 fputs (" <", stdout);
8519 fputs (procname, stdout);
8520 fputc ('>', stdout);
8521 }
8522 }
8523 else
8524 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
8525 fputc ('\n', stdout);
8526
8527 /* The GCC personality routines use the standard compact
8528 encoding, starting with one byte giving the number of
8529 words. */
8530 if (procname != NULL
8531 && (const_strneq (procname, "__gcc_personality_v0")
8532 || const_strneq (procname, "__gxx_personality_v0")
8533 || const_strneq (procname, "__gcj_personality_v0")
8534 || const_strneq (procname, "__gnu_objc_personality_v0")))
8535 {
8536 remaining = 0;
8537 more_words = 1;
8538 ADVANCE;
8539 if (!remaining)
8540 {
8541 printf (_(" [Truncated data]\n"));
8542 return;
8543 }
8544 more_words = word >> 24;
8545 word <<= 8;
8546 remaining--;
8547 per_index = -1;
8548 }
8549 else
8550 return;
8551 }
8552 else
8553 {
1b31d05e 8554 /* ARM EHABI Section 6.3:
0b4362b0 8555
1b31d05e 8556 An exception-handling table entry for the compact model looks like:
0b4362b0 8557
1b31d05e
NC
8558 31 30-28 27-24 23-0
8559 -- ----- ----- ----
8560 1 0 index Data for personalityRoutine[index] */
8561
8562 if (elf_header.e_machine == EM_ARM
8563 && (word & 0x70000000))
83c257ca 8564 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 8565
fa197c1c 8566 per_index = (word >> 24) & 0x7f;
1b31d05e 8567 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
8568 if (per_index == 0)
8569 {
8570 more_words = 0;
8571 word <<= 8;
8572 remaining--;
8573 }
8574 else if (per_index < 3)
8575 {
8576 more_words = (word >> 16) & 0xff;
8577 word <<= 16;
8578 remaining -= 2;
8579 }
8580 }
8581
8582 switch (elf_header.e_machine)
8583 {
8584 case EM_ARM:
8585 if (per_index < 3)
8586 {
8587 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
8588 data_offset, data_sec, data_arm_sec);
8589 }
8590 else
1b31d05e
NC
8591 {
8592 warn (_("Unknown ARM compact model index encountered\n"));
8593 printf (_(" [reserved]\n"));
8594 }
fa197c1c
PB
8595 break;
8596
8597 case EM_TI_C6000:
8598 if (per_index < 3)
8599 {
8600 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 8601 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
8602 }
8603 else if (per_index < 5)
8604 {
8605 if (((word >> 17) & 0x7f) == 0x7f)
8606 printf (_(" Restore stack from frame pointer\n"));
8607 else
8608 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
8609 printf (_(" Registers restored: "));
8610 if (per_index == 4)
8611 printf (" (compact) ");
8612 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
8613 putchar ('\n');
8614 printf (_(" Return register: %s\n"),
8615 tic6x_unwind_regnames[word & 0xf]);
8616 }
8617 else
1b31d05e 8618 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
8619 break;
8620
8621 default:
74e1a04b 8622 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
1b31d05e 8623 elf_header.e_machine);
fa197c1c 8624 }
0b6ae522
DJ
8625
8626 /* Decode the descriptors. Not implemented. */
8627}
8628
8629static void
8630dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
8631{
8632 struct arm_section exidx_arm_sec, extab_arm_sec;
8633 unsigned int i, exidx_len;
948f632f 8634 unsigned long j, nfuns;
0b6ae522
DJ
8635
8636 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
8637 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
8638 exidx_len = exidx_sec->sh_size / 8;
8639
948f632f
DA
8640 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8641 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8642 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8643 aux->funtab[nfuns++] = aux->symtab[j];
8644 aux->nfuns = nfuns;
8645 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8646
0b6ae522
DJ
8647 for (i = 0; i < exidx_len; i++)
8648 {
8649 unsigned int exidx_fn, exidx_entry;
8650 struct absaddr fn_addr, entry_addr;
8651 bfd_vma fn;
8652
8653 fputc ('\n', stdout);
8654
1b31d05e
NC
8655 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8656 8 * i, & exidx_fn, & fn_addr, NULL)
8657 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8658 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 8659 {
948f632f 8660 free (aux->funtab);
1b31d05e
NC
8661 arm_free_section (& exidx_arm_sec);
8662 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
8663 return;
8664 }
8665
83c257ca
NC
8666 /* ARM EHABI, Section 5:
8667 An index table entry consists of 2 words.
8668 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
8669 if (exidx_fn & 0x80000000)
8670 warn (_("corrupt index table entry: %x\n"), exidx_fn);
8671
a734115a 8672 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 8673
a734115a 8674 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
8675 fputs (": ", stdout);
8676
8677 if (exidx_entry == 1)
8678 {
8679 print_vma (exidx_entry, PREFIX_HEX);
8680 fputs (" [cantunwind]\n", stdout);
8681 }
8682 else if (exidx_entry & 0x80000000)
8683 {
8684 print_vma (exidx_entry, PREFIX_HEX);
8685 fputc ('\n', stdout);
8686 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
8687 }
8688 else
8689 {
8f73510c 8690 bfd_vma table, table_offset = 0;
0b6ae522
DJ
8691 Elf_Internal_Shdr *table_sec;
8692
8693 fputs ("@", stdout);
a734115a 8694 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
8695 print_vma (table, PREFIX_HEX);
8696 printf ("\n");
8697
8698 /* Locate the matching .ARM.extab. */
8699 if (entry_addr.section != SHN_UNDEF
8700 && entry_addr.section < elf_header.e_shnum)
8701 {
8702 table_sec = section_headers + entry_addr.section;
8703 table_offset = entry_addr.offset;
1a915552
NC
8704 /* PR 18879 */
8705 if (table_offset > table_sec->sh_size
8706 || ((bfd_signed_vma) table_offset) < 0)
8707 {
8708 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
8709 (unsigned long) table_offset,
8710 printable_section_name (table_sec));
8711 continue;
8712 }
0b6ae522
DJ
8713 }
8714 else
8715 {
8716 table_sec = find_section_by_address (table);
8717 if (table_sec != NULL)
8718 table_offset = table - table_sec->sh_addr;
8719 }
8720 if (table_sec == NULL)
8721 {
8722 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
8723 (unsigned long) table);
8724 continue;
8725 }
8726 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
8727 &extab_arm_sec);
8728 }
8729 }
8730
8731 printf ("\n");
8732
948f632f 8733 free (aux->funtab);
0b6ae522
DJ
8734 arm_free_section (&exidx_arm_sec);
8735 arm_free_section (&extab_arm_sec);
8736}
8737
fa197c1c 8738/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
8739
8740static void
0b6ae522
DJ
8741arm_process_unwind (FILE *file)
8742{
8743 struct arm_unw_aux_info aux;
8744 Elf_Internal_Shdr *unwsec = NULL;
8745 Elf_Internal_Shdr *strsec;
8746 Elf_Internal_Shdr *sec;
8747 unsigned long i;
fa197c1c 8748 unsigned int sec_type;
0b6ae522 8749
fa197c1c
PB
8750 switch (elf_header.e_machine)
8751 {
8752 case EM_ARM:
8753 sec_type = SHT_ARM_EXIDX;
8754 break;
8755
8756 case EM_TI_C6000:
8757 sec_type = SHT_C6000_UNWIND;
8758 break;
8759
0b4362b0 8760 default:
74e1a04b 8761 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
1b31d05e
NC
8762 elf_header.e_machine);
8763 return;
fa197c1c
PB
8764 }
8765
0b6ae522 8766 if (string_table == NULL)
1b31d05e
NC
8767 return;
8768
8769 memset (& aux, 0, sizeof (aux));
8770 aux.file = file;
0b6ae522
DJ
8771
8772 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8773 {
8774 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
8775 {
ba5cdace 8776 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
8777
8778 strsec = section_headers + sec->sh_link;
74e1a04b
NC
8779
8780 /* PR binutils/17531 file: 011-12666-0.004. */
8781 if (aux.strtab != NULL)
8782 {
4082ef84 8783 error (_("Multiple string tables found in file.\n"));
74e1a04b
NC
8784 free (aux.strtab);
8785 }
0b6ae522
DJ
8786 aux.strtab = get_data (NULL, file, strsec->sh_offset,
8787 1, strsec->sh_size, _("string table"));
8788 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
8789 }
fa197c1c 8790 else if (sec->sh_type == sec_type)
0b6ae522
DJ
8791 unwsec = sec;
8792 }
8793
1b31d05e 8794 if (unwsec == NULL)
0b6ae522 8795 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
8796 else
8797 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8798 {
8799 if (sec->sh_type == sec_type)
8800 {
8801 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
74e1a04b 8802 printable_section_name (sec),
1b31d05e
NC
8803 (unsigned long) sec->sh_offset,
8804 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 8805
1b31d05e
NC
8806 dump_arm_unwind (&aux, sec);
8807 }
8808 }
0b6ae522
DJ
8809
8810 if (aux.symtab)
8811 free (aux.symtab);
8812 if (aux.strtab)
8813 free ((char *) aux.strtab);
0b6ae522
DJ
8814}
8815
1b31d05e 8816static void
2cf0635d 8817process_unwind (FILE * file)
57346661 8818{
2cf0635d
NC
8819 struct unwind_handler
8820 {
57346661 8821 int machtype;
1b31d05e 8822 void (* handler)(FILE *);
2cf0635d
NC
8823 } handlers[] =
8824 {
0b6ae522 8825 { EM_ARM, arm_process_unwind },
57346661
AM
8826 { EM_IA_64, ia64_process_unwind },
8827 { EM_PARISC, hppa_process_unwind },
fa197c1c 8828 { EM_TI_C6000, arm_process_unwind },
57346661
AM
8829 { 0, 0 }
8830 };
8831 int i;
8832
8833 if (!do_unwind)
1b31d05e 8834 return;
57346661
AM
8835
8836 for (i = 0; handlers[i].handler != NULL; i++)
8837 if (elf_header.e_machine == handlers[i].machtype)
9f758fdc
NC
8838 {
8839 handlers[i].handler (file);
8840 return;
8841 }
57346661 8842
1b31d05e
NC
8843 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
8844 get_machine_name (elf_header.e_machine));
57346661
AM
8845}
8846
252b5132 8847static void
2cf0635d 8848dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
8849{
8850 switch (entry->d_tag)
8851 {
8852 case DT_MIPS_FLAGS:
8853 if (entry->d_un.d_val == 0)
4b68bca3 8854 printf (_("NONE"));
252b5132
RH
8855 else
8856 {
8857 static const char * opts[] =
8858 {
8859 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
8860 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
8861 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
8862 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
8863 "RLD_ORDER_SAFE"
8864 };
8865 unsigned int cnt;
8866 int first = 1;
2b692964 8867
60bca95a 8868 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
8869 if (entry->d_un.d_val & (1 << cnt))
8870 {
8871 printf ("%s%s", first ? "" : " ", opts[cnt]);
8872 first = 0;
8873 }
252b5132
RH
8874 }
8875 break;
103f02d3 8876
252b5132 8877 case DT_MIPS_IVERSION:
d79b3d50 8878 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 8879 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8880 else
76ca31c0
NC
8881 {
8882 char buf[40];
8883 sprintf_vma (buf, entry->d_un.d_ptr);
8884 /* Note: coded this way so that there is a single string for translation. */
8885 printf (_("<corrupt: %s>"), buf);
8886 }
252b5132 8887 break;
103f02d3 8888
252b5132
RH
8889 case DT_MIPS_TIME_STAMP:
8890 {
d5b07ef4 8891 char timebuf[128];
2cf0635d 8892 struct tm * tmp;
91d6fa6a 8893 time_t atime = entry->d_un.d_val;
82b1b41b 8894
91d6fa6a 8895 tmp = gmtime (&atime);
82b1b41b
NC
8896 /* PR 17531: file: 6accc532. */
8897 if (tmp == NULL)
8898 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
8899 else
8900 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
8901 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8902 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 8903 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
8904 }
8905 break;
103f02d3 8906
252b5132
RH
8907 case DT_MIPS_RLD_VERSION:
8908 case DT_MIPS_LOCAL_GOTNO:
8909 case DT_MIPS_CONFLICTNO:
8910 case DT_MIPS_LIBLISTNO:
8911 case DT_MIPS_SYMTABNO:
8912 case DT_MIPS_UNREFEXTNO:
8913 case DT_MIPS_HIPAGENO:
8914 case DT_MIPS_DELTA_CLASS_NO:
8915 case DT_MIPS_DELTA_INSTANCE_NO:
8916 case DT_MIPS_DELTA_RELOC_NO:
8917 case DT_MIPS_DELTA_SYM_NO:
8918 case DT_MIPS_DELTA_CLASSSYM_NO:
8919 case DT_MIPS_COMPACT_SIZE:
c69075ac 8920 print_vma (entry->d_un.d_val, DEC);
252b5132 8921 break;
103f02d3
UD
8922
8923 default:
4b68bca3 8924 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 8925 }
4b68bca3 8926 putchar ('\n');
103f02d3
UD
8927}
8928
103f02d3 8929static void
2cf0635d 8930dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
8931{
8932 switch (entry->d_tag)
8933 {
8934 case DT_HP_DLD_FLAGS:
8935 {
8936 static struct
8937 {
8938 long int bit;
2cf0635d 8939 const char * str;
5e220199
NC
8940 }
8941 flags[] =
8942 {
8943 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
8944 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
8945 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
8946 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
8947 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
8948 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
8949 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
8950 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
8951 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
8952 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
8953 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
8954 { DT_HP_GST, "HP_GST" },
8955 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
8956 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
8957 { DT_HP_NODELETE, "HP_NODELETE" },
8958 { DT_HP_GROUP, "HP_GROUP" },
8959 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 8960 };
103f02d3 8961 int first = 1;
5e220199 8962 size_t cnt;
f7a99963 8963 bfd_vma val = entry->d_un.d_val;
103f02d3 8964
60bca95a 8965 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 8966 if (val & flags[cnt].bit)
30800947
NC
8967 {
8968 if (! first)
8969 putchar (' ');
8970 fputs (flags[cnt].str, stdout);
8971 first = 0;
8972 val ^= flags[cnt].bit;
8973 }
76da6bbe 8974
103f02d3 8975 if (val != 0 || first)
f7a99963
NC
8976 {
8977 if (! first)
8978 putchar (' ');
8979 print_vma (val, HEX);
8980 }
103f02d3
UD
8981 }
8982 break;
76da6bbe 8983
252b5132 8984 default:
f7a99963
NC
8985 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8986 break;
252b5132 8987 }
35b1837e 8988 putchar ('\n');
252b5132
RH
8989}
8990
28f997cf
TG
8991#ifdef BFD64
8992
8993/* VMS vs Unix time offset and factor. */
8994
8995#define VMS_EPOCH_OFFSET 35067168000000000LL
8996#define VMS_GRANULARITY_FACTOR 10000000
8997
8998/* Display a VMS time in a human readable format. */
8999
9000static void
9001print_vms_time (bfd_int64_t vmstime)
9002{
9003 struct tm *tm;
9004 time_t unxtime;
9005
9006 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9007 tm = gmtime (&unxtime);
9008 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9009 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9010 tm->tm_hour, tm->tm_min, tm->tm_sec);
9011}
9012#endif /* BFD64 */
9013
ecc51f48 9014static void
2cf0635d 9015dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9016{
9017 switch (entry->d_tag)
9018 {
0de14b54 9019 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9020 /* First 3 slots reserved. */
ecc51f48
NC
9021 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9022 printf (" -- ");
9023 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9024 break;
9025
28f997cf
TG
9026 case DT_IA_64_VMS_LINKTIME:
9027#ifdef BFD64
9028 print_vms_time (entry->d_un.d_val);
9029#endif
9030 break;
9031
9032 case DT_IA_64_VMS_LNKFLAGS:
9033 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9034 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9035 printf (" CALL_DEBUG");
9036 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9037 printf (" NOP0BUFS");
9038 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9039 printf (" P0IMAGE");
9040 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9041 printf (" MKTHREADS");
9042 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9043 printf (" UPCALLS");
9044 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9045 printf (" IMGSTA");
9046 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9047 printf (" INITIALIZE");
9048 if (entry->d_un.d_val & VMS_LF_MAIN)
9049 printf (" MAIN");
9050 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9051 printf (" EXE_INIT");
9052 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9053 printf (" TBK_IN_IMG");
9054 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9055 printf (" DBG_IN_IMG");
9056 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9057 printf (" TBK_IN_DSF");
9058 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9059 printf (" DBG_IN_DSF");
9060 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9061 printf (" SIGNATURES");
9062 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9063 printf (" REL_SEG_OFF");
9064 break;
9065
bdf4d63a
JJ
9066 default:
9067 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9068 break;
ecc51f48 9069 }
bdf4d63a 9070 putchar ('\n');
ecc51f48
NC
9071}
9072
252b5132 9073static int
2cf0635d 9074get_32bit_dynamic_section (FILE * file)
252b5132 9075{
2cf0635d
NC
9076 Elf32_External_Dyn * edyn;
9077 Elf32_External_Dyn * ext;
9078 Elf_Internal_Dyn * entry;
103f02d3 9079
3f5e193b
NC
9080 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
9081 dynamic_size, _("dynamic section"));
a6e9f9df
AM
9082 if (!edyn)
9083 return 0;
103f02d3 9084
071436c6
NC
9085 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9086 might not have the luxury of section headers. Look for the DT_NULL
9087 terminator to determine the number of entries. */
ba2685cc 9088 for (ext = edyn, dynamic_nent = 0;
53c3012c 9089 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9090 ext++)
9091 {
9092 dynamic_nent++;
9093 if (BYTE_GET (ext->d_tag) == DT_NULL)
9094 break;
9095 }
252b5132 9096
3f5e193b
NC
9097 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9098 sizeof (* entry));
b2d38a17 9099 if (dynamic_section == NULL)
252b5132 9100 {
8b73c356
NC
9101 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9102 (unsigned long) dynamic_nent);
9ea033b2
NC
9103 free (edyn);
9104 return 0;
9105 }
252b5132 9106
fb514b26 9107 for (ext = edyn, entry = dynamic_section;
ba2685cc 9108 entry < dynamic_section + dynamic_nent;
fb514b26 9109 ext++, entry++)
9ea033b2 9110 {
fb514b26
AM
9111 entry->d_tag = BYTE_GET (ext->d_tag);
9112 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9113 }
9114
9ea033b2
NC
9115 free (edyn);
9116
9117 return 1;
9118}
9119
9120static int
2cf0635d 9121get_64bit_dynamic_section (FILE * file)
9ea033b2 9122{
2cf0635d
NC
9123 Elf64_External_Dyn * edyn;
9124 Elf64_External_Dyn * ext;
9125 Elf_Internal_Dyn * entry;
103f02d3 9126
071436c6 9127 /* Read in the data. */
3f5e193b
NC
9128 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
9129 dynamic_size, _("dynamic section"));
a6e9f9df
AM
9130 if (!edyn)
9131 return 0;
103f02d3 9132
071436c6
NC
9133 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9134 might not have the luxury of section headers. Look for the DT_NULL
9135 terminator to determine the number of entries. */
ba2685cc 9136 for (ext = edyn, dynamic_nent = 0;
53c3012c
AM
9137 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
9138 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9139 ext++)
9140 {
9141 dynamic_nent++;
66543521 9142 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9143 break;
9144 }
252b5132 9145
3f5e193b
NC
9146 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9147 sizeof (* entry));
b2d38a17 9148 if (dynamic_section == NULL)
252b5132 9149 {
8b73c356
NC
9150 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9151 (unsigned long) dynamic_nent);
252b5132
RH
9152 free (edyn);
9153 return 0;
9154 }
9155
071436c6 9156 /* Convert from external to internal formats. */
fb514b26 9157 for (ext = edyn, entry = dynamic_section;
ba2685cc 9158 entry < dynamic_section + dynamic_nent;
fb514b26 9159 ext++, entry++)
252b5132 9160 {
66543521
AM
9161 entry->d_tag = BYTE_GET (ext->d_tag);
9162 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9163 }
9164
9165 free (edyn);
9166
9ea033b2
NC
9167 return 1;
9168}
9169
e9e44622
JJ
9170static void
9171print_dynamic_flags (bfd_vma flags)
d1133906 9172{
e9e44622 9173 int first = 1;
13ae64f3 9174
d1133906
NC
9175 while (flags)
9176 {
9177 bfd_vma flag;
9178
9179 flag = flags & - flags;
9180 flags &= ~ flag;
9181
e9e44622
JJ
9182 if (first)
9183 first = 0;
9184 else
9185 putc (' ', stdout);
13ae64f3 9186
d1133906
NC
9187 switch (flag)
9188 {
e9e44622
JJ
9189 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
9190 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
9191 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
9192 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
9193 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 9194 default: fputs (_("unknown"), stdout); break;
d1133906
NC
9195 }
9196 }
e9e44622 9197 puts ("");
d1133906
NC
9198}
9199
b2d38a17
NC
9200/* Parse and display the contents of the dynamic section. */
9201
9ea033b2 9202static int
2cf0635d 9203process_dynamic_section (FILE * file)
9ea033b2 9204{
2cf0635d 9205 Elf_Internal_Dyn * entry;
9ea033b2
NC
9206
9207 if (dynamic_size == 0)
9208 {
9209 if (do_dynamic)
b2d38a17 9210 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
9211
9212 return 1;
9213 }
9214
9215 if (is_32bit_elf)
9216 {
b2d38a17 9217 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
9218 return 0;
9219 }
b2d38a17 9220 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
9221 return 0;
9222
252b5132
RH
9223 /* Find the appropriate symbol table. */
9224 if (dynamic_symbols == NULL)
9225 {
86dba8ee
AM
9226 for (entry = dynamic_section;
9227 entry < dynamic_section + dynamic_nent;
9228 ++entry)
252b5132 9229 {
c8286bd1 9230 Elf_Internal_Shdr section;
252b5132
RH
9231
9232 if (entry->d_tag != DT_SYMTAB)
9233 continue;
9234
9235 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
9236
9237 /* Since we do not know how big the symbol table is,
9238 we default to reading in the entire file (!) and
9239 processing that. This is overkill, I know, but it
e3c8793a 9240 should work. */
d93f0186 9241 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 9242
fb52b2f4
NC
9243 if (archive_file_offset != 0)
9244 section.sh_size = archive_file_size - section.sh_offset;
9245 else
9246 {
9247 if (fseek (file, 0, SEEK_END))
591a748a 9248 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
9249
9250 section.sh_size = ftell (file) - section.sh_offset;
9251 }
252b5132 9252
9ea033b2 9253 if (is_32bit_elf)
9ad5cbcf 9254 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 9255 else
9ad5cbcf 9256 section.sh_entsize = sizeof (Elf64_External_Sym);
071436c6 9257 section.sh_name = string_table_length;
252b5132 9258
ba5cdace 9259 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 9260 if (num_dynamic_syms < 1)
252b5132
RH
9261 {
9262 error (_("Unable to determine the number of symbols to load\n"));
9263 continue;
9264 }
252b5132
RH
9265 }
9266 }
9267
9268 /* Similarly find a string table. */
9269 if (dynamic_strings == NULL)
9270 {
86dba8ee
AM
9271 for (entry = dynamic_section;
9272 entry < dynamic_section + dynamic_nent;
9273 ++entry)
252b5132
RH
9274 {
9275 unsigned long offset;
b34976b6 9276 long str_tab_len;
252b5132
RH
9277
9278 if (entry->d_tag != DT_STRTAB)
9279 continue;
9280
9281 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
9282
9283 /* Since we do not know how big the string table is,
9284 we default to reading in the entire file (!) and
9285 processing that. This is overkill, I know, but it
e3c8793a 9286 should work. */
252b5132 9287
d93f0186 9288 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
9289
9290 if (archive_file_offset != 0)
9291 str_tab_len = archive_file_size - offset;
9292 else
9293 {
9294 if (fseek (file, 0, SEEK_END))
9295 error (_("Unable to seek to end of file\n"));
9296 str_tab_len = ftell (file) - offset;
9297 }
252b5132
RH
9298
9299 if (str_tab_len < 1)
9300 {
9301 error
9302 (_("Unable to determine the length of the dynamic string table\n"));
9303 continue;
9304 }
9305
3f5e193b
NC
9306 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
9307 str_tab_len,
9308 _("dynamic string table"));
59245841 9309 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
9310 break;
9311 }
9312 }
9313
9314 /* And find the syminfo section if available. */
9315 if (dynamic_syminfo == NULL)
9316 {
3e8bba36 9317 unsigned long syminsz = 0;
252b5132 9318
86dba8ee
AM
9319 for (entry = dynamic_section;
9320 entry < dynamic_section + dynamic_nent;
9321 ++entry)
252b5132
RH
9322 {
9323 if (entry->d_tag == DT_SYMINENT)
9324 {
9325 /* Note: these braces are necessary to avoid a syntax
9326 error from the SunOS4 C compiler. */
049b0c3a
NC
9327 /* PR binutils/17531: A corrupt file can trigger this test.
9328 So do not use an assert, instead generate an error message. */
9329 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 9330 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 9331 (int) entry->d_un.d_val);
252b5132
RH
9332 }
9333 else if (entry->d_tag == DT_SYMINSZ)
9334 syminsz = entry->d_un.d_val;
9335 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
9336 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
9337 syminsz);
252b5132
RH
9338 }
9339
9340 if (dynamic_syminfo_offset != 0 && syminsz != 0)
9341 {
2cf0635d
NC
9342 Elf_External_Syminfo * extsyminfo;
9343 Elf_External_Syminfo * extsym;
9344 Elf_Internal_Syminfo * syminfo;
252b5132
RH
9345
9346 /* There is a syminfo section. Read the data. */
3f5e193b
NC
9347 extsyminfo = (Elf_External_Syminfo *)
9348 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
9349 _("symbol information"));
a6e9f9df
AM
9350 if (!extsyminfo)
9351 return 0;
252b5132 9352
3f5e193b 9353 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
9354 if (dynamic_syminfo == NULL)
9355 {
8b73c356
NC
9356 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
9357 (unsigned long) syminsz);
252b5132
RH
9358 return 0;
9359 }
9360
9361 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
9362 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
9363 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
9364 ++syminfo, ++extsym)
252b5132 9365 {
86dba8ee
AM
9366 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
9367 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
9368 }
9369
9370 free (extsyminfo);
9371 }
9372 }
9373
9374 if (do_dynamic && dynamic_addr)
8b73c356
NC
9375 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
9376 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
9377 if (do_dynamic)
9378 printf (_(" Tag Type Name/Value\n"));
9379
86dba8ee
AM
9380 for (entry = dynamic_section;
9381 entry < dynamic_section + dynamic_nent;
9382 entry++)
252b5132
RH
9383 {
9384 if (do_dynamic)
f7a99963 9385 {
2cf0635d 9386 const char * dtype;
e699b9ff 9387
f7a99963
NC
9388 putchar (' ');
9389 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
9390 dtype = get_dynamic_type (entry->d_tag);
9391 printf (" (%s)%*s", dtype,
9392 ((is_32bit_elf ? 27 : 19)
9393 - (int) strlen (dtype)),
f7a99963
NC
9394 " ");
9395 }
252b5132
RH
9396
9397 switch (entry->d_tag)
9398 {
d1133906
NC
9399 case DT_FLAGS:
9400 if (do_dynamic)
e9e44622 9401 print_dynamic_flags (entry->d_un.d_val);
d1133906 9402 break;
76da6bbe 9403
252b5132
RH
9404 case DT_AUXILIARY:
9405 case DT_FILTER:
019148e4
L
9406 case DT_CONFIG:
9407 case DT_DEPAUDIT:
9408 case DT_AUDIT:
252b5132
RH
9409 if (do_dynamic)
9410 {
019148e4 9411 switch (entry->d_tag)
b34976b6 9412 {
019148e4
L
9413 case DT_AUXILIARY:
9414 printf (_("Auxiliary library"));
9415 break;
9416
9417 case DT_FILTER:
9418 printf (_("Filter library"));
9419 break;
9420
b34976b6 9421 case DT_CONFIG:
019148e4
L
9422 printf (_("Configuration file"));
9423 break;
9424
9425 case DT_DEPAUDIT:
9426 printf (_("Dependency audit library"));
9427 break;
9428
9429 case DT_AUDIT:
9430 printf (_("Audit library"));
9431 break;
9432 }
252b5132 9433
d79b3d50
NC
9434 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9435 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 9436 else
f7a99963
NC
9437 {
9438 printf (": ");
9439 print_vma (entry->d_un.d_val, PREFIX_HEX);
9440 putchar ('\n');
9441 }
252b5132
RH
9442 }
9443 break;
9444
dcefbbbd 9445 case DT_FEATURE:
252b5132
RH
9446 if (do_dynamic)
9447 {
9448 printf (_("Flags:"));
86f55779 9449
252b5132
RH
9450 if (entry->d_un.d_val == 0)
9451 printf (_(" None\n"));
9452 else
9453 {
9454 unsigned long int val = entry->d_un.d_val;
86f55779 9455
252b5132
RH
9456 if (val & DTF_1_PARINIT)
9457 {
9458 printf (" PARINIT");
9459 val ^= DTF_1_PARINIT;
9460 }
dcefbbbd
L
9461 if (val & DTF_1_CONFEXP)
9462 {
9463 printf (" CONFEXP");
9464 val ^= DTF_1_CONFEXP;
9465 }
252b5132
RH
9466 if (val != 0)
9467 printf (" %lx", val);
9468 puts ("");
9469 }
9470 }
9471 break;
9472
9473 case DT_POSFLAG_1:
9474 if (do_dynamic)
9475 {
9476 printf (_("Flags:"));
86f55779 9477
252b5132
RH
9478 if (entry->d_un.d_val == 0)
9479 printf (_(" None\n"));
9480 else
9481 {
9482 unsigned long int val = entry->d_un.d_val;
86f55779 9483
252b5132
RH
9484 if (val & DF_P1_LAZYLOAD)
9485 {
9486 printf (" LAZYLOAD");
9487 val ^= DF_P1_LAZYLOAD;
9488 }
9489 if (val & DF_P1_GROUPPERM)
9490 {
9491 printf (" GROUPPERM");
9492 val ^= DF_P1_GROUPPERM;
9493 }
9494 if (val != 0)
9495 printf (" %lx", val);
9496 puts ("");
9497 }
9498 }
9499 break;
9500
9501 case DT_FLAGS_1:
9502 if (do_dynamic)
9503 {
9504 printf (_("Flags:"));
9505 if (entry->d_un.d_val == 0)
9506 printf (_(" None\n"));
9507 else
9508 {
9509 unsigned long int val = entry->d_un.d_val;
86f55779 9510
252b5132
RH
9511 if (val & DF_1_NOW)
9512 {
9513 printf (" NOW");
9514 val ^= DF_1_NOW;
9515 }
9516 if (val & DF_1_GLOBAL)
9517 {
9518 printf (" GLOBAL");
9519 val ^= DF_1_GLOBAL;
9520 }
9521 if (val & DF_1_GROUP)
9522 {
9523 printf (" GROUP");
9524 val ^= DF_1_GROUP;
9525 }
9526 if (val & DF_1_NODELETE)
9527 {
9528 printf (" NODELETE");
9529 val ^= DF_1_NODELETE;
9530 }
9531 if (val & DF_1_LOADFLTR)
9532 {
9533 printf (" LOADFLTR");
9534 val ^= DF_1_LOADFLTR;
9535 }
9536 if (val & DF_1_INITFIRST)
9537 {
9538 printf (" INITFIRST");
9539 val ^= DF_1_INITFIRST;
9540 }
9541 if (val & DF_1_NOOPEN)
9542 {
9543 printf (" NOOPEN");
9544 val ^= DF_1_NOOPEN;
9545 }
9546 if (val & DF_1_ORIGIN)
9547 {
9548 printf (" ORIGIN");
9549 val ^= DF_1_ORIGIN;
9550 }
9551 if (val & DF_1_DIRECT)
9552 {
9553 printf (" DIRECT");
9554 val ^= DF_1_DIRECT;
9555 }
9556 if (val & DF_1_TRANS)
9557 {
9558 printf (" TRANS");
9559 val ^= DF_1_TRANS;
9560 }
9561 if (val & DF_1_INTERPOSE)
9562 {
9563 printf (" INTERPOSE");
9564 val ^= DF_1_INTERPOSE;
9565 }
f7db6139 9566 if (val & DF_1_NODEFLIB)
dcefbbbd 9567 {
f7db6139
L
9568 printf (" NODEFLIB");
9569 val ^= DF_1_NODEFLIB;
dcefbbbd
L
9570 }
9571 if (val & DF_1_NODUMP)
9572 {
9573 printf (" NODUMP");
9574 val ^= DF_1_NODUMP;
9575 }
34b60028 9576 if (val & DF_1_CONFALT)
dcefbbbd 9577 {
34b60028
L
9578 printf (" CONFALT");
9579 val ^= DF_1_CONFALT;
9580 }
9581 if (val & DF_1_ENDFILTEE)
9582 {
9583 printf (" ENDFILTEE");
9584 val ^= DF_1_ENDFILTEE;
9585 }
9586 if (val & DF_1_DISPRELDNE)
9587 {
9588 printf (" DISPRELDNE");
9589 val ^= DF_1_DISPRELDNE;
9590 }
9591 if (val & DF_1_DISPRELPND)
9592 {
9593 printf (" DISPRELPND");
9594 val ^= DF_1_DISPRELPND;
9595 }
9596 if (val & DF_1_NODIRECT)
9597 {
9598 printf (" NODIRECT");
9599 val ^= DF_1_NODIRECT;
9600 }
9601 if (val & DF_1_IGNMULDEF)
9602 {
9603 printf (" IGNMULDEF");
9604 val ^= DF_1_IGNMULDEF;
9605 }
9606 if (val & DF_1_NOKSYMS)
9607 {
9608 printf (" NOKSYMS");
9609 val ^= DF_1_NOKSYMS;
9610 }
9611 if (val & DF_1_NOHDR)
9612 {
9613 printf (" NOHDR");
9614 val ^= DF_1_NOHDR;
9615 }
9616 if (val & DF_1_EDITED)
9617 {
9618 printf (" EDITED");
9619 val ^= DF_1_EDITED;
9620 }
9621 if (val & DF_1_NORELOC)
9622 {
9623 printf (" NORELOC");
9624 val ^= DF_1_NORELOC;
9625 }
9626 if (val & DF_1_SYMINTPOSE)
9627 {
9628 printf (" SYMINTPOSE");
9629 val ^= DF_1_SYMINTPOSE;
9630 }
9631 if (val & DF_1_GLOBAUDIT)
9632 {
9633 printf (" GLOBAUDIT");
9634 val ^= DF_1_GLOBAUDIT;
9635 }
9636 if (val & DF_1_SINGLETON)
9637 {
9638 printf (" SINGLETON");
9639 val ^= DF_1_SINGLETON;
dcefbbbd 9640 }
5c383f02
RO
9641 if (val & DF_1_STUB)
9642 {
9643 printf (" STUB");
9644 val ^= DF_1_STUB;
9645 }
9646 if (val & DF_1_PIE)
9647 {
9648 printf (" PIE");
9649 val ^= DF_1_PIE;
9650 }
252b5132
RH
9651 if (val != 0)
9652 printf (" %lx", val);
9653 puts ("");
9654 }
9655 }
9656 break;
9657
9658 case DT_PLTREL:
566b0d53 9659 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
9660 if (do_dynamic)
9661 puts (get_dynamic_type (entry->d_un.d_val));
9662 break;
9663
9664 case DT_NULL :
9665 case DT_NEEDED :
9666 case DT_PLTGOT :
9667 case DT_HASH :
9668 case DT_STRTAB :
9669 case DT_SYMTAB :
9670 case DT_RELA :
9671 case DT_INIT :
9672 case DT_FINI :
9673 case DT_SONAME :
9674 case DT_RPATH :
9675 case DT_SYMBOLIC:
9676 case DT_REL :
9677 case DT_DEBUG :
9678 case DT_TEXTREL :
9679 case DT_JMPREL :
019148e4 9680 case DT_RUNPATH :
252b5132
RH
9681 dynamic_info[entry->d_tag] = entry->d_un.d_val;
9682
9683 if (do_dynamic)
9684 {
2cf0635d 9685 char * name;
252b5132 9686
d79b3d50
NC
9687 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9688 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9689 else
d79b3d50 9690 name = NULL;
252b5132
RH
9691
9692 if (name)
9693 {
9694 switch (entry->d_tag)
9695 {
9696 case DT_NEEDED:
9697 printf (_("Shared library: [%s]"), name);
9698
18bd398b 9699 if (streq (name, program_interpreter))
f7a99963 9700 printf (_(" program interpreter"));
252b5132
RH
9701 break;
9702
9703 case DT_SONAME:
f7a99963 9704 printf (_("Library soname: [%s]"), name);
252b5132
RH
9705 break;
9706
9707 case DT_RPATH:
f7a99963 9708 printf (_("Library rpath: [%s]"), name);
252b5132
RH
9709 break;
9710
019148e4
L
9711 case DT_RUNPATH:
9712 printf (_("Library runpath: [%s]"), name);
9713 break;
9714
252b5132 9715 default:
f7a99963
NC
9716 print_vma (entry->d_un.d_val, PREFIX_HEX);
9717 break;
252b5132
RH
9718 }
9719 }
9720 else
f7a99963
NC
9721 print_vma (entry->d_un.d_val, PREFIX_HEX);
9722
9723 putchar ('\n');
252b5132
RH
9724 }
9725 break;
9726
9727 case DT_PLTRELSZ:
9728 case DT_RELASZ :
9729 case DT_STRSZ :
9730 case DT_RELSZ :
9731 case DT_RELAENT :
9732 case DT_SYMENT :
9733 case DT_RELENT :
566b0d53 9734 dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 9735 /* Fall through. */
252b5132
RH
9736 case DT_PLTPADSZ:
9737 case DT_MOVEENT :
9738 case DT_MOVESZ :
9739 case DT_INIT_ARRAYSZ:
9740 case DT_FINI_ARRAYSZ:
047b2264
JJ
9741 case DT_GNU_CONFLICTSZ:
9742 case DT_GNU_LIBLISTSZ:
252b5132 9743 if (do_dynamic)
f7a99963
NC
9744 {
9745 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 9746 printf (_(" (bytes)\n"));
f7a99963 9747 }
252b5132
RH
9748 break;
9749
9750 case DT_VERDEFNUM:
9751 case DT_VERNEEDNUM:
9752 case DT_RELACOUNT:
9753 case DT_RELCOUNT:
9754 if (do_dynamic)
f7a99963
NC
9755 {
9756 print_vma (entry->d_un.d_val, UNSIGNED);
9757 putchar ('\n');
9758 }
252b5132
RH
9759 break;
9760
9761 case DT_SYMINSZ:
9762 case DT_SYMINENT:
9763 case DT_SYMINFO:
9764 case DT_USED:
9765 case DT_INIT_ARRAY:
9766 case DT_FINI_ARRAY:
9767 if (do_dynamic)
9768 {
d79b3d50
NC
9769 if (entry->d_tag == DT_USED
9770 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 9771 {
2cf0635d 9772 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9773
b34976b6 9774 if (*name)
252b5132
RH
9775 {
9776 printf (_("Not needed object: [%s]\n"), name);
9777 break;
9778 }
9779 }
103f02d3 9780
f7a99963
NC
9781 print_vma (entry->d_un.d_val, PREFIX_HEX);
9782 putchar ('\n');
252b5132
RH
9783 }
9784 break;
9785
9786 case DT_BIND_NOW:
9787 /* The value of this entry is ignored. */
35b1837e
AM
9788 if (do_dynamic)
9789 putchar ('\n');
252b5132 9790 break;
103f02d3 9791
047b2264
JJ
9792 case DT_GNU_PRELINKED:
9793 if (do_dynamic)
9794 {
2cf0635d 9795 struct tm * tmp;
91d6fa6a 9796 time_t atime = entry->d_un.d_val;
047b2264 9797
91d6fa6a 9798 tmp = gmtime (&atime);
071436c6
NC
9799 /* PR 17533 file: 041-1244816-0.004. */
9800 if (tmp == NULL)
5a2cbcf4
L
9801 printf (_("<corrupt time val: %lx"),
9802 (unsigned long) atime);
071436c6
NC
9803 else
9804 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
9805 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9806 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
9807
9808 }
9809 break;
9810
fdc90cb4
JJ
9811 case DT_GNU_HASH:
9812 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
9813 if (do_dynamic)
9814 {
9815 print_vma (entry->d_un.d_val, PREFIX_HEX);
9816 putchar ('\n');
9817 }
9818 break;
9819
252b5132
RH
9820 default:
9821 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 9822 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
9823 entry->d_un.d_val;
9824
9825 if (do_dynamic)
9826 {
9827 switch (elf_header.e_machine)
9828 {
9829 case EM_MIPS:
4fe85591 9830 case EM_MIPS_RS3_LE:
b2d38a17 9831 dynamic_section_mips_val (entry);
252b5132 9832 break;
103f02d3 9833 case EM_PARISC:
b2d38a17 9834 dynamic_section_parisc_val (entry);
103f02d3 9835 break;
ecc51f48 9836 case EM_IA_64:
b2d38a17 9837 dynamic_section_ia64_val (entry);
ecc51f48 9838 break;
252b5132 9839 default:
f7a99963
NC
9840 print_vma (entry->d_un.d_val, PREFIX_HEX);
9841 putchar ('\n');
252b5132
RH
9842 }
9843 }
9844 break;
9845 }
9846 }
9847
9848 return 1;
9849}
9850
9851static char *
d3ba0551 9852get_ver_flags (unsigned int flags)
252b5132 9853{
b34976b6 9854 static char buff[32];
252b5132
RH
9855
9856 buff[0] = 0;
9857
9858 if (flags == 0)
9859 return _("none");
9860
9861 if (flags & VER_FLG_BASE)
9862 strcat (buff, "BASE ");
9863
9864 if (flags & VER_FLG_WEAK)
9865 {
9866 if (flags & VER_FLG_BASE)
9867 strcat (buff, "| ");
9868
9869 strcat (buff, "WEAK ");
9870 }
9871
44ec90b9
RO
9872 if (flags & VER_FLG_INFO)
9873 {
9874 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
9875 strcat (buff, "| ");
9876
9877 strcat (buff, "INFO ");
9878 }
9879
9880 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 9881 strcat (buff, _("| <unknown>"));
252b5132
RH
9882
9883 return buff;
9884}
9885
9886/* Display the contents of the version sections. */
98fb390a 9887
252b5132 9888static int
2cf0635d 9889process_version_sections (FILE * file)
252b5132 9890{
2cf0635d 9891 Elf_Internal_Shdr * section;
b34976b6
AM
9892 unsigned i;
9893 int found = 0;
252b5132
RH
9894
9895 if (! do_version)
9896 return 1;
9897
9898 for (i = 0, section = section_headers;
9899 i < elf_header.e_shnum;
b34976b6 9900 i++, section++)
252b5132
RH
9901 {
9902 switch (section->sh_type)
9903 {
9904 case SHT_GNU_verdef:
9905 {
2cf0635d 9906 Elf_External_Verdef * edefs;
b34976b6
AM
9907 unsigned int idx;
9908 unsigned int cnt;
2cf0635d 9909 char * endbuf;
252b5132
RH
9910
9911 found = 1;
9912
74e1a04b
NC
9913 printf (_("\nVersion definition section '%s' contains %u entries:\n"),
9914 printable_section_name (section),
9915 section->sh_info);
252b5132
RH
9916
9917 printf (_(" Addr: 0x"));
9918 printf_vma (section->sh_addr);
74e1a04b 9919 printf (_(" Offset: %#08lx Link: %u (%s)"),
1b228002 9920 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9921 printable_section_name_from_index (section->sh_link));
252b5132 9922
3f5e193b
NC
9923 edefs = (Elf_External_Verdef *)
9924 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
9925 _("version definition section"));
a6e9f9df
AM
9926 if (!edefs)
9927 break;
59245841 9928 endbuf = (char *) edefs + section->sh_size;
252b5132 9929
b34976b6 9930 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 9931 {
2cf0635d
NC
9932 char * vstart;
9933 Elf_External_Verdef * edef;
b34976b6 9934 Elf_Internal_Verdef ent;
2cf0635d 9935 Elf_External_Verdaux * eaux;
b34976b6
AM
9936 Elf_Internal_Verdaux aux;
9937 int j;
9938 int isum;
103f02d3 9939
7e26601c
NC
9940 /* Check for very large indicies. */
9941 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
9942 break;
9943
252b5132 9944 vstart = ((char *) edefs) + idx;
54806181
AM
9945 if (vstart + sizeof (*edef) > endbuf)
9946 break;
252b5132
RH
9947
9948 edef = (Elf_External_Verdef *) vstart;
9949
9950 ent.vd_version = BYTE_GET (edef->vd_version);
9951 ent.vd_flags = BYTE_GET (edef->vd_flags);
9952 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
9953 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
9954 ent.vd_hash = BYTE_GET (edef->vd_hash);
9955 ent.vd_aux = BYTE_GET (edef->vd_aux);
9956 ent.vd_next = BYTE_GET (edef->vd_next);
9957
9958 printf (_(" %#06x: Rev: %d Flags: %s"),
9959 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
9960
9961 printf (_(" Index: %d Cnt: %d "),
9962 ent.vd_ndx, ent.vd_cnt);
9963
dd24e3da 9964 /* Check for overflow. */
7e26601c 9965 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
9966 break;
9967
252b5132
RH
9968 vstart += ent.vd_aux;
9969
9970 eaux = (Elf_External_Verdaux *) vstart;
9971
9972 aux.vda_name = BYTE_GET (eaux->vda_name);
9973 aux.vda_next = BYTE_GET (eaux->vda_next);
9974
d79b3d50
NC
9975 if (VALID_DYNAMIC_NAME (aux.vda_name))
9976 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9977 else
9978 printf (_("Name index: %ld\n"), aux.vda_name);
9979
9980 isum = idx + ent.vd_aux;
9981
b34976b6 9982 for (j = 1; j < ent.vd_cnt; j++)
252b5132 9983 {
dd24e3da 9984 /* Check for overflow. */
7e26601c 9985 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
9986 break;
9987
252b5132
RH
9988 isum += aux.vda_next;
9989 vstart += aux.vda_next;
9990
9991 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
9992 if (vstart + sizeof (*eaux) > endbuf)
9993 break;
252b5132
RH
9994
9995 aux.vda_name = BYTE_GET (eaux->vda_name);
9996 aux.vda_next = BYTE_GET (eaux->vda_next);
9997
d79b3d50 9998 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 9999 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 10000 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
10001 else
10002 printf (_(" %#06x: Parent %d, name index: %ld\n"),
10003 isum, j, aux.vda_name);
10004 }
dd24e3da 10005
54806181
AM
10006 if (j < ent.vd_cnt)
10007 printf (_(" Version def aux past end of section\n"));
252b5132 10008
5d921cbd
NC
10009 /* PR 17531: file: id:000001,src:000172+005151,op:splice,rep:2. */
10010 if (idx + ent.vd_next <= idx)
10011 break;
10012
252b5132
RH
10013 idx += ent.vd_next;
10014 }
dd24e3da 10015
54806181
AM
10016 if (cnt < section->sh_info)
10017 printf (_(" Version definition past end of section\n"));
252b5132
RH
10018
10019 free (edefs);
10020 }
10021 break;
103f02d3 10022
252b5132
RH
10023 case SHT_GNU_verneed:
10024 {
2cf0635d 10025 Elf_External_Verneed * eneed;
b34976b6
AM
10026 unsigned int idx;
10027 unsigned int cnt;
2cf0635d 10028 char * endbuf;
252b5132
RH
10029
10030 found = 1;
10031
72de5009 10032 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
74e1a04b 10033 printable_section_name (section), section->sh_info);
252b5132
RH
10034
10035 printf (_(" Addr: 0x"));
10036 printf_vma (section->sh_addr);
72de5009 10037 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10038 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 10039 printable_section_name_from_index (section->sh_link));
252b5132 10040
3f5e193b
NC
10041 eneed = (Elf_External_Verneed *) get_data (NULL, file,
10042 section->sh_offset, 1,
10043 section->sh_size,
9cf03b7e 10044 _("Version Needs section"));
a6e9f9df
AM
10045 if (!eneed)
10046 break;
59245841 10047 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
10048
10049 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
10050 {
2cf0635d 10051 Elf_External_Verneed * entry;
b34976b6
AM
10052 Elf_Internal_Verneed ent;
10053 int j;
10054 int isum;
2cf0635d 10055 char * vstart;
252b5132 10056
7e26601c 10057 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
10058 break;
10059
252b5132 10060 vstart = ((char *) eneed) + idx;
54806181
AM
10061 if (vstart + sizeof (*entry) > endbuf)
10062 break;
252b5132
RH
10063
10064 entry = (Elf_External_Verneed *) vstart;
10065
10066 ent.vn_version = BYTE_GET (entry->vn_version);
10067 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
10068 ent.vn_file = BYTE_GET (entry->vn_file);
10069 ent.vn_aux = BYTE_GET (entry->vn_aux);
10070 ent.vn_next = BYTE_GET (entry->vn_next);
10071
10072 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
10073
d79b3d50
NC
10074 if (VALID_DYNAMIC_NAME (ent.vn_file))
10075 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
10076 else
10077 printf (_(" File: %lx"), ent.vn_file);
10078
10079 printf (_(" Cnt: %d\n"), ent.vn_cnt);
10080
dd24e3da 10081 /* Check for overflow. */
7e26601c 10082 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 10083 break;
252b5132
RH
10084 vstart += ent.vn_aux;
10085
10086 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
10087 {
2cf0635d 10088 Elf_External_Vernaux * eaux;
b34976b6 10089 Elf_Internal_Vernaux aux;
252b5132 10090
54806181
AM
10091 if (vstart + sizeof (*eaux) > endbuf)
10092 break;
252b5132
RH
10093 eaux = (Elf_External_Vernaux *) vstart;
10094
10095 aux.vna_hash = BYTE_GET (eaux->vna_hash);
10096 aux.vna_flags = BYTE_GET (eaux->vna_flags);
10097 aux.vna_other = BYTE_GET (eaux->vna_other);
10098 aux.vna_name = BYTE_GET (eaux->vna_name);
10099 aux.vna_next = BYTE_GET (eaux->vna_next);
10100
d79b3d50 10101 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 10102 printf (_(" %#06x: Name: %s"),
d79b3d50 10103 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 10104 else
ecc2063b 10105 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
10106 isum, aux.vna_name);
10107
10108 printf (_(" Flags: %s Version: %d\n"),
10109 get_ver_flags (aux.vna_flags), aux.vna_other);
10110
dd24e3da 10111 /* Check for overflow. */
53774b7e
NC
10112 if (aux.vna_next > (size_t) (endbuf - vstart)
10113 || (aux.vna_next == 0 && j < ent.vn_cnt - 1))
10114 {
10115 warn (_("Invalid vna_next field of %lx\n"),
10116 aux.vna_next);
10117 j = ent.vn_cnt;
10118 break;
10119 }
252b5132
RH
10120 isum += aux.vna_next;
10121 vstart += aux.vna_next;
10122 }
9cf03b7e 10123
54806181 10124 if (j < ent.vn_cnt)
9cf03b7e 10125 warn (_("Missing Version Needs auxillary information\n"));
252b5132 10126
bcf83b2a 10127 if (ent.vn_next == 0 && cnt < section->sh_info - 1)
c24cf8b6
NC
10128 {
10129 warn (_("Corrupt Version Needs structure - offset to next structure is zero with entries still left to be processed\n"));
10130 cnt = section->sh_info;
10131 break;
10132 }
252b5132
RH
10133 idx += ent.vn_next;
10134 }
9cf03b7e 10135
54806181 10136 if (cnt < section->sh_info)
9cf03b7e 10137 warn (_("Missing Version Needs information\n"));
103f02d3 10138
252b5132
RH
10139 free (eneed);
10140 }
10141 break;
10142
10143 case SHT_GNU_versym:
10144 {
2cf0635d 10145 Elf_Internal_Shdr * link_section;
8b73c356
NC
10146 size_t total;
10147 unsigned int cnt;
2cf0635d
NC
10148 unsigned char * edata;
10149 unsigned short * data;
10150 char * strtab;
10151 Elf_Internal_Sym * symbols;
10152 Elf_Internal_Shdr * string_sec;
ba5cdace 10153 unsigned long num_syms;
d3ba0551 10154 long off;
252b5132 10155
4fbb74a6 10156 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
10157 break;
10158
4fbb74a6 10159 link_section = section_headers + section->sh_link;
08d8fa11 10160 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 10161
4fbb74a6 10162 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
10163 break;
10164
252b5132
RH
10165 found = 1;
10166
ba5cdace 10167 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
10168 if (symbols == NULL)
10169 break;
252b5132 10170
4fbb74a6 10171 string_sec = section_headers + link_section->sh_link;
252b5132 10172
3f5e193b
NC
10173 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
10174 string_sec->sh_size,
10175 _("version string table"));
a6e9f9df 10176 if (!strtab)
0429c154
MS
10177 {
10178 free (symbols);
10179 break;
10180 }
252b5132 10181
8b73c356
NC
10182 printf (_("\nVersion symbols section '%s' contains %lu entries:\n"),
10183 printable_section_name (section), (unsigned long) total);
252b5132
RH
10184
10185 printf (_(" Addr: "));
10186 printf_vma (section->sh_addr);
72de5009 10187 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10188 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 10189 printable_section_name (link_section));
252b5132 10190
d3ba0551
AM
10191 off = offset_from_vma (file,
10192 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10193 total * sizeof (short));
3f5e193b
NC
10194 edata = (unsigned char *) get_data (NULL, file, off, total,
10195 sizeof (short),
10196 _("version symbol data"));
a6e9f9df
AM
10197 if (!edata)
10198 {
10199 free (strtab);
0429c154 10200 free (symbols);
a6e9f9df
AM
10201 break;
10202 }
252b5132 10203
3f5e193b 10204 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
10205
10206 for (cnt = total; cnt --;)
b34976b6
AM
10207 data[cnt] = byte_get (edata + cnt * sizeof (short),
10208 sizeof (short));
252b5132
RH
10209
10210 free (edata);
10211
10212 for (cnt = 0; cnt < total; cnt += 4)
10213 {
10214 int j, nn;
ab273396
AM
10215 char *name;
10216 char *invalid = _("*invalid*");
252b5132
RH
10217
10218 printf (" %03x:", cnt);
10219
10220 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 10221 switch (data[cnt + j])
252b5132
RH
10222 {
10223 case 0:
10224 fputs (_(" 0 (*local*) "), stdout);
10225 break;
10226
10227 case 1:
10228 fputs (_(" 1 (*global*) "), stdout);
10229 break;
10230
10231 default:
c244d050
NC
10232 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
10233 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 10234
dd24e3da 10235 /* If this index value is greater than the size of the symbols
ba5cdace
NC
10236 array, break to avoid an out-of-bounds read. */
10237 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
10238 {
10239 warn (_("invalid index into symbol array\n"));
10240 break;
10241 }
10242
ab273396
AM
10243 name = NULL;
10244 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 10245 {
b34976b6
AM
10246 Elf_Internal_Verneed ivn;
10247 unsigned long offset;
252b5132 10248
d93f0186
NC
10249 offset = offset_from_vma
10250 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
10251 sizeof (Elf_External_Verneed));
252b5132 10252
b34976b6 10253 do
252b5132 10254 {
b34976b6
AM
10255 Elf_Internal_Vernaux ivna;
10256 Elf_External_Verneed evn;
10257 Elf_External_Vernaux evna;
10258 unsigned long a_off;
252b5132 10259
59245841
NC
10260 if (get_data (&evn, file, offset, sizeof (evn), 1,
10261 _("version need")) == NULL)
10262 break;
0b4362b0 10263
252b5132
RH
10264 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10265 ivn.vn_next = BYTE_GET (evn.vn_next);
10266
10267 a_off = offset + ivn.vn_aux;
10268
10269 do
10270 {
59245841
NC
10271 if (get_data (&evna, file, a_off, sizeof (evna),
10272 1, _("version need aux (2)")) == NULL)
10273 {
10274 ivna.vna_next = 0;
10275 ivna.vna_other = 0;
10276 }
10277 else
10278 {
10279 ivna.vna_next = BYTE_GET (evna.vna_next);
10280 ivna.vna_other = BYTE_GET (evna.vna_other);
10281 }
252b5132
RH
10282
10283 a_off += ivna.vna_next;
10284 }
b34976b6 10285 while (ivna.vna_other != data[cnt + j]
252b5132
RH
10286 && ivna.vna_next != 0);
10287
b34976b6 10288 if (ivna.vna_other == data[cnt + j])
252b5132
RH
10289 {
10290 ivna.vna_name = BYTE_GET (evna.vna_name);
10291
54806181 10292 if (ivna.vna_name >= string_sec->sh_size)
ab273396 10293 name = invalid;
54806181
AM
10294 else
10295 name = strtab + ivna.vna_name;
252b5132
RH
10296 break;
10297 }
10298
10299 offset += ivn.vn_next;
10300 }
10301 while (ivn.vn_next);
10302 }
00d93f34 10303
ab273396 10304 if (data[cnt + j] != 0x8001
b34976b6 10305 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 10306 {
b34976b6
AM
10307 Elf_Internal_Verdef ivd;
10308 Elf_External_Verdef evd;
10309 unsigned long offset;
252b5132 10310
d93f0186
NC
10311 offset = offset_from_vma
10312 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10313 sizeof evd);
252b5132
RH
10314
10315 do
10316 {
59245841
NC
10317 if (get_data (&evd, file, offset, sizeof (evd), 1,
10318 _("version def")) == NULL)
10319 {
10320 ivd.vd_next = 0;
948f632f 10321 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
10322 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
10323 break;
59245841
NC
10324 }
10325 else
10326 {
10327 ivd.vd_next = BYTE_GET (evd.vd_next);
10328 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10329 }
252b5132
RH
10330
10331 offset += ivd.vd_next;
10332 }
c244d050 10333 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
10334 && ivd.vd_next != 0);
10335
c244d050 10336 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 10337 {
b34976b6
AM
10338 Elf_External_Verdaux evda;
10339 Elf_Internal_Verdaux ivda;
252b5132
RH
10340
10341 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10342
59245841
NC
10343 if (get_data (&evda, file,
10344 offset - ivd.vd_next + ivd.vd_aux,
10345 sizeof (evda), 1,
10346 _("version def aux")) == NULL)
10347 break;
252b5132
RH
10348
10349 ivda.vda_name = BYTE_GET (evda.vda_name);
10350
54806181 10351 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
10352 name = invalid;
10353 else if (name != NULL && name != invalid)
10354 name = _("*both*");
54806181
AM
10355 else
10356 name = strtab + ivda.vda_name;
252b5132
RH
10357 }
10358 }
ab273396
AM
10359 if (name != NULL)
10360 nn += printf ("(%s%-*s",
10361 name,
10362 12 - (int) strlen (name),
10363 ")");
252b5132
RH
10364
10365 if (nn < 18)
10366 printf ("%*c", 18 - nn, ' ');
10367 }
10368
10369 putchar ('\n');
10370 }
10371
10372 free (data);
10373 free (strtab);
10374 free (symbols);
10375 }
10376 break;
103f02d3 10377
252b5132
RH
10378 default:
10379 break;
10380 }
10381 }
10382
10383 if (! found)
10384 printf (_("\nNo version information found in this file.\n"));
10385
10386 return 1;
10387}
10388
d1133906 10389static const char *
d3ba0551 10390get_symbol_binding (unsigned int binding)
252b5132 10391{
b34976b6 10392 static char buff[32];
252b5132
RH
10393
10394 switch (binding)
10395 {
b34976b6
AM
10396 case STB_LOCAL: return "LOCAL";
10397 case STB_GLOBAL: return "GLOBAL";
10398 case STB_WEAK: return "WEAK";
252b5132
RH
10399 default:
10400 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
10401 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
10402 binding);
252b5132 10403 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
10404 {
10405 if (binding == STB_GNU_UNIQUE
9c55345c
TS
10406 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
10407 /* GNU is still using the default value 0. */
3e7a7d11
NC
10408 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
10409 return "UNIQUE";
10410 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
10411 }
252b5132 10412 else
e9e44622 10413 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
10414 return buff;
10415 }
10416}
10417
d1133906 10418static const char *
d3ba0551 10419get_symbol_type (unsigned int type)
252b5132 10420{
b34976b6 10421 static char buff[32];
252b5132
RH
10422
10423 switch (type)
10424 {
b34976b6
AM
10425 case STT_NOTYPE: return "NOTYPE";
10426 case STT_OBJECT: return "OBJECT";
10427 case STT_FUNC: return "FUNC";
10428 case STT_SECTION: return "SECTION";
10429 case STT_FILE: return "FILE";
10430 case STT_COMMON: return "COMMON";
10431 case STT_TLS: return "TLS";
15ab5209
DB
10432 case STT_RELC: return "RELC";
10433 case STT_SRELC: return "SRELC";
252b5132
RH
10434 default:
10435 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 10436 {
3510a7b8
NC
10437 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
10438 return "THUMB_FUNC";
103f02d3 10439
351b4b40 10440 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
10441 return "REGISTER";
10442
10443 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
10444 return "PARISC_MILLI";
10445
e9e44622 10446 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 10447 }
252b5132 10448 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
10449 {
10450 if (elf_header.e_machine == EM_PARISC)
10451 {
10452 if (type == STT_HP_OPAQUE)
10453 return "HP_OPAQUE";
10454 if (type == STT_HP_STUB)
10455 return "HP_STUB";
10456 }
10457
d8045f23 10458 if (type == STT_GNU_IFUNC
9c55345c 10459 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 10460 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 10461 /* GNU is still using the default value 0. */
d8045f23
NC
10462 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
10463 return "IFUNC";
10464
e9e44622 10465 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 10466 }
252b5132 10467 else
e9e44622 10468 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
10469 return buff;
10470 }
10471}
10472
d1133906 10473static const char *
d3ba0551 10474get_symbol_visibility (unsigned int visibility)
d1133906
NC
10475{
10476 switch (visibility)
10477 {
b34976b6
AM
10478 case STV_DEFAULT: return "DEFAULT";
10479 case STV_INTERNAL: return "INTERNAL";
10480 case STV_HIDDEN: return "HIDDEN";
d1133906 10481 case STV_PROTECTED: return "PROTECTED";
bee0ee85
NC
10482 default:
10483 error (_("Unrecognized visibility value: %u"), visibility);
10484 return _("<unknown>");
d1133906
NC
10485 }
10486}
10487
fd85a6a1
NC
10488static const char *
10489get_solaris_symbol_visibility (unsigned int visibility)
10490{
10491 switch (visibility)
10492 {
10493 case 4: return "EXPORTED";
10494 case 5: return "SINGLETON";
10495 case 6: return "ELIMINATE";
10496 default: return get_symbol_visibility (visibility);
10497 }
10498}
10499
5e2b0d47
NC
10500static const char *
10501get_mips_symbol_other (unsigned int other)
10502{
10503 switch (other)
10504 {
df58fc94
RS
10505 case STO_OPTIONAL:
10506 return "OPTIONAL";
10507 case STO_MIPS_PLT:
10508 return "MIPS PLT";
10509 case STO_MIPS_PIC:
10510 return "MIPS PIC";
10511 case STO_MICROMIPS:
10512 return "MICROMIPS";
10513 case STO_MICROMIPS | STO_MIPS_PIC:
10514 return "MICROMIPS, MIPS PIC";
10515 case STO_MIPS16:
10516 return "MIPS16";
10517 default:
10518 return NULL;
5e2b0d47
NC
10519 }
10520}
10521
28f997cf
TG
10522static const char *
10523get_ia64_symbol_other (unsigned int other)
10524{
10525 if (is_ia64_vms ())
10526 {
10527 static char res[32];
10528
10529 res[0] = 0;
10530
10531 /* Function types is for images and .STB files only. */
10532 switch (elf_header.e_type)
10533 {
10534 case ET_DYN:
10535 case ET_EXEC:
10536 switch (VMS_ST_FUNC_TYPE (other))
10537 {
10538 case VMS_SFT_CODE_ADDR:
10539 strcat (res, " CA");
10540 break;
10541 case VMS_SFT_SYMV_IDX:
10542 strcat (res, " VEC");
10543 break;
10544 case VMS_SFT_FD:
10545 strcat (res, " FD");
10546 break;
10547 case VMS_SFT_RESERVE:
10548 strcat (res, " RSV");
10549 break;
10550 default:
bee0ee85
NC
10551 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
10552 VMS_ST_FUNC_TYPE (other));
10553 strcat (res, " <unknown>");
10554 break;
28f997cf
TG
10555 }
10556 break;
10557 default:
10558 break;
10559 }
10560 switch (VMS_ST_LINKAGE (other))
10561 {
10562 case VMS_STL_IGNORE:
10563 strcat (res, " IGN");
10564 break;
10565 case VMS_STL_RESERVE:
10566 strcat (res, " RSV");
10567 break;
10568 case VMS_STL_STD:
10569 strcat (res, " STD");
10570 break;
10571 case VMS_STL_LNK:
10572 strcat (res, " LNK");
10573 break;
10574 default:
bee0ee85
NC
10575 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
10576 VMS_ST_LINKAGE (other));
10577 strcat (res, " <unknown>");
10578 break;
28f997cf
TG
10579 }
10580
10581 if (res[0] != 0)
10582 return res + 1;
10583 else
10584 return res;
10585 }
10586 return NULL;
10587}
10588
6911b7dc
AM
10589static const char *
10590get_ppc64_symbol_other (unsigned int other)
10591{
10592 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
10593 {
10594 static char buf[32];
10595 snprintf (buf, sizeof buf, _("<localentry>: %d"),
10596 PPC64_LOCAL_ENTRY_OFFSET (other));
10597 return buf;
10598 }
10599 return NULL;
10600}
10601
5e2b0d47
NC
10602static const char *
10603get_symbol_other (unsigned int other)
10604{
10605 const char * result = NULL;
10606 static char buff [32];
10607
10608 if (other == 0)
10609 return "";
10610
10611 switch (elf_header.e_machine)
10612 {
10613 case EM_MIPS:
10614 result = get_mips_symbol_other (other);
28f997cf
TG
10615 break;
10616 case EM_IA_64:
10617 result = get_ia64_symbol_other (other);
10618 break;
6911b7dc
AM
10619 case EM_PPC64:
10620 result = get_ppc64_symbol_other (other);
10621 break;
5e2b0d47 10622 default:
fd85a6a1 10623 result = NULL;
5e2b0d47
NC
10624 break;
10625 }
10626
10627 if (result)
10628 return result;
10629
10630 snprintf (buff, sizeof buff, _("<other>: %x"), other);
10631 return buff;
10632}
10633
d1133906 10634static const char *
d3ba0551 10635get_symbol_index_type (unsigned int type)
252b5132 10636{
b34976b6 10637 static char buff[32];
5cf1065c 10638
252b5132
RH
10639 switch (type)
10640 {
b34976b6
AM
10641 case SHN_UNDEF: return "UND";
10642 case SHN_ABS: return "ABS";
10643 case SHN_COMMON: return "COM";
252b5132 10644 default:
9ce701e2
L
10645 if (type == SHN_IA_64_ANSI_COMMON
10646 && elf_header.e_machine == EM_IA_64
10647 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
10648 return "ANSI_COM";
8a9036a4 10649 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
10650 || elf_header.e_machine == EM_L1OM
10651 || elf_header.e_machine == EM_K1OM)
3b22753a
L
10652 && type == SHN_X86_64_LCOMMON)
10653 return "LARGE_COM";
ac145307
BS
10654 else if ((type == SHN_MIPS_SCOMMON
10655 && elf_header.e_machine == EM_MIPS)
10656 || (type == SHN_TIC6X_SCOMMON
10657 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
10658 return "SCOM";
10659 else if (type == SHN_MIPS_SUNDEFINED
10660 && elf_header.e_machine == EM_MIPS)
10661 return "SUND";
9ce701e2 10662 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 10663 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 10664 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
10665 sprintf (buff, "OS [0x%04x]", type & 0xffff);
10666 else if (type >= SHN_LORESERVE)
10667 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4 10668 else if (type >= elf_header.e_shnum)
e0a31db1 10669 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 10670 else
232e7cb8 10671 sprintf (buff, "%3d", type);
5cf1065c 10672 break;
252b5132 10673 }
5cf1065c
NC
10674
10675 return buff;
252b5132
RH
10676}
10677
66543521 10678static bfd_vma *
57028622 10679get_dynamic_data (FILE * file, bfd_size_type number, unsigned int ent_size)
252b5132 10680{
2cf0635d
NC
10681 unsigned char * e_data;
10682 bfd_vma * i_data;
252b5132 10683
57028622
NC
10684 /* If the size_t type is smaller than the bfd_size_type, eg because
10685 you are building a 32-bit tool on a 64-bit host, then make sure
10686 that when (number) is cast to (size_t) no information is lost. */
10687 if (sizeof (size_t) < sizeof (bfd_size_type)
10688 && (bfd_size_type) ((size_t) number) != number)
10689 {
ed754a13
AM
10690 error (_("Size truncation prevents reading %" BFD_VMA_FMT "u"
10691 " elements of size %u\n"),
10692 number, ent_size);
57028622
NC
10693 return NULL;
10694 }
948f632f 10695
3102e897
NC
10696 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
10697 attempting to allocate memory when the read is bound to fail. */
10698 if (ent_size * number > current_file_size)
10699 {
ed754a13
AM
10700 error (_("Invalid number of dynamic entries: %" BFD_VMA_FMT "u\n"),
10701 number);
3102e897
NC
10702 return NULL;
10703 }
10704
57028622 10705 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
252b5132
RH
10706 if (e_data == NULL)
10707 {
ed754a13
AM
10708 error (_("Out of memory reading %" BFD_VMA_FMT "u dynamic entries\n"),
10709 number);
252b5132
RH
10710 return NULL;
10711 }
10712
57028622 10713 if (fread (e_data, ent_size, (size_t) number, file) != number)
252b5132 10714 {
ed754a13
AM
10715 error (_("Unable to read in %" BFD_VMA_FMT "u bytes of dynamic data\n"),
10716 number * ent_size);
3102e897 10717 free (e_data);
252b5132
RH
10718 return NULL;
10719 }
10720
57028622 10721 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
252b5132
RH
10722 if (i_data == NULL)
10723 {
ed754a13
AM
10724 error (_("Out of memory allocating space for %" BFD_VMA_FMT "u"
10725 " dynamic entries\n"),
10726 number);
252b5132
RH
10727 free (e_data);
10728 return NULL;
10729 }
10730
10731 while (number--)
66543521 10732 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
10733
10734 free (e_data);
10735
10736 return i_data;
10737}
10738
6bd1a22c
L
10739static void
10740print_dynamic_symbol (bfd_vma si, unsigned long hn)
10741{
2cf0635d 10742 Elf_Internal_Sym * psym;
6bd1a22c
L
10743 int n;
10744
6bd1a22c
L
10745 n = print_vma (si, DEC_5);
10746 if (n < 5)
0b4362b0 10747 fputs (&" "[n], stdout);
6bd1a22c 10748 printf (" %3lu: ", hn);
e0a31db1
NC
10749
10750 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
10751 {
3102e897
NC
10752 printf (_("<No info available for dynamic symbol number %lu>\n"),
10753 (unsigned long) si);
e0a31db1
NC
10754 return;
10755 }
10756
10757 psym = dynamic_symbols + si;
6bd1a22c
L
10758 print_vma (psym->st_value, LONG_HEX);
10759 putchar (' ');
10760 print_vma (psym->st_size, DEC_5);
10761
f4be36b3
AM
10762 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10763 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
fd85a6a1
NC
10764
10765 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
10766 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
10767 else
10768 {
10769 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
10770
10771 printf (" %-7s", get_symbol_visibility (vis));
10772 /* Check to see if any other bits in the st_other field are set.
10773 Note - displaying this information disrupts the layout of the
10774 table being generated, but for the moment this case is very
10775 rare. */
10776 if (psym->st_other ^ vis)
10777 printf (" [%s] ", get_symbol_other (psym->st_other ^ vis));
10778 }
10779
6bd1a22c
L
10780 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
10781 if (VALID_DYNAMIC_NAME (psym->st_name))
10782 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
10783 else
2b692964 10784 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
10785 putchar ('\n');
10786}
10787
bb4d2ac2 10788static const char *
1449284b
NC
10789get_symbol_version_string (FILE * file,
10790 bfd_boolean is_dynsym,
10791 const char * strtab,
10792 unsigned long int strtab_size,
10793 unsigned int si,
10794 Elf_Internal_Sym * psym,
10795 enum versioned_symbol_info * sym_info,
10796 unsigned short * vna_other)
bb4d2ac2 10797{
ab273396
AM
10798 unsigned char data[2];
10799 unsigned short vers_data;
10800 unsigned long offset;
bb4d2ac2 10801
ab273396
AM
10802 if (!is_dynsym
10803 || version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
10804 return NULL;
bb4d2ac2 10805
ab273396
AM
10806 offset = offset_from_vma (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10807 sizeof data + si * sizeof (vers_data));
bb4d2ac2 10808
ab273396
AM
10809 if (get_data (&data, file, offset + si * sizeof (vers_data),
10810 sizeof (data), 1, _("version data")) == NULL)
10811 return NULL;
10812
10813 vers_data = byte_get (data, 2);
bb4d2ac2 10814
ab273396
AM
10815 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data <= 1)
10816 return NULL;
bb4d2ac2 10817
ab273396
AM
10818 /* Usually we'd only see verdef for defined symbols, and verneed for
10819 undefined symbols. However, symbols defined by the linker in
10820 .dynbss for variables copied from a shared library in order to
10821 avoid text relocations are defined yet have verneed. We could
10822 use a heuristic to detect the special case, for example, check
10823 for verneed first on symbols defined in SHT_NOBITS sections, but
10824 it is simpler and more reliable to just look for both verdef and
10825 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 10826
ab273396
AM
10827 if (psym->st_shndx != SHN_UNDEF
10828 && vers_data != 0x8001
10829 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
10830 {
10831 Elf_Internal_Verdef ivd;
10832 Elf_Internal_Verdaux ivda;
10833 Elf_External_Verdaux evda;
10834 unsigned long off;
bb4d2ac2 10835
ab273396
AM
10836 off = offset_from_vma (file,
10837 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10838 sizeof (Elf_External_Verdef));
10839
10840 do
bb4d2ac2 10841 {
ab273396
AM
10842 Elf_External_Verdef evd;
10843
10844 if (get_data (&evd, file, off, sizeof (evd), 1,
10845 _("version def")) == NULL)
10846 {
10847 ivd.vd_ndx = 0;
10848 ivd.vd_aux = 0;
10849 ivd.vd_next = 0;
10850 }
10851 else
bb4d2ac2 10852 {
ab273396
AM
10853 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10854 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10855 ivd.vd_next = BYTE_GET (evd.vd_next);
10856 }
bb4d2ac2 10857
ab273396
AM
10858 off += ivd.vd_next;
10859 }
10860 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 10861
ab273396
AM
10862 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
10863 {
10864 off -= ivd.vd_next;
10865 off += ivd.vd_aux;
bb4d2ac2 10866
ab273396
AM
10867 if (get_data (&evda, file, off, sizeof (evda), 1,
10868 _("version def aux")) != NULL)
10869 {
10870 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 10871
ab273396
AM
10872 if (psym->st_name != ivda.vda_name)
10873 {
10874 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
10875 ? symbol_hidden : symbol_public);
10876 return (ivda.vda_name < strtab_size
10877 ? strtab + ivda.vda_name : _("<corrupt>"));
10878 }
10879 }
10880 }
10881 }
bb4d2ac2 10882
ab273396
AM
10883 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
10884 {
10885 Elf_External_Verneed evn;
10886 Elf_Internal_Verneed ivn;
10887 Elf_Internal_Vernaux ivna;
bb4d2ac2 10888
ab273396
AM
10889 offset = offset_from_vma (file,
10890 version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
10891 sizeof evn);
10892 do
10893 {
10894 unsigned long vna_off;
bb4d2ac2 10895
ab273396
AM
10896 if (get_data (&evn, file, offset, sizeof (evn), 1,
10897 _("version need")) == NULL)
10898 {
10899 ivna.vna_next = 0;
10900 ivna.vna_other = 0;
10901 ivna.vna_name = 0;
10902 break;
10903 }
bb4d2ac2 10904
ab273396
AM
10905 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10906 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 10907
ab273396 10908 vna_off = offset + ivn.vn_aux;
bb4d2ac2 10909
ab273396
AM
10910 do
10911 {
10912 Elf_External_Vernaux evna;
bb4d2ac2 10913
ab273396
AM
10914 if (get_data (&evna, file, vna_off, sizeof (evna), 1,
10915 _("version need aux (3)")) == NULL)
bb4d2ac2 10916 {
ab273396
AM
10917 ivna.vna_next = 0;
10918 ivna.vna_other = 0;
10919 ivna.vna_name = 0;
bb4d2ac2 10920 }
bb4d2ac2 10921 else
bb4d2ac2 10922 {
ab273396
AM
10923 ivna.vna_other = BYTE_GET (evna.vna_other);
10924 ivna.vna_next = BYTE_GET (evna.vna_next);
10925 ivna.vna_name = BYTE_GET (evna.vna_name);
10926 }
bb4d2ac2 10927
ab273396
AM
10928 vna_off += ivna.vna_next;
10929 }
10930 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 10931
ab273396
AM
10932 if (ivna.vna_other == vers_data)
10933 break;
bb4d2ac2 10934
ab273396
AM
10935 offset += ivn.vn_next;
10936 }
10937 while (ivn.vn_next != 0);
bb4d2ac2 10938
ab273396
AM
10939 if (ivna.vna_other == vers_data)
10940 {
10941 *sym_info = symbol_undefined;
10942 *vna_other = ivna.vna_other;
10943 return (ivna.vna_name < strtab_size
10944 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2
L
10945 }
10946 }
ab273396 10947 return NULL;
bb4d2ac2
L
10948}
10949
e3c8793a 10950/* Dump the symbol table. */
252b5132 10951static int
2cf0635d 10952process_symbol_table (FILE * file)
252b5132 10953{
2cf0635d 10954 Elf_Internal_Shdr * section;
8b73c356
NC
10955 bfd_size_type nbuckets = 0;
10956 bfd_size_type nchains = 0;
2cf0635d
NC
10957 bfd_vma * buckets = NULL;
10958 bfd_vma * chains = NULL;
fdc90cb4 10959 bfd_vma ngnubuckets = 0;
2cf0635d
NC
10960 bfd_vma * gnubuckets = NULL;
10961 bfd_vma * gnuchains = NULL;
6bd1a22c 10962 bfd_vma gnusymidx = 0;
071436c6 10963 bfd_size_type ngnuchains = 0;
252b5132 10964
2c610e4b 10965 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
10966 return 1;
10967
6bd1a22c
L
10968 if (dynamic_info[DT_HASH]
10969 && (do_histogram
2c610e4b
L
10970 || (do_using_dynamic
10971 && !do_dyn_syms
10972 && dynamic_strings != NULL)))
252b5132 10973 {
66543521
AM
10974 unsigned char nb[8];
10975 unsigned char nc[8];
8b73c356 10976 unsigned int hash_ent_size = 4;
66543521
AM
10977
10978 if ((elf_header.e_machine == EM_ALPHA
10979 || elf_header.e_machine == EM_S390
10980 || elf_header.e_machine == EM_S390_OLD)
10981 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
10982 hash_ent_size = 8;
10983
fb52b2f4
NC
10984 if (fseek (file,
10985 (archive_file_offset
10986 + offset_from_vma (file, dynamic_info[DT_HASH],
10987 sizeof nb + sizeof nc)),
d93f0186 10988 SEEK_SET))
252b5132 10989 {
591a748a 10990 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10991 goto no_hash;
252b5132
RH
10992 }
10993
66543521 10994 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
10995 {
10996 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10997 goto no_hash;
252b5132
RH
10998 }
10999
66543521 11000 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
11001 {
11002 error (_("Failed to read in number of chains\n"));
d3a44ec6 11003 goto no_hash;
252b5132
RH
11004 }
11005
66543521
AM
11006 nbuckets = byte_get (nb, hash_ent_size);
11007 nchains = byte_get (nc, hash_ent_size);
252b5132 11008
66543521
AM
11009 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
11010 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 11011
d3a44ec6 11012 no_hash:
252b5132 11013 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
11014 {
11015 if (do_using_dynamic)
11016 return 0;
11017 free (buckets);
11018 free (chains);
11019 buckets = NULL;
11020 chains = NULL;
11021 nbuckets = 0;
11022 nchains = 0;
11023 }
252b5132
RH
11024 }
11025
6bd1a22c
L
11026 if (dynamic_info_DT_GNU_HASH
11027 && (do_histogram
2c610e4b
L
11028 || (do_using_dynamic
11029 && !do_dyn_syms
11030 && dynamic_strings != NULL)))
252b5132 11031 {
6bd1a22c
L
11032 unsigned char nb[16];
11033 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
11034 bfd_vma buckets_vma;
11035
11036 if (fseek (file,
11037 (archive_file_offset
11038 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
11039 sizeof nb)),
11040 SEEK_SET))
11041 {
11042 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11043 goto no_gnu_hash;
6bd1a22c 11044 }
252b5132 11045
6bd1a22c
L
11046 if (fread (nb, 16, 1, file) != 1)
11047 {
11048 error (_("Failed to read in number of buckets\n"));
d3a44ec6 11049 goto no_gnu_hash;
6bd1a22c
L
11050 }
11051
11052 ngnubuckets = byte_get (nb, 4);
11053 gnusymidx = byte_get (nb + 4, 4);
11054 bitmaskwords = byte_get (nb + 8, 4);
11055 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 11056 if (is_32bit_elf)
6bd1a22c 11057 buckets_vma += bitmaskwords * 4;
f7a99963 11058 else
6bd1a22c 11059 buckets_vma += bitmaskwords * 8;
252b5132 11060
6bd1a22c
L
11061 if (fseek (file,
11062 (archive_file_offset
11063 + offset_from_vma (file, buckets_vma, 4)),
11064 SEEK_SET))
252b5132 11065 {
6bd1a22c 11066 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11067 goto no_gnu_hash;
6bd1a22c
L
11068 }
11069
11070 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 11071
6bd1a22c 11072 if (gnubuckets == NULL)
d3a44ec6 11073 goto no_gnu_hash;
6bd1a22c
L
11074
11075 for (i = 0; i < ngnubuckets; i++)
11076 if (gnubuckets[i] != 0)
11077 {
11078 if (gnubuckets[i] < gnusymidx)
11079 return 0;
11080
11081 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
11082 maxchain = gnubuckets[i];
11083 }
11084
11085 if (maxchain == 0xffffffff)
d3a44ec6 11086 goto no_gnu_hash;
6bd1a22c
L
11087
11088 maxchain -= gnusymidx;
11089
11090 if (fseek (file,
11091 (archive_file_offset
11092 + offset_from_vma (file, buckets_vma
11093 + 4 * (ngnubuckets + maxchain), 4)),
11094 SEEK_SET))
11095 {
11096 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11097 goto no_gnu_hash;
6bd1a22c
L
11098 }
11099
11100 do
11101 {
11102 if (fread (nb, 4, 1, file) != 1)
252b5132 11103 {
6bd1a22c 11104 error (_("Failed to determine last chain length\n"));
d3a44ec6 11105 goto no_gnu_hash;
6bd1a22c 11106 }
252b5132 11107
6bd1a22c 11108 if (maxchain + 1 == 0)
d3a44ec6 11109 goto no_gnu_hash;
252b5132 11110
6bd1a22c
L
11111 ++maxchain;
11112 }
11113 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 11114
6bd1a22c
L
11115 if (fseek (file,
11116 (archive_file_offset
11117 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
11118 SEEK_SET))
11119 {
11120 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11121 goto no_gnu_hash;
6bd1a22c
L
11122 }
11123
11124 gnuchains = get_dynamic_data (file, maxchain, 4);
071436c6 11125 ngnuchains = maxchain;
6bd1a22c 11126
d3a44ec6 11127 no_gnu_hash:
6bd1a22c 11128 if (gnuchains == NULL)
d3a44ec6
JJ
11129 {
11130 free (gnubuckets);
d3a44ec6
JJ
11131 gnubuckets = NULL;
11132 ngnubuckets = 0;
f64fddf1
NC
11133 if (do_using_dynamic)
11134 return 0;
d3a44ec6 11135 }
6bd1a22c
L
11136 }
11137
11138 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
11139 && do_syms
11140 && do_using_dynamic
3102e897
NC
11141 && dynamic_strings != NULL
11142 && dynamic_symbols != NULL)
6bd1a22c
L
11143 {
11144 unsigned long hn;
11145
11146 if (dynamic_info[DT_HASH])
11147 {
11148 bfd_vma si;
11149
11150 printf (_("\nSymbol table for image:\n"));
11151 if (is_32bit_elf)
11152 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11153 else
11154 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11155
11156 for (hn = 0; hn < nbuckets; hn++)
11157 {
11158 if (! buckets[hn])
11159 continue;
11160
11161 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
11162 print_dynamic_symbol (si, hn);
252b5132
RH
11163 }
11164 }
6bd1a22c
L
11165
11166 if (dynamic_info_DT_GNU_HASH)
11167 {
11168 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
11169 if (is_32bit_elf)
11170 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11171 else
11172 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11173
11174 for (hn = 0; hn < ngnubuckets; ++hn)
11175 if (gnubuckets[hn] != 0)
11176 {
11177 bfd_vma si = gnubuckets[hn];
11178 bfd_vma off = si - gnusymidx;
11179
11180 do
11181 {
11182 print_dynamic_symbol (si, hn);
11183 si++;
11184 }
071436c6 11185 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
11186 }
11187 }
252b5132 11188 }
8b73c356
NC
11189 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
11190 && section_headers != NULL)
252b5132 11191 {
b34976b6 11192 unsigned int i;
252b5132
RH
11193
11194 for (i = 0, section = section_headers;
11195 i < elf_header.e_shnum;
11196 i++, section++)
11197 {
b34976b6 11198 unsigned int si;
2cf0635d 11199 char * strtab = NULL;
c256ffe7 11200 unsigned long int strtab_size = 0;
2cf0635d
NC
11201 Elf_Internal_Sym * symtab;
11202 Elf_Internal_Sym * psym;
ba5cdace 11203 unsigned long num_syms;
252b5132 11204
2c610e4b
L
11205 if ((section->sh_type != SHT_SYMTAB
11206 && section->sh_type != SHT_DYNSYM)
11207 || (!do_syms
11208 && section->sh_type == SHT_SYMTAB))
252b5132
RH
11209 continue;
11210
dd24e3da
NC
11211 if (section->sh_entsize == 0)
11212 {
11213 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
74e1a04b 11214 printable_section_name (section));
dd24e3da
NC
11215 continue;
11216 }
11217
252b5132 11218 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
74e1a04b 11219 printable_section_name (section),
252b5132 11220 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 11221
f7a99963 11222 if (is_32bit_elf)
ca47b30c 11223 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 11224 else
ca47b30c 11225 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 11226
ba5cdace 11227 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
11228 if (symtab == NULL)
11229 continue;
11230
11231 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
11232 {
11233 strtab = string_table;
11234 strtab_size = string_table_length;
11235 }
4fbb74a6 11236 else if (section->sh_link < elf_header.e_shnum)
252b5132 11237 {
2cf0635d 11238 Elf_Internal_Shdr * string_sec;
252b5132 11239
4fbb74a6 11240 string_sec = section_headers + section->sh_link;
252b5132 11241
3f5e193b
NC
11242 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
11243 1, string_sec->sh_size,
11244 _("string table"));
c256ffe7 11245 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
11246 }
11247
ba5cdace 11248 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 11249 {
bb4d2ac2
L
11250 const char *version_string;
11251 enum versioned_symbol_info sym_info;
11252 unsigned short vna_other;
11253
5e220199 11254 printf ("%6d: ", si);
f7a99963
NC
11255 print_vma (psym->st_value, LONG_HEX);
11256 putchar (' ');
11257 print_vma (psym->st_size, DEC_5);
d1133906
NC
11258 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
11259 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
fd85a6a1
NC
11260 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
11261 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
11262 else
11263 {
11264 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
11265
11266 printf (" %-7s", get_symbol_visibility (vis));
11267 /* Check to see if any other bits in the st_other field are set.
11268 Note - displaying this information disrupts the layout of the
11269 table being generated, but for the moment this case is very rare. */
11270 if (psym->st_other ^ vis)
11271 printf (" [%s] ", get_symbol_other (psym->st_other ^ vis));
11272 }
31104126 11273 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 11274 print_symbol (25, psym->st_name < strtab_size
2b692964 11275 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 11276
bb4d2ac2
L
11277 version_string
11278 = get_symbol_version_string (file,
11279 section->sh_type == SHT_DYNSYM,
11280 strtab, strtab_size, si,
11281 psym, &sym_info, &vna_other);
11282 if (version_string)
252b5132 11283 {
bb4d2ac2
L
11284 if (sym_info == symbol_undefined)
11285 printf ("@%s (%d)", version_string, vna_other);
11286 else
11287 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
11288 version_string);
252b5132
RH
11289 }
11290
11291 putchar ('\n');
52c3c391
NC
11292
11293 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
dd905818
NC
11294 && si >= section->sh_info
11295 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
11296 && elf_header.e_machine != EM_MIPS
11297 /* Solaris binaries have been found to violate this requirement as
11298 well. Not sure if this is a bug or an ABI requirement. */
11299 && elf_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
52c3c391
NC
11300 warn (_("local symbol %u found at index >= %s's sh_info value of %u\n"),
11301 si, printable_section_name (section), section->sh_info);
252b5132
RH
11302 }
11303
11304 free (symtab);
11305 if (strtab != string_table)
11306 free (strtab);
11307 }
11308 }
11309 else if (do_syms)
11310 printf
11311 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
11312
11313 if (do_histogram && buckets != NULL)
11314 {
2cf0635d
NC
11315 unsigned long * lengths;
11316 unsigned long * counts;
66543521
AM
11317 unsigned long hn;
11318 bfd_vma si;
11319 unsigned long maxlength = 0;
11320 unsigned long nzero_counts = 0;
11321 unsigned long nsyms = 0;
94d15024 11322 unsigned long chained;
252b5132 11323
66543521
AM
11324 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
11325 (unsigned long) nbuckets);
252b5132 11326
3f5e193b 11327 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
11328 if (lengths == NULL)
11329 {
8b73c356 11330 error (_("Out of memory allocating space for histogram buckets\n"));
252b5132
RH
11331 return 0;
11332 }
8b73c356
NC
11333
11334 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
11335 for (hn = 0; hn < nbuckets; ++hn)
11336 {
94d15024
MF
11337 for (si = buckets[hn], chained = 0;
11338 si > 0 && si < nchains && si < nbuckets && chained <= nchains;
11339 si = chains[si], ++chained)
252b5132 11340 {
b34976b6 11341 ++nsyms;
252b5132 11342 if (maxlength < ++lengths[hn])
b34976b6 11343 ++maxlength;
252b5132 11344 }
94d15024
MF
11345
11346 /* PR binutils/17531: A corrupt binary could contain broken
11347 histogram data. Do not go into an infinite loop trying
11348 to process it. */
11349 if (chained > nchains)
11350 {
11351 error (_("histogram chain is corrupt\n"));
11352 break;
11353 }
252b5132
RH
11354 }
11355
3f5e193b 11356 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
11357 if (counts == NULL)
11358 {
b2e951ec 11359 free (lengths);
8b73c356 11360 error (_("Out of memory allocating space for histogram counts\n"));
252b5132
RH
11361 return 0;
11362 }
11363
11364 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 11365 ++counts[lengths[hn]];
252b5132 11366
103f02d3 11367 if (nbuckets > 0)
252b5132 11368 {
66543521
AM
11369 unsigned long i;
11370 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 11371 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 11372 for (i = 1; i <= maxlength; ++i)
103f02d3 11373 {
66543521
AM
11374 nzero_counts += counts[i] * i;
11375 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11376 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
11377 (nzero_counts * 100.0) / nsyms);
11378 }
252b5132
RH
11379 }
11380
11381 free (counts);
11382 free (lengths);
11383 }
11384
11385 if (buckets != NULL)
11386 {
11387 free (buckets);
11388 free (chains);
11389 }
11390
d3a44ec6 11391 if (do_histogram && gnubuckets != NULL)
fdc90cb4 11392 {
2cf0635d
NC
11393 unsigned long * lengths;
11394 unsigned long * counts;
fdc90cb4
JJ
11395 unsigned long hn;
11396 unsigned long maxlength = 0;
11397 unsigned long nzero_counts = 0;
11398 unsigned long nsyms = 0;
fdc90cb4 11399
8b73c356
NC
11400 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
11401 (unsigned long) ngnubuckets);
11402
3f5e193b 11403 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
11404 if (lengths == NULL)
11405 {
8b73c356 11406 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fdc90cb4
JJ
11407 return 0;
11408 }
11409
fdc90cb4
JJ
11410 printf (_(" Length Number %% of total Coverage\n"));
11411
11412 for (hn = 0; hn < ngnubuckets; ++hn)
11413 if (gnubuckets[hn] != 0)
11414 {
11415 bfd_vma off, length = 1;
11416
6bd1a22c 11417 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
11418 /* PR 17531 file: 010-77222-0.004. */
11419 off < ngnuchains && (gnuchains[off] & 1) == 0;
11420 ++off)
fdc90cb4
JJ
11421 ++length;
11422 lengths[hn] = length;
11423 if (length > maxlength)
11424 maxlength = length;
11425 nsyms += length;
11426 }
11427
3f5e193b 11428 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
11429 if (counts == NULL)
11430 {
b2e951ec 11431 free (lengths);
8b73c356 11432 error (_("Out of memory allocating space for gnu histogram counts\n"));
fdc90cb4
JJ
11433 return 0;
11434 }
11435
11436 for (hn = 0; hn < ngnubuckets; ++hn)
11437 ++counts[lengths[hn]];
11438
11439 if (ngnubuckets > 0)
11440 {
11441 unsigned long j;
11442 printf (" 0 %-10lu (%5.1f%%)\n",
11443 counts[0], (counts[0] * 100.0) / ngnubuckets);
11444 for (j = 1; j <= maxlength; ++j)
11445 {
11446 nzero_counts += counts[j] * j;
11447 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11448 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
11449 (nzero_counts * 100.0) / nsyms);
11450 }
11451 }
11452
11453 free (counts);
11454 free (lengths);
11455 free (gnubuckets);
11456 free (gnuchains);
11457 }
11458
252b5132
RH
11459 return 1;
11460}
11461
11462static int
2cf0635d 11463process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 11464{
b4c96d0d 11465 unsigned int i;
252b5132
RH
11466
11467 if (dynamic_syminfo == NULL
11468 || !do_dynamic)
11469 /* No syminfo, this is ok. */
11470 return 1;
11471
11472 /* There better should be a dynamic symbol section. */
11473 if (dynamic_symbols == NULL || dynamic_strings == NULL)
11474 return 0;
11475
11476 if (dynamic_addr)
11477 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
11478 dynamic_syminfo_offset, dynamic_syminfo_nent);
11479
11480 printf (_(" Num: Name BoundTo Flags\n"));
11481 for (i = 0; i < dynamic_syminfo_nent; ++i)
11482 {
11483 unsigned short int flags = dynamic_syminfo[i].si_flags;
11484
31104126 11485 printf ("%4d: ", i);
4082ef84
NC
11486 if (i >= num_dynamic_syms)
11487 printf (_("<corrupt index>"));
11488 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
11489 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
11490 else
2b692964 11491 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 11492 putchar (' ');
252b5132
RH
11493
11494 switch (dynamic_syminfo[i].si_boundto)
11495 {
11496 case SYMINFO_BT_SELF:
11497 fputs ("SELF ", stdout);
11498 break;
11499 case SYMINFO_BT_PARENT:
11500 fputs ("PARENT ", stdout);
11501 break;
11502 default:
11503 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
11504 && dynamic_syminfo[i].si_boundto < dynamic_nent
11505 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 11506 {
d79b3d50 11507 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
11508 putchar (' ' );
11509 }
252b5132
RH
11510 else
11511 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
11512 break;
11513 }
11514
11515 if (flags & SYMINFO_FLG_DIRECT)
11516 printf (" DIRECT");
11517 if (flags & SYMINFO_FLG_PASSTHRU)
11518 printf (" PASSTHRU");
11519 if (flags & SYMINFO_FLG_COPY)
11520 printf (" COPY");
11521 if (flags & SYMINFO_FLG_LAZYLOAD)
11522 printf (" LAZYLOAD");
11523
11524 puts ("");
11525 }
11526
11527 return 1;
11528}
11529
cf13d699
NC
11530/* Check to see if the given reloc needs to be handled in a target specific
11531 manner. If so then process the reloc and return TRUE otherwise return
11532 FALSE. */
09c11c86 11533
cf13d699
NC
11534static bfd_boolean
11535target_specific_reloc_handling (Elf_Internal_Rela * reloc,
11536 unsigned char * start,
11537 Elf_Internal_Sym * symtab)
252b5132 11538{
cf13d699 11539 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 11540
cf13d699 11541 switch (elf_header.e_machine)
252b5132 11542 {
13761a11
NC
11543 case EM_MSP430:
11544 case EM_MSP430_OLD:
11545 {
11546 static Elf_Internal_Sym * saved_sym = NULL;
11547
11548 switch (reloc_type)
11549 {
11550 case 10: /* R_MSP430_SYM_DIFF */
11551 if (uses_msp430x_relocs ())
11552 break;
1a0670f3 11553 /* Fall through. */
13761a11
NC
11554 case 21: /* R_MSP430X_SYM_DIFF */
11555 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
11556 return TRUE;
11557
11558 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
11559 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
11560 goto handle_sym_diff;
0b4362b0 11561
13761a11
NC
11562 case 5: /* R_MSP430_16_BYTE */
11563 case 9: /* R_MSP430_8 */
11564 if (uses_msp430x_relocs ())
11565 break;
11566 goto handle_sym_diff;
11567
11568 case 2: /* R_MSP430_ABS16 */
11569 case 15: /* R_MSP430X_ABS16 */
11570 if (! uses_msp430x_relocs ())
11571 break;
11572 goto handle_sym_diff;
0b4362b0 11573
13761a11
NC
11574 handle_sym_diff:
11575 if (saved_sym != NULL)
11576 {
11577 bfd_vma value;
11578
11579 value = reloc->r_addend
11580 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
11581 - saved_sym->st_value);
11582
11583 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
11584
11585 saved_sym = NULL;
11586 return TRUE;
11587 }
11588 break;
11589
11590 default:
11591 if (saved_sym != NULL)
071436c6 11592 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
11593 break;
11594 }
11595 break;
11596 }
11597
cf13d699
NC
11598 case EM_MN10300:
11599 case EM_CYGNUS_MN10300:
11600 {
11601 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 11602
cf13d699
NC
11603 switch (reloc_type)
11604 {
11605 case 34: /* R_MN10300_ALIGN */
11606 return TRUE;
11607 case 33: /* R_MN10300_SYM_DIFF */
11608 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
11609 return TRUE;
11610 case 1: /* R_MN10300_32 */
11611 case 2: /* R_MN10300_16 */
11612 if (saved_sym != NULL)
11613 {
11614 bfd_vma value;
252b5132 11615
cf13d699
NC
11616 value = reloc->r_addend
11617 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
11618 - saved_sym->st_value);
252b5132 11619
cf13d699 11620 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 11621
cf13d699
NC
11622 saved_sym = NULL;
11623 return TRUE;
11624 }
11625 break;
11626 default:
11627 if (saved_sym != NULL)
071436c6 11628 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
11629 break;
11630 }
11631 break;
11632 }
6ff71e76
NC
11633
11634 case EM_RL78:
11635 {
11636 static bfd_vma saved_sym1 = 0;
11637 static bfd_vma saved_sym2 = 0;
11638 static bfd_vma value;
11639
11640 switch (reloc_type)
11641 {
11642 case 0x80: /* R_RL78_SYM. */
11643 saved_sym1 = saved_sym2;
11644 saved_sym2 = symtab[get_reloc_symindex (reloc->r_info)].st_value;
11645 saved_sym2 += reloc->r_addend;
11646 return TRUE;
11647
11648 case 0x83: /* R_RL78_OPsub. */
11649 value = saved_sym1 - saved_sym2;
11650 saved_sym2 = saved_sym1 = 0;
11651 return TRUE;
11652 break;
11653
11654 case 0x41: /* R_RL78_ABS32. */
11655 byte_put (start + reloc->r_offset, value, 4);
11656 value = 0;
11657 return TRUE;
11658
11659 case 0x43: /* R_RL78_ABS16. */
11660 byte_put (start + reloc->r_offset, value, 2);
11661 value = 0;
11662 return TRUE;
11663
11664 default:
11665 break;
11666 }
11667 break;
11668 }
252b5132
RH
11669 }
11670
cf13d699 11671 return FALSE;
252b5132
RH
11672}
11673
aca88567
NC
11674/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
11675 DWARF debug sections. This is a target specific test. Note - we do not
11676 go through the whole including-target-headers-multiple-times route, (as
11677 we have already done with <elf/h8.h>) because this would become very
11678 messy and even then this function would have to contain target specific
11679 information (the names of the relocs instead of their numeric values).
11680 FIXME: This is not the correct way to solve this problem. The proper way
11681 is to have target specific reloc sizing and typing functions created by
11682 the reloc-macros.h header, in the same way that it already creates the
11683 reloc naming functions. */
11684
11685static bfd_boolean
11686is_32bit_abs_reloc (unsigned int reloc_type)
11687{
d347c9df 11688 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567
NC
11689 switch (elf_header.e_machine)
11690 {
41e92641 11691 case EM_386:
22abe556 11692 case EM_IAMCU:
41e92641 11693 return reloc_type == 1; /* R_386_32. */
aca88567
NC
11694 case EM_68K:
11695 return reloc_type == 1; /* R_68K_32. */
11696 case EM_860:
11697 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
11698 case EM_960:
11699 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
11700 case EM_AARCH64:
11701 return reloc_type == 258; /* R_AARCH64_ABS32 */
d347c9df
PS
11702 case EM_ADAPTEVA_EPIPHANY:
11703 return reloc_type == 3;
aca88567 11704 case EM_ALPHA:
137b6b5f 11705 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
11706 case EM_ARC:
11707 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
11708 case EM_ARC_COMPACT:
11709 case EM_ARC_COMPACT2:
11710 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
11711 case EM_ARM:
11712 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 11713 case EM_AVR_OLD:
aca88567
NC
11714 case EM_AVR:
11715 return reloc_type == 1;
11716 case EM_BLACKFIN:
11717 return reloc_type == 0x12; /* R_byte4_data. */
11718 case EM_CRIS:
11719 return reloc_type == 3; /* R_CRIS_32. */
11720 case EM_CR16:
11721 return reloc_type == 3; /* R_CR16_NUM32. */
11722 case EM_CRX:
11723 return reloc_type == 15; /* R_CRX_NUM32. */
11724 case EM_CYGNUS_FRV:
11725 return reloc_type == 1;
41e92641
NC
11726 case EM_CYGNUS_D10V:
11727 case EM_D10V:
11728 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
11729 case EM_CYGNUS_D30V:
11730 case EM_D30V:
11731 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
11732 case EM_DLX:
11733 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
11734 case EM_CYGNUS_FR30:
11735 case EM_FR30:
11736 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
11737 case EM_FT32:
11738 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
11739 case EM_H8S:
11740 case EM_H8_300:
11741 case EM_H8_300H:
11742 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 11743 case EM_IA_64:
d1c4b12b
NC
11744 return reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
11745 || reloc_type == 0x25; /* R_IA64_DIR32LSB. */
aca88567
NC
11746 case EM_IP2K_OLD:
11747 case EM_IP2K:
11748 return reloc_type == 2; /* R_IP2K_32. */
11749 case EM_IQ2000:
11750 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
11751 case EM_LATTICEMICO32:
11752 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 11753 case EM_M32C_OLD:
aca88567
NC
11754 case EM_M32C:
11755 return reloc_type == 3; /* R_M32C_32. */
11756 case EM_M32R:
11757 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
11758 case EM_68HC11:
11759 case EM_68HC12:
11760 return reloc_type == 6; /* R_M68HC11_32. */
aca88567
NC
11761 case EM_MCORE:
11762 return reloc_type == 1; /* R_MCORE_ADDR32. */
11763 case EM_CYGNUS_MEP:
11764 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
11765 case EM_METAG:
11766 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
11767 case EM_MICROBLAZE:
11768 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
11769 case EM_MIPS:
11770 return reloc_type == 2; /* R_MIPS_32. */
11771 case EM_MMIX:
11772 return reloc_type == 4; /* R_MMIX_32. */
11773 case EM_CYGNUS_MN10200:
11774 case EM_MN10200:
11775 return reloc_type == 1; /* R_MN10200_32. */
11776 case EM_CYGNUS_MN10300:
11777 case EM_MN10300:
11778 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
11779 case EM_MOXIE:
11780 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
11781 case EM_MSP430_OLD:
11782 case EM_MSP430:
13761a11 11783 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
11784 case EM_MT:
11785 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
11786 case EM_NDS32:
11787 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 11788 case EM_ALTERA_NIOS2:
36591ba1 11789 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
11790 case EM_NIOS32:
11791 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
11792 case EM_OR1K:
11793 return reloc_type == 1; /* R_OR1K_32. */
aca88567 11794 case EM_PARISC:
5fda8eca
NC
11795 return (reloc_type == 1 /* R_PARISC_DIR32. */
11796 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
11797 case EM_PJ:
11798 case EM_PJ_OLD:
11799 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
11800 case EM_PPC64:
11801 return reloc_type == 1; /* R_PPC64_ADDR32. */
11802 case EM_PPC:
11803 return reloc_type == 1; /* R_PPC_ADDR32. */
e23eba97
NC
11804 case EM_RISCV:
11805 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
11806 case EM_RL78:
11807 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
11808 case EM_RX:
11809 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
11810 case EM_S370:
11811 return reloc_type == 1; /* R_I370_ADDR31. */
11812 case EM_S390_OLD:
11813 case EM_S390:
11814 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
11815 case EM_SCORE:
11816 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
11817 case EM_SH:
11818 return reloc_type == 1; /* R_SH_DIR32. */
11819 case EM_SPARC32PLUS:
11820 case EM_SPARCV9:
11821 case EM_SPARC:
11822 return reloc_type == 3 /* R_SPARC_32. */
11823 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
11824 case EM_SPU:
11825 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
11826 case EM_TI_C6000:
11827 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
11828 case EM_TILEGX:
11829 return reloc_type == 2; /* R_TILEGX_32. */
11830 case EM_TILEPRO:
11831 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
11832 case EM_CYGNUS_V850:
11833 case EM_V850:
11834 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
11835 case EM_V800:
11836 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
11837 case EM_VAX:
11838 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
11839 case EM_VISIUM:
11840 return reloc_type == 3; /* R_VISIUM_32. */
aca88567 11841 case EM_X86_64:
8a9036a4 11842 case EM_L1OM:
7a9068fe 11843 case EM_K1OM:
aca88567 11844 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
11845 case EM_XC16X:
11846 case EM_C166:
11847 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
11848 case EM_XGATE:
11849 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
11850 case EM_XSTORMY16:
11851 return reloc_type == 1; /* R_XSTROMY16_32. */
11852 case EM_XTENSA_OLD:
11853 case EM_XTENSA:
11854 return reloc_type == 1; /* R_XTENSA_32. */
aca88567 11855 default:
bee0ee85
NC
11856 {
11857 static unsigned int prev_warn = 0;
11858
11859 /* Avoid repeating the same warning multiple times. */
11860 if (prev_warn != elf_header.e_machine)
11861 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
11862 elf_header.e_machine);
11863 prev_warn = elf_header.e_machine;
11864 return FALSE;
11865 }
aca88567
NC
11866 }
11867}
11868
11869/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11870 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
11871
11872static bfd_boolean
11873is_32bit_pcrel_reloc (unsigned int reloc_type)
11874{
11875 switch (elf_header.e_machine)
d347c9df 11876 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 11877 {
41e92641 11878 case EM_386:
22abe556 11879 case EM_IAMCU:
3e0873ac 11880 return reloc_type == 2; /* R_386_PC32. */
aca88567 11881 case EM_68K:
3e0873ac 11882 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
11883 case EM_AARCH64:
11884 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
11885 case EM_ADAPTEVA_EPIPHANY:
11886 return reloc_type == 6;
aca88567
NC
11887 case EM_ALPHA:
11888 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
11889 case EM_ARC_COMPACT:
11890 case EM_ARC_COMPACT2:
11891 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 11892 case EM_ARM:
3e0873ac 11893 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
11894 case EM_AVR_OLD:
11895 case EM_AVR:
11896 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
11897 case EM_MICROBLAZE:
11898 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
11899 case EM_OR1K:
11900 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 11901 case EM_PARISC:
85acf597 11902 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
11903 case EM_PPC:
11904 return reloc_type == 26; /* R_PPC_REL32. */
11905 case EM_PPC64:
3e0873ac 11906 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
11907 case EM_S390_OLD:
11908 case EM_S390:
3e0873ac 11909 return reloc_type == 5; /* R_390_PC32. */
aca88567 11910 case EM_SH:
3e0873ac 11911 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
11912 case EM_SPARC32PLUS:
11913 case EM_SPARCV9:
11914 case EM_SPARC:
3e0873ac 11915 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
11916 case EM_SPU:
11917 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
11918 case EM_TILEGX:
11919 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
11920 case EM_TILEPRO:
11921 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
11922 case EM_VISIUM:
11923 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 11924 case EM_X86_64:
8a9036a4 11925 case EM_L1OM:
7a9068fe 11926 case EM_K1OM:
3e0873ac 11927 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
11928 case EM_XTENSA_OLD:
11929 case EM_XTENSA:
11930 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
11931 default:
11932 /* Do not abort or issue an error message here. Not all targets use
11933 pc-relative 32-bit relocs in their DWARF debug information and we
11934 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
11935 more helpful warning message will be generated by apply_relocations
11936 anyway, so just return. */
aca88567
NC
11937 return FALSE;
11938 }
11939}
11940
11941/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11942 a 64-bit absolute RELA relocation used in DWARF debug sections. */
11943
11944static bfd_boolean
11945is_64bit_abs_reloc (unsigned int reloc_type)
11946{
11947 switch (elf_header.e_machine)
11948 {
a06ea964
NC
11949 case EM_AARCH64:
11950 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
11951 case EM_ALPHA:
11952 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
11953 case EM_IA_64:
11954 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
11955 case EM_PARISC:
11956 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
11957 case EM_PPC64:
11958 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
11959 case EM_RISCV:
11960 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
11961 case EM_SPARC32PLUS:
11962 case EM_SPARCV9:
11963 case EM_SPARC:
11964 return reloc_type == 54; /* R_SPARC_UA64. */
11965 case EM_X86_64:
8a9036a4 11966 case EM_L1OM:
7a9068fe 11967 case EM_K1OM:
aca88567 11968 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
11969 case EM_S390_OLD:
11970 case EM_S390:
aa137e4d
NC
11971 return reloc_type == 22; /* R_S390_64. */
11972 case EM_TILEGX:
11973 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 11974 case EM_MIPS:
aa137e4d 11975 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
11976 default:
11977 return FALSE;
11978 }
11979}
11980
85acf597
RH
11981/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
11982 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
11983
11984static bfd_boolean
11985is_64bit_pcrel_reloc (unsigned int reloc_type)
11986{
11987 switch (elf_header.e_machine)
11988 {
a06ea964
NC
11989 case EM_AARCH64:
11990 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 11991 case EM_ALPHA:
aa137e4d 11992 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 11993 case EM_IA_64:
aa137e4d 11994 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 11995 case EM_PARISC:
aa137e4d 11996 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 11997 case EM_PPC64:
aa137e4d 11998 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
11999 case EM_SPARC32PLUS:
12000 case EM_SPARCV9:
12001 case EM_SPARC:
aa137e4d 12002 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 12003 case EM_X86_64:
8a9036a4 12004 case EM_L1OM:
7a9068fe 12005 case EM_K1OM:
aa137e4d 12006 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
12007 case EM_S390_OLD:
12008 case EM_S390:
aa137e4d
NC
12009 return reloc_type == 23; /* R_S390_PC64. */
12010 case EM_TILEGX:
12011 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
12012 default:
12013 return FALSE;
12014 }
12015}
12016
4dc3c23d
AM
12017/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12018 a 24-bit absolute RELA relocation used in DWARF debug sections. */
12019
12020static bfd_boolean
12021is_24bit_abs_reloc (unsigned int reloc_type)
12022{
12023 switch (elf_header.e_machine)
12024 {
12025 case EM_CYGNUS_MN10200:
12026 case EM_MN10200:
12027 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
12028 case EM_FT32:
12029 return reloc_type == 5; /* R_FT32_20. */
4dc3c23d
AM
12030 default:
12031 return FALSE;
12032 }
12033}
12034
aca88567
NC
12035/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12036 a 16-bit absolute RELA relocation used in DWARF debug sections. */
12037
12038static bfd_boolean
12039is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a 12040{
d347c9df 12041 /* Please keep this table alpha-sorted for ease of visual lookup. */
4b78141a
NC
12042 switch (elf_header.e_machine)
12043 {
886a2506
NC
12044 case EM_ARC:
12045 case EM_ARC_COMPACT:
12046 case EM_ARC_COMPACT2:
12047 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
12048 case EM_ADAPTEVA_EPIPHANY:
12049 return reloc_type == 5;
aca88567
NC
12050 case EM_AVR_OLD:
12051 case EM_AVR:
12052 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
12053 case EM_CYGNUS_D10V:
12054 case EM_D10V:
12055 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
12056 case EM_H8S:
12057 case EM_H8_300:
12058 case EM_H8_300H:
aca88567
NC
12059 return reloc_type == R_H8_DIR16;
12060 case EM_IP2K_OLD:
12061 case EM_IP2K:
12062 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 12063 case EM_M32C_OLD:
f4236fe4
DD
12064 case EM_M32C:
12065 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
12066 case EM_CYGNUS_MN10200:
12067 case EM_MN10200:
12068 return reloc_type == 2; /* R_MN10200_16. */
12069 case EM_CYGNUS_MN10300:
12070 case EM_MN10300:
12071 return reloc_type == 2; /* R_MN10300_16. */
aca88567 12072 case EM_MSP430:
13761a11
NC
12073 if (uses_msp430x_relocs ())
12074 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 12075 /* Fall through. */
78c8d46c 12076 case EM_MSP430_OLD:
aca88567 12077 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
12078 case EM_NDS32:
12079 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 12080 case EM_ALTERA_NIOS2:
36591ba1 12081 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
12082 case EM_NIOS32:
12083 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
12084 case EM_OR1K:
12085 return reloc_type == 2; /* R_OR1K_16. */
40b36596
JM
12086 case EM_TI_C6000:
12087 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
12088 case EM_VISIUM:
12089 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
12090 case EM_XC16X:
12091 case EM_C166:
12092 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
12093 case EM_XGATE:
12094 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 12095 default:
aca88567 12096 return FALSE;
4b78141a
NC
12097 }
12098}
12099
2a7b2e88
JK
12100/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
12101 relocation entries (possibly formerly used for SHT_GROUP sections). */
12102
12103static bfd_boolean
12104is_none_reloc (unsigned int reloc_type)
12105{
12106 switch (elf_header.e_machine)
12107 {
cb8f3167 12108 case EM_386: /* R_386_NONE. */
d347c9df 12109 case EM_68K: /* R_68K_NONE. */
cfb8c092 12110 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
12111 case EM_ALPHA: /* R_ALPHA_NONE. */
12112 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 12113 case EM_ARC: /* R_ARC_NONE. */
886a2506 12114 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 12115 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 12116 case EM_ARM: /* R_ARM_NONE. */
d347c9df 12117 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 12118 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
12119 case EM_FT32: /* R_FT32_NONE. */
12120 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 12121 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
12122 case EM_L1OM: /* R_X86_64_NONE. */
12123 case EM_M32R: /* R_M32R_NONE. */
12124 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 12125 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 12126 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
12127 case EM_NIOS32: /* R_NIOS_NONE. */
12128 case EM_OR1K: /* R_OR1K_NONE. */
12129 case EM_PARISC: /* R_PARISC_NONE. */
12130 case EM_PPC64: /* R_PPC64_NONE. */
12131 case EM_PPC: /* R_PPC_NONE. */
e23eba97 12132 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
12133 case EM_S390: /* R_390_NONE. */
12134 case EM_S390_OLD:
12135 case EM_SH: /* R_SH_NONE. */
12136 case EM_SPARC32PLUS:
12137 case EM_SPARC: /* R_SPARC_NONE. */
12138 case EM_SPARCV9:
aa137e4d
NC
12139 case EM_TILEGX: /* R_TILEGX_NONE. */
12140 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
12141 case EM_TI_C6000:/* R_C6000_NONE. */
12142 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 12143 case EM_XC16X:
cb8f3167 12144 return reloc_type == 0;
d347c9df 12145
a06ea964
NC
12146 case EM_AARCH64:
12147 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
12148 case EM_AVR_OLD:
12149 case EM_AVR:
12150 return (reloc_type == 0 /* R_AVR_NONE. */
12151 || reloc_type == 30 /* R_AVR_DIFF8. */
12152 || reloc_type == 31 /* R_AVR_DIFF16. */
12153 || reloc_type == 32 /* R_AVR_DIFF32. */);
12154 case EM_METAG:
12155 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
12156 case EM_NDS32:
12157 return (reloc_type == 0 /* R_XTENSA_NONE. */
12158 || reloc_type == 204 /* R_NDS32_DIFF8. */
12159 || reloc_type == 205 /* R_NDS32_DIFF16. */
12160 || reloc_type == 206 /* R_NDS32_DIFF32. */
12161 || reloc_type == 207 /* R_NDS32_ULEB128. */);
58332dda
JK
12162 case EM_XTENSA_OLD:
12163 case EM_XTENSA:
4dc3c23d
AM
12164 return (reloc_type == 0 /* R_XTENSA_NONE. */
12165 || reloc_type == 17 /* R_XTENSA_DIFF8. */
12166 || reloc_type == 18 /* R_XTENSA_DIFF16. */
12167 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
12168 }
12169 return FALSE;
12170}
12171
d1c4b12b
NC
12172/* Returns TRUE if there is a relocation against
12173 section NAME at OFFSET bytes. */
12174
12175bfd_boolean
12176reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
12177{
12178 Elf_Internal_Rela * relocs;
12179 Elf_Internal_Rela * rp;
12180
12181 if (dsec == NULL || dsec->reloc_info == NULL)
12182 return FALSE;
12183
12184 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
12185
12186 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
12187 if (rp->r_offset == offset)
12188 return TRUE;
12189
12190 return FALSE;
12191}
12192
cf13d699
NC
12193/* Apply relocations to a section.
12194 Note: So far support has been added only for those relocations
12195 which can be found in debug sections.
d1c4b12b
NC
12196 If RELOCS_RETURN is non-NULL then returns in it a pointer to the
12197 loaded relocs. It is then the caller's responsibility to free them.
cf13d699 12198 FIXME: Add support for more relocations ? */
1b315056 12199
cf13d699 12200static void
d1c4b12b
NC
12201apply_relocations (void * file,
12202 const Elf_Internal_Shdr * section,
12203 unsigned char * start,
12204 bfd_size_type size,
1449284b 12205 void ** relocs_return,
d1c4b12b 12206 unsigned long * num_relocs_return)
1b315056 12207{
cf13d699 12208 Elf_Internal_Shdr * relsec;
0d2a7a93 12209 unsigned char * end = start + size;
cb8f3167 12210
d1c4b12b
NC
12211 if (relocs_return != NULL)
12212 {
12213 * (Elf_Internal_Rela **) relocs_return = NULL;
12214 * num_relocs_return = 0;
12215 }
12216
cf13d699
NC
12217 if (elf_header.e_type != ET_REL)
12218 return;
1b315056 12219
cf13d699 12220 /* Find the reloc section associated with the section. */
5b18a4bc
NC
12221 for (relsec = section_headers;
12222 relsec < section_headers + elf_header.e_shnum;
12223 ++relsec)
252b5132 12224 {
41e92641
NC
12225 bfd_boolean is_rela;
12226 unsigned long num_relocs;
2cf0635d
NC
12227 Elf_Internal_Rela * relocs;
12228 Elf_Internal_Rela * rp;
12229 Elf_Internal_Shdr * symsec;
12230 Elf_Internal_Sym * symtab;
ba5cdace 12231 unsigned long num_syms;
2cf0635d 12232 Elf_Internal_Sym * sym;
252b5132 12233
41e92641 12234 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
12235 || relsec->sh_info >= elf_header.e_shnum
12236 || section_headers + relsec->sh_info != section
c256ffe7 12237 || relsec->sh_size == 0
4fbb74a6 12238 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 12239 continue;
428409d5 12240
41e92641
NC
12241 is_rela = relsec->sh_type == SHT_RELA;
12242
12243 if (is_rela)
12244 {
3f5e193b
NC
12245 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
12246 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
12247 return;
12248 }
12249 else
12250 {
3f5e193b
NC
12251 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
12252 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
12253 return;
12254 }
12255
12256 /* SH uses RELA but uses in place value instead of the addend field. */
12257 if (elf_header.e_machine == EM_SH)
12258 is_rela = FALSE;
428409d5 12259
4fbb74a6 12260 symsec = section_headers + relsec->sh_link;
1449284b
NC
12261 if (symsec->sh_type != SHT_SYMTAB
12262 && symsec->sh_type != SHT_DYNSYM)
12263 return;
ba5cdace 12264 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 12265
41e92641 12266 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 12267 {
41e92641
NC
12268 bfd_vma addend;
12269 unsigned int reloc_type;
12270 unsigned int reloc_size;
91d6fa6a 12271 unsigned char * rloc;
ba5cdace 12272 unsigned long sym_index;
4b78141a 12273
aca88567 12274 reloc_type = get_reloc_type (rp->r_info);
41e92641 12275
98fb390a 12276 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 12277 continue;
98fb390a
NC
12278 else if (is_none_reloc (reloc_type))
12279 continue;
12280 else if (is_32bit_abs_reloc (reloc_type)
12281 || is_32bit_pcrel_reloc (reloc_type))
aca88567 12282 reloc_size = 4;
85acf597
RH
12283 else if (is_64bit_abs_reloc (reloc_type)
12284 || is_64bit_pcrel_reloc (reloc_type))
aca88567 12285 reloc_size = 8;
4dc3c23d
AM
12286 else if (is_24bit_abs_reloc (reloc_type))
12287 reloc_size = 3;
aca88567
NC
12288 else if (is_16bit_abs_reloc (reloc_type))
12289 reloc_size = 2;
12290 else
4b78141a 12291 {
bee0ee85
NC
12292 static unsigned int prev_reloc = 0;
12293 if (reloc_type != prev_reloc)
12294 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
12295 reloc_type, printable_section_name (section));
12296 prev_reloc = reloc_type;
4b78141a
NC
12297 continue;
12298 }
103f02d3 12299
91d6fa6a 12300 rloc = start + rp->r_offset;
c8da6823 12301 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
12302 {
12303 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
12304 (unsigned long) rp->r_offset,
74e1a04b 12305 printable_section_name (section));
700dd8b7
L
12306 continue;
12307 }
103f02d3 12308
ba5cdace
NC
12309 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
12310 if (sym_index >= num_syms)
12311 {
12312 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
74e1a04b 12313 sym_index, printable_section_name (section));
ba5cdace
NC
12314 continue;
12315 }
12316 sym = symtab + sym_index;
41e92641
NC
12317
12318 /* If the reloc has a symbol associated with it,
55f25fc3
L
12319 make sure that it is of an appropriate type.
12320
12321 Relocations against symbols without type can happen.
12322 Gcc -feliminate-dwarf2-dups may generate symbols
12323 without type for debug info.
12324
12325 Icc generates relocations against function symbols
12326 instead of local labels.
12327
12328 Relocations against object symbols can happen, eg when
12329 referencing a global array. For an example of this see
12330 the _clz.o binary in libgcc.a. */
aca88567 12331 if (sym != symtab
b8871f35 12332 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 12333 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 12334 {
41e92641 12335 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 12336 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 12337 (long int)(rp - relocs),
74e1a04b 12338 printable_section_name (relsec));
aca88567 12339 continue;
5b18a4bc 12340 }
252b5132 12341
4dc3c23d
AM
12342 addend = 0;
12343 if (is_rela)
12344 addend += rp->r_addend;
c47320c3
AM
12345 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
12346 partial_inplace. */
4dc3c23d
AM
12347 if (!is_rela
12348 || (elf_header.e_machine == EM_XTENSA
12349 && reloc_type == 1)
12350 || ((elf_header.e_machine == EM_PJ
12351 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
12352 && reloc_type == 1)
12353 || ((elf_header.e_machine == EM_D30V
12354 || elf_header.e_machine == EM_CYGNUS_D30V)
12355 && reloc_type == 12))
91d6fa6a 12356 addend += byte_get (rloc, reloc_size);
cb8f3167 12357
85acf597
RH
12358 if (is_32bit_pcrel_reloc (reloc_type)
12359 || is_64bit_pcrel_reloc (reloc_type))
12360 {
12361 /* On HPPA, all pc-relative relocations are biased by 8. */
12362 if (elf_header.e_machine == EM_PARISC)
12363 addend -= 8;
91d6fa6a 12364 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
12365 reloc_size);
12366 }
41e92641 12367 else
91d6fa6a 12368 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 12369 }
252b5132 12370
5b18a4bc 12371 free (symtab);
d1c4b12b
NC
12372
12373 if (relocs_return)
12374 {
12375 * (Elf_Internal_Rela **) relocs_return = relocs;
12376 * num_relocs_return = num_relocs;
12377 }
12378 else
12379 free (relocs);
12380
5b18a4bc
NC
12381 break;
12382 }
5b18a4bc 12383}
103f02d3 12384
cf13d699
NC
12385#ifdef SUPPORT_DISASSEMBLY
12386static int
12387disassemble_section (Elf_Internal_Shdr * section, FILE * file)
12388{
74e1a04b 12389 printf (_("\nAssembly dump of section %s\n"), printable_section_name (section));
cf13d699 12390
74e1a04b 12391 /* FIXME: XXX -- to be done --- XXX */
cf13d699
NC
12392
12393 return 1;
12394}
12395#endif
12396
12397/* Reads in the contents of SECTION from FILE, returning a pointer
12398 to a malloc'ed buffer or NULL if something went wrong. */
12399
12400static char *
12401get_section_contents (Elf_Internal_Shdr * section, FILE * file)
12402{
12403 bfd_size_type num_bytes;
12404
12405 num_bytes = section->sh_size;
12406
12407 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
12408 {
12409 printf (_("\nSection '%s' has no data to dump.\n"),
74e1a04b 12410 printable_section_name (section));
cf13d699
NC
12411 return NULL;
12412 }
12413
3f5e193b
NC
12414 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
12415 _("section contents"));
cf13d699
NC
12416}
12417
0e602686
NC
12418/* Uncompresses a section that was compressed using zlib, in place. */
12419
12420static bfd_boolean
12421uncompress_section_contents (unsigned char **buffer,
12422 dwarf_size_type uncompressed_size,
12423 dwarf_size_type *size)
12424{
12425 dwarf_size_type compressed_size = *size;
12426 unsigned char * compressed_buffer = *buffer;
12427 unsigned char * uncompressed_buffer;
12428 z_stream strm;
12429 int rc;
12430
12431 /* It is possible the section consists of several compressed
12432 buffers concatenated together, so we uncompress in a loop. */
12433 /* PR 18313: The state field in the z_stream structure is supposed
12434 to be invisible to the user (ie us), but some compilers will
12435 still complain about it being used without initialisation. So
12436 we first zero the entire z_stream structure and then set the fields
12437 that we need. */
12438 memset (& strm, 0, sizeof strm);
12439 strm.avail_in = compressed_size;
12440 strm.next_in = (Bytef *) compressed_buffer;
12441 strm.avail_out = uncompressed_size;
12442 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
12443
12444 rc = inflateInit (& strm);
12445 while (strm.avail_in > 0)
12446 {
12447 if (rc != Z_OK)
12448 goto fail;
12449 strm.next_out = ((Bytef *) uncompressed_buffer
12450 + (uncompressed_size - strm.avail_out));
12451 rc = inflate (&strm, Z_FINISH);
12452 if (rc != Z_STREAM_END)
12453 goto fail;
12454 rc = inflateReset (& strm);
12455 }
12456 rc = inflateEnd (& strm);
12457 if (rc != Z_OK
12458 || strm.avail_out != 0)
12459 goto fail;
12460
12461 *buffer = uncompressed_buffer;
12462 *size = uncompressed_size;
12463 return TRUE;
12464
12465 fail:
12466 free (uncompressed_buffer);
12467 /* Indicate decompression failure. */
12468 *buffer = NULL;
12469 return FALSE;
12470}
dd24e3da 12471
cf13d699
NC
12472static void
12473dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
12474{
0e602686
NC
12475 Elf_Internal_Shdr * relsec;
12476 bfd_size_type num_bytes;
fd8008d8
L
12477 unsigned char * data;
12478 unsigned char * end;
12479 unsigned char * real_start;
12480 unsigned char * start;
0e602686 12481 bfd_boolean some_strings_shown;
cf13d699 12482
fd8008d8
L
12483 real_start = start = (unsigned char *) get_section_contents (section,
12484 file);
cf13d699
NC
12485 if (start == NULL)
12486 return;
0e602686 12487 num_bytes = section->sh_size;
cf13d699 12488
74e1a04b 12489 printf (_("\nString dump of section '%s':\n"), printable_section_name (section));
cf13d699 12490
0e602686
NC
12491 if (decompress_dumps)
12492 {
12493 dwarf_size_type new_size = num_bytes;
12494 dwarf_size_type uncompressed_size = 0;
12495
12496 if ((section->sh_flags & SHF_COMPRESSED) != 0)
12497 {
12498 Elf_Internal_Chdr chdr;
12499 unsigned int compression_header_size
12500 = get_compression_header (& chdr, (unsigned char *) start);
12501
813dabb9 12502 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 12503 {
813dabb9
L
12504 warn (_("section '%s' has unsupported compress type: %d\n"),
12505 printable_section_name (section), chdr.ch_type);
12506 return;
12507 }
12508 else if (chdr.ch_addralign != section->sh_addralign)
12509 {
12510 warn (_("compressed section '%s' is corrupted\n"),
12511 printable_section_name (section));
12512 return;
0e602686 12513 }
813dabb9
L
12514 uncompressed_size = chdr.ch_size;
12515 start += compression_header_size;
12516 new_size -= compression_header_size;
0e602686
NC
12517 }
12518 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
12519 {
12520 /* Read the zlib header. In this case, it should be "ZLIB"
12521 followed by the uncompressed section size, 8 bytes in
12522 big-endian order. */
12523 uncompressed_size = start[4]; uncompressed_size <<= 8;
12524 uncompressed_size += start[5]; uncompressed_size <<= 8;
12525 uncompressed_size += start[6]; uncompressed_size <<= 8;
12526 uncompressed_size += start[7]; uncompressed_size <<= 8;
12527 uncompressed_size += start[8]; uncompressed_size <<= 8;
12528 uncompressed_size += start[9]; uncompressed_size <<= 8;
12529 uncompressed_size += start[10]; uncompressed_size <<= 8;
12530 uncompressed_size += start[11];
12531 start += 12;
12532 new_size -= 12;
12533 }
12534
12535 if (uncompressed_size
fd8008d8 12536 && uncompress_section_contents (& start,
0e602686
NC
12537 uncompressed_size, & new_size))
12538 num_bytes = new_size;
12539 }
fd8008d8 12540
cf13d699
NC
12541 /* If the section being dumped has relocations against it the user might
12542 be expecting these relocations to have been applied. Check for this
12543 case and issue a warning message in order to avoid confusion.
12544 FIXME: Maybe we ought to have an option that dumps a section with
12545 relocs applied ? */
12546 for (relsec = section_headers;
12547 relsec < section_headers + elf_header.e_shnum;
12548 ++relsec)
12549 {
12550 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
12551 || relsec->sh_info >= elf_header.e_shnum
12552 || section_headers + relsec->sh_info != section
12553 || relsec->sh_size == 0
12554 || relsec->sh_link >= elf_header.e_shnum)
12555 continue;
12556
12557 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
12558 break;
12559 }
12560
cf13d699
NC
12561 data = start;
12562 end = start + num_bytes;
12563 some_strings_shown = FALSE;
12564
12565 while (data < end)
12566 {
12567 while (!ISPRINT (* data))
12568 if (++ data >= end)
12569 break;
12570
12571 if (data < end)
12572 {
071436c6
NC
12573 size_t maxlen = end - data;
12574
cf13d699 12575#ifndef __MSVCRT__
c975cc98
NC
12576 /* PR 11128: Use two separate invocations in order to work
12577 around bugs in the Solaris 8 implementation of printf. */
12578 printf (" [%6tx] ", data - start);
cf13d699 12579#else
071436c6 12580 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 12581#endif
4082ef84
NC
12582 if (maxlen > 0)
12583 {
fd8008d8 12584 print_symbol ((int) maxlen, (const char *) data);
4082ef84 12585 putchar ('\n');
fd8008d8 12586 data += strnlen ((const char *) data, maxlen);
4082ef84
NC
12587 }
12588 else
12589 {
12590 printf (_("<corrupt>\n"));
12591 data = end;
12592 }
cf13d699
NC
12593 some_strings_shown = TRUE;
12594 }
12595 }
12596
12597 if (! some_strings_shown)
12598 printf (_(" No strings found in this section."));
12599
0e602686 12600 free (real_start);
cf13d699
NC
12601
12602 putchar ('\n');
12603}
12604
12605static void
12606dump_section_as_bytes (Elf_Internal_Shdr * section,
12607 FILE * file,
12608 bfd_boolean relocate)
12609{
12610 Elf_Internal_Shdr * relsec;
0e602686
NC
12611 bfd_size_type bytes;
12612 bfd_size_type section_size;
12613 bfd_vma addr;
12614 unsigned char * data;
12615 unsigned char * real_start;
12616 unsigned char * start;
12617
12618 real_start = start = (unsigned char *) get_section_contents (section, file);
cf13d699
NC
12619 if (start == NULL)
12620 return;
0e602686 12621 section_size = section->sh_size;
cf13d699 12622
74e1a04b 12623 printf (_("\nHex dump of section '%s':\n"), printable_section_name (section));
cf13d699 12624
0e602686
NC
12625 if (decompress_dumps)
12626 {
12627 dwarf_size_type new_size = section_size;
12628 dwarf_size_type uncompressed_size = 0;
12629
12630 if ((section->sh_flags & SHF_COMPRESSED) != 0)
12631 {
12632 Elf_Internal_Chdr chdr;
12633 unsigned int compression_header_size
12634 = get_compression_header (& chdr, start);
12635
813dabb9 12636 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 12637 {
813dabb9
L
12638 warn (_("section '%s' has unsupported compress type: %d\n"),
12639 printable_section_name (section), chdr.ch_type);
12640 return;
0e602686 12641 }
813dabb9
L
12642 else if (chdr.ch_addralign != section->sh_addralign)
12643 {
12644 warn (_("compressed section '%s' is corrupted\n"),
12645 printable_section_name (section));
12646 return;
12647 }
12648 uncompressed_size = chdr.ch_size;
12649 start += compression_header_size;
12650 new_size -= compression_header_size;
0e602686
NC
12651 }
12652 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
12653 {
12654 /* Read the zlib header. In this case, it should be "ZLIB"
12655 followed by the uncompressed section size, 8 bytes in
12656 big-endian order. */
12657 uncompressed_size = start[4]; uncompressed_size <<= 8;
12658 uncompressed_size += start[5]; uncompressed_size <<= 8;
12659 uncompressed_size += start[6]; uncompressed_size <<= 8;
12660 uncompressed_size += start[7]; uncompressed_size <<= 8;
12661 uncompressed_size += start[8]; uncompressed_size <<= 8;
12662 uncompressed_size += start[9]; uncompressed_size <<= 8;
12663 uncompressed_size += start[10]; uncompressed_size <<= 8;
12664 uncompressed_size += start[11];
12665 start += 12;
12666 new_size -= 12;
12667 }
12668
12669 if (uncompressed_size
12670 && uncompress_section_contents (& start, uncompressed_size,
12671 & new_size))
12672 section_size = new_size;
12673 }
14ae95f2 12674
cf13d699
NC
12675 if (relocate)
12676 {
0e602686 12677 apply_relocations (file, section, start, section_size, NULL, NULL);
cf13d699
NC
12678 }
12679 else
12680 {
12681 /* If the section being dumped has relocations against it the user might
12682 be expecting these relocations to have been applied. Check for this
12683 case and issue a warning message in order to avoid confusion.
12684 FIXME: Maybe we ought to have an option that dumps a section with
12685 relocs applied ? */
12686 for (relsec = section_headers;
12687 relsec < section_headers + elf_header.e_shnum;
12688 ++relsec)
12689 {
12690 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
12691 || relsec->sh_info >= elf_header.e_shnum
12692 || section_headers + relsec->sh_info != section
12693 || relsec->sh_size == 0
12694 || relsec->sh_link >= elf_header.e_shnum)
12695 continue;
12696
12697 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
12698 break;
12699 }
12700 }
12701
12702 addr = section->sh_addr;
0e602686 12703 bytes = section_size;
cf13d699
NC
12704 data = start;
12705
12706 while (bytes)
12707 {
12708 int j;
12709 int k;
12710 int lbytes;
12711
12712 lbytes = (bytes > 16 ? 16 : bytes);
12713
12714 printf (" 0x%8.8lx ", (unsigned long) addr);
12715
12716 for (j = 0; j < 16; j++)
12717 {
12718 if (j < lbytes)
12719 printf ("%2.2x", data[j]);
12720 else
12721 printf (" ");
12722
12723 if ((j & 3) == 3)
12724 printf (" ");
12725 }
12726
12727 for (j = 0; j < lbytes; j++)
12728 {
12729 k = data[j];
12730 if (k >= ' ' && k < 0x7f)
12731 printf ("%c", k);
12732 else
12733 printf (".");
12734 }
12735
12736 putchar ('\n');
12737
12738 data += lbytes;
12739 addr += lbytes;
12740 bytes -= lbytes;
12741 }
12742
0e602686 12743 free (real_start);
cf13d699
NC
12744
12745 putchar ('\n');
12746}
12747
d966045b
DJ
12748static int
12749load_specific_debug_section (enum dwarf_section_display_enum debug,
0d2a7a93 12750 const Elf_Internal_Shdr * sec, void * file)
1007acb3 12751{
2cf0635d 12752 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 12753 char buf [64];
1007acb3 12754
19e6b90e
L
12755 /* If it is already loaded, do nothing. */
12756 if (section->start != NULL)
12757 return 1;
1007acb3 12758
19e6b90e
L
12759 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
12760 section->address = sec->sh_addr;
06614111 12761 section->user_data = NULL;
3f5e193b
NC
12762 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
12763 sec->sh_offset, 1,
12764 sec->sh_size, buf);
59245841
NC
12765 if (section->start == NULL)
12766 section->size = 0;
12767 else
12768 {
77115a4a
L
12769 unsigned char *start = section->start;
12770 dwarf_size_type size = sec->sh_size;
dab394de 12771 dwarf_size_type uncompressed_size = 0;
77115a4a
L
12772
12773 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
12774 {
12775 Elf_Internal_Chdr chdr;
d8024a91
NC
12776 unsigned int compression_header_size;
12777
f53be977
L
12778 if (size < (is_32bit_elf
12779 ? sizeof (Elf32_External_Chdr)
12780 : sizeof (Elf64_External_Chdr)))
d8024a91
NC
12781 {
12782 warn (_("compressed section %s is too small to contain a compression header"),
12783 section->name);
12784 return 0;
12785 }
12786
12787 compression_header_size = get_compression_header (&chdr, start);
12788
813dabb9
L
12789 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
12790 {
12791 warn (_("section '%s' has unsupported compress type: %d\n"),
12792 section->name, chdr.ch_type);
12793 return 0;
12794 }
12795 else if (chdr.ch_addralign != sec->sh_addralign)
12796 {
12797 warn (_("compressed section '%s' is corrupted\n"),
12798 section->name);
12799 return 0;
12800 }
dab394de 12801 uncompressed_size = chdr.ch_size;
77115a4a
L
12802 start += compression_header_size;
12803 size -= compression_header_size;
12804 }
dab394de
L
12805 else if (size > 12 && streq ((char *) start, "ZLIB"))
12806 {
12807 /* Read the zlib header. In this case, it should be "ZLIB"
12808 followed by the uncompressed section size, 8 bytes in
12809 big-endian order. */
12810 uncompressed_size = start[4]; uncompressed_size <<= 8;
12811 uncompressed_size += start[5]; uncompressed_size <<= 8;
12812 uncompressed_size += start[6]; uncompressed_size <<= 8;
12813 uncompressed_size += start[7]; uncompressed_size <<= 8;
12814 uncompressed_size += start[8]; uncompressed_size <<= 8;
12815 uncompressed_size += start[9]; uncompressed_size <<= 8;
12816 uncompressed_size += start[10]; uncompressed_size <<= 8;
12817 uncompressed_size += start[11];
12818 start += 12;
12819 size -= 12;
12820 }
12821
12822 if (uncompressed_size
12823 && uncompress_section_contents (&start, uncompressed_size,
12824 &size))
77115a4a
L
12825 {
12826 /* Free the compressed buffer, update the section buffer
12827 and the section size if uncompress is successful. */
12828 free (section->start);
12829 section->start = start;
77115a4a
L
12830 }
12831 section->size = size;
59245841 12832 }
4a114e3e 12833
1b315056
CS
12834 if (section->start == NULL)
12835 return 0;
12836
19e6b90e 12837 if (debug_displays [debug].relocate)
d1c4b12b
NC
12838 apply_relocations ((FILE *) file, sec, section->start, section->size,
12839 & section->reloc_info, & section->num_relocs);
12840 else
12841 {
12842 section->reloc_info = NULL;
12843 section->num_relocs = 0;
12844 }
1007acb3 12845
1b315056 12846 return 1;
1007acb3
L
12847}
12848
657d0d47
CC
12849/* If this is not NULL, load_debug_section will only look for sections
12850 within the list of sections given here. */
12851unsigned int *section_subset = NULL;
12852
d966045b 12853int
2cf0635d 12854load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 12855{
2cf0635d
NC
12856 struct dwarf_section * section = &debug_displays [debug].section;
12857 Elf_Internal_Shdr * sec;
d966045b
DJ
12858
12859 /* Locate the debug section. */
657d0d47 12860 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
12861 if (sec != NULL)
12862 section->name = section->uncompressed_name;
12863 else
12864 {
657d0d47 12865 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
12866 if (sec != NULL)
12867 section->name = section->compressed_name;
12868 }
12869 if (sec == NULL)
12870 return 0;
12871
657d0d47
CC
12872 /* If we're loading from a subset of sections, and we've loaded
12873 a section matching this name before, it's likely that it's a
12874 different one. */
12875 if (section_subset != NULL)
12876 free_debug_section (debug);
12877
3f5e193b 12878 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
12879}
12880
19e6b90e
L
12881void
12882free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 12883{
2cf0635d 12884 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 12885
19e6b90e
L
12886 if (section->start == NULL)
12887 return;
1007acb3 12888
19e6b90e
L
12889 free ((char *) section->start);
12890 section->start = NULL;
12891 section->address = 0;
12892 section->size = 0;
1007acb3
L
12893}
12894
1007acb3 12895static int
657d0d47 12896display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 12897{
2cf0635d 12898 char * name = SECTION_NAME (section);
74e1a04b 12899 const char * print_name = printable_section_name (section);
19e6b90e
L
12900 bfd_size_type length;
12901 int result = 1;
3f5e193b 12902 int i;
1007acb3 12903
19e6b90e
L
12904 length = section->sh_size;
12905 if (length == 0)
1007acb3 12906 {
74e1a04b 12907 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
19e6b90e 12908 return 0;
1007acb3 12909 }
5dff79d8
NC
12910 if (section->sh_type == SHT_NOBITS)
12911 {
12912 /* There is no point in dumping the contents of a debugging section
12913 which has the NOBITS type - the bits in the file will be random.
12914 This can happen when a file containing a .eh_frame section is
12915 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
12916 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
12917 print_name);
5dff79d8
NC
12918 return 0;
12919 }
1007acb3 12920
0112cd26 12921 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 12922 name = ".debug_info";
1007acb3 12923
19e6b90e
L
12924 /* See if we know how to display the contents of this section. */
12925 for (i = 0; i < max; i++)
1b315056 12926 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 12927 || (i == line && const_strneq (name, ".debug_line."))
1b315056 12928 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 12929 {
2cf0635d 12930 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
12931 int secondary = (section != find_section (name));
12932
12933 if (secondary)
3f5e193b 12934 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 12935
b40bf0a2
NC
12936 if (i == line && const_strneq (name, ".debug_line."))
12937 sec->name = name;
12938 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
12939 sec->name = sec->uncompressed_name;
12940 else
12941 sec->name = sec->compressed_name;
3f5e193b
NC
12942 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
12943 section, file))
19e6b90e 12944 {
657d0d47
CC
12945 /* If this debug section is part of a CU/TU set in a .dwp file,
12946 restrict load_debug_section to the sections in that set. */
12947 section_subset = find_cu_tu_set (file, shndx);
12948
19e6b90e 12949 result &= debug_displays[i].display (sec, file);
1007acb3 12950
657d0d47
CC
12951 section_subset = NULL;
12952
d966045b 12953 if (secondary || (i != info && i != abbrev))
3f5e193b 12954 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 12955 }
1007acb3 12956
19e6b90e
L
12957 break;
12958 }
1007acb3 12959
19e6b90e 12960 if (i == max)
1007acb3 12961 {
74e1a04b 12962 printf (_("Unrecognized debug section: %s\n"), print_name);
19e6b90e 12963 result = 0;
1007acb3
L
12964 }
12965
19e6b90e 12966 return result;
5b18a4bc 12967}
103f02d3 12968
aef1f6d0
DJ
12969/* Set DUMP_SECTS for all sections where dumps were requested
12970 based on section name. */
12971
12972static void
12973initialise_dumps_byname (void)
12974{
2cf0635d 12975 struct dump_list_entry * cur;
aef1f6d0
DJ
12976
12977 for (cur = dump_sects_byname; cur; cur = cur->next)
12978 {
12979 unsigned int i;
12980 int any;
12981
12982 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
12983 if (streq (SECTION_NAME (section_headers + i), cur->name))
12984 {
09c11c86 12985 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
12986 any = 1;
12987 }
12988
12989 if (!any)
12990 warn (_("Section '%s' was not dumped because it does not exist!\n"),
12991 cur->name);
12992 }
12993}
12994
5b18a4bc 12995static void
2cf0635d 12996process_section_contents (FILE * file)
5b18a4bc 12997{
2cf0635d 12998 Elf_Internal_Shdr * section;
19e6b90e 12999 unsigned int i;
103f02d3 13000
19e6b90e
L
13001 if (! do_dump)
13002 return;
103f02d3 13003
aef1f6d0
DJ
13004 initialise_dumps_byname ();
13005
19e6b90e
L
13006 for (i = 0, section = section_headers;
13007 i < elf_header.e_shnum && i < num_dump_sects;
13008 i++, section++)
13009 {
13010#ifdef SUPPORT_DISASSEMBLY
13011 if (dump_sects[i] & DISASS_DUMP)
13012 disassemble_section (section, file);
13013#endif
13014 if (dump_sects[i] & HEX_DUMP)
cf13d699 13015 dump_section_as_bytes (section, file, FALSE);
103f02d3 13016
cf13d699
NC
13017 if (dump_sects[i] & RELOC_DUMP)
13018 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
13019
13020 if (dump_sects[i] & STRING_DUMP)
13021 dump_section_as_strings (section, file);
cf13d699
NC
13022
13023 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 13024 display_debug_section (i, section, file);
5b18a4bc 13025 }
103f02d3 13026
19e6b90e
L
13027 /* Check to see if the user requested a
13028 dump of a section that does not exist. */
13029 while (i++ < num_dump_sects)
13030 if (dump_sects[i])
13031 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 13032}
103f02d3 13033
5b18a4bc 13034static void
19e6b90e 13035process_mips_fpe_exception (int mask)
5b18a4bc 13036{
19e6b90e
L
13037 if (mask)
13038 {
13039 int first = 1;
13040 if (mask & OEX_FPU_INEX)
13041 fputs ("INEX", stdout), first = 0;
13042 if (mask & OEX_FPU_UFLO)
13043 printf ("%sUFLO", first ? "" : "|"), first = 0;
13044 if (mask & OEX_FPU_OFLO)
13045 printf ("%sOFLO", first ? "" : "|"), first = 0;
13046 if (mask & OEX_FPU_DIV0)
13047 printf ("%sDIV0", first ? "" : "|"), first = 0;
13048 if (mask & OEX_FPU_INVAL)
13049 printf ("%sINVAL", first ? "" : "|");
13050 }
5b18a4bc 13051 else
19e6b90e 13052 fputs ("0", stdout);
5b18a4bc 13053}
103f02d3 13054
f6f0e17b
NC
13055/* Display's the value of TAG at location P. If TAG is
13056 greater than 0 it is assumed to be an unknown tag, and
13057 a message is printed to this effect. Otherwise it is
13058 assumed that a message has already been printed.
13059
13060 If the bottom bit of TAG is set it assumed to have a
13061 string value, otherwise it is assumed to have an integer
13062 value.
13063
13064 Returns an updated P pointing to the first unread byte
13065 beyond the end of TAG's value.
13066
13067 Reads at or beyond END will not be made. */
13068
13069static unsigned char *
13070display_tag_value (int tag,
13071 unsigned char * p,
13072 const unsigned char * const end)
13073{
13074 unsigned long val;
13075
13076 if (tag > 0)
13077 printf (" Tag_unknown_%d: ", tag);
13078
13079 if (p >= end)
13080 {
4082ef84 13081 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
13082 }
13083 else if (tag & 1)
13084 {
071436c6
NC
13085 /* PR 17531 file: 027-19978-0.004. */
13086 size_t maxlen = (end - p) - 1;
13087
13088 putchar ('"');
4082ef84
NC
13089 if (maxlen > 0)
13090 {
13091 print_symbol ((int) maxlen, (const char *) p);
13092 p += strnlen ((char *) p, maxlen) + 1;
13093 }
13094 else
13095 {
13096 printf (_("<corrupt string tag>"));
13097 p = (unsigned char *) end;
13098 }
071436c6 13099 printf ("\"\n");
f6f0e17b
NC
13100 }
13101 else
13102 {
13103 unsigned int len;
13104
13105 val = read_uleb128 (p, &len, end);
13106 p += len;
13107 printf ("%ld (0x%lx)\n", val, val);
13108 }
13109
4082ef84 13110 assert (p <= end);
f6f0e17b
NC
13111 return p;
13112}
13113
11c1ff18
PB
13114/* ARM EABI attributes section. */
13115typedef struct
13116{
70e99720 13117 unsigned int tag;
2cf0635d 13118 const char * name;
11c1ff18 13119 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 13120 unsigned int type;
2cf0635d 13121 const char ** table;
11c1ff18
PB
13122} arm_attr_public_tag;
13123
2cf0635d 13124static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 13125 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ff8646ee
TP
13126 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "", "v8-M.baseline",
13127 "v8-M.mainline"};
2cf0635d
NC
13128static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
13129static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 13130 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 13131static const char * arm_attr_tag_FP_arch[] =
bca38921 13132 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 13133 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 13134static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 13135static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
13136 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
13137 "NEON for ARMv8.1"};
2cf0635d 13138static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
13139 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
13140 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 13141static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 13142 {"V6", "SB", "TLS", "Unused"};
2cf0635d 13143static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 13144 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 13145static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 13146 {"Absolute", "PC-relative", "None"};
2cf0635d 13147static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 13148 {"None", "direct", "GOT-indirect"};
2cf0635d 13149static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 13150 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
13151static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
13152static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 13153 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
13154static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
13155static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
13156static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 13157 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 13158static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 13159 {"Unused", "small", "int", "forced to int"};
2cf0635d 13160static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 13161 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 13162static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 13163 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 13164static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 13165 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 13166static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
13167 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
13168 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 13169static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
13170 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
13171 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 13172static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 13173static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 13174 {"Not Allowed", "Allowed"};
2cf0635d 13175static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 13176 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
13177static const char * arm_attr_tag_DSP_extension[] =
13178 {"Follow architecture", "Allowed"};
dd24e3da 13179static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
13180 {"Not Allowed", "Allowed"};
13181static const char * arm_attr_tag_DIV_use[] =
dd24e3da 13182 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 13183 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
13184static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
13185static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 13186 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 13187 "TrustZone and Virtualization Extensions"};
dd24e3da 13188static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 13189 {"Not Allowed", "Allowed"};
11c1ff18
PB
13190
13191#define LOOKUP(id, name) \
13192 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 13193static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
13194{
13195 {4, "CPU_raw_name", 1, NULL},
13196 {5, "CPU_name", 1, NULL},
13197 LOOKUP(6, CPU_arch),
13198 {7, "CPU_arch_profile", 0, NULL},
13199 LOOKUP(8, ARM_ISA_use),
13200 LOOKUP(9, THUMB_ISA_use),
75375b3e 13201 LOOKUP(10, FP_arch),
11c1ff18 13202 LOOKUP(11, WMMX_arch),
f5f53991
AS
13203 LOOKUP(12, Advanced_SIMD_arch),
13204 LOOKUP(13, PCS_config),
11c1ff18
PB
13205 LOOKUP(14, ABI_PCS_R9_use),
13206 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 13207 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
13208 LOOKUP(17, ABI_PCS_GOT_use),
13209 LOOKUP(18, ABI_PCS_wchar_t),
13210 LOOKUP(19, ABI_FP_rounding),
13211 LOOKUP(20, ABI_FP_denormal),
13212 LOOKUP(21, ABI_FP_exceptions),
13213 LOOKUP(22, ABI_FP_user_exceptions),
13214 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
13215 {24, "ABI_align_needed", 0, NULL},
13216 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
13217 LOOKUP(26, ABI_enum_size),
13218 LOOKUP(27, ABI_HardFP_use),
13219 LOOKUP(28, ABI_VFP_args),
13220 LOOKUP(29, ABI_WMMX_args),
13221 LOOKUP(30, ABI_optimization_goals),
13222 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 13223 {32, "compatibility", 0, NULL},
f5f53991 13224 LOOKUP(34, CPU_unaligned_access),
75375b3e 13225 LOOKUP(36, FP_HP_extension),
8e79c3df 13226 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
13227 LOOKUP(42, MPextension_use),
13228 LOOKUP(44, DIV_use),
15afaa63 13229 LOOKUP(46, DSP_extension),
f5f53991
AS
13230 {64, "nodefaults", 0, NULL},
13231 {65, "also_compatible_with", 0, NULL},
13232 LOOKUP(66, T2EE_use),
13233 {67, "conformance", 1, NULL},
13234 LOOKUP(68, Virtualization_use),
cd21e546 13235 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
13236};
13237#undef LOOKUP
13238
11c1ff18 13239static unsigned char *
f6f0e17b
NC
13240display_arm_attribute (unsigned char * p,
13241 const unsigned char * const end)
11c1ff18 13242{
70e99720 13243 unsigned int tag;
11c1ff18 13244 unsigned int len;
70e99720 13245 unsigned int val;
2cf0635d 13246 arm_attr_public_tag * attr;
11c1ff18 13247 unsigned i;
70e99720 13248 unsigned int type;
11c1ff18 13249
f6f0e17b 13250 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
13251 p += len;
13252 attr = NULL;
2cf0635d 13253 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
13254 {
13255 if (arm_attr_public_tags[i].tag == tag)
13256 {
13257 attr = &arm_attr_public_tags[i];
13258 break;
13259 }
13260 }
13261
13262 if (attr)
13263 {
13264 printf (" Tag_%s: ", attr->name);
13265 switch (attr->type)
13266 {
13267 case 0:
13268 switch (tag)
13269 {
13270 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 13271 val = read_uleb128 (p, &len, end);
11c1ff18
PB
13272 p += len;
13273 switch (val)
13274 {
2b692964
NC
13275 case 0: printf (_("None\n")); break;
13276 case 'A': printf (_("Application\n")); break;
13277 case 'R': printf (_("Realtime\n")); break;
13278 case 'M': printf (_("Microcontroller\n")); break;
13279 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
13280 default: printf ("??? (%d)\n", val); break;
13281 }
13282 break;
13283
75375b3e 13284 case 24: /* Tag_align_needed. */
f6f0e17b 13285 val = read_uleb128 (p, &len, end);
75375b3e
MGD
13286 p += len;
13287 switch (val)
13288 {
2b692964
NC
13289 case 0: printf (_("None\n")); break;
13290 case 1: printf (_("8-byte\n")); break;
13291 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
13292 case 3: printf ("??? 3\n"); break;
13293 default:
13294 if (val <= 12)
dd24e3da 13295 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
13296 1 << val);
13297 else
13298 printf ("??? (%d)\n", val);
13299 break;
13300 }
13301 break;
13302
13303 case 25: /* Tag_align_preserved. */
f6f0e17b 13304 val = read_uleb128 (p, &len, end);
75375b3e
MGD
13305 p += len;
13306 switch (val)
13307 {
2b692964
NC
13308 case 0: printf (_("None\n")); break;
13309 case 1: printf (_("8-byte, except leaf SP\n")); break;
13310 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
13311 case 3: printf ("??? 3\n"); break;
13312 default:
13313 if (val <= 12)
dd24e3da 13314 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
13315 1 << val);
13316 else
13317 printf ("??? (%d)\n", val);
13318 break;
13319 }
13320 break;
13321
11c1ff18 13322 case 32: /* Tag_compatibility. */
071436c6 13323 {
071436c6
NC
13324 val = read_uleb128 (p, &len, end);
13325 p += len;
071436c6 13326 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
13327 if (p < end - 1)
13328 {
13329 size_t maxlen = (end - p) - 1;
13330
13331 print_symbol ((int) maxlen, (const char *) p);
13332 p += strnlen ((char *) p, maxlen) + 1;
13333 }
13334 else
13335 {
13336 printf (_("<corrupt>"));
13337 p = (unsigned char *) end;
13338 }
071436c6 13339 putchar ('\n');
071436c6 13340 }
11c1ff18
PB
13341 break;
13342
f5f53991 13343 case 64: /* Tag_nodefaults. */
541a3cbd
NC
13344 /* PR 17531: file: 001-505008-0.01. */
13345 if (p < end)
13346 p++;
2b692964 13347 printf (_("True\n"));
f5f53991
AS
13348 break;
13349
13350 case 65: /* Tag_also_compatible_with. */
f6f0e17b 13351 val = read_uleb128 (p, &len, end);
f5f53991
AS
13352 p += len;
13353 if (val == 6 /* Tag_CPU_arch. */)
13354 {
f6f0e17b 13355 val = read_uleb128 (p, &len, end);
f5f53991 13356 p += len;
071436c6 13357 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
13358 printf ("??? (%d)\n", val);
13359 else
13360 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
13361 }
13362 else
13363 printf ("???\n");
071436c6
NC
13364 while (p < end && *(p++) != '\0' /* NUL terminator. */)
13365 ;
f5f53991
AS
13366 break;
13367
11c1ff18 13368 default:
bee0ee85
NC
13369 printf (_("<unknown: %d>\n"), tag);
13370 break;
11c1ff18
PB
13371 }
13372 return p;
13373
13374 case 1:
f6f0e17b 13375 return display_tag_value (-1, p, end);
11c1ff18 13376 case 2:
f6f0e17b 13377 return display_tag_value (0, p, end);
11c1ff18
PB
13378
13379 default:
13380 assert (attr->type & 0x80);
f6f0e17b 13381 val = read_uleb128 (p, &len, end);
11c1ff18
PB
13382 p += len;
13383 type = attr->type & 0x7f;
13384 if (val >= type)
13385 printf ("??? (%d)\n", val);
13386 else
13387 printf ("%s\n", attr->table[val]);
13388 return p;
13389 }
13390 }
11c1ff18 13391
f6f0e17b 13392 return display_tag_value (tag, p, end);
11c1ff18
PB
13393}
13394
104d59d1 13395static unsigned char *
60bca95a 13396display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
13397 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
13398 const unsigned char * const end)
104d59d1
JM
13399{
13400 int tag;
13401 unsigned int len;
13402 int val;
104d59d1 13403
f6f0e17b 13404 tag = read_uleb128 (p, &len, end);
104d59d1
JM
13405 p += len;
13406
13407 /* Tag_compatibility is the only generic GNU attribute defined at
13408 present. */
13409 if (tag == 32)
13410 {
f6f0e17b 13411 val = read_uleb128 (p, &len, end);
104d59d1 13412 p += len;
071436c6
NC
13413
13414 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
13415 if (p == end)
13416 {
071436c6 13417 printf (_("<corrupt>\n"));
f6f0e17b
NC
13418 warn (_("corrupt vendor attribute\n"));
13419 }
13420 else
13421 {
4082ef84
NC
13422 if (p < end - 1)
13423 {
13424 size_t maxlen = (end - p) - 1;
071436c6 13425
4082ef84
NC
13426 print_symbol ((int) maxlen, (const char *) p);
13427 p += strnlen ((char *) p, maxlen) + 1;
13428 }
13429 else
13430 {
13431 printf (_("<corrupt>"));
13432 p = (unsigned char *) end;
13433 }
071436c6 13434 putchar ('\n');
f6f0e17b 13435 }
104d59d1
JM
13436 return p;
13437 }
13438
13439 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 13440 return display_proc_gnu_attribute (p, tag, end);
104d59d1 13441
f6f0e17b 13442 return display_tag_value (tag, p, end);
104d59d1
JM
13443}
13444
34c8bcba 13445static unsigned char *
f6f0e17b
NC
13446display_power_gnu_attribute (unsigned char * p,
13447 int tag,
13448 const unsigned char * const end)
34c8bcba 13449{
34c8bcba 13450 unsigned int len;
005d79fd 13451 unsigned int val;
34c8bcba
JM
13452
13453 if (tag == Tag_GNU_Power_ABI_FP)
13454 {
f6f0e17b 13455 val = read_uleb128 (p, &len, end);
34c8bcba
JM
13456 p += len;
13457 printf (" Tag_GNU_Power_ABI_FP: ");
005d79fd
AM
13458 if (len == 0)
13459 {
13460 printf (_("<corrupt>\n"));
13461 return p;
13462 }
60bca95a 13463
005d79fd
AM
13464 if (val > 15)
13465 printf ("(%#x), ", val);
13466
13467 switch (val & 3)
34c8bcba
JM
13468 {
13469 case 0:
005d79fd 13470 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
13471 break;
13472 case 1:
005d79fd 13473 printf (_("hard float, "));
34c8bcba
JM
13474 break;
13475 case 2:
005d79fd 13476 printf (_("soft float, "));
34c8bcba 13477 break;
3c7b9897 13478 case 3:
005d79fd 13479 printf (_("single-precision hard float, "));
3c7b9897 13480 break;
005d79fd
AM
13481 }
13482
13483 switch (val & 0xC)
13484 {
13485 case 0:
13486 printf (_("unspecified long double\n"));
13487 break;
13488 case 4:
13489 printf (_("128-bit IBM long double\n"));
13490 break;
13491 case 8:
13492 printf (_("64-bit long double\n"));
13493 break;
13494 case 12:
13495 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
13496 break;
13497 }
13498 return p;
005d79fd 13499 }
34c8bcba 13500
c6e65352
DJ
13501 if (tag == Tag_GNU_Power_ABI_Vector)
13502 {
f6f0e17b 13503 val = read_uleb128 (p, &len, end);
c6e65352
DJ
13504 p += len;
13505 printf (" Tag_GNU_Power_ABI_Vector: ");
005d79fd
AM
13506 if (len == 0)
13507 {
13508 printf (_("<corrupt>\n"));
13509 return p;
13510 }
13511
13512 if (val > 3)
13513 printf ("(%#x), ", val);
13514
13515 switch (val & 3)
c6e65352
DJ
13516 {
13517 case 0:
005d79fd 13518 printf (_("unspecified\n"));
c6e65352
DJ
13519 break;
13520 case 1:
005d79fd 13521 printf (_("generic\n"));
c6e65352
DJ
13522 break;
13523 case 2:
13524 printf ("AltiVec\n");
13525 break;
13526 case 3:
13527 printf ("SPE\n");
13528 break;
c6e65352
DJ
13529 }
13530 return p;
005d79fd 13531 }
c6e65352 13532
f82e0623
NF
13533 if (tag == Tag_GNU_Power_ABI_Struct_Return)
13534 {
005d79fd
AM
13535 val = read_uleb128 (p, &len, end);
13536 p += len;
13537 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
13538 if (len == 0)
f6f0e17b 13539 {
005d79fd 13540 printf (_("<corrupt>\n"));
f6f0e17b
NC
13541 return p;
13542 }
0b4362b0 13543
005d79fd
AM
13544 if (val > 2)
13545 printf ("(%#x), ", val);
13546
13547 switch (val & 3)
13548 {
13549 case 0:
13550 printf (_("unspecified\n"));
13551 break;
13552 case 1:
13553 printf ("r3/r4\n");
13554 break;
13555 case 2:
13556 printf (_("memory\n"));
13557 break;
13558 case 3:
13559 printf ("???\n");
13560 break;
13561 }
f82e0623
NF
13562 return p;
13563 }
13564
f6f0e17b 13565 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
13566}
13567
643f7afb
AK
13568static unsigned char *
13569display_s390_gnu_attribute (unsigned char * p,
13570 int tag,
13571 const unsigned char * const end)
13572{
13573 unsigned int len;
13574 int val;
13575
13576 if (tag == Tag_GNU_S390_ABI_Vector)
13577 {
13578 val = read_uleb128 (p, &len, end);
13579 p += len;
13580 printf (" Tag_GNU_S390_ABI_Vector: ");
13581
13582 switch (val)
13583 {
13584 case 0:
13585 printf (_("any\n"));
13586 break;
13587 case 1:
13588 printf (_("software\n"));
13589 break;
13590 case 2:
13591 printf (_("hardware\n"));
13592 break;
13593 default:
13594 printf ("??? (%d)\n", val);
13595 break;
13596 }
13597 return p;
13598 }
13599
13600 return display_tag_value (tag & 1, p, end);
13601}
13602
9e8c70f9
DM
13603static void
13604display_sparc_hwcaps (int mask)
13605{
13606 if (mask)
13607 {
13608 int first = 1;
071436c6 13609
9e8c70f9
DM
13610 if (mask & ELF_SPARC_HWCAP_MUL32)
13611 fputs ("mul32", stdout), first = 0;
13612 if (mask & ELF_SPARC_HWCAP_DIV32)
13613 printf ("%sdiv32", first ? "" : "|"), first = 0;
13614 if (mask & ELF_SPARC_HWCAP_FSMULD)
13615 printf ("%sfsmuld", first ? "" : "|"), first = 0;
13616 if (mask & ELF_SPARC_HWCAP_V8PLUS)
13617 printf ("%sv8plus", first ? "" : "|"), first = 0;
13618 if (mask & ELF_SPARC_HWCAP_POPC)
13619 printf ("%spopc", first ? "" : "|"), first = 0;
13620 if (mask & ELF_SPARC_HWCAP_VIS)
13621 printf ("%svis", first ? "" : "|"), first = 0;
13622 if (mask & ELF_SPARC_HWCAP_VIS2)
13623 printf ("%svis2", first ? "" : "|"), first = 0;
13624 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
13625 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
13626 if (mask & ELF_SPARC_HWCAP_FMAF)
13627 printf ("%sfmaf", first ? "" : "|"), first = 0;
13628 if (mask & ELF_SPARC_HWCAP_VIS3)
13629 printf ("%svis3", first ? "" : "|"), first = 0;
13630 if (mask & ELF_SPARC_HWCAP_HPC)
13631 printf ("%shpc", first ? "" : "|"), first = 0;
13632 if (mask & ELF_SPARC_HWCAP_RANDOM)
13633 printf ("%srandom", first ? "" : "|"), first = 0;
13634 if (mask & ELF_SPARC_HWCAP_TRANS)
13635 printf ("%strans", first ? "" : "|"), first = 0;
13636 if (mask & ELF_SPARC_HWCAP_FJFMAU)
13637 printf ("%sfjfmau", first ? "" : "|"), first = 0;
13638 if (mask & ELF_SPARC_HWCAP_IMA)
13639 printf ("%sima", first ? "" : "|"), first = 0;
13640 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
13641 printf ("%scspare", first ? "" : "|"), first = 0;
13642 }
13643 else
071436c6
NC
13644 fputc ('0', stdout);
13645 fputc ('\n', stdout);
9e8c70f9
DM
13646}
13647
3d68f91c
JM
13648static void
13649display_sparc_hwcaps2 (int mask)
13650{
13651 if (mask)
13652 {
13653 int first = 1;
071436c6 13654
3d68f91c
JM
13655 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
13656 fputs ("fjathplus", stdout), first = 0;
13657 if (mask & ELF_SPARC_HWCAP2_VIS3B)
13658 printf ("%svis3b", first ? "" : "|"), first = 0;
13659 if (mask & ELF_SPARC_HWCAP2_ADP)
13660 printf ("%sadp", first ? "" : "|"), first = 0;
13661 if (mask & ELF_SPARC_HWCAP2_SPARC5)
13662 printf ("%ssparc5", first ? "" : "|"), first = 0;
13663 if (mask & ELF_SPARC_HWCAP2_MWAIT)
13664 printf ("%smwait", first ? "" : "|"), first = 0;
13665 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
13666 printf ("%sxmpmul", first ? "" : "|"), first = 0;
13667 if (mask & ELF_SPARC_HWCAP2_XMONT)
13668 printf ("%sxmont2", first ? "" : "|"), first = 0;
13669 if (mask & ELF_SPARC_HWCAP2_NSEC)
13670 printf ("%snsec", first ? "" : "|"), first = 0;
13671 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
13672 printf ("%sfjathhpc", first ? "" : "|"), first = 0;
13673 if (mask & ELF_SPARC_HWCAP2_FJDES)
13674 printf ("%sfjdes", first ? "" : "|"), first = 0;
13675 if (mask & ELF_SPARC_HWCAP2_FJAES)
13676 printf ("%sfjaes", first ? "" : "|"), first = 0;
13677 }
13678 else
071436c6
NC
13679 fputc ('0', stdout);
13680 fputc ('\n', stdout);
3d68f91c
JM
13681}
13682
9e8c70f9 13683static unsigned char *
f6f0e17b
NC
13684display_sparc_gnu_attribute (unsigned char * p,
13685 int tag,
13686 const unsigned char * const end)
9e8c70f9 13687{
3d68f91c
JM
13688 unsigned int len;
13689 int val;
13690
9e8c70f9
DM
13691 if (tag == Tag_GNU_Sparc_HWCAPS)
13692 {
f6f0e17b 13693 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
13694 p += len;
13695 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
13696 display_sparc_hwcaps (val);
13697 return p;
3d68f91c
JM
13698 }
13699 if (tag == Tag_GNU_Sparc_HWCAPS2)
13700 {
13701 val = read_uleb128 (p, &len, end);
13702 p += len;
13703 printf (" Tag_GNU_Sparc_HWCAPS2: ");
13704 display_sparc_hwcaps2 (val);
13705 return p;
13706 }
9e8c70f9 13707
f6f0e17b 13708 return display_tag_value (tag, p, end);
9e8c70f9
DM
13709}
13710
351cdf24
MF
13711static void
13712print_mips_fp_abi_value (int val)
13713{
13714 switch (val)
13715 {
13716 case Val_GNU_MIPS_ABI_FP_ANY:
13717 printf (_("Hard or soft float\n"));
13718 break;
13719 case Val_GNU_MIPS_ABI_FP_DOUBLE:
13720 printf (_("Hard float (double precision)\n"));
13721 break;
13722 case Val_GNU_MIPS_ABI_FP_SINGLE:
13723 printf (_("Hard float (single precision)\n"));
13724 break;
13725 case Val_GNU_MIPS_ABI_FP_SOFT:
13726 printf (_("Soft float\n"));
13727 break;
13728 case Val_GNU_MIPS_ABI_FP_OLD_64:
13729 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
13730 break;
13731 case Val_GNU_MIPS_ABI_FP_XX:
13732 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
13733 break;
13734 case Val_GNU_MIPS_ABI_FP_64:
13735 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
13736 break;
13737 case Val_GNU_MIPS_ABI_FP_64A:
13738 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
13739 break;
3350cc01
CM
13740 case Val_GNU_MIPS_ABI_FP_NAN2008:
13741 printf (_("NaN 2008 compatibility\n"));
13742 break;
351cdf24
MF
13743 default:
13744 printf ("??? (%d)\n", val);
13745 break;
13746 }
13747}
13748
2cf19d5c 13749static unsigned char *
f6f0e17b
NC
13750display_mips_gnu_attribute (unsigned char * p,
13751 int tag,
13752 const unsigned char * const end)
2cf19d5c 13753{
2cf19d5c
JM
13754 if (tag == Tag_GNU_MIPS_ABI_FP)
13755 {
f6f0e17b
NC
13756 unsigned int len;
13757 int val;
13758
13759 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
13760 p += len;
13761 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 13762
351cdf24
MF
13763 print_mips_fp_abi_value (val);
13764
2cf19d5c
JM
13765 return p;
13766 }
13767
a9f58168
CF
13768 if (tag == Tag_GNU_MIPS_ABI_MSA)
13769 {
13770 unsigned int len;
13771 int val;
13772
13773 val = read_uleb128 (p, &len, end);
13774 p += len;
13775 printf (" Tag_GNU_MIPS_ABI_MSA: ");
13776
13777 switch (val)
13778 {
13779 case Val_GNU_MIPS_ABI_MSA_ANY:
13780 printf (_("Any MSA or not\n"));
13781 break;
13782 case Val_GNU_MIPS_ABI_MSA_128:
13783 printf (_("128-bit MSA\n"));
13784 break;
13785 default:
13786 printf ("??? (%d)\n", val);
13787 break;
13788 }
13789 return p;
13790 }
13791
f6f0e17b 13792 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
13793}
13794
59e6276b 13795static unsigned char *
f6f0e17b
NC
13796display_tic6x_attribute (unsigned char * p,
13797 const unsigned char * const end)
59e6276b
JM
13798{
13799 int tag;
13800 unsigned int len;
13801 int val;
13802
f6f0e17b 13803 tag = read_uleb128 (p, &len, end);
59e6276b
JM
13804 p += len;
13805
13806 switch (tag)
13807 {
75fa6dc1 13808 case Tag_ISA:
f6f0e17b 13809 val = read_uleb128 (p, &len, end);
59e6276b 13810 p += len;
75fa6dc1 13811 printf (" Tag_ISA: ");
59e6276b
JM
13812
13813 switch (val)
13814 {
75fa6dc1 13815 case C6XABI_Tag_ISA_none:
59e6276b
JM
13816 printf (_("None\n"));
13817 break;
75fa6dc1 13818 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
13819 printf ("C62x\n");
13820 break;
75fa6dc1 13821 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
13822 printf ("C67x\n");
13823 break;
75fa6dc1 13824 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
13825 printf ("C67x+\n");
13826 break;
75fa6dc1 13827 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
13828 printf ("C64x\n");
13829 break;
75fa6dc1 13830 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
13831 printf ("C64x+\n");
13832 break;
75fa6dc1 13833 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
13834 printf ("C674x\n");
13835 break;
13836 default:
13837 printf ("??? (%d)\n", val);
13838 break;
13839 }
13840 return p;
13841
87779176 13842 case Tag_ABI_wchar_t:
f6f0e17b 13843 val = read_uleb128 (p, &len, end);
87779176
JM
13844 p += len;
13845 printf (" Tag_ABI_wchar_t: ");
13846 switch (val)
13847 {
13848 case 0:
13849 printf (_("Not used\n"));
13850 break;
13851 case 1:
13852 printf (_("2 bytes\n"));
13853 break;
13854 case 2:
13855 printf (_("4 bytes\n"));
13856 break;
13857 default:
13858 printf ("??? (%d)\n", val);
13859 break;
13860 }
13861 return p;
13862
13863 case Tag_ABI_stack_align_needed:
f6f0e17b 13864 val = read_uleb128 (p, &len, end);
87779176
JM
13865 p += len;
13866 printf (" Tag_ABI_stack_align_needed: ");
13867 switch (val)
13868 {
13869 case 0:
13870 printf (_("8-byte\n"));
13871 break;
13872 case 1:
13873 printf (_("16-byte\n"));
13874 break;
13875 default:
13876 printf ("??? (%d)\n", val);
13877 break;
13878 }
13879 return p;
13880
13881 case Tag_ABI_stack_align_preserved:
f6f0e17b 13882 val = read_uleb128 (p, &len, end);
87779176
JM
13883 p += len;
13884 printf (" Tag_ABI_stack_align_preserved: ");
13885 switch (val)
13886 {
13887 case 0:
13888 printf (_("8-byte\n"));
13889 break;
13890 case 1:
13891 printf (_("16-byte\n"));
13892 break;
13893 default:
13894 printf ("??? (%d)\n", val);
13895 break;
13896 }
13897 return p;
13898
b5593623 13899 case Tag_ABI_DSBT:
f6f0e17b 13900 val = read_uleb128 (p, &len, end);
b5593623
JM
13901 p += len;
13902 printf (" Tag_ABI_DSBT: ");
13903 switch (val)
13904 {
13905 case 0:
13906 printf (_("DSBT addressing not used\n"));
13907 break;
13908 case 1:
13909 printf (_("DSBT addressing used\n"));
13910 break;
13911 default:
13912 printf ("??? (%d)\n", val);
13913 break;
13914 }
13915 return p;
13916
87779176 13917 case Tag_ABI_PID:
f6f0e17b 13918 val = read_uleb128 (p, &len, end);
87779176
JM
13919 p += len;
13920 printf (" Tag_ABI_PID: ");
13921 switch (val)
13922 {
13923 case 0:
13924 printf (_("Data addressing position-dependent\n"));
13925 break;
13926 case 1:
13927 printf (_("Data addressing position-independent, GOT near DP\n"));
13928 break;
13929 case 2:
13930 printf (_("Data addressing position-independent, GOT far from DP\n"));
13931 break;
13932 default:
13933 printf ("??? (%d)\n", val);
13934 break;
13935 }
13936 return p;
13937
13938 case Tag_ABI_PIC:
f6f0e17b 13939 val = read_uleb128 (p, &len, end);
87779176
JM
13940 p += len;
13941 printf (" Tag_ABI_PIC: ");
13942 switch (val)
13943 {
13944 case 0:
13945 printf (_("Code addressing position-dependent\n"));
13946 break;
13947 case 1:
13948 printf (_("Code addressing position-independent\n"));
13949 break;
13950 default:
13951 printf ("??? (%d)\n", val);
13952 break;
13953 }
13954 return p;
13955
13956 case Tag_ABI_array_object_alignment:
f6f0e17b 13957 val = read_uleb128 (p, &len, end);
87779176
JM
13958 p += len;
13959 printf (" Tag_ABI_array_object_alignment: ");
13960 switch (val)
13961 {
13962 case 0:
13963 printf (_("8-byte\n"));
13964 break;
13965 case 1:
13966 printf (_("4-byte\n"));
13967 break;
13968 case 2:
13969 printf (_("16-byte\n"));
13970 break;
13971 default:
13972 printf ("??? (%d)\n", val);
13973 break;
13974 }
13975 return p;
13976
13977 case Tag_ABI_array_object_align_expected:
f6f0e17b 13978 val = read_uleb128 (p, &len, end);
87779176
JM
13979 p += len;
13980 printf (" Tag_ABI_array_object_align_expected: ");
13981 switch (val)
13982 {
13983 case 0:
13984 printf (_("8-byte\n"));
13985 break;
13986 case 1:
13987 printf (_("4-byte\n"));
13988 break;
13989 case 2:
13990 printf (_("16-byte\n"));
13991 break;
13992 default:
13993 printf ("??? (%d)\n", val);
13994 break;
13995 }
13996 return p;
13997
3cbd1c06 13998 case Tag_ABI_compatibility:
071436c6 13999 {
071436c6
NC
14000 val = read_uleb128 (p, &len, end);
14001 p += len;
14002 printf (" Tag_ABI_compatibility: ");
071436c6 14003 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
14004 if (p < end - 1)
14005 {
14006 size_t maxlen = (end - p) - 1;
14007
14008 print_symbol ((int) maxlen, (const char *) p);
14009 p += strnlen ((char *) p, maxlen) + 1;
14010 }
14011 else
14012 {
14013 printf (_("<corrupt>"));
14014 p = (unsigned char *) end;
14015 }
071436c6 14016 putchar ('\n');
071436c6
NC
14017 return p;
14018 }
87779176
JM
14019
14020 case Tag_ABI_conformance:
071436c6 14021 {
4082ef84
NC
14022 printf (" Tag_ABI_conformance: \"");
14023 if (p < end - 1)
14024 {
14025 size_t maxlen = (end - p) - 1;
071436c6 14026
4082ef84
NC
14027 print_symbol ((int) maxlen, (const char *) p);
14028 p += strnlen ((char *) p, maxlen) + 1;
14029 }
14030 else
14031 {
14032 printf (_("<corrupt>"));
14033 p = (unsigned char *) end;
14034 }
071436c6 14035 printf ("\"\n");
071436c6
NC
14036 return p;
14037 }
59e6276b
JM
14038 }
14039
f6f0e17b
NC
14040 return display_tag_value (tag, p, end);
14041}
59e6276b 14042
f6f0e17b
NC
14043static void
14044display_raw_attribute (unsigned char * p, unsigned char * end)
14045{
14046 unsigned long addr = 0;
14047 size_t bytes = end - p;
14048
e0a31db1 14049 assert (end > p);
f6f0e17b 14050 while (bytes)
87779176 14051 {
f6f0e17b
NC
14052 int j;
14053 int k;
14054 int lbytes = (bytes > 16 ? 16 : bytes);
14055
14056 printf (" 0x%8.8lx ", addr);
14057
14058 for (j = 0; j < 16; j++)
14059 {
14060 if (j < lbytes)
14061 printf ("%2.2x", p[j]);
14062 else
14063 printf (" ");
14064
14065 if ((j & 3) == 3)
14066 printf (" ");
14067 }
14068
14069 for (j = 0; j < lbytes; j++)
14070 {
14071 k = p[j];
14072 if (k >= ' ' && k < 0x7f)
14073 printf ("%c", k);
14074 else
14075 printf (".");
14076 }
14077
14078 putchar ('\n');
14079
14080 p += lbytes;
14081 bytes -= lbytes;
14082 addr += lbytes;
87779176 14083 }
59e6276b 14084
f6f0e17b 14085 putchar ('\n');
59e6276b
JM
14086}
14087
13761a11
NC
14088static unsigned char *
14089display_msp430x_attribute (unsigned char * p,
14090 const unsigned char * const end)
14091{
14092 unsigned int len;
14093 int val;
14094 int tag;
14095
14096 tag = read_uleb128 (p, & len, end);
14097 p += len;
0b4362b0 14098
13761a11
NC
14099 switch (tag)
14100 {
14101 case OFBA_MSPABI_Tag_ISA:
14102 val = read_uleb128 (p, &len, end);
14103 p += len;
14104 printf (" Tag_ISA: ");
14105 switch (val)
14106 {
14107 case 0: printf (_("None\n")); break;
14108 case 1: printf (_("MSP430\n")); break;
14109 case 2: printf (_("MSP430X\n")); break;
14110 default: printf ("??? (%d)\n", val); break;
14111 }
14112 break;
14113
14114 case OFBA_MSPABI_Tag_Code_Model:
14115 val = read_uleb128 (p, &len, end);
14116 p += len;
14117 printf (" Tag_Code_Model: ");
14118 switch (val)
14119 {
14120 case 0: printf (_("None\n")); break;
14121 case 1: printf (_("Small\n")); break;
14122 case 2: printf (_("Large\n")); break;
14123 default: printf ("??? (%d)\n", val); break;
14124 }
14125 break;
14126
14127 case OFBA_MSPABI_Tag_Data_Model:
14128 val = read_uleb128 (p, &len, end);
14129 p += len;
14130 printf (" Tag_Data_Model: ");
14131 switch (val)
14132 {
14133 case 0: printf (_("None\n")); break;
14134 case 1: printf (_("Small\n")); break;
14135 case 2: printf (_("Large\n")); break;
14136 case 3: printf (_("Restricted Large\n")); break;
14137 default: printf ("??? (%d)\n", val); break;
14138 }
14139 break;
14140
14141 default:
14142 printf (_(" <unknown tag %d>: "), tag);
14143
14144 if (tag & 1)
14145 {
071436c6 14146 putchar ('"');
4082ef84
NC
14147 if (p < end - 1)
14148 {
14149 size_t maxlen = (end - p) - 1;
14150
14151 print_symbol ((int) maxlen, (const char *) p);
14152 p += strnlen ((char *) p, maxlen) + 1;
14153 }
14154 else
14155 {
14156 printf (_("<corrupt>"));
14157 p = (unsigned char *) end;
14158 }
071436c6 14159 printf ("\"\n");
13761a11
NC
14160 }
14161 else
14162 {
14163 val = read_uleb128 (p, &len, end);
14164 p += len;
14165 printf ("%d (0x%x)\n", val, val);
14166 }
14167 break;
14168 }
14169
4082ef84 14170 assert (p <= end);
13761a11
NC
14171 return p;
14172}
14173
11c1ff18 14174static int
60bca95a
NC
14175process_attributes (FILE * file,
14176 const char * public_name,
104d59d1 14177 unsigned int proc_type,
f6f0e17b
NC
14178 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
14179 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 14180{
2cf0635d 14181 Elf_Internal_Shdr * sect;
11c1ff18
PB
14182 unsigned i;
14183
14184 /* Find the section header so that we get the size. */
14185 for (i = 0, sect = section_headers;
14186 i < elf_header.e_shnum;
14187 i++, sect++)
14188 {
071436c6
NC
14189 unsigned char * contents;
14190 unsigned char * p;
14191
104d59d1 14192 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
14193 continue;
14194
3f5e193b
NC
14195 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
14196 sect->sh_size, _("attributes"));
60bca95a 14197 if (contents == NULL)
11c1ff18 14198 continue;
60bca95a 14199
11c1ff18
PB
14200 p = contents;
14201 if (*p == 'A')
14202 {
071436c6
NC
14203 bfd_vma section_len;
14204
14205 section_len = sect->sh_size - 1;
11c1ff18 14206 p++;
60bca95a 14207
071436c6 14208 while (section_len > 0)
11c1ff18 14209 {
071436c6 14210 bfd_vma attr_len;
e9847026 14211 unsigned int namelen;
11c1ff18 14212 bfd_boolean public_section;
104d59d1 14213 bfd_boolean gnu_section;
11c1ff18 14214
071436c6 14215 if (section_len <= 4)
e0a31db1
NC
14216 {
14217 error (_("Tag section ends prematurely\n"));
14218 break;
14219 }
071436c6 14220 attr_len = byte_get (p, 4);
11c1ff18 14221 p += 4;
60bca95a 14222
071436c6 14223 if (attr_len > section_len)
11c1ff18 14224 {
071436c6
NC
14225 error (_("Bad attribute length (%u > %u)\n"),
14226 (unsigned) attr_len, (unsigned) section_len);
14227 attr_len = section_len;
11c1ff18 14228 }
74e1a04b 14229 /* PR 17531: file: 001-101425-0.004 */
071436c6 14230 else if (attr_len < 5)
74e1a04b 14231 {
071436c6 14232 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
74e1a04b
NC
14233 break;
14234 }
e9847026 14235
071436c6
NC
14236 section_len -= attr_len;
14237 attr_len -= 4;
14238
14239 namelen = strnlen ((char *) p, attr_len) + 1;
14240 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
14241 {
14242 error (_("Corrupt attribute section name\n"));
14243 break;
14244 }
14245
071436c6
NC
14246 printf (_("Attribute Section: "));
14247 print_symbol (INT_MAX, (const char *) p);
14248 putchar ('\n');
60bca95a
NC
14249
14250 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
14251 public_section = TRUE;
14252 else
14253 public_section = FALSE;
60bca95a
NC
14254
14255 if (streq ((char *) p, "gnu"))
104d59d1
JM
14256 gnu_section = TRUE;
14257 else
14258 gnu_section = FALSE;
60bca95a 14259
11c1ff18 14260 p += namelen;
071436c6 14261 attr_len -= namelen;
e0a31db1 14262
071436c6 14263 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 14264 {
e0a31db1 14265 int tag;
11c1ff18
PB
14266 int val;
14267 bfd_vma size;
071436c6 14268 unsigned char * end;
60bca95a 14269
e0a31db1 14270 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 14271 if (attr_len < 6)
e0a31db1
NC
14272 {
14273 error (_("Unused bytes at end of section\n"));
14274 section_len = 0;
14275 break;
14276 }
14277
14278 tag = *(p++);
11c1ff18 14279 size = byte_get (p, 4);
071436c6 14280 if (size > attr_len)
11c1ff18 14281 {
e9847026 14282 error (_("Bad subsection length (%u > %u)\n"),
071436c6
NC
14283 (unsigned) size, (unsigned) attr_len);
14284 size = attr_len;
11c1ff18 14285 }
e0a31db1
NC
14286 /* PR binutils/17531: Safe handling of corrupt files. */
14287 if (size < 6)
14288 {
14289 error (_("Bad subsection length (%u < 6)\n"),
14290 (unsigned) size);
14291 section_len = 0;
14292 break;
14293 }
60bca95a 14294
071436c6 14295 attr_len -= size;
11c1ff18 14296 end = p + size - 1;
071436c6 14297 assert (end <= contents + sect->sh_size);
11c1ff18 14298 p += 4;
60bca95a 14299
11c1ff18
PB
14300 switch (tag)
14301 {
14302 case 1:
2b692964 14303 printf (_("File Attributes\n"));
11c1ff18
PB
14304 break;
14305 case 2:
2b692964 14306 printf (_("Section Attributes:"));
11c1ff18
PB
14307 goto do_numlist;
14308 case 3:
2b692964 14309 printf (_("Symbol Attributes:"));
1a0670f3 14310 /* Fall through. */
11c1ff18
PB
14311 do_numlist:
14312 for (;;)
14313 {
91d6fa6a 14314 unsigned int j;
60bca95a 14315
f6f0e17b 14316 val = read_uleb128 (p, &j, end);
91d6fa6a 14317 p += j;
11c1ff18
PB
14318 if (val == 0)
14319 break;
14320 printf (" %d", val);
14321 }
14322 printf ("\n");
14323 break;
14324 default:
2b692964 14325 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
14326 public_section = FALSE;
14327 break;
14328 }
60bca95a 14329
071436c6 14330 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
14331 {
14332 while (p < end)
f6f0e17b 14333 p = display_pub_attribute (p, end);
071436c6 14334 assert (p <= end);
104d59d1 14335 }
071436c6 14336 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
14337 {
14338 while (p < end)
14339 p = display_gnu_attribute (p,
f6f0e17b
NC
14340 display_proc_gnu_attribute,
14341 end);
071436c6 14342 assert (p <= end);
11c1ff18 14343 }
071436c6 14344 else if (p < end)
11c1ff18 14345 {
071436c6 14346 printf (_(" Unknown attribute:\n"));
f6f0e17b 14347 display_raw_attribute (p, end);
11c1ff18
PB
14348 p = end;
14349 }
071436c6
NC
14350 else
14351 attr_len = 0;
11c1ff18
PB
14352 }
14353 }
14354 }
14355 else
e9847026 14356 printf (_("Unknown format '%c' (%d)\n"), *p, *p);
d70c5fc7 14357
60bca95a 14358 free (contents);
11c1ff18
PB
14359 }
14360 return 1;
14361}
14362
104d59d1 14363static int
2cf0635d 14364process_arm_specific (FILE * file)
104d59d1
JM
14365{
14366 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
14367 display_arm_attribute, NULL);
14368}
14369
34c8bcba 14370static int
2cf0635d 14371process_power_specific (FILE * file)
34c8bcba
JM
14372{
14373 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
14374 display_power_gnu_attribute);
14375}
14376
643f7afb
AK
14377static int
14378process_s390_specific (FILE * file)
14379{
14380 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
14381 display_s390_gnu_attribute);
14382}
14383
9e8c70f9
DM
14384static int
14385process_sparc_specific (FILE * file)
14386{
14387 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
14388 display_sparc_gnu_attribute);
14389}
14390
59e6276b
JM
14391static int
14392process_tic6x_specific (FILE * file)
14393{
14394 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
14395 display_tic6x_attribute, NULL);
14396}
14397
13761a11
NC
14398static int
14399process_msp430x_specific (FILE * file)
14400{
14401 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
14402 display_msp430x_attribute, NULL);
14403}
14404
ccb4c951
RS
14405/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
14406 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
14407 and return the VMA of the next entry, or -1 if there was a problem.
14408 Does not read from DATA_END or beyond. */
ccb4c951
RS
14409
14410static bfd_vma
82b1b41b
NC
14411print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
14412 unsigned char * data_end)
ccb4c951
RS
14413{
14414 printf (" ");
14415 print_vma (addr, LONG_HEX);
14416 printf (" ");
14417 if (addr < pltgot + 0xfff0)
14418 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
14419 else
14420 printf ("%10s", "");
14421 printf (" ");
14422 if (data == NULL)
2b692964 14423 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
14424 else
14425 {
14426 bfd_vma entry;
82b1b41b 14427 unsigned char * from = data + addr - pltgot;
ccb4c951 14428
82b1b41b
NC
14429 if (from + (is_32bit_elf ? 4 : 8) > data_end)
14430 {
14431 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
14432 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
14433 return (bfd_vma) -1;
14434 }
14435 else
14436 {
14437 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
14438 print_vma (entry, LONG_HEX);
14439 }
ccb4c951
RS
14440 }
14441 return addr + (is_32bit_elf ? 4 : 8);
14442}
14443
861fb55a
DJ
14444/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
14445 PLTGOT. Print the Address and Initial fields of an entry at VMA
14446 ADDR and return the VMA of the next entry. */
14447
14448static bfd_vma
2cf0635d 14449print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
14450{
14451 printf (" ");
14452 print_vma (addr, LONG_HEX);
14453 printf (" ");
14454 if (data == NULL)
2b692964 14455 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
14456 else
14457 {
14458 bfd_vma entry;
14459
14460 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
14461 print_vma (entry, LONG_HEX);
14462 }
14463 return addr + (is_32bit_elf ? 4 : 8);
14464}
14465
351cdf24
MF
14466static void
14467print_mips_ases (unsigned int mask)
14468{
14469 if (mask & AFL_ASE_DSP)
14470 fputs ("\n\tDSP ASE", stdout);
14471 if (mask & AFL_ASE_DSPR2)
14472 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
14473 if (mask & AFL_ASE_DSPR3)
14474 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
14475 if (mask & AFL_ASE_EVA)
14476 fputs ("\n\tEnhanced VA Scheme", stdout);
14477 if (mask & AFL_ASE_MCU)
14478 fputs ("\n\tMCU (MicroController) ASE", stdout);
14479 if (mask & AFL_ASE_MDMX)
14480 fputs ("\n\tMDMX ASE", stdout);
14481 if (mask & AFL_ASE_MIPS3D)
14482 fputs ("\n\tMIPS-3D ASE", stdout);
14483 if (mask & AFL_ASE_MT)
14484 fputs ("\n\tMT ASE", stdout);
14485 if (mask & AFL_ASE_SMARTMIPS)
14486 fputs ("\n\tSmartMIPS ASE", stdout);
14487 if (mask & AFL_ASE_VIRT)
14488 fputs ("\n\tVZ ASE", stdout);
14489 if (mask & AFL_ASE_MSA)
14490 fputs ("\n\tMSA ASE", stdout);
14491 if (mask & AFL_ASE_MIPS16)
14492 fputs ("\n\tMIPS16 ASE", stdout);
14493 if (mask & AFL_ASE_MICROMIPS)
14494 fputs ("\n\tMICROMIPS ASE", stdout);
14495 if (mask & AFL_ASE_XPA)
14496 fputs ("\n\tXPA ASE", stdout);
14497 if (mask == 0)
14498 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
14499 else if ((mask & ~AFL_ASE_MASK) != 0)
14500 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
14501}
14502
14503static void
14504print_mips_isa_ext (unsigned int isa_ext)
14505{
14506 switch (isa_ext)
14507 {
14508 case 0:
14509 fputs (_("None"), stdout);
14510 break;
14511 case AFL_EXT_XLR:
14512 fputs ("RMI XLR", stdout);
14513 break;
2c629856
N
14514 case AFL_EXT_OCTEON3:
14515 fputs ("Cavium Networks Octeon3", stdout);
14516 break;
351cdf24
MF
14517 case AFL_EXT_OCTEON2:
14518 fputs ("Cavium Networks Octeon2", stdout);
14519 break;
14520 case AFL_EXT_OCTEONP:
14521 fputs ("Cavium Networks OcteonP", stdout);
14522 break;
14523 case AFL_EXT_LOONGSON_3A:
14524 fputs ("Loongson 3A", stdout);
14525 break;
14526 case AFL_EXT_OCTEON:
14527 fputs ("Cavium Networks Octeon", stdout);
14528 break;
14529 case AFL_EXT_5900:
14530 fputs ("Toshiba R5900", stdout);
14531 break;
14532 case AFL_EXT_4650:
14533 fputs ("MIPS R4650", stdout);
14534 break;
14535 case AFL_EXT_4010:
14536 fputs ("LSI R4010", stdout);
14537 break;
14538 case AFL_EXT_4100:
14539 fputs ("NEC VR4100", stdout);
14540 break;
14541 case AFL_EXT_3900:
14542 fputs ("Toshiba R3900", stdout);
14543 break;
14544 case AFL_EXT_10000:
14545 fputs ("MIPS R10000", stdout);
14546 break;
14547 case AFL_EXT_SB1:
14548 fputs ("Broadcom SB-1", stdout);
14549 break;
14550 case AFL_EXT_4111:
14551 fputs ("NEC VR4111/VR4181", stdout);
14552 break;
14553 case AFL_EXT_4120:
14554 fputs ("NEC VR4120", stdout);
14555 break;
14556 case AFL_EXT_5400:
14557 fputs ("NEC VR5400", stdout);
14558 break;
14559 case AFL_EXT_5500:
14560 fputs ("NEC VR5500", stdout);
14561 break;
14562 case AFL_EXT_LOONGSON_2E:
14563 fputs ("ST Microelectronics Loongson 2E", stdout);
14564 break;
14565 case AFL_EXT_LOONGSON_2F:
14566 fputs ("ST Microelectronics Loongson 2F", stdout);
14567 break;
14568 default:
00ac7aa0 14569 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
14570 }
14571}
14572
14573static int
14574get_mips_reg_size (int reg_size)
14575{
14576 return (reg_size == AFL_REG_NONE) ? 0
14577 : (reg_size == AFL_REG_32) ? 32
14578 : (reg_size == AFL_REG_64) ? 64
14579 : (reg_size == AFL_REG_128) ? 128
14580 : -1;
14581}
14582
19e6b90e 14583static int
2cf0635d 14584process_mips_specific (FILE * file)
5b18a4bc 14585{
2cf0635d 14586 Elf_Internal_Dyn * entry;
351cdf24 14587 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
14588 size_t liblist_offset = 0;
14589 size_t liblistno = 0;
14590 size_t conflictsno = 0;
14591 size_t options_offset = 0;
14592 size_t conflicts_offset = 0;
861fb55a
DJ
14593 size_t pltrelsz = 0;
14594 size_t pltrel = 0;
ccb4c951 14595 bfd_vma pltgot = 0;
861fb55a
DJ
14596 bfd_vma mips_pltgot = 0;
14597 bfd_vma jmprel = 0;
ccb4c951
RS
14598 bfd_vma local_gotno = 0;
14599 bfd_vma gotsym = 0;
14600 bfd_vma symtabno = 0;
103f02d3 14601
2cf19d5c
JM
14602 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
14603 display_mips_gnu_attribute);
14604
351cdf24
MF
14605 sect = find_section (".MIPS.abiflags");
14606
14607 if (sect != NULL)
14608 {
14609 Elf_External_ABIFlags_v0 *abiflags_ext;
14610 Elf_Internal_ABIFlags_v0 abiflags_in;
14611
14612 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
14613 fputs ("\nCorrupt ABI Flags section.\n", stdout);
14614 else
14615 {
14616 abiflags_ext = get_data (NULL, file, sect->sh_offset, 1,
14617 sect->sh_size, _("MIPS ABI Flags section"));
14618 if (abiflags_ext)
14619 {
14620 abiflags_in.version = BYTE_GET (abiflags_ext->version);
14621 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
14622 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
14623 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
14624 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
14625 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
14626 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
14627 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
14628 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
14629 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
14630 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
14631
14632 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
14633 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
14634 if (abiflags_in.isa_rev > 1)
14635 printf ("r%d", abiflags_in.isa_rev);
14636 printf ("\nGPR size: %d",
14637 get_mips_reg_size (abiflags_in.gpr_size));
14638 printf ("\nCPR1 size: %d",
14639 get_mips_reg_size (abiflags_in.cpr1_size));
14640 printf ("\nCPR2 size: %d",
14641 get_mips_reg_size (abiflags_in.cpr2_size));
14642 fputs ("\nFP ABI: ", stdout);
14643 print_mips_fp_abi_value (abiflags_in.fp_abi);
14644 fputs ("ISA Extension: ", stdout);
14645 print_mips_isa_ext (abiflags_in.isa_ext);
14646 fputs ("\nASEs:", stdout);
14647 print_mips_ases (abiflags_in.ases);
14648 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
14649 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
14650 fputc ('\n', stdout);
14651 free (abiflags_ext);
14652 }
14653 }
14654 }
14655
19e6b90e
L
14656 /* We have a lot of special sections. Thanks SGI! */
14657 if (dynamic_section == NULL)
14658 /* No information available. */
14659 return 0;
252b5132 14660
071436c6
NC
14661 for (entry = dynamic_section;
14662 /* PR 17531 file: 012-50589-0.004. */
14663 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
14664 ++entry)
252b5132
RH
14665 switch (entry->d_tag)
14666 {
14667 case DT_MIPS_LIBLIST:
d93f0186
NC
14668 liblist_offset
14669 = offset_from_vma (file, entry->d_un.d_val,
14670 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
14671 break;
14672 case DT_MIPS_LIBLISTNO:
14673 liblistno = entry->d_un.d_val;
14674 break;
14675 case DT_MIPS_OPTIONS:
d93f0186 14676 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
14677 break;
14678 case DT_MIPS_CONFLICT:
d93f0186
NC
14679 conflicts_offset
14680 = offset_from_vma (file, entry->d_un.d_val,
14681 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
14682 break;
14683 case DT_MIPS_CONFLICTNO:
14684 conflictsno = entry->d_un.d_val;
14685 break;
ccb4c951 14686 case DT_PLTGOT:
861fb55a
DJ
14687 pltgot = entry->d_un.d_ptr;
14688 break;
ccb4c951
RS
14689 case DT_MIPS_LOCAL_GOTNO:
14690 local_gotno = entry->d_un.d_val;
14691 break;
14692 case DT_MIPS_GOTSYM:
14693 gotsym = entry->d_un.d_val;
14694 break;
14695 case DT_MIPS_SYMTABNO:
14696 symtabno = entry->d_un.d_val;
14697 break;
861fb55a
DJ
14698 case DT_MIPS_PLTGOT:
14699 mips_pltgot = entry->d_un.d_ptr;
14700 break;
14701 case DT_PLTREL:
14702 pltrel = entry->d_un.d_val;
14703 break;
14704 case DT_PLTRELSZ:
14705 pltrelsz = entry->d_un.d_val;
14706 break;
14707 case DT_JMPREL:
14708 jmprel = entry->d_un.d_ptr;
14709 break;
252b5132
RH
14710 default:
14711 break;
14712 }
14713
14714 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
14715 {
2cf0635d 14716 Elf32_External_Lib * elib;
252b5132
RH
14717 size_t cnt;
14718
3f5e193b
NC
14719 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
14720 liblistno,
14721 sizeof (Elf32_External_Lib),
9cf03b7e 14722 _("liblist section data"));
a6e9f9df 14723 if (elib)
252b5132 14724 {
2b692964 14725 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 14726 (unsigned long) liblistno);
2b692964 14727 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
14728 stdout);
14729
14730 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 14731 {
a6e9f9df 14732 Elf32_Lib liblist;
91d6fa6a 14733 time_t atime;
d5b07ef4 14734 char timebuf[128];
2cf0635d 14735 struct tm * tmp;
a6e9f9df
AM
14736
14737 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 14738 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
14739 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
14740 liblist.l_version = BYTE_GET (elib[cnt].l_version);
14741 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
14742
91d6fa6a 14743 tmp = gmtime (&atime);
e9e44622
JJ
14744 snprintf (timebuf, sizeof (timebuf),
14745 "%04u-%02u-%02uT%02u:%02u:%02u",
14746 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
14747 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 14748
31104126 14749 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
14750 if (VALID_DYNAMIC_NAME (liblist.l_name))
14751 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
14752 else
2b692964 14753 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
14754 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
14755 liblist.l_version);
a6e9f9df
AM
14756
14757 if (liblist.l_flags == 0)
2b692964 14758 puts (_(" NONE"));
a6e9f9df
AM
14759 else
14760 {
14761 static const struct
252b5132 14762 {
2cf0635d 14763 const char * name;
a6e9f9df 14764 int bit;
252b5132 14765 }
a6e9f9df
AM
14766 l_flags_vals[] =
14767 {
14768 { " EXACT_MATCH", LL_EXACT_MATCH },
14769 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
14770 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
14771 { " EXPORTS", LL_EXPORTS },
14772 { " DELAY_LOAD", LL_DELAY_LOAD },
14773 { " DELTA", LL_DELTA }
14774 };
14775 int flags = liblist.l_flags;
14776 size_t fcnt;
14777
60bca95a 14778 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
14779 if ((flags & l_flags_vals[fcnt].bit) != 0)
14780 {
14781 fputs (l_flags_vals[fcnt].name, stdout);
14782 flags ^= l_flags_vals[fcnt].bit;
14783 }
14784 if (flags != 0)
14785 printf (" %#x", (unsigned int) flags);
252b5132 14786
a6e9f9df
AM
14787 puts ("");
14788 }
252b5132 14789 }
252b5132 14790
a6e9f9df
AM
14791 free (elib);
14792 }
252b5132
RH
14793 }
14794
14795 if (options_offset != 0)
14796 {
2cf0635d 14797 Elf_External_Options * eopt;
2cf0635d
NC
14798 Elf_Internal_Options * iopt;
14799 Elf_Internal_Options * option;
252b5132
RH
14800 size_t offset;
14801 int cnt;
351cdf24 14802 sect = section_headers;
252b5132
RH
14803
14804 /* Find the section header so that we get the size. */
071436c6 14805 sect = find_section_by_type (SHT_MIPS_OPTIONS);
948f632f 14806 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
14807 if (sect == NULL)
14808 {
14809 error (_("No MIPS_OPTIONS header found\n"));
14810 return 0;
14811 }
252b5132 14812
3f5e193b
NC
14813 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
14814 sect->sh_size, _("options"));
a6e9f9df 14815 if (eopt)
252b5132 14816 {
3f5e193b
NC
14817 iopt = (Elf_Internal_Options *)
14818 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
14819 if (iopt == NULL)
14820 {
fb324ee9 14821 error (_("Out of memory allocating space for MIPS options\n"));
a6e9f9df
AM
14822 return 0;
14823 }
76da6bbe 14824
a6e9f9df
AM
14825 offset = cnt = 0;
14826 option = iopt;
252b5132 14827
82b1b41b 14828 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 14829 {
2cf0635d 14830 Elf_External_Options * eoption;
252b5132 14831
a6e9f9df 14832 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 14833
a6e9f9df
AM
14834 option->kind = BYTE_GET (eoption->kind);
14835 option->size = BYTE_GET (eoption->size);
14836 option->section = BYTE_GET (eoption->section);
14837 option->info = BYTE_GET (eoption->info);
76da6bbe 14838
82b1b41b
NC
14839 /* PR 17531: file: ffa0fa3b. */
14840 if (option->size < sizeof (* eopt)
14841 || offset + option->size > sect->sh_size)
14842 {
55325047
NC
14843 error (_("Invalid size (%u) for MIPS option\n"), option->size);
14844 return 0;
82b1b41b 14845 }
a6e9f9df 14846 offset += option->size;
14ae95f2 14847
a6e9f9df
AM
14848 ++option;
14849 ++cnt;
14850 }
252b5132 14851
a6e9f9df 14852 printf (_("\nSection '%s' contains %d entries:\n"),
74e1a04b 14853 printable_section_name (sect), cnt);
76da6bbe 14854
a6e9f9df 14855 option = iopt;
82b1b41b 14856 offset = 0;
252b5132 14857
a6e9f9df 14858 while (cnt-- > 0)
252b5132 14859 {
a6e9f9df
AM
14860 size_t len;
14861
14862 switch (option->kind)
252b5132 14863 {
a6e9f9df
AM
14864 case ODK_NULL:
14865 /* This shouldn't happen. */
14866 printf (" NULL %d %lx", option->section, option->info);
14867 break;
14868 case ODK_REGINFO:
14869 printf (" REGINFO ");
14870 if (elf_header.e_machine == EM_MIPS)
14871 {
14872 /* 32bit form. */
2cf0635d 14873 Elf32_External_RegInfo * ereg;
b34976b6 14874 Elf32_RegInfo reginfo;
a6e9f9df
AM
14875
14876 ereg = (Elf32_External_RegInfo *) (option + 1);
14877 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
14878 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
14879 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
14880 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
14881 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
14882 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
14883
14884 printf ("GPR %08lx GP 0x%lx\n",
14885 reginfo.ri_gprmask,
14886 (unsigned long) reginfo.ri_gp_value);
14887 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
14888 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
14889 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
14890 }
14891 else
14892 {
14893 /* 64 bit form. */
2cf0635d 14894 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
14895 Elf64_Internal_RegInfo reginfo;
14896
14897 ereg = (Elf64_External_RegInfo *) (option + 1);
14898 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
14899 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
14900 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
14901 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
14902 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 14903 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
14904
14905 printf ("GPR %08lx GP 0x",
14906 reginfo.ri_gprmask);
14907 printf_vma (reginfo.ri_gp_value);
14908 printf ("\n");
14909
14910 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
14911 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
14912 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
14913 }
14914 ++option;
14915 continue;
14916 case ODK_EXCEPTIONS:
14917 fputs (" EXCEPTIONS fpe_min(", stdout);
14918 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
14919 fputs (") fpe_max(", stdout);
14920 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
14921 fputs (")", stdout);
14922
14923 if (option->info & OEX_PAGE0)
14924 fputs (" PAGE0", stdout);
14925 if (option->info & OEX_SMM)
14926 fputs (" SMM", stdout);
14927 if (option->info & OEX_FPDBUG)
14928 fputs (" FPDBUG", stdout);
14929 if (option->info & OEX_DISMISS)
14930 fputs (" DISMISS", stdout);
14931 break;
14932 case ODK_PAD:
14933 fputs (" PAD ", stdout);
14934 if (option->info & OPAD_PREFIX)
14935 fputs (" PREFIX", stdout);
14936 if (option->info & OPAD_POSTFIX)
14937 fputs (" POSTFIX", stdout);
14938 if (option->info & OPAD_SYMBOL)
14939 fputs (" SYMBOL", stdout);
14940 break;
14941 case ODK_HWPATCH:
14942 fputs (" HWPATCH ", stdout);
14943 if (option->info & OHW_R4KEOP)
14944 fputs (" R4KEOP", stdout);
14945 if (option->info & OHW_R8KPFETCH)
14946 fputs (" R8KPFETCH", stdout);
14947 if (option->info & OHW_R5KEOP)
14948 fputs (" R5KEOP", stdout);
14949 if (option->info & OHW_R5KCVTL)
14950 fputs (" R5KCVTL", stdout);
14951 break;
14952 case ODK_FILL:
14953 fputs (" FILL ", stdout);
14954 /* XXX Print content of info word? */
14955 break;
14956 case ODK_TAGS:
14957 fputs (" TAGS ", stdout);
14958 /* XXX Print content of info word? */
14959 break;
14960 case ODK_HWAND:
14961 fputs (" HWAND ", stdout);
14962 if (option->info & OHWA0_R4KEOP_CHECKED)
14963 fputs (" R4KEOP_CHECKED", stdout);
14964 if (option->info & OHWA0_R4KEOP_CLEAN)
14965 fputs (" R4KEOP_CLEAN", stdout);
14966 break;
14967 case ODK_HWOR:
14968 fputs (" HWOR ", stdout);
14969 if (option->info & OHWA0_R4KEOP_CHECKED)
14970 fputs (" R4KEOP_CHECKED", stdout);
14971 if (option->info & OHWA0_R4KEOP_CLEAN)
14972 fputs (" R4KEOP_CLEAN", stdout);
14973 break;
14974 case ODK_GP_GROUP:
14975 printf (" GP_GROUP %#06lx self-contained %#06lx",
14976 option->info & OGP_GROUP,
14977 (option->info & OGP_SELF) >> 16);
14978 break;
14979 case ODK_IDENT:
14980 printf (" IDENT %#06lx self-contained %#06lx",
14981 option->info & OGP_GROUP,
14982 (option->info & OGP_SELF) >> 16);
14983 break;
14984 default:
14985 /* This shouldn't happen. */
14986 printf (" %3d ??? %d %lx",
14987 option->kind, option->section, option->info);
14988 break;
252b5132 14989 }
a6e9f9df 14990
2cf0635d 14991 len = sizeof (* eopt);
a6e9f9df 14992 while (len < option->size)
82b1b41b 14993 {
7e27a9d5 14994 unsigned char datum = * ((unsigned char *) eopt + offset + len);
a6e9f9df 14995
82b1b41b
NC
14996 if (ISPRINT (datum))
14997 printf ("%c", datum);
14998 else
14999 printf ("\\%03o", datum);
15000 len ++;
15001 }
a6e9f9df 15002 fputs ("\n", stdout);
82b1b41b
NC
15003
15004 offset += option->size;
252b5132 15005 ++option;
252b5132
RH
15006 }
15007
a6e9f9df 15008 free (eopt);
252b5132 15009 }
252b5132
RH
15010 }
15011
15012 if (conflicts_offset != 0 && conflictsno != 0)
15013 {
2cf0635d 15014 Elf32_Conflict * iconf;
252b5132
RH
15015 size_t cnt;
15016
15017 if (dynamic_symbols == NULL)
15018 {
591a748a 15019 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
15020 return 0;
15021 }
15022
3f5e193b 15023 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
15024 if (iconf == NULL)
15025 {
8b73c356 15026 error (_("Out of memory allocating space for dynamic conflicts\n"));
252b5132
RH
15027 return 0;
15028 }
15029
9ea033b2 15030 if (is_32bit_elf)
252b5132 15031 {
2cf0635d 15032 Elf32_External_Conflict * econf32;
a6e9f9df 15033
3f5e193b
NC
15034 econf32 = (Elf32_External_Conflict *)
15035 get_data (NULL, file, conflicts_offset, conflictsno,
15036 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
15037 if (!econf32)
15038 return 0;
252b5132
RH
15039
15040 for (cnt = 0; cnt < conflictsno; ++cnt)
15041 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
15042
15043 free (econf32);
252b5132
RH
15044 }
15045 else
15046 {
2cf0635d 15047 Elf64_External_Conflict * econf64;
a6e9f9df 15048
3f5e193b
NC
15049 econf64 = (Elf64_External_Conflict *)
15050 get_data (NULL, file, conflicts_offset, conflictsno,
15051 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
15052 if (!econf64)
15053 return 0;
252b5132
RH
15054
15055 for (cnt = 0; cnt < conflictsno; ++cnt)
15056 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
15057
15058 free (econf64);
252b5132
RH
15059 }
15060
c7e7ca54
NC
15061 printf (_("\nSection '.conflict' contains %lu entries:\n"),
15062 (unsigned long) conflictsno);
252b5132
RH
15063 puts (_(" Num: Index Value Name"));
15064
15065 for (cnt = 0; cnt < conflictsno; ++cnt)
15066 {
b34976b6 15067 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
15068
15069 if (iconf[cnt] >= num_dynamic_syms)
15070 printf (_("<corrupt symbol index>"));
d79b3d50 15071 else
e0a31db1
NC
15072 {
15073 Elf_Internal_Sym * psym;
15074
15075 psym = & dynamic_symbols[iconf[cnt]];
15076 print_vma (psym->st_value, FULL_HEX);
15077 putchar (' ');
15078 if (VALID_DYNAMIC_NAME (psym->st_name))
15079 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
15080 else
15081 printf (_("<corrupt: %14ld>"), psym->st_name);
15082 }
31104126 15083 putchar ('\n');
252b5132
RH
15084 }
15085
252b5132
RH
15086 free (iconf);
15087 }
15088
ccb4c951
RS
15089 if (pltgot != 0 && local_gotno != 0)
15090 {
91d6fa6a 15091 bfd_vma ent, local_end, global_end;
bbeee7ea 15092 size_t i, offset;
2cf0635d 15093 unsigned char * data;
82b1b41b 15094 unsigned char * data_end;
bbeee7ea 15095 int addr_size;
ccb4c951 15096
91d6fa6a 15097 ent = pltgot;
ccb4c951
RS
15098 addr_size = (is_32bit_elf ? 4 : 8);
15099 local_end = pltgot + local_gotno * addr_size;
ccb4c951 15100
74e1a04b
NC
15101 /* PR binutils/17533 file: 012-111227-0.004 */
15102 if (symtabno < gotsym)
15103 {
15104 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 15105 (unsigned long) gotsym, (unsigned long) symtabno);
74e1a04b
NC
15106 return 0;
15107 }
82b1b41b 15108
74e1a04b 15109 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
15110 /* PR 17531: file: 54c91a34. */
15111 if (global_end < local_end)
15112 {
15113 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
15114 return 0;
15115 }
948f632f 15116
ccb4c951 15117 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 15118 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
15119 global_end - pltgot, 1,
15120 _("Global Offset Table data"));
59245841
NC
15121 if (data == NULL)
15122 return 0;
82b1b41b 15123 data_end = data + (global_end - pltgot);
59245841 15124
ccb4c951
RS
15125 printf (_("\nPrimary GOT:\n"));
15126 printf (_(" Canonical gp value: "));
15127 print_vma (pltgot + 0x7ff0, LONG_HEX);
15128 printf ("\n\n");
15129
15130 printf (_(" Reserved entries:\n"));
15131 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
15132 addr_size * 2, _("Address"), _("Access"),
15133 addr_size * 2, _("Initial"));
82b1b41b 15134 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 15135 printf (_(" Lazy resolver\n"));
82b1b41b
NC
15136 if (ent == (bfd_vma) -1)
15137 goto got_print_fail;
ccb4c951 15138 if (data
91d6fa6a 15139 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
15140 >> (addr_size * 8 - 1)) != 0)
15141 {
82b1b41b 15142 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 15143 printf (_(" Module pointer (GNU extension)\n"));
82b1b41b
NC
15144 if (ent == (bfd_vma) -1)
15145 goto got_print_fail;
ccb4c951
RS
15146 }
15147 printf ("\n");
15148
91d6fa6a 15149 if (ent < local_end)
ccb4c951
RS
15150 {
15151 printf (_(" Local entries:\n"));
cc5914eb 15152 printf (" %*s %10s %*s\n",
2b692964
NC
15153 addr_size * 2, _("Address"), _("Access"),
15154 addr_size * 2, _("Initial"));
91d6fa6a 15155 while (ent < local_end)
ccb4c951 15156 {
82b1b41b 15157 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 15158 printf ("\n");
82b1b41b
NC
15159 if (ent == (bfd_vma) -1)
15160 goto got_print_fail;
ccb4c951
RS
15161 }
15162 printf ("\n");
15163 }
15164
15165 if (gotsym < symtabno)
15166 {
15167 int sym_width;
15168
15169 printf (_(" Global entries:\n"));
cc5914eb 15170 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
15171 addr_size * 2, _("Address"),
15172 _("Access"),
2b692964 15173 addr_size * 2, _("Initial"),
9cf03b7e
NC
15174 addr_size * 2, _("Sym.Val."),
15175 _("Type"),
15176 /* Note for translators: "Ndx" = abbreviated form of "Index". */
15177 _("Ndx"), _("Name"));
0b4362b0 15178
ccb4c951 15179 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 15180
ccb4c951
RS
15181 for (i = gotsym; i < symtabno; i++)
15182 {
82b1b41b 15183 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 15184 printf (" ");
e0a31db1
NC
15185
15186 if (dynamic_symbols == NULL)
15187 printf (_("<no dynamic symbols>"));
15188 else if (i < num_dynamic_syms)
15189 {
15190 Elf_Internal_Sym * psym = dynamic_symbols + i;
15191
15192 print_vma (psym->st_value, LONG_HEX);
15193 printf (" %-7s %3s ",
15194 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
15195 get_symbol_index_type (psym->st_shndx));
15196
15197 if (VALID_DYNAMIC_NAME (psym->st_name))
15198 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
15199 else
15200 printf (_("<corrupt: %14ld>"), psym->st_name);
15201 }
ccb4c951 15202 else
7fc5ac57
JBG
15203 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
15204 (unsigned long) i);
e0a31db1 15205
ccb4c951 15206 printf ("\n");
82b1b41b
NC
15207 if (ent == (bfd_vma) -1)
15208 break;
ccb4c951
RS
15209 }
15210 printf ("\n");
15211 }
15212
82b1b41b 15213 got_print_fail:
ccb4c951
RS
15214 if (data)
15215 free (data);
15216 }
15217
861fb55a
DJ
15218 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
15219 {
91d6fa6a 15220 bfd_vma ent, end;
861fb55a
DJ
15221 size_t offset, rel_offset;
15222 unsigned long count, i;
2cf0635d 15223 unsigned char * data;
861fb55a 15224 int addr_size, sym_width;
2cf0635d 15225 Elf_Internal_Rela * rels;
861fb55a
DJ
15226
15227 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
15228 if (pltrel == DT_RELA)
15229 {
15230 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
15231 return 0;
15232 }
15233 else
15234 {
15235 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
15236 return 0;
15237 }
15238
91d6fa6a 15239 ent = mips_pltgot;
861fb55a
DJ
15240 addr_size = (is_32bit_elf ? 4 : 8);
15241 end = mips_pltgot + (2 + count) * addr_size;
15242
15243 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 15244 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 15245 1, _("Procedure Linkage Table data"));
59245841
NC
15246 if (data == NULL)
15247 return 0;
15248
9cf03b7e 15249 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
15250 printf (_(" Reserved entries:\n"));
15251 printf (_(" %*s %*s Purpose\n"),
2b692964 15252 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 15253 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 15254 printf (_(" PLT lazy resolver\n"));
91d6fa6a 15255 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 15256 printf (_(" Module pointer\n"));
861fb55a
DJ
15257 printf ("\n");
15258
15259 printf (_(" Entries:\n"));
cc5914eb 15260 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
15261 addr_size * 2, _("Address"),
15262 addr_size * 2, _("Initial"),
15263 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
15264 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
15265 for (i = 0; i < count; i++)
15266 {
df97ab2a 15267 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 15268
91d6fa6a 15269 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 15270 printf (" ");
e0a31db1 15271
df97ab2a
MF
15272 if (idx >= num_dynamic_syms)
15273 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 15274 else
e0a31db1 15275 {
df97ab2a 15276 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
15277
15278 print_vma (psym->st_value, LONG_HEX);
15279 printf (" %-7s %3s ",
15280 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
15281 get_symbol_index_type (psym->st_shndx));
15282 if (VALID_DYNAMIC_NAME (psym->st_name))
15283 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
15284 else
15285 printf (_("<corrupt: %14ld>"), psym->st_name);
15286 }
861fb55a
DJ
15287 printf ("\n");
15288 }
15289 printf ("\n");
15290
15291 if (data)
15292 free (data);
15293 free (rels);
15294 }
15295
252b5132
RH
15296 return 1;
15297}
15298
35c08157
KLC
15299static int
15300process_nds32_specific (FILE * file)
15301{
15302 Elf_Internal_Shdr *sect = NULL;
15303
15304 sect = find_section (".nds32_e_flags");
15305 if (sect != NULL)
15306 {
15307 unsigned int *flag;
15308
15309 printf ("\nNDS32 elf flags section:\n");
15310 flag = get_data (NULL, file, sect->sh_offset, 1,
15311 sect->sh_size, _("NDS32 elf flags section"));
15312
15313 switch ((*flag) & 0x3)
15314 {
15315 case 0:
15316 printf ("(VEC_SIZE):\tNo entry.\n");
15317 break;
15318 case 1:
15319 printf ("(VEC_SIZE):\t4 bytes\n");
15320 break;
15321 case 2:
15322 printf ("(VEC_SIZE):\t16 bytes\n");
15323 break;
15324 case 3:
15325 printf ("(VEC_SIZE):\treserved\n");
15326 break;
15327 }
15328 }
15329
15330 return TRUE;
15331}
15332
047b2264 15333static int
2cf0635d 15334process_gnu_liblist (FILE * file)
047b2264 15335{
2cf0635d
NC
15336 Elf_Internal_Shdr * section;
15337 Elf_Internal_Shdr * string_sec;
15338 Elf32_External_Lib * elib;
15339 char * strtab;
c256ffe7 15340 size_t strtab_size;
047b2264
JJ
15341 size_t cnt;
15342 unsigned i;
15343
15344 if (! do_arch)
15345 return 0;
15346
15347 for (i = 0, section = section_headers;
15348 i < elf_header.e_shnum;
b34976b6 15349 i++, section++)
047b2264
JJ
15350 {
15351 switch (section->sh_type)
15352 {
15353 case SHT_GNU_LIBLIST:
4fbb74a6 15354 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
15355 break;
15356
3f5e193b
NC
15357 elib = (Elf32_External_Lib *)
15358 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 15359 _("liblist section data"));
047b2264
JJ
15360
15361 if (elib == NULL)
15362 break;
4fbb74a6 15363 string_sec = section_headers + section->sh_link;
047b2264 15364
3f5e193b
NC
15365 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
15366 string_sec->sh_size,
15367 _("liblist string table"));
047b2264
JJ
15368 if (strtab == NULL
15369 || section->sh_entsize != sizeof (Elf32_External_Lib))
15370 {
15371 free (elib);
2842702f 15372 free (strtab);
047b2264
JJ
15373 break;
15374 }
59245841 15375 strtab_size = string_sec->sh_size;
047b2264
JJ
15376
15377 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
74e1a04b 15378 printable_section_name (section),
0af1713e 15379 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 15380
2b692964 15381 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
15382
15383 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
15384 ++cnt)
15385 {
15386 Elf32_Lib liblist;
91d6fa6a 15387 time_t atime;
d5b07ef4 15388 char timebuf[128];
2cf0635d 15389 struct tm * tmp;
047b2264
JJ
15390
15391 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 15392 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
15393 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
15394 liblist.l_version = BYTE_GET (elib[cnt].l_version);
15395 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
15396
91d6fa6a 15397 tmp = gmtime (&atime);
e9e44622
JJ
15398 snprintf (timebuf, sizeof (timebuf),
15399 "%04u-%02u-%02uT%02u:%02u:%02u",
15400 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
15401 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
15402
15403 printf ("%3lu: ", (unsigned long) cnt);
15404 if (do_wide)
c256ffe7 15405 printf ("%-20s", liblist.l_name < strtab_size
2b692964 15406 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 15407 else
c256ffe7 15408 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 15409 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
15410 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
15411 liblist.l_version, liblist.l_flags);
15412 }
15413
15414 free (elib);
2842702f 15415 free (strtab);
047b2264
JJ
15416 }
15417 }
15418
15419 return 1;
15420}
15421
9437c45b 15422static const char *
d3ba0551 15423get_note_type (unsigned e_type)
779fe533
NC
15424{
15425 static char buff[64];
103f02d3 15426
1ec5cd37
NC
15427 if (elf_header.e_type == ET_CORE)
15428 switch (e_type)
15429 {
57346661 15430 case NT_AUXV:
1ec5cd37 15431 return _("NT_AUXV (auxiliary vector)");
57346661 15432 case NT_PRSTATUS:
1ec5cd37 15433 return _("NT_PRSTATUS (prstatus structure)");
57346661 15434 case NT_FPREGSET:
1ec5cd37 15435 return _("NT_FPREGSET (floating point registers)");
57346661 15436 case NT_PRPSINFO:
1ec5cd37 15437 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 15438 case NT_TASKSTRUCT:
1ec5cd37 15439 return _("NT_TASKSTRUCT (task structure)");
57346661 15440 case NT_PRXFPREG:
1ec5cd37 15441 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
15442 case NT_PPC_VMX:
15443 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
15444 case NT_PPC_VSX:
15445 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
15446 case NT_386_TLS:
15447 return _("NT_386_TLS (x86 TLS information)");
15448 case NT_386_IOPERM:
15449 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
15450 case NT_X86_XSTATE:
15451 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
15452 case NT_S390_HIGH_GPRS:
15453 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
15454 case NT_S390_TIMER:
15455 return _("NT_S390_TIMER (s390 timer register)");
15456 case NT_S390_TODCMP:
15457 return _("NT_S390_TODCMP (s390 TOD comparator register)");
15458 case NT_S390_TODPREG:
15459 return _("NT_S390_TODPREG (s390 TOD programmable register)");
15460 case NT_S390_CTRS:
15461 return _("NT_S390_CTRS (s390 control registers)");
15462 case NT_S390_PREFIX:
15463 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
15464 case NT_S390_LAST_BREAK:
15465 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
15466 case NT_S390_SYSTEM_CALL:
15467 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
15468 case NT_S390_TDB:
15469 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
15470 case NT_S390_VXRS_LOW:
15471 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
15472 case NT_S390_VXRS_HIGH:
15473 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
faa9a424
UW
15474 case NT_ARM_VFP:
15475 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
15476 case NT_ARM_TLS:
15477 return _("NT_ARM_TLS (AArch TLS registers)");
15478 case NT_ARM_HW_BREAK:
15479 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
15480 case NT_ARM_HW_WATCH:
15481 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 15482 case NT_PSTATUS:
1ec5cd37 15483 return _("NT_PSTATUS (pstatus structure)");
57346661 15484 case NT_FPREGS:
1ec5cd37 15485 return _("NT_FPREGS (floating point registers)");
57346661 15486 case NT_PSINFO:
1ec5cd37 15487 return _("NT_PSINFO (psinfo structure)");
57346661 15488 case NT_LWPSTATUS:
1ec5cd37 15489 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 15490 case NT_LWPSINFO:
1ec5cd37 15491 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 15492 case NT_WIN32PSTATUS:
1ec5cd37 15493 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
15494 case NT_SIGINFO:
15495 return _("NT_SIGINFO (siginfo_t data)");
15496 case NT_FILE:
15497 return _("NT_FILE (mapped files)");
1ec5cd37
NC
15498 default:
15499 break;
15500 }
15501 else
15502 switch (e_type)
15503 {
15504 case NT_VERSION:
15505 return _("NT_VERSION (version)");
15506 case NT_ARCH:
15507 return _("NT_ARCH (architecture)");
15508 default:
15509 break;
15510 }
15511
e9e44622 15512 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 15513 return buff;
779fe533
NC
15514}
15515
9ece1fa9
TT
15516static int
15517print_core_note (Elf_Internal_Note *pnote)
15518{
15519 unsigned int addr_size = is_32bit_elf ? 4 : 8;
15520 bfd_vma count, page_size;
15521 unsigned char *descdata, *filenames, *descend;
15522
15523 if (pnote->type != NT_FILE)
15524 return 1;
15525
15526#ifndef BFD64
15527 if (!is_32bit_elf)
15528 {
15529 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
15530 /* Still "successful". */
15531 return 1;
15532 }
15533#endif
15534
15535 if (pnote->descsz < 2 * addr_size)
15536 {
15537 printf (_(" Malformed note - too short for header\n"));
15538 return 0;
15539 }
15540
15541 descdata = (unsigned char *) pnote->descdata;
15542 descend = descdata + pnote->descsz;
15543
15544 if (descdata[pnote->descsz - 1] != '\0')
15545 {
15546 printf (_(" Malformed note - does not end with \\0\n"));
15547 return 0;
15548 }
15549
15550 count = byte_get (descdata, addr_size);
15551 descdata += addr_size;
15552
15553 page_size = byte_get (descdata, addr_size);
15554 descdata += addr_size;
15555
15556 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
15557 {
15558 printf (_(" Malformed note - too short for supplied file count\n"));
15559 return 0;
15560 }
15561
15562 printf (_(" Page size: "));
15563 print_vma (page_size, DEC);
15564 printf ("\n");
15565
15566 printf (_(" %*s%*s%*s\n"),
15567 (int) (2 + 2 * addr_size), _("Start"),
15568 (int) (4 + 2 * addr_size), _("End"),
15569 (int) (4 + 2 * addr_size), _("Page Offset"));
15570 filenames = descdata + count * 3 * addr_size;
595712bb 15571 while (count-- > 0)
9ece1fa9
TT
15572 {
15573 bfd_vma start, end, file_ofs;
15574
15575 if (filenames == descend)
15576 {
15577 printf (_(" Malformed note - filenames end too early\n"));
15578 return 0;
15579 }
15580
15581 start = byte_get (descdata, addr_size);
15582 descdata += addr_size;
15583 end = byte_get (descdata, addr_size);
15584 descdata += addr_size;
15585 file_ofs = byte_get (descdata, addr_size);
15586 descdata += addr_size;
15587
15588 printf (" ");
15589 print_vma (start, FULL_HEX);
15590 printf (" ");
15591 print_vma (end, FULL_HEX);
15592 printf (" ");
15593 print_vma (file_ofs, FULL_HEX);
15594 printf ("\n %s\n", filenames);
15595
15596 filenames += 1 + strlen ((char *) filenames);
15597 }
15598
15599 return 1;
15600}
15601
1118d252
RM
15602static const char *
15603get_gnu_elf_note_type (unsigned e_type)
15604{
1449284b 15605 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
15606 switch (e_type)
15607 {
15608 case NT_GNU_ABI_TAG:
15609 return _("NT_GNU_ABI_TAG (ABI version tag)");
15610 case NT_GNU_HWCAP:
15611 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
15612 case NT_GNU_BUILD_ID:
15613 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
15614 case NT_GNU_GOLD_VERSION:
15615 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252 15616 default:
1449284b
NC
15617 {
15618 static char buff[64];
1118d252 15619
1449284b
NC
15620 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
15621 return buff;
15622 }
15623 }
1118d252
RM
15624}
15625
664f90a3
TT
15626static int
15627print_gnu_note (Elf_Internal_Note *pnote)
15628{
1449284b 15629 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
15630 switch (pnote->type)
15631 {
15632 case NT_GNU_BUILD_ID:
15633 {
15634 unsigned long i;
15635
15636 printf (_(" Build ID: "));
15637 for (i = 0; i < pnote->descsz; ++i)
15638 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 15639 printf ("\n");
664f90a3
TT
15640 }
15641 break;
15642
15643 case NT_GNU_ABI_TAG:
15644 {
15645 unsigned long os, major, minor, subminor;
15646 const char *osname;
15647
3102e897
NC
15648 /* PR 17531: file: 030-599401-0.004. */
15649 if (pnote->descsz < 16)
15650 {
15651 printf (_(" <corrupt GNU_ABI_TAG>\n"));
15652 break;
15653 }
15654
664f90a3
TT
15655 os = byte_get ((unsigned char *) pnote->descdata, 4);
15656 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
15657 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
15658 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
15659
15660 switch (os)
15661 {
15662 case GNU_ABI_TAG_LINUX:
15663 osname = "Linux";
15664 break;
15665 case GNU_ABI_TAG_HURD:
15666 osname = "Hurd";
15667 break;
15668 case GNU_ABI_TAG_SOLARIS:
15669 osname = "Solaris";
15670 break;
15671 case GNU_ABI_TAG_FREEBSD:
15672 osname = "FreeBSD";
15673 break;
15674 case GNU_ABI_TAG_NETBSD:
15675 osname = "NetBSD";
15676 break;
14ae95f2
RM
15677 case GNU_ABI_TAG_SYLLABLE:
15678 osname = "Syllable";
15679 break;
15680 case GNU_ABI_TAG_NACL:
15681 osname = "NaCl";
15682 break;
664f90a3
TT
15683 default:
15684 osname = "Unknown";
15685 break;
15686 }
15687
15688 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
15689 major, minor, subminor);
15690 }
15691 break;
926c5385
CC
15692
15693 case NT_GNU_GOLD_VERSION:
15694 {
15695 unsigned long i;
15696
15697 printf (_(" Version: "));
15698 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
15699 printf ("%c", pnote->descdata[i]);
15700 printf ("\n");
15701 }
15702 break;
1449284b
NC
15703
15704 case NT_GNU_HWCAP:
15705 {
15706 unsigned long num_entries, mask;
15707
15708 /* Hardware capabilities information. Word 0 is the number of entries.
15709 Word 1 is a bitmask of enabled entries. The rest of the descriptor
15710 is a series of entries, where each entry is a single byte followed
15711 by a nul terminated string. The byte gives the bit number to test
15712 if enabled in the bitmask. */
15713 printf (_(" Hardware Capabilities: "));
15714 if (pnote->descsz < 8)
15715 {
15716 printf (_("<corrupt GNU_HWCAP>\n"));
15717 break;
15718 }
15719 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
15720 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
15721 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
15722 /* FIXME: Add code to display the entries... */
15723 }
15724 break;
15725
15726 default:
15727 /* Handle unrecognised types. An error message should have already been
15728 created by get_gnu_elf_note_type(), so all that we need to do is to
15729 display the data. */
15730 {
15731 unsigned long i;
15732
15733 printf (_(" Description data: "));
15734 for (i = 0; i < pnote->descsz; ++i)
15735 printf ("%02x ", pnote->descdata[i] & 0xff);
15736 printf ("\n");
15737 }
15738 break;
664f90a3
TT
15739 }
15740
15741 return 1;
15742}
15743
685080f2
NC
15744static const char *
15745get_v850_elf_note_type (enum v850_notes n_type)
15746{
15747 static char buff[64];
15748
15749 switch (n_type)
15750 {
15751 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
15752 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
15753 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
15754 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
15755 case V850_NOTE_CACHE_INFO: return _("Use of cache");
15756 case V850_NOTE_MMU_INFO: return _("Use of MMU");
15757 default:
15758 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
15759 return buff;
15760 }
15761}
15762
15763static int
15764print_v850_note (Elf_Internal_Note * pnote)
15765{
15766 unsigned int val;
15767
15768 if (pnote->descsz != 4)
15769 return 0;
15770 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
15771
15772 if (val == 0)
15773 {
15774 printf (_("not set\n"));
15775 return 1;
15776 }
15777
15778 switch (pnote->type)
15779 {
15780 case V850_NOTE_ALIGNMENT:
15781 switch (val)
15782 {
15783 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return 1;
15784 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return 1;
15785 }
15786 break;
14ae95f2 15787
685080f2
NC
15788 case V850_NOTE_DATA_SIZE:
15789 switch (val)
15790 {
15791 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return 1;
15792 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return 1;
15793 }
15794 break;
14ae95f2 15795
685080f2
NC
15796 case V850_NOTE_FPU_INFO:
15797 switch (val)
15798 {
15799 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return 1;
15800 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return 1;
15801 }
15802 break;
14ae95f2 15803
685080f2
NC
15804 case V850_NOTE_MMU_INFO:
15805 case V850_NOTE_CACHE_INFO:
15806 case V850_NOTE_SIMD_INFO:
15807 if (val == EF_RH850_SIMD)
15808 {
15809 printf (_("yes\n"));
15810 return 1;
15811 }
15812 break;
15813
15814 default:
15815 /* An 'unknown note type' message will already have been displayed. */
15816 break;
15817 }
15818
15819 printf (_("unknown value: %x\n"), val);
15820 return 0;
15821}
15822
15f205b1 15823static int
c6056a74
SF
15824process_netbsd_elf_note (Elf_Internal_Note * pnote)
15825{
15826 unsigned int version;
15827
15828 switch (pnote->type)
15829 {
15830 case NT_NETBSD_IDENT:
15831 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
15832 if ((version / 10000) % 100)
15833 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
15834 version, version / 100000000, (version / 1000000) % 100,
15835 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 15836 'A' + (version / 10000) % 26);
c6056a74
SF
15837 else
15838 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
15839 version, version / 100000000, (version / 1000000) % 100,
15f205b1 15840 (version / 100) % 100);
c6056a74
SF
15841 return 1;
15842
15843 case NT_NETBSD_MARCH:
15844 printf (" NetBSD\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
15845 pnote->descdata);
15846 return 1;
15847
15848 default:
15849 break;
15850 }
15851
15852 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n", pnote->descsz,
15853 pnote->type);
15854 return 1;
15855}
15856
f4ddf30f
JB
15857static const char *
15858get_freebsd_elfcore_note_type (unsigned e_type)
15859{
f4ddf30f
JB
15860 switch (e_type)
15861 {
15862 case NT_FREEBSD_THRMISC:
15863 return _("NT_THRMISC (thrmisc structure)");
15864 case NT_FREEBSD_PROCSTAT_PROC:
15865 return _("NT_PROCSTAT_PROC (proc data)");
15866 case NT_FREEBSD_PROCSTAT_FILES:
15867 return _("NT_PROCSTAT_FILES (files data)");
15868 case NT_FREEBSD_PROCSTAT_VMMAP:
15869 return _("NT_PROCSTAT_VMMAP (vmmap data)");
15870 case NT_FREEBSD_PROCSTAT_GROUPS:
15871 return _("NT_PROCSTAT_GROUPS (groups data)");
15872 case NT_FREEBSD_PROCSTAT_UMASK:
15873 return _("NT_PROCSTAT_UMASK (umask data)");
15874 case NT_FREEBSD_PROCSTAT_RLIMIT:
15875 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
15876 case NT_FREEBSD_PROCSTAT_OSREL:
15877 return _("NT_PROCSTAT_OSREL (osreldate data)");
15878 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
15879 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
15880 case NT_FREEBSD_PROCSTAT_AUXV:
15881 return _("NT_PROCSTAT_AUXV (auxv data)");
15882 }
15883 return get_note_type (e_type);
15884}
15885
9437c45b 15886static const char *
d3ba0551 15887get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
15888{
15889 static char buff[64];
15890
b4db1224 15891 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
15892 {
15893 /* NetBSD core "procinfo" structure. */
15894 return _("NetBSD procinfo structure");
15895 }
15896
15897 /* As of Jan 2002 there are no other machine-independent notes
15898 defined for NetBSD core files. If the note type is less
15899 than the start of the machine-dependent note types, we don't
15900 understand it. */
15901
b4db1224 15902 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 15903 {
e9e44622 15904 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
15905 return buff;
15906 }
15907
15908 switch (elf_header.e_machine)
15909 {
15910 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
15911 and PT_GETFPREGS == mach+2. */
15912
15913 case EM_OLD_ALPHA:
15914 case EM_ALPHA:
15915 case EM_SPARC:
15916 case EM_SPARC32PLUS:
15917 case EM_SPARCV9:
15918 switch (e_type)
15919 {
2b692964 15920 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 15921 return _("PT_GETREGS (reg structure)");
2b692964 15922 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 15923 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
15924 default:
15925 break;
15926 }
15927 break;
15928
15929 /* On all other arch's, PT_GETREGS == mach+1 and
15930 PT_GETFPREGS == mach+3. */
15931 default:
15932 switch (e_type)
15933 {
2b692964 15934 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 15935 return _("PT_GETREGS (reg structure)");
2b692964 15936 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 15937 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
15938 default:
15939 break;
15940 }
15941 }
15942
9cf03b7e 15943 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 15944 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
15945 return buff;
15946}
15947
70616151
TT
15948static const char *
15949get_stapsdt_note_type (unsigned e_type)
15950{
15951 static char buff[64];
15952
15953 switch (e_type)
15954 {
15955 case NT_STAPSDT:
15956 return _("NT_STAPSDT (SystemTap probe descriptors)");
15957
15958 default:
15959 break;
15960 }
15961
15962 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
15963 return buff;
15964}
15965
c6a9fc58
TT
15966static int
15967print_stapsdt_note (Elf_Internal_Note *pnote)
15968{
15969 int addr_size = is_32bit_elf ? 4 : 8;
15970 char *data = pnote->descdata;
15971 char *data_end = pnote->descdata + pnote->descsz;
15972 bfd_vma pc, base_addr, semaphore;
15973 char *provider, *probe, *arg_fmt;
15974
15975 pc = byte_get ((unsigned char *) data, addr_size);
15976 data += addr_size;
15977 base_addr = byte_get ((unsigned char *) data, addr_size);
15978 data += addr_size;
15979 semaphore = byte_get ((unsigned char *) data, addr_size);
15980 data += addr_size;
15981
15982 provider = data;
15983 data += strlen (data) + 1;
15984 probe = data;
15985 data += strlen (data) + 1;
15986 arg_fmt = data;
15987 data += strlen (data) + 1;
15988
15989 printf (_(" Provider: %s\n"), provider);
15990 printf (_(" Name: %s\n"), probe);
15991 printf (_(" Location: "));
15992 print_vma (pc, FULL_HEX);
15993 printf (_(", Base: "));
15994 print_vma (base_addr, FULL_HEX);
15995 printf (_(", Semaphore: "));
15996 print_vma (semaphore, FULL_HEX);
9cf03b7e 15997 printf ("\n");
c6a9fc58
TT
15998 printf (_(" Arguments: %s\n"), arg_fmt);
15999
16000 return data == data_end;
16001}
16002
00e98fc7
TG
16003static const char *
16004get_ia64_vms_note_type (unsigned e_type)
16005{
16006 static char buff[64];
16007
16008 switch (e_type)
16009 {
16010 case NT_VMS_MHD:
16011 return _("NT_VMS_MHD (module header)");
16012 case NT_VMS_LNM:
16013 return _("NT_VMS_LNM (language name)");
16014 case NT_VMS_SRC:
16015 return _("NT_VMS_SRC (source files)");
16016 case NT_VMS_TITLE:
9cf03b7e 16017 return "NT_VMS_TITLE";
00e98fc7
TG
16018 case NT_VMS_EIDC:
16019 return _("NT_VMS_EIDC (consistency check)");
16020 case NT_VMS_FPMODE:
16021 return _("NT_VMS_FPMODE (FP mode)");
16022 case NT_VMS_LINKTIME:
9cf03b7e 16023 return "NT_VMS_LINKTIME";
00e98fc7
TG
16024 case NT_VMS_IMGNAM:
16025 return _("NT_VMS_IMGNAM (image name)");
16026 case NT_VMS_IMGID:
16027 return _("NT_VMS_IMGID (image id)");
16028 case NT_VMS_LINKID:
16029 return _("NT_VMS_LINKID (link id)");
16030 case NT_VMS_IMGBID:
16031 return _("NT_VMS_IMGBID (build id)");
16032 case NT_VMS_GSTNAM:
16033 return _("NT_VMS_GSTNAM (sym table name)");
16034 case NT_VMS_ORIG_DYN:
9cf03b7e 16035 return "NT_VMS_ORIG_DYN";
00e98fc7 16036 case NT_VMS_PATCHTIME:
9cf03b7e 16037 return "NT_VMS_PATCHTIME";
00e98fc7
TG
16038 default:
16039 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
16040 return buff;
16041 }
16042}
16043
16044static int
16045print_ia64_vms_note (Elf_Internal_Note * pnote)
16046{
16047 switch (pnote->type)
16048 {
16049 case NT_VMS_MHD:
16050 if (pnote->descsz > 36)
16051 {
16052 size_t l = strlen (pnote->descdata + 34);
16053 printf (_(" Creation date : %.17s\n"), pnote->descdata);
16054 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
16055 printf (_(" Module name : %s\n"), pnote->descdata + 34);
16056 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
16057 }
16058 else
16059 printf (_(" Invalid size\n"));
16060 break;
16061 case NT_VMS_LNM:
16062 printf (_(" Language: %s\n"), pnote->descdata);
16063 break;
16064#ifdef BFD64
16065 case NT_VMS_FPMODE:
9cf03b7e 16066 printf (_(" Floating Point mode: "));
4a5cb34f 16067 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 16068 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
16069 break;
16070 case NT_VMS_LINKTIME:
16071 printf (_(" Link time: "));
16072 print_vms_time
16073 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
16074 printf ("\n");
16075 break;
16076 case NT_VMS_PATCHTIME:
16077 printf (_(" Patch time: "));
16078 print_vms_time
16079 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
16080 printf ("\n");
16081 break;
16082 case NT_VMS_ORIG_DYN:
16083 printf (_(" Major id: %u, minor id: %u\n"),
16084 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
16085 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 16086 printf (_(" Last modified : "));
00e98fc7
TG
16087 print_vms_time
16088 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 16089 printf (_("\n Link flags : "));
4a5cb34f 16090 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 16091 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 16092 printf (_(" Header flags: 0x%08x\n"),
948f632f 16093 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
00e98fc7
TG
16094 printf (_(" Image id : %s\n"), pnote->descdata + 32);
16095 break;
16096#endif
16097 case NT_VMS_IMGNAM:
16098 printf (_(" Image name: %s\n"), pnote->descdata);
16099 break;
16100 case NT_VMS_GSTNAM:
16101 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
16102 break;
16103 case NT_VMS_IMGID:
16104 printf (_(" Image id: %s\n"), pnote->descdata);
16105 break;
16106 case NT_VMS_LINKID:
16107 printf (_(" Linker id: %s\n"), pnote->descdata);
16108 break;
16109 default:
16110 break;
16111 }
16112 return 1;
16113}
16114
6d118b09
NC
16115/* Note that by the ELF standard, the name field is already null byte
16116 terminated, and namesz includes the terminating null byte.
16117 I.E. the value of namesz for the name "FSF" is 4.
16118
e3c8793a 16119 If the value of namesz is zero, there is no name present. */
779fe533 16120static int
1449284b
NC
16121process_note (Elf_Internal_Note * pnote,
16122 FILE * file ATTRIBUTE_UNUSED,
16123 Elf_Internal_Shdr * section ATTRIBUTE_UNUSED)
779fe533 16124{
2cf0635d
NC
16125 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
16126 const char * nt;
9437c45b
JT
16127
16128 if (pnote->namesz == 0)
1ec5cd37
NC
16129 /* If there is no note name, then use the default set of
16130 note type strings. */
16131 nt = get_note_type (pnote->type);
16132
1118d252
RM
16133 else if (const_strneq (pnote->namedata, "GNU"))
16134 /* GNU-specific object file notes. */
16135 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
16136
16137 else if (const_strneq (pnote->namedata, "FreeBSD"))
16138 /* FreeBSD-specific core file notes. */
16139 nt = get_freebsd_elfcore_note_type (pnote->type);
1118d252 16140
0112cd26 16141 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
16142 /* NetBSD-specific core file notes. */
16143 nt = get_netbsd_elfcore_note_type (pnote->type);
16144
c6056a74
SF
16145 else if (const_strneq (pnote->namedata, "NetBSD"))
16146 /* NetBSD-specific core file notes. */
16147 return process_netbsd_elf_note (pnote);
16148
b15fa79e
AM
16149 else if (strneq (pnote->namedata, "SPU/", 4))
16150 {
16151 /* SPU-specific core file notes. */
16152 nt = pnote->namedata + 4;
16153 name = "SPU";
16154 }
16155
00e98fc7
TG
16156 else if (const_strneq (pnote->namedata, "IPF/VMS"))
16157 /* VMS/ia64-specific file notes. */
16158 nt = get_ia64_vms_note_type (pnote->type);
16159
70616151
TT
16160 else if (const_strneq (pnote->namedata, "stapsdt"))
16161 nt = get_stapsdt_note_type (pnote->type);
16162
9437c45b 16163 else
1ec5cd37
NC
16164 /* Don't recognize this note name; just use the default set of
16165 note type strings. */
00e98fc7 16166 nt = get_note_type (pnote->type);
9437c45b 16167
1449284b
NC
16168 printf (" ");
16169 print_symbol (-20, name);
16170 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
16171
16172 if (const_strneq (pnote->namedata, "IPF/VMS"))
16173 return print_ia64_vms_note (pnote);
664f90a3
TT
16174 else if (const_strneq (pnote->namedata, "GNU"))
16175 return print_gnu_note (pnote);
c6a9fc58
TT
16176 else if (const_strneq (pnote->namedata, "stapsdt"))
16177 return print_stapsdt_note (pnote);
9ece1fa9
TT
16178 else if (const_strneq (pnote->namedata, "CORE"))
16179 return print_core_note (pnote);
779fe533 16180
1449284b
NC
16181 else if (pnote->descsz)
16182 {
16183 unsigned long i;
16184
16185 printf (_(" description data: "));
16186 for (i = 0; i < pnote->descsz; i++)
16187 printf ("%02x ", pnote->descdata[i]);
16188 printf ("\n");
16189 }
16190
16191 return 1;
16192}
6d118b09 16193
779fe533 16194static int
1449284b
NC
16195process_notes_at (FILE * file,
16196 Elf_Internal_Shdr * section,
16197 bfd_vma offset,
16198 bfd_vma length)
779fe533 16199{
2cf0635d
NC
16200 Elf_External_Note * pnotes;
16201 Elf_External_Note * external;
c8071705 16202 char * end;
b34976b6 16203 int res = 1;
103f02d3 16204
779fe533
NC
16205 if (length <= 0)
16206 return 0;
103f02d3 16207
1449284b
NC
16208 if (section)
16209 {
16210 pnotes = (Elf_External_Note *) get_section_contents (section, file);
16211 if (pnotes)
16212 apply_relocations (file, section, (unsigned char *) pnotes, length, NULL, NULL);
16213 }
16214 else
16215 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
16216 _("notes"));
dd24e3da 16217 if (pnotes == NULL)
a6e9f9df 16218 return 0;
779fe533 16219
103f02d3 16220 external = pnotes;
103f02d3 16221
1449284b
NC
16222 if (section)
16223 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (section));
16224 else
16225 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
16226 (unsigned long) offset, (unsigned long) length);
16227
2aee03ae 16228 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 16229
c8071705
NC
16230 end = (char *) pnotes + length;
16231 while ((char *) external < end)
779fe533 16232 {
b34976b6 16233 Elf_Internal_Note inote;
15b42fb0
AM
16234 size_t min_notesz;
16235 char *next;
2cf0635d 16236 char * temp = NULL;
c8071705 16237 size_t data_remaining = end - (char *) external;
6d118b09 16238
00e98fc7 16239 if (!is_ia64_vms ())
15b42fb0 16240 {
9dd3a467
NC
16241 /* PR binutils/15191
16242 Make sure that there is enough data to read. */
15b42fb0
AM
16243 min_notesz = offsetof (Elf_External_Note, name);
16244 if (data_remaining < min_notesz)
9dd3a467
NC
16245 {
16246 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
16247 (int) data_remaining);
16248 break;
16249 }
15b42fb0
AM
16250 inote.type = BYTE_GET (external->type);
16251 inote.namesz = BYTE_GET (external->namesz);
16252 inote.namedata = external->name;
16253 inote.descsz = BYTE_GET (external->descsz);
16254 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
834f871c 16255 /* PR 17531: file: 3443835e. */
c8071705 16256 if (inote.descdata < (char *) pnotes || inote.descdata > end)
834f871c
NC
16257 {
16258 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
16259 inote.descdata = inote.namedata;
16260 inote.namesz = 0;
16261 }
14ae95f2 16262
15b42fb0
AM
16263 inote.descpos = offset + (inote.descdata - (char *) pnotes);
16264 next = inote.descdata + align_power (inote.descsz, 2);
16265 }
00e98fc7 16266 else
15b42fb0
AM
16267 {
16268 Elf64_External_VMS_Note *vms_external;
00e98fc7 16269
9dd3a467
NC
16270 /* PR binutils/15191
16271 Make sure that there is enough data to read. */
15b42fb0
AM
16272 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16273 if (data_remaining < min_notesz)
9dd3a467
NC
16274 {
16275 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
16276 (int) data_remaining);
16277 break;
16278 }
3e55a963 16279
15b42fb0
AM
16280 vms_external = (Elf64_External_VMS_Note *) external;
16281 inote.type = BYTE_GET (vms_external->type);
16282 inote.namesz = BYTE_GET (vms_external->namesz);
16283 inote.namedata = vms_external->name;
16284 inote.descsz = BYTE_GET (vms_external->descsz);
16285 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16286 inote.descpos = offset + (inote.descdata - (char *) pnotes);
16287 next = inote.descdata + align_power (inote.descsz, 3);
16288 }
16289
16290 if (inote.descdata < (char *) external + min_notesz
16291 || next < (char *) external + min_notesz
5d921cbd
NC
16292 /* PR binutils/17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
16293 || inote.namedata + inote.namesz < inote.namedata
16294 || inote.descdata + inote.descsz < inote.descdata
15b42fb0 16295 || data_remaining < (size_t)(next - (char *) external))
3e55a963 16296 {
15b42fb0 16297 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 16298 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 16299 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
16300 inote.type, inote.namesz, inote.descsz);
16301 break;
16302 }
16303
15b42fb0 16304 external = (Elf_External_Note *) next;
dd24e3da 16305
6d118b09
NC
16306 /* Verify that name is null terminated. It appears that at least
16307 one version of Linux (RedHat 6.0) generates corefiles that don't
16308 comply with the ELF spec by failing to include the null byte in
16309 namesz. */
8b971f9f 16310 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 16311 {
3f5e193b 16312 temp = (char *) malloc (inote.namesz + 1);
6d118b09
NC
16313 if (temp == NULL)
16314 {
8b73c356 16315 error (_("Out of memory allocating space for inote name\n"));
6d118b09
NC
16316 res = 0;
16317 break;
16318 }
76da6bbe 16319
6d118b09
NC
16320 strncpy (temp, inote.namedata, inote.namesz);
16321 temp[inote.namesz] = 0;
76da6bbe 16322
6d118b09
NC
16323 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
16324 inote.namedata = temp;
16325 }
16326
1449284b 16327 res &= process_note (& inote, file, section);
103f02d3 16328
6d118b09
NC
16329 if (temp != NULL)
16330 {
16331 free (temp);
16332 temp = NULL;
16333 }
779fe533
NC
16334 }
16335
16336 free (pnotes);
103f02d3 16337
779fe533
NC
16338 return res;
16339}
16340
16341static int
2cf0635d 16342process_corefile_note_segments (FILE * file)
779fe533 16343{
2cf0635d 16344 Elf_Internal_Phdr * segment;
b34976b6
AM
16345 unsigned int i;
16346 int res = 1;
103f02d3 16347
d93f0186 16348 if (! get_program_headers (file))
779fe533 16349 return 0;
103f02d3 16350
779fe533
NC
16351 for (i = 0, segment = program_headers;
16352 i < elf_header.e_phnum;
b34976b6 16353 i++, segment++)
779fe533
NC
16354 {
16355 if (segment->p_type == PT_NOTE)
1449284b
NC
16356 res &= process_notes_at (file, NULL,
16357 (bfd_vma) segment->p_offset,
16358 (bfd_vma) segment->p_filesz);
779fe533 16359 }
103f02d3 16360
779fe533
NC
16361 return res;
16362}
16363
685080f2
NC
16364static int
16365process_v850_notes (FILE * file, bfd_vma offset, bfd_vma length)
16366{
16367 Elf_External_Note * pnotes;
16368 Elf_External_Note * external;
c8071705 16369 char * end;
685080f2
NC
16370 int res = 1;
16371
16372 if (length <= 0)
16373 return 0;
16374
16375 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
16376 _("v850 notes"));
16377 if (pnotes == NULL)
16378 return 0;
16379
16380 external = pnotes;
c8071705 16381 end = (char*) pnotes + length;
685080f2
NC
16382
16383 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
16384 (unsigned long) offset, (unsigned long) length);
16385
c8071705 16386 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
16387 {
16388 Elf_External_Note * next;
16389 Elf_Internal_Note inote;
16390
16391 inote.type = BYTE_GET (external->type);
16392 inote.namesz = BYTE_GET (external->namesz);
16393 inote.namedata = external->name;
16394 inote.descsz = BYTE_GET (external->descsz);
16395 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
16396 inote.descpos = offset + (inote.descdata - (char *) pnotes);
16397
c8071705
NC
16398 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
16399 {
16400 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
16401 inote.descdata = inote.namedata;
16402 inote.namesz = 0;
16403 }
16404
685080f2
NC
16405 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
16406
c8071705 16407 if ( ((char *) next > end)
685080f2
NC
16408 || ((char *) next < (char *) pnotes))
16409 {
16410 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
16411 (unsigned long) ((char *) external - (char *) pnotes));
16412 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
16413 inote.type, inote.namesz, inote.descsz);
16414 break;
16415 }
16416
16417 external = next;
16418
16419 /* Prevent out-of-bounds indexing. */
c8071705 16420 if ( inote.namedata + inote.namesz > end
685080f2
NC
16421 || inote.namedata + inote.namesz < inote.namedata)
16422 {
16423 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
16424 (unsigned long) ((char *) external - (char *) pnotes));
16425 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
16426 inote.type, inote.namesz, inote.descsz);
16427 break;
16428 }
16429
16430 printf (" %s: ", get_v850_elf_note_type (inote.type));
16431
16432 if (! print_v850_note (& inote))
16433 {
16434 res = 0;
16435 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
16436 inote.namesz, inote.descsz);
16437 }
16438 }
16439
16440 free (pnotes);
16441
16442 return res;
16443}
16444
779fe533 16445static int
2cf0635d 16446process_note_sections (FILE * file)
1ec5cd37 16447{
2cf0635d 16448 Elf_Internal_Shdr * section;
1ec5cd37 16449 unsigned long i;
df565f32 16450 int n = 0;
1ec5cd37
NC
16451 int res = 1;
16452
16453 for (i = 0, section = section_headers;
fa1908fd 16454 i < elf_header.e_shnum && section != NULL;
1ec5cd37 16455 i++, section++)
685080f2
NC
16456 {
16457 if (section->sh_type == SHT_NOTE)
16458 {
1449284b
NC
16459 res &= process_notes_at (file, section,
16460 (bfd_vma) section->sh_offset,
16461 (bfd_vma) section->sh_size);
685080f2
NC
16462 n++;
16463 }
16464
16465 if (( elf_header.e_machine == EM_V800
16466 || elf_header.e_machine == EM_V850
16467 || elf_header.e_machine == EM_CYGNUS_V850)
16468 && section->sh_type == SHT_RENESAS_INFO)
16469 {
16470 res &= process_v850_notes (file,
16471 (bfd_vma) section->sh_offset,
16472 (bfd_vma) section->sh_size);
16473 n++;
16474 }
16475 }
df565f32
NC
16476
16477 if (n == 0)
16478 /* Try processing NOTE segments instead. */
16479 return process_corefile_note_segments (file);
1ec5cd37
NC
16480
16481 return res;
16482}
16483
16484static int
2cf0635d 16485process_notes (FILE * file)
779fe533
NC
16486{
16487 /* If we have not been asked to display the notes then do nothing. */
16488 if (! do_notes)
16489 return 1;
103f02d3 16490
779fe533 16491 if (elf_header.e_type != ET_CORE)
1ec5cd37 16492 return process_note_sections (file);
103f02d3 16493
779fe533 16494 /* No program headers means no NOTE segment. */
1ec5cd37
NC
16495 if (elf_header.e_phnum > 0)
16496 return process_corefile_note_segments (file);
779fe533 16497
1ec5cd37
NC
16498 printf (_("No note segments present in the core file.\n"));
16499 return 1;
779fe533
NC
16500}
16501
252b5132 16502static int
2cf0635d 16503process_arch_specific (FILE * file)
252b5132 16504{
a952a375
NC
16505 if (! do_arch)
16506 return 1;
16507
252b5132
RH
16508 switch (elf_header.e_machine)
16509 {
11c1ff18
PB
16510 case EM_ARM:
16511 return process_arm_specific (file);
252b5132 16512 case EM_MIPS:
4fe85591 16513 case EM_MIPS_RS3_LE:
252b5132
RH
16514 return process_mips_specific (file);
16515 break;
35c08157
KLC
16516 case EM_NDS32:
16517 return process_nds32_specific (file);
16518 break;
34c8bcba 16519 case EM_PPC:
b82317dd 16520 case EM_PPC64:
34c8bcba
JM
16521 return process_power_specific (file);
16522 break;
643f7afb
AK
16523 case EM_S390:
16524 case EM_S390_OLD:
16525 return process_s390_specific (file);
16526 break;
9e8c70f9
DM
16527 case EM_SPARC:
16528 case EM_SPARC32PLUS:
16529 case EM_SPARCV9:
16530 return process_sparc_specific (file);
16531 break;
59e6276b
JM
16532 case EM_TI_C6000:
16533 return process_tic6x_specific (file);
16534 break;
13761a11
NC
16535 case EM_MSP430:
16536 return process_msp430x_specific (file);
252b5132
RH
16537 default:
16538 break;
16539 }
16540 return 1;
16541}
16542
16543static int
2cf0635d 16544get_file_header (FILE * file)
252b5132 16545{
9ea033b2
NC
16546 /* Read in the identity array. */
16547 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
16548 return 0;
16549
9ea033b2 16550 /* Determine how to read the rest of the header. */
b34976b6 16551 switch (elf_header.e_ident[EI_DATA])
9ea033b2 16552 {
1a0670f3
AM
16553 default:
16554 case ELFDATANONE:
adab8cdc
AO
16555 case ELFDATA2LSB:
16556 byte_get = byte_get_little_endian;
16557 byte_put = byte_put_little_endian;
16558 break;
16559 case ELFDATA2MSB:
16560 byte_get = byte_get_big_endian;
16561 byte_put = byte_put_big_endian;
16562 break;
9ea033b2
NC
16563 }
16564
16565 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 16566 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
16567
16568 /* Read in the rest of the header. */
16569 if (is_32bit_elf)
16570 {
16571 Elf32_External_Ehdr ehdr32;
252b5132 16572
9ea033b2
NC
16573 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
16574 return 0;
103f02d3 16575
9ea033b2
NC
16576 elf_header.e_type = BYTE_GET (ehdr32.e_type);
16577 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
16578 elf_header.e_version = BYTE_GET (ehdr32.e_version);
16579 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
16580 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
16581 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
16582 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
16583 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
16584 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
16585 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
16586 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
16587 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
16588 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
16589 }
252b5132 16590 else
9ea033b2
NC
16591 {
16592 Elf64_External_Ehdr ehdr64;
a952a375
NC
16593
16594 /* If we have been compiled with sizeof (bfd_vma) == 4, then
16595 we will not be able to cope with the 64bit data found in
16596 64 ELF files. Detect this now and abort before we start
50c2245b 16597 overwriting things. */
a952a375
NC
16598 if (sizeof (bfd_vma) < 8)
16599 {
e3c8793a
NC
16600 error (_("This instance of readelf has been built without support for a\n\
1660164 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
16602 return 0;
16603 }
103f02d3 16604
9ea033b2
NC
16605 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
16606 return 0;
103f02d3 16607
9ea033b2
NC
16608 elf_header.e_type = BYTE_GET (ehdr64.e_type);
16609 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
16610 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
16611 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
16612 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
16613 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
16614 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
16615 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
16616 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
16617 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
16618 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
16619 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
16620 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
16621 }
252b5132 16622
7ece0d85
JJ
16623 if (elf_header.e_shoff)
16624 {
16625 /* There may be some extensions in the first section header. Don't
16626 bomb if we can't read it. */
16627 if (is_32bit_elf)
049b0c3a 16628 get_32bit_section_headers (file, TRUE);
7ece0d85 16629 else
049b0c3a 16630 get_64bit_section_headers (file, TRUE);
7ece0d85 16631 }
560f3c1c 16632
252b5132
RH
16633 return 1;
16634}
16635
fb52b2f4
NC
16636/* Process one ELF object file according to the command line options.
16637 This file may actually be stored in an archive. The file is
16638 positioned at the start of the ELF object. */
16639
ff78d6d6 16640static int
2cf0635d 16641process_object (char * file_name, FILE * file)
252b5132 16642{
252b5132
RH
16643 unsigned int i;
16644
252b5132
RH
16645 if (! get_file_header (file))
16646 {
16647 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 16648 return 1;
252b5132
RH
16649 }
16650
16651 /* Initialise per file variables. */
60bca95a 16652 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
16653 version_info[i] = 0;
16654
60bca95a 16655 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 16656 dynamic_info[i] = 0;
5115b233 16657 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
16658
16659 /* Process the file. */
16660 if (show_name)
16661 printf (_("\nFile: %s\n"), file_name);
16662
18bd398b
NC
16663 /* Initialise the dump_sects array from the cmdline_dump_sects array.
16664 Note we do this even if cmdline_dump_sects is empty because we
16665 must make sure that the dump_sets array is zeroed out before each
16666 object file is processed. */
16667 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 16668 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
16669
16670 if (num_cmdline_dump_sects > 0)
16671 {
16672 if (num_dump_sects == 0)
16673 /* A sneaky way of allocating the dump_sects array. */
09c11c86 16674 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
16675
16676 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
16677 memcpy (dump_sects, cmdline_dump_sects,
16678 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 16679 }
d70c5fc7 16680
252b5132 16681 if (! process_file_header ())
fb52b2f4 16682 return 1;
252b5132 16683
d1f5c6e3 16684 if (! process_section_headers (file))
2f62977e 16685 {
d1f5c6e3
L
16686 /* Without loaded section headers we cannot process lots of
16687 things. */
2f62977e 16688 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 16689
2f62977e 16690 if (! do_using_dynamic)
2c610e4b 16691 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 16692 }
252b5132 16693
d1f5c6e3
L
16694 if (! process_section_groups (file))
16695 {
16696 /* Without loaded section groups we cannot process unwind. */
16697 do_unwind = 0;
16698 }
16699
2f62977e 16700 if (process_program_headers (file))
b2d38a17 16701 process_dynamic_section (file);
252b5132
RH
16702
16703 process_relocs (file);
16704
4d6ed7c8
NC
16705 process_unwind (file);
16706
252b5132
RH
16707 process_symbol_table (file);
16708
16709 process_syminfo (file);
16710
16711 process_version_sections (file);
16712
16713 process_section_contents (file);
f5842774 16714
1ec5cd37 16715 process_notes (file);
103f02d3 16716
047b2264
JJ
16717 process_gnu_liblist (file);
16718
252b5132
RH
16719 process_arch_specific (file);
16720
d93f0186
NC
16721 if (program_headers)
16722 {
16723 free (program_headers);
16724 program_headers = NULL;
16725 }
16726
252b5132
RH
16727 if (section_headers)
16728 {
16729 free (section_headers);
16730 section_headers = NULL;
16731 }
16732
16733 if (string_table)
16734 {
16735 free (string_table);
16736 string_table = NULL;
d40ac9bd 16737 string_table_length = 0;
252b5132
RH
16738 }
16739
16740 if (dynamic_strings)
16741 {
16742 free (dynamic_strings);
16743 dynamic_strings = NULL;
d79b3d50 16744 dynamic_strings_length = 0;
252b5132
RH
16745 }
16746
16747 if (dynamic_symbols)
16748 {
16749 free (dynamic_symbols);
16750 dynamic_symbols = NULL;
19936277 16751 num_dynamic_syms = 0;
252b5132
RH
16752 }
16753
16754 if (dynamic_syminfo)
16755 {
16756 free (dynamic_syminfo);
16757 dynamic_syminfo = NULL;
16758 }
ff78d6d6 16759
293c573e
MR
16760 if (dynamic_section)
16761 {
16762 free (dynamic_section);
16763 dynamic_section = NULL;
16764 }
16765
e4b17d5c
L
16766 if (section_headers_groups)
16767 {
16768 free (section_headers_groups);
16769 section_headers_groups = NULL;
16770 }
16771
16772 if (section_groups)
16773 {
2cf0635d
NC
16774 struct group_list * g;
16775 struct group_list * next;
e4b17d5c
L
16776
16777 for (i = 0; i < group_count; i++)
16778 {
16779 for (g = section_groups [i].root; g != NULL; g = next)
16780 {
16781 next = g->next;
16782 free (g);
16783 }
16784 }
16785
16786 free (section_groups);
16787 section_groups = NULL;
16788 }
16789
19e6b90e 16790 free_debug_memory ();
18bd398b 16791
ff78d6d6 16792 return 0;
252b5132
RH
16793}
16794
2cf0635d
NC
16795/* Process an ELF archive.
16796 On entry the file is positioned just after the ARMAG string. */
16797
16798static int
16799process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
16800{
16801 struct archive_info arch;
16802 struct archive_info nested_arch;
16803 size_t got;
2cf0635d
NC
16804 int ret;
16805
16806 show_name = 1;
16807
16808 /* The ARCH structure is used to hold information about this archive. */
16809 arch.file_name = NULL;
16810 arch.file = NULL;
16811 arch.index_array = NULL;
16812 arch.sym_table = NULL;
16813 arch.longnames = NULL;
16814
16815 /* The NESTED_ARCH structure is used as a single-item cache of information
16816 about a nested archive (when members of a thin archive reside within
16817 another regular archive file). */
16818 nested_arch.file_name = NULL;
16819 nested_arch.file = NULL;
16820 nested_arch.index_array = NULL;
16821 nested_arch.sym_table = NULL;
16822 nested_arch.longnames = NULL;
16823
16824 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
16825 {
16826 ret = 1;
16827 goto out;
4145f1d5 16828 }
fb52b2f4 16829
4145f1d5
NC
16830 if (do_archive_index)
16831 {
2cf0635d 16832 if (arch.sym_table == NULL)
4145f1d5
NC
16833 error (_("%s: unable to dump the index as none was found\n"), file_name);
16834 else
16835 {
591f7597 16836 unsigned long i, l;
4145f1d5
NC
16837 unsigned long current_pos;
16838
591f7597
NC
16839 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
16840 file_name, (unsigned long) arch.index_num, arch.sym_size);
4145f1d5
NC
16841 current_pos = ftell (file);
16842
2cf0635d 16843 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 16844 {
2cf0635d
NC
16845 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
16846 {
16847 char * member_name;
4145f1d5 16848
2cf0635d
NC
16849 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
16850
16851 if (member_name != NULL)
16852 {
16853 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
16854
16855 if (qualified_name != NULL)
16856 {
c2a7d3f5
NC
16857 printf (_("Contents of binary %s at offset "), qualified_name);
16858 (void) print_vma (arch.index_array[i], PREFIX_HEX);
16859 putchar ('\n');
2cf0635d
NC
16860 free (qualified_name);
16861 }
4145f1d5
NC
16862 }
16863 }
2cf0635d
NC
16864
16865 if (l >= arch.sym_size)
4145f1d5
NC
16866 {
16867 error (_("%s: end of the symbol table reached before the end of the index\n"),
16868 file_name);
cb8f3167 16869 break;
4145f1d5 16870 }
591f7597
NC
16871 /* PR 17531: file: 0b6630b2. */
16872 printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
16873 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
16874 }
16875
c2a7d3f5
NC
16876 if (arch.uses_64bit_indicies)
16877 l = (l + 7) & ~ 7;
16878 else
16879 l += l & 1;
16880
2cf0635d 16881 if (l < arch.sym_size)
c2a7d3f5
NC
16882 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
16883 file_name, arch.sym_size - l);
4145f1d5 16884
4145f1d5
NC
16885 if (fseek (file, current_pos, SEEK_SET) != 0)
16886 {
16887 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
16888 ret = 1;
16889 goto out;
4145f1d5 16890 }
fb52b2f4 16891 }
4145f1d5
NC
16892
16893 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
16894 && !do_segments && !do_header && !do_dump && !do_version
16895 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 16896 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
16897 {
16898 ret = 0; /* Archive index only. */
16899 goto out;
16900 }
fb52b2f4
NC
16901 }
16902
d989285c 16903 ret = 0;
fb52b2f4
NC
16904
16905 while (1)
16906 {
2cf0635d
NC
16907 char * name;
16908 size_t namelen;
16909 char * qualified_name;
16910
16911 /* Read the next archive header. */
16912 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
16913 {
16914 error (_("%s: failed to seek to next archive header\n"), file_name);
16915 return 1;
16916 }
16917 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
16918 if (got != sizeof arch.arhdr)
16919 {
16920 if (got == 0)
16921 break;
16922 error (_("%s: failed to read archive header\n"), file_name);
16923 ret = 1;
16924 break;
16925 }
16926 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
16927 {
16928 error (_("%s: did not find a valid archive header\n"), arch.file_name);
16929 ret = 1;
16930 break;
16931 }
16932
16933 arch.next_arhdr_offset += sizeof arch.arhdr;
16934
16935 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
16936 if (archive_file_size & 01)
16937 ++archive_file_size;
16938
16939 name = get_archive_member_name (&arch, &nested_arch);
16940 if (name == NULL)
fb52b2f4 16941 {
0fd3a477 16942 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
16943 ret = 1;
16944 break;
fb52b2f4 16945 }
2cf0635d 16946 namelen = strlen (name);
fb52b2f4 16947
2cf0635d
NC
16948 qualified_name = make_qualified_name (&arch, &nested_arch, name);
16949 if (qualified_name == NULL)
fb52b2f4 16950 {
2cf0635d 16951 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
16952 ret = 1;
16953 break;
fb52b2f4
NC
16954 }
16955
2cf0635d
NC
16956 if (is_thin_archive && arch.nested_member_origin == 0)
16957 {
16958 /* This is a proxy for an external member of a thin archive. */
16959 FILE * member_file;
16960 char * member_file_name = adjust_relative_path (file_name, name, namelen);
16961 if (member_file_name == NULL)
16962 {
16963 ret = 1;
16964 break;
16965 }
16966
16967 member_file = fopen (member_file_name, "rb");
16968 if (member_file == NULL)
16969 {
16970 error (_("Input file '%s' is not readable.\n"), member_file_name);
16971 free (member_file_name);
16972 ret = 1;
16973 break;
16974 }
16975
16976 archive_file_offset = arch.nested_member_origin;
16977
16978 ret |= process_object (qualified_name, member_file);
16979
16980 fclose (member_file);
16981 free (member_file_name);
16982 }
16983 else if (is_thin_archive)
16984 {
a043396b
NC
16985 /* PR 15140: Allow for corrupt thin archives. */
16986 if (nested_arch.file == NULL)
16987 {
16988 error (_("%s: contains corrupt thin archive: %s\n"),
16989 file_name, name);
16990 ret = 1;
16991 break;
16992 }
16993
2cf0635d
NC
16994 /* This is a proxy for a member of a nested archive. */
16995 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
16996
16997 /* The nested archive file will have been opened and setup by
16998 get_archive_member_name. */
16999 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
17000 {
17001 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
17002 ret = 1;
17003 break;
17004 }
17005
17006 ret |= process_object (qualified_name, nested_arch.file);
17007 }
17008 else
17009 {
17010 archive_file_offset = arch.next_arhdr_offset;
17011 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 17012
2cf0635d
NC
17013 ret |= process_object (qualified_name, file);
17014 }
fb52b2f4 17015
2b52916e
L
17016 if (dump_sects != NULL)
17017 {
17018 free (dump_sects);
17019 dump_sects = NULL;
17020 num_dump_sects = 0;
17021 }
17022
2cf0635d 17023 free (qualified_name);
fb52b2f4
NC
17024 }
17025
4145f1d5 17026 out:
2cf0635d
NC
17027 if (nested_arch.file != NULL)
17028 fclose (nested_arch.file);
17029 release_archive (&nested_arch);
17030 release_archive (&arch);
fb52b2f4 17031
d989285c 17032 return ret;
fb52b2f4
NC
17033}
17034
17035static int
2cf0635d 17036process_file (char * file_name)
fb52b2f4 17037{
2cf0635d 17038 FILE * file;
fb52b2f4
NC
17039 struct stat statbuf;
17040 char armag[SARMAG];
17041 int ret;
17042
17043 if (stat (file_name, &statbuf) < 0)
17044 {
f24ddbdd
NC
17045 if (errno == ENOENT)
17046 error (_("'%s': No such file\n"), file_name);
17047 else
17048 error (_("Could not locate '%s'. System error message: %s\n"),
17049 file_name, strerror (errno));
17050 return 1;
17051 }
17052
17053 if (! S_ISREG (statbuf.st_mode))
17054 {
17055 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
17056 return 1;
17057 }
17058
17059 file = fopen (file_name, "rb");
17060 if (file == NULL)
17061 {
f24ddbdd 17062 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
17063 return 1;
17064 }
17065
17066 if (fread (armag, SARMAG, 1, file) != 1)
17067 {
4145f1d5 17068 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
17069 fclose (file);
17070 return 1;
17071 }
17072
f54498b4
NC
17073 current_file_size = (bfd_size_type) statbuf.st_size;
17074
fb52b2f4 17075 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
17076 ret = process_archive (file_name, file, FALSE);
17077 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
17078 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
17079 else
17080 {
4145f1d5
NC
17081 if (do_archive_index)
17082 error (_("File %s is not an archive so its index cannot be displayed.\n"),
17083 file_name);
17084
fb52b2f4
NC
17085 rewind (file);
17086 archive_file_size = archive_file_offset = 0;
17087 ret = process_object (file_name, file);
17088 }
17089
17090 fclose (file);
17091
f54498b4 17092 current_file_size = 0;
fb52b2f4
NC
17093 return ret;
17094}
17095
252b5132
RH
17096#ifdef SUPPORT_DISASSEMBLY
17097/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 17098 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 17099 symbols. */
252b5132
RH
17100
17101void
2cf0635d 17102print_address (unsigned int addr, FILE * outfile)
252b5132
RH
17103{
17104 fprintf (outfile,"0x%8.8x", addr);
17105}
17106
e3c8793a 17107/* Needed by the i386 disassembler. */
252b5132
RH
17108void
17109db_task_printsym (unsigned int addr)
17110{
17111 print_address (addr, stderr);
17112}
17113#endif
17114
17115int
2cf0635d 17116main (int argc, char ** argv)
252b5132 17117{
ff78d6d6
L
17118 int err;
17119
252b5132
RH
17120#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
17121 setlocale (LC_MESSAGES, "");
3882b010
L
17122#endif
17123#if defined (HAVE_SETLOCALE)
17124 setlocale (LC_CTYPE, "");
252b5132
RH
17125#endif
17126 bindtextdomain (PACKAGE, LOCALEDIR);
17127 textdomain (PACKAGE);
17128
869b9d07
MM
17129 expandargv (&argc, &argv);
17130
252b5132
RH
17131 parse_args (argc, argv);
17132
18bd398b 17133 if (num_dump_sects > 0)
59f14fc0 17134 {
18bd398b 17135 /* Make a copy of the dump_sects array. */
3f5e193b
NC
17136 cmdline_dump_sects = (dump_type *)
17137 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 17138 if (cmdline_dump_sects == NULL)
591a748a 17139 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
17140 else
17141 {
09c11c86
NC
17142 memcpy (cmdline_dump_sects, dump_sects,
17143 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
17144 num_cmdline_dump_sects = num_dump_sects;
17145 }
17146 }
17147
18bd398b
NC
17148 if (optind < (argc - 1))
17149 show_name = 1;
5656ba2c
L
17150 else if (optind >= argc)
17151 {
17152 warn (_("Nothing to do.\n"));
17153 usage (stderr);
17154 }
18bd398b 17155
ff78d6d6 17156 err = 0;
252b5132 17157 while (optind < argc)
18bd398b 17158 err |= process_file (argv[optind++]);
252b5132
RH
17159
17160 if (dump_sects != NULL)
17161 free (dump_sects);
59f14fc0
AS
17162 if (cmdline_dump_sects != NULL)
17163 free (cmdline_dump_sects);
252b5132 17164
ff78d6d6 17165 return err;
252b5132 17166}