]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
ld: add support for eBPF
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
82704155 2 Copyright (C) 1998-2019 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"
b8891f8d 101#include "elf/csky.h"
252b5132
RH
102#include "elf/d10v.h"
103#include "elf/d30v.h"
d172d4ba 104#include "elf/dlx.h"
cfb8c092 105#include "elf/epiphany.h"
252b5132 106#include "elf/fr30.h"
5c70f934 107#include "elf/frv.h"
3f8107ab 108#include "elf/ft32.h"
3b16e843
NC
109#include "elf/h8.h"
110#include "elf/hppa.h"
111#include "elf/i386.h"
f954747f
AM
112#include "elf/i370.h"
113#include "elf/i860.h"
114#include "elf/i960.h"
3b16e843 115#include "elf/ia64.h"
1e4cf259 116#include "elf/ip2k.h"
84e94c90 117#include "elf/lm32.h"
1c0d3aa6 118#include "elf/iq2000.h"
49f58d10 119#include "elf/m32c.h"
3b16e843
NC
120#include "elf/m32r.h"
121#include "elf/m68k.h"
75751cd9 122#include "elf/m68hc11.h"
7b4ae824 123#include "elf/s12z.h"
252b5132 124#include "elf/mcore.h"
15ab5209 125#include "elf/mep.h"
a3c62988 126#include "elf/metag.h"
7ba29e2a 127#include "elf/microblaze.h"
3b16e843 128#include "elf/mips.h"
3c3bdf30 129#include "elf/mmix.h"
3b16e843
NC
130#include "elf/mn10200.h"
131#include "elf/mn10300.h"
5506d11a 132#include "elf/moxie.h"
4970f871 133#include "elf/mt.h"
2469cfa2 134#include "elf/msp430.h"
35c08157 135#include "elf/nds32.h"
fe944acf 136#include "elf/nfp.h"
13761a11 137#include "elf/nios2.h"
73589c9d 138#include "elf/or1k.h"
7d466069 139#include "elf/pj.h"
3b16e843 140#include "elf/ppc.h"
c833c019 141#include "elf/ppc64.h"
2b100bb5 142#include "elf/pru.h"
03336641 143#include "elf/riscv.h"
99c513f6 144#include "elf/rl78.h"
c7927a3c 145#include "elf/rx.h"
a85d7ed0 146#include "elf/s390.h"
1c0d3aa6 147#include "elf/score.h"
3b16e843
NC
148#include "elf/sh.h"
149#include "elf/sparc.h"
e9f53129 150#include "elf/spu.h"
40b36596 151#include "elf/tic6x.h"
aa137e4d
NC
152#include "elf/tilegx.h"
153#include "elf/tilepro.h"
3b16e843 154#include "elf/v850.h"
179d3252 155#include "elf/vax.h"
619ed720 156#include "elf/visium.h"
f96bd6c2 157#include "elf/wasm32.h"
3b16e843 158#include "elf/x86-64.h"
c29aca4a 159#include "elf/xc16x.h"
f6c1a2d5 160#include "elf/xgate.h"
93fbbb04 161#include "elf/xstormy16.h"
88da6820 162#include "elf/xtensa.h"
252b5132 163
252b5132 164#include "getopt.h"
566b0d53 165#include "libiberty.h"
09c11c86 166#include "safe-ctype.h"
2cf0635d 167#include "filenames.h"
252b5132 168
15b42fb0
AM
169#ifndef offsetof
170#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
171#endif
172
6a40cf0c
NC
173typedef struct elf_section_list
174{
dda8d76d
NC
175 Elf_Internal_Shdr * hdr;
176 struct elf_section_list * next;
6a40cf0c
NC
177} elf_section_list;
178
dda8d76d
NC
179/* Flag bits indicating particular types of dump. */
180#define HEX_DUMP (1 << 0) /* The -x command line switch. */
181#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
182#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
183#define STRING_DUMP (1 << 3) /* The -p command line switch. */
184#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
185
186typedef unsigned char dump_type;
187
188/* A linked list of the section names for which dumps were requested. */
189struct dump_list_entry
190{
191 char * name;
192 dump_type type;
193 struct dump_list_entry * next;
194};
195
196typedef struct filedata
197{
198 const char * file_name;
199 FILE * handle;
200 bfd_size_type file_size;
201 Elf_Internal_Ehdr file_header;
202 Elf_Internal_Shdr * section_headers;
203 Elf_Internal_Phdr * program_headers;
204 char * string_table;
205 unsigned long string_table_length;
206 /* A dynamic array of flags indicating for which sections a dump of
207 some kind has been requested. It is reset on a per-object file
208 basis and then initialised from the cmdline_dump_sects array,
209 the results of interpreting the -w switch, and the
210 dump_sects_byname list. */
211 dump_type * dump_sects;
212 unsigned int num_dump_sects;
213} Filedata;
214
2cf0635d 215char * program_name = "readelf";
dda8d76d 216
c9c1d674 217static unsigned long archive_file_offset;
85b1c36d
BE
218static unsigned long archive_file_size;
219static unsigned long dynamic_addr;
220static bfd_size_type dynamic_size;
8b73c356 221static size_t dynamic_nent;
2cf0635d 222static char * dynamic_strings;
85b1c36d 223static unsigned long dynamic_strings_length;
85b1c36d 224static unsigned long num_dynamic_syms;
2cf0635d
NC
225static Elf_Internal_Sym * dynamic_symbols;
226static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
227static unsigned long dynamic_syminfo_offset;
228static unsigned int dynamic_syminfo_nent;
f8eae8b2 229static char program_interpreter[PATH_MAX];
bb8a0291 230static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 231static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d 232static bfd_vma version_info[16];
2cf0635d 233static Elf_Internal_Dyn * dynamic_section;
6a40cf0c 234static elf_section_list * symtab_shndx_list;
32ec8896
NC
235static bfd_boolean show_name = FALSE;
236static bfd_boolean do_dynamic = FALSE;
237static bfd_boolean do_syms = FALSE;
238static bfd_boolean do_dyn_syms = FALSE;
239static bfd_boolean do_reloc = FALSE;
240static bfd_boolean do_sections = FALSE;
241static bfd_boolean do_section_groups = FALSE;
242static bfd_boolean do_section_details = FALSE;
243static bfd_boolean do_segments = FALSE;
244static bfd_boolean do_unwind = FALSE;
245static bfd_boolean do_using_dynamic = FALSE;
246static bfd_boolean do_header = FALSE;
247static bfd_boolean do_dump = FALSE;
248static bfd_boolean do_version = FALSE;
249static bfd_boolean do_histogram = FALSE;
250static bfd_boolean do_debugging = FALSE;
251static bfd_boolean do_arch = FALSE;
252static bfd_boolean do_notes = FALSE;
253static bfd_boolean do_archive_index = FALSE;
254static bfd_boolean is_32bit_elf = FALSE;
255static bfd_boolean decompress_dumps = FALSE;
252b5132 256
e4b17d5c
L
257struct group_list
258{
dda8d76d
NC
259 struct group_list * next;
260 unsigned int section_index;
e4b17d5c
L
261};
262
263struct group
264{
dda8d76d
NC
265 struct group_list * root;
266 unsigned int group_index;
e4b17d5c
L
267};
268
dda8d76d
NC
269static size_t group_count;
270static struct group * section_groups;
271static struct group ** section_headers_groups;
aef1f6d0 272
09c11c86
NC
273/* A dynamic array of flags indicating for which sections a dump
274 has been requested via command line switches. */
dda8d76d 275static Filedata cmdline;
252b5132 276
dda8d76d 277static struct dump_list_entry * dump_sects_byname;
252b5132 278
c256ffe7 279/* How to print a vma value. */
843dd992
NC
280typedef enum print_mode
281{
282 HEX,
283 DEC,
284 DEC_5,
285 UNSIGNED,
286 PREFIX_HEX,
287 FULL_HEX,
288 LONG_HEX
289}
290print_mode;
291
bb4d2ac2
L
292/* Versioned symbol info. */
293enum versioned_symbol_info
294{
295 symbol_undefined,
296 symbol_hidden,
297 symbol_public
298};
299
32ec8896 300static const char * get_symbol_version_string
dda8d76d 301 (Filedata *, bfd_boolean, const char *, unsigned long, unsigned,
32ec8896 302 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 303
9c19a809
NC
304#define UNKNOWN -1
305
2b692964
NC
306#define SECTION_NAME(X) \
307 ((X) == NULL ? _("<none>") \
dda8d76d
NC
308 : filedata->string_table == NULL ? _("<no-strings>") \
309 : ((X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
310 : filedata->string_table + (X)->sh_name))
252b5132 311
ee42cf8c 312#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 313
ba5cdace
NC
314#define GET_ELF_SYMBOLS(file, section, sym_count) \
315 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
316 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 317
d79b3d50
NC
318#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
319/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
320 already been called and verified that the string exists. */
321#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 322
61865e30
NC
323#define REMOVE_ARCH_BITS(ADDR) \
324 do \
325 { \
dda8d76d 326 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
327 (ADDR) &= ~1; \
328 } \
329 while (0)
d79b3d50 330\f
66cfc0fd
AM
331/* Print a BFD_VMA to an internal buffer, for use in error messages.
332 BFD_FMA_FMT can't be used in translated strings. */
333
334static const char *
335bfd_vmatoa (char *fmtch, bfd_vma value)
336{
337 /* bfd_vmatoa is used more then once in a printf call for output.
338 Cycle through an array of buffers. */
339 static int buf_pos = 0;
340 static struct bfd_vmatoa_buf
341 {
342 char place[64];
343 } buf[4];
344 char *ret;
345 char fmt[32];
346
347 ret = buf[buf_pos++].place;
348 buf_pos %= ARRAY_SIZE (buf);
349
350 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
351 snprintf (ret, sizeof (buf[0].place), fmt, value);
352 return ret;
353}
354
dda8d76d
NC
355/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
356 OFFSET + the offset of the current archive member, if we are examining an
357 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
358 allocate a buffer using malloc and fill that. In either case return the
359 pointer to the start of the retrieved data or NULL if something went wrong.
360 If something does go wrong and REASON is not NULL then emit an error
361 message using REASON as part of the context. */
59245841 362
c256ffe7 363static void *
dda8d76d
NC
364get_data (void * var,
365 Filedata * filedata,
366 unsigned long offset,
367 bfd_size_type size,
368 bfd_size_type nmemb,
369 const char * reason)
a6e9f9df 370{
2cf0635d 371 void * mvar;
57028622 372 bfd_size_type amt = size * nmemb;
a6e9f9df 373
c256ffe7 374 if (size == 0 || nmemb == 0)
a6e9f9df
AM
375 return NULL;
376
57028622
NC
377 /* If the size_t type is smaller than the bfd_size_type, eg because
378 you are building a 32-bit tool on a 64-bit host, then make sure
379 that when the sizes are cast to (size_t) no information is lost. */
380 if (sizeof (size_t) < sizeof (bfd_size_type)
381 && ( (bfd_size_type) ((size_t) size) != size
382 || (bfd_size_type) ((size_t) nmemb) != nmemb))
383 {
384 if (reason)
66cfc0fd
AM
385 error (_("Size truncation prevents reading %s"
386 " elements of size %s for %s\n"),
387 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
388 return NULL;
389 }
390
391 /* Check for size overflow. */
392 if (amt < nmemb)
393 {
394 if (reason)
66cfc0fd
AM
395 error (_("Size overflow prevents reading %s"
396 " elements of size %s for %s\n"),
397 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
398 return NULL;
399 }
400
c22b42ce 401 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 402 attempting to allocate memory when the read is bound to fail. */
c22b42ce
AM
403 if (archive_file_offset > filedata->file_size
404 || offset > filedata->file_size - archive_file_offset
405 || amt > filedata->file_size - archive_file_offset - offset)
a6e9f9df 406 {
049b0c3a 407 if (reason)
66cfc0fd
AM
408 error (_("Reading %s bytes extends past end of file for %s\n"),
409 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
410 return NULL;
411 }
412
dda8d76d 413 if (fseek (filedata->handle, archive_file_offset + offset, SEEK_SET))
071436c6
NC
414 {
415 if (reason)
c9c1d674 416 error (_("Unable to seek to 0x%lx for %s\n"),
ed754a13 417 archive_file_offset + offset, reason);
071436c6
NC
418 return NULL;
419 }
420
a6e9f9df
AM
421 mvar = var;
422 if (mvar == NULL)
423 {
c256ffe7 424 /* Check for overflow. */
57028622 425 if (nmemb < (~(bfd_size_type) 0 - 1) / size)
c256ffe7 426 /* + 1 so that we can '\0' terminate invalid string table sections. */
57028622 427 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
428
429 if (mvar == NULL)
430 {
049b0c3a 431 if (reason)
66cfc0fd
AM
432 error (_("Out of memory allocating %s bytes for %s\n"),
433 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
434 return NULL;
435 }
c256ffe7 436
c9c1d674 437 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
438 }
439
dda8d76d 440 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 441 {
049b0c3a 442 if (reason)
66cfc0fd
AM
443 error (_("Unable to read in %s bytes of %s\n"),
444 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
445 if (mvar != var)
446 free (mvar);
447 return NULL;
448 }
449
450 return mvar;
451}
452
32ec8896
NC
453/* Print a VMA value in the MODE specified.
454 Returns the number of characters displayed. */
cb8f3167 455
32ec8896 456static unsigned int
14a91970 457print_vma (bfd_vma vma, print_mode mode)
66543521 458{
32ec8896 459 unsigned int nc = 0;
66543521 460
14a91970 461 switch (mode)
66543521 462 {
14a91970
AM
463 case FULL_HEX:
464 nc = printf ("0x");
1a0670f3 465 /* Fall through. */
14a91970 466 case LONG_HEX:
f7a99963 467#ifdef BFD64
14a91970 468 if (is_32bit_elf)
437c2fb7 469 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 470#endif
14a91970
AM
471 printf_vma (vma);
472 return nc + 16;
b19aac67 473
14a91970
AM
474 case DEC_5:
475 if (vma <= 99999)
476 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 477 /* Fall through. */
14a91970
AM
478 case PREFIX_HEX:
479 nc = printf ("0x");
1a0670f3 480 /* Fall through. */
14a91970
AM
481 case HEX:
482 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 483
14a91970
AM
484 case DEC:
485 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 486
14a91970
AM
487 case UNSIGNED:
488 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896
NC
489
490 default:
491 /* FIXME: Report unrecognised mode ? */
492 return 0;
f7a99963 493 }
f7a99963
NC
494}
495
7bfd842d 496/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 497 multibye characters (assuming the host environment supports them).
31104126 498
7bfd842d
NC
499 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
500
501 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
502 padding as necessary.
171191ba
NC
503
504 Returns the number of emitted characters. */
505
506static unsigned int
32ec8896 507print_symbol (signed int width, const char *symbol)
31104126 508{
171191ba 509 bfd_boolean extra_padding = FALSE;
32ec8896 510 signed int num_printed = 0;
3bfcb652 511#ifdef HAVE_MBSTATE_T
7bfd842d 512 mbstate_t state;
3bfcb652 513#endif
32ec8896 514 unsigned int width_remaining;
961c521f 515
7bfd842d 516 if (width < 0)
961c521f 517 {
88305e1b 518 /* Keep the width positive. This helps the code below. */
961c521f 519 width = - width;
171191ba 520 extra_padding = TRUE;
0b4362b0 521 }
56d8f8a9
NC
522 else if (width == 0)
523 return 0;
961c521f 524
7bfd842d
NC
525 if (do_wide)
526 /* Set the remaining width to a very large value.
527 This simplifies the code below. */
528 width_remaining = INT_MAX;
529 else
530 width_remaining = width;
cb8f3167 531
3bfcb652 532#ifdef HAVE_MBSTATE_T
7bfd842d
NC
533 /* Initialise the multibyte conversion state. */
534 memset (& state, 0, sizeof (state));
3bfcb652 535#endif
961c521f 536
7bfd842d
NC
537 while (width_remaining)
538 {
539 size_t n;
7bfd842d 540 const char c = *symbol++;
961c521f 541
7bfd842d 542 if (c == 0)
961c521f
NC
543 break;
544
7bfd842d
NC
545 /* Do not print control characters directly as they can affect terminal
546 settings. Such characters usually appear in the names generated
547 by the assembler for local labels. */
548 if (ISCNTRL (c))
961c521f 549 {
7bfd842d 550 if (width_remaining < 2)
961c521f
NC
551 break;
552
7bfd842d
NC
553 printf ("^%c", c + 0x40);
554 width_remaining -= 2;
171191ba 555 num_printed += 2;
961c521f 556 }
7bfd842d
NC
557 else if (ISPRINT (c))
558 {
559 putchar (c);
560 width_remaining --;
561 num_printed ++;
562 }
961c521f
NC
563 else
564 {
3bfcb652
NC
565#ifdef HAVE_MBSTATE_T
566 wchar_t w;
567#endif
7bfd842d
NC
568 /* Let printf do the hard work of displaying multibyte characters. */
569 printf ("%.1s", symbol - 1);
570 width_remaining --;
571 num_printed ++;
572
3bfcb652 573#ifdef HAVE_MBSTATE_T
7bfd842d
NC
574 /* Try to find out how many bytes made up the character that was
575 just printed. Advance the symbol pointer past the bytes that
576 were displayed. */
577 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
578#else
579 n = 1;
580#endif
7bfd842d
NC
581 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
582 symbol += (n - 1);
961c521f 583 }
961c521f 584 }
171191ba 585
7bfd842d 586 if (extra_padding && num_printed < width)
171191ba
NC
587 {
588 /* Fill in the remaining spaces. */
7bfd842d
NC
589 printf ("%-*s", width - num_printed, " ");
590 num_printed = width;
171191ba
NC
591 }
592
593 return num_printed;
31104126
NC
594}
595
1449284b 596/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
597 the given section's name. Like print_symbol, except that it does not try
598 to print multibyte characters, it just interprets them as hex values. */
599
600static const char *
dda8d76d 601printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b
NC
602{
603#define MAX_PRINT_SEC_NAME_LEN 128
604 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
605 const char * name = SECTION_NAME (sec);
606 char * buf = sec_name_buf;
607 char c;
608 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
609
610 while ((c = * name ++) != 0)
611 {
612 if (ISCNTRL (c))
613 {
614 if (remaining < 2)
615 break;
948f632f 616
74e1a04b
NC
617 * buf ++ = '^';
618 * buf ++ = c + 0x40;
619 remaining -= 2;
620 }
621 else if (ISPRINT (c))
622 {
623 * buf ++ = c;
624 remaining -= 1;
625 }
626 else
627 {
628 static char hex[17] = "0123456789ABCDEF";
629
630 if (remaining < 4)
631 break;
632 * buf ++ = '<';
633 * buf ++ = hex[(c & 0xf0) >> 4];
634 * buf ++ = hex[c & 0x0f];
635 * buf ++ = '>';
636 remaining -= 4;
637 }
638
639 if (remaining == 0)
640 break;
641 }
642
643 * buf = 0;
644 return sec_name_buf;
645}
646
647static const char *
dda8d76d 648printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 649{
dda8d76d 650 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
651 return _("<corrupt>");
652
dda8d76d 653 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
654}
655
89fac5e3
RS
656/* Return a pointer to section NAME, or NULL if no such section exists. */
657
658static Elf_Internal_Shdr *
dda8d76d 659find_section (Filedata * filedata, const char * name)
89fac5e3
RS
660{
661 unsigned int i;
662
68807c3c
NC
663 if (filedata->section_headers == NULL)
664 return NULL;
dda8d76d
NC
665
666 for (i = 0; i < filedata->file_header.e_shnum; i++)
667 if (streq (SECTION_NAME (filedata->section_headers + i), name))
668 return filedata->section_headers + i;
89fac5e3
RS
669
670 return NULL;
671}
672
0b6ae522
DJ
673/* Return a pointer to a section containing ADDR, or NULL if no such
674 section exists. */
675
676static Elf_Internal_Shdr *
dda8d76d 677find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
678{
679 unsigned int i;
680
68807c3c
NC
681 if (filedata->section_headers == NULL)
682 return NULL;
683
dda8d76d 684 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 685 {
dda8d76d
NC
686 Elf_Internal_Shdr *sec = filedata->section_headers + i;
687
0b6ae522
DJ
688 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
689 return sec;
690 }
691
692 return NULL;
693}
694
071436c6 695static Elf_Internal_Shdr *
dda8d76d 696find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
697{
698 unsigned int i;
699
68807c3c
NC
700 if (filedata->section_headers == NULL)
701 return NULL;
702
dda8d76d 703 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 704 {
dda8d76d
NC
705 Elf_Internal_Shdr *sec = filedata->section_headers + i;
706
071436c6
NC
707 if (sec->sh_type == type)
708 return sec;
709 }
710
711 return NULL;
712}
713
657d0d47
CC
714/* Return a pointer to section NAME, or NULL if no such section exists,
715 restricted to the list of sections given in SET. */
716
717static Elf_Internal_Shdr *
dda8d76d 718find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
719{
720 unsigned int i;
721
68807c3c
NC
722 if (filedata->section_headers == NULL)
723 return NULL;
724
657d0d47
CC
725 if (set != NULL)
726 {
727 while ((i = *set++) > 0)
b814a36d
NC
728 {
729 /* See PR 21156 for a reproducer. */
dda8d76d 730 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
731 continue; /* FIXME: Should we issue an error message ? */
732
dda8d76d
NC
733 if (streq (SECTION_NAME (filedata->section_headers + i), name))
734 return filedata->section_headers + i;
b814a36d 735 }
657d0d47
CC
736 }
737
dda8d76d 738 return find_section (filedata, name);
657d0d47
CC
739}
740
32ec8896
NC
741/* Read an unsigned LEB128 encoded value from DATA.
742 Set *LENGTH_RETURN to the number of bytes read. */
0b6ae522 743
f6f0e17b 744static inline unsigned long
32ec8896
NC
745read_uleb128 (unsigned char * data,
746 unsigned int * length_return,
f6f0e17b 747 const unsigned char * const end)
0b6ae522 748{
f6f0e17b 749 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
750}
751
32ec8896 752/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
753 This OS has so many departures from the ELF standard that we test it at
754 many places. */
755
32ec8896 756static inline bfd_boolean
dda8d76d 757is_ia64_vms (Filedata * filedata)
28f997cf 758{
dda8d76d
NC
759 return filedata->file_header.e_machine == EM_IA_64
760 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
761}
762
bcedfee6 763/* Guess the relocation size commonly used by the specific machines. */
252b5132 764
32ec8896 765static bfd_boolean
2dc4cec1 766guess_is_rela (unsigned int e_machine)
252b5132 767{
9c19a809 768 switch (e_machine)
252b5132
RH
769 {
770 /* Targets that use REL relocations. */
252b5132 771 case EM_386:
22abe556 772 case EM_IAMCU:
f954747f 773 case EM_960:
e9f53129 774 case EM_ARM:
2b0337b0 775 case EM_D10V:
252b5132 776 case EM_CYGNUS_D10V:
e9f53129 777 case EM_DLX:
252b5132 778 case EM_MIPS:
4fe85591 779 case EM_MIPS_RS3_LE:
e9f53129 780 case EM_CYGNUS_M32R:
1c0d3aa6 781 case EM_SCORE:
f6c1a2d5 782 case EM_XGATE:
fe944acf 783 case EM_NFP:
9c19a809 784 return FALSE;
103f02d3 785
252b5132
RH
786 /* Targets that use RELA relocations. */
787 case EM_68K:
f954747f 788 case EM_860:
a06ea964 789 case EM_AARCH64:
cfb8c092 790 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
791 case EM_ALPHA:
792 case EM_ALTERA_NIOS2:
886a2506
NC
793 case EM_ARC:
794 case EM_ARC_COMPACT:
795 case EM_ARC_COMPACT2:
e9f53129
AM
796 case EM_AVR:
797 case EM_AVR_OLD:
798 case EM_BLACKFIN:
60bca95a 799 case EM_CR16:
e9f53129
AM
800 case EM_CRIS:
801 case EM_CRX:
b8891f8d 802 case EM_CSKY:
2b0337b0 803 case EM_D30V:
252b5132 804 case EM_CYGNUS_D30V:
2b0337b0 805 case EM_FR30:
3f8107ab 806 case EM_FT32:
252b5132 807 case EM_CYGNUS_FR30:
5c70f934 808 case EM_CYGNUS_FRV:
e9f53129
AM
809 case EM_H8S:
810 case EM_H8_300:
811 case EM_H8_300H:
800eeca4 812 case EM_IA_64:
1e4cf259
NC
813 case EM_IP2K:
814 case EM_IP2K_OLD:
3b36097d 815 case EM_IQ2000:
84e94c90 816 case EM_LATTICEMICO32:
ff7eeb89 817 case EM_M32C_OLD:
49f58d10 818 case EM_M32C:
e9f53129
AM
819 case EM_M32R:
820 case EM_MCORE:
15ab5209 821 case EM_CYGNUS_MEP:
a3c62988 822 case EM_METAG:
e9f53129
AM
823 case EM_MMIX:
824 case EM_MN10200:
825 case EM_CYGNUS_MN10200:
826 case EM_MN10300:
827 case EM_CYGNUS_MN10300:
5506d11a 828 case EM_MOXIE:
e9f53129
AM
829 case EM_MSP430:
830 case EM_MSP430_OLD:
d031aafb 831 case EM_MT:
35c08157 832 case EM_NDS32:
64fd6348 833 case EM_NIOS32:
73589c9d 834 case EM_OR1K:
e9f53129
AM
835 case EM_PPC64:
836 case EM_PPC:
2b100bb5 837 case EM_TI_PRU:
e23eba97 838 case EM_RISCV:
99c513f6 839 case EM_RL78:
c7927a3c 840 case EM_RX:
e9f53129
AM
841 case EM_S390:
842 case EM_S390_OLD:
843 case EM_SH:
844 case EM_SPARC:
845 case EM_SPARC32PLUS:
846 case EM_SPARCV9:
847 case EM_SPU:
40b36596 848 case EM_TI_C6000:
aa137e4d
NC
849 case EM_TILEGX:
850 case EM_TILEPRO:
708e2187 851 case EM_V800:
e9f53129
AM
852 case EM_V850:
853 case EM_CYGNUS_V850:
854 case EM_VAX:
619ed720 855 case EM_VISIUM:
e9f53129 856 case EM_X86_64:
8a9036a4 857 case EM_L1OM:
7a9068fe 858 case EM_K1OM:
e9f53129
AM
859 case EM_XSTORMY16:
860 case EM_XTENSA:
861 case EM_XTENSA_OLD:
7ba29e2a
NC
862 case EM_MICROBLAZE:
863 case EM_MICROBLAZE_OLD:
f96bd6c2 864 case EM_WEBASSEMBLY:
9c19a809 865 return TRUE;
103f02d3 866
e9f53129
AM
867 case EM_68HC05:
868 case EM_68HC08:
869 case EM_68HC11:
870 case EM_68HC16:
871 case EM_FX66:
872 case EM_ME16:
d1133906 873 case EM_MMA:
d1133906
NC
874 case EM_NCPU:
875 case EM_NDR1:
e9f53129 876 case EM_PCP:
d1133906 877 case EM_ST100:
e9f53129 878 case EM_ST19:
d1133906 879 case EM_ST7:
e9f53129
AM
880 case EM_ST9PLUS:
881 case EM_STARCORE:
d1133906 882 case EM_SVX:
e9f53129 883 case EM_TINYJ:
9c19a809
NC
884 default:
885 warn (_("Don't know about relocations on this machine architecture\n"));
886 return FALSE;
887 }
888}
252b5132 889
dda8d76d 890/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
891 Returns TRUE upon success, FALSE otherwise. If successful then a
892 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
893 and the number of relocs loaded is placed in *NRELASP. It is the caller's
894 responsibility to free the allocated buffer. */
895
896static bfd_boolean
dda8d76d
NC
897slurp_rela_relocs (Filedata * filedata,
898 unsigned long rel_offset,
899 unsigned long rel_size,
900 Elf_Internal_Rela ** relasp,
901 unsigned long * nrelasp)
9c19a809 902{
2cf0635d 903 Elf_Internal_Rela * relas;
8b73c356 904 size_t nrelas;
4d6ed7c8 905 unsigned int i;
252b5132 906
4d6ed7c8
NC
907 if (is_32bit_elf)
908 {
2cf0635d 909 Elf32_External_Rela * erelas;
103f02d3 910
dda8d76d 911 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 912 rel_size, _("32-bit relocation data"));
a6e9f9df 913 if (!erelas)
32ec8896 914 return FALSE;
252b5132 915
4d6ed7c8 916 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 917
3f5e193b
NC
918 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
919 sizeof (Elf_Internal_Rela));
103f02d3 920
4d6ed7c8
NC
921 if (relas == NULL)
922 {
c256ffe7 923 free (erelas);
591a748a 924 error (_("out of memory parsing relocs\n"));
32ec8896 925 return FALSE;
4d6ed7c8 926 }
103f02d3 927
4d6ed7c8
NC
928 for (i = 0; i < nrelas; i++)
929 {
930 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
931 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 932 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 933 }
103f02d3 934
4d6ed7c8
NC
935 free (erelas);
936 }
937 else
938 {
2cf0635d 939 Elf64_External_Rela * erelas;
103f02d3 940
dda8d76d 941 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 942 rel_size, _("64-bit relocation data"));
a6e9f9df 943 if (!erelas)
32ec8896 944 return FALSE;
4d6ed7c8
NC
945
946 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 947
3f5e193b
NC
948 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
949 sizeof (Elf_Internal_Rela));
103f02d3 950
4d6ed7c8
NC
951 if (relas == NULL)
952 {
c256ffe7 953 free (erelas);
591a748a 954 error (_("out of memory parsing relocs\n"));
32ec8896 955 return FALSE;
9c19a809 956 }
4d6ed7c8
NC
957
958 for (i = 0; i < nrelas; i++)
9c19a809 959 {
66543521
AM
960 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
961 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 962 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
963
964 /* The #ifdef BFD64 below is to prevent a compile time
965 warning. We know that if we do not have a 64 bit data
966 type that we will never execute this code anyway. */
967#ifdef BFD64
dda8d76d
NC
968 if (filedata->file_header.e_machine == EM_MIPS
969 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
970 {
971 /* In little-endian objects, r_info isn't really a
972 64-bit little-endian value: it has a 32-bit
973 little-endian symbol index followed by four
974 individual byte fields. Reorder INFO
975 accordingly. */
91d6fa6a
NC
976 bfd_vma inf = relas[i].r_info;
977 inf = (((inf & 0xffffffff) << 32)
978 | ((inf >> 56) & 0xff)
979 | ((inf >> 40) & 0xff00)
980 | ((inf >> 24) & 0xff0000)
981 | ((inf >> 8) & 0xff000000));
982 relas[i].r_info = inf;
861fb55a
DJ
983 }
984#endif /* BFD64 */
4d6ed7c8 985 }
103f02d3 986
4d6ed7c8
NC
987 free (erelas);
988 }
32ec8896 989
4d6ed7c8
NC
990 *relasp = relas;
991 *nrelasp = nrelas;
32ec8896 992 return TRUE;
4d6ed7c8 993}
103f02d3 994
dda8d76d 995/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
996 Returns TRUE upon success, FALSE otherwise. If successful then a
997 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
998 and the number of relocs loaded is placed in *NRELSP. It is the caller's
999 responsibility to free the allocated buffer. */
1000
1001static bfd_boolean
dda8d76d
NC
1002slurp_rel_relocs (Filedata * filedata,
1003 unsigned long rel_offset,
1004 unsigned long rel_size,
1005 Elf_Internal_Rela ** relsp,
1006 unsigned long * nrelsp)
4d6ed7c8 1007{
2cf0635d 1008 Elf_Internal_Rela * rels;
8b73c356 1009 size_t nrels;
4d6ed7c8 1010 unsigned int i;
103f02d3 1011
4d6ed7c8
NC
1012 if (is_32bit_elf)
1013 {
2cf0635d 1014 Elf32_External_Rel * erels;
103f02d3 1015
dda8d76d 1016 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1017 rel_size, _("32-bit relocation data"));
a6e9f9df 1018 if (!erels)
32ec8896 1019 return FALSE;
103f02d3 1020
4d6ed7c8 1021 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1022
3f5e193b 1023 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1024
4d6ed7c8
NC
1025 if (rels == NULL)
1026 {
c256ffe7 1027 free (erels);
591a748a 1028 error (_("out of memory parsing relocs\n"));
32ec8896 1029 return FALSE;
4d6ed7c8
NC
1030 }
1031
1032 for (i = 0; i < nrels; i++)
1033 {
1034 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1035 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1036 rels[i].r_addend = 0;
9ea033b2 1037 }
4d6ed7c8
NC
1038
1039 free (erels);
9c19a809
NC
1040 }
1041 else
1042 {
2cf0635d 1043 Elf64_External_Rel * erels;
9ea033b2 1044
dda8d76d 1045 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1046 rel_size, _("64-bit relocation data"));
a6e9f9df 1047 if (!erels)
32ec8896 1048 return FALSE;
103f02d3 1049
4d6ed7c8 1050 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1051
3f5e193b 1052 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1053
4d6ed7c8 1054 if (rels == NULL)
9c19a809 1055 {
c256ffe7 1056 free (erels);
591a748a 1057 error (_("out of memory parsing relocs\n"));
32ec8896 1058 return FALSE;
4d6ed7c8 1059 }
103f02d3 1060
4d6ed7c8
NC
1061 for (i = 0; i < nrels; i++)
1062 {
66543521
AM
1063 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1064 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1065 rels[i].r_addend = 0;
861fb55a
DJ
1066
1067 /* The #ifdef BFD64 below is to prevent a compile time
1068 warning. We know that if we do not have a 64 bit data
1069 type that we will never execute this code anyway. */
1070#ifdef BFD64
dda8d76d
NC
1071 if (filedata->file_header.e_machine == EM_MIPS
1072 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1073 {
1074 /* In little-endian objects, r_info isn't really a
1075 64-bit little-endian value: it has a 32-bit
1076 little-endian symbol index followed by four
1077 individual byte fields. Reorder INFO
1078 accordingly. */
91d6fa6a
NC
1079 bfd_vma inf = rels[i].r_info;
1080 inf = (((inf & 0xffffffff) << 32)
1081 | ((inf >> 56) & 0xff)
1082 | ((inf >> 40) & 0xff00)
1083 | ((inf >> 24) & 0xff0000)
1084 | ((inf >> 8) & 0xff000000));
1085 rels[i].r_info = inf;
861fb55a
DJ
1086 }
1087#endif /* BFD64 */
4d6ed7c8 1088 }
103f02d3 1089
4d6ed7c8
NC
1090 free (erels);
1091 }
32ec8896 1092
4d6ed7c8
NC
1093 *relsp = rels;
1094 *nrelsp = nrels;
32ec8896 1095 return TRUE;
4d6ed7c8 1096}
103f02d3 1097
aca88567
NC
1098/* Returns the reloc type extracted from the reloc info field. */
1099
1100static unsigned int
dda8d76d 1101get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1102{
1103 if (is_32bit_elf)
1104 return ELF32_R_TYPE (reloc_info);
1105
dda8d76d 1106 switch (filedata->file_header.e_machine)
aca88567
NC
1107 {
1108 case EM_MIPS:
1109 /* Note: We assume that reloc_info has already been adjusted for us. */
1110 return ELF64_MIPS_R_TYPE (reloc_info);
1111
1112 case EM_SPARCV9:
1113 return ELF64_R_TYPE_ID (reloc_info);
1114
1115 default:
1116 return ELF64_R_TYPE (reloc_info);
1117 }
1118}
1119
1120/* Return the symbol index extracted from the reloc info field. */
1121
1122static bfd_vma
1123get_reloc_symindex (bfd_vma reloc_info)
1124{
1125 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1126}
1127
13761a11 1128static inline bfd_boolean
dda8d76d 1129uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1130{
1131 return
dda8d76d 1132 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1133 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1134 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1135 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1136 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1137}
1138
d3ba0551
AM
1139/* Display the contents of the relocation data found at the specified
1140 offset. */
ee42cf8c 1141
32ec8896 1142static bfd_boolean
dda8d76d
NC
1143dump_relocations (Filedata * filedata,
1144 unsigned long rel_offset,
1145 unsigned long rel_size,
1146 Elf_Internal_Sym * symtab,
1147 unsigned long nsyms,
1148 char * strtab,
1149 unsigned long strtablen,
1150 int is_rela,
1151 bfd_boolean is_dynsym)
4d6ed7c8 1152{
32ec8896 1153 unsigned long i;
2cf0635d 1154 Elf_Internal_Rela * rels;
32ec8896 1155 bfd_boolean res = TRUE;
103f02d3 1156
4d6ed7c8 1157 if (is_rela == UNKNOWN)
dda8d76d 1158 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1159
4d6ed7c8
NC
1160 if (is_rela)
1161 {
dda8d76d 1162 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1163 return FALSE;
4d6ed7c8
NC
1164 }
1165 else
1166 {
dda8d76d 1167 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1168 return FALSE;
252b5132
RH
1169 }
1170
410f7a12
L
1171 if (is_32bit_elf)
1172 {
1173 if (is_rela)
2c71103e
NC
1174 {
1175 if (do_wide)
1176 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1177 else
1178 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1179 }
410f7a12 1180 else
2c71103e
NC
1181 {
1182 if (do_wide)
1183 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1184 else
1185 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1186 }
410f7a12 1187 }
252b5132 1188 else
410f7a12
L
1189 {
1190 if (is_rela)
2c71103e
NC
1191 {
1192 if (do_wide)
8beeaeb7 1193 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1194 else
1195 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1196 }
410f7a12 1197 else
2c71103e
NC
1198 {
1199 if (do_wide)
8beeaeb7 1200 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1201 else
1202 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1203 }
410f7a12 1204 }
252b5132
RH
1205
1206 for (i = 0; i < rel_size; i++)
1207 {
2cf0635d 1208 const char * rtype;
b34976b6 1209 bfd_vma offset;
91d6fa6a 1210 bfd_vma inf;
b34976b6
AM
1211 bfd_vma symtab_index;
1212 bfd_vma type;
103f02d3 1213
b34976b6 1214 offset = rels[i].r_offset;
91d6fa6a 1215 inf = rels[i].r_info;
103f02d3 1216
dda8d76d 1217 type = get_reloc_type (filedata, inf);
91d6fa6a 1218 symtab_index = get_reloc_symindex (inf);
252b5132 1219
410f7a12
L
1220 if (is_32bit_elf)
1221 {
39dbeff8
AM
1222 printf ("%8.8lx %8.8lx ",
1223 (unsigned long) offset & 0xffffffff,
91d6fa6a 1224 (unsigned long) inf & 0xffffffff);
410f7a12
L
1225 }
1226 else
1227 {
39dbeff8
AM
1228#if BFD_HOST_64BIT_LONG
1229 printf (do_wide
1230 ? "%16.16lx %16.16lx "
1231 : "%12.12lx %12.12lx ",
91d6fa6a 1232 offset, inf);
39dbeff8 1233#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1234#ifndef __MSVCRT__
39dbeff8
AM
1235 printf (do_wide
1236 ? "%16.16llx %16.16llx "
1237 : "%12.12llx %12.12llx ",
91d6fa6a 1238 offset, inf);
6e3d6dc1
NC
1239#else
1240 printf (do_wide
1241 ? "%16.16I64x %16.16I64x "
1242 : "%12.12I64x %12.12I64x ",
91d6fa6a 1243 offset, inf);
6e3d6dc1 1244#endif
39dbeff8 1245#else
2c71103e
NC
1246 printf (do_wide
1247 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1248 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1249 _bfd_int64_high (offset),
1250 _bfd_int64_low (offset),
91d6fa6a
NC
1251 _bfd_int64_high (inf),
1252 _bfd_int64_low (inf));
9ea033b2 1253#endif
410f7a12 1254 }
103f02d3 1255
dda8d76d 1256 switch (filedata->file_header.e_machine)
252b5132
RH
1257 {
1258 default:
1259 rtype = NULL;
1260 break;
1261
a06ea964
NC
1262 case EM_AARCH64:
1263 rtype = elf_aarch64_reloc_type (type);
1264 break;
1265
2b0337b0 1266 case EM_M32R:
252b5132 1267 case EM_CYGNUS_M32R:
9ea033b2 1268 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1269 break;
1270
1271 case EM_386:
22abe556 1272 case EM_IAMCU:
9ea033b2 1273 rtype = elf_i386_reloc_type (type);
252b5132
RH
1274 break;
1275
ba2685cc
AM
1276 case EM_68HC11:
1277 case EM_68HC12:
1278 rtype = elf_m68hc11_reloc_type (type);
1279 break;
75751cd9 1280
7b4ae824
JD
1281 case EM_S12Z:
1282 rtype = elf_s12z_reloc_type (type);
1283 break;
1284
252b5132 1285 case EM_68K:
9ea033b2 1286 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1287 break;
1288
f954747f
AM
1289 case EM_960:
1290 rtype = elf_i960_reloc_type (type);
1291 break;
1292
adde6300 1293 case EM_AVR:
2b0337b0 1294 case EM_AVR_OLD:
adde6300
AM
1295 rtype = elf_avr_reloc_type (type);
1296 break;
1297
9ea033b2
NC
1298 case EM_OLD_SPARCV9:
1299 case EM_SPARC32PLUS:
1300 case EM_SPARCV9:
252b5132 1301 case EM_SPARC:
9ea033b2 1302 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1303 break;
1304
e9f53129
AM
1305 case EM_SPU:
1306 rtype = elf_spu_reloc_type (type);
1307 break;
1308
708e2187
NC
1309 case EM_V800:
1310 rtype = v800_reloc_type (type);
1311 break;
2b0337b0 1312 case EM_V850:
252b5132 1313 case EM_CYGNUS_V850:
9ea033b2 1314 rtype = v850_reloc_type (type);
252b5132
RH
1315 break;
1316
2b0337b0 1317 case EM_D10V:
252b5132 1318 case EM_CYGNUS_D10V:
9ea033b2 1319 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1320 break;
1321
2b0337b0 1322 case EM_D30V:
252b5132 1323 case EM_CYGNUS_D30V:
9ea033b2 1324 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1325 break;
1326
d172d4ba
NC
1327 case EM_DLX:
1328 rtype = elf_dlx_reloc_type (type);
1329 break;
1330
252b5132 1331 case EM_SH:
9ea033b2 1332 rtype = elf_sh_reloc_type (type);
252b5132
RH
1333 break;
1334
2b0337b0 1335 case EM_MN10300:
252b5132 1336 case EM_CYGNUS_MN10300:
9ea033b2 1337 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1338 break;
1339
2b0337b0 1340 case EM_MN10200:
252b5132 1341 case EM_CYGNUS_MN10200:
9ea033b2 1342 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1343 break;
1344
2b0337b0 1345 case EM_FR30:
252b5132 1346 case EM_CYGNUS_FR30:
9ea033b2 1347 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1348 break;
1349
ba2685cc
AM
1350 case EM_CYGNUS_FRV:
1351 rtype = elf_frv_reloc_type (type);
1352 break;
5c70f934 1353
b8891f8d
AJ
1354 case EM_CSKY:
1355 rtype = elf_csky_reloc_type (type);
1356 break;
1357
3f8107ab
AM
1358 case EM_FT32:
1359 rtype = elf_ft32_reloc_type (type);
1360 break;
1361
252b5132 1362 case EM_MCORE:
9ea033b2 1363 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1364 break;
1365
3c3bdf30
NC
1366 case EM_MMIX:
1367 rtype = elf_mmix_reloc_type (type);
1368 break;
1369
5506d11a
AM
1370 case EM_MOXIE:
1371 rtype = elf_moxie_reloc_type (type);
1372 break;
1373
2469cfa2 1374 case EM_MSP430:
dda8d76d 1375 if (uses_msp430x_relocs (filedata))
13761a11
NC
1376 {
1377 rtype = elf_msp430x_reloc_type (type);
1378 break;
1379 }
1a0670f3 1380 /* Fall through. */
2469cfa2
NC
1381 case EM_MSP430_OLD:
1382 rtype = elf_msp430_reloc_type (type);
1383 break;
1384
35c08157
KLC
1385 case EM_NDS32:
1386 rtype = elf_nds32_reloc_type (type);
1387 break;
1388
252b5132 1389 case EM_PPC:
9ea033b2 1390 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1391 break;
1392
c833c019
AM
1393 case EM_PPC64:
1394 rtype = elf_ppc64_reloc_type (type);
1395 break;
1396
252b5132 1397 case EM_MIPS:
4fe85591 1398 case EM_MIPS_RS3_LE:
9ea033b2 1399 rtype = elf_mips_reloc_type (type);
252b5132
RH
1400 break;
1401
e23eba97
NC
1402 case EM_RISCV:
1403 rtype = elf_riscv_reloc_type (type);
1404 break;
1405
252b5132 1406 case EM_ALPHA:
9ea033b2 1407 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1408 break;
1409
1410 case EM_ARM:
9ea033b2 1411 rtype = elf_arm_reloc_type (type);
252b5132
RH
1412 break;
1413
584da044 1414 case EM_ARC:
886a2506
NC
1415 case EM_ARC_COMPACT:
1416 case EM_ARC_COMPACT2:
9ea033b2 1417 rtype = elf_arc_reloc_type (type);
252b5132
RH
1418 break;
1419
1420 case EM_PARISC:
69e617ca 1421 rtype = elf_hppa_reloc_type (type);
252b5132 1422 break;
7d466069 1423
b8720f9d
JL
1424 case EM_H8_300:
1425 case EM_H8_300H:
1426 case EM_H8S:
1427 rtype = elf_h8_reloc_type (type);
1428 break;
1429
73589c9d
CS
1430 case EM_OR1K:
1431 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1432 break;
1433
7d466069 1434 case EM_PJ:
2b0337b0 1435 case EM_PJ_OLD:
7d466069
ILT
1436 rtype = elf_pj_reloc_type (type);
1437 break;
800eeca4
JW
1438 case EM_IA_64:
1439 rtype = elf_ia64_reloc_type (type);
1440 break;
1b61cf92
HPN
1441
1442 case EM_CRIS:
1443 rtype = elf_cris_reloc_type (type);
1444 break;
535c37ff 1445
f954747f
AM
1446 case EM_860:
1447 rtype = elf_i860_reloc_type (type);
1448 break;
1449
bcedfee6 1450 case EM_X86_64:
8a9036a4 1451 case EM_L1OM:
7a9068fe 1452 case EM_K1OM:
bcedfee6
NC
1453 rtype = elf_x86_64_reloc_type (type);
1454 break;
a85d7ed0 1455
f954747f
AM
1456 case EM_S370:
1457 rtype = i370_reloc_type (type);
1458 break;
1459
53c7db4b
KH
1460 case EM_S390_OLD:
1461 case EM_S390:
1462 rtype = elf_s390_reloc_type (type);
1463 break;
93fbbb04 1464
1c0d3aa6
NC
1465 case EM_SCORE:
1466 rtype = elf_score_reloc_type (type);
1467 break;
1468
93fbbb04
GK
1469 case EM_XSTORMY16:
1470 rtype = elf_xstormy16_reloc_type (type);
1471 break;
179d3252 1472
1fe1f39c
NC
1473 case EM_CRX:
1474 rtype = elf_crx_reloc_type (type);
1475 break;
1476
179d3252
JT
1477 case EM_VAX:
1478 rtype = elf_vax_reloc_type (type);
1479 break;
1e4cf259 1480
619ed720
EB
1481 case EM_VISIUM:
1482 rtype = elf_visium_reloc_type (type);
1483 break;
1484
cfb8c092
NC
1485 case EM_ADAPTEVA_EPIPHANY:
1486 rtype = elf_epiphany_reloc_type (type);
1487 break;
1488
1e4cf259
NC
1489 case EM_IP2K:
1490 case EM_IP2K_OLD:
1491 rtype = elf_ip2k_reloc_type (type);
1492 break;
3b36097d
SC
1493
1494 case EM_IQ2000:
1495 rtype = elf_iq2000_reloc_type (type);
1496 break;
88da6820
NC
1497
1498 case EM_XTENSA_OLD:
1499 case EM_XTENSA:
1500 rtype = elf_xtensa_reloc_type (type);
1501 break;
a34e3ecb 1502
84e94c90
NC
1503 case EM_LATTICEMICO32:
1504 rtype = elf_lm32_reloc_type (type);
1505 break;
1506
ff7eeb89 1507 case EM_M32C_OLD:
49f58d10
JB
1508 case EM_M32C:
1509 rtype = elf_m32c_reloc_type (type);
1510 break;
1511
d031aafb
NS
1512 case EM_MT:
1513 rtype = elf_mt_reloc_type (type);
a34e3ecb 1514 break;
1d65ded4
CM
1515
1516 case EM_BLACKFIN:
1517 rtype = elf_bfin_reloc_type (type);
1518 break;
15ab5209
DB
1519
1520 case EM_CYGNUS_MEP:
1521 rtype = elf_mep_reloc_type (type);
1522 break;
60bca95a
NC
1523
1524 case EM_CR16:
1525 rtype = elf_cr16_reloc_type (type);
1526 break;
dd24e3da 1527
7ba29e2a
NC
1528 case EM_MICROBLAZE:
1529 case EM_MICROBLAZE_OLD:
1530 rtype = elf_microblaze_reloc_type (type);
1531 break;
c7927a3c 1532
99c513f6
DD
1533 case EM_RL78:
1534 rtype = elf_rl78_reloc_type (type);
1535 break;
1536
c7927a3c
NC
1537 case EM_RX:
1538 rtype = elf_rx_reloc_type (type);
1539 break;
c29aca4a 1540
a3c62988
NC
1541 case EM_METAG:
1542 rtype = elf_metag_reloc_type (type);
1543 break;
1544
c29aca4a
NC
1545 case EM_XC16X:
1546 case EM_C166:
1547 rtype = elf_xc16x_reloc_type (type);
1548 break;
40b36596
JM
1549
1550 case EM_TI_C6000:
1551 rtype = elf_tic6x_reloc_type (type);
1552 break;
aa137e4d
NC
1553
1554 case EM_TILEGX:
1555 rtype = elf_tilegx_reloc_type (type);
1556 break;
1557
1558 case EM_TILEPRO:
1559 rtype = elf_tilepro_reloc_type (type);
1560 break;
f6c1a2d5 1561
f96bd6c2
PC
1562 case EM_WEBASSEMBLY:
1563 rtype = elf_wasm32_reloc_type (type);
1564 break;
1565
f6c1a2d5
NC
1566 case EM_XGATE:
1567 rtype = elf_xgate_reloc_type (type);
1568 break;
36591ba1
SL
1569
1570 case EM_ALTERA_NIOS2:
1571 rtype = elf_nios2_reloc_type (type);
1572 break;
2b100bb5
DD
1573
1574 case EM_TI_PRU:
1575 rtype = elf_pru_reloc_type (type);
1576 break;
fe944acf
FT
1577
1578 case EM_NFP:
1579 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1580 rtype = elf_nfp3200_reloc_type (type);
1581 else
1582 rtype = elf_nfp_reloc_type (type);
1583 break;
252b5132
RH
1584 }
1585
1586 if (rtype == NULL)
39dbeff8 1587 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1588 else
5c144731 1589 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1590
dda8d76d 1591 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1592 && rtype != NULL
7ace3541
RH
1593 && streq (rtype, "R_ALPHA_LITUSE")
1594 && is_rela)
1595 {
1596 switch (rels[i].r_addend)
1597 {
1598 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1599 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1600 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1601 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1602 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1603 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1604 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1605 default: rtype = NULL;
1606 }
32ec8896 1607
7ace3541
RH
1608 if (rtype)
1609 printf (" (%s)", rtype);
1610 else
1611 {
1612 putchar (' ');
1613 printf (_("<unknown addend: %lx>"),
1614 (unsigned long) rels[i].r_addend);
32ec8896 1615 res = FALSE;
7ace3541
RH
1616 }
1617 }
1618 else if (symtab_index)
252b5132 1619 {
af3fc3bc 1620 if (symtab == NULL || symtab_index >= nsyms)
32ec8896
NC
1621 {
1622 error (_(" bad symbol index: %08lx in reloc"), (unsigned long) symtab_index);
1623 res = FALSE;
1624 }
af3fc3bc 1625 else
19936277 1626 {
2cf0635d 1627 Elf_Internal_Sym * psym;
bb4d2ac2
L
1628 const char * version_string;
1629 enum versioned_symbol_info sym_info;
1630 unsigned short vna_other;
19936277 1631
af3fc3bc 1632 psym = symtab + symtab_index;
103f02d3 1633
bb4d2ac2 1634 version_string
dda8d76d 1635 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1636 strtab, strtablen,
1637 symtab_index,
1638 psym,
1639 &sym_info,
1640 &vna_other);
1641
af3fc3bc 1642 printf (" ");
171191ba 1643
d8045f23
NC
1644 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1645 {
1646 const char * name;
1647 unsigned int len;
1648 unsigned int width = is_32bit_elf ? 8 : 14;
1649
1650 /* Relocations against GNU_IFUNC symbols do not use the value
1651 of the symbol as the address to relocate against. Instead
1652 they invoke the function named by the symbol and use its
1653 result as the address for relocation.
1654
1655 To indicate this to the user, do not display the value of
1656 the symbol in the "Symbols's Value" field. Instead show
1657 its name followed by () as a hint that the symbol is
1658 invoked. */
1659
1660 if (strtab == NULL
1661 || psym->st_name == 0
1662 || psym->st_name >= strtablen)
1663 name = "??";
1664 else
1665 name = strtab + psym->st_name;
1666
1667 len = print_symbol (width, name);
bb4d2ac2
L
1668 if (version_string)
1669 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1670 version_string);
d8045f23
NC
1671 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1672 }
1673 else
1674 {
1675 print_vma (psym->st_value, LONG_HEX);
171191ba 1676
d8045f23
NC
1677 printf (is_32bit_elf ? " " : " ");
1678 }
103f02d3 1679
af3fc3bc 1680 if (psym->st_name == 0)
f1ef08cb 1681 {
2cf0635d 1682 const char * sec_name = "<null>";
f1ef08cb
AM
1683 char name_buf[40];
1684
1685 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1686 {
dda8d76d
NC
1687 if (psym->st_shndx < filedata->file_header.e_shnum)
1688 sec_name = SECTION_NAME (filedata->section_headers + psym->st_shndx);
f1ef08cb
AM
1689 else if (psym->st_shndx == SHN_ABS)
1690 sec_name = "ABS";
1691 else if (psym->st_shndx == SHN_COMMON)
1692 sec_name = "COMMON";
dda8d76d 1693 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1694 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1695 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1696 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1697 sec_name = "SCOMMON";
dda8d76d 1698 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1699 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1700 sec_name = "SUNDEF";
dda8d76d
NC
1701 else if ((filedata->file_header.e_machine == EM_X86_64
1702 || filedata->file_header.e_machine == EM_L1OM
1703 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1704 && psym->st_shndx == SHN_X86_64_LCOMMON)
1705 sec_name = "LARGE_COMMON";
dda8d76d
NC
1706 else if (filedata->file_header.e_machine == EM_IA_64
1707 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1708 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1709 sec_name = "ANSI_COM";
dda8d76d 1710 else if (is_ia64_vms (filedata)
148b93f2
NC
1711 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1712 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1713 else
1714 {
1715 sprintf (name_buf, "<section 0x%x>",
1716 (unsigned int) psym->st_shndx);
1717 sec_name = name_buf;
1718 }
1719 }
1720 print_symbol (22, sec_name);
1721 }
af3fc3bc 1722 else if (strtab == NULL)
d79b3d50 1723 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1724 else if (psym->st_name >= strtablen)
32ec8896
NC
1725 {
1726 error (_("<corrupt string table index: %3ld>"), psym->st_name);
1727 res = FALSE;
1728 }
af3fc3bc 1729 else
bb4d2ac2
L
1730 {
1731 print_symbol (22, strtab + psym->st_name);
1732 if (version_string)
1733 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1734 version_string);
1735 }
103f02d3 1736
af3fc3bc 1737 if (is_rela)
171191ba 1738 {
7360e63f 1739 bfd_vma off = rels[i].r_addend;
171191ba 1740
7360e63f 1741 if ((bfd_signed_vma) off < 0)
598aaa76 1742 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1743 else
598aaa76 1744 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1745 }
19936277 1746 }
252b5132 1747 }
1b228002 1748 else if (is_rela)
f7a99963 1749 {
7360e63f 1750 bfd_vma off = rels[i].r_addend;
e04d7088
L
1751
1752 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1753 if ((bfd_signed_vma) off < 0)
e04d7088
L
1754 printf ("-%" BFD_VMA_FMT "x", - off);
1755 else
1756 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1757 }
252b5132 1758
dda8d76d 1759 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1760 && rtype != NULL
1761 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1762 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1763
252b5132 1764 putchar ('\n');
2c71103e 1765
aca88567 1766#ifdef BFD64
dda8d76d 1767 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1768 {
91d6fa6a
NC
1769 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1770 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1771 const char * rtype2 = elf_mips_reloc_type (type2);
1772 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1773
2c71103e
NC
1774 printf (" Type2: ");
1775
1776 if (rtype2 == NULL)
39dbeff8
AM
1777 printf (_("unrecognized: %-7lx"),
1778 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1779 else
1780 printf ("%-17.17s", rtype2);
1781
18bd398b 1782 printf ("\n Type3: ");
2c71103e
NC
1783
1784 if (rtype3 == NULL)
39dbeff8
AM
1785 printf (_("unrecognized: %-7lx"),
1786 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1787 else
1788 printf ("%-17.17s", rtype3);
1789
53c7db4b 1790 putchar ('\n');
2c71103e 1791 }
aca88567 1792#endif /* BFD64 */
252b5132
RH
1793 }
1794
c8286bd1 1795 free (rels);
32ec8896
NC
1796
1797 return res;
252b5132
RH
1798}
1799
37c18eed
SD
1800static const char *
1801get_aarch64_dynamic_type (unsigned long type)
1802{
1803 switch (type)
1804 {
1805 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1806 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
37c18eed
SD
1807 default:
1808 return NULL;
1809 }
1810}
1811
252b5132 1812static const char *
d3ba0551 1813get_mips_dynamic_type (unsigned long type)
252b5132
RH
1814{
1815 switch (type)
1816 {
1817 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1818 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1819 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1820 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1821 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1822 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1823 case DT_MIPS_MSYM: return "MIPS_MSYM";
1824 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1825 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1826 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1827 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1828 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1829 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1830 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1831 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1832 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1833 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1834 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1835 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1836 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1837 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1838 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1839 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1840 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1841 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1842 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1843 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1844 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1845 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1846 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1847 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1848 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1849 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1850 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1851 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1852 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1853 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1854 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1855 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1856 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1857 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1858 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1859 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1860 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1861 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1862 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1863 default:
1864 return NULL;
1865 }
1866}
1867
9a097730 1868static const char *
d3ba0551 1869get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1870{
1871 switch (type)
1872 {
1873 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1874 default:
1875 return NULL;
1876 }
103f02d3
UD
1877}
1878
7490d522
AM
1879static const char *
1880get_ppc_dynamic_type (unsigned long type)
1881{
1882 switch (type)
1883 {
a7f2871e 1884 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1885 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1886 default:
1887 return NULL;
1888 }
1889}
1890
f1cb7e17 1891static const char *
d3ba0551 1892get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1893{
1894 switch (type)
1895 {
a7f2871e
AM
1896 case DT_PPC64_GLINK: return "PPC64_GLINK";
1897 case DT_PPC64_OPD: return "PPC64_OPD";
1898 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1899 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1900 default:
1901 return NULL;
1902 }
1903}
1904
103f02d3 1905static const char *
d3ba0551 1906get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1907{
1908 switch (type)
1909 {
1910 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1911 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1912 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1913 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1914 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1915 case DT_HP_PREINIT: return "HP_PREINIT";
1916 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1917 case DT_HP_NEEDED: return "HP_NEEDED";
1918 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1919 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1920 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1921 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1922 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1923 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1924 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1925 case DT_HP_FILTERED: return "HP_FILTERED";
1926 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1927 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1928 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1929 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1930 case DT_PLT: return "PLT";
1931 case DT_PLT_SIZE: return "PLT_SIZE";
1932 case DT_DLT: return "DLT";
1933 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1934 default:
1935 return NULL;
1936 }
1937}
9a097730 1938
ecc51f48 1939static const char *
d3ba0551 1940get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1941{
1942 switch (type)
1943 {
148b93f2
NC
1944 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1945 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1946 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1947 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1948 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1949 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1950 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1951 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1952 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1953 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1954 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1955 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1956 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1957 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1958 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1959 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1960 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1961 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1962 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1963 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1964 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1965 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1966 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1967 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1968 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1969 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1970 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1971 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1972 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1973 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1974 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1975 default:
1976 return NULL;
1977 }
1978}
1979
fd85a6a1
NC
1980static const char *
1981get_solaris_section_type (unsigned long type)
1982{
1983 switch (type)
1984 {
1985 case 0x6fffffee: return "SUNW_ancillary";
1986 case 0x6fffffef: return "SUNW_capchain";
1987 case 0x6ffffff0: return "SUNW_capinfo";
1988 case 0x6ffffff1: return "SUNW_symsort";
1989 case 0x6ffffff2: return "SUNW_tlssort";
1990 case 0x6ffffff3: return "SUNW_LDYNSYM";
1991 case 0x6ffffff4: return "SUNW_dof";
1992 case 0x6ffffff5: return "SUNW_cap";
1993 case 0x6ffffff6: return "SUNW_SIGNATURE";
1994 case 0x6ffffff7: return "SUNW_ANNOTATE";
1995 case 0x6ffffff8: return "SUNW_DEBUGSTR";
1996 case 0x6ffffff9: return "SUNW_DEBUG";
1997 case 0x6ffffffa: return "SUNW_move";
1998 case 0x6ffffffb: return "SUNW_COMDAT";
1999 case 0x6ffffffc: return "SUNW_syminfo";
2000 case 0x6ffffffd: return "SUNW_verdef";
2001 case 0x6ffffffe: return "SUNW_verneed";
2002 case 0x6fffffff: return "SUNW_versym";
2003 case 0x70000000: return "SPARC_GOTDATA";
2004 default: return NULL;
2005 }
2006}
2007
fabcb361
RH
2008static const char *
2009get_alpha_dynamic_type (unsigned long type)
2010{
2011 switch (type)
2012 {
2013 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2014 default: return NULL;
fabcb361
RH
2015 }
2016}
2017
1c0d3aa6
NC
2018static const char *
2019get_score_dynamic_type (unsigned long type)
2020{
2021 switch (type)
2022 {
2023 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2024 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2025 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2026 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2027 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2028 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2029 default: return NULL;
1c0d3aa6
NC
2030 }
2031}
2032
40b36596
JM
2033static const char *
2034get_tic6x_dynamic_type (unsigned long type)
2035{
2036 switch (type)
2037 {
2038 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2039 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2040 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2041 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2042 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2043 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2044 default: return NULL;
40b36596
JM
2045 }
2046}
1c0d3aa6 2047
36591ba1
SL
2048static const char *
2049get_nios2_dynamic_type (unsigned long type)
2050{
2051 switch (type)
2052 {
2053 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2054 default: return NULL;
36591ba1
SL
2055 }
2056}
2057
fd85a6a1
NC
2058static const char *
2059get_solaris_dynamic_type (unsigned long type)
2060{
2061 switch (type)
2062 {
2063 case 0x6000000d: return "SUNW_AUXILIARY";
2064 case 0x6000000e: return "SUNW_RTLDINF";
2065 case 0x6000000f: return "SUNW_FILTER";
2066 case 0x60000010: return "SUNW_CAP";
2067 case 0x60000011: return "SUNW_SYMTAB";
2068 case 0x60000012: return "SUNW_SYMSZ";
2069 case 0x60000013: return "SUNW_SORTENT";
2070 case 0x60000014: return "SUNW_SYMSORT";
2071 case 0x60000015: return "SUNW_SYMSORTSZ";
2072 case 0x60000016: return "SUNW_TLSSORT";
2073 case 0x60000017: return "SUNW_TLSSORTSZ";
2074 case 0x60000018: return "SUNW_CAPINFO";
2075 case 0x60000019: return "SUNW_STRPAD";
2076 case 0x6000001a: return "SUNW_CAPCHAIN";
2077 case 0x6000001b: return "SUNW_LDMACH";
2078 case 0x6000001d: return "SUNW_CAPCHAINENT";
2079 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2080 case 0x60000021: return "SUNW_PARENT";
2081 case 0x60000023: return "SUNW_ASLR";
2082 case 0x60000025: return "SUNW_RELAX";
2083 case 0x60000029: return "SUNW_NXHEAP";
2084 case 0x6000002b: return "SUNW_NXSTACK";
2085
2086 case 0x70000001: return "SPARC_REGISTER";
2087 case 0x7ffffffd: return "AUXILIARY";
2088 case 0x7ffffffe: return "USED";
2089 case 0x7fffffff: return "FILTER";
2090
15f205b1 2091 default: return NULL;
fd85a6a1
NC
2092 }
2093}
2094
252b5132 2095static const char *
dda8d76d 2096get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2097{
e9e44622 2098 static char buff[64];
252b5132
RH
2099
2100 switch (type)
2101 {
2102 case DT_NULL: return "NULL";
2103 case DT_NEEDED: return "NEEDED";
2104 case DT_PLTRELSZ: return "PLTRELSZ";
2105 case DT_PLTGOT: return "PLTGOT";
2106 case DT_HASH: return "HASH";
2107 case DT_STRTAB: return "STRTAB";
2108 case DT_SYMTAB: return "SYMTAB";
2109 case DT_RELA: return "RELA";
2110 case DT_RELASZ: return "RELASZ";
2111 case DT_RELAENT: return "RELAENT";
2112 case DT_STRSZ: return "STRSZ";
2113 case DT_SYMENT: return "SYMENT";
2114 case DT_INIT: return "INIT";
2115 case DT_FINI: return "FINI";
2116 case DT_SONAME: return "SONAME";
2117 case DT_RPATH: return "RPATH";
2118 case DT_SYMBOLIC: return "SYMBOLIC";
2119 case DT_REL: return "REL";
2120 case DT_RELSZ: return "RELSZ";
2121 case DT_RELENT: return "RELENT";
2122 case DT_PLTREL: return "PLTREL";
2123 case DT_DEBUG: return "DEBUG";
2124 case DT_TEXTREL: return "TEXTREL";
2125 case DT_JMPREL: return "JMPREL";
2126 case DT_BIND_NOW: return "BIND_NOW";
2127 case DT_INIT_ARRAY: return "INIT_ARRAY";
2128 case DT_FINI_ARRAY: return "FINI_ARRAY";
2129 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2130 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2131 case DT_RUNPATH: return "RUNPATH";
2132 case DT_FLAGS: return "FLAGS";
2d0e6f43 2133
d1133906
NC
2134 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2135 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2136 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2137
05107a46 2138 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2139 case DT_PLTPADSZ: return "PLTPADSZ";
2140 case DT_MOVEENT: return "MOVEENT";
2141 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2142 case DT_FEATURE: return "FEATURE";
252b5132
RH
2143 case DT_POSFLAG_1: return "POSFLAG_1";
2144 case DT_SYMINSZ: return "SYMINSZ";
2145 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2146
252b5132 2147 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2148 case DT_CONFIG: return "CONFIG";
2149 case DT_DEPAUDIT: return "DEPAUDIT";
2150 case DT_AUDIT: return "AUDIT";
2151 case DT_PLTPAD: return "PLTPAD";
2152 case DT_MOVETAB: return "MOVETAB";
252b5132 2153 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2154
252b5132 2155 case DT_VERSYM: return "VERSYM";
103f02d3 2156
67a4f2b7
AO
2157 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2158 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2159 case DT_RELACOUNT: return "RELACOUNT";
2160 case DT_RELCOUNT: return "RELCOUNT";
2161 case DT_FLAGS_1: return "FLAGS_1";
2162 case DT_VERDEF: return "VERDEF";
2163 case DT_VERDEFNUM: return "VERDEFNUM";
2164 case DT_VERNEED: return "VERNEED";
2165 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2166
019148e4 2167 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2168 case DT_USED: return "USED";
2169 case DT_FILTER: return "FILTER";
103f02d3 2170
047b2264
JJ
2171 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2172 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2173 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2174 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2175 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2176 case DT_GNU_HASH: return "GNU_HASH";
047b2264 2177
252b5132
RH
2178 default:
2179 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2180 {
2cf0635d 2181 const char * result;
103f02d3 2182
dda8d76d 2183 switch (filedata->file_header.e_machine)
252b5132 2184 {
37c18eed
SD
2185 case EM_AARCH64:
2186 result = get_aarch64_dynamic_type (type);
2187 break;
252b5132 2188 case EM_MIPS:
4fe85591 2189 case EM_MIPS_RS3_LE:
252b5132
RH
2190 result = get_mips_dynamic_type (type);
2191 break;
9a097730
RH
2192 case EM_SPARCV9:
2193 result = get_sparc64_dynamic_type (type);
2194 break;
7490d522
AM
2195 case EM_PPC:
2196 result = get_ppc_dynamic_type (type);
2197 break;
f1cb7e17
AM
2198 case EM_PPC64:
2199 result = get_ppc64_dynamic_type (type);
2200 break;
ecc51f48
NC
2201 case EM_IA_64:
2202 result = get_ia64_dynamic_type (type);
2203 break;
fabcb361
RH
2204 case EM_ALPHA:
2205 result = get_alpha_dynamic_type (type);
2206 break;
1c0d3aa6
NC
2207 case EM_SCORE:
2208 result = get_score_dynamic_type (type);
2209 break;
40b36596
JM
2210 case EM_TI_C6000:
2211 result = get_tic6x_dynamic_type (type);
2212 break;
36591ba1
SL
2213 case EM_ALTERA_NIOS2:
2214 result = get_nios2_dynamic_type (type);
2215 break;
252b5132 2216 default:
dda8d76d 2217 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2218 result = get_solaris_dynamic_type (type);
2219 else
2220 result = NULL;
252b5132
RH
2221 break;
2222 }
2223
2224 if (result != NULL)
2225 return result;
2226
e9e44622 2227 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2228 }
eec8f817 2229 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2230 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2231 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2232 {
2cf0635d 2233 const char * result;
103f02d3 2234
dda8d76d 2235 switch (filedata->file_header.e_machine)
103f02d3
UD
2236 {
2237 case EM_PARISC:
2238 result = get_parisc_dynamic_type (type);
2239 break;
148b93f2
NC
2240 case EM_IA_64:
2241 result = get_ia64_dynamic_type (type);
2242 break;
103f02d3 2243 default:
dda8d76d 2244 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2245 result = get_solaris_dynamic_type (type);
2246 else
2247 result = NULL;
103f02d3
UD
2248 break;
2249 }
2250
2251 if (result != NULL)
2252 return result;
2253
e9e44622
JJ
2254 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2255 type);
103f02d3 2256 }
252b5132 2257 else
e9e44622 2258 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2259
252b5132
RH
2260 return buff;
2261 }
2262}
2263
2264static char *
d3ba0551 2265get_file_type (unsigned e_type)
252b5132 2266{
b34976b6 2267 static char buff[32];
252b5132
RH
2268
2269 switch (e_type)
2270 {
32ec8896
NC
2271 case ET_NONE: return _("NONE (None)");
2272 case ET_REL: return _("REL (Relocatable file)");
2273 case ET_EXEC: return _("EXEC (Executable file)");
2274 case ET_DYN: return _("DYN (Shared object file)");
2275 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2276
2277 default:
2278 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2279 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2280 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2281 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2282 else
e9e44622 2283 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2284 return buff;
2285 }
2286}
2287
2288static char *
d3ba0551 2289get_machine_name (unsigned e_machine)
252b5132 2290{
b34976b6 2291 static char buff[64]; /* XXX */
252b5132
RH
2292
2293 switch (e_machine)
2294 {
55e22ca8
NC
2295 /* Please keep this switch table sorted by increasing EM_ value. */
2296 /* 0 */
c45021f2
NC
2297 case EM_NONE: return _("None");
2298 case EM_M32: return "WE32100";
2299 case EM_SPARC: return "Sparc";
2300 case EM_386: return "Intel 80386";
2301 case EM_68K: return "MC68000";
2302 case EM_88K: return "MC88000";
22abe556 2303 case EM_IAMCU: return "Intel MCU";
fb70ec17 2304 case EM_860: return "Intel 80860";
c45021f2
NC
2305 case EM_MIPS: return "MIPS R3000";
2306 case EM_S370: return "IBM System/370";
55e22ca8 2307 /* 10 */
7036c0e1 2308 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2309 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2310 case EM_PARISC: return "HPPA";
55e22ca8 2311 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2312 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2313 case EM_960: return "Intel 80960";
c45021f2 2314 case EM_PPC: return "PowerPC";
55e22ca8 2315 /* 20 */
285d1771 2316 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2317 case EM_S390_OLD:
2318 case EM_S390: return "IBM S/390";
2319 case EM_SPU: return "SPU";
2320 /* 30 */
2321 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2322 case EM_FR20: return "Fujitsu FR20";
2323 case EM_RH32: return "TRW RH32";
b34976b6 2324 case EM_MCORE: return "MCORE";
55e22ca8 2325 /* 40 */
7036c0e1
AJ
2326 case EM_ARM: return "ARM";
2327 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2328 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2329 case EM_SPARCV9: return "Sparc v9";
2330 case EM_TRICORE: return "Siemens Tricore";
584da044 2331 case EM_ARC: return "ARC";
c2dcd04e
NC
2332 case EM_H8_300: return "Renesas H8/300";
2333 case EM_H8_300H: return "Renesas H8/300H";
2334 case EM_H8S: return "Renesas H8S";
2335 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2336 /* 50 */
30800947 2337 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2338 case EM_MIPS_X: return "Stanford MIPS-X";
2339 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2340 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2341 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2342 case EM_PCP: return "Siemens PCP";
2343 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2344 case EM_NDR1: return "Denso NDR1 microprocesspr";
2345 case EM_STARCORE: return "Motorola Star*Core processor";
2346 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2347 /* 60 */
7036c0e1
AJ
2348 case EM_ST100: return "STMicroelectronics ST100 processor";
2349 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2350 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2351 case EM_PDSP: return "Sony DSP processor";
2352 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2353 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2354 case EM_FX66: return "Siemens FX66 microcontroller";
2355 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2356 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2357 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2358 /* 70 */
7036c0e1
AJ
2359 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2360 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2361 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2362 case EM_SVX: return "Silicon Graphics SVx";
2363 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2364 case EM_VAX: return "Digital VAX";
1b61cf92 2365 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2366 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2367 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2368 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2369 /* 80 */
b34976b6 2370 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2371 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2372 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2373 case EM_AVR_OLD:
2374 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2375 case EM_CYGNUS_FR30:
2376 case EM_FR30: return "Fujitsu FR30";
2377 case EM_CYGNUS_D10V:
2378 case EM_D10V: return "d10v";
2379 case EM_CYGNUS_D30V:
2380 case EM_D30V: return "d30v";
2381 case EM_CYGNUS_V850:
2382 case EM_V850: return "Renesas V850";
2383 case EM_CYGNUS_M32R:
2384 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2385 case EM_CYGNUS_MN10300:
2386 case EM_MN10300: return "mn10300";
2387 /* 90 */
2388 case EM_CYGNUS_MN10200:
2389 case EM_MN10200: return "mn10200";
2390 case EM_PJ: return "picoJava";
73589c9d 2391 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2392 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2393 case EM_XTENSA_OLD:
2394 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2395 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2396 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2397 case EM_NS32K: return "National Semiconductor 32000 series";
2398 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2399 case EM_SNP1K: return "Trebia SNP 1000 processor";
2400 /* 100 */
2401 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2402 case EM_IP2K_OLD:
2403 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2404 case EM_MAX: return "MAX Processor";
2405 case EM_CR: return "National Semiconductor CompactRISC";
2406 case EM_F2MC16: return "Fujitsu F2MC16";
2407 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2408 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2409 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2410 case EM_SEP: return "Sharp embedded microprocessor";
2411 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2412 /* 110 */
11636f9e
JM
2413 case EM_UNICORE: return "Unicore";
2414 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2415 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2416 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2417 case EM_CRX: return "National Semiconductor CRX microprocessor";
2418 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2419 case EM_C166:
d70c5fc7 2420 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2421 case EM_M16C: return "Renesas M16C series microprocessors";
2422 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2423 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2424 /* 120 */
2425 case EM_M32C: return "Renesas M32c";
2426 /* 130 */
11636f9e
JM
2427 case EM_TSK3000: return "Altium TSK3000 core";
2428 case EM_RS08: return "Freescale RS08 embedded processor";
2429 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2430 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2431 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2432 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2433 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2434 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2435 /* 140 */
11636f9e
JM
2436 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2437 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2438 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2439 case EM_TI_PRU: return "TI PRU I/O processor";
2440 /* 160 */
11636f9e
JM
2441 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2442 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2443 case EM_R32C: return "Renesas R32C series microprocessors";
2444 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2445 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2446 case EM_8051: return "Intel 8051 and variants";
2447 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2448 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2449 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2450 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2451 /* 170 */
11636f9e
JM
2452 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2453 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2454 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2455 case EM_RX: return "Renesas RX";
a3c62988 2456 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2457 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2458 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2459 case EM_CR16:
2460 case EM_MICROBLAZE:
2461 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2462 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2463 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2464 /* 180 */
2465 case EM_L1OM: return "Intel L1OM";
2466 case EM_K1OM: return "Intel K1OM";
2467 case EM_INTEL182: return "Intel (reserved)";
2468 case EM_AARCH64: return "AArch64";
2469 case EM_ARM184: return "ARM (reserved)";
2470 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2471 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2472 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2473 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2474 /* 190 */
11636f9e 2475 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2476 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2477 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2478 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2479 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2480 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2481 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2482 case EM_RL78: return "Renesas RL78";
6d913794 2483 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2484 case EM_78K0R: return "Renesas 78K0R";
2485 /* 200 */
6d913794 2486 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2487 case EM_BA1: return "Beyond BA1 CPU architecture";
2488 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2489 case EM_XCORE: return "XMOS xCORE processor family";
2490 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
55e22ca8 2491 /* 210 */
6d913794
NC
2492 case EM_KM32: return "KM211 KM32 32-bit processor";
2493 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2494 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2495 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2496 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2497 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2498 case EM_COGE: return "Cognitive Smart Memory Processor";
2499 case EM_COOL: return "Bluechip Systems CoolEngine";
2500 case EM_NORC: return "Nanoradio Optimized RISC";
2501 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2502 /* 220 */
15f205b1 2503 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2504 case EM_VISIUM: return "CDS VISIUMcore processor";
2505 case EM_FT32: return "FTDI Chip FT32";
2506 case EM_MOXIE: return "Moxie";
2507 case EM_AMDGPU: return "AMD GPU";
2508 case EM_RISCV: return "RISC-V";
2509 case EM_LANAI: return "Lanai 32-bit processor";
2510 case EM_BPF: return "Linux BPF";
fe944acf 2511 case EM_NFP: return "Netronome Flow Processor";
55e22ca8
NC
2512
2513 /* Large numbers... */
2514 case EM_MT: return "Morpho Techologies MT processor";
2515 case EM_ALPHA: return "Alpha";
2516 case EM_WEBASSEMBLY: return "Web Assembly";
2517 case EM_DLX: return "OpenDLX";
2518 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2519 case EM_IQ2000: return "Vitesse IQ2000";
2520 case EM_M32C_OLD:
2521 case EM_NIOS32: return "Altera Nios";
2522 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2523 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2524 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2525 case EM_S12Z: return "Freescale S12Z";
b8891f8d 2526 case EM_CSKY: return "C-SKY";
55e22ca8 2527
252b5132 2528 default:
35d9dd2f 2529 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2530 return buff;
2531 }
2532}
2533
a9522a21
AB
2534static void
2535decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2536{
2537 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
2538 other compilers don't a specific architecture type in the e_flags, and
2539 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2540 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2541 architectures.
2542
2543 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2544 but also sets a specific architecture type in the e_flags field.
2545
2546 However, when decoding the flags we don't worry if we see an
2547 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2548 ARCEM architecture type. */
2549
2550 switch (e_flags & EF_ARC_MACH_MSK)
2551 {
2552 /* We only expect these to occur for EM_ARC_COMPACT2. */
2553 case EF_ARC_CPU_ARCV2EM:
2554 strcat (buf, ", ARC EM");
2555 break;
2556 case EF_ARC_CPU_ARCV2HS:
2557 strcat (buf, ", ARC HS");
2558 break;
2559
2560 /* We only expect these to occur for EM_ARC_COMPACT. */
2561 case E_ARC_MACH_ARC600:
2562 strcat (buf, ", ARC600");
2563 break;
2564 case E_ARC_MACH_ARC601:
2565 strcat (buf, ", ARC601");
2566 break;
2567 case E_ARC_MACH_ARC700:
2568 strcat (buf, ", ARC700");
2569 break;
2570
2571 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2572 new ELF with new architecture being read by an old version of
2573 readelf, or (c) An ELF built with non-GNU compiler that does not
2574 set the architecture in the e_flags. */
2575 default:
2576 if (e_machine == EM_ARC_COMPACT)
2577 strcat (buf, ", Unknown ARCompact");
2578 else
2579 strcat (buf, ", Unknown ARC");
2580 break;
2581 }
2582
2583 switch (e_flags & EF_ARC_OSABI_MSK)
2584 {
2585 case E_ARC_OSABI_ORIG:
2586 strcat (buf, ", (ABI:legacy)");
2587 break;
2588 case E_ARC_OSABI_V2:
2589 strcat (buf, ", (ABI:v2)");
2590 break;
2591 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2592 case E_ARC_OSABI_V3:
2593 strcat (buf, ", v3 no-legacy-syscalls ABI");
2594 break;
53a346d8
CZ
2595 case E_ARC_OSABI_V4:
2596 strcat (buf, ", v4 ABI");
2597 break;
a9522a21
AB
2598 default:
2599 strcat (buf, ", unrecognised ARC OSABI flag");
2600 break;
2601 }
2602}
2603
f3485b74 2604static void
d3ba0551 2605decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2606{
2607 unsigned eabi;
32ec8896 2608 bfd_boolean unknown = FALSE;
f3485b74
NC
2609
2610 eabi = EF_ARM_EABI_VERSION (e_flags);
2611 e_flags &= ~ EF_ARM_EABIMASK;
2612
2613 /* Handle "generic" ARM flags. */
2614 if (e_flags & EF_ARM_RELEXEC)
2615 {
2616 strcat (buf, ", relocatable executable");
2617 e_flags &= ~ EF_ARM_RELEXEC;
2618 }
76da6bbe 2619
18a20338
CL
2620 if (e_flags & EF_ARM_PIC)
2621 {
2622 strcat (buf, ", position independent");
2623 e_flags &= ~ EF_ARM_PIC;
2624 }
2625
f3485b74
NC
2626 /* Now handle EABI specific flags. */
2627 switch (eabi)
2628 {
2629 default:
2c71103e 2630 strcat (buf, ", <unrecognized EABI>");
f3485b74 2631 if (e_flags)
32ec8896 2632 unknown = TRUE;
f3485b74
NC
2633 break;
2634
2635 case EF_ARM_EABI_VER1:
a5bcd848 2636 strcat (buf, ", Version1 EABI");
f3485b74
NC
2637 while (e_flags)
2638 {
2639 unsigned flag;
76da6bbe 2640
f3485b74
NC
2641 /* Process flags one bit at a time. */
2642 flag = e_flags & - e_flags;
2643 e_flags &= ~ flag;
76da6bbe 2644
f3485b74
NC
2645 switch (flag)
2646 {
a5bcd848 2647 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2648 strcat (buf, ", sorted symbol tables");
2649 break;
76da6bbe 2650
f3485b74 2651 default:
32ec8896 2652 unknown = TRUE;
f3485b74
NC
2653 break;
2654 }
2655 }
2656 break;
76da6bbe 2657
a5bcd848
PB
2658 case EF_ARM_EABI_VER2:
2659 strcat (buf, ", Version2 EABI");
2660 while (e_flags)
2661 {
2662 unsigned flag;
2663
2664 /* Process flags one bit at a time. */
2665 flag = e_flags & - e_flags;
2666 e_flags &= ~ flag;
2667
2668 switch (flag)
2669 {
2670 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2671 strcat (buf, ", sorted symbol tables");
2672 break;
2673
2674 case EF_ARM_DYNSYMSUSESEGIDX:
2675 strcat (buf, ", dynamic symbols use segment index");
2676 break;
2677
2678 case EF_ARM_MAPSYMSFIRST:
2679 strcat (buf, ", mapping symbols precede others");
2680 break;
2681
2682 default:
32ec8896 2683 unknown = TRUE;
a5bcd848
PB
2684 break;
2685 }
2686 }
2687 break;
2688
d507cf36
PB
2689 case EF_ARM_EABI_VER3:
2690 strcat (buf, ", Version3 EABI");
8cb51566
PB
2691 break;
2692
2693 case EF_ARM_EABI_VER4:
2694 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2695 while (e_flags)
2696 {
2697 unsigned flag;
2698
2699 /* Process flags one bit at a time. */
2700 flag = e_flags & - e_flags;
2701 e_flags &= ~ flag;
2702
2703 switch (flag)
2704 {
2705 case EF_ARM_BE8:
2706 strcat (buf, ", BE8");
2707 break;
2708
2709 case EF_ARM_LE8:
2710 strcat (buf, ", LE8");
2711 break;
2712
2713 default:
32ec8896 2714 unknown = TRUE;
3bfcb652
NC
2715 break;
2716 }
3bfcb652
NC
2717 }
2718 break;
3a4a14e9
PB
2719
2720 case EF_ARM_EABI_VER5:
2721 strcat (buf, ", Version5 EABI");
d507cf36
PB
2722 while (e_flags)
2723 {
2724 unsigned flag;
2725
2726 /* Process flags one bit at a time. */
2727 flag = e_flags & - e_flags;
2728 e_flags &= ~ flag;
2729
2730 switch (flag)
2731 {
2732 case EF_ARM_BE8:
2733 strcat (buf, ", BE8");
2734 break;
2735
2736 case EF_ARM_LE8:
2737 strcat (buf, ", LE8");
2738 break;
2739
3bfcb652
NC
2740 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2741 strcat (buf, ", soft-float ABI");
2742 break;
2743
2744 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2745 strcat (buf, ", hard-float ABI");
2746 break;
2747
d507cf36 2748 default:
32ec8896 2749 unknown = TRUE;
d507cf36
PB
2750 break;
2751 }
2752 }
2753 break;
2754
f3485b74 2755 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2756 strcat (buf, ", GNU EABI");
f3485b74
NC
2757 while (e_flags)
2758 {
2759 unsigned flag;
76da6bbe 2760
f3485b74
NC
2761 /* Process flags one bit at a time. */
2762 flag = e_flags & - e_flags;
2763 e_flags &= ~ flag;
76da6bbe 2764
f3485b74
NC
2765 switch (flag)
2766 {
a5bcd848 2767 case EF_ARM_INTERWORK:
f3485b74
NC
2768 strcat (buf, ", interworking enabled");
2769 break;
76da6bbe 2770
a5bcd848 2771 case EF_ARM_APCS_26:
f3485b74
NC
2772 strcat (buf, ", uses APCS/26");
2773 break;
76da6bbe 2774
a5bcd848 2775 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2776 strcat (buf, ", uses APCS/float");
2777 break;
76da6bbe 2778
a5bcd848 2779 case EF_ARM_PIC:
f3485b74
NC
2780 strcat (buf, ", position independent");
2781 break;
76da6bbe 2782
a5bcd848 2783 case EF_ARM_ALIGN8:
f3485b74
NC
2784 strcat (buf, ", 8 bit structure alignment");
2785 break;
76da6bbe 2786
a5bcd848 2787 case EF_ARM_NEW_ABI:
f3485b74
NC
2788 strcat (buf, ", uses new ABI");
2789 break;
76da6bbe 2790
a5bcd848 2791 case EF_ARM_OLD_ABI:
f3485b74
NC
2792 strcat (buf, ", uses old ABI");
2793 break;
76da6bbe 2794
a5bcd848 2795 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2796 strcat (buf, ", software FP");
2797 break;
76da6bbe 2798
90e01f86
ILT
2799 case EF_ARM_VFP_FLOAT:
2800 strcat (buf, ", VFP");
2801 break;
2802
fde78edd
NC
2803 case EF_ARM_MAVERICK_FLOAT:
2804 strcat (buf, ", Maverick FP");
2805 break;
2806
f3485b74 2807 default:
32ec8896 2808 unknown = TRUE;
f3485b74
NC
2809 break;
2810 }
2811 }
2812 }
f3485b74
NC
2813
2814 if (unknown)
2b692964 2815 strcat (buf,_(", <unknown>"));
f3485b74
NC
2816}
2817
343433df
AB
2818static void
2819decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2820{
2821 --size; /* Leave space for null terminator. */
2822
2823 switch (e_flags & EF_AVR_MACH)
2824 {
2825 case E_AVR_MACH_AVR1:
2826 strncat (buf, ", avr:1", size);
2827 break;
2828 case E_AVR_MACH_AVR2:
2829 strncat (buf, ", avr:2", size);
2830 break;
2831 case E_AVR_MACH_AVR25:
2832 strncat (buf, ", avr:25", size);
2833 break;
2834 case E_AVR_MACH_AVR3:
2835 strncat (buf, ", avr:3", size);
2836 break;
2837 case E_AVR_MACH_AVR31:
2838 strncat (buf, ", avr:31", size);
2839 break;
2840 case E_AVR_MACH_AVR35:
2841 strncat (buf, ", avr:35", size);
2842 break;
2843 case E_AVR_MACH_AVR4:
2844 strncat (buf, ", avr:4", size);
2845 break;
2846 case E_AVR_MACH_AVR5:
2847 strncat (buf, ", avr:5", size);
2848 break;
2849 case E_AVR_MACH_AVR51:
2850 strncat (buf, ", avr:51", size);
2851 break;
2852 case E_AVR_MACH_AVR6:
2853 strncat (buf, ", avr:6", size);
2854 break;
2855 case E_AVR_MACH_AVRTINY:
2856 strncat (buf, ", avr:100", size);
2857 break;
2858 case E_AVR_MACH_XMEGA1:
2859 strncat (buf, ", avr:101", size);
2860 break;
2861 case E_AVR_MACH_XMEGA2:
2862 strncat (buf, ", avr:102", size);
2863 break;
2864 case E_AVR_MACH_XMEGA3:
2865 strncat (buf, ", avr:103", size);
2866 break;
2867 case E_AVR_MACH_XMEGA4:
2868 strncat (buf, ", avr:104", size);
2869 break;
2870 case E_AVR_MACH_XMEGA5:
2871 strncat (buf, ", avr:105", size);
2872 break;
2873 case E_AVR_MACH_XMEGA6:
2874 strncat (buf, ", avr:106", size);
2875 break;
2876 case E_AVR_MACH_XMEGA7:
2877 strncat (buf, ", avr:107", size);
2878 break;
2879 default:
2880 strncat (buf, ", avr:<unknown>", size);
2881 break;
2882 }
2883
2884 size -= strlen (buf);
2885 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2886 strncat (buf, ", link-relax", size);
2887}
2888
35c08157
KLC
2889static void
2890decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2891{
2892 unsigned abi;
2893 unsigned arch;
2894 unsigned config;
2895 unsigned version;
32ec8896
NC
2896 bfd_boolean has_fpu = FALSE;
2897 unsigned int r = 0;
35c08157
KLC
2898
2899 static const char *ABI_STRINGS[] =
2900 {
2901 "ABI v0", /* use r5 as return register; only used in N1213HC */
2902 "ABI v1", /* use r0 as return register */
2903 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2904 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2905 "AABI",
2906 "ABI2 FP+"
35c08157
KLC
2907 };
2908 static const char *VER_STRINGS[] =
2909 {
2910 "Andes ELF V1.3 or older",
2911 "Andes ELF V1.3.1",
2912 "Andes ELF V1.4"
2913 };
2914 static const char *ARCH_STRINGS[] =
2915 {
2916 "",
2917 "Andes Star v1.0",
2918 "Andes Star v2.0",
2919 "Andes Star v3.0",
2920 "Andes Star v3.0m"
2921 };
2922
2923 abi = EF_NDS_ABI & e_flags;
2924 arch = EF_NDS_ARCH & e_flags;
2925 config = EF_NDS_INST & e_flags;
2926 version = EF_NDS32_ELF_VERSION & e_flags;
2927
2928 memset (buf, 0, size);
2929
2930 switch (abi)
2931 {
2932 case E_NDS_ABI_V0:
2933 case E_NDS_ABI_V1:
2934 case E_NDS_ABI_V2:
2935 case E_NDS_ABI_V2FP:
2936 case E_NDS_ABI_AABI:
40c7a7cb 2937 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2938 /* In case there are holes in the array. */
2939 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2940 break;
2941
2942 default:
2943 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2944 break;
2945 }
2946
2947 switch (version)
2948 {
2949 case E_NDS32_ELF_VER_1_2:
2950 case E_NDS32_ELF_VER_1_3:
2951 case E_NDS32_ELF_VER_1_4:
2952 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2953 break;
2954
2955 default:
2956 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2957 break;
2958 }
2959
2960 if (E_NDS_ABI_V0 == abi)
2961 {
2962 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2963 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2964 if (arch == E_NDS_ARCH_STAR_V1_0)
2965 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2966 return;
2967 }
2968
2969 switch (arch)
2970 {
2971 case E_NDS_ARCH_STAR_V1_0:
2972 case E_NDS_ARCH_STAR_V2_0:
2973 case E_NDS_ARCH_STAR_V3_0:
2974 case E_NDS_ARCH_STAR_V3_M:
2975 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
2976 break;
2977
2978 default:
2979 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
2980 /* ARCH version determines how the e_flags are interpreted.
2981 If it is unknown, we cannot proceed. */
2982 return;
2983 }
2984
2985 /* Newer ABI; Now handle architecture specific flags. */
2986 if (arch == E_NDS_ARCH_STAR_V1_0)
2987 {
2988 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2989 r += snprintf (buf + r, size -r, ", MFUSR_PC");
2990
2991 if (!(config & E_NDS32_HAS_NO_MAC_INST))
2992 r += snprintf (buf + r, size -r, ", MAC");
2993
2994 if (config & E_NDS32_HAS_DIV_INST)
2995 r += snprintf (buf + r, size -r, ", DIV");
2996
2997 if (config & E_NDS32_HAS_16BIT_INST)
2998 r += snprintf (buf + r, size -r, ", 16b");
2999 }
3000 else
3001 {
3002 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3003 {
3004 if (version <= E_NDS32_ELF_VER_1_3)
3005 r += snprintf (buf + r, size -r, ", [B8]");
3006 else
3007 r += snprintf (buf + r, size -r, ", EX9");
3008 }
3009
3010 if (config & E_NDS32_HAS_MAC_DX_INST)
3011 r += snprintf (buf + r, size -r, ", MAC_DX");
3012
3013 if (config & E_NDS32_HAS_DIV_DX_INST)
3014 r += snprintf (buf + r, size -r, ", DIV_DX");
3015
3016 if (config & E_NDS32_HAS_16BIT_INST)
3017 {
3018 if (version <= E_NDS32_ELF_VER_1_3)
3019 r += snprintf (buf + r, size -r, ", 16b");
3020 else
3021 r += snprintf (buf + r, size -r, ", IFC");
3022 }
3023 }
3024
3025 if (config & E_NDS32_HAS_EXT_INST)
3026 r += snprintf (buf + r, size -r, ", PERF1");
3027
3028 if (config & E_NDS32_HAS_EXT2_INST)
3029 r += snprintf (buf + r, size -r, ", PERF2");
3030
3031 if (config & E_NDS32_HAS_FPU_INST)
3032 {
32ec8896 3033 has_fpu = TRUE;
35c08157
KLC
3034 r += snprintf (buf + r, size -r, ", FPU_SP");
3035 }
3036
3037 if (config & E_NDS32_HAS_FPU_DP_INST)
3038 {
32ec8896 3039 has_fpu = TRUE;
35c08157
KLC
3040 r += snprintf (buf + r, size -r, ", FPU_DP");
3041 }
3042
3043 if (config & E_NDS32_HAS_FPU_MAC_INST)
3044 {
32ec8896 3045 has_fpu = TRUE;
35c08157
KLC
3046 r += snprintf (buf + r, size -r, ", FPU_MAC");
3047 }
3048
3049 if (has_fpu)
3050 {
3051 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3052 {
3053 case E_NDS32_FPU_REG_8SP_4DP:
3054 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3055 break;
3056 case E_NDS32_FPU_REG_16SP_8DP:
3057 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3058 break;
3059 case E_NDS32_FPU_REG_32SP_16DP:
3060 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3061 break;
3062 case E_NDS32_FPU_REG_32SP_32DP:
3063 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3064 break;
3065 }
3066 }
3067
3068 if (config & E_NDS32_HAS_AUDIO_INST)
3069 r += snprintf (buf + r, size -r, ", AUDIO");
3070
3071 if (config & E_NDS32_HAS_STRING_INST)
3072 r += snprintf (buf + r, size -r, ", STR");
3073
3074 if (config & E_NDS32_HAS_REDUCED_REGS)
3075 r += snprintf (buf + r, size -r, ", 16REG");
3076
3077 if (config & E_NDS32_HAS_VIDEO_INST)
3078 {
3079 if (version <= E_NDS32_ELF_VER_1_3)
3080 r += snprintf (buf + r, size -r, ", VIDEO");
3081 else
3082 r += snprintf (buf + r, size -r, ", SATURATION");
3083 }
3084
3085 if (config & E_NDS32_HAS_ENCRIPT_INST)
3086 r += snprintf (buf + r, size -r, ", ENCRP");
3087
3088 if (config & E_NDS32_HAS_L2C_INST)
3089 r += snprintf (buf + r, size -r, ", L2C");
3090}
3091
252b5132 3092static char *
dda8d76d 3093get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3094{
b34976b6 3095 static char buf[1024];
252b5132
RH
3096
3097 buf[0] = '\0';
76da6bbe 3098
252b5132
RH
3099 if (e_flags)
3100 {
3101 switch (e_machine)
3102 {
3103 default:
3104 break;
3105
886a2506 3106 case EM_ARC_COMPACT2:
886a2506 3107 case EM_ARC_COMPACT:
a9522a21
AB
3108 decode_ARC_machine_flags (e_flags, e_machine, buf);
3109 break;
886a2506 3110
f3485b74
NC
3111 case EM_ARM:
3112 decode_ARM_machine_flags (e_flags, buf);
3113 break;
76da6bbe 3114
343433df
AB
3115 case EM_AVR:
3116 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3117 break;
3118
781303ce
MF
3119 case EM_BLACKFIN:
3120 if (e_flags & EF_BFIN_PIC)
3121 strcat (buf, ", PIC");
3122
3123 if (e_flags & EF_BFIN_FDPIC)
3124 strcat (buf, ", FDPIC");
3125
3126 if (e_flags & EF_BFIN_CODE_IN_L1)
3127 strcat (buf, ", code in L1");
3128
3129 if (e_flags & EF_BFIN_DATA_IN_L1)
3130 strcat (buf, ", data in L1");
3131
3132 break;
3133
ec2dfb42
AO
3134 case EM_CYGNUS_FRV:
3135 switch (e_flags & EF_FRV_CPU_MASK)
3136 {
3137 case EF_FRV_CPU_GENERIC:
3138 break;
3139
3140 default:
3141 strcat (buf, ", fr???");
3142 break;
57346661 3143
ec2dfb42
AO
3144 case EF_FRV_CPU_FR300:
3145 strcat (buf, ", fr300");
3146 break;
3147
3148 case EF_FRV_CPU_FR400:
3149 strcat (buf, ", fr400");
3150 break;
3151 case EF_FRV_CPU_FR405:
3152 strcat (buf, ", fr405");
3153 break;
3154
3155 case EF_FRV_CPU_FR450:
3156 strcat (buf, ", fr450");
3157 break;
3158
3159 case EF_FRV_CPU_FR500:
3160 strcat (buf, ", fr500");
3161 break;
3162 case EF_FRV_CPU_FR550:
3163 strcat (buf, ", fr550");
3164 break;
3165
3166 case EF_FRV_CPU_SIMPLE:
3167 strcat (buf, ", simple");
3168 break;
3169 case EF_FRV_CPU_TOMCAT:
3170 strcat (buf, ", tomcat");
3171 break;
3172 }
1c877e87 3173 break;
ec2dfb42 3174
53c7db4b 3175 case EM_68K:
425c6cb0 3176 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3177 strcat (buf, ", m68000");
425c6cb0 3178 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3179 strcat (buf, ", cpu32");
3180 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3181 strcat (buf, ", fido_a");
425c6cb0 3182 else
266abb8f 3183 {
2cf0635d
NC
3184 char const * isa = _("unknown");
3185 char const * mac = _("unknown mac");
3186 char const * additional = NULL;
0112cd26 3187
c694fd50 3188 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3189 {
c694fd50 3190 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3191 isa = "A";
3192 additional = ", nodiv";
3193 break;
c694fd50 3194 case EF_M68K_CF_ISA_A:
266abb8f
NS
3195 isa = "A";
3196 break;
c694fd50 3197 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3198 isa = "A+";
3199 break;
c694fd50 3200 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3201 isa = "B";
3202 additional = ", nousp";
3203 break;
c694fd50 3204 case EF_M68K_CF_ISA_B:
266abb8f
NS
3205 isa = "B";
3206 break;
f608cd77
NS
3207 case EF_M68K_CF_ISA_C:
3208 isa = "C";
3209 break;
3210 case EF_M68K_CF_ISA_C_NODIV:
3211 isa = "C";
3212 additional = ", nodiv";
3213 break;
266abb8f
NS
3214 }
3215 strcat (buf, ", cf, isa ");
3216 strcat (buf, isa);
0b2e31dc
NS
3217 if (additional)
3218 strcat (buf, additional);
c694fd50 3219 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3220 strcat (buf, ", float");
c694fd50 3221 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3222 {
3223 case 0:
3224 mac = NULL;
3225 break;
c694fd50 3226 case EF_M68K_CF_MAC:
266abb8f
NS
3227 mac = "mac";
3228 break;
c694fd50 3229 case EF_M68K_CF_EMAC:
266abb8f
NS
3230 mac = "emac";
3231 break;
f608cd77
NS
3232 case EF_M68K_CF_EMAC_B:
3233 mac = "emac_b";
3234 break;
266abb8f
NS
3235 }
3236 if (mac)
3237 {
3238 strcat (buf, ", ");
3239 strcat (buf, mac);
3240 }
266abb8f 3241 }
53c7db4b 3242 break;
33c63f9d 3243
153a2776
NC
3244 case EM_CYGNUS_MEP:
3245 switch (e_flags & EF_MEP_CPU_MASK)
3246 {
3247 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3248 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3249 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3250 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3251 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3252 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3253 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3254 }
3255
3256 switch (e_flags & EF_MEP_COP_MASK)
3257 {
3258 case EF_MEP_COP_NONE: break;
3259 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3260 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3261 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3262 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3263 default: strcat (buf, _("<unknown MeP copro type>")); break;
3264 }
3265
3266 if (e_flags & EF_MEP_LIBRARY)
3267 strcat (buf, ", Built for Library");
3268
3269 if (e_flags & EF_MEP_INDEX_MASK)
3270 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3271 e_flags & EF_MEP_INDEX_MASK);
3272
3273 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3274 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3275 e_flags & ~ EF_MEP_ALL_FLAGS);
3276 break;
3277
252b5132
RH
3278 case EM_PPC:
3279 if (e_flags & EF_PPC_EMB)
3280 strcat (buf, ", emb");
3281
3282 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3283 strcat (buf, _(", relocatable"));
252b5132
RH
3284
3285 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3286 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3287 break;
3288
ee67d69a
AM
3289 case EM_PPC64:
3290 if (e_flags & EF_PPC64_ABI)
3291 {
3292 char abi[] = ", abiv0";
3293
3294 abi[6] += e_flags & EF_PPC64_ABI;
3295 strcat (buf, abi);
3296 }
3297 break;
3298
708e2187
NC
3299 case EM_V800:
3300 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3301 strcat (buf, ", RH850 ABI");
0b4362b0 3302
708e2187
NC
3303 if (e_flags & EF_V800_850E3)
3304 strcat (buf, ", V3 architecture");
3305
3306 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3307 strcat (buf, ", FPU not used");
3308
3309 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3310 strcat (buf, ", regmode: COMMON");
3311
3312 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3313 strcat (buf, ", r4 not used");
3314
3315 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3316 strcat (buf, ", r30 not used");
3317
3318 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3319 strcat (buf, ", r5 not used");
3320
3321 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3322 strcat (buf, ", r2 not used");
3323
3324 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3325 {
3326 switch (e_flags & - e_flags)
3327 {
3328 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3329 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3330 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3331 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3332 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3333 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3334 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3335 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3336 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3337 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3338 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3339 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3340 default: break;
3341 }
3342 }
3343 break;
3344
2b0337b0 3345 case EM_V850:
252b5132
RH
3346 case EM_CYGNUS_V850:
3347 switch (e_flags & EF_V850_ARCH)
3348 {
78c8d46c
NC
3349 case E_V850E3V5_ARCH:
3350 strcat (buf, ", v850e3v5");
3351 break;
1cd986c5
NC
3352 case E_V850E2V3_ARCH:
3353 strcat (buf, ", v850e2v3");
3354 break;
3355 case E_V850E2_ARCH:
3356 strcat (buf, ", v850e2");
3357 break;
3358 case E_V850E1_ARCH:
3359 strcat (buf, ", v850e1");
8ad30312 3360 break;
252b5132
RH
3361 case E_V850E_ARCH:
3362 strcat (buf, ", v850e");
3363 break;
252b5132
RH
3364 case E_V850_ARCH:
3365 strcat (buf, ", v850");
3366 break;
3367 default:
2b692964 3368 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3369 break;
3370 }
3371 break;
3372
2b0337b0 3373 case EM_M32R:
252b5132
RH
3374 case EM_CYGNUS_M32R:
3375 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3376 strcat (buf, ", m32r");
252b5132
RH
3377 break;
3378
3379 case EM_MIPS:
4fe85591 3380 case EM_MIPS_RS3_LE:
252b5132
RH
3381 if (e_flags & EF_MIPS_NOREORDER)
3382 strcat (buf, ", noreorder");
3383
3384 if (e_flags & EF_MIPS_PIC)
3385 strcat (buf, ", pic");
3386
3387 if (e_flags & EF_MIPS_CPIC)
3388 strcat (buf, ", cpic");
3389
d1bdd336
TS
3390 if (e_flags & EF_MIPS_UCODE)
3391 strcat (buf, ", ugen_reserved");
3392
252b5132
RH
3393 if (e_flags & EF_MIPS_ABI2)
3394 strcat (buf, ", abi2");
3395
43521d43
TS
3396 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3397 strcat (buf, ", odk first");
3398
a5d22d2a
TS
3399 if (e_flags & EF_MIPS_32BITMODE)
3400 strcat (buf, ", 32bitmode");
3401
ba92f887
MR
3402 if (e_flags & EF_MIPS_NAN2008)
3403 strcat (buf, ", nan2008");
3404
fef1b0b3
SE
3405 if (e_flags & EF_MIPS_FP64)
3406 strcat (buf, ", fp64");
3407
156c2f8b
NC
3408 switch ((e_flags & EF_MIPS_MACH))
3409 {
3410 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3411 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3412 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3413 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3414 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3415 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3416 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3417 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3418 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3419 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3420 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3421 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3422 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3423 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3424 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3425 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3426 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3427 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3428 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3429 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3430 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3431 case 0:
3432 /* We simply ignore the field in this case to avoid confusion:
3433 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3434 extension. */
3435 break;
2b692964 3436 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3437 }
43521d43
TS
3438
3439 switch ((e_flags & EF_MIPS_ABI))
3440 {
3441 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3442 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3443 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3444 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3445 case 0:
3446 /* We simply ignore the field in this case to avoid confusion:
3447 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3448 This means it is likely to be an o32 file, but not for
3449 sure. */
3450 break;
2b692964 3451 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3452 }
3453
3454 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3455 strcat (buf, ", mdmx");
3456
3457 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3458 strcat (buf, ", mips16");
3459
df58fc94
RS
3460 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3461 strcat (buf, ", micromips");
3462
43521d43
TS
3463 switch ((e_flags & EF_MIPS_ARCH))
3464 {
3465 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3466 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3467 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3468 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3469 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3470 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3471 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3472 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3473 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3474 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3475 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3476 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3477 }
252b5132 3478 break;
351b4b40 3479
35c08157
KLC
3480 case EM_NDS32:
3481 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3482 break;
3483
fe944acf
FT
3484 case EM_NFP:
3485 switch (EF_NFP_MACH (e_flags))
3486 {
3487 case E_NFP_MACH_3200:
3488 strcat (buf, ", NFP-32xx");
3489 break;
3490 case E_NFP_MACH_6000:
3491 strcat (buf, ", NFP-6xxx");
3492 break;
3493 }
3494 break;
3495
e23eba97
NC
3496 case EM_RISCV:
3497 if (e_flags & EF_RISCV_RVC)
3498 strcat (buf, ", RVC");
2922d21d 3499
7f999549
JW
3500 if (e_flags & EF_RISCV_RVE)
3501 strcat (buf, ", RVE");
3502
2922d21d
AW
3503 switch (e_flags & EF_RISCV_FLOAT_ABI)
3504 {
3505 case EF_RISCV_FLOAT_ABI_SOFT:
3506 strcat (buf, ", soft-float ABI");
3507 break;
3508
3509 case EF_RISCV_FLOAT_ABI_SINGLE:
3510 strcat (buf, ", single-float ABI");
3511 break;
3512
3513 case EF_RISCV_FLOAT_ABI_DOUBLE:
3514 strcat (buf, ", double-float ABI");
3515 break;
3516
3517 case EF_RISCV_FLOAT_ABI_QUAD:
3518 strcat (buf, ", quad-float ABI");
3519 break;
3520 }
e23eba97
NC
3521 break;
3522
ccde1100
AO
3523 case EM_SH:
3524 switch ((e_flags & EF_SH_MACH_MASK))
3525 {
3526 case EF_SH1: strcat (buf, ", sh1"); break;
3527 case EF_SH2: strcat (buf, ", sh2"); break;
3528 case EF_SH3: strcat (buf, ", sh3"); break;
3529 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3530 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3531 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3532 case EF_SH3E: strcat (buf, ", sh3e"); break;
3533 case EF_SH4: strcat (buf, ", sh4"); break;
3534 case EF_SH5: strcat (buf, ", sh5"); break;
3535 case EF_SH2E: strcat (buf, ", sh2e"); break;
3536 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3537 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3538 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3539 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3540 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3541 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3542 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3543 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3544 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3545 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3546 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3547 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3548 }
3549
cec6a5b8
MR
3550 if (e_flags & EF_SH_PIC)
3551 strcat (buf, ", pic");
3552
3553 if (e_flags & EF_SH_FDPIC)
3554 strcat (buf, ", fdpic");
ccde1100 3555 break;
948f632f 3556
73589c9d
CS
3557 case EM_OR1K:
3558 if (e_flags & EF_OR1K_NODELAY)
3559 strcat (buf, ", no delay");
3560 break;
57346661 3561
351b4b40
RH
3562 case EM_SPARCV9:
3563 if (e_flags & EF_SPARC_32PLUS)
3564 strcat (buf, ", v8+");
3565
3566 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3567 strcat (buf, ", ultrasparcI");
3568
3569 if (e_flags & EF_SPARC_SUN_US3)
3570 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3571
3572 if (e_flags & EF_SPARC_HAL_R1)
3573 strcat (buf, ", halr1");
3574
3575 if (e_flags & EF_SPARC_LEDATA)
3576 strcat (buf, ", ledata");
3577
3578 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3579 strcat (buf, ", tso");
3580
3581 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3582 strcat (buf, ", pso");
3583
3584 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3585 strcat (buf, ", rmo");
3586 break;
7d466069 3587
103f02d3
UD
3588 case EM_PARISC:
3589 switch (e_flags & EF_PARISC_ARCH)
3590 {
3591 case EFA_PARISC_1_0:
3592 strcpy (buf, ", PA-RISC 1.0");
3593 break;
3594 case EFA_PARISC_1_1:
3595 strcpy (buf, ", PA-RISC 1.1");
3596 break;
3597 case EFA_PARISC_2_0:
3598 strcpy (buf, ", PA-RISC 2.0");
3599 break;
3600 default:
3601 break;
3602 }
3603 if (e_flags & EF_PARISC_TRAPNIL)
3604 strcat (buf, ", trapnil");
3605 if (e_flags & EF_PARISC_EXT)
3606 strcat (buf, ", ext");
3607 if (e_flags & EF_PARISC_LSB)
3608 strcat (buf, ", lsb");
3609 if (e_flags & EF_PARISC_WIDE)
3610 strcat (buf, ", wide");
3611 if (e_flags & EF_PARISC_NO_KABP)
3612 strcat (buf, ", no kabp");
3613 if (e_flags & EF_PARISC_LAZYSWAP)
3614 strcat (buf, ", lazyswap");
30800947 3615 break;
76da6bbe 3616
7d466069 3617 case EM_PJ:
2b0337b0 3618 case EM_PJ_OLD:
7d466069
ILT
3619 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3620 strcat (buf, ", new calling convention");
3621
3622 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3623 strcat (buf, ", gnu calling convention");
3624 break;
4d6ed7c8
NC
3625
3626 case EM_IA_64:
3627 if ((e_flags & EF_IA_64_ABI64))
3628 strcat (buf, ", 64-bit");
3629 else
3630 strcat (buf, ", 32-bit");
3631 if ((e_flags & EF_IA_64_REDUCEDFP))
3632 strcat (buf, ", reduced fp model");
3633 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3634 strcat (buf, ", no function descriptors, constant gp");
3635 else if ((e_flags & EF_IA_64_CONS_GP))
3636 strcat (buf, ", constant gp");
3637 if ((e_flags & EF_IA_64_ABSOLUTE))
3638 strcat (buf, ", absolute");
dda8d76d 3639 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3640 {
3641 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3642 strcat (buf, ", vms_linkages");
3643 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3644 {
3645 case EF_IA_64_VMS_COMCOD_SUCCESS:
3646 break;
3647 case EF_IA_64_VMS_COMCOD_WARNING:
3648 strcat (buf, ", warning");
3649 break;
3650 case EF_IA_64_VMS_COMCOD_ERROR:
3651 strcat (buf, ", error");
3652 break;
3653 case EF_IA_64_VMS_COMCOD_ABORT:
3654 strcat (buf, ", abort");
3655 break;
3656 default:
bee0ee85
NC
3657 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3658 e_flags & EF_IA_64_VMS_COMCOD);
3659 strcat (buf, ", <unknown>");
28f997cf
TG
3660 }
3661 }
4d6ed7c8 3662 break;
179d3252
JT
3663
3664 case EM_VAX:
3665 if ((e_flags & EF_VAX_NONPIC))
3666 strcat (buf, ", non-PIC");
3667 if ((e_flags & EF_VAX_DFLOAT))
3668 strcat (buf, ", D-Float");
3669 if ((e_flags & EF_VAX_GFLOAT))
3670 strcat (buf, ", G-Float");
3671 break;
c7927a3c 3672
619ed720
EB
3673 case EM_VISIUM:
3674 if (e_flags & EF_VISIUM_ARCH_MCM)
3675 strcat (buf, ", mcm");
3676 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3677 strcat (buf, ", mcm24");
3678 if (e_flags & EF_VISIUM_ARCH_GR6)
3679 strcat (buf, ", gr6");
3680 break;
3681
4046d87a 3682 case EM_RL78:
1740ba0c
NC
3683 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3684 {
3685 case E_FLAG_RL78_ANY_CPU: break;
3686 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3687 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3688 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3689 }
856ea05c
KP
3690 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3691 strcat (buf, ", 64-bit doubles");
4046d87a 3692 break;
0b4362b0 3693
c7927a3c
NC
3694 case EM_RX:
3695 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3696 strcat (buf, ", 64-bit doubles");
3697 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3698 strcat (buf, ", dsp");
d4cb0ea0 3699 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3700 strcat (buf, ", pid");
708e2187
NC
3701 if (e_flags & E_FLAG_RX_ABI)
3702 strcat (buf, ", RX ABI");
3525236c
NC
3703 if (e_flags & E_FLAG_RX_SINSNS_SET)
3704 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3705 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3706 if (e_flags & E_FLAG_RX_V2)
3707 strcat (buf, ", V2");
f87673e0
YS
3708 if (e_flags & E_FLAG_RX_V3)
3709 strcat (buf, ", V3");
d4cb0ea0 3710 break;
55786da2
AK
3711
3712 case EM_S390:
3713 if (e_flags & EF_S390_HIGH_GPRS)
3714 strcat (buf, ", highgprs");
d4cb0ea0 3715 break;
40b36596
JM
3716
3717 case EM_TI_C6000:
3718 if ((e_flags & EF_C6000_REL))
3719 strcat (buf, ", relocatable module");
d4cb0ea0 3720 break;
13761a11
NC
3721
3722 case EM_MSP430:
3723 strcat (buf, _(": architecture variant: "));
3724 switch (e_flags & EF_MSP430_MACH)
3725 {
3726 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3727 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3728 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3729 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3730 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3731 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3732 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3733 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3734 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3735 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3736 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3737 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3738 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3739 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3740 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3741 default:
3742 strcat (buf, _(": unknown")); break;
3743 }
3744
3745 if (e_flags & ~ EF_MSP430_MACH)
3746 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3747 }
3748 }
3749
3750 return buf;
3751}
3752
252b5132 3753static const char *
dda8d76d 3754get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3755{
3756 static char buff[32];
3757
3758 switch (osabi)
3759 {
3760 case ELFOSABI_NONE: return "UNIX - System V";
3761 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3762 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3763 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3764 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3765 case ELFOSABI_AIX: return "UNIX - AIX";
3766 case ELFOSABI_IRIX: return "UNIX - IRIX";
3767 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3768 case ELFOSABI_TRU64: return "UNIX - TRU64";
3769 case ELFOSABI_MODESTO: return "Novell - Modesto";
3770 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3771 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3772 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3773 case ELFOSABI_AROS: return "AROS";
11636f9e 3774 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3775 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3776 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3777 default:
40b36596 3778 if (osabi >= 64)
dda8d76d 3779 switch (filedata->file_header.e_machine)
40b36596
JM
3780 {
3781 case EM_ARM:
3782 switch (osabi)
3783 {
3784 case ELFOSABI_ARM: return "ARM";
18a20338 3785 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3786 default:
3787 break;
3788 }
3789 break;
3790
3791 case EM_MSP430:
3792 case EM_MSP430_OLD:
619ed720 3793 case EM_VISIUM:
40b36596
JM
3794 switch (osabi)
3795 {
3796 case ELFOSABI_STANDALONE: return _("Standalone App");
3797 default:
3798 break;
3799 }
3800 break;
3801
3802 case EM_TI_C6000:
3803 switch (osabi)
3804 {
3805 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3806 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3807 default:
3808 break;
3809 }
3810 break;
3811
3812 default:
3813 break;
3814 }
e9e44622 3815 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3816 return buff;
3817 }
3818}
3819
a06ea964
NC
3820static const char *
3821get_aarch64_segment_type (unsigned long type)
3822{
3823 switch (type)
3824 {
32ec8896
NC
3825 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3826 default: return NULL;
a06ea964 3827 }
a06ea964
NC
3828}
3829
b294bdf8
MM
3830static const char *
3831get_arm_segment_type (unsigned long type)
3832{
3833 switch (type)
3834 {
32ec8896
NC
3835 case PT_ARM_EXIDX: return "EXIDX";
3836 default: return NULL;
b294bdf8 3837 }
b294bdf8
MM
3838}
3839
b4cbbe8f
AK
3840static const char *
3841get_s390_segment_type (unsigned long type)
3842{
3843 switch (type)
3844 {
3845 case PT_S390_PGSTE: return "S390_PGSTE";
3846 default: return NULL;
3847 }
3848}
3849
d3ba0551
AM
3850static const char *
3851get_mips_segment_type (unsigned long type)
252b5132
RH
3852{
3853 switch (type)
3854 {
32ec8896
NC
3855 case PT_MIPS_REGINFO: return "REGINFO";
3856 case PT_MIPS_RTPROC: return "RTPROC";
3857 case PT_MIPS_OPTIONS: return "OPTIONS";
3858 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3859 default: return NULL;
252b5132 3860 }
252b5132
RH
3861}
3862
103f02d3 3863static const char *
d3ba0551 3864get_parisc_segment_type (unsigned long type)
103f02d3
UD
3865{
3866 switch (type)
3867 {
3868 case PT_HP_TLS: return "HP_TLS";
3869 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3870 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3871 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3872 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3873 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3874 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3875 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3876 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3877 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3878 case PT_HP_PARALLEL: return "HP_PARALLEL";
3879 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3880 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3881 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3882 case PT_HP_STACK: return "HP_STACK";
3883 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3884 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3885 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3886 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3887 default: return NULL;
103f02d3 3888 }
103f02d3
UD
3889}
3890
4d6ed7c8 3891static const char *
d3ba0551 3892get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3893{
3894 switch (type)
3895 {
3896 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3897 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3898 case PT_HP_TLS: return "HP_TLS";
3899 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3900 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3901 case PT_IA_64_HP_STACK: return "HP_STACK";
32ec8896 3902 default: return NULL;
4d6ed7c8 3903 }
4d6ed7c8
NC
3904}
3905
40b36596
JM
3906static const char *
3907get_tic6x_segment_type (unsigned long type)
3908{
3909 switch (type)
3910 {
32ec8896
NC
3911 case PT_C6000_PHATTR: return "C6000_PHATTR";
3912 default: return NULL;
40b36596 3913 }
40b36596
JM
3914}
3915
5522f910
NC
3916static const char *
3917get_solaris_segment_type (unsigned long type)
3918{
3919 switch (type)
3920 {
3921 case 0x6464e550: return "PT_SUNW_UNWIND";
3922 case 0x6474e550: return "PT_SUNW_EH_FRAME";
3923 case 0x6ffffff7: return "PT_LOSUNW";
3924 case 0x6ffffffa: return "PT_SUNWBSS";
3925 case 0x6ffffffb: return "PT_SUNWSTACK";
3926 case 0x6ffffffc: return "PT_SUNWDTRACE";
3927 case 0x6ffffffd: return "PT_SUNWCAP";
3928 case 0x6fffffff: return "PT_HISUNW";
32ec8896 3929 default: return NULL;
5522f910
NC
3930 }
3931}
3932
252b5132 3933static const char *
dda8d76d 3934get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 3935{
b34976b6 3936 static char buff[32];
252b5132
RH
3937
3938 switch (p_type)
3939 {
b34976b6
AM
3940 case PT_NULL: return "NULL";
3941 case PT_LOAD: return "LOAD";
252b5132 3942 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3943 case PT_INTERP: return "INTERP";
3944 case PT_NOTE: return "NOTE";
3945 case PT_SHLIB: return "SHLIB";
3946 case PT_PHDR: return "PHDR";
13ae64f3 3947 case PT_TLS: return "TLS";
32ec8896 3948 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 3949 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3950 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 3951 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 3952
252b5132 3953 default:
a91e1603
L
3954 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
3955 {
3956 sprintf (buff, "GNU_MBIND+%#lx",
3957 p_type - PT_GNU_MBIND_LO);
3958 }
3959 else if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 3960 {
2cf0635d 3961 const char * result;
103f02d3 3962
dda8d76d 3963 switch (filedata->file_header.e_machine)
252b5132 3964 {
a06ea964
NC
3965 case EM_AARCH64:
3966 result = get_aarch64_segment_type (p_type);
3967 break;
b294bdf8
MM
3968 case EM_ARM:
3969 result = get_arm_segment_type (p_type);
3970 break;
252b5132 3971 case EM_MIPS:
4fe85591 3972 case EM_MIPS_RS3_LE:
252b5132
RH
3973 result = get_mips_segment_type (p_type);
3974 break;
103f02d3
UD
3975 case EM_PARISC:
3976 result = get_parisc_segment_type (p_type);
3977 break;
4d6ed7c8
NC
3978 case EM_IA_64:
3979 result = get_ia64_segment_type (p_type);
3980 break;
40b36596
JM
3981 case EM_TI_C6000:
3982 result = get_tic6x_segment_type (p_type);
3983 break;
b4cbbe8f
AK
3984 case EM_S390:
3985 case EM_S390_OLD:
3986 result = get_s390_segment_type (p_type);
3987 break;
252b5132
RH
3988 default:
3989 result = NULL;
3990 break;
3991 }
103f02d3 3992
252b5132
RH
3993 if (result != NULL)
3994 return result;
103f02d3 3995
1a9ccd70 3996 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
3997 }
3998 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3999 {
2cf0635d 4000 const char * result;
103f02d3 4001
dda8d76d 4002 switch (filedata->file_header.e_machine)
103f02d3
UD
4003 {
4004 case EM_PARISC:
4005 result = get_parisc_segment_type (p_type);
4006 break;
00428cca
AM
4007 case EM_IA_64:
4008 result = get_ia64_segment_type (p_type);
4009 break;
103f02d3 4010 default:
dda8d76d 4011 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
5522f910
NC
4012 result = get_solaris_segment_type (p_type);
4013 else
4014 result = NULL;
103f02d3
UD
4015 break;
4016 }
4017
4018 if (result != NULL)
4019 return result;
4020
1a9ccd70 4021 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4022 }
252b5132 4023 else
e9e44622 4024 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4025
4026 return buff;
4027 }
4028}
4029
53a346d8
CZ
4030static const char *
4031get_arc_section_type_name (unsigned int sh_type)
4032{
4033 switch (sh_type)
4034 {
4035 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4036 default:
4037 break;
4038 }
4039 return NULL;
4040}
4041
252b5132 4042static const char *
d3ba0551 4043get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4044{
4045 switch (sh_type)
4046 {
b34976b6
AM
4047 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4048 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4049 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4050 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4051 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4052 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4053 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4054 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4055 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4056 case SHT_MIPS_RELD: return "MIPS_RELD";
4057 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4058 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4059 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4060 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4061 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4062 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4063 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4064 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4065 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4066 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4067 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4068 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4069 case SHT_MIPS_LINE: return "MIPS_LINE";
4070 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4071 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4072 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4073 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4074 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4075 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4076 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4077 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4078 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4079 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4080 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4081 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4082 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4083 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4084 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4085 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4086 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
252b5132
RH
4087 default:
4088 break;
4089 }
4090 return NULL;
4091}
4092
103f02d3 4093static const char *
d3ba0551 4094get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4095{
4096 switch (sh_type)
4097 {
4098 case SHT_PARISC_EXT: return "PARISC_EXT";
4099 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4100 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4101 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4102 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4103 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4104 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4105 default: return NULL;
103f02d3 4106 }
103f02d3
UD
4107}
4108
4d6ed7c8 4109static const char *
dda8d76d 4110get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4111{
18bd398b 4112 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4113 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4114 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4115
4d6ed7c8
NC
4116 switch (sh_type)
4117 {
148b93f2
NC
4118 case SHT_IA_64_EXT: return "IA_64_EXT";
4119 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4120 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4121 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4122 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4123 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4124 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4125 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4126 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4127 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4128 default:
4129 break;
4130 }
4131 return NULL;
4132}
4133
d2b2c203
DJ
4134static const char *
4135get_x86_64_section_type_name (unsigned int sh_type)
4136{
4137 switch (sh_type)
4138 {
4139 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4140 default: return NULL;
d2b2c203 4141 }
d2b2c203
DJ
4142}
4143
a06ea964
NC
4144static const char *
4145get_aarch64_section_type_name (unsigned int sh_type)
4146{
4147 switch (sh_type)
4148 {
32ec8896
NC
4149 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4150 default: return NULL;
a06ea964 4151 }
a06ea964
NC
4152}
4153
40a18ebd
NC
4154static const char *
4155get_arm_section_type_name (unsigned int sh_type)
4156{
4157 switch (sh_type)
4158 {
7f6fed87
NC
4159 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4160 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4161 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4162 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4163 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4164 default: return NULL;
40a18ebd 4165 }
40a18ebd
NC
4166}
4167
40b36596
JM
4168static const char *
4169get_tic6x_section_type_name (unsigned int sh_type)
4170{
4171 switch (sh_type)
4172 {
32ec8896
NC
4173 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4174 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4175 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4176 case SHT_TI_ICODE: return "TI_ICODE";
4177 case SHT_TI_XREF: return "TI_XREF";
4178 case SHT_TI_HANDLER: return "TI_HANDLER";
4179 case SHT_TI_INITINFO: return "TI_INITINFO";
4180 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4181 default: return NULL;
40b36596 4182 }
40b36596
JM
4183}
4184
13761a11
NC
4185static const char *
4186get_msp430x_section_type_name (unsigned int sh_type)
4187{
4188 switch (sh_type)
4189 {
32ec8896
NC
4190 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4191 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4192 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4193 default: return NULL;
13761a11
NC
4194 }
4195}
4196
fe944acf
FT
4197static const char *
4198get_nfp_section_type_name (unsigned int sh_type)
4199{
4200 switch (sh_type)
4201 {
4202 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4203 case SHT_NFP_INITREG: return "NFP_INITREG";
4204 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4205 default: return NULL;
4206 }
4207}
4208
685080f2
NC
4209static const char *
4210get_v850_section_type_name (unsigned int sh_type)
4211{
4212 switch (sh_type)
4213 {
32ec8896
NC
4214 case SHT_V850_SCOMMON: return "V850 Small Common";
4215 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4216 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4217 case SHT_RENESAS_IOP: return "RENESAS IOP";
4218 case SHT_RENESAS_INFO: return "RENESAS INFO";
4219 default: return NULL;
685080f2
NC
4220 }
4221}
4222
2dc8dd17
JW
4223static const char *
4224get_riscv_section_type_name (unsigned int sh_type)
4225{
4226 switch (sh_type)
4227 {
4228 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4229 default: return NULL;
4230 }
4231}
4232
252b5132 4233static const char *
dda8d76d 4234get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4235{
b34976b6 4236 static char buff[32];
9fb71ee4 4237 const char * result;
252b5132
RH
4238
4239 switch (sh_type)
4240 {
4241 case SHT_NULL: return "NULL";
4242 case SHT_PROGBITS: return "PROGBITS";
4243 case SHT_SYMTAB: return "SYMTAB";
4244 case SHT_STRTAB: return "STRTAB";
4245 case SHT_RELA: return "RELA";
4246 case SHT_HASH: return "HASH";
4247 case SHT_DYNAMIC: return "DYNAMIC";
4248 case SHT_NOTE: return "NOTE";
4249 case SHT_NOBITS: return "NOBITS";
4250 case SHT_REL: return "REL";
4251 case SHT_SHLIB: return "SHLIB";
4252 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4253 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4254 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4255 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4256 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4257 case SHT_GROUP: return "GROUP";
67ce483b 4258 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4259 case SHT_GNU_verdef: return "VERDEF";
4260 case SHT_GNU_verneed: return "VERNEED";
4261 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4262 case 0x6ffffff0: return "VERSYM";
4263 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4264 case 0x7ffffffd: return "AUXILIARY";
4265 case 0x7fffffff: return "FILTER";
047b2264 4266 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4267
4268 default:
4269 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4270 {
dda8d76d 4271 switch (filedata->file_header.e_machine)
252b5132 4272 {
53a346d8
CZ
4273 case EM_ARC:
4274 case EM_ARC_COMPACT:
4275 case EM_ARC_COMPACT2:
4276 result = get_arc_section_type_name (sh_type);
4277 break;
252b5132 4278 case EM_MIPS:
4fe85591 4279 case EM_MIPS_RS3_LE:
252b5132
RH
4280 result = get_mips_section_type_name (sh_type);
4281 break;
103f02d3
UD
4282 case EM_PARISC:
4283 result = get_parisc_section_type_name (sh_type);
4284 break;
4d6ed7c8 4285 case EM_IA_64:
dda8d76d 4286 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4287 break;
d2b2c203 4288 case EM_X86_64:
8a9036a4 4289 case EM_L1OM:
7a9068fe 4290 case EM_K1OM:
d2b2c203
DJ
4291 result = get_x86_64_section_type_name (sh_type);
4292 break;
a06ea964
NC
4293 case EM_AARCH64:
4294 result = get_aarch64_section_type_name (sh_type);
4295 break;
40a18ebd
NC
4296 case EM_ARM:
4297 result = get_arm_section_type_name (sh_type);
4298 break;
40b36596
JM
4299 case EM_TI_C6000:
4300 result = get_tic6x_section_type_name (sh_type);
4301 break;
13761a11
NC
4302 case EM_MSP430:
4303 result = get_msp430x_section_type_name (sh_type);
4304 break;
fe944acf
FT
4305 case EM_NFP:
4306 result = get_nfp_section_type_name (sh_type);
4307 break;
685080f2
NC
4308 case EM_V800:
4309 case EM_V850:
4310 case EM_CYGNUS_V850:
4311 result = get_v850_section_type_name (sh_type);
4312 break;
2dc8dd17
JW
4313 case EM_RISCV:
4314 result = get_riscv_section_type_name (sh_type);
4315 break;
252b5132
RH
4316 default:
4317 result = NULL;
4318 break;
4319 }
4320
4321 if (result != NULL)
4322 return result;
4323
9fb71ee4 4324 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4325 }
4326 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4327 {
dda8d76d 4328 switch (filedata->file_header.e_machine)
148b93f2
NC
4329 {
4330 case EM_IA_64:
dda8d76d 4331 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4332 break;
4333 default:
dda8d76d 4334 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4335 result = get_solaris_section_type (sh_type);
4336 else
1b4b80bf
NC
4337 {
4338 switch (sh_type)
4339 {
4340 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4341 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4342 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4343 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4344 default:
4345 result = NULL;
4346 break;
4347 }
4348 }
148b93f2
NC
4349 break;
4350 }
4351
4352 if (result != NULL)
4353 return result;
4354
9fb71ee4 4355 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4356 }
252b5132 4357 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4358 {
dda8d76d 4359 switch (filedata->file_header.e_machine)
685080f2
NC
4360 {
4361 case EM_V800:
4362 case EM_V850:
4363 case EM_CYGNUS_V850:
9fb71ee4 4364 result = get_v850_section_type_name (sh_type);
a9fb83be 4365 break;
685080f2 4366 default:
9fb71ee4 4367 result = NULL;
685080f2
NC
4368 break;
4369 }
4370
9fb71ee4
NC
4371 if (result != NULL)
4372 return result;
4373
4374 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4375 }
252b5132 4376 else
a7dbfd1c
NC
4377 /* This message is probably going to be displayed in a 15
4378 character wide field, so put the hex value first. */
4379 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4380
252b5132
RH
4381 return buff;
4382 }
4383}
4384
2979dc34 4385#define OPTION_DEBUG_DUMP 512
2c610e4b 4386#define OPTION_DYN_SYMS 513
fd2f0033
TT
4387#define OPTION_DWARF_DEPTH 514
4388#define OPTION_DWARF_START 515
4723351a 4389#define OPTION_DWARF_CHECK 516
2979dc34 4390
85b1c36d 4391static struct option options[] =
252b5132 4392{
b34976b6 4393 {"all", no_argument, 0, 'a'},
252b5132
RH
4394 {"file-header", no_argument, 0, 'h'},
4395 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
4396 {"headers", no_argument, 0, 'e'},
4397 {"histogram", no_argument, 0, 'I'},
4398 {"segments", no_argument, 0, 'l'},
4399 {"sections", no_argument, 0, 'S'},
252b5132 4400 {"section-headers", no_argument, 0, 'S'},
f5842774 4401 {"section-groups", no_argument, 0, 'g'},
5477e8a0 4402 {"section-details", no_argument, 0, 't'},
595cf52e 4403 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
4404 {"symbols", no_argument, 0, 's'},
4405 {"syms", no_argument, 0, 's'},
2c610e4b 4406 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
4407 {"relocs", no_argument, 0, 'r'},
4408 {"notes", no_argument, 0, 'n'},
4409 {"dynamic", no_argument, 0, 'd'},
a952a375 4410 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
4411 {"version-info", no_argument, 0, 'V'},
4412 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 4413 {"unwind", no_argument, 0, 'u'},
4145f1d5 4414 {"archive-index", no_argument, 0, 'c'},
b34976b6 4415 {"hex-dump", required_argument, 0, 'x'},
cf13d699 4416 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 4417 {"string-dump", required_argument, 0, 'p'},
0e602686 4418 {"decompress", no_argument, 0, 'z'},
252b5132
RH
4419#ifdef SUPPORT_DISASSEMBLY
4420 {"instruction-dump", required_argument, 0, 'i'},
4421#endif
cf13d699 4422 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 4423
fd2f0033
TT
4424 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4425 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4426 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 4427
b34976b6
AM
4428 {"version", no_argument, 0, 'v'},
4429 {"wide", no_argument, 0, 'W'},
4430 {"help", no_argument, 0, 'H'},
4431 {0, no_argument, 0, 0}
252b5132
RH
4432};
4433
4434static void
2cf0635d 4435usage (FILE * stream)
252b5132 4436{
92f01d61
JM
4437 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4438 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4439 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4440 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4441 -h --file-header Display the ELF file header\n\
4442 -l --program-headers Display the program headers\n\
4443 --segments An alias for --program-headers\n\
4444 -S --section-headers Display the sections' header\n\
4445 --sections An alias for --section-headers\n\
f5842774 4446 -g --section-groups Display the section groups\n\
5477e8a0 4447 -t --section-details Display the section details\n\
8b53311e
NC
4448 -e --headers Equivalent to: -h -l -S\n\
4449 -s --syms Display the symbol table\n\
3f08eb35 4450 --symbols An alias for --syms\n\
2c610e4b 4451 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
4452 -n --notes Display the core notes (if present)\n\
4453 -r --relocs Display the relocations (if present)\n\
4454 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4455 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4456 -V --version-info Display the version sections (if present)\n\
1b31d05e 4457 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4458 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4459 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
4460 -x --hex-dump=<number|name>\n\
4461 Dump the contents of section <number|name> as bytes\n\
4462 -p --string-dump=<number|name>\n\
4463 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4464 -R --relocated-dump=<number|name>\n\
4465 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4466 -z --decompress Decompress section before dumping it\n\
dda8d76d 4467 -w[lLiaprmfFsoRtUuTgAckK] or\n\
1ed06042 4468 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 4469 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47 4470 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
dda8d76d
NC
4471 =addr,=cu_index,=links,=follow-links]\n\
4472 Display the contents of DWARF debug sections\n"));
fd2f0033
TT
4473 fprintf (stream, _("\
4474 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4475 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4476 or deeper\n"));
252b5132 4477#ifdef SUPPORT_DISASSEMBLY
92f01d61 4478 fprintf (stream, _("\
09c11c86
NC
4479 -i --instruction-dump=<number|name>\n\
4480 Disassemble the contents of section <number|name>\n"));
252b5132 4481#endif
92f01d61 4482 fprintf (stream, _("\
8b53311e
NC
4483 -I --histogram Display histogram of bucket list lengths\n\
4484 -W --wide Allow output width to exceed 80 characters\n\
07012eee 4485 @<file> Read options from <file>\n\
8b53311e
NC
4486 -H --help Display this information\n\
4487 -v --version Display the version number of readelf\n"));
1118d252 4488
92f01d61
JM
4489 if (REPORT_BUGS_TO[0] && stream == stdout)
4490 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4491
92f01d61 4492 exit (stream == stdout ? 0 : 1);
252b5132
RH
4493}
4494
18bd398b
NC
4495/* Record the fact that the user wants the contents of section number
4496 SECTION to be displayed using the method(s) encoded as flags bits
4497 in TYPE. Note, TYPE can be zero if we are creating the array for
4498 the first time. */
4499
252b5132 4500static void
dda8d76d 4501request_dump_bynumber (Filedata * filedata, unsigned int section, dump_type type)
252b5132 4502{
dda8d76d 4503 if (section >= filedata->num_dump_sects)
252b5132 4504 {
2cf0635d 4505 dump_type * new_dump_sects;
252b5132 4506
3f5e193b 4507 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4508 sizeof (* new_dump_sects));
252b5132
RH
4509
4510 if (new_dump_sects == NULL)
591a748a 4511 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4512 else
4513 {
dda8d76d 4514 if (filedata->dump_sects)
21b65bac
NC
4515 {
4516 /* Copy current flag settings. */
dda8d76d
NC
4517 memcpy (new_dump_sects, filedata->dump_sects,
4518 filedata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4519
dda8d76d 4520 free (filedata->dump_sects);
21b65bac 4521 }
252b5132 4522
dda8d76d
NC
4523 filedata->dump_sects = new_dump_sects;
4524 filedata->num_dump_sects = section + 1;
252b5132
RH
4525 }
4526 }
4527
dda8d76d
NC
4528 if (filedata->dump_sects)
4529 filedata->dump_sects[section] |= type;
252b5132
RH
4530}
4531
aef1f6d0
DJ
4532/* Request a dump by section name. */
4533
4534static void
2cf0635d 4535request_dump_byname (const char * section, dump_type type)
aef1f6d0 4536{
2cf0635d 4537 struct dump_list_entry * new_request;
aef1f6d0 4538
3f5e193b
NC
4539 new_request = (struct dump_list_entry *)
4540 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4541 if (!new_request)
591a748a 4542 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4543
4544 new_request->name = strdup (section);
4545 if (!new_request->name)
591a748a 4546 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4547
4548 new_request->type = type;
4549
4550 new_request->next = dump_sects_byname;
4551 dump_sects_byname = new_request;
4552}
4553
cf13d699 4554static inline void
dda8d76d 4555request_dump (Filedata * filedata, dump_type type)
cf13d699
NC
4556{
4557 int section;
4558 char * cp;
4559
4560 do_dump++;
4561 section = strtoul (optarg, & cp, 0);
4562
4563 if (! *cp && section >= 0)
dda8d76d 4564 request_dump_bynumber (filedata, section, type);
cf13d699
NC
4565 else
4566 request_dump_byname (optarg, type);
4567}
4568
252b5132 4569static void
dda8d76d 4570parse_args (Filedata * filedata, int argc, char ** argv)
252b5132
RH
4571{
4572 int c;
4573
4574 if (argc < 2)
92f01d61 4575 usage (stderr);
252b5132
RH
4576
4577 while ((c = getopt_long
0e602686 4578 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4579 {
252b5132
RH
4580 switch (c)
4581 {
4582 case 0:
4583 /* Long options. */
4584 break;
4585 case 'H':
92f01d61 4586 usage (stdout);
252b5132
RH
4587 break;
4588
4589 case 'a':
32ec8896
NC
4590 do_syms = TRUE;
4591 do_reloc = TRUE;
4592 do_unwind = TRUE;
4593 do_dynamic = TRUE;
4594 do_header = TRUE;
4595 do_sections = TRUE;
4596 do_section_groups = TRUE;
4597 do_segments = TRUE;
4598 do_version = TRUE;
4599 do_histogram = TRUE;
4600 do_arch = TRUE;
4601 do_notes = TRUE;
252b5132 4602 break;
f5842774 4603 case 'g':
32ec8896 4604 do_section_groups = TRUE;
f5842774 4605 break;
5477e8a0 4606 case 't':
595cf52e 4607 case 'N':
32ec8896
NC
4608 do_sections = TRUE;
4609 do_section_details = TRUE;
595cf52e 4610 break;
252b5132 4611 case 'e':
32ec8896
NC
4612 do_header = TRUE;
4613 do_sections = TRUE;
4614 do_segments = TRUE;
252b5132 4615 break;
a952a375 4616 case 'A':
32ec8896 4617 do_arch = TRUE;
a952a375 4618 break;
252b5132 4619 case 'D':
32ec8896 4620 do_using_dynamic = TRUE;
252b5132
RH
4621 break;
4622 case 'r':
32ec8896 4623 do_reloc = TRUE;
252b5132 4624 break;
4d6ed7c8 4625 case 'u':
32ec8896 4626 do_unwind = TRUE;
4d6ed7c8 4627 break;
252b5132 4628 case 'h':
32ec8896 4629 do_header = TRUE;
252b5132
RH
4630 break;
4631 case 'l':
32ec8896 4632 do_segments = TRUE;
252b5132
RH
4633 break;
4634 case 's':
32ec8896 4635 do_syms = TRUE;
252b5132
RH
4636 break;
4637 case 'S':
32ec8896 4638 do_sections = TRUE;
252b5132
RH
4639 break;
4640 case 'd':
32ec8896 4641 do_dynamic = TRUE;
252b5132 4642 break;
a952a375 4643 case 'I':
32ec8896 4644 do_histogram = TRUE;
a952a375 4645 break;
779fe533 4646 case 'n':
32ec8896 4647 do_notes = TRUE;
779fe533 4648 break;
4145f1d5 4649 case 'c':
32ec8896 4650 do_archive_index = TRUE;
4145f1d5 4651 break;
252b5132 4652 case 'x':
dda8d76d 4653 request_dump (filedata, HEX_DUMP);
aef1f6d0 4654 break;
09c11c86 4655 case 'p':
dda8d76d 4656 request_dump (filedata, STRING_DUMP);
cf13d699
NC
4657 break;
4658 case 'R':
dda8d76d 4659 request_dump (filedata, RELOC_DUMP);
09c11c86 4660 break;
0e602686 4661 case 'z':
32ec8896 4662 decompress_dumps = TRUE;
0e602686 4663 break;
252b5132 4664 case 'w':
32ec8896 4665 do_dump = TRUE;
252b5132 4666 if (optarg == 0)
613ff48b 4667 {
32ec8896 4668 do_debugging = TRUE;
613ff48b
CC
4669 dwarf_select_sections_all ();
4670 }
252b5132
RH
4671 else
4672 {
32ec8896 4673 do_debugging = FALSE;
4cb93e3b 4674 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4675 }
4676 break;
2979dc34 4677 case OPTION_DEBUG_DUMP:
32ec8896 4678 do_dump = TRUE;
2979dc34 4679 if (optarg == 0)
32ec8896 4680 do_debugging = TRUE;
2979dc34
JJ
4681 else
4682 {
32ec8896 4683 do_debugging = FALSE;
4cb93e3b 4684 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4685 }
4686 break;
fd2f0033
TT
4687 case OPTION_DWARF_DEPTH:
4688 {
4689 char *cp;
4690
4691 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4692 }
4693 break;
4694 case OPTION_DWARF_START:
4695 {
4696 char *cp;
4697
4698 dwarf_start_die = strtoul (optarg, & cp, 0);
4699 }
4700 break;
4723351a 4701 case OPTION_DWARF_CHECK:
32ec8896 4702 dwarf_check = TRUE;
4723351a 4703 break;
2c610e4b 4704 case OPTION_DYN_SYMS:
32ec8896 4705 do_dyn_syms = TRUE;
2c610e4b 4706 break;
252b5132
RH
4707#ifdef SUPPORT_DISASSEMBLY
4708 case 'i':
dda8d76d 4709 request_dump (filedata, DISASS_DUMP);
cf13d699 4710 break;
252b5132
RH
4711#endif
4712 case 'v':
4713 print_version (program_name);
4714 break;
4715 case 'V':
32ec8896 4716 do_version = TRUE;
252b5132 4717 break;
d974e256 4718 case 'W':
32ec8896 4719 do_wide = TRUE;
d974e256 4720 break;
252b5132 4721 default:
252b5132
RH
4722 /* xgettext:c-format */
4723 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4724 /* Fall through. */
252b5132 4725 case '?':
92f01d61 4726 usage (stderr);
252b5132
RH
4727 }
4728 }
4729
4d6ed7c8 4730 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4731 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4732 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4733 && !do_section_groups && !do_archive_index
4734 && !do_dyn_syms)
92f01d61 4735 usage (stderr);
252b5132
RH
4736}
4737
4738static const char *
d3ba0551 4739get_elf_class (unsigned int elf_class)
252b5132 4740{
b34976b6 4741 static char buff[32];
103f02d3 4742
252b5132
RH
4743 switch (elf_class)
4744 {
4745 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4746 case ELFCLASS32: return "ELF32";
4747 case ELFCLASS64: return "ELF64";
ab5e7794 4748 default:
e9e44622 4749 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4750 return buff;
252b5132
RH
4751 }
4752}
4753
4754static const char *
d3ba0551 4755get_data_encoding (unsigned int encoding)
252b5132 4756{
b34976b6 4757 static char buff[32];
103f02d3 4758
252b5132
RH
4759 switch (encoding)
4760 {
4761 case ELFDATANONE: return _("none");
33c63f9d
CM
4762 case ELFDATA2LSB: return _("2's complement, little endian");
4763 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4764 default:
e9e44622 4765 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4766 return buff;
252b5132
RH
4767 }
4768}
4769
dda8d76d 4770/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 4771
32ec8896 4772static bfd_boolean
dda8d76d 4773process_file_header (Filedata * filedata)
252b5132 4774{
dda8d76d
NC
4775 Elf_Internal_Ehdr * header = & filedata->file_header;
4776
4777 if ( header->e_ident[EI_MAG0] != ELFMAG0
4778 || header->e_ident[EI_MAG1] != ELFMAG1
4779 || header->e_ident[EI_MAG2] != ELFMAG2
4780 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4781 {
4782 error
4783 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 4784 return FALSE;
252b5132
RH
4785 }
4786
dda8d76d 4787 init_dwarf_regnames (header->e_machine);
2dc4cec1 4788
252b5132
RH
4789 if (do_header)
4790 {
32ec8896 4791 unsigned i;
252b5132
RH
4792
4793 printf (_("ELF Header:\n"));
4794 printf (_(" Magic: "));
b34976b6 4795 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 4796 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
4797 printf ("\n");
4798 printf (_(" Class: %s\n"),
dda8d76d 4799 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 4800 printf (_(" Data: %s\n"),
dda8d76d 4801 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 4802 printf (_(" Version: %d%s\n"),
dda8d76d
NC
4803 header->e_ident[EI_VERSION],
4804 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 4805 ? _(" (current)")
dda8d76d 4806 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 4807 ? _(" <unknown>")
789be9f7 4808 : "")));
252b5132 4809 printf (_(" OS/ABI: %s\n"),
dda8d76d 4810 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 4811 printf (_(" ABI Version: %d\n"),
dda8d76d 4812 header->e_ident[EI_ABIVERSION]);
252b5132 4813 printf (_(" Type: %s\n"),
dda8d76d 4814 get_file_type (header->e_type));
252b5132 4815 printf (_(" Machine: %s\n"),
dda8d76d 4816 get_machine_name (header->e_machine));
252b5132 4817 printf (_(" Version: 0x%lx\n"),
e8a64888 4818 header->e_version);
76da6bbe 4819
f7a99963 4820 printf (_(" Entry point address: "));
e8a64888 4821 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 4822 printf (_("\n Start of program headers: "));
e8a64888 4823 print_vma (header->e_phoff, DEC);
f7a99963 4824 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 4825 print_vma (header->e_shoff, DEC);
f7a99963 4826 printf (_(" (bytes into file)\n"));
76da6bbe 4827
252b5132 4828 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 4829 header->e_flags,
dda8d76d 4830 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
4831 printf (_(" Size of this header: %u (bytes)\n"),
4832 header->e_ehsize);
4833 printf (_(" Size of program headers: %u (bytes)\n"),
4834 header->e_phentsize);
4835 printf (_(" Number of program headers: %u"),
4836 header->e_phnum);
dda8d76d
NC
4837 if (filedata->section_headers != NULL
4838 && header->e_phnum == PN_XNUM
4839 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
4840 {
4841 header->e_phnum = filedata->section_headers[0].sh_info;
4842 printf (" (%u)", header->e_phnum);
4843 }
2046a35d 4844 putc ('\n', stdout);
e8a64888
AM
4845 printf (_(" Size of section headers: %u (bytes)\n"),
4846 header->e_shentsize);
4847 printf (_(" Number of section headers: %u"),
4848 header->e_shnum);
dda8d76d 4849 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
4850 {
4851 header->e_shnum = filedata->section_headers[0].sh_size;
4852 printf (" (%u)", header->e_shnum);
4853 }
560f3c1c 4854 putc ('\n', stdout);
e8a64888
AM
4855 printf (_(" Section header string table index: %u"),
4856 header->e_shstrndx);
dda8d76d
NC
4857 if (filedata->section_headers != NULL
4858 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
4859 {
4860 header->e_shstrndx = filedata->section_headers[0].sh_link;
4861 printf (" (%u)", header->e_shstrndx);
4862 }
4863 if (header->e_shstrndx != SHN_UNDEF
4864 && header->e_shstrndx >= header->e_shnum)
4865 {
4866 header->e_shstrndx = SHN_UNDEF;
4867 printf (_(" <corrupt: out of range>"));
4868 }
560f3c1c
AM
4869 putc ('\n', stdout);
4870 }
4871
dda8d76d 4872 if (filedata->section_headers != NULL)
560f3c1c 4873 {
dda8d76d
NC
4874 if (header->e_phnum == PN_XNUM
4875 && filedata->section_headers[0].sh_info != 0)
4876 header->e_phnum = filedata->section_headers[0].sh_info;
4877 if (header->e_shnum == SHN_UNDEF)
4878 header->e_shnum = filedata->section_headers[0].sh_size;
4879 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
4880 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 4881 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
4882 header->e_shstrndx = SHN_UNDEF;
4883 free (filedata->section_headers);
4884 filedata->section_headers = NULL;
252b5132 4885 }
103f02d3 4886
32ec8896 4887 return TRUE;
9ea033b2
NC
4888}
4889
dda8d76d
NC
4890/* Read in the program headers from FILEDATA and store them in PHEADERS.
4891 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
4892
e0a31db1 4893static bfd_boolean
dda8d76d 4894get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 4895{
2cf0635d
NC
4896 Elf32_External_Phdr * phdrs;
4897 Elf32_External_Phdr * external;
4898 Elf_Internal_Phdr * internal;
b34976b6 4899 unsigned int i;
dda8d76d
NC
4900 unsigned int size = filedata->file_header.e_phentsize;
4901 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
4902
4903 /* PR binutils/17531: Cope with unexpected section header sizes. */
4904 if (size == 0 || num == 0)
4905 return FALSE;
4906 if (size < sizeof * phdrs)
4907 {
4908 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4909 return FALSE;
4910 }
4911 if (size > sizeof * phdrs)
4912 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4913
dda8d76d 4914 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
4915 size, num, _("program headers"));
4916 if (phdrs == NULL)
4917 return FALSE;
9ea033b2 4918
91d6fa6a 4919 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 4920 i < filedata->file_header.e_phnum;
b34976b6 4921 i++, internal++, external++)
252b5132 4922 {
9ea033b2
NC
4923 internal->p_type = BYTE_GET (external->p_type);
4924 internal->p_offset = BYTE_GET (external->p_offset);
4925 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4926 internal->p_paddr = BYTE_GET (external->p_paddr);
4927 internal->p_filesz = BYTE_GET (external->p_filesz);
4928 internal->p_memsz = BYTE_GET (external->p_memsz);
4929 internal->p_flags = BYTE_GET (external->p_flags);
4930 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4931 }
4932
9ea033b2 4933 free (phdrs);
e0a31db1 4934 return TRUE;
252b5132
RH
4935}
4936
dda8d76d
NC
4937/* Read in the program headers from FILEDATA and store them in PHEADERS.
4938 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
4939
e0a31db1 4940static bfd_boolean
dda8d76d 4941get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 4942{
2cf0635d
NC
4943 Elf64_External_Phdr * phdrs;
4944 Elf64_External_Phdr * external;
4945 Elf_Internal_Phdr * internal;
b34976b6 4946 unsigned int i;
dda8d76d
NC
4947 unsigned int size = filedata->file_header.e_phentsize;
4948 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
4949
4950 /* PR binutils/17531: Cope with unexpected section header sizes. */
4951 if (size == 0 || num == 0)
4952 return FALSE;
4953 if (size < sizeof * phdrs)
4954 {
4955 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4956 return FALSE;
4957 }
4958 if (size > sizeof * phdrs)
4959 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4960
dda8d76d 4961 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 4962 size, num, _("program headers"));
a6e9f9df 4963 if (!phdrs)
e0a31db1 4964 return FALSE;
9ea033b2 4965
91d6fa6a 4966 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 4967 i < filedata->file_header.e_phnum;
b34976b6 4968 i++, internal++, external++)
9ea033b2
NC
4969 {
4970 internal->p_type = BYTE_GET (external->p_type);
4971 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4972 internal->p_offset = BYTE_GET (external->p_offset);
4973 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4974 internal->p_paddr = BYTE_GET (external->p_paddr);
4975 internal->p_filesz = BYTE_GET (external->p_filesz);
4976 internal->p_memsz = BYTE_GET (external->p_memsz);
4977 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4978 }
4979
4980 free (phdrs);
e0a31db1 4981 return TRUE;
9ea033b2 4982}
252b5132 4983
32ec8896 4984/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 4985
32ec8896 4986static bfd_boolean
dda8d76d 4987get_program_headers (Filedata * filedata)
d93f0186 4988{
2cf0635d 4989 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4990
4991 /* Check cache of prior read. */
dda8d76d 4992 if (filedata->program_headers != NULL)
32ec8896 4993 return TRUE;
d93f0186 4994
82156ab7
NC
4995 /* Be kind to memory checkers by looking for
4996 e_phnum values which we know must be invalid. */
dda8d76d 4997 if (filedata->file_header.e_phnum
82156ab7 4998 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 4999 >= filedata->file_size)
82156ab7
NC
5000 {
5001 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5002 filedata->file_header.e_phnum);
82156ab7
NC
5003 return FALSE;
5004 }
d93f0186 5005
dda8d76d 5006 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5007 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5008 if (phdrs == NULL)
5009 {
8b73c356 5010 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5011 filedata->file_header.e_phnum);
32ec8896 5012 return FALSE;
d93f0186
NC
5013 }
5014
5015 if (is_32bit_elf
dda8d76d
NC
5016 ? get_32bit_program_headers (filedata, phdrs)
5017 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5018 {
dda8d76d 5019 filedata->program_headers = phdrs;
32ec8896 5020 return TRUE;
d93f0186
NC
5021 }
5022
5023 free (phdrs);
32ec8896 5024 return FALSE;
d93f0186
NC
5025}
5026
32ec8896 5027/* Returns TRUE if the program headers were loaded. */
2f62977e 5028
32ec8896 5029static bfd_boolean
dda8d76d 5030process_program_headers (Filedata * filedata)
252b5132 5031{
2cf0635d 5032 Elf_Internal_Phdr * segment;
b34976b6 5033 unsigned int i;
1a9ccd70 5034 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5035
dda8d76d 5036 if (filedata->file_header.e_phnum == 0)
252b5132 5037 {
82f2dbf7 5038 /* PR binutils/12467. */
dda8d76d 5039 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5040 {
5041 warn (_("possibly corrupt ELF header - it has a non-zero program"
5042 " header offset, but no program headers\n"));
5043 return FALSE;
5044 }
82f2dbf7 5045 else if (do_segments)
252b5132 5046 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 5047 return TRUE;
252b5132
RH
5048 }
5049
5050 if (do_segments && !do_header)
5051 {
dda8d76d
NC
5052 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
5053 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5054 printf (ngettext ("There is %d program header, starting at offset %s\n",
5055 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5056 filedata->file_header.e_phnum),
5057 filedata->file_header.e_phnum,
5058 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5059 }
5060
dda8d76d 5061 if (! get_program_headers (filedata))
6b4bf3bc 5062 return TRUE;
103f02d3 5063
252b5132
RH
5064 if (do_segments)
5065 {
dda8d76d 5066 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5067 printf (_("\nProgram Headers:\n"));
5068 else
5069 printf (_("\nProgram Headers:\n"));
76da6bbe 5070
f7a99963
NC
5071 if (is_32bit_elf)
5072 printf
5073 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5074 else if (do_wide)
5075 printf
5076 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5077 else
5078 {
5079 printf
5080 (_(" Type Offset VirtAddr PhysAddr\n"));
5081 printf
5082 (_(" FileSiz MemSiz Flags Align\n"));
5083 }
252b5132
RH
5084 }
5085
252b5132 5086 dynamic_addr = 0;
1b228002 5087 dynamic_size = 0;
252b5132 5088
dda8d76d
NC
5089 for (i = 0, segment = filedata->program_headers;
5090 i < filedata->file_header.e_phnum;
b34976b6 5091 i++, segment++)
252b5132
RH
5092 {
5093 if (do_segments)
5094 {
dda8d76d 5095 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5096
5097 if (is_32bit_elf)
5098 {
5099 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5100 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5101 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5102 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5103 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5104 printf ("%c%c%c ",
5105 (segment->p_flags & PF_R ? 'R' : ' '),
5106 (segment->p_flags & PF_W ? 'W' : ' '),
5107 (segment->p_flags & PF_X ? 'E' : ' '));
5108 printf ("%#lx", (unsigned long) segment->p_align);
5109 }
d974e256
JJ
5110 else if (do_wide)
5111 {
5112 if ((unsigned long) segment->p_offset == segment->p_offset)
5113 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5114 else
5115 {
5116 print_vma (segment->p_offset, FULL_HEX);
5117 putchar (' ');
5118 }
5119
5120 print_vma (segment->p_vaddr, FULL_HEX);
5121 putchar (' ');
5122 print_vma (segment->p_paddr, FULL_HEX);
5123 putchar (' ');
5124
5125 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5126 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5127 else
5128 {
5129 print_vma (segment->p_filesz, FULL_HEX);
5130 putchar (' ');
5131 }
5132
5133 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5134 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5135 else
5136 {
f48e6c45 5137 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5138 }
5139
5140 printf (" %c%c%c ",
5141 (segment->p_flags & PF_R ? 'R' : ' '),
5142 (segment->p_flags & PF_W ? 'W' : ' '),
5143 (segment->p_flags & PF_X ? 'E' : ' '));
5144
5145 if ((unsigned long) segment->p_align == segment->p_align)
5146 printf ("%#lx", (unsigned long) segment->p_align);
5147 else
5148 {
5149 print_vma (segment->p_align, PREFIX_HEX);
5150 }
5151 }
f7a99963
NC
5152 else
5153 {
5154 print_vma (segment->p_offset, FULL_HEX);
5155 putchar (' ');
5156 print_vma (segment->p_vaddr, FULL_HEX);
5157 putchar (' ');
5158 print_vma (segment->p_paddr, FULL_HEX);
5159 printf ("\n ");
5160 print_vma (segment->p_filesz, FULL_HEX);
5161 putchar (' ');
5162 print_vma (segment->p_memsz, FULL_HEX);
5163 printf (" %c%c%c ",
5164 (segment->p_flags & PF_R ? 'R' : ' '),
5165 (segment->p_flags & PF_W ? 'W' : ' '),
5166 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5167 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5168 }
252b5132 5169
1a9ccd70
NC
5170 putc ('\n', stdout);
5171 }
f54498b4 5172
252b5132
RH
5173 switch (segment->p_type)
5174 {
1a9ccd70 5175 case PT_LOAD:
502d895c
NC
5176#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5177 required by the ELF standard, several programs, including the Linux
5178 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5179 if (previous_load
5180 && previous_load->p_vaddr > segment->p_vaddr)
5181 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5182#endif
1a9ccd70
NC
5183 if (segment->p_memsz < segment->p_filesz)
5184 error (_("the segment's file size is larger than its memory size\n"));
5185 previous_load = segment;
5186 break;
5187
5188 case PT_PHDR:
5189 /* PR 20815 - Verify that the program header is loaded into memory. */
5190 if (i > 0 && previous_load != NULL)
5191 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5192 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5193 {
5194 unsigned int j;
5195
dda8d76d
NC
5196 for (j = 1; j < filedata->file_header.e_phnum; j++)
5197 if (filedata->program_headers[j].p_vaddr <= segment->p_vaddr
5198 && (filedata->program_headers[j].p_vaddr
5199 + filedata->program_headers[j].p_memsz)
1a9ccd70
NC
5200 >= (segment->p_vaddr + segment->p_filesz))
5201 break;
dda8d76d 5202 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5203 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5204 }
5205 break;
5206
252b5132
RH
5207 case PT_DYNAMIC:
5208 if (dynamic_addr)
5209 error (_("more than one dynamic segment\n"));
5210
20737c13
AM
5211 /* By default, assume that the .dynamic section is the first
5212 section in the DYNAMIC segment. */
5213 dynamic_addr = segment->p_offset;
5214 dynamic_size = segment->p_filesz;
5215
b2d38a17
NC
5216 /* Try to locate the .dynamic section. If there is
5217 a section header table, we can easily locate it. */
dda8d76d 5218 if (filedata->section_headers != NULL)
b2d38a17 5219 {
2cf0635d 5220 Elf_Internal_Shdr * sec;
b2d38a17 5221
dda8d76d 5222 sec = find_section (filedata, ".dynamic");
89fac5e3 5223 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5224 {
28f997cf
TG
5225 /* A corresponding .dynamic section is expected, but on
5226 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5227 if (!is_ia64_vms (filedata))
28f997cf 5228 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5229 break;
5230 }
5231
42bb2e33 5232 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
5233 {
5234 dynamic_size = 0;
5235 break;
5236 }
42bb2e33 5237
b2d38a17
NC
5238 dynamic_addr = sec->sh_offset;
5239 dynamic_size = sec->sh_size;
5240
5241 if (dynamic_addr < segment->p_offset
5242 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
5243 warn (_("the .dynamic section is not contained"
5244 " within the dynamic segment\n"));
b2d38a17 5245 else if (dynamic_addr > segment->p_offset)
20737c13
AM
5246 warn (_("the .dynamic section is not the first section"
5247 " in the dynamic segment.\n"));
b2d38a17 5248 }
39e224f6
MW
5249
5250 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5251 segment. Check this after matching against the section headers
5252 so we don't warn on debuginfo file (which have NOBITS .dynamic
5253 sections). */
c22b42ce
AM
5254 if (dynamic_addr > filedata->file_size
5255 || dynamic_size > filedata->file_size - dynamic_addr)
39e224f6
MW
5256 {
5257 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
5258 dynamic_addr = dynamic_size = 0;
5259 }
252b5132
RH
5260 break;
5261
5262 case PT_INTERP:
dda8d76d 5263 if (fseek (filedata->handle, archive_file_offset + (long) segment->p_offset,
fb52b2f4 5264 SEEK_SET))
252b5132
RH
5265 error (_("Unable to find program interpreter name\n"));
5266 else
5267 {
f8eae8b2 5268 char fmt [32];
9495b2e6 5269 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5270
5271 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5272 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5273
252b5132 5274 program_interpreter[0] = 0;
dda8d76d 5275 if (fscanf (filedata->handle, fmt, program_interpreter) <= 0)
7bd7b3ef 5276 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5277
5278 if (do_segments)
f54498b4 5279 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
5280 program_interpreter);
5281 }
5282 break;
5283 }
252b5132
RH
5284 }
5285
dda8d76d
NC
5286 if (do_segments
5287 && filedata->section_headers != NULL
5288 && filedata->string_table != NULL)
252b5132
RH
5289 {
5290 printf (_("\n Section to Segment mapping:\n"));
5291 printf (_(" Segment Sections...\n"));
5292
dda8d76d 5293 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5294 {
9ad5cbcf 5295 unsigned int j;
2cf0635d 5296 Elf_Internal_Shdr * section;
252b5132 5297
dda8d76d
NC
5298 segment = filedata->program_headers + i;
5299 section = filedata->section_headers + 1;
252b5132
RH
5300
5301 printf (" %2.2d ", i);
5302
dda8d76d 5303 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5304 {
f4638467
AM
5305 if (!ELF_TBSS_SPECIAL (section, segment)
5306 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5307 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5308 }
5309
5310 putc ('\n',stdout);
5311 }
5312 }
5313
32ec8896 5314 return TRUE;
252b5132
RH
5315}
5316
5317
d93f0186
NC
5318/* Find the file offset corresponding to VMA by using the program headers. */
5319
5320static long
dda8d76d 5321offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5322{
2cf0635d 5323 Elf_Internal_Phdr * seg;
d93f0186 5324
dda8d76d 5325 if (! get_program_headers (filedata))
d93f0186
NC
5326 {
5327 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5328 return (long) vma;
5329 }
5330
dda8d76d
NC
5331 for (seg = filedata->program_headers;
5332 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5333 ++seg)
5334 {
5335 if (seg->p_type != PT_LOAD)
5336 continue;
5337
5338 if (vma >= (seg->p_vaddr & -seg->p_align)
5339 && vma + size <= seg->p_vaddr + seg->p_filesz)
5340 return vma - seg->p_vaddr + seg->p_offset;
5341 }
5342
5343 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5344 (unsigned long) vma);
d93f0186
NC
5345 return (long) vma;
5346}
5347
5348
dda8d76d
NC
5349/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5350 If PROBE is true, this is just a probe and we do not generate any error
5351 messages if the load fails. */
049b0c3a
NC
5352
5353static bfd_boolean
dda8d76d 5354get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5355{
2cf0635d
NC
5356 Elf32_External_Shdr * shdrs;
5357 Elf_Internal_Shdr * internal;
dda8d76d
NC
5358 unsigned int i;
5359 unsigned int size = filedata->file_header.e_shentsize;
5360 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5361
5362 /* PR binutils/17531: Cope with unexpected section header sizes. */
5363 if (size == 0 || num == 0)
5364 return FALSE;
5365 if (size < sizeof * shdrs)
5366 {
5367 if (! probe)
5368 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5369 return FALSE;
5370 }
5371 if (!probe && size > sizeof * shdrs)
5372 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5373
dda8d76d 5374 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5375 size, num,
5376 probe ? NULL : _("section headers"));
5377 if (shdrs == NULL)
5378 return FALSE;
252b5132 5379
dda8d76d
NC
5380 free (filedata->section_headers);
5381 filedata->section_headers = (Elf_Internal_Shdr *)
5382 cmalloc (num, sizeof (Elf_Internal_Shdr));
5383 if (filedata->section_headers == NULL)
252b5132 5384 {
049b0c3a 5385 if (!probe)
8b73c356 5386 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5387 free (shdrs);
049b0c3a 5388 return FALSE;
252b5132
RH
5389 }
5390
dda8d76d 5391 for (i = 0, internal = filedata->section_headers;
560f3c1c 5392 i < num;
b34976b6 5393 i++, internal++)
252b5132
RH
5394 {
5395 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5396 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5397 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5398 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5399 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5400 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5401 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5402 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5403 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5404 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5405 if (!probe && internal->sh_link > num)
5406 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5407 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5408 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5409 }
5410
5411 free (shdrs);
049b0c3a 5412 return TRUE;
252b5132
RH
5413}
5414
dda8d76d
NC
5415/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5416
049b0c3a 5417static bfd_boolean
dda8d76d 5418get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5419{
dda8d76d
NC
5420 Elf64_External_Shdr * shdrs;
5421 Elf_Internal_Shdr * internal;
5422 unsigned int i;
5423 unsigned int size = filedata->file_header.e_shentsize;
5424 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5425
5426 /* PR binutils/17531: Cope with unexpected section header sizes. */
5427 if (size == 0 || num == 0)
5428 return FALSE;
dda8d76d 5429
049b0c3a
NC
5430 if (size < sizeof * shdrs)
5431 {
5432 if (! probe)
5433 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5434 return FALSE;
5435 }
dda8d76d 5436
049b0c3a
NC
5437 if (! probe && size > sizeof * shdrs)
5438 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5439
dda8d76d
NC
5440 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5441 filedata->file_header.e_shoff,
049b0c3a
NC
5442 size, num,
5443 probe ? NULL : _("section headers"));
5444 if (shdrs == NULL)
5445 return FALSE;
9ea033b2 5446
dda8d76d
NC
5447 free (filedata->section_headers);
5448 filedata->section_headers = (Elf_Internal_Shdr *)
5449 cmalloc (num, sizeof (Elf_Internal_Shdr));
5450 if (filedata->section_headers == NULL)
9ea033b2 5451 {
049b0c3a 5452 if (! probe)
8b73c356 5453 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5454 free (shdrs);
049b0c3a 5455 return FALSE;
9ea033b2
NC
5456 }
5457
dda8d76d 5458 for (i = 0, internal = filedata->section_headers;
560f3c1c 5459 i < num;
b34976b6 5460 i++, internal++)
9ea033b2
NC
5461 {
5462 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5463 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5464 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5465 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5466 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5467 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5468 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5469 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5470 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5471 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5472 if (!probe && internal->sh_link > num)
5473 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5474 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5475 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5476 }
5477
5478 free (shdrs);
049b0c3a 5479 return TRUE;
9ea033b2
NC
5480}
5481
252b5132 5482static Elf_Internal_Sym *
dda8d76d
NC
5483get_32bit_elf_symbols (Filedata * filedata,
5484 Elf_Internal_Shdr * section,
5485 unsigned long * num_syms_return)
252b5132 5486{
ba5cdace 5487 unsigned long number = 0;
dd24e3da 5488 Elf32_External_Sym * esyms = NULL;
ba5cdace 5489 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5490 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5491 Elf_Internal_Sym * psym;
b34976b6 5492 unsigned int j;
e3d39609 5493 elf_section_list * entry;
252b5132 5494
c9c1d674
EG
5495 if (section->sh_size == 0)
5496 {
5497 if (num_syms_return != NULL)
5498 * num_syms_return = 0;
5499 return NULL;
5500 }
5501
dd24e3da 5502 /* Run some sanity checks first. */
c9c1d674 5503 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5504 {
c9c1d674 5505 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5506 printable_section_name (filedata, section),
5507 (unsigned long) section->sh_entsize);
ba5cdace 5508 goto exit_point;
dd24e3da
NC
5509 }
5510
dda8d76d 5511 if (section->sh_size > filedata->file_size)
f54498b4
NC
5512 {
5513 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5514 printable_section_name (filedata, section),
5515 (unsigned long) section->sh_size);
f54498b4
NC
5516 goto exit_point;
5517 }
5518
dd24e3da
NC
5519 number = section->sh_size / section->sh_entsize;
5520
5521 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5522 {
c9c1d674 5523 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5524 (unsigned long) section->sh_size,
dda8d76d 5525 printable_section_name (filedata, section),
8066deb1 5526 (unsigned long) section->sh_entsize);
ba5cdace 5527 goto exit_point;
dd24e3da
NC
5528 }
5529
dda8d76d 5530 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5531 section->sh_size, _("symbols"));
dd24e3da 5532 if (esyms == NULL)
ba5cdace 5533 goto exit_point;
252b5132 5534
e3d39609
NC
5535 shndx = NULL;
5536 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
5537 {
5538 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5539 continue;
5540
5541 if (shndx != NULL)
5542 {
5543 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5544 free (shndx);
5545 }
5546
5547 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5548 entry->hdr->sh_offset,
5549 1, entry->hdr->sh_size,
5550 _("symbol table section indices"));
5551 if (shndx == NULL)
5552 goto exit_point;
5553
5554 /* PR17531: file: heap-buffer-overflow */
5555 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5556 {
5557 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5558 printable_section_name (filedata, entry->hdr),
5559 (unsigned long) entry->hdr->sh_size,
5560 (unsigned long) section->sh_size);
5561 goto exit_point;
c9c1d674 5562 }
e3d39609 5563 }
9ad5cbcf 5564
3f5e193b 5565 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5566
5567 if (isyms == NULL)
5568 {
8b73c356
NC
5569 error (_("Out of memory reading %lu symbols\n"),
5570 (unsigned long) number);
dd24e3da 5571 goto exit_point;
252b5132
RH
5572 }
5573
dd24e3da 5574 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5575 {
5576 psym->st_name = BYTE_GET (esyms[j].st_name);
5577 psym->st_value = BYTE_GET (esyms[j].st_value);
5578 psym->st_size = BYTE_GET (esyms[j].st_size);
5579 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5580 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5581 psym->st_shndx
5582 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5583 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5584 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5585 psym->st_info = BYTE_GET (esyms[j].st_info);
5586 psym->st_other = BYTE_GET (esyms[j].st_other);
5587 }
5588
dd24e3da 5589 exit_point:
e3d39609
NC
5590 free (shndx);
5591 free (esyms);
252b5132 5592
ba5cdace
NC
5593 if (num_syms_return != NULL)
5594 * num_syms_return = isyms == NULL ? 0 : number;
5595
252b5132
RH
5596 return isyms;
5597}
5598
9ea033b2 5599static Elf_Internal_Sym *
dda8d76d
NC
5600get_64bit_elf_symbols (Filedata * filedata,
5601 Elf_Internal_Shdr * section,
5602 unsigned long * num_syms_return)
9ea033b2 5603{
ba5cdace
NC
5604 unsigned long number = 0;
5605 Elf64_External_Sym * esyms = NULL;
5606 Elf_External_Sym_Shndx * shndx = NULL;
5607 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5608 Elf_Internal_Sym * psym;
b34976b6 5609 unsigned int j;
e3d39609 5610 elf_section_list * entry;
9ea033b2 5611
c9c1d674
EG
5612 if (section->sh_size == 0)
5613 {
5614 if (num_syms_return != NULL)
5615 * num_syms_return = 0;
5616 return NULL;
5617 }
5618
dd24e3da 5619 /* Run some sanity checks first. */
c9c1d674 5620 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5621 {
c9c1d674 5622 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5623 printable_section_name (filedata, section),
8066deb1 5624 (unsigned long) section->sh_entsize);
ba5cdace 5625 goto exit_point;
dd24e3da
NC
5626 }
5627
dda8d76d 5628 if (section->sh_size > filedata->file_size)
f54498b4
NC
5629 {
5630 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5631 printable_section_name (filedata, section),
8066deb1 5632 (unsigned long) section->sh_size);
f54498b4
NC
5633 goto exit_point;
5634 }
5635
dd24e3da
NC
5636 number = section->sh_size / section->sh_entsize;
5637
5638 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5639 {
c9c1d674 5640 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5641 (unsigned long) section->sh_size,
dda8d76d 5642 printable_section_name (filedata, section),
8066deb1 5643 (unsigned long) section->sh_entsize);
ba5cdace 5644 goto exit_point;
dd24e3da
NC
5645 }
5646
dda8d76d 5647 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5648 section->sh_size, _("symbols"));
a6e9f9df 5649 if (!esyms)
ba5cdace 5650 goto exit_point;
9ea033b2 5651
e3d39609
NC
5652 shndx = NULL;
5653 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
5654 {
5655 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5656 continue;
5657
5658 if (shndx != NULL)
5659 {
5660 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5661 free (shndx);
c9c1d674 5662 }
e3d39609
NC
5663
5664 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5665 entry->hdr->sh_offset,
5666 1, entry->hdr->sh_size,
5667 _("symbol table section indices"));
5668 if (shndx == NULL)
5669 goto exit_point;
5670
5671 /* PR17531: file: heap-buffer-overflow */
5672 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5673 {
5674 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5675 printable_section_name (filedata, entry->hdr),
5676 (unsigned long) entry->hdr->sh_size,
5677 (unsigned long) section->sh_size);
5678 goto exit_point;
5679 }
5680 }
9ad5cbcf 5681
3f5e193b 5682 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5683
5684 if (isyms == NULL)
5685 {
8b73c356
NC
5686 error (_("Out of memory reading %lu symbols\n"),
5687 (unsigned long) number);
ba5cdace 5688 goto exit_point;
9ea033b2
NC
5689 }
5690
ba5cdace 5691 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5692 {
5693 psym->st_name = BYTE_GET (esyms[j].st_name);
5694 psym->st_info = BYTE_GET (esyms[j].st_info);
5695 psym->st_other = BYTE_GET (esyms[j].st_other);
5696 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5697
4fbb74a6 5698 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5699 psym->st_shndx
5700 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5701 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5702 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5703
66543521
AM
5704 psym->st_value = BYTE_GET (esyms[j].st_value);
5705 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5706 }
5707
ba5cdace 5708 exit_point:
e3d39609
NC
5709 free (shndx);
5710 free (esyms);
ba5cdace
NC
5711
5712 if (num_syms_return != NULL)
5713 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5714
5715 return isyms;
5716}
5717
d1133906 5718static const char *
dda8d76d 5719get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5720{
5477e8a0 5721 static char buff[1024];
2cf0635d 5722 char * p = buff;
32ec8896
NC
5723 unsigned int field_size = is_32bit_elf ? 8 : 16;
5724 signed int sindex;
5725 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5726 bfd_vma os_flags = 0;
5727 bfd_vma proc_flags = 0;
5728 bfd_vma unknown_flags = 0;
148b93f2 5729 static const struct
5477e8a0 5730 {
2cf0635d 5731 const char * str;
32ec8896 5732 unsigned int len;
5477e8a0
L
5733 }
5734 flags [] =
5735 {
cfcac11d
NC
5736 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5737 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5738 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5739 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5740 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5741 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5742 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5743 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5744 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5745 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5746 /* IA-64 specific. */
5747 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5748 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5749 /* IA-64 OpenVMS specific. */
5750 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5751 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5752 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5753 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5754 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5755 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5756 /* Generic. */
cfcac11d 5757 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5758 /* SPARC specific. */
77115a4a 5759 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5760 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5761 /* ARM specific. */
5762 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5763 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
5764 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
5765 /* GNU specific. */
5766 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
5767 /* VLE specific. */
5768 /* 25 */ { STRING_COMMA_LEN ("VLE") },
5477e8a0
L
5769 };
5770
5771 if (do_section_details)
5772 {
8d5ff12c
L
5773 sprintf (buff, "[%*.*lx]: ",
5774 field_size, field_size, (unsigned long) sh_flags);
5775 p += field_size + 4;
5477e8a0 5776 }
76da6bbe 5777
d1133906
NC
5778 while (sh_flags)
5779 {
5780 bfd_vma flag;
5781
5782 flag = sh_flags & - sh_flags;
5783 sh_flags &= ~ flag;
76da6bbe 5784
5477e8a0 5785 if (do_section_details)
d1133906 5786 {
5477e8a0
L
5787 switch (flag)
5788 {
91d6fa6a
NC
5789 case SHF_WRITE: sindex = 0; break;
5790 case SHF_ALLOC: sindex = 1; break;
5791 case SHF_EXECINSTR: sindex = 2; break;
5792 case SHF_MERGE: sindex = 3; break;
5793 case SHF_STRINGS: sindex = 4; break;
5794 case SHF_INFO_LINK: sindex = 5; break;
5795 case SHF_LINK_ORDER: sindex = 6; break;
5796 case SHF_OS_NONCONFORMING: sindex = 7; break;
5797 case SHF_GROUP: sindex = 8; break;
5798 case SHF_TLS: sindex = 9; break;
18ae9cc1 5799 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 5800 case SHF_COMPRESSED: sindex = 20; break;
a91e1603 5801 case SHF_GNU_MBIND: sindex = 24; break;
76da6bbe 5802
5477e8a0 5803 default:
91d6fa6a 5804 sindex = -1;
dda8d76d 5805 switch (filedata->file_header.e_machine)
148b93f2 5806 {
cfcac11d 5807 case EM_IA_64:
148b93f2 5808 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5809 sindex = 10;
148b93f2 5810 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5811 sindex = 11;
148b93f2 5812#ifdef BFD64
dda8d76d 5813 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
5814 switch (flag)
5815 {
91d6fa6a
NC
5816 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5817 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5818 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5819 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5820 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5821 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5822 default: break;
5823 }
5824#endif
cfcac11d
NC
5825 break;
5826
caa83f8b 5827 case EM_386:
22abe556 5828 case EM_IAMCU:
caa83f8b 5829 case EM_X86_64:
7f502d6c 5830 case EM_L1OM:
7a9068fe 5831 case EM_K1OM:
cfcac11d
NC
5832 case EM_OLD_SPARCV9:
5833 case EM_SPARC32PLUS:
5834 case EM_SPARCV9:
5835 case EM_SPARC:
18ae9cc1 5836 if (flag == SHF_ORDERED)
91d6fa6a 5837 sindex = 19;
cfcac11d 5838 break;
ac4c9b04
MG
5839
5840 case EM_ARM:
5841 switch (flag)
5842 {
5843 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 5844 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
5845 case SHF_COMDEF: sindex = 23; break;
5846 default: break;
5847 }
5848 break;
83eef883
AFB
5849 case EM_PPC:
5850 if (flag == SHF_PPC_VLE)
5851 sindex = 25;
5852 break;
ac4c9b04 5853
cfcac11d
NC
5854 default:
5855 break;
148b93f2 5856 }
5477e8a0
L
5857 }
5858
91d6fa6a 5859 if (sindex != -1)
5477e8a0 5860 {
8d5ff12c
L
5861 if (p != buff + field_size + 4)
5862 {
5863 if (size < (10 + 2))
bee0ee85
NC
5864 {
5865 warn (_("Internal error: not enough buffer room for section flag info"));
5866 return _("<unknown>");
5867 }
8d5ff12c
L
5868 size -= 2;
5869 *p++ = ',';
5870 *p++ = ' ';
5871 }
5872
91d6fa6a
NC
5873 size -= flags [sindex].len;
5874 p = stpcpy (p, flags [sindex].str);
5477e8a0 5875 }
3b22753a 5876 else if (flag & SHF_MASKOS)
8d5ff12c 5877 os_flags |= flag;
d1133906 5878 else if (flag & SHF_MASKPROC)
8d5ff12c 5879 proc_flags |= flag;
d1133906 5880 else
8d5ff12c 5881 unknown_flags |= flag;
5477e8a0
L
5882 }
5883 else
5884 {
5885 switch (flag)
5886 {
5887 case SHF_WRITE: *p = 'W'; break;
5888 case SHF_ALLOC: *p = 'A'; break;
5889 case SHF_EXECINSTR: *p = 'X'; break;
5890 case SHF_MERGE: *p = 'M'; break;
5891 case SHF_STRINGS: *p = 'S'; break;
5892 case SHF_INFO_LINK: *p = 'I'; break;
5893 case SHF_LINK_ORDER: *p = 'L'; break;
5894 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5895 case SHF_GROUP: *p = 'G'; break;
5896 case SHF_TLS: *p = 'T'; break;
18ae9cc1 5897 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 5898 case SHF_COMPRESSED: *p = 'C'; break;
a91e1603 5899 case SHF_GNU_MBIND: *p = 'D'; break;
5477e8a0
L
5900
5901 default:
dda8d76d
NC
5902 if ((filedata->file_header.e_machine == EM_X86_64
5903 || filedata->file_header.e_machine == EM_L1OM
5904 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
5905 && flag == SHF_X86_64_LARGE)
5906 *p = 'l';
dda8d76d 5907 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 5908 && flag == SHF_ARM_PURECODE)
91f68a68 5909 *p = 'y';
dda8d76d 5910 else if (filedata->file_header.e_machine == EM_PPC
83eef883
AFB
5911 && flag == SHF_PPC_VLE)
5912 *p = 'v';
5477e8a0
L
5913 else if (flag & SHF_MASKOS)
5914 {
5915 *p = 'o';
5916 sh_flags &= ~ SHF_MASKOS;
5917 }
5918 else if (flag & SHF_MASKPROC)
5919 {
5920 *p = 'p';
5921 sh_flags &= ~ SHF_MASKPROC;
5922 }
5923 else
5924 *p = 'x';
5925 break;
5926 }
5927 p++;
d1133906
NC
5928 }
5929 }
76da6bbe 5930
8d5ff12c
L
5931 if (do_section_details)
5932 {
5933 if (os_flags)
5934 {
5935 size -= 5 + field_size;
5936 if (p != buff + field_size + 4)
5937 {
5938 if (size < (2 + 1))
bee0ee85
NC
5939 {
5940 warn (_("Internal error: not enough buffer room for section flag info"));
5941 return _("<unknown>");
5942 }
8d5ff12c
L
5943 size -= 2;
5944 *p++ = ',';
5945 *p++ = ' ';
5946 }
5947 sprintf (p, "OS (%*.*lx)", field_size, field_size,
5948 (unsigned long) os_flags);
5949 p += 5 + field_size;
5950 }
5951 if (proc_flags)
5952 {
5953 size -= 7 + field_size;
5954 if (p != buff + field_size + 4)
5955 {
5956 if (size < (2 + 1))
bee0ee85
NC
5957 {
5958 warn (_("Internal error: not enough buffer room for section flag info"));
5959 return _("<unknown>");
5960 }
8d5ff12c
L
5961 size -= 2;
5962 *p++ = ',';
5963 *p++ = ' ';
5964 }
5965 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
5966 (unsigned long) proc_flags);
5967 p += 7 + field_size;
5968 }
5969 if (unknown_flags)
5970 {
5971 size -= 10 + field_size;
5972 if (p != buff + field_size + 4)
5973 {
5974 if (size < (2 + 1))
bee0ee85
NC
5975 {
5976 warn (_("Internal error: not enough buffer room for section flag info"));
5977 return _("<unknown>");
5978 }
8d5ff12c
L
5979 size -= 2;
5980 *p++ = ',';
5981 *p++ = ' ';
5982 }
2b692964 5983 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
5984 (unsigned long) unknown_flags);
5985 p += 10 + field_size;
5986 }
5987 }
5988
e9e44622 5989 *p = '\0';
d1133906
NC
5990 return buff;
5991}
5992
77115a4a 5993static unsigned int
ebdf1ebf 5994get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
5995{
5996 if (is_32bit_elf)
5997 {
5998 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 5999
ebdf1ebf
NC
6000 if (size < sizeof (* echdr))
6001 {
6002 error (_("Compressed section is too small even for a compression header\n"));
6003 return 0;
6004 }
6005
77115a4a
L
6006 chdr->ch_type = BYTE_GET (echdr->ch_type);
6007 chdr->ch_size = BYTE_GET (echdr->ch_size);
6008 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6009 return sizeof (*echdr);
6010 }
6011 else
6012 {
6013 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6014
ebdf1ebf
NC
6015 if (size < sizeof (* echdr))
6016 {
6017 error (_("Compressed section is too small even for a compression header\n"));
6018 return 0;
6019 }
6020
77115a4a
L
6021 chdr->ch_type = BYTE_GET (echdr->ch_type);
6022 chdr->ch_size = BYTE_GET (echdr->ch_size);
6023 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6024 return sizeof (*echdr);
6025 }
6026}
6027
32ec8896 6028static bfd_boolean
dda8d76d 6029process_section_headers (Filedata * filedata)
252b5132 6030{
2cf0635d 6031 Elf_Internal_Shdr * section;
b34976b6 6032 unsigned int i;
252b5132 6033
dda8d76d 6034 filedata->section_headers = NULL;
252b5132 6035
dda8d76d 6036 if (filedata->file_header.e_shnum == 0)
252b5132 6037 {
82f2dbf7 6038 /* PR binutils/12467. */
dda8d76d 6039 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6040 {
6041 warn (_("possibly corrupt ELF file header - it has a non-zero"
6042 " section header offset, but no section headers\n"));
6043 return FALSE;
6044 }
82f2dbf7 6045 else if (do_sections)
252b5132
RH
6046 printf (_("\nThere are no sections in this file.\n"));
6047
32ec8896 6048 return TRUE;
252b5132
RH
6049 }
6050
6051 if (do_sections && !do_header)
d3a49aa8
AM
6052 printf (ngettext ("There is %d section header, "
6053 "starting at offset 0x%lx:\n",
6054 "There are %d section headers, "
6055 "starting at offset 0x%lx:\n",
dda8d76d
NC
6056 filedata->file_header.e_shnum),
6057 filedata->file_header.e_shnum,
6058 (unsigned long) filedata->file_header.e_shoff);
252b5132 6059
9ea033b2
NC
6060 if (is_32bit_elf)
6061 {
dda8d76d 6062 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
6063 return FALSE;
6064 }
6065 else
6066 {
dda8d76d 6067 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 6068 return FALSE;
9ea033b2 6069 }
252b5132
RH
6070
6071 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6072 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6073 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6074 {
dda8d76d 6075 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6076
c256ffe7
JJ
6077 if (section->sh_size != 0)
6078 {
dda8d76d
NC
6079 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6080 1, section->sh_size,
6081 _("string table"));
0de14b54 6082
dda8d76d 6083 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6084 }
252b5132
RH
6085 }
6086
6087 /* Scan the sections for the dynamic symbol table
e3c8793a 6088 and dynamic string table and debug sections. */
252b5132
RH
6089 dynamic_symbols = NULL;
6090 dynamic_strings = NULL;
6091 dynamic_syminfo = NULL;
6a40cf0c 6092 symtab_shndx_list = NULL;
103f02d3 6093
89fac5e3 6094 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6095 switch (filedata->file_header.e_machine)
89fac5e3
RS
6096 {
6097 case EM_MIPS:
6098 case EM_MIPS_RS3_LE:
6099 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6100 FDE addresses. However, the ABI also has a semi-official ILP32
6101 variant for which the normal FDE address size rules apply.
6102
6103 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6104 section, where XX is the size of longs in bits. Unfortunately,
6105 earlier compilers provided no way of distinguishing ILP32 objects
6106 from LP64 objects, so if there's any doubt, we should assume that
6107 the official LP64 form is being used. */
dda8d76d
NC
6108 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6109 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6110 eh_addr_size = 8;
6111 break;
0f56a26a
DD
6112
6113 case EM_H8_300:
6114 case EM_H8_300H:
dda8d76d 6115 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6116 {
6117 case E_H8_MACH_H8300:
6118 case E_H8_MACH_H8300HN:
6119 case E_H8_MACH_H8300SN:
6120 case E_H8_MACH_H8300SXN:
6121 eh_addr_size = 2;
6122 break;
6123 case E_H8_MACH_H8300H:
6124 case E_H8_MACH_H8300S:
6125 case E_H8_MACH_H8300SX:
6126 eh_addr_size = 4;
6127 break;
6128 }
f4236fe4
DD
6129 break;
6130
ff7eeb89 6131 case EM_M32C_OLD:
f4236fe4 6132 case EM_M32C:
dda8d76d 6133 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6134 {
6135 case EF_M32C_CPU_M16C:
6136 eh_addr_size = 2;
6137 break;
6138 }
6139 break;
89fac5e3
RS
6140 }
6141
76ca31c0
NC
6142#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6143 do \
6144 { \
6145 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6146 if (section->sh_entsize != expected_entsize) \
9dd3a467 6147 { \
76ca31c0
NC
6148 char buf[40]; \
6149 sprintf_vma (buf, section->sh_entsize); \
6150 /* Note: coded this way so that there is a single string for \
6151 translation. */ \
6152 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6153 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6154 (unsigned) expected_entsize); \
9dd3a467 6155 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6156 } \
6157 } \
08d8fa11 6158 while (0)
9dd3a467
NC
6159
6160#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
6161 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
6162 sizeof (Elf64_External_##type))
6163
dda8d76d
NC
6164 for (i = 0, section = filedata->section_headers;
6165 i < filedata->file_header.e_shnum;
b34976b6 6166 i++, section++)
252b5132 6167 {
2cf0635d 6168 char * name = SECTION_NAME (section);
252b5132
RH
6169
6170 if (section->sh_type == SHT_DYNSYM)
6171 {
6172 if (dynamic_symbols != NULL)
6173 {
6174 error (_("File contains multiple dynamic symbol tables\n"));
6175 continue;
6176 }
6177
08d8fa11 6178 CHECK_ENTSIZE (section, i, Sym);
dda8d76d 6179 dynamic_symbols = GET_ELF_SYMBOLS (filedata, section, & num_dynamic_syms);
252b5132
RH
6180 }
6181 else if (section->sh_type == SHT_STRTAB
18bd398b 6182 && streq (name, ".dynstr"))
252b5132
RH
6183 {
6184 if (dynamic_strings != NULL)
6185 {
6186 error (_("File contains multiple dynamic string tables\n"));
6187 continue;
6188 }
6189
dda8d76d 6190 dynamic_strings = (char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
6191 1, section->sh_size,
6192 _("dynamic strings"));
59245841 6193 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 6194 }
9ad5cbcf
AM
6195 else if (section->sh_type == SHT_SYMTAB_SHNDX)
6196 {
6a40cf0c 6197 elf_section_list * entry = xmalloc (sizeof * entry);
dda8d76d 6198
6a40cf0c
NC
6199 entry->hdr = section;
6200 entry->next = symtab_shndx_list;
6201 symtab_shndx_list = entry;
9ad5cbcf 6202 }
08d8fa11
JJ
6203 else if (section->sh_type == SHT_SYMTAB)
6204 CHECK_ENTSIZE (section, i, Sym);
6205 else if (section->sh_type == SHT_GROUP)
6206 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6207 else if (section->sh_type == SHT_REL)
6208 CHECK_ENTSIZE (section, i, Rel);
6209 else if (section->sh_type == SHT_RELA)
6210 CHECK_ENTSIZE (section, i, Rela);
252b5132 6211 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 6212 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 6213 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47 6214 || do_debug_str || do_debug_loc || do_debug_ranges
d85bf2ba 6215 || do_debug_addr || do_debug_cu_index || do_debug_links)
1b315056
CS
6216 && (const_strneq (name, ".debug_")
6217 || const_strneq (name, ".zdebug_")))
252b5132 6218 {
1b315056
CS
6219 if (name[1] == 'z')
6220 name += sizeof (".zdebug_") - 1;
6221 else
6222 name += sizeof (".debug_") - 1;
252b5132
RH
6223
6224 if (do_debugging
4723351a
CC
6225 || (do_debug_info && const_strneq (name, "info"))
6226 || (do_debug_info && const_strneq (name, "types"))
6227 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6228 || (do_debug_lines && strcmp (name, "line") == 0)
6229 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6230 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6231 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6232 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6233 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6234 || (do_debug_aranges && const_strneq (name, "aranges"))
6235 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6236 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6237 || (do_debug_frames && const_strneq (name, "frame"))
6238 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6239 || (do_debug_macinfo && const_strneq (name, "macro"))
6240 || (do_debug_str && const_strneq (name, "str"))
6241 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6242 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6243 || (do_debug_addr && const_strneq (name, "addr"))
6244 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6245 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6246 )
dda8d76d 6247 request_dump_bynumber (filedata, i, DEBUG_DUMP);
252b5132 6248 }
a262ae96 6249 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6250 else if ((do_debugging || do_debug_info)
0112cd26 6251 && const_strneq (name, ".gnu.linkonce.wi."))
dda8d76d 6252 request_dump_bynumber (filedata, i, DEBUG_DUMP);
18bd398b 6253 else if (do_debug_frames && streq (name, ".eh_frame"))
dda8d76d 6254 request_dump_bynumber (filedata, i, DEBUG_DUMP);
61364358
JK
6255 else if (do_gdb_index && (streq (name, ".gdb_index")
6256 || streq (name, ".debug_names")))
dda8d76d 6257 request_dump_bynumber (filedata, i, DEBUG_DUMP);
6f875884
TG
6258 /* Trace sections for Itanium VMS. */
6259 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6260 || do_trace_aranges)
6261 && const_strneq (name, ".trace_"))
6262 {
6263 name += sizeof (".trace_") - 1;
6264
6265 if (do_debugging
6266 || (do_trace_info && streq (name, "info"))
6267 || (do_trace_abbrevs && streq (name, "abbrev"))
6268 || (do_trace_aranges && streq (name, "aranges"))
6269 )
dda8d76d 6270 request_dump_bynumber (filedata, i, DEBUG_DUMP);
6f875884 6271 }
dda8d76d
NC
6272 else if ((do_debugging || do_debug_links)
6273 && (const_strneq (name, ".gnu_debuglink")
6274 || const_strneq (name, ".gnu_debugaltlink")))
6275 request_dump_bynumber (filedata, i, DEBUG_DUMP);
252b5132
RH
6276 }
6277
6278 if (! do_sections)
32ec8896 6279 return TRUE;
252b5132 6280
dda8d76d 6281 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6282 printf (_("\nSection Headers:\n"));
6283 else
6284 printf (_("\nSection Header:\n"));
76da6bbe 6285
f7a99963 6286 if (is_32bit_elf)
595cf52e 6287 {
5477e8a0 6288 if (do_section_details)
595cf52e
L
6289 {
6290 printf (_(" [Nr] Name\n"));
5477e8a0 6291 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6292 }
6293 else
6294 printf
6295 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6296 }
d974e256 6297 else if (do_wide)
595cf52e 6298 {
5477e8a0 6299 if (do_section_details)
595cf52e
L
6300 {
6301 printf (_(" [Nr] Name\n"));
5477e8a0 6302 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6303 }
6304 else
6305 printf
6306 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6307 }
f7a99963
NC
6308 else
6309 {
5477e8a0 6310 if (do_section_details)
595cf52e
L
6311 {
6312 printf (_(" [Nr] Name\n"));
5477e8a0
L
6313 printf (_(" Type Address Offset Link\n"));
6314 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6315 }
6316 else
6317 {
6318 printf (_(" [Nr] Name Type Address Offset\n"));
6319 printf (_(" Size EntSize Flags Link Info Align\n"));
6320 }
f7a99963 6321 }
252b5132 6322
5477e8a0
L
6323 if (do_section_details)
6324 printf (_(" Flags\n"));
6325
dda8d76d
NC
6326 for (i = 0, section = filedata->section_headers;
6327 i < filedata->file_header.e_shnum;
b34976b6 6328 i++, section++)
252b5132 6329 {
dd905818
NC
6330 /* Run some sanity checks on the section header. */
6331
6332 /* Check the sh_link field. */
6333 switch (section->sh_type)
6334 {
285e3f99
AM
6335 case SHT_REL:
6336 case SHT_RELA:
6337 if (section->sh_link == 0
6338 && (filedata->file_header.e_type == ET_EXEC
6339 || filedata->file_header.e_type == ET_DYN))
6340 /* A dynamic relocation section where all entries use a
6341 zero symbol index need not specify a symtab section. */
6342 break;
6343 /* Fall through. */
dd905818
NC
6344 case SHT_SYMTAB_SHNDX:
6345 case SHT_GROUP:
6346 case SHT_HASH:
6347 case SHT_GNU_HASH:
6348 case SHT_GNU_versym:
285e3f99 6349 if (section->sh_link == 0
dda8d76d
NC
6350 || section->sh_link >= filedata->file_header.e_shnum
6351 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6352 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6353 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6354 i, section->sh_link);
6355 break;
6356
6357 case SHT_DYNAMIC:
6358 case SHT_SYMTAB:
6359 case SHT_DYNSYM:
6360 case SHT_GNU_verneed:
6361 case SHT_GNU_verdef:
6362 case SHT_GNU_LIBLIST:
285e3f99 6363 if (section->sh_link == 0
dda8d76d
NC
6364 || section->sh_link >= filedata->file_header.e_shnum
6365 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6366 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6367 i, section->sh_link);
6368 break;
6369
6370 case SHT_INIT_ARRAY:
6371 case SHT_FINI_ARRAY:
6372 case SHT_PREINIT_ARRAY:
6373 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6374 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6375 i, section->sh_link);
6376 break;
6377
6378 default:
6379 /* FIXME: Add support for target specific section types. */
6380#if 0 /* Currently we do not check other section types as there are too
6381 many special cases. Stab sections for example have a type
6382 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6383 section. */
6384 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6385 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6386 i, section->sh_link);
6387#endif
6388 break;
6389 }
6390
6391 /* Check the sh_info field. */
6392 switch (section->sh_type)
6393 {
6394 case SHT_REL:
6395 case SHT_RELA:
285e3f99
AM
6396 if (section->sh_info == 0
6397 && (filedata->file_header.e_type == ET_EXEC
6398 || filedata->file_header.e_type == ET_DYN))
6399 /* Dynamic relocations apply to segments, so they do not
6400 need to specify the section they relocate. */
6401 break;
6402 if (section->sh_info == 0
dda8d76d
NC
6403 || section->sh_info >= filedata->file_header.e_shnum
6404 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6405 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6406 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6407 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6408 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6409 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6410 /* FIXME: Are other section types valid ? */
dda8d76d 6411 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6412 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6413 i, section->sh_info);
dd905818
NC
6414 break;
6415
6416 case SHT_DYNAMIC:
6417 case SHT_HASH:
6418 case SHT_SYMTAB_SHNDX:
6419 case SHT_INIT_ARRAY:
6420 case SHT_FINI_ARRAY:
6421 case SHT_PREINIT_ARRAY:
6422 if (section->sh_info != 0)
6423 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6424 i, section->sh_info);
6425 break;
6426
6427 case SHT_GROUP:
6428 case SHT_SYMTAB:
6429 case SHT_DYNSYM:
6430 /* A symbol index - we assume that it is valid. */
6431 break;
6432
6433 default:
6434 /* FIXME: Add support for target specific section types. */
6435 if (section->sh_type == SHT_NOBITS)
6436 /* NOBITS section headers with non-zero sh_info fields can be
6437 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6438 information. The stripped sections have their headers
6439 preserved but their types set to SHT_NOBITS. So do not check
6440 this type of section. */
dd905818
NC
6441 ;
6442 else if (section->sh_flags & SHF_INFO_LINK)
6443 {
dda8d76d 6444 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6445 warn (_("[%2u]: Expected link to another section in info field"), i);
6446 }
a91e1603
L
6447 else if (section->sh_type < SHT_LOOS
6448 && (section->sh_flags & SHF_GNU_MBIND) == 0
6449 && section->sh_info != 0)
dd905818
NC
6450 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6451 i, section->sh_info);
6452 break;
6453 }
6454
3e6b6445 6455 /* Check the sh_size field. */
dda8d76d 6456 if (section->sh_size > filedata->file_size
3e6b6445
NC
6457 && section->sh_type != SHT_NOBITS
6458 && section->sh_type != SHT_NULL
6459 && section->sh_type < SHT_LOOS)
6460 warn (_("Size of section %u is larger than the entire file!\n"), i);
6461
7bfd842d 6462 printf (" [%2u] ", i);
5477e8a0 6463 if (do_section_details)
dda8d76d 6464 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6465 else
74e1a04b 6466 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6467
ea52a088 6468 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6469 get_section_type_name (filedata, section->sh_type));
0b4362b0 6470
f7a99963
NC
6471 if (is_32bit_elf)
6472 {
cfcac11d
NC
6473 const char * link_too_big = NULL;
6474
f7a99963 6475 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6476
f7a99963
NC
6477 printf ( " %6.6lx %6.6lx %2.2lx",
6478 (unsigned long) section->sh_offset,
6479 (unsigned long) section->sh_size,
6480 (unsigned long) section->sh_entsize);
d1133906 6481
5477e8a0
L
6482 if (do_section_details)
6483 fputs (" ", stdout);
6484 else
dda8d76d 6485 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6486
dda8d76d 6487 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6488 {
6489 link_too_big = "";
6490 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6491 an error but it can have special values in Solaris binaries. */
dda8d76d 6492 switch (filedata->file_header.e_machine)
cfcac11d 6493 {
caa83f8b 6494 case EM_386:
22abe556 6495 case EM_IAMCU:
caa83f8b 6496 case EM_X86_64:
7f502d6c 6497 case EM_L1OM:
7a9068fe 6498 case EM_K1OM:
cfcac11d
NC
6499 case EM_OLD_SPARCV9:
6500 case EM_SPARC32PLUS:
6501 case EM_SPARCV9:
6502 case EM_SPARC:
6503 if (section->sh_link == (SHN_BEFORE & 0xffff))
6504 link_too_big = "BEFORE";
6505 else if (section->sh_link == (SHN_AFTER & 0xffff))
6506 link_too_big = "AFTER";
6507 break;
6508 default:
6509 break;
6510 }
6511 }
6512
6513 if (do_section_details)
6514 {
6515 if (link_too_big != NULL && * link_too_big)
6516 printf ("<%s> ", link_too_big);
6517 else
6518 printf ("%2u ", section->sh_link);
6519 printf ("%3u %2lu\n", section->sh_info,
6520 (unsigned long) section->sh_addralign);
6521 }
6522 else
6523 printf ("%2u %3u %2lu\n",
6524 section->sh_link,
6525 section->sh_info,
6526 (unsigned long) section->sh_addralign);
6527
6528 if (link_too_big && ! * link_too_big)
6529 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6530 i, section->sh_link);
f7a99963 6531 }
d974e256
JJ
6532 else if (do_wide)
6533 {
6534 print_vma (section->sh_addr, LONG_HEX);
6535
6536 if ((long) section->sh_offset == section->sh_offset)
6537 printf (" %6.6lx", (unsigned long) section->sh_offset);
6538 else
6539 {
6540 putchar (' ');
6541 print_vma (section->sh_offset, LONG_HEX);
6542 }
6543
6544 if ((unsigned long) section->sh_size == section->sh_size)
6545 printf (" %6.6lx", (unsigned long) section->sh_size);
6546 else
6547 {
6548 putchar (' ');
6549 print_vma (section->sh_size, LONG_HEX);
6550 }
6551
6552 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6553 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6554 else
6555 {
6556 putchar (' ');
6557 print_vma (section->sh_entsize, LONG_HEX);
6558 }
6559
5477e8a0
L
6560 if (do_section_details)
6561 fputs (" ", stdout);
6562 else
dda8d76d 6563 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6564
72de5009 6565 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6566
6567 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6568 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6569 else
6570 {
6571 print_vma (section->sh_addralign, DEC);
6572 putchar ('\n');
6573 }
6574 }
5477e8a0 6575 else if (do_section_details)
595cf52e 6576 {
55cc53e9 6577 putchar (' ');
595cf52e
L
6578 print_vma (section->sh_addr, LONG_HEX);
6579 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6580 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6581 else
6582 {
6583 printf (" ");
6584 print_vma (section->sh_offset, LONG_HEX);
6585 }
72de5009 6586 printf (" %u\n ", section->sh_link);
595cf52e 6587 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6588 putchar (' ');
595cf52e
L
6589 print_vma (section->sh_entsize, LONG_HEX);
6590
72de5009
AM
6591 printf (" %-16u %lu\n",
6592 section->sh_info,
595cf52e
L
6593 (unsigned long) section->sh_addralign);
6594 }
f7a99963
NC
6595 else
6596 {
6597 putchar (' ');
6598 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6599 if ((long) section->sh_offset == section->sh_offset)
6600 printf (" %8.8lx", (unsigned long) section->sh_offset);
6601 else
6602 {
6603 printf (" ");
6604 print_vma (section->sh_offset, LONG_HEX);
6605 }
f7a99963
NC
6606 printf ("\n ");
6607 print_vma (section->sh_size, LONG_HEX);
6608 printf (" ");
6609 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6610
dda8d76d 6611 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6612
72de5009
AM
6613 printf (" %2u %3u %lu\n",
6614 section->sh_link,
6615 section->sh_info,
f7a99963
NC
6616 (unsigned long) section->sh_addralign);
6617 }
5477e8a0
L
6618
6619 if (do_section_details)
77115a4a 6620 {
dda8d76d 6621 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6622 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6623 {
6624 /* Minimum section size is 12 bytes for 32-bit compression
6625 header + 12 bytes for compressed data header. */
6626 unsigned char buf[24];
d8024a91 6627
77115a4a 6628 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6629 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6630 sizeof (buf), _("compression header")))
6631 {
6632 Elf_Internal_Chdr chdr;
d8024a91 6633
ebdf1ebf 6634 (void) get_compression_header (&chdr, buf, sizeof (buf));
d8024a91 6635
77115a4a
L
6636 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6637 printf (" ZLIB, ");
6638 else
6639 printf (_(" [<unknown>: 0x%x], "),
6640 chdr.ch_type);
6641 print_vma (chdr.ch_size, LONG_HEX);
6642 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6643 }
6644 }
6645 }
252b5132
RH
6646 }
6647
5477e8a0 6648 if (!do_section_details)
3dbcc61d 6649 {
9fb71ee4
NC
6650 /* The ordering of the letters shown here matches the ordering of the
6651 corresponding SHF_xxx values, and hence the order in which these
6652 letters will be displayed to the user. */
6653 printf (_("Key to Flags:\n\
6654 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6655 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6656 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
dda8d76d
NC
6657 if (filedata->file_header.e_machine == EM_X86_64
6658 || filedata->file_header.e_machine == EM_L1OM
6659 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 6660 printf (_("l (large), "));
dda8d76d 6661 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 6662 printf (_("y (purecode), "));
dda8d76d 6663 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 6664 printf (_("v (VLE), "));
9fb71ee4 6665 printf ("p (processor specific)\n");
0b4362b0 6666 }
d1133906 6667
32ec8896 6668 return TRUE;
252b5132
RH
6669}
6670
f5842774
L
6671static const char *
6672get_group_flags (unsigned int flags)
6673{
1449284b 6674 static char buff[128];
220453ec 6675
6d913794
NC
6676 if (flags == 0)
6677 return "";
6678 else if (flags == GRP_COMDAT)
6679 return "COMDAT ";
f5842774 6680
6d913794
NC
6681 snprintf (buff, 14, _("[0x%x: "), flags);
6682
6683 flags &= ~ GRP_COMDAT;
6684 if (flags & GRP_MASKOS)
6685 {
6686 strcat (buff, "<OS specific>");
6687 flags &= ~ GRP_MASKOS;
f5842774 6688 }
6d913794
NC
6689
6690 if (flags & GRP_MASKPROC)
6691 {
6692 strcat (buff, "<PROC specific>");
6693 flags &= ~ GRP_MASKPROC;
6694 }
6695
6696 if (flags)
6697 strcat (buff, "<unknown>");
6698
6699 strcat (buff, "]");
f5842774
L
6700 return buff;
6701}
6702
32ec8896 6703static bfd_boolean
dda8d76d 6704process_section_groups (Filedata * filedata)
f5842774 6705{
2cf0635d 6706 Elf_Internal_Shdr * section;
f5842774 6707 unsigned int i;
2cf0635d
NC
6708 struct group * group;
6709 Elf_Internal_Shdr * symtab_sec;
6710 Elf_Internal_Shdr * strtab_sec;
6711 Elf_Internal_Sym * symtab;
ba5cdace 6712 unsigned long num_syms;
2cf0635d 6713 char * strtab;
c256ffe7 6714 size_t strtab_size;
d1f5c6e3
L
6715
6716 /* Don't process section groups unless needed. */
6717 if (!do_unwind && !do_section_groups)
32ec8896 6718 return TRUE;
f5842774 6719
dda8d76d 6720 if (filedata->file_header.e_shnum == 0)
f5842774
L
6721 {
6722 if (do_section_groups)
82f2dbf7 6723 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 6724
32ec8896 6725 return TRUE;
f5842774
L
6726 }
6727
dda8d76d 6728 if (filedata->section_headers == NULL)
f5842774
L
6729 {
6730 error (_("Section headers are not available!\n"));
fa1908fd 6731 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 6732 return FALSE;
f5842774
L
6733 }
6734
dda8d76d 6735 section_headers_groups = (struct group **) calloc (filedata->file_header.e_shnum,
3f5e193b 6736 sizeof (struct group *));
e4b17d5c
L
6737
6738 if (section_headers_groups == NULL)
6739 {
8b73c356 6740 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 6741 filedata->file_header.e_shnum);
32ec8896 6742 return FALSE;
e4b17d5c
L
6743 }
6744
f5842774 6745 /* Scan the sections for the group section. */
d1f5c6e3 6746 group_count = 0;
dda8d76d
NC
6747 for (i = 0, section = filedata->section_headers;
6748 i < filedata->file_header.e_shnum;
f5842774 6749 i++, section++)
e4b17d5c
L
6750 if (section->sh_type == SHT_GROUP)
6751 group_count++;
6752
d1f5c6e3
L
6753 if (group_count == 0)
6754 {
6755 if (do_section_groups)
6756 printf (_("\nThere are no section groups in this file.\n"));
6757
32ec8896 6758 return TRUE;
d1f5c6e3
L
6759 }
6760
3f5e193b 6761 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
6762
6763 if (section_groups == NULL)
6764 {
8b73c356
NC
6765 error (_("Out of memory reading %lu groups\n"),
6766 (unsigned long) group_count);
32ec8896 6767 return FALSE;
e4b17d5c
L
6768 }
6769
d1f5c6e3
L
6770 symtab_sec = NULL;
6771 strtab_sec = NULL;
6772 symtab = NULL;
ba5cdace 6773 num_syms = 0;
d1f5c6e3 6774 strtab = NULL;
c256ffe7 6775 strtab_size = 0;
dda8d76d
NC
6776 for (i = 0, section = filedata->section_headers, group = section_groups;
6777 i < filedata->file_header.e_shnum;
e4b17d5c 6778 i++, section++)
f5842774
L
6779 {
6780 if (section->sh_type == SHT_GROUP)
6781 {
dda8d76d 6782 const char * name = printable_section_name (filedata, section);
74e1a04b 6783 const char * group_name;
2cf0635d
NC
6784 unsigned char * start;
6785 unsigned char * indices;
f5842774 6786 unsigned int entry, j, size;
2cf0635d
NC
6787 Elf_Internal_Shdr * sec;
6788 Elf_Internal_Sym * sym;
f5842774
L
6789
6790 /* Get the symbol table. */
dda8d76d
NC
6791 if (section->sh_link >= filedata->file_header.e_shnum
6792 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 6793 != SHT_SYMTAB))
f5842774
L
6794 {
6795 error (_("Bad sh_link in group section `%s'\n"), name);
6796 continue;
6797 }
d1f5c6e3
L
6798
6799 if (symtab_sec != sec)
6800 {
6801 symtab_sec = sec;
6802 if (symtab)
6803 free (symtab);
dda8d76d 6804 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 6805 }
f5842774 6806
dd24e3da
NC
6807 if (symtab == NULL)
6808 {
6809 error (_("Corrupt header in group section `%s'\n"), name);
6810 continue;
6811 }
6812
ba5cdace
NC
6813 if (section->sh_info >= num_syms)
6814 {
6815 error (_("Bad sh_info in group section `%s'\n"), name);
6816 continue;
6817 }
6818
f5842774
L
6819 sym = symtab + section->sh_info;
6820
6821 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
6822 {
4fbb74a6 6823 if (sym->st_shndx == 0
dda8d76d 6824 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
6825 {
6826 error (_("Bad sh_info in group section `%s'\n"), name);
6827 continue;
6828 }
ba2685cc 6829
dda8d76d 6830 group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
c256ffe7
JJ
6831 strtab_sec = NULL;
6832 if (strtab)
6833 free (strtab);
f5842774 6834 strtab = NULL;
c256ffe7 6835 strtab_size = 0;
f5842774
L
6836 }
6837 else
6838 {
6839 /* Get the string table. */
dda8d76d 6840 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
6841 {
6842 strtab_sec = NULL;
6843 if (strtab)
6844 free (strtab);
6845 strtab = NULL;
6846 strtab_size = 0;
6847 }
6848 else if (strtab_sec
dda8d76d 6849 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
6850 {
6851 strtab_sec = sec;
6852 if (strtab)
6853 free (strtab);
071436c6 6854
dda8d76d 6855 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
6856 1, strtab_sec->sh_size,
6857 _("string table"));
c256ffe7 6858 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 6859 }
c256ffe7 6860 group_name = sym->st_name < strtab_size
2b692964 6861 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
6862 }
6863
c9c1d674
EG
6864 /* PR 17531: file: loop. */
6865 if (section->sh_entsize > section->sh_size)
6866 {
6867 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 6868 printable_section_name (filedata, section),
8066deb1
AM
6869 (unsigned long) section->sh_entsize,
6870 (unsigned long) section->sh_size);
c9c1d674
EG
6871 break;
6872 }
6873
dda8d76d 6874 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
6875 1, section->sh_size,
6876 _("section data"));
59245841
NC
6877 if (start == NULL)
6878 continue;
f5842774
L
6879
6880 indices = start;
6881 size = (section->sh_size / section->sh_entsize) - 1;
6882 entry = byte_get (indices, 4);
6883 indices += 4;
e4b17d5c
L
6884
6885 if (do_section_groups)
6886 {
2b692964 6887 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 6888 get_group_flags (entry), i, name, group_name, size);
ba2685cc 6889
e4b17d5c
L
6890 printf (_(" [Index] Name\n"));
6891 }
6892
6893 group->group_index = i;
6894
f5842774
L
6895 for (j = 0; j < size; j++)
6896 {
2cf0635d 6897 struct group_list * g;
e4b17d5c 6898
f5842774
L
6899 entry = byte_get (indices, 4);
6900 indices += 4;
6901
dda8d76d 6902 if (entry >= filedata->file_header.e_shnum)
391cb864 6903 {
57028622
NC
6904 static unsigned num_group_errors = 0;
6905
6906 if (num_group_errors ++ < 10)
6907 {
6908 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 6909 entry, i, filedata->file_header.e_shnum - 1);
57028622 6910 if (num_group_errors == 10)
67ce483b 6911 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 6912 }
391cb864
L
6913 continue;
6914 }
391cb864 6915
4fbb74a6 6916 if (section_headers_groups [entry] != NULL)
e4b17d5c 6917 {
d1f5c6e3
L
6918 if (entry)
6919 {
57028622
NC
6920 static unsigned num_errs = 0;
6921
6922 if (num_errs ++ < 10)
6923 {
6924 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
6925 entry, i,
6926 section_headers_groups [entry]->group_index);
6927 if (num_errs == 10)
6928 warn (_("Further error messages about already contained group sections suppressed\n"));
6929 }
d1f5c6e3
L
6930 continue;
6931 }
6932 else
6933 {
6934 /* Intel C/C++ compiler may put section 0 in a
32ec8896 6935 section group. We just warn it the first time
d1f5c6e3 6936 and ignore it afterwards. */
32ec8896 6937 static bfd_boolean warned = FALSE;
d1f5c6e3
L
6938 if (!warned)
6939 {
6940 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 6941 section_headers_groups [entry]->group_index);
32ec8896 6942 warned = TRUE;
d1f5c6e3
L
6943 }
6944 }
e4b17d5c
L
6945 }
6946
4fbb74a6 6947 section_headers_groups [entry] = group;
e4b17d5c
L
6948
6949 if (do_section_groups)
6950 {
dda8d76d
NC
6951 sec = filedata->section_headers + entry;
6952 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
6953 }
6954
3f5e193b 6955 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
6956 g->section_index = entry;
6957 g->next = group->root;
6958 group->root = g;
f5842774
L
6959 }
6960
f5842774
L
6961 if (start)
6962 free (start);
e4b17d5c
L
6963
6964 group++;
f5842774
L
6965 }
6966 }
6967
d1f5c6e3
L
6968 if (symtab)
6969 free (symtab);
6970 if (strtab)
6971 free (strtab);
32ec8896 6972 return TRUE;
f5842774
L
6973}
6974
28f997cf
TG
6975/* Data used to display dynamic fixups. */
6976
6977struct ia64_vms_dynfixup
6978{
6979 bfd_vma needed_ident; /* Library ident number. */
6980 bfd_vma needed; /* Index in the dstrtab of the library name. */
6981 bfd_vma fixup_needed; /* Index of the library. */
6982 bfd_vma fixup_rela_cnt; /* Number of fixups. */
6983 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
6984};
6985
6986/* Data used to display dynamic relocations. */
6987
6988struct ia64_vms_dynimgrela
6989{
6990 bfd_vma img_rela_cnt; /* Number of relocations. */
6991 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
6992};
6993
6994/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
6995 library). */
6996
32ec8896 6997static bfd_boolean
dda8d76d
NC
6998dump_ia64_vms_dynamic_fixups (Filedata * filedata,
6999 struct ia64_vms_dynfixup * fixup,
7000 const char * strtab,
7001 unsigned int strtab_sz)
28f997cf 7002{
32ec8896 7003 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7004 long i;
32ec8896 7005 const char * lib_name;
28f997cf 7006
dda8d76d 7007 imfs = get_data (NULL, filedata, dynamic_addr + fixup->fixup_rela_off,
28f997cf
TG
7008 1, fixup->fixup_rela_cnt * sizeof (*imfs),
7009 _("dynamic section image fixups"));
7010 if (!imfs)
32ec8896 7011 return FALSE;
28f997cf
TG
7012
7013 if (fixup->needed < strtab_sz)
7014 lib_name = strtab + fixup->needed;
7015 else
7016 {
32ec8896 7017 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7018 (unsigned long) fixup->needed);
28f997cf
TG
7019 lib_name = "???";
7020 }
7021 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7022 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7023 printf
7024 (_("Seg Offset Type SymVec DataType\n"));
7025
7026 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7027 {
7028 unsigned int type;
7029 const char *rtype;
7030
7031 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7032 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7033 type = BYTE_GET (imfs [i].type);
7034 rtype = elf_ia64_reloc_type (type);
7035 if (rtype == NULL)
7036 printf (" 0x%08x ", type);
7037 else
7038 printf (" %-32s ", rtype);
7039 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7040 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7041 }
7042
7043 free (imfs);
32ec8896 7044 return TRUE;
28f997cf
TG
7045}
7046
7047/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7048
32ec8896 7049static bfd_boolean
dda8d76d 7050dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7051{
7052 Elf64_External_VMS_IMAGE_RELA *imrs;
7053 long i;
7054
dda8d76d 7055 imrs = get_data (NULL, filedata, dynamic_addr + imgrela->img_rela_off,
28f997cf 7056 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 7057 _("dynamic section image relocations"));
28f997cf 7058 if (!imrs)
32ec8896 7059 return FALSE;
28f997cf
TG
7060
7061 printf (_("\nImage relocs\n"));
7062 printf
7063 (_("Seg Offset Type Addend Seg Sym Off\n"));
7064
7065 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7066 {
7067 unsigned int type;
7068 const char *rtype;
7069
7070 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7071 printf ("%08" BFD_VMA_FMT "x ",
7072 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7073 type = BYTE_GET (imrs [i].type);
7074 rtype = elf_ia64_reloc_type (type);
7075 if (rtype == NULL)
7076 printf ("0x%08x ", type);
7077 else
7078 printf ("%-31s ", rtype);
7079 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7080 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7081 printf ("%08" BFD_VMA_FMT "x\n",
7082 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7083 }
7084
7085 free (imrs);
32ec8896 7086 return TRUE;
28f997cf
TG
7087}
7088
7089/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7090
32ec8896 7091static bfd_boolean
dda8d76d 7092process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7093{
7094 struct ia64_vms_dynfixup fixup;
7095 struct ia64_vms_dynimgrela imgrela;
7096 Elf_Internal_Dyn *entry;
28f997cf
TG
7097 bfd_vma strtab_off = 0;
7098 bfd_vma strtab_sz = 0;
7099 char *strtab = NULL;
32ec8896 7100 bfd_boolean res = TRUE;
28f997cf
TG
7101
7102 memset (&fixup, 0, sizeof (fixup));
7103 memset (&imgrela, 0, sizeof (imgrela));
7104
7105 /* Note: the order of the entries is specified by the OpenVMS specs. */
7106 for (entry = dynamic_section;
7107 entry < dynamic_section + dynamic_nent;
7108 entry++)
7109 {
7110 switch (entry->d_tag)
7111 {
7112 case DT_IA_64_VMS_STRTAB_OFFSET:
7113 strtab_off = entry->d_un.d_val;
7114 break;
7115 case DT_STRSZ:
7116 strtab_sz = entry->d_un.d_val;
7117 if (strtab == NULL)
dda8d76d 7118 strtab = get_data (NULL, filedata, dynamic_addr + strtab_off,
28f997cf
TG
7119 1, strtab_sz, _("dynamic string section"));
7120 break;
7121
7122 case DT_IA_64_VMS_NEEDED_IDENT:
7123 fixup.needed_ident = entry->d_un.d_val;
7124 break;
7125 case DT_NEEDED:
7126 fixup.needed = entry->d_un.d_val;
7127 break;
7128 case DT_IA_64_VMS_FIXUP_NEEDED:
7129 fixup.fixup_needed = entry->d_un.d_val;
7130 break;
7131 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7132 fixup.fixup_rela_cnt = entry->d_un.d_val;
7133 break;
7134 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7135 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7136 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7137 res = FALSE;
28f997cf 7138 break;
28f997cf
TG
7139 case DT_IA_64_VMS_IMG_RELA_CNT:
7140 imgrela.img_rela_cnt = entry->d_un.d_val;
7141 break;
7142 case DT_IA_64_VMS_IMG_RELA_OFF:
7143 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7144 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7145 res = FALSE;
28f997cf
TG
7146 break;
7147
7148 default:
7149 break;
7150 }
7151 }
7152
7153 if (strtab != NULL)
7154 free (strtab);
7155
7156 return res;
7157}
7158
85b1c36d 7159static struct
566b0d53 7160{
2cf0635d 7161 const char * name;
566b0d53
L
7162 int reloc;
7163 int size;
7164 int rela;
32ec8896
NC
7165}
7166 dynamic_relocations [] =
566b0d53 7167{
32ec8896
NC
7168 { "REL", DT_REL, DT_RELSZ, FALSE },
7169 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7170 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7171};
7172
252b5132 7173/* Process the reloc section. */
18bd398b 7174
32ec8896 7175static bfd_boolean
dda8d76d 7176process_relocs (Filedata * filedata)
252b5132 7177{
b34976b6
AM
7178 unsigned long rel_size;
7179 unsigned long rel_offset;
252b5132 7180
252b5132 7181 if (!do_reloc)
32ec8896 7182 return TRUE;
252b5132
RH
7183
7184 if (do_using_dynamic)
7185 {
32ec8896 7186 int is_rela;
2cf0635d 7187 const char * name;
32ec8896 7188 bfd_boolean has_dynamic_reloc;
566b0d53 7189 unsigned int i;
0de14b54 7190
32ec8896 7191 has_dynamic_reloc = FALSE;
252b5132 7192
566b0d53 7193 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7194 {
566b0d53
L
7195 is_rela = dynamic_relocations [i].rela;
7196 name = dynamic_relocations [i].name;
7197 rel_size = dynamic_info [dynamic_relocations [i].size];
7198 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 7199
32ec8896
NC
7200 if (rel_size)
7201 has_dynamic_reloc = TRUE;
566b0d53
L
7202
7203 if (is_rela == UNKNOWN)
aa903cfb 7204 {
566b0d53
L
7205 if (dynamic_relocations [i].reloc == DT_JMPREL)
7206 switch (dynamic_info[DT_PLTREL])
7207 {
7208 case DT_REL:
7209 is_rela = FALSE;
7210 break;
7211 case DT_RELA:
7212 is_rela = TRUE;
7213 break;
7214 }
aa903cfb 7215 }
252b5132 7216
566b0d53
L
7217 if (rel_size)
7218 {
7219 printf
7220 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7221 name, rel_offset, rel_size);
252b5132 7222
dda8d76d
NC
7223 dump_relocations (filedata,
7224 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7225 rel_size,
566b0d53 7226 dynamic_symbols, num_dynamic_syms,
bb4d2ac2 7227 dynamic_strings, dynamic_strings_length,
32ec8896 7228 is_rela, TRUE /* is_dynamic */);
566b0d53 7229 }
252b5132 7230 }
566b0d53 7231
dda8d76d
NC
7232 if (is_ia64_vms (filedata))
7233 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7234 has_dynamic_reloc = TRUE;
28f997cf 7235
566b0d53 7236 if (! has_dynamic_reloc)
252b5132
RH
7237 printf (_("\nThere are no dynamic relocations in this file.\n"));
7238 }
7239 else
7240 {
2cf0635d 7241 Elf_Internal_Shdr * section;
b34976b6 7242 unsigned long i;
32ec8896 7243 bfd_boolean found = FALSE;
252b5132 7244
dda8d76d
NC
7245 for (i = 0, section = filedata->section_headers;
7246 i < filedata->file_header.e_shnum;
b34976b6 7247 i++, section++)
252b5132
RH
7248 {
7249 if ( section->sh_type != SHT_RELA
7250 && section->sh_type != SHT_REL)
7251 continue;
7252
7253 rel_offset = section->sh_offset;
7254 rel_size = section->sh_size;
7255
7256 if (rel_size)
7257 {
2cf0635d 7258 Elf_Internal_Shdr * strsec;
b34976b6 7259 int is_rela;
d3a49aa8 7260 unsigned long num_rela;
103f02d3 7261
252b5132
RH
7262 printf (_("\nRelocation section "));
7263
dda8d76d 7264 if (filedata->string_table == NULL)
19936277 7265 printf ("%d", section->sh_name);
252b5132 7266 else
dda8d76d 7267 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7268
d3a49aa8
AM
7269 num_rela = rel_size / section->sh_entsize;
7270 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7271 " at offset 0x%lx contains %lu entries:\n",
7272 num_rela),
7273 rel_offset, num_rela);
252b5132 7274
d79b3d50
NC
7275 is_rela = section->sh_type == SHT_RELA;
7276
4fbb74a6 7277 if (section->sh_link != 0
dda8d76d 7278 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7279 {
2cf0635d
NC
7280 Elf_Internal_Shdr * symsec;
7281 Elf_Internal_Sym * symtab;
d79b3d50 7282 unsigned long nsyms;
c256ffe7 7283 unsigned long strtablen = 0;
2cf0635d 7284 char * strtab = NULL;
57346661 7285
dda8d76d 7286 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7287 if (symsec->sh_type != SHT_SYMTAB
7288 && symsec->sh_type != SHT_DYNSYM)
7289 continue;
7290
dda8d76d 7291 symtab = GET_ELF_SYMBOLS (filedata, symsec, & nsyms);
252b5132 7292
af3fc3bc
AM
7293 if (symtab == NULL)
7294 continue;
252b5132 7295
4fbb74a6 7296 if (symsec->sh_link != 0
dda8d76d 7297 && symsec->sh_link < filedata->file_header.e_shnum)
c256ffe7 7298 {
dda8d76d 7299 strsec = filedata->section_headers + symsec->sh_link;
103f02d3 7300
dda8d76d 7301 strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
071436c6
NC
7302 1, strsec->sh_size,
7303 _("string table"));
c256ffe7
JJ
7304 strtablen = strtab == NULL ? 0 : strsec->sh_size;
7305 }
252b5132 7306
dda8d76d 7307 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7308 symtab, nsyms, strtab, strtablen,
7309 is_rela,
7310 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
7311 if (strtab)
7312 free (strtab);
7313 free (symtab);
7314 }
7315 else
dda8d76d 7316 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7317 NULL, 0, NULL, 0, is_rela,
7318 FALSE /* is_dynamic */);
252b5132 7319
32ec8896 7320 found = TRUE;
252b5132
RH
7321 }
7322 }
7323
7324 if (! found)
45ac8f4f
NC
7325 {
7326 /* Users sometimes forget the -D option, so try to be helpful. */
7327 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7328 {
7329 if (dynamic_info [dynamic_relocations [i].size])
7330 {
7331 printf (_("\nThere are no static relocations in this file."));
7332 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7333
7334 break;
7335 }
7336 }
7337 if (i == ARRAY_SIZE (dynamic_relocations))
7338 printf (_("\nThere are no relocations in this file.\n"));
7339 }
252b5132
RH
7340 }
7341
32ec8896 7342 return TRUE;
252b5132
RH
7343}
7344
4d6ed7c8
NC
7345/* An absolute address consists of a section and an offset. If the
7346 section is NULL, the offset itself is the address, otherwise, the
7347 address equals to LOAD_ADDRESS(section) + offset. */
7348
7349struct absaddr
948f632f
DA
7350{
7351 unsigned short section;
7352 bfd_vma offset;
7353};
4d6ed7c8 7354
1949de15
L
7355#define ABSADDR(a) \
7356 ((a).section \
dda8d76d 7357 ? filedata->section_headers [(a).section].sh_addr + (a).offset \
1949de15
L
7358 : (a).offset)
7359
948f632f
DA
7360/* Find the nearest symbol at or below ADDR. Returns the symbol
7361 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7362
4d6ed7c8 7363static void
dda8d76d
NC
7364find_symbol_for_address (Filedata * filedata,
7365 Elf_Internal_Sym * symtab,
7366 unsigned long nsyms,
7367 const char * strtab,
7368 unsigned long strtab_size,
7369 struct absaddr addr,
7370 const char ** symname,
7371 bfd_vma * offset)
4d6ed7c8 7372{
d3ba0551 7373 bfd_vma dist = 0x100000;
2cf0635d 7374 Elf_Internal_Sym * sym;
948f632f
DA
7375 Elf_Internal_Sym * beg;
7376 Elf_Internal_Sym * end;
2cf0635d 7377 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7378
0b6ae522 7379 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7380 beg = symtab;
7381 end = symtab + nsyms;
0b6ae522 7382
948f632f 7383 while (beg < end)
4d6ed7c8 7384 {
948f632f
DA
7385 bfd_vma value;
7386
7387 sym = beg + (end - beg) / 2;
0b6ae522 7388
948f632f 7389 value = sym->st_value;
0b6ae522
DJ
7390 REMOVE_ARCH_BITS (value);
7391
948f632f 7392 if (sym->st_name != 0
4d6ed7c8 7393 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7394 && addr.offset >= value
7395 && addr.offset - value < dist)
4d6ed7c8
NC
7396 {
7397 best = sym;
0b6ae522 7398 dist = addr.offset - value;
4d6ed7c8
NC
7399 if (!dist)
7400 break;
7401 }
948f632f
DA
7402
7403 if (addr.offset < value)
7404 end = sym;
7405 else
7406 beg = sym + 1;
4d6ed7c8 7407 }
1b31d05e 7408
4d6ed7c8
NC
7409 if (best)
7410 {
57346661 7411 *symname = (best->st_name >= strtab_size
2b692964 7412 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7413 *offset = dist;
7414 return;
7415 }
1b31d05e 7416
4d6ed7c8
NC
7417 *symname = NULL;
7418 *offset = addr.offset;
7419}
7420
32ec8896 7421static /* signed */ int
948f632f
DA
7422symcmp (const void *p, const void *q)
7423{
7424 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7425 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7426
7427 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7428}
7429
7430/* Process the unwind section. */
7431
7432#include "unwind-ia64.h"
7433
7434struct ia64_unw_table_entry
7435{
7436 struct absaddr start;
7437 struct absaddr end;
7438 struct absaddr info;
7439};
7440
7441struct ia64_unw_aux_info
7442{
32ec8896
NC
7443 struct ia64_unw_table_entry * table; /* Unwind table. */
7444 unsigned long table_len; /* Length of unwind table. */
7445 unsigned char * info; /* Unwind info. */
7446 unsigned long info_size; /* Size of unwind info. */
7447 bfd_vma info_addr; /* Starting address of unwind info. */
7448 bfd_vma seg_base; /* Starting address of segment. */
7449 Elf_Internal_Sym * symtab; /* The symbol table. */
7450 unsigned long nsyms; /* Number of symbols. */
7451 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7452 unsigned long nfuns; /* Number of entries in funtab. */
7453 char * strtab; /* The string table. */
7454 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7455};
7456
32ec8896 7457static bfd_boolean
dda8d76d 7458dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7459{
2cf0635d 7460 struct ia64_unw_table_entry * tp;
948f632f 7461 unsigned long j, nfuns;
4d6ed7c8 7462 int in_body;
32ec8896 7463 bfd_boolean res = TRUE;
7036c0e1 7464
948f632f
DA
7465 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7466 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7467 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7468 aux->funtab[nfuns++] = aux->symtab[j];
7469 aux->nfuns = nfuns;
7470 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7471
4d6ed7c8
NC
7472 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7473 {
7474 bfd_vma stamp;
7475 bfd_vma offset;
2cf0635d
NC
7476 const unsigned char * dp;
7477 const unsigned char * head;
53774b7e 7478 const unsigned char * end;
2cf0635d 7479 const char * procname;
4d6ed7c8 7480
dda8d76d 7481 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7482 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7483
7484 fputs ("\n<", stdout);
7485
7486 if (procname)
7487 {
7488 fputs (procname, stdout);
7489
7490 if (offset)
7491 printf ("+%lx", (unsigned long) offset);
7492 }
7493
7494 fputs (">: [", stdout);
7495 print_vma (tp->start.offset, PREFIX_HEX);
7496 fputc ('-', stdout);
7497 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7498 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7499 (unsigned long) (tp->info.offset - aux->seg_base));
7500
53774b7e
NC
7501 /* PR 17531: file: 86232b32. */
7502 if (aux->info == NULL)
7503 continue;
7504
7505 /* PR 17531: file: 0997b4d1. */
7506 if ((ABSADDR (tp->info) - aux->info_addr) >= aux->info_size)
7507 {
7508 warn (_("Invalid offset %lx in table entry %ld\n"),
7509 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7510 res = FALSE;
53774b7e
NC
7511 continue;
7512 }
7513
1949de15 7514 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 7515 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7516
86f55779 7517 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7518 (unsigned) UNW_VER (stamp),
7519 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7520 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7521 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7522 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7523
7524 if (UNW_VER (stamp) != 1)
7525 {
2b692964 7526 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7527 continue;
7528 }
7529
7530 in_body = 0;
53774b7e
NC
7531 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7532 /* PR 17531: file: 16ceda89. */
7533 if (end > aux->info + aux->info_size)
7534 end = aux->info + aux->info_size;
7535 for (dp = head + 8; dp < end;)
b4477bc8 7536 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7537 }
948f632f
DA
7538
7539 free (aux->funtab);
32ec8896
NC
7540
7541 return res;
4d6ed7c8
NC
7542}
7543
53774b7e 7544static bfd_boolean
dda8d76d
NC
7545slurp_ia64_unwind_table (Filedata * filedata,
7546 struct ia64_unw_aux_info * aux,
7547 Elf_Internal_Shdr * sec)
4d6ed7c8 7548{
89fac5e3 7549 unsigned long size, nrelas, i;
2cf0635d
NC
7550 Elf_Internal_Phdr * seg;
7551 struct ia64_unw_table_entry * tep;
7552 Elf_Internal_Shdr * relsec;
7553 Elf_Internal_Rela * rela;
7554 Elf_Internal_Rela * rp;
7555 unsigned char * table;
7556 unsigned char * tp;
7557 Elf_Internal_Sym * sym;
7558 const char * relname;
4d6ed7c8 7559
53774b7e
NC
7560 aux->table_len = 0;
7561
4d6ed7c8
NC
7562 /* First, find the starting address of the segment that includes
7563 this section: */
7564
dda8d76d 7565 if (filedata->file_header.e_phnum)
4d6ed7c8 7566 {
dda8d76d 7567 if (! get_program_headers (filedata))
53774b7e 7568 return FALSE;
4d6ed7c8 7569
dda8d76d
NC
7570 for (seg = filedata->program_headers;
7571 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7572 ++seg)
4d6ed7c8
NC
7573 {
7574 if (seg->p_type != PT_LOAD)
7575 continue;
7576
7577 if (sec->sh_addr >= seg->p_vaddr
7578 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7579 {
7580 aux->seg_base = seg->p_vaddr;
7581 break;
7582 }
7583 }
4d6ed7c8
NC
7584 }
7585
7586 /* Second, build the unwind table from the contents of the unwind section: */
7587 size = sec->sh_size;
dda8d76d 7588 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7589 _("unwind table"));
a6e9f9df 7590 if (!table)
53774b7e 7591 return FALSE;
4d6ed7c8 7592
53774b7e 7593 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7594 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7595 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7596 tep = aux->table;
53774b7e
NC
7597
7598 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7599 {
7600 tep->start.section = SHN_UNDEF;
7601 tep->end.section = SHN_UNDEF;
7602 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7603 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7604 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7605 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7606 tep->start.offset += aux->seg_base;
7607 tep->end.offset += aux->seg_base;
7608 tep->info.offset += aux->seg_base;
7609 }
7610 free (table);
7611
41e92641 7612 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
7613 for (relsec = filedata->section_headers;
7614 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
7615 ++relsec)
7616 {
7617 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7618 || relsec->sh_info >= filedata->file_header.e_shnum
7619 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7620 continue;
7621
dda8d76d 7622 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 7623 & rela, & nrelas))
53774b7e
NC
7624 {
7625 free (aux->table);
7626 aux->table = NULL;
7627 aux->table_len = 0;
7628 return FALSE;
7629 }
4d6ed7c8
NC
7630
7631 for (rp = rela; rp < rela + nrelas; ++rp)
7632 {
4770fb94 7633 unsigned int sym_ndx;
726bd37d
AM
7634 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
7635 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 7636
82b1b41b
NC
7637 /* PR 17531: file: 9fa67536. */
7638 if (relname == NULL)
7639 {
726bd37d 7640 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
7641 continue;
7642 }
948f632f 7643
0112cd26 7644 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7645 {
82b1b41b 7646 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7647 continue;
7648 }
7649
89fac5e3 7650 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7651
53774b7e
NC
7652 /* PR 17531: file: 5bc8d9bf. */
7653 if (i >= aux->table_len)
7654 {
7655 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7656 continue;
7657 }
7658
4770fb94
AM
7659 sym_ndx = get_reloc_symindex (rp->r_info);
7660 if (sym_ndx >= aux->nsyms)
7661 {
7662 warn (_("Skipping reloc with invalid symbol index: %u\n"),
7663 sym_ndx);
7664 continue;
7665 }
7666 sym = aux->symtab + sym_ndx;
7667
53774b7e 7668 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7669 {
7670 case 0:
7671 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7672 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7673 break;
7674 case 1:
7675 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7676 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7677 break;
7678 case 2:
7679 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7680 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7681 break;
7682 default:
7683 break;
7684 }
7685 }
7686
7687 free (rela);
7688 }
7689
53774b7e 7690 return TRUE;
4d6ed7c8
NC
7691}
7692
32ec8896 7693static bfd_boolean
dda8d76d 7694ia64_process_unwind (Filedata * filedata)
4d6ed7c8 7695{
2cf0635d
NC
7696 Elf_Internal_Shdr * sec;
7697 Elf_Internal_Shdr * unwsec = NULL;
7698 Elf_Internal_Shdr * strsec;
89fac5e3 7699 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7700 struct ia64_unw_aux_info aux;
32ec8896 7701 bfd_boolean res = TRUE;
f1467e33 7702
4d6ed7c8
NC
7703 memset (& aux, 0, sizeof (aux));
7704
dda8d76d 7705 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 7706 {
c256ffe7 7707 if (sec->sh_type == SHT_SYMTAB
dda8d76d 7708 && sec->sh_link < filedata->file_header.e_shnum)
4d6ed7c8 7709 {
dda8d76d 7710 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
4d6ed7c8 7711
dda8d76d 7712 strsec = filedata->section_headers + sec->sh_link;
4082ef84
NC
7713 if (aux.strtab != NULL)
7714 {
7715 error (_("Multiple auxillary string tables encountered\n"));
7716 free (aux.strtab);
32ec8896 7717 res = FALSE;
4082ef84 7718 }
dda8d76d 7719 aux.strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
3f5e193b
NC
7720 1, strsec->sh_size,
7721 _("string table"));
c256ffe7 7722 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
7723 }
7724 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
7725 unwcount++;
7726 }
7727
7728 if (!unwcount)
7729 printf (_("\nThere are no unwind sections in this file.\n"));
7730
7731 while (unwcount-- > 0)
7732 {
2cf0635d 7733 char * suffix;
579f31ac
JJ
7734 size_t len, len2;
7735
dda8d76d
NC
7736 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
7737 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
7738 if (sec->sh_type == SHT_IA_64_UNWIND)
7739 {
7740 unwsec = sec;
7741 break;
7742 }
4082ef84
NC
7743 /* We have already counted the number of SHT_IA64_UNWIND
7744 sections so the loop above should never fail. */
7745 assert (unwsec != NULL);
579f31ac
JJ
7746
7747 unwstart = i + 1;
7748 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
7749
e4b17d5c
L
7750 if ((unwsec->sh_flags & SHF_GROUP) != 0)
7751 {
7752 /* We need to find which section group it is in. */
4082ef84 7753 struct group_list * g;
e4b17d5c 7754
4082ef84
NC
7755 if (section_headers_groups == NULL
7756 || section_headers_groups [i] == NULL)
dda8d76d 7757 i = filedata->file_header.e_shnum;
4082ef84 7758 else
e4b17d5c 7759 {
4082ef84 7760 g = section_headers_groups [i]->root;
18bd398b 7761
4082ef84
NC
7762 for (; g != NULL; g = g->next)
7763 {
dda8d76d 7764 sec = filedata->section_headers + g->section_index;
e4b17d5c 7765
4082ef84
NC
7766 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
7767 break;
7768 }
7769
7770 if (g == NULL)
dda8d76d 7771 i = filedata->file_header.e_shnum;
4082ef84 7772 }
e4b17d5c 7773 }
18bd398b 7774 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 7775 {
18bd398b 7776 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
7777 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
7778 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7779 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7780 ++i, ++sec)
18bd398b
NC
7781 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
7782 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7783 break;
7784 }
7785 else
7786 {
7787 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 7788 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
7789 len = sizeof (ELF_STRING_ia64_unwind) - 1;
7790 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
7791 suffix = "";
18bd398b 7792 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 7793 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7794 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7795 ++i, ++sec)
18bd398b
NC
7796 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
7797 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7798 break;
7799 }
7800
dda8d76d 7801 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
7802 {
7803 printf (_("\nCould not find unwind info section for "));
7804
dda8d76d 7805 if (filedata->string_table == NULL)
579f31ac
JJ
7806 printf ("%d", unwsec->sh_name);
7807 else
dda8d76d 7808 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
7809 }
7810 else
4d6ed7c8 7811 {
4d6ed7c8 7812 aux.info_addr = sec->sh_addr;
dda8d76d 7813 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
7814 sec->sh_size,
7815 _("unwind info"));
59245841 7816 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 7817
579f31ac 7818 printf (_("\nUnwind section "));
4d6ed7c8 7819
dda8d76d 7820 if (filedata->string_table == NULL)
579f31ac
JJ
7821 printf ("%d", unwsec->sh_name);
7822 else
dda8d76d 7823 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 7824
579f31ac 7825 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 7826 (unsigned long) unwsec->sh_offset,
89fac5e3 7827 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 7828
dda8d76d 7829 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 7830 && aux.table_len > 0)
dda8d76d 7831 dump_ia64_unwind (filedata, & aux);
579f31ac
JJ
7832
7833 if (aux.table)
7834 free ((char *) aux.table);
7835 if (aux.info)
7836 free ((char *) aux.info);
7837 aux.table = NULL;
7838 aux.info = NULL;
7839 }
4d6ed7c8 7840 }
4d6ed7c8 7841
4d6ed7c8
NC
7842 if (aux.symtab)
7843 free (aux.symtab);
7844 if (aux.strtab)
7845 free ((char *) aux.strtab);
32ec8896
NC
7846
7847 return res;
4d6ed7c8
NC
7848}
7849
3f5e193b 7850struct hppa_unw_table_entry
32ec8896
NC
7851{
7852 struct absaddr start;
7853 struct absaddr end;
7854 unsigned int Cannot_unwind:1; /* 0 */
7855 unsigned int Millicode:1; /* 1 */
7856 unsigned int Millicode_save_sr0:1; /* 2 */
7857 unsigned int Region_description:2; /* 3..4 */
7858 unsigned int reserved1:1; /* 5 */
7859 unsigned int Entry_SR:1; /* 6 */
7860 unsigned int Entry_FR:4; /* Number saved 7..10 */
7861 unsigned int Entry_GR:5; /* Number saved 11..15 */
7862 unsigned int Args_stored:1; /* 16 */
7863 unsigned int Variable_Frame:1; /* 17 */
7864 unsigned int Separate_Package_Body:1; /* 18 */
7865 unsigned int Frame_Extension_Millicode:1; /* 19 */
7866 unsigned int Stack_Overflow_Check:1; /* 20 */
7867 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
7868 unsigned int Ada_Region:1; /* 22 */
7869 unsigned int cxx_info:1; /* 23 */
7870 unsigned int cxx_try_catch:1; /* 24 */
7871 unsigned int sched_entry_seq:1; /* 25 */
7872 unsigned int reserved2:1; /* 26 */
7873 unsigned int Save_SP:1; /* 27 */
7874 unsigned int Save_RP:1; /* 28 */
7875 unsigned int Save_MRP_in_frame:1; /* 29 */
7876 unsigned int extn_ptr_defined:1; /* 30 */
7877 unsigned int Cleanup_defined:1; /* 31 */
7878
7879 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
7880 unsigned int HP_UX_interrupt_marker:1; /* 1 */
7881 unsigned int Large_frame:1; /* 2 */
7882 unsigned int Pseudo_SP_Set:1; /* 3 */
7883 unsigned int reserved4:1; /* 4 */
7884 unsigned int Total_frame_size:27; /* 5..31 */
7885};
3f5e193b 7886
57346661 7887struct hppa_unw_aux_info
948f632f 7888{
32ec8896
NC
7889 struct hppa_unw_table_entry * table; /* Unwind table. */
7890 unsigned long table_len; /* Length of unwind table. */
7891 bfd_vma seg_base; /* Starting address of segment. */
7892 Elf_Internal_Sym * symtab; /* The symbol table. */
7893 unsigned long nsyms; /* Number of symbols. */
7894 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7895 unsigned long nfuns; /* Number of entries in funtab. */
7896 char * strtab; /* The string table. */
7897 unsigned long strtab_size; /* Size of string table. */
948f632f 7898};
57346661 7899
32ec8896 7900static bfd_boolean
dda8d76d 7901dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 7902{
2cf0635d 7903 struct hppa_unw_table_entry * tp;
948f632f 7904 unsigned long j, nfuns;
32ec8896 7905 bfd_boolean res = TRUE;
948f632f
DA
7906
7907 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7908 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7909 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7910 aux->funtab[nfuns++] = aux->symtab[j];
7911 aux->nfuns = nfuns;
7912 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 7913
57346661
AM
7914 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7915 {
7916 bfd_vma offset;
2cf0635d 7917 const char * procname;
57346661 7918
dda8d76d 7919 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
7920 aux->strtab_size, tp->start, &procname,
7921 &offset);
7922
7923 fputs ("\n<", stdout);
7924
7925 if (procname)
7926 {
7927 fputs (procname, stdout);
7928
7929 if (offset)
7930 printf ("+%lx", (unsigned long) offset);
7931 }
7932
7933 fputs (">: [", stdout);
7934 print_vma (tp->start.offset, PREFIX_HEX);
7935 fputc ('-', stdout);
7936 print_vma (tp->end.offset, PREFIX_HEX);
7937 printf ("]\n\t");
7938
18bd398b
NC
7939#define PF(_m) if (tp->_m) printf (#_m " ");
7940#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
7941 PF(Cannot_unwind);
7942 PF(Millicode);
7943 PF(Millicode_save_sr0);
18bd398b 7944 /* PV(Region_description); */
57346661
AM
7945 PF(Entry_SR);
7946 PV(Entry_FR);
7947 PV(Entry_GR);
7948 PF(Args_stored);
7949 PF(Variable_Frame);
7950 PF(Separate_Package_Body);
7951 PF(Frame_Extension_Millicode);
7952 PF(Stack_Overflow_Check);
7953 PF(Two_Instruction_SP_Increment);
7954 PF(Ada_Region);
7955 PF(cxx_info);
7956 PF(cxx_try_catch);
7957 PF(sched_entry_seq);
7958 PF(Save_SP);
7959 PF(Save_RP);
7960 PF(Save_MRP_in_frame);
7961 PF(extn_ptr_defined);
7962 PF(Cleanup_defined);
7963 PF(MPE_XL_interrupt_marker);
7964 PF(HP_UX_interrupt_marker);
7965 PF(Large_frame);
7966 PF(Pseudo_SP_Set);
7967 PV(Total_frame_size);
7968#undef PF
7969#undef PV
7970 }
7971
18bd398b 7972 printf ("\n");
948f632f
DA
7973
7974 free (aux->funtab);
32ec8896
NC
7975
7976 return res;
57346661
AM
7977}
7978
32ec8896 7979static bfd_boolean
dda8d76d
NC
7980slurp_hppa_unwind_table (Filedata * filedata,
7981 struct hppa_unw_aux_info * aux,
7982 Elf_Internal_Shdr * sec)
57346661 7983{
1c0751b2 7984 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
7985 Elf_Internal_Phdr * seg;
7986 struct hppa_unw_table_entry * tep;
7987 Elf_Internal_Shdr * relsec;
7988 Elf_Internal_Rela * rela;
7989 Elf_Internal_Rela * rp;
7990 unsigned char * table;
7991 unsigned char * tp;
7992 Elf_Internal_Sym * sym;
7993 const char * relname;
57346661 7994
57346661
AM
7995 /* First, find the starting address of the segment that includes
7996 this section. */
dda8d76d 7997 if (filedata->file_header.e_phnum)
57346661 7998 {
dda8d76d 7999 if (! get_program_headers (filedata))
32ec8896 8000 return FALSE;
57346661 8001
dda8d76d
NC
8002 for (seg = filedata->program_headers;
8003 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8004 ++seg)
8005 {
8006 if (seg->p_type != PT_LOAD)
8007 continue;
8008
8009 if (sec->sh_addr >= seg->p_vaddr
8010 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8011 {
8012 aux->seg_base = seg->p_vaddr;
8013 break;
8014 }
8015 }
8016 }
8017
8018 /* Second, build the unwind table from the contents of the unwind
8019 section. */
8020 size = sec->sh_size;
dda8d76d 8021 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8022 _("unwind table"));
57346661 8023 if (!table)
32ec8896 8024 return FALSE;
57346661 8025
1c0751b2
DA
8026 unw_ent_size = 16;
8027 nentries = size / unw_ent_size;
8028 size = unw_ent_size * nentries;
57346661 8029
3f5e193b
NC
8030 tep = aux->table = (struct hppa_unw_table_entry *)
8031 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8032
1c0751b2 8033 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8034 {
8035 unsigned int tmp1, tmp2;
8036
8037 tep->start.section = SHN_UNDEF;
8038 tep->end.section = SHN_UNDEF;
8039
1c0751b2
DA
8040 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8041 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8042 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8043 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8044
8045 tep->start.offset += aux->seg_base;
8046 tep->end.offset += aux->seg_base;
57346661
AM
8047
8048 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8049 tep->Millicode = (tmp1 >> 30) & 0x1;
8050 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8051 tep->Region_description = (tmp1 >> 27) & 0x3;
8052 tep->reserved1 = (tmp1 >> 26) & 0x1;
8053 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8054 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8055 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8056 tep->Args_stored = (tmp1 >> 15) & 0x1;
8057 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8058 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8059 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8060 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8061 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8062 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8063 tep->cxx_info = (tmp1 >> 8) & 0x1;
8064 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8065 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8066 tep->reserved2 = (tmp1 >> 5) & 0x1;
8067 tep->Save_SP = (tmp1 >> 4) & 0x1;
8068 tep->Save_RP = (tmp1 >> 3) & 0x1;
8069 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8070 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8071 tep->Cleanup_defined = tmp1 & 0x1;
8072
8073 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8074 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8075 tep->Large_frame = (tmp2 >> 29) & 0x1;
8076 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8077 tep->reserved4 = (tmp2 >> 27) & 0x1;
8078 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8079 }
8080 free (table);
8081
8082 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8083 for (relsec = filedata->section_headers;
8084 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8085 ++relsec)
8086 {
8087 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8088 || relsec->sh_info >= filedata->file_header.e_shnum
8089 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8090 continue;
8091
dda8d76d 8092 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8093 & rela, & nrelas))
32ec8896 8094 return FALSE;
57346661
AM
8095
8096 for (rp = rela; rp < rela + nrelas; ++rp)
8097 {
4770fb94 8098 unsigned int sym_ndx;
726bd37d
AM
8099 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8100 relname = elf_hppa_reloc_type (r_type);
57346661 8101
726bd37d
AM
8102 if (relname == NULL)
8103 {
8104 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8105 continue;
8106 }
8107
57346661 8108 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 8109 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661 8110 {
726bd37d 8111 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8112 continue;
8113 }
8114
8115 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8116 if (i >= aux->table_len)
8117 {
8118 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8119 continue;
8120 }
57346661 8121
4770fb94
AM
8122 sym_ndx = get_reloc_symindex (rp->r_info);
8123 if (sym_ndx >= aux->nsyms)
8124 {
8125 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8126 sym_ndx);
8127 continue;
8128 }
8129 sym = aux->symtab + sym_ndx;
8130
43f6cd05 8131 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8132 {
8133 case 0:
8134 aux->table[i].start.section = sym->st_shndx;
1e456d54 8135 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8136 break;
8137 case 1:
8138 aux->table[i].end.section = sym->st_shndx;
1e456d54 8139 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8140 break;
8141 default:
8142 break;
8143 }
8144 }
8145
8146 free (rela);
8147 }
8148
1c0751b2 8149 aux->table_len = nentries;
57346661 8150
32ec8896 8151 return TRUE;
57346661
AM
8152}
8153
32ec8896 8154static bfd_boolean
dda8d76d 8155hppa_process_unwind (Filedata * filedata)
57346661 8156{
57346661 8157 struct hppa_unw_aux_info aux;
2cf0635d
NC
8158 Elf_Internal_Shdr * unwsec = NULL;
8159 Elf_Internal_Shdr * strsec;
8160 Elf_Internal_Shdr * sec;
18bd398b 8161 unsigned long i;
32ec8896 8162 bfd_boolean res = TRUE;
57346661 8163
dda8d76d 8164 if (filedata->string_table == NULL)
32ec8896 8165 return FALSE;
1b31d05e
NC
8166
8167 memset (& aux, 0, sizeof (aux));
57346661 8168
dda8d76d 8169 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8170 {
c256ffe7 8171 if (sec->sh_type == SHT_SYMTAB
dda8d76d 8172 && sec->sh_link < filedata->file_header.e_shnum)
57346661 8173 {
dda8d76d 8174 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
57346661 8175
dda8d76d 8176 strsec = filedata->section_headers + sec->sh_link;
4082ef84
NC
8177 if (aux.strtab != NULL)
8178 {
8179 error (_("Multiple auxillary string tables encountered\n"));
8180 free (aux.strtab);
32ec8896 8181 res = FALSE;
4082ef84 8182 }
dda8d76d 8183 aux.strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
3f5e193b
NC
8184 1, strsec->sh_size,
8185 _("string table"));
c256ffe7 8186 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 8187 }
18bd398b 8188 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8189 unwsec = sec;
8190 }
8191
8192 if (!unwsec)
8193 printf (_("\nThere are no unwind sections in this file.\n"));
8194
dda8d76d 8195 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8196 {
18bd398b 8197 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8198 {
43f6cd05 8199 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8200
d3a49aa8
AM
8201 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8202 "contains %lu entry:\n",
8203 "\nUnwind section '%s' at offset 0x%lx "
8204 "contains %lu entries:\n",
8205 num_unwind),
dda8d76d 8206 printable_section_name (filedata, sec),
57346661 8207 (unsigned long) sec->sh_offset,
d3a49aa8 8208 num_unwind);
57346661 8209
dda8d76d 8210 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896 8211 res = FALSE;
66b09c7e
S
8212
8213 if (res && aux.table_len > 0)
32ec8896 8214 {
dda8d76d 8215 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8216 res = FALSE;
8217 }
57346661
AM
8218
8219 if (aux.table)
8220 free ((char *) aux.table);
8221 aux.table = NULL;
8222 }
8223 }
8224
8225 if (aux.symtab)
8226 free (aux.symtab);
8227 if (aux.strtab)
8228 free ((char *) aux.strtab);
32ec8896
NC
8229
8230 return res;
57346661
AM
8231}
8232
0b6ae522
DJ
8233struct arm_section
8234{
a734115a
NC
8235 unsigned char * data; /* The unwind data. */
8236 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8237 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8238 unsigned long nrelas; /* The number of relocations. */
8239 unsigned int rel_type; /* REL or RELA ? */
8240 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8241};
8242
8243struct arm_unw_aux_info
8244{
dda8d76d 8245 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8246 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8247 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8248 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8249 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8250 char * strtab; /* The file's string table. */
8251 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8252};
8253
8254static const char *
dda8d76d
NC
8255arm_print_vma_and_name (Filedata * filedata,
8256 struct arm_unw_aux_info * aux,
8257 bfd_vma fn,
8258 struct absaddr addr)
0b6ae522
DJ
8259{
8260 const char *procname;
8261 bfd_vma sym_offset;
8262
8263 if (addr.section == SHN_UNDEF)
8264 addr.offset = fn;
8265
dda8d76d 8266 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8267 aux->strtab_size, addr, &procname,
8268 &sym_offset);
8269
8270 print_vma (fn, PREFIX_HEX);
8271
8272 if (procname)
8273 {
8274 fputs (" <", stdout);
8275 fputs (procname, stdout);
8276
8277 if (sym_offset)
8278 printf ("+0x%lx", (unsigned long) sym_offset);
8279 fputc ('>', stdout);
8280 }
8281
8282 return procname;
8283}
8284
8285static void
8286arm_free_section (struct arm_section *arm_sec)
8287{
8288 if (arm_sec->data != NULL)
8289 free (arm_sec->data);
8290
8291 if (arm_sec->rela != NULL)
8292 free (arm_sec->rela);
8293}
8294
a734115a
NC
8295/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8296 cached section and install SEC instead.
8297 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8298 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8299 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8300 relocation's offset in ADDR.
1b31d05e
NC
8301 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8302 into the string table of the symbol associated with the reloc. If no
8303 reloc was applied store -1 there.
8304 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8305
8306static bfd_boolean
dda8d76d
NC
8307get_unwind_section_word (Filedata * filedata,
8308 struct arm_unw_aux_info * aux,
1b31d05e
NC
8309 struct arm_section * arm_sec,
8310 Elf_Internal_Shdr * sec,
8311 bfd_vma word_offset,
8312 unsigned int * wordp,
8313 struct absaddr * addr,
8314 bfd_vma * sym_name)
0b6ae522
DJ
8315{
8316 Elf_Internal_Rela *rp;
8317 Elf_Internal_Sym *sym;
8318 const char * relname;
8319 unsigned int word;
8320 bfd_boolean wrapped;
8321
e0a31db1
NC
8322 if (sec == NULL || arm_sec == NULL)
8323 return FALSE;
8324
0b6ae522
DJ
8325 addr->section = SHN_UNDEF;
8326 addr->offset = 0;
8327
1b31d05e
NC
8328 if (sym_name != NULL)
8329 *sym_name = (bfd_vma) -1;
8330
a734115a 8331 /* If necessary, update the section cache. */
0b6ae522
DJ
8332 if (sec != arm_sec->sec)
8333 {
8334 Elf_Internal_Shdr *relsec;
8335
8336 arm_free_section (arm_sec);
8337
8338 arm_sec->sec = sec;
dda8d76d 8339 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8340 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8341 arm_sec->rela = NULL;
8342 arm_sec->nrelas = 0;
8343
dda8d76d
NC
8344 for (relsec = filedata->section_headers;
8345 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8346 ++relsec)
8347 {
dda8d76d
NC
8348 if (relsec->sh_info >= filedata->file_header.e_shnum
8349 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8350 /* PR 15745: Check the section type as well. */
8351 || (relsec->sh_type != SHT_REL
8352 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8353 continue;
8354
a734115a 8355 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8356 if (relsec->sh_type == SHT_REL)
8357 {
dda8d76d 8358 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8359 relsec->sh_size,
8360 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8361 return FALSE;
0b6ae522 8362 }
1ae40aa4 8363 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8364 {
dda8d76d 8365 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8366 relsec->sh_size,
8367 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8368 return FALSE;
0b6ae522 8369 }
1ae40aa4 8370 break;
0b6ae522
DJ
8371 }
8372
8373 arm_sec->next_rela = arm_sec->rela;
8374 }
8375
a734115a 8376 /* If there is no unwind data we can do nothing. */
0b6ae522 8377 if (arm_sec->data == NULL)
a734115a 8378 return FALSE;
0b6ae522 8379
e0a31db1 8380 /* If the offset is invalid then fail. */
f32ba729
NC
8381 if (/* PR 21343 *//* PR 18879 */
8382 sec->sh_size < 4
8383 || word_offset > (sec->sh_size - 4)
1a915552 8384 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8385 return FALSE;
8386
a734115a 8387 /* Get the word at the required offset. */
0b6ae522
DJ
8388 word = byte_get (arm_sec->data + word_offset, 4);
8389
0eff7165
NC
8390 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8391 if (arm_sec->rela == NULL)
8392 {
8393 * wordp = word;
8394 return TRUE;
8395 }
8396
a734115a 8397 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8398 wrapped = FALSE;
8399 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8400 {
8401 bfd_vma prelval, offset;
8402
8403 if (rp->r_offset > word_offset && !wrapped)
8404 {
8405 rp = arm_sec->rela;
8406 wrapped = TRUE;
8407 }
8408 if (rp->r_offset > word_offset)
8409 break;
8410
8411 if (rp->r_offset & 3)
8412 {
8413 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8414 (unsigned long) rp->r_offset);
8415 continue;
8416 }
8417
8418 if (rp->r_offset < word_offset)
8419 continue;
8420
74e1a04b
NC
8421 /* PR 17531: file: 027-161405-0.004 */
8422 if (aux->symtab == NULL)
8423 continue;
8424
0b6ae522
DJ
8425 if (arm_sec->rel_type == SHT_REL)
8426 {
8427 offset = word & 0x7fffffff;
8428 if (offset & 0x40000000)
8429 offset |= ~ (bfd_vma) 0x7fffffff;
8430 }
a734115a 8431 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8432 offset = rp->r_addend;
a734115a 8433 else
74e1a04b
NC
8434 {
8435 error (_("Unknown section relocation type %d encountered\n"),
8436 arm_sec->rel_type);
8437 break;
8438 }
0b6ae522 8439
071436c6
NC
8440 /* PR 17531 file: 027-1241568-0.004. */
8441 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8442 {
8443 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8444 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8445 break;
8446 }
8447
8448 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8449 offset += sym->st_value;
8450 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8451
a734115a 8452 /* Check that we are processing the expected reloc type. */
dda8d76d 8453 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8454 {
8455 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8456 if (relname == NULL)
8457 {
8458 warn (_("Skipping unknown ARM relocation type: %d\n"),
8459 (int) ELF32_R_TYPE (rp->r_info));
8460 continue;
8461 }
a734115a
NC
8462
8463 if (streq (relname, "R_ARM_NONE"))
8464 continue;
0b4362b0 8465
a734115a
NC
8466 if (! streq (relname, "R_ARM_PREL31"))
8467 {
071436c6 8468 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8469 continue;
8470 }
8471 }
dda8d76d 8472 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8473 {
8474 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8475 if (relname == NULL)
8476 {
8477 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8478 (int) ELF32_R_TYPE (rp->r_info));
8479 continue;
8480 }
0b4362b0 8481
a734115a
NC
8482 if (streq (relname, "R_C6000_NONE"))
8483 continue;
8484
8485 if (! streq (relname, "R_C6000_PREL31"))
8486 {
071436c6 8487 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8488 continue;
8489 }
8490
8491 prelval >>= 1;
8492 }
8493 else
74e1a04b
NC
8494 {
8495 /* This function currently only supports ARM and TI unwinders. */
8496 warn (_("Only TI and ARM unwinders are currently supported\n"));
8497 break;
8498 }
fa197c1c 8499
0b6ae522
DJ
8500 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8501 addr->section = sym->st_shndx;
8502 addr->offset = offset;
74e1a04b 8503
1b31d05e
NC
8504 if (sym_name)
8505 * sym_name = sym->st_name;
0b6ae522
DJ
8506 break;
8507 }
8508
8509 *wordp = word;
8510 arm_sec->next_rela = rp;
8511
a734115a 8512 return TRUE;
0b6ae522
DJ
8513}
8514
a734115a
NC
8515static const char *tic6x_unwind_regnames[16] =
8516{
0b4362b0
RM
8517 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8518 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8519 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8520};
fa197c1c 8521
0b6ae522 8522static void
fa197c1c 8523decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8524{
fa197c1c
PB
8525 int i;
8526
8527 for (i = 12; mask; mask >>= 1, i--)
8528 {
8529 if (mask & 1)
8530 {
8531 fputs (tic6x_unwind_regnames[i], stdout);
8532 if (mask > 1)
8533 fputs (", ", stdout);
8534 }
8535 }
8536}
0b6ae522
DJ
8537
8538#define ADVANCE \
8539 if (remaining == 0 && more_words) \
8540 { \
8541 data_offset += 4; \
dda8d76d 8542 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8543 data_offset, & word, & addr, NULL)) \
32ec8896 8544 return FALSE; \
0b6ae522
DJ
8545 remaining = 4; \
8546 more_words--; \
8547 } \
8548
8549#define GET_OP(OP) \
8550 ADVANCE; \
8551 if (remaining) \
8552 { \
8553 remaining--; \
8554 (OP) = word >> 24; \
8555 word <<= 8; \
8556 } \
8557 else \
8558 { \
2b692964 8559 printf (_("[Truncated opcode]\n")); \
32ec8896 8560 return FALSE; \
0b6ae522 8561 } \
cc5914eb 8562 printf ("0x%02x ", OP)
0b6ae522 8563
32ec8896 8564static bfd_boolean
dda8d76d
NC
8565decode_arm_unwind_bytecode (Filedata * filedata,
8566 struct arm_unw_aux_info * aux,
948f632f
DA
8567 unsigned int word,
8568 unsigned int remaining,
8569 unsigned int more_words,
8570 bfd_vma data_offset,
8571 Elf_Internal_Shdr * data_sec,
8572 struct arm_section * data_arm_sec)
fa197c1c
PB
8573{
8574 struct absaddr addr;
32ec8896 8575 bfd_boolean res = TRUE;
0b6ae522
DJ
8576
8577 /* Decode the unwinding instructions. */
8578 while (1)
8579 {
8580 unsigned int op, op2;
8581
8582 ADVANCE;
8583 if (remaining == 0)
8584 break;
8585 remaining--;
8586 op = word >> 24;
8587 word <<= 8;
8588
cc5914eb 8589 printf (" 0x%02x ", op);
0b6ae522
DJ
8590
8591 if ((op & 0xc0) == 0x00)
8592 {
8593 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8594
cc5914eb 8595 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8596 }
8597 else if ((op & 0xc0) == 0x40)
8598 {
8599 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8600
cc5914eb 8601 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8602 }
8603 else if ((op & 0xf0) == 0x80)
8604 {
8605 GET_OP (op2);
8606 if (op == 0x80 && op2 == 0)
8607 printf (_("Refuse to unwind"));
8608 else
8609 {
8610 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8611 bfd_boolean first = TRUE;
0b6ae522 8612 int i;
2b692964 8613
0b6ae522
DJ
8614 printf ("pop {");
8615 for (i = 0; i < 12; i++)
8616 if (mask & (1 << i))
8617 {
8618 if (first)
32ec8896 8619 first = FALSE;
0b6ae522
DJ
8620 else
8621 printf (", ");
8622 printf ("r%d", 4 + i);
8623 }
8624 printf ("}");
8625 }
8626 }
8627 else if ((op & 0xf0) == 0x90)
8628 {
8629 if (op == 0x9d || op == 0x9f)
8630 printf (_(" [Reserved]"));
8631 else
cc5914eb 8632 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8633 }
8634 else if ((op & 0xf0) == 0xa0)
8635 {
8636 int end = 4 + (op & 0x07);
32ec8896 8637 bfd_boolean first = TRUE;
0b6ae522 8638 int i;
61865e30 8639
0b6ae522
DJ
8640 printf (" pop {");
8641 for (i = 4; i <= end; i++)
8642 {
8643 if (first)
32ec8896 8644 first = FALSE;
0b6ae522
DJ
8645 else
8646 printf (", ");
8647 printf ("r%d", i);
8648 }
8649 if (op & 0x08)
8650 {
1b31d05e 8651 if (!first)
0b6ae522
DJ
8652 printf (", ");
8653 printf ("r14");
8654 }
8655 printf ("}");
8656 }
8657 else if (op == 0xb0)
8658 printf (_(" finish"));
8659 else if (op == 0xb1)
8660 {
8661 GET_OP (op2);
8662 if (op2 == 0 || (op2 & 0xf0) != 0)
8663 printf (_("[Spare]"));
8664 else
8665 {
8666 unsigned int mask = op2 & 0x0f;
32ec8896 8667 bfd_boolean first = TRUE;
0b6ae522 8668 int i;
61865e30 8669
0b6ae522
DJ
8670 printf ("pop {");
8671 for (i = 0; i < 12; i++)
8672 if (mask & (1 << i))
8673 {
8674 if (first)
32ec8896 8675 first = FALSE;
0b6ae522
DJ
8676 else
8677 printf (", ");
8678 printf ("r%d", i);
8679 }
8680 printf ("}");
8681 }
8682 }
8683 else if (op == 0xb2)
8684 {
b115cf96 8685 unsigned char buf[9];
0b6ae522
DJ
8686 unsigned int i, len;
8687 unsigned long offset;
61865e30 8688
b115cf96 8689 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8690 {
8691 GET_OP (buf[i]);
8692 if ((buf[i] & 0x80) == 0)
8693 break;
8694 }
4082ef84 8695 if (i == sizeof (buf))
32ec8896
NC
8696 {
8697 error (_("corrupt change to vsp"));
8698 res = FALSE;
8699 }
4082ef84
NC
8700 else
8701 {
8702 offset = read_uleb128 (buf, &len, buf + i + 1);
8703 assert (len == i + 1);
8704 offset = offset * 4 + 0x204;
8705 printf ("vsp = vsp + %ld", offset);
8706 }
0b6ae522 8707 }
61865e30 8708 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8709 {
61865e30
NC
8710 unsigned int first, last;
8711
8712 GET_OP (op2);
8713 first = op2 >> 4;
8714 last = op2 & 0x0f;
8715 if (op == 0xc8)
8716 first = first + 16;
8717 printf ("pop {D%d", first);
8718 if (last)
8719 printf ("-D%d", first + last);
8720 printf ("}");
8721 }
8722 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
8723 {
8724 unsigned int count = op & 0x07;
8725
8726 printf ("pop {D8");
8727 if (count)
8728 printf ("-D%d", 8 + count);
8729 printf ("}");
8730 }
8731 else if (op >= 0xc0 && op <= 0xc5)
8732 {
8733 unsigned int count = op & 0x07;
8734
8735 printf (" pop {wR10");
8736 if (count)
8737 printf ("-wR%d", 10 + count);
8738 printf ("}");
8739 }
8740 else if (op == 0xc6)
8741 {
8742 unsigned int first, last;
8743
8744 GET_OP (op2);
8745 first = op2 >> 4;
8746 last = op2 & 0x0f;
8747 printf ("pop {wR%d", first);
8748 if (last)
8749 printf ("-wR%d", first + last);
8750 printf ("}");
8751 }
8752 else if (op == 0xc7)
8753 {
8754 GET_OP (op2);
8755 if (op2 == 0 || (op2 & 0xf0) != 0)
8756 printf (_("[Spare]"));
0b6ae522
DJ
8757 else
8758 {
61865e30 8759 unsigned int mask = op2 & 0x0f;
32ec8896 8760 bfd_boolean first = TRUE;
61865e30
NC
8761 int i;
8762
8763 printf ("pop {");
8764 for (i = 0; i < 4; i++)
8765 if (mask & (1 << i))
8766 {
8767 if (first)
32ec8896 8768 first = FALSE;
61865e30
NC
8769 else
8770 printf (", ");
8771 printf ("wCGR%d", i);
8772 }
8773 printf ("}");
0b6ae522
DJ
8774 }
8775 }
61865e30 8776 else
32ec8896
NC
8777 {
8778 printf (_(" [unsupported opcode]"));
8779 res = FALSE;
8780 }
8781
0b6ae522
DJ
8782 printf ("\n");
8783 }
32ec8896
NC
8784
8785 return res;
fa197c1c
PB
8786}
8787
32ec8896 8788static bfd_boolean
dda8d76d
NC
8789decode_tic6x_unwind_bytecode (Filedata * filedata,
8790 struct arm_unw_aux_info * aux,
948f632f
DA
8791 unsigned int word,
8792 unsigned int remaining,
8793 unsigned int more_words,
8794 bfd_vma data_offset,
8795 Elf_Internal_Shdr * data_sec,
8796 struct arm_section * data_arm_sec)
fa197c1c
PB
8797{
8798 struct absaddr addr;
8799
8800 /* Decode the unwinding instructions. */
8801 while (1)
8802 {
8803 unsigned int op, op2;
8804
8805 ADVANCE;
8806 if (remaining == 0)
8807 break;
8808 remaining--;
8809 op = word >> 24;
8810 word <<= 8;
8811
9cf03b7e 8812 printf (" 0x%02x ", op);
fa197c1c
PB
8813
8814 if ((op & 0xc0) == 0x00)
8815 {
8816 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 8817 printf (" sp = sp + %d", offset);
fa197c1c
PB
8818 }
8819 else if ((op & 0xc0) == 0x80)
8820 {
8821 GET_OP (op2);
8822 if (op == 0x80 && op2 == 0)
8823 printf (_("Refuse to unwind"));
8824 else
8825 {
8826 unsigned int mask = ((op & 0x1f) << 8) | op2;
8827 if (op & 0x20)
8828 printf ("pop compact {");
8829 else
8830 printf ("pop {");
8831
8832 decode_tic6x_unwind_regmask (mask);
8833 printf("}");
8834 }
8835 }
8836 else if ((op & 0xf0) == 0xc0)
8837 {
8838 unsigned int reg;
8839 unsigned int nregs;
8840 unsigned int i;
8841 const char *name;
a734115a
NC
8842 struct
8843 {
32ec8896
NC
8844 unsigned int offset;
8845 unsigned int reg;
fa197c1c
PB
8846 } regpos[16];
8847
8848 /* Scan entire instruction first so that GET_OP output is not
8849 interleaved with disassembly. */
8850 nregs = 0;
8851 for (i = 0; nregs < (op & 0xf); i++)
8852 {
8853 GET_OP (op2);
8854 reg = op2 >> 4;
8855 if (reg != 0xf)
8856 {
8857 regpos[nregs].offset = i * 2;
8858 regpos[nregs].reg = reg;
8859 nregs++;
8860 }
8861
8862 reg = op2 & 0xf;
8863 if (reg != 0xf)
8864 {
8865 regpos[nregs].offset = i * 2 + 1;
8866 regpos[nregs].reg = reg;
8867 nregs++;
8868 }
8869 }
8870
8871 printf (_("pop frame {"));
18344509 8872 if (nregs == 0)
fa197c1c 8873 {
18344509
NC
8874 printf (_("*corrupt* - no registers specified"));
8875 }
8876 else
8877 {
8878 reg = nregs - 1;
8879 for (i = i * 2; i > 0; i--)
fa197c1c 8880 {
18344509
NC
8881 if (regpos[reg].offset == i - 1)
8882 {
8883 name = tic6x_unwind_regnames[regpos[reg].reg];
8884 if (reg > 0)
8885 reg--;
8886 }
8887 else
8888 name = _("[pad]");
fa197c1c 8889
18344509
NC
8890 fputs (name, stdout);
8891 if (i > 1)
8892 printf (", ");
8893 }
fa197c1c
PB
8894 }
8895
8896 printf ("}");
8897 }
8898 else if (op == 0xd0)
8899 printf (" MOV FP, SP");
8900 else if (op == 0xd1)
8901 printf (" __c6xabi_pop_rts");
8902 else if (op == 0xd2)
8903 {
8904 unsigned char buf[9];
8905 unsigned int i, len;
8906 unsigned long offset;
a734115a 8907
fa197c1c
PB
8908 for (i = 0; i < sizeof (buf); i++)
8909 {
8910 GET_OP (buf[i]);
8911 if ((buf[i] & 0x80) == 0)
8912 break;
8913 }
0eff7165
NC
8914 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
8915 if (i == sizeof (buf))
8916 {
0eff7165 8917 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 8918 return FALSE;
0eff7165 8919 }
948f632f 8920
f6f0e17b 8921 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
8922 assert (len == i + 1);
8923 offset = offset * 8 + 0x408;
8924 printf (_("sp = sp + %ld"), offset);
8925 }
8926 else if ((op & 0xf0) == 0xe0)
8927 {
8928 if ((op & 0x0f) == 7)
8929 printf (" RETURN");
8930 else
8931 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
8932 }
8933 else
8934 {
8935 printf (_(" [unsupported opcode]"));
8936 }
8937 putchar ('\n');
8938 }
32ec8896
NC
8939
8940 return TRUE;
fa197c1c
PB
8941}
8942
8943static bfd_vma
dda8d76d 8944arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
8945{
8946 bfd_vma offset;
8947
8948 offset = word & 0x7fffffff;
8949 if (offset & 0x40000000)
8950 offset |= ~ (bfd_vma) 0x7fffffff;
8951
dda8d76d 8952 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
8953 offset <<= 1;
8954
8955 return offset + where;
8956}
8957
32ec8896 8958static bfd_boolean
dda8d76d
NC
8959decode_arm_unwind (Filedata * filedata,
8960 struct arm_unw_aux_info * aux,
1b31d05e
NC
8961 unsigned int word,
8962 unsigned int remaining,
8963 bfd_vma data_offset,
8964 Elf_Internal_Shdr * data_sec,
8965 struct arm_section * data_arm_sec)
fa197c1c
PB
8966{
8967 int per_index;
8968 unsigned int more_words = 0;
37e14bc3 8969 struct absaddr addr;
1b31d05e 8970 bfd_vma sym_name = (bfd_vma) -1;
97953bab 8971 bfd_boolean res = TRUE;
fa197c1c
PB
8972
8973 if (remaining == 0)
8974 {
1b31d05e
NC
8975 /* Fetch the first word.
8976 Note - when decoding an object file the address extracted
8977 here will always be 0. So we also pass in the sym_name
8978 parameter so that we can find the symbol associated with
8979 the personality routine. */
dda8d76d 8980 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 8981 & word, & addr, & sym_name))
32ec8896 8982 return FALSE;
1b31d05e 8983
fa197c1c
PB
8984 remaining = 4;
8985 }
8986
8987 if ((word & 0x80000000) == 0)
8988 {
8989 /* Expand prel31 for personality routine. */
8990 bfd_vma fn;
8991 const char *procname;
8992
dda8d76d 8993 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 8994 printf (_(" Personality routine: "));
1b31d05e
NC
8995 if (fn == 0
8996 && addr.section == SHN_UNDEF && addr.offset == 0
8997 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
8998 {
8999 procname = aux->strtab + sym_name;
9000 print_vma (fn, PREFIX_HEX);
9001 if (procname)
9002 {
9003 fputs (" <", stdout);
9004 fputs (procname, stdout);
9005 fputc ('>', stdout);
9006 }
9007 }
9008 else
dda8d76d 9009 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9010 fputc ('\n', stdout);
9011
9012 /* The GCC personality routines use the standard compact
9013 encoding, starting with one byte giving the number of
9014 words. */
9015 if (procname != NULL
9016 && (const_strneq (procname, "__gcc_personality_v0")
9017 || const_strneq (procname, "__gxx_personality_v0")
9018 || const_strneq (procname, "__gcj_personality_v0")
9019 || const_strneq (procname, "__gnu_objc_personality_v0")))
9020 {
9021 remaining = 0;
9022 more_words = 1;
9023 ADVANCE;
9024 if (!remaining)
9025 {
9026 printf (_(" [Truncated data]\n"));
32ec8896 9027 return FALSE;
fa197c1c
PB
9028 }
9029 more_words = word >> 24;
9030 word <<= 8;
9031 remaining--;
9032 per_index = -1;
9033 }
9034 else
32ec8896 9035 return TRUE;
fa197c1c
PB
9036 }
9037 else
9038 {
1b31d05e 9039 /* ARM EHABI Section 6.3:
0b4362b0 9040
1b31d05e 9041 An exception-handling table entry for the compact model looks like:
0b4362b0 9042
1b31d05e
NC
9043 31 30-28 27-24 23-0
9044 -- ----- ----- ----
9045 1 0 index Data for personalityRoutine[index] */
9046
dda8d76d 9047 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9048 && (word & 0x70000000))
32ec8896
NC
9049 {
9050 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
9051 res = FALSE;
9052 }
1b31d05e 9053
fa197c1c 9054 per_index = (word >> 24) & 0x7f;
1b31d05e 9055 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9056 if (per_index == 0)
9057 {
9058 more_words = 0;
9059 word <<= 8;
9060 remaining--;
9061 }
9062 else if (per_index < 3)
9063 {
9064 more_words = (word >> 16) & 0xff;
9065 word <<= 16;
9066 remaining -= 2;
9067 }
9068 }
9069
dda8d76d 9070 switch (filedata->file_header.e_machine)
fa197c1c
PB
9071 {
9072 case EM_ARM:
9073 if (per_index < 3)
9074 {
dda8d76d 9075 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9076 data_offset, data_sec, data_arm_sec))
9077 res = FALSE;
fa197c1c
PB
9078 }
9079 else
1b31d05e
NC
9080 {
9081 warn (_("Unknown ARM compact model index encountered\n"));
9082 printf (_(" [reserved]\n"));
32ec8896 9083 res = FALSE;
1b31d05e 9084 }
fa197c1c
PB
9085 break;
9086
9087 case EM_TI_C6000:
9088 if (per_index < 3)
9089 {
dda8d76d 9090 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9091 data_offset, data_sec, data_arm_sec))
9092 res = FALSE;
fa197c1c
PB
9093 }
9094 else if (per_index < 5)
9095 {
9096 if (((word >> 17) & 0x7f) == 0x7f)
9097 printf (_(" Restore stack from frame pointer\n"));
9098 else
9099 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9100 printf (_(" Registers restored: "));
9101 if (per_index == 4)
9102 printf (" (compact) ");
9103 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9104 putchar ('\n');
9105 printf (_(" Return register: %s\n"),
9106 tic6x_unwind_regnames[word & 0xf]);
9107 }
9108 else
1b31d05e 9109 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9110 break;
9111
9112 default:
74e1a04b 9113 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9114 filedata->file_header.e_machine);
32ec8896 9115 res = FALSE;
fa197c1c 9116 }
0b6ae522
DJ
9117
9118 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9119
9120 return res;
0b6ae522
DJ
9121}
9122
32ec8896 9123static bfd_boolean
dda8d76d
NC
9124dump_arm_unwind (Filedata * filedata,
9125 struct arm_unw_aux_info * aux,
9126 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9127{
9128 struct arm_section exidx_arm_sec, extab_arm_sec;
9129 unsigned int i, exidx_len;
948f632f 9130 unsigned long j, nfuns;
32ec8896 9131 bfd_boolean res = TRUE;
0b6ae522
DJ
9132
9133 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9134 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9135 exidx_len = exidx_sec->sh_size / 8;
9136
948f632f
DA
9137 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9138 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9139 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9140 aux->funtab[nfuns++] = aux->symtab[j];
9141 aux->nfuns = nfuns;
9142 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9143
0b6ae522
DJ
9144 for (i = 0; i < exidx_len; i++)
9145 {
9146 unsigned int exidx_fn, exidx_entry;
9147 struct absaddr fn_addr, entry_addr;
9148 bfd_vma fn;
9149
9150 fputc ('\n', stdout);
9151
dda8d76d 9152 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9153 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9154 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9155 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9156 {
948f632f 9157 free (aux->funtab);
1b31d05e
NC
9158 arm_free_section (& exidx_arm_sec);
9159 arm_free_section (& extab_arm_sec);
32ec8896 9160 return FALSE;
0b6ae522
DJ
9161 }
9162
83c257ca
NC
9163 /* ARM EHABI, Section 5:
9164 An index table entry consists of 2 words.
9165 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9166 if (exidx_fn & 0x80000000)
32ec8896
NC
9167 {
9168 warn (_("corrupt index table entry: %x\n"), exidx_fn);
9169 res = FALSE;
9170 }
83c257ca 9171
dda8d76d 9172 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9173
dda8d76d 9174 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9175 fputs (": ", stdout);
9176
9177 if (exidx_entry == 1)
9178 {
9179 print_vma (exidx_entry, PREFIX_HEX);
9180 fputs (" [cantunwind]\n", stdout);
9181 }
9182 else if (exidx_entry & 0x80000000)
9183 {
9184 print_vma (exidx_entry, PREFIX_HEX);
9185 fputc ('\n', stdout);
dda8d76d 9186 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9187 }
9188 else
9189 {
8f73510c 9190 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9191 Elf_Internal_Shdr *table_sec;
9192
9193 fputs ("@", stdout);
dda8d76d 9194 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9195 print_vma (table, PREFIX_HEX);
9196 printf ("\n");
9197
9198 /* Locate the matching .ARM.extab. */
9199 if (entry_addr.section != SHN_UNDEF
dda8d76d 9200 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9201 {
dda8d76d 9202 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9203 table_offset = entry_addr.offset;
1a915552
NC
9204 /* PR 18879 */
9205 if (table_offset > table_sec->sh_size
9206 || ((bfd_signed_vma) table_offset) < 0)
9207 {
9208 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9209 (unsigned long) table_offset,
dda8d76d 9210 printable_section_name (filedata, table_sec));
32ec8896 9211 res = FALSE;
1a915552
NC
9212 continue;
9213 }
0b6ae522
DJ
9214 }
9215 else
9216 {
dda8d76d 9217 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9218 if (table_sec != NULL)
9219 table_offset = table - table_sec->sh_addr;
9220 }
32ec8896 9221
0b6ae522
DJ
9222 if (table_sec == NULL)
9223 {
9224 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9225 (unsigned long) table);
32ec8896 9226 res = FALSE;
0b6ae522
DJ
9227 continue;
9228 }
32ec8896 9229
dda8d76d 9230 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9231 &extab_arm_sec))
9232 res = FALSE;
0b6ae522
DJ
9233 }
9234 }
9235
9236 printf ("\n");
9237
948f632f 9238 free (aux->funtab);
0b6ae522
DJ
9239 arm_free_section (&exidx_arm_sec);
9240 arm_free_section (&extab_arm_sec);
32ec8896
NC
9241
9242 return res;
0b6ae522
DJ
9243}
9244
fa197c1c 9245/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9246
32ec8896 9247static bfd_boolean
dda8d76d 9248arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9249{
9250 struct arm_unw_aux_info aux;
9251 Elf_Internal_Shdr *unwsec = NULL;
9252 Elf_Internal_Shdr *strsec;
9253 Elf_Internal_Shdr *sec;
9254 unsigned long i;
fa197c1c 9255 unsigned int sec_type;
32ec8896 9256 bfd_boolean res = TRUE;
0b6ae522 9257
dda8d76d 9258 switch (filedata->file_header.e_machine)
fa197c1c
PB
9259 {
9260 case EM_ARM:
9261 sec_type = SHT_ARM_EXIDX;
9262 break;
9263
9264 case EM_TI_C6000:
9265 sec_type = SHT_C6000_UNWIND;
9266 break;
9267
0b4362b0 9268 default:
74e1a04b 9269 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9270 filedata->file_header.e_machine);
32ec8896 9271 return FALSE;
fa197c1c
PB
9272 }
9273
dda8d76d 9274 if (filedata->string_table == NULL)
32ec8896 9275 return FALSE;
1b31d05e
NC
9276
9277 memset (& aux, 0, sizeof (aux));
dda8d76d 9278 aux.filedata = filedata;
0b6ae522 9279
dda8d76d 9280 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9281 {
dda8d76d 9282 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < filedata->file_header.e_shnum)
0b6ae522 9283 {
dda8d76d 9284 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
0b6ae522 9285
dda8d76d 9286 strsec = filedata->section_headers + sec->sh_link;
74e1a04b
NC
9287
9288 /* PR binutils/17531 file: 011-12666-0.004. */
9289 if (aux.strtab != NULL)
9290 {
4082ef84 9291 error (_("Multiple string tables found in file.\n"));
74e1a04b 9292 free (aux.strtab);
32ec8896 9293 res = FALSE;
74e1a04b 9294 }
dda8d76d 9295 aux.strtab = get_data (NULL, filedata, strsec->sh_offset,
0b6ae522
DJ
9296 1, strsec->sh_size, _("string table"));
9297 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
9298 }
fa197c1c 9299 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9300 unwsec = sec;
9301 }
9302
1b31d05e 9303 if (unwsec == NULL)
0b6ae522 9304 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9305 else
dda8d76d 9306 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9307 {
9308 if (sec->sh_type == sec_type)
9309 {
d3a49aa8
AM
9310 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9311 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9312 "contains %lu entry:\n",
9313 "\nUnwind section '%s' at offset 0x%lx "
9314 "contains %lu entries:\n",
9315 num_unwind),
dda8d76d 9316 printable_section_name (filedata, sec),
1b31d05e 9317 (unsigned long) sec->sh_offset,
d3a49aa8 9318 num_unwind);
0b6ae522 9319
dda8d76d 9320 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9321 res = FALSE;
1b31d05e
NC
9322 }
9323 }
0b6ae522
DJ
9324
9325 if (aux.symtab)
9326 free (aux.symtab);
9327 if (aux.strtab)
9328 free ((char *) aux.strtab);
32ec8896
NC
9329
9330 return res;
0b6ae522
DJ
9331}
9332
32ec8896 9333static bfd_boolean
dda8d76d 9334process_unwind (Filedata * filedata)
57346661 9335{
2cf0635d
NC
9336 struct unwind_handler
9337 {
32ec8896 9338 unsigned int machtype;
dda8d76d 9339 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9340 } handlers[] =
9341 {
0b6ae522 9342 { EM_ARM, arm_process_unwind },
57346661
AM
9343 { EM_IA_64, ia64_process_unwind },
9344 { EM_PARISC, hppa_process_unwind },
fa197c1c 9345 { EM_TI_C6000, arm_process_unwind },
32ec8896 9346 { 0, NULL }
57346661
AM
9347 };
9348 int i;
9349
9350 if (!do_unwind)
32ec8896 9351 return TRUE;
57346661
AM
9352
9353 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9354 if (filedata->file_header.e_machine == handlers[i].machtype)
9355 return handlers[i].handler (filedata);
57346661 9356
1b31d05e 9357 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9358 get_machine_name (filedata->file_header.e_machine));
32ec8896 9359 return TRUE;
57346661
AM
9360}
9361
37c18eed
SD
9362static void
9363dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9364{
9365 switch (entry->d_tag)
9366 {
9367 case DT_AARCH64_BTI_PLT:
1dbade74 9368 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9369 break;
9370 default:
9371 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9372 break;
9373 }
9374 putchar ('\n');
9375}
9376
252b5132 9377static void
2cf0635d 9378dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
9379{
9380 switch (entry->d_tag)
9381 {
9382 case DT_MIPS_FLAGS:
9383 if (entry->d_un.d_val == 0)
4b68bca3 9384 printf (_("NONE"));
252b5132
RH
9385 else
9386 {
9387 static const char * opts[] =
9388 {
9389 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9390 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9391 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9392 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9393 "RLD_ORDER_SAFE"
9394 };
9395 unsigned int cnt;
32ec8896 9396 bfd_boolean first = TRUE;
2b692964 9397
60bca95a 9398 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9399 if (entry->d_un.d_val & (1 << cnt))
9400 {
9401 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9402 first = FALSE;
252b5132 9403 }
252b5132
RH
9404 }
9405 break;
103f02d3 9406
252b5132 9407 case DT_MIPS_IVERSION:
d79b3d50 9408 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 9409 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 9410 else
76ca31c0
NC
9411 {
9412 char buf[40];
9413 sprintf_vma (buf, entry->d_un.d_ptr);
9414 /* Note: coded this way so that there is a single string for translation. */
9415 printf (_("<corrupt: %s>"), buf);
9416 }
252b5132 9417 break;
103f02d3 9418
252b5132
RH
9419 case DT_MIPS_TIME_STAMP:
9420 {
d5b07ef4 9421 char timebuf[128];
2cf0635d 9422 struct tm * tmp;
91d6fa6a 9423 time_t atime = entry->d_un.d_val;
82b1b41b 9424
91d6fa6a 9425 tmp = gmtime (&atime);
82b1b41b
NC
9426 /* PR 17531: file: 6accc532. */
9427 if (tmp == NULL)
9428 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9429 else
9430 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9431 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9432 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9433 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9434 }
9435 break;
103f02d3 9436
252b5132
RH
9437 case DT_MIPS_RLD_VERSION:
9438 case DT_MIPS_LOCAL_GOTNO:
9439 case DT_MIPS_CONFLICTNO:
9440 case DT_MIPS_LIBLISTNO:
9441 case DT_MIPS_SYMTABNO:
9442 case DT_MIPS_UNREFEXTNO:
9443 case DT_MIPS_HIPAGENO:
9444 case DT_MIPS_DELTA_CLASS_NO:
9445 case DT_MIPS_DELTA_INSTANCE_NO:
9446 case DT_MIPS_DELTA_RELOC_NO:
9447 case DT_MIPS_DELTA_SYM_NO:
9448 case DT_MIPS_DELTA_CLASSSYM_NO:
9449 case DT_MIPS_COMPACT_SIZE:
c69075ac 9450 print_vma (entry->d_un.d_val, DEC);
252b5132 9451 break;
103f02d3
UD
9452
9453 default:
4b68bca3 9454 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9455 }
4b68bca3 9456 putchar ('\n');
103f02d3
UD
9457}
9458
103f02d3 9459static void
2cf0635d 9460dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9461{
9462 switch (entry->d_tag)
9463 {
9464 case DT_HP_DLD_FLAGS:
9465 {
9466 static struct
9467 {
9468 long int bit;
2cf0635d 9469 const char * str;
5e220199
NC
9470 }
9471 flags[] =
9472 {
9473 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9474 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9475 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9476 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9477 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9478 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9479 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9480 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9481 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9482 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9483 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9484 { DT_HP_GST, "HP_GST" },
9485 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9486 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9487 { DT_HP_NODELETE, "HP_NODELETE" },
9488 { DT_HP_GROUP, "HP_GROUP" },
9489 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9490 };
32ec8896 9491 bfd_boolean first = TRUE;
5e220199 9492 size_t cnt;
f7a99963 9493 bfd_vma val = entry->d_un.d_val;
103f02d3 9494
60bca95a 9495 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9496 if (val & flags[cnt].bit)
30800947
NC
9497 {
9498 if (! first)
9499 putchar (' ');
9500 fputs (flags[cnt].str, stdout);
32ec8896 9501 first = FALSE;
30800947
NC
9502 val ^= flags[cnt].bit;
9503 }
76da6bbe 9504
103f02d3 9505 if (val != 0 || first)
f7a99963
NC
9506 {
9507 if (! first)
9508 putchar (' ');
9509 print_vma (val, HEX);
9510 }
103f02d3
UD
9511 }
9512 break;
76da6bbe 9513
252b5132 9514 default:
f7a99963
NC
9515 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9516 break;
252b5132 9517 }
35b1837e 9518 putchar ('\n');
252b5132
RH
9519}
9520
28f997cf
TG
9521#ifdef BFD64
9522
9523/* VMS vs Unix time offset and factor. */
9524
9525#define VMS_EPOCH_OFFSET 35067168000000000LL
9526#define VMS_GRANULARITY_FACTOR 10000000
9527
9528/* Display a VMS time in a human readable format. */
9529
9530static void
9531print_vms_time (bfd_int64_t vmstime)
9532{
9533 struct tm *tm;
9534 time_t unxtime;
9535
9536 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9537 tm = gmtime (&unxtime);
9538 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9539 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9540 tm->tm_hour, tm->tm_min, tm->tm_sec);
9541}
9542#endif /* BFD64 */
9543
ecc51f48 9544static void
2cf0635d 9545dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9546{
9547 switch (entry->d_tag)
9548 {
0de14b54 9549 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9550 /* First 3 slots reserved. */
ecc51f48
NC
9551 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9552 printf (" -- ");
9553 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9554 break;
9555
28f997cf
TG
9556 case DT_IA_64_VMS_LINKTIME:
9557#ifdef BFD64
9558 print_vms_time (entry->d_un.d_val);
9559#endif
9560 break;
9561
9562 case DT_IA_64_VMS_LNKFLAGS:
9563 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9564 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9565 printf (" CALL_DEBUG");
9566 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9567 printf (" NOP0BUFS");
9568 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9569 printf (" P0IMAGE");
9570 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9571 printf (" MKTHREADS");
9572 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9573 printf (" UPCALLS");
9574 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9575 printf (" IMGSTA");
9576 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9577 printf (" INITIALIZE");
9578 if (entry->d_un.d_val & VMS_LF_MAIN)
9579 printf (" MAIN");
9580 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9581 printf (" EXE_INIT");
9582 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9583 printf (" TBK_IN_IMG");
9584 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9585 printf (" DBG_IN_IMG");
9586 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9587 printf (" TBK_IN_DSF");
9588 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9589 printf (" DBG_IN_DSF");
9590 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9591 printf (" SIGNATURES");
9592 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9593 printf (" REL_SEG_OFF");
9594 break;
9595
bdf4d63a
JJ
9596 default:
9597 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9598 break;
ecc51f48 9599 }
bdf4d63a 9600 putchar ('\n');
ecc51f48
NC
9601}
9602
32ec8896 9603static bfd_boolean
dda8d76d 9604get_32bit_dynamic_section (Filedata * filedata)
252b5132 9605{
2cf0635d
NC
9606 Elf32_External_Dyn * edyn;
9607 Elf32_External_Dyn * ext;
9608 Elf_Internal_Dyn * entry;
103f02d3 9609
dda8d76d 9610 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata, dynamic_addr, 1,
3f5e193b 9611 dynamic_size, _("dynamic section"));
a6e9f9df 9612 if (!edyn)
32ec8896 9613 return FALSE;
103f02d3 9614
071436c6
NC
9615 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9616 might not have the luxury of section headers. Look for the DT_NULL
9617 terminator to determine the number of entries. */
ba2685cc 9618 for (ext = edyn, dynamic_nent = 0;
53c3012c 9619 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9620 ext++)
9621 {
9622 dynamic_nent++;
9623 if (BYTE_GET (ext->d_tag) == DT_NULL)
9624 break;
9625 }
252b5132 9626
3f5e193b
NC
9627 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9628 sizeof (* entry));
b2d38a17 9629 if (dynamic_section == NULL)
252b5132 9630 {
8b73c356
NC
9631 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9632 (unsigned long) dynamic_nent);
9ea033b2 9633 free (edyn);
32ec8896 9634 return FALSE;
9ea033b2 9635 }
252b5132 9636
fb514b26 9637 for (ext = edyn, entry = dynamic_section;
ba2685cc 9638 entry < dynamic_section + dynamic_nent;
fb514b26 9639 ext++, entry++)
9ea033b2 9640 {
fb514b26
AM
9641 entry->d_tag = BYTE_GET (ext->d_tag);
9642 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9643 }
9644
9ea033b2
NC
9645 free (edyn);
9646
32ec8896 9647 return TRUE;
9ea033b2
NC
9648}
9649
32ec8896 9650static bfd_boolean
dda8d76d 9651get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 9652{
2cf0635d
NC
9653 Elf64_External_Dyn * edyn;
9654 Elf64_External_Dyn * ext;
9655 Elf_Internal_Dyn * entry;
103f02d3 9656
071436c6 9657 /* Read in the data. */
dda8d76d 9658 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata, dynamic_addr, 1,
3f5e193b 9659 dynamic_size, _("dynamic section"));
a6e9f9df 9660 if (!edyn)
32ec8896 9661 return FALSE;
103f02d3 9662
071436c6
NC
9663 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9664 might not have the luxury of section headers. Look for the DT_NULL
9665 terminator to determine the number of entries. */
ba2685cc 9666 for (ext = edyn, dynamic_nent = 0;
53c3012c
AM
9667 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
9668 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9669 ext++)
9670 {
9671 dynamic_nent++;
66543521 9672 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9673 break;
9674 }
252b5132 9675
3f5e193b
NC
9676 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9677 sizeof (* entry));
b2d38a17 9678 if (dynamic_section == NULL)
252b5132 9679 {
8b73c356
NC
9680 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9681 (unsigned long) dynamic_nent);
252b5132 9682 free (edyn);
32ec8896 9683 return FALSE;
252b5132
RH
9684 }
9685
071436c6 9686 /* Convert from external to internal formats. */
fb514b26 9687 for (ext = edyn, entry = dynamic_section;
ba2685cc 9688 entry < dynamic_section + dynamic_nent;
fb514b26 9689 ext++, entry++)
252b5132 9690 {
66543521
AM
9691 entry->d_tag = BYTE_GET (ext->d_tag);
9692 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9693 }
9694
9695 free (edyn);
9696
32ec8896 9697 return TRUE;
9ea033b2
NC
9698}
9699
e9e44622
JJ
9700static void
9701print_dynamic_flags (bfd_vma flags)
d1133906 9702{
32ec8896 9703 bfd_boolean first = TRUE;
13ae64f3 9704
d1133906
NC
9705 while (flags)
9706 {
9707 bfd_vma flag;
9708
9709 flag = flags & - flags;
9710 flags &= ~ flag;
9711
e9e44622 9712 if (first)
32ec8896 9713 first = FALSE;
e9e44622
JJ
9714 else
9715 putc (' ', stdout);
13ae64f3 9716
d1133906
NC
9717 switch (flag)
9718 {
e9e44622
JJ
9719 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
9720 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
9721 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
9722 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
9723 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 9724 default: fputs (_("unknown"), stdout); break;
d1133906
NC
9725 }
9726 }
e9e44622 9727 puts ("");
d1133906
NC
9728}
9729
b2d38a17
NC
9730/* Parse and display the contents of the dynamic section. */
9731
32ec8896 9732static bfd_boolean
dda8d76d 9733process_dynamic_section (Filedata * filedata)
9ea033b2 9734{
2cf0635d 9735 Elf_Internal_Dyn * entry;
9ea033b2
NC
9736
9737 if (dynamic_size == 0)
9738 {
9739 if (do_dynamic)
b2d38a17 9740 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 9741
32ec8896 9742 return TRUE;
9ea033b2
NC
9743 }
9744
9745 if (is_32bit_elf)
9746 {
dda8d76d 9747 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
9748 return FALSE;
9749 }
9750 else
9751 {
dda8d76d 9752 if (! get_64bit_dynamic_section (filedata))
32ec8896 9753 return FALSE;
9ea033b2 9754 }
9ea033b2 9755
252b5132
RH
9756 /* Find the appropriate symbol table. */
9757 if (dynamic_symbols == NULL)
9758 {
86dba8ee
AM
9759 for (entry = dynamic_section;
9760 entry < dynamic_section + dynamic_nent;
9761 ++entry)
252b5132 9762 {
c8286bd1 9763 Elf_Internal_Shdr section;
252b5132
RH
9764
9765 if (entry->d_tag != DT_SYMTAB)
9766 continue;
9767
9768 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
9769
9770 /* Since we do not know how big the symbol table is,
9771 we default to reading in the entire file (!) and
9772 processing that. This is overkill, I know, but it
e3c8793a 9773 should work. */
dda8d76d
NC
9774 section.sh_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
9775 if ((bfd_size_type) section.sh_offset > filedata->file_size)
7296a62a
NC
9776 {
9777 /* See PR 21379 for a reproducer. */
9778 error (_("Invalid DT_SYMTAB entry: %lx"), (long) section.sh_offset);
9779 return FALSE;
9780 }
252b5132 9781
fb52b2f4
NC
9782 if (archive_file_offset != 0)
9783 section.sh_size = archive_file_size - section.sh_offset;
9784 else
dda8d76d 9785 section.sh_size = filedata->file_size - section.sh_offset;
252b5132 9786
9ea033b2 9787 if (is_32bit_elf)
9ad5cbcf 9788 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 9789 else
9ad5cbcf 9790 section.sh_entsize = sizeof (Elf64_External_Sym);
dda8d76d 9791 section.sh_name = filedata->string_table_length;
252b5132 9792
e3d39609
NC
9793 if (dynamic_symbols != NULL)
9794 {
9795 error (_("Multiple dynamic symbol table sections found\n"));
9796 free (dynamic_symbols);
9797 }
dda8d76d 9798 dynamic_symbols = GET_ELF_SYMBOLS (filedata, &section, & num_dynamic_syms);
19936277 9799 if (num_dynamic_syms < 1)
252b5132
RH
9800 {
9801 error (_("Unable to determine the number of symbols to load\n"));
9802 continue;
9803 }
252b5132
RH
9804 }
9805 }
9806
9807 /* Similarly find a string table. */
9808 if (dynamic_strings == NULL)
9809 {
86dba8ee
AM
9810 for (entry = dynamic_section;
9811 entry < dynamic_section + dynamic_nent;
9812 ++entry)
252b5132
RH
9813 {
9814 unsigned long offset;
b34976b6 9815 long str_tab_len;
252b5132
RH
9816
9817 if (entry->d_tag != DT_STRTAB)
9818 continue;
9819
9820 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
9821
9822 /* Since we do not know how big the string table is,
9823 we default to reading in the entire file (!) and
9824 processing that. This is overkill, I know, but it
e3c8793a 9825 should work. */
252b5132 9826
dda8d76d 9827 offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
fb52b2f4
NC
9828
9829 if (archive_file_offset != 0)
9830 str_tab_len = archive_file_size - offset;
9831 else
86c6c6df 9832 str_tab_len = filedata->file_size - offset;
252b5132
RH
9833
9834 if (str_tab_len < 1)
9835 {
9836 error
9837 (_("Unable to determine the length of the dynamic string table\n"));
9838 continue;
9839 }
9840
e3d39609
NC
9841 if (dynamic_strings != NULL)
9842 {
9843 error (_("Multiple dynamic string tables found\n"));
9844 free (dynamic_strings);
9845 }
9846
dda8d76d 9847 dynamic_strings = (char *) get_data (NULL, filedata, offset, 1,
3f5e193b
NC
9848 str_tab_len,
9849 _("dynamic string table"));
59245841 9850 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
9851 }
9852 }
9853
9854 /* And find the syminfo section if available. */
9855 if (dynamic_syminfo == NULL)
9856 {
3e8bba36 9857 unsigned long syminsz = 0;
252b5132 9858
86dba8ee
AM
9859 for (entry = dynamic_section;
9860 entry < dynamic_section + dynamic_nent;
9861 ++entry)
252b5132
RH
9862 {
9863 if (entry->d_tag == DT_SYMINENT)
9864 {
9865 /* Note: these braces are necessary to avoid a syntax
9866 error from the SunOS4 C compiler. */
049b0c3a
NC
9867 /* PR binutils/17531: A corrupt file can trigger this test.
9868 So do not use an assert, instead generate an error message. */
9869 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 9870 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 9871 (int) entry->d_un.d_val);
252b5132
RH
9872 }
9873 else if (entry->d_tag == DT_SYMINSZ)
9874 syminsz = entry->d_un.d_val;
9875 else if (entry->d_tag == DT_SYMINFO)
dda8d76d 9876 dynamic_syminfo_offset = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 9877 syminsz);
252b5132
RH
9878 }
9879
9880 if (dynamic_syminfo_offset != 0 && syminsz != 0)
9881 {
2cf0635d
NC
9882 Elf_External_Syminfo * extsyminfo;
9883 Elf_External_Syminfo * extsym;
9884 Elf_Internal_Syminfo * syminfo;
252b5132
RH
9885
9886 /* There is a syminfo section. Read the data. */
3f5e193b 9887 extsyminfo = (Elf_External_Syminfo *)
dda8d76d 9888 get_data (NULL, filedata, dynamic_syminfo_offset, 1, syminsz,
3f5e193b 9889 _("symbol information"));
a6e9f9df 9890 if (!extsyminfo)
32ec8896 9891 return FALSE;
252b5132 9892
e3d39609
NC
9893 if (dynamic_syminfo != NULL)
9894 {
9895 error (_("Multiple dynamic symbol information sections found\n"));
9896 free (dynamic_syminfo);
9897 }
3f5e193b 9898 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
9899 if (dynamic_syminfo == NULL)
9900 {
8b73c356
NC
9901 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
9902 (unsigned long) syminsz);
32ec8896 9903 return FALSE;
252b5132
RH
9904 }
9905
9906 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
9907 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
9908 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
9909 ++syminfo, ++extsym)
252b5132 9910 {
86dba8ee
AM
9911 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
9912 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
9913 }
9914
9915 free (extsyminfo);
9916 }
9917 }
9918
9919 if (do_dynamic && dynamic_addr)
d3a49aa8
AM
9920 printf (ngettext ("\nDynamic section at offset 0x%lx "
9921 "contains %lu entry:\n",
9922 "\nDynamic section at offset 0x%lx "
9923 "contains %lu entries:\n",
9924 dynamic_nent),
8b73c356 9925 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
9926 if (do_dynamic)
9927 printf (_(" Tag Type Name/Value\n"));
9928
86dba8ee
AM
9929 for (entry = dynamic_section;
9930 entry < dynamic_section + dynamic_nent;
9931 entry++)
252b5132
RH
9932 {
9933 if (do_dynamic)
f7a99963 9934 {
2cf0635d 9935 const char * dtype;
e699b9ff 9936
f7a99963
NC
9937 putchar (' ');
9938 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 9939 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 9940 printf (" (%s)%*s", dtype,
32ec8896 9941 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 9942 }
252b5132
RH
9943
9944 switch (entry->d_tag)
9945 {
d1133906
NC
9946 case DT_FLAGS:
9947 if (do_dynamic)
e9e44622 9948 print_dynamic_flags (entry->d_un.d_val);
d1133906 9949 break;
76da6bbe 9950
252b5132
RH
9951 case DT_AUXILIARY:
9952 case DT_FILTER:
019148e4
L
9953 case DT_CONFIG:
9954 case DT_DEPAUDIT:
9955 case DT_AUDIT:
252b5132
RH
9956 if (do_dynamic)
9957 {
019148e4 9958 switch (entry->d_tag)
b34976b6 9959 {
019148e4
L
9960 case DT_AUXILIARY:
9961 printf (_("Auxiliary library"));
9962 break;
9963
9964 case DT_FILTER:
9965 printf (_("Filter library"));
9966 break;
9967
b34976b6 9968 case DT_CONFIG:
019148e4
L
9969 printf (_("Configuration file"));
9970 break;
9971
9972 case DT_DEPAUDIT:
9973 printf (_("Dependency audit library"));
9974 break;
9975
9976 case DT_AUDIT:
9977 printf (_("Audit library"));
9978 break;
9979 }
252b5132 9980
d79b3d50
NC
9981 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9982 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 9983 else
f7a99963
NC
9984 {
9985 printf (": ");
9986 print_vma (entry->d_un.d_val, PREFIX_HEX);
9987 putchar ('\n');
9988 }
252b5132
RH
9989 }
9990 break;
9991
dcefbbbd 9992 case DT_FEATURE:
252b5132
RH
9993 if (do_dynamic)
9994 {
9995 printf (_("Flags:"));
86f55779 9996
252b5132
RH
9997 if (entry->d_un.d_val == 0)
9998 printf (_(" None\n"));
9999 else
10000 {
10001 unsigned long int val = entry->d_un.d_val;
86f55779 10002
252b5132
RH
10003 if (val & DTF_1_PARINIT)
10004 {
10005 printf (" PARINIT");
10006 val ^= DTF_1_PARINIT;
10007 }
dcefbbbd
L
10008 if (val & DTF_1_CONFEXP)
10009 {
10010 printf (" CONFEXP");
10011 val ^= DTF_1_CONFEXP;
10012 }
252b5132
RH
10013 if (val != 0)
10014 printf (" %lx", val);
10015 puts ("");
10016 }
10017 }
10018 break;
10019
10020 case DT_POSFLAG_1:
10021 if (do_dynamic)
10022 {
10023 printf (_("Flags:"));
86f55779 10024
252b5132
RH
10025 if (entry->d_un.d_val == 0)
10026 printf (_(" None\n"));
10027 else
10028 {
10029 unsigned long int val = entry->d_un.d_val;
86f55779 10030
252b5132
RH
10031 if (val & DF_P1_LAZYLOAD)
10032 {
10033 printf (" LAZYLOAD");
10034 val ^= DF_P1_LAZYLOAD;
10035 }
10036 if (val & DF_P1_GROUPPERM)
10037 {
10038 printf (" GROUPPERM");
10039 val ^= DF_P1_GROUPPERM;
10040 }
10041 if (val != 0)
10042 printf (" %lx", val);
10043 puts ("");
10044 }
10045 }
10046 break;
10047
10048 case DT_FLAGS_1:
10049 if (do_dynamic)
10050 {
10051 printf (_("Flags:"));
10052 if (entry->d_un.d_val == 0)
10053 printf (_(" None\n"));
10054 else
10055 {
10056 unsigned long int val = entry->d_un.d_val;
86f55779 10057
252b5132
RH
10058 if (val & DF_1_NOW)
10059 {
10060 printf (" NOW");
10061 val ^= DF_1_NOW;
10062 }
10063 if (val & DF_1_GLOBAL)
10064 {
10065 printf (" GLOBAL");
10066 val ^= DF_1_GLOBAL;
10067 }
10068 if (val & DF_1_GROUP)
10069 {
10070 printf (" GROUP");
10071 val ^= DF_1_GROUP;
10072 }
10073 if (val & DF_1_NODELETE)
10074 {
10075 printf (" NODELETE");
10076 val ^= DF_1_NODELETE;
10077 }
10078 if (val & DF_1_LOADFLTR)
10079 {
10080 printf (" LOADFLTR");
10081 val ^= DF_1_LOADFLTR;
10082 }
10083 if (val & DF_1_INITFIRST)
10084 {
10085 printf (" INITFIRST");
10086 val ^= DF_1_INITFIRST;
10087 }
10088 if (val & DF_1_NOOPEN)
10089 {
10090 printf (" NOOPEN");
10091 val ^= DF_1_NOOPEN;
10092 }
10093 if (val & DF_1_ORIGIN)
10094 {
10095 printf (" ORIGIN");
10096 val ^= DF_1_ORIGIN;
10097 }
10098 if (val & DF_1_DIRECT)
10099 {
10100 printf (" DIRECT");
10101 val ^= DF_1_DIRECT;
10102 }
10103 if (val & DF_1_TRANS)
10104 {
10105 printf (" TRANS");
10106 val ^= DF_1_TRANS;
10107 }
10108 if (val & DF_1_INTERPOSE)
10109 {
10110 printf (" INTERPOSE");
10111 val ^= DF_1_INTERPOSE;
10112 }
f7db6139 10113 if (val & DF_1_NODEFLIB)
dcefbbbd 10114 {
f7db6139
L
10115 printf (" NODEFLIB");
10116 val ^= DF_1_NODEFLIB;
dcefbbbd
L
10117 }
10118 if (val & DF_1_NODUMP)
10119 {
10120 printf (" NODUMP");
10121 val ^= DF_1_NODUMP;
10122 }
34b60028 10123 if (val & DF_1_CONFALT)
dcefbbbd 10124 {
34b60028
L
10125 printf (" CONFALT");
10126 val ^= DF_1_CONFALT;
10127 }
10128 if (val & DF_1_ENDFILTEE)
10129 {
10130 printf (" ENDFILTEE");
10131 val ^= DF_1_ENDFILTEE;
10132 }
10133 if (val & DF_1_DISPRELDNE)
10134 {
10135 printf (" DISPRELDNE");
10136 val ^= DF_1_DISPRELDNE;
10137 }
10138 if (val & DF_1_DISPRELPND)
10139 {
10140 printf (" DISPRELPND");
10141 val ^= DF_1_DISPRELPND;
10142 }
10143 if (val & DF_1_NODIRECT)
10144 {
10145 printf (" NODIRECT");
10146 val ^= DF_1_NODIRECT;
10147 }
10148 if (val & DF_1_IGNMULDEF)
10149 {
10150 printf (" IGNMULDEF");
10151 val ^= DF_1_IGNMULDEF;
10152 }
10153 if (val & DF_1_NOKSYMS)
10154 {
10155 printf (" NOKSYMS");
10156 val ^= DF_1_NOKSYMS;
10157 }
10158 if (val & DF_1_NOHDR)
10159 {
10160 printf (" NOHDR");
10161 val ^= DF_1_NOHDR;
10162 }
10163 if (val & DF_1_EDITED)
10164 {
10165 printf (" EDITED");
10166 val ^= DF_1_EDITED;
10167 }
10168 if (val & DF_1_NORELOC)
10169 {
10170 printf (" NORELOC");
10171 val ^= DF_1_NORELOC;
10172 }
10173 if (val & DF_1_SYMINTPOSE)
10174 {
10175 printf (" SYMINTPOSE");
10176 val ^= DF_1_SYMINTPOSE;
10177 }
10178 if (val & DF_1_GLOBAUDIT)
10179 {
10180 printf (" GLOBAUDIT");
10181 val ^= DF_1_GLOBAUDIT;
10182 }
10183 if (val & DF_1_SINGLETON)
10184 {
10185 printf (" SINGLETON");
10186 val ^= DF_1_SINGLETON;
dcefbbbd 10187 }
5c383f02
RO
10188 if (val & DF_1_STUB)
10189 {
10190 printf (" STUB");
10191 val ^= DF_1_STUB;
10192 }
10193 if (val & DF_1_PIE)
10194 {
10195 printf (" PIE");
10196 val ^= DF_1_PIE;
10197 }
b1202ffa
L
10198 if (val & DF_1_KMOD)
10199 {
10200 printf (" KMOD");
10201 val ^= DF_1_KMOD;
10202 }
10203 if (val & DF_1_WEAKFILTER)
10204 {
10205 printf (" WEAKFILTER");
10206 val ^= DF_1_WEAKFILTER;
10207 }
10208 if (val & DF_1_NOCOMMON)
10209 {
10210 printf (" NOCOMMON");
10211 val ^= DF_1_NOCOMMON;
10212 }
252b5132
RH
10213 if (val != 0)
10214 printf (" %lx", val);
10215 puts ("");
10216 }
10217 }
10218 break;
10219
10220 case DT_PLTREL:
566b0d53 10221 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10222 if (do_dynamic)
dda8d76d 10223 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10224 break;
10225
10226 case DT_NULL :
10227 case DT_NEEDED :
10228 case DT_PLTGOT :
10229 case DT_HASH :
10230 case DT_STRTAB :
10231 case DT_SYMTAB :
10232 case DT_RELA :
10233 case DT_INIT :
10234 case DT_FINI :
10235 case DT_SONAME :
10236 case DT_RPATH :
10237 case DT_SYMBOLIC:
10238 case DT_REL :
10239 case DT_DEBUG :
10240 case DT_TEXTREL :
10241 case DT_JMPREL :
019148e4 10242 case DT_RUNPATH :
252b5132
RH
10243 dynamic_info[entry->d_tag] = entry->d_un.d_val;
10244
10245 if (do_dynamic)
10246 {
2cf0635d 10247 char * name;
252b5132 10248
d79b3d50
NC
10249 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
10250 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 10251 else
d79b3d50 10252 name = NULL;
252b5132
RH
10253
10254 if (name)
10255 {
10256 switch (entry->d_tag)
10257 {
10258 case DT_NEEDED:
10259 printf (_("Shared library: [%s]"), name);
10260
18bd398b 10261 if (streq (name, program_interpreter))
f7a99963 10262 printf (_(" program interpreter"));
252b5132
RH
10263 break;
10264
10265 case DT_SONAME:
f7a99963 10266 printf (_("Library soname: [%s]"), name);
252b5132
RH
10267 break;
10268
10269 case DT_RPATH:
f7a99963 10270 printf (_("Library rpath: [%s]"), name);
252b5132
RH
10271 break;
10272
019148e4
L
10273 case DT_RUNPATH:
10274 printf (_("Library runpath: [%s]"), name);
10275 break;
10276
252b5132 10277 default:
f7a99963
NC
10278 print_vma (entry->d_un.d_val, PREFIX_HEX);
10279 break;
252b5132
RH
10280 }
10281 }
10282 else
f7a99963
NC
10283 print_vma (entry->d_un.d_val, PREFIX_HEX);
10284
10285 putchar ('\n');
252b5132
RH
10286 }
10287 break;
10288
10289 case DT_PLTRELSZ:
10290 case DT_RELASZ :
10291 case DT_STRSZ :
10292 case DT_RELSZ :
10293 case DT_RELAENT :
10294 case DT_SYMENT :
10295 case DT_RELENT :
566b0d53 10296 dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 10297 /* Fall through. */
252b5132
RH
10298 case DT_PLTPADSZ:
10299 case DT_MOVEENT :
10300 case DT_MOVESZ :
10301 case DT_INIT_ARRAYSZ:
10302 case DT_FINI_ARRAYSZ:
047b2264
JJ
10303 case DT_GNU_CONFLICTSZ:
10304 case DT_GNU_LIBLISTSZ:
252b5132 10305 if (do_dynamic)
f7a99963
NC
10306 {
10307 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 10308 printf (_(" (bytes)\n"));
f7a99963 10309 }
252b5132
RH
10310 break;
10311
10312 case DT_VERDEFNUM:
10313 case DT_VERNEEDNUM:
10314 case DT_RELACOUNT:
10315 case DT_RELCOUNT:
10316 if (do_dynamic)
f7a99963
NC
10317 {
10318 print_vma (entry->d_un.d_val, UNSIGNED);
10319 putchar ('\n');
10320 }
252b5132
RH
10321 break;
10322
10323 case DT_SYMINSZ:
10324 case DT_SYMINENT:
10325 case DT_SYMINFO:
10326 case DT_USED:
10327 case DT_INIT_ARRAY:
10328 case DT_FINI_ARRAY:
10329 if (do_dynamic)
10330 {
d79b3d50
NC
10331 if (entry->d_tag == DT_USED
10332 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 10333 {
2cf0635d 10334 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 10335
b34976b6 10336 if (*name)
252b5132
RH
10337 {
10338 printf (_("Not needed object: [%s]\n"), name);
10339 break;
10340 }
10341 }
103f02d3 10342
f7a99963
NC
10343 print_vma (entry->d_un.d_val, PREFIX_HEX);
10344 putchar ('\n');
252b5132
RH
10345 }
10346 break;
10347
10348 case DT_BIND_NOW:
10349 /* The value of this entry is ignored. */
35b1837e
AM
10350 if (do_dynamic)
10351 putchar ('\n');
252b5132 10352 break;
103f02d3 10353
047b2264
JJ
10354 case DT_GNU_PRELINKED:
10355 if (do_dynamic)
10356 {
2cf0635d 10357 struct tm * tmp;
91d6fa6a 10358 time_t atime = entry->d_un.d_val;
047b2264 10359
91d6fa6a 10360 tmp = gmtime (&atime);
071436c6
NC
10361 /* PR 17533 file: 041-1244816-0.004. */
10362 if (tmp == NULL)
5a2cbcf4
L
10363 printf (_("<corrupt time val: %lx"),
10364 (unsigned long) atime);
071436c6
NC
10365 else
10366 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
10367 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10368 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10369
10370 }
10371 break;
10372
fdc90cb4
JJ
10373 case DT_GNU_HASH:
10374 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10375 if (do_dynamic)
10376 {
10377 print_vma (entry->d_un.d_val, PREFIX_HEX);
10378 putchar ('\n');
10379 }
10380 break;
10381
252b5132
RH
10382 default:
10383 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 10384 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
10385 entry->d_un.d_val;
10386
10387 if (do_dynamic)
10388 {
dda8d76d 10389 switch (filedata->file_header.e_machine)
252b5132 10390 {
37c18eed
SD
10391 case EM_AARCH64:
10392 dynamic_section_aarch64_val (entry);
10393 break;
252b5132 10394 case EM_MIPS:
4fe85591 10395 case EM_MIPS_RS3_LE:
b2d38a17 10396 dynamic_section_mips_val (entry);
252b5132 10397 break;
103f02d3 10398 case EM_PARISC:
b2d38a17 10399 dynamic_section_parisc_val (entry);
103f02d3 10400 break;
ecc51f48 10401 case EM_IA_64:
b2d38a17 10402 dynamic_section_ia64_val (entry);
ecc51f48 10403 break;
252b5132 10404 default:
f7a99963
NC
10405 print_vma (entry->d_un.d_val, PREFIX_HEX);
10406 putchar ('\n');
252b5132
RH
10407 }
10408 }
10409 break;
10410 }
10411 }
10412
32ec8896 10413 return TRUE;
252b5132
RH
10414}
10415
10416static char *
d3ba0551 10417get_ver_flags (unsigned int flags)
252b5132 10418{
6d4f21f6 10419 static char buff[128];
252b5132
RH
10420
10421 buff[0] = 0;
10422
10423 if (flags == 0)
10424 return _("none");
10425
10426 if (flags & VER_FLG_BASE)
7bb1ad17 10427 strcat (buff, "BASE");
252b5132
RH
10428
10429 if (flags & VER_FLG_WEAK)
10430 {
10431 if (flags & VER_FLG_BASE)
7bb1ad17 10432 strcat (buff, " | ");
252b5132 10433
7bb1ad17 10434 strcat (buff, "WEAK");
252b5132
RH
10435 }
10436
44ec90b9
RO
10437 if (flags & VER_FLG_INFO)
10438 {
10439 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 10440 strcat (buff, " | ");
44ec90b9 10441
7bb1ad17 10442 strcat (buff, "INFO");
44ec90b9
RO
10443 }
10444
10445 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
10446 {
10447 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
10448 strcat (buff, " | ");
10449
10450 strcat (buff, _("<unknown>"));
10451 }
252b5132
RH
10452
10453 return buff;
10454}
10455
10456/* Display the contents of the version sections. */
98fb390a 10457
32ec8896 10458static bfd_boolean
dda8d76d 10459process_version_sections (Filedata * filedata)
252b5132 10460{
2cf0635d 10461 Elf_Internal_Shdr * section;
b34976b6 10462 unsigned i;
32ec8896 10463 bfd_boolean found = FALSE;
252b5132
RH
10464
10465 if (! do_version)
32ec8896 10466 return TRUE;
252b5132 10467
dda8d76d
NC
10468 for (i = 0, section = filedata->section_headers;
10469 i < filedata->file_header.e_shnum;
b34976b6 10470 i++, section++)
252b5132
RH
10471 {
10472 switch (section->sh_type)
10473 {
10474 case SHT_GNU_verdef:
10475 {
2cf0635d 10476 Elf_External_Verdef * edefs;
452bf675
AM
10477 unsigned long idx;
10478 unsigned long cnt;
2cf0635d 10479 char * endbuf;
252b5132 10480
32ec8896 10481 found = TRUE;
252b5132 10482
d3a49aa8
AM
10483 printf (ngettext ("\nVersion definition section '%s' "
10484 "contains %u entry:\n",
10485 "\nVersion definition section '%s' "
10486 "contains %u entries:\n",
10487 section->sh_info),
dda8d76d 10488 printable_section_name (filedata, section),
74e1a04b 10489 section->sh_info);
252b5132
RH
10490
10491 printf (_(" Addr: 0x"));
10492 printf_vma (section->sh_addr);
233f82cf 10493 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10494 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10495 printable_section_name_from_index (filedata, section->sh_link));
252b5132 10496
3f5e193b 10497 edefs = (Elf_External_Verdef *)
dda8d76d 10498 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 10499 _("version definition section"));
a6e9f9df
AM
10500 if (!edefs)
10501 break;
59245841 10502 endbuf = (char *) edefs + section->sh_size;
252b5132 10503
1445030f 10504 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 10505 {
2cf0635d
NC
10506 char * vstart;
10507 Elf_External_Verdef * edef;
b34976b6 10508 Elf_Internal_Verdef ent;
2cf0635d 10509 Elf_External_Verdaux * eaux;
b34976b6 10510 Elf_Internal_Verdaux aux;
452bf675 10511 unsigned long isum;
b34976b6 10512 int j;
103f02d3 10513
252b5132 10514 vstart = ((char *) edefs) + idx;
54806181
AM
10515 if (vstart + sizeof (*edef) > endbuf)
10516 break;
252b5132
RH
10517
10518 edef = (Elf_External_Verdef *) vstart;
10519
10520 ent.vd_version = BYTE_GET (edef->vd_version);
10521 ent.vd_flags = BYTE_GET (edef->vd_flags);
10522 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
10523 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
10524 ent.vd_hash = BYTE_GET (edef->vd_hash);
10525 ent.vd_aux = BYTE_GET (edef->vd_aux);
10526 ent.vd_next = BYTE_GET (edef->vd_next);
10527
452bf675 10528 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
10529 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
10530
10531 printf (_(" Index: %d Cnt: %d "),
10532 ent.vd_ndx, ent.vd_cnt);
10533
452bf675 10534 /* Check for overflow. */
1445030f 10535 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
10536 break;
10537
252b5132
RH
10538 vstart += ent.vd_aux;
10539
1445030f
AM
10540 if (vstart + sizeof (*eaux) > endbuf)
10541 break;
252b5132
RH
10542 eaux = (Elf_External_Verdaux *) vstart;
10543
10544 aux.vda_name = BYTE_GET (eaux->vda_name);
10545 aux.vda_next = BYTE_GET (eaux->vda_next);
10546
d79b3d50
NC
10547 if (VALID_DYNAMIC_NAME (aux.vda_name))
10548 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
10549 else
10550 printf (_("Name index: %ld\n"), aux.vda_name);
10551
10552 isum = idx + ent.vd_aux;
10553
b34976b6 10554 for (j = 1; j < ent.vd_cnt; j++)
252b5132 10555 {
1445030f
AM
10556 if (aux.vda_next < sizeof (*eaux)
10557 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
10558 {
10559 warn (_("Invalid vda_next field of %lx\n"),
10560 aux.vda_next);
10561 j = ent.vd_cnt;
10562 break;
10563 }
dd24e3da 10564 /* Check for overflow. */
7e26601c 10565 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
10566 break;
10567
252b5132
RH
10568 isum += aux.vda_next;
10569 vstart += aux.vda_next;
10570
54806181
AM
10571 if (vstart + sizeof (*eaux) > endbuf)
10572 break;
1445030f 10573 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
10574
10575 aux.vda_name = BYTE_GET (eaux->vda_name);
10576 aux.vda_next = BYTE_GET (eaux->vda_next);
10577
d79b3d50 10578 if (VALID_DYNAMIC_NAME (aux.vda_name))
452bf675 10579 printf (_(" %#06lx: Parent %d: %s\n"),
d79b3d50 10580 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132 10581 else
452bf675 10582 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
10583 isum, j, aux.vda_name);
10584 }
dd24e3da 10585
54806181
AM
10586 if (j < ent.vd_cnt)
10587 printf (_(" Version def aux past end of section\n"));
252b5132 10588
c9f02c3e
MR
10589 /* PR 17531:
10590 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
10591 if (ent.vd_next < sizeof (*edef)
10592 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
10593 {
10594 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
10595 cnt = section->sh_info;
10596 break;
10597 }
452bf675 10598 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
10599 break;
10600
252b5132
RH
10601 idx += ent.vd_next;
10602 }
dd24e3da 10603
54806181
AM
10604 if (cnt < section->sh_info)
10605 printf (_(" Version definition past end of section\n"));
252b5132
RH
10606
10607 free (edefs);
10608 }
10609 break;
103f02d3 10610
252b5132
RH
10611 case SHT_GNU_verneed:
10612 {
2cf0635d 10613 Elf_External_Verneed * eneed;
452bf675
AM
10614 unsigned long idx;
10615 unsigned long cnt;
2cf0635d 10616 char * endbuf;
252b5132 10617
32ec8896 10618 found = TRUE;
252b5132 10619
d3a49aa8
AM
10620 printf (ngettext ("\nVersion needs section '%s' "
10621 "contains %u entry:\n",
10622 "\nVersion needs section '%s' "
10623 "contains %u entries:\n",
10624 section->sh_info),
dda8d76d 10625 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
10626
10627 printf (_(" Addr: 0x"));
10628 printf_vma (section->sh_addr);
72de5009 10629 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10630 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10631 printable_section_name_from_index (filedata, section->sh_link));
252b5132 10632
dda8d76d 10633 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
10634 section->sh_offset, 1,
10635 section->sh_size,
9cf03b7e 10636 _("Version Needs section"));
a6e9f9df
AM
10637 if (!eneed)
10638 break;
59245841 10639 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
10640
10641 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
10642 {
2cf0635d 10643 Elf_External_Verneed * entry;
b34976b6 10644 Elf_Internal_Verneed ent;
452bf675 10645 unsigned long isum;
b34976b6 10646 int j;
2cf0635d 10647 char * vstart;
252b5132
RH
10648
10649 vstart = ((char *) eneed) + idx;
54806181
AM
10650 if (vstart + sizeof (*entry) > endbuf)
10651 break;
252b5132
RH
10652
10653 entry = (Elf_External_Verneed *) vstart;
10654
10655 ent.vn_version = BYTE_GET (entry->vn_version);
10656 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
10657 ent.vn_file = BYTE_GET (entry->vn_file);
10658 ent.vn_aux = BYTE_GET (entry->vn_aux);
10659 ent.vn_next = BYTE_GET (entry->vn_next);
10660
452bf675 10661 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 10662
d79b3d50
NC
10663 if (VALID_DYNAMIC_NAME (ent.vn_file))
10664 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
10665 else
10666 printf (_(" File: %lx"), ent.vn_file);
10667
10668 printf (_(" Cnt: %d\n"), ent.vn_cnt);
10669
dd24e3da 10670 /* Check for overflow. */
7e26601c 10671 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 10672 break;
252b5132
RH
10673 vstart += ent.vn_aux;
10674
10675 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
10676 {
2cf0635d 10677 Elf_External_Vernaux * eaux;
b34976b6 10678 Elf_Internal_Vernaux aux;
252b5132 10679
54806181
AM
10680 if (vstart + sizeof (*eaux) > endbuf)
10681 break;
252b5132
RH
10682 eaux = (Elf_External_Vernaux *) vstart;
10683
10684 aux.vna_hash = BYTE_GET (eaux->vna_hash);
10685 aux.vna_flags = BYTE_GET (eaux->vna_flags);
10686 aux.vna_other = BYTE_GET (eaux->vna_other);
10687 aux.vna_name = BYTE_GET (eaux->vna_name);
10688 aux.vna_next = BYTE_GET (eaux->vna_next);
10689
d79b3d50 10690 if (VALID_DYNAMIC_NAME (aux.vna_name))
452bf675 10691 printf (_(" %#06lx: Name: %s"),
d79b3d50 10692 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 10693 else
452bf675 10694 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
10695 isum, aux.vna_name);
10696
10697 printf (_(" Flags: %s Version: %d\n"),
10698 get_ver_flags (aux.vna_flags), aux.vna_other);
10699
1445030f
AM
10700 if (aux.vna_next < sizeof (*eaux)
10701 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
10702 {
10703 warn (_("Invalid vna_next field of %lx\n"),
10704 aux.vna_next);
10705 j = ent.vn_cnt;
10706 break;
10707 }
1445030f
AM
10708 /* Check for overflow. */
10709 if (aux.vna_next > (size_t) (endbuf - vstart))
10710 break;
252b5132
RH
10711 isum += aux.vna_next;
10712 vstart += aux.vna_next;
10713 }
9cf03b7e 10714
54806181 10715 if (j < ent.vn_cnt)
9cf03b7e 10716 warn (_("Missing Version Needs auxillary information\n"));
252b5132 10717
1445030f
AM
10718 if (ent.vn_next < sizeof (*entry)
10719 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 10720 {
452bf675 10721 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
10722 cnt = section->sh_info;
10723 break;
10724 }
1445030f
AM
10725 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
10726 break;
252b5132
RH
10727 idx += ent.vn_next;
10728 }
9cf03b7e 10729
54806181 10730 if (cnt < section->sh_info)
9cf03b7e 10731 warn (_("Missing Version Needs information\n"));
103f02d3 10732
252b5132
RH
10733 free (eneed);
10734 }
10735 break;
10736
10737 case SHT_GNU_versym:
10738 {
2cf0635d 10739 Elf_Internal_Shdr * link_section;
8b73c356
NC
10740 size_t total;
10741 unsigned int cnt;
2cf0635d
NC
10742 unsigned char * edata;
10743 unsigned short * data;
10744 char * strtab;
10745 Elf_Internal_Sym * symbols;
10746 Elf_Internal_Shdr * string_sec;
ba5cdace 10747 unsigned long num_syms;
d3ba0551 10748 long off;
252b5132 10749
dda8d76d 10750 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
10751 break;
10752
dda8d76d 10753 link_section = filedata->section_headers + section->sh_link;
08d8fa11 10754 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 10755
dda8d76d 10756 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
10757 break;
10758
32ec8896 10759 found = TRUE;
252b5132 10760
dda8d76d 10761 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
10762 if (symbols == NULL)
10763 break;
252b5132 10764
dda8d76d 10765 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 10766
dda8d76d 10767 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
10768 string_sec->sh_size,
10769 _("version string table"));
a6e9f9df 10770 if (!strtab)
0429c154
MS
10771 {
10772 free (symbols);
10773 break;
10774 }
252b5132 10775
d3a49aa8
AM
10776 printf (ngettext ("\nVersion symbols section '%s' "
10777 "contains %lu entry:\n",
10778 "\nVersion symbols section '%s' "
10779 "contains %lu entries:\n",
10780 total),
dda8d76d 10781 printable_section_name (filedata, section), (unsigned long) total);
252b5132
RH
10782
10783 printf (_(" Addr: "));
10784 printf_vma (section->sh_addr);
72de5009 10785 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10786 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10787 printable_section_name (filedata, link_section));
252b5132 10788
dda8d76d 10789 off = offset_from_vma (filedata,
d3ba0551
AM
10790 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10791 total * sizeof (short));
dda8d76d 10792 edata = (unsigned char *) get_data (NULL, filedata, off, total,
3f5e193b
NC
10793 sizeof (short),
10794 _("version symbol data"));
a6e9f9df
AM
10795 if (!edata)
10796 {
10797 free (strtab);
0429c154 10798 free (symbols);
a6e9f9df
AM
10799 break;
10800 }
252b5132 10801
3f5e193b 10802 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
10803
10804 for (cnt = total; cnt --;)
b34976b6
AM
10805 data[cnt] = byte_get (edata + cnt * sizeof (short),
10806 sizeof (short));
252b5132
RH
10807
10808 free (edata);
10809
10810 for (cnt = 0; cnt < total; cnt += 4)
10811 {
10812 int j, nn;
ab273396
AM
10813 char *name;
10814 char *invalid = _("*invalid*");
252b5132
RH
10815
10816 printf (" %03x:", cnt);
10817
10818 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 10819 switch (data[cnt + j])
252b5132
RH
10820 {
10821 case 0:
10822 fputs (_(" 0 (*local*) "), stdout);
10823 break;
10824
10825 case 1:
10826 fputs (_(" 1 (*global*) "), stdout);
10827 break;
10828
10829 default:
c244d050
NC
10830 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
10831 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 10832
dd24e3da 10833 /* If this index value is greater than the size of the symbols
ba5cdace
NC
10834 array, break to avoid an out-of-bounds read. */
10835 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
10836 {
10837 warn (_("invalid index into symbol array\n"));
10838 break;
10839 }
10840
ab273396
AM
10841 name = NULL;
10842 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 10843 {
b34976b6
AM
10844 Elf_Internal_Verneed ivn;
10845 unsigned long offset;
252b5132 10846
d93f0186 10847 offset = offset_from_vma
dda8d76d 10848 (filedata, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 10849 sizeof (Elf_External_Verneed));
252b5132 10850
b34976b6 10851 do
252b5132 10852 {
b34976b6
AM
10853 Elf_Internal_Vernaux ivna;
10854 Elf_External_Verneed evn;
10855 Elf_External_Vernaux evna;
10856 unsigned long a_off;
252b5132 10857
dda8d76d 10858 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
10859 _("version need")) == NULL)
10860 break;
0b4362b0 10861
252b5132
RH
10862 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10863 ivn.vn_next = BYTE_GET (evn.vn_next);
10864
10865 a_off = offset + ivn.vn_aux;
10866
10867 do
10868 {
dda8d76d 10869 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
10870 1, _("version need aux (2)")) == NULL)
10871 {
10872 ivna.vna_next = 0;
10873 ivna.vna_other = 0;
10874 }
10875 else
10876 {
10877 ivna.vna_next = BYTE_GET (evna.vna_next);
10878 ivna.vna_other = BYTE_GET (evna.vna_other);
10879 }
252b5132
RH
10880
10881 a_off += ivna.vna_next;
10882 }
b34976b6 10883 while (ivna.vna_other != data[cnt + j]
252b5132
RH
10884 && ivna.vna_next != 0);
10885
b34976b6 10886 if (ivna.vna_other == data[cnt + j])
252b5132
RH
10887 {
10888 ivna.vna_name = BYTE_GET (evna.vna_name);
10889
54806181 10890 if (ivna.vna_name >= string_sec->sh_size)
ab273396 10891 name = invalid;
54806181
AM
10892 else
10893 name = strtab + ivna.vna_name;
252b5132
RH
10894 break;
10895 }
10896
10897 offset += ivn.vn_next;
10898 }
10899 while (ivn.vn_next);
10900 }
00d93f34 10901
ab273396 10902 if (data[cnt + j] != 0x8001
b34976b6 10903 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 10904 {
b34976b6
AM
10905 Elf_Internal_Verdef ivd;
10906 Elf_External_Verdef evd;
10907 unsigned long offset;
252b5132 10908
d93f0186 10909 offset = offset_from_vma
dda8d76d 10910 (filedata, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 10911 sizeof evd);
252b5132
RH
10912
10913 do
10914 {
dda8d76d 10915 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
10916 _("version def")) == NULL)
10917 {
10918 ivd.vd_next = 0;
948f632f 10919 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
10920 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
10921 break;
59245841
NC
10922 }
10923 else
10924 {
10925 ivd.vd_next = BYTE_GET (evd.vd_next);
10926 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10927 }
252b5132
RH
10928
10929 offset += ivd.vd_next;
10930 }
c244d050 10931 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
10932 && ivd.vd_next != 0);
10933
c244d050 10934 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 10935 {
b34976b6
AM
10936 Elf_External_Verdaux evda;
10937 Elf_Internal_Verdaux ivda;
252b5132
RH
10938
10939 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10940
dda8d76d 10941 if (get_data (&evda, filedata,
59245841
NC
10942 offset - ivd.vd_next + ivd.vd_aux,
10943 sizeof (evda), 1,
10944 _("version def aux")) == NULL)
10945 break;
252b5132
RH
10946
10947 ivda.vda_name = BYTE_GET (evda.vda_name);
10948
54806181 10949 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
10950 name = invalid;
10951 else if (name != NULL && name != invalid)
10952 name = _("*both*");
54806181
AM
10953 else
10954 name = strtab + ivda.vda_name;
252b5132
RH
10955 }
10956 }
ab273396
AM
10957 if (name != NULL)
10958 nn += printf ("(%s%-*s",
10959 name,
10960 12 - (int) strlen (name),
10961 ")");
252b5132
RH
10962
10963 if (nn < 18)
10964 printf ("%*c", 18 - nn, ' ');
10965 }
10966
10967 putchar ('\n');
10968 }
10969
10970 free (data);
10971 free (strtab);
10972 free (symbols);
10973 }
10974 break;
103f02d3 10975
252b5132
RH
10976 default:
10977 break;
10978 }
10979 }
10980
10981 if (! found)
10982 printf (_("\nNo version information found in this file.\n"));
10983
32ec8896 10984 return TRUE;
252b5132
RH
10985}
10986
d1133906 10987static const char *
dda8d76d 10988get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 10989{
b34976b6 10990 static char buff[32];
252b5132
RH
10991
10992 switch (binding)
10993 {
b34976b6
AM
10994 case STB_LOCAL: return "LOCAL";
10995 case STB_GLOBAL: return "GLOBAL";
10996 case STB_WEAK: return "WEAK";
252b5132
RH
10997 default:
10998 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
10999 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
11000 binding);
252b5132 11001 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
11002 {
11003 if (binding == STB_GNU_UNIQUE
dda8d76d 11004 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9c55345c 11005 /* GNU is still using the default value 0. */
dda8d76d 11006 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
3e7a7d11
NC
11007 return "UNIQUE";
11008 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
11009 }
252b5132 11010 else
e9e44622 11011 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
11012 return buff;
11013 }
11014}
11015
d1133906 11016static const char *
dda8d76d 11017get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 11018{
b34976b6 11019 static char buff[32];
252b5132
RH
11020
11021 switch (type)
11022 {
b34976b6
AM
11023 case STT_NOTYPE: return "NOTYPE";
11024 case STT_OBJECT: return "OBJECT";
11025 case STT_FUNC: return "FUNC";
11026 case STT_SECTION: return "SECTION";
11027 case STT_FILE: return "FILE";
11028 case STT_COMMON: return "COMMON";
11029 case STT_TLS: return "TLS";
15ab5209
DB
11030 case STT_RELC: return "RELC";
11031 case STT_SRELC: return "SRELC";
252b5132
RH
11032 default:
11033 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 11034 {
dda8d76d 11035 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 11036 return "THUMB_FUNC";
103f02d3 11037
dda8d76d 11038 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
11039 return "REGISTER";
11040
dda8d76d 11041 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
11042 return "PARISC_MILLI";
11043
e9e44622 11044 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 11045 }
252b5132 11046 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 11047 {
dda8d76d 11048 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
11049 {
11050 if (type == STT_HP_OPAQUE)
11051 return "HP_OPAQUE";
11052 if (type == STT_HP_STUB)
11053 return "HP_STUB";
11054 }
11055
d8045f23 11056 if (type == STT_GNU_IFUNC
dda8d76d
NC
11057 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
11058 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 11059 /* GNU is still using the default value 0. */
dda8d76d 11060 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
d8045f23
NC
11061 return "IFUNC";
11062
e9e44622 11063 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 11064 }
252b5132 11065 else
e9e44622 11066 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
11067 return buff;
11068 }
11069}
11070
d1133906 11071static const char *
d3ba0551 11072get_symbol_visibility (unsigned int visibility)
d1133906
NC
11073{
11074 switch (visibility)
11075 {
b34976b6
AM
11076 case STV_DEFAULT: return "DEFAULT";
11077 case STV_INTERNAL: return "INTERNAL";
11078 case STV_HIDDEN: return "HIDDEN";
d1133906 11079 case STV_PROTECTED: return "PROTECTED";
bee0ee85
NC
11080 default:
11081 error (_("Unrecognized visibility value: %u"), visibility);
11082 return _("<unknown>");
d1133906
NC
11083 }
11084}
11085
fd85a6a1
NC
11086static const char *
11087get_solaris_symbol_visibility (unsigned int visibility)
11088{
11089 switch (visibility)
11090 {
11091 case 4: return "EXPORTED";
11092 case 5: return "SINGLETON";
11093 case 6: return "ELIMINATE";
11094 default: return get_symbol_visibility (visibility);
11095 }
11096}
11097
5e2b0d47
NC
11098static const char *
11099get_mips_symbol_other (unsigned int other)
11100{
11101 switch (other)
11102 {
32ec8896
NC
11103 case STO_OPTIONAL: return "OPTIONAL";
11104 case STO_MIPS_PLT: return "MIPS PLT";
11105 case STO_MIPS_PIC: return "MIPS PIC";
11106 case STO_MICROMIPS: return "MICROMIPS";
11107 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
11108 case STO_MIPS16: return "MIPS16";
11109 default: return NULL;
5e2b0d47
NC
11110 }
11111}
11112
28f997cf 11113static const char *
dda8d76d 11114get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 11115{
dda8d76d 11116 if (is_ia64_vms (filedata))
28f997cf
TG
11117 {
11118 static char res[32];
11119
11120 res[0] = 0;
11121
11122 /* Function types is for images and .STB files only. */
dda8d76d 11123 switch (filedata->file_header.e_type)
28f997cf
TG
11124 {
11125 case ET_DYN:
11126 case ET_EXEC:
11127 switch (VMS_ST_FUNC_TYPE (other))
11128 {
11129 case VMS_SFT_CODE_ADDR:
11130 strcat (res, " CA");
11131 break;
11132 case VMS_SFT_SYMV_IDX:
11133 strcat (res, " VEC");
11134 break;
11135 case VMS_SFT_FD:
11136 strcat (res, " FD");
11137 break;
11138 case VMS_SFT_RESERVE:
11139 strcat (res, " RSV");
11140 break;
11141 default:
bee0ee85
NC
11142 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
11143 VMS_ST_FUNC_TYPE (other));
11144 strcat (res, " <unknown>");
11145 break;
28f997cf
TG
11146 }
11147 break;
11148 default:
11149 break;
11150 }
11151 switch (VMS_ST_LINKAGE (other))
11152 {
11153 case VMS_STL_IGNORE:
11154 strcat (res, " IGN");
11155 break;
11156 case VMS_STL_RESERVE:
11157 strcat (res, " RSV");
11158 break;
11159 case VMS_STL_STD:
11160 strcat (res, " STD");
11161 break;
11162 case VMS_STL_LNK:
11163 strcat (res, " LNK");
11164 break;
11165 default:
bee0ee85
NC
11166 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
11167 VMS_ST_LINKAGE (other));
11168 strcat (res, " <unknown>");
11169 break;
28f997cf
TG
11170 }
11171
11172 if (res[0] != 0)
11173 return res + 1;
11174 else
11175 return res;
11176 }
11177 return NULL;
11178}
11179
6911b7dc
AM
11180static const char *
11181get_ppc64_symbol_other (unsigned int other)
11182{
14732552
AM
11183 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
11184 return NULL;
11185
11186 other >>= STO_PPC64_LOCAL_BIT;
11187 if (other <= 6)
6911b7dc
AM
11188 {
11189 static char buf[32];
14732552
AM
11190 if (other >= 2)
11191 other = ppc64_decode_local_entry (other);
11192 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
11193 return buf;
11194 }
11195 return NULL;
11196}
11197
5e2b0d47 11198static const char *
dda8d76d 11199get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
11200{
11201 const char * result = NULL;
11202 static char buff [32];
11203
11204 if (other == 0)
11205 return "";
11206
dda8d76d 11207 switch (filedata->file_header.e_machine)
5e2b0d47
NC
11208 {
11209 case EM_MIPS:
11210 result = get_mips_symbol_other (other);
28f997cf
TG
11211 break;
11212 case EM_IA_64:
dda8d76d 11213 result = get_ia64_symbol_other (filedata, other);
28f997cf 11214 break;
6911b7dc
AM
11215 case EM_PPC64:
11216 result = get_ppc64_symbol_other (other);
11217 break;
5e2b0d47 11218 default:
fd85a6a1 11219 result = NULL;
5e2b0d47
NC
11220 break;
11221 }
11222
11223 if (result)
11224 return result;
11225
11226 snprintf (buff, sizeof buff, _("<other>: %x"), other);
11227 return buff;
11228}
11229
d1133906 11230static const char *
dda8d76d 11231get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 11232{
b34976b6 11233 static char buff[32];
5cf1065c 11234
252b5132
RH
11235 switch (type)
11236 {
b34976b6
AM
11237 case SHN_UNDEF: return "UND";
11238 case SHN_ABS: return "ABS";
11239 case SHN_COMMON: return "COM";
252b5132 11240 default:
9ce701e2 11241 if (type == SHN_IA_64_ANSI_COMMON
dda8d76d
NC
11242 && filedata->file_header.e_machine == EM_IA_64
11243 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9ce701e2 11244 return "ANSI_COM";
dda8d76d
NC
11245 else if ((filedata->file_header.e_machine == EM_X86_64
11246 || filedata->file_header.e_machine == EM_L1OM
11247 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
11248 && type == SHN_X86_64_LCOMMON)
11249 return "LARGE_COM";
ac145307 11250 else if ((type == SHN_MIPS_SCOMMON
dda8d76d 11251 && filedata->file_header.e_machine == EM_MIPS)
ac145307 11252 || (type == SHN_TIC6X_SCOMMON
dda8d76d 11253 && filedata->file_header.e_machine == EM_TI_C6000))
172553c7
TS
11254 return "SCOM";
11255 else if (type == SHN_MIPS_SUNDEFINED
dda8d76d 11256 && filedata->file_header.e_machine == EM_MIPS)
172553c7 11257 return "SUND";
9ce701e2 11258 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 11259 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 11260 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
11261 sprintf (buff, "OS [0x%04x]", type & 0xffff);
11262 else if (type >= SHN_LORESERVE)
11263 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
dda8d76d 11264 else if (type >= filedata->file_header.e_shnum)
e0a31db1 11265 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 11266 else
232e7cb8 11267 sprintf (buff, "%3d", type);
5cf1065c 11268 break;
252b5132 11269 }
5cf1065c
NC
11270
11271 return buff;
252b5132
RH
11272}
11273
66543521 11274static bfd_vma *
dda8d76d 11275get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
252b5132 11276{
2cf0635d
NC
11277 unsigned char * e_data;
11278 bfd_vma * i_data;
252b5132 11279
57028622
NC
11280 /* If the size_t type is smaller than the bfd_size_type, eg because
11281 you are building a 32-bit tool on a 64-bit host, then make sure
11282 that when (number) is cast to (size_t) no information is lost. */
11283 if (sizeof (size_t) < sizeof (bfd_size_type)
11284 && (bfd_size_type) ((size_t) number) != number)
11285 {
66cfc0fd
AM
11286 error (_("Size truncation prevents reading %s elements of size %u\n"),
11287 bfd_vmatoa ("u", number), ent_size);
57028622
NC
11288 return NULL;
11289 }
948f632f 11290
3102e897
NC
11291 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
11292 attempting to allocate memory when the read is bound to fail. */
dda8d76d 11293 if (ent_size * number > filedata->file_size)
3102e897 11294 {
66cfc0fd
AM
11295 error (_("Invalid number of dynamic entries: %s\n"),
11296 bfd_vmatoa ("u", number));
3102e897
NC
11297 return NULL;
11298 }
11299
57028622 11300 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
252b5132
RH
11301 if (e_data == NULL)
11302 {
66cfc0fd
AM
11303 error (_("Out of memory reading %s dynamic entries\n"),
11304 bfd_vmatoa ("u", number));
252b5132
RH
11305 return NULL;
11306 }
11307
dda8d76d 11308 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
252b5132 11309 {
66cfc0fd
AM
11310 error (_("Unable to read in %s bytes of dynamic data\n"),
11311 bfd_vmatoa ("u", number * ent_size));
3102e897 11312 free (e_data);
252b5132
RH
11313 return NULL;
11314 }
11315
57028622 11316 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
252b5132
RH
11317 if (i_data == NULL)
11318 {
66cfc0fd
AM
11319 error (_("Out of memory allocating space for %s dynamic entries\n"),
11320 bfd_vmatoa ("u", number));
252b5132
RH
11321 free (e_data);
11322 return NULL;
11323 }
11324
11325 while (number--)
66543521 11326 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
11327
11328 free (e_data);
11329
11330 return i_data;
11331}
11332
6bd1a22c 11333static void
dda8d76d 11334print_dynamic_symbol (Filedata * filedata, bfd_vma si, unsigned long hn)
6bd1a22c 11335{
2cf0635d 11336 Elf_Internal_Sym * psym;
6bd1a22c
L
11337 int n;
11338
6bd1a22c
L
11339 n = print_vma (si, DEC_5);
11340 if (n < 5)
0b4362b0 11341 fputs (&" "[n], stdout);
6bd1a22c 11342 printf (" %3lu: ", hn);
e0a31db1
NC
11343
11344 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
11345 {
3102e897
NC
11346 printf (_("<No info available for dynamic symbol number %lu>\n"),
11347 (unsigned long) si);
e0a31db1
NC
11348 return;
11349 }
11350
11351 psym = dynamic_symbols + si;
6bd1a22c
L
11352 print_vma (psym->st_value, LONG_HEX);
11353 putchar (' ');
11354 print_vma (psym->st_size, DEC_5);
11355
dda8d76d
NC
11356 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
11357 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
fd85a6a1 11358
dda8d76d 11359 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
11360 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
11361 else
11362 {
11363 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
11364
11365 printf (" %-7s", get_symbol_visibility (vis));
11366 /* Check to see if any other bits in the st_other field are set.
11367 Note - displaying this information disrupts the layout of the
11368 table being generated, but for the moment this case is very
11369 rare. */
11370 if (psym->st_other ^ vis)
dda8d76d 11371 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
fd85a6a1
NC
11372 }
11373
dda8d76d 11374 printf (" %3.3s ", get_symbol_index_type (filedata, psym->st_shndx));
6bd1a22c
L
11375 if (VALID_DYNAMIC_NAME (psym->st_name))
11376 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
11377 else
2b692964 11378 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
11379 putchar ('\n');
11380}
11381
bb4d2ac2 11382static const char *
dda8d76d 11383get_symbol_version_string (Filedata * filedata,
1449284b
NC
11384 bfd_boolean is_dynsym,
11385 const char * strtab,
11386 unsigned long int strtab_size,
11387 unsigned int si,
11388 Elf_Internal_Sym * psym,
11389 enum versioned_symbol_info * sym_info,
11390 unsigned short * vna_other)
bb4d2ac2 11391{
ab273396
AM
11392 unsigned char data[2];
11393 unsigned short vers_data;
11394 unsigned long offset;
7a815dd5 11395 unsigned short max_vd_ndx;
bb4d2ac2 11396
ab273396
AM
11397 if (!is_dynsym
11398 || version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
11399 return NULL;
bb4d2ac2 11400
dda8d76d 11401 offset = offset_from_vma (filedata, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 11402 sizeof data + si * sizeof (vers_data));
bb4d2ac2 11403
dda8d76d 11404 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
11405 sizeof (data), 1, _("version data")) == NULL)
11406 return NULL;
11407
11408 vers_data = byte_get (data, 2);
bb4d2ac2 11409
1f6f5dba 11410 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 11411 return NULL;
bb4d2ac2 11412
7a815dd5
L
11413 max_vd_ndx = 0;
11414
ab273396
AM
11415 /* Usually we'd only see verdef for defined symbols, and verneed for
11416 undefined symbols. However, symbols defined by the linker in
11417 .dynbss for variables copied from a shared library in order to
11418 avoid text relocations are defined yet have verneed. We could
11419 use a heuristic to detect the special case, for example, check
11420 for verneed first on symbols defined in SHT_NOBITS sections, but
11421 it is simpler and more reliable to just look for both verdef and
11422 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 11423
ab273396
AM
11424 if (psym->st_shndx != SHN_UNDEF
11425 && vers_data != 0x8001
11426 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
11427 {
11428 Elf_Internal_Verdef ivd;
11429 Elf_Internal_Verdaux ivda;
11430 Elf_External_Verdaux evda;
11431 unsigned long off;
bb4d2ac2 11432
dda8d76d 11433 off = offset_from_vma (filedata,
ab273396
AM
11434 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
11435 sizeof (Elf_External_Verdef));
11436
11437 do
bb4d2ac2 11438 {
ab273396
AM
11439 Elf_External_Verdef evd;
11440
dda8d76d 11441 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
11442 _("version def")) == NULL)
11443 {
11444 ivd.vd_ndx = 0;
11445 ivd.vd_aux = 0;
11446 ivd.vd_next = 0;
1f6f5dba 11447 ivd.vd_flags = 0;
ab273396
AM
11448 }
11449 else
bb4d2ac2 11450 {
ab273396
AM
11451 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11452 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11453 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 11454 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 11455 }
bb4d2ac2 11456
7a815dd5
L
11457 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
11458 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
11459
ab273396
AM
11460 off += ivd.vd_next;
11461 }
11462 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 11463
ab273396
AM
11464 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
11465 {
1f6f5dba
L
11466 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
11467 return NULL;
11468
ab273396
AM
11469 off -= ivd.vd_next;
11470 off += ivd.vd_aux;
bb4d2ac2 11471
dda8d76d 11472 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
11473 _("version def aux")) != NULL)
11474 {
11475 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 11476
ab273396
AM
11477 if (psym->st_name != ivda.vda_name)
11478 {
11479 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
11480 ? symbol_hidden : symbol_public);
11481 return (ivda.vda_name < strtab_size
11482 ? strtab + ivda.vda_name : _("<corrupt>"));
11483 }
11484 }
11485 }
11486 }
bb4d2ac2 11487
ab273396
AM
11488 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
11489 {
11490 Elf_External_Verneed evn;
11491 Elf_Internal_Verneed ivn;
11492 Elf_Internal_Vernaux ivna;
bb4d2ac2 11493
dda8d76d 11494 offset = offset_from_vma (filedata,
ab273396
AM
11495 version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
11496 sizeof evn);
11497 do
11498 {
11499 unsigned long vna_off;
bb4d2ac2 11500
dda8d76d 11501 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
11502 _("version need")) == NULL)
11503 {
11504 ivna.vna_next = 0;
11505 ivna.vna_other = 0;
11506 ivna.vna_name = 0;
11507 break;
11508 }
bb4d2ac2 11509
ab273396
AM
11510 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11511 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 11512
ab273396 11513 vna_off = offset + ivn.vn_aux;
bb4d2ac2 11514
ab273396
AM
11515 do
11516 {
11517 Elf_External_Vernaux evna;
bb4d2ac2 11518
dda8d76d 11519 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 11520 _("version need aux (3)")) == NULL)
bb4d2ac2 11521 {
ab273396
AM
11522 ivna.vna_next = 0;
11523 ivna.vna_other = 0;
11524 ivna.vna_name = 0;
bb4d2ac2 11525 }
bb4d2ac2 11526 else
bb4d2ac2 11527 {
ab273396
AM
11528 ivna.vna_other = BYTE_GET (evna.vna_other);
11529 ivna.vna_next = BYTE_GET (evna.vna_next);
11530 ivna.vna_name = BYTE_GET (evna.vna_name);
11531 }
bb4d2ac2 11532
ab273396
AM
11533 vna_off += ivna.vna_next;
11534 }
11535 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 11536
ab273396
AM
11537 if (ivna.vna_other == vers_data)
11538 break;
bb4d2ac2 11539
ab273396
AM
11540 offset += ivn.vn_next;
11541 }
11542 while (ivn.vn_next != 0);
bb4d2ac2 11543
ab273396
AM
11544 if (ivna.vna_other == vers_data)
11545 {
11546 *sym_info = symbol_undefined;
11547 *vna_other = ivna.vna_other;
11548 return (ivna.vna_name < strtab_size
11549 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 11550 }
7a815dd5
L
11551 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
11552 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
11553 return _("<corrupt>");
bb4d2ac2 11554 }
ab273396 11555 return NULL;
bb4d2ac2
L
11556}
11557
e3c8793a 11558/* Dump the symbol table. */
32ec8896 11559static bfd_boolean
dda8d76d 11560process_symbol_table (Filedata * filedata)
252b5132 11561{
2cf0635d 11562 Elf_Internal_Shdr * section;
8b73c356
NC
11563 bfd_size_type nbuckets = 0;
11564 bfd_size_type nchains = 0;
2cf0635d
NC
11565 bfd_vma * buckets = NULL;
11566 bfd_vma * chains = NULL;
fdc90cb4 11567 bfd_vma ngnubuckets = 0;
2cf0635d
NC
11568 bfd_vma * gnubuckets = NULL;
11569 bfd_vma * gnuchains = NULL;
6bd1a22c 11570 bfd_vma gnusymidx = 0;
071436c6 11571 bfd_size_type ngnuchains = 0;
252b5132 11572
2c610e4b 11573 if (!do_syms && !do_dyn_syms && !do_histogram)
32ec8896 11574 return TRUE;
252b5132 11575
6bd1a22c
L
11576 if (dynamic_info[DT_HASH]
11577 && (do_histogram
2c610e4b
L
11578 || (do_using_dynamic
11579 && !do_dyn_syms
11580 && dynamic_strings != NULL)))
252b5132 11581 {
66543521
AM
11582 unsigned char nb[8];
11583 unsigned char nc[8];
8b73c356 11584 unsigned int hash_ent_size = 4;
66543521 11585
dda8d76d
NC
11586 if ((filedata->file_header.e_machine == EM_ALPHA
11587 || filedata->file_header.e_machine == EM_S390
11588 || filedata->file_header.e_machine == EM_S390_OLD)
11589 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
66543521
AM
11590 hash_ent_size = 8;
11591
dda8d76d 11592 if (fseek (filedata->handle,
fb52b2f4 11593 (archive_file_offset
dda8d76d 11594 + offset_from_vma (filedata, dynamic_info[DT_HASH],
fb52b2f4 11595 sizeof nb + sizeof nc)),
d93f0186 11596 SEEK_SET))
252b5132 11597 {
591a748a 11598 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11599 goto no_hash;
252b5132
RH
11600 }
11601
dda8d76d 11602 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
252b5132
RH
11603 {
11604 error (_("Failed to read in number of buckets\n"));
d3a44ec6 11605 goto no_hash;
252b5132
RH
11606 }
11607
dda8d76d 11608 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
252b5132
RH
11609 {
11610 error (_("Failed to read in number of chains\n"));
d3a44ec6 11611 goto no_hash;
252b5132
RH
11612 }
11613
66543521
AM
11614 nbuckets = byte_get (nb, hash_ent_size);
11615 nchains = byte_get (nc, hash_ent_size);
252b5132 11616
dda8d76d
NC
11617 buckets = get_dynamic_data (filedata, nbuckets, hash_ent_size);
11618 chains = get_dynamic_data (filedata, nchains, hash_ent_size);
252b5132 11619
d3a44ec6 11620 no_hash:
252b5132 11621 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
11622 {
11623 if (do_using_dynamic)
32ec8896 11624 return FALSE;
d3a44ec6
JJ
11625 free (buckets);
11626 free (chains);
11627 buckets = NULL;
11628 chains = NULL;
11629 nbuckets = 0;
11630 nchains = 0;
11631 }
252b5132
RH
11632 }
11633
6bd1a22c
L
11634 if (dynamic_info_DT_GNU_HASH
11635 && (do_histogram
2c610e4b
L
11636 || (do_using_dynamic
11637 && !do_dyn_syms
11638 && dynamic_strings != NULL)))
252b5132 11639 {
6bd1a22c
L
11640 unsigned char nb[16];
11641 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
11642 bfd_vma buckets_vma;
11643
dda8d76d 11644 if (fseek (filedata->handle,
6bd1a22c 11645 (archive_file_offset
dda8d76d 11646 + offset_from_vma (filedata, dynamic_info_DT_GNU_HASH,
6bd1a22c
L
11647 sizeof nb)),
11648 SEEK_SET))
11649 {
11650 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11651 goto no_gnu_hash;
6bd1a22c 11652 }
252b5132 11653
dda8d76d 11654 if (fread (nb, 16, 1, filedata->handle) != 1)
6bd1a22c
L
11655 {
11656 error (_("Failed to read in number of buckets\n"));
d3a44ec6 11657 goto no_gnu_hash;
6bd1a22c
L
11658 }
11659
11660 ngnubuckets = byte_get (nb, 4);
11661 gnusymidx = byte_get (nb + 4, 4);
11662 bitmaskwords = byte_get (nb + 8, 4);
11663 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 11664 if (is_32bit_elf)
6bd1a22c 11665 buckets_vma += bitmaskwords * 4;
f7a99963 11666 else
6bd1a22c 11667 buckets_vma += bitmaskwords * 8;
252b5132 11668
dda8d76d 11669 if (fseek (filedata->handle,
6bd1a22c 11670 (archive_file_offset
dda8d76d 11671 + offset_from_vma (filedata, buckets_vma, 4)),
6bd1a22c 11672 SEEK_SET))
252b5132 11673 {
6bd1a22c 11674 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11675 goto no_gnu_hash;
6bd1a22c
L
11676 }
11677
dda8d76d 11678 gnubuckets = get_dynamic_data (filedata, ngnubuckets, 4);
252b5132 11679
6bd1a22c 11680 if (gnubuckets == NULL)
d3a44ec6 11681 goto no_gnu_hash;
6bd1a22c
L
11682
11683 for (i = 0; i < ngnubuckets; i++)
11684 if (gnubuckets[i] != 0)
11685 {
11686 if (gnubuckets[i] < gnusymidx)
32ec8896 11687 return FALSE;
6bd1a22c
L
11688
11689 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
11690 maxchain = gnubuckets[i];
11691 }
11692
11693 if (maxchain == 0xffffffff)
d3a44ec6 11694 goto no_gnu_hash;
6bd1a22c
L
11695
11696 maxchain -= gnusymidx;
11697
dda8d76d 11698 if (fseek (filedata->handle,
6bd1a22c 11699 (archive_file_offset
dda8d76d 11700 + offset_from_vma (filedata, buckets_vma
6bd1a22c
L
11701 + 4 * (ngnubuckets + maxchain), 4)),
11702 SEEK_SET))
11703 {
11704 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11705 goto no_gnu_hash;
6bd1a22c
L
11706 }
11707
11708 do
11709 {
dda8d76d 11710 if (fread (nb, 4, 1, filedata->handle) != 1)
252b5132 11711 {
6bd1a22c 11712 error (_("Failed to determine last chain length\n"));
d3a44ec6 11713 goto no_gnu_hash;
6bd1a22c 11714 }
252b5132 11715
6bd1a22c 11716 if (maxchain + 1 == 0)
d3a44ec6 11717 goto no_gnu_hash;
252b5132 11718
6bd1a22c
L
11719 ++maxchain;
11720 }
11721 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 11722
dda8d76d 11723 if (fseek (filedata->handle,
6bd1a22c 11724 (archive_file_offset
dda8d76d 11725 + offset_from_vma (filedata, buckets_vma + 4 * ngnubuckets, 4)),
6bd1a22c
L
11726 SEEK_SET))
11727 {
11728 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11729 goto no_gnu_hash;
6bd1a22c
L
11730 }
11731
dda8d76d 11732 gnuchains = get_dynamic_data (filedata, maxchain, 4);
071436c6 11733 ngnuchains = maxchain;
6bd1a22c 11734
d3a44ec6 11735 no_gnu_hash:
6bd1a22c 11736 if (gnuchains == NULL)
d3a44ec6
JJ
11737 {
11738 free (gnubuckets);
d3a44ec6
JJ
11739 gnubuckets = NULL;
11740 ngnubuckets = 0;
f64fddf1 11741 if (do_using_dynamic)
32ec8896 11742 return FALSE;
d3a44ec6 11743 }
6bd1a22c
L
11744 }
11745
11746 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
11747 && do_syms
11748 && do_using_dynamic
3102e897
NC
11749 && dynamic_strings != NULL
11750 && dynamic_symbols != NULL)
6bd1a22c
L
11751 {
11752 unsigned long hn;
11753
11754 if (dynamic_info[DT_HASH])
11755 {
11756 bfd_vma si;
6bd6a03d 11757 char *visited;
6bd1a22c
L
11758
11759 printf (_("\nSymbol table for image:\n"));
11760 if (is_32bit_elf)
11761 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11762 else
11763 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11764
6bd6a03d
AM
11765 visited = xcmalloc (nchains, 1);
11766 memset (visited, 0, nchains);
6bd1a22c
L
11767 for (hn = 0; hn < nbuckets; hn++)
11768 {
6bd6a03d
AM
11769 for (si = buckets[hn]; si > 0; si = chains[si])
11770 {
dda8d76d 11771 print_dynamic_symbol (filedata, si, hn);
6bd6a03d
AM
11772 if (si >= nchains || visited[si])
11773 {
11774 error (_("histogram chain is corrupt\n"));
11775 break;
11776 }
11777 visited[si] = 1;
11778 }
252b5132 11779 }
6bd6a03d 11780 free (visited);
252b5132 11781 }
6bd1a22c
L
11782
11783 if (dynamic_info_DT_GNU_HASH)
11784 {
11785 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
11786 if (is_32bit_elf)
11787 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11788 else
11789 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11790
11791 for (hn = 0; hn < ngnubuckets; ++hn)
11792 if (gnubuckets[hn] != 0)
11793 {
11794 bfd_vma si = gnubuckets[hn];
11795 bfd_vma off = si - gnusymidx;
11796
11797 do
11798 {
dda8d76d 11799 print_dynamic_symbol (filedata, si, hn);
6bd1a22c
L
11800 si++;
11801 }
071436c6 11802 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
11803 }
11804 }
252b5132 11805 }
8b73c356 11806 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 11807 && filedata->section_headers != NULL)
252b5132 11808 {
b34976b6 11809 unsigned int i;
252b5132 11810
dda8d76d
NC
11811 for (i = 0, section = filedata->section_headers;
11812 i < filedata->file_header.e_shnum;
252b5132
RH
11813 i++, section++)
11814 {
b34976b6 11815 unsigned int si;
2cf0635d 11816 char * strtab = NULL;
c256ffe7 11817 unsigned long int strtab_size = 0;
2cf0635d
NC
11818 Elf_Internal_Sym * symtab;
11819 Elf_Internal_Sym * psym;
ba5cdace 11820 unsigned long num_syms;
252b5132 11821
2c610e4b
L
11822 if ((section->sh_type != SHT_SYMTAB
11823 && section->sh_type != SHT_DYNSYM)
11824 || (!do_syms
11825 && section->sh_type == SHT_SYMTAB))
252b5132
RH
11826 continue;
11827
dd24e3da
NC
11828 if (section->sh_entsize == 0)
11829 {
11830 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 11831 printable_section_name (filedata, section));
dd24e3da
NC
11832 continue;
11833 }
11834
d3a49aa8
AM
11835 num_syms = section->sh_size / section->sh_entsize;
11836 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
11837 "\nSymbol table '%s' contains %lu entries:\n",
11838 num_syms),
dda8d76d 11839 printable_section_name (filedata, section),
d3a49aa8 11840 num_syms);
dd24e3da 11841
f7a99963 11842 if (is_32bit_elf)
ca47b30c 11843 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 11844 else
ca47b30c 11845 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 11846
dda8d76d 11847 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
11848 if (symtab == NULL)
11849 continue;
11850
dda8d76d 11851 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 11852 {
dda8d76d
NC
11853 strtab = filedata->string_table;
11854 strtab_size = filedata->string_table_length;
c256ffe7 11855 }
dda8d76d 11856 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 11857 {
2cf0635d 11858 Elf_Internal_Shdr * string_sec;
252b5132 11859
dda8d76d 11860 string_sec = filedata->section_headers + section->sh_link;
252b5132 11861
dda8d76d 11862 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
11863 1, string_sec->sh_size,
11864 _("string table"));
c256ffe7 11865 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
11866 }
11867
ba5cdace 11868 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 11869 {
bb4d2ac2
L
11870 const char *version_string;
11871 enum versioned_symbol_info sym_info;
11872 unsigned short vna_other;
11873
5e220199 11874 printf ("%6d: ", si);
f7a99963
NC
11875 print_vma (psym->st_value, LONG_HEX);
11876 putchar (' ');
11877 print_vma (psym->st_size, DEC_5);
dda8d76d
NC
11878 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
11879 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
11880 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
11881 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
11882 else
11883 {
11884 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
11885
11886 printf (" %-7s", get_symbol_visibility (vis));
11887 /* Check to see if any other bits in the st_other field are set.
11888 Note - displaying this information disrupts the layout of the
11889 table being generated, but for the moment this case is very rare. */
11890 if (psym->st_other ^ vis)
dda8d76d 11891 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
fd85a6a1 11892 }
dda8d76d 11893 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
c256ffe7 11894 print_symbol (25, psym->st_name < strtab_size
2b692964 11895 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 11896
bb4d2ac2 11897 version_string
dda8d76d 11898 = get_symbol_version_string (filedata,
bb4d2ac2
L
11899 section->sh_type == SHT_DYNSYM,
11900 strtab, strtab_size, si,
11901 psym, &sym_info, &vna_other);
11902 if (version_string)
252b5132 11903 {
bb4d2ac2
L
11904 if (sym_info == symbol_undefined)
11905 printf ("@%s (%d)", version_string, vna_other);
11906 else
11907 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
11908 version_string);
252b5132
RH
11909 }
11910
11911 putchar ('\n');
52c3c391
NC
11912
11913 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
dd905818
NC
11914 && si >= section->sh_info
11915 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
dda8d76d 11916 && filedata->file_header.e_machine != EM_MIPS
dd905818
NC
11917 /* Solaris binaries have been found to violate this requirement as
11918 well. Not sure if this is a bug or an ABI requirement. */
dda8d76d 11919 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
52c3c391 11920 warn (_("local symbol %u found at index >= %s's sh_info value of %u\n"),
dda8d76d 11921 si, printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11922 }
11923
11924 free (symtab);
dda8d76d 11925 if (strtab != filedata->string_table)
252b5132
RH
11926 free (strtab);
11927 }
11928 }
11929 else if (do_syms)
11930 printf
11931 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
11932
11933 if (do_histogram && buckets != NULL)
11934 {
2cf0635d
NC
11935 unsigned long * lengths;
11936 unsigned long * counts;
66543521
AM
11937 unsigned long hn;
11938 bfd_vma si;
11939 unsigned long maxlength = 0;
11940 unsigned long nzero_counts = 0;
11941 unsigned long nsyms = 0;
6bd6a03d 11942 char *visited;
252b5132 11943
d3a49aa8
AM
11944 printf (ngettext ("\nHistogram for bucket list length "
11945 "(total of %lu bucket):\n",
11946 "\nHistogram for bucket list length "
11947 "(total of %lu buckets):\n",
11948 (unsigned long) nbuckets),
66543521 11949 (unsigned long) nbuckets);
252b5132 11950
3f5e193b 11951 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
11952 if (lengths == NULL)
11953 {
8b73c356 11954 error (_("Out of memory allocating space for histogram buckets\n"));
32ec8896 11955 return FALSE;
252b5132 11956 }
6bd6a03d
AM
11957 visited = xcmalloc (nchains, 1);
11958 memset (visited, 0, nchains);
8b73c356
NC
11959
11960 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
11961 for (hn = 0; hn < nbuckets; ++hn)
11962 {
6bd6a03d 11963 for (si = buckets[hn]; si > 0; si = chains[si])
252b5132 11964 {
b34976b6 11965 ++nsyms;
252b5132 11966 if (maxlength < ++lengths[hn])
b34976b6 11967 ++maxlength;
6bd6a03d
AM
11968 if (si >= nchains || visited[si])
11969 {
11970 error (_("histogram chain is corrupt\n"));
11971 break;
11972 }
11973 visited[si] = 1;
252b5132
RH
11974 }
11975 }
6bd6a03d 11976 free (visited);
252b5132 11977
3f5e193b 11978 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
11979 if (counts == NULL)
11980 {
b2e951ec 11981 free (lengths);
8b73c356 11982 error (_("Out of memory allocating space for histogram counts\n"));
32ec8896 11983 return FALSE;
252b5132
RH
11984 }
11985
11986 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 11987 ++counts[lengths[hn]];
252b5132 11988
103f02d3 11989 if (nbuckets > 0)
252b5132 11990 {
66543521
AM
11991 unsigned long i;
11992 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 11993 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 11994 for (i = 1; i <= maxlength; ++i)
103f02d3 11995 {
66543521
AM
11996 nzero_counts += counts[i] * i;
11997 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11998 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
11999 (nzero_counts * 100.0) / nsyms);
12000 }
252b5132
RH
12001 }
12002
12003 free (counts);
12004 free (lengths);
12005 }
12006
12007 if (buckets != NULL)
12008 {
12009 free (buckets);
12010 free (chains);
12011 }
12012
d3a44ec6 12013 if (do_histogram && gnubuckets != NULL)
fdc90cb4 12014 {
2cf0635d
NC
12015 unsigned long * lengths;
12016 unsigned long * counts;
fdc90cb4
JJ
12017 unsigned long hn;
12018 unsigned long maxlength = 0;
12019 unsigned long nzero_counts = 0;
12020 unsigned long nsyms = 0;
fdc90cb4 12021
d3a49aa8
AM
12022 printf (ngettext ("\nHistogram for `.gnu.hash' bucket list length "
12023 "(total of %lu bucket):\n",
12024 "\nHistogram for `.gnu.hash' bucket list length "
12025 "(total of %lu buckets):\n",
12026 (unsigned long) ngnubuckets),
8b73c356
NC
12027 (unsigned long) ngnubuckets);
12028
3f5e193b 12029 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
12030 if (lengths == NULL)
12031 {
8b73c356 12032 error (_("Out of memory allocating space for gnu histogram buckets\n"));
32ec8896 12033 return FALSE;
fdc90cb4
JJ
12034 }
12035
fdc90cb4
JJ
12036 printf (_(" Length Number %% of total Coverage\n"));
12037
12038 for (hn = 0; hn < ngnubuckets; ++hn)
12039 if (gnubuckets[hn] != 0)
12040 {
12041 bfd_vma off, length = 1;
12042
6bd1a22c 12043 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
12044 /* PR 17531 file: 010-77222-0.004. */
12045 off < ngnuchains && (gnuchains[off] & 1) == 0;
12046 ++off)
fdc90cb4
JJ
12047 ++length;
12048 lengths[hn] = length;
12049 if (length > maxlength)
12050 maxlength = length;
12051 nsyms += length;
12052 }
12053
3f5e193b 12054 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
12055 if (counts == NULL)
12056 {
b2e951ec 12057 free (lengths);
8b73c356 12058 error (_("Out of memory allocating space for gnu histogram counts\n"));
32ec8896 12059 return FALSE;
fdc90cb4
JJ
12060 }
12061
12062 for (hn = 0; hn < ngnubuckets; ++hn)
12063 ++counts[lengths[hn]];
12064
12065 if (ngnubuckets > 0)
12066 {
12067 unsigned long j;
12068 printf (" 0 %-10lu (%5.1f%%)\n",
12069 counts[0], (counts[0] * 100.0) / ngnubuckets);
12070 for (j = 1; j <= maxlength; ++j)
12071 {
12072 nzero_counts += counts[j] * j;
12073 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
12074 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
12075 (nzero_counts * 100.0) / nsyms);
12076 }
12077 }
12078
12079 free (counts);
12080 free (lengths);
12081 free (gnubuckets);
12082 free (gnuchains);
12083 }
12084
32ec8896 12085 return TRUE;
252b5132
RH
12086}
12087
32ec8896 12088static bfd_boolean
dda8d76d 12089process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 12090{
b4c96d0d 12091 unsigned int i;
252b5132
RH
12092
12093 if (dynamic_syminfo == NULL
12094 || !do_dynamic)
12095 /* No syminfo, this is ok. */
32ec8896 12096 return TRUE;
252b5132
RH
12097
12098 /* There better should be a dynamic symbol section. */
12099 if (dynamic_symbols == NULL || dynamic_strings == NULL)
32ec8896 12100 return FALSE;
252b5132
RH
12101
12102 if (dynamic_addr)
d3a49aa8
AM
12103 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
12104 "contains %d entry:\n",
12105 "\nDynamic info segment at offset 0x%lx "
12106 "contains %d entries:\n",
12107 dynamic_syminfo_nent),
252b5132
RH
12108 dynamic_syminfo_offset, dynamic_syminfo_nent);
12109
12110 printf (_(" Num: Name BoundTo Flags\n"));
12111 for (i = 0; i < dynamic_syminfo_nent; ++i)
12112 {
12113 unsigned short int flags = dynamic_syminfo[i].si_flags;
12114
31104126 12115 printf ("%4d: ", i);
4082ef84
NC
12116 if (i >= num_dynamic_syms)
12117 printf (_("<corrupt index>"));
12118 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
12119 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
12120 else
2b692964 12121 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 12122 putchar (' ');
252b5132
RH
12123
12124 switch (dynamic_syminfo[i].si_boundto)
12125 {
12126 case SYMINFO_BT_SELF:
12127 fputs ("SELF ", stdout);
12128 break;
12129 case SYMINFO_BT_PARENT:
12130 fputs ("PARENT ", stdout);
12131 break;
12132 default:
12133 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
12134 && dynamic_syminfo[i].si_boundto < dynamic_nent
12135 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 12136 {
d79b3d50 12137 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
12138 putchar (' ' );
12139 }
252b5132
RH
12140 else
12141 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
12142 break;
12143 }
12144
12145 if (flags & SYMINFO_FLG_DIRECT)
12146 printf (" DIRECT");
12147 if (flags & SYMINFO_FLG_PASSTHRU)
12148 printf (" PASSTHRU");
12149 if (flags & SYMINFO_FLG_COPY)
12150 printf (" COPY");
12151 if (flags & SYMINFO_FLG_LAZYLOAD)
12152 printf (" LAZYLOAD");
12153
12154 puts ("");
12155 }
12156
32ec8896 12157 return TRUE;
252b5132
RH
12158}
12159
b32e566b
NC
12160#define IN_RANGE(START,END,ADDR,OFF) \
12161 (((ADDR) >= (START)) && ((ADDR) + (OFF) < (END)))
12162
cf13d699
NC
12163/* Check to see if the given reloc needs to be handled in a target specific
12164 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
12165 FALSE.
12166
12167 If called with reloc == NULL, then this is a signal that reloc processing
12168 for the current section has finished, and any saved state should be
12169 discarded. */
09c11c86 12170
cf13d699 12171static bfd_boolean
dda8d76d
NC
12172target_specific_reloc_handling (Filedata * filedata,
12173 Elf_Internal_Rela * reloc,
12174 unsigned char * start,
12175 unsigned char * end,
12176 Elf_Internal_Sym * symtab,
12177 unsigned long num_syms)
252b5132 12178{
f84ce13b
NC
12179 unsigned int reloc_type = 0;
12180 unsigned long sym_index = 0;
12181
12182 if (reloc)
12183 {
dda8d76d 12184 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
12185 sym_index = get_reloc_symindex (reloc->r_info);
12186 }
252b5132 12187
dda8d76d 12188 switch (filedata->file_header.e_machine)
252b5132 12189 {
13761a11
NC
12190 case EM_MSP430:
12191 case EM_MSP430_OLD:
12192 {
12193 static Elf_Internal_Sym * saved_sym = NULL;
12194
f84ce13b
NC
12195 if (reloc == NULL)
12196 {
12197 saved_sym = NULL;
12198 return TRUE;
12199 }
12200
13761a11
NC
12201 switch (reloc_type)
12202 {
12203 case 10: /* R_MSP430_SYM_DIFF */
dda8d76d 12204 if (uses_msp430x_relocs (filedata))
13761a11 12205 break;
1a0670f3 12206 /* Fall through. */
13761a11 12207 case 21: /* R_MSP430X_SYM_DIFF */
f84ce13b
NC
12208 /* PR 21139. */
12209 if (sym_index >= num_syms)
12210 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
12211 sym_index);
12212 else
12213 saved_sym = symtab + sym_index;
13761a11
NC
12214 return TRUE;
12215
12216 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
12217 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
12218 goto handle_sym_diff;
0b4362b0 12219
13761a11
NC
12220 case 5: /* R_MSP430_16_BYTE */
12221 case 9: /* R_MSP430_8 */
dda8d76d 12222 if (uses_msp430x_relocs (filedata))
13761a11
NC
12223 break;
12224 goto handle_sym_diff;
12225
12226 case 2: /* R_MSP430_ABS16 */
12227 case 15: /* R_MSP430X_ABS16 */
dda8d76d 12228 if (! uses_msp430x_relocs (filedata))
13761a11
NC
12229 break;
12230 goto handle_sym_diff;
0b4362b0 12231
13761a11
NC
12232 handle_sym_diff:
12233 if (saved_sym != NULL)
12234 {
03f7786e 12235 int reloc_size = reloc_type == 1 ? 4 : 2;
13761a11
NC
12236 bfd_vma value;
12237
f84ce13b
NC
12238 if (sym_index >= num_syms)
12239 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
12240 sym_index);
03f7786e 12241 else
f84ce13b
NC
12242 {
12243 value = reloc->r_addend + (symtab[sym_index].st_value
12244 - saved_sym->st_value);
12245
b32e566b 12246 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12247 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12248 else
12249 /* PR 21137 */
12250 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
12251 (long) reloc->r_offset);
f84ce13b 12252 }
13761a11
NC
12253
12254 saved_sym = NULL;
12255 return TRUE;
12256 }
12257 break;
12258
12259 default:
12260 if (saved_sym != NULL)
071436c6 12261 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
12262 break;
12263 }
12264 break;
12265 }
12266
cf13d699
NC
12267 case EM_MN10300:
12268 case EM_CYGNUS_MN10300:
12269 {
12270 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 12271
f84ce13b
NC
12272 if (reloc == NULL)
12273 {
12274 saved_sym = NULL;
12275 return TRUE;
12276 }
12277
cf13d699
NC
12278 switch (reloc_type)
12279 {
12280 case 34: /* R_MN10300_ALIGN */
12281 return TRUE;
12282 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
12283 if (sym_index >= num_syms)
12284 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
12285 sym_index);
12286 else
12287 saved_sym = symtab + sym_index;
cf13d699 12288 return TRUE;
f84ce13b 12289
cf13d699
NC
12290 case 1: /* R_MN10300_32 */
12291 case 2: /* R_MN10300_16 */
12292 if (saved_sym != NULL)
12293 {
03f7786e 12294 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 12295 bfd_vma value;
252b5132 12296
f84ce13b
NC
12297 if (sym_index >= num_syms)
12298 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
12299 sym_index);
03f7786e 12300 else
f84ce13b
NC
12301 {
12302 value = reloc->r_addend + (symtab[sym_index].st_value
12303 - saved_sym->st_value);
12304
b32e566b 12305 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12306 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12307 else
12308 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
12309 (long) reloc->r_offset);
f84ce13b 12310 }
252b5132 12311
cf13d699
NC
12312 saved_sym = NULL;
12313 return TRUE;
12314 }
12315 break;
12316 default:
12317 if (saved_sym != NULL)
071436c6 12318 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
12319 break;
12320 }
12321 break;
12322 }
6ff71e76
NC
12323
12324 case EM_RL78:
12325 {
12326 static bfd_vma saved_sym1 = 0;
12327 static bfd_vma saved_sym2 = 0;
12328 static bfd_vma value;
12329
f84ce13b
NC
12330 if (reloc == NULL)
12331 {
12332 saved_sym1 = saved_sym2 = 0;
12333 return TRUE;
12334 }
12335
6ff71e76
NC
12336 switch (reloc_type)
12337 {
12338 case 0x80: /* R_RL78_SYM. */
12339 saved_sym1 = saved_sym2;
f84ce13b
NC
12340 if (sym_index >= num_syms)
12341 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
12342 sym_index);
12343 else
12344 {
12345 saved_sym2 = symtab[sym_index].st_value;
12346 saved_sym2 += reloc->r_addend;
12347 }
6ff71e76
NC
12348 return TRUE;
12349
12350 case 0x83: /* R_RL78_OPsub. */
12351 value = saved_sym1 - saved_sym2;
12352 saved_sym2 = saved_sym1 = 0;
12353 return TRUE;
12354 break;
12355
12356 case 0x41: /* R_RL78_ABS32. */
b32e566b 12357 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 12358 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
12359 else
12360 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12361 (long) reloc->r_offset);
6ff71e76
NC
12362 value = 0;
12363 return TRUE;
12364
12365 case 0x43: /* R_RL78_ABS16. */
b32e566b 12366 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 12367 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
12368 else
12369 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12370 (long) reloc->r_offset);
6ff71e76
NC
12371 value = 0;
12372 return TRUE;
12373
12374 default:
12375 break;
12376 }
12377 break;
12378 }
252b5132
RH
12379 }
12380
cf13d699 12381 return FALSE;
252b5132
RH
12382}
12383
aca88567
NC
12384/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
12385 DWARF debug sections. This is a target specific test. Note - we do not
12386 go through the whole including-target-headers-multiple-times route, (as
12387 we have already done with <elf/h8.h>) because this would become very
12388 messy and even then this function would have to contain target specific
12389 information (the names of the relocs instead of their numeric values).
12390 FIXME: This is not the correct way to solve this problem. The proper way
12391 is to have target specific reloc sizing and typing functions created by
12392 the reloc-macros.h header, in the same way that it already creates the
12393 reloc naming functions. */
12394
12395static bfd_boolean
dda8d76d 12396is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12397{
d347c9df 12398 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12399 switch (filedata->file_header.e_machine)
aca88567 12400 {
41e92641 12401 case EM_386:
22abe556 12402 case EM_IAMCU:
41e92641 12403 return reloc_type == 1; /* R_386_32. */
aca88567
NC
12404 case EM_68K:
12405 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
12406 case EM_860:
12407 return reloc_type == 1; /* R_860_32. */
12408 case EM_960:
12409 return reloc_type == 2; /* R_960_32. */
a06ea964 12410 case EM_AARCH64:
9282b95a
JW
12411 return (reloc_type == 258
12412 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
d347c9df
PS
12413 case EM_ADAPTEVA_EPIPHANY:
12414 return reloc_type == 3;
aca88567 12415 case EM_ALPHA:
137b6b5f 12416 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
12417 case EM_ARC:
12418 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
12419 case EM_ARC_COMPACT:
12420 case EM_ARC_COMPACT2:
12421 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
12422 case EM_ARM:
12423 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 12424 case EM_AVR_OLD:
aca88567
NC
12425 case EM_AVR:
12426 return reloc_type == 1;
12427 case EM_BLACKFIN:
12428 return reloc_type == 0x12; /* R_byte4_data. */
12429 case EM_CRIS:
12430 return reloc_type == 3; /* R_CRIS_32. */
12431 case EM_CR16:
12432 return reloc_type == 3; /* R_CR16_NUM32. */
12433 case EM_CRX:
12434 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
12435 case EM_CSKY:
12436 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
12437 case EM_CYGNUS_FRV:
12438 return reloc_type == 1;
41e92641
NC
12439 case EM_CYGNUS_D10V:
12440 case EM_D10V:
12441 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
12442 case EM_CYGNUS_D30V:
12443 case EM_D30V:
12444 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
12445 case EM_DLX:
12446 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
12447 case EM_CYGNUS_FR30:
12448 case EM_FR30:
12449 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
12450 case EM_FT32:
12451 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
12452 case EM_H8S:
12453 case EM_H8_300:
12454 case EM_H8_300H:
12455 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 12456 case EM_IA_64:
262cdac7
AM
12457 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
12458 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
12459 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
12460 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
12461 case EM_IP2K_OLD:
12462 case EM_IP2K:
12463 return reloc_type == 2; /* R_IP2K_32. */
12464 case EM_IQ2000:
12465 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
12466 case EM_LATTICEMICO32:
12467 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 12468 case EM_M32C_OLD:
aca88567
NC
12469 case EM_M32C:
12470 return reloc_type == 3; /* R_M32C_32. */
12471 case EM_M32R:
12472 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
12473 case EM_68HC11:
12474 case EM_68HC12:
12475 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 12476 case EM_S12Z:
2849d19f
JD
12477 return reloc_type == 7 || /* R_S12Z_EXT32 */
12478 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
12479 case EM_MCORE:
12480 return reloc_type == 1; /* R_MCORE_ADDR32. */
12481 case EM_CYGNUS_MEP:
12482 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
12483 case EM_METAG:
12484 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
12485 case EM_MICROBLAZE:
12486 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
12487 case EM_MIPS:
12488 return reloc_type == 2; /* R_MIPS_32. */
12489 case EM_MMIX:
12490 return reloc_type == 4; /* R_MMIX_32. */
12491 case EM_CYGNUS_MN10200:
12492 case EM_MN10200:
12493 return reloc_type == 1; /* R_MN10200_32. */
12494 case EM_CYGNUS_MN10300:
12495 case EM_MN10300:
12496 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
12497 case EM_MOXIE:
12498 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
12499 case EM_MSP430_OLD:
12500 case EM_MSP430:
13761a11 12501 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
12502 case EM_MT:
12503 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
12504 case EM_NDS32:
12505 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 12506 case EM_ALTERA_NIOS2:
36591ba1 12507 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
12508 case EM_NIOS32:
12509 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
12510 case EM_OR1K:
12511 return reloc_type == 1; /* R_OR1K_32. */
aca88567 12512 case EM_PARISC:
0df8ad28
NC
12513 return (reloc_type == 1 /* R_PARISC_DIR32. */
12514 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 12515 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
12516 case EM_PJ:
12517 case EM_PJ_OLD:
12518 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
12519 case EM_PPC64:
12520 return reloc_type == 1; /* R_PPC64_ADDR32. */
12521 case EM_PPC:
12522 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
12523 case EM_TI_PRU:
12524 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
12525 case EM_RISCV:
12526 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
12527 case EM_RL78:
12528 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
12529 case EM_RX:
12530 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
12531 case EM_S370:
12532 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
12533 case EM_S390_OLD:
12534 case EM_S390:
12535 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
12536 case EM_SCORE:
12537 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
12538 case EM_SH:
12539 return reloc_type == 1; /* R_SH_DIR32. */
12540 case EM_SPARC32PLUS:
12541 case EM_SPARCV9:
12542 case EM_SPARC:
12543 return reloc_type == 3 /* R_SPARC_32. */
12544 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
12545 case EM_SPU:
12546 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
12547 case EM_TI_C6000:
12548 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
12549 case EM_TILEGX:
12550 return reloc_type == 2; /* R_TILEGX_32. */
12551 case EM_TILEPRO:
12552 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
12553 case EM_CYGNUS_V850:
12554 case EM_V850:
12555 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
12556 case EM_V800:
12557 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
12558 case EM_VAX:
12559 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
12560 case EM_VISIUM:
12561 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
12562 case EM_WEBASSEMBLY:
12563 return reloc_type == 1; /* R_WASM32_32. */
aca88567 12564 case EM_X86_64:
8a9036a4 12565 case EM_L1OM:
7a9068fe 12566 case EM_K1OM:
aca88567 12567 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
12568 case EM_XC16X:
12569 case EM_C166:
12570 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
12571 case EM_XGATE:
12572 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
12573 case EM_XSTORMY16:
12574 return reloc_type == 1; /* R_XSTROMY16_32. */
12575 case EM_XTENSA_OLD:
12576 case EM_XTENSA:
12577 return reloc_type == 1; /* R_XTENSA_32. */
aca88567 12578 default:
bee0ee85
NC
12579 {
12580 static unsigned int prev_warn = 0;
12581
12582 /* Avoid repeating the same warning multiple times. */
dda8d76d 12583 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 12584 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
12585 filedata->file_header.e_machine);
12586 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
12587 return FALSE;
12588 }
aca88567
NC
12589 }
12590}
12591
12592/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12593 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
12594
12595static bfd_boolean
dda8d76d 12596is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12597{
dda8d76d 12598 switch (filedata->file_header.e_machine)
d347c9df 12599 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 12600 {
41e92641 12601 case EM_386:
22abe556 12602 case EM_IAMCU:
3e0873ac 12603 return reloc_type == 2; /* R_386_PC32. */
aca88567 12604 case EM_68K:
3e0873ac 12605 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
12606 case EM_AARCH64:
12607 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
12608 case EM_ADAPTEVA_EPIPHANY:
12609 return reloc_type == 6;
aca88567
NC
12610 case EM_ALPHA:
12611 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
12612 case EM_ARC_COMPACT:
12613 case EM_ARC_COMPACT2:
12614 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 12615 case EM_ARM:
3e0873ac 12616 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
12617 case EM_AVR_OLD:
12618 case EM_AVR:
12619 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
12620 case EM_MICROBLAZE:
12621 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
12622 case EM_OR1K:
12623 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 12624 case EM_PARISC:
85acf597 12625 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
12626 case EM_PPC:
12627 return reloc_type == 26; /* R_PPC_REL32. */
12628 case EM_PPC64:
3e0873ac 12629 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
12630 case EM_RISCV:
12631 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
12632 case EM_S390_OLD:
12633 case EM_S390:
3e0873ac 12634 return reloc_type == 5; /* R_390_PC32. */
aca88567 12635 case EM_SH:
3e0873ac 12636 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
12637 case EM_SPARC32PLUS:
12638 case EM_SPARCV9:
12639 case EM_SPARC:
3e0873ac 12640 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
12641 case EM_SPU:
12642 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
12643 case EM_TILEGX:
12644 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
12645 case EM_TILEPRO:
12646 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
12647 case EM_VISIUM:
12648 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 12649 case EM_X86_64:
8a9036a4 12650 case EM_L1OM:
7a9068fe 12651 case EM_K1OM:
3e0873ac 12652 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
12653 case EM_XTENSA_OLD:
12654 case EM_XTENSA:
12655 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
12656 default:
12657 /* Do not abort or issue an error message here. Not all targets use
12658 pc-relative 32-bit relocs in their DWARF debug information and we
12659 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
12660 more helpful warning message will be generated by apply_relocations
12661 anyway, so just return. */
aca88567
NC
12662 return FALSE;
12663 }
12664}
12665
12666/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12667 a 64-bit absolute RELA relocation used in DWARF debug sections. */
12668
12669static bfd_boolean
dda8d76d 12670is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12671{
dda8d76d 12672 switch (filedata->file_header.e_machine)
aca88567 12673 {
a06ea964
NC
12674 case EM_AARCH64:
12675 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
12676 case EM_ALPHA:
12677 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 12678 case EM_IA_64:
262cdac7
AM
12679 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
12680 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
12681 case EM_PARISC:
12682 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
12683 case EM_PPC64:
12684 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
12685 case EM_RISCV:
12686 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
12687 case EM_SPARC32PLUS:
12688 case EM_SPARCV9:
12689 case EM_SPARC:
714da62f
NC
12690 return reloc_type == 32 /* R_SPARC_64. */
12691 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 12692 case EM_X86_64:
8a9036a4 12693 case EM_L1OM:
7a9068fe 12694 case EM_K1OM:
aca88567 12695 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
12696 case EM_S390_OLD:
12697 case EM_S390:
aa137e4d
NC
12698 return reloc_type == 22; /* R_S390_64. */
12699 case EM_TILEGX:
12700 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 12701 case EM_MIPS:
aa137e4d 12702 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
12703 default:
12704 return FALSE;
12705 }
12706}
12707
85acf597
RH
12708/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
12709 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
12710
12711static bfd_boolean
dda8d76d 12712is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 12713{
dda8d76d 12714 switch (filedata->file_header.e_machine)
85acf597 12715 {
a06ea964
NC
12716 case EM_AARCH64:
12717 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 12718 case EM_ALPHA:
aa137e4d 12719 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 12720 case EM_IA_64:
262cdac7
AM
12721 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
12722 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 12723 case EM_PARISC:
aa137e4d 12724 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 12725 case EM_PPC64:
aa137e4d 12726 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
12727 case EM_SPARC32PLUS:
12728 case EM_SPARCV9:
12729 case EM_SPARC:
aa137e4d 12730 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 12731 case EM_X86_64:
8a9036a4 12732 case EM_L1OM:
7a9068fe 12733 case EM_K1OM:
aa137e4d 12734 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
12735 case EM_S390_OLD:
12736 case EM_S390:
aa137e4d
NC
12737 return reloc_type == 23; /* R_S390_PC64. */
12738 case EM_TILEGX:
12739 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
12740 default:
12741 return FALSE;
12742 }
12743}
12744
4dc3c23d
AM
12745/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12746 a 24-bit absolute RELA relocation used in DWARF debug sections. */
12747
12748static bfd_boolean
dda8d76d 12749is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 12750{
dda8d76d 12751 switch (filedata->file_header.e_machine)
4dc3c23d
AM
12752 {
12753 case EM_CYGNUS_MN10200:
12754 case EM_MN10200:
12755 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
12756 case EM_FT32:
12757 return reloc_type == 5; /* R_FT32_20. */
4dc3c23d
AM
12758 default:
12759 return FALSE;
12760 }
12761}
12762
aca88567
NC
12763/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12764 a 16-bit absolute RELA relocation used in DWARF debug sections. */
12765
12766static bfd_boolean
dda8d76d 12767is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 12768{
d347c9df 12769 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12770 switch (filedata->file_header.e_machine)
4b78141a 12771 {
886a2506
NC
12772 case EM_ARC:
12773 case EM_ARC_COMPACT:
12774 case EM_ARC_COMPACT2:
12775 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
12776 case EM_ADAPTEVA_EPIPHANY:
12777 return reloc_type == 5;
aca88567
NC
12778 case EM_AVR_OLD:
12779 case EM_AVR:
12780 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
12781 case EM_CYGNUS_D10V:
12782 case EM_D10V:
12783 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
12784 case EM_FT32:
12785 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
12786 case EM_H8S:
12787 case EM_H8_300:
12788 case EM_H8_300H:
aca88567
NC
12789 return reloc_type == R_H8_DIR16;
12790 case EM_IP2K_OLD:
12791 case EM_IP2K:
12792 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 12793 case EM_M32C_OLD:
f4236fe4
DD
12794 case EM_M32C:
12795 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
12796 case EM_CYGNUS_MN10200:
12797 case EM_MN10200:
12798 return reloc_type == 2; /* R_MN10200_16. */
12799 case EM_CYGNUS_MN10300:
12800 case EM_MN10300:
12801 return reloc_type == 2; /* R_MN10300_16. */
aca88567 12802 case EM_MSP430:
dda8d76d 12803 if (uses_msp430x_relocs (filedata))
13761a11 12804 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 12805 /* Fall through. */
78c8d46c 12806 case EM_MSP430_OLD:
aca88567 12807 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
12808 case EM_NDS32:
12809 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 12810 case EM_ALTERA_NIOS2:
36591ba1 12811 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
12812 case EM_NIOS32:
12813 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
12814 case EM_OR1K:
12815 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
12816 case EM_RISCV:
12817 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
12818 case EM_TI_PRU:
12819 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
12820 case EM_TI_C6000:
12821 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
12822 case EM_VISIUM:
12823 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
12824 case EM_XC16X:
12825 case EM_C166:
12826 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
12827 case EM_XGATE:
12828 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 12829 default:
aca88567 12830 return FALSE;
4b78141a
NC
12831 }
12832}
12833
39e07931
AS
12834/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12835 a 8-bit absolute RELA relocation used in DWARF debug sections. */
12836
12837static bfd_boolean
12838is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
12839{
12840 switch (filedata->file_header.e_machine)
12841 {
12842 case EM_RISCV:
12843 return reloc_type == 54; /* R_RISCV_SET8. */
12844 default:
12845 return FALSE;
12846 }
12847}
12848
12849/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12850 a 6-bit absolute RELA relocation used in DWARF debug sections. */
12851
12852static bfd_boolean
12853is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
12854{
12855 switch (filedata->file_header.e_machine)
12856 {
12857 case EM_RISCV:
12858 return reloc_type == 53; /* R_RISCV_SET6. */
12859 default:
12860 return FALSE;
12861 }
12862}
12863
03336641
JW
12864/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12865 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
12866
12867static bfd_boolean
12868is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12869{
12870 /* Please keep this table alpha-sorted for ease of visual lookup. */
12871 switch (filedata->file_header.e_machine)
12872 {
12873 case EM_RISCV:
12874 return reloc_type == 35; /* R_RISCV_ADD32. */
12875 default:
12876 return FALSE;
12877 }
12878}
12879
12880/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12881 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
12882
12883static bfd_boolean
12884is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12885{
12886 /* Please keep this table alpha-sorted for ease of visual lookup. */
12887 switch (filedata->file_header.e_machine)
12888 {
12889 case EM_RISCV:
12890 return reloc_type == 39; /* R_RISCV_SUB32. */
12891 default:
12892 return FALSE;
12893 }
12894}
12895
12896/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12897 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
12898
12899static bfd_boolean
12900is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12901{
12902 /* Please keep this table alpha-sorted for ease of visual lookup. */
12903 switch (filedata->file_header.e_machine)
12904 {
12905 case EM_RISCV:
12906 return reloc_type == 36; /* R_RISCV_ADD64. */
12907 default:
12908 return FALSE;
12909 }
12910}
12911
12912/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12913 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
12914
12915static bfd_boolean
12916is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12917{
12918 /* Please keep this table alpha-sorted for ease of visual lookup. */
12919 switch (filedata->file_header.e_machine)
12920 {
12921 case EM_RISCV:
12922 return reloc_type == 40; /* R_RISCV_SUB64. */
12923 default:
12924 return FALSE;
12925 }
12926}
12927
12928/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12929 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
12930
12931static bfd_boolean
12932is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12933{
12934 /* Please keep this table alpha-sorted for ease of visual lookup. */
12935 switch (filedata->file_header.e_machine)
12936 {
12937 case EM_RISCV:
12938 return reloc_type == 34; /* R_RISCV_ADD16. */
12939 default:
12940 return FALSE;
12941 }
12942}
12943
12944/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12945 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
12946
12947static bfd_boolean
12948is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12949{
12950 /* Please keep this table alpha-sorted for ease of visual lookup. */
12951 switch (filedata->file_header.e_machine)
12952 {
12953 case EM_RISCV:
12954 return reloc_type == 38; /* R_RISCV_SUB16. */
12955 default:
12956 return FALSE;
12957 }
12958}
12959
12960/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12961 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
12962
12963static bfd_boolean
12964is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12965{
12966 /* Please keep this table alpha-sorted for ease of visual lookup. */
12967 switch (filedata->file_header.e_machine)
12968 {
12969 case EM_RISCV:
12970 return reloc_type == 33; /* R_RISCV_ADD8. */
12971 default:
12972 return FALSE;
12973 }
12974}
12975
12976/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12977 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
12978
12979static bfd_boolean
12980is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12981{
12982 /* Please keep this table alpha-sorted for ease of visual lookup. */
12983 switch (filedata->file_header.e_machine)
12984 {
12985 case EM_RISCV:
12986 return reloc_type == 37; /* R_RISCV_SUB8. */
12987 default:
12988 return FALSE;
12989 }
12990}
12991
39e07931
AS
12992/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12993 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
12994
12995static bfd_boolean
12996is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12997{
12998 switch (filedata->file_header.e_machine)
12999 {
13000 case EM_RISCV:
13001 return reloc_type == 52; /* R_RISCV_SUB6. */
13002 default:
13003 return FALSE;
13004 }
13005}
13006
2a7b2e88
JK
13007/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
13008 relocation entries (possibly formerly used for SHT_GROUP sections). */
13009
13010static bfd_boolean
dda8d76d 13011is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 13012{
dda8d76d 13013 switch (filedata->file_header.e_machine)
2a7b2e88 13014 {
cb8f3167 13015 case EM_386: /* R_386_NONE. */
d347c9df 13016 case EM_68K: /* R_68K_NONE. */
cfb8c092 13017 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
13018 case EM_ALPHA: /* R_ALPHA_NONE. */
13019 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 13020 case EM_ARC: /* R_ARC_NONE. */
886a2506 13021 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 13022 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 13023 case EM_ARM: /* R_ARM_NONE. */
d347c9df 13024 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 13025 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
13026 case EM_FT32: /* R_FT32_NONE. */
13027 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 13028 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
13029 case EM_L1OM: /* R_X86_64_NONE. */
13030 case EM_M32R: /* R_M32R_NONE. */
13031 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 13032 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 13033 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
13034 case EM_NIOS32: /* R_NIOS_NONE. */
13035 case EM_OR1K: /* R_OR1K_NONE. */
13036 case EM_PARISC: /* R_PARISC_NONE. */
13037 case EM_PPC64: /* R_PPC64_NONE. */
13038 case EM_PPC: /* R_PPC_NONE. */
e23eba97 13039 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
13040 case EM_S390: /* R_390_NONE. */
13041 case EM_S390_OLD:
13042 case EM_SH: /* R_SH_NONE. */
13043 case EM_SPARC32PLUS:
13044 case EM_SPARC: /* R_SPARC_NONE. */
13045 case EM_SPARCV9:
aa137e4d
NC
13046 case EM_TILEGX: /* R_TILEGX_NONE. */
13047 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
13048 case EM_TI_C6000:/* R_C6000_NONE. */
13049 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 13050 case EM_XC16X:
f96bd6c2 13051 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 13052 return reloc_type == 0;
d347c9df 13053
a06ea964
NC
13054 case EM_AARCH64:
13055 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
13056 case EM_AVR_OLD:
13057 case EM_AVR:
13058 return (reloc_type == 0 /* R_AVR_NONE. */
13059 || reloc_type == 30 /* R_AVR_DIFF8. */
13060 || reloc_type == 31 /* R_AVR_DIFF16. */
13061 || reloc_type == 32 /* R_AVR_DIFF32. */);
13062 case EM_METAG:
13063 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
13064 case EM_NDS32:
13065 return (reloc_type == 0 /* R_XTENSA_NONE. */
13066 || reloc_type == 204 /* R_NDS32_DIFF8. */
13067 || reloc_type == 205 /* R_NDS32_DIFF16. */
13068 || reloc_type == 206 /* R_NDS32_DIFF32. */
13069 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
13070 case EM_TI_PRU:
13071 return (reloc_type == 0 /* R_PRU_NONE. */
13072 || reloc_type == 65 /* R_PRU_DIFF8. */
13073 || reloc_type == 66 /* R_PRU_DIFF16. */
13074 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
13075 case EM_XTENSA_OLD:
13076 case EM_XTENSA:
4dc3c23d
AM
13077 return (reloc_type == 0 /* R_XTENSA_NONE. */
13078 || reloc_type == 17 /* R_XTENSA_DIFF8. */
13079 || reloc_type == 18 /* R_XTENSA_DIFF16. */
13080 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
13081 }
13082 return FALSE;
13083}
13084
d1c4b12b
NC
13085/* Returns TRUE if there is a relocation against
13086 section NAME at OFFSET bytes. */
13087
13088bfd_boolean
13089reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
13090{
13091 Elf_Internal_Rela * relocs;
13092 Elf_Internal_Rela * rp;
13093
13094 if (dsec == NULL || dsec->reloc_info == NULL)
13095 return FALSE;
13096
13097 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
13098
13099 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
13100 if (rp->r_offset == offset)
13101 return TRUE;
13102
13103 return FALSE;
13104}
13105
cf13d699 13106/* Apply relocations to a section.
32ec8896
NC
13107 Returns TRUE upon success, FALSE otherwise.
13108 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
13109 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
13110 will be set to the number of relocs loaded.
13111
cf13d699 13112 Note: So far support has been added only for those relocations
32ec8896
NC
13113 which can be found in debug sections. FIXME: Add support for
13114 more relocations ? */
1b315056 13115
32ec8896 13116static bfd_boolean
dda8d76d 13117apply_relocations (Filedata * filedata,
d1c4b12b
NC
13118 const Elf_Internal_Shdr * section,
13119 unsigned char * start,
13120 bfd_size_type size,
1449284b 13121 void ** relocs_return,
d1c4b12b 13122 unsigned long * num_relocs_return)
1b315056 13123{
cf13d699 13124 Elf_Internal_Shdr * relsec;
0d2a7a93 13125 unsigned char * end = start + size;
cb8f3167 13126
d1c4b12b
NC
13127 if (relocs_return != NULL)
13128 {
13129 * (Elf_Internal_Rela **) relocs_return = NULL;
13130 * num_relocs_return = 0;
13131 }
13132
dda8d76d 13133 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
13134 /* No relocs to apply. */
13135 return TRUE;
1b315056 13136
cf13d699 13137 /* Find the reloc section associated with the section. */
dda8d76d
NC
13138 for (relsec = filedata->section_headers;
13139 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 13140 ++relsec)
252b5132 13141 {
41e92641
NC
13142 bfd_boolean is_rela;
13143 unsigned long num_relocs;
2cf0635d
NC
13144 Elf_Internal_Rela * relocs;
13145 Elf_Internal_Rela * rp;
13146 Elf_Internal_Shdr * symsec;
13147 Elf_Internal_Sym * symtab;
ba5cdace 13148 unsigned long num_syms;
2cf0635d 13149 Elf_Internal_Sym * sym;
252b5132 13150
41e92641 13151 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13152 || relsec->sh_info >= filedata->file_header.e_shnum
13153 || filedata->section_headers + relsec->sh_info != section
c256ffe7 13154 || relsec->sh_size == 0
dda8d76d 13155 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 13156 continue;
428409d5 13157
41e92641
NC
13158 is_rela = relsec->sh_type == SHT_RELA;
13159
13160 if (is_rela)
13161 {
dda8d76d 13162 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 13163 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13164 return FALSE;
41e92641
NC
13165 }
13166 else
13167 {
dda8d76d 13168 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 13169 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13170 return FALSE;
41e92641
NC
13171 }
13172
13173 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 13174 if (filedata->file_header.e_machine == EM_SH)
41e92641 13175 is_rela = FALSE;
428409d5 13176
dda8d76d 13177 symsec = filedata->section_headers + relsec->sh_link;
1449284b
NC
13178 if (symsec->sh_type != SHT_SYMTAB
13179 && symsec->sh_type != SHT_DYNSYM)
32ec8896 13180 return FALSE;
dda8d76d 13181 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 13182
41e92641 13183 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 13184 {
41e92641
NC
13185 bfd_vma addend;
13186 unsigned int reloc_type;
13187 unsigned int reloc_size;
03336641
JW
13188 bfd_boolean reloc_inplace = FALSE;
13189 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 13190 unsigned char * rloc;
ba5cdace 13191 unsigned long sym_index;
4b78141a 13192
dda8d76d 13193 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 13194
dda8d76d 13195 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 13196 continue;
dda8d76d 13197 else if (is_none_reloc (filedata, reloc_type))
98fb390a 13198 continue;
dda8d76d
NC
13199 else if (is_32bit_abs_reloc (filedata, reloc_type)
13200 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 13201 reloc_size = 4;
dda8d76d
NC
13202 else if (is_64bit_abs_reloc (filedata, reloc_type)
13203 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 13204 reloc_size = 8;
dda8d76d 13205 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 13206 reloc_size = 3;
dda8d76d 13207 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 13208 reloc_size = 2;
39e07931
AS
13209 else if (is_8bit_abs_reloc (filedata, reloc_type)
13210 || is_6bit_abs_reloc (filedata, reloc_type))
13211 reloc_size = 1;
03336641
JW
13212 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
13213 reloc_type))
13214 || is_32bit_inplace_add_reloc (filedata, reloc_type))
13215 {
13216 reloc_size = 4;
13217 reloc_inplace = TRUE;
13218 }
13219 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
13220 reloc_type))
13221 || is_64bit_inplace_add_reloc (filedata, reloc_type))
13222 {
13223 reloc_size = 8;
13224 reloc_inplace = TRUE;
13225 }
13226 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
13227 reloc_type))
13228 || is_16bit_inplace_add_reloc (filedata, reloc_type))
13229 {
13230 reloc_size = 2;
13231 reloc_inplace = TRUE;
13232 }
13233 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
13234 reloc_type))
13235 || is_8bit_inplace_add_reloc (filedata, reloc_type))
13236 {
13237 reloc_size = 1;
13238 reloc_inplace = TRUE;
13239 }
39e07931
AS
13240 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
13241 reloc_type)))
13242 {
13243 reloc_size = 1;
13244 reloc_inplace = TRUE;
13245 }
aca88567 13246 else
4b78141a 13247 {
bee0ee85 13248 static unsigned int prev_reloc = 0;
dda8d76d 13249
bee0ee85
NC
13250 if (reloc_type != prev_reloc)
13251 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 13252 reloc_type, printable_section_name (filedata, section));
bee0ee85 13253 prev_reloc = reloc_type;
4b78141a
NC
13254 continue;
13255 }
103f02d3 13256
91d6fa6a 13257 rloc = start + rp->r_offset;
c8da6823 13258 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
13259 {
13260 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
13261 (unsigned long) rp->r_offset,
dda8d76d 13262 printable_section_name (filedata, section));
700dd8b7
L
13263 continue;
13264 }
103f02d3 13265
ba5cdace
NC
13266 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
13267 if (sym_index >= num_syms)
13268 {
13269 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 13270 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
13271 continue;
13272 }
13273 sym = symtab + sym_index;
41e92641
NC
13274
13275 /* If the reloc has a symbol associated with it,
55f25fc3
L
13276 make sure that it is of an appropriate type.
13277
13278 Relocations against symbols without type can happen.
13279 Gcc -feliminate-dwarf2-dups may generate symbols
13280 without type for debug info.
13281
13282 Icc generates relocations against function symbols
13283 instead of local labels.
13284
13285 Relocations against object symbols can happen, eg when
13286 referencing a global array. For an example of this see
13287 the _clz.o binary in libgcc.a. */
aca88567 13288 if (sym != symtab
b8871f35 13289 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 13290 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 13291 {
d3a49aa8 13292 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
13293 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
13294 printable_section_name (filedata, relsec),
d3a49aa8 13295 (long int)(rp - relocs));
aca88567 13296 continue;
5b18a4bc 13297 }
252b5132 13298
4dc3c23d
AM
13299 addend = 0;
13300 if (is_rela)
13301 addend += rp->r_addend;
c47320c3
AM
13302 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
13303 partial_inplace. */
4dc3c23d 13304 if (!is_rela
dda8d76d 13305 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 13306 && reloc_type == 1)
dda8d76d
NC
13307 || ((filedata->file_header.e_machine == EM_PJ
13308 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 13309 && reloc_type == 1)
dda8d76d
NC
13310 || ((filedata->file_header.e_machine == EM_D30V
13311 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
13312 && reloc_type == 12)
13313 || reloc_inplace)
39e07931
AS
13314 {
13315 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
13316 addend += byte_get (rloc, reloc_size) & 0x3f;
13317 else
13318 addend += byte_get (rloc, reloc_size);
13319 }
cb8f3167 13320
dda8d76d
NC
13321 if (is_32bit_pcrel_reloc (filedata, reloc_type)
13322 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
13323 {
13324 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 13325 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 13326 addend -= 8;
91d6fa6a 13327 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
13328 reloc_size);
13329 }
39e07931
AS
13330 else if (is_6bit_abs_reloc (filedata, reloc_type)
13331 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
13332 {
13333 if (reloc_subtract)
13334 addend -= sym->st_value;
13335 else
13336 addend += sym->st_value;
13337 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
13338 byte_put (rloc, addend, reloc_size);
13339 }
03336641
JW
13340 else if (reloc_subtract)
13341 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 13342 else
91d6fa6a 13343 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 13344 }
252b5132 13345
5b18a4bc 13346 free (symtab);
f84ce13b
NC
13347 /* Let the target specific reloc processing code know that
13348 we have finished with these relocs. */
dda8d76d 13349 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
13350
13351 if (relocs_return)
13352 {
13353 * (Elf_Internal_Rela **) relocs_return = relocs;
13354 * num_relocs_return = num_relocs;
13355 }
13356 else
13357 free (relocs);
13358
5b18a4bc
NC
13359 break;
13360 }
32ec8896 13361
dfc616fa 13362 return TRUE;
5b18a4bc 13363}
103f02d3 13364
cf13d699 13365#ifdef SUPPORT_DISASSEMBLY
32ec8896 13366static bfd_boolean
dda8d76d 13367disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13368{
dda8d76d 13369 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 13370
74e1a04b 13371 /* FIXME: XXX -- to be done --- XXX */
cf13d699 13372
32ec8896 13373 return TRUE;
cf13d699
NC
13374}
13375#endif
13376
13377/* Reads in the contents of SECTION from FILE, returning a pointer
13378 to a malloc'ed buffer or NULL if something went wrong. */
13379
13380static char *
dda8d76d 13381get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13382{
dda8d76d 13383 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
13384
13385 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
13386 {
c6b78c96 13387 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 13388 printable_section_name (filedata, section));
cf13d699
NC
13389 return NULL;
13390 }
13391
dda8d76d 13392 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 13393 _("section contents"));
cf13d699
NC
13394}
13395
0e602686
NC
13396/* Uncompresses a section that was compressed using zlib, in place. */
13397
13398static bfd_boolean
dda8d76d
NC
13399uncompress_section_contents (unsigned char ** buffer,
13400 dwarf_size_type uncompressed_size,
13401 dwarf_size_type * size)
0e602686
NC
13402{
13403 dwarf_size_type compressed_size = *size;
13404 unsigned char * compressed_buffer = *buffer;
13405 unsigned char * uncompressed_buffer;
13406 z_stream strm;
13407 int rc;
13408
13409 /* It is possible the section consists of several compressed
13410 buffers concatenated together, so we uncompress in a loop. */
13411 /* PR 18313: The state field in the z_stream structure is supposed
13412 to be invisible to the user (ie us), but some compilers will
13413 still complain about it being used without initialisation. So
13414 we first zero the entire z_stream structure and then set the fields
13415 that we need. */
13416 memset (& strm, 0, sizeof strm);
13417 strm.avail_in = compressed_size;
13418 strm.next_in = (Bytef *) compressed_buffer;
13419 strm.avail_out = uncompressed_size;
13420 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
13421
13422 rc = inflateInit (& strm);
13423 while (strm.avail_in > 0)
13424 {
13425 if (rc != Z_OK)
13426 goto fail;
13427 strm.next_out = ((Bytef *) uncompressed_buffer
13428 + (uncompressed_size - strm.avail_out));
13429 rc = inflate (&strm, Z_FINISH);
13430 if (rc != Z_STREAM_END)
13431 goto fail;
13432 rc = inflateReset (& strm);
13433 }
13434 rc = inflateEnd (& strm);
13435 if (rc != Z_OK
13436 || strm.avail_out != 0)
13437 goto fail;
13438
13439 *buffer = uncompressed_buffer;
13440 *size = uncompressed_size;
13441 return TRUE;
13442
13443 fail:
13444 free (uncompressed_buffer);
13445 /* Indicate decompression failure. */
13446 *buffer = NULL;
13447 return FALSE;
13448}
dd24e3da 13449
32ec8896 13450static bfd_boolean
dda8d76d 13451dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13452{
0e602686
NC
13453 Elf_Internal_Shdr * relsec;
13454 bfd_size_type num_bytes;
fd8008d8
L
13455 unsigned char * data;
13456 unsigned char * end;
13457 unsigned char * real_start;
13458 unsigned char * start;
0e602686 13459 bfd_boolean some_strings_shown;
cf13d699 13460
dda8d76d 13461 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13462 if (start == NULL)
c6b78c96
NC
13463 /* PR 21820: Do not fail if the section was empty. */
13464 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
13465
0e602686 13466 num_bytes = section->sh_size;
cf13d699 13467
dda8d76d 13468 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13469
0e602686
NC
13470 if (decompress_dumps)
13471 {
13472 dwarf_size_type new_size = num_bytes;
13473 dwarf_size_type uncompressed_size = 0;
13474
13475 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13476 {
13477 Elf_Internal_Chdr chdr;
13478 unsigned int compression_header_size
ebdf1ebf
NC
13479 = get_compression_header (& chdr, (unsigned char *) start,
13480 num_bytes);
0e602686 13481
813dabb9 13482 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13483 {
813dabb9 13484 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13485 printable_section_name (filedata, section), chdr.ch_type);
32ec8896 13486 return FALSE;
813dabb9 13487 }
813dabb9
L
13488 uncompressed_size = chdr.ch_size;
13489 start += compression_header_size;
13490 new_size -= compression_header_size;
0e602686
NC
13491 }
13492 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13493 {
13494 /* Read the zlib header. In this case, it should be "ZLIB"
13495 followed by the uncompressed section size, 8 bytes in
13496 big-endian order. */
13497 uncompressed_size = start[4]; uncompressed_size <<= 8;
13498 uncompressed_size += start[5]; uncompressed_size <<= 8;
13499 uncompressed_size += start[6]; uncompressed_size <<= 8;
13500 uncompressed_size += start[7]; uncompressed_size <<= 8;
13501 uncompressed_size += start[8]; uncompressed_size <<= 8;
13502 uncompressed_size += start[9]; uncompressed_size <<= 8;
13503 uncompressed_size += start[10]; uncompressed_size <<= 8;
13504 uncompressed_size += start[11];
13505 start += 12;
13506 new_size -= 12;
13507 }
13508
1835f746
NC
13509 if (uncompressed_size)
13510 {
13511 if (uncompress_section_contents (& start,
13512 uncompressed_size, & new_size))
13513 num_bytes = new_size;
13514 else
13515 {
13516 error (_("Unable to decompress section %s\n"),
dda8d76d 13517 printable_section_name (filedata, section));
32ec8896 13518 return FALSE;
1835f746
NC
13519 }
13520 }
bc303e5d
NC
13521 else
13522 start = real_start;
0e602686 13523 }
fd8008d8 13524
cf13d699
NC
13525 /* If the section being dumped has relocations against it the user might
13526 be expecting these relocations to have been applied. Check for this
13527 case and issue a warning message in order to avoid confusion.
13528 FIXME: Maybe we ought to have an option that dumps a section with
13529 relocs applied ? */
dda8d76d
NC
13530 for (relsec = filedata->section_headers;
13531 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13532 ++relsec)
13533 {
13534 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13535 || relsec->sh_info >= filedata->file_header.e_shnum
13536 || filedata->section_headers + relsec->sh_info != section
cf13d699 13537 || relsec->sh_size == 0
dda8d76d 13538 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13539 continue;
13540
13541 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13542 break;
13543 }
13544
cf13d699
NC
13545 data = start;
13546 end = start + num_bytes;
13547 some_strings_shown = FALSE;
13548
13549 while (data < end)
13550 {
13551 while (!ISPRINT (* data))
13552 if (++ data >= end)
13553 break;
13554
13555 if (data < end)
13556 {
071436c6
NC
13557 size_t maxlen = end - data;
13558
cf13d699 13559#ifndef __MSVCRT__
c975cc98
NC
13560 /* PR 11128: Use two separate invocations in order to work
13561 around bugs in the Solaris 8 implementation of printf. */
13562 printf (" [%6tx] ", data - start);
cf13d699 13563#else
071436c6 13564 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 13565#endif
4082ef84
NC
13566 if (maxlen > 0)
13567 {
fd8008d8 13568 print_symbol ((int) maxlen, (const char *) data);
4082ef84 13569 putchar ('\n');
fd8008d8 13570 data += strnlen ((const char *) data, maxlen);
4082ef84
NC
13571 }
13572 else
13573 {
13574 printf (_("<corrupt>\n"));
13575 data = end;
13576 }
cf13d699
NC
13577 some_strings_shown = TRUE;
13578 }
13579 }
13580
13581 if (! some_strings_shown)
13582 printf (_(" No strings found in this section."));
13583
0e602686 13584 free (real_start);
cf13d699
NC
13585
13586 putchar ('\n');
32ec8896 13587 return TRUE;
cf13d699
NC
13588}
13589
32ec8896 13590static bfd_boolean
dda8d76d
NC
13591dump_section_as_bytes (Elf_Internal_Shdr * section,
13592 Filedata * filedata,
13593 bfd_boolean relocate)
cf13d699
NC
13594{
13595 Elf_Internal_Shdr * relsec;
0e602686
NC
13596 bfd_size_type bytes;
13597 bfd_size_type section_size;
13598 bfd_vma addr;
13599 unsigned char * data;
13600 unsigned char * real_start;
13601 unsigned char * start;
13602
dda8d76d 13603 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13604 if (start == NULL)
c6b78c96
NC
13605 /* PR 21820: Do not fail if the section was empty. */
13606 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 13607
0e602686 13608 section_size = section->sh_size;
cf13d699 13609
dda8d76d 13610 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13611
0e602686
NC
13612 if (decompress_dumps)
13613 {
13614 dwarf_size_type new_size = section_size;
13615 dwarf_size_type uncompressed_size = 0;
13616
13617 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13618 {
13619 Elf_Internal_Chdr chdr;
13620 unsigned int compression_header_size
ebdf1ebf 13621 = get_compression_header (& chdr, start, section_size);
0e602686 13622
813dabb9 13623 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13624 {
813dabb9 13625 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13626 printable_section_name (filedata, section), chdr.ch_type);
32ec8896 13627 return FALSE;
0e602686 13628 }
813dabb9
L
13629 uncompressed_size = chdr.ch_size;
13630 start += compression_header_size;
13631 new_size -= compression_header_size;
0e602686
NC
13632 }
13633 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13634 {
13635 /* Read the zlib header. In this case, it should be "ZLIB"
13636 followed by the uncompressed section size, 8 bytes in
13637 big-endian order. */
13638 uncompressed_size = start[4]; uncompressed_size <<= 8;
13639 uncompressed_size += start[5]; uncompressed_size <<= 8;
13640 uncompressed_size += start[6]; uncompressed_size <<= 8;
13641 uncompressed_size += start[7]; uncompressed_size <<= 8;
13642 uncompressed_size += start[8]; uncompressed_size <<= 8;
13643 uncompressed_size += start[9]; uncompressed_size <<= 8;
13644 uncompressed_size += start[10]; uncompressed_size <<= 8;
13645 uncompressed_size += start[11];
13646 start += 12;
13647 new_size -= 12;
13648 }
13649
f055032e
NC
13650 if (uncompressed_size)
13651 {
13652 if (uncompress_section_contents (& start, uncompressed_size,
13653 & new_size))
bc303e5d
NC
13654 {
13655 section_size = new_size;
13656 }
f055032e
NC
13657 else
13658 {
13659 error (_("Unable to decompress section %s\n"),
dda8d76d 13660 printable_section_name (filedata, section));
bc303e5d 13661 /* FIXME: Print the section anyway ? */
32ec8896 13662 return FALSE;
f055032e
NC
13663 }
13664 }
bc303e5d
NC
13665 else
13666 start = real_start;
0e602686 13667 }
14ae95f2 13668
cf13d699
NC
13669 if (relocate)
13670 {
dda8d76d 13671 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
32ec8896 13672 return FALSE;
cf13d699
NC
13673 }
13674 else
13675 {
13676 /* If the section being dumped has relocations against it the user might
13677 be expecting these relocations to have been applied. Check for this
13678 case and issue a warning message in order to avoid confusion.
13679 FIXME: Maybe we ought to have an option that dumps a section with
13680 relocs applied ? */
dda8d76d
NC
13681 for (relsec = filedata->section_headers;
13682 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13683 ++relsec)
13684 {
13685 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13686 || relsec->sh_info >= filedata->file_header.e_shnum
13687 || filedata->section_headers + relsec->sh_info != section
cf13d699 13688 || relsec->sh_size == 0
dda8d76d 13689 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13690 continue;
13691
13692 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13693 break;
13694 }
13695 }
13696
13697 addr = section->sh_addr;
0e602686 13698 bytes = section_size;
cf13d699
NC
13699 data = start;
13700
13701 while (bytes)
13702 {
13703 int j;
13704 int k;
13705 int lbytes;
13706
13707 lbytes = (bytes > 16 ? 16 : bytes);
13708
13709 printf (" 0x%8.8lx ", (unsigned long) addr);
13710
13711 for (j = 0; j < 16; j++)
13712 {
13713 if (j < lbytes)
13714 printf ("%2.2x", data[j]);
13715 else
13716 printf (" ");
13717
13718 if ((j & 3) == 3)
13719 printf (" ");
13720 }
13721
13722 for (j = 0; j < lbytes; j++)
13723 {
13724 k = data[j];
13725 if (k >= ' ' && k < 0x7f)
13726 printf ("%c", k);
13727 else
13728 printf (".");
13729 }
13730
13731 putchar ('\n');
13732
13733 data += lbytes;
13734 addr += lbytes;
13735 bytes -= lbytes;
13736 }
13737
0e602686 13738 free (real_start);
cf13d699
NC
13739
13740 putchar ('\n');
32ec8896 13741 return TRUE;
cf13d699
NC
13742}
13743
32ec8896 13744static bfd_boolean
dda8d76d
NC
13745load_specific_debug_section (enum dwarf_section_display_enum debug,
13746 const Elf_Internal_Shdr * sec,
13747 void * data)
1007acb3 13748{
2cf0635d 13749 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 13750 char buf [64];
dda8d76d
NC
13751 Filedata * filedata = (Filedata *) data;
13752
19e6b90e 13753 if (section->start != NULL)
dda8d76d
NC
13754 {
13755 /* If it is already loaded, do nothing. */
13756 if (streq (section->filename, filedata->file_name))
13757 return TRUE;
13758 free (section->start);
13759 }
1007acb3 13760
19e6b90e
L
13761 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
13762 section->address = sec->sh_addr;
06614111 13763 section->user_data = NULL;
dda8d76d
NC
13764 section->filename = filedata->file_name;
13765 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
13766 sec->sh_offset, 1,
13767 sec->sh_size, buf);
59245841
NC
13768 if (section->start == NULL)
13769 section->size = 0;
13770 else
13771 {
77115a4a
L
13772 unsigned char *start = section->start;
13773 dwarf_size_type size = sec->sh_size;
dab394de 13774 dwarf_size_type uncompressed_size = 0;
77115a4a
L
13775
13776 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
13777 {
13778 Elf_Internal_Chdr chdr;
d8024a91
NC
13779 unsigned int compression_header_size;
13780
f53be977
L
13781 if (size < (is_32bit_elf
13782 ? sizeof (Elf32_External_Chdr)
13783 : sizeof (Elf64_External_Chdr)))
d8024a91
NC
13784 {
13785 warn (_("compressed section %s is too small to contain a compression header"),
13786 section->name);
32ec8896 13787 return FALSE;
d8024a91
NC
13788 }
13789
ebdf1ebf 13790 compression_header_size = get_compression_header (&chdr, start, size);
d8024a91 13791
813dabb9
L
13792 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
13793 {
13794 warn (_("section '%s' has unsupported compress type: %d\n"),
13795 section->name, chdr.ch_type);
32ec8896 13796 return FALSE;
813dabb9 13797 }
dab394de 13798 uncompressed_size = chdr.ch_size;
77115a4a
L
13799 start += compression_header_size;
13800 size -= compression_header_size;
13801 }
dab394de
L
13802 else if (size > 12 && streq ((char *) start, "ZLIB"))
13803 {
13804 /* Read the zlib header. In this case, it should be "ZLIB"
13805 followed by the uncompressed section size, 8 bytes in
13806 big-endian order. */
13807 uncompressed_size = start[4]; uncompressed_size <<= 8;
13808 uncompressed_size += start[5]; uncompressed_size <<= 8;
13809 uncompressed_size += start[6]; uncompressed_size <<= 8;
13810 uncompressed_size += start[7]; uncompressed_size <<= 8;
13811 uncompressed_size += start[8]; uncompressed_size <<= 8;
13812 uncompressed_size += start[9]; uncompressed_size <<= 8;
13813 uncompressed_size += start[10]; uncompressed_size <<= 8;
13814 uncompressed_size += start[11];
13815 start += 12;
13816 size -= 12;
13817 }
13818
1835f746 13819 if (uncompressed_size)
77115a4a 13820 {
1835f746
NC
13821 if (uncompress_section_contents (&start, uncompressed_size,
13822 &size))
13823 {
13824 /* Free the compressed buffer, update the section buffer
13825 and the section size if uncompress is successful. */
13826 free (section->start);
13827 section->start = start;
13828 }
13829 else
13830 {
13831 error (_("Unable to decompress section %s\n"),
dda8d76d 13832 printable_section_name (filedata, sec));
32ec8896 13833 return FALSE;
1835f746 13834 }
77115a4a 13835 }
bc303e5d 13836
77115a4a 13837 section->size = size;
59245841 13838 }
4a114e3e 13839
1b315056 13840 if (section->start == NULL)
32ec8896 13841 return FALSE;
1b315056 13842
19e6b90e 13843 if (debug_displays [debug].relocate)
32ec8896 13844 {
dda8d76d 13845 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
13846 & section->reloc_info, & section->num_relocs))
13847 return FALSE;
13848 }
d1c4b12b
NC
13849 else
13850 {
13851 section->reloc_info = NULL;
13852 section->num_relocs = 0;
13853 }
1007acb3 13854
32ec8896 13855 return TRUE;
1007acb3
L
13856}
13857
657d0d47
CC
13858/* If this is not NULL, load_debug_section will only look for sections
13859 within the list of sections given here. */
32ec8896 13860static unsigned int * section_subset = NULL;
657d0d47 13861
32ec8896 13862bfd_boolean
dda8d76d 13863load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 13864{
2cf0635d
NC
13865 struct dwarf_section * section = &debug_displays [debug].section;
13866 Elf_Internal_Shdr * sec;
dda8d76d
NC
13867 Filedata * filedata = (Filedata *) data;
13868
f425ec66
NC
13869 /* Without section headers we cannot find any sections. */
13870 if (filedata->section_headers == NULL)
13871 return FALSE;
13872
9c1ce108
AM
13873 if (filedata->string_table == NULL
13874 && filedata->file_header.e_shstrndx != SHN_UNDEF
13875 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
13876 {
13877 Elf_Internal_Shdr * strs;
13878
13879 /* Read in the string table, so that we have section names to scan. */
13880 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
13881
4dff97b2 13882 if (strs != NULL && strs->sh_size != 0)
dda8d76d 13883 {
9c1ce108
AM
13884 filedata->string_table
13885 = (char *) get_data (NULL, filedata, strs->sh_offset,
13886 1, strs->sh_size, _("string table"));
dda8d76d 13887
9c1ce108
AM
13888 filedata->string_table_length
13889 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
13890 }
13891 }
d966045b
DJ
13892
13893 /* Locate the debug section. */
dda8d76d 13894 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
13895 if (sec != NULL)
13896 section->name = section->uncompressed_name;
13897 else
13898 {
dda8d76d 13899 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
13900 if (sec != NULL)
13901 section->name = section->compressed_name;
13902 }
13903 if (sec == NULL)
32ec8896 13904 return FALSE;
d966045b 13905
657d0d47
CC
13906 /* If we're loading from a subset of sections, and we've loaded
13907 a section matching this name before, it's likely that it's a
13908 different one. */
13909 if (section_subset != NULL)
13910 free_debug_section (debug);
13911
dda8d76d 13912 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
13913}
13914
19e6b90e
L
13915void
13916free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 13917{
2cf0635d 13918 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 13919
19e6b90e
L
13920 if (section->start == NULL)
13921 return;
1007acb3 13922
19e6b90e
L
13923 free ((char *) section->start);
13924 section->start = NULL;
13925 section->address = 0;
13926 section->size = 0;
1007acb3
L
13927}
13928
32ec8896 13929static bfd_boolean
dda8d76d 13930display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 13931{
2cf0635d 13932 char * name = SECTION_NAME (section);
dda8d76d 13933 const char * print_name = printable_section_name (filedata, section);
19e6b90e 13934 bfd_size_type length;
32ec8896 13935 bfd_boolean result = TRUE;
3f5e193b 13936 int i;
1007acb3 13937
19e6b90e
L
13938 length = section->sh_size;
13939 if (length == 0)
1007acb3 13940 {
74e1a04b 13941 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 13942 return TRUE;
1007acb3 13943 }
5dff79d8
NC
13944 if (section->sh_type == SHT_NOBITS)
13945 {
13946 /* There is no point in dumping the contents of a debugging section
13947 which has the NOBITS type - the bits in the file will be random.
13948 This can happen when a file containing a .eh_frame section is
13949 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
13950 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
13951 print_name);
32ec8896 13952 return FALSE;
5dff79d8 13953 }
1007acb3 13954
0112cd26 13955 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 13956 name = ".debug_info";
1007acb3 13957
19e6b90e
L
13958 /* See if we know how to display the contents of this section. */
13959 for (i = 0; i < max; i++)
d85bf2ba
NC
13960 {
13961 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
13962 struct dwarf_section_display * display = debug_displays + i;
13963 struct dwarf_section * sec = & display->section;
d966045b 13964
d85bf2ba
NC
13965 if (streq (sec->uncompressed_name, name)
13966 || (id == line && const_strneq (name, ".debug_line."))
13967 || streq (sec->compressed_name, name))
13968 {
13969 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 13970
d85bf2ba
NC
13971 if (secondary)
13972 free_debug_section (id);
dda8d76d 13973
d85bf2ba
NC
13974 if (i == line && const_strneq (name, ".debug_line."))
13975 sec->name = name;
13976 else if (streq (sec->uncompressed_name, name))
13977 sec->name = sec->uncompressed_name;
13978 else
13979 sec->name = sec->compressed_name;
657d0d47 13980
d85bf2ba
NC
13981 if (load_specific_debug_section (id, section, filedata))
13982 {
13983 /* If this debug section is part of a CU/TU set in a .dwp file,
13984 restrict load_debug_section to the sections in that set. */
13985 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 13986
d85bf2ba 13987 result &= display->display (sec, filedata);
657d0d47 13988
d85bf2ba 13989 section_subset = NULL;
1007acb3 13990
d85bf2ba
NC
13991 if (secondary || (id != info && id != abbrev))
13992 free_debug_section (id);
13993 }
13994 break;
13995 }
13996 }
1007acb3 13997
19e6b90e 13998 if (i == max)
1007acb3 13999 {
74e1a04b 14000 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 14001 result = FALSE;
1007acb3
L
14002 }
14003
19e6b90e 14004 return result;
5b18a4bc 14005}
103f02d3 14006
aef1f6d0
DJ
14007/* Set DUMP_SECTS for all sections where dumps were requested
14008 based on section name. */
14009
14010static void
dda8d76d 14011initialise_dumps_byname (Filedata * filedata)
aef1f6d0 14012{
2cf0635d 14013 struct dump_list_entry * cur;
aef1f6d0
DJ
14014
14015 for (cur = dump_sects_byname; cur; cur = cur->next)
14016 {
14017 unsigned int i;
32ec8896 14018 bfd_boolean any = FALSE;
aef1f6d0 14019
dda8d76d
NC
14020 for (i = 0; i < filedata->file_header.e_shnum; i++)
14021 if (streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 14022 {
dda8d76d 14023 request_dump_bynumber (filedata, i, cur->type);
32ec8896 14024 any = TRUE;
aef1f6d0
DJ
14025 }
14026
14027 if (!any)
14028 warn (_("Section '%s' was not dumped because it does not exist!\n"),
14029 cur->name);
14030 }
14031}
14032
32ec8896 14033static bfd_boolean
dda8d76d 14034process_section_contents (Filedata * filedata)
5b18a4bc 14035{
2cf0635d 14036 Elf_Internal_Shdr * section;
19e6b90e 14037 unsigned int i;
32ec8896 14038 bfd_boolean res = TRUE;
103f02d3 14039
19e6b90e 14040 if (! do_dump)
32ec8896 14041 return TRUE;
103f02d3 14042
dda8d76d 14043 initialise_dumps_byname (filedata);
aef1f6d0 14044
dda8d76d
NC
14045 for (i = 0, section = filedata->section_headers;
14046 i < filedata->file_header.e_shnum && i < filedata->num_dump_sects;
19e6b90e
L
14047 i++, section++)
14048 {
dda8d76d
NC
14049 dump_type dump = filedata->dump_sects[i];
14050
19e6b90e 14051#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
14052 if (dump & DISASS_DUMP)
14053 {
14054 if (! disassemble_section (section, filedata))
14055 res = FALSE;
14056 }
19e6b90e 14057#endif
dda8d76d 14058 if (dump & HEX_DUMP)
32ec8896 14059 {
dda8d76d 14060 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
14061 res = FALSE;
14062 }
103f02d3 14063
dda8d76d 14064 if (dump & RELOC_DUMP)
32ec8896 14065 {
dda8d76d 14066 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
14067 res = FALSE;
14068 }
09c11c86 14069
dda8d76d 14070 if (dump & STRING_DUMP)
32ec8896 14071 {
dda8d76d 14072 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
14073 res = FALSE;
14074 }
cf13d699 14075
dda8d76d 14076 if (dump & DEBUG_DUMP)
32ec8896 14077 {
dda8d76d 14078 if (! display_debug_section (i, section, filedata))
32ec8896
NC
14079 res = FALSE;
14080 }
5b18a4bc 14081 }
103f02d3 14082
19e6b90e
L
14083 /* Check to see if the user requested a
14084 dump of a section that does not exist. */
dda8d76d 14085 while (i < filedata->num_dump_sects)
0ee3043f 14086 {
dda8d76d 14087 if (filedata->dump_sects[i])
32ec8896
NC
14088 {
14089 warn (_("Section %d was not dumped because it does not exist!\n"), i);
14090 res = FALSE;
14091 }
0ee3043f
NC
14092 i++;
14093 }
32ec8896
NC
14094
14095 return res;
5b18a4bc 14096}
103f02d3 14097
5b18a4bc 14098static void
19e6b90e 14099process_mips_fpe_exception (int mask)
5b18a4bc 14100{
19e6b90e
L
14101 if (mask)
14102 {
32ec8896
NC
14103 bfd_boolean first = TRUE;
14104
19e6b90e 14105 if (mask & OEX_FPU_INEX)
32ec8896 14106 fputs ("INEX", stdout), first = FALSE;
19e6b90e 14107 if (mask & OEX_FPU_UFLO)
32ec8896 14108 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14109 if (mask & OEX_FPU_OFLO)
32ec8896 14110 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14111 if (mask & OEX_FPU_DIV0)
32ec8896 14112 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
14113 if (mask & OEX_FPU_INVAL)
14114 printf ("%sINVAL", first ? "" : "|");
14115 }
5b18a4bc 14116 else
19e6b90e 14117 fputs ("0", stdout);
5b18a4bc 14118}
103f02d3 14119
f6f0e17b
NC
14120/* Display's the value of TAG at location P. If TAG is
14121 greater than 0 it is assumed to be an unknown tag, and
14122 a message is printed to this effect. Otherwise it is
14123 assumed that a message has already been printed.
14124
14125 If the bottom bit of TAG is set it assumed to have a
14126 string value, otherwise it is assumed to have an integer
14127 value.
14128
14129 Returns an updated P pointing to the first unread byte
14130 beyond the end of TAG's value.
14131
14132 Reads at or beyond END will not be made. */
14133
14134static unsigned char *
60abdbed 14135display_tag_value (signed int tag,
f6f0e17b
NC
14136 unsigned char * p,
14137 const unsigned char * const end)
14138{
14139 unsigned long val;
14140
14141 if (tag > 0)
14142 printf (" Tag_unknown_%d: ", tag);
14143
14144 if (p >= end)
14145 {
4082ef84 14146 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
14147 }
14148 else if (tag & 1)
14149 {
071436c6
NC
14150 /* PR 17531 file: 027-19978-0.004. */
14151 size_t maxlen = (end - p) - 1;
14152
14153 putchar ('"');
4082ef84
NC
14154 if (maxlen > 0)
14155 {
14156 print_symbol ((int) maxlen, (const char *) p);
14157 p += strnlen ((char *) p, maxlen) + 1;
14158 }
14159 else
14160 {
14161 printf (_("<corrupt string tag>"));
14162 p = (unsigned char *) end;
14163 }
071436c6 14164 printf ("\"\n");
f6f0e17b
NC
14165 }
14166 else
14167 {
14168 unsigned int len;
14169
14170 val = read_uleb128 (p, &len, end);
14171 p += len;
14172 printf ("%ld (0x%lx)\n", val, val);
14173 }
14174
4082ef84 14175 assert (p <= end);
f6f0e17b
NC
14176 return p;
14177}
14178
53a346d8
CZ
14179/* ARC ABI attributes section. */
14180
14181static unsigned char *
14182display_arc_attribute (unsigned char * p,
14183 const unsigned char * const end)
14184{
14185 unsigned int tag;
14186 unsigned int len;
14187 unsigned int val;
14188
14189 tag = read_uleb128 (p, &len, end);
14190 p += len;
14191
14192 switch (tag)
14193 {
14194 case Tag_ARC_PCS_config:
14195 val = read_uleb128 (p, &len, end);
14196 p += len;
14197 printf (" Tag_ARC_PCS_config: ");
14198 switch (val)
14199 {
14200 case 0:
14201 printf (_("Absent/Non standard\n"));
14202 break;
14203 case 1:
14204 printf (_("Bare metal/mwdt\n"));
14205 break;
14206 case 2:
14207 printf (_("Bare metal/newlib\n"));
14208 break;
14209 case 3:
14210 printf (_("Linux/uclibc\n"));
14211 break;
14212 case 4:
14213 printf (_("Linux/glibc\n"));
14214 break;
14215 default:
14216 printf (_("Unknown\n"));
14217 break;
14218 }
14219 break;
14220
14221 case Tag_ARC_CPU_base:
14222 val = read_uleb128 (p, &len, end);
14223 p += len;
14224 printf (" Tag_ARC_CPU_base: ");
14225 switch (val)
14226 {
14227 default:
14228 case TAG_CPU_NONE:
14229 printf (_("Absent\n"));
14230 break;
14231 case TAG_CPU_ARC6xx:
14232 printf ("ARC6xx\n");
14233 break;
14234 case TAG_CPU_ARC7xx:
14235 printf ("ARC7xx\n");
14236 break;
14237 case TAG_CPU_ARCEM:
14238 printf ("ARCEM\n");
14239 break;
14240 case TAG_CPU_ARCHS:
14241 printf ("ARCHS\n");
14242 break;
14243 }
14244 break;
14245
14246 case Tag_ARC_CPU_variation:
14247 val = read_uleb128 (p, &len, end);
14248 p += len;
14249 printf (" Tag_ARC_CPU_variation: ");
14250 switch (val)
14251 {
14252 default:
14253 if (val > 0 && val < 16)
53a346d8 14254 printf ("Core%d\n", val);
d8cbc93b
JL
14255 else
14256 printf ("Unknown\n");
14257 break;
14258
53a346d8
CZ
14259 case 0:
14260 printf (_("Absent\n"));
14261 break;
14262 }
14263 break;
14264
14265 case Tag_ARC_CPU_name:
14266 printf (" Tag_ARC_CPU_name: ");
14267 p = display_tag_value (-1, p, end);
14268 break;
14269
14270 case Tag_ARC_ABI_rf16:
14271 val = read_uleb128 (p, &len, end);
14272 p += len;
14273 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
14274 break;
14275
14276 case Tag_ARC_ABI_osver:
14277 val = read_uleb128 (p, &len, end);
14278 p += len;
14279 printf (" Tag_ARC_ABI_osver: v%d\n", val);
14280 break;
14281
14282 case Tag_ARC_ABI_pic:
14283 case Tag_ARC_ABI_sda:
14284 val = read_uleb128 (p, &len, end);
14285 p += len;
14286 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
14287 : " Tag_ARC_ABI_pic: ");
14288 switch (val)
14289 {
14290 case 0:
14291 printf (_("Absent\n"));
14292 break;
14293 case 1:
14294 printf ("MWDT\n");
14295 break;
14296 case 2:
14297 printf ("GNU\n");
14298 break;
14299 default:
14300 printf (_("Unknown\n"));
14301 break;
14302 }
14303 break;
14304
14305 case Tag_ARC_ABI_tls:
14306 val = read_uleb128 (p, &len, end);
14307 p += len;
14308 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
14309 break;
14310
14311 case Tag_ARC_ABI_enumsize:
14312 val = read_uleb128 (p, &len, end);
14313 p += len;
14314 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
14315 _("smallest"));
14316 break;
14317
14318 case Tag_ARC_ABI_exceptions:
14319 val = read_uleb128 (p, &len, end);
14320 p += len;
14321 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
14322 : _("default"));
14323 break;
14324
14325 case Tag_ARC_ABI_double_size:
14326 val = read_uleb128 (p, &len, end);
14327 p += len;
14328 printf (" Tag_ARC_ABI_double_size: %d\n", val);
14329 break;
14330
14331 case Tag_ARC_ISA_config:
14332 printf (" Tag_ARC_ISA_config: ");
14333 p = display_tag_value (-1, p, end);
14334 break;
14335
14336 case Tag_ARC_ISA_apex:
14337 printf (" Tag_ARC_ISA_apex: ");
14338 p = display_tag_value (-1, p, end);
14339 break;
14340
14341 case Tag_ARC_ISA_mpy_option:
14342 val = read_uleb128 (p, &len, end);
14343 p += len;
14344 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
14345 break;
14346
db1e1b45 14347 case Tag_ARC_ATR_version:
14348 val = read_uleb128 (p, &len, end);
14349 p += len;
14350 printf (" Tag_ARC_ATR_version: %d\n", val);
14351 break;
14352
53a346d8
CZ
14353 default:
14354 return display_tag_value (tag & 1, p, end);
14355 }
14356
14357 return p;
14358}
14359
11c1ff18
PB
14360/* ARM EABI attributes section. */
14361typedef struct
14362{
70e99720 14363 unsigned int tag;
2cf0635d 14364 const char * name;
11c1ff18 14365 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 14366 unsigned int type;
2cf0635d 14367 const char ** table;
11c1ff18
PB
14368} arm_attr_public_tag;
14369
2cf0635d 14370static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 14371 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 14372 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 14373 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
2cf0635d
NC
14374static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
14375static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 14376 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 14377static const char * arm_attr_tag_FP_arch[] =
bca38921 14378 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 14379 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 14380static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 14381static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
14382 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
14383 "NEON for ARMv8.1"};
2cf0635d 14384static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
14385 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
14386 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 14387static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 14388 {"V6", "SB", "TLS", "Unused"};
2cf0635d 14389static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 14390 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 14391static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 14392 {"Absolute", "PC-relative", "None"};
2cf0635d 14393static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 14394 {"None", "direct", "GOT-indirect"};
2cf0635d 14395static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 14396 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
14397static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
14398static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 14399 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
14400static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
14401static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
14402static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 14403 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 14404static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 14405 {"Unused", "small", "int", "forced to int"};
2cf0635d 14406static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 14407 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 14408static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 14409 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 14410static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 14411 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 14412static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
14413 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
14414 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 14415static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
14416 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
14417 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 14418static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 14419static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 14420 {"Not Allowed", "Allowed"};
2cf0635d 14421static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 14422 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
14423static const char * arm_attr_tag_DSP_extension[] =
14424 {"Follow architecture", "Allowed"};
dd24e3da 14425static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
14426 {"Not Allowed", "Allowed"};
14427static const char * arm_attr_tag_DIV_use[] =
dd24e3da 14428 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 14429 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
14430static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
14431static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 14432 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 14433 "TrustZone and Virtualization Extensions"};
dd24e3da 14434static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 14435 {"Not Allowed", "Allowed"};
11c1ff18 14436
a7ad558c
AV
14437static const char * arm_attr_tag_MVE_arch[] =
14438 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
14439
11c1ff18
PB
14440#define LOOKUP(id, name) \
14441 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 14442static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
14443{
14444 {4, "CPU_raw_name", 1, NULL},
14445 {5, "CPU_name", 1, NULL},
14446 LOOKUP(6, CPU_arch),
14447 {7, "CPU_arch_profile", 0, NULL},
14448 LOOKUP(8, ARM_ISA_use),
14449 LOOKUP(9, THUMB_ISA_use),
75375b3e 14450 LOOKUP(10, FP_arch),
11c1ff18 14451 LOOKUP(11, WMMX_arch),
f5f53991
AS
14452 LOOKUP(12, Advanced_SIMD_arch),
14453 LOOKUP(13, PCS_config),
11c1ff18
PB
14454 LOOKUP(14, ABI_PCS_R9_use),
14455 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 14456 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
14457 LOOKUP(17, ABI_PCS_GOT_use),
14458 LOOKUP(18, ABI_PCS_wchar_t),
14459 LOOKUP(19, ABI_FP_rounding),
14460 LOOKUP(20, ABI_FP_denormal),
14461 LOOKUP(21, ABI_FP_exceptions),
14462 LOOKUP(22, ABI_FP_user_exceptions),
14463 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
14464 {24, "ABI_align_needed", 0, NULL},
14465 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
14466 LOOKUP(26, ABI_enum_size),
14467 LOOKUP(27, ABI_HardFP_use),
14468 LOOKUP(28, ABI_VFP_args),
14469 LOOKUP(29, ABI_WMMX_args),
14470 LOOKUP(30, ABI_optimization_goals),
14471 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 14472 {32, "compatibility", 0, NULL},
f5f53991 14473 LOOKUP(34, CPU_unaligned_access),
75375b3e 14474 LOOKUP(36, FP_HP_extension),
8e79c3df 14475 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
14476 LOOKUP(42, MPextension_use),
14477 LOOKUP(44, DIV_use),
15afaa63 14478 LOOKUP(46, DSP_extension),
a7ad558c 14479 LOOKUP(48, MVE_arch),
f5f53991
AS
14480 {64, "nodefaults", 0, NULL},
14481 {65, "also_compatible_with", 0, NULL},
14482 LOOKUP(66, T2EE_use),
14483 {67, "conformance", 1, NULL},
14484 LOOKUP(68, Virtualization_use),
cd21e546 14485 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
14486};
14487#undef LOOKUP
14488
11c1ff18 14489static unsigned char *
f6f0e17b
NC
14490display_arm_attribute (unsigned char * p,
14491 const unsigned char * const end)
11c1ff18 14492{
70e99720 14493 unsigned int tag;
11c1ff18 14494 unsigned int len;
70e99720 14495 unsigned int val;
2cf0635d 14496 arm_attr_public_tag * attr;
11c1ff18 14497 unsigned i;
70e99720 14498 unsigned int type;
11c1ff18 14499
f6f0e17b 14500 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
14501 p += len;
14502 attr = NULL;
2cf0635d 14503 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
14504 {
14505 if (arm_attr_public_tags[i].tag == tag)
14506 {
14507 attr = &arm_attr_public_tags[i];
14508 break;
14509 }
14510 }
14511
14512 if (attr)
14513 {
14514 printf (" Tag_%s: ", attr->name);
14515 switch (attr->type)
14516 {
14517 case 0:
14518 switch (tag)
14519 {
14520 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 14521 val = read_uleb128 (p, &len, end);
11c1ff18
PB
14522 p += len;
14523 switch (val)
14524 {
2b692964
NC
14525 case 0: printf (_("None\n")); break;
14526 case 'A': printf (_("Application\n")); break;
14527 case 'R': printf (_("Realtime\n")); break;
14528 case 'M': printf (_("Microcontroller\n")); break;
14529 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
14530 default: printf ("??? (%d)\n", val); break;
14531 }
14532 break;
14533
75375b3e 14534 case 24: /* Tag_align_needed. */
f6f0e17b 14535 val = read_uleb128 (p, &len, end);
75375b3e
MGD
14536 p += len;
14537 switch (val)
14538 {
2b692964
NC
14539 case 0: printf (_("None\n")); break;
14540 case 1: printf (_("8-byte\n")); break;
14541 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
14542 case 3: printf ("??? 3\n"); break;
14543 default:
14544 if (val <= 12)
dd24e3da 14545 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
14546 1 << val);
14547 else
14548 printf ("??? (%d)\n", val);
14549 break;
14550 }
14551 break;
14552
14553 case 25: /* Tag_align_preserved. */
f6f0e17b 14554 val = read_uleb128 (p, &len, end);
75375b3e
MGD
14555 p += len;
14556 switch (val)
14557 {
2b692964
NC
14558 case 0: printf (_("None\n")); break;
14559 case 1: printf (_("8-byte, except leaf SP\n")); break;
14560 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
14561 case 3: printf ("??? 3\n"); break;
14562 default:
14563 if (val <= 12)
dd24e3da 14564 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
14565 1 << val);
14566 else
14567 printf ("??? (%d)\n", val);
14568 break;
14569 }
14570 break;
14571
11c1ff18 14572 case 32: /* Tag_compatibility. */
071436c6 14573 {
071436c6
NC
14574 val = read_uleb128 (p, &len, end);
14575 p += len;
071436c6 14576 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
14577 if (p < end - 1)
14578 {
14579 size_t maxlen = (end - p) - 1;
14580
14581 print_symbol ((int) maxlen, (const char *) p);
14582 p += strnlen ((char *) p, maxlen) + 1;
14583 }
14584 else
14585 {
14586 printf (_("<corrupt>"));
14587 p = (unsigned char *) end;
14588 }
071436c6 14589 putchar ('\n');
071436c6 14590 }
11c1ff18
PB
14591 break;
14592
f5f53991 14593 case 64: /* Tag_nodefaults. */
541a3cbd
NC
14594 /* PR 17531: file: 001-505008-0.01. */
14595 if (p < end)
14596 p++;
2b692964 14597 printf (_("True\n"));
f5f53991
AS
14598 break;
14599
14600 case 65: /* Tag_also_compatible_with. */
f6f0e17b 14601 val = read_uleb128 (p, &len, end);
f5f53991
AS
14602 p += len;
14603 if (val == 6 /* Tag_CPU_arch. */)
14604 {
f6f0e17b 14605 val = read_uleb128 (p, &len, end);
f5f53991 14606 p += len;
071436c6 14607 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
14608 printf ("??? (%d)\n", val);
14609 else
14610 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
14611 }
14612 else
14613 printf ("???\n");
071436c6
NC
14614 while (p < end && *(p++) != '\0' /* NUL terminator. */)
14615 ;
f5f53991
AS
14616 break;
14617
11c1ff18 14618 default:
bee0ee85
NC
14619 printf (_("<unknown: %d>\n"), tag);
14620 break;
11c1ff18
PB
14621 }
14622 return p;
14623
14624 case 1:
f6f0e17b 14625 return display_tag_value (-1, p, end);
11c1ff18 14626 case 2:
f6f0e17b 14627 return display_tag_value (0, p, end);
11c1ff18
PB
14628
14629 default:
14630 assert (attr->type & 0x80);
f6f0e17b 14631 val = read_uleb128 (p, &len, end);
11c1ff18
PB
14632 p += len;
14633 type = attr->type & 0x7f;
14634 if (val >= type)
14635 printf ("??? (%d)\n", val);
14636 else
14637 printf ("%s\n", attr->table[val]);
14638 return p;
14639 }
14640 }
11c1ff18 14641
f6f0e17b 14642 return display_tag_value (tag, p, end);
11c1ff18
PB
14643}
14644
104d59d1 14645static unsigned char *
60bca95a 14646display_gnu_attribute (unsigned char * p,
60abdbed 14647 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 14648 const unsigned char * const end)
104d59d1
JM
14649{
14650 int tag;
14651 unsigned int len;
60abdbed 14652 unsigned int val;
104d59d1 14653
f6f0e17b 14654 tag = read_uleb128 (p, &len, end);
104d59d1
JM
14655 p += len;
14656
14657 /* Tag_compatibility is the only generic GNU attribute defined at
14658 present. */
14659 if (tag == 32)
14660 {
f6f0e17b 14661 val = read_uleb128 (p, &len, end);
104d59d1 14662 p += len;
071436c6
NC
14663
14664 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
14665 if (p == end)
14666 {
071436c6 14667 printf (_("<corrupt>\n"));
f6f0e17b
NC
14668 warn (_("corrupt vendor attribute\n"));
14669 }
14670 else
14671 {
4082ef84
NC
14672 if (p < end - 1)
14673 {
14674 size_t maxlen = (end - p) - 1;
071436c6 14675
4082ef84
NC
14676 print_symbol ((int) maxlen, (const char *) p);
14677 p += strnlen ((char *) p, maxlen) + 1;
14678 }
14679 else
14680 {
14681 printf (_("<corrupt>"));
14682 p = (unsigned char *) end;
14683 }
071436c6 14684 putchar ('\n');
f6f0e17b 14685 }
104d59d1
JM
14686 return p;
14687 }
14688
14689 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 14690 return display_proc_gnu_attribute (p, tag, end);
104d59d1 14691
f6f0e17b 14692 return display_tag_value (tag, p, end);
104d59d1
JM
14693}
14694
34c8bcba 14695static unsigned char *
f6f0e17b 14696display_power_gnu_attribute (unsigned char * p,
60abdbed 14697 unsigned int tag,
f6f0e17b 14698 const unsigned char * const end)
34c8bcba 14699{
34c8bcba 14700 unsigned int len;
005d79fd 14701 unsigned int val;
34c8bcba
JM
14702
14703 if (tag == Tag_GNU_Power_ABI_FP)
14704 {
f6f0e17b 14705 val = read_uleb128 (p, &len, end);
34c8bcba
JM
14706 p += len;
14707 printf (" Tag_GNU_Power_ABI_FP: ");
005d79fd
AM
14708 if (len == 0)
14709 {
14710 printf (_("<corrupt>\n"));
14711 return p;
14712 }
60bca95a 14713
005d79fd
AM
14714 if (val > 15)
14715 printf ("(%#x), ", val);
14716
14717 switch (val & 3)
34c8bcba
JM
14718 {
14719 case 0:
005d79fd 14720 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
14721 break;
14722 case 1:
005d79fd 14723 printf (_("hard float, "));
34c8bcba
JM
14724 break;
14725 case 2:
005d79fd 14726 printf (_("soft float, "));
34c8bcba 14727 break;
3c7b9897 14728 case 3:
005d79fd 14729 printf (_("single-precision hard float, "));
3c7b9897 14730 break;
005d79fd
AM
14731 }
14732
14733 switch (val & 0xC)
14734 {
14735 case 0:
14736 printf (_("unspecified long double\n"));
14737 break;
14738 case 4:
14739 printf (_("128-bit IBM long double\n"));
14740 break;
14741 case 8:
14742 printf (_("64-bit long double\n"));
14743 break;
14744 case 12:
14745 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
14746 break;
14747 }
14748 return p;
005d79fd 14749 }
34c8bcba 14750
c6e65352
DJ
14751 if (tag == Tag_GNU_Power_ABI_Vector)
14752 {
f6f0e17b 14753 val = read_uleb128 (p, &len, end);
c6e65352
DJ
14754 p += len;
14755 printf (" Tag_GNU_Power_ABI_Vector: ");
005d79fd
AM
14756 if (len == 0)
14757 {
14758 printf (_("<corrupt>\n"));
14759 return p;
14760 }
14761
14762 if (val > 3)
14763 printf ("(%#x), ", val);
14764
14765 switch (val & 3)
c6e65352
DJ
14766 {
14767 case 0:
005d79fd 14768 printf (_("unspecified\n"));
c6e65352
DJ
14769 break;
14770 case 1:
005d79fd 14771 printf (_("generic\n"));
c6e65352
DJ
14772 break;
14773 case 2:
14774 printf ("AltiVec\n");
14775 break;
14776 case 3:
14777 printf ("SPE\n");
14778 break;
c6e65352
DJ
14779 }
14780 return p;
005d79fd 14781 }
c6e65352 14782
f82e0623
NF
14783 if (tag == Tag_GNU_Power_ABI_Struct_Return)
14784 {
005d79fd
AM
14785 val = read_uleb128 (p, &len, end);
14786 p += len;
14787 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
14788 if (len == 0)
f6f0e17b 14789 {
005d79fd 14790 printf (_("<corrupt>\n"));
f6f0e17b
NC
14791 return p;
14792 }
0b4362b0 14793
005d79fd
AM
14794 if (val > 2)
14795 printf ("(%#x), ", val);
14796
14797 switch (val & 3)
14798 {
14799 case 0:
14800 printf (_("unspecified\n"));
14801 break;
14802 case 1:
14803 printf ("r3/r4\n");
14804 break;
14805 case 2:
14806 printf (_("memory\n"));
14807 break;
14808 case 3:
14809 printf ("???\n");
14810 break;
14811 }
f82e0623
NF
14812 return p;
14813 }
14814
f6f0e17b 14815 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
14816}
14817
643f7afb
AK
14818static unsigned char *
14819display_s390_gnu_attribute (unsigned char * p,
60abdbed 14820 unsigned int tag,
643f7afb
AK
14821 const unsigned char * const end)
14822{
14823 unsigned int len;
14824 int val;
14825
14826 if (tag == Tag_GNU_S390_ABI_Vector)
14827 {
14828 val = read_uleb128 (p, &len, end);
14829 p += len;
14830 printf (" Tag_GNU_S390_ABI_Vector: ");
14831
14832 switch (val)
14833 {
14834 case 0:
14835 printf (_("any\n"));
14836 break;
14837 case 1:
14838 printf (_("software\n"));
14839 break;
14840 case 2:
14841 printf (_("hardware\n"));
14842 break;
14843 default:
14844 printf ("??? (%d)\n", val);
14845 break;
14846 }
14847 return p;
14848 }
14849
14850 return display_tag_value (tag & 1, p, end);
14851}
14852
9e8c70f9 14853static void
60abdbed 14854display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
14855{
14856 if (mask)
14857 {
32ec8896 14858 bfd_boolean first = TRUE;
071436c6 14859
9e8c70f9 14860 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 14861 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 14862 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 14863 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 14864 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 14865 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 14866 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 14867 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 14868 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 14869 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 14870 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 14871 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 14872 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 14873 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 14874 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 14875 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 14876 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 14877 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 14878 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 14879 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 14880 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 14881 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 14882 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 14883 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 14884 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 14885 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 14886 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 14887 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 14888 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 14889 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 14890 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 14891 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
14892 }
14893 else
071436c6
NC
14894 fputc ('0', stdout);
14895 fputc ('\n', stdout);
9e8c70f9
DM
14896}
14897
3d68f91c 14898static void
60abdbed 14899display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
14900{
14901 if (mask)
14902 {
32ec8896 14903 bfd_boolean first = TRUE;
071436c6 14904
3d68f91c 14905 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 14906 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 14907 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 14908 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 14909 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 14910 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 14911 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 14912 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 14913 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 14914 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 14915 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 14916 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 14917 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 14918 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 14919 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 14920 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 14921 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 14922 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 14923 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 14924 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 14925 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 14926 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
14927 }
14928 else
071436c6
NC
14929 fputc ('0', stdout);
14930 fputc ('\n', stdout);
3d68f91c
JM
14931}
14932
9e8c70f9 14933static unsigned char *
f6f0e17b 14934display_sparc_gnu_attribute (unsigned char * p,
60abdbed 14935 unsigned int tag,
f6f0e17b 14936 const unsigned char * const end)
9e8c70f9 14937{
3d68f91c
JM
14938 unsigned int len;
14939 int val;
14940
9e8c70f9
DM
14941 if (tag == Tag_GNU_Sparc_HWCAPS)
14942 {
f6f0e17b 14943 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
14944 p += len;
14945 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
14946 display_sparc_hwcaps (val);
14947 return p;
3d68f91c
JM
14948 }
14949 if (tag == Tag_GNU_Sparc_HWCAPS2)
14950 {
14951 val = read_uleb128 (p, &len, end);
14952 p += len;
14953 printf (" Tag_GNU_Sparc_HWCAPS2: ");
14954 display_sparc_hwcaps2 (val);
14955 return p;
14956 }
9e8c70f9 14957
f6f0e17b 14958 return display_tag_value (tag, p, end);
9e8c70f9
DM
14959}
14960
351cdf24 14961static void
32ec8896 14962print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
14963{
14964 switch (val)
14965 {
14966 case Val_GNU_MIPS_ABI_FP_ANY:
14967 printf (_("Hard or soft float\n"));
14968 break;
14969 case Val_GNU_MIPS_ABI_FP_DOUBLE:
14970 printf (_("Hard float (double precision)\n"));
14971 break;
14972 case Val_GNU_MIPS_ABI_FP_SINGLE:
14973 printf (_("Hard float (single precision)\n"));
14974 break;
14975 case Val_GNU_MIPS_ABI_FP_SOFT:
14976 printf (_("Soft float\n"));
14977 break;
14978 case Val_GNU_MIPS_ABI_FP_OLD_64:
14979 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
14980 break;
14981 case Val_GNU_MIPS_ABI_FP_XX:
14982 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
14983 break;
14984 case Val_GNU_MIPS_ABI_FP_64:
14985 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
14986 break;
14987 case Val_GNU_MIPS_ABI_FP_64A:
14988 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
14989 break;
3350cc01
CM
14990 case Val_GNU_MIPS_ABI_FP_NAN2008:
14991 printf (_("NaN 2008 compatibility\n"));
14992 break;
351cdf24
MF
14993 default:
14994 printf ("??? (%d)\n", val);
14995 break;
14996 }
14997}
14998
2cf19d5c 14999static unsigned char *
f6f0e17b 15000display_mips_gnu_attribute (unsigned char * p,
60abdbed 15001 unsigned int tag,
f6f0e17b 15002 const unsigned char * const end)
2cf19d5c 15003{
2cf19d5c
JM
15004 if (tag == Tag_GNU_MIPS_ABI_FP)
15005 {
f6f0e17b 15006 unsigned int len;
32ec8896 15007 unsigned int val;
f6f0e17b
NC
15008
15009 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
15010 p += len;
15011 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 15012
351cdf24
MF
15013 print_mips_fp_abi_value (val);
15014
2cf19d5c
JM
15015 return p;
15016 }
15017
a9f58168
CF
15018 if (tag == Tag_GNU_MIPS_ABI_MSA)
15019 {
15020 unsigned int len;
32ec8896 15021 unsigned int val;
a9f58168
CF
15022
15023 val = read_uleb128 (p, &len, end);
15024 p += len;
15025 printf (" Tag_GNU_MIPS_ABI_MSA: ");
15026
15027 switch (val)
15028 {
15029 case Val_GNU_MIPS_ABI_MSA_ANY:
15030 printf (_("Any MSA or not\n"));
15031 break;
15032 case Val_GNU_MIPS_ABI_MSA_128:
15033 printf (_("128-bit MSA\n"));
15034 break;
15035 default:
15036 printf ("??? (%d)\n", val);
15037 break;
15038 }
15039 return p;
15040 }
15041
f6f0e17b 15042 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
15043}
15044
59e6276b 15045static unsigned char *
f6f0e17b
NC
15046display_tic6x_attribute (unsigned char * p,
15047 const unsigned char * const end)
59e6276b 15048{
60abdbed 15049 unsigned int tag;
59e6276b
JM
15050 unsigned int len;
15051 int val;
15052
f6f0e17b 15053 tag = read_uleb128 (p, &len, end);
59e6276b
JM
15054 p += len;
15055
15056 switch (tag)
15057 {
75fa6dc1 15058 case Tag_ISA:
f6f0e17b 15059 val = read_uleb128 (p, &len, end);
59e6276b 15060 p += len;
75fa6dc1 15061 printf (" Tag_ISA: ");
59e6276b
JM
15062
15063 switch (val)
15064 {
75fa6dc1 15065 case C6XABI_Tag_ISA_none:
59e6276b
JM
15066 printf (_("None\n"));
15067 break;
75fa6dc1 15068 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
15069 printf ("C62x\n");
15070 break;
75fa6dc1 15071 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
15072 printf ("C67x\n");
15073 break;
75fa6dc1 15074 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
15075 printf ("C67x+\n");
15076 break;
75fa6dc1 15077 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
15078 printf ("C64x\n");
15079 break;
75fa6dc1 15080 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
15081 printf ("C64x+\n");
15082 break;
75fa6dc1 15083 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
15084 printf ("C674x\n");
15085 break;
15086 default:
15087 printf ("??? (%d)\n", val);
15088 break;
15089 }
15090 return p;
15091
87779176 15092 case Tag_ABI_wchar_t:
f6f0e17b 15093 val = read_uleb128 (p, &len, end);
87779176
JM
15094 p += len;
15095 printf (" Tag_ABI_wchar_t: ");
15096 switch (val)
15097 {
15098 case 0:
15099 printf (_("Not used\n"));
15100 break;
15101 case 1:
15102 printf (_("2 bytes\n"));
15103 break;
15104 case 2:
15105 printf (_("4 bytes\n"));
15106 break;
15107 default:
15108 printf ("??? (%d)\n", val);
15109 break;
15110 }
15111 return p;
15112
15113 case Tag_ABI_stack_align_needed:
f6f0e17b 15114 val = read_uleb128 (p, &len, end);
87779176
JM
15115 p += len;
15116 printf (" Tag_ABI_stack_align_needed: ");
15117 switch (val)
15118 {
15119 case 0:
15120 printf (_("8-byte\n"));
15121 break;
15122 case 1:
15123 printf (_("16-byte\n"));
15124 break;
15125 default:
15126 printf ("??? (%d)\n", val);
15127 break;
15128 }
15129 return p;
15130
15131 case Tag_ABI_stack_align_preserved:
f6f0e17b 15132 val = read_uleb128 (p, &len, end);
87779176
JM
15133 p += len;
15134 printf (" Tag_ABI_stack_align_preserved: ");
15135 switch (val)
15136 {
15137 case 0:
15138 printf (_("8-byte\n"));
15139 break;
15140 case 1:
15141 printf (_("16-byte\n"));
15142 break;
15143 default:
15144 printf ("??? (%d)\n", val);
15145 break;
15146 }
15147 return p;
15148
b5593623 15149 case Tag_ABI_DSBT:
f6f0e17b 15150 val = read_uleb128 (p, &len, end);
b5593623
JM
15151 p += len;
15152 printf (" Tag_ABI_DSBT: ");
15153 switch (val)
15154 {
15155 case 0:
15156 printf (_("DSBT addressing not used\n"));
15157 break;
15158 case 1:
15159 printf (_("DSBT addressing used\n"));
15160 break;
15161 default:
15162 printf ("??? (%d)\n", val);
15163 break;
15164 }
15165 return p;
15166
87779176 15167 case Tag_ABI_PID:
f6f0e17b 15168 val = read_uleb128 (p, &len, end);
87779176
JM
15169 p += len;
15170 printf (" Tag_ABI_PID: ");
15171 switch (val)
15172 {
15173 case 0:
15174 printf (_("Data addressing position-dependent\n"));
15175 break;
15176 case 1:
15177 printf (_("Data addressing position-independent, GOT near DP\n"));
15178 break;
15179 case 2:
15180 printf (_("Data addressing position-independent, GOT far from DP\n"));
15181 break;
15182 default:
15183 printf ("??? (%d)\n", val);
15184 break;
15185 }
15186 return p;
15187
15188 case Tag_ABI_PIC:
f6f0e17b 15189 val = read_uleb128 (p, &len, end);
87779176
JM
15190 p += len;
15191 printf (" Tag_ABI_PIC: ");
15192 switch (val)
15193 {
15194 case 0:
15195 printf (_("Code addressing position-dependent\n"));
15196 break;
15197 case 1:
15198 printf (_("Code addressing position-independent\n"));
15199 break;
15200 default:
15201 printf ("??? (%d)\n", val);
15202 break;
15203 }
15204 return p;
15205
15206 case Tag_ABI_array_object_alignment:
f6f0e17b 15207 val = read_uleb128 (p, &len, end);
87779176
JM
15208 p += len;
15209 printf (" Tag_ABI_array_object_alignment: ");
15210 switch (val)
15211 {
15212 case 0:
15213 printf (_("8-byte\n"));
15214 break;
15215 case 1:
15216 printf (_("4-byte\n"));
15217 break;
15218 case 2:
15219 printf (_("16-byte\n"));
15220 break;
15221 default:
15222 printf ("??? (%d)\n", val);
15223 break;
15224 }
15225 return p;
15226
15227 case Tag_ABI_array_object_align_expected:
f6f0e17b 15228 val = read_uleb128 (p, &len, end);
87779176
JM
15229 p += len;
15230 printf (" Tag_ABI_array_object_align_expected: ");
15231 switch (val)
15232 {
15233 case 0:
15234 printf (_("8-byte\n"));
15235 break;
15236 case 1:
15237 printf (_("4-byte\n"));
15238 break;
15239 case 2:
15240 printf (_("16-byte\n"));
15241 break;
15242 default:
15243 printf ("??? (%d)\n", val);
15244 break;
15245 }
15246 return p;
15247
3cbd1c06 15248 case Tag_ABI_compatibility:
071436c6 15249 {
071436c6
NC
15250 val = read_uleb128 (p, &len, end);
15251 p += len;
15252 printf (" Tag_ABI_compatibility: ");
071436c6 15253 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15254 if (p < end - 1)
15255 {
15256 size_t maxlen = (end - p) - 1;
15257
15258 print_symbol ((int) maxlen, (const char *) p);
15259 p += strnlen ((char *) p, maxlen) + 1;
15260 }
15261 else
15262 {
15263 printf (_("<corrupt>"));
15264 p = (unsigned char *) end;
15265 }
071436c6 15266 putchar ('\n');
071436c6
NC
15267 return p;
15268 }
87779176
JM
15269
15270 case Tag_ABI_conformance:
071436c6 15271 {
4082ef84
NC
15272 printf (" Tag_ABI_conformance: \"");
15273 if (p < end - 1)
15274 {
15275 size_t maxlen = (end - p) - 1;
071436c6 15276
4082ef84
NC
15277 print_symbol ((int) maxlen, (const char *) p);
15278 p += strnlen ((char *) p, maxlen) + 1;
15279 }
15280 else
15281 {
15282 printf (_("<corrupt>"));
15283 p = (unsigned char *) end;
15284 }
071436c6 15285 printf ("\"\n");
071436c6
NC
15286 return p;
15287 }
59e6276b
JM
15288 }
15289
f6f0e17b
NC
15290 return display_tag_value (tag, p, end);
15291}
59e6276b 15292
f6f0e17b 15293static void
60abdbed 15294display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
15295{
15296 unsigned long addr = 0;
15297 size_t bytes = end - p;
15298
feceaa59 15299 assert (end >= p);
f6f0e17b 15300 while (bytes)
87779176 15301 {
f6f0e17b
NC
15302 int j;
15303 int k;
15304 int lbytes = (bytes > 16 ? 16 : bytes);
15305
15306 printf (" 0x%8.8lx ", addr);
15307
15308 for (j = 0; j < 16; j++)
15309 {
15310 if (j < lbytes)
15311 printf ("%2.2x", p[j]);
15312 else
15313 printf (" ");
15314
15315 if ((j & 3) == 3)
15316 printf (" ");
15317 }
15318
15319 for (j = 0; j < lbytes; j++)
15320 {
15321 k = p[j];
15322 if (k >= ' ' && k < 0x7f)
15323 printf ("%c", k);
15324 else
15325 printf (".");
15326 }
15327
15328 putchar ('\n');
15329
15330 p += lbytes;
15331 bytes -= lbytes;
15332 addr += lbytes;
87779176 15333 }
59e6276b 15334
f6f0e17b 15335 putchar ('\n');
59e6276b
JM
15336}
15337
13761a11
NC
15338static unsigned char *
15339display_msp430x_attribute (unsigned char * p,
15340 const unsigned char * const end)
15341{
15342 unsigned int len;
60abdbed
NC
15343 unsigned int val;
15344 unsigned int tag;
13761a11
NC
15345
15346 tag = read_uleb128 (p, & len, end);
15347 p += len;
0b4362b0 15348
13761a11
NC
15349 switch (tag)
15350 {
15351 case OFBA_MSPABI_Tag_ISA:
15352 val = read_uleb128 (p, &len, end);
15353 p += len;
15354 printf (" Tag_ISA: ");
15355 switch (val)
15356 {
15357 case 0: printf (_("None\n")); break;
15358 case 1: printf (_("MSP430\n")); break;
15359 case 2: printf (_("MSP430X\n")); break;
15360 default: printf ("??? (%d)\n", val); break;
15361 }
15362 break;
15363
15364 case OFBA_MSPABI_Tag_Code_Model:
15365 val = read_uleb128 (p, &len, end);
15366 p += len;
15367 printf (" Tag_Code_Model: ");
15368 switch (val)
15369 {
15370 case 0: printf (_("None\n")); break;
15371 case 1: printf (_("Small\n")); break;
15372 case 2: printf (_("Large\n")); break;
15373 default: printf ("??? (%d)\n", val); break;
15374 }
15375 break;
15376
15377 case OFBA_MSPABI_Tag_Data_Model:
15378 val = read_uleb128 (p, &len, end);
15379 p += len;
15380 printf (" Tag_Data_Model: ");
15381 switch (val)
15382 {
15383 case 0: printf (_("None\n")); break;
15384 case 1: printf (_("Small\n")); break;
15385 case 2: printf (_("Large\n")); break;
15386 case 3: printf (_("Restricted Large\n")); break;
15387 default: printf ("??? (%d)\n", val); break;
15388 }
15389 break;
15390
15391 default:
15392 printf (_(" <unknown tag %d>: "), tag);
15393
15394 if (tag & 1)
15395 {
071436c6 15396 putchar ('"');
4082ef84
NC
15397 if (p < end - 1)
15398 {
15399 size_t maxlen = (end - p) - 1;
15400
15401 print_symbol ((int) maxlen, (const char *) p);
15402 p += strnlen ((char *) p, maxlen) + 1;
15403 }
15404 else
15405 {
15406 printf (_("<corrupt>"));
15407 p = (unsigned char *) end;
15408 }
071436c6 15409 printf ("\"\n");
13761a11
NC
15410 }
15411 else
15412 {
15413 val = read_uleb128 (p, &len, end);
15414 p += len;
15415 printf ("%d (0x%x)\n", val, val);
15416 }
15417 break;
15418 }
15419
4082ef84 15420 assert (p <= end);
13761a11
NC
15421 return p;
15422}
15423
2dc8dd17
JW
15424struct riscv_attr_tag_t {
15425 const char *name;
15426 int tag;
15427};
15428
15429static struct riscv_attr_tag_t riscv_attr_tag[] =
15430{
15431#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
15432 T(arch),
15433 T(priv_spec),
15434 T(priv_spec_minor),
15435 T(priv_spec_revision),
15436 T(unaligned_access),
15437 T(stack_align),
15438#undef T
15439};
15440
15441static unsigned char *
15442display_riscv_attribute (unsigned char *p,
15443 const unsigned char * const end)
15444{
15445 unsigned int len;
15446 int val;
15447 int tag;
15448 struct riscv_attr_tag_t *attr = NULL;
15449 unsigned i;
15450
15451 tag = read_uleb128 (p, &len, end);
15452 p += len;
15453
15454 /* Find the name of attribute. */
15455 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
15456 {
15457 if (riscv_attr_tag[i].tag == tag)
15458 {
15459 attr = &riscv_attr_tag[i];
15460 break;
15461 }
15462 }
15463
15464 if (attr)
15465 printf (" %s: ", attr->name);
15466 else
15467 return display_tag_value (tag, p, end);
15468
15469 switch (tag)
15470 {
15471 case Tag_RISCV_priv_spec:
15472 case Tag_RISCV_priv_spec_minor:
15473 case Tag_RISCV_priv_spec_revision:
15474 val = read_uleb128 (p, &len, end);
15475 p += len;
15476 printf (_("%d\n"), val);
15477 break;
15478 case Tag_RISCV_unaligned_access:
15479 val = read_uleb128 (p, &len, end);
15480 p += len;
15481 switch (val)
15482 {
15483 case 0:
15484 printf (_("No unaligned access\n"));
15485 break;
15486 case 1:
15487 printf (_("Unaligned access\n"));
15488 break;
15489 }
15490 break;
15491 case Tag_RISCV_stack_align:
15492 val = read_uleb128 (p, &len, end);
15493 p += len;
15494 printf (_("%d-bytes\n"), val);
15495 break;
15496 case Tag_RISCV_arch:
15497 p = display_tag_value (-1, p, end);
15498 break;
15499 default:
15500 return display_tag_value (tag, p, end);
15501 }
15502
15503 return p;
15504}
15505
32ec8896 15506static bfd_boolean
dda8d76d 15507process_attributes (Filedata * filedata,
60bca95a 15508 const char * public_name,
104d59d1 15509 unsigned int proc_type,
f6f0e17b 15510 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 15511 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 15512{
2cf0635d 15513 Elf_Internal_Shdr * sect;
11c1ff18 15514 unsigned i;
32ec8896 15515 bfd_boolean res = TRUE;
11c1ff18
PB
15516
15517 /* Find the section header so that we get the size. */
dda8d76d
NC
15518 for (i = 0, sect = filedata->section_headers;
15519 i < filedata->file_header.e_shnum;
11c1ff18
PB
15520 i++, sect++)
15521 {
071436c6
NC
15522 unsigned char * contents;
15523 unsigned char * p;
15524
104d59d1 15525 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
15526 continue;
15527
dda8d76d 15528 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 15529 sect->sh_size, _("attributes"));
60bca95a 15530 if (contents == NULL)
32ec8896
NC
15531 {
15532 res = FALSE;
15533 continue;
15534 }
60bca95a 15535
11c1ff18 15536 p = contents;
60abdbed
NC
15537 /* The first character is the version of the attributes.
15538 Currently only version 1, (aka 'A') is recognised here. */
15539 if (*p != 'A')
32ec8896
NC
15540 {
15541 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
15542 res = FALSE;
15543 }
60abdbed 15544 else
11c1ff18 15545 {
071436c6
NC
15546 bfd_vma section_len;
15547
15548 section_len = sect->sh_size - 1;
11c1ff18 15549 p++;
60bca95a 15550
071436c6 15551 while (section_len > 0)
11c1ff18 15552 {
071436c6 15553 bfd_vma attr_len;
e9847026 15554 unsigned int namelen;
11c1ff18 15555 bfd_boolean public_section;
104d59d1 15556 bfd_boolean gnu_section;
11c1ff18 15557
071436c6 15558 if (section_len <= 4)
e0a31db1
NC
15559 {
15560 error (_("Tag section ends prematurely\n"));
32ec8896 15561 res = FALSE;
e0a31db1
NC
15562 break;
15563 }
071436c6 15564 attr_len = byte_get (p, 4);
11c1ff18 15565 p += 4;
60bca95a 15566
071436c6 15567 if (attr_len > section_len)
11c1ff18 15568 {
071436c6
NC
15569 error (_("Bad attribute length (%u > %u)\n"),
15570 (unsigned) attr_len, (unsigned) section_len);
15571 attr_len = section_len;
32ec8896 15572 res = FALSE;
11c1ff18 15573 }
74e1a04b 15574 /* PR 17531: file: 001-101425-0.004 */
071436c6 15575 else if (attr_len < 5)
74e1a04b 15576 {
071436c6 15577 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 15578 res = FALSE;
74e1a04b
NC
15579 break;
15580 }
e9847026 15581
071436c6
NC
15582 section_len -= attr_len;
15583 attr_len -= 4;
15584
15585 namelen = strnlen ((char *) p, attr_len) + 1;
15586 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
15587 {
15588 error (_("Corrupt attribute section name\n"));
32ec8896 15589 res = FALSE;
e9847026
NC
15590 break;
15591 }
15592
071436c6
NC
15593 printf (_("Attribute Section: "));
15594 print_symbol (INT_MAX, (const char *) p);
15595 putchar ('\n');
60bca95a
NC
15596
15597 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
15598 public_section = TRUE;
15599 else
15600 public_section = FALSE;
60bca95a
NC
15601
15602 if (streq ((char *) p, "gnu"))
104d59d1
JM
15603 gnu_section = TRUE;
15604 else
15605 gnu_section = FALSE;
60bca95a 15606
11c1ff18 15607 p += namelen;
071436c6 15608 attr_len -= namelen;
e0a31db1 15609
071436c6 15610 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 15611 {
e0a31db1 15612 int tag;
11c1ff18
PB
15613 int val;
15614 bfd_vma size;
071436c6 15615 unsigned char * end;
60bca95a 15616
e0a31db1 15617 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 15618 if (attr_len < 6)
e0a31db1
NC
15619 {
15620 error (_("Unused bytes at end of section\n"));
32ec8896 15621 res = FALSE;
e0a31db1
NC
15622 section_len = 0;
15623 break;
15624 }
15625
15626 tag = *(p++);
11c1ff18 15627 size = byte_get (p, 4);
071436c6 15628 if (size > attr_len)
11c1ff18 15629 {
e9847026 15630 error (_("Bad subsection length (%u > %u)\n"),
071436c6 15631 (unsigned) size, (unsigned) attr_len);
32ec8896 15632 res = FALSE;
071436c6 15633 size = attr_len;
11c1ff18 15634 }
e0a31db1
NC
15635 /* PR binutils/17531: Safe handling of corrupt files. */
15636 if (size < 6)
15637 {
15638 error (_("Bad subsection length (%u < 6)\n"),
15639 (unsigned) size);
32ec8896 15640 res = FALSE;
e0a31db1
NC
15641 section_len = 0;
15642 break;
15643 }
60bca95a 15644
071436c6 15645 attr_len -= size;
11c1ff18 15646 end = p + size - 1;
071436c6 15647 assert (end <= contents + sect->sh_size);
11c1ff18 15648 p += 4;
60bca95a 15649
11c1ff18
PB
15650 switch (tag)
15651 {
15652 case 1:
2b692964 15653 printf (_("File Attributes\n"));
11c1ff18
PB
15654 break;
15655 case 2:
2b692964 15656 printf (_("Section Attributes:"));
11c1ff18
PB
15657 goto do_numlist;
15658 case 3:
2b692964 15659 printf (_("Symbol Attributes:"));
1a0670f3 15660 /* Fall through. */
11c1ff18
PB
15661 do_numlist:
15662 for (;;)
15663 {
91d6fa6a 15664 unsigned int j;
60bca95a 15665
f6f0e17b 15666 val = read_uleb128 (p, &j, end);
91d6fa6a 15667 p += j;
11c1ff18
PB
15668 if (val == 0)
15669 break;
15670 printf (" %d", val);
15671 }
15672 printf ("\n");
15673 break;
15674 default:
2b692964 15675 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
15676 public_section = FALSE;
15677 break;
15678 }
60bca95a 15679
071436c6 15680 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
15681 {
15682 while (p < end)
f6f0e17b 15683 p = display_pub_attribute (p, end);
60abdbed 15684 assert (p == end);
104d59d1 15685 }
071436c6 15686 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
15687 {
15688 while (p < end)
15689 p = display_gnu_attribute (p,
f6f0e17b
NC
15690 display_proc_gnu_attribute,
15691 end);
60abdbed 15692 assert (p == end);
11c1ff18 15693 }
071436c6 15694 else if (p < end)
11c1ff18 15695 {
071436c6 15696 printf (_(" Unknown attribute:\n"));
f6f0e17b 15697 display_raw_attribute (p, end);
11c1ff18
PB
15698 p = end;
15699 }
071436c6
NC
15700 else
15701 attr_len = 0;
11c1ff18
PB
15702 }
15703 }
15704 }
d70c5fc7 15705
60bca95a 15706 free (contents);
11c1ff18 15707 }
32ec8896
NC
15708
15709 return res;
11c1ff18
PB
15710}
15711
ccb4c951
RS
15712/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
15713 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
15714 and return the VMA of the next entry, or -1 if there was a problem.
15715 Does not read from DATA_END or beyond. */
ccb4c951
RS
15716
15717static bfd_vma
82b1b41b
NC
15718print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
15719 unsigned char * data_end)
ccb4c951
RS
15720{
15721 printf (" ");
15722 print_vma (addr, LONG_HEX);
15723 printf (" ");
15724 if (addr < pltgot + 0xfff0)
15725 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
15726 else
15727 printf ("%10s", "");
15728 printf (" ");
15729 if (data == NULL)
2b692964 15730 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
15731 else
15732 {
15733 bfd_vma entry;
82b1b41b 15734 unsigned char * from = data + addr - pltgot;
ccb4c951 15735
82b1b41b
NC
15736 if (from + (is_32bit_elf ? 4 : 8) > data_end)
15737 {
15738 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
15739 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
15740 return (bfd_vma) -1;
15741 }
15742 else
15743 {
15744 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
15745 print_vma (entry, LONG_HEX);
15746 }
ccb4c951
RS
15747 }
15748 return addr + (is_32bit_elf ? 4 : 8);
15749}
15750
861fb55a
DJ
15751/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
15752 PLTGOT. Print the Address and Initial fields of an entry at VMA
15753 ADDR and return the VMA of the next entry. */
15754
15755static bfd_vma
2cf0635d 15756print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
15757{
15758 printf (" ");
15759 print_vma (addr, LONG_HEX);
15760 printf (" ");
15761 if (data == NULL)
2b692964 15762 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
15763 else
15764 {
15765 bfd_vma entry;
15766
15767 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
15768 print_vma (entry, LONG_HEX);
15769 }
15770 return addr + (is_32bit_elf ? 4 : 8);
15771}
15772
351cdf24
MF
15773static void
15774print_mips_ases (unsigned int mask)
15775{
15776 if (mask & AFL_ASE_DSP)
15777 fputs ("\n\tDSP ASE", stdout);
15778 if (mask & AFL_ASE_DSPR2)
15779 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
15780 if (mask & AFL_ASE_DSPR3)
15781 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
15782 if (mask & AFL_ASE_EVA)
15783 fputs ("\n\tEnhanced VA Scheme", stdout);
15784 if (mask & AFL_ASE_MCU)
15785 fputs ("\n\tMCU (MicroController) ASE", stdout);
15786 if (mask & AFL_ASE_MDMX)
15787 fputs ("\n\tMDMX ASE", stdout);
15788 if (mask & AFL_ASE_MIPS3D)
15789 fputs ("\n\tMIPS-3D ASE", stdout);
15790 if (mask & AFL_ASE_MT)
15791 fputs ("\n\tMT ASE", stdout);
15792 if (mask & AFL_ASE_SMARTMIPS)
15793 fputs ("\n\tSmartMIPS ASE", stdout);
15794 if (mask & AFL_ASE_VIRT)
15795 fputs ("\n\tVZ ASE", stdout);
15796 if (mask & AFL_ASE_MSA)
15797 fputs ("\n\tMSA ASE", stdout);
15798 if (mask & AFL_ASE_MIPS16)
15799 fputs ("\n\tMIPS16 ASE", stdout);
15800 if (mask & AFL_ASE_MICROMIPS)
15801 fputs ("\n\tMICROMIPS ASE", stdout);
15802 if (mask & AFL_ASE_XPA)
15803 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
15804 if (mask & AFL_ASE_MIPS16E2)
15805 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
15806 if (mask & AFL_ASE_CRC)
15807 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
15808 if (mask & AFL_ASE_GINV)
15809 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
15810 if (mask & AFL_ASE_LOONGSON_MMI)
15811 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
15812 if (mask & AFL_ASE_LOONGSON_CAM)
15813 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
15814 if (mask & AFL_ASE_LOONGSON_EXT)
15815 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
15816 if (mask & AFL_ASE_LOONGSON_EXT2)
15817 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
15818 if (mask == 0)
15819 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
15820 else if ((mask & ~AFL_ASE_MASK) != 0)
15821 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
15822}
15823
15824static void
15825print_mips_isa_ext (unsigned int isa_ext)
15826{
15827 switch (isa_ext)
15828 {
15829 case 0:
15830 fputs (_("None"), stdout);
15831 break;
15832 case AFL_EXT_XLR:
15833 fputs ("RMI XLR", stdout);
15834 break;
2c629856
N
15835 case AFL_EXT_OCTEON3:
15836 fputs ("Cavium Networks Octeon3", stdout);
15837 break;
351cdf24
MF
15838 case AFL_EXT_OCTEON2:
15839 fputs ("Cavium Networks Octeon2", stdout);
15840 break;
15841 case AFL_EXT_OCTEONP:
15842 fputs ("Cavium Networks OcteonP", stdout);
15843 break;
351cdf24
MF
15844 case AFL_EXT_OCTEON:
15845 fputs ("Cavium Networks Octeon", stdout);
15846 break;
15847 case AFL_EXT_5900:
15848 fputs ("Toshiba R5900", stdout);
15849 break;
15850 case AFL_EXT_4650:
15851 fputs ("MIPS R4650", stdout);
15852 break;
15853 case AFL_EXT_4010:
15854 fputs ("LSI R4010", stdout);
15855 break;
15856 case AFL_EXT_4100:
15857 fputs ("NEC VR4100", stdout);
15858 break;
15859 case AFL_EXT_3900:
15860 fputs ("Toshiba R3900", stdout);
15861 break;
15862 case AFL_EXT_10000:
15863 fputs ("MIPS R10000", stdout);
15864 break;
15865 case AFL_EXT_SB1:
15866 fputs ("Broadcom SB-1", stdout);
15867 break;
15868 case AFL_EXT_4111:
15869 fputs ("NEC VR4111/VR4181", stdout);
15870 break;
15871 case AFL_EXT_4120:
15872 fputs ("NEC VR4120", stdout);
15873 break;
15874 case AFL_EXT_5400:
15875 fputs ("NEC VR5400", stdout);
15876 break;
15877 case AFL_EXT_5500:
15878 fputs ("NEC VR5500", stdout);
15879 break;
15880 case AFL_EXT_LOONGSON_2E:
15881 fputs ("ST Microelectronics Loongson 2E", stdout);
15882 break;
15883 case AFL_EXT_LOONGSON_2F:
15884 fputs ("ST Microelectronics Loongson 2F", stdout);
15885 break;
38bf472a
MR
15886 case AFL_EXT_INTERAPTIV_MR2:
15887 fputs ("Imagination interAptiv MR2", stdout);
15888 break;
351cdf24 15889 default:
00ac7aa0 15890 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
15891 }
15892}
15893
32ec8896 15894static signed int
351cdf24
MF
15895get_mips_reg_size (int reg_size)
15896{
15897 return (reg_size == AFL_REG_NONE) ? 0
15898 : (reg_size == AFL_REG_32) ? 32
15899 : (reg_size == AFL_REG_64) ? 64
15900 : (reg_size == AFL_REG_128) ? 128
15901 : -1;
15902}
15903
32ec8896 15904static bfd_boolean
dda8d76d 15905process_mips_specific (Filedata * filedata)
5b18a4bc 15906{
2cf0635d 15907 Elf_Internal_Dyn * entry;
351cdf24 15908 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
15909 size_t liblist_offset = 0;
15910 size_t liblistno = 0;
15911 size_t conflictsno = 0;
15912 size_t options_offset = 0;
15913 size_t conflicts_offset = 0;
861fb55a
DJ
15914 size_t pltrelsz = 0;
15915 size_t pltrel = 0;
ccb4c951 15916 bfd_vma pltgot = 0;
861fb55a
DJ
15917 bfd_vma mips_pltgot = 0;
15918 bfd_vma jmprel = 0;
ccb4c951
RS
15919 bfd_vma local_gotno = 0;
15920 bfd_vma gotsym = 0;
15921 bfd_vma symtabno = 0;
32ec8896 15922 bfd_boolean res = TRUE;
103f02d3 15923
dda8d76d 15924 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
15925 display_mips_gnu_attribute))
15926 res = FALSE;
2cf19d5c 15927
dda8d76d 15928 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
15929
15930 if (sect != NULL)
15931 {
15932 Elf_External_ABIFlags_v0 *abiflags_ext;
15933 Elf_Internal_ABIFlags_v0 abiflags_in;
15934
15935 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
15936 {
15937 error (_("Corrupt MIPS ABI Flags section.\n"));
15938 res = FALSE;
15939 }
351cdf24
MF
15940 else
15941 {
dda8d76d 15942 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
15943 sect->sh_size, _("MIPS ABI Flags section"));
15944 if (abiflags_ext)
15945 {
15946 abiflags_in.version = BYTE_GET (abiflags_ext->version);
15947 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
15948 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
15949 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
15950 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
15951 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
15952 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
15953 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
15954 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
15955 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
15956 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
15957
15958 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
15959 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
15960 if (abiflags_in.isa_rev > 1)
15961 printf ("r%d", abiflags_in.isa_rev);
15962 printf ("\nGPR size: %d",
15963 get_mips_reg_size (abiflags_in.gpr_size));
15964 printf ("\nCPR1 size: %d",
15965 get_mips_reg_size (abiflags_in.cpr1_size));
15966 printf ("\nCPR2 size: %d",
15967 get_mips_reg_size (abiflags_in.cpr2_size));
15968 fputs ("\nFP ABI: ", stdout);
15969 print_mips_fp_abi_value (abiflags_in.fp_abi);
15970 fputs ("ISA Extension: ", stdout);
15971 print_mips_isa_ext (abiflags_in.isa_ext);
15972 fputs ("\nASEs:", stdout);
15973 print_mips_ases (abiflags_in.ases);
15974 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
15975 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
15976 fputc ('\n', stdout);
15977 free (abiflags_ext);
15978 }
15979 }
15980 }
15981
19e6b90e
L
15982 /* We have a lot of special sections. Thanks SGI! */
15983 if (dynamic_section == NULL)
bbdd9a68
MR
15984 {
15985 /* No dynamic information available. See if there is static GOT. */
dda8d76d 15986 sect = find_section (filedata, ".got");
bbdd9a68
MR
15987 if (sect != NULL)
15988 {
15989 unsigned char *data_end;
15990 unsigned char *data;
15991 bfd_vma ent, end;
15992 int addr_size;
15993
15994 pltgot = sect->sh_addr;
15995
15996 ent = pltgot;
15997 addr_size = (is_32bit_elf ? 4 : 8);
15998 end = pltgot + sect->sh_size;
15999
dda8d76d 16000 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
16001 end - pltgot, 1,
16002 _("Global Offset Table data"));
16003 /* PR 12855: Null data is handled gracefully throughout. */
16004 data_end = data + (end - pltgot);
16005
16006 printf (_("\nStatic GOT:\n"));
16007 printf (_(" Canonical gp value: "));
16008 print_vma (ent + 0x7ff0, LONG_HEX);
16009 printf ("\n\n");
16010
16011 /* In a dynamic binary GOT[0] is reserved for the dynamic
16012 loader to store the lazy resolver pointer, however in
16013 a static binary it may well have been omitted and GOT
16014 reduced to a table of addresses.
16015 PR 21344: Check for the entry being fully available
16016 before fetching it. */
16017 if (data
16018 && data + ent - pltgot + addr_size <= data_end
16019 && byte_get (data + ent - pltgot, addr_size) == 0)
16020 {
16021 printf (_(" Reserved entries:\n"));
16022 printf (_(" %*s %10s %*s\n"),
16023 addr_size * 2, _("Address"), _("Access"),
16024 addr_size * 2, _("Value"));
16025 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16026 printf ("\n");
16027 if (ent == (bfd_vma) -1)
16028 goto sgot_print_fail;
16029
16030 /* Check for the MSB of GOT[1] being set, identifying a
16031 GNU object. This entry will be used by some runtime
16032 loaders, to store the module pointer. Otherwise this
16033 is an ordinary local entry.
16034 PR 21344: Check for the entry being fully available
16035 before fetching it. */
16036 if (data
16037 && data + ent - pltgot + addr_size <= data_end
16038 && (byte_get (data + ent - pltgot, addr_size)
16039 >> (addr_size * 8 - 1)) != 0)
16040 {
16041 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16042 printf ("\n");
16043 if (ent == (bfd_vma) -1)
16044 goto sgot_print_fail;
16045 }
16046 printf ("\n");
16047 }
16048
f17e9d8a 16049 if (data != NULL && ent < end)
bbdd9a68
MR
16050 {
16051 printf (_(" Local entries:\n"));
16052 printf (" %*s %10s %*s\n",
16053 addr_size * 2, _("Address"), _("Access"),
16054 addr_size * 2, _("Value"));
16055 while (ent < end)
16056 {
16057 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16058 printf ("\n");
16059 if (ent == (bfd_vma) -1)
16060 goto sgot_print_fail;
16061 }
16062 printf ("\n");
16063 }
16064
16065 sgot_print_fail:
16066 if (data)
16067 free (data);
16068 }
16069 return res;
16070 }
252b5132 16071
071436c6
NC
16072 for (entry = dynamic_section;
16073 /* PR 17531 file: 012-50589-0.004. */
16074 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
16075 ++entry)
252b5132
RH
16076 switch (entry->d_tag)
16077 {
16078 case DT_MIPS_LIBLIST:
d93f0186 16079 liblist_offset
dda8d76d 16080 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16081 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
16082 break;
16083 case DT_MIPS_LIBLISTNO:
16084 liblistno = entry->d_un.d_val;
16085 break;
16086 case DT_MIPS_OPTIONS:
dda8d76d 16087 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
16088 break;
16089 case DT_MIPS_CONFLICT:
d93f0186 16090 conflicts_offset
dda8d76d 16091 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16092 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
16093 break;
16094 case DT_MIPS_CONFLICTNO:
16095 conflictsno = entry->d_un.d_val;
16096 break;
ccb4c951 16097 case DT_PLTGOT:
861fb55a
DJ
16098 pltgot = entry->d_un.d_ptr;
16099 break;
ccb4c951
RS
16100 case DT_MIPS_LOCAL_GOTNO:
16101 local_gotno = entry->d_un.d_val;
16102 break;
16103 case DT_MIPS_GOTSYM:
16104 gotsym = entry->d_un.d_val;
16105 break;
16106 case DT_MIPS_SYMTABNO:
16107 symtabno = entry->d_un.d_val;
16108 break;
861fb55a
DJ
16109 case DT_MIPS_PLTGOT:
16110 mips_pltgot = entry->d_un.d_ptr;
16111 break;
16112 case DT_PLTREL:
16113 pltrel = entry->d_un.d_val;
16114 break;
16115 case DT_PLTRELSZ:
16116 pltrelsz = entry->d_un.d_val;
16117 break;
16118 case DT_JMPREL:
16119 jmprel = entry->d_un.d_ptr;
16120 break;
252b5132
RH
16121 default:
16122 break;
16123 }
16124
16125 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
16126 {
2cf0635d 16127 Elf32_External_Lib * elib;
252b5132
RH
16128 size_t cnt;
16129
dda8d76d 16130 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
3f5e193b
NC
16131 liblistno,
16132 sizeof (Elf32_External_Lib),
9cf03b7e 16133 _("liblist section data"));
a6e9f9df 16134 if (elib)
252b5132 16135 {
d3a49aa8
AM
16136 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
16137 "\nSection '.liblist' contains %lu entries:\n",
16138 (unsigned long) liblistno),
a6e9f9df 16139 (unsigned long) liblistno);
2b692964 16140 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
16141 stdout);
16142
16143 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 16144 {
a6e9f9df 16145 Elf32_Lib liblist;
91d6fa6a 16146 time_t atime;
d5b07ef4 16147 char timebuf[128];
2cf0635d 16148 struct tm * tmp;
a6e9f9df
AM
16149
16150 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 16151 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
16152 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
16153 liblist.l_version = BYTE_GET (elib[cnt].l_version);
16154 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
16155
91d6fa6a 16156 tmp = gmtime (&atime);
e9e44622
JJ
16157 snprintf (timebuf, sizeof (timebuf),
16158 "%04u-%02u-%02uT%02u:%02u:%02u",
16159 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
16160 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 16161
31104126 16162 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
16163 if (VALID_DYNAMIC_NAME (liblist.l_name))
16164 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
16165 else
2b692964 16166 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
16167 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
16168 liblist.l_version);
a6e9f9df
AM
16169
16170 if (liblist.l_flags == 0)
2b692964 16171 puts (_(" NONE"));
a6e9f9df
AM
16172 else
16173 {
16174 static const struct
252b5132 16175 {
2cf0635d 16176 const char * name;
a6e9f9df 16177 int bit;
252b5132 16178 }
a6e9f9df
AM
16179 l_flags_vals[] =
16180 {
16181 { " EXACT_MATCH", LL_EXACT_MATCH },
16182 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
16183 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
16184 { " EXPORTS", LL_EXPORTS },
16185 { " DELAY_LOAD", LL_DELAY_LOAD },
16186 { " DELTA", LL_DELTA }
16187 };
16188 int flags = liblist.l_flags;
16189 size_t fcnt;
16190
60bca95a 16191 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
16192 if ((flags & l_flags_vals[fcnt].bit) != 0)
16193 {
16194 fputs (l_flags_vals[fcnt].name, stdout);
16195 flags ^= l_flags_vals[fcnt].bit;
16196 }
16197 if (flags != 0)
16198 printf (" %#x", (unsigned int) flags);
252b5132 16199
a6e9f9df
AM
16200 puts ("");
16201 }
252b5132 16202 }
252b5132 16203
a6e9f9df
AM
16204 free (elib);
16205 }
32ec8896
NC
16206 else
16207 res = FALSE;
252b5132
RH
16208 }
16209
16210 if (options_offset != 0)
16211 {
2cf0635d 16212 Elf_External_Options * eopt;
2cf0635d
NC
16213 Elf_Internal_Options * iopt;
16214 Elf_Internal_Options * option;
252b5132
RH
16215 size_t offset;
16216 int cnt;
dda8d76d 16217 sect = filedata->section_headers;
252b5132
RH
16218
16219 /* Find the section header so that we get the size. */
dda8d76d 16220 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 16221 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
16222 if (sect == NULL)
16223 {
16224 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 16225 return FALSE;
071436c6 16226 }
7fc0c668
NC
16227 /* PR 24243 */
16228 if (sect->sh_size < sizeof (* eopt))
16229 {
16230 error (_("The MIPS options section is too small.\n"));
16231 return FALSE;
16232 }
252b5132 16233
dda8d76d 16234 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 16235 sect->sh_size, _("options"));
a6e9f9df 16236 if (eopt)
252b5132 16237 {
3f5e193b
NC
16238 iopt = (Elf_Internal_Options *)
16239 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
16240 if (iopt == NULL)
16241 {
fb324ee9 16242 error (_("Out of memory allocating space for MIPS options\n"));
32ec8896 16243 return FALSE;
a6e9f9df 16244 }
76da6bbe 16245
a6e9f9df
AM
16246 offset = cnt = 0;
16247 option = iopt;
252b5132 16248
82b1b41b 16249 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 16250 {
2cf0635d 16251 Elf_External_Options * eoption;
252b5132 16252
a6e9f9df 16253 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 16254
a6e9f9df
AM
16255 option->kind = BYTE_GET (eoption->kind);
16256 option->size = BYTE_GET (eoption->size);
16257 option->section = BYTE_GET (eoption->section);
16258 option->info = BYTE_GET (eoption->info);
76da6bbe 16259
82b1b41b
NC
16260 /* PR 17531: file: ffa0fa3b. */
16261 if (option->size < sizeof (* eopt)
16262 || offset + option->size > sect->sh_size)
16263 {
55325047 16264 error (_("Invalid size (%u) for MIPS option\n"), option->size);
32ec8896 16265 return FALSE;
82b1b41b 16266 }
a6e9f9df 16267 offset += option->size;
14ae95f2 16268
a6e9f9df
AM
16269 ++option;
16270 ++cnt;
16271 }
252b5132 16272
d3a49aa8
AM
16273 printf (ngettext ("\nSection '%s' contains %d entry:\n",
16274 "\nSection '%s' contains %d entries:\n",
16275 cnt),
dda8d76d 16276 printable_section_name (filedata, sect), cnt);
76da6bbe 16277
a6e9f9df 16278 option = iopt;
82b1b41b 16279 offset = 0;
252b5132 16280
a6e9f9df 16281 while (cnt-- > 0)
252b5132 16282 {
a6e9f9df
AM
16283 size_t len;
16284
16285 switch (option->kind)
252b5132 16286 {
a6e9f9df
AM
16287 case ODK_NULL:
16288 /* This shouldn't happen. */
16289 printf (" NULL %d %lx", option->section, option->info);
16290 break;
16291 case ODK_REGINFO:
16292 printf (" REGINFO ");
dda8d76d 16293 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df
AM
16294 {
16295 /* 32bit form. */
2cf0635d 16296 Elf32_External_RegInfo * ereg;
b34976b6 16297 Elf32_RegInfo reginfo;
a6e9f9df
AM
16298
16299 ereg = (Elf32_External_RegInfo *) (option + 1);
16300 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
16301 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
16302 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
16303 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
16304 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
16305 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
16306
16307 printf ("GPR %08lx GP 0x%lx\n",
16308 reginfo.ri_gprmask,
16309 (unsigned long) reginfo.ri_gp_value);
16310 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
16311 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
16312 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
16313 }
16314 else
16315 {
16316 /* 64 bit form. */
2cf0635d 16317 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
16318 Elf64_Internal_RegInfo reginfo;
16319
16320 ereg = (Elf64_External_RegInfo *) (option + 1);
16321 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
16322 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
16323 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
16324 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
16325 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 16326 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
16327
16328 printf ("GPR %08lx GP 0x",
16329 reginfo.ri_gprmask);
16330 printf_vma (reginfo.ri_gp_value);
16331 printf ("\n");
16332
16333 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
16334 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
16335 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
16336 }
16337 ++option;
16338 continue;
16339 case ODK_EXCEPTIONS:
16340 fputs (" EXCEPTIONS fpe_min(", stdout);
16341 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
16342 fputs (") fpe_max(", stdout);
16343 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
16344 fputs (")", stdout);
16345
16346 if (option->info & OEX_PAGE0)
16347 fputs (" PAGE0", stdout);
16348 if (option->info & OEX_SMM)
16349 fputs (" SMM", stdout);
16350 if (option->info & OEX_FPDBUG)
16351 fputs (" FPDBUG", stdout);
16352 if (option->info & OEX_DISMISS)
16353 fputs (" DISMISS", stdout);
16354 break;
16355 case ODK_PAD:
16356 fputs (" PAD ", stdout);
16357 if (option->info & OPAD_PREFIX)
16358 fputs (" PREFIX", stdout);
16359 if (option->info & OPAD_POSTFIX)
16360 fputs (" POSTFIX", stdout);
16361 if (option->info & OPAD_SYMBOL)
16362 fputs (" SYMBOL", stdout);
16363 break;
16364 case ODK_HWPATCH:
16365 fputs (" HWPATCH ", stdout);
16366 if (option->info & OHW_R4KEOP)
16367 fputs (" R4KEOP", stdout);
16368 if (option->info & OHW_R8KPFETCH)
16369 fputs (" R8KPFETCH", stdout);
16370 if (option->info & OHW_R5KEOP)
16371 fputs (" R5KEOP", stdout);
16372 if (option->info & OHW_R5KCVTL)
16373 fputs (" R5KCVTL", stdout);
16374 break;
16375 case ODK_FILL:
16376 fputs (" FILL ", stdout);
16377 /* XXX Print content of info word? */
16378 break;
16379 case ODK_TAGS:
16380 fputs (" TAGS ", stdout);
16381 /* XXX Print content of info word? */
16382 break;
16383 case ODK_HWAND:
16384 fputs (" HWAND ", stdout);
16385 if (option->info & OHWA0_R4KEOP_CHECKED)
16386 fputs (" R4KEOP_CHECKED", stdout);
16387 if (option->info & OHWA0_R4KEOP_CLEAN)
16388 fputs (" R4KEOP_CLEAN", stdout);
16389 break;
16390 case ODK_HWOR:
16391 fputs (" HWOR ", stdout);
16392 if (option->info & OHWA0_R4KEOP_CHECKED)
16393 fputs (" R4KEOP_CHECKED", stdout);
16394 if (option->info & OHWA0_R4KEOP_CLEAN)
16395 fputs (" R4KEOP_CLEAN", stdout);
16396 break;
16397 case ODK_GP_GROUP:
16398 printf (" GP_GROUP %#06lx self-contained %#06lx",
16399 option->info & OGP_GROUP,
16400 (option->info & OGP_SELF) >> 16);
16401 break;
16402 case ODK_IDENT:
16403 printf (" IDENT %#06lx self-contained %#06lx",
16404 option->info & OGP_GROUP,
16405 (option->info & OGP_SELF) >> 16);
16406 break;
16407 default:
16408 /* This shouldn't happen. */
16409 printf (" %3d ??? %d %lx",
16410 option->kind, option->section, option->info);
16411 break;
252b5132 16412 }
a6e9f9df 16413
2cf0635d 16414 len = sizeof (* eopt);
a6e9f9df 16415 while (len < option->size)
82b1b41b 16416 {
7e27a9d5 16417 unsigned char datum = * ((unsigned char *) eopt + offset + len);
a6e9f9df 16418
82b1b41b
NC
16419 if (ISPRINT (datum))
16420 printf ("%c", datum);
16421 else
16422 printf ("\\%03o", datum);
16423 len ++;
16424 }
a6e9f9df 16425 fputs ("\n", stdout);
82b1b41b
NC
16426
16427 offset += option->size;
252b5132 16428 ++option;
252b5132
RH
16429 }
16430
a6e9f9df 16431 free (eopt);
252b5132 16432 }
32ec8896
NC
16433 else
16434 res = FALSE;
252b5132
RH
16435 }
16436
16437 if (conflicts_offset != 0 && conflictsno != 0)
16438 {
2cf0635d 16439 Elf32_Conflict * iconf;
252b5132
RH
16440 size_t cnt;
16441
16442 if (dynamic_symbols == NULL)
16443 {
591a748a 16444 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 16445 return FALSE;
252b5132
RH
16446 }
16447
7296a62a
NC
16448 /* PR 21345 - print a slightly more helpful error message
16449 if we are sure that the cmalloc will fail. */
dda8d76d 16450 if (conflictsno * sizeof (* iconf) > filedata->file_size)
7296a62a
NC
16451 {
16452 error (_("Overlarge number of conflicts detected: %lx\n"),
16453 (long) conflictsno);
16454 return FALSE;
16455 }
16456
3f5e193b 16457 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
16458 if (iconf == NULL)
16459 {
8b73c356 16460 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 16461 return FALSE;
252b5132
RH
16462 }
16463
9ea033b2 16464 if (is_32bit_elf)
252b5132 16465 {
2cf0635d 16466 Elf32_External_Conflict * econf32;
a6e9f9df 16467
3f5e193b 16468 econf32 = (Elf32_External_Conflict *)
dda8d76d 16469 get_data (NULL, filedata, conflicts_offset, conflictsno,
3f5e193b 16470 sizeof (* econf32), _("conflict"));
a6e9f9df 16471 if (!econf32)
32ec8896 16472 return FALSE;
252b5132
RH
16473
16474 for (cnt = 0; cnt < conflictsno; ++cnt)
16475 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
16476
16477 free (econf32);
252b5132
RH
16478 }
16479 else
16480 {
2cf0635d 16481 Elf64_External_Conflict * econf64;
a6e9f9df 16482
3f5e193b 16483 econf64 = (Elf64_External_Conflict *)
dda8d76d 16484 get_data (NULL, filedata, conflicts_offset, conflictsno,
3f5e193b 16485 sizeof (* econf64), _("conflict"));
a6e9f9df 16486 if (!econf64)
32ec8896 16487 return FALSE;
252b5132
RH
16488
16489 for (cnt = 0; cnt < conflictsno; ++cnt)
16490 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
16491
16492 free (econf64);
252b5132
RH
16493 }
16494
d3a49aa8
AM
16495 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
16496 "\nSection '.conflict' contains %lu entries:\n",
16497 (unsigned long) conflictsno),
c7e7ca54 16498 (unsigned long) conflictsno);
252b5132
RH
16499 puts (_(" Num: Index Value Name"));
16500
16501 for (cnt = 0; cnt < conflictsno; ++cnt)
16502 {
b34976b6 16503 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
16504
16505 if (iconf[cnt] >= num_dynamic_syms)
16506 printf (_("<corrupt symbol index>"));
d79b3d50 16507 else
e0a31db1
NC
16508 {
16509 Elf_Internal_Sym * psym;
16510
16511 psym = & dynamic_symbols[iconf[cnt]];
16512 print_vma (psym->st_value, FULL_HEX);
16513 putchar (' ');
16514 if (VALID_DYNAMIC_NAME (psym->st_name))
16515 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
16516 else
16517 printf (_("<corrupt: %14ld>"), psym->st_name);
16518 }
31104126 16519 putchar ('\n');
252b5132
RH
16520 }
16521
252b5132
RH
16522 free (iconf);
16523 }
16524
ccb4c951
RS
16525 if (pltgot != 0 && local_gotno != 0)
16526 {
91d6fa6a 16527 bfd_vma ent, local_end, global_end;
bbeee7ea 16528 size_t i, offset;
2cf0635d 16529 unsigned char * data;
82b1b41b 16530 unsigned char * data_end;
bbeee7ea 16531 int addr_size;
ccb4c951 16532
91d6fa6a 16533 ent = pltgot;
ccb4c951
RS
16534 addr_size = (is_32bit_elf ? 4 : 8);
16535 local_end = pltgot + local_gotno * addr_size;
ccb4c951 16536
74e1a04b
NC
16537 /* PR binutils/17533 file: 012-111227-0.004 */
16538 if (symtabno < gotsym)
16539 {
16540 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 16541 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 16542 return FALSE;
74e1a04b 16543 }
82b1b41b 16544
74e1a04b 16545 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
16546 /* PR 17531: file: 54c91a34. */
16547 if (global_end < local_end)
16548 {
16549 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 16550 return FALSE;
82b1b41b 16551 }
948f632f 16552
dda8d76d
NC
16553 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
16554 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
16555 global_end - pltgot, 1,
16556 _("Global Offset Table data"));
919383ac 16557 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 16558 data_end = data + (global_end - pltgot);
59245841 16559
ccb4c951
RS
16560 printf (_("\nPrimary GOT:\n"));
16561 printf (_(" Canonical gp value: "));
16562 print_vma (pltgot + 0x7ff0, LONG_HEX);
16563 printf ("\n\n");
16564
16565 printf (_(" Reserved entries:\n"));
16566 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
16567 addr_size * 2, _("Address"), _("Access"),
16568 addr_size * 2, _("Initial"));
82b1b41b 16569 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 16570 printf (_(" Lazy resolver\n"));
82b1b41b
NC
16571 if (ent == (bfd_vma) -1)
16572 goto got_print_fail;
75ec1fdb 16573
c4ab9505
MR
16574 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
16575 This entry will be used by some runtime loaders, to store the
16576 module pointer. Otherwise this is an ordinary local entry.
16577 PR 21344: Check for the entry being fully available before
16578 fetching it. */
16579 if (data
16580 && data + ent - pltgot + addr_size <= data_end
16581 && (byte_get (data + ent - pltgot, addr_size)
16582 >> (addr_size * 8 - 1)) != 0)
16583 {
16584 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16585 printf (_(" Module pointer (GNU extension)\n"));
16586 if (ent == (bfd_vma) -1)
16587 goto got_print_fail;
ccb4c951
RS
16588 }
16589 printf ("\n");
16590
f17e9d8a 16591 if (data != NULL && ent < local_end)
ccb4c951
RS
16592 {
16593 printf (_(" Local entries:\n"));
cc5914eb 16594 printf (" %*s %10s %*s\n",
2b692964
NC
16595 addr_size * 2, _("Address"), _("Access"),
16596 addr_size * 2, _("Initial"));
91d6fa6a 16597 while (ent < local_end)
ccb4c951 16598 {
82b1b41b 16599 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 16600 printf ("\n");
82b1b41b
NC
16601 if (ent == (bfd_vma) -1)
16602 goto got_print_fail;
ccb4c951
RS
16603 }
16604 printf ("\n");
16605 }
16606
f17e9d8a 16607 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
16608 {
16609 int sym_width;
16610
16611 printf (_(" Global entries:\n"));
cc5914eb 16612 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
16613 addr_size * 2, _("Address"),
16614 _("Access"),
2b692964 16615 addr_size * 2, _("Initial"),
9cf03b7e
NC
16616 addr_size * 2, _("Sym.Val."),
16617 _("Type"),
16618 /* Note for translators: "Ndx" = abbreviated form of "Index". */
16619 _("Ndx"), _("Name"));
0b4362b0 16620
ccb4c951 16621 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 16622
ccb4c951
RS
16623 for (i = gotsym; i < symtabno; i++)
16624 {
82b1b41b 16625 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 16626 printf (" ");
e0a31db1
NC
16627
16628 if (dynamic_symbols == NULL)
16629 printf (_("<no dynamic symbols>"));
16630 else if (i < num_dynamic_syms)
16631 {
16632 Elf_Internal_Sym * psym = dynamic_symbols + i;
16633
16634 print_vma (psym->st_value, LONG_HEX);
16635 printf (" %-7s %3s ",
dda8d76d
NC
16636 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
16637 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1
NC
16638
16639 if (VALID_DYNAMIC_NAME (psym->st_name))
16640 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
16641 else
16642 printf (_("<corrupt: %14ld>"), psym->st_name);
16643 }
ccb4c951 16644 else
7fc5ac57
JBG
16645 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
16646 (unsigned long) i);
e0a31db1 16647
ccb4c951 16648 printf ("\n");
82b1b41b
NC
16649 if (ent == (bfd_vma) -1)
16650 break;
ccb4c951
RS
16651 }
16652 printf ("\n");
16653 }
16654
82b1b41b 16655 got_print_fail:
ccb4c951
RS
16656 if (data)
16657 free (data);
16658 }
16659
861fb55a
DJ
16660 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
16661 {
91d6fa6a 16662 bfd_vma ent, end;
861fb55a
DJ
16663 size_t offset, rel_offset;
16664 unsigned long count, i;
2cf0635d 16665 unsigned char * data;
861fb55a 16666 int addr_size, sym_width;
2cf0635d 16667 Elf_Internal_Rela * rels;
861fb55a 16668
dda8d76d 16669 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
16670 if (pltrel == DT_RELA)
16671 {
dda8d76d 16672 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 16673 return FALSE;
861fb55a
DJ
16674 }
16675 else
16676 {
dda8d76d 16677 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 16678 return FALSE;
861fb55a
DJ
16679 }
16680
91d6fa6a 16681 ent = mips_pltgot;
861fb55a
DJ
16682 addr_size = (is_32bit_elf ? 4 : 8);
16683 end = mips_pltgot + (2 + count) * addr_size;
16684
dda8d76d
NC
16685 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
16686 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 16687 1, _("Procedure Linkage Table data"));
59245841 16688 if (data == NULL)
32ec8896 16689 return FALSE;
59245841 16690
9cf03b7e 16691 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
16692 printf (_(" Reserved entries:\n"));
16693 printf (_(" %*s %*s Purpose\n"),
2b692964 16694 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 16695 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 16696 printf (_(" PLT lazy resolver\n"));
91d6fa6a 16697 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 16698 printf (_(" Module pointer\n"));
861fb55a
DJ
16699 printf ("\n");
16700
16701 printf (_(" Entries:\n"));
cc5914eb 16702 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
16703 addr_size * 2, _("Address"),
16704 addr_size * 2, _("Initial"),
16705 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
16706 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
16707 for (i = 0; i < count; i++)
16708 {
df97ab2a 16709 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 16710
91d6fa6a 16711 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 16712 printf (" ");
e0a31db1 16713
df97ab2a
MF
16714 if (idx >= num_dynamic_syms)
16715 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 16716 else
e0a31db1 16717 {
df97ab2a 16718 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
16719
16720 print_vma (psym->st_value, LONG_HEX);
16721 printf (" %-7s %3s ",
dda8d76d
NC
16722 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
16723 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1
NC
16724 if (VALID_DYNAMIC_NAME (psym->st_name))
16725 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
16726 else
16727 printf (_("<corrupt: %14ld>"), psym->st_name);
16728 }
861fb55a
DJ
16729 printf ("\n");
16730 }
16731 printf ("\n");
16732
16733 if (data)
16734 free (data);
16735 free (rels);
16736 }
16737
32ec8896 16738 return res;
252b5132
RH
16739}
16740
32ec8896 16741static bfd_boolean
dda8d76d 16742process_nds32_specific (Filedata * filedata)
35c08157
KLC
16743{
16744 Elf_Internal_Shdr *sect = NULL;
16745
dda8d76d 16746 sect = find_section (filedata, ".nds32_e_flags");
35c08157
KLC
16747 if (sect != NULL)
16748 {
16749 unsigned int *flag;
16750
16751 printf ("\nNDS32 elf flags section:\n");
dda8d76d 16752 flag = get_data (NULL, filedata, sect->sh_offset, 1,
35c08157
KLC
16753 sect->sh_size, _("NDS32 elf flags section"));
16754
32ec8896
NC
16755 if (! flag)
16756 return FALSE;
16757
35c08157
KLC
16758 switch ((*flag) & 0x3)
16759 {
16760 case 0:
16761 printf ("(VEC_SIZE):\tNo entry.\n");
16762 break;
16763 case 1:
16764 printf ("(VEC_SIZE):\t4 bytes\n");
16765 break;
16766 case 2:
16767 printf ("(VEC_SIZE):\t16 bytes\n");
16768 break;
16769 case 3:
16770 printf ("(VEC_SIZE):\treserved\n");
16771 break;
16772 }
16773 }
16774
16775 return TRUE;
16776}
16777
32ec8896 16778static bfd_boolean
dda8d76d 16779process_gnu_liblist (Filedata * filedata)
047b2264 16780{
2cf0635d
NC
16781 Elf_Internal_Shdr * section;
16782 Elf_Internal_Shdr * string_sec;
16783 Elf32_External_Lib * elib;
16784 char * strtab;
c256ffe7 16785 size_t strtab_size;
047b2264 16786 size_t cnt;
d3a49aa8 16787 unsigned long num_liblist;
047b2264 16788 unsigned i;
32ec8896 16789 bfd_boolean res = TRUE;
047b2264
JJ
16790
16791 if (! do_arch)
32ec8896 16792 return TRUE;
047b2264 16793
dda8d76d
NC
16794 for (i = 0, section = filedata->section_headers;
16795 i < filedata->file_header.e_shnum;
b34976b6 16796 i++, section++)
047b2264
JJ
16797 {
16798 switch (section->sh_type)
16799 {
16800 case SHT_GNU_LIBLIST:
dda8d76d 16801 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
16802 break;
16803
3f5e193b 16804 elib = (Elf32_External_Lib *)
dda8d76d 16805 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 16806 _("liblist section data"));
047b2264
JJ
16807
16808 if (elib == NULL)
32ec8896
NC
16809 {
16810 res = FALSE;
16811 break;
16812 }
047b2264 16813
dda8d76d
NC
16814 string_sec = filedata->section_headers + section->sh_link;
16815 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
16816 string_sec->sh_size,
16817 _("liblist string table"));
047b2264
JJ
16818 if (strtab == NULL
16819 || section->sh_entsize != sizeof (Elf32_External_Lib))
16820 {
16821 free (elib);
2842702f 16822 free (strtab);
32ec8896 16823 res = FALSE;
047b2264
JJ
16824 break;
16825 }
59245841 16826 strtab_size = string_sec->sh_size;
047b2264 16827
d3a49aa8
AM
16828 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
16829 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
16830 "\nLibrary list section '%s' contains %lu entries:\n",
16831 num_liblist),
dda8d76d 16832 printable_section_name (filedata, section),
d3a49aa8 16833 num_liblist);
047b2264 16834
2b692964 16835 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
16836
16837 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
16838 ++cnt)
16839 {
16840 Elf32_Lib liblist;
91d6fa6a 16841 time_t atime;
d5b07ef4 16842 char timebuf[128];
2cf0635d 16843 struct tm * tmp;
047b2264
JJ
16844
16845 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 16846 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
16847 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
16848 liblist.l_version = BYTE_GET (elib[cnt].l_version);
16849 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
16850
91d6fa6a 16851 tmp = gmtime (&atime);
e9e44622
JJ
16852 snprintf (timebuf, sizeof (timebuf),
16853 "%04u-%02u-%02uT%02u:%02u:%02u",
16854 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
16855 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
16856
16857 printf ("%3lu: ", (unsigned long) cnt);
16858 if (do_wide)
c256ffe7 16859 printf ("%-20s", liblist.l_name < strtab_size
2b692964 16860 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 16861 else
c256ffe7 16862 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 16863 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
16864 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
16865 liblist.l_version, liblist.l_flags);
16866 }
16867
16868 free (elib);
2842702f 16869 free (strtab);
047b2264
JJ
16870 }
16871 }
16872
32ec8896 16873 return res;
047b2264
JJ
16874}
16875
9437c45b 16876static const char *
dda8d76d 16877get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
16878{
16879 static char buff[64];
103f02d3 16880
dda8d76d 16881 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
16882 switch (e_type)
16883 {
57346661 16884 case NT_AUXV:
1ec5cd37 16885 return _("NT_AUXV (auxiliary vector)");
57346661 16886 case NT_PRSTATUS:
1ec5cd37 16887 return _("NT_PRSTATUS (prstatus structure)");
57346661 16888 case NT_FPREGSET:
1ec5cd37 16889 return _("NT_FPREGSET (floating point registers)");
57346661 16890 case NT_PRPSINFO:
1ec5cd37 16891 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 16892 case NT_TASKSTRUCT:
1ec5cd37 16893 return _("NT_TASKSTRUCT (task structure)");
57346661 16894 case NT_PRXFPREG:
1ec5cd37 16895 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
16896 case NT_PPC_VMX:
16897 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
16898 case NT_PPC_VSX:
16899 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
16900 case NT_PPC_TAR:
16901 return _("NT_PPC_TAR (ppc TAR register)");
16902 case NT_PPC_PPR:
16903 return _("NT_PPC_PPR (ppc PPR register)");
16904 case NT_PPC_DSCR:
16905 return _("NT_PPC_DSCR (ppc DSCR register)");
16906 case NT_PPC_EBB:
16907 return _("NT_PPC_EBB (ppc EBB registers)");
16908 case NT_PPC_PMU:
16909 return _("NT_PPC_PMU (ppc PMU registers)");
16910 case NT_PPC_TM_CGPR:
16911 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
16912 case NT_PPC_TM_CFPR:
16913 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
16914 case NT_PPC_TM_CVMX:
16915 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
16916 case NT_PPC_TM_CVSX:
3fd21718 16917 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
16918 case NT_PPC_TM_SPR:
16919 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
16920 case NT_PPC_TM_CTAR:
16921 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
16922 case NT_PPC_TM_CPPR:
16923 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
16924 case NT_PPC_TM_CDSCR:
16925 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
16926 case NT_386_TLS:
16927 return _("NT_386_TLS (x86 TLS information)");
16928 case NT_386_IOPERM:
16929 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
16930 case NT_X86_XSTATE:
16931 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
16932 case NT_S390_HIGH_GPRS:
16933 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
16934 case NT_S390_TIMER:
16935 return _("NT_S390_TIMER (s390 timer register)");
16936 case NT_S390_TODCMP:
16937 return _("NT_S390_TODCMP (s390 TOD comparator register)");
16938 case NT_S390_TODPREG:
16939 return _("NT_S390_TODPREG (s390 TOD programmable register)");
16940 case NT_S390_CTRS:
16941 return _("NT_S390_CTRS (s390 control registers)");
16942 case NT_S390_PREFIX:
16943 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
16944 case NT_S390_LAST_BREAK:
16945 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
16946 case NT_S390_SYSTEM_CALL:
16947 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
16948 case NT_S390_TDB:
16949 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
16950 case NT_S390_VXRS_LOW:
16951 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
16952 case NT_S390_VXRS_HIGH:
16953 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
16954 case NT_S390_GS_CB:
16955 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
16956 case NT_S390_GS_BC:
16957 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
16958 case NT_ARM_VFP:
16959 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
16960 case NT_ARM_TLS:
16961 return _("NT_ARM_TLS (AArch TLS registers)");
16962 case NT_ARM_HW_BREAK:
16963 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
16964 case NT_ARM_HW_WATCH:
16965 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 16966 case NT_PSTATUS:
1ec5cd37 16967 return _("NT_PSTATUS (pstatus structure)");
57346661 16968 case NT_FPREGS:
1ec5cd37 16969 return _("NT_FPREGS (floating point registers)");
57346661 16970 case NT_PSINFO:
1ec5cd37 16971 return _("NT_PSINFO (psinfo structure)");
57346661 16972 case NT_LWPSTATUS:
1ec5cd37 16973 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 16974 case NT_LWPSINFO:
1ec5cd37 16975 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 16976 case NT_WIN32PSTATUS:
1ec5cd37 16977 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
16978 case NT_SIGINFO:
16979 return _("NT_SIGINFO (siginfo_t data)");
16980 case NT_FILE:
16981 return _("NT_FILE (mapped files)");
1ec5cd37
NC
16982 default:
16983 break;
16984 }
16985 else
16986 switch (e_type)
16987 {
16988 case NT_VERSION:
16989 return _("NT_VERSION (version)");
16990 case NT_ARCH:
16991 return _("NT_ARCH (architecture)");
9ef920e9 16992 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 16993 return _("OPEN");
9ef920e9 16994 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 16995 return _("func");
1ec5cd37
NC
16996 default:
16997 break;
16998 }
16999
e9e44622 17000 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 17001 return buff;
779fe533
NC
17002}
17003
32ec8896 17004static bfd_boolean
9ece1fa9
TT
17005print_core_note (Elf_Internal_Note *pnote)
17006{
17007 unsigned int addr_size = is_32bit_elf ? 4 : 8;
17008 bfd_vma count, page_size;
17009 unsigned char *descdata, *filenames, *descend;
17010
17011 if (pnote->type != NT_FILE)
04ac15ab
AS
17012 {
17013 if (do_wide)
17014 printf ("\n");
17015 return TRUE;
17016 }
9ece1fa9
TT
17017
17018#ifndef BFD64
17019 if (!is_32bit_elf)
17020 {
17021 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
17022 /* Still "successful". */
32ec8896 17023 return TRUE;
9ece1fa9
TT
17024 }
17025#endif
17026
17027 if (pnote->descsz < 2 * addr_size)
17028 {
32ec8896
NC
17029 error (_(" Malformed note - too short for header\n"));
17030 return FALSE;
9ece1fa9
TT
17031 }
17032
17033 descdata = (unsigned char *) pnote->descdata;
17034 descend = descdata + pnote->descsz;
17035
17036 if (descdata[pnote->descsz - 1] != '\0')
17037 {
32ec8896
NC
17038 error (_(" Malformed note - does not end with \\0\n"));
17039 return FALSE;
9ece1fa9
TT
17040 }
17041
17042 count = byte_get (descdata, addr_size);
17043 descdata += addr_size;
17044
17045 page_size = byte_get (descdata, addr_size);
17046 descdata += addr_size;
17047
5396a86e
AM
17048 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
17049 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 17050 {
32ec8896
NC
17051 error (_(" Malformed note - too short for supplied file count\n"));
17052 return FALSE;
9ece1fa9
TT
17053 }
17054
17055 printf (_(" Page size: "));
17056 print_vma (page_size, DEC);
17057 printf ("\n");
17058
17059 printf (_(" %*s%*s%*s\n"),
17060 (int) (2 + 2 * addr_size), _("Start"),
17061 (int) (4 + 2 * addr_size), _("End"),
17062 (int) (4 + 2 * addr_size), _("Page Offset"));
17063 filenames = descdata + count * 3 * addr_size;
595712bb 17064 while (count-- > 0)
9ece1fa9
TT
17065 {
17066 bfd_vma start, end, file_ofs;
17067
17068 if (filenames == descend)
17069 {
32ec8896
NC
17070 error (_(" Malformed note - filenames end too early\n"));
17071 return FALSE;
9ece1fa9
TT
17072 }
17073
17074 start = byte_get (descdata, addr_size);
17075 descdata += addr_size;
17076 end = byte_get (descdata, addr_size);
17077 descdata += addr_size;
17078 file_ofs = byte_get (descdata, addr_size);
17079 descdata += addr_size;
17080
17081 printf (" ");
17082 print_vma (start, FULL_HEX);
17083 printf (" ");
17084 print_vma (end, FULL_HEX);
17085 printf (" ");
17086 print_vma (file_ofs, FULL_HEX);
17087 printf ("\n %s\n", filenames);
17088
17089 filenames += 1 + strlen ((char *) filenames);
17090 }
17091
32ec8896 17092 return TRUE;
9ece1fa9
TT
17093}
17094
1118d252
RM
17095static const char *
17096get_gnu_elf_note_type (unsigned e_type)
17097{
1449284b 17098 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
17099 switch (e_type)
17100 {
17101 case NT_GNU_ABI_TAG:
17102 return _("NT_GNU_ABI_TAG (ABI version tag)");
17103 case NT_GNU_HWCAP:
17104 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
17105 case NT_GNU_BUILD_ID:
17106 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
17107 case NT_GNU_GOLD_VERSION:
17108 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
17109 case NT_GNU_PROPERTY_TYPE_0:
17110 return _("NT_GNU_PROPERTY_TYPE_0");
17111 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
17112 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
17113 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
17114 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 17115 default:
1449284b
NC
17116 {
17117 static char buff[64];
1118d252 17118
1449284b
NC
17119 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17120 return buff;
17121 }
17122 }
1118d252
RM
17123}
17124
a9eafb08
L
17125static void
17126decode_x86_compat_isa (unsigned int bitmask)
17127{
17128 while (bitmask)
17129 {
17130 unsigned int bit = bitmask & (- bitmask);
17131
17132 bitmask &= ~ bit;
17133 switch (bit)
17134 {
17135 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
17136 printf ("i486");
17137 break;
17138 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
17139 printf ("586");
17140 break;
17141 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
17142 printf ("686");
17143 break;
17144 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
17145 printf ("SSE");
17146 break;
17147 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
17148 printf ("SSE2");
17149 break;
17150 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
17151 printf ("SSE3");
17152 break;
17153 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
17154 printf ("SSSE3");
17155 break;
17156 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
17157 printf ("SSE4_1");
17158 break;
17159 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
17160 printf ("SSE4_2");
17161 break;
17162 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
17163 printf ("AVX");
17164 break;
17165 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
17166 printf ("AVX2");
17167 break;
17168 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
17169 printf ("AVX512F");
17170 break;
17171 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
17172 printf ("AVX512CD");
17173 break;
17174 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
17175 printf ("AVX512ER");
17176 break;
17177 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
17178 printf ("AVX512PF");
17179 break;
17180 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
17181 printf ("AVX512VL");
17182 break;
17183 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
17184 printf ("AVX512DQ");
17185 break;
17186 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
17187 printf ("AVX512BW");
17188 break;
65b3d26e
L
17189 default:
17190 printf (_("<unknown: %x>"), bit);
17191 break;
a9eafb08
L
17192 }
17193 if (bitmask)
17194 printf (", ");
17195 }
17196}
17197
9ef920e9 17198static void
1fc87489 17199decode_x86_isa (unsigned int bitmask)
9ef920e9 17200{
0a59decb 17201 if (!bitmask)
90c745dc
L
17202 {
17203 printf (_("<None>"));
17204 return;
17205 }
90c745dc 17206
9ef920e9
NC
17207 while (bitmask)
17208 {
1fc87489 17209 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
17210
17211 bitmask &= ~ bit;
17212 switch (bit)
17213 {
a9eafb08
L
17214 case GNU_PROPERTY_X86_ISA_1_CMOV:
17215 printf ("CMOV");
17216 break;
17217 case GNU_PROPERTY_X86_ISA_1_SSE:
17218 printf ("SSE");
17219 break;
17220 case GNU_PROPERTY_X86_ISA_1_SSE2:
17221 printf ("SSE2");
17222 break;
17223 case GNU_PROPERTY_X86_ISA_1_SSE3:
17224 printf ("SSE3");
17225 break;
17226 case GNU_PROPERTY_X86_ISA_1_SSSE3:
17227 printf ("SSSE3");
17228 break;
17229 case GNU_PROPERTY_X86_ISA_1_SSE4_1:
17230 printf ("SSE4_1");
17231 break;
17232 case GNU_PROPERTY_X86_ISA_1_SSE4_2:
17233 printf ("SSE4_2");
17234 break;
17235 case GNU_PROPERTY_X86_ISA_1_AVX:
17236 printf ("AVX");
17237 break;
17238 case GNU_PROPERTY_X86_ISA_1_AVX2:
17239 printf ("AVX2");
17240 break;
17241 case GNU_PROPERTY_X86_ISA_1_FMA:
17242 printf ("FMA");
17243 break;
17244 case GNU_PROPERTY_X86_ISA_1_AVX512F:
17245 printf ("AVX512F");
17246 break;
17247 case GNU_PROPERTY_X86_ISA_1_AVX512CD:
17248 printf ("AVX512CD");
17249 break;
17250 case GNU_PROPERTY_X86_ISA_1_AVX512ER:
17251 printf ("AVX512ER");
17252 break;
17253 case GNU_PROPERTY_X86_ISA_1_AVX512PF:
17254 printf ("AVX512PF");
17255 break;
17256 case GNU_PROPERTY_X86_ISA_1_AVX512VL:
17257 printf ("AVX512VL");
17258 break;
17259 case GNU_PROPERTY_X86_ISA_1_AVX512DQ:
17260 printf ("AVX512DQ");
17261 break;
17262 case GNU_PROPERTY_X86_ISA_1_AVX512BW:
17263 printf ("AVX512BW");
17264 break;
17265 case GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS:
17266 printf ("AVX512_4FMAPS");
17267 break;
17268 case GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW:
17269 printf ("AVX512_4VNNIW");
17270 break;
17271 case GNU_PROPERTY_X86_ISA_1_AVX512_BITALG:
17272 printf ("AVX512_BITALG");
17273 break;
17274 case GNU_PROPERTY_X86_ISA_1_AVX512_IFMA:
17275 printf ("AVX512_IFMA");
17276 break;
17277 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI:
17278 printf ("AVX512_VBMI");
17279 break;
17280 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2:
17281 printf ("AVX512_VBMI2");
17282 break;
17283 case GNU_PROPERTY_X86_ISA_1_AVX512_VNNI:
17284 printf ("AVX512_VNNI");
17285 break;
462cac58
L
17286 case GNU_PROPERTY_X86_ISA_1_AVX512_BF16:
17287 printf ("AVX512_BF16");
17288 break;
65b3d26e
L
17289 default:
17290 printf (_("<unknown: %x>"), bit);
17291 break;
9ef920e9
NC
17292 }
17293 if (bitmask)
17294 printf (", ");
17295 }
17296}
17297
ee2fdd6f 17298static void
a9eafb08 17299decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 17300{
0a59decb 17301 if (!bitmask)
90c745dc
L
17302 {
17303 printf (_("<None>"));
17304 return;
17305 }
90c745dc 17306
ee2fdd6f
L
17307 while (bitmask)
17308 {
17309 unsigned int bit = bitmask & (- bitmask);
17310
17311 bitmask &= ~ bit;
17312 switch (bit)
17313 {
17314 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 17315 printf ("IBT");
ee2fdd6f 17316 break;
48580982 17317 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 17318 printf ("SHSTK");
48580982 17319 break;
ee2fdd6f
L
17320 default:
17321 printf (_("<unknown: %x>"), bit);
17322 break;
17323 }
17324 if (bitmask)
17325 printf (", ");
17326 }
17327}
17328
a9eafb08
L
17329static void
17330decode_x86_feature_2 (unsigned int bitmask)
17331{
0a59decb 17332 if (!bitmask)
90c745dc
L
17333 {
17334 printf (_("<None>"));
17335 return;
17336 }
90c745dc 17337
a9eafb08
L
17338 while (bitmask)
17339 {
17340 unsigned int bit = bitmask & (- bitmask);
17341
17342 bitmask &= ~ bit;
17343 switch (bit)
17344 {
17345 case GNU_PROPERTY_X86_FEATURE_2_X86:
17346 printf ("x86");
17347 break;
17348 case GNU_PROPERTY_X86_FEATURE_2_X87:
17349 printf ("x87");
17350 break;
17351 case GNU_PROPERTY_X86_FEATURE_2_MMX:
17352 printf ("MMX");
17353 break;
17354 case GNU_PROPERTY_X86_FEATURE_2_XMM:
17355 printf ("XMM");
17356 break;
17357 case GNU_PROPERTY_X86_FEATURE_2_YMM:
17358 printf ("YMM");
17359 break;
17360 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
17361 printf ("ZMM");
17362 break;
17363 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
17364 printf ("FXSR");
17365 break;
17366 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
17367 printf ("XSAVE");
17368 break;
17369 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
17370 printf ("XSAVEOPT");
17371 break;
17372 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
17373 printf ("XSAVEC");
17374 break;
65b3d26e
L
17375 default:
17376 printf (_("<unknown: %x>"), bit);
17377 break;
a9eafb08
L
17378 }
17379 if (bitmask)
17380 printf (", ");
17381 }
17382}
17383
cd702818
SD
17384static void
17385decode_aarch64_feature_1_and (unsigned int bitmask)
17386{
17387 while (bitmask)
17388 {
17389 unsigned int bit = bitmask & (- bitmask);
17390
17391 bitmask &= ~ bit;
17392 switch (bit)
17393 {
17394 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
17395 printf ("BTI");
17396 break;
17397
17398 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
17399 printf ("PAC");
17400 break;
17401
17402 default:
17403 printf (_("<unknown: %x>"), bit);
17404 break;
17405 }
17406 if (bitmask)
17407 printf (", ");
17408 }
17409}
17410
9ef920e9 17411static void
dda8d76d 17412print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
17413{
17414 unsigned char * ptr = (unsigned char *) pnote->descdata;
17415 unsigned char * ptr_end = ptr + pnote->descsz;
17416 unsigned int size = is_32bit_elf ? 4 : 8;
17417
17418 printf (_(" Properties: "));
17419
1fc87489 17420 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
17421 {
17422 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
17423 return;
17424 }
17425
6ab2c4ed 17426 while (ptr < ptr_end)
9ef920e9 17427 {
1fc87489 17428 unsigned int j;
6ab2c4ed
MC
17429 unsigned int type;
17430 unsigned int datasz;
17431
17432 if ((size_t) (ptr_end - ptr) < 8)
17433 {
17434 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
17435 break;
17436 }
17437
17438 type = byte_get (ptr, 4);
17439 datasz = byte_get (ptr + 4, 4);
9ef920e9 17440
1fc87489 17441 ptr += 8;
9ef920e9 17442
6ab2c4ed 17443 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 17444 {
1fc87489
L
17445 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
17446 type, datasz);
9ef920e9 17447 break;
1fc87489 17448 }
9ef920e9 17449
1fc87489
L
17450 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
17451 {
dda8d76d
NC
17452 if (filedata->file_header.e_machine == EM_X86_64
17453 || filedata->file_header.e_machine == EM_IAMCU
17454 || filedata->file_header.e_machine == EM_386)
1fc87489 17455 {
aa7bca9b
L
17456 unsigned int bitmask;
17457
17458 if (datasz == 4)
0a59decb 17459 bitmask = byte_get (ptr, 4);
aa7bca9b
L
17460 else
17461 bitmask = 0;
17462
1fc87489
L
17463 switch (type)
17464 {
17465 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 17466 if (datasz != 4)
aa7bca9b
L
17467 printf (_("x86 ISA used: <corrupt length: %#x> "),
17468 datasz);
1fc87489 17469 else
aa7bca9b
L
17470 {
17471 printf ("x86 ISA used: ");
17472 decode_x86_isa (bitmask);
17473 }
1fc87489 17474 goto next;
9ef920e9 17475
1fc87489 17476 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 17477 if (datasz != 4)
aa7bca9b
L
17478 printf (_("x86 ISA needed: <corrupt length: %#x> "),
17479 datasz);
1fc87489 17480 else
aa7bca9b
L
17481 {
17482 printf ("x86 ISA needed: ");
17483 decode_x86_isa (bitmask);
17484 }
1fc87489 17485 goto next;
9ef920e9 17486
ee2fdd6f 17487 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 17488 if (datasz != 4)
aa7bca9b
L
17489 printf (_("x86 feature: <corrupt length: %#x> "),
17490 datasz);
ee2fdd6f 17491 else
aa7bca9b
L
17492 {
17493 printf ("x86 feature: ");
a9eafb08
L
17494 decode_x86_feature_1 (bitmask);
17495 }
17496 goto next;
17497
17498 case GNU_PROPERTY_X86_FEATURE_2_USED:
17499 if (datasz != 4)
17500 printf (_("x86 feature used: <corrupt length: %#x> "),
17501 datasz);
17502 else
17503 {
17504 printf ("x86 feature used: ");
17505 decode_x86_feature_2 (bitmask);
17506 }
17507 goto next;
17508
17509 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
17510 if (datasz != 4)
17511 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
17512 else
17513 {
17514 printf ("x86 feature needed: ");
17515 decode_x86_feature_2 (bitmask);
17516 }
17517 goto next;
17518
17519 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
17520 if (datasz != 4)
17521 printf (_("x86 ISA used: <corrupt length: %#x> "),
17522 datasz);
17523 else
17524 {
17525 printf ("x86 ISA used: ");
17526 decode_x86_compat_isa (bitmask);
17527 }
17528 goto next;
17529
17530 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
17531 if (datasz != 4)
17532 printf (_("x86 ISA needed: <corrupt length: %#x> "),
17533 datasz);
17534 else
17535 {
17536 printf ("x86 ISA needed: ");
17537 decode_x86_compat_isa (bitmask);
aa7bca9b 17538 }
ee2fdd6f
L
17539 goto next;
17540
1fc87489
L
17541 default:
17542 break;
17543 }
17544 }
cd702818
SD
17545 else if (filedata->file_header.e_machine == EM_AARCH64)
17546 {
17547 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
17548 {
17549 printf ("AArch64 feature: ");
17550 if (datasz != 4)
17551 printf (_("<corrupt length: %#x> "), datasz);
17552 else
17553 decode_aarch64_feature_1_and (byte_get (ptr, 4));
17554 goto next;
17555 }
17556 }
1fc87489
L
17557 }
17558 else
17559 {
17560 switch (type)
9ef920e9 17561 {
1fc87489
L
17562 case GNU_PROPERTY_STACK_SIZE:
17563 printf (_("stack size: "));
17564 if (datasz != size)
17565 printf (_("<corrupt length: %#x> "), datasz);
17566 else
17567 printf ("%#lx", (unsigned long) byte_get (ptr, size));
17568 goto next;
17569
17570 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
17571 printf ("no copy on protected ");
17572 if (datasz)
17573 printf (_("<corrupt length: %#x> "), datasz);
17574 goto next;
17575
17576 default:
9ef920e9
NC
17577 break;
17578 }
9ef920e9
NC
17579 }
17580
1fc87489
L
17581 if (type < GNU_PROPERTY_LOPROC)
17582 printf (_("<unknown type %#x data: "), type);
17583 else if (type < GNU_PROPERTY_LOUSER)
17584 printf (_("<procesor-specific type %#x data: "), type);
17585 else
17586 printf (_("<application-specific type %#x data: "), type);
17587 for (j = 0; j < datasz; ++j)
17588 printf ("%02x ", ptr[j] & 0xff);
17589 printf (">");
17590
17591next:
9ef920e9 17592 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
17593 if (ptr == ptr_end)
17594 break;
1fc87489 17595
6ab2c4ed
MC
17596 if (do_wide)
17597 printf (", ");
17598 else
17599 printf ("\n\t");
9ef920e9
NC
17600 }
17601
17602 printf ("\n");
17603}
17604
32ec8896 17605static bfd_boolean
dda8d76d 17606print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 17607{
1449284b 17608 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
17609 switch (pnote->type)
17610 {
17611 case NT_GNU_BUILD_ID:
17612 {
17613 unsigned long i;
17614
17615 printf (_(" Build ID: "));
17616 for (i = 0; i < pnote->descsz; ++i)
17617 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 17618 printf ("\n");
664f90a3
TT
17619 }
17620 break;
17621
17622 case NT_GNU_ABI_TAG:
17623 {
17624 unsigned long os, major, minor, subminor;
17625 const char *osname;
17626
3102e897
NC
17627 /* PR 17531: file: 030-599401-0.004. */
17628 if (pnote->descsz < 16)
17629 {
17630 printf (_(" <corrupt GNU_ABI_TAG>\n"));
17631 break;
17632 }
17633
664f90a3
TT
17634 os = byte_get ((unsigned char *) pnote->descdata, 4);
17635 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
17636 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
17637 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
17638
17639 switch (os)
17640 {
17641 case GNU_ABI_TAG_LINUX:
17642 osname = "Linux";
17643 break;
17644 case GNU_ABI_TAG_HURD:
17645 osname = "Hurd";
17646 break;
17647 case GNU_ABI_TAG_SOLARIS:
17648 osname = "Solaris";
17649 break;
17650 case GNU_ABI_TAG_FREEBSD:
17651 osname = "FreeBSD";
17652 break;
17653 case GNU_ABI_TAG_NETBSD:
17654 osname = "NetBSD";
17655 break;
14ae95f2
RM
17656 case GNU_ABI_TAG_SYLLABLE:
17657 osname = "Syllable";
17658 break;
17659 case GNU_ABI_TAG_NACL:
17660 osname = "NaCl";
17661 break;
664f90a3
TT
17662 default:
17663 osname = "Unknown";
17664 break;
17665 }
17666
17667 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
17668 major, minor, subminor);
17669 }
17670 break;
926c5385
CC
17671
17672 case NT_GNU_GOLD_VERSION:
17673 {
17674 unsigned long i;
17675
17676 printf (_(" Version: "));
17677 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
17678 printf ("%c", pnote->descdata[i]);
17679 printf ("\n");
17680 }
17681 break;
1449284b
NC
17682
17683 case NT_GNU_HWCAP:
17684 {
17685 unsigned long num_entries, mask;
17686
17687 /* Hardware capabilities information. Word 0 is the number of entries.
17688 Word 1 is a bitmask of enabled entries. The rest of the descriptor
17689 is a series of entries, where each entry is a single byte followed
17690 by a nul terminated string. The byte gives the bit number to test
17691 if enabled in the bitmask. */
17692 printf (_(" Hardware Capabilities: "));
17693 if (pnote->descsz < 8)
17694 {
32ec8896
NC
17695 error (_("<corrupt GNU_HWCAP>\n"));
17696 return FALSE;
1449284b
NC
17697 }
17698 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
17699 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
17700 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
17701 /* FIXME: Add code to display the entries... */
17702 }
17703 break;
17704
9ef920e9 17705 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 17706 print_gnu_property_note (filedata, pnote);
9ef920e9
NC
17707 break;
17708
1449284b
NC
17709 default:
17710 /* Handle unrecognised types. An error message should have already been
17711 created by get_gnu_elf_note_type(), so all that we need to do is to
17712 display the data. */
17713 {
17714 unsigned long i;
17715
17716 printf (_(" Description data: "));
17717 for (i = 0; i < pnote->descsz; ++i)
17718 printf ("%02x ", pnote->descdata[i] & 0xff);
17719 printf ("\n");
17720 }
17721 break;
664f90a3
TT
17722 }
17723
32ec8896 17724 return TRUE;
664f90a3
TT
17725}
17726
685080f2
NC
17727static const char *
17728get_v850_elf_note_type (enum v850_notes n_type)
17729{
17730 static char buff[64];
17731
17732 switch (n_type)
17733 {
17734 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
17735 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
17736 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
17737 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
17738 case V850_NOTE_CACHE_INFO: return _("Use of cache");
17739 case V850_NOTE_MMU_INFO: return _("Use of MMU");
17740 default:
17741 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
17742 return buff;
17743 }
17744}
17745
32ec8896 17746static bfd_boolean
685080f2
NC
17747print_v850_note (Elf_Internal_Note * pnote)
17748{
17749 unsigned int val;
17750
17751 if (pnote->descsz != 4)
32ec8896
NC
17752 return FALSE;
17753
685080f2
NC
17754 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
17755
17756 if (val == 0)
17757 {
17758 printf (_("not set\n"));
32ec8896 17759 return TRUE;
685080f2
NC
17760 }
17761
17762 switch (pnote->type)
17763 {
17764 case V850_NOTE_ALIGNMENT:
17765 switch (val)
17766 {
32ec8896
NC
17767 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
17768 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
17769 }
17770 break;
14ae95f2 17771
685080f2
NC
17772 case V850_NOTE_DATA_SIZE:
17773 switch (val)
17774 {
32ec8896
NC
17775 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
17776 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
17777 }
17778 break;
14ae95f2 17779
685080f2
NC
17780 case V850_NOTE_FPU_INFO:
17781 switch (val)
17782 {
32ec8896
NC
17783 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
17784 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
17785 }
17786 break;
14ae95f2 17787
685080f2
NC
17788 case V850_NOTE_MMU_INFO:
17789 case V850_NOTE_CACHE_INFO:
17790 case V850_NOTE_SIMD_INFO:
17791 if (val == EF_RH850_SIMD)
17792 {
17793 printf (_("yes\n"));
32ec8896 17794 return TRUE;
685080f2
NC
17795 }
17796 break;
17797
17798 default:
17799 /* An 'unknown note type' message will already have been displayed. */
17800 break;
17801 }
17802
17803 printf (_("unknown value: %x\n"), val);
32ec8896 17804 return FALSE;
685080f2
NC
17805}
17806
32ec8896 17807static bfd_boolean
c6056a74
SF
17808process_netbsd_elf_note (Elf_Internal_Note * pnote)
17809{
17810 unsigned int version;
17811
17812 switch (pnote->type)
17813 {
17814 case NT_NETBSD_IDENT:
17815 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
17816 if ((version / 10000) % 100)
17817 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
17818 version, version / 100000000, (version / 1000000) % 100,
17819 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 17820 'A' + (version / 10000) % 26);
c6056a74
SF
17821 else
17822 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
17823 version, version / 100000000, (version / 1000000) % 100,
15f205b1 17824 (version / 100) % 100);
32ec8896 17825 return TRUE;
c6056a74
SF
17826
17827 case NT_NETBSD_MARCH:
17828 printf (" NetBSD\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
17829 pnote->descdata);
32ec8896 17830 return TRUE;
c6056a74
SF
17831
17832 default:
32ec8896
NC
17833 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n", pnote->descsz,
17834 pnote->type);
17835 return FALSE;
c6056a74 17836 }
c6056a74
SF
17837}
17838
f4ddf30f 17839static const char *
dda8d76d 17840get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 17841{
f4ddf30f
JB
17842 switch (e_type)
17843 {
17844 case NT_FREEBSD_THRMISC:
17845 return _("NT_THRMISC (thrmisc structure)");
17846 case NT_FREEBSD_PROCSTAT_PROC:
17847 return _("NT_PROCSTAT_PROC (proc data)");
17848 case NT_FREEBSD_PROCSTAT_FILES:
17849 return _("NT_PROCSTAT_FILES (files data)");
17850 case NT_FREEBSD_PROCSTAT_VMMAP:
17851 return _("NT_PROCSTAT_VMMAP (vmmap data)");
17852 case NT_FREEBSD_PROCSTAT_GROUPS:
17853 return _("NT_PROCSTAT_GROUPS (groups data)");
17854 case NT_FREEBSD_PROCSTAT_UMASK:
17855 return _("NT_PROCSTAT_UMASK (umask data)");
17856 case NT_FREEBSD_PROCSTAT_RLIMIT:
17857 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
17858 case NT_FREEBSD_PROCSTAT_OSREL:
17859 return _("NT_PROCSTAT_OSREL (osreldate data)");
17860 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
17861 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
17862 case NT_FREEBSD_PROCSTAT_AUXV:
17863 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
17864 case NT_FREEBSD_PTLWPINFO:
17865 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 17866 }
dda8d76d 17867 return get_note_type (filedata, e_type);
f4ddf30f
JB
17868}
17869
9437c45b 17870static const char *
dda8d76d 17871get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
17872{
17873 static char buff[64];
17874
b4db1224 17875 if (e_type == NT_NETBSDCORE_PROCINFO)
dda8d76d 17876 return _("NetBSD procinfo structure");
9437c45b
JT
17877
17878 /* As of Jan 2002 there are no other machine-independent notes
17879 defined for NetBSD core files. If the note type is less
17880 than the start of the machine-dependent note types, we don't
17881 understand it. */
17882
b4db1224 17883 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 17884 {
e9e44622 17885 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
17886 return buff;
17887 }
17888
dda8d76d 17889 switch (filedata->file_header.e_machine)
9437c45b
JT
17890 {
17891 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
17892 and PT_GETFPREGS == mach+2. */
17893
17894 case EM_OLD_ALPHA:
17895 case EM_ALPHA:
17896 case EM_SPARC:
17897 case EM_SPARC32PLUS:
17898 case EM_SPARCV9:
17899 switch (e_type)
17900 {
2b692964 17901 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 17902 return _("PT_GETREGS (reg structure)");
2b692964 17903 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 17904 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
17905 default:
17906 break;
17907 }
17908 break;
17909
17910 /* On all other arch's, PT_GETREGS == mach+1 and
17911 PT_GETFPREGS == mach+3. */
17912 default:
17913 switch (e_type)
17914 {
2b692964 17915 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 17916 return _("PT_GETREGS (reg structure)");
2b692964 17917 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 17918 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
17919 default:
17920 break;
17921 }
17922 }
17923
9cf03b7e 17924 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 17925 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
17926 return buff;
17927}
17928
70616151
TT
17929static const char *
17930get_stapsdt_note_type (unsigned e_type)
17931{
17932 static char buff[64];
17933
17934 switch (e_type)
17935 {
17936 case NT_STAPSDT:
17937 return _("NT_STAPSDT (SystemTap probe descriptors)");
17938
17939 default:
17940 break;
17941 }
17942
17943 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17944 return buff;
17945}
17946
32ec8896 17947static bfd_boolean
c6a9fc58
TT
17948print_stapsdt_note (Elf_Internal_Note *pnote)
17949{
3ca60c57
NC
17950 size_t len, maxlen;
17951 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
17952 char *data = pnote->descdata;
17953 char *data_end = pnote->descdata + pnote->descsz;
17954 bfd_vma pc, base_addr, semaphore;
17955 char *provider, *probe, *arg_fmt;
17956
3ca60c57
NC
17957 if (pnote->descsz < (addr_size * 3))
17958 goto stapdt_note_too_small;
17959
c6a9fc58
TT
17960 pc = byte_get ((unsigned char *) data, addr_size);
17961 data += addr_size;
3ca60c57 17962
c6a9fc58
TT
17963 base_addr = byte_get ((unsigned char *) data, addr_size);
17964 data += addr_size;
3ca60c57 17965
c6a9fc58
TT
17966 semaphore = byte_get ((unsigned char *) data, addr_size);
17967 data += addr_size;
17968
3ca60c57
NC
17969 if (data >= data_end)
17970 goto stapdt_note_too_small;
17971 maxlen = data_end - data;
17972 len = strnlen (data, maxlen);
17973 if (len < maxlen)
17974 {
17975 provider = data;
17976 data += len + 1;
17977 }
17978 else
17979 goto stapdt_note_too_small;
17980
17981 if (data >= data_end)
17982 goto stapdt_note_too_small;
17983 maxlen = data_end - data;
17984 len = strnlen (data, maxlen);
17985 if (len < maxlen)
17986 {
17987 probe = data;
17988 data += len + 1;
17989 }
17990 else
17991 goto stapdt_note_too_small;
17992
17993 if (data >= data_end)
17994 goto stapdt_note_too_small;
17995 maxlen = data_end - data;
17996 len = strnlen (data, maxlen);
17997 if (len < maxlen)
17998 {
17999 arg_fmt = data;
18000 data += len + 1;
18001 }
18002 else
18003 goto stapdt_note_too_small;
c6a9fc58
TT
18004
18005 printf (_(" Provider: %s\n"), provider);
18006 printf (_(" Name: %s\n"), probe);
18007 printf (_(" Location: "));
18008 print_vma (pc, FULL_HEX);
18009 printf (_(", Base: "));
18010 print_vma (base_addr, FULL_HEX);
18011 printf (_(", Semaphore: "));
18012 print_vma (semaphore, FULL_HEX);
9cf03b7e 18013 printf ("\n");
c6a9fc58
TT
18014 printf (_(" Arguments: %s\n"), arg_fmt);
18015
18016 return data == data_end;
3ca60c57
NC
18017
18018 stapdt_note_too_small:
18019 printf (_(" <corrupt - note is too small>\n"));
18020 error (_("corrupt stapdt note - the data size is too small\n"));
18021 return FALSE;
c6a9fc58
TT
18022}
18023
00e98fc7
TG
18024static const char *
18025get_ia64_vms_note_type (unsigned e_type)
18026{
18027 static char buff[64];
18028
18029 switch (e_type)
18030 {
18031 case NT_VMS_MHD:
18032 return _("NT_VMS_MHD (module header)");
18033 case NT_VMS_LNM:
18034 return _("NT_VMS_LNM (language name)");
18035 case NT_VMS_SRC:
18036 return _("NT_VMS_SRC (source files)");
18037 case NT_VMS_TITLE:
9cf03b7e 18038 return "NT_VMS_TITLE";
00e98fc7
TG
18039 case NT_VMS_EIDC:
18040 return _("NT_VMS_EIDC (consistency check)");
18041 case NT_VMS_FPMODE:
18042 return _("NT_VMS_FPMODE (FP mode)");
18043 case NT_VMS_LINKTIME:
9cf03b7e 18044 return "NT_VMS_LINKTIME";
00e98fc7
TG
18045 case NT_VMS_IMGNAM:
18046 return _("NT_VMS_IMGNAM (image name)");
18047 case NT_VMS_IMGID:
18048 return _("NT_VMS_IMGID (image id)");
18049 case NT_VMS_LINKID:
18050 return _("NT_VMS_LINKID (link id)");
18051 case NT_VMS_IMGBID:
18052 return _("NT_VMS_IMGBID (build id)");
18053 case NT_VMS_GSTNAM:
18054 return _("NT_VMS_GSTNAM (sym table name)");
18055 case NT_VMS_ORIG_DYN:
9cf03b7e 18056 return "NT_VMS_ORIG_DYN";
00e98fc7 18057 case NT_VMS_PATCHTIME:
9cf03b7e 18058 return "NT_VMS_PATCHTIME";
00e98fc7
TG
18059 default:
18060 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18061 return buff;
18062 }
18063}
18064
32ec8896 18065static bfd_boolean
00e98fc7
TG
18066print_ia64_vms_note (Elf_Internal_Note * pnote)
18067{
8d18bf79
NC
18068 int maxlen = pnote->descsz;
18069
18070 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
18071 goto desc_size_fail;
18072
00e98fc7
TG
18073 switch (pnote->type)
18074 {
18075 case NT_VMS_MHD:
8d18bf79
NC
18076 if (maxlen <= 36)
18077 goto desc_size_fail;
18078
18079 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
18080
18081 printf (_(" Creation date : %.17s\n"), pnote->descdata);
18082 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
18083 if (l + 34 < maxlen)
18084 {
18085 printf (_(" Module name : %s\n"), pnote->descdata + 34);
18086 if (l + 35 < maxlen)
18087 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
18088 else
18089 printf (_(" Module version : <missing>\n"));
18090 }
00e98fc7 18091 else
8d18bf79
NC
18092 {
18093 printf (_(" Module name : <missing>\n"));
18094 printf (_(" Module version : <missing>\n"));
18095 }
00e98fc7 18096 break;
8d18bf79 18097
00e98fc7 18098 case NT_VMS_LNM:
8d18bf79 18099 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18100 break;
8d18bf79 18101
00e98fc7
TG
18102#ifdef BFD64
18103 case NT_VMS_FPMODE:
9cf03b7e 18104 printf (_(" Floating Point mode: "));
8d18bf79
NC
18105 if (maxlen < 8)
18106 goto desc_size_fail;
18107 /* FIXME: Generate an error if descsz > 8 ? */
18108
4a5cb34f 18109 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 18110 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 18111 break;
8d18bf79 18112
00e98fc7
TG
18113 case NT_VMS_LINKTIME:
18114 printf (_(" Link time: "));
8d18bf79
NC
18115 if (maxlen < 8)
18116 goto desc_size_fail;
18117 /* FIXME: Generate an error if descsz > 8 ? */
18118
00e98fc7 18119 print_vms_time
8d18bf79 18120 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
18121 printf ("\n");
18122 break;
8d18bf79 18123
00e98fc7
TG
18124 case NT_VMS_PATCHTIME:
18125 printf (_(" Patch time: "));
8d18bf79
NC
18126 if (maxlen < 8)
18127 goto desc_size_fail;
18128 /* FIXME: Generate an error if descsz > 8 ? */
18129
00e98fc7 18130 print_vms_time
8d18bf79 18131 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
18132 printf ("\n");
18133 break;
8d18bf79 18134
00e98fc7 18135 case NT_VMS_ORIG_DYN:
8d18bf79
NC
18136 if (maxlen < 34)
18137 goto desc_size_fail;
18138
00e98fc7
TG
18139 printf (_(" Major id: %u, minor id: %u\n"),
18140 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
18141 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 18142 printf (_(" Last modified : "));
00e98fc7
TG
18143 print_vms_time
18144 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 18145 printf (_("\n Link flags : "));
4a5cb34f 18146 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 18147 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 18148 printf (_(" Header flags: 0x%08x\n"),
948f632f 18149 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 18150 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
18151 break;
18152#endif
8d18bf79 18153
00e98fc7 18154 case NT_VMS_IMGNAM:
8d18bf79 18155 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18156 break;
8d18bf79 18157
00e98fc7 18158 case NT_VMS_GSTNAM:
8d18bf79 18159 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18160 break;
8d18bf79 18161
00e98fc7 18162 case NT_VMS_IMGID:
8d18bf79 18163 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18164 break;
8d18bf79 18165
00e98fc7 18166 case NT_VMS_LINKID:
8d18bf79 18167 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18168 break;
8d18bf79 18169
00e98fc7 18170 default:
32ec8896 18171 return FALSE;
00e98fc7 18172 }
8d18bf79 18173
32ec8896 18174 return TRUE;
8d18bf79
NC
18175
18176 desc_size_fail:
18177 printf (_(" <corrupt - data size is too small>\n"));
18178 error (_("corrupt IA64 note: data size is too small\n"));
18179 return FALSE;
00e98fc7
TG
18180}
18181
6f156d7a
NC
18182/* Find the symbol associated with a build attribute that is attached
18183 to address OFFSET. If PNAME is non-NULL then store the name of
18184 the symbol (if found) in the provided pointer, Returns NULL if a
18185 symbol could not be found. */
c799a79d 18186
6f156d7a
NC
18187static Elf_Internal_Sym *
18188get_symbol_for_build_attribute (Filedata * filedata,
18189 unsigned long offset,
18190 bfd_boolean is_open_attr,
18191 const char ** pname)
9ef920e9 18192{
dda8d76d 18193 static Filedata * saved_filedata = NULL;
c799a79d
NC
18194 static char * strtab;
18195 static unsigned long strtablen;
18196 static Elf_Internal_Sym * symtab;
18197 static unsigned long nsyms;
7296a62a
NC
18198 Elf_Internal_Sym * saved_sym = NULL;
18199 Elf_Internal_Sym * sym;
9ef920e9 18200
dda8d76d
NC
18201 if (filedata->section_headers != NULL
18202 && (saved_filedata == NULL || filedata != saved_filedata))
9ef920e9 18203 {
c799a79d 18204 Elf_Internal_Shdr * symsec;
9ef920e9 18205
c799a79d 18206 /* Load the symbol and string sections. */
dda8d76d
NC
18207 for (symsec = filedata->section_headers;
18208 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 18209 symsec ++)
9ef920e9 18210 {
c799a79d 18211 if (symsec->sh_type == SHT_SYMTAB)
9ef920e9 18212 {
dda8d76d 18213 symtab = GET_ELF_SYMBOLS (filedata, symsec, & nsyms);
9ef920e9 18214
dda8d76d 18215 if (symsec->sh_link < filedata->file_header.e_shnum)
c799a79d 18216 {
dda8d76d 18217 Elf_Internal_Shdr * strtab_sec = filedata->section_headers + symsec->sh_link;
c799a79d 18218
dda8d76d 18219 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
c799a79d
NC
18220 1, strtab_sec->sh_size,
18221 _("string table"));
18222 strtablen = strtab != NULL ? strtab_sec->sh_size : 0;
18223 }
9ef920e9
NC
18224 }
18225 }
dda8d76d 18226 saved_filedata = filedata;
9ef920e9
NC
18227 }
18228
c799a79d 18229 if (symtab == NULL || strtab == NULL)
6f156d7a 18230 return NULL;
9ef920e9 18231
c799a79d
NC
18232 /* Find a symbol whose value matches offset. */
18233 for (sym = symtab; sym < symtab + nsyms; sym ++)
18234 if (sym->st_value == offset)
18235 {
18236 if (sym->st_name >= strtablen)
18237 /* Huh ? This should not happen. */
18238 continue;
9ef920e9 18239
c799a79d
NC
18240 if (strtab[sym->st_name] == 0)
18241 continue;
9ef920e9 18242
8fd75781
NC
18243 /* The AArch64 and ARM architectures define mapping symbols
18244 (eg $d, $x, $t) which we want to ignore. */
18245 if (strtab[sym->st_name] == '$'
18246 && strtab[sym->st_name + 1] != 0
18247 && strtab[sym->st_name + 2] == 0)
18248 continue;
18249
c799a79d
NC
18250 if (is_open_attr)
18251 {
18252 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
18253 and FILE or OBJECT symbols over NOTYPE symbols. We skip
18254 FUNC symbols entirely. */
18255 switch (ELF_ST_TYPE (sym->st_info))
18256 {
c799a79d 18257 case STT_OBJECT:
6f156d7a 18258 case STT_FILE:
c799a79d 18259 saved_sym = sym;
6f156d7a
NC
18260 if (sym->st_size)
18261 {
18262 /* If the symbol has a size associated
18263 with it then we can stop searching. */
18264 sym = symtab + nsyms;
18265 }
c799a79d 18266 continue;
9ef920e9 18267
c799a79d
NC
18268 case STT_FUNC:
18269 /* Ignore function symbols. */
18270 continue;
18271
18272 default:
18273 break;
18274 }
18275
18276 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 18277 {
c799a79d
NC
18278 case STB_GLOBAL:
18279 if (saved_sym == NULL
18280 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
18281 saved_sym = sym;
18282 break;
c871dade 18283
c799a79d
NC
18284 case STB_LOCAL:
18285 if (saved_sym == NULL)
18286 saved_sym = sym;
18287 break;
18288
18289 default:
9ef920e9
NC
18290 break;
18291 }
18292 }
c799a79d
NC
18293 else
18294 {
18295 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
18296 continue;
18297
18298 saved_sym = sym;
18299 break;
18300 }
18301 }
18302
6f156d7a
NC
18303 if (saved_sym && pname)
18304 * pname = strtab + saved_sym->st_name;
18305
18306 return saved_sym;
c799a79d
NC
18307}
18308
d20e98ab
NC
18309/* Returns true iff addr1 and addr2 are in the same section. */
18310
18311static bfd_boolean
18312same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
18313{
18314 Elf_Internal_Shdr * a1;
18315 Elf_Internal_Shdr * a2;
18316
18317 a1 = find_section_by_address (filedata, addr1);
18318 a2 = find_section_by_address (filedata, addr2);
18319
18320 return a1 == a2 && a1 != NULL;
18321}
18322
c799a79d 18323static bfd_boolean
dda8d76d
NC
18324print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
18325 Filedata * filedata)
c799a79d 18326{
6f156d7a
NC
18327 static unsigned long global_offset = 0;
18328 static unsigned long global_end = 0;
18329 static unsigned long func_offset = 0;
18330 static unsigned long func_end = 0;
c871dade 18331
6f156d7a
NC
18332 Elf_Internal_Sym * sym;
18333 const char * name;
18334 unsigned long start;
18335 unsigned long end;
18336 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
18337
18338 switch (pnote->descsz)
c799a79d 18339 {
6f156d7a
NC
18340 case 0:
18341 /* A zero-length description means that the range of
18342 the previous note of the same type should be used. */
c799a79d 18343 if (is_open_attr)
c871dade 18344 {
6f156d7a
NC
18345 if (global_end > global_offset)
18346 printf (_(" Applies to region from %#lx to %#lx\n"),
18347 global_offset, global_end);
18348 else
18349 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
18350 }
18351 else
18352 {
6f156d7a
NC
18353 if (func_end > func_offset)
18354 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
18355 else
18356 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 18357 }
6f156d7a 18358 return TRUE;
9ef920e9 18359
6f156d7a
NC
18360 case 4:
18361 start = byte_get ((unsigned char *) pnote->descdata, 4);
18362 end = 0;
18363 break;
18364
18365 case 8:
18366 if (is_32bit_elf)
18367 {
18368 /* FIXME: We should check that version 3+ notes are being used here... */
18369 start = byte_get ((unsigned char *) pnote->descdata, 4);
18370 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18371 }
18372 else
18373 {
18374 start = byte_get ((unsigned char *) pnote->descdata, 8);
18375 end = 0;
18376 }
18377 break;
18378
18379 case 16:
18380 start = byte_get ((unsigned char *) pnote->descdata, 8);
18381 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
18382 break;
18383
18384 default:
c799a79d
NC
18385 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
18386 printf (_(" <invalid descsz>"));
18387 return FALSE;
18388 }
18389
6f156d7a
NC
18390 name = NULL;
18391 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
18392 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
18393 in order to avoid them being confused with the start address of the
18394 first function in the file... */
18395 if (sym == NULL && is_open_attr)
18396 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
18397 & name);
6f156d7a
NC
18398
18399 if (end == 0 && sym != NULL && sym->st_size > 0)
18400 end = start + sym->st_size;
c799a79d
NC
18401
18402 if (is_open_attr)
18403 {
d20e98ab
NC
18404 /* FIXME: Need to properly allow for section alignment.
18405 16 is just the alignment used on x86_64. */
18406 if (global_end > 0
18407 && start > BFD_ALIGN (global_end, 16)
18408 /* Build notes are not guaranteed to be organised in order of
18409 increasing address, but we should find the all of the notes
18410 for one section in the same place. */
18411 && same_section (filedata, start, global_end))
6f156d7a
NC
18412 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
18413 global_end + 1, start - 1);
18414
18415 printf (_(" Applies to region from %#lx"), start);
18416 global_offset = start;
18417
18418 if (end)
18419 {
18420 printf (_(" to %#lx"), end);
18421 global_end = end;
18422 }
c799a79d
NC
18423 }
18424 else
18425 {
6f156d7a
NC
18426 printf (_(" Applies to region from %#lx"), start);
18427 func_offset = start;
18428
18429 if (end)
18430 {
18431 printf (_(" to %#lx"), end);
18432 func_end = end;
18433 }
c799a79d
NC
18434 }
18435
6f156d7a
NC
18436 if (sym && name)
18437 printf (_(" (%s)"), name);
18438
18439 printf ("\n");
18440 return TRUE;
9ef920e9
NC
18441}
18442
18443static bfd_boolean
18444print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
18445{
1d15e434
NC
18446 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
18447 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
18448 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
18449 char name_type;
18450 char name_attribute;
1d15e434 18451 const char * expected_types;
9ef920e9
NC
18452 const char * name = pnote->namedata;
18453 const char * text;
88305e1b 18454 signed int left;
9ef920e9
NC
18455
18456 if (name == NULL || pnote->namesz < 2)
18457 {
18458 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 18459 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
18460 return FALSE;
18461 }
18462
6f156d7a
NC
18463 if (do_wide)
18464 left = 28;
18465 else
18466 left = 20;
88305e1b
NC
18467
18468 /* Version 2 of the spec adds a "GA" prefix to the name field. */
18469 if (name[0] == 'G' && name[1] == 'A')
18470 {
6f156d7a
NC
18471 if (pnote->namesz < 4)
18472 {
18473 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
18474 print_symbol (-20, _(" <corrupt name>"));
18475 return FALSE;
18476 }
18477
88305e1b
NC
18478 printf ("GA");
18479 name += 2;
18480 left -= 2;
18481 }
18482
9ef920e9
NC
18483 switch ((name_type = * name))
18484 {
18485 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
18486 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
18487 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
18488 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
18489 printf ("%c", * name);
88305e1b 18490 left --;
9ef920e9
NC
18491 break;
18492 default:
18493 error (_("unrecognised attribute type in name field: %d\n"), name_type);
18494 print_symbol (-20, _("<unknown name type>"));
18495 return FALSE;
18496 }
18497
9ef920e9
NC
18498 ++ name;
18499 text = NULL;
18500
18501 switch ((name_attribute = * name))
18502 {
18503 case GNU_BUILD_ATTRIBUTE_VERSION:
18504 text = _("<version>");
1d15e434 18505 expected_types = string_expected;
9ef920e9
NC
18506 ++ name;
18507 break;
18508 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
18509 text = _("<stack prot>");
75d7d298 18510 expected_types = "!+*";
9ef920e9
NC
18511 ++ name;
18512 break;
18513 case GNU_BUILD_ATTRIBUTE_RELRO:
18514 text = _("<relro>");
1d15e434 18515 expected_types = bool_expected;
9ef920e9
NC
18516 ++ name;
18517 break;
18518 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
18519 text = _("<stack size>");
1d15e434 18520 expected_types = number_expected;
9ef920e9
NC
18521 ++ name;
18522 break;
18523 case GNU_BUILD_ATTRIBUTE_TOOL:
18524 text = _("<tool>");
1d15e434 18525 expected_types = string_expected;
9ef920e9
NC
18526 ++ name;
18527 break;
18528 case GNU_BUILD_ATTRIBUTE_ABI:
18529 text = _("<ABI>");
18530 expected_types = "$*";
18531 ++ name;
18532 break;
18533 case GNU_BUILD_ATTRIBUTE_PIC:
18534 text = _("<PIC>");
1d15e434 18535 expected_types = number_expected;
9ef920e9
NC
18536 ++ name;
18537 break;
a8be5506
NC
18538 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
18539 text = _("<short enum>");
1d15e434 18540 expected_types = bool_expected;
a8be5506
NC
18541 ++ name;
18542 break;
9ef920e9
NC
18543 default:
18544 if (ISPRINT (* name))
18545 {
18546 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
18547
18548 if (len > left && ! do_wide)
18549 len = left;
75d7d298 18550 printf ("%.*s:", len, name);
9ef920e9 18551 left -= len;
0dd6ae21 18552 name += len;
9ef920e9
NC
18553 }
18554 else
18555 {
3e6b6445 18556 static char tmpbuf [128];
88305e1b 18557
3e6b6445
NC
18558 error (_("unrecognised byte in name field: %d\n"), * name);
18559 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
18560 text = tmpbuf;
18561 name ++;
9ef920e9
NC
18562 }
18563 expected_types = "*$!+";
18564 break;
18565 }
18566
18567 if (text)
88305e1b 18568 left -= printf ("%s", text);
9ef920e9
NC
18569
18570 if (strchr (expected_types, name_type) == NULL)
75d7d298 18571 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
18572
18573 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
18574 {
18575 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
18576 (unsigned long) pnote->namesz,
18577 (long) (name - pnote->namedata));
18578 return FALSE;
18579 }
18580
18581 if (left < 1 && ! do_wide)
18582 return TRUE;
18583
18584 switch (name_type)
18585 {
18586 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
18587 {
b06b2c92 18588 unsigned int bytes;
ddef72cd
NC
18589 unsigned long long val = 0;
18590 unsigned int shift = 0;
18591 char * decoded = NULL;
18592
b06b2c92
NC
18593 bytes = pnote->namesz - (name - pnote->namedata);
18594 if (bytes > 0)
18595 /* The -1 is because the name field is always 0 terminated, and we
18596 want to be able to ensure that the shift in the while loop below
18597 will not overflow. */
18598 -- bytes;
18599
ddef72cd
NC
18600 if (bytes > sizeof (val))
18601 {
3e6b6445
NC
18602 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
18603 bytes);
18604 bytes = sizeof (val);
ddef72cd 18605 }
3e6b6445
NC
18606 /* We do not bother to warn if bytes == 0 as this can
18607 happen with some early versions of the gcc plugin. */
9ef920e9
NC
18608
18609 while (bytes --)
18610 {
79a964dc
NC
18611 unsigned long byte = (* name ++) & 0xff;
18612
18613 val |= byte << shift;
9ef920e9
NC
18614 shift += 8;
18615 }
18616
75d7d298 18617 switch (name_attribute)
9ef920e9 18618 {
75d7d298 18619 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
18620 switch (val)
18621 {
75d7d298
NC
18622 case 0: decoded = "static"; break;
18623 case 1: decoded = "pic"; break;
18624 case 2: decoded = "PIC"; break;
18625 case 3: decoded = "pie"; break;
18626 case 4: decoded = "PIE"; break;
18627 default: break;
9ef920e9 18628 }
75d7d298
NC
18629 break;
18630 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
18631 switch (val)
9ef920e9 18632 {
75d7d298
NC
18633 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
18634 case 0: decoded = "off"; break;
18635 case 1: decoded = "on"; break;
18636 case 2: decoded = "all"; break;
18637 case 3: decoded = "strong"; break;
18638 case 4: decoded = "explicit"; break;
18639 default: break;
9ef920e9 18640 }
75d7d298
NC
18641 break;
18642 default:
18643 break;
9ef920e9
NC
18644 }
18645
75d7d298 18646 if (decoded != NULL)
3e6b6445
NC
18647 {
18648 print_symbol (-left, decoded);
18649 left = 0;
18650 }
18651 else if (val == 0)
18652 {
18653 printf ("0x0");
18654 left -= 3;
18655 }
9ef920e9 18656 else
75d7d298
NC
18657 {
18658 if (do_wide)
ddef72cd 18659 left -= printf ("0x%llx", val);
75d7d298 18660 else
ddef72cd 18661 left -= printf ("0x%-.*llx", left, val);
75d7d298 18662 }
9ef920e9
NC
18663 }
18664 break;
18665 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
18666 left -= print_symbol (- left, name);
18667 break;
18668 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
18669 left -= print_symbol (- left, "true");
18670 break;
18671 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
18672 left -= print_symbol (- left, "false");
18673 break;
18674 }
18675
18676 if (do_wide && left > 0)
18677 printf ("%-*s", left, " ");
18678
18679 return TRUE;
18680}
18681
6d118b09
NC
18682/* Note that by the ELF standard, the name field is already null byte
18683 terminated, and namesz includes the terminating null byte.
18684 I.E. the value of namesz for the name "FSF" is 4.
18685
e3c8793a 18686 If the value of namesz is zero, there is no name present. */
9ef920e9 18687
32ec8896 18688static bfd_boolean
9ef920e9 18689process_note (Elf_Internal_Note * pnote,
dda8d76d 18690 Filedata * filedata)
779fe533 18691{
2cf0635d
NC
18692 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
18693 const char * nt;
9437c45b
JT
18694
18695 if (pnote->namesz == 0)
1ec5cd37
NC
18696 /* If there is no note name, then use the default set of
18697 note type strings. */
dda8d76d 18698 nt = get_note_type (filedata, pnote->type);
1ec5cd37 18699
1118d252
RM
18700 else if (const_strneq (pnote->namedata, "GNU"))
18701 /* GNU-specific object file notes. */
18702 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
18703
18704 else if (const_strneq (pnote->namedata, "FreeBSD"))
18705 /* FreeBSD-specific core file notes. */
dda8d76d 18706 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 18707
0112cd26 18708 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 18709 /* NetBSD-specific core file notes. */
dda8d76d 18710 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 18711
c6056a74
SF
18712 else if (const_strneq (pnote->namedata, "NetBSD"))
18713 /* NetBSD-specific core file notes. */
18714 return process_netbsd_elf_note (pnote);
18715
b15fa79e
AM
18716 else if (strneq (pnote->namedata, "SPU/", 4))
18717 {
18718 /* SPU-specific core file notes. */
18719 nt = pnote->namedata + 4;
18720 name = "SPU";
18721 }
18722
00e98fc7
TG
18723 else if (const_strneq (pnote->namedata, "IPF/VMS"))
18724 /* VMS/ia64-specific file notes. */
18725 nt = get_ia64_vms_note_type (pnote->type);
18726
70616151
TT
18727 else if (const_strneq (pnote->namedata, "stapsdt"))
18728 nt = get_stapsdt_note_type (pnote->type);
18729
9437c45b 18730 else
1ec5cd37
NC
18731 /* Don't recognize this note name; just use the default set of
18732 note type strings. */
dda8d76d 18733 nt = get_note_type (filedata, pnote->type);
9437c45b 18734
1449284b 18735 printf (" ");
9ef920e9 18736
483767a3
AM
18737 if (((const_strneq (pnote->namedata, "GA")
18738 && strchr ("*$!+", pnote->namedata[2]) != NULL)
18739 || strchr ("*$!+", pnote->namedata[0]) != NULL)
18740 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
18741 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
18742 print_gnu_build_attribute_name (pnote);
18743 else
18744 print_symbol (-20, name);
18745
18746 if (do_wide)
18747 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
18748 else
18749 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
18750
18751 if (const_strneq (pnote->namedata, "IPF/VMS"))
18752 return print_ia64_vms_note (pnote);
664f90a3 18753 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 18754 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
18755 else if (const_strneq (pnote->namedata, "stapsdt"))
18756 return print_stapsdt_note (pnote);
9ece1fa9
TT
18757 else if (const_strneq (pnote->namedata, "CORE"))
18758 return print_core_note (pnote);
483767a3
AM
18759 else if (((const_strneq (pnote->namedata, "GA")
18760 && strchr ("*$!+", pnote->namedata[2]) != NULL)
18761 || strchr ("*$!+", pnote->namedata[0]) != NULL)
18762 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
18763 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 18764 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 18765
9ef920e9 18766 if (pnote->descsz)
1449284b
NC
18767 {
18768 unsigned long i;
18769
18770 printf (_(" description data: "));
18771 for (i = 0; i < pnote->descsz; i++)
18772 printf ("%02x ", pnote->descdata[i]);
04ac15ab
AS
18773 if (!do_wide)
18774 printf ("\n");
1449284b
NC
18775 }
18776
9ef920e9
NC
18777 if (do_wide)
18778 printf ("\n");
18779
32ec8896 18780 return TRUE;
1449284b 18781}
6d118b09 18782
32ec8896 18783static bfd_boolean
dda8d76d
NC
18784process_notes_at (Filedata * filedata,
18785 Elf_Internal_Shdr * section,
18786 bfd_vma offset,
82ed9683
L
18787 bfd_vma length,
18788 bfd_vma align)
779fe533 18789{
2cf0635d
NC
18790 Elf_External_Note * pnotes;
18791 Elf_External_Note * external;
4dff97b2
NC
18792 char * end;
18793 bfd_boolean res = TRUE;
103f02d3 18794
779fe533 18795 if (length <= 0)
32ec8896 18796 return FALSE;
103f02d3 18797
1449284b
NC
18798 if (section)
18799 {
dda8d76d 18800 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 18801 if (pnotes)
32ec8896 18802 {
dda8d76d 18803 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
32ec8896
NC
18804 return FALSE;
18805 }
1449284b
NC
18806 }
18807 else
82ed9683 18808 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 18809 _("notes"));
4dff97b2 18810
dd24e3da 18811 if (pnotes == NULL)
32ec8896 18812 return FALSE;
779fe533 18813
103f02d3 18814 external = pnotes;
103f02d3 18815
1449284b 18816 if (section)
dda8d76d 18817 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
18818 else
18819 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
18820 (unsigned long) offset, (unsigned long) length);
18821
82ed9683
L
18822 /* NB: Some note sections may have alignment value of 0 or 1. gABI
18823 specifies that notes should be aligned to 4 bytes in 32-bit
18824 objects and to 8 bytes in 64-bit objects. As a Linux extension,
18825 we also support 4 byte alignment in 64-bit objects. If section
18826 alignment is less than 4, we treate alignment as 4 bytes. */
18827 if (align < 4)
18828 align = 4;
18829 else if (align != 4 && align != 8)
18830 {
18831 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
18832 (long) align);
18833 return FALSE;
18834 }
18835
2aee03ae 18836 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 18837
c8071705
NC
18838 end = (char *) pnotes + length;
18839 while ((char *) external < end)
779fe533 18840 {
b34976b6 18841 Elf_Internal_Note inote;
15b42fb0 18842 size_t min_notesz;
4dff97b2 18843 char * next;
2cf0635d 18844 char * temp = NULL;
c8071705 18845 size_t data_remaining = end - (char *) external;
6d118b09 18846
dda8d76d 18847 if (!is_ia64_vms (filedata))
15b42fb0 18848 {
9dd3a467
NC
18849 /* PR binutils/15191
18850 Make sure that there is enough data to read. */
15b42fb0
AM
18851 min_notesz = offsetof (Elf_External_Note, name);
18852 if (data_remaining < min_notesz)
9dd3a467 18853 {
d3a49aa8
AM
18854 warn (ngettext ("Corrupt note: only %ld byte remains, "
18855 "not enough for a full note\n",
18856 "Corrupt note: only %ld bytes remain, "
18857 "not enough for a full note\n",
18858 data_remaining),
18859 (long) data_remaining);
9dd3a467
NC
18860 break;
18861 }
5396a86e
AM
18862 data_remaining -= min_notesz;
18863
15b42fb0
AM
18864 inote.type = BYTE_GET (external->type);
18865 inote.namesz = BYTE_GET (external->namesz);
18866 inote.namedata = external->name;
18867 inote.descsz = BYTE_GET (external->descsz);
276da9b3 18868 inote.descdata = ((char *) external
4dff97b2 18869 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 18870 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 18871 next = ((char *) external
4dff97b2 18872 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 18873 }
00e98fc7 18874 else
15b42fb0
AM
18875 {
18876 Elf64_External_VMS_Note *vms_external;
00e98fc7 18877
9dd3a467
NC
18878 /* PR binutils/15191
18879 Make sure that there is enough data to read. */
15b42fb0
AM
18880 min_notesz = offsetof (Elf64_External_VMS_Note, name);
18881 if (data_remaining < min_notesz)
9dd3a467 18882 {
d3a49aa8
AM
18883 warn (ngettext ("Corrupt note: only %ld byte remains, "
18884 "not enough for a full note\n",
18885 "Corrupt note: only %ld bytes remain, "
18886 "not enough for a full note\n",
18887 data_remaining),
18888 (long) data_remaining);
9dd3a467
NC
18889 break;
18890 }
5396a86e 18891 data_remaining -= min_notesz;
3e55a963 18892
15b42fb0
AM
18893 vms_external = (Elf64_External_VMS_Note *) external;
18894 inote.type = BYTE_GET (vms_external->type);
18895 inote.namesz = BYTE_GET (vms_external->namesz);
18896 inote.namedata = vms_external->name;
18897 inote.descsz = BYTE_GET (vms_external->descsz);
18898 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
18899 inote.descpos = offset + (inote.descdata - (char *) pnotes);
18900 next = inote.descdata + align_power (inote.descsz, 3);
18901 }
18902
5396a86e
AM
18903 /* PR 17531: file: 3443835e. */
18904 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
18905 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
18906 || (size_t) (inote.descdata - inote.namedata) > data_remaining
18907 || (size_t) (next - inote.descdata) < inote.descsz
18908 || ((size_t) (next - inote.descdata)
18909 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 18910 {
15b42fb0 18911 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 18912 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
18913 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
18914 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
18915 break;
18916 }
18917
15b42fb0 18918 external = (Elf_External_Note *) next;
dd24e3da 18919
6d118b09
NC
18920 /* Verify that name is null terminated. It appears that at least
18921 one version of Linux (RedHat 6.0) generates corefiles that don't
18922 comply with the ELF spec by failing to include the null byte in
18923 namesz. */
18344509 18924 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 18925 {
5396a86e 18926 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 18927 {
5396a86e
AM
18928 temp = (char *) malloc (inote.namesz + 1);
18929 if (temp == NULL)
18930 {
18931 error (_("Out of memory allocating space for inote name\n"));
18932 res = FALSE;
18933 break;
18934 }
76da6bbe 18935
5396a86e
AM
18936 memcpy (temp, inote.namedata, inote.namesz);
18937 inote.namedata = temp;
18938 }
18939 inote.namedata[inote.namesz] = 0;
6d118b09
NC
18940 }
18941
dda8d76d 18942 if (! process_note (& inote, filedata))
6b4bf3bc 18943 res = FALSE;
103f02d3 18944
6d118b09
NC
18945 if (temp != NULL)
18946 {
18947 free (temp);
18948 temp = NULL;
18949 }
779fe533
NC
18950 }
18951
18952 free (pnotes);
103f02d3 18953
779fe533
NC
18954 return res;
18955}
18956
32ec8896 18957static bfd_boolean
dda8d76d 18958process_corefile_note_segments (Filedata * filedata)
779fe533 18959{
2cf0635d 18960 Elf_Internal_Phdr * segment;
b34976b6 18961 unsigned int i;
32ec8896 18962 bfd_boolean res = TRUE;
103f02d3 18963
dda8d76d 18964 if (! get_program_headers (filedata))
6b4bf3bc 18965 return TRUE;
103f02d3 18966
dda8d76d
NC
18967 for (i = 0, segment = filedata->program_headers;
18968 i < filedata->file_header.e_phnum;
b34976b6 18969 i++, segment++)
779fe533
NC
18970 {
18971 if (segment->p_type == PT_NOTE)
dda8d76d 18972 if (! process_notes_at (filedata, NULL,
32ec8896 18973 (bfd_vma) segment->p_offset,
82ed9683
L
18974 (bfd_vma) segment->p_filesz,
18975 (bfd_vma) segment->p_align))
32ec8896 18976 res = FALSE;
779fe533 18977 }
103f02d3 18978
779fe533
NC
18979 return res;
18980}
18981
32ec8896 18982static bfd_boolean
dda8d76d 18983process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
18984{
18985 Elf_External_Note * pnotes;
18986 Elf_External_Note * external;
c8071705 18987 char * end;
32ec8896 18988 bfd_boolean res = TRUE;
685080f2
NC
18989
18990 if (length <= 0)
32ec8896 18991 return FALSE;
685080f2 18992
dda8d76d 18993 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
18994 _("v850 notes"));
18995 if (pnotes == NULL)
32ec8896 18996 return FALSE;
685080f2
NC
18997
18998 external = pnotes;
c8071705 18999 end = (char*) pnotes + length;
685080f2
NC
19000
19001 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
19002 (unsigned long) offset, (unsigned long) length);
19003
c8071705 19004 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
19005 {
19006 Elf_External_Note * next;
19007 Elf_Internal_Note inote;
19008
19009 inote.type = BYTE_GET (external->type);
19010 inote.namesz = BYTE_GET (external->namesz);
19011 inote.namedata = external->name;
19012 inote.descsz = BYTE_GET (external->descsz);
19013 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
19014 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19015
c8071705
NC
19016 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
19017 {
19018 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
19019 inote.descdata = inote.namedata;
19020 inote.namesz = 0;
19021 }
19022
685080f2
NC
19023 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
19024
c8071705 19025 if ( ((char *) next > end)
685080f2
NC
19026 || ((char *) next < (char *) pnotes))
19027 {
19028 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
19029 (unsigned long) ((char *) external - (char *) pnotes));
19030 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19031 inote.type, inote.namesz, inote.descsz);
19032 break;
19033 }
19034
19035 external = next;
19036
19037 /* Prevent out-of-bounds indexing. */
c8071705 19038 if ( inote.namedata + inote.namesz > end
685080f2
NC
19039 || inote.namedata + inote.namesz < inote.namedata)
19040 {
19041 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
19042 (unsigned long) ((char *) external - (char *) pnotes));
19043 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19044 inote.type, inote.namesz, inote.descsz);
19045 break;
19046 }
19047
19048 printf (" %s: ", get_v850_elf_note_type (inote.type));
19049
19050 if (! print_v850_note (& inote))
19051 {
32ec8896 19052 res = FALSE;
685080f2
NC
19053 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
19054 inote.namesz, inote.descsz);
19055 }
19056 }
19057
19058 free (pnotes);
19059
19060 return res;
19061}
19062
32ec8896 19063static bfd_boolean
dda8d76d 19064process_note_sections (Filedata * filedata)
1ec5cd37 19065{
2cf0635d 19066 Elf_Internal_Shdr * section;
1ec5cd37 19067 unsigned long i;
32ec8896
NC
19068 unsigned int n = 0;
19069 bfd_boolean res = TRUE;
1ec5cd37 19070
dda8d76d
NC
19071 for (i = 0, section = filedata->section_headers;
19072 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 19073 i++, section++)
685080f2
NC
19074 {
19075 if (section->sh_type == SHT_NOTE)
19076 {
dda8d76d 19077 if (! process_notes_at (filedata, section,
32ec8896 19078 (bfd_vma) section->sh_offset,
82ed9683
L
19079 (bfd_vma) section->sh_size,
19080 (bfd_vma) section->sh_addralign))
32ec8896 19081 res = FALSE;
685080f2
NC
19082 n++;
19083 }
19084
dda8d76d
NC
19085 if (( filedata->file_header.e_machine == EM_V800
19086 || filedata->file_header.e_machine == EM_V850
19087 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
19088 && section->sh_type == SHT_RENESAS_INFO)
19089 {
dda8d76d 19090 if (! process_v850_notes (filedata,
32ec8896
NC
19091 (bfd_vma) section->sh_offset,
19092 (bfd_vma) section->sh_size))
19093 res = FALSE;
685080f2
NC
19094 n++;
19095 }
19096 }
df565f32
NC
19097
19098 if (n == 0)
19099 /* Try processing NOTE segments instead. */
dda8d76d 19100 return process_corefile_note_segments (filedata);
1ec5cd37
NC
19101
19102 return res;
19103}
19104
32ec8896 19105static bfd_boolean
dda8d76d 19106process_notes (Filedata * filedata)
779fe533
NC
19107{
19108 /* If we have not been asked to display the notes then do nothing. */
19109 if (! do_notes)
32ec8896 19110 return TRUE;
103f02d3 19111
dda8d76d
NC
19112 if (filedata->file_header.e_type != ET_CORE)
19113 return process_note_sections (filedata);
103f02d3 19114
779fe533 19115 /* No program headers means no NOTE segment. */
dda8d76d
NC
19116 if (filedata->file_header.e_phnum > 0)
19117 return process_corefile_note_segments (filedata);
779fe533 19118
1ec5cd37 19119 printf (_("No note segments present in the core file.\n"));
32ec8896 19120 return TRUE;
779fe533
NC
19121}
19122
60abdbed
NC
19123static unsigned char *
19124display_public_gnu_attributes (unsigned char * start,
19125 const unsigned char * const end)
19126{
19127 printf (_(" Unknown GNU attribute: %s\n"), start);
19128
19129 start += strnlen ((char *) start, end - start);
19130 display_raw_attribute (start, end);
19131
19132 return (unsigned char *) end;
19133}
19134
19135static unsigned char *
19136display_generic_attribute (unsigned char * start,
19137 unsigned int tag,
19138 const unsigned char * const end)
19139{
19140 if (tag == 0)
19141 return (unsigned char *) end;
19142
19143 return display_tag_value (tag, start, end);
19144}
19145
32ec8896 19146static bfd_boolean
dda8d76d 19147process_arch_specific (Filedata * filedata)
252b5132 19148{
a952a375 19149 if (! do_arch)
32ec8896 19150 return TRUE;
a952a375 19151
dda8d76d 19152 switch (filedata->file_header.e_machine)
252b5132 19153 {
53a346d8
CZ
19154 case EM_ARC:
19155 case EM_ARC_COMPACT:
19156 case EM_ARC_COMPACT2:
dda8d76d 19157 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
19158 display_arc_attribute,
19159 display_generic_attribute);
11c1ff18 19160 case EM_ARM:
dda8d76d 19161 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
19162 display_arm_attribute,
19163 display_generic_attribute);
19164
252b5132 19165 case EM_MIPS:
4fe85591 19166 case EM_MIPS_RS3_LE:
dda8d76d 19167 return process_mips_specific (filedata);
60abdbed
NC
19168
19169 case EM_MSP430:
dda8d76d
NC
19170 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
19171 display_msp430x_attribute,
19172 display_generic_attribute);
60abdbed 19173
2dc8dd17
JW
19174 case EM_RISCV:
19175 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
19176 display_riscv_attribute,
19177 display_generic_attribute);
19178
35c08157 19179 case EM_NDS32:
dda8d76d 19180 return process_nds32_specific (filedata);
60abdbed 19181
34c8bcba 19182 case EM_PPC:
b82317dd 19183 case EM_PPC64:
dda8d76d 19184 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
19185 display_power_gnu_attribute);
19186
643f7afb
AK
19187 case EM_S390:
19188 case EM_S390_OLD:
dda8d76d 19189 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
19190 display_s390_gnu_attribute);
19191
9e8c70f9
DM
19192 case EM_SPARC:
19193 case EM_SPARC32PLUS:
19194 case EM_SPARCV9:
dda8d76d 19195 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
19196 display_sparc_gnu_attribute);
19197
59e6276b 19198 case EM_TI_C6000:
dda8d76d 19199 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
19200 display_tic6x_attribute,
19201 display_generic_attribute);
19202
252b5132 19203 default:
dda8d76d 19204 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
19205 display_public_gnu_attributes,
19206 display_generic_attribute);
252b5132 19207 }
252b5132
RH
19208}
19209
32ec8896 19210static bfd_boolean
dda8d76d 19211get_file_header (Filedata * filedata)
252b5132 19212{
9ea033b2 19213 /* Read in the identity array. */
dda8d76d 19214 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 19215 return FALSE;
252b5132 19216
9ea033b2 19217 /* Determine how to read the rest of the header. */
dda8d76d 19218 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 19219 {
1a0670f3
AM
19220 default:
19221 case ELFDATANONE:
adab8cdc
AO
19222 case ELFDATA2LSB:
19223 byte_get = byte_get_little_endian;
19224 byte_put = byte_put_little_endian;
19225 break;
19226 case ELFDATA2MSB:
19227 byte_get = byte_get_big_endian;
19228 byte_put = byte_put_big_endian;
19229 break;
9ea033b2
NC
19230 }
19231
19232 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 19233 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
19234
19235 /* Read in the rest of the header. */
19236 if (is_32bit_elf)
19237 {
19238 Elf32_External_Ehdr ehdr32;
252b5132 19239
dda8d76d 19240 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 19241 return FALSE;
103f02d3 19242
dda8d76d
NC
19243 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
19244 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
19245 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
19246 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
19247 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
19248 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
19249 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
19250 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
19251 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
19252 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
19253 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
19254 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
19255 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 19256 }
252b5132 19257 else
9ea033b2
NC
19258 {
19259 Elf64_External_Ehdr ehdr64;
a952a375
NC
19260
19261 /* If we have been compiled with sizeof (bfd_vma) == 4, then
19262 we will not be able to cope with the 64bit data found in
19263 64 ELF files. Detect this now and abort before we start
50c2245b 19264 overwriting things. */
a952a375
NC
19265 if (sizeof (bfd_vma) < 8)
19266 {
e3c8793a
NC
19267 error (_("This instance of readelf has been built without support for a\n\
1926864 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 19269 return FALSE;
a952a375 19270 }
103f02d3 19271
dda8d76d 19272 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 19273 return FALSE;
103f02d3 19274
dda8d76d
NC
19275 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
19276 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
19277 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
19278 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
19279 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
19280 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
19281 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
19282 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
19283 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
19284 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
19285 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
19286 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
19287 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 19288 }
252b5132 19289
dda8d76d 19290 if (filedata->file_header.e_shoff)
7ece0d85
JJ
19291 {
19292 /* There may be some extensions in the first section header. Don't
19293 bomb if we can't read it. */
19294 if (is_32bit_elf)
dda8d76d 19295 get_32bit_section_headers (filedata, TRUE);
7ece0d85 19296 else
dda8d76d 19297 get_64bit_section_headers (filedata, TRUE);
7ece0d85 19298 }
560f3c1c 19299
32ec8896 19300 return TRUE;
252b5132
RH
19301}
19302
dda8d76d
NC
19303static void
19304close_file (Filedata * filedata)
19305{
19306 if (filedata)
19307 {
19308 if (filedata->handle)
19309 fclose (filedata->handle);
19310 free (filedata);
19311 }
19312}
19313
19314void
19315close_debug_file (void * data)
19316{
19317 close_file ((Filedata *) data);
19318}
19319
19320static Filedata *
19321open_file (const char * pathname)
19322{
19323 struct stat statbuf;
19324 Filedata * filedata = NULL;
19325
19326 if (stat (pathname, & statbuf) < 0
19327 || ! S_ISREG (statbuf.st_mode))
19328 goto fail;
19329
19330 filedata = calloc (1, sizeof * filedata);
19331 if (filedata == NULL)
19332 goto fail;
19333
19334 filedata->handle = fopen (pathname, "rb");
19335 if (filedata->handle == NULL)
19336 goto fail;
19337
19338 filedata->file_size = (bfd_size_type) statbuf.st_size;
19339 filedata->file_name = pathname;
19340
19341 if (! get_file_header (filedata))
19342 goto fail;
19343
19344 if (filedata->file_header.e_shoff)
19345 {
19346 bfd_boolean res;
19347
19348 /* Read the section headers again, this time for real. */
19349 if (is_32bit_elf)
19350 res = get_32bit_section_headers (filedata, FALSE);
19351 else
19352 res = get_64bit_section_headers (filedata, FALSE);
19353
19354 if (!res)
19355 goto fail;
19356 }
19357
19358 return filedata;
19359
19360 fail:
19361 if (filedata)
19362 {
19363 if (filedata->handle)
19364 fclose (filedata->handle);
19365 free (filedata);
19366 }
19367 return NULL;
19368}
19369
19370void *
19371open_debug_file (const char * pathname)
19372{
19373 return open_file (pathname);
19374}
19375
fb52b2f4
NC
19376/* Process one ELF object file according to the command line options.
19377 This file may actually be stored in an archive. The file is
32ec8896
NC
19378 positioned at the start of the ELF object. Returns TRUE if no
19379 problems were encountered, FALSE otherwise. */
fb52b2f4 19380
32ec8896 19381static bfd_boolean
dda8d76d 19382process_object (Filedata * filedata)
252b5132 19383{
24841daa 19384 bfd_boolean have_separate_files;
252b5132 19385 unsigned int i;
32ec8896 19386 bfd_boolean res = TRUE;
252b5132 19387
dda8d76d 19388 if (! get_file_header (filedata))
252b5132 19389 {
dda8d76d 19390 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 19391 return FALSE;
252b5132
RH
19392 }
19393
19394 /* Initialise per file variables. */
60bca95a 19395 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
19396 version_info[i] = 0;
19397
60bca95a 19398 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 19399 dynamic_info[i] = 0;
5115b233 19400 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
19401
19402 /* Process the file. */
19403 if (show_name)
dda8d76d 19404 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 19405
18bd398b
NC
19406 /* Initialise the dump_sects array from the cmdline_dump_sects array.
19407 Note we do this even if cmdline_dump_sects is empty because we
19408 must make sure that the dump_sets array is zeroed out before each
19409 object file is processed. */
dda8d76d
NC
19410 if (filedata->num_dump_sects > cmdline.num_dump_sects)
19411 memset (filedata->dump_sects, 0, filedata->num_dump_sects * sizeof (* filedata->dump_sects));
18bd398b 19412
dda8d76d 19413 if (cmdline.num_dump_sects > 0)
18bd398b 19414 {
dda8d76d 19415 if (filedata->num_dump_sects == 0)
18bd398b 19416 /* A sneaky way of allocating the dump_sects array. */
dda8d76d 19417 request_dump_bynumber (filedata, cmdline.num_dump_sects, 0);
18bd398b 19418
dda8d76d
NC
19419 assert (filedata->num_dump_sects >= cmdline.num_dump_sects);
19420 memcpy (filedata->dump_sects, cmdline.dump_sects,
19421 cmdline.num_dump_sects * sizeof (* filedata->dump_sects));
18bd398b 19422 }
d70c5fc7 19423
dda8d76d 19424 if (! process_file_header (filedata))
32ec8896 19425 return FALSE;
252b5132 19426
dda8d76d 19427 if (! process_section_headers (filedata))
2f62977e 19428 {
32ec8896
NC
19429 /* Without loaded section headers we cannot process lots of things. */
19430 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 19431
2f62977e 19432 if (! do_using_dynamic)
32ec8896 19433 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 19434 }
252b5132 19435
dda8d76d 19436 if (! process_section_groups (filedata))
32ec8896
NC
19437 /* Without loaded section groups we cannot process unwind. */
19438 do_unwind = FALSE;
d1f5c6e3 19439
dda8d76d
NC
19440 if (process_program_headers (filedata))
19441 process_dynamic_section (filedata);
32ec8896
NC
19442 else
19443 res = FALSE;
252b5132 19444
dda8d76d 19445 if (! process_relocs (filedata))
32ec8896 19446 res = FALSE;
252b5132 19447
dda8d76d 19448 if (! process_unwind (filedata))
32ec8896 19449 res = FALSE;
4d6ed7c8 19450
dda8d76d 19451 if (! process_symbol_table (filedata))
32ec8896 19452 res = FALSE;
252b5132 19453
dda8d76d 19454 if (! process_syminfo (filedata))
32ec8896 19455 res = FALSE;
252b5132 19456
dda8d76d 19457 if (! process_version_sections (filedata))
32ec8896 19458 res = FALSE;
252b5132 19459
82ed9683 19460 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 19461 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 19462 else
24841daa 19463 have_separate_files = FALSE;
dda8d76d
NC
19464
19465 if (! process_section_contents (filedata))
32ec8896 19466 res = FALSE;
f5842774 19467
24841daa 19468 if (have_separate_files)
dda8d76d 19469 {
24841daa
NC
19470 separate_info * d;
19471
19472 for (d = first_separate_info; d != NULL; d = d->next)
19473 {
19474 if (! process_section_headers (d->handle))
19475 res = FALSE;
19476 else if (! process_section_contents (d->handle))
19477 res = FALSE;
19478 }
19479
19480 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
19481 }
19482
19483 if (! process_notes (filedata))
32ec8896 19484 res = FALSE;
103f02d3 19485
dda8d76d 19486 if (! process_gnu_liblist (filedata))
32ec8896 19487 res = FALSE;
047b2264 19488
dda8d76d 19489 if (! process_arch_specific (filedata))
32ec8896 19490 res = FALSE;
252b5132 19491
dda8d76d
NC
19492 free (filedata->program_headers);
19493 filedata->program_headers = NULL;
d93f0186 19494
dda8d76d
NC
19495 free (filedata->section_headers);
19496 filedata->section_headers = NULL;
252b5132 19497
dda8d76d
NC
19498 free (filedata->string_table);
19499 filedata->string_table = NULL;
19500 filedata->string_table_length = 0;
252b5132
RH
19501
19502 if (dynamic_strings)
19503 {
19504 free (dynamic_strings);
19505 dynamic_strings = NULL;
d79b3d50 19506 dynamic_strings_length = 0;
252b5132
RH
19507 }
19508
19509 if (dynamic_symbols)
19510 {
19511 free (dynamic_symbols);
19512 dynamic_symbols = NULL;
19936277 19513 num_dynamic_syms = 0;
252b5132
RH
19514 }
19515
19516 if (dynamic_syminfo)
19517 {
19518 free (dynamic_syminfo);
19519 dynamic_syminfo = NULL;
19520 }
ff78d6d6 19521
293c573e
MR
19522 if (dynamic_section)
19523 {
19524 free (dynamic_section);
19525 dynamic_section = NULL;
19526 }
19527
e4b17d5c
L
19528 if (section_headers_groups)
19529 {
19530 free (section_headers_groups);
19531 section_headers_groups = NULL;
19532 }
19533
19534 if (section_groups)
19535 {
2cf0635d
NC
19536 struct group_list * g;
19537 struct group_list * next;
e4b17d5c
L
19538
19539 for (i = 0; i < group_count; i++)
19540 {
19541 for (g = section_groups [i].root; g != NULL; g = next)
19542 {
19543 next = g->next;
19544 free (g);
19545 }
19546 }
19547
19548 free (section_groups);
19549 section_groups = NULL;
19550 }
19551
19e6b90e 19552 free_debug_memory ();
18bd398b 19553
32ec8896 19554 return res;
252b5132
RH
19555}
19556
2cf0635d 19557/* Process an ELF archive.
32ec8896
NC
19558 On entry the file is positioned just after the ARMAG string.
19559 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 19560
32ec8896 19561static bfd_boolean
dda8d76d 19562process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
19563{
19564 struct archive_info arch;
19565 struct archive_info nested_arch;
19566 size_t got;
32ec8896 19567 bfd_boolean ret = TRUE;
2cf0635d 19568
32ec8896 19569 show_name = TRUE;
2cf0635d
NC
19570
19571 /* The ARCH structure is used to hold information about this archive. */
19572 arch.file_name = NULL;
19573 arch.file = NULL;
19574 arch.index_array = NULL;
19575 arch.sym_table = NULL;
19576 arch.longnames = NULL;
19577
19578 /* The NESTED_ARCH structure is used as a single-item cache of information
19579 about a nested archive (when members of a thin archive reside within
19580 another regular archive file). */
19581 nested_arch.file_name = NULL;
19582 nested_arch.file = NULL;
19583 nested_arch.index_array = NULL;
19584 nested_arch.sym_table = NULL;
19585 nested_arch.longnames = NULL;
19586
dda8d76d
NC
19587 if (setup_archive (&arch, filedata->file_name, filedata->handle,
19588 is_thin_archive, do_archive_index) != 0)
2cf0635d 19589 {
32ec8896 19590 ret = FALSE;
2cf0635d 19591 goto out;
4145f1d5 19592 }
fb52b2f4 19593
4145f1d5
NC
19594 if (do_archive_index)
19595 {
2cf0635d 19596 if (arch.sym_table == NULL)
dda8d76d 19597 error (_("%s: unable to dump the index as none was found\n"), filedata->file_name);
4145f1d5
NC
19598 else
19599 {
591f7597 19600 unsigned long i, l;
4145f1d5
NC
19601 unsigned long current_pos;
19602
591f7597 19603 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
dda8d76d
NC
19604 filedata->file_name, (unsigned long) arch.index_num, arch.sym_size);
19605
19606 current_pos = ftell (filedata->handle);
4145f1d5 19607
2cf0635d 19608 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 19609 {
2cf0635d
NC
19610 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
19611 {
19612 char * member_name;
4145f1d5 19613
2cf0635d
NC
19614 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
19615
19616 if (member_name != NULL)
19617 {
19618 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
19619
19620 if (qualified_name != NULL)
19621 {
c2a7d3f5
NC
19622 printf (_("Contents of binary %s at offset "), qualified_name);
19623 (void) print_vma (arch.index_array[i], PREFIX_HEX);
19624 putchar ('\n');
2cf0635d
NC
19625 free (qualified_name);
19626 }
4145f1d5
NC
19627 }
19628 }
2cf0635d
NC
19629
19630 if (l >= arch.sym_size)
4145f1d5
NC
19631 {
19632 error (_("%s: end of the symbol table reached before the end of the index\n"),
dda8d76d 19633 filedata->file_name);
32ec8896 19634 ret = FALSE;
cb8f3167 19635 break;
4145f1d5 19636 }
591f7597
NC
19637 /* PR 17531: file: 0b6630b2. */
19638 printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
19639 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
19640 }
19641
67ce483b 19642 if (arch.uses_64bit_indices)
c2a7d3f5
NC
19643 l = (l + 7) & ~ 7;
19644 else
19645 l += l & 1;
19646
2cf0635d 19647 if (l < arch.sym_size)
32ec8896 19648 {
d3a49aa8
AM
19649 error (ngettext ("%s: %ld byte remains in the symbol table, "
19650 "but without corresponding entries in "
19651 "the index table\n",
19652 "%s: %ld bytes remain in the symbol table, "
19653 "but without corresponding entries in "
19654 "the index table\n",
19655 arch.sym_size - l),
dda8d76d 19656 filedata->file_name, arch.sym_size - l);
32ec8896
NC
19657 ret = FALSE;
19658 }
4145f1d5 19659
dda8d76d 19660 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 19661 {
dda8d76d
NC
19662 error (_("%s: failed to seek back to start of object files in the archive\n"),
19663 filedata->file_name);
32ec8896 19664 ret = FALSE;
2cf0635d 19665 goto out;
4145f1d5 19666 }
fb52b2f4 19667 }
4145f1d5
NC
19668
19669 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
19670 && !do_segments && !do_header && !do_dump && !do_version
19671 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 19672 && !do_section_groups && !do_dyn_syms)
2cf0635d 19673 {
32ec8896 19674 ret = TRUE; /* Archive index only. */
2cf0635d
NC
19675 goto out;
19676 }
fb52b2f4
NC
19677 }
19678
fb52b2f4
NC
19679 while (1)
19680 {
2cf0635d
NC
19681 char * name;
19682 size_t namelen;
19683 char * qualified_name;
19684
19685 /* Read the next archive header. */
dda8d76d 19686 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
2cf0635d 19687 {
28e817cc 19688 error (_("%s: failed to seek to next archive header\n"), arch.file_name);
32ec8896 19689 return FALSE;
2cf0635d 19690 }
dda8d76d 19691 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d
NC
19692 if (got != sizeof arch.arhdr)
19693 {
19694 if (got == 0)
19695 break;
28e817cc
NC
19696 /* PR 24049 - we cannot use filedata->file_name as this will
19697 have already been freed. */
19698 error (_("%s: failed to read archive header\n"), arch.file_name);
19699
32ec8896 19700 ret = FALSE;
2cf0635d
NC
19701 break;
19702 }
19703 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
19704 {
19705 error (_("%s: did not find a valid archive header\n"), arch.file_name);
32ec8896 19706 ret = FALSE;
2cf0635d
NC
19707 break;
19708 }
19709
19710 arch.next_arhdr_offset += sizeof arch.arhdr;
19711
19712 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
19713 if (archive_file_size & 01)
19714 ++archive_file_size;
19715
19716 name = get_archive_member_name (&arch, &nested_arch);
19717 if (name == NULL)
fb52b2f4 19718 {
28e817cc 19719 error (_("%s: bad archive file name\n"), arch.file_name);
32ec8896 19720 ret = FALSE;
d989285c 19721 break;
fb52b2f4 19722 }
2cf0635d 19723 namelen = strlen (name);
fb52b2f4 19724
2cf0635d
NC
19725 qualified_name = make_qualified_name (&arch, &nested_arch, name);
19726 if (qualified_name == NULL)
fb52b2f4 19727 {
28e817cc 19728 error (_("%s: bad archive file name\n"), arch.file_name);
32ec8896 19729 ret = FALSE;
d989285c 19730 break;
fb52b2f4
NC
19731 }
19732
2cf0635d
NC
19733 if (is_thin_archive && arch.nested_member_origin == 0)
19734 {
19735 /* This is a proxy for an external member of a thin archive. */
dda8d76d
NC
19736 Filedata * member_filedata;
19737 char * member_file_name = adjust_relative_path
19738 (filedata->file_name, name, namelen);
32ec8896 19739
2cf0635d
NC
19740 if (member_file_name == NULL)
19741 {
32ec8896 19742 ret = FALSE;
2cf0635d
NC
19743 break;
19744 }
19745
dda8d76d
NC
19746 member_filedata = open_file (member_file_name);
19747 if (member_filedata == NULL)
2cf0635d
NC
19748 {
19749 error (_("Input file '%s' is not readable.\n"), member_file_name);
19750 free (member_file_name);
32ec8896 19751 ret = FALSE;
2cf0635d
NC
19752 break;
19753 }
19754
19755 archive_file_offset = arch.nested_member_origin;
dda8d76d 19756 member_filedata->file_name = qualified_name;
2cf0635d 19757
dda8d76d 19758 if (! process_object (member_filedata))
32ec8896 19759 ret = FALSE;
2cf0635d 19760
dda8d76d 19761 close_file (member_filedata);
2cf0635d
NC
19762 free (member_file_name);
19763 }
19764 else if (is_thin_archive)
19765 {
eb02c04d
PK
19766 Filedata thin_filedata;
19767
19768 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 19769
a043396b
NC
19770 /* PR 15140: Allow for corrupt thin archives. */
19771 if (nested_arch.file == NULL)
19772 {
19773 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 19774 qualified_name, name);
32ec8896 19775 ret = FALSE;
a043396b
NC
19776 break;
19777 }
19778
2cf0635d
NC
19779 /* This is a proxy for a member of a nested archive. */
19780 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
19781
19782 /* The nested archive file will have been opened and setup by
19783 get_archive_member_name. */
19784 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
19785 {
19786 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
32ec8896 19787 ret = FALSE;
2cf0635d
NC
19788 break;
19789 }
19790
dda8d76d
NC
19791 thin_filedata.handle = nested_arch.file;
19792 thin_filedata.file_name = qualified_name;
19793
19794 if (! process_object (& thin_filedata))
32ec8896 19795 ret = FALSE;
2cf0635d
NC
19796 }
19797 else
19798 {
19799 archive_file_offset = arch.next_arhdr_offset;
19800 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 19801
6a6196fc 19802 filedata->file_name = qualified_name;
dda8d76d 19803 if (! process_object (filedata))
32ec8896 19804 ret = FALSE;
2cf0635d 19805 }
fb52b2f4 19806
dda8d76d 19807 if (filedata->dump_sects != NULL)
2b52916e 19808 {
dda8d76d
NC
19809 free (filedata->dump_sects);
19810 filedata->dump_sects = NULL;
19811 filedata->num_dump_sects = 0;
2b52916e
L
19812 }
19813
2cf0635d 19814 free (qualified_name);
fb52b2f4
NC
19815 }
19816
4145f1d5 19817 out:
2cf0635d
NC
19818 if (nested_arch.file != NULL)
19819 fclose (nested_arch.file);
19820 release_archive (&nested_arch);
19821 release_archive (&arch);
fb52b2f4 19822
d989285c 19823 return ret;
fb52b2f4
NC
19824}
19825
32ec8896 19826static bfd_boolean
2cf0635d 19827process_file (char * file_name)
fb52b2f4 19828{
dda8d76d 19829 Filedata * filedata = NULL;
fb52b2f4
NC
19830 struct stat statbuf;
19831 char armag[SARMAG];
32ec8896 19832 bfd_boolean ret = TRUE;
fb52b2f4
NC
19833
19834 if (stat (file_name, &statbuf) < 0)
19835 {
f24ddbdd
NC
19836 if (errno == ENOENT)
19837 error (_("'%s': No such file\n"), file_name);
19838 else
19839 error (_("Could not locate '%s'. System error message: %s\n"),
19840 file_name, strerror (errno));
32ec8896 19841 return FALSE;
f24ddbdd
NC
19842 }
19843
19844 if (! S_ISREG (statbuf.st_mode))
19845 {
19846 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 19847 return FALSE;
fb52b2f4
NC
19848 }
19849
dda8d76d
NC
19850 filedata = calloc (1, sizeof * filedata);
19851 if (filedata == NULL)
19852 {
19853 error (_("Out of memory allocating file data structure\n"));
19854 return FALSE;
19855 }
19856
19857 filedata->file_name = file_name;
19858 filedata->handle = fopen (file_name, "rb");
19859 if (filedata->handle == NULL)
fb52b2f4 19860 {
f24ddbdd 19861 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 19862 free (filedata);
32ec8896 19863 return FALSE;
fb52b2f4
NC
19864 }
19865
dda8d76d 19866 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 19867 {
4145f1d5 19868 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
19869 fclose (filedata->handle);
19870 free (filedata);
32ec8896 19871 return FALSE;
fb52b2f4
NC
19872 }
19873
dda8d76d 19874 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 19875
fb52b2f4 19876 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 19877 {
dda8d76d 19878 if (! process_archive (filedata, FALSE))
32ec8896
NC
19879 ret = FALSE;
19880 }
2cf0635d 19881 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 19882 {
dda8d76d 19883 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
19884 ret = FALSE;
19885 }
fb52b2f4
NC
19886 else
19887 {
4145f1d5
NC
19888 if (do_archive_index)
19889 error (_("File %s is not an archive so its index cannot be displayed.\n"),
19890 file_name);
19891
dda8d76d 19892 rewind (filedata->handle);
fb52b2f4 19893 archive_file_size = archive_file_offset = 0;
32ec8896 19894
dda8d76d 19895 if (! process_object (filedata))
32ec8896 19896 ret = FALSE;
fb52b2f4
NC
19897 }
19898
dda8d76d
NC
19899 fclose (filedata->handle);
19900 free (filedata);
32ec8896 19901
fb52b2f4
NC
19902 return ret;
19903}
19904
252b5132
RH
19905#ifdef SUPPORT_DISASSEMBLY
19906/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 19907 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 19908 symbols. */
252b5132
RH
19909
19910void
2cf0635d 19911print_address (unsigned int addr, FILE * outfile)
252b5132
RH
19912{
19913 fprintf (outfile,"0x%8.8x", addr);
19914}
19915
e3c8793a 19916/* Needed by the i386 disassembler. */
dda8d76d 19917
252b5132
RH
19918void
19919db_task_printsym (unsigned int addr)
19920{
19921 print_address (addr, stderr);
19922}
19923#endif
19924
19925int
2cf0635d 19926main (int argc, char ** argv)
252b5132 19927{
ff78d6d6
L
19928 int err;
19929
252b5132
RH
19930#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
19931 setlocale (LC_MESSAGES, "");
3882b010
L
19932#endif
19933#if defined (HAVE_SETLOCALE)
19934 setlocale (LC_CTYPE, "");
252b5132
RH
19935#endif
19936 bindtextdomain (PACKAGE, LOCALEDIR);
19937 textdomain (PACKAGE);
19938
869b9d07
MM
19939 expandargv (&argc, &argv);
19940
dda8d76d
NC
19941 cmdline.file_name = "<cmdline>";
19942 parse_args (& cmdline, argc, argv);
59f14fc0 19943
18bd398b 19944 if (optind < (argc - 1))
32ec8896 19945 show_name = TRUE;
5656ba2c
L
19946 else if (optind >= argc)
19947 {
19948 warn (_("Nothing to do.\n"));
19949 usage (stderr);
19950 }
18bd398b 19951
32ec8896 19952 err = FALSE;
252b5132 19953 while (optind < argc)
32ec8896
NC
19954 if (! process_file (argv[optind++]))
19955 err = TRUE;
252b5132 19956
dda8d76d
NC
19957 if (cmdline.dump_sects != NULL)
19958 free (cmdline.dump_sects);
252b5132 19959
32ec8896 19960 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 19961}