Fix an integer overflow in RISC-V relocation handling
[deliverable/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
1a9ccd70 3800 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
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
1a9ccd70 3825 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 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;
1a9ccd70 4773 Elf_Internal_Phdr * previous_load = NULL;
252b5132
RH
4774
4775 if (elf_header.e_phnum == 0)
4776 {
82f2dbf7
NC
4777 /* PR binutils/12467. */
4778 if (elf_header.e_phoff != 0)
4779 warn (_("possibly corrupt ELF header - it has a non-zero program"
9035ed51 4780 " header offset, but no program headers\n"));
82f2dbf7 4781 else if (do_segments)
252b5132 4782 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 4783 return 0;
252b5132
RH
4784 }
4785
4786 if (do_segments && !do_header)
4787 {
f7a99963
NC
4788 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
4789 printf (_("Entry point "));
4790 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4791 printf (_("\nThere are %d program headers, starting at offset "),
4792 elf_header.e_phnum);
4793 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4794 printf ("\n");
252b5132
RH
4795 }
4796
d93f0186 4797 if (! get_program_headers (file))
252b5132 4798 return 0;
103f02d3 4799
252b5132
RH
4800 if (do_segments)
4801 {
3a1a2036
NC
4802 if (elf_header.e_phnum > 1)
4803 printf (_("\nProgram Headers:\n"));
4804 else
4805 printf (_("\nProgram Headers:\n"));
76da6bbe 4806
f7a99963
NC
4807 if (is_32bit_elf)
4808 printf
4809 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4810 else if (do_wide)
4811 printf
4812 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4813 else
4814 {
4815 printf
4816 (_(" Type Offset VirtAddr PhysAddr\n"));
4817 printf
4818 (_(" FileSiz MemSiz Flags Align\n"));
4819 }
252b5132
RH
4820 }
4821
252b5132 4822 dynamic_addr = 0;
1b228002 4823 dynamic_size = 0;
252b5132
RH
4824
4825 for (i = 0, segment = program_headers;
4826 i < elf_header.e_phnum;
b34976b6 4827 i++, segment++)
252b5132
RH
4828 {
4829 if (do_segments)
4830 {
103f02d3 4831 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
4832
4833 if (is_32bit_elf)
4834 {
4835 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4836 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4837 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4838 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4839 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4840 printf ("%c%c%c ",
4841 (segment->p_flags & PF_R ? 'R' : ' '),
4842 (segment->p_flags & PF_W ? 'W' : ' '),
4843 (segment->p_flags & PF_X ? 'E' : ' '));
4844 printf ("%#lx", (unsigned long) segment->p_align);
4845 }
d974e256
JJ
4846 else if (do_wide)
4847 {
4848 if ((unsigned long) segment->p_offset == segment->p_offset)
4849 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4850 else
4851 {
4852 print_vma (segment->p_offset, FULL_HEX);
4853 putchar (' ');
4854 }
4855
4856 print_vma (segment->p_vaddr, FULL_HEX);
4857 putchar (' ');
4858 print_vma (segment->p_paddr, FULL_HEX);
4859 putchar (' ');
4860
4861 if ((unsigned long) segment->p_filesz == segment->p_filesz)
4862 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
4863 else
4864 {
4865 print_vma (segment->p_filesz, FULL_HEX);
4866 putchar (' ');
4867 }
4868
4869 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4870 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4871 else
4872 {
f48e6c45 4873 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4874 }
4875
4876 printf (" %c%c%c ",
4877 (segment->p_flags & PF_R ? 'R' : ' '),
4878 (segment->p_flags & PF_W ? 'W' : ' '),
4879 (segment->p_flags & PF_X ? 'E' : ' '));
4880
4881 if ((unsigned long) segment->p_align == segment->p_align)
4882 printf ("%#lx", (unsigned long) segment->p_align);
4883 else
4884 {
4885 print_vma (segment->p_align, PREFIX_HEX);
4886 }
4887 }
f7a99963
NC
4888 else
4889 {
4890 print_vma (segment->p_offset, FULL_HEX);
4891 putchar (' ');
4892 print_vma (segment->p_vaddr, FULL_HEX);
4893 putchar (' ');
4894 print_vma (segment->p_paddr, FULL_HEX);
4895 printf ("\n ");
4896 print_vma (segment->p_filesz, FULL_HEX);
4897 putchar (' ');
4898 print_vma (segment->p_memsz, FULL_HEX);
4899 printf (" %c%c%c ",
4900 (segment->p_flags & PF_R ? 'R' : ' '),
4901 (segment->p_flags & PF_W ? 'W' : ' '),
4902 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 4903 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 4904 }
252b5132 4905
1a9ccd70
NC
4906 putc ('\n', stdout);
4907 }
f54498b4 4908
252b5132
RH
4909 switch (segment->p_type)
4910 {
1a9ccd70 4911 case PT_LOAD:
502d895c
NC
4912#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
4913 required by the ELF standard, several programs, including the Linux
4914 kernel, make use of non-ordered segments. */
1a9ccd70
NC
4915 if (previous_load
4916 && previous_load->p_vaddr > segment->p_vaddr)
4917 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 4918#endif
1a9ccd70
NC
4919 if (segment->p_memsz < segment->p_filesz)
4920 error (_("the segment's file size is larger than its memory size\n"));
4921 previous_load = segment;
4922 break;
4923
4924 case PT_PHDR:
4925 /* PR 20815 - Verify that the program header is loaded into memory. */
4926 if (i > 0 && previous_load != NULL)
4927 error (_("the PHDR segment must occur before any LOAD segment\n"));
4928 if (elf_header.e_machine != EM_PARISC)
4929 {
4930 unsigned int j;
4931
4932 for (j = 1; j < elf_header.e_phnum; j++)
4933 if (program_headers[j].p_vaddr <= segment->p_vaddr
4934 && (program_headers[j].p_vaddr + program_headers[j].p_memsz)
4935 >= (segment->p_vaddr + segment->p_filesz))
4936 break;
4937 if (j == elf_header.e_phnum)
4938 error (_("the PHDR segment is not covered by a LOAD segment\n"));
4939 }
4940 break;
4941
252b5132
RH
4942 case PT_DYNAMIC:
4943 if (dynamic_addr)
4944 error (_("more than one dynamic segment\n"));
4945
20737c13
AM
4946 /* By default, assume that the .dynamic section is the first
4947 section in the DYNAMIC segment. */
4948 dynamic_addr = segment->p_offset;
4949 dynamic_size = segment->p_filesz;
f54498b4
NC
4950 /* PR binutils/17512: Avoid corrupt dynamic section info in the segment. */
4951 if (dynamic_addr + dynamic_size >= current_file_size)
4952 {
4953 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
4954 dynamic_addr = dynamic_size = 0;
4955 }
20737c13 4956
b2d38a17
NC
4957 /* Try to locate the .dynamic section. If there is
4958 a section header table, we can easily locate it. */
4959 if (section_headers != NULL)
4960 {
2cf0635d 4961 Elf_Internal_Shdr * sec;
b2d38a17 4962
89fac5e3
RS
4963 sec = find_section (".dynamic");
4964 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4965 {
28f997cf
TG
4966 /* A corresponding .dynamic section is expected, but on
4967 IA-64/OpenVMS it is OK for it to be missing. */
4968 if (!is_ia64_vms ())
4969 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4970 break;
4971 }
4972
42bb2e33 4973 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4974 {
4975 dynamic_size = 0;
4976 break;
4977 }
42bb2e33 4978
b2d38a17
NC
4979 dynamic_addr = sec->sh_offset;
4980 dynamic_size = sec->sh_size;
4981
4982 if (dynamic_addr < segment->p_offset
4983 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4984 warn (_("the .dynamic section is not contained"
4985 " within the dynamic segment\n"));
b2d38a17 4986 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4987 warn (_("the .dynamic section is not the first section"
4988 " in the dynamic segment.\n"));
b2d38a17 4989 }
252b5132
RH
4990 break;
4991
4992 case PT_INTERP:
fb52b2f4
NC
4993 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4994 SEEK_SET))
252b5132
RH
4995 error (_("Unable to find program interpreter name\n"));
4996 else
4997 {
f8eae8b2 4998 char fmt [32];
9495b2e6 4999 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5000
5001 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5002 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5003
252b5132 5004 program_interpreter[0] = 0;
7bd7b3ef
AM
5005 if (fscanf (file, fmt, program_interpreter) <= 0)
5006 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5007
5008 if (do_segments)
f54498b4 5009 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
5010 program_interpreter);
5011 }
5012 break;
5013 }
252b5132
RH
5014 }
5015
c256ffe7 5016 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
5017 {
5018 printf (_("\n Section to Segment mapping:\n"));
5019 printf (_(" Segment Sections...\n"));
5020
252b5132
RH
5021 for (i = 0; i < elf_header.e_phnum; i++)
5022 {
9ad5cbcf 5023 unsigned int j;
2cf0635d 5024 Elf_Internal_Shdr * section;
252b5132
RH
5025
5026 segment = program_headers + i;
b391a3e3 5027 section = section_headers + 1;
252b5132
RH
5028
5029 printf (" %2.2d ", i);
5030
b34976b6 5031 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 5032 {
f4638467
AM
5033 if (!ELF_TBSS_SPECIAL (section, segment)
5034 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
74e1a04b 5035 printf ("%s ", printable_section_name (section));
252b5132
RH
5036 }
5037
5038 putc ('\n',stdout);
5039 }
5040 }
5041
252b5132
RH
5042 return 1;
5043}
5044
5045
d93f0186
NC
5046/* Find the file offset corresponding to VMA by using the program headers. */
5047
5048static long
2cf0635d 5049offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 5050{
2cf0635d 5051 Elf_Internal_Phdr * seg;
d93f0186
NC
5052
5053 if (! get_program_headers (file))
5054 {
5055 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5056 return (long) vma;
5057 }
5058
5059 for (seg = program_headers;
5060 seg < program_headers + elf_header.e_phnum;
5061 ++seg)
5062 {
5063 if (seg->p_type != PT_LOAD)
5064 continue;
5065
5066 if (vma >= (seg->p_vaddr & -seg->p_align)
5067 && vma + size <= seg->p_vaddr + seg->p_filesz)
5068 return vma - seg->p_vaddr + seg->p_offset;
5069 }
5070
5071 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5072 (unsigned long) vma);
d93f0186
NC
5073 return (long) vma;
5074}
5075
5076
049b0c3a
NC
5077/* Allocate memory and load the sections headers into the global pointer
5078 SECTION_HEADERS. If PROBE is true, this is just a probe and we do not
5079 generate any error messages if the load fails. */
5080
5081static bfd_boolean
5082get_32bit_section_headers (FILE * file, bfd_boolean probe)
252b5132 5083{
2cf0635d
NC
5084 Elf32_External_Shdr * shdrs;
5085 Elf_Internal_Shdr * internal;
b34976b6 5086 unsigned int i;
049b0c3a
NC
5087 unsigned int size = elf_header.e_shentsize;
5088 unsigned int num = probe ? 1 : elf_header.e_shnum;
5089
5090 /* PR binutils/17531: Cope with unexpected section header sizes. */
5091 if (size == 0 || num == 0)
5092 return FALSE;
5093 if (size < sizeof * shdrs)
5094 {
5095 if (! probe)
5096 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5097 return FALSE;
5098 }
5099 if (!probe && size > sizeof * shdrs)
5100 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5101
3f5e193b 5102 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
5103 size, num,
5104 probe ? NULL : _("section headers"));
5105 if (shdrs == NULL)
5106 return FALSE;
252b5132 5107
049b0c3a
NC
5108 if (section_headers != NULL)
5109 free (section_headers);
3f5e193b
NC
5110 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
5111 sizeof (Elf_Internal_Shdr));
252b5132
RH
5112 if (section_headers == NULL)
5113 {
049b0c3a 5114 if (!probe)
8b73c356 5115 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 5116 return FALSE;
252b5132
RH
5117 }
5118
5119 for (i = 0, internal = section_headers;
560f3c1c 5120 i < num;
b34976b6 5121 i++, internal++)
252b5132
RH
5122 {
5123 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5124 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5125 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5126 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5127 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5128 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5129 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5130 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5131 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5132 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5133 if (!probe && internal->sh_link > num)
5134 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5135 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5136 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5137 }
5138
5139 free (shdrs);
049b0c3a 5140 return TRUE;
252b5132
RH
5141}
5142
049b0c3a
NC
5143static bfd_boolean
5144get_64bit_section_headers (FILE * file, bfd_boolean probe)
9ea033b2 5145{
2cf0635d
NC
5146 Elf64_External_Shdr * shdrs;
5147 Elf_Internal_Shdr * internal;
b34976b6 5148 unsigned int i;
049b0c3a
NC
5149 unsigned int size = elf_header.e_shentsize;
5150 unsigned int num = probe ? 1 : elf_header.e_shnum;
5151
5152 /* PR binutils/17531: Cope with unexpected section header sizes. */
5153 if (size == 0 || num == 0)
5154 return FALSE;
5155 if (size < sizeof * shdrs)
5156 {
5157 if (! probe)
5158 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5159 return FALSE;
5160 }
5161 if (! probe && size > sizeof * shdrs)
5162 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5163
3f5e193b 5164 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
5165 size, num,
5166 probe ? NULL : _("section headers"));
5167 if (shdrs == NULL)
5168 return FALSE;
9ea033b2 5169
049b0c3a
NC
5170 if (section_headers != NULL)
5171 free (section_headers);
3f5e193b
NC
5172 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
5173 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
5174 if (section_headers == NULL)
5175 {
049b0c3a 5176 if (! probe)
8b73c356 5177 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 5178 return FALSE;
9ea033b2
NC
5179 }
5180
5181 for (i = 0, internal = section_headers;
560f3c1c 5182 i < num;
b34976b6 5183 i++, internal++)
9ea033b2
NC
5184 {
5185 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5186 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5187 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5188 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5189 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5190 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5191 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5192 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5193 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5194 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5195 if (!probe && internal->sh_link > num)
5196 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5197 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5198 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5199 }
5200
5201 free (shdrs);
049b0c3a 5202 return TRUE;
9ea033b2
NC
5203}
5204
252b5132 5205static Elf_Internal_Sym *
ba5cdace
NC
5206get_32bit_elf_symbols (FILE * file,
5207 Elf_Internal_Shdr * section,
5208 unsigned long * num_syms_return)
252b5132 5209{
ba5cdace 5210 unsigned long number = 0;
dd24e3da 5211 Elf32_External_Sym * esyms = NULL;
ba5cdace 5212 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5213 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5214 Elf_Internal_Sym * psym;
b34976b6 5215 unsigned int j;
252b5132 5216
c9c1d674
EG
5217 if (section->sh_size == 0)
5218 {
5219 if (num_syms_return != NULL)
5220 * num_syms_return = 0;
5221 return NULL;
5222 }
5223
dd24e3da 5224 /* Run some sanity checks first. */
c9c1d674 5225 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5226 {
c9c1d674
EG
5227 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
5228 printable_section_name (section), (unsigned long) section->sh_entsize);
ba5cdace 5229 goto exit_point;
dd24e3da
NC
5230 }
5231
f54498b4
NC
5232 if (section->sh_size > current_file_size)
5233 {
5234 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
74e1a04b 5235 printable_section_name (section), (unsigned long) section->sh_size);
f54498b4
NC
5236 goto exit_point;
5237 }
5238
dd24e3da
NC
5239 number = section->sh_size / section->sh_entsize;
5240
5241 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5242 {
c9c1d674 5243 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
5244 (unsigned long) section->sh_size,
5245 printable_section_name (section),
5246 (unsigned long) section->sh_entsize);
ba5cdace 5247 goto exit_point;
dd24e3da
NC
5248 }
5249
3f5e193b
NC
5250 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
5251 section->sh_size, _("symbols"));
dd24e3da 5252 if (esyms == NULL)
ba5cdace 5253 goto exit_point;
252b5132 5254
6a40cf0c
NC
5255 {
5256 elf_section_list * entry;
5257
5258 shndx = NULL;
5259 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
5260 if (entry->hdr->sh_link == (unsigned long) (section - section_headers))
c9c1d674 5261 {
6a40cf0c
NC
5262 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
5263 entry->hdr->sh_offset,
5264 1, entry->hdr->sh_size,
5265 _("symbol table section indicies"));
5266 if (shndx == NULL)
5267 goto exit_point;
5268 /* PR17531: file: heap-buffer-overflow */
5269 else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5270 {
5271 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5272 printable_section_name (entry->hdr),
5273 (unsigned long) entry->hdr->sh_size,
5274 (unsigned long) section->sh_size);
5275 goto exit_point;
5276 }
c9c1d674 5277 }
6a40cf0c 5278 }
9ad5cbcf 5279
3f5e193b 5280 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5281
5282 if (isyms == NULL)
5283 {
8b73c356
NC
5284 error (_("Out of memory reading %lu symbols\n"),
5285 (unsigned long) number);
dd24e3da 5286 goto exit_point;
252b5132
RH
5287 }
5288
dd24e3da 5289 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5290 {
5291 psym->st_name = BYTE_GET (esyms[j].st_name);
5292 psym->st_value = BYTE_GET (esyms[j].st_value);
5293 psym->st_size = BYTE_GET (esyms[j].st_size);
5294 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5295 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5296 psym->st_shndx
5297 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5298 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5299 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5300 psym->st_info = BYTE_GET (esyms[j].st_info);
5301 psym->st_other = BYTE_GET (esyms[j].st_other);
5302 }
5303
dd24e3da 5304 exit_point:
ba5cdace 5305 if (shndx != NULL)
9ad5cbcf 5306 free (shndx);
ba5cdace 5307 if (esyms != NULL)
dd24e3da 5308 free (esyms);
252b5132 5309
ba5cdace
NC
5310 if (num_syms_return != NULL)
5311 * num_syms_return = isyms == NULL ? 0 : number;
5312
252b5132
RH
5313 return isyms;
5314}
5315
9ea033b2 5316static Elf_Internal_Sym *
ba5cdace
NC
5317get_64bit_elf_symbols (FILE * file,
5318 Elf_Internal_Shdr * section,
5319 unsigned long * num_syms_return)
9ea033b2 5320{
ba5cdace
NC
5321 unsigned long number = 0;
5322 Elf64_External_Sym * esyms = NULL;
5323 Elf_External_Sym_Shndx * shndx = NULL;
5324 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5325 Elf_Internal_Sym * psym;
b34976b6 5326 unsigned int j;
9ea033b2 5327
c9c1d674
EG
5328 if (section->sh_size == 0)
5329 {
5330 if (num_syms_return != NULL)
5331 * num_syms_return = 0;
5332 return NULL;
5333 }
5334
dd24e3da 5335 /* Run some sanity checks first. */
c9c1d674 5336 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5337 {
c9c1d674 5338 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
8066deb1
AM
5339 printable_section_name (section),
5340 (unsigned long) section->sh_entsize);
ba5cdace 5341 goto exit_point;
dd24e3da
NC
5342 }
5343
f54498b4
NC
5344 if (section->sh_size > current_file_size)
5345 {
5346 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
8066deb1
AM
5347 printable_section_name (section),
5348 (unsigned long) section->sh_size);
f54498b4
NC
5349 goto exit_point;
5350 }
5351
dd24e3da
NC
5352 number = section->sh_size / section->sh_entsize;
5353
5354 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5355 {
c9c1d674 5356 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
5357 (unsigned long) section->sh_size,
5358 printable_section_name (section),
5359 (unsigned long) section->sh_entsize);
ba5cdace 5360 goto exit_point;
dd24e3da
NC
5361 }
5362
3f5e193b
NC
5363 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
5364 section->sh_size, _("symbols"));
a6e9f9df 5365 if (!esyms)
ba5cdace 5366 goto exit_point;
9ea033b2 5367
6a40cf0c
NC
5368 {
5369 elf_section_list * entry;
5370
5371 shndx = NULL;
5372 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
5373 if (entry->hdr->sh_link == (unsigned long) (section - section_headers))
c9c1d674 5374 {
6a40cf0c
NC
5375 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
5376 entry->hdr->sh_offset,
5377 1, entry->hdr->sh_size,
5378 _("symbol table section indicies"));
5379 if (shndx == NULL)
5380 goto exit_point;
5381 /* PR17531: file: heap-buffer-overflow */
5382 else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5383 {
5384 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5385 printable_section_name (entry->hdr),
5386 (unsigned long) entry->hdr->sh_size,
5387 (unsigned long) section->sh_size);
5388 goto exit_point;
5389 }
c9c1d674 5390 }
6a40cf0c 5391 }
9ad5cbcf 5392
3f5e193b 5393 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5394
5395 if (isyms == NULL)
5396 {
8b73c356
NC
5397 error (_("Out of memory reading %lu symbols\n"),
5398 (unsigned long) number);
ba5cdace 5399 goto exit_point;
9ea033b2
NC
5400 }
5401
ba5cdace 5402 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5403 {
5404 psym->st_name = BYTE_GET (esyms[j].st_name);
5405 psym->st_info = BYTE_GET (esyms[j].st_info);
5406 psym->st_other = BYTE_GET (esyms[j].st_other);
5407 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5408
4fbb74a6 5409 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5410 psym->st_shndx
5411 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5412 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5413 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5414
66543521
AM
5415 psym->st_value = BYTE_GET (esyms[j].st_value);
5416 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5417 }
5418
ba5cdace
NC
5419 exit_point:
5420 if (shndx != NULL)
9ad5cbcf 5421 free (shndx);
ba5cdace
NC
5422 if (esyms != NULL)
5423 free (esyms);
5424
5425 if (num_syms_return != NULL)
5426 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5427
5428 return isyms;
5429}
5430
d1133906 5431static const char *
d3ba0551 5432get_elf_section_flags (bfd_vma sh_flags)
d1133906 5433{
5477e8a0 5434 static char buff[1024];
2cf0635d 5435 char * p = buff;
8d5ff12c 5436 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
5437 int sindex;
5438 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5439 bfd_vma os_flags = 0;
5440 bfd_vma proc_flags = 0;
5441 bfd_vma unknown_flags = 0;
148b93f2 5442 static const struct
5477e8a0 5443 {
2cf0635d 5444 const char * str;
5477e8a0
L
5445 int len;
5446 }
5447 flags [] =
5448 {
cfcac11d
NC
5449 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5450 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5451 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5452 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5453 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5454 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5455 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5456 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5457 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5458 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5459 /* IA-64 specific. */
5460 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5461 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5462 /* IA-64 OpenVMS specific. */
5463 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5464 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5465 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5466 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5467 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5468 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5469 /* Generic. */
cfcac11d 5470 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5471 /* SPARC specific. */
77115a4a 5472 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5473 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5474 /* ARM specific. */
5475 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5476 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
ac4c9b04 5477 /* 23 */ { STRING_COMMA_LEN ("COMDEF") }
5477e8a0
L
5478 };
5479
5480 if (do_section_details)
5481 {
8d5ff12c
L
5482 sprintf (buff, "[%*.*lx]: ",
5483 field_size, field_size, (unsigned long) sh_flags);
5484 p += field_size + 4;
5477e8a0 5485 }
76da6bbe 5486
d1133906
NC
5487 while (sh_flags)
5488 {
5489 bfd_vma flag;
5490
5491 flag = sh_flags & - sh_flags;
5492 sh_flags &= ~ flag;
76da6bbe 5493
5477e8a0 5494 if (do_section_details)
d1133906 5495 {
5477e8a0
L
5496 switch (flag)
5497 {
91d6fa6a
NC
5498 case SHF_WRITE: sindex = 0; break;
5499 case SHF_ALLOC: sindex = 1; break;
5500 case SHF_EXECINSTR: sindex = 2; break;
5501 case SHF_MERGE: sindex = 3; break;
5502 case SHF_STRINGS: sindex = 4; break;
5503 case SHF_INFO_LINK: sindex = 5; break;
5504 case SHF_LINK_ORDER: sindex = 6; break;
5505 case SHF_OS_NONCONFORMING: sindex = 7; break;
5506 case SHF_GROUP: sindex = 8; break;
5507 case SHF_TLS: sindex = 9; break;
18ae9cc1 5508 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 5509 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 5510
5477e8a0 5511 default:
91d6fa6a 5512 sindex = -1;
cfcac11d 5513 switch (elf_header.e_machine)
148b93f2 5514 {
cfcac11d 5515 case EM_IA_64:
148b93f2 5516 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5517 sindex = 10;
148b93f2 5518 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5519 sindex = 11;
148b93f2
NC
5520#ifdef BFD64
5521 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
5522 switch (flag)
5523 {
91d6fa6a
NC
5524 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5525 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5526 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5527 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5528 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5529 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5530 default: break;
5531 }
5532#endif
cfcac11d
NC
5533 break;
5534
caa83f8b 5535 case EM_386:
22abe556 5536 case EM_IAMCU:
caa83f8b 5537 case EM_X86_64:
7f502d6c 5538 case EM_L1OM:
7a9068fe 5539 case EM_K1OM:
cfcac11d
NC
5540 case EM_OLD_SPARCV9:
5541 case EM_SPARC32PLUS:
5542 case EM_SPARCV9:
5543 case EM_SPARC:
18ae9cc1 5544 if (flag == SHF_ORDERED)
91d6fa6a 5545 sindex = 19;
cfcac11d 5546 break;
ac4c9b04
MG
5547
5548 case EM_ARM:
5549 switch (flag)
5550 {
5551 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 5552 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
5553 case SHF_COMDEF: sindex = 23; break;
5554 default: break;
5555 }
5556 break;
5557
cfcac11d
NC
5558 default:
5559 break;
148b93f2 5560 }
5477e8a0
L
5561 }
5562
91d6fa6a 5563 if (sindex != -1)
5477e8a0 5564 {
8d5ff12c
L
5565 if (p != buff + field_size + 4)
5566 {
5567 if (size < (10 + 2))
bee0ee85
NC
5568 {
5569 warn (_("Internal error: not enough buffer room for section flag info"));
5570 return _("<unknown>");
5571 }
8d5ff12c
L
5572 size -= 2;
5573 *p++ = ',';
5574 *p++ = ' ';
5575 }
5576
91d6fa6a
NC
5577 size -= flags [sindex].len;
5578 p = stpcpy (p, flags [sindex].str);
5477e8a0 5579 }
3b22753a 5580 else if (flag & SHF_MASKOS)
8d5ff12c 5581 os_flags |= flag;
d1133906 5582 else if (flag & SHF_MASKPROC)
8d5ff12c 5583 proc_flags |= flag;
d1133906 5584 else
8d5ff12c 5585 unknown_flags |= flag;
5477e8a0
L
5586 }
5587 else
5588 {
5589 switch (flag)
5590 {
5591 case SHF_WRITE: *p = 'W'; break;
5592 case SHF_ALLOC: *p = 'A'; break;
5593 case SHF_EXECINSTR: *p = 'X'; break;
5594 case SHF_MERGE: *p = 'M'; break;
5595 case SHF_STRINGS: *p = 'S'; break;
5596 case SHF_INFO_LINK: *p = 'I'; break;
5597 case SHF_LINK_ORDER: *p = 'L'; break;
5598 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5599 case SHF_GROUP: *p = 'G'; break;
5600 case SHF_TLS: *p = 'T'; break;
18ae9cc1 5601 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 5602 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
5603
5604 default:
8a9036a4 5605 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
5606 || elf_header.e_machine == EM_L1OM
5607 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
5608 && flag == SHF_X86_64_LARGE)
5609 *p = 'l';
91f68a68 5610 else if (elf_header.e_machine == EM_ARM
f0728ee3 5611 && flag == SHF_ARM_PURECODE)
91f68a68 5612 *p = 'y';
5477e8a0
L
5613 else if (flag & SHF_MASKOS)
5614 {
5615 *p = 'o';
5616 sh_flags &= ~ SHF_MASKOS;
5617 }
5618 else if (flag & SHF_MASKPROC)
5619 {
5620 *p = 'p';
5621 sh_flags &= ~ SHF_MASKPROC;
5622 }
5623 else
5624 *p = 'x';
5625 break;
5626 }
5627 p++;
d1133906
NC
5628 }
5629 }
76da6bbe 5630
8d5ff12c
L
5631 if (do_section_details)
5632 {
5633 if (os_flags)
5634 {
5635 size -= 5 + field_size;
5636 if (p != buff + field_size + 4)
5637 {
5638 if (size < (2 + 1))
bee0ee85
NC
5639 {
5640 warn (_("Internal error: not enough buffer room for section flag info"));
5641 return _("<unknown>");
5642 }
8d5ff12c
L
5643 size -= 2;
5644 *p++ = ',';
5645 *p++ = ' ';
5646 }
5647 sprintf (p, "OS (%*.*lx)", field_size, field_size,
5648 (unsigned long) os_flags);
5649 p += 5 + field_size;
5650 }
5651 if (proc_flags)
5652 {
5653 size -= 7 + field_size;
5654 if (p != buff + field_size + 4)
5655 {
5656 if (size < (2 + 1))
bee0ee85
NC
5657 {
5658 warn (_("Internal error: not enough buffer room for section flag info"));
5659 return _("<unknown>");
5660 }
8d5ff12c
L
5661 size -= 2;
5662 *p++ = ',';
5663 *p++ = ' ';
5664 }
5665 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
5666 (unsigned long) proc_flags);
5667 p += 7 + field_size;
5668 }
5669 if (unknown_flags)
5670 {
5671 size -= 10 + field_size;
5672 if (p != buff + field_size + 4)
5673 {
5674 if (size < (2 + 1))
bee0ee85
NC
5675 {
5676 warn (_("Internal error: not enough buffer room for section flag info"));
5677 return _("<unknown>");
5678 }
8d5ff12c
L
5679 size -= 2;
5680 *p++ = ',';
5681 *p++ = ' ';
5682 }
2b692964 5683 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
5684 (unsigned long) unknown_flags);
5685 p += 10 + field_size;
5686 }
5687 }
5688
e9e44622 5689 *p = '\0';
d1133906
NC
5690 return buff;
5691}
5692
77115a4a
L
5693static unsigned int
5694get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf)
5695{
5696 if (is_32bit_elf)
5697 {
5698 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 5699
77115a4a
L
5700 chdr->ch_type = BYTE_GET (echdr->ch_type);
5701 chdr->ch_size = BYTE_GET (echdr->ch_size);
5702 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
5703 return sizeof (*echdr);
5704 }
5705 else
5706 {
5707 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 5708
77115a4a
L
5709 chdr->ch_type = BYTE_GET (echdr->ch_type);
5710 chdr->ch_size = BYTE_GET (echdr->ch_size);
5711 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
5712 return sizeof (*echdr);
5713 }
5714}
5715
252b5132 5716static int
2cf0635d 5717process_section_headers (FILE * file)
252b5132 5718{
2cf0635d 5719 Elf_Internal_Shdr * section;
b34976b6 5720 unsigned int i;
252b5132
RH
5721
5722 section_headers = NULL;
5723
5724 if (elf_header.e_shnum == 0)
5725 {
82f2dbf7
NC
5726 /* PR binutils/12467. */
5727 if (elf_header.e_shoff != 0)
5728 warn (_("possibly corrupt ELF file header - it has a non-zero"
5729 " section header offset, but no section headers\n"));
5730 else if (do_sections)
252b5132
RH
5731 printf (_("\nThere are no sections in this file.\n"));
5732
5733 return 1;
5734 }
5735
5736 if (do_sections && !do_header)
9ea033b2 5737 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
5738 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
5739
9ea033b2
NC
5740 if (is_32bit_elf)
5741 {
049b0c3a 5742 if (! get_32bit_section_headers (file, FALSE))
9ea033b2
NC
5743 return 0;
5744 }
049b0c3a 5745 else if (! get_64bit_section_headers (file, FALSE))
252b5132
RH
5746 return 0;
5747
5748 /* Read in the string table, so that we have names to display. */
0b49d371 5749 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 5750 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 5751 {
4fbb74a6 5752 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 5753
c256ffe7
JJ
5754 if (section->sh_size != 0)
5755 {
3f5e193b
NC
5756 string_table = (char *) get_data (NULL, file, section->sh_offset,
5757 1, section->sh_size,
5758 _("string table"));
0de14b54 5759
c256ffe7
JJ
5760 string_table_length = string_table != NULL ? section->sh_size : 0;
5761 }
252b5132
RH
5762 }
5763
5764 /* Scan the sections for the dynamic symbol table
e3c8793a 5765 and dynamic string table and debug sections. */
252b5132
RH
5766 dynamic_symbols = NULL;
5767 dynamic_strings = NULL;
5768 dynamic_syminfo = NULL;
6a40cf0c 5769 symtab_shndx_list = NULL;
103f02d3 5770
89fac5e3
RS
5771 eh_addr_size = is_32bit_elf ? 4 : 8;
5772 switch (elf_header.e_machine)
5773 {
5774 case EM_MIPS:
5775 case EM_MIPS_RS3_LE:
5776 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
5777 FDE addresses. However, the ABI also has a semi-official ILP32
5778 variant for which the normal FDE address size rules apply.
5779
5780 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
5781 section, where XX is the size of longs in bits. Unfortunately,
5782 earlier compilers provided no way of distinguishing ILP32 objects
5783 from LP64 objects, so if there's any doubt, we should assume that
5784 the official LP64 form is being used. */
5785 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
5786 && find_section (".gcc_compiled_long32") == NULL)
5787 eh_addr_size = 8;
5788 break;
0f56a26a
DD
5789
5790 case EM_H8_300:
5791 case EM_H8_300H:
5792 switch (elf_header.e_flags & EF_H8_MACH)
5793 {
5794 case E_H8_MACH_H8300:
5795 case E_H8_MACH_H8300HN:
5796 case E_H8_MACH_H8300SN:
5797 case E_H8_MACH_H8300SXN:
5798 eh_addr_size = 2;
5799 break;
5800 case E_H8_MACH_H8300H:
5801 case E_H8_MACH_H8300S:
5802 case E_H8_MACH_H8300SX:
5803 eh_addr_size = 4;
5804 break;
5805 }
f4236fe4
DD
5806 break;
5807
ff7eeb89 5808 case EM_M32C_OLD:
f4236fe4
DD
5809 case EM_M32C:
5810 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
5811 {
5812 case EF_M32C_CPU_M16C:
5813 eh_addr_size = 2;
5814 break;
5815 }
5816 break;
89fac5e3
RS
5817 }
5818
76ca31c0
NC
5819#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
5820 do \
5821 { \
5822 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
5823 if (section->sh_entsize != expected_entsize) \
9dd3a467 5824 { \
76ca31c0
NC
5825 char buf[40]; \
5826 sprintf_vma (buf, section->sh_entsize); \
5827 /* Note: coded this way so that there is a single string for \
5828 translation. */ \
5829 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
5830 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
5831 (unsigned) expected_entsize); \
9dd3a467 5832 section->sh_entsize = expected_entsize; \
76ca31c0
NC
5833 } \
5834 } \
08d8fa11 5835 while (0)
9dd3a467
NC
5836
5837#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
5838 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
5839 sizeof (Elf64_External_##type))
5840
252b5132
RH
5841 for (i = 0, section = section_headers;
5842 i < elf_header.e_shnum;
b34976b6 5843 i++, section++)
252b5132 5844 {
2cf0635d 5845 char * name = SECTION_NAME (section);
252b5132
RH
5846
5847 if (section->sh_type == SHT_DYNSYM)
5848 {
5849 if (dynamic_symbols != NULL)
5850 {
5851 error (_("File contains multiple dynamic symbol tables\n"));
5852 continue;
5853 }
5854
08d8fa11 5855 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 5856 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
5857 }
5858 else if (section->sh_type == SHT_STRTAB
18bd398b 5859 && streq (name, ".dynstr"))
252b5132
RH
5860 {
5861 if (dynamic_strings != NULL)
5862 {
5863 error (_("File contains multiple dynamic string tables\n"));
5864 continue;
5865 }
5866
3f5e193b
NC
5867 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
5868 1, section->sh_size,
5869 _("dynamic strings"));
59245841 5870 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 5871 }
9ad5cbcf
AM
5872 else if (section->sh_type == SHT_SYMTAB_SHNDX)
5873 {
6a40cf0c
NC
5874 elf_section_list * entry = xmalloc (sizeof * entry);
5875 entry->hdr = section;
5876 entry->next = symtab_shndx_list;
5877 symtab_shndx_list = entry;
9ad5cbcf 5878 }
08d8fa11
JJ
5879 else if (section->sh_type == SHT_SYMTAB)
5880 CHECK_ENTSIZE (section, i, Sym);
5881 else if (section->sh_type == SHT_GROUP)
5882 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
5883 else if (section->sh_type == SHT_REL)
5884 CHECK_ENTSIZE (section, i, Rel);
5885 else if (section->sh_type == SHT_RELA)
5886 CHECK_ENTSIZE (section, i, Rela);
252b5132 5887 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 5888 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 5889 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
5890 || do_debug_str || do_debug_loc || do_debug_ranges
5891 || do_debug_addr || do_debug_cu_index)
1b315056
CS
5892 && (const_strneq (name, ".debug_")
5893 || const_strneq (name, ".zdebug_")))
252b5132 5894 {
1b315056
CS
5895 if (name[1] == 'z')
5896 name += sizeof (".zdebug_") - 1;
5897 else
5898 name += sizeof (".debug_") - 1;
252b5132
RH
5899
5900 if (do_debugging
4723351a
CC
5901 || (do_debug_info && const_strneq (name, "info"))
5902 || (do_debug_info && const_strneq (name, "types"))
5903 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
5904 || (do_debug_lines && strcmp (name, "line") == 0)
5905 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
5906 || (do_debug_pubnames && const_strneq (name, "pubnames"))
5907 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
5908 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
5909 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
5910 || (do_debug_aranges && const_strneq (name, "aranges"))
5911 || (do_debug_ranges && const_strneq (name, "ranges"))
5912 || (do_debug_frames && const_strneq (name, "frame"))
5913 || (do_debug_macinfo && const_strneq (name, "macinfo"))
5914 || (do_debug_macinfo && const_strneq (name, "macro"))
5915 || (do_debug_str && const_strneq (name, "str"))
5916 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
5917 || (do_debug_addr && const_strneq (name, "addr"))
5918 || (do_debug_cu_index && const_strneq (name, "cu_index"))
5919 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 5920 )
09c11c86 5921 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 5922 }
a262ae96 5923 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 5924 else if ((do_debugging || do_debug_info)
0112cd26 5925 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 5926 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 5927 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 5928 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
5929 else if (do_gdb_index && streq (name, ".gdb_index"))
5930 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
5931 /* Trace sections for Itanium VMS. */
5932 else if ((do_debugging || do_trace_info || do_trace_abbrevs
5933 || do_trace_aranges)
5934 && const_strneq (name, ".trace_"))
5935 {
5936 name += sizeof (".trace_") - 1;
5937
5938 if (do_debugging
5939 || (do_trace_info && streq (name, "info"))
5940 || (do_trace_abbrevs && streq (name, "abbrev"))
5941 || (do_trace_aranges && streq (name, "aranges"))
5942 )
5943 request_dump_bynumber (i, DEBUG_DUMP);
5944 }
252b5132
RH
5945 }
5946
5947 if (! do_sections)
5948 return 1;
5949
3a1a2036
NC
5950 if (elf_header.e_shnum > 1)
5951 printf (_("\nSection Headers:\n"));
5952 else
5953 printf (_("\nSection Header:\n"));
76da6bbe 5954
f7a99963 5955 if (is_32bit_elf)
595cf52e 5956 {
5477e8a0 5957 if (do_section_details)
595cf52e
L
5958 {
5959 printf (_(" [Nr] Name\n"));
5477e8a0 5960 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
5961 }
5962 else
5963 printf
5964 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
5965 }
d974e256 5966 else if (do_wide)
595cf52e 5967 {
5477e8a0 5968 if (do_section_details)
595cf52e
L
5969 {
5970 printf (_(" [Nr] Name\n"));
5477e8a0 5971 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
5972 }
5973 else
5974 printf
5975 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
5976 }
f7a99963
NC
5977 else
5978 {
5477e8a0 5979 if (do_section_details)
595cf52e
L
5980 {
5981 printf (_(" [Nr] Name\n"));
5477e8a0
L
5982 printf (_(" Type Address Offset Link\n"));
5983 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
5984 }
5985 else
5986 {
5987 printf (_(" [Nr] Name Type Address Offset\n"));
5988 printf (_(" Size EntSize Flags Link Info Align\n"));
5989 }
f7a99963 5990 }
252b5132 5991
5477e8a0
L
5992 if (do_section_details)
5993 printf (_(" Flags\n"));
5994
252b5132
RH
5995 for (i = 0, section = section_headers;
5996 i < elf_header.e_shnum;
b34976b6 5997 i++, section++)
252b5132 5998 {
dd905818
NC
5999 /* Run some sanity checks on the section header. */
6000
6001 /* Check the sh_link field. */
6002 switch (section->sh_type)
6003 {
6004 case SHT_SYMTAB_SHNDX:
6005 case SHT_GROUP:
6006 case SHT_HASH:
6007 case SHT_GNU_HASH:
6008 case SHT_GNU_versym:
6009 case SHT_REL:
6010 case SHT_RELA:
6011 if (section->sh_link < 1
cb64e50d 6012 || section->sh_link >= elf_header.e_shnum
dd905818
NC
6013 || (section_headers[section->sh_link].sh_type != SHT_SYMTAB
6014 && section_headers[section->sh_link].sh_type != SHT_DYNSYM))
6015 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6016 i, section->sh_link);
6017 break;
6018
6019 case SHT_DYNAMIC:
6020 case SHT_SYMTAB:
6021 case SHT_DYNSYM:
6022 case SHT_GNU_verneed:
6023 case SHT_GNU_verdef:
6024 case SHT_GNU_LIBLIST:
6025 if (section->sh_link < 1
cb64e50d 6026 || section->sh_link >= elf_header.e_shnum
dd905818
NC
6027 || section_headers[section->sh_link].sh_type != SHT_STRTAB)
6028 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6029 i, section->sh_link);
6030 break;
6031
6032 case SHT_INIT_ARRAY:
6033 case SHT_FINI_ARRAY:
6034 case SHT_PREINIT_ARRAY:
6035 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6036 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6037 i, section->sh_link);
6038 break;
6039
6040 default:
6041 /* FIXME: Add support for target specific section types. */
6042#if 0 /* Currently we do not check other section types as there are too
6043 many special cases. Stab sections for example have a type
6044 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6045 section. */
6046 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6047 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6048 i, section->sh_link);
6049#endif
6050 break;
6051 }
6052
6053 /* Check the sh_info field. */
6054 switch (section->sh_type)
6055 {
6056 case SHT_REL:
6057 case SHT_RELA:
6058 if (section->sh_info < 1
cb64e50d 6059 || section->sh_info >= elf_header.e_shnum
dd905818
NC
6060 || (section_headers[section->sh_info].sh_type != SHT_PROGBITS
6061 && section_headers[section->sh_info].sh_type != SHT_NOBITS
6062 && section_headers[section->sh_info].sh_type != SHT_NOTE
6063 && section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
6064 /* FIXME: Are other section types valid ? */
6065 && section_headers[section->sh_info].sh_type < SHT_LOOS))
6066 {
6067 if (section->sh_info == 0
6068 && (streq (SECTION_NAME (section), ".rel.dyn")
6069 || streq (SECTION_NAME (section), ".rela.dyn")))
6070 /* The .rel.dyn and .rela.dyn sections have an sh_info field
6071 of zero. No idea why. I would have expected the index
6072 of the .plt section. */
6073 ;
6074 else
6075 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6076 i, section->sh_info);
6077 }
6078 break;
6079
6080 case SHT_DYNAMIC:
6081 case SHT_HASH:
6082 case SHT_SYMTAB_SHNDX:
6083 case SHT_INIT_ARRAY:
6084 case SHT_FINI_ARRAY:
6085 case SHT_PREINIT_ARRAY:
6086 if (section->sh_info != 0)
6087 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6088 i, section->sh_info);
6089 break;
6090
6091 case SHT_GROUP:
6092 case SHT_SYMTAB:
6093 case SHT_DYNSYM:
6094 /* A symbol index - we assume that it is valid. */
6095 break;
6096
6097 default:
6098 /* FIXME: Add support for target specific section types. */
6099 if (section->sh_type == SHT_NOBITS)
6100 /* NOBITS section headers with non-zero sh_info fields can be
6101 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6102 information. The stripped sections have their headers
6103 preserved but their types set to SHT_NOBITS. So do not check
6104 this type of section. */
dd905818
NC
6105 ;
6106 else if (section->sh_flags & SHF_INFO_LINK)
6107 {
cb64e50d 6108 if (section->sh_info < 1 || section->sh_info >= elf_header.e_shnum)
dd905818
NC
6109 warn (_("[%2u]: Expected link to another section in info field"), i);
6110 }
6111 else if (section->sh_type < SHT_LOOS && section->sh_info != 0)
6112 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6113 i, section->sh_info);
6114 break;
6115 }
6116
7bfd842d 6117 printf (" [%2u] ", i);
5477e8a0 6118 if (do_section_details)
74e1a04b 6119 printf ("%s\n ", printable_section_name (section));
595cf52e 6120 else
74e1a04b 6121 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6122
ea52a088
NC
6123 printf (do_wide ? " %-15s " : " %-15.15s ",
6124 get_section_type_name (section->sh_type));
0b4362b0 6125
f7a99963
NC
6126 if (is_32bit_elf)
6127 {
cfcac11d
NC
6128 const char * link_too_big = NULL;
6129
f7a99963 6130 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6131
f7a99963
NC
6132 printf ( " %6.6lx %6.6lx %2.2lx",
6133 (unsigned long) section->sh_offset,
6134 (unsigned long) section->sh_size,
6135 (unsigned long) section->sh_entsize);
d1133906 6136
5477e8a0
L
6137 if (do_section_details)
6138 fputs (" ", stdout);
6139 else
6140 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 6141
cfcac11d
NC
6142 if (section->sh_link >= elf_header.e_shnum)
6143 {
6144 link_too_big = "";
6145 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6146 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
6147 switch (elf_header.e_machine)
6148 {
caa83f8b 6149 case EM_386:
22abe556 6150 case EM_IAMCU:
caa83f8b 6151 case EM_X86_64:
7f502d6c 6152 case EM_L1OM:
7a9068fe 6153 case EM_K1OM:
cfcac11d
NC
6154 case EM_OLD_SPARCV9:
6155 case EM_SPARC32PLUS:
6156 case EM_SPARCV9:
6157 case EM_SPARC:
6158 if (section->sh_link == (SHN_BEFORE & 0xffff))
6159 link_too_big = "BEFORE";
6160 else if (section->sh_link == (SHN_AFTER & 0xffff))
6161 link_too_big = "AFTER";
6162 break;
6163 default:
6164 break;
6165 }
6166 }
6167
6168 if (do_section_details)
6169 {
6170 if (link_too_big != NULL && * link_too_big)
6171 printf ("<%s> ", link_too_big);
6172 else
6173 printf ("%2u ", section->sh_link);
6174 printf ("%3u %2lu\n", section->sh_info,
6175 (unsigned long) section->sh_addralign);
6176 }
6177 else
6178 printf ("%2u %3u %2lu\n",
6179 section->sh_link,
6180 section->sh_info,
6181 (unsigned long) section->sh_addralign);
6182
6183 if (link_too_big && ! * link_too_big)
6184 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6185 i, section->sh_link);
f7a99963 6186 }
d974e256
JJ
6187 else if (do_wide)
6188 {
6189 print_vma (section->sh_addr, LONG_HEX);
6190
6191 if ((long) section->sh_offset == section->sh_offset)
6192 printf (" %6.6lx", (unsigned long) section->sh_offset);
6193 else
6194 {
6195 putchar (' ');
6196 print_vma (section->sh_offset, LONG_HEX);
6197 }
6198
6199 if ((unsigned long) section->sh_size == section->sh_size)
6200 printf (" %6.6lx", (unsigned long) section->sh_size);
6201 else
6202 {
6203 putchar (' ');
6204 print_vma (section->sh_size, LONG_HEX);
6205 }
6206
6207 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6208 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6209 else
6210 {
6211 putchar (' ');
6212 print_vma (section->sh_entsize, LONG_HEX);
6213 }
6214
5477e8a0
L
6215 if (do_section_details)
6216 fputs (" ", stdout);
6217 else
6218 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 6219
72de5009 6220 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6221
6222 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6223 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6224 else
6225 {
6226 print_vma (section->sh_addralign, DEC);
6227 putchar ('\n');
6228 }
6229 }
5477e8a0 6230 else if (do_section_details)
595cf52e 6231 {
5477e8a0 6232 printf (" %-15.15s ",
595cf52e 6233 get_section_type_name (section->sh_type));
595cf52e
L
6234 print_vma (section->sh_addr, LONG_HEX);
6235 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6236 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6237 else
6238 {
6239 printf (" ");
6240 print_vma (section->sh_offset, LONG_HEX);
6241 }
72de5009 6242 printf (" %u\n ", section->sh_link);
595cf52e 6243 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6244 putchar (' ');
595cf52e
L
6245 print_vma (section->sh_entsize, LONG_HEX);
6246
72de5009
AM
6247 printf (" %-16u %lu\n",
6248 section->sh_info,
595cf52e
L
6249 (unsigned long) section->sh_addralign);
6250 }
f7a99963
NC
6251 else
6252 {
6253 putchar (' ');
6254 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6255 if ((long) section->sh_offset == section->sh_offset)
6256 printf (" %8.8lx", (unsigned long) section->sh_offset);
6257 else
6258 {
6259 printf (" ");
6260 print_vma (section->sh_offset, LONG_HEX);
6261 }
f7a99963
NC
6262 printf ("\n ");
6263 print_vma (section->sh_size, LONG_HEX);
6264 printf (" ");
6265 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6266
d1133906 6267 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 6268
72de5009
AM
6269 printf (" %2u %3u %lu\n",
6270 section->sh_link,
6271 section->sh_info,
f7a99963
NC
6272 (unsigned long) section->sh_addralign);
6273 }
5477e8a0
L
6274
6275 if (do_section_details)
77115a4a
L
6276 {
6277 printf (" %s\n", get_elf_section_flags (section->sh_flags));
6278 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6279 {
6280 /* Minimum section size is 12 bytes for 32-bit compression
6281 header + 12 bytes for compressed data header. */
6282 unsigned char buf[24];
d8024a91 6283
77115a4a
L
6284 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
6285 if (get_data (&buf, (FILE *) file, section->sh_offset, 1,
6286 sizeof (buf), _("compression header")))
6287 {
6288 Elf_Internal_Chdr chdr;
d8024a91
NC
6289
6290 (void) get_compression_header (&chdr, buf);
6291
77115a4a
L
6292 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6293 printf (" ZLIB, ");
6294 else
6295 printf (_(" [<unknown>: 0x%x], "),
6296 chdr.ch_type);
6297 print_vma (chdr.ch_size, LONG_HEX);
6298 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6299 }
6300 }
6301 }
252b5132
RH
6302 }
6303
5477e8a0 6304 if (!do_section_details)
3dbcc61d 6305 {
9fb71ee4
NC
6306 /* The ordering of the letters shown here matches the ordering of the
6307 corresponding SHF_xxx values, and hence the order in which these
6308 letters will be displayed to the user. */
6309 printf (_("Key to Flags:\n\
6310 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6311 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6312 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
3dbcc61d 6313 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
6314 || elf_header.e_machine == EM_L1OM
6315 || elf_header.e_machine == EM_K1OM)
9fb71ee4 6316 printf (_("l (large), "));
91f68a68 6317 else if (elf_header.e_machine == EM_ARM)
f0728ee3 6318 printf (_("y (purecode), "));
9fb71ee4 6319 printf ("p (processor specific)\n");
0b4362b0 6320 }
d1133906 6321
252b5132
RH
6322 return 1;
6323}
6324
f5842774
L
6325static const char *
6326get_group_flags (unsigned int flags)
6327{
1449284b 6328 static char buff[128];
220453ec 6329
6d913794
NC
6330 if (flags == 0)
6331 return "";
6332 else if (flags == GRP_COMDAT)
6333 return "COMDAT ";
f5842774 6334
6d913794
NC
6335 snprintf (buff, 14, _("[0x%x: "), flags);
6336
6337 flags &= ~ GRP_COMDAT;
6338 if (flags & GRP_MASKOS)
6339 {
6340 strcat (buff, "<OS specific>");
6341 flags &= ~ GRP_MASKOS;
f5842774 6342 }
6d913794
NC
6343
6344 if (flags & GRP_MASKPROC)
6345 {
6346 strcat (buff, "<PROC specific>");
6347 flags &= ~ GRP_MASKPROC;
6348 }
6349
6350 if (flags)
6351 strcat (buff, "<unknown>");
6352
6353 strcat (buff, "]");
f5842774
L
6354 return buff;
6355}
6356
6357static int
2cf0635d 6358process_section_groups (FILE * file)
f5842774 6359{
2cf0635d 6360 Elf_Internal_Shdr * section;
f5842774 6361 unsigned int i;
2cf0635d
NC
6362 struct group * group;
6363 Elf_Internal_Shdr * symtab_sec;
6364 Elf_Internal_Shdr * strtab_sec;
6365 Elf_Internal_Sym * symtab;
ba5cdace 6366 unsigned long num_syms;
2cf0635d 6367 char * strtab;
c256ffe7 6368 size_t strtab_size;
d1f5c6e3
L
6369
6370 /* Don't process section groups unless needed. */
6371 if (!do_unwind && !do_section_groups)
6372 return 1;
f5842774
L
6373
6374 if (elf_header.e_shnum == 0)
6375 {
6376 if (do_section_groups)
82f2dbf7 6377 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
6378
6379 return 1;
6380 }
6381
6382 if (section_headers == NULL)
6383 {
6384 error (_("Section headers are not available!\n"));
fa1908fd
NC
6385 /* PR 13622: This can happen with a corrupt ELF header. */
6386 return 0;
f5842774
L
6387 }
6388
3f5e193b
NC
6389 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
6390 sizeof (struct group *));
e4b17d5c
L
6391
6392 if (section_headers_groups == NULL)
6393 {
8b73c356
NC
6394 error (_("Out of memory reading %u section group headers\n"),
6395 elf_header.e_shnum);
e4b17d5c
L
6396 return 0;
6397 }
6398
f5842774 6399 /* Scan the sections for the group section. */
d1f5c6e3 6400 group_count = 0;
f5842774
L
6401 for (i = 0, section = section_headers;
6402 i < elf_header.e_shnum;
6403 i++, section++)
e4b17d5c
L
6404 if (section->sh_type == SHT_GROUP)
6405 group_count++;
6406
d1f5c6e3
L
6407 if (group_count == 0)
6408 {
6409 if (do_section_groups)
6410 printf (_("\nThere are no section groups in this file.\n"));
6411
6412 return 1;
6413 }
6414
3f5e193b 6415 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
6416
6417 if (section_groups == NULL)
6418 {
8b73c356
NC
6419 error (_("Out of memory reading %lu groups\n"),
6420 (unsigned long) group_count);
e4b17d5c
L
6421 return 0;
6422 }
6423
d1f5c6e3
L
6424 symtab_sec = NULL;
6425 strtab_sec = NULL;
6426 symtab = NULL;
ba5cdace 6427 num_syms = 0;
d1f5c6e3 6428 strtab = NULL;
c256ffe7 6429 strtab_size = 0;
e4b17d5c
L
6430 for (i = 0, section = section_headers, group = section_groups;
6431 i < elf_header.e_shnum;
6432 i++, section++)
f5842774
L
6433 {
6434 if (section->sh_type == SHT_GROUP)
6435 {
74e1a04b
NC
6436 const char * name = printable_section_name (section);
6437 const char * group_name;
2cf0635d
NC
6438 unsigned char * start;
6439 unsigned char * indices;
f5842774 6440 unsigned int entry, j, size;
2cf0635d
NC
6441 Elf_Internal_Shdr * sec;
6442 Elf_Internal_Sym * sym;
f5842774
L
6443
6444 /* Get the symbol table. */
4fbb74a6
AM
6445 if (section->sh_link >= elf_header.e_shnum
6446 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 6447 != SHT_SYMTAB))
f5842774
L
6448 {
6449 error (_("Bad sh_link in group section `%s'\n"), name);
6450 continue;
6451 }
d1f5c6e3
L
6452
6453 if (symtab_sec != sec)
6454 {
6455 symtab_sec = sec;
6456 if (symtab)
6457 free (symtab);
ba5cdace 6458 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 6459 }
f5842774 6460
dd24e3da
NC
6461 if (symtab == NULL)
6462 {
6463 error (_("Corrupt header in group section `%s'\n"), name);
6464 continue;
6465 }
6466
ba5cdace
NC
6467 if (section->sh_info >= num_syms)
6468 {
6469 error (_("Bad sh_info in group section `%s'\n"), name);
6470 continue;
6471 }
6472
f5842774
L
6473 sym = symtab + section->sh_info;
6474
6475 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
6476 {
4fbb74a6
AM
6477 if (sym->st_shndx == 0
6478 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
6479 {
6480 error (_("Bad sh_info in group section `%s'\n"), name);
6481 continue;
6482 }
ba2685cc 6483
4fbb74a6 6484 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
6485 strtab_sec = NULL;
6486 if (strtab)
6487 free (strtab);
f5842774 6488 strtab = NULL;
c256ffe7 6489 strtab_size = 0;
f5842774
L
6490 }
6491 else
6492 {
6493 /* Get the string table. */
4fbb74a6 6494 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
6495 {
6496 strtab_sec = NULL;
6497 if (strtab)
6498 free (strtab);
6499 strtab = NULL;
6500 strtab_size = 0;
6501 }
6502 else if (strtab_sec
4fbb74a6 6503 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
6504 {
6505 strtab_sec = sec;
6506 if (strtab)
6507 free (strtab);
071436c6 6508
3f5e193b 6509 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
071436c6
NC
6510 1, strtab_sec->sh_size,
6511 _("string table"));
c256ffe7 6512 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 6513 }
c256ffe7 6514 group_name = sym->st_name < strtab_size
2b692964 6515 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
6516 }
6517
c9c1d674
EG
6518 /* PR 17531: file: loop. */
6519 if (section->sh_entsize > section->sh_size)
6520 {
6521 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
6522 printable_section_name (section),
8066deb1
AM
6523 (unsigned long) section->sh_entsize,
6524 (unsigned long) section->sh_size);
c9c1d674
EG
6525 break;
6526 }
6527
3f5e193b
NC
6528 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
6529 1, section->sh_size,
6530 _("section data"));
59245841
NC
6531 if (start == NULL)
6532 continue;
f5842774
L
6533
6534 indices = start;
6535 size = (section->sh_size / section->sh_entsize) - 1;
6536 entry = byte_get (indices, 4);
6537 indices += 4;
e4b17d5c
L
6538
6539 if (do_section_groups)
6540 {
2b692964 6541 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 6542 get_group_flags (entry), i, name, group_name, size);
ba2685cc 6543
e4b17d5c
L
6544 printf (_(" [Index] Name\n"));
6545 }
6546
6547 group->group_index = i;
6548
f5842774
L
6549 for (j = 0; j < size; j++)
6550 {
2cf0635d 6551 struct group_list * g;
e4b17d5c 6552
f5842774
L
6553 entry = byte_get (indices, 4);
6554 indices += 4;
6555
4fbb74a6 6556 if (entry >= elf_header.e_shnum)
391cb864 6557 {
57028622
NC
6558 static unsigned num_group_errors = 0;
6559
6560 if (num_group_errors ++ < 10)
6561 {
6562 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
6563 entry, i, elf_header.e_shnum - 1);
6564 if (num_group_errors == 10)
6565 warn (_("Futher error messages about overlarge group section indicies suppressed\n"));
6566 }
391cb864
L
6567 continue;
6568 }
391cb864 6569
4fbb74a6 6570 if (section_headers_groups [entry] != NULL)
e4b17d5c 6571 {
d1f5c6e3
L
6572 if (entry)
6573 {
57028622
NC
6574 static unsigned num_errs = 0;
6575
6576 if (num_errs ++ < 10)
6577 {
6578 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
6579 entry, i,
6580 section_headers_groups [entry]->group_index);
6581 if (num_errs == 10)
6582 warn (_("Further error messages about already contained group sections suppressed\n"));
6583 }
d1f5c6e3
L
6584 continue;
6585 }
6586 else
6587 {
6588 /* Intel C/C++ compiler may put section 0 in a
6589 section group. We just warn it the first time
6590 and ignore it afterwards. */
6591 static int warned = 0;
6592 if (!warned)
6593 {
6594 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 6595 section_headers_groups [entry]->group_index);
d1f5c6e3
L
6596 warned++;
6597 }
6598 }
e4b17d5c
L
6599 }
6600
4fbb74a6 6601 section_headers_groups [entry] = group;
e4b17d5c
L
6602
6603 if (do_section_groups)
6604 {
4fbb74a6 6605 sec = section_headers + entry;
74e1a04b 6606 printf (" [%5u] %s\n", entry, printable_section_name (sec));
ba2685cc
AM
6607 }
6608
3f5e193b 6609 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
6610 g->section_index = entry;
6611 g->next = group->root;
6612 group->root = g;
f5842774
L
6613 }
6614
f5842774
L
6615 if (start)
6616 free (start);
e4b17d5c
L
6617
6618 group++;
f5842774
L
6619 }
6620 }
6621
d1f5c6e3
L
6622 if (symtab)
6623 free (symtab);
6624 if (strtab)
6625 free (strtab);
f5842774
L
6626 return 1;
6627}
6628
28f997cf
TG
6629/* Data used to display dynamic fixups. */
6630
6631struct ia64_vms_dynfixup
6632{
6633 bfd_vma needed_ident; /* Library ident number. */
6634 bfd_vma needed; /* Index in the dstrtab of the library name. */
6635 bfd_vma fixup_needed; /* Index of the library. */
6636 bfd_vma fixup_rela_cnt; /* Number of fixups. */
6637 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
6638};
6639
6640/* Data used to display dynamic relocations. */
6641
6642struct ia64_vms_dynimgrela
6643{
6644 bfd_vma img_rela_cnt; /* Number of relocations. */
6645 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
6646};
6647
6648/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
6649 library). */
6650
6651static void
6652dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
6653 const char *strtab, unsigned int strtab_sz)
6654{
6655 Elf64_External_VMS_IMAGE_FIXUP *imfs;
6656 long i;
6657 const char *lib_name;
6658
6659 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
6660 1, fixup->fixup_rela_cnt * sizeof (*imfs),
6661 _("dynamic section image fixups"));
6662 if (!imfs)
6663 return;
6664
6665 if (fixup->needed < strtab_sz)
6666 lib_name = strtab + fixup->needed;
6667 else
6668 {
6669 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 6670 (unsigned long) fixup->needed);
28f997cf
TG
6671 lib_name = "???";
6672 }
6673 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
6674 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
6675 printf
6676 (_("Seg Offset Type SymVec DataType\n"));
6677
6678 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
6679 {
6680 unsigned int type;
6681 const char *rtype;
6682
6683 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
6684 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
6685 type = BYTE_GET (imfs [i].type);
6686 rtype = elf_ia64_reloc_type (type);
6687 if (rtype == NULL)
6688 printf (" 0x%08x ", type);
6689 else
6690 printf (" %-32s ", rtype);
6691 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
6692 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
6693 }
6694
6695 free (imfs);
6696}
6697
6698/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
6699
6700static void
6701dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
6702{
6703 Elf64_External_VMS_IMAGE_RELA *imrs;
6704 long i;
6705
6706 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
6707 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 6708 _("dynamic section image relocations"));
28f997cf
TG
6709 if (!imrs)
6710 return;
6711
6712 printf (_("\nImage relocs\n"));
6713 printf
6714 (_("Seg Offset Type Addend Seg Sym Off\n"));
6715
6716 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
6717 {
6718 unsigned int type;
6719 const char *rtype;
6720
6721 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
6722 printf ("%08" BFD_VMA_FMT "x ",
6723 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
6724 type = BYTE_GET (imrs [i].type);
6725 rtype = elf_ia64_reloc_type (type);
6726 if (rtype == NULL)
6727 printf ("0x%08x ", type);
6728 else
6729 printf ("%-31s ", rtype);
6730 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
6731 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
6732 printf ("%08" BFD_VMA_FMT "x\n",
6733 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
6734 }
6735
6736 free (imrs);
6737}
6738
6739/* Display IA-64 OpenVMS dynamic relocations and fixups. */
6740
6741static int
6742process_ia64_vms_dynamic_relocs (FILE *file)
6743{
6744 struct ia64_vms_dynfixup fixup;
6745 struct ia64_vms_dynimgrela imgrela;
6746 Elf_Internal_Dyn *entry;
6747 int res = 0;
6748 bfd_vma strtab_off = 0;
6749 bfd_vma strtab_sz = 0;
6750 char *strtab = NULL;
6751
6752 memset (&fixup, 0, sizeof (fixup));
6753 memset (&imgrela, 0, sizeof (imgrela));
6754
6755 /* Note: the order of the entries is specified by the OpenVMS specs. */
6756 for (entry = dynamic_section;
6757 entry < dynamic_section + dynamic_nent;
6758 entry++)
6759 {
6760 switch (entry->d_tag)
6761 {
6762 case DT_IA_64_VMS_STRTAB_OFFSET:
6763 strtab_off = entry->d_un.d_val;
6764 break;
6765 case DT_STRSZ:
6766 strtab_sz = entry->d_un.d_val;
6767 if (strtab == NULL)
6768 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
6769 1, strtab_sz, _("dynamic string section"));
6770 break;
6771
6772 case DT_IA_64_VMS_NEEDED_IDENT:
6773 fixup.needed_ident = entry->d_un.d_val;
6774 break;
6775 case DT_NEEDED:
6776 fixup.needed = entry->d_un.d_val;
6777 break;
6778 case DT_IA_64_VMS_FIXUP_NEEDED:
6779 fixup.fixup_needed = entry->d_un.d_val;
6780 break;
6781 case DT_IA_64_VMS_FIXUP_RELA_CNT:
6782 fixup.fixup_rela_cnt = entry->d_un.d_val;
6783 break;
6784 case DT_IA_64_VMS_FIXUP_RELA_OFF:
6785 fixup.fixup_rela_off = entry->d_un.d_val;
6786 res++;
6787 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
6788 break;
6789
6790 case DT_IA_64_VMS_IMG_RELA_CNT:
6791 imgrela.img_rela_cnt = entry->d_un.d_val;
6792 break;
6793 case DT_IA_64_VMS_IMG_RELA_OFF:
6794 imgrela.img_rela_off = entry->d_un.d_val;
6795 res++;
6796 dump_ia64_vms_dynamic_relocs (file, &imgrela);
6797 break;
6798
6799 default:
6800 break;
6801 }
6802 }
6803
6804 if (strtab != NULL)
6805 free (strtab);
6806
6807 return res;
6808}
6809
85b1c36d 6810static struct
566b0d53 6811{
2cf0635d 6812 const char * name;
566b0d53
L
6813 int reloc;
6814 int size;
6815 int rela;
6816} dynamic_relocations [] =
6817{
6818 { "REL", DT_REL, DT_RELSZ, FALSE },
6819 { "RELA", DT_RELA, DT_RELASZ, TRUE },
6820 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
6821};
6822
252b5132 6823/* Process the reloc section. */
18bd398b 6824
252b5132 6825static int
2cf0635d 6826process_relocs (FILE * file)
252b5132 6827{
b34976b6
AM
6828 unsigned long rel_size;
6829 unsigned long rel_offset;
252b5132
RH
6830
6831
6832 if (!do_reloc)
6833 return 1;
6834
6835 if (do_using_dynamic)
6836 {
566b0d53 6837 int is_rela;
2cf0635d 6838 const char * name;
566b0d53
L
6839 int has_dynamic_reloc;
6840 unsigned int i;
0de14b54 6841
566b0d53 6842 has_dynamic_reloc = 0;
252b5132 6843
566b0d53 6844 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 6845 {
566b0d53
L
6846 is_rela = dynamic_relocations [i].rela;
6847 name = dynamic_relocations [i].name;
6848 rel_size = dynamic_info [dynamic_relocations [i].size];
6849 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 6850
566b0d53
L
6851 has_dynamic_reloc |= rel_size;
6852
6853 if (is_rela == UNKNOWN)
aa903cfb 6854 {
566b0d53
L
6855 if (dynamic_relocations [i].reloc == DT_JMPREL)
6856 switch (dynamic_info[DT_PLTREL])
6857 {
6858 case DT_REL:
6859 is_rela = FALSE;
6860 break;
6861 case DT_RELA:
6862 is_rela = TRUE;
6863 break;
6864 }
aa903cfb 6865 }
252b5132 6866
566b0d53
L
6867 if (rel_size)
6868 {
6869 printf
6870 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
6871 name, rel_offset, rel_size);
252b5132 6872
d93f0186
NC
6873 dump_relocations (file,
6874 offset_from_vma (file, rel_offset, rel_size),
6875 rel_size,
566b0d53 6876 dynamic_symbols, num_dynamic_syms,
bb4d2ac2
L
6877 dynamic_strings, dynamic_strings_length,
6878 is_rela, 1);
566b0d53 6879 }
252b5132 6880 }
566b0d53 6881
28f997cf
TG
6882 if (is_ia64_vms ())
6883 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
6884
566b0d53 6885 if (! has_dynamic_reloc)
252b5132
RH
6886 printf (_("\nThere are no dynamic relocations in this file.\n"));
6887 }
6888 else
6889 {
2cf0635d 6890 Elf_Internal_Shdr * section;
b34976b6
AM
6891 unsigned long i;
6892 int found = 0;
252b5132
RH
6893
6894 for (i = 0, section = section_headers;
6895 i < elf_header.e_shnum;
b34976b6 6896 i++, section++)
252b5132
RH
6897 {
6898 if ( section->sh_type != SHT_RELA
6899 && section->sh_type != SHT_REL)
6900 continue;
6901
6902 rel_offset = section->sh_offset;
6903 rel_size = section->sh_size;
6904
6905 if (rel_size)
6906 {
2cf0635d 6907 Elf_Internal_Shdr * strsec;
b34976b6 6908 int is_rela;
103f02d3 6909
252b5132
RH
6910 printf (_("\nRelocation section "));
6911
6912 if (string_table == NULL)
19936277 6913 printf ("%d", section->sh_name);
252b5132 6914 else
74e1a04b 6915 printf ("'%s'", printable_section_name (section));
252b5132
RH
6916
6917 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6918 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
6919
d79b3d50
NC
6920 is_rela = section->sh_type == SHT_RELA;
6921
4fbb74a6
AM
6922 if (section->sh_link != 0
6923 && section->sh_link < elf_header.e_shnum)
af3fc3bc 6924 {
2cf0635d
NC
6925 Elf_Internal_Shdr * symsec;
6926 Elf_Internal_Sym * symtab;
d79b3d50 6927 unsigned long nsyms;
c256ffe7 6928 unsigned long strtablen = 0;
2cf0635d 6929 char * strtab = NULL;
57346661 6930
4fbb74a6 6931 symsec = section_headers + section->sh_link;
08d8fa11
JJ
6932 if (symsec->sh_type != SHT_SYMTAB
6933 && symsec->sh_type != SHT_DYNSYM)
6934 continue;
6935
ba5cdace 6936 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 6937
af3fc3bc
AM
6938 if (symtab == NULL)
6939 continue;
252b5132 6940
4fbb74a6
AM
6941 if (symsec->sh_link != 0
6942 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 6943 {
4fbb74a6 6944 strsec = section_headers + symsec->sh_link;
103f02d3 6945
3f5e193b 6946 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
071436c6
NC
6947 1, strsec->sh_size,
6948 _("string table"));
c256ffe7
JJ
6949 strtablen = strtab == NULL ? 0 : strsec->sh_size;
6950 }
252b5132 6951
d79b3d50 6952 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2
L
6953 symtab, nsyms, strtab, strtablen,
6954 is_rela,
6955 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
6956 if (strtab)
6957 free (strtab);
6958 free (symtab);
6959 }
6960 else
6961 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2 6962 NULL, 0, NULL, 0, is_rela, 0);
252b5132
RH
6963
6964 found = 1;
6965 }
6966 }
6967
6968 if (! found)
6969 printf (_("\nThere are no relocations in this file.\n"));
6970 }
6971
6972 return 1;
6973}
6974
4d6ed7c8
NC
6975/* An absolute address consists of a section and an offset. If the
6976 section is NULL, the offset itself is the address, otherwise, the
6977 address equals to LOAD_ADDRESS(section) + offset. */
6978
6979struct absaddr
948f632f
DA
6980{
6981 unsigned short section;
6982 bfd_vma offset;
6983};
4d6ed7c8 6984
1949de15
L
6985#define ABSADDR(a) \
6986 ((a).section \
6987 ? section_headers [(a).section].sh_addr + (a).offset \
6988 : (a).offset)
6989
948f632f
DA
6990/* Find the nearest symbol at or below ADDR. Returns the symbol
6991 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 6992
4d6ed7c8 6993static void
2cf0635d 6994find_symbol_for_address (Elf_Internal_Sym * symtab,
948f632f
DA
6995 unsigned long nsyms,
6996 const char * strtab,
6997 unsigned long strtab_size,
6998 struct absaddr addr,
6999 const char ** symname,
7000 bfd_vma * offset)
4d6ed7c8 7001{
d3ba0551 7002 bfd_vma dist = 0x100000;
2cf0635d 7003 Elf_Internal_Sym * sym;
948f632f
DA
7004 Elf_Internal_Sym * beg;
7005 Elf_Internal_Sym * end;
2cf0635d 7006 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7007
0b6ae522 7008 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7009 beg = symtab;
7010 end = symtab + nsyms;
0b6ae522 7011
948f632f 7012 while (beg < end)
4d6ed7c8 7013 {
948f632f
DA
7014 bfd_vma value;
7015
7016 sym = beg + (end - beg) / 2;
0b6ae522 7017
948f632f 7018 value = sym->st_value;
0b6ae522
DJ
7019 REMOVE_ARCH_BITS (value);
7020
948f632f 7021 if (sym->st_name != 0
4d6ed7c8 7022 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7023 && addr.offset >= value
7024 && addr.offset - value < dist)
4d6ed7c8
NC
7025 {
7026 best = sym;
0b6ae522 7027 dist = addr.offset - value;
4d6ed7c8
NC
7028 if (!dist)
7029 break;
7030 }
948f632f
DA
7031
7032 if (addr.offset < value)
7033 end = sym;
7034 else
7035 beg = sym + 1;
4d6ed7c8 7036 }
1b31d05e 7037
4d6ed7c8
NC
7038 if (best)
7039 {
57346661 7040 *symname = (best->st_name >= strtab_size
2b692964 7041 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7042 *offset = dist;
7043 return;
7044 }
1b31d05e 7045
4d6ed7c8
NC
7046 *symname = NULL;
7047 *offset = addr.offset;
7048}
7049
948f632f
DA
7050static int
7051symcmp (const void *p, const void *q)
7052{
7053 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7054 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7055
7056 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7057}
7058
7059/* Process the unwind section. */
7060
7061#include "unwind-ia64.h"
7062
7063struct ia64_unw_table_entry
7064{
7065 struct absaddr start;
7066 struct absaddr end;
7067 struct absaddr info;
7068};
7069
7070struct ia64_unw_aux_info
7071{
7072 struct ia64_unw_table_entry *table; /* Unwind table. */
7073 unsigned long table_len; /* Length of unwind table. */
7074 unsigned char * info; /* Unwind info. */
7075 unsigned long info_size; /* Size of unwind info. */
7076 bfd_vma info_addr; /* Starting address of unwind info. */
7077 bfd_vma seg_base; /* Starting address of segment. */
7078 Elf_Internal_Sym * symtab; /* The symbol table. */
7079 unsigned long nsyms; /* Number of symbols. */
7080 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7081 unsigned long nfuns; /* Number of entries in funtab. */
7082 char * strtab; /* The string table. */
7083 unsigned long strtab_size; /* Size of string table. */
7084};
7085
4d6ed7c8 7086static void
2cf0635d 7087dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 7088{
2cf0635d 7089 struct ia64_unw_table_entry * tp;
948f632f 7090 unsigned long j, nfuns;
4d6ed7c8 7091 int in_body;
7036c0e1 7092
948f632f
DA
7093 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7094 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7095 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7096 aux->funtab[nfuns++] = aux->symtab[j];
7097 aux->nfuns = nfuns;
7098 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7099
4d6ed7c8
NC
7100 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7101 {
7102 bfd_vma stamp;
7103 bfd_vma offset;
2cf0635d
NC
7104 const unsigned char * dp;
7105 const unsigned char * head;
53774b7e 7106 const unsigned char * end;
2cf0635d 7107 const char * procname;
4d6ed7c8 7108
948f632f 7109 find_symbol_for_address (aux->funtab, aux->nfuns, aux->strtab,
57346661 7110 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7111
7112 fputs ("\n<", stdout);
7113
7114 if (procname)
7115 {
7116 fputs (procname, stdout);
7117
7118 if (offset)
7119 printf ("+%lx", (unsigned long) offset);
7120 }
7121
7122 fputs (">: [", stdout);
7123 print_vma (tp->start.offset, PREFIX_HEX);
7124 fputc ('-', stdout);
7125 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7126 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7127 (unsigned long) (tp->info.offset - aux->seg_base));
7128
53774b7e
NC
7129 /* PR 17531: file: 86232b32. */
7130 if (aux->info == NULL)
7131 continue;
7132
7133 /* PR 17531: file: 0997b4d1. */
7134 if ((ABSADDR (tp->info) - aux->info_addr) >= aux->info_size)
7135 {
7136 warn (_("Invalid offset %lx in table entry %ld\n"),
7137 (long) tp->info.offset, (long) (tp - aux->table));
7138 continue;
7139 }
7140
1949de15 7141 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 7142 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7143
86f55779 7144 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7145 (unsigned) UNW_VER (stamp),
7146 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7147 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7148 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7149 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7150
7151 if (UNW_VER (stamp) != 1)
7152 {
2b692964 7153 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7154 continue;
7155 }
7156
7157 in_body = 0;
53774b7e
NC
7158 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7159 /* PR 17531: file: 16ceda89. */
7160 if (end > aux->info + aux->info_size)
7161 end = aux->info + aux->info_size;
7162 for (dp = head + 8; dp < end;)
b4477bc8 7163 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7164 }
948f632f
DA
7165
7166 free (aux->funtab);
4d6ed7c8
NC
7167}
7168
53774b7e 7169static bfd_boolean
2cf0635d
NC
7170slurp_ia64_unwind_table (FILE * file,
7171 struct ia64_unw_aux_info * aux,
7172 Elf_Internal_Shdr * sec)
4d6ed7c8 7173{
89fac5e3 7174 unsigned long size, nrelas, i;
2cf0635d
NC
7175 Elf_Internal_Phdr * seg;
7176 struct ia64_unw_table_entry * tep;
7177 Elf_Internal_Shdr * relsec;
7178 Elf_Internal_Rela * rela;
7179 Elf_Internal_Rela * rp;
7180 unsigned char * table;
7181 unsigned char * tp;
7182 Elf_Internal_Sym * sym;
7183 const char * relname;
4d6ed7c8 7184
53774b7e
NC
7185 aux->table_len = 0;
7186
4d6ed7c8
NC
7187 /* First, find the starting address of the segment that includes
7188 this section: */
7189
7190 if (elf_header.e_phnum)
7191 {
d93f0186 7192 if (! get_program_headers (file))
53774b7e 7193 return FALSE;
4d6ed7c8 7194
d93f0186
NC
7195 for (seg = program_headers;
7196 seg < program_headers + elf_header.e_phnum;
7197 ++seg)
4d6ed7c8
NC
7198 {
7199 if (seg->p_type != PT_LOAD)
7200 continue;
7201
7202 if (sec->sh_addr >= seg->p_vaddr
7203 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7204 {
7205 aux->seg_base = seg->p_vaddr;
7206 break;
7207 }
7208 }
4d6ed7c8
NC
7209 }
7210
7211 /* Second, build the unwind table from the contents of the unwind section: */
7212 size = sec->sh_size;
3f5e193b
NC
7213 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
7214 _("unwind table"));
a6e9f9df 7215 if (!table)
53774b7e 7216 return FALSE;
4d6ed7c8 7217
53774b7e 7218 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7219 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7220 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7221 tep = aux->table;
53774b7e
NC
7222
7223 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7224 {
7225 tep->start.section = SHN_UNDEF;
7226 tep->end.section = SHN_UNDEF;
7227 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7228 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7229 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7230 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7231 tep->start.offset += aux->seg_base;
7232 tep->end.offset += aux->seg_base;
7233 tep->info.offset += aux->seg_base;
7234 }
7235 free (table);
7236
41e92641 7237 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
7238 for (relsec = section_headers;
7239 relsec < section_headers + elf_header.e_shnum;
7240 ++relsec)
7241 {
7242 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
7243 || relsec->sh_info >= elf_header.e_shnum
7244 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7245 continue;
7246
7247 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7248 & rela, & nrelas))
53774b7e
NC
7249 {
7250 free (aux->table);
7251 aux->table = NULL;
7252 aux->table_len = 0;
7253 return FALSE;
7254 }
4d6ed7c8
NC
7255
7256 for (rp = rela; rp < rela + nrelas; ++rp)
7257 {
aca88567
NC
7258 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
7259 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 7260
82b1b41b
NC
7261 /* PR 17531: file: 9fa67536. */
7262 if (relname == NULL)
7263 {
7264 warn (_("Skipping unknown relocation type: %u\n"), get_reloc_type (rp->r_info));
7265 continue;
7266 }
948f632f 7267
0112cd26 7268 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7269 {
82b1b41b 7270 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7271 continue;
7272 }
7273
89fac5e3 7274 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7275
53774b7e
NC
7276 /* PR 17531: file: 5bc8d9bf. */
7277 if (i >= aux->table_len)
7278 {
7279 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7280 continue;
7281 }
7282
7283 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7284 {
7285 case 0:
7286 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7287 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7288 break;
7289 case 1:
7290 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7291 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7292 break;
7293 case 2:
7294 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7295 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7296 break;
7297 default:
7298 break;
7299 }
7300 }
7301
7302 free (rela);
7303 }
7304
53774b7e 7305 return TRUE;
4d6ed7c8
NC
7306}
7307
1b31d05e 7308static void
2cf0635d 7309ia64_process_unwind (FILE * file)
4d6ed7c8 7310{
2cf0635d
NC
7311 Elf_Internal_Shdr * sec;
7312 Elf_Internal_Shdr * unwsec = NULL;
7313 Elf_Internal_Shdr * strsec;
89fac5e3 7314 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7315 struct ia64_unw_aux_info aux;
f1467e33 7316
4d6ed7c8
NC
7317 memset (& aux, 0, sizeof (aux));
7318
4d6ed7c8
NC
7319 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7320 {
c256ffe7 7321 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 7322 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 7323 {
ba5cdace 7324 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 7325
4fbb74a6 7326 strsec = section_headers + sec->sh_link;
4082ef84
NC
7327 if (aux.strtab != NULL)
7328 {
7329 error (_("Multiple auxillary string tables encountered\n"));
7330 free (aux.strtab);
7331 }
3f5e193b
NC
7332 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
7333 1, strsec->sh_size,
7334 _("string table"));
c256ffe7 7335 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
7336 }
7337 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
7338 unwcount++;
7339 }
7340
7341 if (!unwcount)
7342 printf (_("\nThere are no unwind sections in this file.\n"));
7343
7344 while (unwcount-- > 0)
7345 {
2cf0635d 7346 char * suffix;
579f31ac
JJ
7347 size_t len, len2;
7348
4082ef84 7349 for (i = unwstart, sec = section_headers + unwstart, unwsec = NULL;
579f31ac
JJ
7350 i < elf_header.e_shnum; ++i, ++sec)
7351 if (sec->sh_type == SHT_IA_64_UNWIND)
7352 {
7353 unwsec = sec;
7354 break;
7355 }
4082ef84
NC
7356 /* We have already counted the number of SHT_IA64_UNWIND
7357 sections so the loop above should never fail. */
7358 assert (unwsec != NULL);
579f31ac
JJ
7359
7360 unwstart = i + 1;
7361 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
7362
e4b17d5c
L
7363 if ((unwsec->sh_flags & SHF_GROUP) != 0)
7364 {
7365 /* We need to find which section group it is in. */
4082ef84 7366 struct group_list * g;
e4b17d5c 7367
4082ef84
NC
7368 if (section_headers_groups == NULL
7369 || section_headers_groups [i] == NULL)
7370 i = elf_header.e_shnum;
7371 else
e4b17d5c 7372 {
4082ef84 7373 g = section_headers_groups [i]->root;
18bd398b 7374
4082ef84
NC
7375 for (; g != NULL; g = g->next)
7376 {
7377 sec = section_headers + g->section_index;
e4b17d5c 7378
4082ef84
NC
7379 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
7380 break;
7381 }
7382
7383 if (g == NULL)
7384 i = elf_header.e_shnum;
7385 }
e4b17d5c 7386 }
18bd398b 7387 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 7388 {
18bd398b 7389 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
7390 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
7391 suffix = SECTION_NAME (unwsec) + len;
7392 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
7393 ++i, ++sec)
18bd398b
NC
7394 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
7395 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7396 break;
7397 }
7398 else
7399 {
7400 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 7401 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
7402 len = sizeof (ELF_STRING_ia64_unwind) - 1;
7403 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
7404 suffix = "";
18bd398b 7405 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
7406 suffix = SECTION_NAME (unwsec) + len;
7407 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
7408 ++i, ++sec)
18bd398b
NC
7409 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
7410 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7411 break;
7412 }
7413
7414 if (i == elf_header.e_shnum)
7415 {
7416 printf (_("\nCould not find unwind info section for "));
7417
7418 if (string_table == NULL)
7419 printf ("%d", unwsec->sh_name);
7420 else
74e1a04b 7421 printf ("'%s'", printable_section_name (unwsec));
579f31ac
JJ
7422 }
7423 else
4d6ed7c8 7424 {
4d6ed7c8 7425 aux.info_addr = sec->sh_addr;
3f5e193b 7426 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
4082ef84
NC
7427 sec->sh_size,
7428 _("unwind info"));
59245841 7429 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 7430
579f31ac 7431 printf (_("\nUnwind section "));
4d6ed7c8 7432
579f31ac
JJ
7433 if (string_table == NULL)
7434 printf ("%d", unwsec->sh_name);
7435 else
74e1a04b 7436 printf ("'%s'", printable_section_name (unwsec));
4d6ed7c8 7437
579f31ac 7438 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 7439 (unsigned long) unwsec->sh_offset,
89fac5e3 7440 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 7441
53774b7e
NC
7442 if (slurp_ia64_unwind_table (file, & aux, unwsec)
7443 && aux.table_len > 0)
579f31ac
JJ
7444 dump_ia64_unwind (& aux);
7445
7446 if (aux.table)
7447 free ((char *) aux.table);
7448 if (aux.info)
7449 free ((char *) aux.info);
7450 aux.table = NULL;
7451 aux.info = NULL;
7452 }
4d6ed7c8 7453 }
4d6ed7c8 7454
4d6ed7c8
NC
7455 if (aux.symtab)
7456 free (aux.symtab);
7457 if (aux.strtab)
7458 free ((char *) aux.strtab);
4d6ed7c8
NC
7459}
7460
3f5e193b
NC
7461struct hppa_unw_table_entry
7462 {
7463 struct absaddr start;
7464 struct absaddr end;
948f632f 7465 unsigned int Cannot_unwind:1; /* 0 */
3f5e193b
NC
7466 unsigned int Millicode:1; /* 1 */
7467 unsigned int Millicode_save_sr0:1; /* 2 */
7468 unsigned int Region_description:2; /* 3..4 */
7469 unsigned int reserved1:1; /* 5 */
7470 unsigned int Entry_SR:1; /* 6 */
7471 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
7472 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
7473 unsigned int Args_stored:1; /* 16 */
948f632f
DA
7474 unsigned int Variable_Frame:1; /* 17 */
7475 unsigned int Separate_Package_Body:1; /* 18 */
3f5e193b 7476 unsigned int Frame_Extension_Millicode:1; /* 19 */
948f632f
DA
7477 unsigned int Stack_Overflow_Check:1; /* 20 */
7478 unsigned int Two_Instruction_SP_Increment:1;/* 21 */
3f5e193b
NC
7479 unsigned int Ada_Region:1; /* 22 */
7480 unsigned int cxx_info:1; /* 23 */
948f632f
DA
7481 unsigned int cxx_try_catch:1; /* 24 */
7482 unsigned int sched_entry_seq:1; /* 25 */
3f5e193b 7483 unsigned int reserved2:1; /* 26 */
948f632f
DA
7484 unsigned int Save_SP:1; /* 27 */
7485 unsigned int Save_RP:1; /* 28 */
3f5e193b
NC
7486 unsigned int Save_MRP_in_frame:1; /* 29 */
7487 unsigned int extn_ptr_defined:1; /* 30 */
948f632f 7488 unsigned int Cleanup_defined:1; /* 31 */
3f5e193b 7489
948f632f
DA
7490 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
7491 unsigned int HP_UX_interrupt_marker:1; /* 1 */
3f5e193b 7492 unsigned int Large_frame:1; /* 2 */
948f632f 7493 unsigned int Pseudo_SP_Set:1; /* 3 */
3f5e193b
NC
7494 unsigned int reserved4:1; /* 4 */
7495 unsigned int Total_frame_size:27; /* 5..31 */
7496 };
7497
57346661 7498struct hppa_unw_aux_info
948f632f
DA
7499{
7500 struct hppa_unw_table_entry * table; /* Unwind table. */
7501 unsigned long table_len; /* Length of unwind table. */
7502 bfd_vma seg_base; /* Starting address of segment. */
7503 Elf_Internal_Sym * symtab; /* The symbol table. */
7504 unsigned long nsyms; /* Number of symbols. */
7505 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7506 unsigned long nfuns; /* Number of entries in funtab. */
7507 char * strtab; /* The string table. */
7508 unsigned long strtab_size; /* Size of string table. */
7509};
57346661
AM
7510
7511static void
2cf0635d 7512dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 7513{
2cf0635d 7514 struct hppa_unw_table_entry * tp;
948f632f
DA
7515 unsigned long j, nfuns;
7516
7517 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7518 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7519 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7520 aux->funtab[nfuns++] = aux->symtab[j];
7521 aux->nfuns = nfuns;
7522 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 7523
57346661
AM
7524 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7525 {
7526 bfd_vma offset;
2cf0635d 7527 const char * procname;
57346661 7528
948f632f 7529 find_symbol_for_address (aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
7530 aux->strtab_size, tp->start, &procname,
7531 &offset);
7532
7533 fputs ("\n<", stdout);
7534
7535 if (procname)
7536 {
7537 fputs (procname, stdout);
7538
7539 if (offset)
7540 printf ("+%lx", (unsigned long) offset);
7541 }
7542
7543 fputs (">: [", stdout);
7544 print_vma (tp->start.offset, PREFIX_HEX);
7545 fputc ('-', stdout);
7546 print_vma (tp->end.offset, PREFIX_HEX);
7547 printf ("]\n\t");
7548
18bd398b
NC
7549#define PF(_m) if (tp->_m) printf (#_m " ");
7550#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
7551 PF(Cannot_unwind);
7552 PF(Millicode);
7553 PF(Millicode_save_sr0);
18bd398b 7554 /* PV(Region_description); */
57346661
AM
7555 PF(Entry_SR);
7556 PV(Entry_FR);
7557 PV(Entry_GR);
7558 PF(Args_stored);
7559 PF(Variable_Frame);
7560 PF(Separate_Package_Body);
7561 PF(Frame_Extension_Millicode);
7562 PF(Stack_Overflow_Check);
7563 PF(Two_Instruction_SP_Increment);
7564 PF(Ada_Region);
7565 PF(cxx_info);
7566 PF(cxx_try_catch);
7567 PF(sched_entry_seq);
7568 PF(Save_SP);
7569 PF(Save_RP);
7570 PF(Save_MRP_in_frame);
7571 PF(extn_ptr_defined);
7572 PF(Cleanup_defined);
7573 PF(MPE_XL_interrupt_marker);
7574 PF(HP_UX_interrupt_marker);
7575 PF(Large_frame);
7576 PF(Pseudo_SP_Set);
7577 PV(Total_frame_size);
7578#undef PF
7579#undef PV
7580 }
7581
18bd398b 7582 printf ("\n");
948f632f
DA
7583
7584 free (aux->funtab);
57346661
AM
7585}
7586
7587static int
2cf0635d
NC
7588slurp_hppa_unwind_table (FILE * file,
7589 struct hppa_unw_aux_info * aux,
7590 Elf_Internal_Shdr * sec)
57346661 7591{
1c0751b2 7592 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
7593 Elf_Internal_Phdr * seg;
7594 struct hppa_unw_table_entry * tep;
7595 Elf_Internal_Shdr * relsec;
7596 Elf_Internal_Rela * rela;
7597 Elf_Internal_Rela * rp;
7598 unsigned char * table;
7599 unsigned char * tp;
7600 Elf_Internal_Sym * sym;
7601 const char * relname;
57346661 7602
57346661
AM
7603 /* First, find the starting address of the segment that includes
7604 this section. */
7605
7606 if (elf_header.e_phnum)
7607 {
7608 if (! get_program_headers (file))
7609 return 0;
7610
7611 for (seg = program_headers;
7612 seg < program_headers + elf_header.e_phnum;
7613 ++seg)
7614 {
7615 if (seg->p_type != PT_LOAD)
7616 continue;
7617
7618 if (sec->sh_addr >= seg->p_vaddr
7619 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7620 {
7621 aux->seg_base = seg->p_vaddr;
7622 break;
7623 }
7624 }
7625 }
7626
7627 /* Second, build the unwind table from the contents of the unwind
7628 section. */
7629 size = sec->sh_size;
3f5e193b
NC
7630 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
7631 _("unwind table"));
57346661
AM
7632 if (!table)
7633 return 0;
7634
1c0751b2
DA
7635 unw_ent_size = 16;
7636 nentries = size / unw_ent_size;
7637 size = unw_ent_size * nentries;
57346661 7638
3f5e193b
NC
7639 tep = aux->table = (struct hppa_unw_table_entry *)
7640 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 7641
1c0751b2 7642 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
7643 {
7644 unsigned int tmp1, tmp2;
7645
7646 tep->start.section = SHN_UNDEF;
7647 tep->end.section = SHN_UNDEF;
7648
1c0751b2
DA
7649 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
7650 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
7651 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
7652 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
7653
7654 tep->start.offset += aux->seg_base;
7655 tep->end.offset += aux->seg_base;
57346661
AM
7656
7657 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
7658 tep->Millicode = (tmp1 >> 30) & 0x1;
7659 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
7660 tep->Region_description = (tmp1 >> 27) & 0x3;
7661 tep->reserved1 = (tmp1 >> 26) & 0x1;
7662 tep->Entry_SR = (tmp1 >> 25) & 0x1;
7663 tep->Entry_FR = (tmp1 >> 21) & 0xf;
7664 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
7665 tep->Args_stored = (tmp1 >> 15) & 0x1;
7666 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
7667 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
7668 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
7669 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
7670 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
7671 tep->Ada_Region = (tmp1 >> 9) & 0x1;
7672 tep->cxx_info = (tmp1 >> 8) & 0x1;
7673 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
7674 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
7675 tep->reserved2 = (tmp1 >> 5) & 0x1;
7676 tep->Save_SP = (tmp1 >> 4) & 0x1;
7677 tep->Save_RP = (tmp1 >> 3) & 0x1;
7678 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
7679 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
7680 tep->Cleanup_defined = tmp1 & 0x1;
7681
7682 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
7683 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
7684 tep->Large_frame = (tmp2 >> 29) & 0x1;
7685 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
7686 tep->reserved4 = (tmp2 >> 27) & 0x1;
7687 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
7688 }
7689 free (table);
7690
7691 /* Third, apply any relocations to the unwind table. */
57346661
AM
7692 for (relsec = section_headers;
7693 relsec < section_headers + elf_header.e_shnum;
7694 ++relsec)
7695 {
7696 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
7697 || relsec->sh_info >= elf_header.e_shnum
7698 || section_headers + relsec->sh_info != sec)
57346661
AM
7699 continue;
7700
7701 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7702 & rela, & nrelas))
7703 return 0;
7704
7705 for (rp = rela; rp < rela + nrelas; ++rp)
7706 {
aca88567
NC
7707 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
7708 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
7709
7710 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 7711 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
7712 {
7713 warn (_("Skipping unexpected relocation type %s\n"), relname);
7714 continue;
7715 }
7716
7717 i = rp->r_offset / unw_ent_size;
7718
89fac5e3 7719 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
7720 {
7721 case 0:
7722 aux->table[i].start.section = sym->st_shndx;
1e456d54 7723 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
7724 break;
7725 case 1:
7726 aux->table[i].end.section = sym->st_shndx;
1e456d54 7727 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
7728 break;
7729 default:
7730 break;
7731 }
7732 }
7733
7734 free (rela);
7735 }
7736
1c0751b2 7737 aux->table_len = nentries;
57346661
AM
7738
7739 return 1;
7740}
7741
1b31d05e 7742static void
2cf0635d 7743hppa_process_unwind (FILE * file)
57346661 7744{
57346661 7745 struct hppa_unw_aux_info aux;
2cf0635d
NC
7746 Elf_Internal_Shdr * unwsec = NULL;
7747 Elf_Internal_Shdr * strsec;
7748 Elf_Internal_Shdr * sec;
18bd398b 7749 unsigned long i;
57346661 7750
c256ffe7 7751 if (string_table == NULL)
1b31d05e
NC
7752 return;
7753
7754 memset (& aux, 0, sizeof (aux));
57346661
AM
7755
7756 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7757 {
c256ffe7 7758 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 7759 && sec->sh_link < elf_header.e_shnum)
57346661 7760 {
ba5cdace 7761 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 7762
4fbb74a6 7763 strsec = section_headers + sec->sh_link;
4082ef84
NC
7764 if (aux.strtab != NULL)
7765 {
7766 error (_("Multiple auxillary string tables encountered\n"));
7767 free (aux.strtab);
7768 }
3f5e193b
NC
7769 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
7770 1, strsec->sh_size,
7771 _("string table"));
c256ffe7 7772 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 7773 }
18bd398b 7774 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
7775 unwsec = sec;
7776 }
7777
7778 if (!unwsec)
7779 printf (_("\nThere are no unwind sections in this file.\n"));
7780
7781 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7782 {
18bd398b 7783 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 7784 {
74e1a04b
NC
7785 printf (_("\nUnwind section '%s' at offset 0x%lx contains %lu entries:\n"),
7786 printable_section_name (sec),
57346661 7787 (unsigned long) sec->sh_offset,
89fac5e3 7788 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
7789
7790 slurp_hppa_unwind_table (file, &aux, sec);
7791 if (aux.table_len > 0)
7792 dump_hppa_unwind (&aux);
7793
7794 if (aux.table)
7795 free ((char *) aux.table);
7796 aux.table = NULL;
7797 }
7798 }
7799
7800 if (aux.symtab)
7801 free (aux.symtab);
7802 if (aux.strtab)
7803 free ((char *) aux.strtab);
57346661
AM
7804}
7805
0b6ae522
DJ
7806struct arm_section
7807{
a734115a
NC
7808 unsigned char * data; /* The unwind data. */
7809 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
7810 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
7811 unsigned long nrelas; /* The number of relocations. */
7812 unsigned int rel_type; /* REL or RELA ? */
7813 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
7814};
7815
7816struct arm_unw_aux_info
7817{
a734115a
NC
7818 FILE * file; /* The file containing the unwind sections. */
7819 Elf_Internal_Sym * symtab; /* The file's symbol table. */
7820 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
7821 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7822 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
7823 char * strtab; /* The file's string table. */
7824 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
7825};
7826
7827static const char *
7828arm_print_vma_and_name (struct arm_unw_aux_info *aux,
7829 bfd_vma fn, struct absaddr addr)
7830{
7831 const char *procname;
7832 bfd_vma sym_offset;
7833
7834 if (addr.section == SHN_UNDEF)
7835 addr.offset = fn;
7836
948f632f 7837 find_symbol_for_address (aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
7838 aux->strtab_size, addr, &procname,
7839 &sym_offset);
7840
7841 print_vma (fn, PREFIX_HEX);
7842
7843 if (procname)
7844 {
7845 fputs (" <", stdout);
7846 fputs (procname, stdout);
7847
7848 if (sym_offset)
7849 printf ("+0x%lx", (unsigned long) sym_offset);
7850 fputc ('>', stdout);
7851 }
7852
7853 return procname;
7854}
7855
7856static void
7857arm_free_section (struct arm_section *arm_sec)
7858{
7859 if (arm_sec->data != NULL)
7860 free (arm_sec->data);
7861
7862 if (arm_sec->rela != NULL)
7863 free (arm_sec->rela);
7864}
7865
a734115a
NC
7866/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
7867 cached section and install SEC instead.
7868 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
7869 and return its valued in * WORDP, relocating if necessary.
1b31d05e 7870 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 7871 relocation's offset in ADDR.
1b31d05e
NC
7872 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
7873 into the string table of the symbol associated with the reloc. If no
7874 reloc was applied store -1 there.
7875 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
7876
7877static bfd_boolean
1b31d05e
NC
7878get_unwind_section_word (struct arm_unw_aux_info * aux,
7879 struct arm_section * arm_sec,
7880 Elf_Internal_Shdr * sec,
7881 bfd_vma word_offset,
7882 unsigned int * wordp,
7883 struct absaddr * addr,
7884 bfd_vma * sym_name)
0b6ae522
DJ
7885{
7886 Elf_Internal_Rela *rp;
7887 Elf_Internal_Sym *sym;
7888 const char * relname;
7889 unsigned int word;
7890 bfd_boolean wrapped;
7891
e0a31db1
NC
7892 if (sec == NULL || arm_sec == NULL)
7893 return FALSE;
7894
0b6ae522
DJ
7895 addr->section = SHN_UNDEF;
7896 addr->offset = 0;
7897
1b31d05e
NC
7898 if (sym_name != NULL)
7899 *sym_name = (bfd_vma) -1;
7900
a734115a 7901 /* If necessary, update the section cache. */
0b6ae522
DJ
7902 if (sec != arm_sec->sec)
7903 {
7904 Elf_Internal_Shdr *relsec;
7905
7906 arm_free_section (arm_sec);
7907
7908 arm_sec->sec = sec;
7909 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
7910 sec->sh_size, _("unwind data"));
0b6ae522
DJ
7911 arm_sec->rela = NULL;
7912 arm_sec->nrelas = 0;
7913
7914 for (relsec = section_headers;
7915 relsec < section_headers + elf_header.e_shnum;
7916 ++relsec)
7917 {
7918 if (relsec->sh_info >= elf_header.e_shnum
1ae40aa4
NC
7919 || section_headers + relsec->sh_info != sec
7920 /* PR 15745: Check the section type as well. */
7921 || (relsec->sh_type != SHT_REL
7922 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
7923 continue;
7924
a734115a 7925 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
7926 if (relsec->sh_type == SHT_REL)
7927 {
7928 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
7929 relsec->sh_size,
7930 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7931 return FALSE;
0b6ae522 7932 }
1ae40aa4 7933 else /* relsec->sh_type == SHT_RELA */
0b6ae522
DJ
7934 {
7935 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
7936 relsec->sh_size,
7937 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7938 return FALSE;
0b6ae522 7939 }
1ae40aa4 7940 break;
0b6ae522
DJ
7941 }
7942
7943 arm_sec->next_rela = arm_sec->rela;
7944 }
7945
a734115a 7946 /* If there is no unwind data we can do nothing. */
0b6ae522 7947 if (arm_sec->data == NULL)
a734115a 7948 return FALSE;
0b6ae522 7949
e0a31db1 7950 /* If the offset is invalid then fail. */
1a915552
NC
7951 if (word_offset > (sec->sh_size - 4)
7952 /* PR 18879 */
7953 || (sec->sh_size < 5 && word_offset >= sec->sh_size)
7954 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
7955 return FALSE;
7956
a734115a 7957 /* Get the word at the required offset. */
0b6ae522
DJ
7958 word = byte_get (arm_sec->data + word_offset, 4);
7959
0eff7165
NC
7960 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
7961 if (arm_sec->rela == NULL)
7962 {
7963 * wordp = word;
7964 return TRUE;
7965 }
7966
a734115a 7967 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
7968 wrapped = FALSE;
7969 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
7970 {
7971 bfd_vma prelval, offset;
7972
7973 if (rp->r_offset > word_offset && !wrapped)
7974 {
7975 rp = arm_sec->rela;
7976 wrapped = TRUE;
7977 }
7978 if (rp->r_offset > word_offset)
7979 break;
7980
7981 if (rp->r_offset & 3)
7982 {
7983 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
7984 (unsigned long) rp->r_offset);
7985 continue;
7986 }
7987
7988 if (rp->r_offset < word_offset)
7989 continue;
7990
74e1a04b
NC
7991 /* PR 17531: file: 027-161405-0.004 */
7992 if (aux->symtab == NULL)
7993 continue;
7994
0b6ae522
DJ
7995 if (arm_sec->rel_type == SHT_REL)
7996 {
7997 offset = word & 0x7fffffff;
7998 if (offset & 0x40000000)
7999 offset |= ~ (bfd_vma) 0x7fffffff;
8000 }
a734115a 8001 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8002 offset = rp->r_addend;
a734115a 8003 else
74e1a04b
NC
8004 {
8005 error (_("Unknown section relocation type %d encountered\n"),
8006 arm_sec->rel_type);
8007 break;
8008 }
0b6ae522 8009
071436c6
NC
8010 /* PR 17531 file: 027-1241568-0.004. */
8011 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8012 {
8013 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8014 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8015 break;
8016 }
8017
8018 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8019 offset += sym->st_value;
8020 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8021
a734115a
NC
8022 /* Check that we are processing the expected reloc type. */
8023 if (elf_header.e_machine == EM_ARM)
8024 {
8025 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8026 if (relname == NULL)
8027 {
8028 warn (_("Skipping unknown ARM relocation type: %d\n"),
8029 (int) ELF32_R_TYPE (rp->r_info));
8030 continue;
8031 }
a734115a
NC
8032
8033 if (streq (relname, "R_ARM_NONE"))
8034 continue;
0b4362b0 8035
a734115a
NC
8036 if (! streq (relname, "R_ARM_PREL31"))
8037 {
071436c6 8038 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8039 continue;
8040 }
8041 }
8042 else if (elf_header.e_machine == EM_TI_C6000)
8043 {
8044 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8045 if (relname == NULL)
8046 {
8047 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8048 (int) ELF32_R_TYPE (rp->r_info));
8049 continue;
8050 }
0b4362b0 8051
a734115a
NC
8052 if (streq (relname, "R_C6000_NONE"))
8053 continue;
8054
8055 if (! streq (relname, "R_C6000_PREL31"))
8056 {
071436c6 8057 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8058 continue;
8059 }
8060
8061 prelval >>= 1;
8062 }
8063 else
74e1a04b
NC
8064 {
8065 /* This function currently only supports ARM and TI unwinders. */
8066 warn (_("Only TI and ARM unwinders are currently supported\n"));
8067 break;
8068 }
fa197c1c 8069
0b6ae522
DJ
8070 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8071 addr->section = sym->st_shndx;
8072 addr->offset = offset;
74e1a04b 8073
1b31d05e
NC
8074 if (sym_name)
8075 * sym_name = sym->st_name;
0b6ae522
DJ
8076 break;
8077 }
8078
8079 *wordp = word;
8080 arm_sec->next_rela = rp;
8081
a734115a 8082 return TRUE;
0b6ae522
DJ
8083}
8084
a734115a
NC
8085static const char *tic6x_unwind_regnames[16] =
8086{
0b4362b0
RM
8087 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8088 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8089 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8090};
fa197c1c 8091
0b6ae522 8092static void
fa197c1c 8093decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8094{
fa197c1c
PB
8095 int i;
8096
8097 for (i = 12; mask; mask >>= 1, i--)
8098 {
8099 if (mask & 1)
8100 {
8101 fputs (tic6x_unwind_regnames[i], stdout);
8102 if (mask > 1)
8103 fputs (", ", stdout);
8104 }
8105 }
8106}
0b6ae522
DJ
8107
8108#define ADVANCE \
8109 if (remaining == 0 && more_words) \
8110 { \
8111 data_offset += 4; \
1b31d05e
NC
8112 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
8113 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
8114 return; \
8115 remaining = 4; \
8116 more_words--; \
8117 } \
8118
8119#define GET_OP(OP) \
8120 ADVANCE; \
8121 if (remaining) \
8122 { \
8123 remaining--; \
8124 (OP) = word >> 24; \
8125 word <<= 8; \
8126 } \
8127 else \
8128 { \
2b692964 8129 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
8130 return; \
8131 } \
cc5914eb 8132 printf ("0x%02x ", OP)
0b6ae522 8133
fa197c1c 8134static void
948f632f
DA
8135decode_arm_unwind_bytecode (struct arm_unw_aux_info * aux,
8136 unsigned int word,
8137 unsigned int remaining,
8138 unsigned int more_words,
8139 bfd_vma data_offset,
8140 Elf_Internal_Shdr * data_sec,
8141 struct arm_section * data_arm_sec)
fa197c1c
PB
8142{
8143 struct absaddr addr;
0b6ae522
DJ
8144
8145 /* Decode the unwinding instructions. */
8146 while (1)
8147 {
8148 unsigned int op, op2;
8149
8150 ADVANCE;
8151 if (remaining == 0)
8152 break;
8153 remaining--;
8154 op = word >> 24;
8155 word <<= 8;
8156
cc5914eb 8157 printf (" 0x%02x ", op);
0b6ae522
DJ
8158
8159 if ((op & 0xc0) == 0x00)
8160 {
8161 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8162
cc5914eb 8163 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8164 }
8165 else if ((op & 0xc0) == 0x40)
8166 {
8167 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8168
cc5914eb 8169 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8170 }
8171 else if ((op & 0xf0) == 0x80)
8172 {
8173 GET_OP (op2);
8174 if (op == 0x80 && op2 == 0)
8175 printf (_("Refuse to unwind"));
8176 else
8177 {
8178 unsigned int mask = ((op & 0x0f) << 8) | op2;
8179 int first = 1;
8180 int i;
2b692964 8181
0b6ae522
DJ
8182 printf ("pop {");
8183 for (i = 0; i < 12; i++)
8184 if (mask & (1 << i))
8185 {
8186 if (first)
8187 first = 0;
8188 else
8189 printf (", ");
8190 printf ("r%d", 4 + i);
8191 }
8192 printf ("}");
8193 }
8194 }
8195 else if ((op & 0xf0) == 0x90)
8196 {
8197 if (op == 0x9d || op == 0x9f)
8198 printf (_(" [Reserved]"));
8199 else
cc5914eb 8200 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8201 }
8202 else if ((op & 0xf0) == 0xa0)
8203 {
8204 int end = 4 + (op & 0x07);
8205 int first = 1;
8206 int i;
61865e30 8207
0b6ae522
DJ
8208 printf (" pop {");
8209 for (i = 4; i <= end; i++)
8210 {
8211 if (first)
8212 first = 0;
8213 else
8214 printf (", ");
8215 printf ("r%d", i);
8216 }
8217 if (op & 0x08)
8218 {
1b31d05e 8219 if (!first)
0b6ae522
DJ
8220 printf (", ");
8221 printf ("r14");
8222 }
8223 printf ("}");
8224 }
8225 else if (op == 0xb0)
8226 printf (_(" finish"));
8227 else if (op == 0xb1)
8228 {
8229 GET_OP (op2);
8230 if (op2 == 0 || (op2 & 0xf0) != 0)
8231 printf (_("[Spare]"));
8232 else
8233 {
8234 unsigned int mask = op2 & 0x0f;
8235 int first = 1;
8236 int i;
61865e30 8237
0b6ae522
DJ
8238 printf ("pop {");
8239 for (i = 0; i < 12; i++)
8240 if (mask & (1 << i))
8241 {
8242 if (first)
8243 first = 0;
8244 else
8245 printf (", ");
8246 printf ("r%d", i);
8247 }
8248 printf ("}");
8249 }
8250 }
8251 else if (op == 0xb2)
8252 {
b115cf96 8253 unsigned char buf[9];
0b6ae522
DJ
8254 unsigned int i, len;
8255 unsigned long offset;
61865e30 8256
b115cf96 8257 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8258 {
8259 GET_OP (buf[i]);
8260 if ((buf[i] & 0x80) == 0)
8261 break;
8262 }
4082ef84
NC
8263 if (i == sizeof (buf))
8264 printf (_("corrupt change to vsp"));
8265 else
8266 {
8267 offset = read_uleb128 (buf, &len, buf + i + 1);
8268 assert (len == i + 1);
8269 offset = offset * 4 + 0x204;
8270 printf ("vsp = vsp + %ld", offset);
8271 }
0b6ae522 8272 }
61865e30 8273 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8274 {
61865e30
NC
8275 unsigned int first, last;
8276
8277 GET_OP (op2);
8278 first = op2 >> 4;
8279 last = op2 & 0x0f;
8280 if (op == 0xc8)
8281 first = first + 16;
8282 printf ("pop {D%d", first);
8283 if (last)
8284 printf ("-D%d", first + last);
8285 printf ("}");
8286 }
8287 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
8288 {
8289 unsigned int count = op & 0x07;
8290
8291 printf ("pop {D8");
8292 if (count)
8293 printf ("-D%d", 8 + count);
8294 printf ("}");
8295 }
8296 else if (op >= 0xc0 && op <= 0xc5)
8297 {
8298 unsigned int count = op & 0x07;
8299
8300 printf (" pop {wR10");
8301 if (count)
8302 printf ("-wR%d", 10 + count);
8303 printf ("}");
8304 }
8305 else if (op == 0xc6)
8306 {
8307 unsigned int first, last;
8308
8309 GET_OP (op2);
8310 first = op2 >> 4;
8311 last = op2 & 0x0f;
8312 printf ("pop {wR%d", first);
8313 if (last)
8314 printf ("-wR%d", first + last);
8315 printf ("}");
8316 }
8317 else if (op == 0xc7)
8318 {
8319 GET_OP (op2);
8320 if (op2 == 0 || (op2 & 0xf0) != 0)
8321 printf (_("[Spare]"));
0b6ae522
DJ
8322 else
8323 {
61865e30
NC
8324 unsigned int mask = op2 & 0x0f;
8325 int first = 1;
8326 int i;
8327
8328 printf ("pop {");
8329 for (i = 0; i < 4; i++)
8330 if (mask & (1 << i))
8331 {
8332 if (first)
8333 first = 0;
8334 else
8335 printf (", ");
8336 printf ("wCGR%d", i);
8337 }
8338 printf ("}");
0b6ae522
DJ
8339 }
8340 }
61865e30
NC
8341 else
8342 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
8343 printf ("\n");
8344 }
fa197c1c
PB
8345}
8346
8347static void
948f632f
DA
8348decode_tic6x_unwind_bytecode (struct arm_unw_aux_info * aux,
8349 unsigned int word,
8350 unsigned int remaining,
8351 unsigned int more_words,
8352 bfd_vma data_offset,
8353 Elf_Internal_Shdr * data_sec,
8354 struct arm_section * data_arm_sec)
fa197c1c
PB
8355{
8356 struct absaddr addr;
8357
8358 /* Decode the unwinding instructions. */
8359 while (1)
8360 {
8361 unsigned int op, op2;
8362
8363 ADVANCE;
8364 if (remaining == 0)
8365 break;
8366 remaining--;
8367 op = word >> 24;
8368 word <<= 8;
8369
9cf03b7e 8370 printf (" 0x%02x ", op);
fa197c1c
PB
8371
8372 if ((op & 0xc0) == 0x00)
8373 {
8374 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 8375 printf (" sp = sp + %d", offset);
fa197c1c
PB
8376 }
8377 else if ((op & 0xc0) == 0x80)
8378 {
8379 GET_OP (op2);
8380 if (op == 0x80 && op2 == 0)
8381 printf (_("Refuse to unwind"));
8382 else
8383 {
8384 unsigned int mask = ((op & 0x1f) << 8) | op2;
8385 if (op & 0x20)
8386 printf ("pop compact {");
8387 else
8388 printf ("pop {");
8389
8390 decode_tic6x_unwind_regmask (mask);
8391 printf("}");
8392 }
8393 }
8394 else if ((op & 0xf0) == 0xc0)
8395 {
8396 unsigned int reg;
8397 unsigned int nregs;
8398 unsigned int i;
8399 const char *name;
a734115a
NC
8400 struct
8401 {
fa197c1c
PB
8402 unsigned int offset;
8403 unsigned int reg;
8404 } regpos[16];
8405
8406 /* Scan entire instruction first so that GET_OP output is not
8407 interleaved with disassembly. */
8408 nregs = 0;
8409 for (i = 0; nregs < (op & 0xf); i++)
8410 {
8411 GET_OP (op2);
8412 reg = op2 >> 4;
8413 if (reg != 0xf)
8414 {
8415 regpos[nregs].offset = i * 2;
8416 regpos[nregs].reg = reg;
8417 nregs++;
8418 }
8419
8420 reg = op2 & 0xf;
8421 if (reg != 0xf)
8422 {
8423 regpos[nregs].offset = i * 2 + 1;
8424 regpos[nregs].reg = reg;
8425 nregs++;
8426 }
8427 }
8428
8429 printf (_("pop frame {"));
8430 reg = nregs - 1;
8431 for (i = i * 2; i > 0; i--)
8432 {
8433 if (regpos[reg].offset == i - 1)
8434 {
8435 name = tic6x_unwind_regnames[regpos[reg].reg];
8436 if (reg > 0)
8437 reg--;
8438 }
8439 else
8440 name = _("[pad]");
8441
8442 fputs (name, stdout);
8443 if (i > 1)
8444 printf (", ");
8445 }
8446
8447 printf ("}");
8448 }
8449 else if (op == 0xd0)
8450 printf (" MOV FP, SP");
8451 else if (op == 0xd1)
8452 printf (" __c6xabi_pop_rts");
8453 else if (op == 0xd2)
8454 {
8455 unsigned char buf[9];
8456 unsigned int i, len;
8457 unsigned long offset;
a734115a 8458
fa197c1c
PB
8459 for (i = 0; i < sizeof (buf); i++)
8460 {
8461 GET_OP (buf[i]);
8462 if ((buf[i] & 0x80) == 0)
8463 break;
8464 }
0eff7165
NC
8465 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
8466 if (i == sizeof (buf))
8467 {
8468 printf ("<corrupt sp adjust>\n");
8469 warn (_("Corrupt stack pointer adjustment detected\n"));
8470 return;
8471 }
948f632f 8472
f6f0e17b 8473 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
8474 assert (len == i + 1);
8475 offset = offset * 8 + 0x408;
8476 printf (_("sp = sp + %ld"), offset);
8477 }
8478 else if ((op & 0xf0) == 0xe0)
8479 {
8480 if ((op & 0x0f) == 7)
8481 printf (" RETURN");
8482 else
8483 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
8484 }
8485 else
8486 {
8487 printf (_(" [unsupported opcode]"));
8488 }
8489 putchar ('\n');
8490 }
8491}
8492
8493static bfd_vma
a734115a 8494arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
8495{
8496 bfd_vma offset;
8497
8498 offset = word & 0x7fffffff;
8499 if (offset & 0x40000000)
8500 offset |= ~ (bfd_vma) 0x7fffffff;
8501
8502 if (elf_header.e_machine == EM_TI_C6000)
8503 offset <<= 1;
8504
8505 return offset + where;
8506}
8507
8508static void
1b31d05e
NC
8509decode_arm_unwind (struct arm_unw_aux_info * aux,
8510 unsigned int word,
8511 unsigned int remaining,
8512 bfd_vma data_offset,
8513 Elf_Internal_Shdr * data_sec,
8514 struct arm_section * data_arm_sec)
fa197c1c
PB
8515{
8516 int per_index;
8517 unsigned int more_words = 0;
37e14bc3 8518 struct absaddr addr;
1b31d05e 8519 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
8520
8521 if (remaining == 0)
8522 {
1b31d05e
NC
8523 /* Fetch the first word.
8524 Note - when decoding an object file the address extracted
8525 here will always be 0. So we also pass in the sym_name
8526 parameter so that we can find the symbol associated with
8527 the personality routine. */
8528 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
8529 & word, & addr, & sym_name))
fa197c1c 8530 return;
1b31d05e 8531
fa197c1c
PB
8532 remaining = 4;
8533 }
8534
8535 if ((word & 0x80000000) == 0)
8536 {
8537 /* Expand prel31 for personality routine. */
8538 bfd_vma fn;
8539 const char *procname;
8540
a734115a 8541 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 8542 printf (_(" Personality routine: "));
1b31d05e
NC
8543 if (fn == 0
8544 && addr.section == SHN_UNDEF && addr.offset == 0
8545 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
8546 {
8547 procname = aux->strtab + sym_name;
8548 print_vma (fn, PREFIX_HEX);
8549 if (procname)
8550 {
8551 fputs (" <", stdout);
8552 fputs (procname, stdout);
8553 fputc ('>', stdout);
8554 }
8555 }
8556 else
8557 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
8558 fputc ('\n', stdout);
8559
8560 /* The GCC personality routines use the standard compact
8561 encoding, starting with one byte giving the number of
8562 words. */
8563 if (procname != NULL
8564 && (const_strneq (procname, "__gcc_personality_v0")
8565 || const_strneq (procname, "__gxx_personality_v0")
8566 || const_strneq (procname, "__gcj_personality_v0")
8567 || const_strneq (procname, "__gnu_objc_personality_v0")))
8568 {
8569 remaining = 0;
8570 more_words = 1;
8571 ADVANCE;
8572 if (!remaining)
8573 {
8574 printf (_(" [Truncated data]\n"));
8575 return;
8576 }
8577 more_words = word >> 24;
8578 word <<= 8;
8579 remaining--;
8580 per_index = -1;
8581 }
8582 else
8583 return;
8584 }
8585 else
8586 {
1b31d05e 8587 /* ARM EHABI Section 6.3:
0b4362b0 8588
1b31d05e 8589 An exception-handling table entry for the compact model looks like:
0b4362b0 8590
1b31d05e
NC
8591 31 30-28 27-24 23-0
8592 -- ----- ----- ----
8593 1 0 index Data for personalityRoutine[index] */
8594
8595 if (elf_header.e_machine == EM_ARM
8596 && (word & 0x70000000))
83c257ca 8597 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 8598
fa197c1c 8599 per_index = (word >> 24) & 0x7f;
1b31d05e 8600 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
8601 if (per_index == 0)
8602 {
8603 more_words = 0;
8604 word <<= 8;
8605 remaining--;
8606 }
8607 else if (per_index < 3)
8608 {
8609 more_words = (word >> 16) & 0xff;
8610 word <<= 16;
8611 remaining -= 2;
8612 }
8613 }
8614
8615 switch (elf_header.e_machine)
8616 {
8617 case EM_ARM:
8618 if (per_index < 3)
8619 {
8620 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
8621 data_offset, data_sec, data_arm_sec);
8622 }
8623 else
1b31d05e
NC
8624 {
8625 warn (_("Unknown ARM compact model index encountered\n"));
8626 printf (_(" [reserved]\n"));
8627 }
fa197c1c
PB
8628 break;
8629
8630 case EM_TI_C6000:
8631 if (per_index < 3)
8632 {
8633 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 8634 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
8635 }
8636 else if (per_index < 5)
8637 {
8638 if (((word >> 17) & 0x7f) == 0x7f)
8639 printf (_(" Restore stack from frame pointer\n"));
8640 else
8641 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
8642 printf (_(" Registers restored: "));
8643 if (per_index == 4)
8644 printf (" (compact) ");
8645 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
8646 putchar ('\n');
8647 printf (_(" Return register: %s\n"),
8648 tic6x_unwind_regnames[word & 0xf]);
8649 }
8650 else
1b31d05e 8651 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
8652 break;
8653
8654 default:
74e1a04b 8655 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
1b31d05e 8656 elf_header.e_machine);
fa197c1c 8657 }
0b6ae522
DJ
8658
8659 /* Decode the descriptors. Not implemented. */
8660}
8661
8662static void
8663dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
8664{
8665 struct arm_section exidx_arm_sec, extab_arm_sec;
8666 unsigned int i, exidx_len;
948f632f 8667 unsigned long j, nfuns;
0b6ae522
DJ
8668
8669 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
8670 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
8671 exidx_len = exidx_sec->sh_size / 8;
8672
948f632f
DA
8673 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8674 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8675 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8676 aux->funtab[nfuns++] = aux->symtab[j];
8677 aux->nfuns = nfuns;
8678 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8679
0b6ae522
DJ
8680 for (i = 0; i < exidx_len; i++)
8681 {
8682 unsigned int exidx_fn, exidx_entry;
8683 struct absaddr fn_addr, entry_addr;
8684 bfd_vma fn;
8685
8686 fputc ('\n', stdout);
8687
1b31d05e
NC
8688 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8689 8 * i, & exidx_fn, & fn_addr, NULL)
8690 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8691 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 8692 {
948f632f 8693 free (aux->funtab);
1b31d05e
NC
8694 arm_free_section (& exidx_arm_sec);
8695 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
8696 return;
8697 }
8698
83c257ca
NC
8699 /* ARM EHABI, Section 5:
8700 An index table entry consists of 2 words.
8701 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
8702 if (exidx_fn & 0x80000000)
8703 warn (_("corrupt index table entry: %x\n"), exidx_fn);
8704
a734115a 8705 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 8706
a734115a 8707 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
8708 fputs (": ", stdout);
8709
8710 if (exidx_entry == 1)
8711 {
8712 print_vma (exidx_entry, PREFIX_HEX);
8713 fputs (" [cantunwind]\n", stdout);
8714 }
8715 else if (exidx_entry & 0x80000000)
8716 {
8717 print_vma (exidx_entry, PREFIX_HEX);
8718 fputc ('\n', stdout);
8719 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
8720 }
8721 else
8722 {
8f73510c 8723 bfd_vma table, table_offset = 0;
0b6ae522
DJ
8724 Elf_Internal_Shdr *table_sec;
8725
8726 fputs ("@", stdout);
a734115a 8727 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
8728 print_vma (table, PREFIX_HEX);
8729 printf ("\n");
8730
8731 /* Locate the matching .ARM.extab. */
8732 if (entry_addr.section != SHN_UNDEF
8733 && entry_addr.section < elf_header.e_shnum)
8734 {
8735 table_sec = section_headers + entry_addr.section;
8736 table_offset = entry_addr.offset;
1a915552
NC
8737 /* PR 18879 */
8738 if (table_offset > table_sec->sh_size
8739 || ((bfd_signed_vma) table_offset) < 0)
8740 {
8741 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
8742 (unsigned long) table_offset,
8743 printable_section_name (table_sec));
8744 continue;
8745 }
0b6ae522
DJ
8746 }
8747 else
8748 {
8749 table_sec = find_section_by_address (table);
8750 if (table_sec != NULL)
8751 table_offset = table - table_sec->sh_addr;
8752 }
8753 if (table_sec == NULL)
8754 {
8755 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
8756 (unsigned long) table);
8757 continue;
8758 }
8759 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
8760 &extab_arm_sec);
8761 }
8762 }
8763
8764 printf ("\n");
8765
948f632f 8766 free (aux->funtab);
0b6ae522
DJ
8767 arm_free_section (&exidx_arm_sec);
8768 arm_free_section (&extab_arm_sec);
8769}
8770
fa197c1c 8771/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
8772
8773static void
0b6ae522
DJ
8774arm_process_unwind (FILE *file)
8775{
8776 struct arm_unw_aux_info aux;
8777 Elf_Internal_Shdr *unwsec = NULL;
8778 Elf_Internal_Shdr *strsec;
8779 Elf_Internal_Shdr *sec;
8780 unsigned long i;
fa197c1c 8781 unsigned int sec_type;
0b6ae522 8782
fa197c1c
PB
8783 switch (elf_header.e_machine)
8784 {
8785 case EM_ARM:
8786 sec_type = SHT_ARM_EXIDX;
8787 break;
8788
8789 case EM_TI_C6000:
8790 sec_type = SHT_C6000_UNWIND;
8791 break;
8792
0b4362b0 8793 default:
74e1a04b 8794 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
1b31d05e
NC
8795 elf_header.e_machine);
8796 return;
fa197c1c
PB
8797 }
8798
0b6ae522 8799 if (string_table == NULL)
1b31d05e
NC
8800 return;
8801
8802 memset (& aux, 0, sizeof (aux));
8803 aux.file = file;
0b6ae522
DJ
8804
8805 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8806 {
8807 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
8808 {
ba5cdace 8809 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
8810
8811 strsec = section_headers + sec->sh_link;
74e1a04b
NC
8812
8813 /* PR binutils/17531 file: 011-12666-0.004. */
8814 if (aux.strtab != NULL)
8815 {
4082ef84 8816 error (_("Multiple string tables found in file.\n"));
74e1a04b
NC
8817 free (aux.strtab);
8818 }
0b6ae522
DJ
8819 aux.strtab = get_data (NULL, file, strsec->sh_offset,
8820 1, strsec->sh_size, _("string table"));
8821 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
8822 }
fa197c1c 8823 else if (sec->sh_type == sec_type)
0b6ae522
DJ
8824 unwsec = sec;
8825 }
8826
1b31d05e 8827 if (unwsec == NULL)
0b6ae522 8828 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
8829 else
8830 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8831 {
8832 if (sec->sh_type == sec_type)
8833 {
8834 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
74e1a04b 8835 printable_section_name (sec),
1b31d05e
NC
8836 (unsigned long) sec->sh_offset,
8837 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 8838
1b31d05e
NC
8839 dump_arm_unwind (&aux, sec);
8840 }
8841 }
0b6ae522
DJ
8842
8843 if (aux.symtab)
8844 free (aux.symtab);
8845 if (aux.strtab)
8846 free ((char *) aux.strtab);
0b6ae522
DJ
8847}
8848
1b31d05e 8849static void
2cf0635d 8850process_unwind (FILE * file)
57346661 8851{
2cf0635d
NC
8852 struct unwind_handler
8853 {
57346661 8854 int machtype;
1b31d05e 8855 void (* handler)(FILE *);
2cf0635d
NC
8856 } handlers[] =
8857 {
0b6ae522 8858 { EM_ARM, arm_process_unwind },
57346661
AM
8859 { EM_IA_64, ia64_process_unwind },
8860 { EM_PARISC, hppa_process_unwind },
fa197c1c 8861 { EM_TI_C6000, arm_process_unwind },
57346661
AM
8862 { 0, 0 }
8863 };
8864 int i;
8865
8866 if (!do_unwind)
1b31d05e 8867 return;
57346661
AM
8868
8869 for (i = 0; handlers[i].handler != NULL; i++)
8870 if (elf_header.e_machine == handlers[i].machtype)
9f758fdc
NC
8871 {
8872 handlers[i].handler (file);
8873 return;
8874 }
57346661 8875
1b31d05e
NC
8876 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
8877 get_machine_name (elf_header.e_machine));
57346661
AM
8878}
8879
252b5132 8880static void
2cf0635d 8881dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
8882{
8883 switch (entry->d_tag)
8884 {
8885 case DT_MIPS_FLAGS:
8886 if (entry->d_un.d_val == 0)
4b68bca3 8887 printf (_("NONE"));
252b5132
RH
8888 else
8889 {
8890 static const char * opts[] =
8891 {
8892 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
8893 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
8894 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
8895 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
8896 "RLD_ORDER_SAFE"
8897 };
8898 unsigned int cnt;
8899 int first = 1;
2b692964 8900
60bca95a 8901 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
8902 if (entry->d_un.d_val & (1 << cnt))
8903 {
8904 printf ("%s%s", first ? "" : " ", opts[cnt]);
8905 first = 0;
8906 }
252b5132
RH
8907 }
8908 break;
103f02d3 8909
252b5132 8910 case DT_MIPS_IVERSION:
d79b3d50 8911 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 8912 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8913 else
76ca31c0
NC
8914 {
8915 char buf[40];
8916 sprintf_vma (buf, entry->d_un.d_ptr);
8917 /* Note: coded this way so that there is a single string for translation. */
8918 printf (_("<corrupt: %s>"), buf);
8919 }
252b5132 8920 break;
103f02d3 8921
252b5132
RH
8922 case DT_MIPS_TIME_STAMP:
8923 {
d5b07ef4 8924 char timebuf[128];
2cf0635d 8925 struct tm * tmp;
91d6fa6a 8926 time_t atime = entry->d_un.d_val;
82b1b41b 8927
91d6fa6a 8928 tmp = gmtime (&atime);
82b1b41b
NC
8929 /* PR 17531: file: 6accc532. */
8930 if (tmp == NULL)
8931 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
8932 else
8933 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
8934 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8935 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 8936 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
8937 }
8938 break;
103f02d3 8939
252b5132
RH
8940 case DT_MIPS_RLD_VERSION:
8941 case DT_MIPS_LOCAL_GOTNO:
8942 case DT_MIPS_CONFLICTNO:
8943 case DT_MIPS_LIBLISTNO:
8944 case DT_MIPS_SYMTABNO:
8945 case DT_MIPS_UNREFEXTNO:
8946 case DT_MIPS_HIPAGENO:
8947 case DT_MIPS_DELTA_CLASS_NO:
8948 case DT_MIPS_DELTA_INSTANCE_NO:
8949 case DT_MIPS_DELTA_RELOC_NO:
8950 case DT_MIPS_DELTA_SYM_NO:
8951 case DT_MIPS_DELTA_CLASSSYM_NO:
8952 case DT_MIPS_COMPACT_SIZE:
c69075ac 8953 print_vma (entry->d_un.d_val, DEC);
252b5132 8954 break;
103f02d3
UD
8955
8956 default:
4b68bca3 8957 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 8958 }
4b68bca3 8959 putchar ('\n');
103f02d3
UD
8960}
8961
103f02d3 8962static void
2cf0635d 8963dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
8964{
8965 switch (entry->d_tag)
8966 {
8967 case DT_HP_DLD_FLAGS:
8968 {
8969 static struct
8970 {
8971 long int bit;
2cf0635d 8972 const char * str;
5e220199
NC
8973 }
8974 flags[] =
8975 {
8976 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
8977 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
8978 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
8979 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
8980 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
8981 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
8982 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
8983 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
8984 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
8985 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
8986 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
8987 { DT_HP_GST, "HP_GST" },
8988 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
8989 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
8990 { DT_HP_NODELETE, "HP_NODELETE" },
8991 { DT_HP_GROUP, "HP_GROUP" },
8992 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 8993 };
103f02d3 8994 int first = 1;
5e220199 8995 size_t cnt;
f7a99963 8996 bfd_vma val = entry->d_un.d_val;
103f02d3 8997
60bca95a 8998 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 8999 if (val & flags[cnt].bit)
30800947
NC
9000 {
9001 if (! first)
9002 putchar (' ');
9003 fputs (flags[cnt].str, stdout);
9004 first = 0;
9005 val ^= flags[cnt].bit;
9006 }
76da6bbe 9007
103f02d3 9008 if (val != 0 || first)
f7a99963
NC
9009 {
9010 if (! first)
9011 putchar (' ');
9012 print_vma (val, HEX);
9013 }
103f02d3
UD
9014 }
9015 break;
76da6bbe 9016
252b5132 9017 default:
f7a99963
NC
9018 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9019 break;
252b5132 9020 }
35b1837e 9021 putchar ('\n');
252b5132
RH
9022}
9023
28f997cf
TG
9024#ifdef BFD64
9025
9026/* VMS vs Unix time offset and factor. */
9027
9028#define VMS_EPOCH_OFFSET 35067168000000000LL
9029#define VMS_GRANULARITY_FACTOR 10000000
9030
9031/* Display a VMS time in a human readable format. */
9032
9033static void
9034print_vms_time (bfd_int64_t vmstime)
9035{
9036 struct tm *tm;
9037 time_t unxtime;
9038
9039 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9040 tm = gmtime (&unxtime);
9041 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9042 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9043 tm->tm_hour, tm->tm_min, tm->tm_sec);
9044}
9045#endif /* BFD64 */
9046
ecc51f48 9047static void
2cf0635d 9048dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9049{
9050 switch (entry->d_tag)
9051 {
0de14b54 9052 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9053 /* First 3 slots reserved. */
ecc51f48
NC
9054 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9055 printf (" -- ");
9056 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9057 break;
9058
28f997cf
TG
9059 case DT_IA_64_VMS_LINKTIME:
9060#ifdef BFD64
9061 print_vms_time (entry->d_un.d_val);
9062#endif
9063 break;
9064
9065 case DT_IA_64_VMS_LNKFLAGS:
9066 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9067 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9068 printf (" CALL_DEBUG");
9069 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9070 printf (" NOP0BUFS");
9071 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9072 printf (" P0IMAGE");
9073 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9074 printf (" MKTHREADS");
9075 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9076 printf (" UPCALLS");
9077 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9078 printf (" IMGSTA");
9079 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9080 printf (" INITIALIZE");
9081 if (entry->d_un.d_val & VMS_LF_MAIN)
9082 printf (" MAIN");
9083 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9084 printf (" EXE_INIT");
9085 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9086 printf (" TBK_IN_IMG");
9087 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9088 printf (" DBG_IN_IMG");
9089 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9090 printf (" TBK_IN_DSF");
9091 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9092 printf (" DBG_IN_DSF");
9093 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9094 printf (" SIGNATURES");
9095 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9096 printf (" REL_SEG_OFF");
9097 break;
9098
bdf4d63a
JJ
9099 default:
9100 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9101 break;
ecc51f48 9102 }
bdf4d63a 9103 putchar ('\n');
ecc51f48
NC
9104}
9105
252b5132 9106static int
2cf0635d 9107get_32bit_dynamic_section (FILE * file)
252b5132 9108{
2cf0635d
NC
9109 Elf32_External_Dyn * edyn;
9110 Elf32_External_Dyn * ext;
9111 Elf_Internal_Dyn * entry;
103f02d3 9112
3f5e193b
NC
9113 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
9114 dynamic_size, _("dynamic section"));
a6e9f9df
AM
9115 if (!edyn)
9116 return 0;
103f02d3 9117
071436c6
NC
9118 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9119 might not have the luxury of section headers. Look for the DT_NULL
9120 terminator to determine the number of entries. */
ba2685cc 9121 for (ext = edyn, dynamic_nent = 0;
53c3012c 9122 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9123 ext++)
9124 {
9125 dynamic_nent++;
9126 if (BYTE_GET (ext->d_tag) == DT_NULL)
9127 break;
9128 }
252b5132 9129
3f5e193b
NC
9130 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9131 sizeof (* entry));
b2d38a17 9132 if (dynamic_section == NULL)
252b5132 9133 {
8b73c356
NC
9134 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9135 (unsigned long) dynamic_nent);
9ea033b2
NC
9136 free (edyn);
9137 return 0;
9138 }
252b5132 9139
fb514b26 9140 for (ext = edyn, entry = dynamic_section;
ba2685cc 9141 entry < dynamic_section + dynamic_nent;
fb514b26 9142 ext++, entry++)
9ea033b2 9143 {
fb514b26
AM
9144 entry->d_tag = BYTE_GET (ext->d_tag);
9145 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9146 }
9147
9ea033b2
NC
9148 free (edyn);
9149
9150 return 1;
9151}
9152
9153static int
2cf0635d 9154get_64bit_dynamic_section (FILE * file)
9ea033b2 9155{
2cf0635d
NC
9156 Elf64_External_Dyn * edyn;
9157 Elf64_External_Dyn * ext;
9158 Elf_Internal_Dyn * entry;
103f02d3 9159
071436c6 9160 /* Read in the data. */
3f5e193b
NC
9161 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
9162 dynamic_size, _("dynamic section"));
a6e9f9df
AM
9163 if (!edyn)
9164 return 0;
103f02d3 9165
071436c6
NC
9166 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9167 might not have the luxury of section headers. Look for the DT_NULL
9168 terminator to determine the number of entries. */
ba2685cc 9169 for (ext = edyn, dynamic_nent = 0;
53c3012c
AM
9170 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
9171 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9172 ext++)
9173 {
9174 dynamic_nent++;
66543521 9175 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9176 break;
9177 }
252b5132 9178
3f5e193b
NC
9179 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9180 sizeof (* entry));
b2d38a17 9181 if (dynamic_section == NULL)
252b5132 9182 {
8b73c356
NC
9183 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9184 (unsigned long) dynamic_nent);
252b5132
RH
9185 free (edyn);
9186 return 0;
9187 }
9188
071436c6 9189 /* Convert from external to internal formats. */
fb514b26 9190 for (ext = edyn, entry = dynamic_section;
ba2685cc 9191 entry < dynamic_section + dynamic_nent;
fb514b26 9192 ext++, entry++)
252b5132 9193 {
66543521
AM
9194 entry->d_tag = BYTE_GET (ext->d_tag);
9195 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9196 }
9197
9198 free (edyn);
9199
9ea033b2
NC
9200 return 1;
9201}
9202
e9e44622
JJ
9203static void
9204print_dynamic_flags (bfd_vma flags)
d1133906 9205{
e9e44622 9206 int first = 1;
13ae64f3 9207
d1133906
NC
9208 while (flags)
9209 {
9210 bfd_vma flag;
9211
9212 flag = flags & - flags;
9213 flags &= ~ flag;
9214
e9e44622
JJ
9215 if (first)
9216 first = 0;
9217 else
9218 putc (' ', stdout);
13ae64f3 9219
d1133906
NC
9220 switch (flag)
9221 {
e9e44622
JJ
9222 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
9223 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
9224 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
9225 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
9226 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 9227 default: fputs (_("unknown"), stdout); break;
d1133906
NC
9228 }
9229 }
e9e44622 9230 puts ("");
d1133906
NC
9231}
9232
b2d38a17
NC
9233/* Parse and display the contents of the dynamic section. */
9234
9ea033b2 9235static int
2cf0635d 9236process_dynamic_section (FILE * file)
9ea033b2 9237{
2cf0635d 9238 Elf_Internal_Dyn * entry;
9ea033b2
NC
9239
9240 if (dynamic_size == 0)
9241 {
9242 if (do_dynamic)
b2d38a17 9243 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
9244
9245 return 1;
9246 }
9247
9248 if (is_32bit_elf)
9249 {
b2d38a17 9250 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
9251 return 0;
9252 }
b2d38a17 9253 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
9254 return 0;
9255
252b5132
RH
9256 /* Find the appropriate symbol table. */
9257 if (dynamic_symbols == NULL)
9258 {
86dba8ee
AM
9259 for (entry = dynamic_section;
9260 entry < dynamic_section + dynamic_nent;
9261 ++entry)
252b5132 9262 {
c8286bd1 9263 Elf_Internal_Shdr section;
252b5132
RH
9264
9265 if (entry->d_tag != DT_SYMTAB)
9266 continue;
9267
9268 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
9269
9270 /* Since we do not know how big the symbol table is,
9271 we default to reading in the entire file (!) and
9272 processing that. This is overkill, I know, but it
e3c8793a 9273 should work. */
d93f0186 9274 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 9275
fb52b2f4
NC
9276 if (archive_file_offset != 0)
9277 section.sh_size = archive_file_size - section.sh_offset;
9278 else
9279 {
9280 if (fseek (file, 0, SEEK_END))
591a748a 9281 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
9282
9283 section.sh_size = ftell (file) - section.sh_offset;
9284 }
252b5132 9285
9ea033b2 9286 if (is_32bit_elf)
9ad5cbcf 9287 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 9288 else
9ad5cbcf 9289 section.sh_entsize = sizeof (Elf64_External_Sym);
071436c6 9290 section.sh_name = string_table_length;
252b5132 9291
ba5cdace 9292 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 9293 if (num_dynamic_syms < 1)
252b5132
RH
9294 {
9295 error (_("Unable to determine the number of symbols to load\n"));
9296 continue;
9297 }
252b5132
RH
9298 }
9299 }
9300
9301 /* Similarly find a string table. */
9302 if (dynamic_strings == NULL)
9303 {
86dba8ee
AM
9304 for (entry = dynamic_section;
9305 entry < dynamic_section + dynamic_nent;
9306 ++entry)
252b5132
RH
9307 {
9308 unsigned long offset;
b34976b6 9309 long str_tab_len;
252b5132
RH
9310
9311 if (entry->d_tag != DT_STRTAB)
9312 continue;
9313
9314 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
9315
9316 /* Since we do not know how big the string table is,
9317 we default to reading in the entire file (!) and
9318 processing that. This is overkill, I know, but it
e3c8793a 9319 should work. */
252b5132 9320
d93f0186 9321 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
9322
9323 if (archive_file_offset != 0)
9324 str_tab_len = archive_file_size - offset;
9325 else
9326 {
9327 if (fseek (file, 0, SEEK_END))
9328 error (_("Unable to seek to end of file\n"));
9329 str_tab_len = ftell (file) - offset;
9330 }
252b5132
RH
9331
9332 if (str_tab_len < 1)
9333 {
9334 error
9335 (_("Unable to determine the length of the dynamic string table\n"));
9336 continue;
9337 }
9338
3f5e193b
NC
9339 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
9340 str_tab_len,
9341 _("dynamic string table"));
59245841 9342 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
9343 break;
9344 }
9345 }
9346
9347 /* And find the syminfo section if available. */
9348 if (dynamic_syminfo == NULL)
9349 {
3e8bba36 9350 unsigned long syminsz = 0;
252b5132 9351
86dba8ee
AM
9352 for (entry = dynamic_section;
9353 entry < dynamic_section + dynamic_nent;
9354 ++entry)
252b5132
RH
9355 {
9356 if (entry->d_tag == DT_SYMINENT)
9357 {
9358 /* Note: these braces are necessary to avoid a syntax
9359 error from the SunOS4 C compiler. */
049b0c3a
NC
9360 /* PR binutils/17531: A corrupt file can trigger this test.
9361 So do not use an assert, instead generate an error message. */
9362 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 9363 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 9364 (int) entry->d_un.d_val);
252b5132
RH
9365 }
9366 else if (entry->d_tag == DT_SYMINSZ)
9367 syminsz = entry->d_un.d_val;
9368 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
9369 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
9370 syminsz);
252b5132
RH
9371 }
9372
9373 if (dynamic_syminfo_offset != 0 && syminsz != 0)
9374 {
2cf0635d
NC
9375 Elf_External_Syminfo * extsyminfo;
9376 Elf_External_Syminfo * extsym;
9377 Elf_Internal_Syminfo * syminfo;
252b5132
RH
9378
9379 /* There is a syminfo section. Read the data. */
3f5e193b
NC
9380 extsyminfo = (Elf_External_Syminfo *)
9381 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
9382 _("symbol information"));
a6e9f9df
AM
9383 if (!extsyminfo)
9384 return 0;
252b5132 9385
3f5e193b 9386 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
9387 if (dynamic_syminfo == NULL)
9388 {
8b73c356
NC
9389 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
9390 (unsigned long) syminsz);
252b5132
RH
9391 return 0;
9392 }
9393
9394 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
9395 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
9396 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
9397 ++syminfo, ++extsym)
252b5132 9398 {
86dba8ee
AM
9399 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
9400 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
9401 }
9402
9403 free (extsyminfo);
9404 }
9405 }
9406
9407 if (do_dynamic && dynamic_addr)
8b73c356
NC
9408 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
9409 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
9410 if (do_dynamic)
9411 printf (_(" Tag Type Name/Value\n"));
9412
86dba8ee
AM
9413 for (entry = dynamic_section;
9414 entry < dynamic_section + dynamic_nent;
9415 entry++)
252b5132
RH
9416 {
9417 if (do_dynamic)
f7a99963 9418 {
2cf0635d 9419 const char * dtype;
e699b9ff 9420
f7a99963
NC
9421 putchar (' ');
9422 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
9423 dtype = get_dynamic_type (entry->d_tag);
9424 printf (" (%s)%*s", dtype,
9425 ((is_32bit_elf ? 27 : 19)
9426 - (int) strlen (dtype)),
f7a99963
NC
9427 " ");
9428 }
252b5132
RH
9429
9430 switch (entry->d_tag)
9431 {
d1133906
NC
9432 case DT_FLAGS:
9433 if (do_dynamic)
e9e44622 9434 print_dynamic_flags (entry->d_un.d_val);
d1133906 9435 break;
76da6bbe 9436
252b5132
RH
9437 case DT_AUXILIARY:
9438 case DT_FILTER:
019148e4
L
9439 case DT_CONFIG:
9440 case DT_DEPAUDIT:
9441 case DT_AUDIT:
252b5132
RH
9442 if (do_dynamic)
9443 {
019148e4 9444 switch (entry->d_tag)
b34976b6 9445 {
019148e4
L
9446 case DT_AUXILIARY:
9447 printf (_("Auxiliary library"));
9448 break;
9449
9450 case DT_FILTER:
9451 printf (_("Filter library"));
9452 break;
9453
b34976b6 9454 case DT_CONFIG:
019148e4
L
9455 printf (_("Configuration file"));
9456 break;
9457
9458 case DT_DEPAUDIT:
9459 printf (_("Dependency audit library"));
9460 break;
9461
9462 case DT_AUDIT:
9463 printf (_("Audit library"));
9464 break;
9465 }
252b5132 9466
d79b3d50
NC
9467 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9468 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 9469 else
f7a99963
NC
9470 {
9471 printf (": ");
9472 print_vma (entry->d_un.d_val, PREFIX_HEX);
9473 putchar ('\n');
9474 }
252b5132
RH
9475 }
9476 break;
9477
dcefbbbd 9478 case DT_FEATURE:
252b5132
RH
9479 if (do_dynamic)
9480 {
9481 printf (_("Flags:"));
86f55779 9482
252b5132
RH
9483 if (entry->d_un.d_val == 0)
9484 printf (_(" None\n"));
9485 else
9486 {
9487 unsigned long int val = entry->d_un.d_val;
86f55779 9488
252b5132
RH
9489 if (val & DTF_1_PARINIT)
9490 {
9491 printf (" PARINIT");
9492 val ^= DTF_1_PARINIT;
9493 }
dcefbbbd
L
9494 if (val & DTF_1_CONFEXP)
9495 {
9496 printf (" CONFEXP");
9497 val ^= DTF_1_CONFEXP;
9498 }
252b5132
RH
9499 if (val != 0)
9500 printf (" %lx", val);
9501 puts ("");
9502 }
9503 }
9504 break;
9505
9506 case DT_POSFLAG_1:
9507 if (do_dynamic)
9508 {
9509 printf (_("Flags:"));
86f55779 9510
252b5132
RH
9511 if (entry->d_un.d_val == 0)
9512 printf (_(" None\n"));
9513 else
9514 {
9515 unsigned long int val = entry->d_un.d_val;
86f55779 9516
252b5132
RH
9517 if (val & DF_P1_LAZYLOAD)
9518 {
9519 printf (" LAZYLOAD");
9520 val ^= DF_P1_LAZYLOAD;
9521 }
9522 if (val & DF_P1_GROUPPERM)
9523 {
9524 printf (" GROUPPERM");
9525 val ^= DF_P1_GROUPPERM;
9526 }
9527 if (val != 0)
9528 printf (" %lx", val);
9529 puts ("");
9530 }
9531 }
9532 break;
9533
9534 case DT_FLAGS_1:
9535 if (do_dynamic)
9536 {
9537 printf (_("Flags:"));
9538 if (entry->d_un.d_val == 0)
9539 printf (_(" None\n"));
9540 else
9541 {
9542 unsigned long int val = entry->d_un.d_val;
86f55779 9543
252b5132
RH
9544 if (val & DF_1_NOW)
9545 {
9546 printf (" NOW");
9547 val ^= DF_1_NOW;
9548 }
9549 if (val & DF_1_GLOBAL)
9550 {
9551 printf (" GLOBAL");
9552 val ^= DF_1_GLOBAL;
9553 }
9554 if (val & DF_1_GROUP)
9555 {
9556 printf (" GROUP");
9557 val ^= DF_1_GROUP;
9558 }
9559 if (val & DF_1_NODELETE)
9560 {
9561 printf (" NODELETE");
9562 val ^= DF_1_NODELETE;
9563 }
9564 if (val & DF_1_LOADFLTR)
9565 {
9566 printf (" LOADFLTR");
9567 val ^= DF_1_LOADFLTR;
9568 }
9569 if (val & DF_1_INITFIRST)
9570 {
9571 printf (" INITFIRST");
9572 val ^= DF_1_INITFIRST;
9573 }
9574 if (val & DF_1_NOOPEN)
9575 {
9576 printf (" NOOPEN");
9577 val ^= DF_1_NOOPEN;
9578 }
9579 if (val & DF_1_ORIGIN)
9580 {
9581 printf (" ORIGIN");
9582 val ^= DF_1_ORIGIN;
9583 }
9584 if (val & DF_1_DIRECT)
9585 {
9586 printf (" DIRECT");
9587 val ^= DF_1_DIRECT;
9588 }
9589 if (val & DF_1_TRANS)
9590 {
9591 printf (" TRANS");
9592 val ^= DF_1_TRANS;
9593 }
9594 if (val & DF_1_INTERPOSE)
9595 {
9596 printf (" INTERPOSE");
9597 val ^= DF_1_INTERPOSE;
9598 }
f7db6139 9599 if (val & DF_1_NODEFLIB)
dcefbbbd 9600 {
f7db6139
L
9601 printf (" NODEFLIB");
9602 val ^= DF_1_NODEFLIB;
dcefbbbd
L
9603 }
9604 if (val & DF_1_NODUMP)
9605 {
9606 printf (" NODUMP");
9607 val ^= DF_1_NODUMP;
9608 }
34b60028 9609 if (val & DF_1_CONFALT)
dcefbbbd 9610 {
34b60028
L
9611 printf (" CONFALT");
9612 val ^= DF_1_CONFALT;
9613 }
9614 if (val & DF_1_ENDFILTEE)
9615 {
9616 printf (" ENDFILTEE");
9617 val ^= DF_1_ENDFILTEE;
9618 }
9619 if (val & DF_1_DISPRELDNE)
9620 {
9621 printf (" DISPRELDNE");
9622 val ^= DF_1_DISPRELDNE;
9623 }
9624 if (val & DF_1_DISPRELPND)
9625 {
9626 printf (" DISPRELPND");
9627 val ^= DF_1_DISPRELPND;
9628 }
9629 if (val & DF_1_NODIRECT)
9630 {
9631 printf (" NODIRECT");
9632 val ^= DF_1_NODIRECT;
9633 }
9634 if (val & DF_1_IGNMULDEF)
9635 {
9636 printf (" IGNMULDEF");
9637 val ^= DF_1_IGNMULDEF;
9638 }
9639 if (val & DF_1_NOKSYMS)
9640 {
9641 printf (" NOKSYMS");
9642 val ^= DF_1_NOKSYMS;
9643 }
9644 if (val & DF_1_NOHDR)
9645 {
9646 printf (" NOHDR");
9647 val ^= DF_1_NOHDR;
9648 }
9649 if (val & DF_1_EDITED)
9650 {
9651 printf (" EDITED");
9652 val ^= DF_1_EDITED;
9653 }
9654 if (val & DF_1_NORELOC)
9655 {
9656 printf (" NORELOC");
9657 val ^= DF_1_NORELOC;
9658 }
9659 if (val & DF_1_SYMINTPOSE)
9660 {
9661 printf (" SYMINTPOSE");
9662 val ^= DF_1_SYMINTPOSE;
9663 }
9664 if (val & DF_1_GLOBAUDIT)
9665 {
9666 printf (" GLOBAUDIT");
9667 val ^= DF_1_GLOBAUDIT;
9668 }
9669 if (val & DF_1_SINGLETON)
9670 {
9671 printf (" SINGLETON");
9672 val ^= DF_1_SINGLETON;
dcefbbbd 9673 }
5c383f02
RO
9674 if (val & DF_1_STUB)
9675 {
9676 printf (" STUB");
9677 val ^= DF_1_STUB;
9678 }
9679 if (val & DF_1_PIE)
9680 {
9681 printf (" PIE");
9682 val ^= DF_1_PIE;
9683 }
252b5132
RH
9684 if (val != 0)
9685 printf (" %lx", val);
9686 puts ("");
9687 }
9688 }
9689 break;
9690
9691 case DT_PLTREL:
566b0d53 9692 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
9693 if (do_dynamic)
9694 puts (get_dynamic_type (entry->d_un.d_val));
9695 break;
9696
9697 case DT_NULL :
9698 case DT_NEEDED :
9699 case DT_PLTGOT :
9700 case DT_HASH :
9701 case DT_STRTAB :
9702 case DT_SYMTAB :
9703 case DT_RELA :
9704 case DT_INIT :
9705 case DT_FINI :
9706 case DT_SONAME :
9707 case DT_RPATH :
9708 case DT_SYMBOLIC:
9709 case DT_REL :
9710 case DT_DEBUG :
9711 case DT_TEXTREL :
9712 case DT_JMPREL :
019148e4 9713 case DT_RUNPATH :
252b5132
RH
9714 dynamic_info[entry->d_tag] = entry->d_un.d_val;
9715
9716 if (do_dynamic)
9717 {
2cf0635d 9718 char * name;
252b5132 9719
d79b3d50
NC
9720 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9721 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9722 else
d79b3d50 9723 name = NULL;
252b5132
RH
9724
9725 if (name)
9726 {
9727 switch (entry->d_tag)
9728 {
9729 case DT_NEEDED:
9730 printf (_("Shared library: [%s]"), name);
9731
18bd398b 9732 if (streq (name, program_interpreter))
f7a99963 9733 printf (_(" program interpreter"));
252b5132
RH
9734 break;
9735
9736 case DT_SONAME:
f7a99963 9737 printf (_("Library soname: [%s]"), name);
252b5132
RH
9738 break;
9739
9740 case DT_RPATH:
f7a99963 9741 printf (_("Library rpath: [%s]"), name);
252b5132
RH
9742 break;
9743
019148e4
L
9744 case DT_RUNPATH:
9745 printf (_("Library runpath: [%s]"), name);
9746 break;
9747
252b5132 9748 default:
f7a99963
NC
9749 print_vma (entry->d_un.d_val, PREFIX_HEX);
9750 break;
252b5132
RH
9751 }
9752 }
9753 else
f7a99963
NC
9754 print_vma (entry->d_un.d_val, PREFIX_HEX);
9755
9756 putchar ('\n');
252b5132
RH
9757 }
9758 break;
9759
9760 case DT_PLTRELSZ:
9761 case DT_RELASZ :
9762 case DT_STRSZ :
9763 case DT_RELSZ :
9764 case DT_RELAENT :
9765 case DT_SYMENT :
9766 case DT_RELENT :
566b0d53 9767 dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 9768 /* Fall through. */
252b5132
RH
9769 case DT_PLTPADSZ:
9770 case DT_MOVEENT :
9771 case DT_MOVESZ :
9772 case DT_INIT_ARRAYSZ:
9773 case DT_FINI_ARRAYSZ:
047b2264
JJ
9774 case DT_GNU_CONFLICTSZ:
9775 case DT_GNU_LIBLISTSZ:
252b5132 9776 if (do_dynamic)
f7a99963
NC
9777 {
9778 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 9779 printf (_(" (bytes)\n"));
f7a99963 9780 }
252b5132
RH
9781 break;
9782
9783 case DT_VERDEFNUM:
9784 case DT_VERNEEDNUM:
9785 case DT_RELACOUNT:
9786 case DT_RELCOUNT:
9787 if (do_dynamic)
f7a99963
NC
9788 {
9789 print_vma (entry->d_un.d_val, UNSIGNED);
9790 putchar ('\n');
9791 }
252b5132
RH
9792 break;
9793
9794 case DT_SYMINSZ:
9795 case DT_SYMINENT:
9796 case DT_SYMINFO:
9797 case DT_USED:
9798 case DT_INIT_ARRAY:
9799 case DT_FINI_ARRAY:
9800 if (do_dynamic)
9801 {
d79b3d50
NC
9802 if (entry->d_tag == DT_USED
9803 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 9804 {
2cf0635d 9805 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9806
b34976b6 9807 if (*name)
252b5132
RH
9808 {
9809 printf (_("Not needed object: [%s]\n"), name);
9810 break;
9811 }
9812 }
103f02d3 9813
f7a99963
NC
9814 print_vma (entry->d_un.d_val, PREFIX_HEX);
9815 putchar ('\n');
252b5132
RH
9816 }
9817 break;
9818
9819 case DT_BIND_NOW:
9820 /* The value of this entry is ignored. */
35b1837e
AM
9821 if (do_dynamic)
9822 putchar ('\n');
252b5132 9823 break;
103f02d3 9824
047b2264
JJ
9825 case DT_GNU_PRELINKED:
9826 if (do_dynamic)
9827 {
2cf0635d 9828 struct tm * tmp;
91d6fa6a 9829 time_t atime = entry->d_un.d_val;
047b2264 9830
91d6fa6a 9831 tmp = gmtime (&atime);
071436c6
NC
9832 /* PR 17533 file: 041-1244816-0.004. */
9833 if (tmp == NULL)
5a2cbcf4
L
9834 printf (_("<corrupt time val: %lx"),
9835 (unsigned long) atime);
071436c6
NC
9836 else
9837 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
9838 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9839 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
9840
9841 }
9842 break;
9843
fdc90cb4
JJ
9844 case DT_GNU_HASH:
9845 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
9846 if (do_dynamic)
9847 {
9848 print_vma (entry->d_un.d_val, PREFIX_HEX);
9849 putchar ('\n');
9850 }
9851 break;
9852
252b5132
RH
9853 default:
9854 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 9855 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
9856 entry->d_un.d_val;
9857
9858 if (do_dynamic)
9859 {
9860 switch (elf_header.e_machine)
9861 {
9862 case EM_MIPS:
4fe85591 9863 case EM_MIPS_RS3_LE:
b2d38a17 9864 dynamic_section_mips_val (entry);
252b5132 9865 break;
103f02d3 9866 case EM_PARISC:
b2d38a17 9867 dynamic_section_parisc_val (entry);
103f02d3 9868 break;
ecc51f48 9869 case EM_IA_64:
b2d38a17 9870 dynamic_section_ia64_val (entry);
ecc51f48 9871 break;
252b5132 9872 default:
f7a99963
NC
9873 print_vma (entry->d_un.d_val, PREFIX_HEX);
9874 putchar ('\n');
252b5132
RH
9875 }
9876 }
9877 break;
9878 }
9879 }
9880
9881 return 1;
9882}
9883
9884static char *
d3ba0551 9885get_ver_flags (unsigned int flags)
252b5132 9886{
b34976b6 9887 static char buff[32];
252b5132
RH
9888
9889 buff[0] = 0;
9890
9891 if (flags == 0)
9892 return _("none");
9893
9894 if (flags & VER_FLG_BASE)
9895 strcat (buff, "BASE ");
9896
9897 if (flags & VER_FLG_WEAK)
9898 {
9899 if (flags & VER_FLG_BASE)
9900 strcat (buff, "| ");
9901
9902 strcat (buff, "WEAK ");
9903 }
9904
44ec90b9
RO
9905 if (flags & VER_FLG_INFO)
9906 {
9907 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
9908 strcat (buff, "| ");
9909
9910 strcat (buff, "INFO ");
9911 }
9912
9913 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 9914 strcat (buff, _("| <unknown>"));
252b5132
RH
9915
9916 return buff;
9917}
9918
9919/* Display the contents of the version sections. */
98fb390a 9920
252b5132 9921static int
2cf0635d 9922process_version_sections (FILE * file)
252b5132 9923{
2cf0635d 9924 Elf_Internal_Shdr * section;
b34976b6
AM
9925 unsigned i;
9926 int found = 0;
252b5132
RH
9927
9928 if (! do_version)
9929 return 1;
9930
9931 for (i = 0, section = section_headers;
9932 i < elf_header.e_shnum;
b34976b6 9933 i++, section++)
252b5132
RH
9934 {
9935 switch (section->sh_type)
9936 {
9937 case SHT_GNU_verdef:
9938 {
2cf0635d 9939 Elf_External_Verdef * edefs;
b34976b6
AM
9940 unsigned int idx;
9941 unsigned int cnt;
2cf0635d 9942 char * endbuf;
252b5132
RH
9943
9944 found = 1;
9945
74e1a04b
NC
9946 printf (_("\nVersion definition section '%s' contains %u entries:\n"),
9947 printable_section_name (section),
9948 section->sh_info);
252b5132
RH
9949
9950 printf (_(" Addr: 0x"));
9951 printf_vma (section->sh_addr);
74e1a04b 9952 printf (_(" Offset: %#08lx Link: %u (%s)"),
1b228002 9953 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9954 printable_section_name_from_index (section->sh_link));
252b5132 9955
3f5e193b
NC
9956 edefs = (Elf_External_Verdef *)
9957 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
9958 _("version definition section"));
a6e9f9df
AM
9959 if (!edefs)
9960 break;
59245841 9961 endbuf = (char *) edefs + section->sh_size;
252b5132 9962
b34976b6 9963 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 9964 {
2cf0635d
NC
9965 char * vstart;
9966 Elf_External_Verdef * edef;
b34976b6 9967 Elf_Internal_Verdef ent;
2cf0635d 9968 Elf_External_Verdaux * eaux;
b34976b6
AM
9969 Elf_Internal_Verdaux aux;
9970 int j;
9971 int isum;
103f02d3 9972
222c2bf0 9973 /* Check for very large indices. */
7e26601c 9974 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
9975 break;
9976
252b5132 9977 vstart = ((char *) edefs) + idx;
54806181
AM
9978 if (vstart + sizeof (*edef) > endbuf)
9979 break;
252b5132
RH
9980
9981 edef = (Elf_External_Verdef *) vstart;
9982
9983 ent.vd_version = BYTE_GET (edef->vd_version);
9984 ent.vd_flags = BYTE_GET (edef->vd_flags);
9985 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
9986 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
9987 ent.vd_hash = BYTE_GET (edef->vd_hash);
9988 ent.vd_aux = BYTE_GET (edef->vd_aux);
9989 ent.vd_next = BYTE_GET (edef->vd_next);
9990
9991 printf (_(" %#06x: Rev: %d Flags: %s"),
9992 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
9993
9994 printf (_(" Index: %d Cnt: %d "),
9995 ent.vd_ndx, ent.vd_cnt);
9996
dd24e3da 9997 /* Check for overflow. */
7e26601c 9998 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
9999 break;
10000
252b5132
RH
10001 vstart += ent.vd_aux;
10002
10003 eaux = (Elf_External_Verdaux *) vstart;
10004
10005 aux.vda_name = BYTE_GET (eaux->vda_name);
10006 aux.vda_next = BYTE_GET (eaux->vda_next);
10007
d79b3d50
NC
10008 if (VALID_DYNAMIC_NAME (aux.vda_name))
10009 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
10010 else
10011 printf (_("Name index: %ld\n"), aux.vda_name);
10012
10013 isum = idx + ent.vd_aux;
10014
b34976b6 10015 for (j = 1; j < ent.vd_cnt; j++)
252b5132 10016 {
dd24e3da 10017 /* Check for overflow. */
7e26601c 10018 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
10019 break;
10020
252b5132
RH
10021 isum += aux.vda_next;
10022 vstart += aux.vda_next;
10023
10024 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
10025 if (vstart + sizeof (*eaux) > endbuf)
10026 break;
252b5132
RH
10027
10028 aux.vda_name = BYTE_GET (eaux->vda_name);
10029 aux.vda_next = BYTE_GET (eaux->vda_next);
10030
d79b3d50 10031 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 10032 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 10033 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
10034 else
10035 printf (_(" %#06x: Parent %d, name index: %ld\n"),
10036 isum, j, aux.vda_name);
10037 }
dd24e3da 10038
54806181
AM
10039 if (j < ent.vd_cnt)
10040 printf (_(" Version def aux past end of section\n"));
252b5132 10041
5d921cbd
NC
10042 /* PR 17531: file: id:000001,src:000172+005151,op:splice,rep:2. */
10043 if (idx + ent.vd_next <= idx)
10044 break;
10045
252b5132
RH
10046 idx += ent.vd_next;
10047 }
dd24e3da 10048
54806181
AM
10049 if (cnt < section->sh_info)
10050 printf (_(" Version definition past end of section\n"));
252b5132
RH
10051
10052 free (edefs);
10053 }
10054 break;
103f02d3 10055
252b5132
RH
10056 case SHT_GNU_verneed:
10057 {
2cf0635d 10058 Elf_External_Verneed * eneed;
b34976b6
AM
10059 unsigned int idx;
10060 unsigned int cnt;
2cf0635d 10061 char * endbuf;
252b5132
RH
10062
10063 found = 1;
10064
72de5009 10065 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
74e1a04b 10066 printable_section_name (section), section->sh_info);
252b5132
RH
10067
10068 printf (_(" Addr: 0x"));
10069 printf_vma (section->sh_addr);
72de5009 10070 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10071 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 10072 printable_section_name_from_index (section->sh_link));
252b5132 10073
3f5e193b
NC
10074 eneed = (Elf_External_Verneed *) get_data (NULL, file,
10075 section->sh_offset, 1,
10076 section->sh_size,
9cf03b7e 10077 _("Version Needs section"));
a6e9f9df
AM
10078 if (!eneed)
10079 break;
59245841 10080 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
10081
10082 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
10083 {
2cf0635d 10084 Elf_External_Verneed * entry;
b34976b6
AM
10085 Elf_Internal_Verneed ent;
10086 int j;
10087 int isum;
2cf0635d 10088 char * vstart;
252b5132 10089
7e26601c 10090 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
10091 break;
10092
252b5132 10093 vstart = ((char *) eneed) + idx;
54806181
AM
10094 if (vstart + sizeof (*entry) > endbuf)
10095 break;
252b5132
RH
10096
10097 entry = (Elf_External_Verneed *) vstart;
10098
10099 ent.vn_version = BYTE_GET (entry->vn_version);
10100 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
10101 ent.vn_file = BYTE_GET (entry->vn_file);
10102 ent.vn_aux = BYTE_GET (entry->vn_aux);
10103 ent.vn_next = BYTE_GET (entry->vn_next);
10104
10105 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
10106
d79b3d50
NC
10107 if (VALID_DYNAMIC_NAME (ent.vn_file))
10108 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
10109 else
10110 printf (_(" File: %lx"), ent.vn_file);
10111
10112 printf (_(" Cnt: %d\n"), ent.vn_cnt);
10113
dd24e3da 10114 /* Check for overflow. */
7e26601c 10115 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 10116 break;
252b5132
RH
10117 vstart += ent.vn_aux;
10118
10119 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
10120 {
2cf0635d 10121 Elf_External_Vernaux * eaux;
b34976b6 10122 Elf_Internal_Vernaux aux;
252b5132 10123
54806181
AM
10124 if (vstart + sizeof (*eaux) > endbuf)
10125 break;
252b5132
RH
10126 eaux = (Elf_External_Vernaux *) vstart;
10127
10128 aux.vna_hash = BYTE_GET (eaux->vna_hash);
10129 aux.vna_flags = BYTE_GET (eaux->vna_flags);
10130 aux.vna_other = BYTE_GET (eaux->vna_other);
10131 aux.vna_name = BYTE_GET (eaux->vna_name);
10132 aux.vna_next = BYTE_GET (eaux->vna_next);
10133
d79b3d50 10134 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 10135 printf (_(" %#06x: Name: %s"),
d79b3d50 10136 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 10137 else
ecc2063b 10138 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
10139 isum, aux.vna_name);
10140
10141 printf (_(" Flags: %s Version: %d\n"),
10142 get_ver_flags (aux.vna_flags), aux.vna_other);
10143
dd24e3da 10144 /* Check for overflow. */
53774b7e
NC
10145 if (aux.vna_next > (size_t) (endbuf - vstart)
10146 || (aux.vna_next == 0 && j < ent.vn_cnt - 1))
10147 {
10148 warn (_("Invalid vna_next field of %lx\n"),
10149 aux.vna_next);
10150 j = ent.vn_cnt;
10151 break;
10152 }
252b5132
RH
10153 isum += aux.vna_next;
10154 vstart += aux.vna_next;
10155 }
9cf03b7e 10156
54806181 10157 if (j < ent.vn_cnt)
9cf03b7e 10158 warn (_("Missing Version Needs auxillary information\n"));
252b5132 10159
bcf83b2a 10160 if (ent.vn_next == 0 && cnt < section->sh_info - 1)
c24cf8b6
NC
10161 {
10162 warn (_("Corrupt Version Needs structure - offset to next structure is zero with entries still left to be processed\n"));
10163 cnt = section->sh_info;
10164 break;
10165 }
252b5132
RH
10166 idx += ent.vn_next;
10167 }
9cf03b7e 10168
54806181 10169 if (cnt < section->sh_info)
9cf03b7e 10170 warn (_("Missing Version Needs information\n"));
103f02d3 10171
252b5132
RH
10172 free (eneed);
10173 }
10174 break;
10175
10176 case SHT_GNU_versym:
10177 {
2cf0635d 10178 Elf_Internal_Shdr * link_section;
8b73c356
NC
10179 size_t total;
10180 unsigned int cnt;
2cf0635d
NC
10181 unsigned char * edata;
10182 unsigned short * data;
10183 char * strtab;
10184 Elf_Internal_Sym * symbols;
10185 Elf_Internal_Shdr * string_sec;
ba5cdace 10186 unsigned long num_syms;
d3ba0551 10187 long off;
252b5132 10188
4fbb74a6 10189 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
10190 break;
10191
4fbb74a6 10192 link_section = section_headers + section->sh_link;
08d8fa11 10193 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 10194
4fbb74a6 10195 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
10196 break;
10197
252b5132
RH
10198 found = 1;
10199
ba5cdace 10200 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
10201 if (symbols == NULL)
10202 break;
252b5132 10203
4fbb74a6 10204 string_sec = section_headers + link_section->sh_link;
252b5132 10205
3f5e193b
NC
10206 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
10207 string_sec->sh_size,
10208 _("version string table"));
a6e9f9df 10209 if (!strtab)
0429c154
MS
10210 {
10211 free (symbols);
10212 break;
10213 }
252b5132 10214
8b73c356
NC
10215 printf (_("\nVersion symbols section '%s' contains %lu entries:\n"),
10216 printable_section_name (section), (unsigned long) total);
252b5132
RH
10217
10218 printf (_(" Addr: "));
10219 printf_vma (section->sh_addr);
72de5009 10220 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10221 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 10222 printable_section_name (link_section));
252b5132 10223
d3ba0551
AM
10224 off = offset_from_vma (file,
10225 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10226 total * sizeof (short));
3f5e193b
NC
10227 edata = (unsigned char *) get_data (NULL, file, off, total,
10228 sizeof (short),
10229 _("version symbol data"));
a6e9f9df
AM
10230 if (!edata)
10231 {
10232 free (strtab);
0429c154 10233 free (symbols);
a6e9f9df
AM
10234 break;
10235 }
252b5132 10236
3f5e193b 10237 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
10238
10239 for (cnt = total; cnt --;)
b34976b6
AM
10240 data[cnt] = byte_get (edata + cnt * sizeof (short),
10241 sizeof (short));
252b5132
RH
10242
10243 free (edata);
10244
10245 for (cnt = 0; cnt < total; cnt += 4)
10246 {
10247 int j, nn;
ab273396
AM
10248 char *name;
10249 char *invalid = _("*invalid*");
252b5132
RH
10250
10251 printf (" %03x:", cnt);
10252
10253 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 10254 switch (data[cnt + j])
252b5132
RH
10255 {
10256 case 0:
10257 fputs (_(" 0 (*local*) "), stdout);
10258 break;
10259
10260 case 1:
10261 fputs (_(" 1 (*global*) "), stdout);
10262 break;
10263
10264 default:
c244d050
NC
10265 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
10266 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 10267
dd24e3da 10268 /* If this index value is greater than the size of the symbols
ba5cdace
NC
10269 array, break to avoid an out-of-bounds read. */
10270 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
10271 {
10272 warn (_("invalid index into symbol array\n"));
10273 break;
10274 }
10275
ab273396
AM
10276 name = NULL;
10277 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 10278 {
b34976b6
AM
10279 Elf_Internal_Verneed ivn;
10280 unsigned long offset;
252b5132 10281
d93f0186
NC
10282 offset = offset_from_vma
10283 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
10284 sizeof (Elf_External_Verneed));
252b5132 10285
b34976b6 10286 do
252b5132 10287 {
b34976b6
AM
10288 Elf_Internal_Vernaux ivna;
10289 Elf_External_Verneed evn;
10290 Elf_External_Vernaux evna;
10291 unsigned long a_off;
252b5132 10292
59245841
NC
10293 if (get_data (&evn, file, offset, sizeof (evn), 1,
10294 _("version need")) == NULL)
10295 break;
0b4362b0 10296
252b5132
RH
10297 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10298 ivn.vn_next = BYTE_GET (evn.vn_next);
10299
10300 a_off = offset + ivn.vn_aux;
10301
10302 do
10303 {
59245841
NC
10304 if (get_data (&evna, file, a_off, sizeof (evna),
10305 1, _("version need aux (2)")) == NULL)
10306 {
10307 ivna.vna_next = 0;
10308 ivna.vna_other = 0;
10309 }
10310 else
10311 {
10312 ivna.vna_next = BYTE_GET (evna.vna_next);
10313 ivna.vna_other = BYTE_GET (evna.vna_other);
10314 }
252b5132
RH
10315
10316 a_off += ivna.vna_next;
10317 }
b34976b6 10318 while (ivna.vna_other != data[cnt + j]
252b5132
RH
10319 && ivna.vna_next != 0);
10320
b34976b6 10321 if (ivna.vna_other == data[cnt + j])
252b5132
RH
10322 {
10323 ivna.vna_name = BYTE_GET (evna.vna_name);
10324
54806181 10325 if (ivna.vna_name >= string_sec->sh_size)
ab273396 10326 name = invalid;
54806181
AM
10327 else
10328 name = strtab + ivna.vna_name;
252b5132
RH
10329 break;
10330 }
10331
10332 offset += ivn.vn_next;
10333 }
10334 while (ivn.vn_next);
10335 }
00d93f34 10336
ab273396 10337 if (data[cnt + j] != 0x8001
b34976b6 10338 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 10339 {
b34976b6
AM
10340 Elf_Internal_Verdef ivd;
10341 Elf_External_Verdef evd;
10342 unsigned long offset;
252b5132 10343
d93f0186
NC
10344 offset = offset_from_vma
10345 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10346 sizeof evd);
252b5132
RH
10347
10348 do
10349 {
59245841
NC
10350 if (get_data (&evd, file, offset, sizeof (evd), 1,
10351 _("version def")) == NULL)
10352 {
10353 ivd.vd_next = 0;
948f632f 10354 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
10355 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
10356 break;
59245841
NC
10357 }
10358 else
10359 {
10360 ivd.vd_next = BYTE_GET (evd.vd_next);
10361 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10362 }
252b5132
RH
10363
10364 offset += ivd.vd_next;
10365 }
c244d050 10366 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
10367 && ivd.vd_next != 0);
10368
c244d050 10369 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 10370 {
b34976b6
AM
10371 Elf_External_Verdaux evda;
10372 Elf_Internal_Verdaux ivda;
252b5132
RH
10373
10374 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10375
59245841
NC
10376 if (get_data (&evda, file,
10377 offset - ivd.vd_next + ivd.vd_aux,
10378 sizeof (evda), 1,
10379 _("version def aux")) == NULL)
10380 break;
252b5132
RH
10381
10382 ivda.vda_name = BYTE_GET (evda.vda_name);
10383
54806181 10384 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
10385 name = invalid;
10386 else if (name != NULL && name != invalid)
10387 name = _("*both*");
54806181
AM
10388 else
10389 name = strtab + ivda.vda_name;
252b5132
RH
10390 }
10391 }
ab273396
AM
10392 if (name != NULL)
10393 nn += printf ("(%s%-*s",
10394 name,
10395 12 - (int) strlen (name),
10396 ")");
252b5132
RH
10397
10398 if (nn < 18)
10399 printf ("%*c", 18 - nn, ' ');
10400 }
10401
10402 putchar ('\n');
10403 }
10404
10405 free (data);
10406 free (strtab);
10407 free (symbols);
10408 }
10409 break;
103f02d3 10410
252b5132
RH
10411 default:
10412 break;
10413 }
10414 }
10415
10416 if (! found)
10417 printf (_("\nNo version information found in this file.\n"));
10418
10419 return 1;
10420}
10421
d1133906 10422static const char *
d3ba0551 10423get_symbol_binding (unsigned int binding)
252b5132 10424{
b34976b6 10425 static char buff[32];
252b5132
RH
10426
10427 switch (binding)
10428 {
b34976b6
AM
10429 case STB_LOCAL: return "LOCAL";
10430 case STB_GLOBAL: return "GLOBAL";
10431 case STB_WEAK: return "WEAK";
252b5132
RH
10432 default:
10433 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
10434 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
10435 binding);
252b5132 10436 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
10437 {
10438 if (binding == STB_GNU_UNIQUE
9c55345c
TS
10439 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
10440 /* GNU is still using the default value 0. */
3e7a7d11
NC
10441 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
10442 return "UNIQUE";
10443 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
10444 }
252b5132 10445 else
e9e44622 10446 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
10447 return buff;
10448 }
10449}
10450
d1133906 10451static const char *
d3ba0551 10452get_symbol_type (unsigned int type)
252b5132 10453{
b34976b6 10454 static char buff[32];
252b5132
RH
10455
10456 switch (type)
10457 {
b34976b6
AM
10458 case STT_NOTYPE: return "NOTYPE";
10459 case STT_OBJECT: return "OBJECT";
10460 case STT_FUNC: return "FUNC";
10461 case STT_SECTION: return "SECTION";
10462 case STT_FILE: return "FILE";
10463 case STT_COMMON: return "COMMON";
10464 case STT_TLS: return "TLS";
15ab5209
DB
10465 case STT_RELC: return "RELC";
10466 case STT_SRELC: return "SRELC";
252b5132
RH
10467 default:
10468 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 10469 {
3510a7b8
NC
10470 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
10471 return "THUMB_FUNC";
103f02d3 10472
351b4b40 10473 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
10474 return "REGISTER";
10475
10476 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
10477 return "PARISC_MILLI";
10478
e9e44622 10479 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 10480 }
252b5132 10481 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
10482 {
10483 if (elf_header.e_machine == EM_PARISC)
10484 {
10485 if (type == STT_HP_OPAQUE)
10486 return "HP_OPAQUE";
10487 if (type == STT_HP_STUB)
10488 return "HP_STUB";
10489 }
10490
d8045f23 10491 if (type == STT_GNU_IFUNC
9c55345c 10492 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 10493 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 10494 /* GNU is still using the default value 0. */
d8045f23
NC
10495 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
10496 return "IFUNC";
10497
e9e44622 10498 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 10499 }
252b5132 10500 else
e9e44622 10501 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
10502 return buff;
10503 }
10504}
10505
d1133906 10506static const char *
d3ba0551 10507get_symbol_visibility (unsigned int visibility)
d1133906
NC
10508{
10509 switch (visibility)
10510 {
b34976b6
AM
10511 case STV_DEFAULT: return "DEFAULT";
10512 case STV_INTERNAL: return "INTERNAL";
10513 case STV_HIDDEN: return "HIDDEN";
d1133906 10514 case STV_PROTECTED: return "PROTECTED";
bee0ee85
NC
10515 default:
10516 error (_("Unrecognized visibility value: %u"), visibility);
10517 return _("<unknown>");
d1133906
NC
10518 }
10519}
10520
fd85a6a1
NC
10521static const char *
10522get_solaris_symbol_visibility (unsigned int visibility)
10523{
10524 switch (visibility)
10525 {
10526 case 4: return "EXPORTED";
10527 case 5: return "SINGLETON";
10528 case 6: return "ELIMINATE";
10529 default: return get_symbol_visibility (visibility);
10530 }
10531}
10532
5e2b0d47
NC
10533static const char *
10534get_mips_symbol_other (unsigned int other)
10535{
10536 switch (other)
10537 {
df58fc94
RS
10538 case STO_OPTIONAL:
10539 return "OPTIONAL";
10540 case STO_MIPS_PLT:
10541 return "MIPS PLT";
10542 case STO_MIPS_PIC:
10543 return "MIPS PIC";
10544 case STO_MICROMIPS:
10545 return "MICROMIPS";
10546 case STO_MICROMIPS | STO_MIPS_PIC:
10547 return "MICROMIPS, MIPS PIC";
10548 case STO_MIPS16:
10549 return "MIPS16";
10550 default:
10551 return NULL;
5e2b0d47
NC
10552 }
10553}
10554
28f997cf
TG
10555static const char *
10556get_ia64_symbol_other (unsigned int other)
10557{
10558 if (is_ia64_vms ())
10559 {
10560 static char res[32];
10561
10562 res[0] = 0;
10563
10564 /* Function types is for images and .STB files only. */
10565 switch (elf_header.e_type)
10566 {
10567 case ET_DYN:
10568 case ET_EXEC:
10569 switch (VMS_ST_FUNC_TYPE (other))
10570 {
10571 case VMS_SFT_CODE_ADDR:
10572 strcat (res, " CA");
10573 break;
10574 case VMS_SFT_SYMV_IDX:
10575 strcat (res, " VEC");
10576 break;
10577 case VMS_SFT_FD:
10578 strcat (res, " FD");
10579 break;
10580 case VMS_SFT_RESERVE:
10581 strcat (res, " RSV");
10582 break;
10583 default:
bee0ee85
NC
10584 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
10585 VMS_ST_FUNC_TYPE (other));
10586 strcat (res, " <unknown>");
10587 break;
28f997cf
TG
10588 }
10589 break;
10590 default:
10591 break;
10592 }
10593 switch (VMS_ST_LINKAGE (other))
10594 {
10595 case VMS_STL_IGNORE:
10596 strcat (res, " IGN");
10597 break;
10598 case VMS_STL_RESERVE:
10599 strcat (res, " RSV");
10600 break;
10601 case VMS_STL_STD:
10602 strcat (res, " STD");
10603 break;
10604 case VMS_STL_LNK:
10605 strcat (res, " LNK");
10606 break;
10607 default:
bee0ee85
NC
10608 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
10609 VMS_ST_LINKAGE (other));
10610 strcat (res, " <unknown>");
10611 break;
28f997cf
TG
10612 }
10613
10614 if (res[0] != 0)
10615 return res + 1;
10616 else
10617 return res;
10618 }
10619 return NULL;
10620}
10621
6911b7dc
AM
10622static const char *
10623get_ppc64_symbol_other (unsigned int other)
10624{
10625 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
10626 {
10627 static char buf[32];
10628 snprintf (buf, sizeof buf, _("<localentry>: %d"),
10629 PPC64_LOCAL_ENTRY_OFFSET (other));
10630 return buf;
10631 }
10632 return NULL;
10633}
10634
5e2b0d47
NC
10635static const char *
10636get_symbol_other (unsigned int other)
10637{
10638 const char * result = NULL;
10639 static char buff [32];
10640
10641 if (other == 0)
10642 return "";
10643
10644 switch (elf_header.e_machine)
10645 {
10646 case EM_MIPS:
10647 result = get_mips_symbol_other (other);
28f997cf
TG
10648 break;
10649 case EM_IA_64:
10650 result = get_ia64_symbol_other (other);
10651 break;
6911b7dc
AM
10652 case EM_PPC64:
10653 result = get_ppc64_symbol_other (other);
10654 break;
5e2b0d47 10655 default:
fd85a6a1 10656 result = NULL;
5e2b0d47
NC
10657 break;
10658 }
10659
10660 if (result)
10661 return result;
10662
10663 snprintf (buff, sizeof buff, _("<other>: %x"), other);
10664 return buff;
10665}
10666
d1133906 10667static const char *
d3ba0551 10668get_symbol_index_type (unsigned int type)
252b5132 10669{
b34976b6 10670 static char buff[32];
5cf1065c 10671
252b5132
RH
10672 switch (type)
10673 {
b34976b6
AM
10674 case SHN_UNDEF: return "UND";
10675 case SHN_ABS: return "ABS";
10676 case SHN_COMMON: return "COM";
252b5132 10677 default:
9ce701e2
L
10678 if (type == SHN_IA_64_ANSI_COMMON
10679 && elf_header.e_machine == EM_IA_64
10680 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
10681 return "ANSI_COM";
8a9036a4 10682 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
10683 || elf_header.e_machine == EM_L1OM
10684 || elf_header.e_machine == EM_K1OM)
3b22753a
L
10685 && type == SHN_X86_64_LCOMMON)
10686 return "LARGE_COM";
ac145307
BS
10687 else if ((type == SHN_MIPS_SCOMMON
10688 && elf_header.e_machine == EM_MIPS)
10689 || (type == SHN_TIC6X_SCOMMON
10690 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
10691 return "SCOM";
10692 else if (type == SHN_MIPS_SUNDEFINED
10693 && elf_header.e_machine == EM_MIPS)
10694 return "SUND";
9ce701e2 10695 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 10696 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 10697 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
10698 sprintf (buff, "OS [0x%04x]", type & 0xffff);
10699 else if (type >= SHN_LORESERVE)
10700 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4 10701 else if (type >= elf_header.e_shnum)
e0a31db1 10702 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 10703 else
232e7cb8 10704 sprintf (buff, "%3d", type);
5cf1065c 10705 break;
252b5132 10706 }
5cf1065c
NC
10707
10708 return buff;
252b5132
RH
10709}
10710
66543521 10711static bfd_vma *
57028622 10712get_dynamic_data (FILE * file, bfd_size_type number, unsigned int ent_size)
252b5132 10713{
2cf0635d
NC
10714 unsigned char * e_data;
10715 bfd_vma * i_data;
252b5132 10716
57028622
NC
10717 /* If the size_t type is smaller than the bfd_size_type, eg because
10718 you are building a 32-bit tool on a 64-bit host, then make sure
10719 that when (number) is cast to (size_t) no information is lost. */
10720 if (sizeof (size_t) < sizeof (bfd_size_type)
10721 && (bfd_size_type) ((size_t) number) != number)
10722 {
ed754a13
AM
10723 error (_("Size truncation prevents reading %" BFD_VMA_FMT "u"
10724 " elements of size %u\n"),
10725 number, ent_size);
57028622
NC
10726 return NULL;
10727 }
948f632f 10728
3102e897
NC
10729 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
10730 attempting to allocate memory when the read is bound to fail. */
10731 if (ent_size * number > current_file_size)
10732 {
ed754a13
AM
10733 error (_("Invalid number of dynamic entries: %" BFD_VMA_FMT "u\n"),
10734 number);
3102e897
NC
10735 return NULL;
10736 }
10737
57028622 10738 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
252b5132
RH
10739 if (e_data == NULL)
10740 {
ed754a13
AM
10741 error (_("Out of memory reading %" BFD_VMA_FMT "u dynamic entries\n"),
10742 number);
252b5132
RH
10743 return NULL;
10744 }
10745
57028622 10746 if (fread (e_data, ent_size, (size_t) number, file) != number)
252b5132 10747 {
ed754a13
AM
10748 error (_("Unable to read in %" BFD_VMA_FMT "u bytes of dynamic data\n"),
10749 number * ent_size);
3102e897 10750 free (e_data);
252b5132
RH
10751 return NULL;
10752 }
10753
57028622 10754 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
252b5132
RH
10755 if (i_data == NULL)
10756 {
ed754a13
AM
10757 error (_("Out of memory allocating space for %" BFD_VMA_FMT "u"
10758 " dynamic entries\n"),
10759 number);
252b5132
RH
10760 free (e_data);
10761 return NULL;
10762 }
10763
10764 while (number--)
66543521 10765 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
10766
10767 free (e_data);
10768
10769 return i_data;
10770}
10771
6bd1a22c
L
10772static void
10773print_dynamic_symbol (bfd_vma si, unsigned long hn)
10774{
2cf0635d 10775 Elf_Internal_Sym * psym;
6bd1a22c
L
10776 int n;
10777
6bd1a22c
L
10778 n = print_vma (si, DEC_5);
10779 if (n < 5)
0b4362b0 10780 fputs (&" "[n], stdout);
6bd1a22c 10781 printf (" %3lu: ", hn);
e0a31db1
NC
10782
10783 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
10784 {
3102e897
NC
10785 printf (_("<No info available for dynamic symbol number %lu>\n"),
10786 (unsigned long) si);
e0a31db1
NC
10787 return;
10788 }
10789
10790 psym = dynamic_symbols + si;
6bd1a22c
L
10791 print_vma (psym->st_value, LONG_HEX);
10792 putchar (' ');
10793 print_vma (psym->st_size, DEC_5);
10794
f4be36b3
AM
10795 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10796 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
fd85a6a1
NC
10797
10798 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
10799 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
10800 else
10801 {
10802 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
10803
10804 printf (" %-7s", get_symbol_visibility (vis));
10805 /* Check to see if any other bits in the st_other field are set.
10806 Note - displaying this information disrupts the layout of the
10807 table being generated, but for the moment this case is very
10808 rare. */
10809 if (psym->st_other ^ vis)
10810 printf (" [%s] ", get_symbol_other (psym->st_other ^ vis));
10811 }
10812
6bd1a22c
L
10813 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
10814 if (VALID_DYNAMIC_NAME (psym->st_name))
10815 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
10816 else
2b692964 10817 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
10818 putchar ('\n');
10819}
10820
bb4d2ac2 10821static const char *
1449284b
NC
10822get_symbol_version_string (FILE * file,
10823 bfd_boolean is_dynsym,
10824 const char * strtab,
10825 unsigned long int strtab_size,
10826 unsigned int si,
10827 Elf_Internal_Sym * psym,
10828 enum versioned_symbol_info * sym_info,
10829 unsigned short * vna_other)
bb4d2ac2 10830{
ab273396
AM
10831 unsigned char data[2];
10832 unsigned short vers_data;
10833 unsigned long offset;
bb4d2ac2 10834
ab273396
AM
10835 if (!is_dynsym
10836 || version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
10837 return NULL;
bb4d2ac2 10838
ab273396
AM
10839 offset = offset_from_vma (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10840 sizeof data + si * sizeof (vers_data));
bb4d2ac2 10841
ab273396
AM
10842 if (get_data (&data, file, offset + si * sizeof (vers_data),
10843 sizeof (data), 1, _("version data")) == NULL)
10844 return NULL;
10845
10846 vers_data = byte_get (data, 2);
bb4d2ac2 10847
ab273396
AM
10848 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data <= 1)
10849 return NULL;
bb4d2ac2 10850
ab273396
AM
10851 /* Usually we'd only see verdef for defined symbols, and verneed for
10852 undefined symbols. However, symbols defined by the linker in
10853 .dynbss for variables copied from a shared library in order to
10854 avoid text relocations are defined yet have verneed. We could
10855 use a heuristic to detect the special case, for example, check
10856 for verneed first on symbols defined in SHT_NOBITS sections, but
10857 it is simpler and more reliable to just look for both verdef and
10858 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 10859
ab273396
AM
10860 if (psym->st_shndx != SHN_UNDEF
10861 && vers_data != 0x8001
10862 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
10863 {
10864 Elf_Internal_Verdef ivd;
10865 Elf_Internal_Verdaux ivda;
10866 Elf_External_Verdaux evda;
10867 unsigned long off;
bb4d2ac2 10868
ab273396
AM
10869 off = offset_from_vma (file,
10870 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10871 sizeof (Elf_External_Verdef));
10872
10873 do
bb4d2ac2 10874 {
ab273396
AM
10875 Elf_External_Verdef evd;
10876
10877 if (get_data (&evd, file, off, sizeof (evd), 1,
10878 _("version def")) == NULL)
10879 {
10880 ivd.vd_ndx = 0;
10881 ivd.vd_aux = 0;
10882 ivd.vd_next = 0;
10883 }
10884 else
bb4d2ac2 10885 {
ab273396
AM
10886 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10887 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10888 ivd.vd_next = BYTE_GET (evd.vd_next);
10889 }
bb4d2ac2 10890
ab273396
AM
10891 off += ivd.vd_next;
10892 }
10893 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 10894
ab273396
AM
10895 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
10896 {
10897 off -= ivd.vd_next;
10898 off += ivd.vd_aux;
bb4d2ac2 10899
ab273396
AM
10900 if (get_data (&evda, file, off, sizeof (evda), 1,
10901 _("version def aux")) != NULL)
10902 {
10903 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 10904
ab273396
AM
10905 if (psym->st_name != ivda.vda_name)
10906 {
10907 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
10908 ? symbol_hidden : symbol_public);
10909 return (ivda.vda_name < strtab_size
10910 ? strtab + ivda.vda_name : _("<corrupt>"));
10911 }
10912 }
10913 }
10914 }
bb4d2ac2 10915
ab273396
AM
10916 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
10917 {
10918 Elf_External_Verneed evn;
10919 Elf_Internal_Verneed ivn;
10920 Elf_Internal_Vernaux ivna;
bb4d2ac2 10921
ab273396
AM
10922 offset = offset_from_vma (file,
10923 version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
10924 sizeof evn);
10925 do
10926 {
10927 unsigned long vna_off;
bb4d2ac2 10928
ab273396
AM
10929 if (get_data (&evn, file, offset, sizeof (evn), 1,
10930 _("version need")) == NULL)
10931 {
10932 ivna.vna_next = 0;
10933 ivna.vna_other = 0;
10934 ivna.vna_name = 0;
10935 break;
10936 }
bb4d2ac2 10937
ab273396
AM
10938 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10939 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 10940
ab273396 10941 vna_off = offset + ivn.vn_aux;
bb4d2ac2 10942
ab273396
AM
10943 do
10944 {
10945 Elf_External_Vernaux evna;
bb4d2ac2 10946
ab273396
AM
10947 if (get_data (&evna, file, vna_off, sizeof (evna), 1,
10948 _("version need aux (3)")) == NULL)
bb4d2ac2 10949 {
ab273396
AM
10950 ivna.vna_next = 0;
10951 ivna.vna_other = 0;
10952 ivna.vna_name = 0;
bb4d2ac2 10953 }
bb4d2ac2 10954 else
bb4d2ac2 10955 {
ab273396
AM
10956 ivna.vna_other = BYTE_GET (evna.vna_other);
10957 ivna.vna_next = BYTE_GET (evna.vna_next);
10958 ivna.vna_name = BYTE_GET (evna.vna_name);
10959 }
bb4d2ac2 10960
ab273396
AM
10961 vna_off += ivna.vna_next;
10962 }
10963 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 10964
ab273396
AM
10965 if (ivna.vna_other == vers_data)
10966 break;
bb4d2ac2 10967
ab273396
AM
10968 offset += ivn.vn_next;
10969 }
10970 while (ivn.vn_next != 0);
bb4d2ac2 10971
ab273396
AM
10972 if (ivna.vna_other == vers_data)
10973 {
10974 *sym_info = symbol_undefined;
10975 *vna_other = ivna.vna_other;
10976 return (ivna.vna_name < strtab_size
10977 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2
L
10978 }
10979 }
ab273396 10980 return NULL;
bb4d2ac2
L
10981}
10982
e3c8793a 10983/* Dump the symbol table. */
252b5132 10984static int
2cf0635d 10985process_symbol_table (FILE * file)
252b5132 10986{
2cf0635d 10987 Elf_Internal_Shdr * section;
8b73c356
NC
10988 bfd_size_type nbuckets = 0;
10989 bfd_size_type nchains = 0;
2cf0635d
NC
10990 bfd_vma * buckets = NULL;
10991 bfd_vma * chains = NULL;
fdc90cb4 10992 bfd_vma ngnubuckets = 0;
2cf0635d
NC
10993 bfd_vma * gnubuckets = NULL;
10994 bfd_vma * gnuchains = NULL;
6bd1a22c 10995 bfd_vma gnusymidx = 0;
071436c6 10996 bfd_size_type ngnuchains = 0;
252b5132 10997
2c610e4b 10998 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
10999 return 1;
11000
6bd1a22c
L
11001 if (dynamic_info[DT_HASH]
11002 && (do_histogram
2c610e4b
L
11003 || (do_using_dynamic
11004 && !do_dyn_syms
11005 && dynamic_strings != NULL)))
252b5132 11006 {
66543521
AM
11007 unsigned char nb[8];
11008 unsigned char nc[8];
8b73c356 11009 unsigned int hash_ent_size = 4;
66543521
AM
11010
11011 if ((elf_header.e_machine == EM_ALPHA
11012 || elf_header.e_machine == EM_S390
11013 || elf_header.e_machine == EM_S390_OLD)
11014 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
11015 hash_ent_size = 8;
11016
fb52b2f4
NC
11017 if (fseek (file,
11018 (archive_file_offset
11019 + offset_from_vma (file, dynamic_info[DT_HASH],
11020 sizeof nb + sizeof nc)),
d93f0186 11021 SEEK_SET))
252b5132 11022 {
591a748a 11023 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11024 goto no_hash;
252b5132
RH
11025 }
11026
66543521 11027 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
11028 {
11029 error (_("Failed to read in number of buckets\n"));
d3a44ec6 11030 goto no_hash;
252b5132
RH
11031 }
11032
66543521 11033 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
11034 {
11035 error (_("Failed to read in number of chains\n"));
d3a44ec6 11036 goto no_hash;
252b5132
RH
11037 }
11038
66543521
AM
11039 nbuckets = byte_get (nb, hash_ent_size);
11040 nchains = byte_get (nc, hash_ent_size);
252b5132 11041
66543521
AM
11042 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
11043 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 11044
d3a44ec6 11045 no_hash:
252b5132 11046 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
11047 {
11048 if (do_using_dynamic)
11049 return 0;
11050 free (buckets);
11051 free (chains);
11052 buckets = NULL;
11053 chains = NULL;
11054 nbuckets = 0;
11055 nchains = 0;
11056 }
252b5132
RH
11057 }
11058
6bd1a22c
L
11059 if (dynamic_info_DT_GNU_HASH
11060 && (do_histogram
2c610e4b
L
11061 || (do_using_dynamic
11062 && !do_dyn_syms
11063 && dynamic_strings != NULL)))
252b5132 11064 {
6bd1a22c
L
11065 unsigned char nb[16];
11066 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
11067 bfd_vma buckets_vma;
11068
11069 if (fseek (file,
11070 (archive_file_offset
11071 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
11072 sizeof nb)),
11073 SEEK_SET))
11074 {
11075 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11076 goto no_gnu_hash;
6bd1a22c 11077 }
252b5132 11078
6bd1a22c
L
11079 if (fread (nb, 16, 1, file) != 1)
11080 {
11081 error (_("Failed to read in number of buckets\n"));
d3a44ec6 11082 goto no_gnu_hash;
6bd1a22c
L
11083 }
11084
11085 ngnubuckets = byte_get (nb, 4);
11086 gnusymidx = byte_get (nb + 4, 4);
11087 bitmaskwords = byte_get (nb + 8, 4);
11088 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 11089 if (is_32bit_elf)
6bd1a22c 11090 buckets_vma += bitmaskwords * 4;
f7a99963 11091 else
6bd1a22c 11092 buckets_vma += bitmaskwords * 8;
252b5132 11093
6bd1a22c
L
11094 if (fseek (file,
11095 (archive_file_offset
11096 + offset_from_vma (file, buckets_vma, 4)),
11097 SEEK_SET))
252b5132 11098 {
6bd1a22c 11099 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11100 goto no_gnu_hash;
6bd1a22c
L
11101 }
11102
11103 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 11104
6bd1a22c 11105 if (gnubuckets == NULL)
d3a44ec6 11106 goto no_gnu_hash;
6bd1a22c
L
11107
11108 for (i = 0; i < ngnubuckets; i++)
11109 if (gnubuckets[i] != 0)
11110 {
11111 if (gnubuckets[i] < gnusymidx)
11112 return 0;
11113
11114 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
11115 maxchain = gnubuckets[i];
11116 }
11117
11118 if (maxchain == 0xffffffff)
d3a44ec6 11119 goto no_gnu_hash;
6bd1a22c
L
11120
11121 maxchain -= gnusymidx;
11122
11123 if (fseek (file,
11124 (archive_file_offset
11125 + offset_from_vma (file, buckets_vma
11126 + 4 * (ngnubuckets + maxchain), 4)),
11127 SEEK_SET))
11128 {
11129 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11130 goto no_gnu_hash;
6bd1a22c
L
11131 }
11132
11133 do
11134 {
11135 if (fread (nb, 4, 1, file) != 1)
252b5132 11136 {
6bd1a22c 11137 error (_("Failed to determine last chain length\n"));
d3a44ec6 11138 goto no_gnu_hash;
6bd1a22c 11139 }
252b5132 11140
6bd1a22c 11141 if (maxchain + 1 == 0)
d3a44ec6 11142 goto no_gnu_hash;
252b5132 11143
6bd1a22c
L
11144 ++maxchain;
11145 }
11146 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 11147
6bd1a22c
L
11148 if (fseek (file,
11149 (archive_file_offset
11150 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
11151 SEEK_SET))
11152 {
11153 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11154 goto no_gnu_hash;
6bd1a22c
L
11155 }
11156
11157 gnuchains = get_dynamic_data (file, maxchain, 4);
071436c6 11158 ngnuchains = maxchain;
6bd1a22c 11159
d3a44ec6 11160 no_gnu_hash:
6bd1a22c 11161 if (gnuchains == NULL)
d3a44ec6
JJ
11162 {
11163 free (gnubuckets);
d3a44ec6
JJ
11164 gnubuckets = NULL;
11165 ngnubuckets = 0;
f64fddf1
NC
11166 if (do_using_dynamic)
11167 return 0;
d3a44ec6 11168 }
6bd1a22c
L
11169 }
11170
11171 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
11172 && do_syms
11173 && do_using_dynamic
3102e897
NC
11174 && dynamic_strings != NULL
11175 && dynamic_symbols != NULL)
6bd1a22c
L
11176 {
11177 unsigned long hn;
11178
11179 if (dynamic_info[DT_HASH])
11180 {
11181 bfd_vma si;
11182
11183 printf (_("\nSymbol table for image:\n"));
11184 if (is_32bit_elf)
11185 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11186 else
11187 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11188
11189 for (hn = 0; hn < nbuckets; hn++)
11190 {
11191 if (! buckets[hn])
11192 continue;
11193
11194 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
11195 print_dynamic_symbol (si, hn);
252b5132
RH
11196 }
11197 }
6bd1a22c
L
11198
11199 if (dynamic_info_DT_GNU_HASH)
11200 {
11201 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
11202 if (is_32bit_elf)
11203 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11204 else
11205 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11206
11207 for (hn = 0; hn < ngnubuckets; ++hn)
11208 if (gnubuckets[hn] != 0)
11209 {
11210 bfd_vma si = gnubuckets[hn];
11211 bfd_vma off = si - gnusymidx;
11212
11213 do
11214 {
11215 print_dynamic_symbol (si, hn);
11216 si++;
11217 }
071436c6 11218 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
11219 }
11220 }
252b5132 11221 }
8b73c356
NC
11222 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
11223 && section_headers != NULL)
252b5132 11224 {
b34976b6 11225 unsigned int i;
252b5132
RH
11226
11227 for (i = 0, section = section_headers;
11228 i < elf_header.e_shnum;
11229 i++, section++)
11230 {
b34976b6 11231 unsigned int si;
2cf0635d 11232 char * strtab = NULL;
c256ffe7 11233 unsigned long int strtab_size = 0;
2cf0635d
NC
11234 Elf_Internal_Sym * symtab;
11235 Elf_Internal_Sym * psym;
ba5cdace 11236 unsigned long num_syms;
252b5132 11237
2c610e4b
L
11238 if ((section->sh_type != SHT_SYMTAB
11239 && section->sh_type != SHT_DYNSYM)
11240 || (!do_syms
11241 && section->sh_type == SHT_SYMTAB))
252b5132
RH
11242 continue;
11243
dd24e3da
NC
11244 if (section->sh_entsize == 0)
11245 {
11246 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
74e1a04b 11247 printable_section_name (section));
dd24e3da
NC
11248 continue;
11249 }
11250
252b5132 11251 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
74e1a04b 11252 printable_section_name (section),
252b5132 11253 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 11254
f7a99963 11255 if (is_32bit_elf)
ca47b30c 11256 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 11257 else
ca47b30c 11258 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 11259
ba5cdace 11260 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
11261 if (symtab == NULL)
11262 continue;
11263
11264 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
11265 {
11266 strtab = string_table;
11267 strtab_size = string_table_length;
11268 }
4fbb74a6 11269 else if (section->sh_link < elf_header.e_shnum)
252b5132 11270 {
2cf0635d 11271 Elf_Internal_Shdr * string_sec;
252b5132 11272
4fbb74a6 11273 string_sec = section_headers + section->sh_link;
252b5132 11274
3f5e193b
NC
11275 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
11276 1, string_sec->sh_size,
11277 _("string table"));
c256ffe7 11278 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
11279 }
11280
ba5cdace 11281 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 11282 {
bb4d2ac2
L
11283 const char *version_string;
11284 enum versioned_symbol_info sym_info;
11285 unsigned short vna_other;
11286
5e220199 11287 printf ("%6d: ", si);
f7a99963
NC
11288 print_vma (psym->st_value, LONG_HEX);
11289 putchar (' ');
11290 print_vma (psym->st_size, DEC_5);
d1133906
NC
11291 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
11292 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
fd85a6a1
NC
11293 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
11294 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
11295 else
11296 {
11297 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
11298
11299 printf (" %-7s", get_symbol_visibility (vis));
11300 /* Check to see if any other bits in the st_other field are set.
11301 Note - displaying this information disrupts the layout of the
11302 table being generated, but for the moment this case is very rare. */
11303 if (psym->st_other ^ vis)
11304 printf (" [%s] ", get_symbol_other (psym->st_other ^ vis));
11305 }
31104126 11306 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 11307 print_symbol (25, psym->st_name < strtab_size
2b692964 11308 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 11309
bb4d2ac2
L
11310 version_string
11311 = get_symbol_version_string (file,
11312 section->sh_type == SHT_DYNSYM,
11313 strtab, strtab_size, si,
11314 psym, &sym_info, &vna_other);
11315 if (version_string)
252b5132 11316 {
bb4d2ac2
L
11317 if (sym_info == symbol_undefined)
11318 printf ("@%s (%d)", version_string, vna_other);
11319 else
11320 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
11321 version_string);
252b5132
RH
11322 }
11323
11324 putchar ('\n');
52c3c391
NC
11325
11326 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
dd905818
NC
11327 && si >= section->sh_info
11328 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
11329 && elf_header.e_machine != EM_MIPS
11330 /* Solaris binaries have been found to violate this requirement as
11331 well. Not sure if this is a bug or an ABI requirement. */
11332 && elf_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
52c3c391
NC
11333 warn (_("local symbol %u found at index >= %s's sh_info value of %u\n"),
11334 si, printable_section_name (section), section->sh_info);
252b5132
RH
11335 }
11336
11337 free (symtab);
11338 if (strtab != string_table)
11339 free (strtab);
11340 }
11341 }
11342 else if (do_syms)
11343 printf
11344 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
11345
11346 if (do_histogram && buckets != NULL)
11347 {
2cf0635d
NC
11348 unsigned long * lengths;
11349 unsigned long * counts;
66543521
AM
11350 unsigned long hn;
11351 bfd_vma si;
11352 unsigned long maxlength = 0;
11353 unsigned long nzero_counts = 0;
11354 unsigned long nsyms = 0;
94d15024 11355 unsigned long chained;
252b5132 11356
66543521
AM
11357 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
11358 (unsigned long) nbuckets);
252b5132 11359
3f5e193b 11360 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
11361 if (lengths == NULL)
11362 {
8b73c356 11363 error (_("Out of memory allocating space for histogram buckets\n"));
252b5132
RH
11364 return 0;
11365 }
8b73c356
NC
11366
11367 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
11368 for (hn = 0; hn < nbuckets; ++hn)
11369 {
94d15024
MF
11370 for (si = buckets[hn], chained = 0;
11371 si > 0 && si < nchains && si < nbuckets && chained <= nchains;
11372 si = chains[si], ++chained)
252b5132 11373 {
b34976b6 11374 ++nsyms;
252b5132 11375 if (maxlength < ++lengths[hn])
b34976b6 11376 ++maxlength;
252b5132 11377 }
94d15024
MF
11378
11379 /* PR binutils/17531: A corrupt binary could contain broken
11380 histogram data. Do not go into an infinite loop trying
11381 to process it. */
11382 if (chained > nchains)
11383 {
11384 error (_("histogram chain is corrupt\n"));
11385 break;
11386 }
252b5132
RH
11387 }
11388
3f5e193b 11389 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
11390 if (counts == NULL)
11391 {
b2e951ec 11392 free (lengths);
8b73c356 11393 error (_("Out of memory allocating space for histogram counts\n"));
252b5132
RH
11394 return 0;
11395 }
11396
11397 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 11398 ++counts[lengths[hn]];
252b5132 11399
103f02d3 11400 if (nbuckets > 0)
252b5132 11401 {
66543521
AM
11402 unsigned long i;
11403 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 11404 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 11405 for (i = 1; i <= maxlength; ++i)
103f02d3 11406 {
66543521
AM
11407 nzero_counts += counts[i] * i;
11408 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11409 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
11410 (nzero_counts * 100.0) / nsyms);
11411 }
252b5132
RH
11412 }
11413
11414 free (counts);
11415 free (lengths);
11416 }
11417
11418 if (buckets != NULL)
11419 {
11420 free (buckets);
11421 free (chains);
11422 }
11423
d3a44ec6 11424 if (do_histogram && gnubuckets != NULL)
fdc90cb4 11425 {
2cf0635d
NC
11426 unsigned long * lengths;
11427 unsigned long * counts;
fdc90cb4
JJ
11428 unsigned long hn;
11429 unsigned long maxlength = 0;
11430 unsigned long nzero_counts = 0;
11431 unsigned long nsyms = 0;
fdc90cb4 11432
8b73c356
NC
11433 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
11434 (unsigned long) ngnubuckets);
11435
3f5e193b 11436 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
11437 if (lengths == NULL)
11438 {
8b73c356 11439 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fdc90cb4
JJ
11440 return 0;
11441 }
11442
fdc90cb4
JJ
11443 printf (_(" Length Number %% of total Coverage\n"));
11444
11445 for (hn = 0; hn < ngnubuckets; ++hn)
11446 if (gnubuckets[hn] != 0)
11447 {
11448 bfd_vma off, length = 1;
11449
6bd1a22c 11450 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
11451 /* PR 17531 file: 010-77222-0.004. */
11452 off < ngnuchains && (gnuchains[off] & 1) == 0;
11453 ++off)
fdc90cb4
JJ
11454 ++length;
11455 lengths[hn] = length;
11456 if (length > maxlength)
11457 maxlength = length;
11458 nsyms += length;
11459 }
11460
3f5e193b 11461 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
11462 if (counts == NULL)
11463 {
b2e951ec 11464 free (lengths);
8b73c356 11465 error (_("Out of memory allocating space for gnu histogram counts\n"));
fdc90cb4
JJ
11466 return 0;
11467 }
11468
11469 for (hn = 0; hn < ngnubuckets; ++hn)
11470 ++counts[lengths[hn]];
11471
11472 if (ngnubuckets > 0)
11473 {
11474 unsigned long j;
11475 printf (" 0 %-10lu (%5.1f%%)\n",
11476 counts[0], (counts[0] * 100.0) / ngnubuckets);
11477 for (j = 1; j <= maxlength; ++j)
11478 {
11479 nzero_counts += counts[j] * j;
11480 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11481 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
11482 (nzero_counts * 100.0) / nsyms);
11483 }
11484 }
11485
11486 free (counts);
11487 free (lengths);
11488 free (gnubuckets);
11489 free (gnuchains);
11490 }
11491
252b5132
RH
11492 return 1;
11493}
11494
11495static int
2cf0635d 11496process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 11497{
b4c96d0d 11498 unsigned int i;
252b5132
RH
11499
11500 if (dynamic_syminfo == NULL
11501 || !do_dynamic)
11502 /* No syminfo, this is ok. */
11503 return 1;
11504
11505 /* There better should be a dynamic symbol section. */
11506 if (dynamic_symbols == NULL || dynamic_strings == NULL)
11507 return 0;
11508
11509 if (dynamic_addr)
11510 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
11511 dynamic_syminfo_offset, dynamic_syminfo_nent);
11512
11513 printf (_(" Num: Name BoundTo Flags\n"));
11514 for (i = 0; i < dynamic_syminfo_nent; ++i)
11515 {
11516 unsigned short int flags = dynamic_syminfo[i].si_flags;
11517
31104126 11518 printf ("%4d: ", i);
4082ef84
NC
11519 if (i >= num_dynamic_syms)
11520 printf (_("<corrupt index>"));
11521 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
11522 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
11523 else
2b692964 11524 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 11525 putchar (' ');
252b5132
RH
11526
11527 switch (dynamic_syminfo[i].si_boundto)
11528 {
11529 case SYMINFO_BT_SELF:
11530 fputs ("SELF ", stdout);
11531 break;
11532 case SYMINFO_BT_PARENT:
11533 fputs ("PARENT ", stdout);
11534 break;
11535 default:
11536 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
11537 && dynamic_syminfo[i].si_boundto < dynamic_nent
11538 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 11539 {
d79b3d50 11540 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
11541 putchar (' ' );
11542 }
252b5132
RH
11543 else
11544 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
11545 break;
11546 }
11547
11548 if (flags & SYMINFO_FLG_DIRECT)
11549 printf (" DIRECT");
11550 if (flags & SYMINFO_FLG_PASSTHRU)
11551 printf (" PASSTHRU");
11552 if (flags & SYMINFO_FLG_COPY)
11553 printf (" COPY");
11554 if (flags & SYMINFO_FLG_LAZYLOAD)
11555 printf (" LAZYLOAD");
11556
11557 puts ("");
11558 }
11559
11560 return 1;
11561}
11562
cf13d699
NC
11563/* Check to see if the given reloc needs to be handled in a target specific
11564 manner. If so then process the reloc and return TRUE otherwise return
11565 FALSE. */
09c11c86 11566
cf13d699
NC
11567static bfd_boolean
11568target_specific_reloc_handling (Elf_Internal_Rela * reloc,
11569 unsigned char * start,
11570 Elf_Internal_Sym * symtab)
252b5132 11571{
cf13d699 11572 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 11573
cf13d699 11574 switch (elf_header.e_machine)
252b5132 11575 {
13761a11
NC
11576 case EM_MSP430:
11577 case EM_MSP430_OLD:
11578 {
11579 static Elf_Internal_Sym * saved_sym = NULL;
11580
11581 switch (reloc_type)
11582 {
11583 case 10: /* R_MSP430_SYM_DIFF */
11584 if (uses_msp430x_relocs ())
11585 break;
1a0670f3 11586 /* Fall through. */
13761a11
NC
11587 case 21: /* R_MSP430X_SYM_DIFF */
11588 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
11589 return TRUE;
11590
11591 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
11592 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
11593 goto handle_sym_diff;
0b4362b0 11594
13761a11
NC
11595 case 5: /* R_MSP430_16_BYTE */
11596 case 9: /* R_MSP430_8 */
11597 if (uses_msp430x_relocs ())
11598 break;
11599 goto handle_sym_diff;
11600
11601 case 2: /* R_MSP430_ABS16 */
11602 case 15: /* R_MSP430X_ABS16 */
11603 if (! uses_msp430x_relocs ())
11604 break;
11605 goto handle_sym_diff;
0b4362b0 11606
13761a11
NC
11607 handle_sym_diff:
11608 if (saved_sym != NULL)
11609 {
11610 bfd_vma value;
11611
11612 value = reloc->r_addend
11613 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
11614 - saved_sym->st_value);
11615
11616 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
11617
11618 saved_sym = NULL;
11619 return TRUE;
11620 }
11621 break;
11622
11623 default:
11624 if (saved_sym != NULL)
071436c6 11625 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
11626 break;
11627 }
11628 break;
11629 }
11630
cf13d699
NC
11631 case EM_MN10300:
11632 case EM_CYGNUS_MN10300:
11633 {
11634 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 11635
cf13d699
NC
11636 switch (reloc_type)
11637 {
11638 case 34: /* R_MN10300_ALIGN */
11639 return TRUE;
11640 case 33: /* R_MN10300_SYM_DIFF */
11641 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
11642 return TRUE;
11643 case 1: /* R_MN10300_32 */
11644 case 2: /* R_MN10300_16 */
11645 if (saved_sym != NULL)
11646 {
11647 bfd_vma value;
252b5132 11648
cf13d699
NC
11649 value = reloc->r_addend
11650 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
11651 - saved_sym->st_value);
252b5132 11652
cf13d699 11653 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 11654
cf13d699
NC
11655 saved_sym = NULL;
11656 return TRUE;
11657 }
11658 break;
11659 default:
11660 if (saved_sym != NULL)
071436c6 11661 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
11662 break;
11663 }
11664 break;
11665 }
6ff71e76
NC
11666
11667 case EM_RL78:
11668 {
11669 static bfd_vma saved_sym1 = 0;
11670 static bfd_vma saved_sym2 = 0;
11671 static bfd_vma value;
11672
11673 switch (reloc_type)
11674 {
11675 case 0x80: /* R_RL78_SYM. */
11676 saved_sym1 = saved_sym2;
11677 saved_sym2 = symtab[get_reloc_symindex (reloc->r_info)].st_value;
11678 saved_sym2 += reloc->r_addend;
11679 return TRUE;
11680
11681 case 0x83: /* R_RL78_OPsub. */
11682 value = saved_sym1 - saved_sym2;
11683 saved_sym2 = saved_sym1 = 0;
11684 return TRUE;
11685 break;
11686
11687 case 0x41: /* R_RL78_ABS32. */
11688 byte_put (start + reloc->r_offset, value, 4);
11689 value = 0;
11690 return TRUE;
11691
11692 case 0x43: /* R_RL78_ABS16. */
11693 byte_put (start + reloc->r_offset, value, 2);
11694 value = 0;
11695 return TRUE;
11696
11697 default:
11698 break;
11699 }
11700 break;
11701 }
252b5132
RH
11702 }
11703
cf13d699 11704 return FALSE;
252b5132
RH
11705}
11706
aca88567
NC
11707/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
11708 DWARF debug sections. This is a target specific test. Note - we do not
11709 go through the whole including-target-headers-multiple-times route, (as
11710 we have already done with <elf/h8.h>) because this would become very
11711 messy and even then this function would have to contain target specific
11712 information (the names of the relocs instead of their numeric values).
11713 FIXME: This is not the correct way to solve this problem. The proper way
11714 is to have target specific reloc sizing and typing functions created by
11715 the reloc-macros.h header, in the same way that it already creates the
11716 reloc naming functions. */
11717
11718static bfd_boolean
11719is_32bit_abs_reloc (unsigned int reloc_type)
11720{
d347c9df 11721 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567
NC
11722 switch (elf_header.e_machine)
11723 {
41e92641 11724 case EM_386:
22abe556 11725 case EM_IAMCU:
41e92641 11726 return reloc_type == 1; /* R_386_32. */
aca88567
NC
11727 case EM_68K:
11728 return reloc_type == 1; /* R_68K_32. */
11729 case EM_860:
11730 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
11731 case EM_960:
11732 return reloc_type == 2; /* R_960_32. */
a06ea964 11733 case EM_AARCH64:
9282b95a
JW
11734 return (reloc_type == 258
11735 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
d347c9df
PS
11736 case EM_ADAPTEVA_EPIPHANY:
11737 return reloc_type == 3;
aca88567 11738 case EM_ALPHA:
137b6b5f 11739 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
11740 case EM_ARC:
11741 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
11742 case EM_ARC_COMPACT:
11743 case EM_ARC_COMPACT2:
11744 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
11745 case EM_ARM:
11746 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 11747 case EM_AVR_OLD:
aca88567
NC
11748 case EM_AVR:
11749 return reloc_type == 1;
11750 case EM_BLACKFIN:
11751 return reloc_type == 0x12; /* R_byte4_data. */
11752 case EM_CRIS:
11753 return reloc_type == 3; /* R_CRIS_32. */
11754 case EM_CR16:
11755 return reloc_type == 3; /* R_CR16_NUM32. */
11756 case EM_CRX:
11757 return reloc_type == 15; /* R_CRX_NUM32. */
11758 case EM_CYGNUS_FRV:
11759 return reloc_type == 1;
41e92641
NC
11760 case EM_CYGNUS_D10V:
11761 case EM_D10V:
11762 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
11763 case EM_CYGNUS_D30V:
11764 case EM_D30V:
11765 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
11766 case EM_DLX:
11767 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
11768 case EM_CYGNUS_FR30:
11769 case EM_FR30:
11770 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
11771 case EM_FT32:
11772 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
11773 case EM_H8S:
11774 case EM_H8_300:
11775 case EM_H8_300H:
11776 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 11777 case EM_IA_64:
d1c4b12b
NC
11778 return reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
11779 || reloc_type == 0x25; /* R_IA64_DIR32LSB. */
aca88567
NC
11780 case EM_IP2K_OLD:
11781 case EM_IP2K:
11782 return reloc_type == 2; /* R_IP2K_32. */
11783 case EM_IQ2000:
11784 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
11785 case EM_LATTICEMICO32:
11786 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 11787 case EM_M32C_OLD:
aca88567
NC
11788 case EM_M32C:
11789 return reloc_type == 3; /* R_M32C_32. */
11790 case EM_M32R:
11791 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
11792 case EM_68HC11:
11793 case EM_68HC12:
11794 return reloc_type == 6; /* R_M68HC11_32. */
aca88567
NC
11795 case EM_MCORE:
11796 return reloc_type == 1; /* R_MCORE_ADDR32. */
11797 case EM_CYGNUS_MEP:
11798 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
11799 case EM_METAG:
11800 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
11801 case EM_MICROBLAZE:
11802 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
11803 case EM_MIPS:
11804 return reloc_type == 2; /* R_MIPS_32. */
11805 case EM_MMIX:
11806 return reloc_type == 4; /* R_MMIX_32. */
11807 case EM_CYGNUS_MN10200:
11808 case EM_MN10200:
11809 return reloc_type == 1; /* R_MN10200_32. */
11810 case EM_CYGNUS_MN10300:
11811 case EM_MN10300:
11812 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
11813 case EM_MOXIE:
11814 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
11815 case EM_MSP430_OLD:
11816 case EM_MSP430:
13761a11 11817 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
11818 case EM_MT:
11819 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
11820 case EM_NDS32:
11821 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 11822 case EM_ALTERA_NIOS2:
36591ba1 11823 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
11824 case EM_NIOS32:
11825 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
11826 case EM_OR1K:
11827 return reloc_type == 1; /* R_OR1K_32. */
aca88567 11828 case EM_PARISC:
5fda8eca
NC
11829 return (reloc_type == 1 /* R_PARISC_DIR32. */
11830 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
11831 case EM_PJ:
11832 case EM_PJ_OLD:
11833 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
11834 case EM_PPC64:
11835 return reloc_type == 1; /* R_PPC64_ADDR32. */
11836 case EM_PPC:
11837 return reloc_type == 1; /* R_PPC_ADDR32. */
e23eba97
NC
11838 case EM_RISCV:
11839 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
11840 case EM_RL78:
11841 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
11842 case EM_RX:
11843 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
11844 case EM_S370:
11845 return reloc_type == 1; /* R_I370_ADDR31. */
11846 case EM_S390_OLD:
11847 case EM_S390:
11848 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
11849 case EM_SCORE:
11850 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
11851 case EM_SH:
11852 return reloc_type == 1; /* R_SH_DIR32. */
11853 case EM_SPARC32PLUS:
11854 case EM_SPARCV9:
11855 case EM_SPARC:
11856 return reloc_type == 3 /* R_SPARC_32. */
11857 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
11858 case EM_SPU:
11859 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
11860 case EM_TI_C6000:
11861 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
11862 case EM_TILEGX:
11863 return reloc_type == 2; /* R_TILEGX_32. */
11864 case EM_TILEPRO:
11865 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
11866 case EM_CYGNUS_V850:
11867 case EM_V850:
11868 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
11869 case EM_V800:
11870 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
11871 case EM_VAX:
11872 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
11873 case EM_VISIUM:
11874 return reloc_type == 3; /* R_VISIUM_32. */
aca88567 11875 case EM_X86_64:
8a9036a4 11876 case EM_L1OM:
7a9068fe 11877 case EM_K1OM:
aca88567 11878 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
11879 case EM_XC16X:
11880 case EM_C166:
11881 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
11882 case EM_XGATE:
11883 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
11884 case EM_XSTORMY16:
11885 return reloc_type == 1; /* R_XSTROMY16_32. */
11886 case EM_XTENSA_OLD:
11887 case EM_XTENSA:
11888 return reloc_type == 1; /* R_XTENSA_32. */
aca88567 11889 default:
bee0ee85
NC
11890 {
11891 static unsigned int prev_warn = 0;
11892
11893 /* Avoid repeating the same warning multiple times. */
11894 if (prev_warn != elf_header.e_machine)
11895 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
11896 elf_header.e_machine);
11897 prev_warn = elf_header.e_machine;
11898 return FALSE;
11899 }
aca88567
NC
11900 }
11901}
11902
11903/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11904 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
11905
11906static bfd_boolean
11907is_32bit_pcrel_reloc (unsigned int reloc_type)
11908{
11909 switch (elf_header.e_machine)
d347c9df 11910 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 11911 {
41e92641 11912 case EM_386:
22abe556 11913 case EM_IAMCU:
3e0873ac 11914 return reloc_type == 2; /* R_386_PC32. */
aca88567 11915 case EM_68K:
3e0873ac 11916 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
11917 case EM_AARCH64:
11918 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
11919 case EM_ADAPTEVA_EPIPHANY:
11920 return reloc_type == 6;
aca88567
NC
11921 case EM_ALPHA:
11922 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
11923 case EM_ARC_COMPACT:
11924 case EM_ARC_COMPACT2:
11925 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 11926 case EM_ARM:
3e0873ac 11927 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
11928 case EM_AVR_OLD:
11929 case EM_AVR:
11930 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
11931 case EM_MICROBLAZE:
11932 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
11933 case EM_OR1K:
11934 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 11935 case EM_PARISC:
85acf597 11936 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
11937 case EM_PPC:
11938 return reloc_type == 26; /* R_PPC_REL32. */
11939 case EM_PPC64:
3e0873ac 11940 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
11941 case EM_S390_OLD:
11942 case EM_S390:
3e0873ac 11943 return reloc_type == 5; /* R_390_PC32. */
aca88567 11944 case EM_SH:
3e0873ac 11945 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
11946 case EM_SPARC32PLUS:
11947 case EM_SPARCV9:
11948 case EM_SPARC:
3e0873ac 11949 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
11950 case EM_SPU:
11951 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
11952 case EM_TILEGX:
11953 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
11954 case EM_TILEPRO:
11955 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
11956 case EM_VISIUM:
11957 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 11958 case EM_X86_64:
8a9036a4 11959 case EM_L1OM:
7a9068fe 11960 case EM_K1OM:
3e0873ac 11961 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
11962 case EM_XTENSA_OLD:
11963 case EM_XTENSA:
11964 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
11965 default:
11966 /* Do not abort or issue an error message here. Not all targets use
11967 pc-relative 32-bit relocs in their DWARF debug information and we
11968 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
11969 more helpful warning message will be generated by apply_relocations
11970 anyway, so just return. */
aca88567
NC
11971 return FALSE;
11972 }
11973}
11974
11975/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11976 a 64-bit absolute RELA relocation used in DWARF debug sections. */
11977
11978static bfd_boolean
11979is_64bit_abs_reloc (unsigned int reloc_type)
11980{
11981 switch (elf_header.e_machine)
11982 {
a06ea964
NC
11983 case EM_AARCH64:
11984 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
11985 case EM_ALPHA:
11986 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
11987 case EM_IA_64:
11988 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
11989 case EM_PARISC:
11990 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
11991 case EM_PPC64:
11992 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
11993 case EM_RISCV:
11994 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
11995 case EM_SPARC32PLUS:
11996 case EM_SPARCV9:
11997 case EM_SPARC:
11998 return reloc_type == 54; /* R_SPARC_UA64. */
11999 case EM_X86_64:
8a9036a4 12000 case EM_L1OM:
7a9068fe 12001 case EM_K1OM:
aca88567 12002 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
12003 case EM_S390_OLD:
12004 case EM_S390:
aa137e4d
NC
12005 return reloc_type == 22; /* R_S390_64. */
12006 case EM_TILEGX:
12007 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 12008 case EM_MIPS:
aa137e4d 12009 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
12010 default:
12011 return FALSE;
12012 }
12013}
12014
85acf597
RH
12015/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
12016 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
12017
12018static bfd_boolean
12019is_64bit_pcrel_reloc (unsigned int reloc_type)
12020{
12021 switch (elf_header.e_machine)
12022 {
a06ea964
NC
12023 case EM_AARCH64:
12024 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 12025 case EM_ALPHA:
aa137e4d 12026 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 12027 case EM_IA_64:
aa137e4d 12028 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 12029 case EM_PARISC:
aa137e4d 12030 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 12031 case EM_PPC64:
aa137e4d 12032 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
12033 case EM_SPARC32PLUS:
12034 case EM_SPARCV9:
12035 case EM_SPARC:
aa137e4d 12036 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 12037 case EM_X86_64:
8a9036a4 12038 case EM_L1OM:
7a9068fe 12039 case EM_K1OM:
aa137e4d 12040 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
12041 case EM_S390_OLD:
12042 case EM_S390:
aa137e4d
NC
12043 return reloc_type == 23; /* R_S390_PC64. */
12044 case EM_TILEGX:
12045 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
12046 default:
12047 return FALSE;
12048 }
12049}
12050
4dc3c23d
AM
12051/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12052 a 24-bit absolute RELA relocation used in DWARF debug sections. */
12053
12054static bfd_boolean
12055is_24bit_abs_reloc (unsigned int reloc_type)
12056{
12057 switch (elf_header.e_machine)
12058 {
12059 case EM_CYGNUS_MN10200:
12060 case EM_MN10200:
12061 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
12062 case EM_FT32:
12063 return reloc_type == 5; /* R_FT32_20. */
4dc3c23d
AM
12064 default:
12065 return FALSE;
12066 }
12067}
12068
aca88567
NC
12069/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12070 a 16-bit absolute RELA relocation used in DWARF debug sections. */
12071
12072static bfd_boolean
12073is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a 12074{
d347c9df 12075 /* Please keep this table alpha-sorted for ease of visual lookup. */
4b78141a
NC
12076 switch (elf_header.e_machine)
12077 {
886a2506
NC
12078 case EM_ARC:
12079 case EM_ARC_COMPACT:
12080 case EM_ARC_COMPACT2:
12081 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
12082 case EM_ADAPTEVA_EPIPHANY:
12083 return reloc_type == 5;
aca88567
NC
12084 case EM_AVR_OLD:
12085 case EM_AVR:
12086 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
12087 case EM_CYGNUS_D10V:
12088 case EM_D10V:
12089 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
12090 case EM_H8S:
12091 case EM_H8_300:
12092 case EM_H8_300H:
aca88567
NC
12093 return reloc_type == R_H8_DIR16;
12094 case EM_IP2K_OLD:
12095 case EM_IP2K:
12096 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 12097 case EM_M32C_OLD:
f4236fe4
DD
12098 case EM_M32C:
12099 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
12100 case EM_CYGNUS_MN10200:
12101 case EM_MN10200:
12102 return reloc_type == 2; /* R_MN10200_16. */
12103 case EM_CYGNUS_MN10300:
12104 case EM_MN10300:
12105 return reloc_type == 2; /* R_MN10300_16. */
aca88567 12106 case EM_MSP430:
13761a11
NC
12107 if (uses_msp430x_relocs ())
12108 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 12109 /* Fall through. */
78c8d46c 12110 case EM_MSP430_OLD:
aca88567 12111 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
12112 case EM_NDS32:
12113 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 12114 case EM_ALTERA_NIOS2:
36591ba1 12115 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
12116 case EM_NIOS32:
12117 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
12118 case EM_OR1K:
12119 return reloc_type == 2; /* R_OR1K_16. */
40b36596
JM
12120 case EM_TI_C6000:
12121 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
12122 case EM_VISIUM:
12123 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
12124 case EM_XC16X:
12125 case EM_C166:
12126 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
12127 case EM_XGATE:
12128 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 12129 default:
aca88567 12130 return FALSE;
4b78141a
NC
12131 }
12132}
12133
2a7b2e88
JK
12134/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
12135 relocation entries (possibly formerly used for SHT_GROUP sections). */
12136
12137static bfd_boolean
12138is_none_reloc (unsigned int reloc_type)
12139{
12140 switch (elf_header.e_machine)
12141 {
cb8f3167 12142 case EM_386: /* R_386_NONE. */
d347c9df 12143 case EM_68K: /* R_68K_NONE. */
cfb8c092 12144 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
12145 case EM_ALPHA: /* R_ALPHA_NONE. */
12146 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 12147 case EM_ARC: /* R_ARC_NONE. */
886a2506 12148 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 12149 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 12150 case EM_ARM: /* R_ARM_NONE. */
d347c9df 12151 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 12152 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
12153 case EM_FT32: /* R_FT32_NONE. */
12154 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 12155 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
12156 case EM_L1OM: /* R_X86_64_NONE. */
12157 case EM_M32R: /* R_M32R_NONE. */
12158 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 12159 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 12160 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
12161 case EM_NIOS32: /* R_NIOS_NONE. */
12162 case EM_OR1K: /* R_OR1K_NONE. */
12163 case EM_PARISC: /* R_PARISC_NONE. */
12164 case EM_PPC64: /* R_PPC64_NONE. */
12165 case EM_PPC: /* R_PPC_NONE. */
e23eba97 12166 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
12167 case EM_S390: /* R_390_NONE. */
12168 case EM_S390_OLD:
12169 case EM_SH: /* R_SH_NONE. */
12170 case EM_SPARC32PLUS:
12171 case EM_SPARC: /* R_SPARC_NONE. */
12172 case EM_SPARCV9:
aa137e4d
NC
12173 case EM_TILEGX: /* R_TILEGX_NONE. */
12174 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
12175 case EM_TI_C6000:/* R_C6000_NONE. */
12176 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 12177 case EM_XC16X:
cb8f3167 12178 return reloc_type == 0;
d347c9df 12179
a06ea964
NC
12180 case EM_AARCH64:
12181 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
12182 case EM_AVR_OLD:
12183 case EM_AVR:
12184 return (reloc_type == 0 /* R_AVR_NONE. */
12185 || reloc_type == 30 /* R_AVR_DIFF8. */
12186 || reloc_type == 31 /* R_AVR_DIFF16. */
12187 || reloc_type == 32 /* R_AVR_DIFF32. */);
12188 case EM_METAG:
12189 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
12190 case EM_NDS32:
12191 return (reloc_type == 0 /* R_XTENSA_NONE. */
12192 || reloc_type == 204 /* R_NDS32_DIFF8. */
12193 || reloc_type == 205 /* R_NDS32_DIFF16. */
12194 || reloc_type == 206 /* R_NDS32_DIFF32. */
12195 || reloc_type == 207 /* R_NDS32_ULEB128. */);
58332dda
JK
12196 case EM_XTENSA_OLD:
12197 case EM_XTENSA:
4dc3c23d
AM
12198 return (reloc_type == 0 /* R_XTENSA_NONE. */
12199 || reloc_type == 17 /* R_XTENSA_DIFF8. */
12200 || reloc_type == 18 /* R_XTENSA_DIFF16. */
12201 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
12202 }
12203 return FALSE;
12204}
12205
d1c4b12b
NC
12206/* Returns TRUE if there is a relocation against
12207 section NAME at OFFSET bytes. */
12208
12209bfd_boolean
12210reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
12211{
12212 Elf_Internal_Rela * relocs;
12213 Elf_Internal_Rela * rp;
12214
12215 if (dsec == NULL || dsec->reloc_info == NULL)
12216 return FALSE;
12217
12218 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
12219
12220 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
12221 if (rp->r_offset == offset)
12222 return TRUE;
12223
12224 return FALSE;
12225}
12226
cf13d699
NC
12227/* Apply relocations to a section.
12228 Note: So far support has been added only for those relocations
12229 which can be found in debug sections.
d1c4b12b
NC
12230 If RELOCS_RETURN is non-NULL then returns in it a pointer to the
12231 loaded relocs. It is then the caller's responsibility to free them.
cf13d699 12232 FIXME: Add support for more relocations ? */
1b315056 12233
cf13d699 12234static void
d1c4b12b
NC
12235apply_relocations (void * file,
12236 const Elf_Internal_Shdr * section,
12237 unsigned char * start,
12238 bfd_size_type size,
1449284b 12239 void ** relocs_return,
d1c4b12b 12240 unsigned long * num_relocs_return)
1b315056 12241{
cf13d699 12242 Elf_Internal_Shdr * relsec;
0d2a7a93 12243 unsigned char * end = start + size;
cb8f3167 12244
d1c4b12b
NC
12245 if (relocs_return != NULL)
12246 {
12247 * (Elf_Internal_Rela **) relocs_return = NULL;
12248 * num_relocs_return = 0;
12249 }
12250
cf13d699
NC
12251 if (elf_header.e_type != ET_REL)
12252 return;
1b315056 12253
cf13d699 12254 /* Find the reloc section associated with the section. */
5b18a4bc
NC
12255 for (relsec = section_headers;
12256 relsec < section_headers + elf_header.e_shnum;
12257 ++relsec)
252b5132 12258 {
41e92641
NC
12259 bfd_boolean is_rela;
12260 unsigned long num_relocs;
2cf0635d
NC
12261 Elf_Internal_Rela * relocs;
12262 Elf_Internal_Rela * rp;
12263 Elf_Internal_Shdr * symsec;
12264 Elf_Internal_Sym * symtab;
ba5cdace 12265 unsigned long num_syms;
2cf0635d 12266 Elf_Internal_Sym * sym;
252b5132 12267
41e92641 12268 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
12269 || relsec->sh_info >= elf_header.e_shnum
12270 || section_headers + relsec->sh_info != section
c256ffe7 12271 || relsec->sh_size == 0
4fbb74a6 12272 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 12273 continue;
428409d5 12274
41e92641
NC
12275 is_rela = relsec->sh_type == SHT_RELA;
12276
12277 if (is_rela)
12278 {
3f5e193b
NC
12279 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
12280 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
12281 return;
12282 }
12283 else
12284 {
3f5e193b
NC
12285 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
12286 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
12287 return;
12288 }
12289
12290 /* SH uses RELA but uses in place value instead of the addend field. */
12291 if (elf_header.e_machine == EM_SH)
12292 is_rela = FALSE;
428409d5 12293
4fbb74a6 12294 symsec = section_headers + relsec->sh_link;
1449284b
NC
12295 if (symsec->sh_type != SHT_SYMTAB
12296 && symsec->sh_type != SHT_DYNSYM)
12297 return;
ba5cdace 12298 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 12299
41e92641 12300 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 12301 {
41e92641
NC
12302 bfd_vma addend;
12303 unsigned int reloc_type;
12304 unsigned int reloc_size;
91d6fa6a 12305 unsigned char * rloc;
ba5cdace 12306 unsigned long sym_index;
4b78141a 12307
aca88567 12308 reloc_type = get_reloc_type (rp->r_info);
41e92641 12309
98fb390a 12310 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 12311 continue;
98fb390a
NC
12312 else if (is_none_reloc (reloc_type))
12313 continue;
12314 else if (is_32bit_abs_reloc (reloc_type)
12315 || is_32bit_pcrel_reloc (reloc_type))
aca88567 12316 reloc_size = 4;
85acf597
RH
12317 else if (is_64bit_abs_reloc (reloc_type)
12318 || is_64bit_pcrel_reloc (reloc_type))
aca88567 12319 reloc_size = 8;
4dc3c23d
AM
12320 else if (is_24bit_abs_reloc (reloc_type))
12321 reloc_size = 3;
aca88567
NC
12322 else if (is_16bit_abs_reloc (reloc_type))
12323 reloc_size = 2;
12324 else
4b78141a 12325 {
bee0ee85
NC
12326 static unsigned int prev_reloc = 0;
12327 if (reloc_type != prev_reloc)
12328 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
12329 reloc_type, printable_section_name (section));
12330 prev_reloc = reloc_type;
4b78141a
NC
12331 continue;
12332 }
103f02d3 12333
91d6fa6a 12334 rloc = start + rp->r_offset;
c8da6823 12335 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
12336 {
12337 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
12338 (unsigned long) rp->r_offset,
74e1a04b 12339 printable_section_name (section));
700dd8b7
L
12340 continue;
12341 }
103f02d3 12342
ba5cdace
NC
12343 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
12344 if (sym_index >= num_syms)
12345 {
12346 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
74e1a04b 12347 sym_index, printable_section_name (section));
ba5cdace
NC
12348 continue;
12349 }
12350 sym = symtab + sym_index;
41e92641
NC
12351
12352 /* If the reloc has a symbol associated with it,
55f25fc3
L
12353 make sure that it is of an appropriate type.
12354
12355 Relocations against symbols without type can happen.
12356 Gcc -feliminate-dwarf2-dups may generate symbols
12357 without type for debug info.
12358
12359 Icc generates relocations against function symbols
12360 instead of local labels.
12361
12362 Relocations against object symbols can happen, eg when
12363 referencing a global array. For an example of this see
12364 the _clz.o binary in libgcc.a. */
aca88567 12365 if (sym != symtab
b8871f35 12366 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 12367 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 12368 {
41e92641 12369 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 12370 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 12371 (long int)(rp - relocs),
74e1a04b 12372 printable_section_name (relsec));
aca88567 12373 continue;
5b18a4bc 12374 }
252b5132 12375
4dc3c23d
AM
12376 addend = 0;
12377 if (is_rela)
12378 addend += rp->r_addend;
c47320c3
AM
12379 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
12380 partial_inplace. */
4dc3c23d
AM
12381 if (!is_rela
12382 || (elf_header.e_machine == EM_XTENSA
12383 && reloc_type == 1)
12384 || ((elf_header.e_machine == EM_PJ
12385 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
12386 && reloc_type == 1)
12387 || ((elf_header.e_machine == EM_D30V
12388 || elf_header.e_machine == EM_CYGNUS_D30V)
12389 && reloc_type == 12))
91d6fa6a 12390 addend += byte_get (rloc, reloc_size);
cb8f3167 12391
85acf597
RH
12392 if (is_32bit_pcrel_reloc (reloc_type)
12393 || is_64bit_pcrel_reloc (reloc_type))
12394 {
12395 /* On HPPA, all pc-relative relocations are biased by 8. */
12396 if (elf_header.e_machine == EM_PARISC)
12397 addend -= 8;
91d6fa6a 12398 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
12399 reloc_size);
12400 }
41e92641 12401 else
91d6fa6a 12402 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 12403 }
252b5132 12404
5b18a4bc 12405 free (symtab);
d1c4b12b
NC
12406
12407 if (relocs_return)
12408 {
12409 * (Elf_Internal_Rela **) relocs_return = relocs;
12410 * num_relocs_return = num_relocs;
12411 }
12412 else
12413 free (relocs);
12414
5b18a4bc
NC
12415 break;
12416 }
5b18a4bc 12417}
103f02d3 12418
cf13d699
NC
12419#ifdef SUPPORT_DISASSEMBLY
12420static int
12421disassemble_section (Elf_Internal_Shdr * section, FILE * file)
12422{
74e1a04b 12423 printf (_("\nAssembly dump of section %s\n"), printable_section_name (section));
cf13d699 12424
74e1a04b 12425 /* FIXME: XXX -- to be done --- XXX */
cf13d699
NC
12426
12427 return 1;
12428}
12429#endif
12430
12431/* Reads in the contents of SECTION from FILE, returning a pointer
12432 to a malloc'ed buffer or NULL if something went wrong. */
12433
12434static char *
12435get_section_contents (Elf_Internal_Shdr * section, FILE * file)
12436{
12437 bfd_size_type num_bytes;
12438
12439 num_bytes = section->sh_size;
12440
12441 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
12442 {
12443 printf (_("\nSection '%s' has no data to dump.\n"),
74e1a04b 12444 printable_section_name (section));
cf13d699
NC
12445 return NULL;
12446 }
12447
3f5e193b
NC
12448 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
12449 _("section contents"));
cf13d699
NC
12450}
12451
0e602686
NC
12452/* Uncompresses a section that was compressed using zlib, in place. */
12453
12454static bfd_boolean
12455uncompress_section_contents (unsigned char **buffer,
12456 dwarf_size_type uncompressed_size,
12457 dwarf_size_type *size)
12458{
12459 dwarf_size_type compressed_size = *size;
12460 unsigned char * compressed_buffer = *buffer;
12461 unsigned char * uncompressed_buffer;
12462 z_stream strm;
12463 int rc;
12464
12465 /* It is possible the section consists of several compressed
12466 buffers concatenated together, so we uncompress in a loop. */
12467 /* PR 18313: The state field in the z_stream structure is supposed
12468 to be invisible to the user (ie us), but some compilers will
12469 still complain about it being used without initialisation. So
12470 we first zero the entire z_stream structure and then set the fields
12471 that we need. */
12472 memset (& strm, 0, sizeof strm);
12473 strm.avail_in = compressed_size;
12474 strm.next_in = (Bytef *) compressed_buffer;
12475 strm.avail_out = uncompressed_size;
12476 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
12477
12478 rc = inflateInit (& strm);
12479 while (strm.avail_in > 0)
12480 {
12481 if (rc != Z_OK)
12482 goto fail;
12483 strm.next_out = ((Bytef *) uncompressed_buffer
12484 + (uncompressed_size - strm.avail_out));
12485 rc = inflate (&strm, Z_FINISH);
12486 if (rc != Z_STREAM_END)
12487 goto fail;
12488 rc = inflateReset (& strm);
12489 }
12490 rc = inflateEnd (& strm);
12491 if (rc != Z_OK
12492 || strm.avail_out != 0)
12493 goto fail;
12494
12495 *buffer = uncompressed_buffer;
12496 *size = uncompressed_size;
12497 return TRUE;
12498
12499 fail:
12500 free (uncompressed_buffer);
12501 /* Indicate decompression failure. */
12502 *buffer = NULL;
12503 return FALSE;
12504}
dd24e3da 12505
cf13d699
NC
12506static void
12507dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
12508{
0e602686
NC
12509 Elf_Internal_Shdr * relsec;
12510 bfd_size_type num_bytes;
fd8008d8
L
12511 unsigned char * data;
12512 unsigned char * end;
12513 unsigned char * real_start;
12514 unsigned char * start;
0e602686 12515 bfd_boolean some_strings_shown;
cf13d699 12516
fd8008d8
L
12517 real_start = start = (unsigned char *) get_section_contents (section,
12518 file);
cf13d699
NC
12519 if (start == NULL)
12520 return;
0e602686 12521 num_bytes = section->sh_size;
cf13d699 12522
74e1a04b 12523 printf (_("\nString dump of section '%s':\n"), printable_section_name (section));
cf13d699 12524
0e602686
NC
12525 if (decompress_dumps)
12526 {
12527 dwarf_size_type new_size = num_bytes;
12528 dwarf_size_type uncompressed_size = 0;
12529
12530 if ((section->sh_flags & SHF_COMPRESSED) != 0)
12531 {
12532 Elf_Internal_Chdr chdr;
12533 unsigned int compression_header_size
12534 = get_compression_header (& chdr, (unsigned char *) start);
12535
813dabb9 12536 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 12537 {
813dabb9
L
12538 warn (_("section '%s' has unsupported compress type: %d\n"),
12539 printable_section_name (section), chdr.ch_type);
12540 return;
12541 }
12542 else if (chdr.ch_addralign != section->sh_addralign)
12543 {
12544 warn (_("compressed section '%s' is corrupted\n"),
12545 printable_section_name (section));
12546 return;
0e602686 12547 }
813dabb9
L
12548 uncompressed_size = chdr.ch_size;
12549 start += compression_header_size;
12550 new_size -= compression_header_size;
0e602686
NC
12551 }
12552 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
12553 {
12554 /* Read the zlib header. In this case, it should be "ZLIB"
12555 followed by the uncompressed section size, 8 bytes in
12556 big-endian order. */
12557 uncompressed_size = start[4]; uncompressed_size <<= 8;
12558 uncompressed_size += start[5]; uncompressed_size <<= 8;
12559 uncompressed_size += start[6]; uncompressed_size <<= 8;
12560 uncompressed_size += start[7]; uncompressed_size <<= 8;
12561 uncompressed_size += start[8]; uncompressed_size <<= 8;
12562 uncompressed_size += start[9]; uncompressed_size <<= 8;
12563 uncompressed_size += start[10]; uncompressed_size <<= 8;
12564 uncompressed_size += start[11];
12565 start += 12;
12566 new_size -= 12;
12567 }
12568
12569 if (uncompressed_size
fd8008d8 12570 && uncompress_section_contents (& start,
0e602686
NC
12571 uncompressed_size, & new_size))
12572 num_bytes = new_size;
12573 }
fd8008d8 12574
cf13d699
NC
12575 /* If the section being dumped has relocations against it the user might
12576 be expecting these relocations to have been applied. Check for this
12577 case and issue a warning message in order to avoid confusion.
12578 FIXME: Maybe we ought to have an option that dumps a section with
12579 relocs applied ? */
12580 for (relsec = section_headers;
12581 relsec < section_headers + elf_header.e_shnum;
12582 ++relsec)
12583 {
12584 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
12585 || relsec->sh_info >= elf_header.e_shnum
12586 || section_headers + relsec->sh_info != section
12587 || relsec->sh_size == 0
12588 || relsec->sh_link >= elf_header.e_shnum)
12589 continue;
12590
12591 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
12592 break;
12593 }
12594
cf13d699
NC
12595 data = start;
12596 end = start + num_bytes;
12597 some_strings_shown = FALSE;
12598
12599 while (data < end)
12600 {
12601 while (!ISPRINT (* data))
12602 if (++ data >= end)
12603 break;
12604
12605 if (data < end)
12606 {
071436c6
NC
12607 size_t maxlen = end - data;
12608
cf13d699 12609#ifndef __MSVCRT__
c975cc98
NC
12610 /* PR 11128: Use two separate invocations in order to work
12611 around bugs in the Solaris 8 implementation of printf. */
12612 printf (" [%6tx] ", data - start);
cf13d699 12613#else
071436c6 12614 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 12615#endif
4082ef84
NC
12616 if (maxlen > 0)
12617 {
fd8008d8 12618 print_symbol ((int) maxlen, (const char *) data);
4082ef84 12619 putchar ('\n');
fd8008d8 12620 data += strnlen ((const char *) data, maxlen);
4082ef84
NC
12621 }
12622 else
12623 {
12624 printf (_("<corrupt>\n"));
12625 data = end;
12626 }
cf13d699
NC
12627 some_strings_shown = TRUE;
12628 }
12629 }
12630
12631 if (! some_strings_shown)
12632 printf (_(" No strings found in this section."));
12633
0e602686 12634 free (real_start);
cf13d699
NC
12635
12636 putchar ('\n');
12637}
12638
12639static void
12640dump_section_as_bytes (Elf_Internal_Shdr * section,
12641 FILE * file,
12642 bfd_boolean relocate)
12643{
12644 Elf_Internal_Shdr * relsec;
0e602686
NC
12645 bfd_size_type bytes;
12646 bfd_size_type section_size;
12647 bfd_vma addr;
12648 unsigned char * data;
12649 unsigned char * real_start;
12650 unsigned char * start;
12651
12652 real_start = start = (unsigned char *) get_section_contents (section, file);
cf13d699
NC
12653 if (start == NULL)
12654 return;
0e602686 12655 section_size = section->sh_size;
cf13d699 12656
74e1a04b 12657 printf (_("\nHex dump of section '%s':\n"), printable_section_name (section));
cf13d699 12658
0e602686
NC
12659 if (decompress_dumps)
12660 {
12661 dwarf_size_type new_size = section_size;
12662 dwarf_size_type uncompressed_size = 0;
12663
12664 if ((section->sh_flags & SHF_COMPRESSED) != 0)
12665 {
12666 Elf_Internal_Chdr chdr;
12667 unsigned int compression_header_size
12668 = get_compression_header (& chdr, start);
12669
813dabb9 12670 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 12671 {
813dabb9
L
12672 warn (_("section '%s' has unsupported compress type: %d\n"),
12673 printable_section_name (section), chdr.ch_type);
12674 return;
0e602686 12675 }
813dabb9
L
12676 else if (chdr.ch_addralign != section->sh_addralign)
12677 {
12678 warn (_("compressed section '%s' is corrupted\n"),
12679 printable_section_name (section));
12680 return;
12681 }
12682 uncompressed_size = chdr.ch_size;
12683 start += compression_header_size;
12684 new_size -= compression_header_size;
0e602686
NC
12685 }
12686 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
12687 {
12688 /* Read the zlib header. In this case, it should be "ZLIB"
12689 followed by the uncompressed section size, 8 bytes in
12690 big-endian order. */
12691 uncompressed_size = start[4]; uncompressed_size <<= 8;
12692 uncompressed_size += start[5]; uncompressed_size <<= 8;
12693 uncompressed_size += start[6]; uncompressed_size <<= 8;
12694 uncompressed_size += start[7]; uncompressed_size <<= 8;
12695 uncompressed_size += start[8]; uncompressed_size <<= 8;
12696 uncompressed_size += start[9]; uncompressed_size <<= 8;
12697 uncompressed_size += start[10]; uncompressed_size <<= 8;
12698 uncompressed_size += start[11];
12699 start += 12;
12700 new_size -= 12;
12701 }
12702
12703 if (uncompressed_size
12704 && uncompress_section_contents (& start, uncompressed_size,
12705 & new_size))
12706 section_size = new_size;
12707 }
14ae95f2 12708
cf13d699
NC
12709 if (relocate)
12710 {
0e602686 12711 apply_relocations (file, section, start, section_size, NULL, NULL);
cf13d699
NC
12712 }
12713 else
12714 {
12715 /* If the section being dumped has relocations against it the user might
12716 be expecting these relocations to have been applied. Check for this
12717 case and issue a warning message in order to avoid confusion.
12718 FIXME: Maybe we ought to have an option that dumps a section with
12719 relocs applied ? */
12720 for (relsec = section_headers;
12721 relsec < section_headers + elf_header.e_shnum;
12722 ++relsec)
12723 {
12724 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
12725 || relsec->sh_info >= elf_header.e_shnum
12726 || section_headers + relsec->sh_info != section
12727 || relsec->sh_size == 0
12728 || relsec->sh_link >= elf_header.e_shnum)
12729 continue;
12730
12731 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
12732 break;
12733 }
12734 }
12735
12736 addr = section->sh_addr;
0e602686 12737 bytes = section_size;
cf13d699
NC
12738 data = start;
12739
12740 while (bytes)
12741 {
12742 int j;
12743 int k;
12744 int lbytes;
12745
12746 lbytes = (bytes > 16 ? 16 : bytes);
12747
12748 printf (" 0x%8.8lx ", (unsigned long) addr);
12749
12750 for (j = 0; j < 16; j++)
12751 {
12752 if (j < lbytes)
12753 printf ("%2.2x", data[j]);
12754 else
12755 printf (" ");
12756
12757 if ((j & 3) == 3)
12758 printf (" ");
12759 }
12760
12761 for (j = 0; j < lbytes; j++)
12762 {
12763 k = data[j];
12764 if (k >= ' ' && k < 0x7f)
12765 printf ("%c", k);
12766 else
12767 printf (".");
12768 }
12769
12770 putchar ('\n');
12771
12772 data += lbytes;
12773 addr += lbytes;
12774 bytes -= lbytes;
12775 }
12776
0e602686 12777 free (real_start);
cf13d699
NC
12778
12779 putchar ('\n');
12780}
12781
d966045b
DJ
12782static int
12783load_specific_debug_section (enum dwarf_section_display_enum debug,
0d2a7a93 12784 const Elf_Internal_Shdr * sec, void * file)
1007acb3 12785{
2cf0635d 12786 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 12787 char buf [64];
1007acb3 12788
19e6b90e
L
12789 /* If it is already loaded, do nothing. */
12790 if (section->start != NULL)
12791 return 1;
1007acb3 12792
19e6b90e
L
12793 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
12794 section->address = sec->sh_addr;
06614111 12795 section->user_data = NULL;
3f5e193b
NC
12796 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
12797 sec->sh_offset, 1,
12798 sec->sh_size, buf);
59245841
NC
12799 if (section->start == NULL)
12800 section->size = 0;
12801 else
12802 {
77115a4a
L
12803 unsigned char *start = section->start;
12804 dwarf_size_type size = sec->sh_size;
dab394de 12805 dwarf_size_type uncompressed_size = 0;
77115a4a
L
12806
12807 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
12808 {
12809 Elf_Internal_Chdr chdr;
d8024a91
NC
12810 unsigned int compression_header_size;
12811
f53be977
L
12812 if (size < (is_32bit_elf
12813 ? sizeof (Elf32_External_Chdr)
12814 : sizeof (Elf64_External_Chdr)))
d8024a91
NC
12815 {
12816 warn (_("compressed section %s is too small to contain a compression header"),
12817 section->name);
12818 return 0;
12819 }
12820
12821 compression_header_size = get_compression_header (&chdr, start);
12822
813dabb9
L
12823 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
12824 {
12825 warn (_("section '%s' has unsupported compress type: %d\n"),
12826 section->name, chdr.ch_type);
12827 return 0;
12828 }
12829 else if (chdr.ch_addralign != sec->sh_addralign)
12830 {
12831 warn (_("compressed section '%s' is corrupted\n"),
12832 section->name);
12833 return 0;
12834 }
dab394de 12835 uncompressed_size = chdr.ch_size;
77115a4a
L
12836 start += compression_header_size;
12837 size -= compression_header_size;
12838 }
dab394de
L
12839 else if (size > 12 && streq ((char *) start, "ZLIB"))
12840 {
12841 /* Read the zlib header. In this case, it should be "ZLIB"
12842 followed by the uncompressed section size, 8 bytes in
12843 big-endian order. */
12844 uncompressed_size = start[4]; uncompressed_size <<= 8;
12845 uncompressed_size += start[5]; uncompressed_size <<= 8;
12846 uncompressed_size += start[6]; uncompressed_size <<= 8;
12847 uncompressed_size += start[7]; uncompressed_size <<= 8;
12848 uncompressed_size += start[8]; uncompressed_size <<= 8;
12849 uncompressed_size += start[9]; uncompressed_size <<= 8;
12850 uncompressed_size += start[10]; uncompressed_size <<= 8;
12851 uncompressed_size += start[11];
12852 start += 12;
12853 size -= 12;
12854 }
12855
12856 if (uncompressed_size
12857 && uncompress_section_contents (&start, uncompressed_size,
12858 &size))
77115a4a
L
12859 {
12860 /* Free the compressed buffer, update the section buffer
12861 and the section size if uncompress is successful. */
12862 free (section->start);
12863 section->start = start;
77115a4a
L
12864 }
12865 section->size = size;
59245841 12866 }
4a114e3e 12867
1b315056
CS
12868 if (section->start == NULL)
12869 return 0;
12870
19e6b90e 12871 if (debug_displays [debug].relocate)
d1c4b12b
NC
12872 apply_relocations ((FILE *) file, sec, section->start, section->size,
12873 & section->reloc_info, & section->num_relocs);
12874 else
12875 {
12876 section->reloc_info = NULL;
12877 section->num_relocs = 0;
12878 }
1007acb3 12879
1b315056 12880 return 1;
1007acb3
L
12881}
12882
657d0d47
CC
12883/* If this is not NULL, load_debug_section will only look for sections
12884 within the list of sections given here. */
12885unsigned int *section_subset = NULL;
12886
d966045b 12887int
2cf0635d 12888load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 12889{
2cf0635d
NC
12890 struct dwarf_section * section = &debug_displays [debug].section;
12891 Elf_Internal_Shdr * sec;
d966045b
DJ
12892
12893 /* Locate the debug section. */
657d0d47 12894 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
12895 if (sec != NULL)
12896 section->name = section->uncompressed_name;
12897 else
12898 {
657d0d47 12899 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
12900 if (sec != NULL)
12901 section->name = section->compressed_name;
12902 }
12903 if (sec == NULL)
12904 return 0;
12905
657d0d47
CC
12906 /* If we're loading from a subset of sections, and we've loaded
12907 a section matching this name before, it's likely that it's a
12908 different one. */
12909 if (section_subset != NULL)
12910 free_debug_section (debug);
12911
3f5e193b 12912 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
12913}
12914
19e6b90e
L
12915void
12916free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 12917{
2cf0635d 12918 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 12919
19e6b90e
L
12920 if (section->start == NULL)
12921 return;
1007acb3 12922
19e6b90e
L
12923 free ((char *) section->start);
12924 section->start = NULL;
12925 section->address = 0;
12926 section->size = 0;
1007acb3
L
12927}
12928
1007acb3 12929static int
657d0d47 12930display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 12931{
2cf0635d 12932 char * name = SECTION_NAME (section);
74e1a04b 12933 const char * print_name = printable_section_name (section);
19e6b90e
L
12934 bfd_size_type length;
12935 int result = 1;
3f5e193b 12936 int i;
1007acb3 12937
19e6b90e
L
12938 length = section->sh_size;
12939 if (length == 0)
1007acb3 12940 {
74e1a04b 12941 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
19e6b90e 12942 return 0;
1007acb3 12943 }
5dff79d8
NC
12944 if (section->sh_type == SHT_NOBITS)
12945 {
12946 /* There is no point in dumping the contents of a debugging section
12947 which has the NOBITS type - the bits in the file will be random.
12948 This can happen when a file containing a .eh_frame section is
12949 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
12950 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
12951 print_name);
5dff79d8
NC
12952 return 0;
12953 }
1007acb3 12954
0112cd26 12955 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 12956 name = ".debug_info";
1007acb3 12957
19e6b90e
L
12958 /* See if we know how to display the contents of this section. */
12959 for (i = 0; i < max; i++)
1b315056 12960 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 12961 || (i == line && const_strneq (name, ".debug_line."))
1b315056 12962 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 12963 {
2cf0635d 12964 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
12965 int secondary = (section != find_section (name));
12966
12967 if (secondary)
3f5e193b 12968 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 12969
b40bf0a2
NC
12970 if (i == line && const_strneq (name, ".debug_line."))
12971 sec->name = name;
12972 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
12973 sec->name = sec->uncompressed_name;
12974 else
12975 sec->name = sec->compressed_name;
3f5e193b
NC
12976 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
12977 section, file))
19e6b90e 12978 {
657d0d47
CC
12979 /* If this debug section is part of a CU/TU set in a .dwp file,
12980 restrict load_debug_section to the sections in that set. */
12981 section_subset = find_cu_tu_set (file, shndx);
12982
19e6b90e 12983 result &= debug_displays[i].display (sec, file);
1007acb3 12984
657d0d47
CC
12985 section_subset = NULL;
12986
d966045b 12987 if (secondary || (i != info && i != abbrev))
3f5e193b 12988 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 12989 }
1007acb3 12990
19e6b90e
L
12991 break;
12992 }
1007acb3 12993
19e6b90e 12994 if (i == max)
1007acb3 12995 {
74e1a04b 12996 printf (_("Unrecognized debug section: %s\n"), print_name);
19e6b90e 12997 result = 0;
1007acb3
L
12998 }
12999
19e6b90e 13000 return result;
5b18a4bc 13001}
103f02d3 13002
aef1f6d0
DJ
13003/* Set DUMP_SECTS for all sections where dumps were requested
13004 based on section name. */
13005
13006static void
13007initialise_dumps_byname (void)
13008{
2cf0635d 13009 struct dump_list_entry * cur;
aef1f6d0
DJ
13010
13011 for (cur = dump_sects_byname; cur; cur = cur->next)
13012 {
13013 unsigned int i;
13014 int any;
13015
13016 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
13017 if (streq (SECTION_NAME (section_headers + i), cur->name))
13018 {
09c11c86 13019 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
13020 any = 1;
13021 }
13022
13023 if (!any)
13024 warn (_("Section '%s' was not dumped because it does not exist!\n"),
13025 cur->name);
13026 }
13027}
13028
5b18a4bc 13029static void
2cf0635d 13030process_section_contents (FILE * file)
5b18a4bc 13031{
2cf0635d 13032 Elf_Internal_Shdr * section;
19e6b90e 13033 unsigned int i;
103f02d3 13034
19e6b90e
L
13035 if (! do_dump)
13036 return;
103f02d3 13037
aef1f6d0
DJ
13038 initialise_dumps_byname ();
13039
19e6b90e
L
13040 for (i = 0, section = section_headers;
13041 i < elf_header.e_shnum && i < num_dump_sects;
13042 i++, section++)
13043 {
13044#ifdef SUPPORT_DISASSEMBLY
13045 if (dump_sects[i] & DISASS_DUMP)
13046 disassemble_section (section, file);
13047#endif
13048 if (dump_sects[i] & HEX_DUMP)
cf13d699 13049 dump_section_as_bytes (section, file, FALSE);
103f02d3 13050
cf13d699
NC
13051 if (dump_sects[i] & RELOC_DUMP)
13052 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
13053
13054 if (dump_sects[i] & STRING_DUMP)
13055 dump_section_as_strings (section, file);
cf13d699
NC
13056
13057 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 13058 display_debug_section (i, section, file);
5b18a4bc 13059 }
103f02d3 13060
19e6b90e
L
13061 /* Check to see if the user requested a
13062 dump of a section that does not exist. */
13063 while (i++ < num_dump_sects)
13064 if (dump_sects[i])
13065 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 13066}
103f02d3 13067
5b18a4bc 13068static void
19e6b90e 13069process_mips_fpe_exception (int mask)
5b18a4bc 13070{
19e6b90e
L
13071 if (mask)
13072 {
13073 int first = 1;
13074 if (mask & OEX_FPU_INEX)
13075 fputs ("INEX", stdout), first = 0;
13076 if (mask & OEX_FPU_UFLO)
13077 printf ("%sUFLO", first ? "" : "|"), first = 0;
13078 if (mask & OEX_FPU_OFLO)
13079 printf ("%sOFLO", first ? "" : "|"), first = 0;
13080 if (mask & OEX_FPU_DIV0)
13081 printf ("%sDIV0", first ? "" : "|"), first = 0;
13082 if (mask & OEX_FPU_INVAL)
13083 printf ("%sINVAL", first ? "" : "|");
13084 }
5b18a4bc 13085 else
19e6b90e 13086 fputs ("0", stdout);
5b18a4bc 13087}
103f02d3 13088
f6f0e17b
NC
13089/* Display's the value of TAG at location P. If TAG is
13090 greater than 0 it is assumed to be an unknown tag, and
13091 a message is printed to this effect. Otherwise it is
13092 assumed that a message has already been printed.
13093
13094 If the bottom bit of TAG is set it assumed to have a
13095 string value, otherwise it is assumed to have an integer
13096 value.
13097
13098 Returns an updated P pointing to the first unread byte
13099 beyond the end of TAG's value.
13100
13101 Reads at or beyond END will not be made. */
13102
13103static unsigned char *
13104display_tag_value (int tag,
13105 unsigned char * p,
13106 const unsigned char * const end)
13107{
13108 unsigned long val;
13109
13110 if (tag > 0)
13111 printf (" Tag_unknown_%d: ", tag);
13112
13113 if (p >= end)
13114 {
4082ef84 13115 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
13116 }
13117 else if (tag & 1)
13118 {
071436c6
NC
13119 /* PR 17531 file: 027-19978-0.004. */
13120 size_t maxlen = (end - p) - 1;
13121
13122 putchar ('"');
4082ef84
NC
13123 if (maxlen > 0)
13124 {
13125 print_symbol ((int) maxlen, (const char *) p);
13126 p += strnlen ((char *) p, maxlen) + 1;
13127 }
13128 else
13129 {
13130 printf (_("<corrupt string tag>"));
13131 p = (unsigned char *) end;
13132 }
071436c6 13133 printf ("\"\n");
f6f0e17b
NC
13134 }
13135 else
13136 {
13137 unsigned int len;
13138
13139 val = read_uleb128 (p, &len, end);
13140 p += len;
13141 printf ("%ld (0x%lx)\n", val, val);
13142 }
13143
4082ef84 13144 assert (p <= end);
f6f0e17b
NC
13145 return p;
13146}
13147
11c1ff18
PB
13148/* ARM EABI attributes section. */
13149typedef struct
13150{
70e99720 13151 unsigned int tag;
2cf0635d 13152 const char * name;
11c1ff18 13153 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 13154 unsigned int type;
2cf0635d 13155 const char ** table;
11c1ff18
PB
13156} arm_attr_public_tag;
13157
2cf0635d 13158static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 13159 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ff8646ee
TP
13160 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "", "v8-M.baseline",
13161 "v8-M.mainline"};
2cf0635d
NC
13162static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
13163static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 13164 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 13165static const char * arm_attr_tag_FP_arch[] =
bca38921 13166 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 13167 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 13168static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 13169static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
13170 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
13171 "NEON for ARMv8.1"};
2cf0635d 13172static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
13173 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
13174 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 13175static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 13176 {"V6", "SB", "TLS", "Unused"};
2cf0635d 13177static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 13178 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 13179static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 13180 {"Absolute", "PC-relative", "None"};
2cf0635d 13181static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 13182 {"None", "direct", "GOT-indirect"};
2cf0635d 13183static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 13184 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
13185static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
13186static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 13187 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
13188static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
13189static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
13190static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 13191 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 13192static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 13193 {"Unused", "small", "int", "forced to int"};
2cf0635d 13194static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 13195 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 13196static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 13197 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 13198static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 13199 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 13200static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
13201 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
13202 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 13203static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
13204 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
13205 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 13206static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 13207static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 13208 {"Not Allowed", "Allowed"};
2cf0635d 13209static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 13210 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
13211static const char * arm_attr_tag_DSP_extension[] =
13212 {"Follow architecture", "Allowed"};
dd24e3da 13213static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
13214 {"Not Allowed", "Allowed"};
13215static const char * arm_attr_tag_DIV_use[] =
dd24e3da 13216 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 13217 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
13218static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
13219static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 13220 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 13221 "TrustZone and Virtualization Extensions"};
dd24e3da 13222static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 13223 {"Not Allowed", "Allowed"};
11c1ff18
PB
13224
13225#define LOOKUP(id, name) \
13226 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 13227static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
13228{
13229 {4, "CPU_raw_name", 1, NULL},
13230 {5, "CPU_name", 1, NULL},
13231 LOOKUP(6, CPU_arch),
13232 {7, "CPU_arch_profile", 0, NULL},
13233 LOOKUP(8, ARM_ISA_use),
13234 LOOKUP(9, THUMB_ISA_use),
75375b3e 13235 LOOKUP(10, FP_arch),
11c1ff18 13236 LOOKUP(11, WMMX_arch),
f5f53991
AS
13237 LOOKUP(12, Advanced_SIMD_arch),
13238 LOOKUP(13, PCS_config),
11c1ff18
PB
13239 LOOKUP(14, ABI_PCS_R9_use),
13240 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 13241 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
13242 LOOKUP(17, ABI_PCS_GOT_use),
13243 LOOKUP(18, ABI_PCS_wchar_t),
13244 LOOKUP(19, ABI_FP_rounding),
13245 LOOKUP(20, ABI_FP_denormal),
13246 LOOKUP(21, ABI_FP_exceptions),
13247 LOOKUP(22, ABI_FP_user_exceptions),
13248 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
13249 {24, "ABI_align_needed", 0, NULL},
13250 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
13251 LOOKUP(26, ABI_enum_size),
13252 LOOKUP(27, ABI_HardFP_use),
13253 LOOKUP(28, ABI_VFP_args),
13254 LOOKUP(29, ABI_WMMX_args),
13255 LOOKUP(30, ABI_optimization_goals),
13256 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 13257 {32, "compatibility", 0, NULL},
f5f53991 13258 LOOKUP(34, CPU_unaligned_access),
75375b3e 13259 LOOKUP(36, FP_HP_extension),
8e79c3df 13260 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
13261 LOOKUP(42, MPextension_use),
13262 LOOKUP(44, DIV_use),
15afaa63 13263 LOOKUP(46, DSP_extension),
f5f53991
AS
13264 {64, "nodefaults", 0, NULL},
13265 {65, "also_compatible_with", 0, NULL},
13266 LOOKUP(66, T2EE_use),
13267 {67, "conformance", 1, NULL},
13268 LOOKUP(68, Virtualization_use),
cd21e546 13269 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
13270};
13271#undef LOOKUP
13272
11c1ff18 13273static unsigned char *
f6f0e17b
NC
13274display_arm_attribute (unsigned char * p,
13275 const unsigned char * const end)
11c1ff18 13276{
70e99720 13277 unsigned int tag;
11c1ff18 13278 unsigned int len;
70e99720 13279 unsigned int val;
2cf0635d 13280 arm_attr_public_tag * attr;
11c1ff18 13281 unsigned i;
70e99720 13282 unsigned int type;
11c1ff18 13283
f6f0e17b 13284 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
13285 p += len;
13286 attr = NULL;
2cf0635d 13287 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
13288 {
13289 if (arm_attr_public_tags[i].tag == tag)
13290 {
13291 attr = &arm_attr_public_tags[i];
13292 break;
13293 }
13294 }
13295
13296 if (attr)
13297 {
13298 printf (" Tag_%s: ", attr->name);
13299 switch (attr->type)
13300 {
13301 case 0:
13302 switch (tag)
13303 {
13304 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 13305 val = read_uleb128 (p, &len, end);
11c1ff18
PB
13306 p += len;
13307 switch (val)
13308 {
2b692964
NC
13309 case 0: printf (_("None\n")); break;
13310 case 'A': printf (_("Application\n")); break;
13311 case 'R': printf (_("Realtime\n")); break;
13312 case 'M': printf (_("Microcontroller\n")); break;
13313 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
13314 default: printf ("??? (%d)\n", val); break;
13315 }
13316 break;
13317
75375b3e 13318 case 24: /* Tag_align_needed. */
f6f0e17b 13319 val = read_uleb128 (p, &len, end);
75375b3e
MGD
13320 p += len;
13321 switch (val)
13322 {
2b692964
NC
13323 case 0: printf (_("None\n")); break;
13324 case 1: printf (_("8-byte\n")); break;
13325 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
13326 case 3: printf ("??? 3\n"); break;
13327 default:
13328 if (val <= 12)
dd24e3da 13329 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
13330 1 << val);
13331 else
13332 printf ("??? (%d)\n", val);
13333 break;
13334 }
13335 break;
13336
13337 case 25: /* Tag_align_preserved. */
f6f0e17b 13338 val = read_uleb128 (p, &len, end);
75375b3e
MGD
13339 p += len;
13340 switch (val)
13341 {
2b692964
NC
13342 case 0: printf (_("None\n")); break;
13343 case 1: printf (_("8-byte, except leaf SP\n")); break;
13344 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
13345 case 3: printf ("??? 3\n"); break;
13346 default:
13347 if (val <= 12)
dd24e3da 13348 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
13349 1 << val);
13350 else
13351 printf ("??? (%d)\n", val);
13352 break;
13353 }
13354 break;
13355
11c1ff18 13356 case 32: /* Tag_compatibility. */
071436c6 13357 {
071436c6
NC
13358 val = read_uleb128 (p, &len, end);
13359 p += len;
071436c6 13360 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
13361 if (p < end - 1)
13362 {
13363 size_t maxlen = (end - p) - 1;
13364
13365 print_symbol ((int) maxlen, (const char *) p);
13366 p += strnlen ((char *) p, maxlen) + 1;
13367 }
13368 else
13369 {
13370 printf (_("<corrupt>"));
13371 p = (unsigned char *) end;
13372 }
071436c6 13373 putchar ('\n');
071436c6 13374 }
11c1ff18
PB
13375 break;
13376
f5f53991 13377 case 64: /* Tag_nodefaults. */
541a3cbd
NC
13378 /* PR 17531: file: 001-505008-0.01. */
13379 if (p < end)
13380 p++;
2b692964 13381 printf (_("True\n"));
f5f53991
AS
13382 break;
13383
13384 case 65: /* Tag_also_compatible_with. */
f6f0e17b 13385 val = read_uleb128 (p, &len, end);
f5f53991
AS
13386 p += len;
13387 if (val == 6 /* Tag_CPU_arch. */)
13388 {
f6f0e17b 13389 val = read_uleb128 (p, &len, end);
f5f53991 13390 p += len;
071436c6 13391 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
13392 printf ("??? (%d)\n", val);
13393 else
13394 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
13395 }
13396 else
13397 printf ("???\n");
071436c6
NC
13398 while (p < end && *(p++) != '\0' /* NUL terminator. */)
13399 ;
f5f53991
AS
13400 break;
13401
11c1ff18 13402 default:
bee0ee85
NC
13403 printf (_("<unknown: %d>\n"), tag);
13404 break;
11c1ff18
PB
13405 }
13406 return p;
13407
13408 case 1:
f6f0e17b 13409 return display_tag_value (-1, p, end);
11c1ff18 13410 case 2:
f6f0e17b 13411 return display_tag_value (0, p, end);
11c1ff18
PB
13412
13413 default:
13414 assert (attr->type & 0x80);
f6f0e17b 13415 val = read_uleb128 (p, &len, end);
11c1ff18
PB
13416 p += len;
13417 type = attr->type & 0x7f;
13418 if (val >= type)
13419 printf ("??? (%d)\n", val);
13420 else
13421 printf ("%s\n", attr->table[val]);
13422 return p;
13423 }
13424 }
11c1ff18 13425
f6f0e17b 13426 return display_tag_value (tag, p, end);
11c1ff18
PB
13427}
13428
104d59d1 13429static unsigned char *
60bca95a 13430display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
13431 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
13432 const unsigned char * const end)
104d59d1
JM
13433{
13434 int tag;
13435 unsigned int len;
13436 int val;
104d59d1 13437
f6f0e17b 13438 tag = read_uleb128 (p, &len, end);
104d59d1
JM
13439 p += len;
13440
13441 /* Tag_compatibility is the only generic GNU attribute defined at
13442 present. */
13443 if (tag == 32)
13444 {
f6f0e17b 13445 val = read_uleb128 (p, &len, end);
104d59d1 13446 p += len;
071436c6
NC
13447
13448 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
13449 if (p == end)
13450 {
071436c6 13451 printf (_("<corrupt>\n"));
f6f0e17b
NC
13452 warn (_("corrupt vendor attribute\n"));
13453 }
13454 else
13455 {
4082ef84
NC
13456 if (p < end - 1)
13457 {
13458 size_t maxlen = (end - p) - 1;
071436c6 13459
4082ef84
NC
13460 print_symbol ((int) maxlen, (const char *) p);
13461 p += strnlen ((char *) p, maxlen) + 1;
13462 }
13463 else
13464 {
13465 printf (_("<corrupt>"));
13466 p = (unsigned char *) end;
13467 }
071436c6 13468 putchar ('\n');
f6f0e17b 13469 }
104d59d1
JM
13470 return p;
13471 }
13472
13473 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 13474 return display_proc_gnu_attribute (p, tag, end);
104d59d1 13475
f6f0e17b 13476 return display_tag_value (tag, p, end);
104d59d1
JM
13477}
13478
34c8bcba 13479static unsigned char *
f6f0e17b
NC
13480display_power_gnu_attribute (unsigned char * p,
13481 int tag,
13482 const unsigned char * const end)
34c8bcba 13483{
34c8bcba 13484 unsigned int len;
005d79fd 13485 unsigned int val;
34c8bcba
JM
13486
13487 if (tag == Tag_GNU_Power_ABI_FP)
13488 {
f6f0e17b 13489 val = read_uleb128 (p, &len, end);
34c8bcba
JM
13490 p += len;
13491 printf (" Tag_GNU_Power_ABI_FP: ");
005d79fd
AM
13492 if (len == 0)
13493 {
13494 printf (_("<corrupt>\n"));
13495 return p;
13496 }
60bca95a 13497
005d79fd
AM
13498 if (val > 15)
13499 printf ("(%#x), ", val);
13500
13501 switch (val & 3)
34c8bcba
JM
13502 {
13503 case 0:
005d79fd 13504 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
13505 break;
13506 case 1:
005d79fd 13507 printf (_("hard float, "));
34c8bcba
JM
13508 break;
13509 case 2:
005d79fd 13510 printf (_("soft float, "));
34c8bcba 13511 break;
3c7b9897 13512 case 3:
005d79fd 13513 printf (_("single-precision hard float, "));
3c7b9897 13514 break;
005d79fd
AM
13515 }
13516
13517 switch (val & 0xC)
13518 {
13519 case 0:
13520 printf (_("unspecified long double\n"));
13521 break;
13522 case 4:
13523 printf (_("128-bit IBM long double\n"));
13524 break;
13525 case 8:
13526 printf (_("64-bit long double\n"));
13527 break;
13528 case 12:
13529 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
13530 break;
13531 }
13532 return p;
005d79fd 13533 }
34c8bcba 13534
c6e65352
DJ
13535 if (tag == Tag_GNU_Power_ABI_Vector)
13536 {
f6f0e17b 13537 val = read_uleb128 (p, &len, end);
c6e65352
DJ
13538 p += len;
13539 printf (" Tag_GNU_Power_ABI_Vector: ");
005d79fd
AM
13540 if (len == 0)
13541 {
13542 printf (_("<corrupt>\n"));
13543 return p;
13544 }
13545
13546 if (val > 3)
13547 printf ("(%#x), ", val);
13548
13549 switch (val & 3)
c6e65352
DJ
13550 {
13551 case 0:
005d79fd 13552 printf (_("unspecified\n"));
c6e65352
DJ
13553 break;
13554 case 1:
005d79fd 13555 printf (_("generic\n"));
c6e65352
DJ
13556 break;
13557 case 2:
13558 printf ("AltiVec\n");
13559 break;
13560 case 3:
13561 printf ("SPE\n");
13562 break;
c6e65352
DJ
13563 }
13564 return p;
005d79fd 13565 }
c6e65352 13566
f82e0623
NF
13567 if (tag == Tag_GNU_Power_ABI_Struct_Return)
13568 {
005d79fd
AM
13569 val = read_uleb128 (p, &len, end);
13570 p += len;
13571 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
13572 if (len == 0)
f6f0e17b 13573 {
005d79fd 13574 printf (_("<corrupt>\n"));
f6f0e17b
NC
13575 return p;
13576 }
0b4362b0 13577
005d79fd
AM
13578 if (val > 2)
13579 printf ("(%#x), ", val);
13580
13581 switch (val & 3)
13582 {
13583 case 0:
13584 printf (_("unspecified\n"));
13585 break;
13586 case 1:
13587 printf ("r3/r4\n");
13588 break;
13589 case 2:
13590 printf (_("memory\n"));
13591 break;
13592 case 3:
13593 printf ("???\n");
13594 break;
13595 }
f82e0623
NF
13596 return p;
13597 }
13598
f6f0e17b 13599 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
13600}
13601
643f7afb
AK
13602static unsigned char *
13603display_s390_gnu_attribute (unsigned char * p,
13604 int tag,
13605 const unsigned char * const end)
13606{
13607 unsigned int len;
13608 int val;
13609
13610 if (tag == Tag_GNU_S390_ABI_Vector)
13611 {
13612 val = read_uleb128 (p, &len, end);
13613 p += len;
13614 printf (" Tag_GNU_S390_ABI_Vector: ");
13615
13616 switch (val)
13617 {
13618 case 0:
13619 printf (_("any\n"));
13620 break;
13621 case 1:
13622 printf (_("software\n"));
13623 break;
13624 case 2:
13625 printf (_("hardware\n"));
13626 break;
13627 default:
13628 printf ("??? (%d)\n", val);
13629 break;
13630 }
13631 return p;
13632 }
13633
13634 return display_tag_value (tag & 1, p, end);
13635}
13636
9e8c70f9
DM
13637static void
13638display_sparc_hwcaps (int mask)
13639{
13640 if (mask)
13641 {
13642 int first = 1;
071436c6 13643
9e8c70f9
DM
13644 if (mask & ELF_SPARC_HWCAP_MUL32)
13645 fputs ("mul32", stdout), first = 0;
13646 if (mask & ELF_SPARC_HWCAP_DIV32)
13647 printf ("%sdiv32", first ? "" : "|"), first = 0;
13648 if (mask & ELF_SPARC_HWCAP_FSMULD)
13649 printf ("%sfsmuld", first ? "" : "|"), first = 0;
13650 if (mask & ELF_SPARC_HWCAP_V8PLUS)
13651 printf ("%sv8plus", first ? "" : "|"), first = 0;
13652 if (mask & ELF_SPARC_HWCAP_POPC)
13653 printf ("%spopc", first ? "" : "|"), first = 0;
13654 if (mask & ELF_SPARC_HWCAP_VIS)
13655 printf ("%svis", first ? "" : "|"), first = 0;
13656 if (mask & ELF_SPARC_HWCAP_VIS2)
13657 printf ("%svis2", first ? "" : "|"), first = 0;
13658 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
13659 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
13660 if (mask & ELF_SPARC_HWCAP_FMAF)
13661 printf ("%sfmaf", first ? "" : "|"), first = 0;
13662 if (mask & ELF_SPARC_HWCAP_VIS3)
13663 printf ("%svis3", first ? "" : "|"), first = 0;
13664 if (mask & ELF_SPARC_HWCAP_HPC)
13665 printf ("%shpc", first ? "" : "|"), first = 0;
13666 if (mask & ELF_SPARC_HWCAP_RANDOM)
13667 printf ("%srandom", first ? "" : "|"), first = 0;
13668 if (mask & ELF_SPARC_HWCAP_TRANS)
13669 printf ("%strans", first ? "" : "|"), first = 0;
13670 if (mask & ELF_SPARC_HWCAP_FJFMAU)
13671 printf ("%sfjfmau", first ? "" : "|"), first = 0;
13672 if (mask & ELF_SPARC_HWCAP_IMA)
13673 printf ("%sima", first ? "" : "|"), first = 0;
13674 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
13675 printf ("%scspare", first ? "" : "|"), first = 0;
13676 }
13677 else
071436c6
NC
13678 fputc ('0', stdout);
13679 fputc ('\n', stdout);
9e8c70f9
DM
13680}
13681
3d68f91c
JM
13682static void
13683display_sparc_hwcaps2 (int mask)
13684{
13685 if (mask)
13686 {
13687 int first = 1;
071436c6 13688
3d68f91c
JM
13689 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
13690 fputs ("fjathplus", stdout), first = 0;
13691 if (mask & ELF_SPARC_HWCAP2_VIS3B)
13692 printf ("%svis3b", first ? "" : "|"), first = 0;
13693 if (mask & ELF_SPARC_HWCAP2_ADP)
13694 printf ("%sadp", first ? "" : "|"), first = 0;
13695 if (mask & ELF_SPARC_HWCAP2_SPARC5)
13696 printf ("%ssparc5", first ? "" : "|"), first = 0;
13697 if (mask & ELF_SPARC_HWCAP2_MWAIT)
13698 printf ("%smwait", first ? "" : "|"), first = 0;
13699 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
13700 printf ("%sxmpmul", first ? "" : "|"), first = 0;
13701 if (mask & ELF_SPARC_HWCAP2_XMONT)
13702 printf ("%sxmont2", first ? "" : "|"), first = 0;
13703 if (mask & ELF_SPARC_HWCAP2_NSEC)
13704 printf ("%snsec", first ? "" : "|"), first = 0;
13705 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
13706 printf ("%sfjathhpc", first ? "" : "|"), first = 0;
13707 if (mask & ELF_SPARC_HWCAP2_FJDES)
13708 printf ("%sfjdes", first ? "" : "|"), first = 0;
13709 if (mask & ELF_SPARC_HWCAP2_FJAES)
13710 printf ("%sfjaes", first ? "" : "|"), first = 0;
13711 }
13712 else
071436c6
NC
13713 fputc ('0', stdout);
13714 fputc ('\n', stdout);
3d68f91c
JM
13715}
13716
9e8c70f9 13717static unsigned char *
f6f0e17b
NC
13718display_sparc_gnu_attribute (unsigned char * p,
13719 int tag,
13720 const unsigned char * const end)
9e8c70f9 13721{
3d68f91c
JM
13722 unsigned int len;
13723 int val;
13724
9e8c70f9
DM
13725 if (tag == Tag_GNU_Sparc_HWCAPS)
13726 {
f6f0e17b 13727 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
13728 p += len;
13729 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
13730 display_sparc_hwcaps (val);
13731 return p;
3d68f91c
JM
13732 }
13733 if (tag == Tag_GNU_Sparc_HWCAPS2)
13734 {
13735 val = read_uleb128 (p, &len, end);
13736 p += len;
13737 printf (" Tag_GNU_Sparc_HWCAPS2: ");
13738 display_sparc_hwcaps2 (val);
13739 return p;
13740 }
9e8c70f9 13741
f6f0e17b 13742 return display_tag_value (tag, p, end);
9e8c70f9
DM
13743}
13744
351cdf24
MF
13745static void
13746print_mips_fp_abi_value (int val)
13747{
13748 switch (val)
13749 {
13750 case Val_GNU_MIPS_ABI_FP_ANY:
13751 printf (_("Hard or soft float\n"));
13752 break;
13753 case Val_GNU_MIPS_ABI_FP_DOUBLE:
13754 printf (_("Hard float (double precision)\n"));
13755 break;
13756 case Val_GNU_MIPS_ABI_FP_SINGLE:
13757 printf (_("Hard float (single precision)\n"));
13758 break;
13759 case Val_GNU_MIPS_ABI_FP_SOFT:
13760 printf (_("Soft float\n"));
13761 break;
13762 case Val_GNU_MIPS_ABI_FP_OLD_64:
13763 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
13764 break;
13765 case Val_GNU_MIPS_ABI_FP_XX:
13766 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
13767 break;
13768 case Val_GNU_MIPS_ABI_FP_64:
13769 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
13770 break;
13771 case Val_GNU_MIPS_ABI_FP_64A:
13772 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
13773 break;
3350cc01
CM
13774 case Val_GNU_MIPS_ABI_FP_NAN2008:
13775 printf (_("NaN 2008 compatibility\n"));
13776 break;
351cdf24
MF
13777 default:
13778 printf ("??? (%d)\n", val);
13779 break;
13780 }
13781}
13782
2cf19d5c 13783static unsigned char *
f6f0e17b
NC
13784display_mips_gnu_attribute (unsigned char * p,
13785 int tag,
13786 const unsigned char * const end)
2cf19d5c 13787{
2cf19d5c
JM
13788 if (tag == Tag_GNU_MIPS_ABI_FP)
13789 {
f6f0e17b
NC
13790 unsigned int len;
13791 int val;
13792
13793 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
13794 p += len;
13795 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 13796
351cdf24
MF
13797 print_mips_fp_abi_value (val);
13798
2cf19d5c
JM
13799 return p;
13800 }
13801
a9f58168
CF
13802 if (tag == Tag_GNU_MIPS_ABI_MSA)
13803 {
13804 unsigned int len;
13805 int val;
13806
13807 val = read_uleb128 (p, &len, end);
13808 p += len;
13809 printf (" Tag_GNU_MIPS_ABI_MSA: ");
13810
13811 switch (val)
13812 {
13813 case Val_GNU_MIPS_ABI_MSA_ANY:
13814 printf (_("Any MSA or not\n"));
13815 break;
13816 case Val_GNU_MIPS_ABI_MSA_128:
13817 printf (_("128-bit MSA\n"));
13818 break;
13819 default:
13820 printf ("??? (%d)\n", val);
13821 break;
13822 }
13823 return p;
13824 }
13825
f6f0e17b 13826 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
13827}
13828
59e6276b 13829static unsigned char *
f6f0e17b
NC
13830display_tic6x_attribute (unsigned char * p,
13831 const unsigned char * const end)
59e6276b
JM
13832{
13833 int tag;
13834 unsigned int len;
13835 int val;
13836
f6f0e17b 13837 tag = read_uleb128 (p, &len, end);
59e6276b
JM
13838 p += len;
13839
13840 switch (tag)
13841 {
75fa6dc1 13842 case Tag_ISA:
f6f0e17b 13843 val = read_uleb128 (p, &len, end);
59e6276b 13844 p += len;
75fa6dc1 13845 printf (" Tag_ISA: ");
59e6276b
JM
13846
13847 switch (val)
13848 {
75fa6dc1 13849 case C6XABI_Tag_ISA_none:
59e6276b
JM
13850 printf (_("None\n"));
13851 break;
75fa6dc1 13852 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
13853 printf ("C62x\n");
13854 break;
75fa6dc1 13855 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
13856 printf ("C67x\n");
13857 break;
75fa6dc1 13858 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
13859 printf ("C67x+\n");
13860 break;
75fa6dc1 13861 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
13862 printf ("C64x\n");
13863 break;
75fa6dc1 13864 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
13865 printf ("C64x+\n");
13866 break;
75fa6dc1 13867 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
13868 printf ("C674x\n");
13869 break;
13870 default:
13871 printf ("??? (%d)\n", val);
13872 break;
13873 }
13874 return p;
13875
87779176 13876 case Tag_ABI_wchar_t:
f6f0e17b 13877 val = read_uleb128 (p, &len, end);
87779176
JM
13878 p += len;
13879 printf (" Tag_ABI_wchar_t: ");
13880 switch (val)
13881 {
13882 case 0:
13883 printf (_("Not used\n"));
13884 break;
13885 case 1:
13886 printf (_("2 bytes\n"));
13887 break;
13888 case 2:
13889 printf (_("4 bytes\n"));
13890 break;
13891 default:
13892 printf ("??? (%d)\n", val);
13893 break;
13894 }
13895 return p;
13896
13897 case Tag_ABI_stack_align_needed:
f6f0e17b 13898 val = read_uleb128 (p, &len, end);
87779176
JM
13899 p += len;
13900 printf (" Tag_ABI_stack_align_needed: ");
13901 switch (val)
13902 {
13903 case 0:
13904 printf (_("8-byte\n"));
13905 break;
13906 case 1:
13907 printf (_("16-byte\n"));
13908 break;
13909 default:
13910 printf ("??? (%d)\n", val);
13911 break;
13912 }
13913 return p;
13914
13915 case Tag_ABI_stack_align_preserved:
f6f0e17b 13916 val = read_uleb128 (p, &len, end);
87779176
JM
13917 p += len;
13918 printf (" Tag_ABI_stack_align_preserved: ");
13919 switch (val)
13920 {
13921 case 0:
13922 printf (_("8-byte\n"));
13923 break;
13924 case 1:
13925 printf (_("16-byte\n"));
13926 break;
13927 default:
13928 printf ("??? (%d)\n", val);
13929 break;
13930 }
13931 return p;
13932
b5593623 13933 case Tag_ABI_DSBT:
f6f0e17b 13934 val = read_uleb128 (p, &len, end);
b5593623
JM
13935 p += len;
13936 printf (" Tag_ABI_DSBT: ");
13937 switch (val)
13938 {
13939 case 0:
13940 printf (_("DSBT addressing not used\n"));
13941 break;
13942 case 1:
13943 printf (_("DSBT addressing used\n"));
13944 break;
13945 default:
13946 printf ("??? (%d)\n", val);
13947 break;
13948 }
13949 return p;
13950
87779176 13951 case Tag_ABI_PID:
f6f0e17b 13952 val = read_uleb128 (p, &len, end);
87779176
JM
13953 p += len;
13954 printf (" Tag_ABI_PID: ");
13955 switch (val)
13956 {
13957 case 0:
13958 printf (_("Data addressing position-dependent\n"));
13959 break;
13960 case 1:
13961 printf (_("Data addressing position-independent, GOT near DP\n"));
13962 break;
13963 case 2:
13964 printf (_("Data addressing position-independent, GOT far from DP\n"));
13965 break;
13966 default:
13967 printf ("??? (%d)\n", val);
13968 break;
13969 }
13970 return p;
13971
13972 case Tag_ABI_PIC:
f6f0e17b 13973 val = read_uleb128 (p, &len, end);
87779176
JM
13974 p += len;
13975 printf (" Tag_ABI_PIC: ");
13976 switch (val)
13977 {
13978 case 0:
13979 printf (_("Code addressing position-dependent\n"));
13980 break;
13981 case 1:
13982 printf (_("Code addressing position-independent\n"));
13983 break;
13984 default:
13985 printf ("??? (%d)\n", val);
13986 break;
13987 }
13988 return p;
13989
13990 case Tag_ABI_array_object_alignment:
f6f0e17b 13991 val = read_uleb128 (p, &len, end);
87779176
JM
13992 p += len;
13993 printf (" Tag_ABI_array_object_alignment: ");
13994 switch (val)
13995 {
13996 case 0:
13997 printf (_("8-byte\n"));
13998 break;
13999 case 1:
14000 printf (_("4-byte\n"));
14001 break;
14002 case 2:
14003 printf (_("16-byte\n"));
14004 break;
14005 default:
14006 printf ("??? (%d)\n", val);
14007 break;
14008 }
14009 return p;
14010
14011 case Tag_ABI_array_object_align_expected:
f6f0e17b 14012 val = read_uleb128 (p, &len, end);
87779176
JM
14013 p += len;
14014 printf (" Tag_ABI_array_object_align_expected: ");
14015 switch (val)
14016 {
14017 case 0:
14018 printf (_("8-byte\n"));
14019 break;
14020 case 1:
14021 printf (_("4-byte\n"));
14022 break;
14023 case 2:
14024 printf (_("16-byte\n"));
14025 break;
14026 default:
14027 printf ("??? (%d)\n", val);
14028 break;
14029 }
14030 return p;
14031
3cbd1c06 14032 case Tag_ABI_compatibility:
071436c6 14033 {
071436c6
NC
14034 val = read_uleb128 (p, &len, end);
14035 p += len;
14036 printf (" Tag_ABI_compatibility: ");
071436c6 14037 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
14038 if (p < end - 1)
14039 {
14040 size_t maxlen = (end - p) - 1;
14041
14042 print_symbol ((int) maxlen, (const char *) p);
14043 p += strnlen ((char *) p, maxlen) + 1;
14044 }
14045 else
14046 {
14047 printf (_("<corrupt>"));
14048 p = (unsigned char *) end;
14049 }
071436c6 14050 putchar ('\n');
071436c6
NC
14051 return p;
14052 }
87779176
JM
14053
14054 case Tag_ABI_conformance:
071436c6 14055 {
4082ef84
NC
14056 printf (" Tag_ABI_conformance: \"");
14057 if (p < end - 1)
14058 {
14059 size_t maxlen = (end - p) - 1;
071436c6 14060
4082ef84
NC
14061 print_symbol ((int) maxlen, (const char *) p);
14062 p += strnlen ((char *) p, maxlen) + 1;
14063 }
14064 else
14065 {
14066 printf (_("<corrupt>"));
14067 p = (unsigned char *) end;
14068 }
071436c6 14069 printf ("\"\n");
071436c6
NC
14070 return p;
14071 }
59e6276b
JM
14072 }
14073
f6f0e17b
NC
14074 return display_tag_value (tag, p, end);
14075}
59e6276b 14076
f6f0e17b
NC
14077static void
14078display_raw_attribute (unsigned char * p, unsigned char * end)
14079{
14080 unsigned long addr = 0;
14081 size_t bytes = end - p;
14082
e0a31db1 14083 assert (end > p);
f6f0e17b 14084 while (bytes)
87779176 14085 {
f6f0e17b
NC
14086 int j;
14087 int k;
14088 int lbytes = (bytes > 16 ? 16 : bytes);
14089
14090 printf (" 0x%8.8lx ", addr);
14091
14092 for (j = 0; j < 16; j++)
14093 {
14094 if (j < lbytes)
14095 printf ("%2.2x", p[j]);
14096 else
14097 printf (" ");
14098
14099 if ((j & 3) == 3)
14100 printf (" ");
14101 }
14102
14103 for (j = 0; j < lbytes; j++)
14104 {
14105 k = p[j];
14106 if (k >= ' ' && k < 0x7f)
14107 printf ("%c", k);
14108 else
14109 printf (".");
14110 }
14111
14112 putchar ('\n');
14113
14114 p += lbytes;
14115 bytes -= lbytes;
14116 addr += lbytes;
87779176 14117 }
59e6276b 14118
f6f0e17b 14119 putchar ('\n');
59e6276b
JM
14120}
14121
13761a11
NC
14122static unsigned char *
14123display_msp430x_attribute (unsigned char * p,
14124 const unsigned char * const end)
14125{
14126 unsigned int len;
14127 int val;
14128 int tag;
14129
14130 tag = read_uleb128 (p, & len, end);
14131 p += len;
0b4362b0 14132
13761a11
NC
14133 switch (tag)
14134 {
14135 case OFBA_MSPABI_Tag_ISA:
14136 val = read_uleb128 (p, &len, end);
14137 p += len;
14138 printf (" Tag_ISA: ");
14139 switch (val)
14140 {
14141 case 0: printf (_("None\n")); break;
14142 case 1: printf (_("MSP430\n")); break;
14143 case 2: printf (_("MSP430X\n")); break;
14144 default: printf ("??? (%d)\n", val); break;
14145 }
14146 break;
14147
14148 case OFBA_MSPABI_Tag_Code_Model:
14149 val = read_uleb128 (p, &len, end);
14150 p += len;
14151 printf (" Tag_Code_Model: ");
14152 switch (val)
14153 {
14154 case 0: printf (_("None\n")); break;
14155 case 1: printf (_("Small\n")); break;
14156 case 2: printf (_("Large\n")); break;
14157 default: printf ("??? (%d)\n", val); break;
14158 }
14159 break;
14160
14161 case OFBA_MSPABI_Tag_Data_Model:
14162 val = read_uleb128 (p, &len, end);
14163 p += len;
14164 printf (" Tag_Data_Model: ");
14165 switch (val)
14166 {
14167 case 0: printf (_("None\n")); break;
14168 case 1: printf (_("Small\n")); break;
14169 case 2: printf (_("Large\n")); break;
14170 case 3: printf (_("Restricted Large\n")); break;
14171 default: printf ("??? (%d)\n", val); break;
14172 }
14173 break;
14174
14175 default:
14176 printf (_(" <unknown tag %d>: "), tag);
14177
14178 if (tag & 1)
14179 {
071436c6 14180 putchar ('"');
4082ef84
NC
14181 if (p < end - 1)
14182 {
14183 size_t maxlen = (end - p) - 1;
14184
14185 print_symbol ((int) maxlen, (const char *) p);
14186 p += strnlen ((char *) p, maxlen) + 1;
14187 }
14188 else
14189 {
14190 printf (_("<corrupt>"));
14191 p = (unsigned char *) end;
14192 }
071436c6 14193 printf ("\"\n");
13761a11
NC
14194 }
14195 else
14196 {
14197 val = read_uleb128 (p, &len, end);
14198 p += len;
14199 printf ("%d (0x%x)\n", val, val);
14200 }
14201 break;
14202 }
14203
4082ef84 14204 assert (p <= end);
13761a11
NC
14205 return p;
14206}
14207
11c1ff18 14208static int
60bca95a
NC
14209process_attributes (FILE * file,
14210 const char * public_name,
104d59d1 14211 unsigned int proc_type,
f6f0e17b
NC
14212 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
14213 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 14214{
2cf0635d 14215 Elf_Internal_Shdr * sect;
11c1ff18
PB
14216 unsigned i;
14217
14218 /* Find the section header so that we get the size. */
14219 for (i = 0, sect = section_headers;
14220 i < elf_header.e_shnum;
14221 i++, sect++)
14222 {
071436c6
NC
14223 unsigned char * contents;
14224 unsigned char * p;
14225
104d59d1 14226 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
14227 continue;
14228
3f5e193b
NC
14229 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
14230 sect->sh_size, _("attributes"));
60bca95a 14231 if (contents == NULL)
11c1ff18 14232 continue;
60bca95a 14233
11c1ff18
PB
14234 p = contents;
14235 if (*p == 'A')
14236 {
071436c6
NC
14237 bfd_vma section_len;
14238
14239 section_len = sect->sh_size - 1;
11c1ff18 14240 p++;
60bca95a 14241
071436c6 14242 while (section_len > 0)
11c1ff18 14243 {
071436c6 14244 bfd_vma attr_len;
e9847026 14245 unsigned int namelen;
11c1ff18 14246 bfd_boolean public_section;
104d59d1 14247 bfd_boolean gnu_section;
11c1ff18 14248
071436c6 14249 if (section_len <= 4)
e0a31db1
NC
14250 {
14251 error (_("Tag section ends prematurely\n"));
14252 break;
14253 }
071436c6 14254 attr_len = byte_get (p, 4);
11c1ff18 14255 p += 4;
60bca95a 14256
071436c6 14257 if (attr_len > section_len)
11c1ff18 14258 {
071436c6
NC
14259 error (_("Bad attribute length (%u > %u)\n"),
14260 (unsigned) attr_len, (unsigned) section_len);
14261 attr_len = section_len;
11c1ff18 14262 }
74e1a04b 14263 /* PR 17531: file: 001-101425-0.004 */
071436c6 14264 else if (attr_len < 5)
74e1a04b 14265 {
071436c6 14266 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
74e1a04b
NC
14267 break;
14268 }
e9847026 14269
071436c6
NC
14270 section_len -= attr_len;
14271 attr_len -= 4;
14272
14273 namelen = strnlen ((char *) p, attr_len) + 1;
14274 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
14275 {
14276 error (_("Corrupt attribute section name\n"));
14277 break;
14278 }
14279
071436c6
NC
14280 printf (_("Attribute Section: "));
14281 print_symbol (INT_MAX, (const char *) p);
14282 putchar ('\n');
60bca95a
NC
14283
14284 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
14285 public_section = TRUE;
14286 else
14287 public_section = FALSE;
60bca95a
NC
14288
14289 if (streq ((char *) p, "gnu"))
104d59d1
JM
14290 gnu_section = TRUE;
14291 else
14292 gnu_section = FALSE;
60bca95a 14293
11c1ff18 14294 p += namelen;
071436c6 14295 attr_len -= namelen;
e0a31db1 14296
071436c6 14297 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 14298 {
e0a31db1 14299 int tag;
11c1ff18
PB
14300 int val;
14301 bfd_vma size;
071436c6 14302 unsigned char * end;
60bca95a 14303
e0a31db1 14304 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 14305 if (attr_len < 6)
e0a31db1
NC
14306 {
14307 error (_("Unused bytes at end of section\n"));
14308 section_len = 0;
14309 break;
14310 }
14311
14312 tag = *(p++);
11c1ff18 14313 size = byte_get (p, 4);
071436c6 14314 if (size > attr_len)
11c1ff18 14315 {
e9847026 14316 error (_("Bad subsection length (%u > %u)\n"),
071436c6
NC
14317 (unsigned) size, (unsigned) attr_len);
14318 size = attr_len;
11c1ff18 14319 }
e0a31db1
NC
14320 /* PR binutils/17531: Safe handling of corrupt files. */
14321 if (size < 6)
14322 {
14323 error (_("Bad subsection length (%u < 6)\n"),
14324 (unsigned) size);
14325 section_len = 0;
14326 break;
14327 }
60bca95a 14328
071436c6 14329 attr_len -= size;
11c1ff18 14330 end = p + size - 1;
071436c6 14331 assert (end <= contents + sect->sh_size);
11c1ff18 14332 p += 4;
60bca95a 14333
11c1ff18
PB
14334 switch (tag)
14335 {
14336 case 1:
2b692964 14337 printf (_("File Attributes\n"));
11c1ff18
PB
14338 break;
14339 case 2:
2b692964 14340 printf (_("Section Attributes:"));
11c1ff18
PB
14341 goto do_numlist;
14342 case 3:
2b692964 14343 printf (_("Symbol Attributes:"));
1a0670f3 14344 /* Fall through. */
11c1ff18
PB
14345 do_numlist:
14346 for (;;)
14347 {
91d6fa6a 14348 unsigned int j;
60bca95a 14349
f6f0e17b 14350 val = read_uleb128 (p, &j, end);
91d6fa6a 14351 p += j;
11c1ff18
PB
14352 if (val == 0)
14353 break;
14354 printf (" %d", val);
14355 }
14356 printf ("\n");
14357 break;
14358 default:
2b692964 14359 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
14360 public_section = FALSE;
14361 break;
14362 }
60bca95a 14363
071436c6 14364 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
14365 {
14366 while (p < end)
f6f0e17b 14367 p = display_pub_attribute (p, end);
071436c6 14368 assert (p <= end);
104d59d1 14369 }
071436c6 14370 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
14371 {
14372 while (p < end)
14373 p = display_gnu_attribute (p,
f6f0e17b
NC
14374 display_proc_gnu_attribute,
14375 end);
071436c6 14376 assert (p <= end);
11c1ff18 14377 }
071436c6 14378 else if (p < end)
11c1ff18 14379 {
071436c6 14380 printf (_(" Unknown attribute:\n"));
f6f0e17b 14381 display_raw_attribute (p, end);
11c1ff18
PB
14382 p = end;
14383 }
071436c6
NC
14384 else
14385 attr_len = 0;
11c1ff18
PB
14386 }
14387 }
14388 }
14389 else
e9847026 14390 printf (_("Unknown format '%c' (%d)\n"), *p, *p);
d70c5fc7 14391
60bca95a 14392 free (contents);
11c1ff18
PB
14393 }
14394 return 1;
14395}
14396
104d59d1 14397static int
2cf0635d 14398process_arm_specific (FILE * file)
104d59d1
JM
14399{
14400 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
14401 display_arm_attribute, NULL);
14402}
14403
34c8bcba 14404static int
2cf0635d 14405process_power_specific (FILE * file)
34c8bcba
JM
14406{
14407 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
14408 display_power_gnu_attribute);
14409}
14410
643f7afb
AK
14411static int
14412process_s390_specific (FILE * file)
14413{
14414 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
14415 display_s390_gnu_attribute);
14416}
14417
9e8c70f9
DM
14418static int
14419process_sparc_specific (FILE * file)
14420{
14421 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
14422 display_sparc_gnu_attribute);
14423}
14424
59e6276b
JM
14425static int
14426process_tic6x_specific (FILE * file)
14427{
14428 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
14429 display_tic6x_attribute, NULL);
14430}
14431
13761a11
NC
14432static int
14433process_msp430x_specific (FILE * file)
14434{
14435 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
14436 display_msp430x_attribute, NULL);
14437}
14438
ccb4c951
RS
14439/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
14440 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
14441 and return the VMA of the next entry, or -1 if there was a problem.
14442 Does not read from DATA_END or beyond. */
ccb4c951
RS
14443
14444static bfd_vma
82b1b41b
NC
14445print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
14446 unsigned char * data_end)
ccb4c951
RS
14447{
14448 printf (" ");
14449 print_vma (addr, LONG_HEX);
14450 printf (" ");
14451 if (addr < pltgot + 0xfff0)
14452 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
14453 else
14454 printf ("%10s", "");
14455 printf (" ");
14456 if (data == NULL)
2b692964 14457 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
14458 else
14459 {
14460 bfd_vma entry;
82b1b41b 14461 unsigned char * from = data + addr - pltgot;
ccb4c951 14462
82b1b41b
NC
14463 if (from + (is_32bit_elf ? 4 : 8) > data_end)
14464 {
14465 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
14466 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
14467 return (bfd_vma) -1;
14468 }
14469 else
14470 {
14471 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
14472 print_vma (entry, LONG_HEX);
14473 }
ccb4c951
RS
14474 }
14475 return addr + (is_32bit_elf ? 4 : 8);
14476}
14477
861fb55a
DJ
14478/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
14479 PLTGOT. Print the Address and Initial fields of an entry at VMA
14480 ADDR and return the VMA of the next entry. */
14481
14482static bfd_vma
2cf0635d 14483print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
14484{
14485 printf (" ");
14486 print_vma (addr, LONG_HEX);
14487 printf (" ");
14488 if (data == NULL)
2b692964 14489 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
14490 else
14491 {
14492 bfd_vma entry;
14493
14494 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
14495 print_vma (entry, LONG_HEX);
14496 }
14497 return addr + (is_32bit_elf ? 4 : 8);
14498}
14499
351cdf24
MF
14500static void
14501print_mips_ases (unsigned int mask)
14502{
14503 if (mask & AFL_ASE_DSP)
14504 fputs ("\n\tDSP ASE", stdout);
14505 if (mask & AFL_ASE_DSPR2)
14506 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
14507 if (mask & AFL_ASE_DSPR3)
14508 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
14509 if (mask & AFL_ASE_EVA)
14510 fputs ("\n\tEnhanced VA Scheme", stdout);
14511 if (mask & AFL_ASE_MCU)
14512 fputs ("\n\tMCU (MicroController) ASE", stdout);
14513 if (mask & AFL_ASE_MDMX)
14514 fputs ("\n\tMDMX ASE", stdout);
14515 if (mask & AFL_ASE_MIPS3D)
14516 fputs ("\n\tMIPS-3D ASE", stdout);
14517 if (mask & AFL_ASE_MT)
14518 fputs ("\n\tMT ASE", stdout);
14519 if (mask & AFL_ASE_SMARTMIPS)
14520 fputs ("\n\tSmartMIPS ASE", stdout);
14521 if (mask & AFL_ASE_VIRT)
14522 fputs ("\n\tVZ ASE", stdout);
14523 if (mask & AFL_ASE_MSA)
14524 fputs ("\n\tMSA ASE", stdout);
14525 if (mask & AFL_ASE_MIPS16)
14526 fputs ("\n\tMIPS16 ASE", stdout);
14527 if (mask & AFL_ASE_MICROMIPS)
14528 fputs ("\n\tMICROMIPS ASE", stdout);
14529 if (mask & AFL_ASE_XPA)
14530 fputs ("\n\tXPA ASE", stdout);
14531 if (mask == 0)
14532 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
14533 else if ((mask & ~AFL_ASE_MASK) != 0)
14534 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
14535}
14536
14537static void
14538print_mips_isa_ext (unsigned int isa_ext)
14539{
14540 switch (isa_ext)
14541 {
14542 case 0:
14543 fputs (_("None"), stdout);
14544 break;
14545 case AFL_EXT_XLR:
14546 fputs ("RMI XLR", stdout);
14547 break;
2c629856
N
14548 case AFL_EXT_OCTEON3:
14549 fputs ("Cavium Networks Octeon3", stdout);
14550 break;
351cdf24
MF
14551 case AFL_EXT_OCTEON2:
14552 fputs ("Cavium Networks Octeon2", stdout);
14553 break;
14554 case AFL_EXT_OCTEONP:
14555 fputs ("Cavium Networks OcteonP", stdout);
14556 break;
14557 case AFL_EXT_LOONGSON_3A:
14558 fputs ("Loongson 3A", stdout);
14559 break;
14560 case AFL_EXT_OCTEON:
14561 fputs ("Cavium Networks Octeon", stdout);
14562 break;
14563 case AFL_EXT_5900:
14564 fputs ("Toshiba R5900", stdout);
14565 break;
14566 case AFL_EXT_4650:
14567 fputs ("MIPS R4650", stdout);
14568 break;
14569 case AFL_EXT_4010:
14570 fputs ("LSI R4010", stdout);
14571 break;
14572 case AFL_EXT_4100:
14573 fputs ("NEC VR4100", stdout);
14574 break;
14575 case AFL_EXT_3900:
14576 fputs ("Toshiba R3900", stdout);
14577 break;
14578 case AFL_EXT_10000:
14579 fputs ("MIPS R10000", stdout);
14580 break;
14581 case AFL_EXT_SB1:
14582 fputs ("Broadcom SB-1", stdout);
14583 break;
14584 case AFL_EXT_4111:
14585 fputs ("NEC VR4111/VR4181", stdout);
14586 break;
14587 case AFL_EXT_4120:
14588 fputs ("NEC VR4120", stdout);
14589 break;
14590 case AFL_EXT_5400:
14591 fputs ("NEC VR5400", stdout);
14592 break;
14593 case AFL_EXT_5500:
14594 fputs ("NEC VR5500", stdout);
14595 break;
14596 case AFL_EXT_LOONGSON_2E:
14597 fputs ("ST Microelectronics Loongson 2E", stdout);
14598 break;
14599 case AFL_EXT_LOONGSON_2F:
14600 fputs ("ST Microelectronics Loongson 2F", stdout);
14601 break;
14602 default:
00ac7aa0 14603 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
14604 }
14605}
14606
14607static int
14608get_mips_reg_size (int reg_size)
14609{
14610 return (reg_size == AFL_REG_NONE) ? 0
14611 : (reg_size == AFL_REG_32) ? 32
14612 : (reg_size == AFL_REG_64) ? 64
14613 : (reg_size == AFL_REG_128) ? 128
14614 : -1;
14615}
14616
19e6b90e 14617static int
2cf0635d 14618process_mips_specific (FILE * file)
5b18a4bc 14619{
2cf0635d 14620 Elf_Internal_Dyn * entry;
351cdf24 14621 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
14622 size_t liblist_offset = 0;
14623 size_t liblistno = 0;
14624 size_t conflictsno = 0;
14625 size_t options_offset = 0;
14626 size_t conflicts_offset = 0;
861fb55a
DJ
14627 size_t pltrelsz = 0;
14628 size_t pltrel = 0;
ccb4c951 14629 bfd_vma pltgot = 0;
861fb55a
DJ
14630 bfd_vma mips_pltgot = 0;
14631 bfd_vma jmprel = 0;
ccb4c951
RS
14632 bfd_vma local_gotno = 0;
14633 bfd_vma gotsym = 0;
14634 bfd_vma symtabno = 0;
103f02d3 14635
2cf19d5c
JM
14636 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
14637 display_mips_gnu_attribute);
14638
351cdf24
MF
14639 sect = find_section (".MIPS.abiflags");
14640
14641 if (sect != NULL)
14642 {
14643 Elf_External_ABIFlags_v0 *abiflags_ext;
14644 Elf_Internal_ABIFlags_v0 abiflags_in;
14645
14646 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
14647 fputs ("\nCorrupt ABI Flags section.\n", stdout);
14648 else
14649 {
14650 abiflags_ext = get_data (NULL, file, sect->sh_offset, 1,
14651 sect->sh_size, _("MIPS ABI Flags section"));
14652 if (abiflags_ext)
14653 {
14654 abiflags_in.version = BYTE_GET (abiflags_ext->version);
14655 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
14656 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
14657 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
14658 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
14659 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
14660 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
14661 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
14662 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
14663 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
14664 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
14665
14666 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
14667 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
14668 if (abiflags_in.isa_rev > 1)
14669 printf ("r%d", abiflags_in.isa_rev);
14670 printf ("\nGPR size: %d",
14671 get_mips_reg_size (abiflags_in.gpr_size));
14672 printf ("\nCPR1 size: %d",
14673 get_mips_reg_size (abiflags_in.cpr1_size));
14674 printf ("\nCPR2 size: %d",
14675 get_mips_reg_size (abiflags_in.cpr2_size));
14676 fputs ("\nFP ABI: ", stdout);
14677 print_mips_fp_abi_value (abiflags_in.fp_abi);
14678 fputs ("ISA Extension: ", stdout);
14679 print_mips_isa_ext (abiflags_in.isa_ext);
14680 fputs ("\nASEs:", stdout);
14681 print_mips_ases (abiflags_in.ases);
14682 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
14683 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
14684 fputc ('\n', stdout);
14685 free (abiflags_ext);
14686 }
14687 }
14688 }
14689
19e6b90e
L
14690 /* We have a lot of special sections. Thanks SGI! */
14691 if (dynamic_section == NULL)
14692 /* No information available. */
14693 return 0;
252b5132 14694
071436c6
NC
14695 for (entry = dynamic_section;
14696 /* PR 17531 file: 012-50589-0.004. */
14697 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
14698 ++entry)
252b5132
RH
14699 switch (entry->d_tag)
14700 {
14701 case DT_MIPS_LIBLIST:
d93f0186
NC
14702 liblist_offset
14703 = offset_from_vma (file, entry->d_un.d_val,
14704 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
14705 break;
14706 case DT_MIPS_LIBLISTNO:
14707 liblistno = entry->d_un.d_val;
14708 break;
14709 case DT_MIPS_OPTIONS:
d93f0186 14710 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
14711 break;
14712 case DT_MIPS_CONFLICT:
d93f0186
NC
14713 conflicts_offset
14714 = offset_from_vma (file, entry->d_un.d_val,
14715 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
14716 break;
14717 case DT_MIPS_CONFLICTNO:
14718 conflictsno = entry->d_un.d_val;
14719 break;
ccb4c951 14720 case DT_PLTGOT:
861fb55a
DJ
14721 pltgot = entry->d_un.d_ptr;
14722 break;
ccb4c951
RS
14723 case DT_MIPS_LOCAL_GOTNO:
14724 local_gotno = entry->d_un.d_val;
14725 break;
14726 case DT_MIPS_GOTSYM:
14727 gotsym = entry->d_un.d_val;
14728 break;
14729 case DT_MIPS_SYMTABNO:
14730 symtabno = entry->d_un.d_val;
14731 break;
861fb55a
DJ
14732 case DT_MIPS_PLTGOT:
14733 mips_pltgot = entry->d_un.d_ptr;
14734 break;
14735 case DT_PLTREL:
14736 pltrel = entry->d_un.d_val;
14737 break;
14738 case DT_PLTRELSZ:
14739 pltrelsz = entry->d_un.d_val;
14740 break;
14741 case DT_JMPREL:
14742 jmprel = entry->d_un.d_ptr;
14743 break;
252b5132
RH
14744 default:
14745 break;
14746 }
14747
14748 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
14749 {
2cf0635d 14750 Elf32_External_Lib * elib;
252b5132
RH
14751 size_t cnt;
14752
3f5e193b
NC
14753 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
14754 liblistno,
14755 sizeof (Elf32_External_Lib),
9cf03b7e 14756 _("liblist section data"));
a6e9f9df 14757 if (elib)
252b5132 14758 {
2b692964 14759 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 14760 (unsigned long) liblistno);
2b692964 14761 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
14762 stdout);
14763
14764 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 14765 {
a6e9f9df 14766 Elf32_Lib liblist;
91d6fa6a 14767 time_t atime;
d5b07ef4 14768 char timebuf[128];
2cf0635d 14769 struct tm * tmp;
a6e9f9df
AM
14770
14771 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 14772 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
14773 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
14774 liblist.l_version = BYTE_GET (elib[cnt].l_version);
14775 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
14776
91d6fa6a 14777 tmp = gmtime (&atime);
e9e44622
JJ
14778 snprintf (timebuf, sizeof (timebuf),
14779 "%04u-%02u-%02uT%02u:%02u:%02u",
14780 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
14781 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 14782
31104126 14783 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
14784 if (VALID_DYNAMIC_NAME (liblist.l_name))
14785 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
14786 else
2b692964 14787 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
14788 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
14789 liblist.l_version);
a6e9f9df
AM
14790
14791 if (liblist.l_flags == 0)
2b692964 14792 puts (_(" NONE"));
a6e9f9df
AM
14793 else
14794 {
14795 static const struct
252b5132 14796 {
2cf0635d 14797 const char * name;
a6e9f9df 14798 int bit;
252b5132 14799 }
a6e9f9df
AM
14800 l_flags_vals[] =
14801 {
14802 { " EXACT_MATCH", LL_EXACT_MATCH },
14803 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
14804 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
14805 { " EXPORTS", LL_EXPORTS },
14806 { " DELAY_LOAD", LL_DELAY_LOAD },
14807 { " DELTA", LL_DELTA }
14808 };
14809 int flags = liblist.l_flags;
14810 size_t fcnt;
14811
60bca95a 14812 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
14813 if ((flags & l_flags_vals[fcnt].bit) != 0)
14814 {
14815 fputs (l_flags_vals[fcnt].name, stdout);
14816 flags ^= l_flags_vals[fcnt].bit;
14817 }
14818 if (flags != 0)
14819 printf (" %#x", (unsigned int) flags);
252b5132 14820
a6e9f9df
AM
14821 puts ("");
14822 }
252b5132 14823 }
252b5132 14824
a6e9f9df
AM
14825 free (elib);
14826 }
252b5132
RH
14827 }
14828
14829 if (options_offset != 0)
14830 {
2cf0635d 14831 Elf_External_Options * eopt;
2cf0635d
NC
14832 Elf_Internal_Options * iopt;
14833 Elf_Internal_Options * option;
252b5132
RH
14834 size_t offset;
14835 int cnt;
351cdf24 14836 sect = section_headers;
252b5132
RH
14837
14838 /* Find the section header so that we get the size. */
071436c6 14839 sect = find_section_by_type (SHT_MIPS_OPTIONS);
948f632f 14840 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
14841 if (sect == NULL)
14842 {
14843 error (_("No MIPS_OPTIONS header found\n"));
14844 return 0;
14845 }
252b5132 14846
3f5e193b
NC
14847 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
14848 sect->sh_size, _("options"));
a6e9f9df 14849 if (eopt)
252b5132 14850 {
3f5e193b
NC
14851 iopt = (Elf_Internal_Options *)
14852 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
14853 if (iopt == NULL)
14854 {
fb324ee9 14855 error (_("Out of memory allocating space for MIPS options\n"));
a6e9f9df
AM
14856 return 0;
14857 }
76da6bbe 14858
a6e9f9df
AM
14859 offset = cnt = 0;
14860 option = iopt;
252b5132 14861
82b1b41b 14862 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 14863 {
2cf0635d 14864 Elf_External_Options * eoption;
252b5132 14865
a6e9f9df 14866 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 14867
a6e9f9df
AM
14868 option->kind = BYTE_GET (eoption->kind);
14869 option->size = BYTE_GET (eoption->size);
14870 option->section = BYTE_GET (eoption->section);
14871 option->info = BYTE_GET (eoption->info);
76da6bbe 14872
82b1b41b
NC
14873 /* PR 17531: file: ffa0fa3b. */
14874 if (option->size < sizeof (* eopt)
14875 || offset + option->size > sect->sh_size)
14876 {
55325047
NC
14877 error (_("Invalid size (%u) for MIPS option\n"), option->size);
14878 return 0;
82b1b41b 14879 }
a6e9f9df 14880 offset += option->size;
14ae95f2 14881
a6e9f9df
AM
14882 ++option;
14883 ++cnt;
14884 }
252b5132 14885
a6e9f9df 14886 printf (_("\nSection '%s' contains %d entries:\n"),
74e1a04b 14887 printable_section_name (sect), cnt);
76da6bbe 14888
a6e9f9df 14889 option = iopt;
82b1b41b 14890 offset = 0;
252b5132 14891
a6e9f9df 14892 while (cnt-- > 0)
252b5132 14893 {
a6e9f9df
AM
14894 size_t len;
14895
14896 switch (option->kind)
252b5132 14897 {
a6e9f9df
AM
14898 case ODK_NULL:
14899 /* This shouldn't happen. */
14900 printf (" NULL %d %lx", option->section, option->info);
14901 break;
14902 case ODK_REGINFO:
14903 printf (" REGINFO ");
14904 if (elf_header.e_machine == EM_MIPS)
14905 {
14906 /* 32bit form. */
2cf0635d 14907 Elf32_External_RegInfo * ereg;
b34976b6 14908 Elf32_RegInfo reginfo;
a6e9f9df
AM
14909
14910 ereg = (Elf32_External_RegInfo *) (option + 1);
14911 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
14912 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
14913 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
14914 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
14915 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
14916 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
14917
14918 printf ("GPR %08lx GP 0x%lx\n",
14919 reginfo.ri_gprmask,
14920 (unsigned long) reginfo.ri_gp_value);
14921 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
14922 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
14923 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
14924 }
14925 else
14926 {
14927 /* 64 bit form. */
2cf0635d 14928 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
14929 Elf64_Internal_RegInfo reginfo;
14930
14931 ereg = (Elf64_External_RegInfo *) (option + 1);
14932 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
14933 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
14934 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
14935 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
14936 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 14937 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
14938
14939 printf ("GPR %08lx GP 0x",
14940 reginfo.ri_gprmask);
14941 printf_vma (reginfo.ri_gp_value);
14942 printf ("\n");
14943
14944 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
14945 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
14946 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
14947 }
14948 ++option;
14949 continue;
14950 case ODK_EXCEPTIONS:
14951 fputs (" EXCEPTIONS fpe_min(", stdout);
14952 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
14953 fputs (") fpe_max(", stdout);
14954 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
14955 fputs (")", stdout);
14956
14957 if (option->info & OEX_PAGE0)
14958 fputs (" PAGE0", stdout);
14959 if (option->info & OEX_SMM)
14960 fputs (" SMM", stdout);
14961 if (option->info & OEX_FPDBUG)
14962 fputs (" FPDBUG", stdout);
14963 if (option->info & OEX_DISMISS)
14964 fputs (" DISMISS", stdout);
14965 break;
14966 case ODK_PAD:
14967 fputs (" PAD ", stdout);
14968 if (option->info & OPAD_PREFIX)
14969 fputs (" PREFIX", stdout);
14970 if (option->info & OPAD_POSTFIX)
14971 fputs (" POSTFIX", stdout);
14972 if (option->info & OPAD_SYMBOL)
14973 fputs (" SYMBOL", stdout);
14974 break;
14975 case ODK_HWPATCH:
14976 fputs (" HWPATCH ", stdout);
14977 if (option->info & OHW_R4KEOP)
14978 fputs (" R4KEOP", stdout);
14979 if (option->info & OHW_R8KPFETCH)
14980 fputs (" R8KPFETCH", stdout);
14981 if (option->info & OHW_R5KEOP)
14982 fputs (" R5KEOP", stdout);
14983 if (option->info & OHW_R5KCVTL)
14984 fputs (" R5KCVTL", stdout);
14985 break;
14986 case ODK_FILL:
14987 fputs (" FILL ", stdout);
14988 /* XXX Print content of info word? */
14989 break;
14990 case ODK_TAGS:
14991 fputs (" TAGS ", stdout);
14992 /* XXX Print content of info word? */
14993 break;
14994 case ODK_HWAND:
14995 fputs (" HWAND ", stdout);
14996 if (option->info & OHWA0_R4KEOP_CHECKED)
14997 fputs (" R4KEOP_CHECKED", stdout);
14998 if (option->info & OHWA0_R4KEOP_CLEAN)
14999 fputs (" R4KEOP_CLEAN", stdout);
15000 break;
15001 case ODK_HWOR:
15002 fputs (" HWOR ", stdout);
15003 if (option->info & OHWA0_R4KEOP_CHECKED)
15004 fputs (" R4KEOP_CHECKED", stdout);
15005 if (option->info & OHWA0_R4KEOP_CLEAN)
15006 fputs (" R4KEOP_CLEAN", stdout);
15007 break;
15008 case ODK_GP_GROUP:
15009 printf (" GP_GROUP %#06lx self-contained %#06lx",
15010 option->info & OGP_GROUP,
15011 (option->info & OGP_SELF) >> 16);
15012 break;
15013 case ODK_IDENT:
15014 printf (" IDENT %#06lx self-contained %#06lx",
15015 option->info & OGP_GROUP,
15016 (option->info & OGP_SELF) >> 16);
15017 break;
15018 default:
15019 /* This shouldn't happen. */
15020 printf (" %3d ??? %d %lx",
15021 option->kind, option->section, option->info);
15022 break;
252b5132 15023 }
a6e9f9df 15024
2cf0635d 15025 len = sizeof (* eopt);
a6e9f9df 15026 while (len < option->size)
82b1b41b 15027 {
7e27a9d5 15028 unsigned char datum = * ((unsigned char *) eopt + offset + len);
a6e9f9df 15029
82b1b41b
NC
15030 if (ISPRINT (datum))
15031 printf ("%c", datum);
15032 else
15033 printf ("\\%03o", datum);
15034 len ++;
15035 }
a6e9f9df 15036 fputs ("\n", stdout);
82b1b41b
NC
15037
15038 offset += option->size;
252b5132 15039 ++option;
252b5132
RH
15040 }
15041
a6e9f9df 15042 free (eopt);
252b5132 15043 }
252b5132
RH
15044 }
15045
15046 if (conflicts_offset != 0 && conflictsno != 0)
15047 {
2cf0635d 15048 Elf32_Conflict * iconf;
252b5132
RH
15049 size_t cnt;
15050
15051 if (dynamic_symbols == NULL)
15052 {
591a748a 15053 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
15054 return 0;
15055 }
15056
3f5e193b 15057 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
15058 if (iconf == NULL)
15059 {
8b73c356 15060 error (_("Out of memory allocating space for dynamic conflicts\n"));
252b5132
RH
15061 return 0;
15062 }
15063
9ea033b2 15064 if (is_32bit_elf)
252b5132 15065 {
2cf0635d 15066 Elf32_External_Conflict * econf32;
a6e9f9df 15067
3f5e193b
NC
15068 econf32 = (Elf32_External_Conflict *)
15069 get_data (NULL, file, conflicts_offset, conflictsno,
15070 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
15071 if (!econf32)
15072 return 0;
252b5132
RH
15073
15074 for (cnt = 0; cnt < conflictsno; ++cnt)
15075 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
15076
15077 free (econf32);
252b5132
RH
15078 }
15079 else
15080 {
2cf0635d 15081 Elf64_External_Conflict * econf64;
a6e9f9df 15082
3f5e193b
NC
15083 econf64 = (Elf64_External_Conflict *)
15084 get_data (NULL, file, conflicts_offset, conflictsno,
15085 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
15086 if (!econf64)
15087 return 0;
252b5132
RH
15088
15089 for (cnt = 0; cnt < conflictsno; ++cnt)
15090 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
15091
15092 free (econf64);
252b5132
RH
15093 }
15094
c7e7ca54
NC
15095 printf (_("\nSection '.conflict' contains %lu entries:\n"),
15096 (unsigned long) conflictsno);
252b5132
RH
15097 puts (_(" Num: Index Value Name"));
15098
15099 for (cnt = 0; cnt < conflictsno; ++cnt)
15100 {
b34976b6 15101 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
15102
15103 if (iconf[cnt] >= num_dynamic_syms)
15104 printf (_("<corrupt symbol index>"));
d79b3d50 15105 else
e0a31db1
NC
15106 {
15107 Elf_Internal_Sym * psym;
15108
15109 psym = & dynamic_symbols[iconf[cnt]];
15110 print_vma (psym->st_value, FULL_HEX);
15111 putchar (' ');
15112 if (VALID_DYNAMIC_NAME (psym->st_name))
15113 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
15114 else
15115 printf (_("<corrupt: %14ld>"), psym->st_name);
15116 }
31104126 15117 putchar ('\n');
252b5132
RH
15118 }
15119
252b5132
RH
15120 free (iconf);
15121 }
15122
ccb4c951
RS
15123 if (pltgot != 0 && local_gotno != 0)
15124 {
91d6fa6a 15125 bfd_vma ent, local_end, global_end;
bbeee7ea 15126 size_t i, offset;
2cf0635d 15127 unsigned char * data;
82b1b41b 15128 unsigned char * data_end;
bbeee7ea 15129 int addr_size;
ccb4c951 15130
91d6fa6a 15131 ent = pltgot;
ccb4c951
RS
15132 addr_size = (is_32bit_elf ? 4 : 8);
15133 local_end = pltgot + local_gotno * addr_size;
ccb4c951 15134
74e1a04b
NC
15135 /* PR binutils/17533 file: 012-111227-0.004 */
15136 if (symtabno < gotsym)
15137 {
15138 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 15139 (unsigned long) gotsym, (unsigned long) symtabno);
74e1a04b
NC
15140 return 0;
15141 }
82b1b41b 15142
74e1a04b 15143 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
15144 /* PR 17531: file: 54c91a34. */
15145 if (global_end < local_end)
15146 {
15147 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
15148 return 0;
15149 }
948f632f 15150
ccb4c951 15151 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 15152 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
15153 global_end - pltgot, 1,
15154 _("Global Offset Table data"));
59245841
NC
15155 if (data == NULL)
15156 return 0;
82b1b41b 15157 data_end = data + (global_end - pltgot);
59245841 15158
ccb4c951
RS
15159 printf (_("\nPrimary GOT:\n"));
15160 printf (_(" Canonical gp value: "));
15161 print_vma (pltgot + 0x7ff0, LONG_HEX);
15162 printf ("\n\n");
15163
15164 printf (_(" Reserved entries:\n"));
15165 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
15166 addr_size * 2, _("Address"), _("Access"),
15167 addr_size * 2, _("Initial"));
82b1b41b 15168 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 15169 printf (_(" Lazy resolver\n"));
82b1b41b
NC
15170 if (ent == (bfd_vma) -1)
15171 goto got_print_fail;
ccb4c951 15172 if (data
91d6fa6a 15173 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
15174 >> (addr_size * 8 - 1)) != 0)
15175 {
82b1b41b 15176 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 15177 printf (_(" Module pointer (GNU extension)\n"));
82b1b41b
NC
15178 if (ent == (bfd_vma) -1)
15179 goto got_print_fail;
ccb4c951
RS
15180 }
15181 printf ("\n");
15182
91d6fa6a 15183 if (ent < local_end)
ccb4c951
RS
15184 {
15185 printf (_(" Local entries:\n"));
cc5914eb 15186 printf (" %*s %10s %*s\n",
2b692964
NC
15187 addr_size * 2, _("Address"), _("Access"),
15188 addr_size * 2, _("Initial"));
91d6fa6a 15189 while (ent < local_end)
ccb4c951 15190 {
82b1b41b 15191 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 15192 printf ("\n");
82b1b41b
NC
15193 if (ent == (bfd_vma) -1)
15194 goto got_print_fail;
ccb4c951
RS
15195 }
15196 printf ("\n");
15197 }
15198
15199 if (gotsym < symtabno)
15200 {
15201 int sym_width;
15202
15203 printf (_(" Global entries:\n"));
cc5914eb 15204 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
15205 addr_size * 2, _("Address"),
15206 _("Access"),
2b692964 15207 addr_size * 2, _("Initial"),
9cf03b7e
NC
15208 addr_size * 2, _("Sym.Val."),
15209 _("Type"),
15210 /* Note for translators: "Ndx" = abbreviated form of "Index". */
15211 _("Ndx"), _("Name"));
0b4362b0 15212
ccb4c951 15213 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 15214
ccb4c951
RS
15215 for (i = gotsym; i < symtabno; i++)
15216 {
82b1b41b 15217 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 15218 printf (" ");
e0a31db1
NC
15219
15220 if (dynamic_symbols == NULL)
15221 printf (_("<no dynamic symbols>"));
15222 else if (i < num_dynamic_syms)
15223 {
15224 Elf_Internal_Sym * psym = dynamic_symbols + i;
15225
15226 print_vma (psym->st_value, LONG_HEX);
15227 printf (" %-7s %3s ",
15228 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
15229 get_symbol_index_type (psym->st_shndx));
15230
15231 if (VALID_DYNAMIC_NAME (psym->st_name))
15232 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
15233 else
15234 printf (_("<corrupt: %14ld>"), psym->st_name);
15235 }
ccb4c951 15236 else
7fc5ac57
JBG
15237 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
15238 (unsigned long) i);
e0a31db1 15239
ccb4c951 15240 printf ("\n");
82b1b41b
NC
15241 if (ent == (bfd_vma) -1)
15242 break;
ccb4c951
RS
15243 }
15244 printf ("\n");
15245 }
15246
82b1b41b 15247 got_print_fail:
ccb4c951
RS
15248 if (data)
15249 free (data);
15250 }
15251
861fb55a
DJ
15252 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
15253 {
91d6fa6a 15254 bfd_vma ent, end;
861fb55a
DJ
15255 size_t offset, rel_offset;
15256 unsigned long count, i;
2cf0635d 15257 unsigned char * data;
861fb55a 15258 int addr_size, sym_width;
2cf0635d 15259 Elf_Internal_Rela * rels;
861fb55a
DJ
15260
15261 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
15262 if (pltrel == DT_RELA)
15263 {
15264 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
15265 return 0;
15266 }
15267 else
15268 {
15269 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
15270 return 0;
15271 }
15272
91d6fa6a 15273 ent = mips_pltgot;
861fb55a
DJ
15274 addr_size = (is_32bit_elf ? 4 : 8);
15275 end = mips_pltgot + (2 + count) * addr_size;
15276
15277 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 15278 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 15279 1, _("Procedure Linkage Table data"));
59245841
NC
15280 if (data == NULL)
15281 return 0;
15282
9cf03b7e 15283 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
15284 printf (_(" Reserved entries:\n"));
15285 printf (_(" %*s %*s Purpose\n"),
2b692964 15286 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 15287 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 15288 printf (_(" PLT lazy resolver\n"));
91d6fa6a 15289 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 15290 printf (_(" Module pointer\n"));
861fb55a
DJ
15291 printf ("\n");
15292
15293 printf (_(" Entries:\n"));
cc5914eb 15294 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
15295 addr_size * 2, _("Address"),
15296 addr_size * 2, _("Initial"),
15297 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
15298 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
15299 for (i = 0; i < count; i++)
15300 {
df97ab2a 15301 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 15302
91d6fa6a 15303 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 15304 printf (" ");
e0a31db1 15305
df97ab2a
MF
15306 if (idx >= num_dynamic_syms)
15307 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 15308 else
e0a31db1 15309 {
df97ab2a 15310 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
15311
15312 print_vma (psym->st_value, LONG_HEX);
15313 printf (" %-7s %3s ",
15314 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
15315 get_symbol_index_type (psym->st_shndx));
15316 if (VALID_DYNAMIC_NAME (psym->st_name))
15317 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
15318 else
15319 printf (_("<corrupt: %14ld>"), psym->st_name);
15320 }
861fb55a
DJ
15321 printf ("\n");
15322 }
15323 printf ("\n");
15324
15325 if (data)
15326 free (data);
15327 free (rels);
15328 }
15329
252b5132
RH
15330 return 1;
15331}
15332
35c08157
KLC
15333static int
15334process_nds32_specific (FILE * file)
15335{
15336 Elf_Internal_Shdr *sect = NULL;
15337
15338 sect = find_section (".nds32_e_flags");
15339 if (sect != NULL)
15340 {
15341 unsigned int *flag;
15342
15343 printf ("\nNDS32 elf flags section:\n");
15344 flag = get_data (NULL, file, sect->sh_offset, 1,
15345 sect->sh_size, _("NDS32 elf flags section"));
15346
15347 switch ((*flag) & 0x3)
15348 {
15349 case 0:
15350 printf ("(VEC_SIZE):\tNo entry.\n");
15351 break;
15352 case 1:
15353 printf ("(VEC_SIZE):\t4 bytes\n");
15354 break;
15355 case 2:
15356 printf ("(VEC_SIZE):\t16 bytes\n");
15357 break;
15358 case 3:
15359 printf ("(VEC_SIZE):\treserved\n");
15360 break;
15361 }
15362 }
15363
15364 return TRUE;
15365}
15366
047b2264 15367static int
2cf0635d 15368process_gnu_liblist (FILE * file)
047b2264 15369{
2cf0635d
NC
15370 Elf_Internal_Shdr * section;
15371 Elf_Internal_Shdr * string_sec;
15372 Elf32_External_Lib * elib;
15373 char * strtab;
c256ffe7 15374 size_t strtab_size;
047b2264
JJ
15375 size_t cnt;
15376 unsigned i;
15377
15378 if (! do_arch)
15379 return 0;
15380
15381 for (i = 0, section = section_headers;
15382 i < elf_header.e_shnum;
b34976b6 15383 i++, section++)
047b2264
JJ
15384 {
15385 switch (section->sh_type)
15386 {
15387 case SHT_GNU_LIBLIST:
4fbb74a6 15388 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
15389 break;
15390
3f5e193b
NC
15391 elib = (Elf32_External_Lib *)
15392 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 15393 _("liblist section data"));
047b2264
JJ
15394
15395 if (elib == NULL)
15396 break;
4fbb74a6 15397 string_sec = section_headers + section->sh_link;
047b2264 15398
3f5e193b
NC
15399 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
15400 string_sec->sh_size,
15401 _("liblist string table"));
047b2264
JJ
15402 if (strtab == NULL
15403 || section->sh_entsize != sizeof (Elf32_External_Lib))
15404 {
15405 free (elib);
2842702f 15406 free (strtab);
047b2264
JJ
15407 break;
15408 }
59245841 15409 strtab_size = string_sec->sh_size;
047b2264
JJ
15410
15411 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
74e1a04b 15412 printable_section_name (section),
0af1713e 15413 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 15414
2b692964 15415 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
15416
15417 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
15418 ++cnt)
15419 {
15420 Elf32_Lib liblist;
91d6fa6a 15421 time_t atime;
d5b07ef4 15422 char timebuf[128];
2cf0635d 15423 struct tm * tmp;
047b2264
JJ
15424
15425 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 15426 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
15427 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
15428 liblist.l_version = BYTE_GET (elib[cnt].l_version);
15429 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
15430
91d6fa6a 15431 tmp = gmtime (&atime);
e9e44622
JJ
15432 snprintf (timebuf, sizeof (timebuf),
15433 "%04u-%02u-%02uT%02u:%02u:%02u",
15434 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
15435 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
15436
15437 printf ("%3lu: ", (unsigned long) cnt);
15438 if (do_wide)
c256ffe7 15439 printf ("%-20s", liblist.l_name < strtab_size
2b692964 15440 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 15441 else
c256ffe7 15442 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 15443 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
15444 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
15445 liblist.l_version, liblist.l_flags);
15446 }
15447
15448 free (elib);
2842702f 15449 free (strtab);
047b2264
JJ
15450 }
15451 }
15452
15453 return 1;
15454}
15455
9437c45b 15456static const char *
d3ba0551 15457get_note_type (unsigned e_type)
779fe533
NC
15458{
15459 static char buff[64];
103f02d3 15460
1ec5cd37
NC
15461 if (elf_header.e_type == ET_CORE)
15462 switch (e_type)
15463 {
57346661 15464 case NT_AUXV:
1ec5cd37 15465 return _("NT_AUXV (auxiliary vector)");
57346661 15466 case NT_PRSTATUS:
1ec5cd37 15467 return _("NT_PRSTATUS (prstatus structure)");
57346661 15468 case NT_FPREGSET:
1ec5cd37 15469 return _("NT_FPREGSET (floating point registers)");
57346661 15470 case NT_PRPSINFO:
1ec5cd37 15471 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 15472 case NT_TASKSTRUCT:
1ec5cd37 15473 return _("NT_TASKSTRUCT (task structure)");
57346661 15474 case NT_PRXFPREG:
1ec5cd37 15475 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
15476 case NT_PPC_VMX:
15477 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
15478 case NT_PPC_VSX:
15479 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
15480 case NT_386_TLS:
15481 return _("NT_386_TLS (x86 TLS information)");
15482 case NT_386_IOPERM:
15483 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
15484 case NT_X86_XSTATE:
15485 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
15486 case NT_S390_HIGH_GPRS:
15487 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
15488 case NT_S390_TIMER:
15489 return _("NT_S390_TIMER (s390 timer register)");
15490 case NT_S390_TODCMP:
15491 return _("NT_S390_TODCMP (s390 TOD comparator register)");
15492 case NT_S390_TODPREG:
15493 return _("NT_S390_TODPREG (s390 TOD programmable register)");
15494 case NT_S390_CTRS:
15495 return _("NT_S390_CTRS (s390 control registers)");
15496 case NT_S390_PREFIX:
15497 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
15498 case NT_S390_LAST_BREAK:
15499 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
15500 case NT_S390_SYSTEM_CALL:
15501 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
15502 case NT_S390_TDB:
15503 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
15504 case NT_S390_VXRS_LOW:
15505 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
15506 case NT_S390_VXRS_HIGH:
15507 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
faa9a424
UW
15508 case NT_ARM_VFP:
15509 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
15510 case NT_ARM_TLS:
15511 return _("NT_ARM_TLS (AArch TLS registers)");
15512 case NT_ARM_HW_BREAK:
15513 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
15514 case NT_ARM_HW_WATCH:
15515 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 15516 case NT_PSTATUS:
1ec5cd37 15517 return _("NT_PSTATUS (pstatus structure)");
57346661 15518 case NT_FPREGS:
1ec5cd37 15519 return _("NT_FPREGS (floating point registers)");
57346661 15520 case NT_PSINFO:
1ec5cd37 15521 return _("NT_PSINFO (psinfo structure)");
57346661 15522 case NT_LWPSTATUS:
1ec5cd37 15523 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 15524 case NT_LWPSINFO:
1ec5cd37 15525 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 15526 case NT_WIN32PSTATUS:
1ec5cd37 15527 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
15528 case NT_SIGINFO:
15529 return _("NT_SIGINFO (siginfo_t data)");
15530 case NT_FILE:
15531 return _("NT_FILE (mapped files)");
1ec5cd37
NC
15532 default:
15533 break;
15534 }
15535 else
15536 switch (e_type)
15537 {
15538 case NT_VERSION:
15539 return _("NT_VERSION (version)");
15540 case NT_ARCH:
15541 return _("NT_ARCH (architecture)");
15542 default:
15543 break;
15544 }
15545
e9e44622 15546 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 15547 return buff;
779fe533
NC
15548}
15549
9ece1fa9
TT
15550static int
15551print_core_note (Elf_Internal_Note *pnote)
15552{
15553 unsigned int addr_size = is_32bit_elf ? 4 : 8;
15554 bfd_vma count, page_size;
15555 unsigned char *descdata, *filenames, *descend;
15556
15557 if (pnote->type != NT_FILE)
15558 return 1;
15559
15560#ifndef BFD64
15561 if (!is_32bit_elf)
15562 {
15563 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
15564 /* Still "successful". */
15565 return 1;
15566 }
15567#endif
15568
15569 if (pnote->descsz < 2 * addr_size)
15570 {
15571 printf (_(" Malformed note - too short for header\n"));
15572 return 0;
15573 }
15574
15575 descdata = (unsigned char *) pnote->descdata;
15576 descend = descdata + pnote->descsz;
15577
15578 if (descdata[pnote->descsz - 1] != '\0')
15579 {
15580 printf (_(" Malformed note - does not end with \\0\n"));
15581 return 0;
15582 }
15583
15584 count = byte_get (descdata, addr_size);
15585 descdata += addr_size;
15586
15587 page_size = byte_get (descdata, addr_size);
15588 descdata += addr_size;
15589
15590 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
15591 {
15592 printf (_(" Malformed note - too short for supplied file count\n"));
15593 return 0;
15594 }
15595
15596 printf (_(" Page size: "));
15597 print_vma (page_size, DEC);
15598 printf ("\n");
15599
15600 printf (_(" %*s%*s%*s\n"),
15601 (int) (2 + 2 * addr_size), _("Start"),
15602 (int) (4 + 2 * addr_size), _("End"),
15603 (int) (4 + 2 * addr_size), _("Page Offset"));
15604 filenames = descdata + count * 3 * addr_size;
595712bb 15605 while (count-- > 0)
9ece1fa9
TT
15606 {
15607 bfd_vma start, end, file_ofs;
15608
15609 if (filenames == descend)
15610 {
15611 printf (_(" Malformed note - filenames end too early\n"));
15612 return 0;
15613 }
15614
15615 start = byte_get (descdata, addr_size);
15616 descdata += addr_size;
15617 end = byte_get (descdata, addr_size);
15618 descdata += addr_size;
15619 file_ofs = byte_get (descdata, addr_size);
15620 descdata += addr_size;
15621
15622 printf (" ");
15623 print_vma (start, FULL_HEX);
15624 printf (" ");
15625 print_vma (end, FULL_HEX);
15626 printf (" ");
15627 print_vma (file_ofs, FULL_HEX);
15628 printf ("\n %s\n", filenames);
15629
15630 filenames += 1 + strlen ((char *) filenames);
15631 }
15632
15633 return 1;
15634}
15635
1118d252
RM
15636static const char *
15637get_gnu_elf_note_type (unsigned e_type)
15638{
1449284b 15639 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
15640 switch (e_type)
15641 {
15642 case NT_GNU_ABI_TAG:
15643 return _("NT_GNU_ABI_TAG (ABI version tag)");
15644 case NT_GNU_HWCAP:
15645 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
15646 case NT_GNU_BUILD_ID:
15647 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
15648 case NT_GNU_GOLD_VERSION:
15649 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252 15650 default:
1449284b
NC
15651 {
15652 static char buff[64];
1118d252 15653
1449284b
NC
15654 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
15655 return buff;
15656 }
15657 }
1118d252
RM
15658}
15659
664f90a3
TT
15660static int
15661print_gnu_note (Elf_Internal_Note *pnote)
15662{
1449284b 15663 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
15664 switch (pnote->type)
15665 {
15666 case NT_GNU_BUILD_ID:
15667 {
15668 unsigned long i;
15669
15670 printf (_(" Build ID: "));
15671 for (i = 0; i < pnote->descsz; ++i)
15672 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 15673 printf ("\n");
664f90a3
TT
15674 }
15675 break;
15676
15677 case NT_GNU_ABI_TAG:
15678 {
15679 unsigned long os, major, minor, subminor;
15680 const char *osname;
15681
3102e897
NC
15682 /* PR 17531: file: 030-599401-0.004. */
15683 if (pnote->descsz < 16)
15684 {
15685 printf (_(" <corrupt GNU_ABI_TAG>\n"));
15686 break;
15687 }
15688
664f90a3
TT
15689 os = byte_get ((unsigned char *) pnote->descdata, 4);
15690 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
15691 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
15692 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
15693
15694 switch (os)
15695 {
15696 case GNU_ABI_TAG_LINUX:
15697 osname = "Linux";
15698 break;
15699 case GNU_ABI_TAG_HURD:
15700 osname = "Hurd";
15701 break;
15702 case GNU_ABI_TAG_SOLARIS:
15703 osname = "Solaris";
15704 break;
15705 case GNU_ABI_TAG_FREEBSD:
15706 osname = "FreeBSD";
15707 break;
15708 case GNU_ABI_TAG_NETBSD:
15709 osname = "NetBSD";
15710 break;
14ae95f2
RM
15711 case GNU_ABI_TAG_SYLLABLE:
15712 osname = "Syllable";
15713 break;
15714 case GNU_ABI_TAG_NACL:
15715 osname = "NaCl";
15716 break;
664f90a3
TT
15717 default:
15718 osname = "Unknown";
15719 break;
15720 }
15721
15722 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
15723 major, minor, subminor);
15724 }
15725 break;
926c5385
CC
15726
15727 case NT_GNU_GOLD_VERSION:
15728 {
15729 unsigned long i;
15730
15731 printf (_(" Version: "));
15732 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
15733 printf ("%c", pnote->descdata[i]);
15734 printf ("\n");
15735 }
15736 break;
1449284b
NC
15737
15738 case NT_GNU_HWCAP:
15739 {
15740 unsigned long num_entries, mask;
15741
15742 /* Hardware capabilities information. Word 0 is the number of entries.
15743 Word 1 is a bitmask of enabled entries. The rest of the descriptor
15744 is a series of entries, where each entry is a single byte followed
15745 by a nul terminated string. The byte gives the bit number to test
15746 if enabled in the bitmask. */
15747 printf (_(" Hardware Capabilities: "));
15748 if (pnote->descsz < 8)
15749 {
15750 printf (_("<corrupt GNU_HWCAP>\n"));
15751 break;
15752 }
15753 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
15754 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
15755 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
15756 /* FIXME: Add code to display the entries... */
15757 }
15758 break;
15759
15760 default:
15761 /* Handle unrecognised types. An error message should have already been
15762 created by get_gnu_elf_note_type(), so all that we need to do is to
15763 display the data. */
15764 {
15765 unsigned long i;
15766
15767 printf (_(" Description data: "));
15768 for (i = 0; i < pnote->descsz; ++i)
15769 printf ("%02x ", pnote->descdata[i] & 0xff);
15770 printf ("\n");
15771 }
15772 break;
664f90a3
TT
15773 }
15774
15775 return 1;
15776}
15777
685080f2
NC
15778static const char *
15779get_v850_elf_note_type (enum v850_notes n_type)
15780{
15781 static char buff[64];
15782
15783 switch (n_type)
15784 {
15785 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
15786 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
15787 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
15788 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
15789 case V850_NOTE_CACHE_INFO: return _("Use of cache");
15790 case V850_NOTE_MMU_INFO: return _("Use of MMU");
15791 default:
15792 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
15793 return buff;
15794 }
15795}
15796
15797static int
15798print_v850_note (Elf_Internal_Note * pnote)
15799{
15800 unsigned int val;
15801
15802 if (pnote->descsz != 4)
15803 return 0;
15804 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
15805
15806 if (val == 0)
15807 {
15808 printf (_("not set\n"));
15809 return 1;
15810 }
15811
15812 switch (pnote->type)
15813 {
15814 case V850_NOTE_ALIGNMENT:
15815 switch (val)
15816 {
15817 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return 1;
15818 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return 1;
15819 }
15820 break;
14ae95f2 15821
685080f2
NC
15822 case V850_NOTE_DATA_SIZE:
15823 switch (val)
15824 {
15825 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return 1;
15826 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return 1;
15827 }
15828 break;
14ae95f2 15829
685080f2
NC
15830 case V850_NOTE_FPU_INFO:
15831 switch (val)
15832 {
15833 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return 1;
15834 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return 1;
15835 }
15836 break;
14ae95f2 15837
685080f2
NC
15838 case V850_NOTE_MMU_INFO:
15839 case V850_NOTE_CACHE_INFO:
15840 case V850_NOTE_SIMD_INFO:
15841 if (val == EF_RH850_SIMD)
15842 {
15843 printf (_("yes\n"));
15844 return 1;
15845 }
15846 break;
15847
15848 default:
15849 /* An 'unknown note type' message will already have been displayed. */
15850 break;
15851 }
15852
15853 printf (_("unknown value: %x\n"), val);
15854 return 0;
15855}
15856
15f205b1 15857static int
c6056a74
SF
15858process_netbsd_elf_note (Elf_Internal_Note * pnote)
15859{
15860 unsigned int version;
15861
15862 switch (pnote->type)
15863 {
15864 case NT_NETBSD_IDENT:
15865 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
15866 if ((version / 10000) % 100)
15867 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
15868 version, version / 100000000, (version / 1000000) % 100,
15869 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 15870 'A' + (version / 10000) % 26);
c6056a74
SF
15871 else
15872 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
15873 version, version / 100000000, (version / 1000000) % 100,
15f205b1 15874 (version / 100) % 100);
c6056a74
SF
15875 return 1;
15876
15877 case NT_NETBSD_MARCH:
15878 printf (" NetBSD\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
15879 pnote->descdata);
15880 return 1;
15881
15882 default:
15883 break;
15884 }
15885
15886 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n", pnote->descsz,
15887 pnote->type);
15888 return 1;
15889}
15890
f4ddf30f
JB
15891static const char *
15892get_freebsd_elfcore_note_type (unsigned e_type)
15893{
f4ddf30f
JB
15894 switch (e_type)
15895 {
15896 case NT_FREEBSD_THRMISC:
15897 return _("NT_THRMISC (thrmisc structure)");
15898 case NT_FREEBSD_PROCSTAT_PROC:
15899 return _("NT_PROCSTAT_PROC (proc data)");
15900 case NT_FREEBSD_PROCSTAT_FILES:
15901 return _("NT_PROCSTAT_FILES (files data)");
15902 case NT_FREEBSD_PROCSTAT_VMMAP:
15903 return _("NT_PROCSTAT_VMMAP (vmmap data)");
15904 case NT_FREEBSD_PROCSTAT_GROUPS:
15905 return _("NT_PROCSTAT_GROUPS (groups data)");
15906 case NT_FREEBSD_PROCSTAT_UMASK:
15907 return _("NT_PROCSTAT_UMASK (umask data)");
15908 case NT_FREEBSD_PROCSTAT_RLIMIT:
15909 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
15910 case NT_FREEBSD_PROCSTAT_OSREL:
15911 return _("NT_PROCSTAT_OSREL (osreldate data)");
15912 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
15913 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
15914 case NT_FREEBSD_PROCSTAT_AUXV:
15915 return _("NT_PROCSTAT_AUXV (auxv data)");
15916 }
15917 return get_note_type (e_type);
15918}
15919
9437c45b 15920static const char *
d3ba0551 15921get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
15922{
15923 static char buff[64];
15924
b4db1224 15925 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
15926 {
15927 /* NetBSD core "procinfo" structure. */
15928 return _("NetBSD procinfo structure");
15929 }
15930
15931 /* As of Jan 2002 there are no other machine-independent notes
15932 defined for NetBSD core files. If the note type is less
15933 than the start of the machine-dependent note types, we don't
15934 understand it. */
15935
b4db1224 15936 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 15937 {
e9e44622 15938 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
15939 return buff;
15940 }
15941
15942 switch (elf_header.e_machine)
15943 {
15944 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
15945 and PT_GETFPREGS == mach+2. */
15946
15947 case EM_OLD_ALPHA:
15948 case EM_ALPHA:
15949 case EM_SPARC:
15950 case EM_SPARC32PLUS:
15951 case EM_SPARCV9:
15952 switch (e_type)
15953 {
2b692964 15954 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 15955 return _("PT_GETREGS (reg structure)");
2b692964 15956 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 15957 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
15958 default:
15959 break;
15960 }
15961 break;
15962
15963 /* On all other arch's, PT_GETREGS == mach+1 and
15964 PT_GETFPREGS == mach+3. */
15965 default:
15966 switch (e_type)
15967 {
2b692964 15968 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 15969 return _("PT_GETREGS (reg structure)");
2b692964 15970 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 15971 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
15972 default:
15973 break;
15974 }
15975 }
15976
9cf03b7e 15977 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 15978 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
15979 return buff;
15980}
15981
70616151
TT
15982static const char *
15983get_stapsdt_note_type (unsigned e_type)
15984{
15985 static char buff[64];
15986
15987 switch (e_type)
15988 {
15989 case NT_STAPSDT:
15990 return _("NT_STAPSDT (SystemTap probe descriptors)");
15991
15992 default:
15993 break;
15994 }
15995
15996 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
15997 return buff;
15998}
15999
c6a9fc58
TT
16000static int
16001print_stapsdt_note (Elf_Internal_Note *pnote)
16002{
16003 int addr_size = is_32bit_elf ? 4 : 8;
16004 char *data = pnote->descdata;
16005 char *data_end = pnote->descdata + pnote->descsz;
16006 bfd_vma pc, base_addr, semaphore;
16007 char *provider, *probe, *arg_fmt;
16008
16009 pc = byte_get ((unsigned char *) data, addr_size);
16010 data += addr_size;
16011 base_addr = byte_get ((unsigned char *) data, addr_size);
16012 data += addr_size;
16013 semaphore = byte_get ((unsigned char *) data, addr_size);
16014 data += addr_size;
16015
16016 provider = data;
16017 data += strlen (data) + 1;
16018 probe = data;
16019 data += strlen (data) + 1;
16020 arg_fmt = data;
16021 data += strlen (data) + 1;
16022
16023 printf (_(" Provider: %s\n"), provider);
16024 printf (_(" Name: %s\n"), probe);
16025 printf (_(" Location: "));
16026 print_vma (pc, FULL_HEX);
16027 printf (_(", Base: "));
16028 print_vma (base_addr, FULL_HEX);
16029 printf (_(", Semaphore: "));
16030 print_vma (semaphore, FULL_HEX);
9cf03b7e 16031 printf ("\n");
c6a9fc58
TT
16032 printf (_(" Arguments: %s\n"), arg_fmt);
16033
16034 return data == data_end;
16035}
16036
00e98fc7
TG
16037static const char *
16038get_ia64_vms_note_type (unsigned e_type)
16039{
16040 static char buff[64];
16041
16042 switch (e_type)
16043 {
16044 case NT_VMS_MHD:
16045 return _("NT_VMS_MHD (module header)");
16046 case NT_VMS_LNM:
16047 return _("NT_VMS_LNM (language name)");
16048 case NT_VMS_SRC:
16049 return _("NT_VMS_SRC (source files)");
16050 case NT_VMS_TITLE:
9cf03b7e 16051 return "NT_VMS_TITLE";
00e98fc7
TG
16052 case NT_VMS_EIDC:
16053 return _("NT_VMS_EIDC (consistency check)");
16054 case NT_VMS_FPMODE:
16055 return _("NT_VMS_FPMODE (FP mode)");
16056 case NT_VMS_LINKTIME:
9cf03b7e 16057 return "NT_VMS_LINKTIME";
00e98fc7
TG
16058 case NT_VMS_IMGNAM:
16059 return _("NT_VMS_IMGNAM (image name)");
16060 case NT_VMS_IMGID:
16061 return _("NT_VMS_IMGID (image id)");
16062 case NT_VMS_LINKID:
16063 return _("NT_VMS_LINKID (link id)");
16064 case NT_VMS_IMGBID:
16065 return _("NT_VMS_IMGBID (build id)");
16066 case NT_VMS_GSTNAM:
16067 return _("NT_VMS_GSTNAM (sym table name)");
16068 case NT_VMS_ORIG_DYN:
9cf03b7e 16069 return "NT_VMS_ORIG_DYN";
00e98fc7 16070 case NT_VMS_PATCHTIME:
9cf03b7e 16071 return "NT_VMS_PATCHTIME";
00e98fc7
TG
16072 default:
16073 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
16074 return buff;
16075 }
16076}
16077
16078static int
16079print_ia64_vms_note (Elf_Internal_Note * pnote)
16080{
16081 switch (pnote->type)
16082 {
16083 case NT_VMS_MHD:
16084 if (pnote->descsz > 36)
16085 {
16086 size_t l = strlen (pnote->descdata + 34);
16087 printf (_(" Creation date : %.17s\n"), pnote->descdata);
16088 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
16089 printf (_(" Module name : %s\n"), pnote->descdata + 34);
16090 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
16091 }
16092 else
16093 printf (_(" Invalid size\n"));
16094 break;
16095 case NT_VMS_LNM:
16096 printf (_(" Language: %s\n"), pnote->descdata);
16097 break;
16098#ifdef BFD64
16099 case NT_VMS_FPMODE:
9cf03b7e 16100 printf (_(" Floating Point mode: "));
4a5cb34f 16101 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 16102 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
16103 break;
16104 case NT_VMS_LINKTIME:
16105 printf (_(" Link time: "));
16106 print_vms_time
16107 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
16108 printf ("\n");
16109 break;
16110 case NT_VMS_PATCHTIME:
16111 printf (_(" Patch time: "));
16112 print_vms_time
16113 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
16114 printf ("\n");
16115 break;
16116 case NT_VMS_ORIG_DYN:
16117 printf (_(" Major id: %u, minor id: %u\n"),
16118 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
16119 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 16120 printf (_(" Last modified : "));
00e98fc7
TG
16121 print_vms_time
16122 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 16123 printf (_("\n Link flags : "));
4a5cb34f 16124 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 16125 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 16126 printf (_(" Header flags: 0x%08x\n"),
948f632f 16127 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
00e98fc7
TG
16128 printf (_(" Image id : %s\n"), pnote->descdata + 32);
16129 break;
16130#endif
16131 case NT_VMS_IMGNAM:
16132 printf (_(" Image name: %s\n"), pnote->descdata);
16133 break;
16134 case NT_VMS_GSTNAM:
16135 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
16136 break;
16137 case NT_VMS_IMGID:
16138 printf (_(" Image id: %s\n"), pnote->descdata);
16139 break;
16140 case NT_VMS_LINKID:
16141 printf (_(" Linker id: %s\n"), pnote->descdata);
16142 break;
16143 default:
16144 break;
16145 }
16146 return 1;
16147}
16148
6d118b09
NC
16149/* Note that by the ELF standard, the name field is already null byte
16150 terminated, and namesz includes the terminating null byte.
16151 I.E. the value of namesz for the name "FSF" is 4.
16152
e3c8793a 16153 If the value of namesz is zero, there is no name present. */
779fe533 16154static int
1449284b
NC
16155process_note (Elf_Internal_Note * pnote,
16156 FILE * file ATTRIBUTE_UNUSED,
16157 Elf_Internal_Shdr * section ATTRIBUTE_UNUSED)
779fe533 16158{
2cf0635d
NC
16159 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
16160 const char * nt;
9437c45b
JT
16161
16162 if (pnote->namesz == 0)
1ec5cd37
NC
16163 /* If there is no note name, then use the default set of
16164 note type strings. */
16165 nt = get_note_type (pnote->type);
16166
1118d252
RM
16167 else if (const_strneq (pnote->namedata, "GNU"))
16168 /* GNU-specific object file notes. */
16169 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
16170
16171 else if (const_strneq (pnote->namedata, "FreeBSD"))
16172 /* FreeBSD-specific core file notes. */
16173 nt = get_freebsd_elfcore_note_type (pnote->type);
1118d252 16174
0112cd26 16175 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
16176 /* NetBSD-specific core file notes. */
16177 nt = get_netbsd_elfcore_note_type (pnote->type);
16178
c6056a74
SF
16179 else if (const_strneq (pnote->namedata, "NetBSD"))
16180 /* NetBSD-specific core file notes. */
16181 return process_netbsd_elf_note (pnote);
16182
b15fa79e
AM
16183 else if (strneq (pnote->namedata, "SPU/", 4))
16184 {
16185 /* SPU-specific core file notes. */
16186 nt = pnote->namedata + 4;
16187 name = "SPU";
16188 }
16189
00e98fc7
TG
16190 else if (const_strneq (pnote->namedata, "IPF/VMS"))
16191 /* VMS/ia64-specific file notes. */
16192 nt = get_ia64_vms_note_type (pnote->type);
16193
70616151
TT
16194 else if (const_strneq (pnote->namedata, "stapsdt"))
16195 nt = get_stapsdt_note_type (pnote->type);
16196
9437c45b 16197 else
1ec5cd37
NC
16198 /* Don't recognize this note name; just use the default set of
16199 note type strings. */
00e98fc7 16200 nt = get_note_type (pnote->type);
9437c45b 16201
1449284b
NC
16202 printf (" ");
16203 print_symbol (-20, name);
16204 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
16205
16206 if (const_strneq (pnote->namedata, "IPF/VMS"))
16207 return print_ia64_vms_note (pnote);
664f90a3
TT
16208 else if (const_strneq (pnote->namedata, "GNU"))
16209 return print_gnu_note (pnote);
c6a9fc58
TT
16210 else if (const_strneq (pnote->namedata, "stapsdt"))
16211 return print_stapsdt_note (pnote);
9ece1fa9
TT
16212 else if (const_strneq (pnote->namedata, "CORE"))
16213 return print_core_note (pnote);
779fe533 16214
1449284b
NC
16215 else if (pnote->descsz)
16216 {
16217 unsigned long i;
16218
16219 printf (_(" description data: "));
16220 for (i = 0; i < pnote->descsz; i++)
16221 printf ("%02x ", pnote->descdata[i]);
16222 printf ("\n");
16223 }
16224
16225 return 1;
16226}
6d118b09 16227
779fe533 16228static int
1449284b
NC
16229process_notes_at (FILE * file,
16230 Elf_Internal_Shdr * section,
16231 bfd_vma offset,
16232 bfd_vma length)
779fe533 16233{
2cf0635d
NC
16234 Elf_External_Note * pnotes;
16235 Elf_External_Note * external;
c8071705 16236 char * end;
b34976b6 16237 int res = 1;
103f02d3 16238
779fe533
NC
16239 if (length <= 0)
16240 return 0;
103f02d3 16241
1449284b
NC
16242 if (section)
16243 {
16244 pnotes = (Elf_External_Note *) get_section_contents (section, file);
16245 if (pnotes)
16246 apply_relocations (file, section, (unsigned char *) pnotes, length, NULL, NULL);
16247 }
16248 else
16249 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
16250 _("notes"));
dd24e3da 16251 if (pnotes == NULL)
a6e9f9df 16252 return 0;
779fe533 16253
103f02d3 16254 external = pnotes;
103f02d3 16255
1449284b
NC
16256 if (section)
16257 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (section));
16258 else
16259 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
16260 (unsigned long) offset, (unsigned long) length);
16261
2aee03ae 16262 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 16263
c8071705
NC
16264 end = (char *) pnotes + length;
16265 while ((char *) external < end)
779fe533 16266 {
b34976b6 16267 Elf_Internal_Note inote;
15b42fb0
AM
16268 size_t min_notesz;
16269 char *next;
2cf0635d 16270 char * temp = NULL;
c8071705 16271 size_t data_remaining = end - (char *) external;
6d118b09 16272
00e98fc7 16273 if (!is_ia64_vms ())
15b42fb0 16274 {
9dd3a467
NC
16275 /* PR binutils/15191
16276 Make sure that there is enough data to read. */
15b42fb0
AM
16277 min_notesz = offsetof (Elf_External_Note, name);
16278 if (data_remaining < min_notesz)
9dd3a467
NC
16279 {
16280 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
16281 (int) data_remaining);
16282 break;
16283 }
15b42fb0
AM
16284 inote.type = BYTE_GET (external->type);
16285 inote.namesz = BYTE_GET (external->namesz);
16286 inote.namedata = external->name;
16287 inote.descsz = BYTE_GET (external->descsz);
16288 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
834f871c 16289 /* PR 17531: file: 3443835e. */
c8071705 16290 if (inote.descdata < (char *) pnotes || inote.descdata > end)
834f871c
NC
16291 {
16292 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
16293 inote.descdata = inote.namedata;
16294 inote.namesz = 0;
16295 }
14ae95f2 16296
15b42fb0
AM
16297 inote.descpos = offset + (inote.descdata - (char *) pnotes);
16298 next = inote.descdata + align_power (inote.descsz, 2);
16299 }
00e98fc7 16300 else
15b42fb0
AM
16301 {
16302 Elf64_External_VMS_Note *vms_external;
00e98fc7 16303
9dd3a467
NC
16304 /* PR binutils/15191
16305 Make sure that there is enough data to read. */
15b42fb0
AM
16306 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16307 if (data_remaining < min_notesz)
9dd3a467
NC
16308 {
16309 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
16310 (int) data_remaining);
16311 break;
16312 }
3e55a963 16313
15b42fb0
AM
16314 vms_external = (Elf64_External_VMS_Note *) external;
16315 inote.type = BYTE_GET (vms_external->type);
16316 inote.namesz = BYTE_GET (vms_external->namesz);
16317 inote.namedata = vms_external->name;
16318 inote.descsz = BYTE_GET (vms_external->descsz);
16319 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16320 inote.descpos = offset + (inote.descdata - (char *) pnotes);
16321 next = inote.descdata + align_power (inote.descsz, 3);
16322 }
16323
16324 if (inote.descdata < (char *) external + min_notesz
16325 || next < (char *) external + min_notesz
5d921cbd
NC
16326 /* PR binutils/17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
16327 || inote.namedata + inote.namesz < inote.namedata
16328 || inote.descdata + inote.descsz < inote.descdata
15b42fb0 16329 || data_remaining < (size_t)(next - (char *) external))
3e55a963 16330 {
15b42fb0 16331 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 16332 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 16333 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
16334 inote.type, inote.namesz, inote.descsz);
16335 break;
16336 }
16337
15b42fb0 16338 external = (Elf_External_Note *) next;
dd24e3da 16339
6d118b09
NC
16340 /* Verify that name is null terminated. It appears that at least
16341 one version of Linux (RedHat 6.0) generates corefiles that don't
16342 comply with the ELF spec by failing to include the null byte in
16343 namesz. */
8b971f9f 16344 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 16345 {
3f5e193b 16346 temp = (char *) malloc (inote.namesz + 1);
6d118b09
NC
16347 if (temp == NULL)
16348 {
8b73c356 16349 error (_("Out of memory allocating space for inote name\n"));
6d118b09
NC
16350 res = 0;
16351 break;
16352 }
76da6bbe 16353
6d118b09
NC
16354 strncpy (temp, inote.namedata, inote.namesz);
16355 temp[inote.namesz] = 0;
76da6bbe 16356
6d118b09
NC
16357 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
16358 inote.namedata = temp;
16359 }
16360
1449284b 16361 res &= process_note (& inote, file, section);
103f02d3 16362
6d118b09
NC
16363 if (temp != NULL)
16364 {
16365 free (temp);
16366 temp = NULL;
16367 }
779fe533
NC
16368 }
16369
16370 free (pnotes);
103f02d3 16371
779fe533
NC
16372 return res;
16373}
16374
16375static int
2cf0635d 16376process_corefile_note_segments (FILE * file)
779fe533 16377{
2cf0635d 16378 Elf_Internal_Phdr * segment;
b34976b6
AM
16379 unsigned int i;
16380 int res = 1;
103f02d3 16381
d93f0186 16382 if (! get_program_headers (file))
779fe533 16383 return 0;
103f02d3 16384
779fe533
NC
16385 for (i = 0, segment = program_headers;
16386 i < elf_header.e_phnum;
b34976b6 16387 i++, segment++)
779fe533
NC
16388 {
16389 if (segment->p_type == PT_NOTE)
1449284b
NC
16390 res &= process_notes_at (file, NULL,
16391 (bfd_vma) segment->p_offset,
16392 (bfd_vma) segment->p_filesz);
779fe533 16393 }
103f02d3 16394
779fe533
NC
16395 return res;
16396}
16397
685080f2
NC
16398static int
16399process_v850_notes (FILE * file, bfd_vma offset, bfd_vma length)
16400{
16401 Elf_External_Note * pnotes;
16402 Elf_External_Note * external;
c8071705 16403 char * end;
685080f2
NC
16404 int res = 1;
16405
16406 if (length <= 0)
16407 return 0;
16408
16409 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
16410 _("v850 notes"));
16411 if (pnotes == NULL)
16412 return 0;
16413
16414 external = pnotes;
c8071705 16415 end = (char*) pnotes + length;
685080f2
NC
16416
16417 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
16418 (unsigned long) offset, (unsigned long) length);
16419
c8071705 16420 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
16421 {
16422 Elf_External_Note * next;
16423 Elf_Internal_Note inote;
16424
16425 inote.type = BYTE_GET (external->type);
16426 inote.namesz = BYTE_GET (external->namesz);
16427 inote.namedata = external->name;
16428 inote.descsz = BYTE_GET (external->descsz);
16429 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
16430 inote.descpos = offset + (inote.descdata - (char *) pnotes);
16431
c8071705
NC
16432 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
16433 {
16434 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
16435 inote.descdata = inote.namedata;
16436 inote.namesz = 0;
16437 }
16438
685080f2
NC
16439 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
16440
c8071705 16441 if ( ((char *) next > end)
685080f2
NC
16442 || ((char *) next < (char *) pnotes))
16443 {
16444 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
16445 (unsigned long) ((char *) external - (char *) pnotes));
16446 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
16447 inote.type, inote.namesz, inote.descsz);
16448 break;
16449 }
16450
16451 external = next;
16452
16453 /* Prevent out-of-bounds indexing. */
c8071705 16454 if ( inote.namedata + inote.namesz > end
685080f2
NC
16455 || inote.namedata + inote.namesz < inote.namedata)
16456 {
16457 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
16458 (unsigned long) ((char *) external - (char *) pnotes));
16459 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
16460 inote.type, inote.namesz, inote.descsz);
16461 break;
16462 }
16463
16464 printf (" %s: ", get_v850_elf_note_type (inote.type));
16465
16466 if (! print_v850_note (& inote))
16467 {
16468 res = 0;
16469 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
16470 inote.namesz, inote.descsz);
16471 }
16472 }
16473
16474 free (pnotes);
16475
16476 return res;
16477}
16478
779fe533 16479static int
2cf0635d 16480process_note_sections (FILE * file)
1ec5cd37 16481{
2cf0635d 16482 Elf_Internal_Shdr * section;
1ec5cd37 16483 unsigned long i;
df565f32 16484 int n = 0;
1ec5cd37
NC
16485 int res = 1;
16486
16487 for (i = 0, section = section_headers;
fa1908fd 16488 i < elf_header.e_shnum && section != NULL;
1ec5cd37 16489 i++, section++)
685080f2
NC
16490 {
16491 if (section->sh_type == SHT_NOTE)
16492 {
1449284b
NC
16493 res &= process_notes_at (file, section,
16494 (bfd_vma) section->sh_offset,
16495 (bfd_vma) section->sh_size);
685080f2
NC
16496 n++;
16497 }
16498
16499 if (( elf_header.e_machine == EM_V800
16500 || elf_header.e_machine == EM_V850
16501 || elf_header.e_machine == EM_CYGNUS_V850)
16502 && section->sh_type == SHT_RENESAS_INFO)
16503 {
16504 res &= process_v850_notes (file,
16505 (bfd_vma) section->sh_offset,
16506 (bfd_vma) section->sh_size);
16507 n++;
16508 }
16509 }
df565f32
NC
16510
16511 if (n == 0)
16512 /* Try processing NOTE segments instead. */
16513 return process_corefile_note_segments (file);
1ec5cd37
NC
16514
16515 return res;
16516}
16517
16518static int
2cf0635d 16519process_notes (FILE * file)
779fe533
NC
16520{
16521 /* If we have not been asked to display the notes then do nothing. */
16522 if (! do_notes)
16523 return 1;
103f02d3 16524
779fe533 16525 if (elf_header.e_type != ET_CORE)
1ec5cd37 16526 return process_note_sections (file);
103f02d3 16527
779fe533 16528 /* No program headers means no NOTE segment. */
1ec5cd37
NC
16529 if (elf_header.e_phnum > 0)
16530 return process_corefile_note_segments (file);
779fe533 16531
1ec5cd37
NC
16532 printf (_("No note segments present in the core file.\n"));
16533 return 1;
779fe533
NC
16534}
16535
252b5132 16536static int
2cf0635d 16537process_arch_specific (FILE * file)
252b5132 16538{
a952a375
NC
16539 if (! do_arch)
16540 return 1;
16541
252b5132
RH
16542 switch (elf_header.e_machine)
16543 {
11c1ff18
PB
16544 case EM_ARM:
16545 return process_arm_specific (file);
252b5132 16546 case EM_MIPS:
4fe85591 16547 case EM_MIPS_RS3_LE:
252b5132
RH
16548 return process_mips_specific (file);
16549 break;
35c08157
KLC
16550 case EM_NDS32:
16551 return process_nds32_specific (file);
16552 break;
34c8bcba 16553 case EM_PPC:
b82317dd 16554 case EM_PPC64:
34c8bcba
JM
16555 return process_power_specific (file);
16556 break;
643f7afb
AK
16557 case EM_S390:
16558 case EM_S390_OLD:
16559 return process_s390_specific (file);
16560 break;
9e8c70f9
DM
16561 case EM_SPARC:
16562 case EM_SPARC32PLUS:
16563 case EM_SPARCV9:
16564 return process_sparc_specific (file);
16565 break;
59e6276b
JM
16566 case EM_TI_C6000:
16567 return process_tic6x_specific (file);
16568 break;
13761a11
NC
16569 case EM_MSP430:
16570 return process_msp430x_specific (file);
252b5132
RH
16571 default:
16572 break;
16573 }
16574 return 1;
16575}
16576
16577static int
2cf0635d 16578get_file_header (FILE * file)
252b5132 16579{
9ea033b2
NC
16580 /* Read in the identity array. */
16581 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
16582 return 0;
16583
9ea033b2 16584 /* Determine how to read the rest of the header. */
b34976b6 16585 switch (elf_header.e_ident[EI_DATA])
9ea033b2 16586 {
1a0670f3
AM
16587 default:
16588 case ELFDATANONE:
adab8cdc
AO
16589 case ELFDATA2LSB:
16590 byte_get = byte_get_little_endian;
16591 byte_put = byte_put_little_endian;
16592 break;
16593 case ELFDATA2MSB:
16594 byte_get = byte_get_big_endian;
16595 byte_put = byte_put_big_endian;
16596 break;
9ea033b2
NC
16597 }
16598
16599 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 16600 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
16601
16602 /* Read in the rest of the header. */
16603 if (is_32bit_elf)
16604 {
16605 Elf32_External_Ehdr ehdr32;
252b5132 16606
9ea033b2
NC
16607 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
16608 return 0;
103f02d3 16609
9ea033b2
NC
16610 elf_header.e_type = BYTE_GET (ehdr32.e_type);
16611 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
16612 elf_header.e_version = BYTE_GET (ehdr32.e_version);
16613 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
16614 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
16615 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
16616 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
16617 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
16618 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
16619 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
16620 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
16621 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
16622 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
16623 }
252b5132 16624 else
9ea033b2
NC
16625 {
16626 Elf64_External_Ehdr ehdr64;
a952a375
NC
16627
16628 /* If we have been compiled with sizeof (bfd_vma) == 4, then
16629 we will not be able to cope with the 64bit data found in
16630 64 ELF files. Detect this now and abort before we start
50c2245b 16631 overwriting things. */
a952a375
NC
16632 if (sizeof (bfd_vma) < 8)
16633 {
e3c8793a
NC
16634 error (_("This instance of readelf has been built without support for a\n\
1663564 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
16636 return 0;
16637 }
103f02d3 16638
9ea033b2
NC
16639 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
16640 return 0;
103f02d3 16641
9ea033b2
NC
16642 elf_header.e_type = BYTE_GET (ehdr64.e_type);
16643 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
16644 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
16645 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
16646 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
16647 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
16648 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
16649 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
16650 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
16651 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
16652 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
16653 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
16654 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
16655 }
252b5132 16656
7ece0d85
JJ
16657 if (elf_header.e_shoff)
16658 {
16659 /* There may be some extensions in the first section header. Don't
16660 bomb if we can't read it. */
16661 if (is_32bit_elf)
049b0c3a 16662 get_32bit_section_headers (file, TRUE);
7ece0d85 16663 else
049b0c3a 16664 get_64bit_section_headers (file, TRUE);
7ece0d85 16665 }
560f3c1c 16666
252b5132
RH
16667 return 1;
16668}
16669
fb52b2f4
NC
16670/* Process one ELF object file according to the command line options.
16671 This file may actually be stored in an archive. The file is
16672 positioned at the start of the ELF object. */
16673
ff78d6d6 16674static int
2cf0635d 16675process_object (char * file_name, FILE * file)
252b5132 16676{
252b5132
RH
16677 unsigned int i;
16678
252b5132
RH
16679 if (! get_file_header (file))
16680 {
16681 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 16682 return 1;
252b5132
RH
16683 }
16684
16685 /* Initialise per file variables. */
60bca95a 16686 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
16687 version_info[i] = 0;
16688
60bca95a 16689 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 16690 dynamic_info[i] = 0;
5115b233 16691 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
16692
16693 /* Process the file. */
16694 if (show_name)
16695 printf (_("\nFile: %s\n"), file_name);
16696
18bd398b
NC
16697 /* Initialise the dump_sects array from the cmdline_dump_sects array.
16698 Note we do this even if cmdline_dump_sects is empty because we
16699 must make sure that the dump_sets array is zeroed out before each
16700 object file is processed. */
16701 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 16702 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
16703
16704 if (num_cmdline_dump_sects > 0)
16705 {
16706 if (num_dump_sects == 0)
16707 /* A sneaky way of allocating the dump_sects array. */
09c11c86 16708 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
16709
16710 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
16711 memcpy (dump_sects, cmdline_dump_sects,
16712 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 16713 }
d70c5fc7 16714
252b5132 16715 if (! process_file_header ())
fb52b2f4 16716 return 1;
252b5132 16717
d1f5c6e3 16718 if (! process_section_headers (file))
2f62977e 16719 {
d1f5c6e3
L
16720 /* Without loaded section headers we cannot process lots of
16721 things. */
2f62977e 16722 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 16723
2f62977e 16724 if (! do_using_dynamic)
2c610e4b 16725 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 16726 }
252b5132 16727
d1f5c6e3
L
16728 if (! process_section_groups (file))
16729 {
16730 /* Without loaded section groups we cannot process unwind. */
16731 do_unwind = 0;
16732 }
16733
2f62977e 16734 if (process_program_headers (file))
b2d38a17 16735 process_dynamic_section (file);
252b5132
RH
16736
16737 process_relocs (file);
16738
4d6ed7c8
NC
16739 process_unwind (file);
16740
252b5132
RH
16741 process_symbol_table (file);
16742
16743 process_syminfo (file);
16744
16745 process_version_sections (file);
16746
16747 process_section_contents (file);
f5842774 16748
1ec5cd37 16749 process_notes (file);
103f02d3 16750
047b2264
JJ
16751 process_gnu_liblist (file);
16752
252b5132
RH
16753 process_arch_specific (file);
16754
d93f0186
NC
16755 if (program_headers)
16756 {
16757 free (program_headers);
16758 program_headers = NULL;
16759 }
16760
252b5132
RH
16761 if (section_headers)
16762 {
16763 free (section_headers);
16764 section_headers = NULL;
16765 }
16766
16767 if (string_table)
16768 {
16769 free (string_table);
16770 string_table = NULL;
d40ac9bd 16771 string_table_length = 0;
252b5132
RH
16772 }
16773
16774 if (dynamic_strings)
16775 {
16776 free (dynamic_strings);
16777 dynamic_strings = NULL;
d79b3d50 16778 dynamic_strings_length = 0;
252b5132
RH
16779 }
16780
16781 if (dynamic_symbols)
16782 {
16783 free (dynamic_symbols);
16784 dynamic_symbols = NULL;
19936277 16785 num_dynamic_syms = 0;
252b5132
RH
16786 }
16787
16788 if (dynamic_syminfo)
16789 {
16790 free (dynamic_syminfo);
16791 dynamic_syminfo = NULL;
16792 }
ff78d6d6 16793
293c573e
MR
16794 if (dynamic_section)
16795 {
16796 free (dynamic_section);
16797 dynamic_section = NULL;
16798 }
16799
e4b17d5c
L
16800 if (section_headers_groups)
16801 {
16802 free (section_headers_groups);
16803 section_headers_groups = NULL;
16804 }
16805
16806 if (section_groups)
16807 {
2cf0635d
NC
16808 struct group_list * g;
16809 struct group_list * next;
e4b17d5c
L
16810
16811 for (i = 0; i < group_count; i++)
16812 {
16813 for (g = section_groups [i].root; g != NULL; g = next)
16814 {
16815 next = g->next;
16816 free (g);
16817 }
16818 }
16819
16820 free (section_groups);
16821 section_groups = NULL;
16822 }
16823
19e6b90e 16824 free_debug_memory ();
18bd398b 16825
ff78d6d6 16826 return 0;
252b5132
RH
16827}
16828
2cf0635d
NC
16829/* Process an ELF archive.
16830 On entry the file is positioned just after the ARMAG string. */
16831
16832static int
16833process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
16834{
16835 struct archive_info arch;
16836 struct archive_info nested_arch;
16837 size_t got;
2cf0635d
NC
16838 int ret;
16839
16840 show_name = 1;
16841
16842 /* The ARCH structure is used to hold information about this archive. */
16843 arch.file_name = NULL;
16844 arch.file = NULL;
16845 arch.index_array = NULL;
16846 arch.sym_table = NULL;
16847 arch.longnames = NULL;
16848
16849 /* The NESTED_ARCH structure is used as a single-item cache of information
16850 about a nested archive (when members of a thin archive reside within
16851 another regular archive file). */
16852 nested_arch.file_name = NULL;
16853 nested_arch.file = NULL;
16854 nested_arch.index_array = NULL;
16855 nested_arch.sym_table = NULL;
16856 nested_arch.longnames = NULL;
16857
16858 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
16859 {
16860 ret = 1;
16861 goto out;
4145f1d5 16862 }
fb52b2f4 16863
4145f1d5
NC
16864 if (do_archive_index)
16865 {
2cf0635d 16866 if (arch.sym_table == NULL)
4145f1d5
NC
16867 error (_("%s: unable to dump the index as none was found\n"), file_name);
16868 else
16869 {
591f7597 16870 unsigned long i, l;
4145f1d5
NC
16871 unsigned long current_pos;
16872
591f7597
NC
16873 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
16874 file_name, (unsigned long) arch.index_num, arch.sym_size);
4145f1d5
NC
16875 current_pos = ftell (file);
16876
2cf0635d 16877 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 16878 {
2cf0635d
NC
16879 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
16880 {
16881 char * member_name;
4145f1d5 16882
2cf0635d
NC
16883 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
16884
16885 if (member_name != NULL)
16886 {
16887 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
16888
16889 if (qualified_name != NULL)
16890 {
c2a7d3f5
NC
16891 printf (_("Contents of binary %s at offset "), qualified_name);
16892 (void) print_vma (arch.index_array[i], PREFIX_HEX);
16893 putchar ('\n');
2cf0635d
NC
16894 free (qualified_name);
16895 }
4145f1d5
NC
16896 }
16897 }
2cf0635d
NC
16898
16899 if (l >= arch.sym_size)
4145f1d5
NC
16900 {
16901 error (_("%s: end of the symbol table reached before the end of the index\n"),
16902 file_name);
cb8f3167 16903 break;
4145f1d5 16904 }
591f7597
NC
16905 /* PR 17531: file: 0b6630b2. */
16906 printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
16907 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
16908 }
16909
c2a7d3f5
NC
16910 if (arch.uses_64bit_indicies)
16911 l = (l + 7) & ~ 7;
16912 else
16913 l += l & 1;
16914
2cf0635d 16915 if (l < arch.sym_size)
c2a7d3f5
NC
16916 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
16917 file_name, arch.sym_size - l);
4145f1d5 16918
4145f1d5
NC
16919 if (fseek (file, current_pos, SEEK_SET) != 0)
16920 {
16921 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
16922 ret = 1;
16923 goto out;
4145f1d5 16924 }
fb52b2f4 16925 }
4145f1d5
NC
16926
16927 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
16928 && !do_segments && !do_header && !do_dump && !do_version
16929 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 16930 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
16931 {
16932 ret = 0; /* Archive index only. */
16933 goto out;
16934 }
fb52b2f4
NC
16935 }
16936
d989285c 16937 ret = 0;
fb52b2f4
NC
16938
16939 while (1)
16940 {
2cf0635d
NC
16941 char * name;
16942 size_t namelen;
16943 char * qualified_name;
16944
16945 /* Read the next archive header. */
16946 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
16947 {
16948 error (_("%s: failed to seek to next archive header\n"), file_name);
16949 return 1;
16950 }
16951 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
16952 if (got != sizeof arch.arhdr)
16953 {
16954 if (got == 0)
16955 break;
16956 error (_("%s: failed to read archive header\n"), file_name);
16957 ret = 1;
16958 break;
16959 }
16960 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
16961 {
16962 error (_("%s: did not find a valid archive header\n"), arch.file_name);
16963 ret = 1;
16964 break;
16965 }
16966
16967 arch.next_arhdr_offset += sizeof arch.arhdr;
16968
16969 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
16970 if (archive_file_size & 01)
16971 ++archive_file_size;
16972
16973 name = get_archive_member_name (&arch, &nested_arch);
16974 if (name == NULL)
fb52b2f4 16975 {
0fd3a477 16976 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
16977 ret = 1;
16978 break;
fb52b2f4 16979 }
2cf0635d 16980 namelen = strlen (name);
fb52b2f4 16981
2cf0635d
NC
16982 qualified_name = make_qualified_name (&arch, &nested_arch, name);
16983 if (qualified_name == NULL)
fb52b2f4 16984 {
2cf0635d 16985 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
16986 ret = 1;
16987 break;
fb52b2f4
NC
16988 }
16989
2cf0635d
NC
16990 if (is_thin_archive && arch.nested_member_origin == 0)
16991 {
16992 /* This is a proxy for an external member of a thin archive. */
16993 FILE * member_file;
16994 char * member_file_name = adjust_relative_path (file_name, name, namelen);
16995 if (member_file_name == NULL)
16996 {
16997 ret = 1;
16998 break;
16999 }
17000
17001 member_file = fopen (member_file_name, "rb");
17002 if (member_file == NULL)
17003 {
17004 error (_("Input file '%s' is not readable.\n"), member_file_name);
17005 free (member_file_name);
17006 ret = 1;
17007 break;
17008 }
17009
17010 archive_file_offset = arch.nested_member_origin;
17011
17012 ret |= process_object (qualified_name, member_file);
17013
17014 fclose (member_file);
17015 free (member_file_name);
17016 }
17017 else if (is_thin_archive)
17018 {
a043396b
NC
17019 /* PR 15140: Allow for corrupt thin archives. */
17020 if (nested_arch.file == NULL)
17021 {
17022 error (_("%s: contains corrupt thin archive: %s\n"),
17023 file_name, name);
17024 ret = 1;
17025 break;
17026 }
17027
2cf0635d
NC
17028 /* This is a proxy for a member of a nested archive. */
17029 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
17030
17031 /* The nested archive file will have been opened and setup by
17032 get_archive_member_name. */
17033 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
17034 {
17035 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
17036 ret = 1;
17037 break;
17038 }
17039
17040 ret |= process_object (qualified_name, nested_arch.file);
17041 }
17042 else
17043 {
17044 archive_file_offset = arch.next_arhdr_offset;
17045 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 17046
2cf0635d
NC
17047 ret |= process_object (qualified_name, file);
17048 }
fb52b2f4 17049
2b52916e
L
17050 if (dump_sects != NULL)
17051 {
17052 free (dump_sects);
17053 dump_sects = NULL;
17054 num_dump_sects = 0;
17055 }
17056
2cf0635d 17057 free (qualified_name);
fb52b2f4
NC
17058 }
17059
4145f1d5 17060 out:
2cf0635d
NC
17061 if (nested_arch.file != NULL)
17062 fclose (nested_arch.file);
17063 release_archive (&nested_arch);
17064 release_archive (&arch);
fb52b2f4 17065
d989285c 17066 return ret;
fb52b2f4
NC
17067}
17068
17069static int
2cf0635d 17070process_file (char * file_name)
fb52b2f4 17071{
2cf0635d 17072 FILE * file;
fb52b2f4
NC
17073 struct stat statbuf;
17074 char armag[SARMAG];
17075 int ret;
17076
17077 if (stat (file_name, &statbuf) < 0)
17078 {
f24ddbdd
NC
17079 if (errno == ENOENT)
17080 error (_("'%s': No such file\n"), file_name);
17081 else
17082 error (_("Could not locate '%s'. System error message: %s\n"),
17083 file_name, strerror (errno));
17084 return 1;
17085 }
17086
17087 if (! S_ISREG (statbuf.st_mode))
17088 {
17089 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
17090 return 1;
17091 }
17092
17093 file = fopen (file_name, "rb");
17094 if (file == NULL)
17095 {
f24ddbdd 17096 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
17097 return 1;
17098 }
17099
17100 if (fread (armag, SARMAG, 1, file) != 1)
17101 {
4145f1d5 17102 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
17103 fclose (file);
17104 return 1;
17105 }
17106
f54498b4
NC
17107 current_file_size = (bfd_size_type) statbuf.st_size;
17108
fb52b2f4 17109 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
17110 ret = process_archive (file_name, file, FALSE);
17111 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
17112 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
17113 else
17114 {
4145f1d5
NC
17115 if (do_archive_index)
17116 error (_("File %s is not an archive so its index cannot be displayed.\n"),
17117 file_name);
17118
fb52b2f4
NC
17119 rewind (file);
17120 archive_file_size = archive_file_offset = 0;
17121 ret = process_object (file_name, file);
17122 }
17123
17124 fclose (file);
17125
f54498b4 17126 current_file_size = 0;
fb52b2f4
NC
17127 return ret;
17128}
17129
252b5132
RH
17130#ifdef SUPPORT_DISASSEMBLY
17131/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 17132 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 17133 symbols. */
252b5132
RH
17134
17135void
2cf0635d 17136print_address (unsigned int addr, FILE * outfile)
252b5132
RH
17137{
17138 fprintf (outfile,"0x%8.8x", addr);
17139}
17140
e3c8793a 17141/* Needed by the i386 disassembler. */
252b5132
RH
17142void
17143db_task_printsym (unsigned int addr)
17144{
17145 print_address (addr, stderr);
17146}
17147#endif
17148
17149int
2cf0635d 17150main (int argc, char ** argv)
252b5132 17151{
ff78d6d6
L
17152 int err;
17153
252b5132
RH
17154#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
17155 setlocale (LC_MESSAGES, "");
3882b010
L
17156#endif
17157#if defined (HAVE_SETLOCALE)
17158 setlocale (LC_CTYPE, "");
252b5132
RH
17159#endif
17160 bindtextdomain (PACKAGE, LOCALEDIR);
17161 textdomain (PACKAGE);
17162
869b9d07
MM
17163 expandargv (&argc, &argv);
17164
252b5132
RH
17165 parse_args (argc, argv);
17166
18bd398b 17167 if (num_dump_sects > 0)
59f14fc0 17168 {
18bd398b 17169 /* Make a copy of the dump_sects array. */
3f5e193b
NC
17170 cmdline_dump_sects = (dump_type *)
17171 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 17172 if (cmdline_dump_sects == NULL)
591a748a 17173 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
17174 else
17175 {
09c11c86
NC
17176 memcpy (cmdline_dump_sects, dump_sects,
17177 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
17178 num_cmdline_dump_sects = num_dump_sects;
17179 }
17180 }
17181
18bd398b
NC
17182 if (optind < (argc - 1))
17183 show_name = 1;
5656ba2c
L
17184 else if (optind >= argc)
17185 {
17186 warn (_("Nothing to do.\n"));
17187 usage (stderr);
17188 }
18bd398b 17189
ff78d6d6 17190 err = 0;
252b5132 17191 while (optind < argc)
18bd398b 17192 err |= process_file (argv[optind++]);
252b5132
RH
17193
17194 if (dump_sects != NULL)
17195 free (dump_sects);
59f14fc0
AS
17196 if (cmdline_dump_sects != NULL)
17197 free (cmdline_dump_sects);
252b5132 17198
ff78d6d6 17199 return err;
252b5132 17200}
This page took 2.574996 seconds and 4 git commands to generate.