]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
libsframe: add the SFrame library
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
a2c58332 2 Copyright (C) 1998-2022 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>
1f5a3546
FS
47#ifdef HAVE_ZSTD
48#include <zstd.h>
49#endif
7bfd842d 50#include <wchar.h>
252b5132 51
2952f10c
SM
52#if defined HAVE_MSGPACK
53#include <msgpack.h>
54#endif
55
19936277 56/* Define BFD64 here, even if our default architecture is 32 bit ELF
625d49fc 57 as this will allow us to read in and parse 64bit and 32bit ELF files. */
19936277 58#define BFD64
a952a375 59
3db64b00
AM
60#include "bfd.h"
61#include "bucomm.h"
3284fe0c 62#include "elfcomm.h"
0d646226 63#include "demanguse.h"
19e6b90e 64#include "dwarf.h"
7d9813f1 65#include "ctf-api.h"
79bc120c 66#include "demangle.h"
252b5132
RH
67
68#include "elf/common.h"
69#include "elf/external.h"
70#include "elf/internal.h"
252b5132 71
4b78141a
NC
72
73/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
74 we can obtain the H8 reloc numbers. We need these for the
75 get_reloc_size() function. We include h8.h again after defining
76 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
77
78#include "elf/h8.h"
79#undef _ELF_H8_H
80
81/* Undo the effects of #including reloc-macros.h. */
82
83#undef START_RELOC_NUMBERS
84#undef RELOC_NUMBER
85#undef FAKE_RELOC
86#undef EMPTY_RELOC
87#undef END_RELOC_NUMBERS
88#undef _RELOC_MACROS_H
89
252b5132
RH
90/* The following headers use the elf/reloc-macros.h file to
91 automatically generate relocation recognition functions
92 such as elf_mips_reloc_type() */
93
94#define RELOC_MACROS_GEN_FUNC
95
a06ea964 96#include "elf/aarch64.h"
252b5132 97#include "elf/alpha.h"
c077c580 98#include "elf/amdgpu.h"
3b16e843 99#include "elf/arc.h"
252b5132 100#include "elf/arm.h"
3b16e843 101#include "elf/avr.h"
1d65ded4 102#include "elf/bfin.h"
60bca95a 103#include "elf/cr16.h"
3b16e843 104#include "elf/cris.h"
1c0d3aa6 105#include "elf/crx.h"
b8891f8d 106#include "elf/csky.h"
252b5132
RH
107#include "elf/d10v.h"
108#include "elf/d30v.h"
d172d4ba 109#include "elf/dlx.h"
aca4efc7 110#include "elf/bpf.h"
cfb8c092 111#include "elf/epiphany.h"
252b5132 112#include "elf/fr30.h"
5c70f934 113#include "elf/frv.h"
3f8107ab 114#include "elf/ft32.h"
3b16e843
NC
115#include "elf/h8.h"
116#include "elf/hppa.h"
117#include "elf/i386.h"
f954747f
AM
118#include "elf/i370.h"
119#include "elf/i860.h"
120#include "elf/i960.h"
3b16e843 121#include "elf/ia64.h"
1e4cf259 122#include "elf/ip2k.h"
84e94c90 123#include "elf/lm32.h"
1c0d3aa6 124#include "elf/iq2000.h"
49f58d10 125#include "elf/m32c.h"
3b16e843
NC
126#include "elf/m32r.h"
127#include "elf/m68k.h"
75751cd9 128#include "elf/m68hc11.h"
7b4ae824 129#include "elf/s12z.h"
252b5132 130#include "elf/mcore.h"
15ab5209 131#include "elf/mep.h"
a3c62988 132#include "elf/metag.h"
7ba29e2a 133#include "elf/microblaze.h"
3b16e843 134#include "elf/mips.h"
3c3bdf30 135#include "elf/mmix.h"
3b16e843
NC
136#include "elf/mn10200.h"
137#include "elf/mn10300.h"
5506d11a 138#include "elf/moxie.h"
4970f871 139#include "elf/mt.h"
2469cfa2 140#include "elf/msp430.h"
35c08157 141#include "elf/nds32.h"
fe944acf 142#include "elf/nfp.h"
13761a11 143#include "elf/nios2.h"
73589c9d 144#include "elf/or1k.h"
7d466069 145#include "elf/pj.h"
3b16e843 146#include "elf/ppc.h"
c833c019 147#include "elf/ppc64.h"
2b100bb5 148#include "elf/pru.h"
03336641 149#include "elf/riscv.h"
99c513f6 150#include "elf/rl78.h"
c7927a3c 151#include "elf/rx.h"
a85d7ed0 152#include "elf/s390.h"
1c0d3aa6 153#include "elf/score.h"
3b16e843
NC
154#include "elf/sh.h"
155#include "elf/sparc.h"
e9f53129 156#include "elf/spu.h"
40b36596 157#include "elf/tic6x.h"
aa137e4d
NC
158#include "elf/tilegx.h"
159#include "elf/tilepro.h"
3b16e843 160#include "elf/v850.h"
179d3252 161#include "elf/vax.h"
619ed720 162#include "elf/visium.h"
f96bd6c2 163#include "elf/wasm32.h"
3b16e843 164#include "elf/x86-64.h"
f6c1a2d5 165#include "elf/xgate.h"
93fbbb04 166#include "elf/xstormy16.h"
88da6820 167#include "elf/xtensa.h"
6655dba2 168#include "elf/z80.h"
e9a0721f 169#include "elf/loongarch.h"
252b5132 170
252b5132 171#include "getopt.h"
566b0d53 172#include "libiberty.h"
09c11c86 173#include "safe-ctype.h"
2cf0635d 174#include "filenames.h"
252b5132 175
15b42fb0
AM
176#ifndef offsetof
177#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
178#endif
179
6a40cf0c
NC
180typedef struct elf_section_list
181{
dda8d76d
NC
182 Elf_Internal_Shdr * hdr;
183 struct elf_section_list * next;
6a40cf0c
NC
184} elf_section_list;
185
dda8d76d
NC
186/* Flag bits indicating particular types of dump. */
187#define HEX_DUMP (1 << 0) /* The -x command line switch. */
188#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
189#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
190#define STRING_DUMP (1 << 3) /* The -p command line switch. */
191#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 192#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
193
194typedef unsigned char dump_type;
195
196/* A linked list of the section names for which dumps were requested. */
197struct dump_list_entry
198{
199 char * name;
200 dump_type type;
201 struct dump_list_entry * next;
202};
203
6431e409
AM
204/* A dynamic array of flags indicating for which sections a dump
205 has been requested via command line switches. */
1b513401
NC
206struct dump_data
207{
6431e409
AM
208 dump_type * dump_sects;
209 unsigned int num_dump_sects;
210};
211
212static struct dump_data cmdline;
213
214static struct dump_list_entry * dump_sects_byname;
215
2cf0635d 216char * program_name = "readelf";
dda8d76d 217
015dc7e1
AM
218static bool show_name = false;
219static bool do_dynamic = false;
220static bool do_syms = false;
221static bool do_dyn_syms = false;
222static bool do_lto_syms = false;
223static bool do_reloc = false;
224static bool do_sections = false;
225static bool do_section_groups = false;
226static bool do_section_details = false;
227static bool do_segments = false;
228static bool do_unwind = false;
229static bool do_using_dynamic = false;
230static bool do_header = false;
231static bool do_dump = false;
232static bool do_version = false;
233static bool do_histogram = false;
234static bool do_debugging = false;
235static bool do_ctf = false;
236static bool do_arch = false;
237static bool do_notes = false;
238static bool do_archive_index = false;
239static bool check_all = false;
240static bool is_32bit_elf = false;
241static bool decompress_dumps = false;
242static bool do_not_show_symbol_truncation = false;
243static bool do_demangle = false; /* Pretty print C++ symbol names. */
244static bool process_links = false;
e1dbfc17 245static bool dump_any_debugging = false;
79bc120c 246static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 247static int sym_base = 0;
252b5132 248
7d9813f1
NA
249static char *dump_ctf_parent_name;
250static char *dump_ctf_symtab_name;
251static char *dump_ctf_strtab_name;
252
e4b17d5c
L
253struct group_list
254{
dda8d76d
NC
255 struct group_list * next;
256 unsigned int section_index;
e4b17d5c
L
257};
258
259struct group
260{
dda8d76d
NC
261 struct group_list * root;
262 unsigned int group_index;
e4b17d5c
L
263};
264
978c4450
AM
265typedef struct filedata
266{
267 const char * file_name;
015dc7e1 268 bool is_separate;
978c4450 269 FILE * handle;
be7d229a 270 uint64_t file_size;
978c4450 271 Elf_Internal_Ehdr file_header;
066f8fbe
AM
272 unsigned long archive_file_offset;
273 unsigned long archive_file_size;
274 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
275 Elf_Internal_Shdr * section_headers;
276 Elf_Internal_Phdr * program_headers;
277 char * string_table;
278 unsigned long string_table_length;
978c4450 279 unsigned long dynamic_addr;
be7d229a 280 uint64_t dynamic_size;
978c4450
AM
281 size_t dynamic_nent;
282 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 283 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
284 char * dynamic_strings;
285 unsigned long dynamic_strings_length;
8ac10c5b 286 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
287 unsigned long num_dynamic_syms;
288 Elf_Internal_Sym * dynamic_symbols;
625d49fc 289 uint64_t version_info[16];
978c4450
AM
290 unsigned int dynamic_syminfo_nent;
291 Elf_Internal_Syminfo * dynamic_syminfo;
292 unsigned long dynamic_syminfo_offset;
be7d229a
AM
293 uint64_t nbuckets;
294 uint64_t nchains;
625d49fc
AM
295 uint64_t * buckets;
296 uint64_t * chains;
be7d229a
AM
297 uint64_t ngnubuckets;
298 uint64_t ngnuchains;
625d49fc
AM
299 uint64_t * gnubuckets;
300 uint64_t * gnuchains;
301 uint64_t * mipsxlat;
302 uint64_t gnusymidx;
13acb58d 303 char * program_interpreter;
625d49fc
AM
304 uint64_t dynamic_info[DT_ENCODING];
305 uint64_t dynamic_info_DT_GNU_HASH;
306 uint64_t dynamic_info_DT_MIPS_XHASH;
978c4450
AM
307 elf_section_list * symtab_shndx_list;
308 size_t group_count;
309 struct group * section_groups;
310 struct group ** section_headers_groups;
311 /* A dynamic array of flags indicating for which sections a dump of
312 some kind has been requested. It is reset on a per-object file
313 basis and then initialised from the cmdline_dump_sects array,
314 the results of interpreting the -w switch, and the
315 dump_sects_byname list. */
316 struct dump_data dump;
317} Filedata;
aef1f6d0 318
c256ffe7 319/* How to print a vma value. */
843dd992
NC
320typedef enum print_mode
321{
322 HEX,
047c3dbf 323 HEX_5,
843dd992
NC
324 DEC,
325 DEC_5,
326 UNSIGNED,
047c3dbf 327 UNSIGNED_5,
843dd992 328 PREFIX_HEX,
047c3dbf 329 PREFIX_HEX_5,
843dd992 330 FULL_HEX,
047c3dbf
NL
331 LONG_HEX,
332 OCTAL,
333 OCTAL_5
843dd992
NC
334}
335print_mode;
336
b3aa80b4
NC
337typedef enum unicode_display_type
338{
339 unicode_default = 0,
340 unicode_locale,
341 unicode_escape,
342 unicode_hex,
343 unicode_highlight,
344 unicode_invalid
345} unicode_display_type;
346
347static unicode_display_type unicode_display = unicode_default;
348
a7fd1186
FS
349typedef enum
350{
351 reltype_unknown,
352 reltype_rel,
353 reltype_rela,
354 reltype_relr
355} relocation_type;
356
bb4d2ac2
L
357/* Versioned symbol info. */
358enum versioned_symbol_info
359{
360 symbol_undefined,
361 symbol_hidden,
362 symbol_public
363};
364
32ec8896 365static const char * get_symbol_version_string
015dc7e1 366 (Filedata *, bool, const char *, unsigned long, unsigned,
32ec8896 367 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 368
9c19a809
NC
369#define UNKNOWN -1
370
84714f86
AM
371static inline const char *
372section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
373{
374 return filedata->string_table + hdr->sh_name;
375}
b9e920ec 376
84714f86
AM
377static inline bool
378section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
379{
380 return (hdr != NULL
381 && filedata->string_table != NULL
382 && hdr->sh_name < filedata->string_table_length);
383}
b9e920ec 384
84714f86
AM
385static inline const char *
386section_name_print (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
387{
388 if (hdr == NULL)
389 return _("<none>");
390 if (filedata->string_table == NULL)
391 return _("<no-strings>");
392 if (hdr->sh_name >= filedata->string_table_length)
393 return _("<corrupt>");
394 return section_name (filedata, hdr);
395}
252b5132 396
ee42cf8c 397#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 398
84714f86
AM
399static inline bool
400valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
401{
402 return strtab != NULL && offset < strtab_size;
403}
404
405static inline bool
406valid_dynamic_name (const Filedata *filedata, uint64_t offset)
407{
408 return valid_symbol_name (filedata->dynamic_strings,
409 filedata->dynamic_strings_length, offset);
410}
411
d79b3d50
NC
412/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
413 already been called and verified that the string exists. */
84714f86
AM
414static inline const char *
415get_dynamic_name (const Filedata *filedata, size_t offset)
416{
417 return filedata->dynamic_strings + offset;
418}
18bd398b 419
61865e30
NC
420#define REMOVE_ARCH_BITS(ADDR) \
421 do \
422 { \
dda8d76d 423 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
424 (ADDR) &= ~1; \
425 } \
426 while (0)
f16a9783
MS
427
428/* Get the correct GNU hash section name. */
978c4450
AM
429#define GNU_HASH_SECTION_NAME(filedata) \
430 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 431\f
dda8d76d
NC
432/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
433 OFFSET + the offset of the current archive member, if we are examining an
434 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
435 allocate a buffer using malloc and fill that. In either case return the
436 pointer to the start of the retrieved data or NULL if something went wrong.
437 If something does go wrong and REASON is not NULL then emit an error
438 message using REASON as part of the context. */
59245841 439
c256ffe7 440static void *
be7d229a
AM
441get_data (void *var,
442 Filedata *filedata,
443 unsigned long offset,
444 uint64_t size,
445 uint64_t nmemb,
446 const char *reason)
a6e9f9df 447{
2cf0635d 448 void * mvar;
be7d229a 449 uint64_t amt = size * nmemb;
a6e9f9df 450
c256ffe7 451 if (size == 0 || nmemb == 0)
a6e9f9df
AM
452 return NULL;
453
be7d229a
AM
454 /* If size_t is smaller than uint64_t, eg because you are building
455 on a 32-bit host, then make sure that when the sizes are cast to
456 size_t no information is lost. */
7c1c1904
AM
457 if ((size_t) size != size
458 || (size_t) nmemb != nmemb
be7d229a
AM
459 || (size_t) amt != amt
460 || amt / size != nmemb
461 || (size_t) amt + 1 == 0)
57028622
NC
462 {
463 if (reason)
b8281767
AM
464 error (_("Size overflow prevents reading %" PRIu64
465 " elements of size %" PRIu64 " for %s\n"),
be7d229a 466 nmemb, size, reason);
57028622
NC
467 return NULL;
468 }
469
c22b42ce 470 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 471 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
472 if (filedata->archive_file_offset > filedata->file_size
473 || offset > filedata->file_size - filedata->archive_file_offset
474 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 475 {
049b0c3a 476 if (reason)
b8281767 477 error (_("Reading %" PRIu64 " bytes extends past end of file for %s\n"),
be7d229a 478 amt, reason);
a6e9f9df
AM
479 return NULL;
480 }
481
978c4450
AM
482 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
483 SEEK_SET))
071436c6
NC
484 {
485 if (reason)
c9c1d674 486 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 487 filedata->archive_file_offset + offset, reason);
071436c6
NC
488 return NULL;
489 }
490
a6e9f9df
AM
491 mvar = var;
492 if (mvar == NULL)
493 {
7c1c1904
AM
494 /* + 1 so that we can '\0' terminate invalid string table sections. */
495 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
496
497 if (mvar == NULL)
498 {
049b0c3a 499 if (reason)
b8281767 500 error (_("Out of memory allocating %" PRIu64 " bytes for %s\n"),
be7d229a 501 amt, reason);
a6e9f9df
AM
502 return NULL;
503 }
c256ffe7 504
c9c1d674 505 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
506 }
507
dda8d76d 508 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 509 {
049b0c3a 510 if (reason)
b8281767 511 error (_("Unable to read in %" PRIu64 " bytes of %s\n"),
be7d229a 512 amt, reason);
a6e9f9df
AM
513 if (mvar != var)
514 free (mvar);
515 return NULL;
516 }
517
518 return mvar;
519}
520
32ec8896
NC
521/* Print a VMA value in the MODE specified.
522 Returns the number of characters displayed. */
cb8f3167 523
32ec8896 524static unsigned int
625d49fc 525print_vma (uint64_t vma, print_mode mode)
66543521 526{
32ec8896 527 unsigned int nc = 0;
66543521 528
14a91970 529 switch (mode)
66543521 530 {
14a91970
AM
531 case FULL_HEX:
532 nc = printf ("0x");
1a0670f3 533 /* Fall through. */
14a91970 534 case LONG_HEX:
f493c217 535 if (!is_32bit_elf)
625d49fc
AM
536 return nc + printf ("%16.16" PRIx64, vma);
537 return nc + printf ("%8.8" PRIx64, vma);
b19aac67 538
14a91970
AM
539 case DEC_5:
540 if (vma <= 99999)
625d49fc 541 return printf ("%5" PRId64, vma);
1a0670f3 542 /* Fall through. */
14a91970
AM
543 case PREFIX_HEX:
544 nc = printf ("0x");
1a0670f3 545 /* Fall through. */
14a91970 546 case HEX:
625d49fc 547 return nc + printf ("%" PRIx64, vma);
b19aac67 548
047c3dbf
NL
549 case PREFIX_HEX_5:
550 nc = printf ("0x");
551 /* Fall through. */
552 case HEX_5:
625d49fc 553 return nc + printf ("%05" PRIx64, vma);
047c3dbf 554
14a91970 555 case DEC:
625d49fc 556 return printf ("%" PRId64, vma);
b19aac67 557
14a91970 558 case UNSIGNED:
625d49fc 559 return printf ("%" PRIu64, vma);
32ec8896 560
047c3dbf 561 case UNSIGNED_5:
625d49fc 562 return printf ("%5" PRIu64, vma);
047c3dbf
NL
563
564 case OCTAL:
625d49fc 565 return printf ("%" PRIo64, vma);
047c3dbf
NL
566
567 case OCTAL_5:
625d49fc 568 return printf ("%5" PRIo64, vma);
047c3dbf 569
32ec8896
NC
570 default:
571 /* FIXME: Report unrecognised mode ? */
572 return 0;
f7a99963 573 }
f7a99963
NC
574}
575
047c3dbf 576
7bfd842d 577/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 578 multibye characters (assuming the host environment supports them).
31104126 579
7bfd842d
NC
580 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
581
0942c7ab
NC
582 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
583 abs(WIDTH) - 5 characters followed by "[...]".
584
7bfd842d
NC
585 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
586 padding as necessary.
171191ba
NC
587
588 Returns the number of emitted characters. */
589
590static unsigned int
0942c7ab 591print_symbol (signed int width, const char * symbol)
31104126 592{
015dc7e1
AM
593 bool extra_padding = false;
594 bool do_dots = false;
32ec8896 595 signed int num_printed = 0;
3bfcb652 596#ifdef HAVE_MBSTATE_T
7bfd842d 597 mbstate_t state;
3bfcb652 598#endif
32ec8896 599 unsigned int width_remaining;
79bc120c 600 const void * alloced_symbol = NULL;
961c521f 601
7bfd842d 602 if (width < 0)
961c521f 603 {
88305e1b 604 /* Keep the width positive. This helps the code below. */
961c521f 605 width = - width;
015dc7e1 606 extra_padding = true;
0b4362b0 607 }
56d8f8a9
NC
608 else if (width == 0)
609 return 0;
961c521f 610
7bfd842d
NC
611 if (do_wide)
612 /* Set the remaining width to a very large value.
613 This simplifies the code below. */
614 width_remaining = INT_MAX;
615 else
0942c7ab
NC
616 {
617 width_remaining = width;
618 if (! do_not_show_symbol_truncation
619 && (int) strlen (symbol) > width)
620 {
621 width_remaining -= 5;
622 if ((int) width_remaining < 0)
623 width_remaining = 0;
015dc7e1 624 do_dots = true;
0942c7ab
NC
625 }
626 }
cb8f3167 627
3bfcb652 628#ifdef HAVE_MBSTATE_T
7bfd842d
NC
629 /* Initialise the multibyte conversion state. */
630 memset (& state, 0, sizeof (state));
3bfcb652 631#endif
961c521f 632
79bc120c
NC
633 if (do_demangle && *symbol)
634 {
635 const char * res = cplus_demangle (symbol, demangle_flags);
636
637 if (res != NULL)
638 alloced_symbol = symbol = res;
639 }
640
7bfd842d
NC
641 while (width_remaining)
642 {
643 size_t n;
7bfd842d 644 const char c = *symbol++;
961c521f 645
7bfd842d 646 if (c == 0)
961c521f
NC
647 break;
648
b3aa80b4
NC
649 if (ISPRINT (c))
650 {
651 putchar (c);
652 width_remaining --;
653 num_printed ++;
654 }
655 else if (ISCNTRL (c))
961c521f 656 {
b3aa80b4
NC
657 /* Do not print control characters directly as they can affect terminal
658 settings. Such characters usually appear in the names generated
659 by the assembler for local labels. */
660
7bfd842d 661 if (width_remaining < 2)
961c521f
NC
662 break;
663
7bfd842d
NC
664 printf ("^%c", c + 0x40);
665 width_remaining -= 2;
171191ba 666 num_printed += 2;
961c521f 667 }
b3aa80b4 668 else if (c == 0x7f)
7bfd842d 669 {
b3aa80b4
NC
670 if (width_remaining < 5)
671 break;
672 printf ("<DEL>");
673 width_remaining -= 5;
674 num_printed += 5;
675 }
676 else if (unicode_display != unicode_locale
677 && unicode_display != unicode_default)
678 {
679 /* Display unicode characters as something else. */
680 unsigned char bytes[4];
681 bool is_utf8;
795588ae 682 unsigned int nbytes;
b3aa80b4
NC
683
684 bytes[0] = c;
685
686 if (bytes[0] < 0xc0)
687 {
688 nbytes = 1;
689 is_utf8 = false;
690 }
691 else
692 {
693 bytes[1] = *symbol++;
694
695 if ((bytes[1] & 0xc0) != 0x80)
696 {
697 is_utf8 = false;
698 /* Do not consume this character. It may only
699 be the first byte in the sequence that was
700 corrupt. */
701 --symbol;
702 nbytes = 1;
703 }
704 else if ((bytes[0] & 0x20) == 0)
705 {
706 is_utf8 = true;
707 nbytes = 2;
708 }
709 else
710 {
711 bytes[2] = *symbol++;
712
713 if ((bytes[2] & 0xc0) != 0x80)
714 {
715 is_utf8 = false;
716 symbol -= 2;
717 nbytes = 1;
718 }
719 else if ((bytes[0] & 0x10) == 0)
720 {
721 is_utf8 = true;
722 nbytes = 3;
723 }
724 else
725 {
726 bytes[3] = *symbol++;
727
728 nbytes = 4;
729
730 if ((bytes[3] & 0xc0) != 0x80)
731 {
732 is_utf8 = false;
733 symbol -= 3;
734 nbytes = 1;
735 }
736 else
737 is_utf8 = true;
738 }
739 }
740 }
741
742 if (unicode_display == unicode_invalid)
743 is_utf8 = false;
744
745 if (unicode_display == unicode_hex || ! is_utf8)
746 {
795588ae 747 unsigned int i;
b3aa80b4
NC
748
749 if (width_remaining < (nbytes * 2) + 2)
750 break;
751
752 putchar (is_utf8 ? '<' : '{');
753 printf ("0x");
754 for (i = 0; i < nbytes; i++)
755 printf ("%02x", bytes[i]);
756 putchar (is_utf8 ? '>' : '}');
757 }
758 else
759 {
760 if (unicode_display == unicode_highlight && isatty (1))
761 printf ("\x1B[31;47m"); /* Red. */
762
763 switch (nbytes)
764 {
765 case 2:
766 if (width_remaining < 6)
767 break;
768 printf ("\\u%02x%02x",
769 (bytes[0] & 0x1c) >> 2,
770 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
771 break;
772 case 3:
773 if (width_remaining < 6)
774 break;
775 printf ("\\u%02x%02x",
776 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
777 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
778 break;
779 case 4:
780 if (width_remaining < 8)
781 break;
782 printf ("\\u%02x%02x%02x",
783 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
784 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
785 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
786
787 break;
788 default:
789 /* URG. */
790 break;
791 }
792
793 if (unicode_display == unicode_highlight && isatty (1))
794 printf ("\033[0m"); /* Default colour. */
795 }
796
797 if (bytes[nbytes - 1] == 0)
798 break;
7bfd842d 799 }
961c521f
NC
800 else
801 {
3bfcb652
NC
802#ifdef HAVE_MBSTATE_T
803 wchar_t w;
804#endif
7bfd842d
NC
805 /* Let printf do the hard work of displaying multibyte characters. */
806 printf ("%.1s", symbol - 1);
807 width_remaining --;
808 num_printed ++;
809
3bfcb652 810#ifdef HAVE_MBSTATE_T
7bfd842d
NC
811 /* Try to find out how many bytes made up the character that was
812 just printed. Advance the symbol pointer past the bytes that
813 were displayed. */
814 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
815#else
816 n = 1;
817#endif
7bfd842d
NC
818 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
819 symbol += (n - 1);
961c521f 820 }
961c521f 821 }
171191ba 822
0942c7ab
NC
823 if (do_dots)
824 num_printed += printf ("[...]");
825
7bfd842d 826 if (extra_padding && num_printed < width)
171191ba
NC
827 {
828 /* Fill in the remaining spaces. */
7bfd842d
NC
829 printf ("%-*s", width - num_printed, " ");
830 num_printed = width;
171191ba
NC
831 }
832
79bc120c 833 free ((void *) alloced_symbol);
171191ba 834 return num_printed;
31104126
NC
835}
836
1449284b 837/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
838 the given section's name. Like print_symbol, except that it does not try
839 to print multibyte characters, it just interprets them as hex values. */
840
841static const char *
dda8d76d 842printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 843{
ca0e11aa 844#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 845 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
84714f86 846 const char * name = section_name_print (filedata, sec);
74e1a04b
NC
847 char * buf = sec_name_buf;
848 char c;
849 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
850
851 while ((c = * name ++) != 0)
852 {
853 if (ISCNTRL (c))
854 {
855 if (remaining < 2)
856 break;
948f632f 857
74e1a04b
NC
858 * buf ++ = '^';
859 * buf ++ = c + 0x40;
860 remaining -= 2;
861 }
862 else if (ISPRINT (c))
863 {
864 * buf ++ = c;
865 remaining -= 1;
866 }
867 else
868 {
869 static char hex[17] = "0123456789ABCDEF";
870
871 if (remaining < 4)
872 break;
873 * buf ++ = '<';
874 * buf ++ = hex[(c & 0xf0) >> 4];
875 * buf ++ = hex[c & 0x0f];
876 * buf ++ = '>';
877 remaining -= 4;
878 }
879
880 if (remaining == 0)
881 break;
882 }
883
884 * buf = 0;
885 return sec_name_buf;
886}
887
888static const char *
dda8d76d 889printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 890{
dda8d76d 891 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
892 return _("<corrupt>");
893
dda8d76d 894 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
895}
896
89fac5e3
RS
897/* Return a pointer to section NAME, or NULL if no such section exists. */
898
899static Elf_Internal_Shdr *
dda8d76d 900find_section (Filedata * filedata, const char * name)
89fac5e3
RS
901{
902 unsigned int i;
903
68807c3c
NC
904 if (filedata->section_headers == NULL)
905 return NULL;
dda8d76d
NC
906
907 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
908 if (section_name_valid (filedata, filedata->section_headers + i)
909 && streq (section_name (filedata, filedata->section_headers + i),
910 name))
dda8d76d 911 return filedata->section_headers + i;
89fac5e3
RS
912
913 return NULL;
914}
915
0b6ae522
DJ
916/* Return a pointer to a section containing ADDR, or NULL if no such
917 section exists. */
918
919static Elf_Internal_Shdr *
625d49fc 920find_section_by_address (Filedata * filedata, uint64_t addr)
0b6ae522
DJ
921{
922 unsigned int i;
923
68807c3c
NC
924 if (filedata->section_headers == NULL)
925 return NULL;
926
dda8d76d 927 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 928 {
dda8d76d
NC
929 Elf_Internal_Shdr *sec = filedata->section_headers + i;
930
0b6ae522
DJ
931 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
932 return sec;
933 }
934
935 return NULL;
936}
937
071436c6 938static Elf_Internal_Shdr *
dda8d76d 939find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
940{
941 unsigned int i;
942
68807c3c
NC
943 if (filedata->section_headers == NULL)
944 return NULL;
945
dda8d76d 946 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 947 {
dda8d76d
NC
948 Elf_Internal_Shdr *sec = filedata->section_headers + i;
949
071436c6
NC
950 if (sec->sh_type == type)
951 return sec;
952 }
953
954 return NULL;
955}
956
657d0d47
CC
957/* Return a pointer to section NAME, or NULL if no such section exists,
958 restricted to the list of sections given in SET. */
959
960static Elf_Internal_Shdr *
dda8d76d 961find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
962{
963 unsigned int i;
964
68807c3c
NC
965 if (filedata->section_headers == NULL)
966 return NULL;
967
657d0d47
CC
968 if (set != NULL)
969 {
970 while ((i = *set++) > 0)
b814a36d
NC
971 {
972 /* See PR 21156 for a reproducer. */
dda8d76d 973 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
974 continue; /* FIXME: Should we issue an error message ? */
975
84714f86
AM
976 if (section_name_valid (filedata, filedata->section_headers + i)
977 && streq (section_name (filedata, filedata->section_headers + i),
978 name))
dda8d76d 979 return filedata->section_headers + i;
b814a36d 980 }
657d0d47
CC
981 }
982
dda8d76d 983 return find_section (filedata, name);
657d0d47
CC
984}
985
32ec8896 986/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
987 This OS has so many departures from the ELF standard that we test it at
988 many places. */
989
015dc7e1 990static inline bool
dda8d76d 991is_ia64_vms (Filedata * filedata)
28f997cf 992{
dda8d76d
NC
993 return filedata->file_header.e_machine == EM_IA_64
994 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
995}
996
bcedfee6 997/* Guess the relocation size commonly used by the specific machines. */
252b5132 998
015dc7e1 999static bool
2dc4cec1 1000guess_is_rela (unsigned int e_machine)
252b5132 1001{
9c19a809 1002 switch (e_machine)
252b5132
RH
1003 {
1004 /* Targets that use REL relocations. */
252b5132 1005 case EM_386:
22abe556 1006 case EM_IAMCU:
f954747f 1007 case EM_960:
e9f53129 1008 case EM_ARM:
2b0337b0 1009 case EM_D10V:
252b5132 1010 case EM_CYGNUS_D10V:
e9f53129 1011 case EM_DLX:
252b5132 1012 case EM_MIPS:
4fe85591 1013 case EM_MIPS_RS3_LE:
e9f53129 1014 case EM_CYGNUS_M32R:
1c0d3aa6 1015 case EM_SCORE:
f6c1a2d5 1016 case EM_XGATE:
fe944acf 1017 case EM_NFP:
aca4efc7 1018 case EM_BPF:
015dc7e1 1019 return false;
103f02d3 1020
252b5132
RH
1021 /* Targets that use RELA relocations. */
1022 case EM_68K:
f954747f 1023 case EM_860:
a06ea964 1024 case EM_AARCH64:
cfb8c092 1025 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1026 case EM_ALPHA:
1027 case EM_ALTERA_NIOS2:
886a2506
NC
1028 case EM_ARC:
1029 case EM_ARC_COMPACT:
1030 case EM_ARC_COMPACT2:
e9f53129
AM
1031 case EM_AVR:
1032 case EM_AVR_OLD:
1033 case EM_BLACKFIN:
60bca95a 1034 case EM_CR16:
e9f53129
AM
1035 case EM_CRIS:
1036 case EM_CRX:
b8891f8d 1037 case EM_CSKY:
2b0337b0 1038 case EM_D30V:
252b5132 1039 case EM_CYGNUS_D30V:
2b0337b0 1040 case EM_FR30:
3f8107ab 1041 case EM_FT32:
252b5132 1042 case EM_CYGNUS_FR30:
5c70f934 1043 case EM_CYGNUS_FRV:
e9f53129
AM
1044 case EM_H8S:
1045 case EM_H8_300:
1046 case EM_H8_300H:
800eeca4 1047 case EM_IA_64:
1e4cf259
NC
1048 case EM_IP2K:
1049 case EM_IP2K_OLD:
3b36097d 1050 case EM_IQ2000:
84e94c90 1051 case EM_LATTICEMICO32:
ff7eeb89 1052 case EM_M32C_OLD:
49f58d10 1053 case EM_M32C:
e9f53129
AM
1054 case EM_M32R:
1055 case EM_MCORE:
15ab5209 1056 case EM_CYGNUS_MEP:
a3c62988 1057 case EM_METAG:
e9f53129
AM
1058 case EM_MMIX:
1059 case EM_MN10200:
1060 case EM_CYGNUS_MN10200:
1061 case EM_MN10300:
1062 case EM_CYGNUS_MN10300:
5506d11a 1063 case EM_MOXIE:
e9f53129
AM
1064 case EM_MSP430:
1065 case EM_MSP430_OLD:
d031aafb 1066 case EM_MT:
35c08157 1067 case EM_NDS32:
64fd6348 1068 case EM_NIOS32:
73589c9d 1069 case EM_OR1K:
e9f53129
AM
1070 case EM_PPC64:
1071 case EM_PPC:
2b100bb5 1072 case EM_TI_PRU:
e23eba97 1073 case EM_RISCV:
99c513f6 1074 case EM_RL78:
c7927a3c 1075 case EM_RX:
e9f53129
AM
1076 case EM_S390:
1077 case EM_S390_OLD:
1078 case EM_SH:
1079 case EM_SPARC:
1080 case EM_SPARC32PLUS:
1081 case EM_SPARCV9:
1082 case EM_SPU:
40b36596 1083 case EM_TI_C6000:
aa137e4d
NC
1084 case EM_TILEGX:
1085 case EM_TILEPRO:
708e2187 1086 case EM_V800:
e9f53129
AM
1087 case EM_V850:
1088 case EM_CYGNUS_V850:
1089 case EM_VAX:
619ed720 1090 case EM_VISIUM:
e9f53129 1091 case EM_X86_64:
8a9036a4 1092 case EM_L1OM:
7a9068fe 1093 case EM_K1OM:
e9f53129
AM
1094 case EM_XSTORMY16:
1095 case EM_XTENSA:
1096 case EM_XTENSA_OLD:
7ba29e2a
NC
1097 case EM_MICROBLAZE:
1098 case EM_MICROBLAZE_OLD:
f96bd6c2 1099 case EM_WEBASSEMBLY:
015dc7e1 1100 return true;
103f02d3 1101
e9f53129
AM
1102 case EM_68HC05:
1103 case EM_68HC08:
1104 case EM_68HC11:
1105 case EM_68HC16:
1106 case EM_FX66:
1107 case EM_ME16:
d1133906 1108 case EM_MMA:
d1133906
NC
1109 case EM_NCPU:
1110 case EM_NDR1:
e9f53129 1111 case EM_PCP:
d1133906 1112 case EM_ST100:
e9f53129 1113 case EM_ST19:
d1133906 1114 case EM_ST7:
e9f53129
AM
1115 case EM_ST9PLUS:
1116 case EM_STARCORE:
d1133906 1117 case EM_SVX:
e9f53129 1118 case EM_TINYJ:
9c19a809
NC
1119 default:
1120 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1121 return false;
9c19a809
NC
1122 }
1123}
252b5132 1124
dda8d76d 1125/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1126 Returns TRUE upon success, FALSE otherwise. If successful then a
1127 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1128 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1129 responsibility to free the allocated buffer. */
1130
015dc7e1 1131static bool
dda8d76d
NC
1132slurp_rela_relocs (Filedata * filedata,
1133 unsigned long rel_offset,
1134 unsigned long rel_size,
1135 Elf_Internal_Rela ** relasp,
1136 unsigned long * nrelasp)
9c19a809 1137{
2cf0635d 1138 Elf_Internal_Rela * relas;
8b73c356 1139 size_t nrelas;
4d6ed7c8 1140 unsigned int i;
252b5132 1141
4d6ed7c8
NC
1142 if (is_32bit_elf)
1143 {
2cf0635d 1144 Elf32_External_Rela * erelas;
103f02d3 1145
dda8d76d 1146 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1147 rel_size, _("32-bit relocation data"));
a6e9f9df 1148 if (!erelas)
015dc7e1 1149 return false;
252b5132 1150
4d6ed7c8 1151 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1152
3f5e193b
NC
1153 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1154 sizeof (Elf_Internal_Rela));
103f02d3 1155
4d6ed7c8
NC
1156 if (relas == NULL)
1157 {
c256ffe7 1158 free (erelas);
591a748a 1159 error (_("out of memory parsing relocs\n"));
015dc7e1 1160 return false;
4d6ed7c8 1161 }
103f02d3 1162
4d6ed7c8
NC
1163 for (i = 0; i < nrelas; i++)
1164 {
1165 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1166 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1167 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1168 }
103f02d3 1169
4d6ed7c8
NC
1170 free (erelas);
1171 }
1172 else
1173 {
2cf0635d 1174 Elf64_External_Rela * erelas;
103f02d3 1175
dda8d76d 1176 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1177 rel_size, _("64-bit relocation data"));
a6e9f9df 1178 if (!erelas)
015dc7e1 1179 return false;
4d6ed7c8
NC
1180
1181 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1182
3f5e193b
NC
1183 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1184 sizeof (Elf_Internal_Rela));
103f02d3 1185
4d6ed7c8
NC
1186 if (relas == NULL)
1187 {
c256ffe7 1188 free (erelas);
591a748a 1189 error (_("out of memory parsing relocs\n"));
015dc7e1 1190 return false;
9c19a809 1191 }
4d6ed7c8
NC
1192
1193 for (i = 0; i < nrelas; i++)
9c19a809 1194 {
66543521
AM
1195 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1196 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1197 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a 1198
dda8d76d
NC
1199 if (filedata->file_header.e_machine == EM_MIPS
1200 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1201 {
1202 /* In little-endian objects, r_info isn't really a
1203 64-bit little-endian value: it has a 32-bit
1204 little-endian symbol index followed by four
1205 individual byte fields. Reorder INFO
1206 accordingly. */
625d49fc 1207 uint64_t inf = relas[i].r_info;
91d6fa6a
NC
1208 inf = (((inf & 0xffffffff) << 32)
1209 | ((inf >> 56) & 0xff)
1210 | ((inf >> 40) & 0xff00)
1211 | ((inf >> 24) & 0xff0000)
1212 | ((inf >> 8) & 0xff000000));
1213 relas[i].r_info = inf;
861fb55a 1214 }
4d6ed7c8 1215 }
103f02d3 1216
4d6ed7c8
NC
1217 free (erelas);
1218 }
32ec8896 1219
4d6ed7c8
NC
1220 *relasp = relas;
1221 *nrelasp = nrelas;
015dc7e1 1222 return true;
4d6ed7c8 1223}
103f02d3 1224
dda8d76d 1225/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1226 Returns TRUE upon success, FALSE otherwise. If successful then a
1227 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1228 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1229 responsibility to free the allocated buffer. */
1230
015dc7e1 1231static bool
dda8d76d
NC
1232slurp_rel_relocs (Filedata * filedata,
1233 unsigned long rel_offset,
1234 unsigned long rel_size,
1235 Elf_Internal_Rela ** relsp,
1236 unsigned long * nrelsp)
4d6ed7c8 1237{
2cf0635d 1238 Elf_Internal_Rela * rels;
8b73c356 1239 size_t nrels;
4d6ed7c8 1240 unsigned int i;
103f02d3 1241
4d6ed7c8
NC
1242 if (is_32bit_elf)
1243 {
2cf0635d 1244 Elf32_External_Rel * erels;
103f02d3 1245
dda8d76d 1246 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1247 rel_size, _("32-bit relocation data"));
a6e9f9df 1248 if (!erels)
015dc7e1 1249 return false;
103f02d3 1250
4d6ed7c8 1251 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1252
3f5e193b 1253 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1254
4d6ed7c8
NC
1255 if (rels == NULL)
1256 {
c256ffe7 1257 free (erels);
591a748a 1258 error (_("out of memory parsing relocs\n"));
015dc7e1 1259 return false;
4d6ed7c8
NC
1260 }
1261
1262 for (i = 0; i < nrels; i++)
1263 {
1264 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1265 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1266 rels[i].r_addend = 0;
9ea033b2 1267 }
4d6ed7c8
NC
1268
1269 free (erels);
9c19a809
NC
1270 }
1271 else
1272 {
2cf0635d 1273 Elf64_External_Rel * erels;
9ea033b2 1274
dda8d76d 1275 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1276 rel_size, _("64-bit relocation data"));
a6e9f9df 1277 if (!erels)
015dc7e1 1278 return false;
103f02d3 1279
4d6ed7c8 1280 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1281
3f5e193b 1282 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1283
4d6ed7c8 1284 if (rels == NULL)
9c19a809 1285 {
c256ffe7 1286 free (erels);
591a748a 1287 error (_("out of memory parsing relocs\n"));
015dc7e1 1288 return false;
4d6ed7c8 1289 }
103f02d3 1290
4d6ed7c8
NC
1291 for (i = 0; i < nrels; i++)
1292 {
66543521
AM
1293 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1294 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1295 rels[i].r_addend = 0;
861fb55a 1296
dda8d76d
NC
1297 if (filedata->file_header.e_machine == EM_MIPS
1298 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1299 {
1300 /* In little-endian objects, r_info isn't really a
1301 64-bit little-endian value: it has a 32-bit
1302 little-endian symbol index followed by four
1303 individual byte fields. Reorder INFO
1304 accordingly. */
625d49fc 1305 uint64_t inf = rels[i].r_info;
91d6fa6a
NC
1306 inf = (((inf & 0xffffffff) << 32)
1307 | ((inf >> 56) & 0xff)
1308 | ((inf >> 40) & 0xff00)
1309 | ((inf >> 24) & 0xff0000)
1310 | ((inf >> 8) & 0xff000000));
1311 rels[i].r_info = inf;
861fb55a 1312 }
4d6ed7c8 1313 }
103f02d3 1314
4d6ed7c8
NC
1315 free (erels);
1316 }
32ec8896 1317
4d6ed7c8
NC
1318 *relsp = rels;
1319 *nrelsp = nrels;
015dc7e1 1320 return true;
4d6ed7c8 1321}
103f02d3 1322
a7fd1186
FS
1323static bool
1324slurp_relr_relocs (Filedata * filedata,
1325 unsigned long relr_offset,
1326 unsigned long relr_size,
625d49fc 1327 uint64_t ** relrsp,
a7fd1186
FS
1328 unsigned long * nrelrsp)
1329{
1330 void *relrs;
1331 size_t size = 0, nentries, i;
625d49fc 1332 uint64_t base = 0, addr, entry;
a7fd1186
FS
1333
1334 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1335 _("RELR relocation data"));
1336 if (!relrs)
1337 return false;
1338
1339 if (is_32bit_elf)
1340 nentries = relr_size / sizeof (Elf32_External_Relr);
1341 else
1342 nentries = relr_size / sizeof (Elf64_External_Relr);
1343 for (i = 0; i < nentries; i++)
1344 {
1345 if (is_32bit_elf)
1346 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1347 else
1348 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1349 if ((entry & 1) == 0)
1350 size++;
1351 else
1352 while ((entry >>= 1) != 0)
1353 if ((entry & 1) == 1)
1354 size++;
1355 }
1356
625d49fc 1357 *relrsp = malloc (size * sizeof (**relrsp));
a7fd1186
FS
1358 if (*relrsp == NULL)
1359 {
1360 free (relrs);
1361 error (_("out of memory parsing relocs\n"));
1362 return false;
1363 }
1364
1365 size = 0;
1366 for (i = 0; i < nentries; i++)
1367 {
625d49fc 1368 const uint64_t entry_bytes = is_32bit_elf ? 4 : 8;
a7fd1186
FS
1369
1370 if (is_32bit_elf)
1371 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1372 else
1373 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1374 if ((entry & 1) == 0)
1375 {
1376 (*relrsp)[size++] = entry;
1377 base = entry + entry_bytes;
1378 }
1379 else
1380 {
1381 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1382 if ((entry & 1) != 0)
1383 (*relrsp)[size++] = addr;
1384 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1385 }
1386 }
1387
1388 *nrelrsp = size;
1389 free (relrs);
1390 return true;
1391}
1392
aca88567
NC
1393/* Returns the reloc type extracted from the reloc info field. */
1394
1395static unsigned int
625d49fc 1396get_reloc_type (Filedata * filedata, uint64_t reloc_info)
aca88567
NC
1397{
1398 if (is_32bit_elf)
1399 return ELF32_R_TYPE (reloc_info);
1400
dda8d76d 1401 switch (filedata->file_header.e_machine)
aca88567
NC
1402 {
1403 case EM_MIPS:
1404 /* Note: We assume that reloc_info has already been adjusted for us. */
1405 return ELF64_MIPS_R_TYPE (reloc_info);
1406
1407 case EM_SPARCV9:
1408 return ELF64_R_TYPE_ID (reloc_info);
1409
1410 default:
1411 return ELF64_R_TYPE (reloc_info);
1412 }
1413}
1414
1415/* Return the symbol index extracted from the reloc info field. */
1416
625d49fc
AM
1417static uint64_t
1418get_reloc_symindex (uint64_t reloc_info)
aca88567
NC
1419{
1420 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1421}
1422
015dc7e1 1423static inline bool
dda8d76d 1424uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1425{
1426 return
dda8d76d 1427 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1428 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1429 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1430 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1431 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1432}
1433
d3ba0551
AM
1434/* Display the contents of the relocation data found at the specified
1435 offset. */
ee42cf8c 1436
015dc7e1 1437static bool
dda8d76d
NC
1438dump_relocations (Filedata * filedata,
1439 unsigned long rel_offset,
1440 unsigned long rel_size,
1441 Elf_Internal_Sym * symtab,
1442 unsigned long nsyms,
1443 char * strtab,
1444 unsigned long strtablen,
a7fd1186 1445 relocation_type rel_type,
015dc7e1 1446 bool is_dynsym)
4d6ed7c8 1447{
32ec8896 1448 unsigned long i;
2cf0635d 1449 Elf_Internal_Rela * rels;
015dc7e1 1450 bool res = true;
103f02d3 1451
a7fd1186
FS
1452 if (rel_type == reltype_unknown)
1453 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1454
a7fd1186 1455 if (rel_type == reltype_rela)
4d6ed7c8 1456 {
dda8d76d 1457 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1458 return false;
4d6ed7c8 1459 }
a7fd1186 1460 else if (rel_type == reltype_rel)
4d6ed7c8 1461 {
dda8d76d 1462 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1463 return false;
252b5132 1464 }
a7fd1186
FS
1465 else if (rel_type == reltype_relr)
1466 {
625d49fc 1467 uint64_t * relrs;
a7fd1186 1468 const char *format
b8281767 1469 = is_32bit_elf ? "%08" PRIx64 "\n" : "%016" PRIx64 "\n";
a7fd1186
FS
1470
1471 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1472 &rel_size))
1473 return false;
1474
b8281767
AM
1475 printf (ngettext (" %lu offset\n", " %lu offsets\n", rel_size),
1476 rel_size);
a7fd1186 1477 for (i = 0; i < rel_size; i++)
625d49fc 1478 printf (format, relrs[i]);
a7fd1186
FS
1479 free (relrs);
1480 return true;
1481 }
252b5132 1482
410f7a12
L
1483 if (is_32bit_elf)
1484 {
a7fd1186 1485 if (rel_type == reltype_rela)
2c71103e
NC
1486 {
1487 if (do_wide)
1488 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1489 else
1490 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1491 }
410f7a12 1492 else
2c71103e
NC
1493 {
1494 if (do_wide)
1495 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1496 else
1497 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1498 }
410f7a12 1499 }
252b5132 1500 else
410f7a12 1501 {
a7fd1186 1502 if (rel_type == reltype_rela)
2c71103e
NC
1503 {
1504 if (do_wide)
8beeaeb7 1505 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1506 else
1507 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1508 }
410f7a12 1509 else
2c71103e
NC
1510 {
1511 if (do_wide)
8beeaeb7 1512 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1513 else
1514 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1515 }
410f7a12 1516 }
252b5132
RH
1517
1518 for (i = 0; i < rel_size; i++)
1519 {
2cf0635d 1520 const char * rtype;
625d49fc
AM
1521 uint64_t offset;
1522 uint64_t inf;
1523 uint64_t symtab_index;
1524 uint64_t type;
103f02d3 1525
b34976b6 1526 offset = rels[i].r_offset;
91d6fa6a 1527 inf = rels[i].r_info;
103f02d3 1528
dda8d76d 1529 type = get_reloc_type (filedata, inf);
91d6fa6a 1530 symtab_index = get_reloc_symindex (inf);
252b5132 1531
410f7a12
L
1532 if (is_32bit_elf)
1533 {
39dbeff8
AM
1534 printf ("%8.8lx %8.8lx ",
1535 (unsigned long) offset & 0xffffffff,
91d6fa6a 1536 (unsigned long) inf & 0xffffffff);
410f7a12
L
1537 }
1538 else
1539 {
39dbeff8 1540 printf (do_wide
b8281767
AM
1541 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
1542 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
625d49fc 1543 offset, inf);
410f7a12 1544 }
103f02d3 1545
dda8d76d 1546 switch (filedata->file_header.e_machine)
252b5132
RH
1547 {
1548 default:
1549 rtype = NULL;
1550 break;
1551
a06ea964
NC
1552 case EM_AARCH64:
1553 rtype = elf_aarch64_reloc_type (type);
1554 break;
1555
2b0337b0 1556 case EM_M32R:
252b5132 1557 case EM_CYGNUS_M32R:
9ea033b2 1558 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1559 break;
1560
1561 case EM_386:
22abe556 1562 case EM_IAMCU:
9ea033b2 1563 rtype = elf_i386_reloc_type (type);
252b5132
RH
1564 break;
1565
ba2685cc
AM
1566 case EM_68HC11:
1567 case EM_68HC12:
1568 rtype = elf_m68hc11_reloc_type (type);
1569 break;
75751cd9 1570
7b4ae824
JD
1571 case EM_S12Z:
1572 rtype = elf_s12z_reloc_type (type);
1573 break;
1574
252b5132 1575 case EM_68K:
9ea033b2 1576 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1577 break;
1578
f954747f
AM
1579 case EM_960:
1580 rtype = elf_i960_reloc_type (type);
1581 break;
1582
adde6300 1583 case EM_AVR:
2b0337b0 1584 case EM_AVR_OLD:
adde6300
AM
1585 rtype = elf_avr_reloc_type (type);
1586 break;
1587
9ea033b2
NC
1588 case EM_OLD_SPARCV9:
1589 case EM_SPARC32PLUS:
1590 case EM_SPARCV9:
252b5132 1591 case EM_SPARC:
9ea033b2 1592 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1593 break;
1594
e9f53129
AM
1595 case EM_SPU:
1596 rtype = elf_spu_reloc_type (type);
1597 break;
1598
708e2187
NC
1599 case EM_V800:
1600 rtype = v800_reloc_type (type);
1601 break;
2b0337b0 1602 case EM_V850:
252b5132 1603 case EM_CYGNUS_V850:
9ea033b2 1604 rtype = v850_reloc_type (type);
252b5132
RH
1605 break;
1606
2b0337b0 1607 case EM_D10V:
252b5132 1608 case EM_CYGNUS_D10V:
9ea033b2 1609 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1610 break;
1611
2b0337b0 1612 case EM_D30V:
252b5132 1613 case EM_CYGNUS_D30V:
9ea033b2 1614 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1615 break;
1616
d172d4ba
NC
1617 case EM_DLX:
1618 rtype = elf_dlx_reloc_type (type);
1619 break;
1620
252b5132 1621 case EM_SH:
9ea033b2 1622 rtype = elf_sh_reloc_type (type);
252b5132
RH
1623 break;
1624
2b0337b0 1625 case EM_MN10300:
252b5132 1626 case EM_CYGNUS_MN10300:
9ea033b2 1627 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1628 break;
1629
2b0337b0 1630 case EM_MN10200:
252b5132 1631 case EM_CYGNUS_MN10200:
9ea033b2 1632 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1633 break;
1634
2b0337b0 1635 case EM_FR30:
252b5132 1636 case EM_CYGNUS_FR30:
9ea033b2 1637 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1638 break;
1639
ba2685cc
AM
1640 case EM_CYGNUS_FRV:
1641 rtype = elf_frv_reloc_type (type);
1642 break;
5c70f934 1643
b8891f8d
AJ
1644 case EM_CSKY:
1645 rtype = elf_csky_reloc_type (type);
1646 break;
1647
3f8107ab
AM
1648 case EM_FT32:
1649 rtype = elf_ft32_reloc_type (type);
1650 break;
1651
252b5132 1652 case EM_MCORE:
9ea033b2 1653 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1654 break;
1655
3c3bdf30
NC
1656 case EM_MMIX:
1657 rtype = elf_mmix_reloc_type (type);
1658 break;
1659
5506d11a
AM
1660 case EM_MOXIE:
1661 rtype = elf_moxie_reloc_type (type);
1662 break;
1663
2469cfa2 1664 case EM_MSP430:
dda8d76d 1665 if (uses_msp430x_relocs (filedata))
13761a11
NC
1666 {
1667 rtype = elf_msp430x_reloc_type (type);
1668 break;
1669 }
1a0670f3 1670 /* Fall through. */
2469cfa2
NC
1671 case EM_MSP430_OLD:
1672 rtype = elf_msp430_reloc_type (type);
1673 break;
1674
35c08157
KLC
1675 case EM_NDS32:
1676 rtype = elf_nds32_reloc_type (type);
1677 break;
1678
252b5132 1679 case EM_PPC:
9ea033b2 1680 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1681 break;
1682
c833c019
AM
1683 case EM_PPC64:
1684 rtype = elf_ppc64_reloc_type (type);
1685 break;
1686
252b5132 1687 case EM_MIPS:
4fe85591 1688 case EM_MIPS_RS3_LE:
9ea033b2 1689 rtype = elf_mips_reloc_type (type);
252b5132
RH
1690 break;
1691
e23eba97
NC
1692 case EM_RISCV:
1693 rtype = elf_riscv_reloc_type (type);
1694 break;
1695
252b5132 1696 case EM_ALPHA:
9ea033b2 1697 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1698 break;
1699
1700 case EM_ARM:
9ea033b2 1701 rtype = elf_arm_reloc_type (type);
252b5132
RH
1702 break;
1703
584da044 1704 case EM_ARC:
886a2506
NC
1705 case EM_ARC_COMPACT:
1706 case EM_ARC_COMPACT2:
9ea033b2 1707 rtype = elf_arc_reloc_type (type);
252b5132
RH
1708 break;
1709
1710 case EM_PARISC:
69e617ca 1711 rtype = elf_hppa_reloc_type (type);
252b5132 1712 break;
7d466069 1713
b8720f9d
JL
1714 case EM_H8_300:
1715 case EM_H8_300H:
1716 case EM_H8S:
1717 rtype = elf_h8_reloc_type (type);
1718 break;
1719
73589c9d
CS
1720 case EM_OR1K:
1721 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1722 break;
1723
7d466069 1724 case EM_PJ:
2b0337b0 1725 case EM_PJ_OLD:
7d466069
ILT
1726 rtype = elf_pj_reloc_type (type);
1727 break;
800eeca4
JW
1728 case EM_IA_64:
1729 rtype = elf_ia64_reloc_type (type);
1730 break;
1b61cf92
HPN
1731
1732 case EM_CRIS:
1733 rtype = elf_cris_reloc_type (type);
1734 break;
535c37ff 1735
f954747f
AM
1736 case EM_860:
1737 rtype = elf_i860_reloc_type (type);
1738 break;
1739
bcedfee6 1740 case EM_X86_64:
8a9036a4 1741 case EM_L1OM:
7a9068fe 1742 case EM_K1OM:
bcedfee6
NC
1743 rtype = elf_x86_64_reloc_type (type);
1744 break;
a85d7ed0 1745
f954747f
AM
1746 case EM_S370:
1747 rtype = i370_reloc_type (type);
1748 break;
1749
53c7db4b
KH
1750 case EM_S390_OLD:
1751 case EM_S390:
1752 rtype = elf_s390_reloc_type (type);
1753 break;
93fbbb04 1754
1c0d3aa6
NC
1755 case EM_SCORE:
1756 rtype = elf_score_reloc_type (type);
1757 break;
1758
93fbbb04
GK
1759 case EM_XSTORMY16:
1760 rtype = elf_xstormy16_reloc_type (type);
1761 break;
179d3252 1762
1fe1f39c
NC
1763 case EM_CRX:
1764 rtype = elf_crx_reloc_type (type);
1765 break;
1766
179d3252
JT
1767 case EM_VAX:
1768 rtype = elf_vax_reloc_type (type);
1769 break;
1e4cf259 1770
619ed720
EB
1771 case EM_VISIUM:
1772 rtype = elf_visium_reloc_type (type);
1773 break;
1774
aca4efc7
JM
1775 case EM_BPF:
1776 rtype = elf_bpf_reloc_type (type);
1777 break;
1778
cfb8c092
NC
1779 case EM_ADAPTEVA_EPIPHANY:
1780 rtype = elf_epiphany_reloc_type (type);
1781 break;
1782
1e4cf259
NC
1783 case EM_IP2K:
1784 case EM_IP2K_OLD:
1785 rtype = elf_ip2k_reloc_type (type);
1786 break;
3b36097d
SC
1787
1788 case EM_IQ2000:
1789 rtype = elf_iq2000_reloc_type (type);
1790 break;
88da6820
NC
1791
1792 case EM_XTENSA_OLD:
1793 case EM_XTENSA:
1794 rtype = elf_xtensa_reloc_type (type);
1795 break;
a34e3ecb 1796
84e94c90
NC
1797 case EM_LATTICEMICO32:
1798 rtype = elf_lm32_reloc_type (type);
1799 break;
1800
ff7eeb89 1801 case EM_M32C_OLD:
49f58d10
JB
1802 case EM_M32C:
1803 rtype = elf_m32c_reloc_type (type);
1804 break;
1805
d031aafb
NS
1806 case EM_MT:
1807 rtype = elf_mt_reloc_type (type);
a34e3ecb 1808 break;
1d65ded4
CM
1809
1810 case EM_BLACKFIN:
1811 rtype = elf_bfin_reloc_type (type);
1812 break;
15ab5209
DB
1813
1814 case EM_CYGNUS_MEP:
1815 rtype = elf_mep_reloc_type (type);
1816 break;
60bca95a
NC
1817
1818 case EM_CR16:
1819 rtype = elf_cr16_reloc_type (type);
1820 break;
dd24e3da 1821
7ba29e2a
NC
1822 case EM_MICROBLAZE:
1823 case EM_MICROBLAZE_OLD:
1824 rtype = elf_microblaze_reloc_type (type);
1825 break;
c7927a3c 1826
99c513f6
DD
1827 case EM_RL78:
1828 rtype = elf_rl78_reloc_type (type);
1829 break;
1830
c7927a3c
NC
1831 case EM_RX:
1832 rtype = elf_rx_reloc_type (type);
1833 break;
c29aca4a 1834
a3c62988
NC
1835 case EM_METAG:
1836 rtype = elf_metag_reloc_type (type);
1837 break;
1838
40b36596
JM
1839 case EM_TI_C6000:
1840 rtype = elf_tic6x_reloc_type (type);
1841 break;
aa137e4d
NC
1842
1843 case EM_TILEGX:
1844 rtype = elf_tilegx_reloc_type (type);
1845 break;
1846
1847 case EM_TILEPRO:
1848 rtype = elf_tilepro_reloc_type (type);
1849 break;
f6c1a2d5 1850
f96bd6c2
PC
1851 case EM_WEBASSEMBLY:
1852 rtype = elf_wasm32_reloc_type (type);
1853 break;
1854
f6c1a2d5
NC
1855 case EM_XGATE:
1856 rtype = elf_xgate_reloc_type (type);
1857 break;
36591ba1
SL
1858
1859 case EM_ALTERA_NIOS2:
1860 rtype = elf_nios2_reloc_type (type);
1861 break;
2b100bb5
DD
1862
1863 case EM_TI_PRU:
1864 rtype = elf_pru_reloc_type (type);
1865 break;
fe944acf
FT
1866
1867 case EM_NFP:
1868 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1869 rtype = elf_nfp3200_reloc_type (type);
1870 else
1871 rtype = elf_nfp_reloc_type (type);
1872 break;
6655dba2
SB
1873
1874 case EM_Z80:
1875 rtype = elf_z80_reloc_type (type);
1876 break;
e9a0721f 1877
1878 case EM_LOONGARCH:
1879 rtype = elf_loongarch_reloc_type (type);
1880 break;
1881
0c857ef4
SM
1882 case EM_AMDGPU:
1883 rtype = elf_amdgpu_reloc_type (type);
1884 break;
252b5132
RH
1885 }
1886
1887 if (rtype == NULL)
39dbeff8 1888 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1889 else
5c144731 1890 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1891
dda8d76d 1892 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1893 && rtype != NULL
7ace3541 1894 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 1895 && rel_type == reltype_rela)
7ace3541
RH
1896 {
1897 switch (rels[i].r_addend)
1898 {
1899 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1900 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1901 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1902 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1903 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1904 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1905 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1906 default: rtype = NULL;
1907 }
32ec8896 1908
7ace3541
RH
1909 if (rtype)
1910 printf (" (%s)", rtype);
1911 else
1912 {
1913 putchar (' ');
1914 printf (_("<unknown addend: %lx>"),
1915 (unsigned long) rels[i].r_addend);
015dc7e1 1916 res = false;
7ace3541
RH
1917 }
1918 }
1919 else if (symtab_index)
252b5132 1920 {
af3fc3bc 1921 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1922 {
27a45f42
AS
1923 error (_(" bad symbol index: %08lx in reloc\n"),
1924 (unsigned long) symtab_index);
015dc7e1 1925 res = false;
32ec8896 1926 }
af3fc3bc 1927 else
19936277 1928 {
2cf0635d 1929 Elf_Internal_Sym * psym;
bb4d2ac2
L
1930 const char * version_string;
1931 enum versioned_symbol_info sym_info;
1932 unsigned short vna_other;
19936277 1933
af3fc3bc 1934 psym = symtab + symtab_index;
103f02d3 1935
bb4d2ac2 1936 version_string
dda8d76d 1937 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1938 strtab, strtablen,
1939 symtab_index,
1940 psym,
1941 &sym_info,
1942 &vna_other);
1943
af3fc3bc 1944 printf (" ");
171191ba 1945
d8045f23
NC
1946 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1947 {
1948 const char * name;
1949 unsigned int len;
1950 unsigned int width = is_32bit_elf ? 8 : 14;
1951
1952 /* Relocations against GNU_IFUNC symbols do not use the value
1953 of the symbol as the address to relocate against. Instead
1954 they invoke the function named by the symbol and use its
1955 result as the address for relocation.
1956
1957 To indicate this to the user, do not display the value of
1958 the symbol in the "Symbols's Value" field. Instead show
1959 its name followed by () as a hint that the symbol is
1960 invoked. */
1961
1962 if (strtab == NULL
1963 || psym->st_name == 0
1964 || psym->st_name >= strtablen)
1965 name = "??";
1966 else
1967 name = strtab + psym->st_name;
1968
1969 len = print_symbol (width, name);
bb4d2ac2
L
1970 if (version_string)
1971 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1972 version_string);
d8045f23
NC
1973 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1974 }
1975 else
1976 {
1977 print_vma (psym->st_value, LONG_HEX);
171191ba 1978
d8045f23
NC
1979 printf (is_32bit_elf ? " " : " ");
1980 }
103f02d3 1981
af3fc3bc 1982 if (psym->st_name == 0)
f1ef08cb 1983 {
2cf0635d 1984 const char * sec_name = "<null>";
f1ef08cb
AM
1985 char name_buf[40];
1986
1987 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1988 {
b9af6379
AM
1989 if (psym->st_shndx < filedata->file_header.e_shnum
1990 && filedata->section_headers != NULL)
84714f86
AM
1991 sec_name = section_name_print (filedata,
1992 filedata->section_headers
b9e920ec 1993 + psym->st_shndx);
f1ef08cb
AM
1994 else if (psym->st_shndx == SHN_ABS)
1995 sec_name = "ABS";
1996 else if (psym->st_shndx == SHN_COMMON)
1997 sec_name = "COMMON";
dda8d76d 1998 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1999 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 2000 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 2001 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 2002 sec_name = "SCOMMON";
dda8d76d 2003 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
2004 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
2005 sec_name = "SUNDEF";
dda8d76d
NC
2006 else if ((filedata->file_header.e_machine == EM_X86_64
2007 || filedata->file_header.e_machine == EM_L1OM
2008 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
2009 && psym->st_shndx == SHN_X86_64_LCOMMON)
2010 sec_name = "LARGE_COMMON";
dda8d76d
NC
2011 else if (filedata->file_header.e_machine == EM_IA_64
2012 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
2013 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
2014 sec_name = "ANSI_COM";
dda8d76d 2015 else if (is_ia64_vms (filedata)
148b93f2
NC
2016 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
2017 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
2018 else
2019 {
2020 sprintf (name_buf, "<section 0x%x>",
2021 (unsigned int) psym->st_shndx);
2022 sec_name = name_buf;
2023 }
2024 }
2025 print_symbol (22, sec_name);
2026 }
af3fc3bc 2027 else if (strtab == NULL)
d79b3d50 2028 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2029 else if (psym->st_name >= strtablen)
32ec8896 2030 {
27a45f42
AS
2031 error (_("<corrupt string table index: %3ld>\n"),
2032 psym->st_name);
015dc7e1 2033 res = false;
32ec8896 2034 }
af3fc3bc 2035 else
bb4d2ac2
L
2036 {
2037 print_symbol (22, strtab + psym->st_name);
2038 if (version_string)
2039 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2040 version_string);
2041 }
103f02d3 2042
a7fd1186 2043 if (rel_type == reltype_rela)
171191ba 2044 {
625d49fc 2045 uint64_t off = rels[i].r_addend;
171191ba 2046
625d49fc
AM
2047 if ((int64_t) off < 0)
2048 printf (" - %" PRIx64, -off);
171191ba 2049 else
625d49fc 2050 printf (" + %" PRIx64, off);
171191ba 2051 }
19936277 2052 }
252b5132 2053 }
a7fd1186 2054 else if (rel_type == reltype_rela)
f7a99963 2055 {
625d49fc 2056 uint64_t off = rels[i].r_addend;
e04d7088
L
2057
2058 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
625d49fc
AM
2059 if ((int64_t) off < 0)
2060 printf ("-%" PRIx64, -off);
e04d7088 2061 else
625d49fc 2062 printf ("%" PRIx64, off);
f7a99963 2063 }
252b5132 2064
dda8d76d 2065 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2066 && rtype != NULL
2067 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 2068 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 2069
252b5132 2070 putchar ('\n');
2c71103e 2071
dda8d76d 2072 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2073 {
625d49fc
AM
2074 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2075 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2076 const char * rtype2 = elf_mips_reloc_type (type2);
2077 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2078
2c71103e
NC
2079 printf (" Type2: ");
2080
2081 if (rtype2 == NULL)
39dbeff8
AM
2082 printf (_("unrecognized: %-7lx"),
2083 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2084 else
2085 printf ("%-17.17s", rtype2);
2086
18bd398b 2087 printf ("\n Type3: ");
2c71103e
NC
2088
2089 if (rtype3 == NULL)
39dbeff8
AM
2090 printf (_("unrecognized: %-7lx"),
2091 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2092 else
2093 printf ("%-17.17s", rtype3);
2094
53c7db4b 2095 putchar ('\n');
2c71103e 2096 }
252b5132
RH
2097 }
2098
c8286bd1 2099 free (rels);
32ec8896
NC
2100
2101 return res;
252b5132
RH
2102}
2103
37c18eed
SD
2104static const char *
2105get_aarch64_dynamic_type (unsigned long type)
2106{
2107 switch (type)
2108 {
2109 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2110 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2111 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2112 default:
2113 return NULL;
2114 }
2115}
2116
252b5132 2117static const char *
d3ba0551 2118get_mips_dynamic_type (unsigned long type)
252b5132
RH
2119{
2120 switch (type)
2121 {
2122 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2123 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2124 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2125 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2126 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2127 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2128 case DT_MIPS_MSYM: return "MIPS_MSYM";
2129 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2130 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2131 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2132 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2133 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2134 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2135 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2136 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2137 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2138 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2139 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2140 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2141 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2142 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2143 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2144 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2145 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2146 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2147 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2148 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2149 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2150 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2151 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2152 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2153 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2154 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2155 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2156 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2157 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2158 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2159 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2160 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2161 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2162 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2163 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2164 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2165 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2166 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2167 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2168 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2169 default:
2170 return NULL;
2171 }
2172}
2173
9a097730 2174static const char *
d3ba0551 2175get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2176{
2177 switch (type)
2178 {
2179 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2180 default:
2181 return NULL;
2182 }
103f02d3
UD
2183}
2184
7490d522
AM
2185static const char *
2186get_ppc_dynamic_type (unsigned long type)
2187{
2188 switch (type)
2189 {
a7f2871e 2190 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2191 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2192 default:
2193 return NULL;
2194 }
2195}
2196
f1cb7e17 2197static const char *
d3ba0551 2198get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2199{
2200 switch (type)
2201 {
a7f2871e
AM
2202 case DT_PPC64_GLINK: return "PPC64_GLINK";
2203 case DT_PPC64_OPD: return "PPC64_OPD";
2204 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2205 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2206 default:
2207 return NULL;
2208 }
2209}
2210
103f02d3 2211static const char *
d3ba0551 2212get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2213{
2214 switch (type)
2215 {
2216 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2217 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2218 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2219 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2220 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2221 case DT_HP_PREINIT: return "HP_PREINIT";
2222 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2223 case DT_HP_NEEDED: return "HP_NEEDED";
2224 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2225 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2226 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2227 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2228 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2229 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2230 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2231 case DT_HP_FILTERED: return "HP_FILTERED";
2232 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2233 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2234 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2235 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2236 case DT_PLT: return "PLT";
2237 case DT_PLT_SIZE: return "PLT_SIZE";
2238 case DT_DLT: return "DLT";
2239 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2240 default:
2241 return NULL;
2242 }
2243}
9a097730 2244
ecc51f48 2245static const char *
d3ba0551 2246get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2247{
2248 switch (type)
2249 {
148b93f2
NC
2250 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2251 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2252 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2253 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2254 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2255 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2256 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2257 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2258 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2259 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2260 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2261 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2262 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2263 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2264 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2265 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2266 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2267 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2268 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2269 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2270 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2271 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2272 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2273 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2274 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2275 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2276 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2277 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2278 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2279 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2280 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2281 default:
2282 return NULL;
2283 }
2284}
2285
fd85a6a1
NC
2286static const char *
2287get_solaris_section_type (unsigned long type)
2288{
2289 switch (type)
2290 {
2291 case 0x6fffffee: return "SUNW_ancillary";
2292 case 0x6fffffef: return "SUNW_capchain";
2293 case 0x6ffffff0: return "SUNW_capinfo";
2294 case 0x6ffffff1: return "SUNW_symsort";
2295 case 0x6ffffff2: return "SUNW_tlssort";
2296 case 0x6ffffff3: return "SUNW_LDYNSYM";
2297 case 0x6ffffff4: return "SUNW_dof";
2298 case 0x6ffffff5: return "SUNW_cap";
2299 case 0x6ffffff6: return "SUNW_SIGNATURE";
2300 case 0x6ffffff7: return "SUNW_ANNOTATE";
2301 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2302 case 0x6ffffff9: return "SUNW_DEBUG";
2303 case 0x6ffffffa: return "SUNW_move";
2304 case 0x6ffffffb: return "SUNW_COMDAT";
2305 case 0x6ffffffc: return "SUNW_syminfo";
2306 case 0x6ffffffd: return "SUNW_verdef";
2307 case 0x6ffffffe: return "SUNW_verneed";
2308 case 0x6fffffff: return "SUNW_versym";
2309 case 0x70000000: return "SPARC_GOTDATA";
2310 default: return NULL;
2311 }
2312}
2313
fabcb361
RH
2314static const char *
2315get_alpha_dynamic_type (unsigned long type)
2316{
2317 switch (type)
2318 {
2319 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2320 default: return NULL;
fabcb361
RH
2321 }
2322}
2323
1c0d3aa6
NC
2324static const char *
2325get_score_dynamic_type (unsigned long type)
2326{
2327 switch (type)
2328 {
2329 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2330 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2331 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2332 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2333 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2334 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2335 default: return NULL;
1c0d3aa6
NC
2336 }
2337}
2338
40b36596
JM
2339static const char *
2340get_tic6x_dynamic_type (unsigned long type)
2341{
2342 switch (type)
2343 {
2344 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2345 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2346 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2347 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2348 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2349 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2350 default: return NULL;
40b36596
JM
2351 }
2352}
1c0d3aa6 2353
36591ba1
SL
2354static const char *
2355get_nios2_dynamic_type (unsigned long type)
2356{
2357 switch (type)
2358 {
2359 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2360 default: return NULL;
36591ba1
SL
2361 }
2362}
2363
fd85a6a1
NC
2364static const char *
2365get_solaris_dynamic_type (unsigned long type)
2366{
2367 switch (type)
2368 {
2369 case 0x6000000d: return "SUNW_AUXILIARY";
2370 case 0x6000000e: return "SUNW_RTLDINF";
2371 case 0x6000000f: return "SUNW_FILTER";
2372 case 0x60000010: return "SUNW_CAP";
2373 case 0x60000011: return "SUNW_SYMTAB";
2374 case 0x60000012: return "SUNW_SYMSZ";
2375 case 0x60000013: return "SUNW_SORTENT";
2376 case 0x60000014: return "SUNW_SYMSORT";
2377 case 0x60000015: return "SUNW_SYMSORTSZ";
2378 case 0x60000016: return "SUNW_TLSSORT";
2379 case 0x60000017: return "SUNW_TLSSORTSZ";
2380 case 0x60000018: return "SUNW_CAPINFO";
2381 case 0x60000019: return "SUNW_STRPAD";
2382 case 0x6000001a: return "SUNW_CAPCHAIN";
2383 case 0x6000001b: return "SUNW_LDMACH";
2384 case 0x6000001d: return "SUNW_CAPCHAINENT";
2385 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2386 case 0x60000021: return "SUNW_PARENT";
2387 case 0x60000023: return "SUNW_ASLR";
2388 case 0x60000025: return "SUNW_RELAX";
2389 case 0x60000029: return "SUNW_NXHEAP";
2390 case 0x6000002b: return "SUNW_NXSTACK";
2391
2392 case 0x70000001: return "SPARC_REGISTER";
2393 case 0x7ffffffd: return "AUXILIARY";
2394 case 0x7ffffffe: return "USED";
2395 case 0x7fffffff: return "FILTER";
2396
15f205b1 2397 default: return NULL;
fd85a6a1
NC
2398 }
2399}
2400
8155b853
NC
2401static const char *
2402get_riscv_dynamic_type (unsigned long type)
2403{
2404 switch (type)
2405 {
2406 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2407 default:
2408 return NULL;
2409 }
2410}
2411
252b5132 2412static const char *
dda8d76d 2413get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2414{
e9e44622 2415 static char buff[64];
252b5132
RH
2416
2417 switch (type)
2418 {
2419 case DT_NULL: return "NULL";
2420 case DT_NEEDED: return "NEEDED";
2421 case DT_PLTRELSZ: return "PLTRELSZ";
2422 case DT_PLTGOT: return "PLTGOT";
2423 case DT_HASH: return "HASH";
2424 case DT_STRTAB: return "STRTAB";
2425 case DT_SYMTAB: return "SYMTAB";
2426 case DT_RELA: return "RELA";
2427 case DT_RELASZ: return "RELASZ";
2428 case DT_RELAENT: return "RELAENT";
2429 case DT_STRSZ: return "STRSZ";
2430 case DT_SYMENT: return "SYMENT";
2431 case DT_INIT: return "INIT";
2432 case DT_FINI: return "FINI";
2433 case DT_SONAME: return "SONAME";
2434 case DT_RPATH: return "RPATH";
2435 case DT_SYMBOLIC: return "SYMBOLIC";
2436 case DT_REL: return "REL";
2437 case DT_RELSZ: return "RELSZ";
2438 case DT_RELENT: return "RELENT";
dd207c13
FS
2439 case DT_RELR: return "RELR";
2440 case DT_RELRSZ: return "RELRSZ";
2441 case DT_RELRENT: return "RELRENT";
252b5132
RH
2442 case DT_PLTREL: return "PLTREL";
2443 case DT_DEBUG: return "DEBUG";
2444 case DT_TEXTREL: return "TEXTREL";
2445 case DT_JMPREL: return "JMPREL";
2446 case DT_BIND_NOW: return "BIND_NOW";
2447 case DT_INIT_ARRAY: return "INIT_ARRAY";
2448 case DT_FINI_ARRAY: return "FINI_ARRAY";
2449 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2450 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2451 case DT_RUNPATH: return "RUNPATH";
2452 case DT_FLAGS: return "FLAGS";
2d0e6f43 2453
d1133906
NC
2454 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2455 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2456 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2457
05107a46 2458 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2459 case DT_PLTPADSZ: return "PLTPADSZ";
2460 case DT_MOVEENT: return "MOVEENT";
2461 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2462 case DT_FEATURE: return "FEATURE";
252b5132
RH
2463 case DT_POSFLAG_1: return "POSFLAG_1";
2464 case DT_SYMINSZ: return "SYMINSZ";
2465 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2466
252b5132 2467 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2468 case DT_CONFIG: return "CONFIG";
2469 case DT_DEPAUDIT: return "DEPAUDIT";
2470 case DT_AUDIT: return "AUDIT";
2471 case DT_PLTPAD: return "PLTPAD";
2472 case DT_MOVETAB: return "MOVETAB";
252b5132 2473 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2474
252b5132 2475 case DT_VERSYM: return "VERSYM";
103f02d3 2476
67a4f2b7
AO
2477 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2478 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2479 case DT_RELACOUNT: return "RELACOUNT";
2480 case DT_RELCOUNT: return "RELCOUNT";
2481 case DT_FLAGS_1: return "FLAGS_1";
2482 case DT_VERDEF: return "VERDEF";
2483 case DT_VERDEFNUM: return "VERDEFNUM";
2484 case DT_VERNEED: return "VERNEED";
2485 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2486
019148e4 2487 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2488 case DT_USED: return "USED";
2489 case DT_FILTER: return "FILTER";
103f02d3 2490
047b2264
JJ
2491 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2492 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2493 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2494 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2495 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2496 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2497 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2498
252b5132
RH
2499 default:
2500 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2501 {
2cf0635d 2502 const char * result;
103f02d3 2503
dda8d76d 2504 switch (filedata->file_header.e_machine)
252b5132 2505 {
37c18eed
SD
2506 case EM_AARCH64:
2507 result = get_aarch64_dynamic_type (type);
2508 break;
252b5132 2509 case EM_MIPS:
4fe85591 2510 case EM_MIPS_RS3_LE:
252b5132
RH
2511 result = get_mips_dynamic_type (type);
2512 break;
9a097730
RH
2513 case EM_SPARCV9:
2514 result = get_sparc64_dynamic_type (type);
2515 break;
7490d522
AM
2516 case EM_PPC:
2517 result = get_ppc_dynamic_type (type);
2518 break;
f1cb7e17
AM
2519 case EM_PPC64:
2520 result = get_ppc64_dynamic_type (type);
2521 break;
ecc51f48
NC
2522 case EM_IA_64:
2523 result = get_ia64_dynamic_type (type);
2524 break;
fabcb361
RH
2525 case EM_ALPHA:
2526 result = get_alpha_dynamic_type (type);
2527 break;
1c0d3aa6
NC
2528 case EM_SCORE:
2529 result = get_score_dynamic_type (type);
2530 break;
40b36596
JM
2531 case EM_TI_C6000:
2532 result = get_tic6x_dynamic_type (type);
2533 break;
36591ba1
SL
2534 case EM_ALTERA_NIOS2:
2535 result = get_nios2_dynamic_type (type);
2536 break;
8155b853
NC
2537 case EM_RISCV:
2538 result = get_riscv_dynamic_type (type);
2539 break;
252b5132 2540 default:
dda8d76d 2541 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2542 result = get_solaris_dynamic_type (type);
2543 else
2544 result = NULL;
252b5132
RH
2545 break;
2546 }
2547
2548 if (result != NULL)
2549 return result;
2550
e9e44622 2551 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2552 }
eec8f817 2553 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2554 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2555 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2556 {
2cf0635d 2557 const char * result;
103f02d3 2558
dda8d76d 2559 switch (filedata->file_header.e_machine)
103f02d3
UD
2560 {
2561 case EM_PARISC:
2562 result = get_parisc_dynamic_type (type);
2563 break;
148b93f2
NC
2564 case EM_IA_64:
2565 result = get_ia64_dynamic_type (type);
2566 break;
103f02d3 2567 default:
dda8d76d 2568 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2569 result = get_solaris_dynamic_type (type);
2570 else
2571 result = NULL;
103f02d3
UD
2572 break;
2573 }
2574
2575 if (result != NULL)
2576 return result;
2577
e9e44622
JJ
2578 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2579 type);
103f02d3 2580 }
252b5132 2581 else
e9e44622 2582 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2583
252b5132
RH
2584 return buff;
2585 }
2586}
2587
93df3340
AM
2588static bool get_program_headers (Filedata *);
2589static bool get_dynamic_section (Filedata *);
2590
2591static void
2592locate_dynamic_section (Filedata *filedata)
2593{
2594 unsigned long dynamic_addr = 0;
be7d229a 2595 uint64_t dynamic_size = 0;
93df3340
AM
2596
2597 if (filedata->file_header.e_phnum != 0
2598 && get_program_headers (filedata))
2599 {
2600 Elf_Internal_Phdr *segment;
2601 unsigned int i;
2602
2603 for (i = 0, segment = filedata->program_headers;
2604 i < filedata->file_header.e_phnum;
2605 i++, segment++)
2606 {
2607 if (segment->p_type == PT_DYNAMIC)
2608 {
2609 dynamic_addr = segment->p_offset;
2610 dynamic_size = segment->p_filesz;
2611
2612 if (filedata->section_headers != NULL)
2613 {
2614 Elf_Internal_Shdr *sec;
2615
2616 sec = find_section (filedata, ".dynamic");
2617 if (sec != NULL)
2618 {
2619 if (sec->sh_size == 0
2620 || sec->sh_type == SHT_NOBITS)
2621 {
2622 dynamic_addr = 0;
2623 dynamic_size = 0;
2624 }
2625 else
2626 {
2627 dynamic_addr = sec->sh_offset;
2628 dynamic_size = sec->sh_size;
2629 }
2630 }
2631 }
2632
2633 if (dynamic_addr > filedata->file_size
2634 || (dynamic_size > filedata->file_size - dynamic_addr))
2635 {
2636 dynamic_addr = 0;
2637 dynamic_size = 0;
2638 }
2639 break;
2640 }
2641 }
2642 }
2643 filedata->dynamic_addr = dynamic_addr;
2644 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2645}
2646
2647static bool
2648is_pie (Filedata *filedata)
2649{
2650 Elf_Internal_Dyn *entry;
2651
2652 if (filedata->dynamic_size == 0)
2653 locate_dynamic_section (filedata);
2654 if (filedata->dynamic_size <= 1)
2655 return false;
2656
2657 if (!get_dynamic_section (filedata))
2658 return false;
2659
2660 for (entry = filedata->dynamic_section;
2661 entry < filedata->dynamic_section + filedata->dynamic_nent;
2662 entry++)
2663 {
2664 if (entry->d_tag == DT_FLAGS_1)
2665 {
2666 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2667 return true;
2668 break;
2669 }
2670 }
2671 return false;
2672}
2673
252b5132 2674static char *
93df3340 2675get_file_type (Filedata *filedata)
252b5132 2676{
93df3340 2677 unsigned e_type = filedata->file_header.e_type;
89246a0e 2678 static char buff[64];
252b5132
RH
2679
2680 switch (e_type)
2681 {
32ec8896
NC
2682 case ET_NONE: return _("NONE (None)");
2683 case ET_REL: return _("REL (Relocatable file)");
2684 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2685 case ET_DYN:
2686 if (is_pie (filedata))
2687 return _("DYN (Position-Independent Executable file)");
2688 else
2689 return _("DYN (Shared object file)");
32ec8896 2690 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2691
2692 default:
2693 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2694 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2695 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2696 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2697 else
e9e44622 2698 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2699 return buff;
2700 }
2701}
2702
2703static char *
d3ba0551 2704get_machine_name (unsigned e_machine)
252b5132 2705{
b34976b6 2706 static char buff[64]; /* XXX */
252b5132
RH
2707
2708 switch (e_machine)
2709 {
55e22ca8
NC
2710 /* Please keep this switch table sorted by increasing EM_ value. */
2711 /* 0 */
c45021f2
NC
2712 case EM_NONE: return _("None");
2713 case EM_M32: return "WE32100";
2714 case EM_SPARC: return "Sparc";
2715 case EM_386: return "Intel 80386";
2716 case EM_68K: return "MC68000";
2717 case EM_88K: return "MC88000";
22abe556 2718 case EM_IAMCU: return "Intel MCU";
fb70ec17 2719 case EM_860: return "Intel 80860";
c45021f2
NC
2720 case EM_MIPS: return "MIPS R3000";
2721 case EM_S370: return "IBM System/370";
55e22ca8 2722 /* 10 */
7036c0e1 2723 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2724 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2725 case EM_PARISC: return "HPPA";
55e22ca8 2726 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2727 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2728 case EM_960: return "Intel 80960";
c45021f2 2729 case EM_PPC: return "PowerPC";
55e22ca8 2730 /* 20 */
285d1771 2731 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2732 case EM_S390_OLD:
2733 case EM_S390: return "IBM S/390";
2734 case EM_SPU: return "SPU";
2735 /* 30 */
2736 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2737 case EM_FR20: return "Fujitsu FR20";
2738 case EM_RH32: return "TRW RH32";
b34976b6 2739 case EM_MCORE: return "MCORE";
55e22ca8 2740 /* 40 */
7036c0e1
AJ
2741 case EM_ARM: return "ARM";
2742 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2743 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2744 case EM_SPARCV9: return "Sparc v9";
2745 case EM_TRICORE: return "Siemens Tricore";
584da044 2746 case EM_ARC: return "ARC";
c2dcd04e
NC
2747 case EM_H8_300: return "Renesas H8/300";
2748 case EM_H8_300H: return "Renesas H8/300H";
2749 case EM_H8S: return "Renesas H8S";
2750 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2751 /* 50 */
30800947 2752 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2753 case EM_MIPS_X: return "Stanford MIPS-X";
2754 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2755 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2756 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2757 case EM_PCP: return "Siemens PCP";
2758 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2759 case EM_NDR1: return "Denso NDR1 microprocesspr";
2760 case EM_STARCORE: return "Motorola Star*Core processor";
2761 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2762 /* 60 */
7036c0e1
AJ
2763 case EM_ST100: return "STMicroelectronics ST100 processor";
2764 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2765 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2766 case EM_PDSP: return "Sony DSP processor";
2767 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2768 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2769 case EM_FX66: return "Siemens FX66 microcontroller";
2770 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2771 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2772 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2773 /* 70 */
7036c0e1
AJ
2774 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2775 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2776 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2777 case EM_SVX: return "Silicon Graphics SVx";
2778 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2779 case EM_VAX: return "Digital VAX";
1b61cf92 2780 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2781 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2782 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2783 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2784 /* 80 */
b34976b6 2785 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2786 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2787 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2788 case EM_AVR_OLD:
2789 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2790 case EM_CYGNUS_FR30:
2791 case EM_FR30: return "Fujitsu FR30";
2792 case EM_CYGNUS_D10V:
2793 case EM_D10V: return "d10v";
2794 case EM_CYGNUS_D30V:
2795 case EM_D30V: return "d30v";
2796 case EM_CYGNUS_V850:
2797 case EM_V850: return "Renesas V850";
2798 case EM_CYGNUS_M32R:
2799 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2800 case EM_CYGNUS_MN10300:
2801 case EM_MN10300: return "mn10300";
2802 /* 90 */
2803 case EM_CYGNUS_MN10200:
2804 case EM_MN10200: return "mn10200";
2805 case EM_PJ: return "picoJava";
73589c9d 2806 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2807 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2808 case EM_XTENSA_OLD:
2809 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2810 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2811 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2812 case EM_NS32K: return "National Semiconductor 32000 series";
2813 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2814 case EM_SNP1K: return "Trebia SNP 1000 processor";
2815 /* 100 */
9abca702 2816 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2817 case EM_IP2K_OLD:
2818 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2819 case EM_MAX: return "MAX Processor";
2820 case EM_CR: return "National Semiconductor CompactRISC";
2821 case EM_F2MC16: return "Fujitsu F2MC16";
2822 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2823 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2824 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2825 case EM_SEP: return "Sharp embedded microprocessor";
2826 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2827 /* 110 */
11636f9e
JM
2828 case EM_UNICORE: return "Unicore";
2829 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2830 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2831 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2832 case EM_CRX: return "National Semiconductor CRX microprocessor";
2833 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2834 case EM_C166:
d70c5fc7 2835 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2836 case EM_M16C: return "Renesas M16C series microprocessors";
2837 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2838 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2839 /* 120 */
2840 case EM_M32C: return "Renesas M32c";
2841 /* 130 */
11636f9e
JM
2842 case EM_TSK3000: return "Altium TSK3000 core";
2843 case EM_RS08: return "Freescale RS08 embedded processor";
2844 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2845 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2846 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2847 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2848 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2849 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2850 /* 140 */
11636f9e
JM
2851 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2852 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2853 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2854 case EM_TI_PRU: return "TI PRU I/O processor";
2855 /* 160 */
11636f9e
JM
2856 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2857 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2858 case EM_R32C: return "Renesas R32C series microprocessors";
2859 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2860 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2861 case EM_8051: return "Intel 8051 and variants";
2862 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2863 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2864 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2865 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2866 /* 170 */
11636f9e
JM
2867 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2868 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2869 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2870 case EM_RX: return "Renesas RX";
a3c62988 2871 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2872 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2873 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2874 case EM_CR16:
2875 case EM_MICROBLAZE:
2876 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2877 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2878 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2879 /* 180 */
2880 case EM_L1OM: return "Intel L1OM";
2881 case EM_K1OM: return "Intel K1OM";
2882 case EM_INTEL182: return "Intel (reserved)";
2883 case EM_AARCH64: return "AArch64";
2884 case EM_ARM184: return "ARM (reserved)";
2885 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2886 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2887 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2888 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2889 /* 190 */
11636f9e 2890 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2891 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2892 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2893 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2894 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2895 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2896 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2897 case EM_RL78: return "Renesas RL78";
6d913794 2898 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2899 case EM_78K0R: return "Renesas 78K0R";
2900 /* 200 */
6d913794 2901 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2902 case EM_BA1: return "Beyond BA1 CPU architecture";
2903 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2904 case EM_XCORE: return "XMOS xCORE processor family";
2905 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2906 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2907 /* 210 */
6d913794
NC
2908 case EM_KM32: return "KM211 KM32 32-bit processor";
2909 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2910 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2911 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2912 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2913 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2914 case EM_COGE: return "Cognitive Smart Memory Processor";
2915 case EM_COOL: return "Bluechip Systems CoolEngine";
2916 case EM_NORC: return "Nanoradio Optimized RISC";
2917 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2918 /* 220 */
15f205b1 2919 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2920 case EM_VISIUM: return "CDS VISIUMcore processor";
2921 case EM_FT32: return "FTDI Chip FT32";
2922 case EM_MOXIE: return "Moxie";
2923 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2924 /* 230 (all reserved) */
2925 /* 240 */
55e22ca8
NC
2926 case EM_RISCV: return "RISC-V";
2927 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2928 case EM_CEVA: return "CEVA Processor Architecture Family";
2929 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2930 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2931 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2932 case EM_IMG1: return "Imagination Technologies";
2933 /* 250 */
fe944acf 2934 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2935 case EM_VE: return "NEC Vector Engine";
2936 case EM_CSKY: return "C-SKY";
2937 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2938 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2939 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2940 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2941 case EM_65816: return "WDC 65816/65C816";
01a8c731 2942 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2943 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2944
2945 /* Large numbers... */
2946 case EM_MT: return "Morpho Techologies MT processor";
2947 case EM_ALPHA: return "Alpha";
2948 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2949 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2950 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2951 case EM_IQ2000: return "Vitesse IQ2000";
2952 case EM_M32C_OLD:
2953 case EM_NIOS32: return "Altera Nios";
2954 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2955 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2956 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2957 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2958
252b5132 2959 default:
35d9dd2f 2960 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2961 return buff;
2962 }
2963}
2964
a9522a21
AB
2965static void
2966decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2967{
2968 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 2969 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
2970 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2971 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2972 architectures.
2973
2974 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2975 but also sets a specific architecture type in the e_flags field.
2976
2977 However, when decoding the flags we don't worry if we see an
2978 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2979 ARCEM architecture type. */
2980
2981 switch (e_flags & EF_ARC_MACH_MSK)
2982 {
2983 /* We only expect these to occur for EM_ARC_COMPACT2. */
2984 case EF_ARC_CPU_ARCV2EM:
2985 strcat (buf, ", ARC EM");
2986 break;
2987 case EF_ARC_CPU_ARCV2HS:
2988 strcat (buf, ", ARC HS");
2989 break;
2990
2991 /* We only expect these to occur for EM_ARC_COMPACT. */
2992 case E_ARC_MACH_ARC600:
2993 strcat (buf, ", ARC600");
2994 break;
2995 case E_ARC_MACH_ARC601:
2996 strcat (buf, ", ARC601");
2997 break;
2998 case E_ARC_MACH_ARC700:
2999 strcat (buf, ", ARC700");
3000 break;
3001
3002 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3003 new ELF with new architecture being read by an old version of
3004 readelf, or (c) An ELF built with non-GNU compiler that does not
3005 set the architecture in the e_flags. */
3006 default:
3007 if (e_machine == EM_ARC_COMPACT)
3008 strcat (buf, ", Unknown ARCompact");
3009 else
3010 strcat (buf, ", Unknown ARC");
3011 break;
3012 }
3013
3014 switch (e_flags & EF_ARC_OSABI_MSK)
3015 {
3016 case E_ARC_OSABI_ORIG:
3017 strcat (buf, ", (ABI:legacy)");
3018 break;
3019 case E_ARC_OSABI_V2:
3020 strcat (buf, ", (ABI:v2)");
3021 break;
3022 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3023 case E_ARC_OSABI_V3:
3024 strcat (buf, ", v3 no-legacy-syscalls ABI");
3025 break;
53a346d8
CZ
3026 case E_ARC_OSABI_V4:
3027 strcat (buf, ", v4 ABI");
3028 break;
a9522a21
AB
3029 default:
3030 strcat (buf, ", unrecognised ARC OSABI flag");
3031 break;
3032 }
3033}
3034
f3485b74 3035static void
d3ba0551 3036decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
3037{
3038 unsigned eabi;
015dc7e1 3039 bool unknown = false;
f3485b74
NC
3040
3041 eabi = EF_ARM_EABI_VERSION (e_flags);
3042 e_flags &= ~ EF_ARM_EABIMASK;
3043
3044 /* Handle "generic" ARM flags. */
3045 if (e_flags & EF_ARM_RELEXEC)
3046 {
3047 strcat (buf, ", relocatable executable");
3048 e_flags &= ~ EF_ARM_RELEXEC;
3049 }
76da6bbe 3050
18a20338
CL
3051 if (e_flags & EF_ARM_PIC)
3052 {
3053 strcat (buf, ", position independent");
3054 e_flags &= ~ EF_ARM_PIC;
3055 }
3056
f3485b74
NC
3057 /* Now handle EABI specific flags. */
3058 switch (eabi)
3059 {
3060 default:
2c71103e 3061 strcat (buf, ", <unrecognized EABI>");
f3485b74 3062 if (e_flags)
015dc7e1 3063 unknown = true;
f3485b74
NC
3064 break;
3065
3066 case EF_ARM_EABI_VER1:
a5bcd848 3067 strcat (buf, ", Version1 EABI");
f3485b74
NC
3068 while (e_flags)
3069 {
3070 unsigned flag;
76da6bbe 3071
f3485b74
NC
3072 /* Process flags one bit at a time. */
3073 flag = e_flags & - e_flags;
3074 e_flags &= ~ flag;
76da6bbe 3075
f3485b74
NC
3076 switch (flag)
3077 {
a5bcd848 3078 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
3079 strcat (buf, ", sorted symbol tables");
3080 break;
76da6bbe 3081
f3485b74 3082 default:
015dc7e1 3083 unknown = true;
f3485b74
NC
3084 break;
3085 }
3086 }
3087 break;
76da6bbe 3088
a5bcd848
PB
3089 case EF_ARM_EABI_VER2:
3090 strcat (buf, ", Version2 EABI");
3091 while (e_flags)
3092 {
3093 unsigned flag;
3094
3095 /* Process flags one bit at a time. */
3096 flag = e_flags & - e_flags;
3097 e_flags &= ~ flag;
3098
3099 switch (flag)
3100 {
3101 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3102 strcat (buf, ", sorted symbol tables");
3103 break;
3104
3105 case EF_ARM_DYNSYMSUSESEGIDX:
3106 strcat (buf, ", dynamic symbols use segment index");
3107 break;
3108
3109 case EF_ARM_MAPSYMSFIRST:
3110 strcat (buf, ", mapping symbols precede others");
3111 break;
3112
3113 default:
015dc7e1 3114 unknown = true;
a5bcd848
PB
3115 break;
3116 }
3117 }
3118 break;
3119
d507cf36
PB
3120 case EF_ARM_EABI_VER3:
3121 strcat (buf, ", Version3 EABI");
8cb51566
PB
3122 break;
3123
3124 case EF_ARM_EABI_VER4:
3125 strcat (buf, ", Version4 EABI");
3bfcb652
NC
3126 while (e_flags)
3127 {
3128 unsigned flag;
3129
3130 /* Process flags one bit at a time. */
3131 flag = e_flags & - e_flags;
3132 e_flags &= ~ flag;
3133
3134 switch (flag)
3135 {
3136 case EF_ARM_BE8:
3137 strcat (buf, ", BE8");
3138 break;
3139
3140 case EF_ARM_LE8:
3141 strcat (buf, ", LE8");
3142 break;
3143
3144 default:
015dc7e1 3145 unknown = true;
3bfcb652
NC
3146 break;
3147 }
3bfcb652
NC
3148 }
3149 break;
3a4a14e9
PB
3150
3151 case EF_ARM_EABI_VER5:
3152 strcat (buf, ", Version5 EABI");
d507cf36
PB
3153 while (e_flags)
3154 {
3155 unsigned flag;
3156
3157 /* Process flags one bit at a time. */
3158 flag = e_flags & - e_flags;
3159 e_flags &= ~ flag;
3160
3161 switch (flag)
3162 {
3163 case EF_ARM_BE8:
3164 strcat (buf, ", BE8");
3165 break;
3166
3167 case EF_ARM_LE8:
3168 strcat (buf, ", LE8");
3169 break;
3170
3bfcb652
NC
3171 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3172 strcat (buf, ", soft-float ABI");
3173 break;
3174
3175 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3176 strcat (buf, ", hard-float ABI");
3177 break;
3178
d507cf36 3179 default:
015dc7e1 3180 unknown = true;
d507cf36
PB
3181 break;
3182 }
3183 }
3184 break;
3185
f3485b74 3186 case EF_ARM_EABI_UNKNOWN:
a5bcd848 3187 strcat (buf, ", GNU EABI");
f3485b74
NC
3188 while (e_flags)
3189 {
3190 unsigned flag;
76da6bbe 3191
f3485b74
NC
3192 /* Process flags one bit at a time. */
3193 flag = e_flags & - e_flags;
3194 e_flags &= ~ flag;
76da6bbe 3195
f3485b74
NC
3196 switch (flag)
3197 {
a5bcd848 3198 case EF_ARM_INTERWORK:
f3485b74
NC
3199 strcat (buf, ", interworking enabled");
3200 break;
76da6bbe 3201
a5bcd848 3202 case EF_ARM_APCS_26:
f3485b74
NC
3203 strcat (buf, ", uses APCS/26");
3204 break;
76da6bbe 3205
a5bcd848 3206 case EF_ARM_APCS_FLOAT:
f3485b74
NC
3207 strcat (buf, ", uses APCS/float");
3208 break;
76da6bbe 3209
a5bcd848 3210 case EF_ARM_PIC:
f3485b74
NC
3211 strcat (buf, ", position independent");
3212 break;
76da6bbe 3213
a5bcd848 3214 case EF_ARM_ALIGN8:
f3485b74
NC
3215 strcat (buf, ", 8 bit structure alignment");
3216 break;
76da6bbe 3217
a5bcd848 3218 case EF_ARM_NEW_ABI:
f3485b74
NC
3219 strcat (buf, ", uses new ABI");
3220 break;
76da6bbe 3221
a5bcd848 3222 case EF_ARM_OLD_ABI:
f3485b74
NC
3223 strcat (buf, ", uses old ABI");
3224 break;
76da6bbe 3225
a5bcd848 3226 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
3227 strcat (buf, ", software FP");
3228 break;
76da6bbe 3229
90e01f86
ILT
3230 case EF_ARM_VFP_FLOAT:
3231 strcat (buf, ", VFP");
3232 break;
3233
fde78edd
NC
3234 case EF_ARM_MAVERICK_FLOAT:
3235 strcat (buf, ", Maverick FP");
3236 break;
3237
f3485b74 3238 default:
015dc7e1 3239 unknown = true;
f3485b74
NC
3240 break;
3241 }
3242 }
3243 }
f3485b74
NC
3244
3245 if (unknown)
2b692964 3246 strcat (buf,_(", <unknown>"));
f3485b74
NC
3247}
3248
343433df
AB
3249static void
3250decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
3251{
3252 --size; /* Leave space for null terminator. */
3253
3254 switch (e_flags & EF_AVR_MACH)
3255 {
3256 case E_AVR_MACH_AVR1:
3257 strncat (buf, ", avr:1", size);
3258 break;
3259 case E_AVR_MACH_AVR2:
3260 strncat (buf, ", avr:2", size);
3261 break;
3262 case E_AVR_MACH_AVR25:
3263 strncat (buf, ", avr:25", size);
3264 break;
3265 case E_AVR_MACH_AVR3:
3266 strncat (buf, ", avr:3", size);
3267 break;
3268 case E_AVR_MACH_AVR31:
3269 strncat (buf, ", avr:31", size);
3270 break;
3271 case E_AVR_MACH_AVR35:
3272 strncat (buf, ", avr:35", size);
3273 break;
3274 case E_AVR_MACH_AVR4:
3275 strncat (buf, ", avr:4", size);
3276 break;
3277 case E_AVR_MACH_AVR5:
3278 strncat (buf, ", avr:5", size);
3279 break;
3280 case E_AVR_MACH_AVR51:
3281 strncat (buf, ", avr:51", size);
3282 break;
3283 case E_AVR_MACH_AVR6:
3284 strncat (buf, ", avr:6", size);
3285 break;
3286 case E_AVR_MACH_AVRTINY:
3287 strncat (buf, ", avr:100", size);
3288 break;
3289 case E_AVR_MACH_XMEGA1:
3290 strncat (buf, ", avr:101", size);
3291 break;
3292 case E_AVR_MACH_XMEGA2:
3293 strncat (buf, ", avr:102", size);
3294 break;
3295 case E_AVR_MACH_XMEGA3:
3296 strncat (buf, ", avr:103", size);
3297 break;
3298 case E_AVR_MACH_XMEGA4:
3299 strncat (buf, ", avr:104", size);
3300 break;
3301 case E_AVR_MACH_XMEGA5:
3302 strncat (buf, ", avr:105", size);
3303 break;
3304 case E_AVR_MACH_XMEGA6:
3305 strncat (buf, ", avr:106", size);
3306 break;
3307 case E_AVR_MACH_XMEGA7:
3308 strncat (buf, ", avr:107", size);
3309 break;
3310 default:
3311 strncat (buf, ", avr:<unknown>", size);
3312 break;
3313 }
3314
3315 size -= strlen (buf);
3316 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3317 strncat (buf, ", link-relax", size);
3318}
3319
35c08157
KLC
3320static void
3321decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
3322{
3323 unsigned abi;
3324 unsigned arch;
3325 unsigned config;
3326 unsigned version;
015dc7e1 3327 bool has_fpu = false;
32ec8896 3328 unsigned int r = 0;
35c08157
KLC
3329
3330 static const char *ABI_STRINGS[] =
3331 {
3332 "ABI v0", /* use r5 as return register; only used in N1213HC */
3333 "ABI v1", /* use r0 as return register */
3334 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3335 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3336 "AABI",
3337 "ABI2 FP+"
35c08157
KLC
3338 };
3339 static const char *VER_STRINGS[] =
3340 {
3341 "Andes ELF V1.3 or older",
3342 "Andes ELF V1.3.1",
3343 "Andes ELF V1.4"
3344 };
3345 static const char *ARCH_STRINGS[] =
3346 {
3347 "",
3348 "Andes Star v1.0",
3349 "Andes Star v2.0",
3350 "Andes Star v3.0",
3351 "Andes Star v3.0m"
3352 };
3353
3354 abi = EF_NDS_ABI & e_flags;
3355 arch = EF_NDS_ARCH & e_flags;
3356 config = EF_NDS_INST & e_flags;
3357 version = EF_NDS32_ELF_VERSION & e_flags;
3358
3359 memset (buf, 0, size);
3360
3361 switch (abi)
3362 {
3363 case E_NDS_ABI_V0:
3364 case E_NDS_ABI_V1:
3365 case E_NDS_ABI_V2:
3366 case E_NDS_ABI_V2FP:
3367 case E_NDS_ABI_AABI:
40c7a7cb 3368 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3369 /* In case there are holes in the array. */
3370 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3371 break;
3372
3373 default:
3374 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3375 break;
3376 }
3377
3378 switch (version)
3379 {
3380 case E_NDS32_ELF_VER_1_2:
3381 case E_NDS32_ELF_VER_1_3:
3382 case E_NDS32_ELF_VER_1_4:
3383 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3384 break;
3385
3386 default:
3387 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3388 break;
3389 }
3390
3391 if (E_NDS_ABI_V0 == abi)
3392 {
3393 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3394 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3395 if (arch == E_NDS_ARCH_STAR_V1_0)
3396 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3397 return;
3398 }
3399
3400 switch (arch)
3401 {
3402 case E_NDS_ARCH_STAR_V1_0:
3403 case E_NDS_ARCH_STAR_V2_0:
3404 case E_NDS_ARCH_STAR_V3_0:
3405 case E_NDS_ARCH_STAR_V3_M:
3406 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3407 break;
3408
3409 default:
3410 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3411 /* ARCH version determines how the e_flags are interpreted.
3412 If it is unknown, we cannot proceed. */
3413 return;
3414 }
3415
3416 /* Newer ABI; Now handle architecture specific flags. */
3417 if (arch == E_NDS_ARCH_STAR_V1_0)
3418 {
3419 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3420 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3421
3422 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3423 r += snprintf (buf + r, size -r, ", MAC");
3424
3425 if (config & E_NDS32_HAS_DIV_INST)
3426 r += snprintf (buf + r, size -r, ", DIV");
3427
3428 if (config & E_NDS32_HAS_16BIT_INST)
3429 r += snprintf (buf + r, size -r, ", 16b");
3430 }
3431 else
3432 {
3433 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3434 {
3435 if (version <= E_NDS32_ELF_VER_1_3)
3436 r += snprintf (buf + r, size -r, ", [B8]");
3437 else
3438 r += snprintf (buf + r, size -r, ", EX9");
3439 }
3440
3441 if (config & E_NDS32_HAS_MAC_DX_INST)
3442 r += snprintf (buf + r, size -r, ", MAC_DX");
3443
3444 if (config & E_NDS32_HAS_DIV_DX_INST)
3445 r += snprintf (buf + r, size -r, ", DIV_DX");
3446
3447 if (config & E_NDS32_HAS_16BIT_INST)
3448 {
3449 if (version <= E_NDS32_ELF_VER_1_3)
3450 r += snprintf (buf + r, size -r, ", 16b");
3451 else
3452 r += snprintf (buf + r, size -r, ", IFC");
3453 }
3454 }
3455
3456 if (config & E_NDS32_HAS_EXT_INST)
3457 r += snprintf (buf + r, size -r, ", PERF1");
3458
3459 if (config & E_NDS32_HAS_EXT2_INST)
3460 r += snprintf (buf + r, size -r, ", PERF2");
3461
3462 if (config & E_NDS32_HAS_FPU_INST)
3463 {
015dc7e1 3464 has_fpu = true;
35c08157
KLC
3465 r += snprintf (buf + r, size -r, ", FPU_SP");
3466 }
3467
3468 if (config & E_NDS32_HAS_FPU_DP_INST)
3469 {
015dc7e1 3470 has_fpu = true;
35c08157
KLC
3471 r += snprintf (buf + r, size -r, ", FPU_DP");
3472 }
3473
3474 if (config & E_NDS32_HAS_FPU_MAC_INST)
3475 {
015dc7e1 3476 has_fpu = true;
35c08157
KLC
3477 r += snprintf (buf + r, size -r, ", FPU_MAC");
3478 }
3479
3480 if (has_fpu)
3481 {
3482 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3483 {
3484 case E_NDS32_FPU_REG_8SP_4DP:
3485 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3486 break;
3487 case E_NDS32_FPU_REG_16SP_8DP:
3488 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3489 break;
3490 case E_NDS32_FPU_REG_32SP_16DP:
3491 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3492 break;
3493 case E_NDS32_FPU_REG_32SP_32DP:
3494 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3495 break;
3496 }
3497 }
3498
3499 if (config & E_NDS32_HAS_AUDIO_INST)
3500 r += snprintf (buf + r, size -r, ", AUDIO");
3501
3502 if (config & E_NDS32_HAS_STRING_INST)
3503 r += snprintf (buf + r, size -r, ", STR");
3504
3505 if (config & E_NDS32_HAS_REDUCED_REGS)
3506 r += snprintf (buf + r, size -r, ", 16REG");
3507
3508 if (config & E_NDS32_HAS_VIDEO_INST)
3509 {
3510 if (version <= E_NDS32_ELF_VER_1_3)
3511 r += snprintf (buf + r, size -r, ", VIDEO");
3512 else
3513 r += snprintf (buf + r, size -r, ", SATURATION");
3514 }
3515
3516 if (config & E_NDS32_HAS_ENCRIPT_INST)
3517 r += snprintf (buf + r, size -r, ", ENCRP");
3518
3519 if (config & E_NDS32_HAS_L2C_INST)
3520 r += snprintf (buf + r, size -r, ", L2C");
3521}
3522
c077c580
SM
3523static void
3524decode_AMDGPU_machine_flags (Filedata *filedata, unsigned int e_flags,
3525 char *buf)
3526{
3527 unsigned char *e_ident = filedata->file_header.e_ident;
3528 unsigned char osabi = e_ident[EI_OSABI];
3529 unsigned char abiversion = e_ident[EI_ABIVERSION];
3530 unsigned int mach;
3531
3532 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
3533 it has been deprecated for a while.
3534
3535 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
3536 of writing, they use the same flags as HSA v3, so the code below uses that
3537 assumption. */
3538 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
3539 return;
3540
3541 mach = e_flags & EF_AMDGPU_MACH;
3542 switch (mach)
3543 {
3544#define AMDGPU_CASE(code, string) \
3545 case code: strcat (buf, ", " string); break;
3546 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
3547 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
3548 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
3549 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
3550 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
3551 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
3552 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
3553 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
3554 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
3555 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
3556 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
3557 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
3558 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
3559 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
3560 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
3561 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
3562 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
3563 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
3564 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
3565 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
3566 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
3567 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
3568 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
3569 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
3570 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
3571 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
3572 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
3573 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
3574 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
3575 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
3576 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
3577 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
3578 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
3579 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
3580 default:
3581 sprintf (buf, _(", <unknown AMDGPU GPU type: %#x>"), mach);
3582 break;
3583#undef AMDGPU_CASE
3584 }
3585
3586 buf += strlen (buf);
3587 e_flags &= ~EF_AMDGPU_MACH;
3588
3589 if ((osabi == ELFOSABI_AMDGPU_HSA
3590 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
3591 || osabi != ELFOSABI_AMDGPU_HSA)
3592 {
3593 /* For HSA v3 and other OS ABIs. */
3594 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
3595 {
3596 strcat (buf, ", xnack on");
3597 buf += strlen (buf);
3598 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
3599 }
3600
3601 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
3602 {
3603 strcat (buf, ", sramecc on");
3604 buf += strlen (buf);
3605 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
3606 }
3607 }
3608 else
3609 {
3610 /* For HSA v4+. */
3611 int xnack, sramecc;
3612
3613 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
3614 switch (xnack)
3615 {
3616 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
3617 break;
3618
3619 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
3620 strcat (buf, ", xnack any");
3621 break;
3622
3623 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
3624 strcat (buf, ", xnack off");
3625 break;
3626
3627 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
3628 strcat (buf, ", xnack on");
3629 break;
3630
3631 default:
3632 sprintf (buf, _(", <unknown xnack value: %#x>"), xnack);
3633 break;
3634 }
3635
3636 buf += strlen (buf);
3637 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
3638
3639 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
3640 switch (sramecc)
3641 {
3642 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
3643 break;
3644
3645 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
3646 strcat (buf, ", sramecc any");
3647 break;
3648
3649 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
3650 strcat (buf, ", sramecc off");
3651 break;
3652
3653 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
3654 strcat (buf, ", sramecc on");
3655 break;
3656
3657 default:
3658 sprintf (buf, _(", <unknown sramecc value: %#x>"), sramecc);
3659 break;
3660 }
3661
3662 buf += strlen (buf);
3663 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
3664 }
3665
3666 if (e_flags != 0)
3667 sprintf (buf, _(", unknown flags bits: %#x"), e_flags);
3668}
3669
252b5132 3670static char *
dda8d76d 3671get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3672{
b34976b6 3673 static char buf[1024];
252b5132
RH
3674
3675 buf[0] = '\0';
76da6bbe 3676
252b5132
RH
3677 if (e_flags)
3678 {
3679 switch (e_machine)
3680 {
3681 default:
3682 break;
3683
886a2506 3684 case EM_ARC_COMPACT2:
886a2506 3685 case EM_ARC_COMPACT:
a9522a21
AB
3686 decode_ARC_machine_flags (e_flags, e_machine, buf);
3687 break;
886a2506 3688
f3485b74
NC
3689 case EM_ARM:
3690 decode_ARM_machine_flags (e_flags, buf);
3691 break;
76da6bbe 3692
343433df
AB
3693 case EM_AVR:
3694 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3695 break;
3696
781303ce
MF
3697 case EM_BLACKFIN:
3698 if (e_flags & EF_BFIN_PIC)
3699 strcat (buf, ", PIC");
3700
3701 if (e_flags & EF_BFIN_FDPIC)
3702 strcat (buf, ", FDPIC");
3703
3704 if (e_flags & EF_BFIN_CODE_IN_L1)
3705 strcat (buf, ", code in L1");
3706
3707 if (e_flags & EF_BFIN_DATA_IN_L1)
3708 strcat (buf, ", data in L1");
3709
3710 break;
3711
ec2dfb42
AO
3712 case EM_CYGNUS_FRV:
3713 switch (e_flags & EF_FRV_CPU_MASK)
3714 {
3715 case EF_FRV_CPU_GENERIC:
3716 break;
3717
3718 default:
3719 strcat (buf, ", fr???");
3720 break;
57346661 3721
ec2dfb42
AO
3722 case EF_FRV_CPU_FR300:
3723 strcat (buf, ", fr300");
3724 break;
3725
3726 case EF_FRV_CPU_FR400:
3727 strcat (buf, ", fr400");
3728 break;
3729 case EF_FRV_CPU_FR405:
3730 strcat (buf, ", fr405");
3731 break;
3732
3733 case EF_FRV_CPU_FR450:
3734 strcat (buf, ", fr450");
3735 break;
3736
3737 case EF_FRV_CPU_FR500:
3738 strcat (buf, ", fr500");
3739 break;
3740 case EF_FRV_CPU_FR550:
3741 strcat (buf, ", fr550");
3742 break;
3743
3744 case EF_FRV_CPU_SIMPLE:
3745 strcat (buf, ", simple");
3746 break;
3747 case EF_FRV_CPU_TOMCAT:
3748 strcat (buf, ", tomcat");
3749 break;
3750 }
1c877e87 3751 break;
ec2dfb42 3752
53c7db4b 3753 case EM_68K:
425c6cb0 3754 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3755 strcat (buf, ", m68000");
425c6cb0 3756 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3757 strcat (buf, ", cpu32");
3758 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3759 strcat (buf, ", fido_a");
425c6cb0 3760 else
266abb8f 3761 {
2cf0635d
NC
3762 char const * isa = _("unknown");
3763 char const * mac = _("unknown mac");
3764 char const * additional = NULL;
0112cd26 3765
c694fd50 3766 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3767 {
c694fd50 3768 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3769 isa = "A";
3770 additional = ", nodiv";
3771 break;
c694fd50 3772 case EF_M68K_CF_ISA_A:
266abb8f
NS
3773 isa = "A";
3774 break;
c694fd50 3775 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3776 isa = "A+";
3777 break;
c694fd50 3778 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3779 isa = "B";
3780 additional = ", nousp";
3781 break;
c694fd50 3782 case EF_M68K_CF_ISA_B:
266abb8f
NS
3783 isa = "B";
3784 break;
f608cd77
NS
3785 case EF_M68K_CF_ISA_C:
3786 isa = "C";
3787 break;
3788 case EF_M68K_CF_ISA_C_NODIV:
3789 isa = "C";
3790 additional = ", nodiv";
3791 break;
266abb8f
NS
3792 }
3793 strcat (buf, ", cf, isa ");
3794 strcat (buf, isa);
0b2e31dc
NS
3795 if (additional)
3796 strcat (buf, additional);
c694fd50 3797 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3798 strcat (buf, ", float");
c694fd50 3799 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3800 {
3801 case 0:
3802 mac = NULL;
3803 break;
c694fd50 3804 case EF_M68K_CF_MAC:
266abb8f
NS
3805 mac = "mac";
3806 break;
c694fd50 3807 case EF_M68K_CF_EMAC:
266abb8f
NS
3808 mac = "emac";
3809 break;
f608cd77
NS
3810 case EF_M68K_CF_EMAC_B:
3811 mac = "emac_b";
3812 break;
266abb8f
NS
3813 }
3814 if (mac)
3815 {
3816 strcat (buf, ", ");
3817 strcat (buf, mac);
3818 }
266abb8f 3819 }
53c7db4b 3820 break;
33c63f9d 3821
c077c580
SM
3822 case EM_AMDGPU:
3823 decode_AMDGPU_machine_flags (filedata, e_flags, buf);
3824 break;
3825
153a2776
NC
3826 case EM_CYGNUS_MEP:
3827 switch (e_flags & EF_MEP_CPU_MASK)
3828 {
3829 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3830 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3831 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3832 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3833 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3834 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3835 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3836 }
3837
3838 switch (e_flags & EF_MEP_COP_MASK)
3839 {
3840 case EF_MEP_COP_NONE: break;
3841 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3842 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3843 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3844 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3845 default: strcat (buf, _("<unknown MeP copro type>")); break;
3846 }
3847
3848 if (e_flags & EF_MEP_LIBRARY)
3849 strcat (buf, ", Built for Library");
3850
3851 if (e_flags & EF_MEP_INDEX_MASK)
3852 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3853 e_flags & EF_MEP_INDEX_MASK);
3854
3855 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3856 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3857 e_flags & ~ EF_MEP_ALL_FLAGS);
3858 break;
3859
252b5132
RH
3860 case EM_PPC:
3861 if (e_flags & EF_PPC_EMB)
3862 strcat (buf, ", emb");
3863
3864 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3865 strcat (buf, _(", relocatable"));
252b5132
RH
3866
3867 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3868 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3869 break;
3870
ee67d69a
AM
3871 case EM_PPC64:
3872 if (e_flags & EF_PPC64_ABI)
3873 {
3874 char abi[] = ", abiv0";
3875
3876 abi[6] += e_flags & EF_PPC64_ABI;
3877 strcat (buf, abi);
3878 }
3879 break;
3880
708e2187
NC
3881 case EM_V800:
3882 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3883 strcat (buf, ", RH850 ABI");
0b4362b0 3884
708e2187
NC
3885 if (e_flags & EF_V800_850E3)
3886 strcat (buf, ", V3 architecture");
3887
3888 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3889 strcat (buf, ", FPU not used");
3890
3891 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3892 strcat (buf, ", regmode: COMMON");
3893
3894 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3895 strcat (buf, ", r4 not used");
3896
3897 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3898 strcat (buf, ", r30 not used");
3899
3900 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3901 strcat (buf, ", r5 not used");
3902
3903 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3904 strcat (buf, ", r2 not used");
3905
3906 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3907 {
3908 switch (e_flags & - e_flags)
3909 {
3910 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3911 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3912 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3913 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3914 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3915 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3916 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3917 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3918 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3919 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3920 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3921 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3922 default: break;
3923 }
3924 }
3925 break;
3926
2b0337b0 3927 case EM_V850:
252b5132
RH
3928 case EM_CYGNUS_V850:
3929 switch (e_flags & EF_V850_ARCH)
3930 {
78c8d46c
NC
3931 case E_V850E3V5_ARCH:
3932 strcat (buf, ", v850e3v5");
3933 break;
1cd986c5
NC
3934 case E_V850E2V3_ARCH:
3935 strcat (buf, ", v850e2v3");
3936 break;
3937 case E_V850E2_ARCH:
3938 strcat (buf, ", v850e2");
3939 break;
3940 case E_V850E1_ARCH:
3941 strcat (buf, ", v850e1");
8ad30312 3942 break;
252b5132
RH
3943 case E_V850E_ARCH:
3944 strcat (buf, ", v850e");
3945 break;
252b5132
RH
3946 case E_V850_ARCH:
3947 strcat (buf, ", v850");
3948 break;
3949 default:
2b692964 3950 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3951 break;
3952 }
3953 break;
3954
2b0337b0 3955 case EM_M32R:
252b5132
RH
3956 case EM_CYGNUS_M32R:
3957 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3958 strcat (buf, ", m32r");
252b5132
RH
3959 break;
3960
3961 case EM_MIPS:
4fe85591 3962 case EM_MIPS_RS3_LE:
252b5132
RH
3963 if (e_flags & EF_MIPS_NOREORDER)
3964 strcat (buf, ", noreorder");
3965
3966 if (e_flags & EF_MIPS_PIC)
3967 strcat (buf, ", pic");
3968
3969 if (e_flags & EF_MIPS_CPIC)
3970 strcat (buf, ", cpic");
3971
d1bdd336
TS
3972 if (e_flags & EF_MIPS_UCODE)
3973 strcat (buf, ", ugen_reserved");
3974
252b5132
RH
3975 if (e_flags & EF_MIPS_ABI2)
3976 strcat (buf, ", abi2");
3977
43521d43
TS
3978 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3979 strcat (buf, ", odk first");
3980
a5d22d2a
TS
3981 if (e_flags & EF_MIPS_32BITMODE)
3982 strcat (buf, ", 32bitmode");
3983
ba92f887
MR
3984 if (e_flags & EF_MIPS_NAN2008)
3985 strcat (buf, ", nan2008");
3986
fef1b0b3
SE
3987 if (e_flags & EF_MIPS_FP64)
3988 strcat (buf, ", fp64");
3989
156c2f8b
NC
3990 switch ((e_flags & EF_MIPS_MACH))
3991 {
3992 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3993 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3994 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3995 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3996 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3997 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3998 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3999 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 4000 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 4001 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 4002 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
4003 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
4004 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 4005 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 4006 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 4007 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 4008 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 4009 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 4010 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 4011 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 4012 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
4013 case 0:
4014 /* We simply ignore the field in this case to avoid confusion:
4015 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4016 extension. */
4017 break;
2b692964 4018 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 4019 }
43521d43
TS
4020
4021 switch ((e_flags & EF_MIPS_ABI))
4022 {
4023 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
4024 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
4025 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
4026 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
4027 case 0:
4028 /* We simply ignore the field in this case to avoid confusion:
4029 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4030 This means it is likely to be an o32 file, but not for
4031 sure. */
4032 break;
2b692964 4033 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
4034 }
4035
4036 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4037 strcat (buf, ", mdmx");
4038
4039 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4040 strcat (buf, ", mips16");
4041
df58fc94
RS
4042 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4043 strcat (buf, ", micromips");
4044
43521d43
TS
4045 switch ((e_flags & EF_MIPS_ARCH))
4046 {
4047 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
4048 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
4049 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
4050 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
4051 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
4052 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 4053 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 4054 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 4055 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 4056 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 4057 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 4058 default: strcat (buf, _(", unknown ISA")); break;
43521d43 4059 }
252b5132 4060 break;
351b4b40 4061
35c08157
KLC
4062 case EM_NDS32:
4063 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
4064 break;
4065
fe944acf
FT
4066 case EM_NFP:
4067 switch (EF_NFP_MACH (e_flags))
4068 {
4069 case E_NFP_MACH_3200:
4070 strcat (buf, ", NFP-32xx");
4071 break;
4072 case E_NFP_MACH_6000:
4073 strcat (buf, ", NFP-6xxx");
4074 break;
4075 }
4076 break;
4077
e23eba97
NC
4078 case EM_RISCV:
4079 if (e_flags & EF_RISCV_RVC)
4080 strcat (buf, ", RVC");
2922d21d 4081
7f999549
JW
4082 if (e_flags & EF_RISCV_RVE)
4083 strcat (buf, ", RVE");
4084
96462b01
S
4085 if (e_flags & EF_RISCV_TSO)
4086 strcat (buf, ", TSO");
4087
2922d21d
AW
4088 switch (e_flags & EF_RISCV_FLOAT_ABI)
4089 {
4090 case EF_RISCV_FLOAT_ABI_SOFT:
4091 strcat (buf, ", soft-float ABI");
4092 break;
4093
4094 case EF_RISCV_FLOAT_ABI_SINGLE:
4095 strcat (buf, ", single-float ABI");
4096 break;
4097
4098 case EF_RISCV_FLOAT_ABI_DOUBLE:
4099 strcat (buf, ", double-float ABI");
4100 break;
4101
4102 case EF_RISCV_FLOAT_ABI_QUAD:
4103 strcat (buf, ", quad-float ABI");
4104 break;
4105 }
e23eba97
NC
4106 break;
4107
ccde1100
AO
4108 case EM_SH:
4109 switch ((e_flags & EF_SH_MACH_MASK))
4110 {
4111 case EF_SH1: strcat (buf, ", sh1"); break;
4112 case EF_SH2: strcat (buf, ", sh2"); break;
4113 case EF_SH3: strcat (buf, ", sh3"); break;
4114 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
4115 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
4116 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
4117 case EF_SH3E: strcat (buf, ", sh3e"); break;
4118 case EF_SH4: strcat (buf, ", sh4"); break;
4119 case EF_SH5: strcat (buf, ", sh5"); break;
4120 case EF_SH2E: strcat (buf, ", sh2e"); break;
4121 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 4122 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
4123 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
4124 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 4125 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
4126 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
4127 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
4128 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
4129 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
4130 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
4131 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 4132 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
4133 }
4134
cec6a5b8
MR
4135 if (e_flags & EF_SH_PIC)
4136 strcat (buf, ", pic");
4137
4138 if (e_flags & EF_SH_FDPIC)
4139 strcat (buf, ", fdpic");
ccde1100 4140 break;
948f632f 4141
73589c9d
CS
4142 case EM_OR1K:
4143 if (e_flags & EF_OR1K_NODELAY)
4144 strcat (buf, ", no delay");
4145 break;
57346661 4146
351b4b40
RH
4147 case EM_SPARCV9:
4148 if (e_flags & EF_SPARC_32PLUS)
4149 strcat (buf, ", v8+");
4150
4151 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
4152 strcat (buf, ", ultrasparcI");
4153
4154 if (e_flags & EF_SPARC_SUN_US3)
4155 strcat (buf, ", ultrasparcIII");
351b4b40
RH
4156
4157 if (e_flags & EF_SPARC_HAL_R1)
4158 strcat (buf, ", halr1");
4159
4160 if (e_flags & EF_SPARC_LEDATA)
4161 strcat (buf, ", ledata");
4162
4163 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4164 strcat (buf, ", tso");
4165
4166 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4167 strcat (buf, ", pso");
4168
4169 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4170 strcat (buf, ", rmo");
4171 break;
7d466069 4172
103f02d3
UD
4173 case EM_PARISC:
4174 switch (e_flags & EF_PARISC_ARCH)
4175 {
4176 case EFA_PARISC_1_0:
4177 strcpy (buf, ", PA-RISC 1.0");
4178 break;
4179 case EFA_PARISC_1_1:
4180 strcpy (buf, ", PA-RISC 1.1");
4181 break;
4182 case EFA_PARISC_2_0:
4183 strcpy (buf, ", PA-RISC 2.0");
4184 break;
4185 default:
4186 break;
4187 }
4188 if (e_flags & EF_PARISC_TRAPNIL)
4189 strcat (buf, ", trapnil");
4190 if (e_flags & EF_PARISC_EXT)
4191 strcat (buf, ", ext");
4192 if (e_flags & EF_PARISC_LSB)
4193 strcat (buf, ", lsb");
4194 if (e_flags & EF_PARISC_WIDE)
4195 strcat (buf, ", wide");
4196 if (e_flags & EF_PARISC_NO_KABP)
4197 strcat (buf, ", no kabp");
4198 if (e_flags & EF_PARISC_LAZYSWAP)
4199 strcat (buf, ", lazyswap");
30800947 4200 break;
76da6bbe 4201
7d466069 4202 case EM_PJ:
2b0337b0 4203 case EM_PJ_OLD:
7d466069
ILT
4204 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4205 strcat (buf, ", new calling convention");
4206
4207 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4208 strcat (buf, ", gnu calling convention");
4209 break;
4d6ed7c8
NC
4210
4211 case EM_IA_64:
4212 if ((e_flags & EF_IA_64_ABI64))
4213 strcat (buf, ", 64-bit");
4214 else
4215 strcat (buf, ", 32-bit");
4216 if ((e_flags & EF_IA_64_REDUCEDFP))
4217 strcat (buf, ", reduced fp model");
4218 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4219 strcat (buf, ", no function descriptors, constant gp");
4220 else if ((e_flags & EF_IA_64_CONS_GP))
4221 strcat (buf, ", constant gp");
4222 if ((e_flags & EF_IA_64_ABSOLUTE))
4223 strcat (buf, ", absolute");
dda8d76d 4224 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
4225 {
4226 if ((e_flags & EF_IA_64_VMS_LINKAGES))
4227 strcat (buf, ", vms_linkages");
4228 switch ((e_flags & EF_IA_64_VMS_COMCOD))
4229 {
4230 case EF_IA_64_VMS_COMCOD_SUCCESS:
4231 break;
4232 case EF_IA_64_VMS_COMCOD_WARNING:
4233 strcat (buf, ", warning");
4234 break;
4235 case EF_IA_64_VMS_COMCOD_ERROR:
4236 strcat (buf, ", error");
4237 break;
4238 case EF_IA_64_VMS_COMCOD_ABORT:
4239 strcat (buf, ", abort");
4240 break;
4241 default:
bee0ee85
NC
4242 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
4243 e_flags & EF_IA_64_VMS_COMCOD);
4244 strcat (buf, ", <unknown>");
28f997cf
TG
4245 }
4246 }
4d6ed7c8 4247 break;
179d3252
JT
4248
4249 case EM_VAX:
4250 if ((e_flags & EF_VAX_NONPIC))
4251 strcat (buf, ", non-PIC");
4252 if ((e_flags & EF_VAX_DFLOAT))
4253 strcat (buf, ", D-Float");
4254 if ((e_flags & EF_VAX_GFLOAT))
4255 strcat (buf, ", G-Float");
4256 break;
c7927a3c 4257
619ed720
EB
4258 case EM_VISIUM:
4259 if (e_flags & EF_VISIUM_ARCH_MCM)
4260 strcat (buf, ", mcm");
4261 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4262 strcat (buf, ", mcm24");
4263 if (e_flags & EF_VISIUM_ARCH_GR6)
4264 strcat (buf, ", gr6");
4265 break;
4266
4046d87a 4267 case EM_RL78:
1740ba0c
NC
4268 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4269 {
4270 case E_FLAG_RL78_ANY_CPU: break;
4271 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
4272 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
4273 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
4274 }
856ea05c
KP
4275 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4276 strcat (buf, ", 64-bit doubles");
4046d87a 4277 break;
0b4362b0 4278
c7927a3c
NC
4279 case EM_RX:
4280 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4281 strcat (buf, ", 64-bit doubles");
4282 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 4283 strcat (buf, ", dsp");
d4cb0ea0 4284 if (e_flags & E_FLAG_RX_PID)
0b4362b0 4285 strcat (buf, ", pid");
708e2187
NC
4286 if (e_flags & E_FLAG_RX_ABI)
4287 strcat (buf, ", RX ABI");
3525236c
NC
4288 if (e_flags & E_FLAG_RX_SINSNS_SET)
4289 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
4290 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
4291 if (e_flags & E_FLAG_RX_V2)
4292 strcat (buf, ", V2");
f87673e0
YS
4293 if (e_flags & E_FLAG_RX_V3)
4294 strcat (buf, ", V3");
d4cb0ea0 4295 break;
55786da2
AK
4296
4297 case EM_S390:
4298 if (e_flags & EF_S390_HIGH_GPRS)
4299 strcat (buf, ", highgprs");
d4cb0ea0 4300 break;
40b36596
JM
4301
4302 case EM_TI_C6000:
4303 if ((e_flags & EF_C6000_REL))
4304 strcat (buf, ", relocatable module");
d4cb0ea0 4305 break;
13761a11
NC
4306
4307 case EM_MSP430:
4308 strcat (buf, _(": architecture variant: "));
4309 switch (e_flags & EF_MSP430_MACH)
4310 {
4311 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
4312 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
4313 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
4314 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
4315 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
4316 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
4317 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
4318 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
4319 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
4320 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
4321 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
4322 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
4323 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
4324 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
4325 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
4326 default:
4327 strcat (buf, _(": unknown")); break;
4328 }
4329
4330 if (e_flags & ~ EF_MSP430_MACH)
4331 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
4332 break;
4333
4334 case EM_Z80:
4335 switch (e_flags & EF_Z80_MACH_MSK)
4336 {
4337 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
4338 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
4339 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
4340 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
4341 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
4342 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 4343 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
4344 default:
4345 strcat (buf, _(", unknown")); break;
4346 }
4347 break;
e9a0721f 4348 case EM_LOONGARCH:
e9a0721f 4349 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
4350 strcat (buf, ", SOFT-FLOAT");
4351 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
4352 strcat (buf, ", SINGLE-FLOAT");
4353 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
4354 strcat (buf, ", DOUBLE-FLOAT");
4355
c4a7e6b5 4356 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
4357 strcat (buf, ", OBJ-v0");
4358 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
4359 strcat (buf, ", OBJ-v1");
4360
e9a0721f 4361 break;
252b5132
RH
4362 }
4363 }
4364
4365 return buf;
4366}
4367
252b5132 4368static const char *
dda8d76d 4369get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4370{
4371 static char buff[32];
4372
4373 switch (osabi)
4374 {
4375 case ELFOSABI_NONE: return "UNIX - System V";
4376 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4377 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4378 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4379 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4380 case ELFOSABI_AIX: return "UNIX - AIX";
4381 case ELFOSABI_IRIX: return "UNIX - IRIX";
4382 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4383 case ELFOSABI_TRU64: return "UNIX - TRU64";
4384 case ELFOSABI_MODESTO: return "Novell - Modesto";
4385 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4386 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4387 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4388 case ELFOSABI_AROS: return "AROS";
11636f9e 4389 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4390 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4391 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4392 default:
40b36596 4393 if (osabi >= 64)
dda8d76d 4394 switch (filedata->file_header.e_machine)
40b36596 4395 {
37870be8
SM
4396 case EM_AMDGPU:
4397 switch (osabi)
4398 {
4399 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4400 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4401 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4402 default:
4403 break;
4404 }
4405 break;
4406
40b36596
JM
4407 case EM_ARM:
4408 switch (osabi)
4409 {
4410 case ELFOSABI_ARM: return "ARM";
18a20338 4411 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4412 default:
4413 break;
4414 }
4415 break;
4416
4417 case EM_MSP430:
4418 case EM_MSP430_OLD:
619ed720 4419 case EM_VISIUM:
40b36596
JM
4420 switch (osabi)
4421 {
4422 case ELFOSABI_STANDALONE: return _("Standalone App");
4423 default:
4424 break;
4425 }
4426 break;
4427
4428 case EM_TI_C6000:
4429 switch (osabi)
4430 {
4431 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4432 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4433 default:
4434 break;
4435 }
4436 break;
4437
4438 default:
4439 break;
4440 }
e9e44622 4441 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4442 return buff;
4443 }
4444}
4445
a06ea964
NC
4446static const char *
4447get_aarch64_segment_type (unsigned long type)
4448{
4449 switch (type)
4450 {
32ec8896 4451 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4452 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4453 default: return NULL;
a06ea964 4454 }
a06ea964
NC
4455}
4456
b294bdf8
MM
4457static const char *
4458get_arm_segment_type (unsigned long type)
4459{
4460 switch (type)
4461 {
32ec8896
NC
4462 case PT_ARM_EXIDX: return "EXIDX";
4463 default: return NULL;
b294bdf8 4464 }
b294bdf8
MM
4465}
4466
b4cbbe8f
AK
4467static const char *
4468get_s390_segment_type (unsigned long type)
4469{
4470 switch (type)
4471 {
4472 case PT_S390_PGSTE: return "S390_PGSTE";
4473 default: return NULL;
4474 }
4475}
4476
d3ba0551
AM
4477static const char *
4478get_mips_segment_type (unsigned long type)
252b5132
RH
4479{
4480 switch (type)
4481 {
32ec8896
NC
4482 case PT_MIPS_REGINFO: return "REGINFO";
4483 case PT_MIPS_RTPROC: return "RTPROC";
4484 case PT_MIPS_OPTIONS: return "OPTIONS";
4485 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4486 default: return NULL;
252b5132 4487 }
252b5132
RH
4488}
4489
103f02d3 4490static const char *
d3ba0551 4491get_parisc_segment_type (unsigned long type)
103f02d3
UD
4492{
4493 switch (type)
4494 {
103f02d3
UD
4495 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4496 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4497 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4498 default: return NULL;
103f02d3 4499 }
103f02d3
UD
4500}
4501
4d6ed7c8 4502static const char *
d3ba0551 4503get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4504{
4505 switch (type)
4506 {
4507 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4508 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4509 default: return NULL;
4d6ed7c8 4510 }
4d6ed7c8
NC
4511}
4512
40b36596
JM
4513static const char *
4514get_tic6x_segment_type (unsigned long type)
4515{
4516 switch (type)
4517 {
32ec8896
NC
4518 case PT_C6000_PHATTR: return "C6000_PHATTR";
4519 default: return NULL;
40b36596 4520 }
40b36596
JM
4521}
4522
fbc95f1e
KC
4523static const char *
4524get_riscv_segment_type (unsigned long type)
4525{
4526 switch (type)
4527 {
4528 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4529 default: return NULL;
4530 }
4531}
4532
df3a023b
AM
4533static const char *
4534get_hpux_segment_type (unsigned long type, unsigned e_machine)
4535{
4536 if (e_machine == EM_PARISC)
4537 switch (type)
4538 {
4539 case PT_HP_TLS: return "HP_TLS";
4540 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4541 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4542 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4543 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4544 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4545 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4546 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4547 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4548 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4549 case PT_HP_PARALLEL: return "HP_PARALLEL";
4550 case PT_HP_FASTBIND: return "HP_FASTBIND";
4551 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4552 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4553 case PT_HP_STACK: return "HP_STACK";
4554 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4555 default: return NULL;
4556 }
4557
4558 if (e_machine == EM_IA_64)
4559 switch (type)
4560 {
4561 case PT_HP_TLS: return "HP_TLS";
4562 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4563 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4564 case PT_IA_64_HP_STACK: return "HP_STACK";
4565 default: return NULL;
4566 }
4567
4568 return NULL;
4569}
4570
5522f910
NC
4571static const char *
4572get_solaris_segment_type (unsigned long type)
4573{
4574 switch (type)
4575 {
4576 case 0x6464e550: return "PT_SUNW_UNWIND";
4577 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4578 case 0x6ffffff7: return "PT_LOSUNW";
4579 case 0x6ffffffa: return "PT_SUNWBSS";
4580 case 0x6ffffffb: return "PT_SUNWSTACK";
4581 case 0x6ffffffc: return "PT_SUNWDTRACE";
4582 case 0x6ffffffd: return "PT_SUNWCAP";
4583 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4584 default: return NULL;
5522f910
NC
4585 }
4586}
4587
252b5132 4588static const char *
dda8d76d 4589get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4590{
b34976b6 4591 static char buff[32];
252b5132
RH
4592
4593 switch (p_type)
4594 {
b34976b6
AM
4595 case PT_NULL: return "NULL";
4596 case PT_LOAD: return "LOAD";
252b5132 4597 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4598 case PT_INTERP: return "INTERP";
4599 case PT_NOTE: return "NOTE";
4600 case PT_SHLIB: return "SHLIB";
4601 case PT_PHDR: return "PHDR";
13ae64f3 4602 case PT_TLS: return "TLS";
32ec8896 4603 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4604 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4605 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4606 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4607
3eba3ef3
NC
4608 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4609 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4610 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4611
252b5132 4612 default:
df3a023b 4613 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4614 {
2cf0635d 4615 const char * result;
103f02d3 4616
dda8d76d 4617 switch (filedata->file_header.e_machine)
252b5132 4618 {
a06ea964
NC
4619 case EM_AARCH64:
4620 result = get_aarch64_segment_type (p_type);
4621 break;
b294bdf8
MM
4622 case EM_ARM:
4623 result = get_arm_segment_type (p_type);
4624 break;
252b5132 4625 case EM_MIPS:
4fe85591 4626 case EM_MIPS_RS3_LE:
252b5132
RH
4627 result = get_mips_segment_type (p_type);
4628 break;
103f02d3
UD
4629 case EM_PARISC:
4630 result = get_parisc_segment_type (p_type);
4631 break;
4d6ed7c8
NC
4632 case EM_IA_64:
4633 result = get_ia64_segment_type (p_type);
4634 break;
40b36596
JM
4635 case EM_TI_C6000:
4636 result = get_tic6x_segment_type (p_type);
4637 break;
b4cbbe8f
AK
4638 case EM_S390:
4639 case EM_S390_OLD:
4640 result = get_s390_segment_type (p_type);
4641 break;
fbc95f1e
KC
4642 case EM_RISCV:
4643 result = get_riscv_segment_type (p_type);
4644 break;
252b5132
RH
4645 default:
4646 result = NULL;
4647 break;
4648 }
103f02d3 4649
252b5132
RH
4650 if (result != NULL)
4651 return result;
103f02d3 4652
1a9ccd70 4653 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4654 }
4655 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4656 {
df3a023b 4657 const char * result = NULL;
103f02d3 4658
df3a023b 4659 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4660 {
df3a023b
AM
4661 case ELFOSABI_GNU:
4662 case ELFOSABI_FREEBSD:
4663 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4664 {
4665 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4666 result = buff;
4667 }
103f02d3 4668 break;
df3a023b
AM
4669 case ELFOSABI_HPUX:
4670 result = get_hpux_segment_type (p_type,
4671 filedata->file_header.e_machine);
4672 break;
4673 case ELFOSABI_SOLARIS:
4674 result = get_solaris_segment_type (p_type);
00428cca 4675 break;
103f02d3 4676 default:
103f02d3
UD
4677 break;
4678 }
103f02d3
UD
4679 if (result != NULL)
4680 return result;
4681
1a9ccd70 4682 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4683 }
252b5132 4684 else
e9e44622 4685 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4686
4687 return buff;
4688 }
4689}
4690
53a346d8
CZ
4691static const char *
4692get_arc_section_type_name (unsigned int sh_type)
4693{
4694 switch (sh_type)
4695 {
4696 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4697 default:
4698 break;
4699 }
4700 return NULL;
4701}
4702
252b5132 4703static const char *
d3ba0551 4704get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4705{
4706 switch (sh_type)
4707 {
b34976b6
AM
4708 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4709 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4710 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4711 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4712 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4713 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4714 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4715 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4716 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4717 case SHT_MIPS_RELD: return "MIPS_RELD";
4718 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4719 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4720 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4721 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4722 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4723 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4724 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4725 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4726 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4727 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4728 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4729 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4730 case SHT_MIPS_LINE: return "MIPS_LINE";
4731 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4732 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4733 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4734 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4735 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4736 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4737 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4738 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4739 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4740 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4741 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4742 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4743 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4744 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4745 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4746 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4747 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4748 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4749 default:
4750 break;
4751 }
4752 return NULL;
4753}
4754
103f02d3 4755static const char *
d3ba0551 4756get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4757{
4758 switch (sh_type)
4759 {
4760 case SHT_PARISC_EXT: return "PARISC_EXT";
4761 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4762 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4763 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4764 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4765 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4766 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4767 default: return NULL;
103f02d3 4768 }
103f02d3
UD
4769}
4770
4d6ed7c8 4771static const char *
dda8d76d 4772get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4773{
18bd398b 4774 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4775 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4776 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4777
4d6ed7c8
NC
4778 switch (sh_type)
4779 {
148b93f2
NC
4780 case SHT_IA_64_EXT: return "IA_64_EXT";
4781 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4782 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4783 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4784 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4785 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4786 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4787 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4788 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4789 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4790 default:
4791 break;
4792 }
4793 return NULL;
4794}
4795
d2b2c203
DJ
4796static const char *
4797get_x86_64_section_type_name (unsigned int sh_type)
4798{
4799 switch (sh_type)
4800 {
4801 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4802 default: return NULL;
d2b2c203 4803 }
d2b2c203
DJ
4804}
4805
a06ea964
NC
4806static const char *
4807get_aarch64_section_type_name (unsigned int sh_type)
4808{
4809 switch (sh_type)
4810 {
32ec8896
NC
4811 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4812 default: return NULL;
a06ea964 4813 }
a06ea964
NC
4814}
4815
40a18ebd
NC
4816static const char *
4817get_arm_section_type_name (unsigned int sh_type)
4818{
4819 switch (sh_type)
4820 {
7f6fed87
NC
4821 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4822 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4823 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4824 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4825 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4826 default: return NULL;
40a18ebd 4827 }
40a18ebd
NC
4828}
4829
40b36596
JM
4830static const char *
4831get_tic6x_section_type_name (unsigned int sh_type)
4832{
4833 switch (sh_type)
4834 {
32ec8896
NC
4835 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4836 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4837 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4838 case SHT_TI_ICODE: return "TI_ICODE";
4839 case SHT_TI_XREF: return "TI_XREF";
4840 case SHT_TI_HANDLER: return "TI_HANDLER";
4841 case SHT_TI_INITINFO: return "TI_INITINFO";
4842 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4843 default: return NULL;
40b36596 4844 }
40b36596
JM
4845}
4846
13761a11 4847static const char *
b0191216 4848get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4849{
4850 switch (sh_type)
4851 {
32ec8896
NC
4852 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4853 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4854 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4855 default: return NULL;
13761a11
NC
4856 }
4857}
4858
fe944acf
FT
4859static const char *
4860get_nfp_section_type_name (unsigned int sh_type)
4861{
4862 switch (sh_type)
4863 {
4864 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4865 case SHT_NFP_INITREG: return "NFP_INITREG";
4866 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4867 default: return NULL;
4868 }
4869}
4870
685080f2
NC
4871static const char *
4872get_v850_section_type_name (unsigned int sh_type)
4873{
4874 switch (sh_type)
4875 {
32ec8896
NC
4876 case SHT_V850_SCOMMON: return "V850 Small Common";
4877 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4878 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4879 case SHT_RENESAS_IOP: return "RENESAS IOP";
4880 case SHT_RENESAS_INFO: return "RENESAS INFO";
4881 default: return NULL;
685080f2
NC
4882 }
4883}
4884
2dc8dd17
JW
4885static const char *
4886get_riscv_section_type_name (unsigned int sh_type)
4887{
4888 switch (sh_type)
4889 {
4890 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4891 default: return NULL;
4892 }
4893}
4894
0861f561
CQ
4895static const char *
4896get_csky_section_type_name (unsigned int sh_type)
4897{
4898 switch (sh_type)
4899 {
4900 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4901 default: return NULL;
4902 }
4903}
4904
252b5132 4905static const char *
dda8d76d 4906get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4907{
b34976b6 4908 static char buff[32];
9fb71ee4 4909 const char * result;
252b5132
RH
4910
4911 switch (sh_type)
4912 {
4913 case SHT_NULL: return "NULL";
4914 case SHT_PROGBITS: return "PROGBITS";
4915 case SHT_SYMTAB: return "SYMTAB";
4916 case SHT_STRTAB: return "STRTAB";
4917 case SHT_RELA: return "RELA";
dd207c13 4918 case SHT_RELR: return "RELR";
252b5132
RH
4919 case SHT_HASH: return "HASH";
4920 case SHT_DYNAMIC: return "DYNAMIC";
4921 case SHT_NOTE: return "NOTE";
4922 case SHT_NOBITS: return "NOBITS";
4923 case SHT_REL: return "REL";
4924 case SHT_SHLIB: return "SHLIB";
4925 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4926 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4927 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4928 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4929 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4930 case SHT_GROUP: return "GROUP";
67ce483b 4931 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4932 case SHT_GNU_verdef: return "VERDEF";
4933 case SHT_GNU_verneed: return "VERNEED";
4934 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4935 case 0x6ffffff0: return "VERSYM";
4936 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4937 case 0x7ffffffd: return "AUXILIARY";
4938 case 0x7fffffff: return "FILTER";
047b2264 4939 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4940
4941 default:
4942 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4943 {
dda8d76d 4944 switch (filedata->file_header.e_machine)
252b5132 4945 {
53a346d8
CZ
4946 case EM_ARC:
4947 case EM_ARC_COMPACT:
4948 case EM_ARC_COMPACT2:
4949 result = get_arc_section_type_name (sh_type);
4950 break;
252b5132 4951 case EM_MIPS:
4fe85591 4952 case EM_MIPS_RS3_LE:
252b5132
RH
4953 result = get_mips_section_type_name (sh_type);
4954 break;
103f02d3
UD
4955 case EM_PARISC:
4956 result = get_parisc_section_type_name (sh_type);
4957 break;
4d6ed7c8 4958 case EM_IA_64:
dda8d76d 4959 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4960 break;
d2b2c203 4961 case EM_X86_64:
8a9036a4 4962 case EM_L1OM:
7a9068fe 4963 case EM_K1OM:
d2b2c203
DJ
4964 result = get_x86_64_section_type_name (sh_type);
4965 break;
a06ea964
NC
4966 case EM_AARCH64:
4967 result = get_aarch64_section_type_name (sh_type);
4968 break;
40a18ebd
NC
4969 case EM_ARM:
4970 result = get_arm_section_type_name (sh_type);
4971 break;
40b36596
JM
4972 case EM_TI_C6000:
4973 result = get_tic6x_section_type_name (sh_type);
4974 break;
13761a11 4975 case EM_MSP430:
b0191216 4976 result = get_msp430_section_type_name (sh_type);
13761a11 4977 break;
fe944acf
FT
4978 case EM_NFP:
4979 result = get_nfp_section_type_name (sh_type);
4980 break;
685080f2
NC
4981 case EM_V800:
4982 case EM_V850:
4983 case EM_CYGNUS_V850:
4984 result = get_v850_section_type_name (sh_type);
4985 break;
2dc8dd17
JW
4986 case EM_RISCV:
4987 result = get_riscv_section_type_name (sh_type);
4988 break;
0861f561
CQ
4989 case EM_CSKY:
4990 result = get_csky_section_type_name (sh_type);
4991 break;
252b5132
RH
4992 default:
4993 result = NULL;
4994 break;
4995 }
4996
4997 if (result != NULL)
4998 return result;
4999
9fb71ee4 5000 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5001 }
5002 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5003 {
dda8d76d 5004 switch (filedata->file_header.e_machine)
148b93f2
NC
5005 {
5006 case EM_IA_64:
dda8d76d 5007 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5008 break;
5009 default:
dda8d76d 5010 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5011 result = get_solaris_section_type (sh_type);
5012 else
1b4b80bf
NC
5013 {
5014 switch (sh_type)
5015 {
5016 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5017 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5018 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5019 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5020 default:
5021 result = NULL;
5022 break;
5023 }
5024 }
148b93f2
NC
5025 break;
5026 }
5027
5028 if (result != NULL)
5029 return result;
5030
9fb71ee4 5031 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5032 }
252b5132 5033 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5034 {
dda8d76d 5035 switch (filedata->file_header.e_machine)
685080f2
NC
5036 {
5037 case EM_V800:
5038 case EM_V850:
5039 case EM_CYGNUS_V850:
9fb71ee4 5040 result = get_v850_section_type_name (sh_type);
a9fb83be 5041 break;
685080f2 5042 default:
9fb71ee4 5043 result = NULL;
685080f2
NC
5044 break;
5045 }
5046
9fb71ee4
NC
5047 if (result != NULL)
5048 return result;
5049
5050 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5051 }
252b5132 5052 else
a7dbfd1c
NC
5053 /* This message is probably going to be displayed in a 15
5054 character wide field, so put the hex value first. */
5055 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5056
252b5132
RH
5057 return buff;
5058 }
5059}
5060
79bc120c
NC
5061enum long_option_values
5062{
5063 OPTION_DEBUG_DUMP = 512,
5064 OPTION_DYN_SYMS,
0f03783c 5065 OPTION_LTO_SYMS,
79bc120c
NC
5066 OPTION_DWARF_DEPTH,
5067 OPTION_DWARF_START,
5068 OPTION_DWARF_CHECK,
5069 OPTION_CTF_DUMP,
5070 OPTION_CTF_PARENT,
5071 OPTION_CTF_SYMBOLS,
5072 OPTION_CTF_STRINGS,
5073 OPTION_WITH_SYMBOL_VERSIONS,
5074 OPTION_RECURSE_LIMIT,
5075 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
5076 OPTION_NO_DEMANGLING,
5077 OPTION_SYM_BASE
79bc120c 5078};
2979dc34 5079
85b1c36d 5080static struct option options[] =
252b5132 5081{
79bc120c
NC
5082 /* Note - This table is alpha-sorted on the 'val'
5083 field in order to make adding new options easier. */
5084 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5085 {"all", no_argument, 0, 'a'},
79bc120c
NC
5086 {"demangle", optional_argument, 0, 'C'},
5087 {"archive-index", no_argument, 0, 'c'},
5088 {"use-dynamic", no_argument, 0, 'D'},
5089 {"dynamic", no_argument, 0, 'd'},
b34976b6 5090 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5091 {"section-groups", no_argument, 0, 'g'},
5092 {"help", no_argument, 0, 'H'},
5093 {"file-header", no_argument, 0, 'h'},
b34976b6 5094 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5095 {"lint", no_argument, 0, 'L'},
5096 {"enable-checks", no_argument, 0, 'L'},
5097 {"program-headers", no_argument, 0, 'l'},
b34976b6 5098 {"segments", no_argument, 0, 'l'},
595cf52e 5099 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5100 {"notes", no_argument, 0, 'n'},
ca0e11aa 5101 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5102 {"string-dump", required_argument, 0, 'p'},
5103 {"relocated-dump", required_argument, 0, 'R'},
5104 {"relocs", no_argument, 0, 'r'},
5105 {"section-headers", no_argument, 0, 'S'},
5106 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5107 {"symbols", no_argument, 0, 's'},
5108 {"syms", no_argument, 0, 's'},
79bc120c
NC
5109 {"silent-truncation",no_argument, 0, 'T'},
5110 {"section-details", no_argument, 0, 't'},
b3aa80b4 5111 {"unicode", required_argument, NULL, 'U'},
09c11c86 5112 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5113 {"version-info", no_argument, 0, 'V'},
5114 {"version", no_argument, 0, 'v'},
5115 {"wide", no_argument, 0, 'W'},
b34976b6 5116 {"hex-dump", required_argument, 0, 'x'},
0e602686 5117 {"decompress", no_argument, 0, 'z'},
252b5132 5118
79bc120c
NC
5119 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5120 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5121 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5122 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5123 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5124 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5125 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5126 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5127 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5128 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5129#ifdef ENABLE_LIBCTF
d344b407 5130 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5131 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5132 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5133 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5134#endif
047c3dbf 5135 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5136
b34976b6 5137 {0, no_argument, 0, 0}
252b5132
RH
5138};
5139
5140static void
2cf0635d 5141usage (FILE * stream)
252b5132 5142{
92f01d61
JM
5143 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5144 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5145 fprintf (stream, _(" Options are:\n"));
5146 fprintf (stream, _("\
5147 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5148 fprintf (stream, _("\
5149 -h --file-header Display the ELF file header\n"));
5150 fprintf (stream, _("\
5151 -l --program-headers Display the program headers\n"));
5152 fprintf (stream, _("\
5153 --segments An alias for --program-headers\n"));
5154 fprintf (stream, _("\
5155 -S --section-headers Display the sections' header\n"));
5156 fprintf (stream, _("\
5157 --sections An alias for --section-headers\n"));
5158 fprintf (stream, _("\
5159 -g --section-groups Display the section groups\n"));
5160 fprintf (stream, _("\
5161 -t --section-details Display the section details\n"));
5162 fprintf (stream, _("\
5163 -e --headers Equivalent to: -h -l -S\n"));
5164 fprintf (stream, _("\
5165 -s --syms Display the symbol table\n"));
5166 fprintf (stream, _("\
5167 --symbols An alias for --syms\n"));
5168 fprintf (stream, _("\
5169 --dyn-syms Display the dynamic symbol table\n"));
5170 fprintf (stream, _("\
5171 --lto-syms Display LTO symbol tables\n"));
5172 fprintf (stream, _("\
047c3dbf
NL
5173 --sym-base=[0|8|10|16] \n\
5174 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5175 mixed (the default), octal, decimal, hexadecimal.\n"));
5176 fprintf (stream, _("\
0d646226
AM
5177 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5178 display_demangler_styles (stream, _("\
5179 STYLE can be "));
d6249f5f
AM
5180 fprintf (stream, _("\
5181 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5182 fprintf (stream, _("\
5183 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5184 fprintf (stream, _("\
5185 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5186 fprintf (stream, _("\
5187 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5188 Display unicode characters as determined by the current locale\n\
5189 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5190 escape sequences, or treat them as invalid and display as\n\
5191 \"{hex sequences}\"\n"));
d6249f5f
AM
5192 fprintf (stream, _("\
5193 -n --notes Display the core notes (if present)\n"));
5194 fprintf (stream, _("\
5195 -r --relocs Display the relocations (if present)\n"));
5196 fprintf (stream, _("\
5197 -u --unwind Display the unwind info (if present)\n"));
5198 fprintf (stream, _("\
5199 -d --dynamic Display the dynamic section (if present)\n"));
5200 fprintf (stream, _("\
5201 -V --version-info Display the version sections (if present)\n"));
5202 fprintf (stream, _("\
5203 -A --arch-specific Display architecture specific information (if any)\n"));
5204 fprintf (stream, _("\
5205 -c --archive-index Display the symbol/file index in an archive\n"));
5206 fprintf (stream, _("\
5207 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5208 fprintf (stream, _("\
5209 -L --lint|--enable-checks\n\
5210 Display warning messages for possible problems\n"));
5211 fprintf (stream, _("\
09c11c86 5212 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5213 Dump the contents of section <number|name> as bytes\n"));
5214 fprintf (stream, _("\
09c11c86 5215 -p --string-dump=<number|name>\n\
d6249f5f
AM
5216 Dump the contents of section <number|name> as strings\n"));
5217 fprintf (stream, _("\
cf13d699 5218 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5219 Dump the relocated contents of section <number|name>\n"));
5220 fprintf (stream, _("\
5221 -z --decompress Decompress section before dumping it\n"));
5222 fprintf (stream, _("\
5223 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5224 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5225 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5226 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5227 U/=trace_info]\n\
5228 Display the contents of DWARF debug sections\n"));
5229 fprintf (stream, _("\
5230 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5231 debuginfo files\n"));
5232 fprintf (stream, _("\
5233 -P --process-links Display the contents of non-debug sections in separate\n\
5234 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5235#if DEFAULT_FOR_FOLLOW_LINKS
5236 fprintf (stream, _("\
d6249f5f
AM
5237 -wK --debug-dump=follow-links\n\
5238 Follow links to separate debug info files (default)\n"));
5239 fprintf (stream, _("\
5240 -wN --debug-dump=no-follow-links\n\
5241 Do not follow links to separate debug info files\n"));
c46b7066
NC
5242#else
5243 fprintf (stream, _("\
d6249f5f
AM
5244 -wK --debug-dump=follow-links\n\
5245 Follow links to separate debug info files\n"));
5246 fprintf (stream, _("\
5247 -wN --debug-dump=no-follow-links\n\
5248 Do not follow links to separate debug info files\n\
5249 (default)\n"));
bed566bb
NC
5250#endif
5251#if HAVE_LIBDEBUGINFOD
5252 fprintf (stream, _("\
5253 -wD --debug-dump=use-debuginfod\n\
5254 When following links, also query debuginfod servers (default)\n"));
5255 fprintf (stream, _("\
5256 -wE --debug-dump=do-not-use-debuginfod\n\
5257 When following links, do not query debuginfod servers\n"));
c46b7066 5258#endif
fd2f0033 5259 fprintf (stream, _("\
d6249f5f
AM
5260 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5261 fprintf (stream, _("\
5262 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5263#ifdef ENABLE_LIBCTF
7d9813f1 5264 fprintf (stream, _("\
d6249f5f
AM
5265 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5266 fprintf (stream, _("\
80b56fad 5267 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5268 fprintf (stream, _("\
7d9813f1 5269 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5270 Use section <number|name> as the CTF external symtab\n"));
5271 fprintf (stream, _("\
7d9813f1 5272 --ctf-strings=<number|name>\n\
d6249f5f 5273 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5274#endif
7d9813f1 5275
252b5132 5276#ifdef SUPPORT_DISASSEMBLY
92f01d61 5277 fprintf (stream, _("\
09c11c86
NC
5278 -i --instruction-dump=<number|name>\n\
5279 Disassemble the contents of section <number|name>\n"));
252b5132 5280#endif
92f01d61 5281 fprintf (stream, _("\
d6249f5f
AM
5282 -I --histogram Display histogram of bucket list lengths\n"));
5283 fprintf (stream, _("\
5284 -W --wide Allow output width to exceed 80 characters\n"));
5285 fprintf (stream, _("\
5286 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5287 fprintf (stream, _("\
5288 @<file> Read options from <file>\n"));
5289 fprintf (stream, _("\
5290 -H --help Display this information\n"));
5291 fprintf (stream, _("\
8b53311e 5292 -v --version Display the version number of readelf\n"));
1118d252 5293
92f01d61
JM
5294 if (REPORT_BUGS_TO[0] && stream == stdout)
5295 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5296
92f01d61 5297 exit (stream == stdout ? 0 : 1);
252b5132
RH
5298}
5299
18bd398b
NC
5300/* Record the fact that the user wants the contents of section number
5301 SECTION to be displayed using the method(s) encoded as flags bits
5302 in TYPE. Note, TYPE can be zero if we are creating the array for
5303 the first time. */
5304
252b5132 5305static void
6431e409
AM
5306request_dump_bynumber (struct dump_data *dumpdata,
5307 unsigned int section, dump_type type)
252b5132 5308{
6431e409 5309 if (section >= dumpdata->num_dump_sects)
252b5132 5310 {
2cf0635d 5311 dump_type * new_dump_sects;
252b5132 5312
3f5e193b 5313 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5314 sizeof (* new_dump_sects));
252b5132
RH
5315
5316 if (new_dump_sects == NULL)
591a748a 5317 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5318 else
5319 {
6431e409 5320 if (dumpdata->dump_sects)
21b65bac
NC
5321 {
5322 /* Copy current flag settings. */
6431e409
AM
5323 memcpy (new_dump_sects, dumpdata->dump_sects,
5324 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5325
6431e409 5326 free (dumpdata->dump_sects);
21b65bac 5327 }
252b5132 5328
6431e409
AM
5329 dumpdata->dump_sects = new_dump_sects;
5330 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5331 }
5332 }
5333
6431e409
AM
5334 if (dumpdata->dump_sects)
5335 dumpdata->dump_sects[section] |= type;
252b5132
RH
5336}
5337
aef1f6d0
DJ
5338/* Request a dump by section name. */
5339
5340static void
2cf0635d 5341request_dump_byname (const char * section, dump_type type)
aef1f6d0 5342{
2cf0635d 5343 struct dump_list_entry * new_request;
aef1f6d0 5344
3f5e193b
NC
5345 new_request = (struct dump_list_entry *)
5346 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5347 if (!new_request)
591a748a 5348 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5349
5350 new_request->name = strdup (section);
5351 if (!new_request->name)
591a748a 5352 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5353
5354 new_request->type = type;
5355
5356 new_request->next = dump_sects_byname;
5357 dump_sects_byname = new_request;
5358}
5359
cf13d699 5360static inline void
6431e409 5361request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5362{
5363 int section;
5364 char * cp;
5365
015dc7e1 5366 do_dump = true;
cf13d699
NC
5367 section = strtoul (optarg, & cp, 0);
5368
5369 if (! *cp && section >= 0)
6431e409 5370 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5371 else
5372 request_dump_byname (optarg, type);
5373}
5374
252b5132 5375static void
6431e409 5376parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5377{
5378 int c;
5379
5380 if (argc < 2)
92f01d61 5381 usage (stderr);
252b5132
RH
5382
5383 while ((c = getopt_long
b3aa80b4 5384 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5385 {
252b5132
RH
5386 switch (c)
5387 {
5388 case 0:
5389 /* Long options. */
5390 break;
5391 case 'H':
92f01d61 5392 usage (stdout);
252b5132
RH
5393 break;
5394
5395 case 'a':
015dc7e1
AM
5396 do_syms = true;
5397 do_reloc = true;
5398 do_unwind = true;
5399 do_dynamic = true;
5400 do_header = true;
5401 do_sections = true;
5402 do_section_groups = true;
5403 do_segments = true;
5404 do_version = true;
5405 do_histogram = true;
5406 do_arch = true;
5407 do_notes = true;
252b5132 5408 break;
79bc120c 5409
f5842774 5410 case 'g':
015dc7e1 5411 do_section_groups = true;
f5842774 5412 break;
5477e8a0 5413 case 't':
595cf52e 5414 case 'N':
015dc7e1
AM
5415 do_sections = true;
5416 do_section_details = true;
595cf52e 5417 break;
252b5132 5418 case 'e':
015dc7e1
AM
5419 do_header = true;
5420 do_sections = true;
5421 do_segments = true;
252b5132 5422 break;
a952a375 5423 case 'A':
015dc7e1 5424 do_arch = true;
a952a375 5425 break;
252b5132 5426 case 'D':
015dc7e1 5427 do_using_dynamic = true;
252b5132
RH
5428 break;
5429 case 'r':
015dc7e1 5430 do_reloc = true;
252b5132 5431 break;
4d6ed7c8 5432 case 'u':
015dc7e1 5433 do_unwind = true;
4d6ed7c8 5434 break;
252b5132 5435 case 'h':
015dc7e1 5436 do_header = true;
252b5132
RH
5437 break;
5438 case 'l':
015dc7e1 5439 do_segments = true;
252b5132
RH
5440 break;
5441 case 's':
015dc7e1 5442 do_syms = true;
252b5132
RH
5443 break;
5444 case 'S':
015dc7e1 5445 do_sections = true;
252b5132
RH
5446 break;
5447 case 'd':
015dc7e1 5448 do_dynamic = true;
252b5132 5449 break;
a952a375 5450 case 'I':
015dc7e1 5451 do_histogram = true;
a952a375 5452 break;
779fe533 5453 case 'n':
015dc7e1 5454 do_notes = true;
779fe533 5455 break;
4145f1d5 5456 case 'c':
015dc7e1 5457 do_archive_index = true;
4145f1d5 5458 break;
1b513401 5459 case 'L':
015dc7e1 5460 do_checks = true;
1b513401 5461 break;
ca0e11aa 5462 case 'P':
015dc7e1
AM
5463 process_links = true;
5464 do_follow_links = true;
e1dbfc17 5465 dump_any_debugging = true;
ca0e11aa 5466 break;
252b5132 5467 case 'x':
6431e409 5468 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5469 break;
09c11c86 5470 case 'p':
6431e409 5471 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5472 break;
5473 case 'R':
6431e409 5474 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5475 break;
0e602686 5476 case 'z':
015dc7e1 5477 decompress_dumps = true;
0e602686 5478 break;
252b5132 5479 case 'w':
0f03783c 5480 if (optarg == NULL)
613ff48b 5481 {
015dc7e1 5482 do_debugging = true;
94585d6d
NC
5483 do_dump = true;
5484 dump_any_debugging = true;
613ff48b
CC
5485 dwarf_select_sections_all ();
5486 }
252b5132
RH
5487 else
5488 {
015dc7e1 5489 do_debugging = false;
94585d6d
NC
5490 if (dwarf_select_sections_by_letters (optarg))
5491 {
5492 do_dump = true;
5493 dump_any_debugging = true;
5494 }
252b5132
RH
5495 }
5496 break;
2979dc34 5497 case OPTION_DEBUG_DUMP:
0f03783c 5498 if (optarg == NULL)
d6249f5f 5499 {
94585d6d 5500 do_dump = true;
d6249f5f 5501 do_debugging = true;
94585d6d 5502 dump_any_debugging = true;
d6249f5f
AM
5503 dwarf_select_sections_all ();
5504 }
2979dc34
JJ
5505 else
5506 {
015dc7e1 5507 do_debugging = false;
94585d6d
NC
5508 if (dwarf_select_sections_by_names (optarg))
5509 {
5510 do_dump = true;
5511 dump_any_debugging = true;
5512 }
2979dc34
JJ
5513 }
5514 break;
fd2f0033
TT
5515 case OPTION_DWARF_DEPTH:
5516 {
5517 char *cp;
5518
5519 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5520 }
5521 break;
5522 case OPTION_DWARF_START:
5523 {
5524 char *cp;
5525
5526 dwarf_start_die = strtoul (optarg, & cp, 0);
5527 }
5528 break;
4723351a 5529 case OPTION_DWARF_CHECK:
015dc7e1 5530 dwarf_check = true;
4723351a 5531 break;
7d9813f1 5532 case OPTION_CTF_DUMP:
015dc7e1 5533 do_ctf = true;
6431e409 5534 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5535 break;
5536 case OPTION_CTF_SYMBOLS:
df16e041 5537 free (dump_ctf_symtab_name);
7d9813f1
NA
5538 dump_ctf_symtab_name = strdup (optarg);
5539 break;
5540 case OPTION_CTF_STRINGS:
df16e041 5541 free (dump_ctf_strtab_name);
7d9813f1
NA
5542 dump_ctf_strtab_name = strdup (optarg);
5543 break;
5544 case OPTION_CTF_PARENT:
df16e041 5545 free (dump_ctf_parent_name);
7d9813f1
NA
5546 dump_ctf_parent_name = strdup (optarg);
5547 break;
2c610e4b 5548 case OPTION_DYN_SYMS:
015dc7e1 5549 do_dyn_syms = true;
2c610e4b 5550 break;
0f03783c 5551 case OPTION_LTO_SYMS:
015dc7e1 5552 do_lto_syms = true;
0f03783c 5553 break;
252b5132
RH
5554#ifdef SUPPORT_DISASSEMBLY
5555 case 'i':
6431e409 5556 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5557 break;
252b5132
RH
5558#endif
5559 case 'v':
5560 print_version (program_name);
5561 break;
5562 case 'V':
015dc7e1 5563 do_version = true;
252b5132 5564 break;
d974e256 5565 case 'W':
015dc7e1 5566 do_wide = true;
d974e256 5567 break;
0942c7ab 5568 case 'T':
015dc7e1 5569 do_not_show_symbol_truncation = true;
0942c7ab 5570 break;
79bc120c 5571 case 'C':
015dc7e1 5572 do_demangle = true;
79bc120c
NC
5573 if (optarg != NULL)
5574 {
5575 enum demangling_styles style;
5576
5577 style = cplus_demangle_name_to_style (optarg);
5578 if (style == unknown_demangling)
5579 error (_("unknown demangling style `%s'"), optarg);
5580
5581 cplus_demangle_set_style (style);
5582 }
5583 break;
5584 case OPTION_NO_DEMANGLING:
015dc7e1 5585 do_demangle = false;
79bc120c
NC
5586 break;
5587 case OPTION_RECURSE_LIMIT:
5588 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5589 break;
5590 case OPTION_NO_RECURSE_LIMIT:
5591 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5592 break;
5593 case OPTION_WITH_SYMBOL_VERSIONS:
5594 /* Ignored for backward compatibility. */
5595 break;
b9e920ec 5596
b3aa80b4
NC
5597 case 'U':
5598 if (optarg == NULL)
5599 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5600 else if (streq (optarg, "default") || streq (optarg, "d"))
5601 unicode_display = unicode_default;
5602 else if (streq (optarg, "locale") || streq (optarg, "l"))
5603 unicode_display = unicode_locale;
5604 else if (streq (optarg, "escape") || streq (optarg, "e"))
5605 unicode_display = unicode_escape;
5606 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5607 unicode_display = unicode_invalid;
5608 else if (streq (optarg, "hex") || streq (optarg, "x"))
5609 unicode_display = unicode_hex;
5610 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5611 unicode_display = unicode_highlight;
5612 else
5613 error (_("invalid argument to -U/--unicode: %s"), optarg);
5614 break;
5615
047c3dbf
NL
5616 case OPTION_SYM_BASE:
5617 sym_base = 0;
5618 if (optarg != NULL)
5619 {
5620 sym_base = strtoul (optarg, NULL, 0);
5621 switch (sym_base)
5622 {
5623 case 0:
5624 case 8:
5625 case 10:
5626 case 16:
5627 break;
5628
5629 default:
5630 sym_base = 0;
5631 break;
5632 }
5633 }
5634 break;
5635
252b5132 5636 default:
252b5132
RH
5637 /* xgettext:c-format */
5638 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5639 /* Fall through. */
252b5132 5640 case '?':
92f01d61 5641 usage (stderr);
252b5132
RH
5642 }
5643 }
5644
4d6ed7c8 5645 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5646 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5647 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5648 && !do_section_groups && !do_archive_index
0f03783c 5649 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5650 {
5651 if (do_checks)
5652 {
015dc7e1
AM
5653 check_all = true;
5654 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5655 do_segments = do_header = do_dump = do_version = true;
5656 do_histogram = do_debugging = do_arch = do_notes = true;
5657 do_section_groups = do_archive_index = do_dyn_syms = true;
5658 do_lto_syms = true;
1b513401
NC
5659 }
5660 else
5661 usage (stderr);
5662 }
252b5132
RH
5663}
5664
5665static const char *
d3ba0551 5666get_elf_class (unsigned int elf_class)
252b5132 5667{
b34976b6 5668 static char buff[32];
103f02d3 5669
252b5132
RH
5670 switch (elf_class)
5671 {
5672 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5673 case ELFCLASS32: return "ELF32";
5674 case ELFCLASS64: return "ELF64";
ab5e7794 5675 default:
e9e44622 5676 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5677 return buff;
252b5132
RH
5678 }
5679}
5680
5681static const char *
d3ba0551 5682get_data_encoding (unsigned int encoding)
252b5132 5683{
b34976b6 5684 static char buff[32];
103f02d3 5685
252b5132
RH
5686 switch (encoding)
5687 {
5688 case ELFDATANONE: return _("none");
33c63f9d
CM
5689 case ELFDATA2LSB: return _("2's complement, little endian");
5690 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5691 default:
e9e44622 5692 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5693 return buff;
252b5132
RH
5694 }
5695}
5696
521f7268
NC
5697static bool
5698check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
5699{
5700 if (header->e_ident[EI_MAG0] == ELFMAG0
5701 && header->e_ident[EI_MAG1] == ELFMAG1
5702 && header->e_ident[EI_MAG2] == ELFMAG2
5703 && header->e_ident[EI_MAG3] == ELFMAG3)
5704 return true;
5705
5706 /* Some compilers produce object files that are not in the ELF file format.
5707 As an aid to users of readelf, try to identify these cases and suggest
5708 alternative tools.
5709
5710 FIXME: It is not clear if all four bytes are used as constant magic
5711 valus by all compilers. It may be necessary to recode this function if
5712 different tools use different length sequences. */
5713
5714 static struct
5715 {
5716 unsigned char magic[4];
5717 const char * obj_message;
5718 const char * ar_message;
5719 }
5720 known_magic[] =
5721 {
5722 { { 'B', 'C', 0xc0, 0xde },
5723 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
5724 N_("This is a LLVM bitcode file - try extracing and then using llvm-bcanalyzer\n")
5725 },
5726 { { 'g', 'o', ' ', 'o' },
5727 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
5728 NULL
5729 }
5730 };
5731 int i;
5732
5733 for (i = ARRAY_SIZE (known_magic); i--;)
5734 {
5735 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
5736 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
5737 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
5738 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
5739 {
5740 /* Some compiler's analyzer tools do not handle archives,
5741 so we provide two different kinds of error message. */
5742 if (filedata->archive_file_size > 0
5743 && known_magic[i].ar_message != NULL)
b3ea2010 5744 error ("%s", known_magic[i].ar_message);
521f7268 5745 else
b3ea2010 5746 error ("%s", known_magic[i].obj_message);
521f7268
NC
5747 return false;
5748 }
5749 }
5750
5751 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
5752 return false;
5753}
5754
dda8d76d 5755/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5756
015dc7e1 5757static bool
dda8d76d 5758process_file_header (Filedata * filedata)
252b5132 5759{
dda8d76d
NC
5760 Elf_Internal_Ehdr * header = & filedata->file_header;
5761
521f7268
NC
5762 if (! check_magic_number (filedata, header))
5763 return false;
252b5132 5764
ca0e11aa
NC
5765 if (! filedata->is_separate)
5766 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5767
252b5132
RH
5768 if (do_header)
5769 {
32ec8896 5770 unsigned i;
252b5132 5771
ca0e11aa
NC
5772 if (filedata->is_separate)
5773 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5774 else
5775 printf (_("ELF Header:\n"));
252b5132 5776 printf (_(" Magic: "));
b34976b6 5777 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5778 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5779 printf ("\n");
5780 printf (_(" Class: %s\n"),
dda8d76d 5781 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5782 printf (_(" Data: %s\n"),
dda8d76d 5783 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5784 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5785 header->e_ident[EI_VERSION],
5786 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5787 ? _(" (current)")
dda8d76d 5788 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5789 ? _(" <unknown>")
789be9f7 5790 : "")));
252b5132 5791 printf (_(" OS/ABI: %s\n"),
dda8d76d 5792 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5793 printf (_(" ABI Version: %d\n"),
dda8d76d 5794 header->e_ident[EI_ABIVERSION]);
252b5132 5795 printf (_(" Type: %s\n"),
93df3340 5796 get_file_type (filedata));
252b5132 5797 printf (_(" Machine: %s\n"),
dda8d76d 5798 get_machine_name (header->e_machine));
252b5132 5799 printf (_(" Version: 0x%lx\n"),
e8a64888 5800 header->e_version);
76da6bbe 5801
f7a99963 5802 printf (_(" Entry point address: "));
e8a64888 5803 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5804 printf (_("\n Start of program headers: "));
e8a64888 5805 print_vma (header->e_phoff, DEC);
f7a99963 5806 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5807 print_vma (header->e_shoff, DEC);
f7a99963 5808 printf (_(" (bytes into file)\n"));
76da6bbe 5809
252b5132 5810 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5811 header->e_flags,
dda8d76d 5812 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5813 printf (_(" Size of this header: %u (bytes)\n"),
5814 header->e_ehsize);
5815 printf (_(" Size of program headers: %u (bytes)\n"),
5816 header->e_phentsize);
5817 printf (_(" Number of program headers: %u"),
5818 header->e_phnum);
dda8d76d
NC
5819 if (filedata->section_headers != NULL
5820 && header->e_phnum == PN_XNUM
5821 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5822 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5823 putc ('\n', stdout);
e8a64888
AM
5824 printf (_(" Size of section headers: %u (bytes)\n"),
5825 header->e_shentsize);
5826 printf (_(" Number of section headers: %u"),
5827 header->e_shnum);
dda8d76d 5828 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5829 {
5830 header->e_shnum = filedata->section_headers[0].sh_size;
5831 printf (" (%u)", header->e_shnum);
5832 }
560f3c1c 5833 putc ('\n', stdout);
e8a64888
AM
5834 printf (_(" Section header string table index: %u"),
5835 header->e_shstrndx);
dda8d76d
NC
5836 if (filedata->section_headers != NULL
5837 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5838 {
5839 header->e_shstrndx = filedata->section_headers[0].sh_link;
5840 printf (" (%u)", header->e_shstrndx);
5841 }
5842 if (header->e_shstrndx != SHN_UNDEF
5843 && header->e_shstrndx >= header->e_shnum)
5844 {
5845 header->e_shstrndx = SHN_UNDEF;
5846 printf (_(" <corrupt: out of range>"));
5847 }
560f3c1c
AM
5848 putc ('\n', stdout);
5849 }
5850
dda8d76d 5851 if (filedata->section_headers != NULL)
560f3c1c 5852 {
dda8d76d
NC
5853 if (header->e_phnum == PN_XNUM
5854 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5855 {
5856 /* Throw away any cached read of PN_XNUM headers. */
5857 free (filedata->program_headers);
5858 filedata->program_headers = NULL;
5859 header->e_phnum = filedata->section_headers[0].sh_info;
5860 }
dda8d76d
NC
5861 if (header->e_shnum == SHN_UNDEF)
5862 header->e_shnum = filedata->section_headers[0].sh_size;
5863 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5864 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5865 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5866 header->e_shstrndx = SHN_UNDEF;
252b5132 5867 }
103f02d3 5868
015dc7e1 5869 return true;
9ea033b2
NC
5870}
5871
dda8d76d
NC
5872/* Read in the program headers from FILEDATA and store them in PHEADERS.
5873 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5874
015dc7e1 5875static bool
dda8d76d 5876get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5877{
2cf0635d
NC
5878 Elf32_External_Phdr * phdrs;
5879 Elf32_External_Phdr * external;
5880 Elf_Internal_Phdr * internal;
b34976b6 5881 unsigned int i;
dda8d76d
NC
5882 unsigned int size = filedata->file_header.e_phentsize;
5883 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5884
5885 /* PR binutils/17531: Cope with unexpected section header sizes. */
5886 if (size == 0 || num == 0)
015dc7e1 5887 return false;
e0a31db1
NC
5888 if (size < sizeof * phdrs)
5889 {
5890 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5891 return false;
e0a31db1
NC
5892 }
5893 if (size > sizeof * phdrs)
5894 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5895
dda8d76d 5896 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5897 size, num, _("program headers"));
5898 if (phdrs == NULL)
015dc7e1 5899 return false;
9ea033b2 5900
91d6fa6a 5901 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5902 i < filedata->file_header.e_phnum;
b34976b6 5903 i++, internal++, external++)
252b5132 5904 {
9ea033b2
NC
5905 internal->p_type = BYTE_GET (external->p_type);
5906 internal->p_offset = BYTE_GET (external->p_offset);
5907 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5908 internal->p_paddr = BYTE_GET (external->p_paddr);
5909 internal->p_filesz = BYTE_GET (external->p_filesz);
5910 internal->p_memsz = BYTE_GET (external->p_memsz);
5911 internal->p_flags = BYTE_GET (external->p_flags);
5912 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5913 }
5914
9ea033b2 5915 free (phdrs);
015dc7e1 5916 return true;
252b5132
RH
5917}
5918
dda8d76d
NC
5919/* Read in the program headers from FILEDATA and store them in PHEADERS.
5920 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5921
015dc7e1 5922static bool
dda8d76d 5923get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5924{
2cf0635d
NC
5925 Elf64_External_Phdr * phdrs;
5926 Elf64_External_Phdr * external;
5927 Elf_Internal_Phdr * internal;
b34976b6 5928 unsigned int i;
dda8d76d
NC
5929 unsigned int size = filedata->file_header.e_phentsize;
5930 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5931
5932 /* PR binutils/17531: Cope with unexpected section header sizes. */
5933 if (size == 0 || num == 0)
015dc7e1 5934 return false;
e0a31db1
NC
5935 if (size < sizeof * phdrs)
5936 {
5937 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5938 return false;
e0a31db1
NC
5939 }
5940 if (size > sizeof * phdrs)
5941 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5942
dda8d76d 5943 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5944 size, num, _("program headers"));
a6e9f9df 5945 if (!phdrs)
015dc7e1 5946 return false;
9ea033b2 5947
91d6fa6a 5948 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5949 i < filedata->file_header.e_phnum;
b34976b6 5950 i++, internal++, external++)
9ea033b2
NC
5951 {
5952 internal->p_type = BYTE_GET (external->p_type);
5953 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5954 internal->p_offset = BYTE_GET (external->p_offset);
5955 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5956 internal->p_paddr = BYTE_GET (external->p_paddr);
5957 internal->p_filesz = BYTE_GET (external->p_filesz);
5958 internal->p_memsz = BYTE_GET (external->p_memsz);
5959 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5960 }
5961
5962 free (phdrs);
015dc7e1 5963 return true;
9ea033b2 5964}
252b5132 5965
32ec8896 5966/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5967
015dc7e1 5968static bool
dda8d76d 5969get_program_headers (Filedata * filedata)
d93f0186 5970{
2cf0635d 5971 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5972
5973 /* Check cache of prior read. */
dda8d76d 5974 if (filedata->program_headers != NULL)
015dc7e1 5975 return true;
d93f0186 5976
82156ab7
NC
5977 /* Be kind to memory checkers by looking for
5978 e_phnum values which we know must be invalid. */
dda8d76d 5979 if (filedata->file_header.e_phnum
82156ab7 5980 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5981 >= filedata->file_size)
82156ab7
NC
5982 {
5983 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5984 filedata->file_header.e_phnum);
015dc7e1 5985 return false;
82156ab7 5986 }
d93f0186 5987
dda8d76d 5988 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5989 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5990 if (phdrs == NULL)
5991 {
8b73c356 5992 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5993 filedata->file_header.e_phnum);
015dc7e1 5994 return false;
d93f0186
NC
5995 }
5996
5997 if (is_32bit_elf
dda8d76d
NC
5998 ? get_32bit_program_headers (filedata, phdrs)
5999 : get_64bit_program_headers (filedata, phdrs))
d93f0186 6000 {
dda8d76d 6001 filedata->program_headers = phdrs;
015dc7e1 6002 return true;
d93f0186
NC
6003 }
6004
6005 free (phdrs);
015dc7e1 6006 return false;
d93f0186
NC
6007}
6008
93df3340 6009/* Print program header info and locate dynamic section. */
2f62977e 6010
93df3340 6011static void
dda8d76d 6012process_program_headers (Filedata * filedata)
252b5132 6013{
2cf0635d 6014 Elf_Internal_Phdr * segment;
b34976b6 6015 unsigned int i;
1a9ccd70 6016 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6017
dda8d76d 6018 if (filedata->file_header.e_phnum == 0)
252b5132 6019 {
82f2dbf7 6020 /* PR binutils/12467. */
dda8d76d 6021 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6022 warn (_("possibly corrupt ELF header - it has a non-zero program"
6023 " header offset, but no program headers\n"));
82f2dbf7 6024 else if (do_segments)
ca0e11aa
NC
6025 {
6026 if (filedata->is_separate)
6027 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6028 filedata->file_name);
6029 else
6030 printf (_("\nThere are no program headers in this file.\n"));
6031 }
93df3340 6032 goto no_headers;
252b5132
RH
6033 }
6034
6035 if (do_segments && !do_header)
6036 {
ca0e11aa
NC
6037 if (filedata->is_separate)
6038 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6039 filedata->file_name, get_file_type (filedata));
ca0e11aa 6040 else
93df3340 6041 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6042 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6043 filedata->file_header.e_entry);
b8281767
AM
6044 printf (ngettext ("There is %d program header,"
6045 " starting at offset %" PRIu64 "\n",
6046 "There are %d program headers,"
6047 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6048 filedata->file_header.e_phnum),
6049 filedata->file_header.e_phnum,
625d49fc 6050 filedata->file_header.e_phoff);
252b5132
RH
6051 }
6052
dda8d76d 6053 if (! get_program_headers (filedata))
93df3340 6054 goto no_headers;
103f02d3 6055
252b5132
RH
6056 if (do_segments)
6057 {
dda8d76d 6058 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6059 printf (_("\nProgram Headers:\n"));
6060 else
6061 printf (_("\nProgram Headers:\n"));
76da6bbe 6062
f7a99963
NC
6063 if (is_32bit_elf)
6064 printf
6065 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6066 else if (do_wide)
6067 printf
6068 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6069 else
6070 {
6071 printf
6072 (_(" Type Offset VirtAddr PhysAddr\n"));
6073 printf
6074 (_(" FileSiz MemSiz Flags Align\n"));
6075 }
252b5132
RH
6076 }
6077
93df3340 6078 unsigned long dynamic_addr = 0;
be7d229a 6079 uint64_t dynamic_size = 0;
dda8d76d
NC
6080 for (i = 0, segment = filedata->program_headers;
6081 i < filedata->file_header.e_phnum;
b34976b6 6082 i++, segment++)
252b5132
RH
6083 {
6084 if (do_segments)
6085 {
dda8d76d 6086 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6087
6088 if (is_32bit_elf)
6089 {
6090 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6091 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6092 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6093 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6094 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6095 printf ("%c%c%c ",
6096 (segment->p_flags & PF_R ? 'R' : ' '),
6097 (segment->p_flags & PF_W ? 'W' : ' '),
6098 (segment->p_flags & PF_X ? 'E' : ' '));
6099 printf ("%#lx", (unsigned long) segment->p_align);
6100 }
d974e256
JJ
6101 else if (do_wide)
6102 {
6103 if ((unsigned long) segment->p_offset == segment->p_offset)
6104 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6105 else
6106 {
6107 print_vma (segment->p_offset, FULL_HEX);
6108 putchar (' ');
6109 }
6110
6111 print_vma (segment->p_vaddr, FULL_HEX);
6112 putchar (' ');
6113 print_vma (segment->p_paddr, FULL_HEX);
6114 putchar (' ');
6115
6116 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6117 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6118 else
6119 {
6120 print_vma (segment->p_filesz, FULL_HEX);
6121 putchar (' ');
6122 }
6123
6124 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6125 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6126 else
6127 {
f48e6c45 6128 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6129 }
6130
6131 printf (" %c%c%c ",
6132 (segment->p_flags & PF_R ? 'R' : ' '),
6133 (segment->p_flags & PF_W ? 'W' : ' '),
6134 (segment->p_flags & PF_X ? 'E' : ' '));
6135
6136 if ((unsigned long) segment->p_align == segment->p_align)
6137 printf ("%#lx", (unsigned long) segment->p_align);
6138 else
6139 {
6140 print_vma (segment->p_align, PREFIX_HEX);
6141 }
6142 }
f7a99963
NC
6143 else
6144 {
6145 print_vma (segment->p_offset, FULL_HEX);
6146 putchar (' ');
6147 print_vma (segment->p_vaddr, FULL_HEX);
6148 putchar (' ');
6149 print_vma (segment->p_paddr, FULL_HEX);
6150 printf ("\n ");
6151 print_vma (segment->p_filesz, FULL_HEX);
6152 putchar (' ');
6153 print_vma (segment->p_memsz, FULL_HEX);
6154 printf (" %c%c%c ",
6155 (segment->p_flags & PF_R ? 'R' : ' '),
6156 (segment->p_flags & PF_W ? 'W' : ' '),
6157 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6158 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6159 }
252b5132 6160
1a9ccd70
NC
6161 putc ('\n', stdout);
6162 }
f54498b4 6163
252b5132
RH
6164 switch (segment->p_type)
6165 {
1a9ccd70 6166 case PT_LOAD:
502d895c
NC
6167#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6168 required by the ELF standard, several programs, including the Linux
6169 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6170 if (previous_load
6171 && previous_load->p_vaddr > segment->p_vaddr)
6172 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6173#endif
1a9ccd70
NC
6174 if (segment->p_memsz < segment->p_filesz)
6175 error (_("the segment's file size is larger than its memory size\n"));
6176 previous_load = segment;
6177 break;
6178
6179 case PT_PHDR:
6180 /* PR 20815 - Verify that the program header is loaded into memory. */
6181 if (i > 0 && previous_load != NULL)
6182 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6183 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6184 {
6185 unsigned int j;
6186
dda8d76d 6187 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6188 {
6189 Elf_Internal_Phdr *load = filedata->program_headers + j;
6190 if (load->p_type == PT_LOAD
6191 && load->p_offset <= segment->p_offset
6192 && (load->p_offset + load->p_filesz
6193 >= segment->p_offset + segment->p_filesz)
6194 && load->p_vaddr <= segment->p_vaddr
6195 && (load->p_vaddr + load->p_filesz
6196 >= segment->p_vaddr + segment->p_filesz))
6197 break;
6198 }
dda8d76d 6199 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6200 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6201 }
6202 break;
6203
252b5132 6204 case PT_DYNAMIC:
93df3340 6205 if (dynamic_addr)
252b5132
RH
6206 error (_("more than one dynamic segment\n"));
6207
20737c13
AM
6208 /* By default, assume that the .dynamic section is the first
6209 section in the DYNAMIC segment. */
93df3340
AM
6210 dynamic_addr = segment->p_offset;
6211 dynamic_size = segment->p_filesz;
20737c13 6212
b2d38a17
NC
6213 /* Try to locate the .dynamic section. If there is
6214 a section header table, we can easily locate it. */
dda8d76d 6215 if (filedata->section_headers != NULL)
b2d38a17 6216 {
2cf0635d 6217 Elf_Internal_Shdr * sec;
b2d38a17 6218
dda8d76d 6219 sec = find_section (filedata, ".dynamic");
89fac5e3 6220 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6221 {
93df3340
AM
6222 /* A corresponding .dynamic section is expected, but on
6223 IA-64/OpenVMS it is OK for it to be missing. */
6224 if (!is_ia64_vms (filedata))
6225 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6226 break;
6227 }
6228
42bb2e33 6229 if (sec->sh_type == SHT_NOBITS)
20737c13 6230 {
93df3340
AM
6231 dynamic_addr = 0;
6232 dynamic_size = 0;
20737c13
AM
6233 break;
6234 }
42bb2e33 6235
93df3340
AM
6236 dynamic_addr = sec->sh_offset;
6237 dynamic_size = sec->sh_size;
b2d38a17 6238
8ac10c5b
L
6239 /* The PT_DYNAMIC segment, which is used by the run-time
6240 loader, should exactly match the .dynamic section. */
6241 if (do_checks
93df3340
AM
6242 && (dynamic_addr != segment->p_offset
6243 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6244 warn (_("\
6245the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6246 }
39e224f6
MW
6247
6248 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6249 segment. Check this after matching against the section headers
6250 so we don't warn on debuginfo file (which have NOBITS .dynamic
6251 sections). */
93df3340
AM
6252 if (dynamic_addr > filedata->file_size
6253 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6254 {
6255 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6256 dynamic_addr = 0;
6257 dynamic_size = 0;
39e224f6 6258 }
252b5132
RH
6259 break;
6260
6261 case PT_INTERP:
13acb58d
AM
6262 if (segment->p_offset >= filedata->file_size
6263 || segment->p_filesz > filedata->file_size - segment->p_offset
6264 || segment->p_filesz - 1 >= (size_t) -2
6265 || fseek (filedata->handle,
6266 filedata->archive_file_offset + (long) segment->p_offset,
6267 SEEK_SET))
252b5132
RH
6268 error (_("Unable to find program interpreter name\n"));
6269 else
6270 {
13acb58d
AM
6271 size_t len = segment->p_filesz;
6272 free (filedata->program_interpreter);
6273 filedata->program_interpreter = xmalloc (len + 1);
6274 len = fread (filedata->program_interpreter, 1, len,
6275 filedata->handle);
6276 filedata->program_interpreter[len] = 0;
252b5132
RH
6277
6278 if (do_segments)
f54498b4 6279 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6280 filedata->program_interpreter);
252b5132
RH
6281 }
6282 break;
6283 }
252b5132
RH
6284 }
6285
dda8d76d
NC
6286 if (do_segments
6287 && filedata->section_headers != NULL
6288 && filedata->string_table != NULL)
252b5132
RH
6289 {
6290 printf (_("\n Section to Segment mapping:\n"));
6291 printf (_(" Segment Sections...\n"));
6292
dda8d76d 6293 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6294 {
9ad5cbcf 6295 unsigned int j;
2cf0635d 6296 Elf_Internal_Shdr * section;
252b5132 6297
dda8d76d
NC
6298 segment = filedata->program_headers + i;
6299 section = filedata->section_headers + 1;
252b5132
RH
6300
6301 printf (" %2.2d ", i);
6302
dda8d76d 6303 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6304 {
f4638467
AM
6305 if (!ELF_TBSS_SPECIAL (section, segment)
6306 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6307 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6308 }
6309
6310 putc ('\n',stdout);
6311 }
6312 }
6313
93df3340
AM
6314 filedata->dynamic_addr = dynamic_addr;
6315 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6316 return;
6317
6318 no_headers:
6319 filedata->dynamic_addr = 0;
6320 filedata->dynamic_size = 1;
252b5132
RH
6321}
6322
6323
d93f0186
NC
6324/* Find the file offset corresponding to VMA by using the program headers. */
6325
6326static long
625d49fc 6327offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 6328{
2cf0635d 6329 Elf_Internal_Phdr * seg;
d93f0186 6330
dda8d76d 6331 if (! get_program_headers (filedata))
d93f0186
NC
6332 {
6333 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6334 return (long) vma;
6335 }
6336
dda8d76d
NC
6337 for (seg = filedata->program_headers;
6338 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6339 ++seg)
6340 {
6341 if (seg->p_type != PT_LOAD)
6342 continue;
6343
6344 if (vma >= (seg->p_vaddr & -seg->p_align)
6345 && vma + size <= seg->p_vaddr + seg->p_filesz)
6346 return vma - seg->p_vaddr + seg->p_offset;
6347 }
6348
6349 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 6350 (unsigned long) vma);
d93f0186
NC
6351 return (long) vma;
6352}
6353
6354
dda8d76d
NC
6355/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6356 If PROBE is true, this is just a probe and we do not generate any error
6357 messages if the load fails. */
049b0c3a 6358
015dc7e1
AM
6359static bool
6360get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6361{
2cf0635d
NC
6362 Elf32_External_Shdr * shdrs;
6363 Elf_Internal_Shdr * internal;
dda8d76d
NC
6364 unsigned int i;
6365 unsigned int size = filedata->file_header.e_shentsize;
6366 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6367
6368 /* PR binutils/17531: Cope with unexpected section header sizes. */
6369 if (size == 0 || num == 0)
015dc7e1 6370 return false;
907b52f4
NC
6371
6372 /* The section header cannot be at the start of the file - that is
6373 where the ELF file header is located. A file with absolutely no
6374 sections in it will use a shoff of 0. */
6375 if (filedata->file_header.e_shoff == 0)
6376 return false;
6377
049b0c3a
NC
6378 if (size < sizeof * shdrs)
6379 {
6380 if (! probe)
6381 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6382 return false;
049b0c3a
NC
6383 }
6384 if (!probe && size > sizeof * shdrs)
6385 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6386
dda8d76d 6387 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6388 size, num,
6389 probe ? NULL : _("section headers"));
6390 if (shdrs == NULL)
015dc7e1 6391 return false;
252b5132 6392
dda8d76d
NC
6393 filedata->section_headers = (Elf_Internal_Shdr *)
6394 cmalloc (num, sizeof (Elf_Internal_Shdr));
6395 if (filedata->section_headers == NULL)
252b5132 6396 {
049b0c3a 6397 if (!probe)
8b73c356 6398 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6399 free (shdrs);
015dc7e1 6400 return false;
252b5132
RH
6401 }
6402
dda8d76d 6403 for (i = 0, internal = filedata->section_headers;
560f3c1c 6404 i < num;
b34976b6 6405 i++, internal++)
252b5132
RH
6406 {
6407 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6408 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6409 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6410 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6411 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6412 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6413 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6414 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6415 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6416 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6417 if (!probe && internal->sh_link > num)
6418 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6419 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6420 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6421 }
6422
6423 free (shdrs);
015dc7e1 6424 return true;
252b5132
RH
6425}
6426
dda8d76d
NC
6427/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6428
015dc7e1
AM
6429static bool
6430get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6431{
dda8d76d
NC
6432 Elf64_External_Shdr * shdrs;
6433 Elf_Internal_Shdr * internal;
6434 unsigned int i;
6435 unsigned int size = filedata->file_header.e_shentsize;
6436 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6437
6438 /* PR binutils/17531: Cope with unexpected section header sizes. */
6439 if (size == 0 || num == 0)
015dc7e1 6440 return false;
dda8d76d 6441
907b52f4
NC
6442 /* The section header cannot be at the start of the file - that is
6443 where the ELF file header is located. A file with absolutely no
6444 sections in it will use a shoff of 0. */
6445 if (filedata->file_header.e_shoff == 0)
6446 return false;
6447
049b0c3a
NC
6448 if (size < sizeof * shdrs)
6449 {
6450 if (! probe)
6451 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6452 return false;
049b0c3a 6453 }
dda8d76d 6454
049b0c3a
NC
6455 if (! probe && size > sizeof * shdrs)
6456 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6457
dda8d76d
NC
6458 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6459 filedata->file_header.e_shoff,
049b0c3a
NC
6460 size, num,
6461 probe ? NULL : _("section headers"));
6462 if (shdrs == NULL)
015dc7e1 6463 return false;
9ea033b2 6464
dda8d76d
NC
6465 filedata->section_headers = (Elf_Internal_Shdr *)
6466 cmalloc (num, sizeof (Elf_Internal_Shdr));
6467 if (filedata->section_headers == NULL)
9ea033b2 6468 {
049b0c3a 6469 if (! probe)
8b73c356 6470 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6471 free (shdrs);
015dc7e1 6472 return false;
9ea033b2
NC
6473 }
6474
dda8d76d 6475 for (i = 0, internal = filedata->section_headers;
560f3c1c 6476 i < num;
b34976b6 6477 i++, internal++)
9ea033b2
NC
6478 {
6479 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6480 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6481 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6482 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6483 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6484 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6485 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6486 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6487 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6488 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6489 if (!probe && internal->sh_link > num)
6490 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6491 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6492 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6493 }
6494
6495 free (shdrs);
015dc7e1 6496 return true;
9ea033b2
NC
6497}
6498
4de91c10
AM
6499static bool
6500get_section_headers (Filedata *filedata, bool probe)
6501{
6502 if (filedata->section_headers != NULL)
6503 return true;
6504
4de91c10
AM
6505 if (is_32bit_elf)
6506 return get_32bit_section_headers (filedata, probe);
6507 else
6508 return get_64bit_section_headers (filedata, probe);
6509}
6510
252b5132 6511static Elf_Internal_Sym *
dda8d76d
NC
6512get_32bit_elf_symbols (Filedata * filedata,
6513 Elf_Internal_Shdr * section,
6514 unsigned long * num_syms_return)
252b5132 6515{
ba5cdace 6516 unsigned long number = 0;
dd24e3da 6517 Elf32_External_Sym * esyms = NULL;
ba5cdace 6518 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6519 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6520 Elf_Internal_Sym * psym;
b34976b6 6521 unsigned int j;
e3d39609 6522 elf_section_list * entry;
252b5132 6523
c9c1d674
EG
6524 if (section->sh_size == 0)
6525 {
6526 if (num_syms_return != NULL)
6527 * num_syms_return = 0;
6528 return NULL;
6529 }
6530
dd24e3da 6531 /* Run some sanity checks first. */
c9c1d674 6532 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6533 {
c9c1d674 6534 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
6535 printable_section_name (filedata, section),
6536 (unsigned long) section->sh_entsize);
ba5cdace 6537 goto exit_point;
dd24e3da
NC
6538 }
6539
dda8d76d 6540 if (section->sh_size > filedata->file_size)
f54498b4
NC
6541 {
6542 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
6543 printable_section_name (filedata, section),
6544 (unsigned long) section->sh_size);
f54498b4
NC
6545 goto exit_point;
6546 }
6547
dd24e3da
NC
6548 number = section->sh_size / section->sh_entsize;
6549
6550 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6551 {
c9c1d674 6552 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6553 (unsigned long) section->sh_size,
dda8d76d 6554 printable_section_name (filedata, section),
8066deb1 6555 (unsigned long) section->sh_entsize);
ba5cdace 6556 goto exit_point;
dd24e3da
NC
6557 }
6558
dda8d76d 6559 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6560 section->sh_size, _("symbols"));
dd24e3da 6561 if (esyms == NULL)
ba5cdace 6562 goto exit_point;
252b5132 6563
e3d39609 6564 shndx = NULL;
978c4450 6565 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6566 {
6567 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6568 continue;
6569
6570 if (shndx != NULL)
6571 {
6572 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6573 free (shndx);
6574 }
6575
6576 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6577 entry->hdr->sh_offset,
6578 1, entry->hdr->sh_size,
6579 _("symbol table section indices"));
6580 if (shndx == NULL)
6581 goto exit_point;
6582
6583 /* PR17531: file: heap-buffer-overflow */
6584 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6585 {
6586 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6587 printable_section_name (filedata, entry->hdr),
6588 (unsigned long) entry->hdr->sh_size,
6589 (unsigned long) section->sh_size);
6590 goto exit_point;
c9c1d674 6591 }
e3d39609 6592 }
9ad5cbcf 6593
3f5e193b 6594 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6595
6596 if (isyms == NULL)
6597 {
8b73c356
NC
6598 error (_("Out of memory reading %lu symbols\n"),
6599 (unsigned long) number);
dd24e3da 6600 goto exit_point;
252b5132
RH
6601 }
6602
dd24e3da 6603 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6604 {
6605 psym->st_name = BYTE_GET (esyms[j].st_name);
6606 psym->st_value = BYTE_GET (esyms[j].st_value);
6607 psym->st_size = BYTE_GET (esyms[j].st_size);
6608 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6609 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6610 psym->st_shndx
6611 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6612 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6613 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6614 psym->st_info = BYTE_GET (esyms[j].st_info);
6615 psym->st_other = BYTE_GET (esyms[j].st_other);
6616 }
6617
dd24e3da 6618 exit_point:
e3d39609
NC
6619 free (shndx);
6620 free (esyms);
252b5132 6621
ba5cdace
NC
6622 if (num_syms_return != NULL)
6623 * num_syms_return = isyms == NULL ? 0 : number;
6624
252b5132
RH
6625 return isyms;
6626}
6627
9ea033b2 6628static Elf_Internal_Sym *
dda8d76d
NC
6629get_64bit_elf_symbols (Filedata * filedata,
6630 Elf_Internal_Shdr * section,
6631 unsigned long * num_syms_return)
9ea033b2 6632{
ba5cdace
NC
6633 unsigned long number = 0;
6634 Elf64_External_Sym * esyms = NULL;
6635 Elf_External_Sym_Shndx * shndx = NULL;
6636 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6637 Elf_Internal_Sym * psym;
b34976b6 6638 unsigned int j;
e3d39609 6639 elf_section_list * entry;
9ea033b2 6640
c9c1d674
EG
6641 if (section->sh_size == 0)
6642 {
6643 if (num_syms_return != NULL)
6644 * num_syms_return = 0;
6645 return NULL;
6646 }
6647
dd24e3da 6648 /* Run some sanity checks first. */
c9c1d674 6649 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6650 {
c9c1d674 6651 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6652 printable_section_name (filedata, section),
8066deb1 6653 (unsigned long) section->sh_entsize);
ba5cdace 6654 goto exit_point;
dd24e3da
NC
6655 }
6656
dda8d76d 6657 if (section->sh_size > filedata->file_size)
f54498b4
NC
6658 {
6659 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6660 printable_section_name (filedata, section),
8066deb1 6661 (unsigned long) section->sh_size);
f54498b4
NC
6662 goto exit_point;
6663 }
6664
dd24e3da
NC
6665 number = section->sh_size / section->sh_entsize;
6666
6667 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6668 {
c9c1d674 6669 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6670 (unsigned long) section->sh_size,
dda8d76d 6671 printable_section_name (filedata, section),
8066deb1 6672 (unsigned long) section->sh_entsize);
ba5cdace 6673 goto exit_point;
dd24e3da
NC
6674 }
6675
dda8d76d 6676 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6677 section->sh_size, _("symbols"));
a6e9f9df 6678 if (!esyms)
ba5cdace 6679 goto exit_point;
9ea033b2 6680
e3d39609 6681 shndx = NULL;
978c4450 6682 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6683 {
6684 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6685 continue;
6686
6687 if (shndx != NULL)
6688 {
6689 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6690 free (shndx);
c9c1d674 6691 }
e3d39609
NC
6692
6693 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6694 entry->hdr->sh_offset,
6695 1, entry->hdr->sh_size,
6696 _("symbol table section indices"));
6697 if (shndx == NULL)
6698 goto exit_point;
6699
6700 /* PR17531: file: heap-buffer-overflow */
6701 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6702 {
6703 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6704 printable_section_name (filedata, entry->hdr),
6705 (unsigned long) entry->hdr->sh_size,
6706 (unsigned long) section->sh_size);
6707 goto exit_point;
6708 }
6709 }
9ad5cbcf 6710
3f5e193b 6711 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6712
6713 if (isyms == NULL)
6714 {
8b73c356
NC
6715 error (_("Out of memory reading %lu symbols\n"),
6716 (unsigned long) number);
ba5cdace 6717 goto exit_point;
9ea033b2
NC
6718 }
6719
ba5cdace 6720 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6721 {
6722 psym->st_name = BYTE_GET (esyms[j].st_name);
6723 psym->st_info = BYTE_GET (esyms[j].st_info);
6724 psym->st_other = BYTE_GET (esyms[j].st_other);
6725 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6726
4fbb74a6 6727 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6728 psym->st_shndx
6729 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6730 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6731 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6732
66543521
AM
6733 psym->st_value = BYTE_GET (esyms[j].st_value);
6734 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6735 }
6736
ba5cdace 6737 exit_point:
e3d39609
NC
6738 free (shndx);
6739 free (esyms);
ba5cdace
NC
6740
6741 if (num_syms_return != NULL)
6742 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6743
6744 return isyms;
6745}
6746
4de91c10
AM
6747static Elf_Internal_Sym *
6748get_elf_symbols (Filedata *filedata,
6749 Elf_Internal_Shdr *section,
6750 unsigned long *num_syms_return)
6751{
6752 if (is_32bit_elf)
6753 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6754 else
6755 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6756}
6757
d1133906 6758static const char *
625d49fc 6759get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 6760{
5477e8a0 6761 static char buff[1024];
2cf0635d 6762 char * p = buff;
32ec8896
NC
6763 unsigned int field_size = is_32bit_elf ? 8 : 16;
6764 signed int sindex;
6765 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
6766 uint64_t os_flags = 0;
6767 uint64_t proc_flags = 0;
6768 uint64_t unknown_flags = 0;
148b93f2 6769 static const struct
5477e8a0 6770 {
2cf0635d 6771 const char * str;
32ec8896 6772 unsigned int len;
5477e8a0
L
6773 }
6774 flags [] =
6775 {
cfcac11d
NC
6776 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6777 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6778 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6779 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6780 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6781 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6782 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6783 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6784 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6785 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6786 /* IA-64 specific. */
6787 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6788 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6789 /* IA-64 OpenVMS specific. */
6790 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6791 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6792 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6793 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6794 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6795 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6796 /* Generic. */
cfcac11d 6797 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6798 /* SPARC specific. */
77115a4a 6799 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6800 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6801 /* ARM specific. */
6802 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6803 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6804 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6805 /* GNU specific. */
6806 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6807 /* VLE specific. */
6808 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6809 /* GNU specific. */
6810 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6811 };
6812
6813 if (do_section_details)
6814 {
8d5ff12c
L
6815 sprintf (buff, "[%*.*lx]: ",
6816 field_size, field_size, (unsigned long) sh_flags);
6817 p += field_size + 4;
5477e8a0 6818 }
76da6bbe 6819
d1133906
NC
6820 while (sh_flags)
6821 {
625d49fc 6822 uint64_t flag;
d1133906
NC
6823
6824 flag = sh_flags & - sh_flags;
6825 sh_flags &= ~ flag;
76da6bbe 6826
5477e8a0 6827 if (do_section_details)
d1133906 6828 {
5477e8a0
L
6829 switch (flag)
6830 {
91d6fa6a
NC
6831 case SHF_WRITE: sindex = 0; break;
6832 case SHF_ALLOC: sindex = 1; break;
6833 case SHF_EXECINSTR: sindex = 2; break;
6834 case SHF_MERGE: sindex = 3; break;
6835 case SHF_STRINGS: sindex = 4; break;
6836 case SHF_INFO_LINK: sindex = 5; break;
6837 case SHF_LINK_ORDER: sindex = 6; break;
6838 case SHF_OS_NONCONFORMING: sindex = 7; break;
6839 case SHF_GROUP: sindex = 8; break;
6840 case SHF_TLS: sindex = 9; break;
18ae9cc1 6841 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6842 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6843
5477e8a0 6844 default:
91d6fa6a 6845 sindex = -1;
dda8d76d 6846 switch (filedata->file_header.e_machine)
148b93f2 6847 {
cfcac11d 6848 case EM_IA_64:
148b93f2 6849 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6850 sindex = 10;
148b93f2 6851 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6852 sindex = 11;
dda8d76d 6853 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6854 switch (flag)
6855 {
91d6fa6a
NC
6856 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6857 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6858 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6859 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6860 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6861 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6862 default: break;
6863 }
cfcac11d
NC
6864 break;
6865
caa83f8b 6866 case EM_386:
22abe556 6867 case EM_IAMCU:
caa83f8b 6868 case EM_X86_64:
7f502d6c 6869 case EM_L1OM:
7a9068fe 6870 case EM_K1OM:
cfcac11d
NC
6871 case EM_OLD_SPARCV9:
6872 case EM_SPARC32PLUS:
6873 case EM_SPARCV9:
6874 case EM_SPARC:
18ae9cc1 6875 if (flag == SHF_ORDERED)
91d6fa6a 6876 sindex = 19;
cfcac11d 6877 break;
ac4c9b04
MG
6878
6879 case EM_ARM:
6880 switch (flag)
6881 {
6882 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6883 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6884 case SHF_COMDEF: sindex = 23; break;
6885 default: break;
6886 }
6887 break;
83eef883
AFB
6888 case EM_PPC:
6889 if (flag == SHF_PPC_VLE)
6890 sindex = 25;
6891 break;
99fabbc9
JL
6892 default:
6893 break;
6894 }
ac4c9b04 6895
99fabbc9
JL
6896 switch (filedata->file_header.e_ident[EI_OSABI])
6897 {
6898 case ELFOSABI_GNU:
6899 case ELFOSABI_FREEBSD:
6900 if (flag == SHF_GNU_RETAIN)
6901 sindex = 26;
6902 /* Fall through */
6903 case ELFOSABI_NONE:
6904 if (flag == SHF_GNU_MBIND)
6905 /* We should not recognize SHF_GNU_MBIND for
6906 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6907 not set the EI_OSABI header byte. */
6908 sindex = 24;
6909 break;
cfcac11d
NC
6910 default:
6911 break;
148b93f2 6912 }
99fabbc9 6913 break;
5477e8a0
L
6914 }
6915
91d6fa6a 6916 if (sindex != -1)
5477e8a0 6917 {
8d5ff12c
L
6918 if (p != buff + field_size + 4)
6919 {
6920 if (size < (10 + 2))
bee0ee85
NC
6921 {
6922 warn (_("Internal error: not enough buffer room for section flag info"));
6923 return _("<unknown>");
6924 }
8d5ff12c
L
6925 size -= 2;
6926 *p++ = ',';
6927 *p++ = ' ';
6928 }
6929
91d6fa6a
NC
6930 size -= flags [sindex].len;
6931 p = stpcpy (p, flags [sindex].str);
5477e8a0 6932 }
3b22753a 6933 else if (flag & SHF_MASKOS)
8d5ff12c 6934 os_flags |= flag;
d1133906 6935 else if (flag & SHF_MASKPROC)
8d5ff12c 6936 proc_flags |= flag;
d1133906 6937 else
8d5ff12c 6938 unknown_flags |= flag;
5477e8a0
L
6939 }
6940 else
6941 {
6942 switch (flag)
6943 {
6944 case SHF_WRITE: *p = 'W'; break;
6945 case SHF_ALLOC: *p = 'A'; break;
6946 case SHF_EXECINSTR: *p = 'X'; break;
6947 case SHF_MERGE: *p = 'M'; break;
6948 case SHF_STRINGS: *p = 'S'; break;
6949 case SHF_INFO_LINK: *p = 'I'; break;
6950 case SHF_LINK_ORDER: *p = 'L'; break;
6951 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6952 case SHF_GROUP: *p = 'G'; break;
6953 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6954 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6955 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6956
6957 default:
dda8d76d
NC
6958 if ((filedata->file_header.e_machine == EM_X86_64
6959 || filedata->file_header.e_machine == EM_L1OM
6960 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6961 && flag == SHF_X86_64_LARGE)
6962 *p = 'l';
dda8d76d 6963 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6964 && flag == SHF_ARM_PURECODE)
99fabbc9 6965 *p = 'y';
dda8d76d 6966 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6967 && flag == SHF_PPC_VLE)
99fabbc9 6968 *p = 'v';
5477e8a0
L
6969 else if (flag & SHF_MASKOS)
6970 {
99fabbc9
JL
6971 switch (filedata->file_header.e_ident[EI_OSABI])
6972 {
6973 case ELFOSABI_GNU:
6974 case ELFOSABI_FREEBSD:
6975 if (flag == SHF_GNU_RETAIN)
6976 {
6977 *p = 'R';
6978 break;
6979 }
6980 /* Fall through */
6981 case ELFOSABI_NONE:
6982 if (flag == SHF_GNU_MBIND)
6983 {
6984 /* We should not recognize SHF_GNU_MBIND for
6985 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6986 not set the EI_OSABI header byte. */
6987 *p = 'D';
6988 break;
6989 }
6990 /* Fall through */
6991 default:
6992 *p = 'o';
6993 sh_flags &= ~SHF_MASKOS;
6994 break;
6995 }
5477e8a0
L
6996 }
6997 else if (flag & SHF_MASKPROC)
6998 {
6999 *p = 'p';
7000 sh_flags &= ~ SHF_MASKPROC;
7001 }
7002 else
7003 *p = 'x';
7004 break;
7005 }
7006 p++;
d1133906
NC
7007 }
7008 }
76da6bbe 7009
8d5ff12c
L
7010 if (do_section_details)
7011 {
7012 if (os_flags)
7013 {
7014 size -= 5 + field_size;
7015 if (p != buff + field_size + 4)
7016 {
7017 if (size < (2 + 1))
bee0ee85
NC
7018 {
7019 warn (_("Internal error: not enough buffer room for section flag info"));
7020 return _("<unknown>");
7021 }
8d5ff12c
L
7022 size -= 2;
7023 *p++ = ',';
7024 *p++ = ' ';
7025 }
7026 sprintf (p, "OS (%*.*lx)", field_size, field_size,
7027 (unsigned long) os_flags);
7028 p += 5 + field_size;
7029 }
7030 if (proc_flags)
7031 {
7032 size -= 7 + field_size;
7033 if (p != buff + field_size + 4)
7034 {
7035 if (size < (2 + 1))
bee0ee85
NC
7036 {
7037 warn (_("Internal error: not enough buffer room for section flag info"));
7038 return _("<unknown>");
7039 }
8d5ff12c
L
7040 size -= 2;
7041 *p++ = ',';
7042 *p++ = ' ';
7043 }
7044 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7045 (unsigned long) proc_flags);
7046 p += 7 + field_size;
7047 }
7048 if (unknown_flags)
7049 {
7050 size -= 10 + field_size;
7051 if (p != buff + field_size + 4)
7052 {
7053 if (size < (2 + 1))
bee0ee85
NC
7054 {
7055 warn (_("Internal error: not enough buffer room for section flag info"));
7056 return _("<unknown>");
7057 }
8d5ff12c
L
7058 size -= 2;
7059 *p++ = ',';
7060 *p++ = ' ';
7061 }
2b692964 7062 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
7063 (unsigned long) unknown_flags);
7064 p += 10 + field_size;
7065 }
7066 }
7067
e9e44622 7068 *p = '\0';
d1133906
NC
7069 return buff;
7070}
7071
5844b465 7072static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7073get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7074 uint64_t size)
77115a4a
L
7075{
7076 if (is_32bit_elf)
7077 {
7078 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7079
ebdf1ebf
NC
7080 if (size < sizeof (* echdr))
7081 {
7082 error (_("Compressed section is too small even for a compression header\n"));
7083 return 0;
7084 }
7085
77115a4a
L
7086 chdr->ch_type = BYTE_GET (echdr->ch_type);
7087 chdr->ch_size = BYTE_GET (echdr->ch_size);
7088 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7089 return sizeof (*echdr);
7090 }
7091 else
7092 {
7093 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7094
ebdf1ebf
NC
7095 if (size < sizeof (* echdr))
7096 {
7097 error (_("Compressed section is too small even for a compression header\n"));
7098 return 0;
7099 }
7100
77115a4a
L
7101 chdr->ch_type = BYTE_GET (echdr->ch_type);
7102 chdr->ch_size = BYTE_GET (echdr->ch_size);
7103 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7104 return sizeof (*echdr);
7105 }
7106}
7107
015dc7e1 7108static bool
dda8d76d 7109process_section_headers (Filedata * filedata)
252b5132 7110{
2cf0635d 7111 Elf_Internal_Shdr * section;
b34976b6 7112 unsigned int i;
252b5132 7113
dda8d76d 7114 if (filedata->file_header.e_shnum == 0)
252b5132 7115 {
82f2dbf7 7116 /* PR binutils/12467. */
dda8d76d 7117 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7118 {
7119 warn (_("possibly corrupt ELF file header - it has a non-zero"
7120 " section header offset, but no section headers\n"));
015dc7e1 7121 return false;
32ec8896 7122 }
82f2dbf7 7123 else if (do_sections)
252b5132
RH
7124 printf (_("\nThere are no sections in this file.\n"));
7125
015dc7e1 7126 return true;
252b5132
RH
7127 }
7128
7129 if (do_sections && !do_header)
ca0e11aa
NC
7130 {
7131 if (filedata->is_separate && process_links)
7132 printf (_("In linked file '%s': "), filedata->file_name);
7133 if (! filedata->is_separate || process_links)
7134 printf (ngettext ("There is %d section header, "
7135 "starting at offset 0x%lx:\n",
7136 "There are %d section headers, "
7137 "starting at offset 0x%lx:\n",
7138 filedata->file_header.e_shnum),
7139 filedata->file_header.e_shnum,
7140 (unsigned long) filedata->file_header.e_shoff);
7141 }
252b5132 7142
4de91c10
AM
7143 if (!get_section_headers (filedata, false))
7144 return false;
252b5132
RH
7145
7146 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7147 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7148 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7149 {
dda8d76d 7150 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7151
c256ffe7
JJ
7152 if (section->sh_size != 0)
7153 {
dda8d76d
NC
7154 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7155 1, section->sh_size,
7156 _("string table"));
0de14b54 7157
dda8d76d 7158 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7159 }
252b5132
RH
7160 }
7161
7162 /* Scan the sections for the dynamic symbol table
e3c8793a 7163 and dynamic string table and debug sections. */
89fac5e3 7164 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7165 switch (filedata->file_header.e_machine)
89fac5e3
RS
7166 {
7167 case EM_MIPS:
7168 case EM_MIPS_RS3_LE:
7169 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7170 FDE addresses. However, the ABI also has a semi-official ILP32
7171 variant for which the normal FDE address size rules apply.
7172
7173 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7174 section, where XX is the size of longs in bits. Unfortunately,
7175 earlier compilers provided no way of distinguishing ILP32 objects
7176 from LP64 objects, so if there's any doubt, we should assume that
7177 the official LP64 form is being used. */
dda8d76d
NC
7178 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7179 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7180 eh_addr_size = 8;
7181 break;
0f56a26a
DD
7182
7183 case EM_H8_300:
7184 case EM_H8_300H:
dda8d76d 7185 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7186 {
7187 case E_H8_MACH_H8300:
7188 case E_H8_MACH_H8300HN:
7189 case E_H8_MACH_H8300SN:
7190 case E_H8_MACH_H8300SXN:
7191 eh_addr_size = 2;
7192 break;
7193 case E_H8_MACH_H8300H:
7194 case E_H8_MACH_H8300S:
7195 case E_H8_MACH_H8300SX:
7196 eh_addr_size = 4;
7197 break;
7198 }
f4236fe4
DD
7199 break;
7200
ff7eeb89 7201 case EM_M32C_OLD:
f4236fe4 7202 case EM_M32C:
dda8d76d 7203 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7204 {
7205 case EF_M32C_CPU_M16C:
7206 eh_addr_size = 2;
7207 break;
7208 }
7209 break;
89fac5e3
RS
7210 }
7211
76ca31c0
NC
7212#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7213 do \
7214 { \
be7d229a 7215 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7216 if (section->sh_entsize != expected_entsize) \
9dd3a467 7217 { \
f493c217 7218 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7219 i, section->sh_entsize); \
f493c217 7220 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7221 expected_entsize); \
9dd3a467 7222 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7223 } \
7224 } \
08d8fa11 7225 while (0)
9dd3a467
NC
7226
7227#define CHECK_ENTSIZE(section, i, type) \
1b513401 7228 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7229 sizeof (Elf64_External_##type))
7230
dda8d76d
NC
7231 for (i = 0, section = filedata->section_headers;
7232 i < filedata->file_header.e_shnum;
b34976b6 7233 i++, section++)
252b5132 7234 {
84714f86 7235 const char *name = section_name_print (filedata, section);
252b5132 7236
1b513401
NC
7237 /* Run some sanity checks on the headers and
7238 possibly fill in some file data as well. */
7239 switch (section->sh_type)
252b5132 7240 {
1b513401 7241 case SHT_DYNSYM:
978c4450 7242 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7243 {
7244 error (_("File contains multiple dynamic symbol tables\n"));
7245 continue;
7246 }
7247
08d8fa11 7248 CHECK_ENTSIZE (section, i, Sym);
978c4450 7249 filedata->dynamic_symbols
4de91c10 7250 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7251 filedata->dynamic_symtab_section = section;
1b513401
NC
7252 break;
7253
7254 case SHT_STRTAB:
7255 if (streq (name, ".dynstr"))
252b5132 7256 {
1b513401
NC
7257 if (filedata->dynamic_strings != NULL)
7258 {
7259 error (_("File contains multiple dynamic string tables\n"));
7260 continue;
7261 }
7262
7263 filedata->dynamic_strings
7264 = (char *) get_data (NULL, filedata, section->sh_offset,
7265 1, section->sh_size, _("dynamic strings"));
7266 filedata->dynamic_strings_length
7267 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7268 filedata->dynamic_strtab_section = section;
252b5132 7269 }
1b513401
NC
7270 break;
7271
7272 case SHT_SYMTAB_SHNDX:
7273 {
7274 elf_section_list * entry = xmalloc (sizeof * entry);
7275
7276 entry->hdr = section;
7277 entry->next = filedata->symtab_shndx_list;
7278 filedata->symtab_shndx_list = entry;
7279 }
7280 break;
7281
7282 case SHT_SYMTAB:
7283 CHECK_ENTSIZE (section, i, Sym);
7284 break;
7285
7286 case SHT_GROUP:
7287 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7288 break;
252b5132 7289
1b513401
NC
7290 case SHT_REL:
7291 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7292 if (do_checks && section->sh_size == 0)
1b513401
NC
7293 warn (_("Section '%s': zero-sized relocation section\n"), name);
7294 break;
7295
7296 case SHT_RELA:
7297 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7298 if (do_checks && section->sh_size == 0)
1b513401
NC
7299 warn (_("Section '%s': zero-sized relocation section\n"), name);
7300 break;
7301
682351b9
AM
7302 case SHT_RELR:
7303 CHECK_ENTSIZE (section, i, Relr);
7304 break;
7305
1b513401
NC
7306 case SHT_NOTE:
7307 case SHT_PROGBITS:
546cb2d8
NC
7308 /* Having a zero sized section is not illegal according to the
7309 ELF standard, but it might be an indication that something
7310 is wrong. So issue a warning if we are running in lint mode. */
7311 if (do_checks && section->sh_size == 0)
1b513401
NC
7312 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7313 break;
7314
7315 default:
7316 break;
7317 }
7318
7319 if ((do_debugging || do_debug_info || do_debug_abbrevs
7320 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7321 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7322 || do_debug_str || do_debug_str_offsets || do_debug_loc
7323 || do_debug_ranges
1b513401 7324 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7325 && (startswith (name, ".debug_")
7326 || startswith (name, ".zdebug_")))
252b5132 7327 {
1b315056
CS
7328 if (name[1] == 'z')
7329 name += sizeof (".zdebug_") - 1;
7330 else
7331 name += sizeof (".debug_") - 1;
252b5132
RH
7332
7333 if (do_debugging
24d127aa
ML
7334 || (do_debug_info && startswith (name, "info"))
7335 || (do_debug_info && startswith (name, "types"))
7336 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7337 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7338 || (do_debug_lines && startswith (name, "line."))
7339 || (do_debug_pubnames && startswith (name, "pubnames"))
7340 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7341 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7342 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7343 || (do_debug_aranges && startswith (name, "aranges"))
7344 || (do_debug_ranges && startswith (name, "ranges"))
7345 || (do_debug_ranges && startswith (name, "rnglists"))
7346 || (do_debug_frames && startswith (name, "frame"))
7347 || (do_debug_macinfo && startswith (name, "macinfo"))
7348 || (do_debug_macinfo && startswith (name, "macro"))
7349 || (do_debug_str && startswith (name, "str"))
7350 || (do_debug_links && startswith (name, "sup"))
7351 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7352 || (do_debug_loc && startswith (name, "loc"))
7353 || (do_debug_loc && startswith (name, "loclists"))
7354 || (do_debug_addr && startswith (name, "addr"))
7355 || (do_debug_cu_index && startswith (name, "cu_index"))
7356 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7357 )
6431e409 7358 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7359 }
a262ae96 7360 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7361 else if ((do_debugging || do_debug_info)
24d127aa 7362 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7363 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7364 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7365 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7366 else if (do_gdb_index && (streq (name, ".gdb_index")
7367 || streq (name, ".debug_names")))
6431e409 7368 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7369 /* Trace sections for Itanium VMS. */
7370 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7371 || do_trace_aranges)
24d127aa 7372 && startswith (name, ".trace_"))
6f875884
TG
7373 {
7374 name += sizeof (".trace_") - 1;
7375
7376 if (do_debugging
7377 || (do_trace_info && streq (name, "info"))
7378 || (do_trace_abbrevs && streq (name, "abbrev"))
7379 || (do_trace_aranges && streq (name, "aranges"))
7380 )
6431e409 7381 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7382 }
dda8d76d 7383 else if ((do_debugging || do_debug_links)
24d127aa
ML
7384 && (startswith (name, ".gnu_debuglink")
7385 || startswith (name, ".gnu_debugaltlink")))
6431e409 7386 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7387 }
7388
7389 if (! do_sections)
015dc7e1 7390 return true;
252b5132 7391
ca0e11aa 7392 if (filedata->is_separate && ! process_links)
015dc7e1 7393 return true;
ca0e11aa
NC
7394
7395 if (filedata->is_separate)
7396 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7397 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7398 printf (_("\nSection Headers:\n"));
7399 else
7400 printf (_("\nSection Header:\n"));
76da6bbe 7401
f7a99963 7402 if (is_32bit_elf)
595cf52e 7403 {
5477e8a0 7404 if (do_section_details)
595cf52e
L
7405 {
7406 printf (_(" [Nr] Name\n"));
5477e8a0 7407 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7408 }
7409 else
7410 printf
7411 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7412 }
d974e256 7413 else if (do_wide)
595cf52e 7414 {
5477e8a0 7415 if (do_section_details)
595cf52e
L
7416 {
7417 printf (_(" [Nr] Name\n"));
5477e8a0 7418 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7419 }
7420 else
7421 printf
7422 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7423 }
f7a99963
NC
7424 else
7425 {
5477e8a0 7426 if (do_section_details)
595cf52e
L
7427 {
7428 printf (_(" [Nr] Name\n"));
5477e8a0
L
7429 printf (_(" Type Address Offset Link\n"));
7430 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7431 }
7432 else
7433 {
7434 printf (_(" [Nr] Name Type Address Offset\n"));
7435 printf (_(" Size EntSize Flags Link Info Align\n"));
7436 }
f7a99963 7437 }
252b5132 7438
5477e8a0
L
7439 if (do_section_details)
7440 printf (_(" Flags\n"));
7441
dda8d76d
NC
7442 for (i = 0, section = filedata->section_headers;
7443 i < filedata->file_header.e_shnum;
b34976b6 7444 i++, section++)
252b5132 7445 {
dd905818
NC
7446 /* Run some sanity checks on the section header. */
7447
7448 /* Check the sh_link field. */
7449 switch (section->sh_type)
7450 {
285e3f99
AM
7451 case SHT_REL:
7452 case SHT_RELA:
7453 if (section->sh_link == 0
7454 && (filedata->file_header.e_type == ET_EXEC
7455 || filedata->file_header.e_type == ET_DYN))
7456 /* A dynamic relocation section where all entries use a
7457 zero symbol index need not specify a symtab section. */
7458 break;
7459 /* Fall through. */
dd905818
NC
7460 case SHT_SYMTAB_SHNDX:
7461 case SHT_GROUP:
7462 case SHT_HASH:
7463 case SHT_GNU_HASH:
7464 case SHT_GNU_versym:
285e3f99 7465 if (section->sh_link == 0
dda8d76d
NC
7466 || section->sh_link >= filedata->file_header.e_shnum
7467 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7468 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7469 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7470 i, section->sh_link);
7471 break;
7472
7473 case SHT_DYNAMIC:
7474 case SHT_SYMTAB:
7475 case SHT_DYNSYM:
7476 case SHT_GNU_verneed:
7477 case SHT_GNU_verdef:
7478 case SHT_GNU_LIBLIST:
285e3f99 7479 if (section->sh_link == 0
dda8d76d
NC
7480 || section->sh_link >= filedata->file_header.e_shnum
7481 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7482 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7483 i, section->sh_link);
7484 break;
7485
7486 case SHT_INIT_ARRAY:
7487 case SHT_FINI_ARRAY:
7488 case SHT_PREINIT_ARRAY:
7489 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7490 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7491 i, section->sh_link);
7492 break;
7493
7494 default:
7495 /* FIXME: Add support for target specific section types. */
7496#if 0 /* Currently we do not check other section types as there are too
7497 many special cases. Stab sections for example have a type
7498 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7499 section. */
7500 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7501 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7502 i, section->sh_link);
7503#endif
7504 break;
7505 }
7506
7507 /* Check the sh_info field. */
7508 switch (section->sh_type)
7509 {
7510 case SHT_REL:
7511 case SHT_RELA:
285e3f99
AM
7512 if (section->sh_info == 0
7513 && (filedata->file_header.e_type == ET_EXEC
7514 || filedata->file_header.e_type == ET_DYN))
7515 /* Dynamic relocations apply to segments, so they do not
7516 need to specify the section they relocate. */
7517 break;
7518 if (section->sh_info == 0
dda8d76d
NC
7519 || section->sh_info >= filedata->file_header.e_shnum
7520 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7521 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7522 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7523 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7524 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7525 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7526 /* FIXME: Are other section types valid ? */
dda8d76d 7527 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7528 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7529 i, section->sh_info);
dd905818
NC
7530 break;
7531
7532 case SHT_DYNAMIC:
7533 case SHT_HASH:
7534 case SHT_SYMTAB_SHNDX:
7535 case SHT_INIT_ARRAY:
7536 case SHT_FINI_ARRAY:
7537 case SHT_PREINIT_ARRAY:
7538 if (section->sh_info != 0)
7539 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7540 i, section->sh_info);
7541 break;
7542
7543 case SHT_GROUP:
7544 case SHT_SYMTAB:
7545 case SHT_DYNSYM:
7546 /* A symbol index - we assume that it is valid. */
7547 break;
7548
7549 default:
7550 /* FIXME: Add support for target specific section types. */
7551 if (section->sh_type == SHT_NOBITS)
7552 /* NOBITS section headers with non-zero sh_info fields can be
7553 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7554 information. The stripped sections have their headers
7555 preserved but their types set to SHT_NOBITS. So do not check
7556 this type of section. */
dd905818
NC
7557 ;
7558 else if (section->sh_flags & SHF_INFO_LINK)
7559 {
dda8d76d 7560 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7561 warn (_("[%2u]: Expected link to another section in info field"), i);
7562 }
a91e1603
L
7563 else if (section->sh_type < SHT_LOOS
7564 && (section->sh_flags & SHF_GNU_MBIND) == 0
7565 && section->sh_info != 0)
dd905818
NC
7566 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7567 i, section->sh_info);
7568 break;
7569 }
7570
3e6b6445 7571 /* Check the sh_size field. */
dda8d76d 7572 if (section->sh_size > filedata->file_size
3e6b6445
NC
7573 && section->sh_type != SHT_NOBITS
7574 && section->sh_type != SHT_NULL
7575 && section->sh_type < SHT_LOOS)
7576 warn (_("Size of section %u is larger than the entire file!\n"), i);
7577
7bfd842d 7578 printf (" [%2u] ", i);
5477e8a0 7579 if (do_section_details)
dda8d76d 7580 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7581 else
84714f86 7582 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7583
ea52a088 7584 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7585 get_section_type_name (filedata, section->sh_type));
0b4362b0 7586
f7a99963
NC
7587 if (is_32bit_elf)
7588 {
cfcac11d
NC
7589 const char * link_too_big = NULL;
7590
f7a99963 7591 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7592
f7a99963
NC
7593 printf ( " %6.6lx %6.6lx %2.2lx",
7594 (unsigned long) section->sh_offset,
7595 (unsigned long) section->sh_size,
7596 (unsigned long) section->sh_entsize);
d1133906 7597
5477e8a0
L
7598 if (do_section_details)
7599 fputs (" ", stdout);
7600 else
dda8d76d 7601 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7602
dda8d76d 7603 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7604 {
7605 link_too_big = "";
7606 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7607 an error but it can have special values in Solaris binaries. */
dda8d76d 7608 switch (filedata->file_header.e_machine)
cfcac11d 7609 {
caa83f8b 7610 case EM_386:
22abe556 7611 case EM_IAMCU:
caa83f8b 7612 case EM_X86_64:
7f502d6c 7613 case EM_L1OM:
7a9068fe 7614 case EM_K1OM:
cfcac11d
NC
7615 case EM_OLD_SPARCV9:
7616 case EM_SPARC32PLUS:
7617 case EM_SPARCV9:
7618 case EM_SPARC:
7619 if (section->sh_link == (SHN_BEFORE & 0xffff))
7620 link_too_big = "BEFORE";
7621 else if (section->sh_link == (SHN_AFTER & 0xffff))
7622 link_too_big = "AFTER";
7623 break;
7624 default:
7625 break;
7626 }
7627 }
7628
7629 if (do_section_details)
7630 {
7631 if (link_too_big != NULL && * link_too_big)
7632 printf ("<%s> ", link_too_big);
7633 else
7634 printf ("%2u ", section->sh_link);
7635 printf ("%3u %2lu\n", section->sh_info,
7636 (unsigned long) section->sh_addralign);
7637 }
7638 else
7639 printf ("%2u %3u %2lu\n",
7640 section->sh_link,
7641 section->sh_info,
7642 (unsigned long) section->sh_addralign);
7643
7644 if (link_too_big && ! * link_too_big)
7645 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7646 i, section->sh_link);
f7a99963 7647 }
d974e256
JJ
7648 else if (do_wide)
7649 {
7650 print_vma (section->sh_addr, LONG_HEX);
7651
7652 if ((long) section->sh_offset == section->sh_offset)
7653 printf (" %6.6lx", (unsigned long) section->sh_offset);
7654 else
7655 {
7656 putchar (' ');
7657 print_vma (section->sh_offset, LONG_HEX);
7658 }
7659
7660 if ((unsigned long) section->sh_size == section->sh_size)
7661 printf (" %6.6lx", (unsigned long) section->sh_size);
7662 else
7663 {
7664 putchar (' ');
7665 print_vma (section->sh_size, LONG_HEX);
7666 }
7667
7668 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7669 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7670 else
7671 {
7672 putchar (' ');
7673 print_vma (section->sh_entsize, LONG_HEX);
7674 }
7675
5477e8a0
L
7676 if (do_section_details)
7677 fputs (" ", stdout);
7678 else
dda8d76d 7679 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7680
72de5009 7681 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7682
7683 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7684 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7685 else
7686 {
7687 print_vma (section->sh_addralign, DEC);
7688 putchar ('\n');
7689 }
7690 }
5477e8a0 7691 else if (do_section_details)
595cf52e 7692 {
55cc53e9 7693 putchar (' ');
595cf52e
L
7694 print_vma (section->sh_addr, LONG_HEX);
7695 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7696 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7697 else
7698 {
7699 printf (" ");
7700 print_vma (section->sh_offset, LONG_HEX);
7701 }
72de5009 7702 printf (" %u\n ", section->sh_link);
595cf52e 7703 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7704 putchar (' ');
595cf52e
L
7705 print_vma (section->sh_entsize, LONG_HEX);
7706
72de5009
AM
7707 printf (" %-16u %lu\n",
7708 section->sh_info,
595cf52e
L
7709 (unsigned long) section->sh_addralign);
7710 }
f7a99963
NC
7711 else
7712 {
7713 putchar (' ');
7714 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7715 if ((long) section->sh_offset == section->sh_offset)
7716 printf (" %8.8lx", (unsigned long) section->sh_offset);
7717 else
7718 {
7719 printf (" ");
7720 print_vma (section->sh_offset, LONG_HEX);
7721 }
f7a99963
NC
7722 printf ("\n ");
7723 print_vma (section->sh_size, LONG_HEX);
7724 printf (" ");
7725 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7726
dda8d76d 7727 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7728
72de5009
AM
7729 printf (" %2u %3u %lu\n",
7730 section->sh_link,
7731 section->sh_info,
f7a99963
NC
7732 (unsigned long) section->sh_addralign);
7733 }
5477e8a0
L
7734
7735 if (do_section_details)
77115a4a 7736 {
dda8d76d 7737 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7738 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7739 {
7740 /* Minimum section size is 12 bytes for 32-bit compression
7741 header + 12 bytes for compressed data header. */
7742 unsigned char buf[24];
d8024a91 7743
77115a4a 7744 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7745 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7746 sizeof (buf), _("compression header")))
7747 {
7748 Elf_Internal_Chdr chdr;
d8024a91 7749
5844b465
NC
7750 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7751 printf (_(" [<corrupt>]\n"));
77115a4a 7752 else
5844b465
NC
7753 {
7754 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7755 printf (" ZLIB, ");
1369522f
CC
7756 else if (chdr.ch_type == ELFCOMPRESS_ZSTD)
7757 printf (" ZSTD, ");
5844b465
NC
7758 else
7759 printf (_(" [<unknown>: 0x%x], "),
7760 chdr.ch_type);
7761 print_vma (chdr.ch_size, LONG_HEX);
7762 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7763 }
77115a4a
L
7764 }
7765 }
7766 }
252b5132
RH
7767 }
7768
5477e8a0 7769 if (!do_section_details)
3dbcc61d 7770 {
9fb71ee4
NC
7771 /* The ordering of the letters shown here matches the ordering of the
7772 corresponding SHF_xxx values, and hence the order in which these
7773 letters will be displayed to the user. */
7774 printf (_("Key to Flags:\n\
7775 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7776 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7777 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7778 switch (filedata->file_header.e_ident[EI_OSABI])
7779 {
7780 case ELFOSABI_GNU:
7781 case ELFOSABI_FREEBSD:
7782 printf (_("R (retain), "));
7783 /* Fall through */
7784 case ELFOSABI_NONE:
7785 printf (_("D (mbind), "));
7786 break;
7787 default:
7788 break;
7789 }
dda8d76d
NC
7790 if (filedata->file_header.e_machine == EM_X86_64
7791 || filedata->file_header.e_machine == EM_L1OM
7792 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7793 printf (_("l (large), "));
dda8d76d 7794 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7795 printf (_("y (purecode), "));
dda8d76d 7796 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7797 printf (_("v (VLE), "));
9fb71ee4 7798 printf ("p (processor specific)\n");
0b4362b0 7799 }
d1133906 7800
015dc7e1 7801 return true;
252b5132
RH
7802}
7803
015dc7e1 7804static bool
28d13567
AM
7805get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7806 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7807 char **strtab, unsigned long *strtablen)
7808{
7809 *strtab = NULL;
7810 *strtablen = 0;
4de91c10 7811 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7812
7813 if (*symtab == NULL)
015dc7e1 7814 return false;
28d13567
AM
7815
7816 if (symsec->sh_link != 0)
7817 {
7818 Elf_Internal_Shdr *strsec;
7819
7820 if (symsec->sh_link >= filedata->file_header.e_shnum)
7821 {
7822 error (_("Bad sh_link in symbol table section\n"));
7823 free (*symtab);
7824 *symtab = NULL;
7825 *nsyms = 0;
015dc7e1 7826 return false;
28d13567
AM
7827 }
7828
7829 strsec = filedata->section_headers + symsec->sh_link;
7830
7831 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7832 1, strsec->sh_size, _("string table"));
7833 if (*strtab == NULL)
7834 {
7835 free (*symtab);
7836 *symtab = NULL;
7837 *nsyms = 0;
015dc7e1 7838 return false;
28d13567
AM
7839 }
7840 *strtablen = strsec->sh_size;
7841 }
015dc7e1 7842 return true;
28d13567
AM
7843}
7844
f5842774
L
7845static const char *
7846get_group_flags (unsigned int flags)
7847{
1449284b 7848 static char buff[128];
220453ec 7849
6d913794
NC
7850 if (flags == 0)
7851 return "";
7852 else if (flags == GRP_COMDAT)
7853 return "COMDAT ";
f5842774 7854
89246a0e
AM
7855 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7856 flags,
7857 flags & GRP_MASKOS ? _("<OS specific>") : "",
7858 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7859 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7860 ? _("<unknown>") : ""));
6d913794 7861
f5842774
L
7862 return buff;
7863}
7864
015dc7e1 7865static bool
dda8d76d 7866process_section_groups (Filedata * filedata)
f5842774 7867{
2cf0635d 7868 Elf_Internal_Shdr * section;
f5842774 7869 unsigned int i;
2cf0635d
NC
7870 struct group * group;
7871 Elf_Internal_Shdr * symtab_sec;
7872 Elf_Internal_Shdr * strtab_sec;
7873 Elf_Internal_Sym * symtab;
ba5cdace 7874 unsigned long num_syms;
2cf0635d 7875 char * strtab;
c256ffe7 7876 size_t strtab_size;
d1f5c6e3
L
7877
7878 /* Don't process section groups unless needed. */
7879 if (!do_unwind && !do_section_groups)
015dc7e1 7880 return true;
f5842774 7881
dda8d76d 7882 if (filedata->file_header.e_shnum == 0)
f5842774
L
7883 {
7884 if (do_section_groups)
ca0e11aa
NC
7885 {
7886 if (filedata->is_separate)
7887 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7888 filedata->file_name);
7889 else
7890 printf (_("\nThere are no section groups in this file.\n"));
7891 }
015dc7e1 7892 return true;
f5842774
L
7893 }
7894
dda8d76d 7895 if (filedata->section_headers == NULL)
f5842774
L
7896 {
7897 error (_("Section headers are not available!\n"));
fa1908fd 7898 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7899 return false;
f5842774
L
7900 }
7901
978c4450
AM
7902 filedata->section_headers_groups
7903 = (struct group **) calloc (filedata->file_header.e_shnum,
7904 sizeof (struct group *));
e4b17d5c 7905
978c4450 7906 if (filedata->section_headers_groups == NULL)
e4b17d5c 7907 {
8b73c356 7908 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7909 filedata->file_header.e_shnum);
015dc7e1 7910 return false;
e4b17d5c
L
7911 }
7912
f5842774 7913 /* Scan the sections for the group section. */
978c4450 7914 filedata->group_count = 0;
dda8d76d
NC
7915 for (i = 0, section = filedata->section_headers;
7916 i < filedata->file_header.e_shnum;
f5842774 7917 i++, section++)
e4b17d5c 7918 if (section->sh_type == SHT_GROUP)
978c4450 7919 filedata->group_count++;
e4b17d5c 7920
978c4450 7921 if (filedata->group_count == 0)
d1f5c6e3
L
7922 {
7923 if (do_section_groups)
ca0e11aa
NC
7924 {
7925 if (filedata->is_separate)
7926 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7927 filedata->file_name);
7928 else
7929 printf (_("\nThere are no section groups in this file.\n"));
7930 }
d1f5c6e3 7931
015dc7e1 7932 return true;
d1f5c6e3
L
7933 }
7934
978c4450
AM
7935 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7936 sizeof (struct group));
e4b17d5c 7937
978c4450 7938 if (filedata->section_groups == NULL)
e4b17d5c 7939 {
8b73c356 7940 error (_("Out of memory reading %lu groups\n"),
978c4450 7941 (unsigned long) filedata->group_count);
015dc7e1 7942 return false;
e4b17d5c
L
7943 }
7944
d1f5c6e3
L
7945 symtab_sec = NULL;
7946 strtab_sec = NULL;
7947 symtab = NULL;
ba5cdace 7948 num_syms = 0;
d1f5c6e3 7949 strtab = NULL;
c256ffe7 7950 strtab_size = 0;
ca0e11aa
NC
7951
7952 if (filedata->is_separate)
7953 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7954
978c4450 7955 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7956 i < filedata->file_header.e_shnum;
e4b17d5c 7957 i++, section++)
f5842774
L
7958 {
7959 if (section->sh_type == SHT_GROUP)
7960 {
dda8d76d 7961 const char * name = printable_section_name (filedata, section);
74e1a04b 7962 const char * group_name;
2cf0635d
NC
7963 unsigned char * start;
7964 unsigned char * indices;
f5842774 7965 unsigned int entry, j, size;
2cf0635d
NC
7966 Elf_Internal_Shdr * sec;
7967 Elf_Internal_Sym * sym;
f5842774
L
7968
7969 /* Get the symbol table. */
dda8d76d
NC
7970 if (section->sh_link >= filedata->file_header.e_shnum
7971 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7972 != SHT_SYMTAB))
f5842774
L
7973 {
7974 error (_("Bad sh_link in group section `%s'\n"), name);
7975 continue;
7976 }
d1f5c6e3
L
7977
7978 if (symtab_sec != sec)
7979 {
7980 symtab_sec = sec;
9db70fc3 7981 free (symtab);
4de91c10 7982 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7983 }
f5842774 7984
dd24e3da
NC
7985 if (symtab == NULL)
7986 {
7987 error (_("Corrupt header in group section `%s'\n"), name);
7988 continue;
7989 }
7990
ba5cdace
NC
7991 if (section->sh_info >= num_syms)
7992 {
7993 error (_("Bad sh_info in group section `%s'\n"), name);
7994 continue;
7995 }
7996
f5842774
L
7997 sym = symtab + section->sh_info;
7998
7999 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8000 {
4fbb74a6 8001 if (sym->st_shndx == 0
dda8d76d 8002 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
8003 {
8004 error (_("Bad sh_info in group section `%s'\n"), name);
8005 continue;
8006 }
ba2685cc 8007
84714f86
AM
8008 group_name = section_name_print (filedata,
8009 filedata->section_headers
b9e920ec 8010 + sym->st_shndx);
c256ffe7 8011 strtab_sec = NULL;
9db70fc3 8012 free (strtab);
f5842774 8013 strtab = NULL;
c256ffe7 8014 strtab_size = 0;
f5842774
L
8015 }
8016 else
8017 {
8018 /* Get the string table. */
dda8d76d 8019 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8020 {
8021 strtab_sec = NULL;
9db70fc3 8022 free (strtab);
c256ffe7
JJ
8023 strtab = NULL;
8024 strtab_size = 0;
8025 }
8026 else if (strtab_sec
dda8d76d 8027 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8028 {
8029 strtab_sec = sec;
9db70fc3 8030 free (strtab);
071436c6 8031
dda8d76d 8032 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8033 1, strtab_sec->sh_size,
8034 _("string table"));
c256ffe7 8035 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8036 }
c256ffe7 8037 group_name = sym->st_name < strtab_size
2b692964 8038 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8039 }
8040
c9c1d674
EG
8041 /* PR 17531: file: loop. */
8042 if (section->sh_entsize > section->sh_size)
8043 {
8044 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 8045 printable_section_name (filedata, section),
8066deb1
AM
8046 (unsigned long) section->sh_entsize,
8047 (unsigned long) section->sh_size);
61dd8e19 8048 continue;
c9c1d674
EG
8049 }
8050
dda8d76d 8051 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8052 1, section->sh_size,
8053 _("section data"));
59245841
NC
8054 if (start == NULL)
8055 continue;
f5842774
L
8056
8057 indices = start;
8058 size = (section->sh_size / section->sh_entsize) - 1;
8059 entry = byte_get (indices, 4);
8060 indices += 4;
e4b17d5c
L
8061
8062 if (do_section_groups)
8063 {
2b692964 8064 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8065 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8066
e4b17d5c
L
8067 printf (_(" [Index] Name\n"));
8068 }
8069
8070 group->group_index = i;
8071
f5842774
L
8072 for (j = 0; j < size; j++)
8073 {
2cf0635d 8074 struct group_list * g;
e4b17d5c 8075
f5842774
L
8076 entry = byte_get (indices, 4);
8077 indices += 4;
8078
dda8d76d 8079 if (entry >= filedata->file_header.e_shnum)
391cb864 8080 {
57028622
NC
8081 static unsigned num_group_errors = 0;
8082
8083 if (num_group_errors ++ < 10)
8084 {
8085 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8086 entry, i, filedata->file_header.e_shnum - 1);
57028622 8087 if (num_group_errors == 10)
67ce483b 8088 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8089 }
391cb864
L
8090 continue;
8091 }
391cb864 8092
978c4450 8093 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8094 {
d1f5c6e3
L
8095 if (entry)
8096 {
57028622
NC
8097 static unsigned num_errs = 0;
8098
8099 if (num_errs ++ < 10)
8100 {
8101 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8102 entry, i,
978c4450 8103 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8104 if (num_errs == 10)
8105 warn (_("Further error messages about already contained group sections suppressed\n"));
8106 }
d1f5c6e3
L
8107 continue;
8108 }
8109 else
8110 {
8111 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8112 section group. We just warn it the first time
d1f5c6e3 8113 and ignore it afterwards. */
015dc7e1 8114 static bool warned = false;
d1f5c6e3
L
8115 if (!warned)
8116 {
8117 error (_("section 0 in group section [%5u]\n"),
978c4450 8118 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8119 warned = true;
d1f5c6e3
L
8120 }
8121 }
e4b17d5c
L
8122 }
8123
978c4450 8124 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8125
8126 if (do_section_groups)
8127 {
dda8d76d
NC
8128 sec = filedata->section_headers + entry;
8129 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8130 }
8131
3f5e193b 8132 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8133 g->section_index = entry;
8134 g->next = group->root;
8135 group->root = g;
f5842774
L
8136 }
8137
9db70fc3 8138 free (start);
e4b17d5c
L
8139
8140 group++;
f5842774
L
8141 }
8142 }
8143
9db70fc3
AM
8144 free (symtab);
8145 free (strtab);
015dc7e1 8146 return true;
f5842774
L
8147}
8148
28f997cf
TG
8149/* Data used to display dynamic fixups. */
8150
8151struct ia64_vms_dynfixup
8152{
625d49fc
AM
8153 uint64_t needed_ident; /* Library ident number. */
8154 uint64_t needed; /* Index in the dstrtab of the library name. */
8155 uint64_t fixup_needed; /* Index of the library. */
8156 uint64_t fixup_rela_cnt; /* Number of fixups. */
8157 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8158};
8159
8160/* Data used to display dynamic relocations. */
8161
8162struct ia64_vms_dynimgrela
8163{
625d49fc
AM
8164 uint64_t img_rela_cnt; /* Number of relocations. */
8165 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8166};
8167
8168/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8169 library). */
8170
015dc7e1 8171static bool
dda8d76d
NC
8172dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8173 struct ia64_vms_dynfixup * fixup,
8174 const char * strtab,
8175 unsigned int strtab_sz)
28f997cf 8176{
32ec8896 8177 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 8178 long i;
32ec8896 8179 const char * lib_name;
28f997cf 8180
978c4450
AM
8181 imfs = get_data (NULL, filedata,
8182 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8183 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8184 _("dynamic section image fixups"));
8185 if (!imfs)
015dc7e1 8186 return false;
28f997cf
TG
8187
8188 if (fixup->needed < strtab_sz)
8189 lib_name = strtab + fixup->needed;
8190 else
8191 {
32ec8896 8192 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 8193 (unsigned long) fixup->needed);
28f997cf
TG
8194 lib_name = "???";
8195 }
736990c4 8196
28f997cf
TG
8197 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
8198 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
8199 printf
8200 (_("Seg Offset Type SymVec DataType\n"));
8201
8202 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
8203 {
8204 unsigned int type;
8205 const char *rtype;
8206
8207 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8208 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8209 type = BYTE_GET (imfs [i].type);
8210 rtype = elf_ia64_reloc_type (type);
8211 if (rtype == NULL)
f493c217 8212 printf ("0x%08x ", type);
28f997cf 8213 else
f493c217 8214 printf ("%-32s ", rtype);
28f997cf
TG
8215 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8216 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8217 }
8218
8219 free (imfs);
015dc7e1 8220 return true;
28f997cf
TG
8221}
8222
8223/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8224
015dc7e1 8225static bool
dda8d76d 8226dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8227{
8228 Elf64_External_VMS_IMAGE_RELA *imrs;
8229 long i;
8230
978c4450
AM
8231 imrs = get_data (NULL, filedata,
8232 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8233 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8234 _("dynamic section image relocations"));
28f997cf 8235 if (!imrs)
015dc7e1 8236 return false;
28f997cf
TG
8237
8238 printf (_("\nImage relocs\n"));
8239 printf
8240 (_("Seg Offset Type Addend Seg Sym Off\n"));
8241
8242 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
8243 {
8244 unsigned int type;
8245 const char *rtype;
8246
8247 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8248 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8249 type = BYTE_GET (imrs [i].type);
8250 rtype = elf_ia64_reloc_type (type);
8251 if (rtype == NULL)
8252 printf ("0x%08x ", type);
8253 else
8254 printf ("%-31s ", rtype);
8255 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8256 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8257 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8258 }
8259
8260 free (imrs);
015dc7e1 8261 return true;
28f997cf
TG
8262}
8263
8264/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8265
015dc7e1 8266static bool
dda8d76d 8267process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8268{
8269 struct ia64_vms_dynfixup fixup;
8270 struct ia64_vms_dynimgrela imgrela;
8271 Elf_Internal_Dyn *entry;
625d49fc
AM
8272 uint64_t strtab_off = 0;
8273 uint64_t strtab_sz = 0;
28f997cf 8274 char *strtab = NULL;
015dc7e1 8275 bool res = true;
28f997cf
TG
8276
8277 memset (&fixup, 0, sizeof (fixup));
8278 memset (&imgrela, 0, sizeof (imgrela));
8279
8280 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8281 for (entry = filedata->dynamic_section;
8282 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8283 entry++)
8284 {
8285 switch (entry->d_tag)
8286 {
8287 case DT_IA_64_VMS_STRTAB_OFFSET:
8288 strtab_off = entry->d_un.d_val;
8289 break;
8290 case DT_STRSZ:
8291 strtab_sz = entry->d_un.d_val;
8292 if (strtab == NULL)
978c4450
AM
8293 strtab = get_data (NULL, filedata,
8294 filedata->dynamic_addr + strtab_off,
28f997cf 8295 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8296 if (strtab == NULL)
8297 strtab_sz = 0;
28f997cf
TG
8298 break;
8299
8300 case DT_IA_64_VMS_NEEDED_IDENT:
8301 fixup.needed_ident = entry->d_un.d_val;
8302 break;
8303 case DT_NEEDED:
8304 fixup.needed = entry->d_un.d_val;
8305 break;
8306 case DT_IA_64_VMS_FIXUP_NEEDED:
8307 fixup.fixup_needed = entry->d_un.d_val;
8308 break;
8309 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8310 fixup.fixup_rela_cnt = entry->d_un.d_val;
8311 break;
8312 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8313 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8314 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8315 res = false;
28f997cf 8316 break;
28f997cf
TG
8317 case DT_IA_64_VMS_IMG_RELA_CNT:
8318 imgrela.img_rela_cnt = entry->d_un.d_val;
8319 break;
8320 case DT_IA_64_VMS_IMG_RELA_OFF:
8321 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8322 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8323 res = false;
28f997cf
TG
8324 break;
8325
8326 default:
8327 break;
8328 }
8329 }
8330
9db70fc3 8331 free (strtab);
28f997cf
TG
8332
8333 return res;
8334}
8335
85b1c36d 8336static struct
566b0d53 8337{
2cf0635d 8338 const char * name;
566b0d53
L
8339 int reloc;
8340 int size;
a7fd1186 8341 relocation_type rel_type;
32ec8896
NC
8342}
8343 dynamic_relocations [] =
566b0d53 8344{
a7fd1186
FS
8345 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8346 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8347 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8348 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8349};
8350
252b5132 8351/* Process the reloc section. */
18bd398b 8352
015dc7e1 8353static bool
dda8d76d 8354process_relocs (Filedata * filedata)
252b5132 8355{
b34976b6
AM
8356 unsigned long rel_size;
8357 unsigned long rel_offset;
252b5132 8358
252b5132 8359 if (!do_reloc)
015dc7e1 8360 return true;
252b5132
RH
8361
8362 if (do_using_dynamic)
8363 {
a7fd1186 8364 relocation_type rel_type;
2cf0635d 8365 const char * name;
015dc7e1 8366 bool has_dynamic_reloc;
566b0d53 8367 unsigned int i;
0de14b54 8368
015dc7e1 8369 has_dynamic_reloc = false;
252b5132 8370
566b0d53 8371 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8372 {
a7fd1186 8373 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8374 name = dynamic_relocations [i].name;
978c4450
AM
8375 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8376 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8377
32ec8896 8378 if (rel_size)
015dc7e1 8379 has_dynamic_reloc = true;
566b0d53 8380
a7fd1186 8381 if (rel_type == reltype_unknown)
aa903cfb 8382 {
566b0d53 8383 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8384 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8385 {
8386 case DT_REL:
a7fd1186 8387 rel_type = reltype_rel;
566b0d53
L
8388 break;
8389 case DT_RELA:
a7fd1186 8390 rel_type = reltype_rela;
566b0d53
L
8391 break;
8392 }
aa903cfb 8393 }
252b5132 8394
566b0d53
L
8395 if (rel_size)
8396 {
ca0e11aa
NC
8397 if (filedata->is_separate)
8398 printf
8399 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
8400 filedata->file_name, name, rel_offset, rel_size);
8401 else
8402 printf
8403 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
8404 name, rel_offset, rel_size);
252b5132 8405
dda8d76d
NC
8406 dump_relocations (filedata,
8407 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8408 rel_size,
978c4450
AM
8409 filedata->dynamic_symbols,
8410 filedata->num_dynamic_syms,
8411 filedata->dynamic_strings,
8412 filedata->dynamic_strings_length,
a7fd1186 8413 rel_type, true /* is_dynamic */);
566b0d53 8414 }
252b5132 8415 }
566b0d53 8416
dda8d76d
NC
8417 if (is_ia64_vms (filedata))
8418 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8419 has_dynamic_reloc = true;
28f997cf 8420
566b0d53 8421 if (! has_dynamic_reloc)
ca0e11aa
NC
8422 {
8423 if (filedata->is_separate)
8424 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8425 filedata->file_name);
8426 else
8427 printf (_("\nThere are no dynamic relocations in this file.\n"));
8428 }
252b5132
RH
8429 }
8430 else
8431 {
2cf0635d 8432 Elf_Internal_Shdr * section;
b34976b6 8433 unsigned long i;
015dc7e1 8434 bool found = false;
252b5132 8435
dda8d76d
NC
8436 for (i = 0, section = filedata->section_headers;
8437 i < filedata->file_header.e_shnum;
b34976b6 8438 i++, section++)
252b5132
RH
8439 {
8440 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8441 && section->sh_type != SHT_REL
8442 && section->sh_type != SHT_RELR)
252b5132
RH
8443 continue;
8444
8445 rel_offset = section->sh_offset;
8446 rel_size = section->sh_size;
8447
8448 if (rel_size)
8449 {
a7fd1186 8450 relocation_type rel_type;
d3a49aa8 8451 unsigned long num_rela;
103f02d3 8452
ca0e11aa
NC
8453 if (filedata->is_separate)
8454 printf (_("\nIn linked file '%s' relocation section "),
8455 filedata->file_name);
8456 else
8457 printf (_("\nRelocation section "));
252b5132 8458
dda8d76d 8459 if (filedata->string_table == NULL)
19936277 8460 printf ("%d", section->sh_name);
252b5132 8461 else
dda8d76d 8462 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8463
d3a49aa8
AM
8464 num_rela = rel_size / section->sh_entsize;
8465 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
8466 " at offset 0x%lx contains %lu entries:\n",
8467 num_rela),
8468 rel_offset, num_rela);
252b5132 8469
a7fd1186
FS
8470 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8471 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8472
4fbb74a6 8473 if (section->sh_link != 0
dda8d76d 8474 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8475 {
2cf0635d
NC
8476 Elf_Internal_Shdr * symsec;
8477 Elf_Internal_Sym * symtab;
d79b3d50 8478 unsigned long nsyms;
c256ffe7 8479 unsigned long strtablen = 0;
2cf0635d 8480 char * strtab = NULL;
57346661 8481
dda8d76d 8482 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8483 if (symsec->sh_type != SHT_SYMTAB
8484 && symsec->sh_type != SHT_DYNSYM)
8485 continue;
8486
28d13567
AM
8487 if (!get_symtab (filedata, symsec,
8488 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8489 continue;
252b5132 8490
dda8d76d 8491 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8492 symtab, nsyms, strtab, strtablen,
a7fd1186 8493 rel_type,
bb4d2ac2 8494 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8495 free (strtab);
d79b3d50
NC
8496 free (symtab);
8497 }
8498 else
dda8d76d 8499 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8500 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8501
015dc7e1 8502 found = true;
252b5132
RH
8503 }
8504 }
8505
8506 if (! found)
45ac8f4f
NC
8507 {
8508 /* Users sometimes forget the -D option, so try to be helpful. */
8509 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8510 {
978c4450 8511 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8512 {
ca0e11aa
NC
8513 if (filedata->is_separate)
8514 printf (_("\nThere are no static relocations in linked file '%s'."),
8515 filedata->file_name);
8516 else
8517 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8518 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8519
8520 break;
8521 }
8522 }
8523 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8524 {
8525 if (filedata->is_separate)
8526 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8527 filedata->file_name);
8528 else
8529 printf (_("\nThere are no relocations in this file.\n"));
8530 }
45ac8f4f 8531 }
252b5132
RH
8532 }
8533
015dc7e1 8534 return true;
252b5132
RH
8535}
8536
4d6ed7c8
NC
8537/* An absolute address consists of a section and an offset. If the
8538 section is NULL, the offset itself is the address, otherwise, the
8539 address equals to LOAD_ADDRESS(section) + offset. */
8540
8541struct absaddr
948f632f
DA
8542{
8543 unsigned short section;
625d49fc 8544 uint64_t offset;
948f632f 8545};
4d6ed7c8 8546
948f632f
DA
8547/* Find the nearest symbol at or below ADDR. Returns the symbol
8548 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8549
4d6ed7c8 8550static void
dda8d76d
NC
8551find_symbol_for_address (Filedata * filedata,
8552 Elf_Internal_Sym * symtab,
8553 unsigned long nsyms,
8554 const char * strtab,
8555 unsigned long strtab_size,
8556 struct absaddr addr,
8557 const char ** symname,
625d49fc 8558 uint64_t * offset)
4d6ed7c8 8559{
625d49fc 8560 uint64_t dist = 0x100000;
2cf0635d 8561 Elf_Internal_Sym * sym;
948f632f
DA
8562 Elf_Internal_Sym * beg;
8563 Elf_Internal_Sym * end;
2cf0635d 8564 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8565
0b6ae522 8566 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8567 beg = symtab;
8568 end = symtab + nsyms;
0b6ae522 8569
948f632f 8570 while (beg < end)
4d6ed7c8 8571 {
625d49fc 8572 uint64_t value;
948f632f
DA
8573
8574 sym = beg + (end - beg) / 2;
0b6ae522 8575
948f632f 8576 value = sym->st_value;
0b6ae522
DJ
8577 REMOVE_ARCH_BITS (value);
8578
948f632f 8579 if (sym->st_name != 0
4d6ed7c8 8580 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8581 && addr.offset >= value
8582 && addr.offset - value < dist)
4d6ed7c8
NC
8583 {
8584 best = sym;
0b6ae522 8585 dist = addr.offset - value;
4d6ed7c8
NC
8586 if (!dist)
8587 break;
8588 }
948f632f
DA
8589
8590 if (addr.offset < value)
8591 end = sym;
8592 else
8593 beg = sym + 1;
4d6ed7c8 8594 }
1b31d05e 8595
4d6ed7c8
NC
8596 if (best)
8597 {
57346661 8598 *symname = (best->st_name >= strtab_size
2b692964 8599 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8600 *offset = dist;
8601 return;
8602 }
1b31d05e 8603
4d6ed7c8
NC
8604 *symname = NULL;
8605 *offset = addr.offset;
8606}
8607
32ec8896 8608static /* signed */ int
948f632f
DA
8609symcmp (const void *p, const void *q)
8610{
8611 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8612 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8613
8614 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8615}
8616
8617/* Process the unwind section. */
8618
8619#include "unwind-ia64.h"
8620
8621struct ia64_unw_table_entry
8622{
8623 struct absaddr start;
8624 struct absaddr end;
8625 struct absaddr info;
8626};
8627
8628struct ia64_unw_aux_info
8629{
32ec8896
NC
8630 struct ia64_unw_table_entry * table; /* Unwind table. */
8631 unsigned long table_len; /* Length of unwind table. */
8632 unsigned char * info; /* Unwind info. */
8633 unsigned long info_size; /* Size of unwind info. */
625d49fc
AM
8634 uint64_t info_addr; /* Starting address of unwind info. */
8635 uint64_t seg_base; /* Starting address of segment. */
32ec8896
NC
8636 Elf_Internal_Sym * symtab; /* The symbol table. */
8637 unsigned long nsyms; /* Number of symbols. */
8638 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8639 unsigned long nfuns; /* Number of entries in funtab. */
8640 char * strtab; /* The string table. */
8641 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8642};
8643
015dc7e1 8644static bool
dda8d76d 8645dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8646{
2cf0635d 8647 struct ia64_unw_table_entry * tp;
948f632f 8648 unsigned long j, nfuns;
4d6ed7c8 8649 int in_body;
015dc7e1 8650 bool res = true;
7036c0e1 8651
948f632f
DA
8652 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8653 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8654 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8655 aux->funtab[nfuns++] = aux->symtab[j];
8656 aux->nfuns = nfuns;
8657 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8658
4d6ed7c8
NC
8659 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8660 {
625d49fc
AM
8661 uint64_t stamp;
8662 uint64_t offset;
2cf0635d
NC
8663 const unsigned char * dp;
8664 const unsigned char * head;
53774b7e 8665 const unsigned char * end;
2cf0635d 8666 const char * procname;
4d6ed7c8 8667
dda8d76d 8668 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8669 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8670
8671 fputs ("\n<", stdout);
8672
8673 if (procname)
8674 {
8675 fputs (procname, stdout);
8676
8677 if (offset)
8678 printf ("+%lx", (unsigned long) offset);
8679 }
8680
8681 fputs (">: [", stdout);
8682 print_vma (tp->start.offset, PREFIX_HEX);
8683 fputc ('-', stdout);
8684 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8685 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8686 (unsigned long) (tp->info.offset - aux->seg_base));
8687
53774b7e
NC
8688 /* PR 17531: file: 86232b32. */
8689 if (aux->info == NULL)
8690 continue;
8691
97c0a079
AM
8692 offset = tp->info.offset;
8693 if (tp->info.section)
8694 {
8695 if (tp->info.section >= filedata->file_header.e_shnum)
8696 {
8697 warn (_("Invalid section %u in table entry %ld\n"),
8698 tp->info.section, (long) (tp - aux->table));
015dc7e1 8699 res = false;
97c0a079
AM
8700 continue;
8701 }
8702 offset += filedata->section_headers[tp->info.section].sh_addr;
8703 }
8704 offset -= aux->info_addr;
53774b7e 8705 /* PR 17531: file: 0997b4d1. */
90679903
AM
8706 if (offset >= aux->info_size
8707 || aux->info_size - offset < 8)
53774b7e
NC
8708 {
8709 warn (_("Invalid offset %lx in table entry %ld\n"),
8710 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8711 res = false;
53774b7e
NC
8712 continue;
8713 }
8714
97c0a079 8715 head = aux->info + offset;
a4a00738 8716 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8717
86f55779 8718 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8719 (unsigned) UNW_VER (stamp),
8720 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8721 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8722 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8723 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8724
8725 if (UNW_VER (stamp) != 1)
8726 {
2b692964 8727 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8728 continue;
8729 }
8730
8731 in_body = 0;
53774b7e
NC
8732 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8733 /* PR 17531: file: 16ceda89. */
8734 if (end > aux->info + aux->info_size)
8735 end = aux->info + aux->info_size;
8736 for (dp = head + 8; dp < end;)
b4477bc8 8737 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8738 }
948f632f
DA
8739
8740 free (aux->funtab);
32ec8896
NC
8741
8742 return res;
4d6ed7c8
NC
8743}
8744
015dc7e1 8745static bool
dda8d76d
NC
8746slurp_ia64_unwind_table (Filedata * filedata,
8747 struct ia64_unw_aux_info * aux,
8748 Elf_Internal_Shdr * sec)
4d6ed7c8 8749{
89fac5e3 8750 unsigned long size, nrelas, i;
2cf0635d
NC
8751 Elf_Internal_Phdr * seg;
8752 struct ia64_unw_table_entry * tep;
8753 Elf_Internal_Shdr * relsec;
8754 Elf_Internal_Rela * rela;
8755 Elf_Internal_Rela * rp;
8756 unsigned char * table;
8757 unsigned char * tp;
8758 Elf_Internal_Sym * sym;
8759 const char * relname;
4d6ed7c8 8760
53774b7e
NC
8761 aux->table_len = 0;
8762
4d6ed7c8
NC
8763 /* First, find the starting address of the segment that includes
8764 this section: */
8765
dda8d76d 8766 if (filedata->file_header.e_phnum)
4d6ed7c8 8767 {
dda8d76d 8768 if (! get_program_headers (filedata))
015dc7e1 8769 return false;
4d6ed7c8 8770
dda8d76d
NC
8771 for (seg = filedata->program_headers;
8772 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8773 ++seg)
4d6ed7c8
NC
8774 {
8775 if (seg->p_type != PT_LOAD)
8776 continue;
8777
8778 if (sec->sh_addr >= seg->p_vaddr
8779 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8780 {
8781 aux->seg_base = seg->p_vaddr;
8782 break;
8783 }
8784 }
4d6ed7c8
NC
8785 }
8786
8787 /* Second, build the unwind table from the contents of the unwind section: */
8788 size = sec->sh_size;
dda8d76d 8789 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8790 _("unwind table"));
a6e9f9df 8791 if (!table)
015dc7e1 8792 return false;
4d6ed7c8 8793
53774b7e 8794 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8795 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8796 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8797 tep = aux->table;
53774b7e
NC
8798
8799 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8800 {
8801 tep->start.section = SHN_UNDEF;
8802 tep->end.section = SHN_UNDEF;
8803 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8804 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8805 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8806 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8807 tep->start.offset += aux->seg_base;
8808 tep->end.offset += aux->seg_base;
8809 tep->info.offset += aux->seg_base;
8810 }
8811 free (table);
8812
41e92641 8813 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8814 for (relsec = filedata->section_headers;
8815 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8816 ++relsec)
8817 {
8818 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8819 || relsec->sh_info >= filedata->file_header.e_shnum
8820 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8821 continue;
8822
dda8d76d 8823 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8824 & rela, & nrelas))
53774b7e
NC
8825 {
8826 free (aux->table);
8827 aux->table = NULL;
8828 aux->table_len = 0;
015dc7e1 8829 return false;
53774b7e 8830 }
4d6ed7c8
NC
8831
8832 for (rp = rela; rp < rela + nrelas; ++rp)
8833 {
4770fb94 8834 unsigned int sym_ndx;
726bd37d
AM
8835 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8836 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8837
82b1b41b
NC
8838 /* PR 17531: file: 9fa67536. */
8839 if (relname == NULL)
8840 {
726bd37d 8841 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8842 continue;
8843 }
948f632f 8844
24d127aa 8845 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8846 {
82b1b41b 8847 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8848 continue;
8849 }
8850
89fac5e3 8851 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8852
53774b7e
NC
8853 /* PR 17531: file: 5bc8d9bf. */
8854 if (i >= aux->table_len)
8855 {
8856 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8857 continue;
8858 }
8859
4770fb94
AM
8860 sym_ndx = get_reloc_symindex (rp->r_info);
8861 if (sym_ndx >= aux->nsyms)
8862 {
8863 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8864 sym_ndx);
8865 continue;
8866 }
8867 sym = aux->symtab + sym_ndx;
8868
53774b7e 8869 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8870 {
8871 case 0:
8872 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8873 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8874 break;
8875 case 1:
8876 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8877 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8878 break;
8879 case 2:
8880 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8881 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8882 break;
8883 default:
8884 break;
8885 }
8886 }
8887
8888 free (rela);
8889 }
8890
015dc7e1 8891 return true;
4d6ed7c8
NC
8892}
8893
015dc7e1 8894static bool
dda8d76d 8895ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8896{
2cf0635d
NC
8897 Elf_Internal_Shdr * sec;
8898 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8899 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8900 struct ia64_unw_aux_info aux;
015dc7e1 8901 bool res = true;
f1467e33 8902
4d6ed7c8
NC
8903 memset (& aux, 0, sizeof (aux));
8904
dda8d76d 8905 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8906 {
28d13567 8907 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8908 {
28d13567 8909 if (aux.symtab)
4082ef84 8910 {
28d13567
AM
8911 error (_("Multiple symbol tables encountered\n"));
8912 free (aux.symtab);
8913 aux.symtab = NULL;
4082ef84 8914 free (aux.strtab);
28d13567 8915 aux.strtab = NULL;
4082ef84 8916 }
28d13567
AM
8917 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8918 &aux.strtab, &aux.strtab_size))
015dc7e1 8919 return false;
4d6ed7c8
NC
8920 }
8921 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8922 unwcount++;
8923 }
8924
8925 if (!unwcount)
8926 printf (_("\nThere are no unwind sections in this file.\n"));
8927
8928 while (unwcount-- > 0)
8929 {
84714f86 8930 const char *suffix;
579f31ac
JJ
8931 size_t len, len2;
8932
dda8d76d
NC
8933 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8934 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8935 if (sec->sh_type == SHT_IA_64_UNWIND)
8936 {
8937 unwsec = sec;
8938 break;
8939 }
4082ef84
NC
8940 /* We have already counted the number of SHT_IA64_UNWIND
8941 sections so the loop above should never fail. */
8942 assert (unwsec != NULL);
579f31ac
JJ
8943
8944 unwstart = i + 1;
8945 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8946
e4b17d5c
L
8947 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8948 {
8949 /* We need to find which section group it is in. */
4082ef84 8950 struct group_list * g;
e4b17d5c 8951
978c4450
AM
8952 if (filedata->section_headers_groups == NULL
8953 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8954 i = filedata->file_header.e_shnum;
4082ef84 8955 else
e4b17d5c 8956 {
978c4450 8957 g = filedata->section_headers_groups[i]->root;
18bd398b 8958
4082ef84
NC
8959 for (; g != NULL; g = g->next)
8960 {
dda8d76d 8961 sec = filedata->section_headers + g->section_index;
e4b17d5c 8962
84714f86
AM
8963 if (section_name_valid (filedata, sec)
8964 && streq (section_name (filedata, sec),
8965 ELF_STRING_ia64_unwind_info))
4082ef84
NC
8966 break;
8967 }
8968
8969 if (g == NULL)
dda8d76d 8970 i = filedata->file_header.e_shnum;
4082ef84 8971 }
e4b17d5c 8972 }
84714f86
AM
8973 else if (section_name_valid (filedata, unwsec)
8974 && startswith (section_name (filedata, unwsec),
e9b095a5 8975 ELF_STRING_ia64_unwind_once))
579f31ac 8976 {
18bd398b 8977 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 8978 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 8979 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8980 for (i = 0, sec = filedata->section_headers;
8981 i < filedata->file_header.e_shnum;
579f31ac 8982 ++i, ++sec)
84714f86
AM
8983 if (section_name_valid (filedata, sec)
8984 && startswith (section_name (filedata, sec),
e9b095a5 8985 ELF_STRING_ia64_unwind_info_once)
84714f86 8986 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8987 break;
8988 }
8989 else
8990 {
8991 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8992 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8993 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8994 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8995 suffix = "";
84714f86
AM
8996 if (section_name_valid (filedata, unwsec)
8997 && startswith (section_name (filedata, unwsec),
8998 ELF_STRING_ia64_unwind))
8999 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9000 for (i = 0, sec = filedata->section_headers;
9001 i < filedata->file_header.e_shnum;
579f31ac 9002 ++i, ++sec)
84714f86
AM
9003 if (section_name_valid (filedata, sec)
9004 && startswith (section_name (filedata, sec),
9005 ELF_STRING_ia64_unwind_info)
9006 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9007 break;
9008 }
9009
dda8d76d 9010 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
9011 {
9012 printf (_("\nCould not find unwind info section for "));
9013
dda8d76d 9014 if (filedata->string_table == NULL)
579f31ac
JJ
9015 printf ("%d", unwsec->sh_name);
9016 else
dda8d76d 9017 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9018 }
9019 else
4d6ed7c8 9020 {
4d6ed7c8 9021 aux.info_addr = sec->sh_addr;
dda8d76d 9022 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9023 sec->sh_size,
9024 _("unwind info"));
59245841 9025 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9026
579f31ac 9027 printf (_("\nUnwind section "));
4d6ed7c8 9028
dda8d76d 9029 if (filedata->string_table == NULL)
579f31ac
JJ
9030 printf ("%d", unwsec->sh_name);
9031 else
dda8d76d 9032 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9033
579f31ac 9034 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 9035 (unsigned long) unwsec->sh_offset,
89fac5e3 9036 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 9037
dda8d76d 9038 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9039 && aux.table_len > 0)
dda8d76d 9040 dump_ia64_unwind (filedata, & aux);
579f31ac 9041
9db70fc3
AM
9042 free ((char *) aux.table);
9043 free ((char *) aux.info);
579f31ac
JJ
9044 aux.table = NULL;
9045 aux.info = NULL;
9046 }
4d6ed7c8 9047 }
4d6ed7c8 9048
9db70fc3
AM
9049 free (aux.symtab);
9050 free ((char *) aux.strtab);
32ec8896
NC
9051
9052 return res;
4d6ed7c8
NC
9053}
9054
3f5e193b 9055struct hppa_unw_table_entry
32ec8896
NC
9056{
9057 struct absaddr start;
9058 struct absaddr end;
9059 unsigned int Cannot_unwind:1; /* 0 */
9060 unsigned int Millicode:1; /* 1 */
9061 unsigned int Millicode_save_sr0:1; /* 2 */
9062 unsigned int Region_description:2; /* 3..4 */
9063 unsigned int reserved1:1; /* 5 */
9064 unsigned int Entry_SR:1; /* 6 */
9065 unsigned int Entry_FR:4; /* Number saved 7..10 */
9066 unsigned int Entry_GR:5; /* Number saved 11..15 */
9067 unsigned int Args_stored:1; /* 16 */
9068 unsigned int Variable_Frame:1; /* 17 */
9069 unsigned int Separate_Package_Body:1; /* 18 */
9070 unsigned int Frame_Extension_Millicode:1; /* 19 */
9071 unsigned int Stack_Overflow_Check:1; /* 20 */
9072 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9073 unsigned int Ada_Region:1; /* 22 */
9074 unsigned int cxx_info:1; /* 23 */
9075 unsigned int cxx_try_catch:1; /* 24 */
9076 unsigned int sched_entry_seq:1; /* 25 */
9077 unsigned int reserved2:1; /* 26 */
9078 unsigned int Save_SP:1; /* 27 */
9079 unsigned int Save_RP:1; /* 28 */
9080 unsigned int Save_MRP_in_frame:1; /* 29 */
9081 unsigned int extn_ptr_defined:1; /* 30 */
9082 unsigned int Cleanup_defined:1; /* 31 */
9083
9084 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9085 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9086 unsigned int Large_frame:1; /* 2 */
9087 unsigned int Pseudo_SP_Set:1; /* 3 */
9088 unsigned int reserved4:1; /* 4 */
9089 unsigned int Total_frame_size:27; /* 5..31 */
9090};
3f5e193b 9091
57346661 9092struct hppa_unw_aux_info
948f632f 9093{
32ec8896
NC
9094 struct hppa_unw_table_entry * table; /* Unwind table. */
9095 unsigned long table_len; /* Length of unwind table. */
625d49fc 9096 uint64_t seg_base; /* Starting address of segment. */
32ec8896
NC
9097 Elf_Internal_Sym * symtab; /* The symbol table. */
9098 unsigned long nsyms; /* Number of symbols. */
9099 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9100 unsigned long nfuns; /* Number of entries in funtab. */
9101 char * strtab; /* The string table. */
9102 unsigned long strtab_size; /* Size of string table. */
948f632f 9103};
57346661 9104
015dc7e1 9105static bool
dda8d76d 9106dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9107{
2cf0635d 9108 struct hppa_unw_table_entry * tp;
948f632f 9109 unsigned long j, nfuns;
015dc7e1 9110 bool res = true;
948f632f
DA
9111
9112 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9113 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9114 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9115 aux->funtab[nfuns++] = aux->symtab[j];
9116 aux->nfuns = nfuns;
9117 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9118
57346661
AM
9119 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9120 {
625d49fc 9121 uint64_t offset;
2cf0635d 9122 const char * procname;
57346661 9123
dda8d76d 9124 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9125 aux->strtab_size, tp->start, &procname,
9126 &offset);
9127
9128 fputs ("\n<", stdout);
9129
9130 if (procname)
9131 {
9132 fputs (procname, stdout);
9133
9134 if (offset)
9135 printf ("+%lx", (unsigned long) offset);
9136 }
9137
9138 fputs (">: [", stdout);
9139 print_vma (tp->start.offset, PREFIX_HEX);
9140 fputc ('-', stdout);
9141 print_vma (tp->end.offset, PREFIX_HEX);
9142 printf ("]\n\t");
9143
18bd398b
NC
9144#define PF(_m) if (tp->_m) printf (#_m " ");
9145#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9146 PF(Cannot_unwind);
9147 PF(Millicode);
9148 PF(Millicode_save_sr0);
18bd398b 9149 /* PV(Region_description); */
57346661
AM
9150 PF(Entry_SR);
9151 PV(Entry_FR);
9152 PV(Entry_GR);
9153 PF(Args_stored);
9154 PF(Variable_Frame);
9155 PF(Separate_Package_Body);
9156 PF(Frame_Extension_Millicode);
9157 PF(Stack_Overflow_Check);
9158 PF(Two_Instruction_SP_Increment);
9159 PF(Ada_Region);
9160 PF(cxx_info);
9161 PF(cxx_try_catch);
9162 PF(sched_entry_seq);
9163 PF(Save_SP);
9164 PF(Save_RP);
9165 PF(Save_MRP_in_frame);
9166 PF(extn_ptr_defined);
9167 PF(Cleanup_defined);
9168 PF(MPE_XL_interrupt_marker);
9169 PF(HP_UX_interrupt_marker);
9170 PF(Large_frame);
9171 PF(Pseudo_SP_Set);
9172 PV(Total_frame_size);
9173#undef PF
9174#undef PV
9175 }
9176
18bd398b 9177 printf ("\n");
948f632f
DA
9178
9179 free (aux->funtab);
32ec8896
NC
9180
9181 return res;
57346661
AM
9182}
9183
015dc7e1 9184static bool
dda8d76d
NC
9185slurp_hppa_unwind_table (Filedata * filedata,
9186 struct hppa_unw_aux_info * aux,
9187 Elf_Internal_Shdr * sec)
57346661 9188{
1c0751b2 9189 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9190 Elf_Internal_Phdr * seg;
9191 struct hppa_unw_table_entry * tep;
9192 Elf_Internal_Shdr * relsec;
9193 Elf_Internal_Rela * rela;
9194 Elf_Internal_Rela * rp;
9195 unsigned char * table;
9196 unsigned char * tp;
9197 Elf_Internal_Sym * sym;
9198 const char * relname;
57346661 9199
57346661
AM
9200 /* First, find the starting address of the segment that includes
9201 this section. */
dda8d76d 9202 if (filedata->file_header.e_phnum)
57346661 9203 {
dda8d76d 9204 if (! get_program_headers (filedata))
015dc7e1 9205 return false;
57346661 9206
dda8d76d
NC
9207 for (seg = filedata->program_headers;
9208 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9209 ++seg)
9210 {
9211 if (seg->p_type != PT_LOAD)
9212 continue;
9213
9214 if (sec->sh_addr >= seg->p_vaddr
9215 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9216 {
9217 aux->seg_base = seg->p_vaddr;
9218 break;
9219 }
9220 }
9221 }
9222
9223 /* Second, build the unwind table from the contents of the unwind
9224 section. */
9225 size = sec->sh_size;
dda8d76d 9226 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9227 _("unwind table"));
57346661 9228 if (!table)
015dc7e1 9229 return false;
57346661 9230
1c0751b2
DA
9231 unw_ent_size = 16;
9232 nentries = size / unw_ent_size;
9233 size = unw_ent_size * nentries;
57346661 9234
e3fdc001 9235 aux->table_len = nentries;
3f5e193b
NC
9236 tep = aux->table = (struct hppa_unw_table_entry *)
9237 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9238
1c0751b2 9239 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9240 {
9241 unsigned int tmp1, tmp2;
9242
9243 tep->start.section = SHN_UNDEF;
9244 tep->end.section = SHN_UNDEF;
9245
1c0751b2
DA
9246 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9247 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9248 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9249 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9250
9251 tep->start.offset += aux->seg_base;
9252 tep->end.offset += aux->seg_base;
57346661
AM
9253
9254 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9255 tep->Millicode = (tmp1 >> 30) & 0x1;
9256 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9257 tep->Region_description = (tmp1 >> 27) & 0x3;
9258 tep->reserved1 = (tmp1 >> 26) & 0x1;
9259 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9260 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9261 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9262 tep->Args_stored = (tmp1 >> 15) & 0x1;
9263 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9264 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9265 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9266 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9267 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9268 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9269 tep->cxx_info = (tmp1 >> 8) & 0x1;
9270 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9271 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9272 tep->reserved2 = (tmp1 >> 5) & 0x1;
9273 tep->Save_SP = (tmp1 >> 4) & 0x1;
9274 tep->Save_RP = (tmp1 >> 3) & 0x1;
9275 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9276 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9277 tep->Cleanup_defined = tmp1 & 0x1;
9278
9279 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9280 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9281 tep->Large_frame = (tmp2 >> 29) & 0x1;
9282 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9283 tep->reserved4 = (tmp2 >> 27) & 0x1;
9284 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9285 }
9286 free (table);
9287
9288 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9289 for (relsec = filedata->section_headers;
9290 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9291 ++relsec)
9292 {
9293 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9294 || relsec->sh_info >= filedata->file_header.e_shnum
9295 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9296 continue;
9297
dda8d76d 9298 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9299 & rela, & nrelas))
015dc7e1 9300 return false;
57346661
AM
9301
9302 for (rp = rela; rp < rela + nrelas; ++rp)
9303 {
4770fb94 9304 unsigned int sym_ndx;
726bd37d
AM
9305 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9306 relname = elf_hppa_reloc_type (r_type);
57346661 9307
726bd37d
AM
9308 if (relname == NULL)
9309 {
9310 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9311 continue;
9312 }
9313
57346661 9314 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9315 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9316 {
726bd37d 9317 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9318 continue;
9319 }
9320
9321 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9322 if (i >= aux->table_len)
9323 {
9324 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
9325 continue;
9326 }
57346661 9327
4770fb94
AM
9328 sym_ndx = get_reloc_symindex (rp->r_info);
9329 if (sym_ndx >= aux->nsyms)
9330 {
9331 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9332 sym_ndx);
9333 continue;
9334 }
9335 sym = aux->symtab + sym_ndx;
9336
43f6cd05 9337 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9338 {
9339 case 0:
9340 aux->table[i].start.section = sym->st_shndx;
1e456d54 9341 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9342 break;
9343 case 1:
9344 aux->table[i].end.section = sym->st_shndx;
1e456d54 9345 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9346 break;
9347 default:
9348 break;
9349 }
9350 }
9351
9352 free (rela);
9353 }
9354
015dc7e1 9355 return true;
57346661
AM
9356}
9357
015dc7e1 9358static bool
dda8d76d 9359hppa_process_unwind (Filedata * filedata)
57346661 9360{
57346661 9361 struct hppa_unw_aux_info aux;
2cf0635d 9362 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9363 Elf_Internal_Shdr * sec;
18bd398b 9364 unsigned long i;
015dc7e1 9365 bool res = true;
57346661 9366
dda8d76d 9367 if (filedata->string_table == NULL)
015dc7e1 9368 return false;
1b31d05e
NC
9369
9370 memset (& aux, 0, sizeof (aux));
57346661 9371
dda8d76d 9372 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9373 {
28d13567 9374 if (sec->sh_type == SHT_SYMTAB)
57346661 9375 {
28d13567 9376 if (aux.symtab)
4082ef84 9377 {
28d13567
AM
9378 error (_("Multiple symbol tables encountered\n"));
9379 free (aux.symtab);
9380 aux.symtab = NULL;
4082ef84 9381 free (aux.strtab);
28d13567 9382 aux.strtab = NULL;
4082ef84 9383 }
28d13567
AM
9384 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9385 &aux.strtab, &aux.strtab_size))
015dc7e1 9386 return false;
57346661 9387 }
84714f86
AM
9388 else if (section_name_valid (filedata, sec)
9389 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9390 unwsec = sec;
9391 }
9392
9393 if (!unwsec)
9394 printf (_("\nThere are no unwind sections in this file.\n"));
9395
dda8d76d 9396 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9397 {
84714f86
AM
9398 if (section_name_valid (filedata, sec)
9399 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9400 {
43f6cd05 9401 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 9402
d3a49aa8
AM
9403 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9404 "contains %lu entry:\n",
9405 "\nUnwind section '%s' at offset 0x%lx "
9406 "contains %lu entries:\n",
9407 num_unwind),
dda8d76d 9408 printable_section_name (filedata, sec),
57346661 9409 (unsigned long) sec->sh_offset,
d3a49aa8 9410 num_unwind);
57346661 9411
dda8d76d 9412 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9413 res = false;
66b09c7e
S
9414
9415 if (res && aux.table_len > 0)
32ec8896 9416 {
dda8d76d 9417 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9418 res = false;
32ec8896 9419 }
57346661 9420
9db70fc3 9421 free ((char *) aux.table);
57346661
AM
9422 aux.table = NULL;
9423 }
9424 }
9425
9db70fc3
AM
9426 free (aux.symtab);
9427 free ((char *) aux.strtab);
32ec8896
NC
9428
9429 return res;
57346661
AM
9430}
9431
0b6ae522
DJ
9432struct arm_section
9433{
a734115a
NC
9434 unsigned char * data; /* The unwind data. */
9435 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9436 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
9437 unsigned long nrelas; /* The number of relocations. */
9438 unsigned int rel_type; /* REL or RELA ? */
9439 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9440};
9441
9442struct arm_unw_aux_info
9443{
dda8d76d 9444 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
9445 Elf_Internal_Sym * symtab; /* The file's symbol table. */
9446 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
9447 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9448 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
9449 char * strtab; /* The file's string table. */
9450 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
9451};
9452
9453static const char *
dda8d76d
NC
9454arm_print_vma_and_name (Filedata * filedata,
9455 struct arm_unw_aux_info * aux,
625d49fc 9456 uint64_t fn,
dda8d76d 9457 struct absaddr addr)
0b6ae522
DJ
9458{
9459 const char *procname;
625d49fc 9460 uint64_t sym_offset;
0b6ae522
DJ
9461
9462 if (addr.section == SHN_UNDEF)
9463 addr.offset = fn;
9464
dda8d76d 9465 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9466 aux->strtab_size, addr, &procname,
9467 &sym_offset);
9468
9469 print_vma (fn, PREFIX_HEX);
9470
9471 if (procname)
9472 {
9473 fputs (" <", stdout);
9474 fputs (procname, stdout);
9475
9476 if (sym_offset)
9477 printf ("+0x%lx", (unsigned long) sym_offset);
9478 fputc ('>', stdout);
9479 }
9480
9481 return procname;
9482}
9483
9484static void
9485arm_free_section (struct arm_section *arm_sec)
9486{
9db70fc3
AM
9487 free (arm_sec->data);
9488 free (arm_sec->rela);
0b6ae522
DJ
9489}
9490
a734115a
NC
9491/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9492 cached section and install SEC instead.
9493 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9494 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9495 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9496 relocation's offset in ADDR.
1b31d05e
NC
9497 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9498 into the string table of the symbol associated with the reloc. If no
9499 reloc was applied store -1 there.
9500 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9501
015dc7e1 9502static bool
dda8d76d
NC
9503get_unwind_section_word (Filedata * filedata,
9504 struct arm_unw_aux_info * aux,
1b31d05e
NC
9505 struct arm_section * arm_sec,
9506 Elf_Internal_Shdr * sec,
625d49fc 9507 uint64_t word_offset,
1b31d05e
NC
9508 unsigned int * wordp,
9509 struct absaddr * addr,
625d49fc 9510 uint64_t * sym_name)
0b6ae522
DJ
9511{
9512 Elf_Internal_Rela *rp;
9513 Elf_Internal_Sym *sym;
9514 const char * relname;
9515 unsigned int word;
015dc7e1 9516 bool wrapped;
0b6ae522 9517
e0a31db1 9518 if (sec == NULL || arm_sec == NULL)
015dc7e1 9519 return false;
e0a31db1 9520
0b6ae522
DJ
9521 addr->section = SHN_UNDEF;
9522 addr->offset = 0;
9523
1b31d05e 9524 if (sym_name != NULL)
625d49fc 9525 *sym_name = (uint64_t) -1;
1b31d05e 9526
a734115a 9527 /* If necessary, update the section cache. */
0b6ae522
DJ
9528 if (sec != arm_sec->sec)
9529 {
9530 Elf_Internal_Shdr *relsec;
9531
9532 arm_free_section (arm_sec);
9533
9534 arm_sec->sec = sec;
dda8d76d 9535 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9536 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9537 arm_sec->rela = NULL;
9538 arm_sec->nrelas = 0;
9539
dda8d76d
NC
9540 for (relsec = filedata->section_headers;
9541 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9542 ++relsec)
9543 {
dda8d76d
NC
9544 if (relsec->sh_info >= filedata->file_header.e_shnum
9545 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9546 /* PR 15745: Check the section type as well. */
9547 || (relsec->sh_type != SHT_REL
9548 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9549 continue;
9550
a734115a 9551 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9552 if (relsec->sh_type == SHT_REL)
9553 {
dda8d76d 9554 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9555 relsec->sh_size,
9556 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9557 return false;
0b6ae522 9558 }
1ae40aa4 9559 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9560 {
dda8d76d 9561 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9562 relsec->sh_size,
9563 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9564 return false;
0b6ae522 9565 }
1ae40aa4 9566 break;
0b6ae522
DJ
9567 }
9568
9569 arm_sec->next_rela = arm_sec->rela;
9570 }
9571
a734115a 9572 /* If there is no unwind data we can do nothing. */
0b6ae522 9573 if (arm_sec->data == NULL)
015dc7e1 9574 return false;
0b6ae522 9575
e0a31db1 9576 /* If the offset is invalid then fail. */
f32ba729
NC
9577 if (/* PR 21343 *//* PR 18879 */
9578 sec->sh_size < 4
625d49fc 9579 || word_offset > sec->sh_size - 4)
015dc7e1 9580 return false;
e0a31db1 9581
a734115a 9582 /* Get the word at the required offset. */
0b6ae522
DJ
9583 word = byte_get (arm_sec->data + word_offset, 4);
9584
0eff7165
NC
9585 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9586 if (arm_sec->rela == NULL)
9587 {
9588 * wordp = word;
015dc7e1 9589 return true;
0eff7165
NC
9590 }
9591
a734115a 9592 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9593 wrapped = false;
0b6ae522
DJ
9594 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9595 {
625d49fc 9596 uint64_t prelval, offset;
0b6ae522
DJ
9597
9598 if (rp->r_offset > word_offset && !wrapped)
9599 {
9600 rp = arm_sec->rela;
015dc7e1 9601 wrapped = true;
0b6ae522
DJ
9602 }
9603 if (rp->r_offset > word_offset)
9604 break;
9605
9606 if (rp->r_offset & 3)
9607 {
9608 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
9609 (unsigned long) rp->r_offset);
9610 continue;
9611 }
9612
9613 if (rp->r_offset < word_offset)
9614 continue;
9615
74e1a04b
NC
9616 /* PR 17531: file: 027-161405-0.004 */
9617 if (aux->symtab == NULL)
9618 continue;
9619
0b6ae522
DJ
9620 if (arm_sec->rel_type == SHT_REL)
9621 {
9622 offset = word & 0x7fffffff;
9623 if (offset & 0x40000000)
625d49fc 9624 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 9625 }
a734115a 9626 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9627 offset = rp->r_addend;
a734115a 9628 else
74e1a04b
NC
9629 {
9630 error (_("Unknown section relocation type %d encountered\n"),
9631 arm_sec->rel_type);
9632 break;
9633 }
0b6ae522 9634
071436c6
NC
9635 /* PR 17531 file: 027-1241568-0.004. */
9636 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9637 {
9638 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
9639 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
9640 break;
9641 }
9642
9643 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9644 offset += sym->st_value;
9645 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9646
a734115a 9647 /* Check that we are processing the expected reloc type. */
dda8d76d 9648 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9649 {
9650 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9651 if (relname == NULL)
9652 {
9653 warn (_("Skipping unknown ARM relocation type: %d\n"),
9654 (int) ELF32_R_TYPE (rp->r_info));
9655 continue;
9656 }
a734115a
NC
9657
9658 if (streq (relname, "R_ARM_NONE"))
9659 continue;
0b4362b0 9660
a734115a
NC
9661 if (! streq (relname, "R_ARM_PREL31"))
9662 {
071436c6 9663 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9664 continue;
9665 }
9666 }
dda8d76d 9667 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9668 {
9669 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9670 if (relname == NULL)
9671 {
9672 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9673 (int) ELF32_R_TYPE (rp->r_info));
9674 continue;
9675 }
0b4362b0 9676
a734115a
NC
9677 if (streq (relname, "R_C6000_NONE"))
9678 continue;
9679
9680 if (! streq (relname, "R_C6000_PREL31"))
9681 {
071436c6 9682 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9683 continue;
9684 }
9685
9686 prelval >>= 1;
9687 }
9688 else
74e1a04b
NC
9689 {
9690 /* This function currently only supports ARM and TI unwinders. */
9691 warn (_("Only TI and ARM unwinders are currently supported\n"));
9692 break;
9693 }
fa197c1c 9694
625d49fc 9695 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
9696 addr->section = sym->st_shndx;
9697 addr->offset = offset;
74e1a04b 9698
1b31d05e
NC
9699 if (sym_name)
9700 * sym_name = sym->st_name;
0b6ae522
DJ
9701 break;
9702 }
9703
9704 *wordp = word;
9705 arm_sec->next_rela = rp;
9706
015dc7e1 9707 return true;
0b6ae522
DJ
9708}
9709
a734115a
NC
9710static const char *tic6x_unwind_regnames[16] =
9711{
0b4362b0
RM
9712 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9713 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9714 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9715};
fa197c1c 9716
0b6ae522 9717static void
fa197c1c 9718decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9719{
fa197c1c
PB
9720 int i;
9721
9722 for (i = 12; mask; mask >>= 1, i--)
9723 {
9724 if (mask & 1)
9725 {
9726 fputs (tic6x_unwind_regnames[i], stdout);
9727 if (mask > 1)
9728 fputs (", ", stdout);
9729 }
9730 }
9731}
0b6ae522
DJ
9732
9733#define ADVANCE \
9734 if (remaining == 0 && more_words) \
9735 { \
9736 data_offset += 4; \
dda8d76d 9737 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9738 data_offset, & word, & addr, NULL)) \
015dc7e1 9739 return false; \
0b6ae522
DJ
9740 remaining = 4; \
9741 more_words--; \
9742 } \
9743
9744#define GET_OP(OP) \
9745 ADVANCE; \
9746 if (remaining) \
9747 { \
9748 remaining--; \
9749 (OP) = word >> 24; \
9750 word <<= 8; \
9751 } \
9752 else \
9753 { \
2b692964 9754 printf (_("[Truncated opcode]\n")); \
015dc7e1 9755 return false; \
0b6ae522 9756 } \
cc5914eb 9757 printf ("0x%02x ", OP)
0b6ae522 9758
015dc7e1 9759static bool
dda8d76d
NC
9760decode_arm_unwind_bytecode (Filedata * filedata,
9761 struct arm_unw_aux_info * aux,
948f632f
DA
9762 unsigned int word,
9763 unsigned int remaining,
9764 unsigned int more_words,
625d49fc 9765 uint64_t data_offset,
948f632f
DA
9766 Elf_Internal_Shdr * data_sec,
9767 struct arm_section * data_arm_sec)
fa197c1c
PB
9768{
9769 struct absaddr addr;
015dc7e1 9770 bool res = true;
0b6ae522
DJ
9771
9772 /* Decode the unwinding instructions. */
9773 while (1)
9774 {
9775 unsigned int op, op2;
9776
9777 ADVANCE;
9778 if (remaining == 0)
9779 break;
9780 remaining--;
9781 op = word >> 24;
9782 word <<= 8;
9783
cc5914eb 9784 printf (" 0x%02x ", op);
0b6ae522
DJ
9785
9786 if ((op & 0xc0) == 0x00)
9787 {
9788 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9789
cc5914eb 9790 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9791 }
9792 else if ((op & 0xc0) == 0x40)
9793 {
9794 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9795
cc5914eb 9796 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9797 }
9798 else if ((op & 0xf0) == 0x80)
9799 {
9800 GET_OP (op2);
9801 if (op == 0x80 && op2 == 0)
9802 printf (_("Refuse to unwind"));
9803 else
9804 {
9805 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9806 bool first = true;
0b6ae522 9807 int i;
2b692964 9808
0b6ae522
DJ
9809 printf ("pop {");
9810 for (i = 0; i < 12; i++)
9811 if (mask & (1 << i))
9812 {
9813 if (first)
015dc7e1 9814 first = false;
0b6ae522
DJ
9815 else
9816 printf (", ");
9817 printf ("r%d", 4 + i);
9818 }
9819 printf ("}");
9820 }
9821 }
9822 else if ((op & 0xf0) == 0x90)
9823 {
9824 if (op == 0x9d || op == 0x9f)
9825 printf (_(" [Reserved]"));
9826 else
cc5914eb 9827 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9828 }
9829 else if ((op & 0xf0) == 0xa0)
9830 {
9831 int end = 4 + (op & 0x07);
015dc7e1 9832 bool first = true;
0b6ae522 9833 int i;
61865e30 9834
0b6ae522
DJ
9835 printf (" pop {");
9836 for (i = 4; i <= end; i++)
9837 {
9838 if (first)
015dc7e1 9839 first = false;
0b6ae522
DJ
9840 else
9841 printf (", ");
9842 printf ("r%d", i);
9843 }
9844 if (op & 0x08)
9845 {
1b31d05e 9846 if (!first)
0b6ae522
DJ
9847 printf (", ");
9848 printf ("r14");
9849 }
9850 printf ("}");
9851 }
9852 else if (op == 0xb0)
9853 printf (_(" finish"));
9854 else if (op == 0xb1)
9855 {
9856 GET_OP (op2);
9857 if (op2 == 0 || (op2 & 0xf0) != 0)
9858 printf (_("[Spare]"));
9859 else
9860 {
9861 unsigned int mask = op2 & 0x0f;
015dc7e1 9862 bool first = true;
0b6ae522 9863 int i;
61865e30 9864
0b6ae522
DJ
9865 printf ("pop {");
9866 for (i = 0; i < 12; i++)
9867 if (mask & (1 << i))
9868 {
9869 if (first)
015dc7e1 9870 first = false;
0b6ae522
DJ
9871 else
9872 printf (", ");
9873 printf ("r%d", i);
9874 }
9875 printf ("}");
9876 }
9877 }
9878 else if (op == 0xb2)
9879 {
b115cf96 9880 unsigned char buf[9];
0b6ae522
DJ
9881 unsigned int i, len;
9882 unsigned long offset;
61865e30 9883
b115cf96 9884 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9885 {
9886 GET_OP (buf[i]);
9887 if ((buf[i] & 0x80) == 0)
9888 break;
9889 }
4082ef84 9890 if (i == sizeof (buf))
32ec8896 9891 {
27a45f42 9892 error (_("corrupt change to vsp\n"));
015dc7e1 9893 res = false;
32ec8896 9894 }
4082ef84
NC
9895 else
9896 {
015dc7e1 9897 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9898 assert (len == i + 1);
9899 offset = offset * 4 + 0x204;
9900 printf ("vsp = vsp + %ld", offset);
9901 }
0b6ae522 9902 }
61865e30 9903 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9904 {
61865e30
NC
9905 unsigned int first, last;
9906
9907 GET_OP (op2);
9908 first = op2 >> 4;
9909 last = op2 & 0x0f;
9910 if (op == 0xc8)
9911 first = first + 16;
9912 printf ("pop {D%d", first);
9913 if (last)
9914 printf ("-D%d", first + last);
9915 printf ("}");
9916 }
09854a88
TB
9917 else if (op == 0xb4)
9918 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
9919 else if (op == 0xb5)
9920 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
9921 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9922 {
9923 unsigned int count = op & 0x07;
9924
9925 printf ("pop {D8");
9926 if (count)
9927 printf ("-D%d", 8 + count);
9928 printf ("}");
9929 }
9930 else if (op >= 0xc0 && op <= 0xc5)
9931 {
9932 unsigned int count = op & 0x07;
9933
9934 printf (" pop {wR10");
9935 if (count)
9936 printf ("-wR%d", 10 + count);
9937 printf ("}");
9938 }
9939 else if (op == 0xc6)
9940 {
9941 unsigned int first, last;
9942
9943 GET_OP (op2);
9944 first = op2 >> 4;
9945 last = op2 & 0x0f;
9946 printf ("pop {wR%d", first);
9947 if (last)
9948 printf ("-wR%d", first + last);
9949 printf ("}");
9950 }
9951 else if (op == 0xc7)
9952 {
9953 GET_OP (op2);
9954 if (op2 == 0 || (op2 & 0xf0) != 0)
9955 printf (_("[Spare]"));
0b6ae522
DJ
9956 else
9957 {
61865e30 9958 unsigned int mask = op2 & 0x0f;
015dc7e1 9959 bool first = true;
61865e30
NC
9960 int i;
9961
9962 printf ("pop {");
9963 for (i = 0; i < 4; i++)
9964 if (mask & (1 << i))
9965 {
9966 if (first)
015dc7e1 9967 first = false;
61865e30
NC
9968 else
9969 printf (", ");
9970 printf ("wCGR%d", i);
9971 }
9972 printf ("}");
0b6ae522
DJ
9973 }
9974 }
61865e30 9975 else
32ec8896
NC
9976 {
9977 printf (_(" [unsupported opcode]"));
015dc7e1 9978 res = false;
32ec8896
NC
9979 }
9980
0b6ae522
DJ
9981 printf ("\n");
9982 }
32ec8896
NC
9983
9984 return res;
fa197c1c
PB
9985}
9986
015dc7e1 9987static bool
dda8d76d
NC
9988decode_tic6x_unwind_bytecode (Filedata * filedata,
9989 struct arm_unw_aux_info * aux,
948f632f
DA
9990 unsigned int word,
9991 unsigned int remaining,
9992 unsigned int more_words,
625d49fc 9993 uint64_t data_offset,
948f632f
DA
9994 Elf_Internal_Shdr * data_sec,
9995 struct arm_section * data_arm_sec)
fa197c1c
PB
9996{
9997 struct absaddr addr;
9998
9999 /* Decode the unwinding instructions. */
10000 while (1)
10001 {
10002 unsigned int op, op2;
10003
10004 ADVANCE;
10005 if (remaining == 0)
10006 break;
10007 remaining--;
10008 op = word >> 24;
10009 word <<= 8;
10010
9cf03b7e 10011 printf (" 0x%02x ", op);
fa197c1c
PB
10012
10013 if ((op & 0xc0) == 0x00)
10014 {
10015 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10016 printf (" sp = sp + %d", offset);
fa197c1c
PB
10017 }
10018 else if ((op & 0xc0) == 0x80)
10019 {
10020 GET_OP (op2);
10021 if (op == 0x80 && op2 == 0)
10022 printf (_("Refuse to unwind"));
10023 else
10024 {
10025 unsigned int mask = ((op & 0x1f) << 8) | op2;
10026 if (op & 0x20)
10027 printf ("pop compact {");
10028 else
10029 printf ("pop {");
10030
10031 decode_tic6x_unwind_regmask (mask);
10032 printf("}");
10033 }
10034 }
10035 else if ((op & 0xf0) == 0xc0)
10036 {
10037 unsigned int reg;
10038 unsigned int nregs;
10039 unsigned int i;
10040 const char *name;
a734115a
NC
10041 struct
10042 {
32ec8896
NC
10043 unsigned int offset;
10044 unsigned int reg;
fa197c1c
PB
10045 } regpos[16];
10046
10047 /* Scan entire instruction first so that GET_OP output is not
10048 interleaved with disassembly. */
10049 nregs = 0;
10050 for (i = 0; nregs < (op & 0xf); i++)
10051 {
10052 GET_OP (op2);
10053 reg = op2 >> 4;
10054 if (reg != 0xf)
10055 {
10056 regpos[nregs].offset = i * 2;
10057 regpos[nregs].reg = reg;
10058 nregs++;
10059 }
10060
10061 reg = op2 & 0xf;
10062 if (reg != 0xf)
10063 {
10064 regpos[nregs].offset = i * 2 + 1;
10065 regpos[nregs].reg = reg;
10066 nregs++;
10067 }
10068 }
10069
10070 printf (_("pop frame {"));
18344509 10071 if (nregs == 0)
fa197c1c 10072 {
18344509
NC
10073 printf (_("*corrupt* - no registers specified"));
10074 }
10075 else
10076 {
10077 reg = nregs - 1;
10078 for (i = i * 2; i > 0; i--)
fa197c1c 10079 {
18344509
NC
10080 if (regpos[reg].offset == i - 1)
10081 {
10082 name = tic6x_unwind_regnames[regpos[reg].reg];
10083 if (reg > 0)
10084 reg--;
10085 }
10086 else
10087 name = _("[pad]");
fa197c1c 10088
18344509
NC
10089 fputs (name, stdout);
10090 if (i > 1)
10091 printf (", ");
10092 }
fa197c1c
PB
10093 }
10094
10095 printf ("}");
10096 }
10097 else if (op == 0xd0)
10098 printf (" MOV FP, SP");
10099 else if (op == 0xd1)
10100 printf (" __c6xabi_pop_rts");
10101 else if (op == 0xd2)
10102 {
10103 unsigned char buf[9];
10104 unsigned int i, len;
10105 unsigned long offset;
a734115a 10106
fa197c1c
PB
10107 for (i = 0; i < sizeof (buf); i++)
10108 {
10109 GET_OP (buf[i]);
10110 if ((buf[i] & 0x80) == 0)
10111 break;
10112 }
0eff7165
NC
10113 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10114 if (i == sizeof (buf))
10115 {
0eff7165 10116 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10117 return false;
0eff7165 10118 }
948f632f 10119
015dc7e1 10120 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10121 assert (len == i + 1);
10122 offset = offset * 8 + 0x408;
10123 printf (_("sp = sp + %ld"), offset);
10124 }
10125 else if ((op & 0xf0) == 0xe0)
10126 {
10127 if ((op & 0x0f) == 7)
10128 printf (" RETURN");
10129 else
10130 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10131 }
10132 else
10133 {
10134 printf (_(" [unsupported opcode]"));
10135 }
10136 putchar ('\n');
10137 }
32ec8896 10138
015dc7e1 10139 return true;
fa197c1c
PB
10140}
10141
625d49fc
AM
10142static uint64_t
10143arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10144{
625d49fc 10145 uint64_t offset;
fa197c1c
PB
10146
10147 offset = word & 0x7fffffff;
10148 if (offset & 0x40000000)
625d49fc 10149 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10150
dda8d76d 10151 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10152 offset <<= 1;
10153
10154 return offset + where;
10155}
10156
015dc7e1 10157static bool
dda8d76d
NC
10158decode_arm_unwind (Filedata * filedata,
10159 struct arm_unw_aux_info * aux,
1b31d05e
NC
10160 unsigned int word,
10161 unsigned int remaining,
625d49fc 10162 uint64_t data_offset,
1b31d05e
NC
10163 Elf_Internal_Shdr * data_sec,
10164 struct arm_section * data_arm_sec)
fa197c1c
PB
10165{
10166 int per_index;
10167 unsigned int more_words = 0;
37e14bc3 10168 struct absaddr addr;
625d49fc 10169 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10170 bool res = true;
fa197c1c
PB
10171
10172 if (remaining == 0)
10173 {
1b31d05e
NC
10174 /* Fetch the first word.
10175 Note - when decoding an object file the address extracted
10176 here will always be 0. So we also pass in the sym_name
10177 parameter so that we can find the symbol associated with
10178 the personality routine. */
dda8d76d 10179 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10180 & word, & addr, & sym_name))
015dc7e1 10181 return false;
1b31d05e 10182
fa197c1c
PB
10183 remaining = 4;
10184 }
c93dbb25
CZ
10185 else
10186 {
10187 addr.section = SHN_UNDEF;
10188 addr.offset = 0;
10189 }
fa197c1c
PB
10190
10191 if ((word & 0x80000000) == 0)
10192 {
10193 /* Expand prel31 for personality routine. */
625d49fc 10194 uint64_t fn;
fa197c1c
PB
10195 const char *procname;
10196
dda8d76d 10197 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10198 printf (_(" Personality routine: "));
1b31d05e
NC
10199 if (fn == 0
10200 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10201 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10202 {
10203 procname = aux->strtab + sym_name;
10204 print_vma (fn, PREFIX_HEX);
10205 if (procname)
10206 {
10207 fputs (" <", stdout);
10208 fputs (procname, stdout);
10209 fputc ('>', stdout);
10210 }
10211 }
10212 else
dda8d76d 10213 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10214 fputc ('\n', stdout);
10215
10216 /* The GCC personality routines use the standard compact
10217 encoding, starting with one byte giving the number of
10218 words. */
10219 if (procname != NULL
24d127aa
ML
10220 && (startswith (procname, "__gcc_personality_v0")
10221 || startswith (procname, "__gxx_personality_v0")
10222 || startswith (procname, "__gcj_personality_v0")
10223 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10224 {
10225 remaining = 0;
10226 more_words = 1;
10227 ADVANCE;
10228 if (!remaining)
10229 {
10230 printf (_(" [Truncated data]\n"));
015dc7e1 10231 return false;
fa197c1c
PB
10232 }
10233 more_words = word >> 24;
10234 word <<= 8;
10235 remaining--;
10236 per_index = -1;
10237 }
10238 else
015dc7e1 10239 return true;
fa197c1c
PB
10240 }
10241 else
10242 {
1b31d05e 10243 /* ARM EHABI Section 6.3:
0b4362b0 10244
1b31d05e 10245 An exception-handling table entry for the compact model looks like:
0b4362b0 10246
1b31d05e
NC
10247 31 30-28 27-24 23-0
10248 -- ----- ----- ----
10249 1 0 index Data for personalityRoutine[index] */
10250
dda8d76d 10251 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10252 && (word & 0x70000000))
32ec8896
NC
10253 {
10254 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10255 res = false;
32ec8896 10256 }
1b31d05e 10257
fa197c1c 10258 per_index = (word >> 24) & 0x7f;
1b31d05e 10259 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10260 if (per_index == 0)
10261 {
10262 more_words = 0;
10263 word <<= 8;
10264 remaining--;
10265 }
10266 else if (per_index < 3)
10267 {
10268 more_words = (word >> 16) & 0xff;
10269 word <<= 16;
10270 remaining -= 2;
10271 }
10272 }
10273
dda8d76d 10274 switch (filedata->file_header.e_machine)
fa197c1c
PB
10275 {
10276 case EM_ARM:
10277 if (per_index < 3)
10278 {
dda8d76d 10279 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10280 data_offset, data_sec, data_arm_sec))
015dc7e1 10281 res = false;
fa197c1c
PB
10282 }
10283 else
1b31d05e
NC
10284 {
10285 warn (_("Unknown ARM compact model index encountered\n"));
10286 printf (_(" [reserved]\n"));
015dc7e1 10287 res = false;
1b31d05e 10288 }
fa197c1c
PB
10289 break;
10290
10291 case EM_TI_C6000:
10292 if (per_index < 3)
10293 {
dda8d76d 10294 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10295 data_offset, data_sec, data_arm_sec))
015dc7e1 10296 res = false;
fa197c1c
PB
10297 }
10298 else if (per_index < 5)
10299 {
10300 if (((word >> 17) & 0x7f) == 0x7f)
10301 printf (_(" Restore stack from frame pointer\n"));
10302 else
10303 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10304 printf (_(" Registers restored: "));
10305 if (per_index == 4)
10306 printf (" (compact) ");
10307 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10308 putchar ('\n');
10309 printf (_(" Return register: %s\n"),
10310 tic6x_unwind_regnames[word & 0xf]);
10311 }
10312 else
1b31d05e 10313 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10314 break;
10315
10316 default:
74e1a04b 10317 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10318 filedata->file_header.e_machine);
015dc7e1 10319 res = false;
fa197c1c 10320 }
0b6ae522
DJ
10321
10322 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10323
10324 return res;
0b6ae522
DJ
10325}
10326
015dc7e1 10327static bool
dda8d76d
NC
10328dump_arm_unwind (Filedata * filedata,
10329 struct arm_unw_aux_info * aux,
10330 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10331{
10332 struct arm_section exidx_arm_sec, extab_arm_sec;
10333 unsigned int i, exidx_len;
948f632f 10334 unsigned long j, nfuns;
015dc7e1 10335 bool res = true;
0b6ae522
DJ
10336
10337 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10338 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10339 exidx_len = exidx_sec->sh_size / 8;
10340
948f632f
DA
10341 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10342 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10343 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10344 aux->funtab[nfuns++] = aux->symtab[j];
10345 aux->nfuns = nfuns;
10346 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10347
0b6ae522
DJ
10348 for (i = 0; i < exidx_len; i++)
10349 {
10350 unsigned int exidx_fn, exidx_entry;
10351 struct absaddr fn_addr, entry_addr;
625d49fc 10352 uint64_t fn;
0b6ae522
DJ
10353
10354 fputc ('\n', stdout);
10355
dda8d76d 10356 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10357 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10358 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10359 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10360 {
948f632f 10361 free (aux->funtab);
1b31d05e
NC
10362 arm_free_section (& exidx_arm_sec);
10363 arm_free_section (& extab_arm_sec);
015dc7e1 10364 return false;
0b6ae522
DJ
10365 }
10366
83c257ca
NC
10367 /* ARM EHABI, Section 5:
10368 An index table entry consists of 2 words.
10369 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10370 if (exidx_fn & 0x80000000)
32ec8896
NC
10371 {
10372 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10373 res = false;
32ec8896 10374 }
83c257ca 10375
dda8d76d 10376 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10377
dda8d76d 10378 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10379 fputs (": ", stdout);
10380
10381 if (exidx_entry == 1)
10382 {
10383 print_vma (exidx_entry, PREFIX_HEX);
10384 fputs (" [cantunwind]\n", stdout);
10385 }
10386 else if (exidx_entry & 0x80000000)
10387 {
10388 print_vma (exidx_entry, PREFIX_HEX);
10389 fputc ('\n', stdout);
dda8d76d 10390 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10391 }
10392 else
10393 {
625d49fc 10394 uint64_t table, table_offset = 0;
0b6ae522
DJ
10395 Elf_Internal_Shdr *table_sec;
10396
10397 fputs ("@", stdout);
dda8d76d 10398 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10399 print_vma (table, PREFIX_HEX);
10400 printf ("\n");
10401
10402 /* Locate the matching .ARM.extab. */
10403 if (entry_addr.section != SHN_UNDEF
dda8d76d 10404 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10405 {
dda8d76d 10406 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10407 table_offset = entry_addr.offset;
1a915552 10408 /* PR 18879 */
625d49fc 10409 if (table_offset > table_sec->sh_size)
1a915552
NC
10410 {
10411 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
10412 (unsigned long) table_offset,
dda8d76d 10413 printable_section_name (filedata, table_sec));
015dc7e1 10414 res = false;
1a915552
NC
10415 continue;
10416 }
0b6ae522
DJ
10417 }
10418 else
10419 {
dda8d76d 10420 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10421 if (table_sec != NULL)
10422 table_offset = table - table_sec->sh_addr;
10423 }
32ec8896 10424
0b6ae522
DJ
10425 if (table_sec == NULL)
10426 {
10427 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
10428 (unsigned long) table);
015dc7e1 10429 res = false;
0b6ae522
DJ
10430 continue;
10431 }
32ec8896 10432
dda8d76d 10433 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10434 &extab_arm_sec))
015dc7e1 10435 res = false;
0b6ae522
DJ
10436 }
10437 }
10438
10439 printf ("\n");
10440
948f632f 10441 free (aux->funtab);
0b6ae522
DJ
10442 arm_free_section (&exidx_arm_sec);
10443 arm_free_section (&extab_arm_sec);
32ec8896
NC
10444
10445 return res;
0b6ae522
DJ
10446}
10447
fa197c1c 10448/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10449
015dc7e1 10450static bool
dda8d76d 10451arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10452{
10453 struct arm_unw_aux_info aux;
10454 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
10455 Elf_Internal_Shdr *sec;
10456 unsigned long i;
fa197c1c 10457 unsigned int sec_type;
015dc7e1 10458 bool res = true;
0b6ae522 10459
dda8d76d 10460 switch (filedata->file_header.e_machine)
fa197c1c
PB
10461 {
10462 case EM_ARM:
10463 sec_type = SHT_ARM_EXIDX;
10464 break;
10465
10466 case EM_TI_C6000:
10467 sec_type = SHT_C6000_UNWIND;
10468 break;
10469
0b4362b0 10470 default:
74e1a04b 10471 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10472 filedata->file_header.e_machine);
015dc7e1 10473 return false;
fa197c1c
PB
10474 }
10475
dda8d76d 10476 if (filedata->string_table == NULL)
015dc7e1 10477 return false;
1b31d05e
NC
10478
10479 memset (& aux, 0, sizeof (aux));
dda8d76d 10480 aux.filedata = filedata;
0b6ae522 10481
dda8d76d 10482 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10483 {
28d13567 10484 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10485 {
28d13567 10486 if (aux.symtab)
74e1a04b 10487 {
28d13567
AM
10488 error (_("Multiple symbol tables encountered\n"));
10489 free (aux.symtab);
10490 aux.symtab = NULL;
74e1a04b 10491 free (aux.strtab);
28d13567 10492 aux.strtab = NULL;
74e1a04b 10493 }
28d13567
AM
10494 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10495 &aux.strtab, &aux.strtab_size))
015dc7e1 10496 return false;
0b6ae522 10497 }
fa197c1c 10498 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10499 unwsec = sec;
10500 }
10501
1b31d05e 10502 if (unwsec == NULL)
0b6ae522 10503 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10504 else
dda8d76d 10505 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10506 {
10507 if (sec->sh_type == sec_type)
10508 {
d3a49aa8
AM
10509 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
10510 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
10511 "contains %lu entry:\n",
10512 "\nUnwind section '%s' at offset 0x%lx "
10513 "contains %lu entries:\n",
10514 num_unwind),
dda8d76d 10515 printable_section_name (filedata, sec),
1b31d05e 10516 (unsigned long) sec->sh_offset,
d3a49aa8 10517 num_unwind);
0b6ae522 10518
dda8d76d 10519 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10520 res = false;
1b31d05e
NC
10521 }
10522 }
0b6ae522 10523
9db70fc3
AM
10524 free (aux.symtab);
10525 free ((char *) aux.strtab);
32ec8896
NC
10526
10527 return res;
0b6ae522
DJ
10528}
10529
3ecc00ec
NC
10530static bool
10531no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10532{
10533 printf (_("No processor specific unwind information to decode\n"));
10534 return true;
10535}
10536
015dc7e1 10537static bool
dda8d76d 10538process_unwind (Filedata * filedata)
57346661 10539{
2cf0635d
NC
10540 struct unwind_handler
10541 {
32ec8896 10542 unsigned int machtype;
015dc7e1 10543 bool (* handler)(Filedata *);
2cf0635d
NC
10544 } handlers[] =
10545 {
0b6ae522 10546 { EM_ARM, arm_process_unwind },
57346661
AM
10547 { EM_IA_64, ia64_process_unwind },
10548 { EM_PARISC, hppa_process_unwind },
fa197c1c 10549 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10550 { EM_386, no_processor_specific_unwind },
10551 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10552 { 0, NULL }
57346661
AM
10553 };
10554 int i;
10555
10556 if (!do_unwind)
015dc7e1 10557 return true;
57346661
AM
10558
10559 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10560 if (filedata->file_header.e_machine == handlers[i].machtype)
10561 return handlers[i].handler (filedata);
57346661 10562
1b31d05e 10563 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10564 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10565 return true;
57346661
AM
10566}
10567
37c18eed
SD
10568static void
10569dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10570{
10571 switch (entry->d_tag)
10572 {
10573 case DT_AARCH64_BTI_PLT:
1dbade74 10574 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10575 break;
10576 default:
10577 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10578 break;
10579 }
10580 putchar ('\n');
10581}
10582
252b5132 10583static void
978c4450 10584dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10585{
10586 switch (entry->d_tag)
10587 {
10588 case DT_MIPS_FLAGS:
10589 if (entry->d_un.d_val == 0)
4b68bca3 10590 printf (_("NONE"));
252b5132
RH
10591 else
10592 {
10593 static const char * opts[] =
10594 {
10595 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10596 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10597 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10598 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10599 "RLD_ORDER_SAFE"
10600 };
10601 unsigned int cnt;
015dc7e1 10602 bool first = true;
2b692964 10603
60bca95a 10604 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10605 if (entry->d_un.d_val & (1 << cnt))
10606 {
10607 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10608 first = false;
252b5132 10609 }
252b5132
RH
10610 }
10611 break;
103f02d3 10612
252b5132 10613 case DT_MIPS_IVERSION:
84714f86 10614 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10615 printf (_("Interface Version: %s"),
84714f86 10616 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10617 else
f493c217 10618 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 10619 entry->d_un.d_ptr);
252b5132 10620 break;
103f02d3 10621
252b5132
RH
10622 case DT_MIPS_TIME_STAMP:
10623 {
d5b07ef4 10624 char timebuf[128];
2cf0635d 10625 struct tm * tmp;
91d6fa6a 10626 time_t atime = entry->d_un.d_val;
82b1b41b 10627
91d6fa6a 10628 tmp = gmtime (&atime);
82b1b41b
NC
10629 /* PR 17531: file: 6accc532. */
10630 if (tmp == NULL)
10631 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10632 else
10633 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10634 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10635 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10636 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10637 }
10638 break;
103f02d3 10639
252b5132
RH
10640 case DT_MIPS_RLD_VERSION:
10641 case DT_MIPS_LOCAL_GOTNO:
10642 case DT_MIPS_CONFLICTNO:
10643 case DT_MIPS_LIBLISTNO:
10644 case DT_MIPS_SYMTABNO:
10645 case DT_MIPS_UNREFEXTNO:
10646 case DT_MIPS_HIPAGENO:
10647 case DT_MIPS_DELTA_CLASS_NO:
10648 case DT_MIPS_DELTA_INSTANCE_NO:
10649 case DT_MIPS_DELTA_RELOC_NO:
10650 case DT_MIPS_DELTA_SYM_NO:
10651 case DT_MIPS_DELTA_CLASSSYM_NO:
10652 case DT_MIPS_COMPACT_SIZE:
c69075ac 10653 print_vma (entry->d_un.d_val, DEC);
252b5132 10654 break;
103f02d3 10655
f16a9783 10656 case DT_MIPS_XHASH:
978c4450
AM
10657 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10658 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10659 /* Falls through. */
10660
103f02d3 10661 default:
4b68bca3 10662 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10663 }
4b68bca3 10664 putchar ('\n');
103f02d3
UD
10665}
10666
103f02d3 10667static void
2cf0635d 10668dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10669{
10670 switch (entry->d_tag)
10671 {
10672 case DT_HP_DLD_FLAGS:
10673 {
10674 static struct
10675 {
10676 long int bit;
2cf0635d 10677 const char * str;
5e220199
NC
10678 }
10679 flags[] =
10680 {
10681 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10682 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10683 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10684 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10685 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10686 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10687 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10688 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10689 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10690 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10691 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10692 { DT_HP_GST, "HP_GST" },
10693 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10694 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10695 { DT_HP_NODELETE, "HP_NODELETE" },
10696 { DT_HP_GROUP, "HP_GROUP" },
10697 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10698 };
015dc7e1 10699 bool first = true;
5e220199 10700 size_t cnt;
625d49fc 10701 uint64_t val = entry->d_un.d_val;
103f02d3 10702
60bca95a 10703 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10704 if (val & flags[cnt].bit)
30800947
NC
10705 {
10706 if (! first)
10707 putchar (' ');
10708 fputs (flags[cnt].str, stdout);
015dc7e1 10709 first = false;
30800947
NC
10710 val ^= flags[cnt].bit;
10711 }
76da6bbe 10712
103f02d3 10713 if (val != 0 || first)
f7a99963
NC
10714 {
10715 if (! first)
10716 putchar (' ');
10717 print_vma (val, HEX);
10718 }
103f02d3
UD
10719 }
10720 break;
76da6bbe 10721
252b5132 10722 default:
f7a99963
NC
10723 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10724 break;
252b5132 10725 }
35b1837e 10726 putchar ('\n');
252b5132
RH
10727}
10728
28f997cf
TG
10729/* VMS vs Unix time offset and factor. */
10730
10731#define VMS_EPOCH_OFFSET 35067168000000000LL
10732#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10733#ifndef INT64_MIN
10734#define INT64_MIN (-9223372036854775807LL - 1)
10735#endif
28f997cf
TG
10736
10737/* Display a VMS time in a human readable format. */
10738
10739static void
0e3c1eeb 10740print_vms_time (int64_t vmstime)
28f997cf 10741{
dccc31de 10742 struct tm *tm = NULL;
28f997cf
TG
10743 time_t unxtime;
10744
dccc31de
AM
10745 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10746 {
10747 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10748 unxtime = vmstime;
10749 if (unxtime == vmstime)
10750 tm = gmtime (&unxtime);
10751 }
10752 if (tm != NULL)
10753 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10754 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10755 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 10756}
28f997cf 10757
ecc51f48 10758static void
2cf0635d 10759dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10760{
10761 switch (entry->d_tag)
10762 {
0de14b54 10763 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10764 /* First 3 slots reserved. */
ecc51f48
NC
10765 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10766 printf (" -- ");
10767 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10768 break;
10769
28f997cf 10770 case DT_IA_64_VMS_LINKTIME:
28f997cf 10771 print_vms_time (entry->d_un.d_val);
28f997cf
TG
10772 break;
10773
10774 case DT_IA_64_VMS_LNKFLAGS:
10775 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10776 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10777 printf (" CALL_DEBUG");
10778 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10779 printf (" NOP0BUFS");
10780 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10781 printf (" P0IMAGE");
10782 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10783 printf (" MKTHREADS");
10784 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10785 printf (" UPCALLS");
10786 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10787 printf (" IMGSTA");
10788 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10789 printf (" INITIALIZE");
10790 if (entry->d_un.d_val & VMS_LF_MAIN)
10791 printf (" MAIN");
10792 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10793 printf (" EXE_INIT");
10794 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10795 printf (" TBK_IN_IMG");
10796 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10797 printf (" DBG_IN_IMG");
10798 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10799 printf (" TBK_IN_DSF");
10800 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10801 printf (" DBG_IN_DSF");
10802 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10803 printf (" SIGNATURES");
10804 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10805 printf (" REL_SEG_OFF");
10806 break;
10807
bdf4d63a
JJ
10808 default:
10809 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10810 break;
ecc51f48 10811 }
bdf4d63a 10812 putchar ('\n');
ecc51f48
NC
10813}
10814
015dc7e1 10815static bool
dda8d76d 10816get_32bit_dynamic_section (Filedata * filedata)
252b5132 10817{
2cf0635d
NC
10818 Elf32_External_Dyn * edyn;
10819 Elf32_External_Dyn * ext;
10820 Elf_Internal_Dyn * entry;
103f02d3 10821
978c4450
AM
10822 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10823 filedata->dynamic_addr, 1,
10824 filedata->dynamic_size,
10825 _("dynamic section"));
a6e9f9df 10826 if (!edyn)
015dc7e1 10827 return false;
103f02d3 10828
071436c6
NC
10829 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10830 might not have the luxury of section headers. Look for the DT_NULL
10831 terminator to determine the number of entries. */
978c4450
AM
10832 for (ext = edyn, filedata->dynamic_nent = 0;
10833 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10834 ext++)
10835 {
978c4450 10836 filedata->dynamic_nent++;
ba2685cc
AM
10837 if (BYTE_GET (ext->d_tag) == DT_NULL)
10838 break;
10839 }
252b5132 10840
978c4450
AM
10841 filedata->dynamic_section
10842 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10843 if (filedata->dynamic_section == NULL)
252b5132 10844 {
8b73c356 10845 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10846 (unsigned long) filedata->dynamic_nent);
9ea033b2 10847 free (edyn);
015dc7e1 10848 return false;
9ea033b2 10849 }
252b5132 10850
978c4450
AM
10851 for (ext = edyn, entry = filedata->dynamic_section;
10852 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10853 ext++, entry++)
9ea033b2 10854 {
fb514b26
AM
10855 entry->d_tag = BYTE_GET (ext->d_tag);
10856 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10857 }
10858
9ea033b2
NC
10859 free (edyn);
10860
015dc7e1 10861 return true;
9ea033b2
NC
10862}
10863
015dc7e1 10864static bool
dda8d76d 10865get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10866{
2cf0635d
NC
10867 Elf64_External_Dyn * edyn;
10868 Elf64_External_Dyn * ext;
10869 Elf_Internal_Dyn * entry;
103f02d3 10870
071436c6 10871 /* Read in the data. */
978c4450
AM
10872 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10873 filedata->dynamic_addr, 1,
10874 filedata->dynamic_size,
10875 _("dynamic section"));
a6e9f9df 10876 if (!edyn)
015dc7e1 10877 return false;
103f02d3 10878
071436c6
NC
10879 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10880 might not have the luxury of section headers. Look for the DT_NULL
10881 terminator to determine the number of entries. */
978c4450 10882 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10883 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10884 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10885 ext++)
10886 {
978c4450 10887 filedata->dynamic_nent++;
66543521 10888 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10889 break;
10890 }
252b5132 10891
978c4450
AM
10892 filedata->dynamic_section
10893 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10894 if (filedata->dynamic_section == NULL)
252b5132 10895 {
8b73c356 10896 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10897 (unsigned long) filedata->dynamic_nent);
252b5132 10898 free (edyn);
015dc7e1 10899 return false;
252b5132
RH
10900 }
10901
071436c6 10902 /* Convert from external to internal formats. */
978c4450
AM
10903 for (ext = edyn, entry = filedata->dynamic_section;
10904 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10905 ext++, entry++)
252b5132 10906 {
66543521
AM
10907 entry->d_tag = BYTE_GET (ext->d_tag);
10908 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10909 }
10910
10911 free (edyn);
10912
015dc7e1 10913 return true;
9ea033b2
NC
10914}
10915
4de91c10
AM
10916static bool
10917get_dynamic_section (Filedata *filedata)
10918{
10919 if (filedata->dynamic_section)
10920 return true;
10921
10922 if (is_32bit_elf)
10923 return get_32bit_dynamic_section (filedata);
10924 else
10925 return get_64bit_dynamic_section (filedata);
10926}
10927
e9e44622 10928static void
625d49fc 10929print_dynamic_flags (uint64_t flags)
d1133906 10930{
015dc7e1 10931 bool first = true;
13ae64f3 10932
d1133906
NC
10933 while (flags)
10934 {
625d49fc 10935 uint64_t flag;
d1133906
NC
10936
10937 flag = flags & - flags;
10938 flags &= ~ flag;
10939
e9e44622 10940 if (first)
015dc7e1 10941 first = false;
e9e44622
JJ
10942 else
10943 putc (' ', stdout);
13ae64f3 10944
d1133906
NC
10945 switch (flag)
10946 {
e9e44622
JJ
10947 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10948 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10949 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10950 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10951 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10952 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10953 }
10954 }
e9e44622 10955 puts ("");
d1133906
NC
10956}
10957
625d49fc 10958static uint64_t *
be7d229a 10959get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
10960{
10961 unsigned char * e_data;
625d49fc 10962 uint64_t * i_data;
10ca4b04 10963
be7d229a
AM
10964 /* If size_t is smaller than uint64_t, eg because you are building
10965 on a 32-bit host, then make sure that when number is cast to
10966 size_t no information is lost. */
10967 if ((size_t) number != number
10968 || ent_size * number / ent_size != number)
10ca4b04 10969 {
be7d229a 10970 error (_("Size overflow prevents reading %" PRIu64
b8281767 10971 " elements of size %u\n"),
be7d229a 10972 number, ent_size);
10ca4b04
L
10973 return NULL;
10974 }
10975
10976 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10977 attempting to allocate memory when the read is bound to fail. */
10978 if (ent_size * number > filedata->file_size)
10979 {
b8281767 10980 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 10981 number);
10ca4b04
L
10982 return NULL;
10983 }
10984
10985 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10986 if (e_data == NULL)
10987 {
b8281767 10988 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 10989 number);
10ca4b04
L
10990 return NULL;
10991 }
10992
10993 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10994 {
b8281767 10995 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 10996 number * ent_size);
10ca4b04
L
10997 free (e_data);
10998 return NULL;
10999 }
11000
625d49fc 11001 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
11002 if (i_data == NULL)
11003 {
b8281767 11004 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 11005 number);
10ca4b04
L
11006 free (e_data);
11007 return NULL;
11008 }
11009
11010 while (number--)
11011 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11012
11013 free (e_data);
11014
11015 return i_data;
11016}
11017
11018static unsigned long
11019get_num_dynamic_syms (Filedata * filedata)
11020{
11021 unsigned long num_of_syms = 0;
11022
11023 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11024 return num_of_syms;
11025
978c4450 11026 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11027 {
11028 unsigned char nb[8];
11029 unsigned char nc[8];
11030 unsigned int hash_ent_size = 4;
11031
11032 if ((filedata->file_header.e_machine == EM_ALPHA
11033 || filedata->file_header.e_machine == EM_S390
11034 || filedata->file_header.e_machine == EM_S390_OLD)
11035 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11036 hash_ent_size = 8;
11037
11038 if (fseek (filedata->handle,
978c4450
AM
11039 (filedata->archive_file_offset
11040 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
11041 sizeof nb + sizeof nc)),
11042 SEEK_SET))
11043 {
11044 error (_("Unable to seek to start of dynamic information\n"));
11045 goto no_hash;
11046 }
11047
11048 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11049 {
11050 error (_("Failed to read in number of buckets\n"));
11051 goto no_hash;
11052 }
11053
11054 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11055 {
11056 error (_("Failed to read in number of chains\n"));
11057 goto no_hash;
11058 }
11059
978c4450
AM
11060 filedata->nbuckets = byte_get (nb, hash_ent_size);
11061 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11062
2482f306
AM
11063 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11064 {
11065 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11066 hash_ent_size);
11067 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11068 hash_ent_size);
001890e1 11069
2482f306
AM
11070 if (filedata->buckets != NULL && filedata->chains != NULL)
11071 num_of_syms = filedata->nchains;
11072 }
ceb9bf11 11073 no_hash:
10ca4b04
L
11074 if (num_of_syms == 0)
11075 {
9db70fc3
AM
11076 free (filedata->buckets);
11077 filedata->buckets = NULL;
11078 free (filedata->chains);
11079 filedata->chains = NULL;
978c4450 11080 filedata->nbuckets = 0;
10ca4b04
L
11081 }
11082 }
11083
978c4450 11084 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11085 {
11086 unsigned char nb[16];
625d49fc
AM
11087 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11088 uint64_t buckets_vma;
10ca4b04 11089 unsigned long hn;
10ca4b04
L
11090
11091 if (fseek (filedata->handle,
978c4450
AM
11092 (filedata->archive_file_offset
11093 + offset_from_vma (filedata,
11094 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
11095 sizeof nb)),
11096 SEEK_SET))
11097 {
11098 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11099 goto no_gnu_hash;
11100 }
11101
11102 if (fread (nb, 16, 1, filedata->handle) != 1)
11103 {
11104 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11105 goto no_gnu_hash;
11106 }
11107
978c4450
AM
11108 filedata->ngnubuckets = byte_get (nb, 4);
11109 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11110 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11111 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11112 if (is_32bit_elf)
11113 buckets_vma += bitmaskwords * 4;
11114 else
11115 buckets_vma += bitmaskwords * 8;
11116
11117 if (fseek (filedata->handle,
978c4450 11118 (filedata->archive_file_offset
10ca4b04
L
11119 + offset_from_vma (filedata, buckets_vma, 4)),
11120 SEEK_SET))
11121 {
11122 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11123 goto no_gnu_hash;
11124 }
11125
978c4450
AM
11126 filedata->gnubuckets
11127 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11128
978c4450 11129 if (filedata->gnubuckets == NULL)
90837ea7 11130 goto no_gnu_hash;
10ca4b04 11131
978c4450
AM
11132 for (i = 0; i < filedata->ngnubuckets; i++)
11133 if (filedata->gnubuckets[i] != 0)
10ca4b04 11134 {
978c4450 11135 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11136 goto no_gnu_hash;
10ca4b04 11137
978c4450
AM
11138 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11139 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11140 }
11141
11142 if (maxchain == 0xffffffff)
90837ea7 11143 goto no_gnu_hash;
10ca4b04 11144
978c4450 11145 maxchain -= filedata->gnusymidx;
10ca4b04
L
11146
11147 if (fseek (filedata->handle,
978c4450
AM
11148 (filedata->archive_file_offset
11149 + offset_from_vma (filedata,
11150 buckets_vma + 4 * (filedata->ngnubuckets
11151 + maxchain),
11152 4)),
10ca4b04
L
11153 SEEK_SET))
11154 {
11155 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11156 goto no_gnu_hash;
11157 }
11158
11159 do
11160 {
11161 if (fread (nb, 4, 1, filedata->handle) != 1)
11162 {
11163 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11164 goto no_gnu_hash;
11165 }
11166
11167 if (maxchain + 1 == 0)
90837ea7 11168 goto no_gnu_hash;
10ca4b04
L
11169
11170 ++maxchain;
11171 }
11172 while ((byte_get (nb, 4) & 1) == 0);
11173
11174 if (fseek (filedata->handle,
978c4450
AM
11175 (filedata->archive_file_offset
11176 + offset_from_vma (filedata, (buckets_vma
11177 + 4 * filedata->ngnubuckets),
11178 4)),
10ca4b04
L
11179 SEEK_SET))
11180 {
11181 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11182 goto no_gnu_hash;
11183 }
11184
978c4450
AM
11185 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11186 filedata->ngnuchains = maxchain;
10ca4b04 11187
978c4450 11188 if (filedata->gnuchains == NULL)
90837ea7 11189 goto no_gnu_hash;
10ca4b04 11190
978c4450 11191 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
11192 {
11193 if (fseek (filedata->handle,
978c4450 11194 (filedata->archive_file_offset
10ca4b04 11195 + offset_from_vma (filedata, (buckets_vma
978c4450 11196 + 4 * (filedata->ngnubuckets
10ca4b04
L
11197 + maxchain)), 4)),
11198 SEEK_SET))
11199 {
11200 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11201 goto no_gnu_hash;
11202 }
11203
978c4450 11204 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11205 if (filedata->mipsxlat == NULL)
11206 goto no_gnu_hash;
10ca4b04
L
11207 }
11208
978c4450
AM
11209 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11210 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11211 {
625d49fc
AM
11212 uint64_t si = filedata->gnubuckets[hn];
11213 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11214
11215 do
11216 {
978c4450 11217 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11218 {
c31ab5a0
AM
11219 if (off < filedata->ngnuchains
11220 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11221 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11222 }
11223 else
11224 {
11225 if (si >= num_of_syms)
11226 num_of_syms = si + 1;
11227 }
11228 si++;
11229 }
978c4450
AM
11230 while (off < filedata->ngnuchains
11231 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11232 }
11233
90837ea7 11234 if (num_of_syms == 0)
10ca4b04 11235 {
90837ea7 11236 no_gnu_hash:
9db70fc3
AM
11237 free (filedata->mipsxlat);
11238 filedata->mipsxlat = NULL;
11239 free (filedata->gnuchains);
11240 filedata->gnuchains = NULL;
11241 free (filedata->gnubuckets);
11242 filedata->gnubuckets = NULL;
978c4450
AM
11243 filedata->ngnubuckets = 0;
11244 filedata->ngnuchains = 0;
10ca4b04
L
11245 }
11246 }
11247
11248 return num_of_syms;
11249}
11250
b2d38a17
NC
11251/* Parse and display the contents of the dynamic section. */
11252
015dc7e1 11253static bool
dda8d76d 11254process_dynamic_section (Filedata * filedata)
9ea033b2 11255{
2cf0635d 11256 Elf_Internal_Dyn * entry;
9ea033b2 11257
93df3340 11258 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11259 {
11260 if (do_dynamic)
ca0e11aa
NC
11261 {
11262 if (filedata->is_separate)
11263 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11264 filedata->file_name);
11265 else
11266 printf (_("\nThere is no dynamic section in this file.\n"));
11267 }
9ea033b2 11268
015dc7e1 11269 return true;
9ea033b2
NC
11270 }
11271
4de91c10
AM
11272 if (!get_dynamic_section (filedata))
11273 return false;
9ea033b2 11274
252b5132 11275 /* Find the appropriate symbol table. */
978c4450 11276 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11277 {
2482f306
AM
11278 unsigned long num_of_syms;
11279
978c4450
AM
11280 for (entry = filedata->dynamic_section;
11281 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11282 ++entry)
10ca4b04 11283 if (entry->d_tag == DT_SYMTAB)
978c4450 11284 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11285 else if (entry->d_tag == DT_SYMENT)
978c4450 11286 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11287 else if (entry->d_tag == DT_HASH)
978c4450 11288 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11289 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11290 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11291 else if ((filedata->file_header.e_machine == EM_MIPS
11292 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11293 && entry->d_tag == DT_MIPS_XHASH)
11294 {
978c4450
AM
11295 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11296 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11297 }
252b5132 11298
2482f306
AM
11299 num_of_syms = get_num_dynamic_syms (filedata);
11300
11301 if (num_of_syms != 0
11302 && filedata->dynamic_symbols == NULL
11303 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11304 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11305 {
11306 Elf_Internal_Phdr *seg;
625d49fc 11307 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11308
2482f306
AM
11309 if (! get_program_headers (filedata))
11310 {
11311 error (_("Cannot interpret virtual addresses "
11312 "without program headers.\n"));
015dc7e1 11313 return false;
2482f306 11314 }
252b5132 11315
2482f306
AM
11316 for (seg = filedata->program_headers;
11317 seg < filedata->program_headers + filedata->file_header.e_phnum;
11318 ++seg)
11319 {
11320 if (seg->p_type != PT_LOAD)
11321 continue;
252b5132 11322
2482f306
AM
11323 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11324 {
11325 /* See PR 21379 for a reproducer. */
11326 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11327 return false;
2482f306 11328 }
252b5132 11329
2482f306
AM
11330 if (vma >= (seg->p_vaddr & -seg->p_align)
11331 && vma < seg->p_vaddr + seg->p_filesz)
11332 {
11333 /* Since we do not know how big the symbol table is,
11334 we default to reading in up to the end of PT_LOAD
11335 segment and processing that. This is overkill, I
11336 know, but it should work. */
11337 Elf_Internal_Shdr section;
11338 section.sh_offset = (vma - seg->p_vaddr
11339 + seg->p_offset);
11340 section.sh_size = (num_of_syms
11341 * filedata->dynamic_info[DT_SYMENT]);
11342 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11343
11344 if (do_checks
11345 && filedata->dynamic_symtab_section != NULL
11346 && ((filedata->dynamic_symtab_section->sh_offset
11347 != section.sh_offset)
11348 || (filedata->dynamic_symtab_section->sh_size
11349 != section.sh_size)
11350 || (filedata->dynamic_symtab_section->sh_entsize
11351 != section.sh_entsize)))
11352 warn (_("\
11353the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11354
2482f306
AM
11355 section.sh_name = filedata->string_table_length;
11356 filedata->dynamic_symbols
4de91c10 11357 = get_elf_symbols (filedata, &section,
2482f306
AM
11358 &filedata->num_dynamic_syms);
11359 if (filedata->dynamic_symbols == NULL
11360 || filedata->num_dynamic_syms != num_of_syms)
11361 {
11362 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11363 return false;
2482f306
AM
11364 }
11365 break;
11366 }
11367 }
11368 }
11369 }
252b5132
RH
11370
11371 /* Similarly find a string table. */
978c4450
AM
11372 if (filedata->dynamic_strings == NULL)
11373 for (entry = filedata->dynamic_section;
11374 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11375 ++entry)
11376 {
11377 if (entry->d_tag == DT_STRTAB)
978c4450 11378 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11379
10ca4b04 11380 if (entry->d_tag == DT_STRSZ)
978c4450 11381 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11382
978c4450
AM
11383 if (filedata->dynamic_info[DT_STRTAB]
11384 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
11385 {
11386 unsigned long offset;
be7d229a 11387 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11388
11389 offset = offset_from_vma (filedata,
978c4450 11390 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11391 str_tab_len);
8ac10c5b
L
11392 if (do_checks
11393 && filedata->dynamic_strtab_section
11394 && ((filedata->dynamic_strtab_section->sh_offset
11395 != (file_ptr) offset)
11396 || (filedata->dynamic_strtab_section->sh_size
11397 != str_tab_len)))
11398 warn (_("\
11399the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11400
978c4450
AM
11401 filedata->dynamic_strings
11402 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11403 _("dynamic string table"));
11404 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11405 {
11406 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11407 break;
11408 }
e3d39609 11409
978c4450 11410 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11411 break;
11412 }
11413 }
252b5132
RH
11414
11415 /* And find the syminfo section if available. */
978c4450 11416 if (filedata->dynamic_syminfo == NULL)
252b5132 11417 {
3e8bba36 11418 unsigned long syminsz = 0;
252b5132 11419
978c4450
AM
11420 for (entry = filedata->dynamic_section;
11421 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11422 ++entry)
252b5132
RH
11423 {
11424 if (entry->d_tag == DT_SYMINENT)
11425 {
11426 /* Note: these braces are necessary to avoid a syntax
11427 error from the SunOS4 C compiler. */
049b0c3a
NC
11428 /* PR binutils/17531: A corrupt file can trigger this test.
11429 So do not use an assert, instead generate an error message. */
11430 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11431 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11432 (int) entry->d_un.d_val);
252b5132
RH
11433 }
11434 else if (entry->d_tag == DT_SYMINSZ)
11435 syminsz = entry->d_un.d_val;
11436 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11437 filedata->dynamic_syminfo_offset
11438 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11439 }
11440
978c4450 11441 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11442 {
2cf0635d
NC
11443 Elf_External_Syminfo * extsyminfo;
11444 Elf_External_Syminfo * extsym;
11445 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11446
11447 /* There is a syminfo section. Read the data. */
3f5e193b 11448 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11449 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11450 1, syminsz, _("symbol information"));
a6e9f9df 11451 if (!extsyminfo)
015dc7e1 11452 return false;
252b5132 11453
978c4450 11454 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11455 {
11456 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11457 free (filedata->dynamic_syminfo);
e3d39609 11458 }
978c4450
AM
11459 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11460 if (filedata->dynamic_syminfo == NULL)
252b5132 11461 {
2482f306
AM
11462 error (_("Out of memory allocating %lu bytes "
11463 "for dynamic symbol info\n"),
8b73c356 11464 (unsigned long) syminsz);
015dc7e1 11465 return false;
252b5132
RH
11466 }
11467
2482f306
AM
11468 filedata->dynamic_syminfo_nent
11469 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11470 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11471 syminfo < (filedata->dynamic_syminfo
11472 + filedata->dynamic_syminfo_nent);
86dba8ee 11473 ++syminfo, ++extsym)
252b5132 11474 {
86dba8ee
AM
11475 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11476 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11477 }
11478
11479 free (extsyminfo);
11480 }
11481 }
11482
978c4450 11483 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11484 {
f253158f
NC
11485 if (filedata->is_separate)
11486 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
11487 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
11488 (unsigned long) filedata->dynamic_nent),
11489 filedata->file_name,
11490 filedata->dynamic_addr,
11491 (unsigned long) filedata->dynamic_nent);
84a9f195
SM
11492 else
11493 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
11494 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
11495 (unsigned long) filedata->dynamic_nent),
11496 filedata->dynamic_addr,
11497 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11498 }
252b5132
RH
11499 if (do_dynamic)
11500 printf (_(" Tag Type Name/Value\n"));
11501
978c4450
AM
11502 for (entry = filedata->dynamic_section;
11503 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11504 entry++)
252b5132
RH
11505 {
11506 if (do_dynamic)
f7a99963 11507 {
2cf0635d 11508 const char * dtype;
e699b9ff 11509
f7a99963
NC
11510 putchar (' ');
11511 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11512 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11513 printf (" (%s)%*s", dtype,
32ec8896 11514 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11515 }
252b5132
RH
11516
11517 switch (entry->d_tag)
11518 {
d1133906
NC
11519 case DT_FLAGS:
11520 if (do_dynamic)
e9e44622 11521 print_dynamic_flags (entry->d_un.d_val);
d1133906 11522 break;
76da6bbe 11523
252b5132
RH
11524 case DT_AUXILIARY:
11525 case DT_FILTER:
019148e4
L
11526 case DT_CONFIG:
11527 case DT_DEPAUDIT:
11528 case DT_AUDIT:
252b5132
RH
11529 if (do_dynamic)
11530 {
019148e4 11531 switch (entry->d_tag)
b34976b6 11532 {
019148e4
L
11533 case DT_AUXILIARY:
11534 printf (_("Auxiliary library"));
11535 break;
11536
11537 case DT_FILTER:
11538 printf (_("Filter library"));
11539 break;
11540
b34976b6 11541 case DT_CONFIG:
019148e4
L
11542 printf (_("Configuration file"));
11543 break;
11544
11545 case DT_DEPAUDIT:
11546 printf (_("Dependency audit library"));
11547 break;
11548
11549 case DT_AUDIT:
11550 printf (_("Audit library"));
11551 break;
11552 }
252b5132 11553
84714f86 11554 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11555 printf (": [%s]\n",
84714f86 11556 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11557 else
f7a99963
NC
11558 {
11559 printf (": ");
11560 print_vma (entry->d_un.d_val, PREFIX_HEX);
11561 putchar ('\n');
11562 }
252b5132
RH
11563 }
11564 break;
11565
dcefbbbd 11566 case DT_FEATURE:
252b5132
RH
11567 if (do_dynamic)
11568 {
11569 printf (_("Flags:"));
86f55779 11570
252b5132
RH
11571 if (entry->d_un.d_val == 0)
11572 printf (_(" None\n"));
11573 else
11574 {
11575 unsigned long int val = entry->d_un.d_val;
86f55779 11576
252b5132
RH
11577 if (val & DTF_1_PARINIT)
11578 {
11579 printf (" PARINIT");
11580 val ^= DTF_1_PARINIT;
11581 }
dcefbbbd
L
11582 if (val & DTF_1_CONFEXP)
11583 {
11584 printf (" CONFEXP");
11585 val ^= DTF_1_CONFEXP;
11586 }
252b5132
RH
11587 if (val != 0)
11588 printf (" %lx", val);
11589 puts ("");
11590 }
11591 }
11592 break;
11593
11594 case DT_POSFLAG_1:
11595 if (do_dynamic)
11596 {
11597 printf (_("Flags:"));
86f55779 11598
252b5132
RH
11599 if (entry->d_un.d_val == 0)
11600 printf (_(" None\n"));
11601 else
11602 {
11603 unsigned long int val = entry->d_un.d_val;
86f55779 11604
252b5132
RH
11605 if (val & DF_P1_LAZYLOAD)
11606 {
11607 printf (" LAZYLOAD");
11608 val ^= DF_P1_LAZYLOAD;
11609 }
11610 if (val & DF_P1_GROUPPERM)
11611 {
11612 printf (" GROUPPERM");
11613 val ^= DF_P1_GROUPPERM;
11614 }
11615 if (val != 0)
11616 printf (" %lx", val);
11617 puts ("");
11618 }
11619 }
11620 break;
11621
11622 case DT_FLAGS_1:
11623 if (do_dynamic)
11624 {
11625 printf (_("Flags:"));
11626 if (entry->d_un.d_val == 0)
11627 printf (_(" None\n"));
11628 else
11629 {
11630 unsigned long int val = entry->d_un.d_val;
86f55779 11631
252b5132
RH
11632 if (val & DF_1_NOW)
11633 {
11634 printf (" NOW");
11635 val ^= DF_1_NOW;
11636 }
11637 if (val & DF_1_GLOBAL)
11638 {
11639 printf (" GLOBAL");
11640 val ^= DF_1_GLOBAL;
11641 }
11642 if (val & DF_1_GROUP)
11643 {
11644 printf (" GROUP");
11645 val ^= DF_1_GROUP;
11646 }
11647 if (val & DF_1_NODELETE)
11648 {
11649 printf (" NODELETE");
11650 val ^= DF_1_NODELETE;
11651 }
11652 if (val & DF_1_LOADFLTR)
11653 {
11654 printf (" LOADFLTR");
11655 val ^= DF_1_LOADFLTR;
11656 }
11657 if (val & DF_1_INITFIRST)
11658 {
11659 printf (" INITFIRST");
11660 val ^= DF_1_INITFIRST;
11661 }
11662 if (val & DF_1_NOOPEN)
11663 {
11664 printf (" NOOPEN");
11665 val ^= DF_1_NOOPEN;
11666 }
11667 if (val & DF_1_ORIGIN)
11668 {
11669 printf (" ORIGIN");
11670 val ^= DF_1_ORIGIN;
11671 }
11672 if (val & DF_1_DIRECT)
11673 {
11674 printf (" DIRECT");
11675 val ^= DF_1_DIRECT;
11676 }
11677 if (val & DF_1_TRANS)
11678 {
11679 printf (" TRANS");
11680 val ^= DF_1_TRANS;
11681 }
11682 if (val & DF_1_INTERPOSE)
11683 {
11684 printf (" INTERPOSE");
11685 val ^= DF_1_INTERPOSE;
11686 }
f7db6139 11687 if (val & DF_1_NODEFLIB)
dcefbbbd 11688 {
f7db6139
L
11689 printf (" NODEFLIB");
11690 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11691 }
11692 if (val & DF_1_NODUMP)
11693 {
11694 printf (" NODUMP");
11695 val ^= DF_1_NODUMP;
11696 }
34b60028 11697 if (val & DF_1_CONFALT)
dcefbbbd 11698 {
34b60028
L
11699 printf (" CONFALT");
11700 val ^= DF_1_CONFALT;
11701 }
11702 if (val & DF_1_ENDFILTEE)
11703 {
11704 printf (" ENDFILTEE");
11705 val ^= DF_1_ENDFILTEE;
11706 }
11707 if (val & DF_1_DISPRELDNE)
11708 {
11709 printf (" DISPRELDNE");
11710 val ^= DF_1_DISPRELDNE;
11711 }
11712 if (val & DF_1_DISPRELPND)
11713 {
11714 printf (" DISPRELPND");
11715 val ^= DF_1_DISPRELPND;
11716 }
11717 if (val & DF_1_NODIRECT)
11718 {
11719 printf (" NODIRECT");
11720 val ^= DF_1_NODIRECT;
11721 }
11722 if (val & DF_1_IGNMULDEF)
11723 {
11724 printf (" IGNMULDEF");
11725 val ^= DF_1_IGNMULDEF;
11726 }
11727 if (val & DF_1_NOKSYMS)
11728 {
11729 printf (" NOKSYMS");
11730 val ^= DF_1_NOKSYMS;
11731 }
11732 if (val & DF_1_NOHDR)
11733 {
11734 printf (" NOHDR");
11735 val ^= DF_1_NOHDR;
11736 }
11737 if (val & DF_1_EDITED)
11738 {
11739 printf (" EDITED");
11740 val ^= DF_1_EDITED;
11741 }
11742 if (val & DF_1_NORELOC)
11743 {
11744 printf (" NORELOC");
11745 val ^= DF_1_NORELOC;
11746 }
11747 if (val & DF_1_SYMINTPOSE)
11748 {
11749 printf (" SYMINTPOSE");
11750 val ^= DF_1_SYMINTPOSE;
11751 }
11752 if (val & DF_1_GLOBAUDIT)
11753 {
11754 printf (" GLOBAUDIT");
11755 val ^= DF_1_GLOBAUDIT;
11756 }
11757 if (val & DF_1_SINGLETON)
11758 {
11759 printf (" SINGLETON");
11760 val ^= DF_1_SINGLETON;
dcefbbbd 11761 }
5c383f02
RO
11762 if (val & DF_1_STUB)
11763 {
11764 printf (" STUB");
11765 val ^= DF_1_STUB;
11766 }
11767 if (val & DF_1_PIE)
11768 {
11769 printf (" PIE");
11770 val ^= DF_1_PIE;
11771 }
b1202ffa
L
11772 if (val & DF_1_KMOD)
11773 {
11774 printf (" KMOD");
11775 val ^= DF_1_KMOD;
11776 }
11777 if (val & DF_1_WEAKFILTER)
11778 {
11779 printf (" WEAKFILTER");
11780 val ^= DF_1_WEAKFILTER;
11781 }
11782 if (val & DF_1_NOCOMMON)
11783 {
11784 printf (" NOCOMMON");
11785 val ^= DF_1_NOCOMMON;
11786 }
252b5132
RH
11787 if (val != 0)
11788 printf (" %lx", val);
11789 puts ("");
11790 }
11791 }
11792 break;
11793
11794 case DT_PLTREL:
978c4450 11795 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11796 if (do_dynamic)
dda8d76d 11797 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11798 break;
11799
11800 case DT_NULL :
11801 case DT_NEEDED :
11802 case DT_PLTGOT :
11803 case DT_HASH :
11804 case DT_STRTAB :
11805 case DT_SYMTAB :
11806 case DT_RELA :
11807 case DT_INIT :
11808 case DT_FINI :
11809 case DT_SONAME :
11810 case DT_RPATH :
11811 case DT_SYMBOLIC:
11812 case DT_REL :
a7fd1186 11813 case DT_RELR :
252b5132
RH
11814 case DT_DEBUG :
11815 case DT_TEXTREL :
11816 case DT_JMPREL :
019148e4 11817 case DT_RUNPATH :
978c4450 11818 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11819
11820 if (do_dynamic)
11821 {
84714f86 11822 const char *name;
252b5132 11823
84714f86
AM
11824 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11825 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11826 else
d79b3d50 11827 name = NULL;
252b5132
RH
11828
11829 if (name)
11830 {
11831 switch (entry->d_tag)
11832 {
11833 case DT_NEEDED:
11834 printf (_("Shared library: [%s]"), name);
11835
13acb58d
AM
11836 if (filedata->program_interpreter
11837 && streq (name, filedata->program_interpreter))
f7a99963 11838 printf (_(" program interpreter"));
252b5132
RH
11839 break;
11840
11841 case DT_SONAME:
f7a99963 11842 printf (_("Library soname: [%s]"), name);
252b5132
RH
11843 break;
11844
11845 case DT_RPATH:
f7a99963 11846 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11847 break;
11848
019148e4
L
11849 case DT_RUNPATH:
11850 printf (_("Library runpath: [%s]"), name);
11851 break;
11852
252b5132 11853 default:
f7a99963
NC
11854 print_vma (entry->d_un.d_val, PREFIX_HEX);
11855 break;
252b5132
RH
11856 }
11857 }
11858 else
f7a99963
NC
11859 print_vma (entry->d_un.d_val, PREFIX_HEX);
11860
11861 putchar ('\n');
252b5132
RH
11862 }
11863 break;
11864
11865 case DT_PLTRELSZ:
11866 case DT_RELASZ :
11867 case DT_STRSZ :
11868 case DT_RELSZ :
11869 case DT_RELAENT :
a7fd1186
FS
11870 case DT_RELRENT :
11871 case DT_RELRSZ :
252b5132
RH
11872 case DT_SYMENT :
11873 case DT_RELENT :
978c4450 11874 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11875 /* Fall through. */
252b5132
RH
11876 case DT_PLTPADSZ:
11877 case DT_MOVEENT :
11878 case DT_MOVESZ :
04d8355a 11879 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11880 case DT_INIT_ARRAYSZ:
11881 case DT_FINI_ARRAYSZ:
047b2264
JJ
11882 case DT_GNU_CONFLICTSZ:
11883 case DT_GNU_LIBLISTSZ:
252b5132 11884 if (do_dynamic)
f7a99963
NC
11885 {
11886 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11887 printf (_(" (bytes)\n"));
f7a99963 11888 }
252b5132
RH
11889 break;
11890
11891 case DT_VERDEFNUM:
11892 case DT_VERNEEDNUM:
11893 case DT_RELACOUNT:
11894 case DT_RELCOUNT:
11895 if (do_dynamic)
f7a99963
NC
11896 {
11897 print_vma (entry->d_un.d_val, UNSIGNED);
11898 putchar ('\n');
11899 }
252b5132
RH
11900 break;
11901
11902 case DT_SYMINSZ:
11903 case DT_SYMINENT:
11904 case DT_SYMINFO:
11905 case DT_USED:
11906 case DT_INIT_ARRAY:
11907 case DT_FINI_ARRAY:
11908 if (do_dynamic)
11909 {
d79b3d50 11910 if (entry->d_tag == DT_USED
84714f86 11911 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11912 {
84714f86
AM
11913 const char *name
11914 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11915
b34976b6 11916 if (*name)
252b5132
RH
11917 {
11918 printf (_("Not needed object: [%s]\n"), name);
11919 break;
11920 }
11921 }
103f02d3 11922
f7a99963
NC
11923 print_vma (entry->d_un.d_val, PREFIX_HEX);
11924 putchar ('\n');
252b5132
RH
11925 }
11926 break;
11927
11928 case DT_BIND_NOW:
11929 /* The value of this entry is ignored. */
35b1837e
AM
11930 if (do_dynamic)
11931 putchar ('\n');
252b5132 11932 break;
103f02d3 11933
047b2264
JJ
11934 case DT_GNU_PRELINKED:
11935 if (do_dynamic)
11936 {
2cf0635d 11937 struct tm * tmp;
91d6fa6a 11938 time_t atime = entry->d_un.d_val;
047b2264 11939
91d6fa6a 11940 tmp = gmtime (&atime);
071436c6
NC
11941 /* PR 17533 file: 041-1244816-0.004. */
11942 if (tmp == NULL)
5a2cbcf4
L
11943 printf (_("<corrupt time val: %lx"),
11944 (unsigned long) atime);
071436c6
NC
11945 else
11946 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11947 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11948 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11949
11950 }
11951 break;
11952
fdc90cb4 11953 case DT_GNU_HASH:
978c4450 11954 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11955 if (do_dynamic)
11956 {
11957 print_vma (entry->d_un.d_val, PREFIX_HEX);
11958 putchar ('\n');
11959 }
11960 break;
11961
a5da3dee
VDM
11962 case DT_GNU_FLAGS_1:
11963 if (do_dynamic)
11964 {
11965 printf (_("Flags:"));
11966 if (entry->d_un.d_val == 0)
11967 printf (_(" None\n"));
11968 else
11969 {
11970 unsigned long int val = entry->d_un.d_val;
11971
11972 if (val & DF_GNU_1_UNIQUE)
11973 {
11974 printf (" UNIQUE");
11975 val ^= DF_GNU_1_UNIQUE;
11976 }
11977 if (val != 0)
11978 printf (" %lx", val);
11979 puts ("");
11980 }
11981 }
11982 break;
11983
252b5132
RH
11984 default:
11985 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11986 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11987 = entry->d_un.d_val;
252b5132
RH
11988
11989 if (do_dynamic)
11990 {
dda8d76d 11991 switch (filedata->file_header.e_machine)
252b5132 11992 {
37c18eed
SD
11993 case EM_AARCH64:
11994 dynamic_section_aarch64_val (entry);
11995 break;
252b5132 11996 case EM_MIPS:
4fe85591 11997 case EM_MIPS_RS3_LE:
978c4450 11998 dynamic_section_mips_val (filedata, entry);
252b5132 11999 break;
103f02d3 12000 case EM_PARISC:
b2d38a17 12001 dynamic_section_parisc_val (entry);
103f02d3 12002 break;
ecc51f48 12003 case EM_IA_64:
b2d38a17 12004 dynamic_section_ia64_val (entry);
ecc51f48 12005 break;
252b5132 12006 default:
f7a99963
NC
12007 print_vma (entry->d_un.d_val, PREFIX_HEX);
12008 putchar ('\n');
252b5132
RH
12009 }
12010 }
12011 break;
12012 }
12013 }
12014
015dc7e1 12015 return true;
252b5132
RH
12016}
12017
12018static char *
d3ba0551 12019get_ver_flags (unsigned int flags)
252b5132 12020{
6d4f21f6 12021 static char buff[128];
252b5132
RH
12022
12023 buff[0] = 0;
12024
12025 if (flags == 0)
12026 return _("none");
12027
12028 if (flags & VER_FLG_BASE)
7bb1ad17 12029 strcat (buff, "BASE");
252b5132
RH
12030
12031 if (flags & VER_FLG_WEAK)
12032 {
12033 if (flags & VER_FLG_BASE)
7bb1ad17 12034 strcat (buff, " | ");
252b5132 12035
7bb1ad17 12036 strcat (buff, "WEAK");
252b5132
RH
12037 }
12038
44ec90b9
RO
12039 if (flags & VER_FLG_INFO)
12040 {
12041 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12042 strcat (buff, " | ");
44ec90b9 12043
7bb1ad17 12044 strcat (buff, "INFO");
44ec90b9
RO
12045 }
12046
12047 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12048 {
12049 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12050 strcat (buff, " | ");
12051
12052 strcat (buff, _("<unknown>"));
12053 }
252b5132
RH
12054
12055 return buff;
12056}
12057
12058/* Display the contents of the version sections. */
98fb390a 12059
015dc7e1 12060static bool
dda8d76d 12061process_version_sections (Filedata * filedata)
252b5132 12062{
2cf0635d 12063 Elf_Internal_Shdr * section;
b34976b6 12064 unsigned i;
015dc7e1 12065 bool found = false;
252b5132
RH
12066
12067 if (! do_version)
015dc7e1 12068 return true;
252b5132 12069
dda8d76d
NC
12070 for (i = 0, section = filedata->section_headers;
12071 i < filedata->file_header.e_shnum;
b34976b6 12072 i++, section++)
252b5132
RH
12073 {
12074 switch (section->sh_type)
12075 {
12076 case SHT_GNU_verdef:
12077 {
2cf0635d 12078 Elf_External_Verdef * edefs;
452bf675
AM
12079 unsigned long idx;
12080 unsigned long cnt;
2cf0635d 12081 char * endbuf;
252b5132 12082
015dc7e1 12083 found = true;
252b5132 12084
ca0e11aa
NC
12085 if (filedata->is_separate)
12086 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12087 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12088 section->sh_info),
12089 filedata->file_name,
12090 printable_section_name (filedata, section),
12091 section->sh_info);
12092 else
12093 printf (ngettext ("\nVersion definition section '%s' "
12094 "contains %u entry:\n",
12095 "\nVersion definition section '%s' "
12096 "contains %u entries:\n",
12097 section->sh_info),
12098 printable_section_name (filedata, section),
12099 section->sh_info);
047c3dbf 12100
625d49fc 12101 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
233f82cf 12102 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12103 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12104 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12105
3f5e193b 12106 edefs = (Elf_External_Verdef *)
dda8d76d 12107 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12108 _("version definition section"));
a6e9f9df
AM
12109 if (!edefs)
12110 break;
59245841 12111 endbuf = (char *) edefs + section->sh_size;
252b5132 12112
1445030f 12113 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12114 {
2cf0635d
NC
12115 char * vstart;
12116 Elf_External_Verdef * edef;
b34976b6 12117 Elf_Internal_Verdef ent;
2cf0635d 12118 Elf_External_Verdaux * eaux;
b34976b6 12119 Elf_Internal_Verdaux aux;
452bf675 12120 unsigned long isum;
b34976b6 12121 int j;
103f02d3 12122
252b5132 12123 vstart = ((char *) edefs) + idx;
54806181
AM
12124 if (vstart + sizeof (*edef) > endbuf)
12125 break;
252b5132
RH
12126
12127 edef = (Elf_External_Verdef *) vstart;
12128
12129 ent.vd_version = BYTE_GET (edef->vd_version);
12130 ent.vd_flags = BYTE_GET (edef->vd_flags);
12131 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12132 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12133 ent.vd_hash = BYTE_GET (edef->vd_hash);
12134 ent.vd_aux = BYTE_GET (edef->vd_aux);
12135 ent.vd_next = BYTE_GET (edef->vd_next);
12136
452bf675 12137 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
12138 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12139
12140 printf (_(" Index: %d Cnt: %d "),
12141 ent.vd_ndx, ent.vd_cnt);
12142
452bf675 12143 /* Check for overflow. */
1445030f 12144 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12145 break;
12146
252b5132
RH
12147 vstart += ent.vd_aux;
12148
1445030f
AM
12149 if (vstart + sizeof (*eaux) > endbuf)
12150 break;
252b5132
RH
12151 eaux = (Elf_External_Verdaux *) vstart;
12152
12153 aux.vda_name = BYTE_GET (eaux->vda_name);
12154 aux.vda_next = BYTE_GET (eaux->vda_next);
12155
84714f86 12156 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12157 printf (_("Name: %s\n"),
84714f86 12158 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12159 else
12160 printf (_("Name index: %ld\n"), aux.vda_name);
12161
12162 isum = idx + ent.vd_aux;
12163
b34976b6 12164 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12165 {
1445030f
AM
12166 if (aux.vda_next < sizeof (*eaux)
12167 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12168 {
12169 warn (_("Invalid vda_next field of %lx\n"),
12170 aux.vda_next);
12171 j = ent.vd_cnt;
12172 break;
12173 }
dd24e3da 12174 /* Check for overflow. */
7e26601c 12175 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12176 break;
12177
252b5132
RH
12178 isum += aux.vda_next;
12179 vstart += aux.vda_next;
12180
54806181
AM
12181 if (vstart + sizeof (*eaux) > endbuf)
12182 break;
1445030f 12183 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12184
12185 aux.vda_name = BYTE_GET (eaux->vda_name);
12186 aux.vda_next = BYTE_GET (eaux->vda_next);
12187
84714f86 12188 if (valid_dynamic_name (filedata, aux.vda_name))
452bf675 12189 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450 12190 isum, j,
84714f86 12191 get_dynamic_name (filedata, aux.vda_name));
252b5132 12192 else
452bf675 12193 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
12194 isum, j, aux.vda_name);
12195 }
dd24e3da 12196
54806181
AM
12197 if (j < ent.vd_cnt)
12198 printf (_(" Version def aux past end of section\n"));
252b5132 12199
c9f02c3e
MR
12200 /* PR 17531:
12201 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12202 if (ent.vd_next < sizeof (*edef)
12203 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12204 {
12205 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12206 cnt = section->sh_info;
12207 break;
12208 }
452bf675 12209 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12210 break;
12211
252b5132
RH
12212 idx += ent.vd_next;
12213 }
dd24e3da 12214
54806181
AM
12215 if (cnt < section->sh_info)
12216 printf (_(" Version definition past end of section\n"));
252b5132
RH
12217
12218 free (edefs);
12219 }
12220 break;
103f02d3 12221
252b5132
RH
12222 case SHT_GNU_verneed:
12223 {
2cf0635d 12224 Elf_External_Verneed * eneed;
452bf675
AM
12225 unsigned long idx;
12226 unsigned long cnt;
2cf0635d 12227 char * endbuf;
252b5132 12228
015dc7e1 12229 found = true;
252b5132 12230
ca0e11aa
NC
12231 if (filedata->is_separate)
12232 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12233 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12234 section->sh_info),
12235 filedata->file_name,
12236 printable_section_name (filedata, section),
12237 section->sh_info);
12238 else
12239 printf (ngettext ("\nVersion needs section '%s' "
12240 "contains %u entry:\n",
12241 "\nVersion needs section '%s' "
12242 "contains %u entries:\n",
12243 section->sh_info),
12244 printable_section_name (filedata, section),
12245 section->sh_info);
047c3dbf 12246
625d49fc 12247 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
72de5009 12248 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12249 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12250 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12251
dda8d76d 12252 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12253 section->sh_offset, 1,
12254 section->sh_size,
9cf03b7e 12255 _("Version Needs section"));
a6e9f9df
AM
12256 if (!eneed)
12257 break;
59245841 12258 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12259
12260 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12261 {
2cf0635d 12262 Elf_External_Verneed * entry;
b34976b6 12263 Elf_Internal_Verneed ent;
452bf675 12264 unsigned long isum;
b34976b6 12265 int j;
2cf0635d 12266 char * vstart;
252b5132
RH
12267
12268 vstart = ((char *) eneed) + idx;
54806181
AM
12269 if (vstart + sizeof (*entry) > endbuf)
12270 break;
252b5132
RH
12271
12272 entry = (Elf_External_Verneed *) vstart;
12273
12274 ent.vn_version = BYTE_GET (entry->vn_version);
12275 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12276 ent.vn_file = BYTE_GET (entry->vn_file);
12277 ent.vn_aux = BYTE_GET (entry->vn_aux);
12278 ent.vn_next = BYTE_GET (entry->vn_next);
12279
452bf675 12280 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 12281
84714f86 12282 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12283 printf (_(" File: %s"),
84714f86 12284 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12285 else
12286 printf (_(" File: %lx"), ent.vn_file);
12287
12288 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12289
dd24e3da 12290 /* Check for overflow. */
7e26601c 12291 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12292 break;
252b5132
RH
12293 vstart += ent.vn_aux;
12294
12295 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12296 {
2cf0635d 12297 Elf_External_Vernaux * eaux;
b34976b6 12298 Elf_Internal_Vernaux aux;
252b5132 12299
54806181
AM
12300 if (vstart + sizeof (*eaux) > endbuf)
12301 break;
252b5132
RH
12302 eaux = (Elf_External_Vernaux *) vstart;
12303
12304 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12305 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12306 aux.vna_other = BYTE_GET (eaux->vna_other);
12307 aux.vna_name = BYTE_GET (eaux->vna_name);
12308 aux.vna_next = BYTE_GET (eaux->vna_next);
12309
84714f86 12310 if (valid_dynamic_name (filedata, aux.vna_name))
452bf675 12311 printf (_(" %#06lx: Name: %s"),
84714f86 12312 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12313 else
452bf675 12314 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
12315 isum, aux.vna_name);
12316
12317 printf (_(" Flags: %s Version: %d\n"),
12318 get_ver_flags (aux.vna_flags), aux.vna_other);
12319
1445030f
AM
12320 if (aux.vna_next < sizeof (*eaux)
12321 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12322 {
12323 warn (_("Invalid vna_next field of %lx\n"),
12324 aux.vna_next);
12325 j = ent.vn_cnt;
12326 break;
12327 }
1445030f
AM
12328 /* Check for overflow. */
12329 if (aux.vna_next > (size_t) (endbuf - vstart))
12330 break;
252b5132
RH
12331 isum += aux.vna_next;
12332 vstart += aux.vna_next;
12333 }
9cf03b7e 12334
54806181 12335 if (j < ent.vn_cnt)
f9a6a8f0 12336 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12337
1445030f
AM
12338 if (ent.vn_next < sizeof (*entry)
12339 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12340 {
452bf675 12341 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12342 cnt = section->sh_info;
12343 break;
12344 }
1445030f
AM
12345 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12346 break;
252b5132
RH
12347 idx += ent.vn_next;
12348 }
9cf03b7e 12349
54806181 12350 if (cnt < section->sh_info)
9cf03b7e 12351 warn (_("Missing Version Needs information\n"));
103f02d3 12352
252b5132
RH
12353 free (eneed);
12354 }
12355 break;
12356
12357 case SHT_GNU_versym:
12358 {
2cf0635d 12359 Elf_Internal_Shdr * link_section;
8b73c356
NC
12360 size_t total;
12361 unsigned int cnt;
2cf0635d
NC
12362 unsigned char * edata;
12363 unsigned short * data;
12364 char * strtab;
12365 Elf_Internal_Sym * symbols;
12366 Elf_Internal_Shdr * string_sec;
ba5cdace 12367 unsigned long num_syms;
d3ba0551 12368 long off;
252b5132 12369
dda8d76d 12370 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12371 break;
12372
dda8d76d 12373 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12374 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12375
dda8d76d 12376 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12377 break;
12378
015dc7e1 12379 found = true;
252b5132 12380
4de91c10 12381 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12382 if (symbols == NULL)
12383 break;
252b5132 12384
dda8d76d 12385 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12386
dda8d76d 12387 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12388 string_sec->sh_size,
12389 _("version string table"));
a6e9f9df 12390 if (!strtab)
0429c154
MS
12391 {
12392 free (symbols);
12393 break;
12394 }
252b5132 12395
ca0e11aa
NC
12396 if (filedata->is_separate)
12397 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
12398 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
12399 total),
12400 filedata->file_name,
12401 printable_section_name (filedata, section),
12402 (unsigned long) total);
12403 else
12404 printf (ngettext ("\nVersion symbols section '%s' "
12405 "contains %lu entry:\n",
12406 "\nVersion symbols section '%s' "
12407 "contains %lu entries:\n",
12408 total),
12409 printable_section_name (filedata, section),
12410 (unsigned long) total);
252b5132 12411
625d49fc 12412 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
72de5009 12413 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12414 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12415 printable_section_name (filedata, link_section));
252b5132 12416
dda8d76d 12417 off = offset_from_vma (filedata,
978c4450 12418 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12419 total * sizeof (short));
95099889
AM
12420 edata = (unsigned char *) get_data (NULL, filedata, off,
12421 sizeof (short), total,
12422 _("version symbol data"));
a6e9f9df
AM
12423 if (!edata)
12424 {
12425 free (strtab);
0429c154 12426 free (symbols);
a6e9f9df
AM
12427 break;
12428 }
252b5132 12429
3f5e193b 12430 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12431
12432 for (cnt = total; cnt --;)
b34976b6
AM
12433 data[cnt] = byte_get (edata + cnt * sizeof (short),
12434 sizeof (short));
252b5132
RH
12435
12436 free (edata);
12437
12438 for (cnt = 0; cnt < total; cnt += 4)
12439 {
12440 int j, nn;
ab273396
AM
12441 char *name;
12442 char *invalid = _("*invalid*");
252b5132
RH
12443
12444 printf (" %03x:", cnt);
12445
12446 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12447 switch (data[cnt + j])
252b5132
RH
12448 {
12449 case 0:
12450 fputs (_(" 0 (*local*) "), stdout);
12451 break;
12452
12453 case 1:
12454 fputs (_(" 1 (*global*) "), stdout);
12455 break;
12456
12457 default:
c244d050
NC
12458 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12459 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12460
dd24e3da 12461 /* If this index value is greater than the size of the symbols
ba5cdace
NC
12462 array, break to avoid an out-of-bounds read. */
12463 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
12464 {
12465 warn (_("invalid index into symbol array\n"));
12466 break;
12467 }
12468
ab273396 12469 name = NULL;
978c4450 12470 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12471 {
b34976b6
AM
12472 Elf_Internal_Verneed ivn;
12473 unsigned long offset;
252b5132 12474
d93f0186 12475 offset = offset_from_vma
978c4450
AM
12476 (filedata,
12477 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12478 sizeof (Elf_External_Verneed));
252b5132 12479
b34976b6 12480 do
252b5132 12481 {
b34976b6
AM
12482 Elf_Internal_Vernaux ivna;
12483 Elf_External_Verneed evn;
12484 Elf_External_Vernaux evna;
12485 unsigned long a_off;
252b5132 12486
dda8d76d 12487 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12488 _("version need")) == NULL)
12489 break;
0b4362b0 12490
252b5132
RH
12491 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12492 ivn.vn_next = BYTE_GET (evn.vn_next);
12493
12494 a_off = offset + ivn.vn_aux;
12495
12496 do
12497 {
dda8d76d 12498 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12499 1, _("version need aux (2)")) == NULL)
12500 {
12501 ivna.vna_next = 0;
12502 ivna.vna_other = 0;
12503 }
12504 else
12505 {
12506 ivna.vna_next = BYTE_GET (evna.vna_next);
12507 ivna.vna_other = BYTE_GET (evna.vna_other);
12508 }
252b5132
RH
12509
12510 a_off += ivna.vna_next;
12511 }
b34976b6 12512 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12513 && ivna.vna_next != 0);
12514
b34976b6 12515 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12516 {
12517 ivna.vna_name = BYTE_GET (evna.vna_name);
12518
54806181 12519 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12520 name = invalid;
54806181
AM
12521 else
12522 name = strtab + ivna.vna_name;
252b5132
RH
12523 break;
12524 }
12525
12526 offset += ivn.vn_next;
12527 }
12528 while (ivn.vn_next);
12529 }
00d93f34 12530
ab273396 12531 if (data[cnt + j] != 0x8001
978c4450 12532 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12533 {
b34976b6
AM
12534 Elf_Internal_Verdef ivd;
12535 Elf_External_Verdef evd;
12536 unsigned long offset;
252b5132 12537
d93f0186 12538 offset = offset_from_vma
978c4450
AM
12539 (filedata,
12540 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12541 sizeof evd);
252b5132
RH
12542
12543 do
12544 {
dda8d76d 12545 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12546 _("version def")) == NULL)
12547 {
12548 ivd.vd_next = 0;
948f632f 12549 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12550 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12551 break;
59245841
NC
12552 }
12553 else
12554 {
12555 ivd.vd_next = BYTE_GET (evd.vd_next);
12556 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12557 }
252b5132
RH
12558
12559 offset += ivd.vd_next;
12560 }
c244d050 12561 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12562 && ivd.vd_next != 0);
12563
c244d050 12564 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12565 {
b34976b6
AM
12566 Elf_External_Verdaux evda;
12567 Elf_Internal_Verdaux ivda;
252b5132
RH
12568
12569 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12570
dda8d76d 12571 if (get_data (&evda, filedata,
59245841
NC
12572 offset - ivd.vd_next + ivd.vd_aux,
12573 sizeof (evda), 1,
12574 _("version def aux")) == NULL)
12575 break;
252b5132
RH
12576
12577 ivda.vda_name = BYTE_GET (evda.vda_name);
12578
54806181 12579 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12580 name = invalid;
12581 else if (name != NULL && name != invalid)
12582 name = _("*both*");
54806181
AM
12583 else
12584 name = strtab + ivda.vda_name;
252b5132
RH
12585 }
12586 }
ab273396
AM
12587 if (name != NULL)
12588 nn += printf ("(%s%-*s",
12589 name,
12590 12 - (int) strlen (name),
12591 ")");
252b5132
RH
12592
12593 if (nn < 18)
12594 printf ("%*c", 18 - nn, ' ');
12595 }
12596
12597 putchar ('\n');
12598 }
12599
12600 free (data);
12601 free (strtab);
12602 free (symbols);
12603 }
12604 break;
103f02d3 12605
252b5132
RH
12606 default:
12607 break;
12608 }
12609 }
12610
12611 if (! found)
ca0e11aa
NC
12612 {
12613 if (filedata->is_separate)
12614 printf (_("\nNo version information found in linked file '%s'.\n"),
12615 filedata->file_name);
12616 else
12617 printf (_("\nNo version information found in this file.\n"));
12618 }
252b5132 12619
015dc7e1 12620 return true;
252b5132
RH
12621}
12622
d1133906 12623static const char *
dda8d76d 12624get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12625{
89246a0e 12626 static char buff[64];
252b5132
RH
12627
12628 switch (binding)
12629 {
b34976b6
AM
12630 case STB_LOCAL: return "LOCAL";
12631 case STB_GLOBAL: return "GLOBAL";
12632 case STB_WEAK: return "WEAK";
252b5132
RH
12633 default:
12634 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12635 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12636 binding);
252b5132 12637 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12638 {
12639 if (binding == STB_GNU_UNIQUE
df3a023b 12640 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12641 return "UNIQUE";
12642 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12643 }
252b5132 12644 else
e9e44622 12645 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12646 return buff;
12647 }
12648}
12649
d1133906 12650static const char *
dda8d76d 12651get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12652{
89246a0e 12653 static char buff[64];
252b5132
RH
12654
12655 switch (type)
12656 {
b34976b6
AM
12657 case STT_NOTYPE: return "NOTYPE";
12658 case STT_OBJECT: return "OBJECT";
12659 case STT_FUNC: return "FUNC";
12660 case STT_SECTION: return "SECTION";
12661 case STT_FILE: return "FILE";
12662 case STT_COMMON: return "COMMON";
12663 case STT_TLS: return "TLS";
15ab5209
DB
12664 case STT_RELC: return "RELC";
12665 case STT_SRELC: return "SRELC";
252b5132
RH
12666 default:
12667 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12668 {
dda8d76d 12669 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12670 return "THUMB_FUNC";
103f02d3 12671
dda8d76d 12672 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12673 return "REGISTER";
12674
dda8d76d 12675 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12676 return "PARISC_MILLI";
12677
e9e44622 12678 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12679 }
252b5132 12680 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12681 {
dda8d76d 12682 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12683 {
12684 if (type == STT_HP_OPAQUE)
12685 return "HP_OPAQUE";
12686 if (type == STT_HP_STUB)
12687 return "HP_STUB";
12688 }
12689
d8045f23 12690 if (type == STT_GNU_IFUNC
dda8d76d 12691 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12692 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12693 return "IFUNC";
12694
e9e44622 12695 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12696 }
252b5132 12697 else
e9e44622 12698 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12699 return buff;
12700 }
12701}
12702
d1133906 12703static const char *
d3ba0551 12704get_symbol_visibility (unsigned int visibility)
d1133906
NC
12705{
12706 switch (visibility)
12707 {
b34976b6
AM
12708 case STV_DEFAULT: return "DEFAULT";
12709 case STV_INTERNAL: return "INTERNAL";
12710 case STV_HIDDEN: return "HIDDEN";
d1133906 12711 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12712 default:
27a45f42 12713 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12714 return _("<unknown>");
d1133906
NC
12715 }
12716}
12717
2057d69d
CZ
12718static const char *
12719get_alpha_symbol_other (unsigned int other)
9abca702 12720{
2057d69d
CZ
12721 switch (other)
12722 {
12723 case STO_ALPHA_NOPV: return "NOPV";
12724 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12725 default:
27a45f42 12726 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12727 return _("<unknown>");
9abca702 12728 }
2057d69d
CZ
12729}
12730
fd85a6a1
NC
12731static const char *
12732get_solaris_symbol_visibility (unsigned int visibility)
12733{
12734 switch (visibility)
12735 {
12736 case 4: return "EXPORTED";
12737 case 5: return "SINGLETON";
12738 case 6: return "ELIMINATE";
12739 default: return get_symbol_visibility (visibility);
12740 }
12741}
12742
2301ed1c
SN
12743static const char *
12744get_aarch64_symbol_other (unsigned int other)
12745{
12746 static char buf[32];
12747
12748 if (other & STO_AARCH64_VARIANT_PCS)
12749 {
12750 other &= ~STO_AARCH64_VARIANT_PCS;
12751 if (other == 0)
12752 return "VARIANT_PCS";
12753 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12754 return buf;
12755 }
12756 return NULL;
12757}
12758
5e2b0d47
NC
12759static const char *
12760get_mips_symbol_other (unsigned int other)
12761{
12762 switch (other)
12763 {
32ec8896
NC
12764 case STO_OPTIONAL: return "OPTIONAL";
12765 case STO_MIPS_PLT: return "MIPS PLT";
12766 case STO_MIPS_PIC: return "MIPS PIC";
12767 case STO_MICROMIPS: return "MICROMIPS";
12768 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12769 case STO_MIPS16: return "MIPS16";
12770 default: return NULL;
5e2b0d47
NC
12771 }
12772}
12773
28f997cf 12774static const char *
dda8d76d 12775get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12776{
dda8d76d 12777 if (is_ia64_vms (filedata))
28f997cf
TG
12778 {
12779 static char res[32];
12780
12781 res[0] = 0;
12782
12783 /* Function types is for images and .STB files only. */
dda8d76d 12784 switch (filedata->file_header.e_type)
28f997cf
TG
12785 {
12786 case ET_DYN:
12787 case ET_EXEC:
12788 switch (VMS_ST_FUNC_TYPE (other))
12789 {
12790 case VMS_SFT_CODE_ADDR:
12791 strcat (res, " CA");
12792 break;
12793 case VMS_SFT_SYMV_IDX:
12794 strcat (res, " VEC");
12795 break;
12796 case VMS_SFT_FD:
12797 strcat (res, " FD");
12798 break;
12799 case VMS_SFT_RESERVE:
12800 strcat (res, " RSV");
12801 break;
12802 default:
bee0ee85
NC
12803 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12804 VMS_ST_FUNC_TYPE (other));
12805 strcat (res, " <unknown>");
12806 break;
28f997cf
TG
12807 }
12808 break;
12809 default:
12810 break;
12811 }
12812 switch (VMS_ST_LINKAGE (other))
12813 {
12814 case VMS_STL_IGNORE:
12815 strcat (res, " IGN");
12816 break;
12817 case VMS_STL_RESERVE:
12818 strcat (res, " RSV");
12819 break;
12820 case VMS_STL_STD:
12821 strcat (res, " STD");
12822 break;
12823 case VMS_STL_LNK:
12824 strcat (res, " LNK");
12825 break;
12826 default:
bee0ee85
NC
12827 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12828 VMS_ST_LINKAGE (other));
12829 strcat (res, " <unknown>");
12830 break;
28f997cf
TG
12831 }
12832
12833 if (res[0] != 0)
12834 return res + 1;
12835 else
12836 return res;
12837 }
12838 return NULL;
12839}
12840
6911b7dc
AM
12841static const char *
12842get_ppc64_symbol_other (unsigned int other)
12843{
14732552
AM
12844 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12845 return NULL;
12846
12847 other >>= STO_PPC64_LOCAL_BIT;
12848 if (other <= 6)
6911b7dc 12849 {
89246a0e 12850 static char buf[64];
14732552
AM
12851 if (other >= 2)
12852 other = ppc64_decode_local_entry (other);
12853 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12854 return buf;
12855 }
12856 return NULL;
12857}
12858
8155b853
NC
12859static const char *
12860get_riscv_symbol_other (unsigned int other)
12861{
12862 static char buf[32];
12863 buf[0] = 0;
12864
12865 if (other & STO_RISCV_VARIANT_CC)
12866 {
12867 strcat (buf, _(" VARIANT_CC"));
12868 other &= ~STO_RISCV_VARIANT_CC;
12869 }
12870
12871 if (other != 0)
12872 snprintf (buf, sizeof buf, " %x", other);
12873
12874
12875 if (buf[0] != 0)
12876 return buf + 1;
12877 else
12878 return buf;
12879}
12880
5e2b0d47 12881static const char *
dda8d76d 12882get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12883{
12884 const char * result = NULL;
89246a0e 12885 static char buff [64];
5e2b0d47
NC
12886
12887 if (other == 0)
12888 return "";
12889
dda8d76d 12890 switch (filedata->file_header.e_machine)
5e2b0d47 12891 {
2057d69d
CZ
12892 case EM_ALPHA:
12893 result = get_alpha_symbol_other (other);
12894 break;
2301ed1c
SN
12895 case EM_AARCH64:
12896 result = get_aarch64_symbol_other (other);
12897 break;
5e2b0d47
NC
12898 case EM_MIPS:
12899 result = get_mips_symbol_other (other);
28f997cf
TG
12900 break;
12901 case EM_IA_64:
dda8d76d 12902 result = get_ia64_symbol_other (filedata, other);
28f997cf 12903 break;
6911b7dc
AM
12904 case EM_PPC64:
12905 result = get_ppc64_symbol_other (other);
12906 break;
8155b853
NC
12907 case EM_RISCV:
12908 result = get_riscv_symbol_other (other);
12909 break;
5e2b0d47 12910 default:
fd85a6a1 12911 result = NULL;
5e2b0d47
NC
12912 break;
12913 }
12914
12915 if (result)
12916 return result;
12917
12918 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12919 return buff;
12920}
12921
d1133906 12922static const char *
dda8d76d 12923get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12924{
b34976b6 12925 static char buff[32];
5cf1065c 12926
252b5132
RH
12927 switch (type)
12928 {
b34976b6
AM
12929 case SHN_UNDEF: return "UND";
12930 case SHN_ABS: return "ABS";
12931 case SHN_COMMON: return "COM";
252b5132 12932 default:
9ce701e2 12933 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12934 && filedata->file_header.e_machine == EM_IA_64
12935 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12936 return "ANSI_COM";
12937 else if ((filedata->file_header.e_machine == EM_X86_64
12938 || filedata->file_header.e_machine == EM_L1OM
12939 || filedata->file_header.e_machine == EM_K1OM)
12940 && type == SHN_X86_64_LCOMMON)
12941 return "LARGE_COM";
12942 else if ((type == SHN_MIPS_SCOMMON
12943 && filedata->file_header.e_machine == EM_MIPS)
12944 || (type == SHN_TIC6X_SCOMMON
12945 && filedata->file_header.e_machine == EM_TI_C6000))
12946 return "SCOM";
12947 else if (type == SHN_MIPS_SUNDEFINED
12948 && filedata->file_header.e_machine == EM_MIPS)
12949 return "SUND";
12950 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12951 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12952 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12953 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12954 else if (type >= SHN_LORESERVE)
12955 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12956 else if (filedata->file_header.e_shnum != 0
12957 && type >= filedata->file_header.e_shnum)
12958 sprintf (buff, _("bad section index[%3d]"), type);
12959 else
12960 sprintf (buff, "%3d", type);
12961 break;
fd85a6a1
NC
12962 }
12963
10ca4b04 12964 return buff;
6bd1a22c
L
12965}
12966
bb4d2ac2 12967static const char *
dda8d76d 12968get_symbol_version_string (Filedata * filedata,
015dc7e1 12969 bool is_dynsym,
1449284b
NC
12970 const char * strtab,
12971 unsigned long int strtab_size,
12972 unsigned int si,
12973 Elf_Internal_Sym * psym,
12974 enum versioned_symbol_info * sym_info,
12975 unsigned short * vna_other)
bb4d2ac2 12976{
ab273396
AM
12977 unsigned char data[2];
12978 unsigned short vers_data;
12979 unsigned long offset;
7a815dd5 12980 unsigned short max_vd_ndx;
bb4d2ac2 12981
ab273396 12982 if (!is_dynsym
978c4450 12983 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12984 return NULL;
bb4d2ac2 12985
978c4450
AM
12986 offset = offset_from_vma (filedata,
12987 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12988 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12989
dda8d76d 12990 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12991 sizeof (data), 1, _("version data")) == NULL)
12992 return NULL;
12993
12994 vers_data = byte_get (data, 2);
bb4d2ac2 12995
1f6f5dba 12996 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12997 return NULL;
bb4d2ac2 12998
0b8b7609 12999 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
13000 max_vd_ndx = 0;
13001
ab273396
AM
13002 /* Usually we'd only see verdef for defined symbols, and verneed for
13003 undefined symbols. However, symbols defined by the linker in
13004 .dynbss for variables copied from a shared library in order to
13005 avoid text relocations are defined yet have verneed. We could
13006 use a heuristic to detect the special case, for example, check
13007 for verneed first on symbols defined in SHT_NOBITS sections, but
13008 it is simpler and more reliable to just look for both verdef and
13009 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13010
ab273396
AM
13011 if (psym->st_shndx != SHN_UNDEF
13012 && vers_data != 0x8001
978c4450 13013 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13014 {
13015 Elf_Internal_Verdef ivd;
13016 Elf_Internal_Verdaux ivda;
13017 Elf_External_Verdaux evda;
13018 unsigned long off;
bb4d2ac2 13019
dda8d76d 13020 off = offset_from_vma (filedata,
978c4450 13021 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13022 sizeof (Elf_External_Verdef));
13023
13024 do
bb4d2ac2 13025 {
ab273396
AM
13026 Elf_External_Verdef evd;
13027
dda8d76d 13028 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13029 _("version def")) == NULL)
13030 {
13031 ivd.vd_ndx = 0;
13032 ivd.vd_aux = 0;
13033 ivd.vd_next = 0;
1f6f5dba 13034 ivd.vd_flags = 0;
ab273396
AM
13035 }
13036 else
bb4d2ac2 13037 {
ab273396
AM
13038 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13039 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13040 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13041 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13042 }
bb4d2ac2 13043
7a815dd5
L
13044 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13045 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13046
ab273396
AM
13047 off += ivd.vd_next;
13048 }
13049 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13050
ab273396
AM
13051 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13052 {
9abca702 13053 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13054 return NULL;
13055
ab273396
AM
13056 off -= ivd.vd_next;
13057 off += ivd.vd_aux;
bb4d2ac2 13058
dda8d76d 13059 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13060 _("version def aux")) != NULL)
13061 {
13062 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13063
ab273396 13064 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13065 return (ivda.vda_name < strtab_size
13066 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13067 }
13068 }
13069 }
bb4d2ac2 13070
978c4450 13071 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13072 {
13073 Elf_External_Verneed evn;
13074 Elf_Internal_Verneed ivn;
13075 Elf_Internal_Vernaux ivna;
bb4d2ac2 13076
dda8d76d 13077 offset = offset_from_vma (filedata,
978c4450 13078 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13079 sizeof evn);
13080 do
13081 {
13082 unsigned long vna_off;
bb4d2ac2 13083
dda8d76d 13084 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13085 _("version need")) == NULL)
13086 {
13087 ivna.vna_next = 0;
13088 ivna.vna_other = 0;
13089 ivna.vna_name = 0;
13090 break;
13091 }
bb4d2ac2 13092
ab273396
AM
13093 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13094 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13095
ab273396 13096 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13097
ab273396
AM
13098 do
13099 {
13100 Elf_External_Vernaux evna;
bb4d2ac2 13101
dda8d76d 13102 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13103 _("version need aux (3)")) == NULL)
bb4d2ac2 13104 {
ab273396
AM
13105 ivna.vna_next = 0;
13106 ivna.vna_other = 0;
13107 ivna.vna_name = 0;
bb4d2ac2 13108 }
bb4d2ac2 13109 else
bb4d2ac2 13110 {
ab273396
AM
13111 ivna.vna_other = BYTE_GET (evna.vna_other);
13112 ivna.vna_next = BYTE_GET (evna.vna_next);
13113 ivna.vna_name = BYTE_GET (evna.vna_name);
13114 }
bb4d2ac2 13115
ab273396
AM
13116 vna_off += ivna.vna_next;
13117 }
13118 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13119
ab273396
AM
13120 if (ivna.vna_other == vers_data)
13121 break;
bb4d2ac2 13122
ab273396
AM
13123 offset += ivn.vn_next;
13124 }
13125 while (ivn.vn_next != 0);
bb4d2ac2 13126
ab273396
AM
13127 if (ivna.vna_other == vers_data)
13128 {
13129 *sym_info = symbol_undefined;
13130 *vna_other = ivna.vna_other;
13131 return (ivna.vna_name < strtab_size
13132 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13133 }
7a815dd5
L
13134 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13135 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13136 return _("<corrupt>");
bb4d2ac2 13137 }
ab273396 13138 return NULL;
bb4d2ac2
L
13139}
13140
047c3dbf
NL
13141/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13142
13143static unsigned int
625d49fc 13144print_dynamic_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13145{
13146 switch (base)
13147 {
13148 case 8:
13149 return print_vma (vma, OCTAL_5);
13150
13151 case 10:
13152 return print_vma (vma, UNSIGNED_5);
13153
13154 case 16:
13155 return print_vma (vma, PREFIX_HEX_5);
13156
13157 case 0:
13158 default:
13159 return print_vma (vma, DEC_5);
13160 }
13161}
13162
10ca4b04
L
13163static void
13164print_dynamic_symbol (Filedata *filedata, unsigned long si,
13165 Elf_Internal_Sym *symtab,
13166 Elf_Internal_Shdr *section,
13167 char *strtab, size_t strtab_size)
252b5132 13168{
10ca4b04
L
13169 const char *version_string;
13170 enum versioned_symbol_info sym_info;
13171 unsigned short vna_other;
23356397
NC
13172 bool is_valid;
13173 const char * sstr;
10ca4b04 13174 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13175
10ca4b04
L
13176 printf ("%6ld: ", si);
13177 print_vma (psym->st_value, LONG_HEX);
13178 putchar (' ');
047c3dbf 13179 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13180 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13181 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13182 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13183 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13184 else
252b5132 13185 {
10ca4b04 13186 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13187
10ca4b04
L
13188 printf (" %-7s", get_symbol_visibility (vis));
13189 /* Check to see if any other bits in the st_other field are set.
13190 Note - displaying this information disrupts the layout of the
13191 table being generated, but for the moment this case is very rare. */
13192 if (psym->st_other ^ vis)
13193 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13194 }
10ca4b04 13195 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13196
23356397
NC
13197 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13198 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13199 && filedata->section_headers != NULL
23356397
NC
13200 && psym->st_name == 0)
13201 {
84714f86
AM
13202 is_valid
13203 = section_name_valid (filedata,
13204 filedata->section_headers + psym->st_shndx);
23356397 13205 sstr = is_valid ?
84714f86
AM
13206 section_name_print (filedata,
13207 filedata->section_headers + psym->st_shndx)
23356397
NC
13208 : _("<corrupt>");
13209 }
13210 else
13211 {
84714f86 13212 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13213 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13214 }
10ca4b04
L
13215
13216 version_string
13217 = get_symbol_version_string (filedata,
13218 (section == NULL
13219 || section->sh_type == SHT_DYNSYM),
13220 strtab, strtab_size, si,
13221 psym, &sym_info, &vna_other);
b9e920ec 13222
0942c7ab
NC
13223 int len_avail = 21;
13224 if (! do_wide && version_string != NULL)
13225 {
ddb43bab 13226 char buffer[16];
0942c7ab 13227
ddb43bab 13228 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13229
13230 if (sym_info == symbol_undefined)
13231 len_avail -= sprintf (buffer," (%d)", vna_other);
13232 else if (sym_info != symbol_hidden)
13233 len_avail -= 1;
13234 }
13235
13236 print_symbol (len_avail, sstr);
b9e920ec 13237
10ca4b04
L
13238 if (version_string)
13239 {
13240 if (sym_info == symbol_undefined)
13241 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13242 else
10ca4b04
L
13243 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13244 version_string);
13245 }
6bd1a22c 13246
10ca4b04 13247 putchar ('\n');
6bd1a22c 13248
10ca4b04
L
13249 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13250 && section != NULL
13251 && si >= section->sh_info
13252 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13253 && filedata->file_header.e_machine != EM_MIPS
13254 /* Solaris binaries have been found to violate this requirement as
13255 well. Not sure if this is a bug or an ABI requirement. */
13256 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
13257 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
13258 si, printable_section_name (filedata, section), section->sh_info);
13259}
f16a9783 13260
0f03783c
NC
13261static const char *
13262get_lto_kind (unsigned int kind)
13263{
13264 switch (kind)
13265 {
13266 case 0: return "DEF";
13267 case 1: return "WEAKDEF";
13268 case 2: return "UNDEF";
13269 case 3: return "WEAKUNDEF";
13270 case 4: return "COMMON";
13271 default:
13272 break;
13273 }
13274
13275 static char buffer[30];
13276 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13277 sprintf (buffer, "<unknown: %u>", kind);
13278 return buffer;
13279}
13280
13281static const char *
13282get_lto_visibility (unsigned int visibility)
13283{
13284 switch (visibility)
13285 {
13286 case 0: return "DEFAULT";
13287 case 1: return "PROTECTED";
13288 case 2: return "INTERNAL";
13289 case 3: return "HIDDEN";
13290 default:
13291 break;
13292 }
13293
13294 static char buffer[30];
13295 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13296 sprintf (buffer, "<unknown: %u>", visibility);
13297 return buffer;
13298}
13299
13300static const char *
13301get_lto_sym_type (unsigned int sym_type)
13302{
13303 switch (sym_type)
13304 {
13305 case 0: return "UNKNOWN";
13306 case 1: return "FUNCTION";
13307 case 2: return "VARIABLE";
13308 default:
13309 break;
13310 }
13311
13312 static char buffer[30];
13313 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13314 sprintf (buffer, "<unknown: %u>", sym_type);
13315 return buffer;
13316}
13317
13318/* Display an LTO format symbol table.
13319 FIXME: The format of LTO symbol tables is not formalized.
13320 So this code could need changing in the future. */
13321
015dc7e1 13322static bool
0f03783c
NC
13323display_lto_symtab (Filedata * filedata,
13324 Elf_Internal_Shdr * section)
13325{
13326 if (section->sh_size == 0)
13327 {
ca0e11aa
NC
13328 if (filedata->is_separate)
13329 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13330 printable_section_name (filedata, section),
13331 filedata->file_name);
13332 else
13333 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13334 printable_section_name (filedata, section));
047c3dbf 13335
015dc7e1 13336 return true;
0f03783c
NC
13337 }
13338
13339 if (section->sh_size > filedata->file_size)
13340 {
13341 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
13342 printable_section_name (filedata, section),
13343 (unsigned long) section->sh_size);
015dc7e1 13344 return false;
0f03783c
NC
13345 }
13346
13347 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13348 section->sh_size, 1, _("LTO symbols"));
13349 if (alloced_data == NULL)
015dc7e1 13350 return false;
0f03783c
NC
13351
13352 /* Look for extended data for the symbol table. */
13353 Elf_Internal_Shdr * ext;
13354 void * ext_data_orig = NULL;
13355 char * ext_data = NULL;
13356 char * ext_data_end = NULL;
13357 char * ext_name = NULL;
13358
13359 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13360 (section_name (filedata, section)
13361 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13362 && ext_name != NULL /* Paranoia. */
13363 && (ext = find_section (filedata, ext_name)) != NULL)
13364 {
13365 if (ext->sh_size < 3)
13366 error (_("LTO Symbol extension table '%s' is empty!\n"),
13367 printable_section_name (filedata, ext));
13368 else
13369 {
13370 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13371 ext->sh_size, 1,
13372 _("LTO ext symbol data"));
13373 if (ext_data != NULL)
13374 {
13375 ext_data_end = ext_data + ext->sh_size;
13376 if (* ext_data++ != 1)
13377 error (_("Unexpected version number in symbol extension table\n"));
13378 }
13379 }
13380 }
b9e920ec 13381
0f03783c
NC
13382 const unsigned char * data = (const unsigned char *) alloced_data;
13383 const unsigned char * end = data + section->sh_size;
13384
ca0e11aa
NC
13385 if (filedata->is_separate)
13386 printf (_("\nIn linked file '%s': "), filedata->file_name);
13387 else
13388 printf ("\n");
13389
0f03783c
NC
13390 if (ext_data_orig != NULL)
13391 {
13392 if (do_wide)
ca0e11aa 13393 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13394 printable_section_name (filedata, section),
13395 printable_section_name (filedata, ext));
13396 else
13397 {
ca0e11aa 13398 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13399 printable_section_name (filedata, section));
13400 printf (_(" and extension table '%s' contain:\n"),
13401 printable_section_name (filedata, ext));
13402 }
13403 }
13404 else
ca0e11aa 13405 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13406 printable_section_name (filedata, section));
b9e920ec 13407
0f03783c 13408 /* FIXME: Add a wide version. */
b9e920ec 13409 if (ext_data_orig != NULL)
0f03783c
NC
13410 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13411 else
13412 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13413
13414 /* FIXME: We do not handle style prefixes. */
13415
13416 while (data < end)
13417 {
13418 const unsigned char * sym_name = data;
13419 data += strnlen ((const char *) sym_name, end - data) + 1;
13420 if (data >= end)
13421 goto fail;
13422
13423 const unsigned char * comdat_key = data;
13424 data += strnlen ((const char *) comdat_key, end - data) + 1;
13425 if (data >= end)
13426 goto fail;
13427
13428 if (data + 2 + 8 + 4 > end)
13429 goto fail;
13430
13431 unsigned int kind = *data++;
13432 unsigned int visibility = *data++;
13433
928c411d 13434 uint64_t size = byte_get (data, 8);
0f03783c
NC
13435 data += 8;
13436
928c411d 13437 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13438 data += 4;
13439
13440 if (ext_data != NULL)
13441 {
13442 if (ext_data < (ext_data_end - 1))
13443 {
13444 unsigned int sym_type = * ext_data ++;
13445 unsigned int sec_kind = * ext_data ++;
13446
31e5a3a3 13447 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
13448 * comdat_key == 0 ? "-" : (char *) comdat_key,
13449 get_lto_kind (kind),
13450 get_lto_visibility (visibility),
31e5a3a3
AM
13451 size,
13452 slot,
0f03783c 13453 get_lto_sym_type (sym_type),
31e5a3a3 13454 sec_kind);
0f03783c
NC
13455 print_symbol (6, (const char *) sym_name);
13456 }
13457 else
13458 {
13459 error (_("Ran out of LTO symbol extension data\n"));
13460 ext_data = NULL;
13461 /* FIXME: return FAIL result ? */
13462 }
13463 }
13464 else
13465 {
31e5a3a3 13466 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
13467 * comdat_key == 0 ? "-" : (char *) comdat_key,
13468 get_lto_kind (kind),
13469 get_lto_visibility (visibility),
31e5a3a3
AM
13470 size,
13471 slot);
0f03783c
NC
13472 print_symbol (21, (const char *) sym_name);
13473 }
13474 putchar ('\n');
13475 }
13476
13477 if (ext_data != NULL && ext_data < ext_data_end)
13478 {
13479 error (_("Data remains in the LTO symbol extension table\n"));
13480 goto fail;
13481 }
13482
13483 free (alloced_data);
13484 free (ext_data_orig);
13485 free (ext_name);
015dc7e1 13486 return true;
b9e920ec 13487
0f03783c
NC
13488 fail:
13489 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13490 free (alloced_data);
13491 free (ext_data_orig);
13492 free (ext_name);
015dc7e1 13493 return false;
0f03783c
NC
13494}
13495
13496/* Display LTO symbol tables. */
13497
015dc7e1 13498static bool
0f03783c
NC
13499process_lto_symbol_tables (Filedata * filedata)
13500{
13501 Elf_Internal_Shdr * section;
13502 unsigned int i;
015dc7e1 13503 bool res = true;
0f03783c
NC
13504
13505 if (!do_lto_syms)
015dc7e1 13506 return true;
0f03783c
NC
13507
13508 if (filedata->section_headers == NULL)
015dc7e1 13509 return true;
0f03783c
NC
13510
13511 for (i = 0, section = filedata->section_headers;
13512 i < filedata->file_header.e_shnum;
13513 i++, section++)
84714f86
AM
13514 if (section_name_valid (filedata, section)
13515 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13516 res &= display_lto_symtab (filedata, section);
13517
b9e920ec 13518 return res;
0f03783c
NC
13519}
13520
10ca4b04 13521/* Dump the symbol table. */
0f03783c 13522
015dc7e1 13523static bool
10ca4b04
L
13524process_symbol_table (Filedata * filedata)
13525{
13526 Elf_Internal_Shdr * section;
f16a9783 13527
10ca4b04 13528 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13529 return true;
6bd1a22c 13530
978c4450 13531 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13532 && do_syms
13533 && do_using_dynamic
978c4450
AM
13534 && filedata->dynamic_strings != NULL
13535 && filedata->dynamic_symbols != NULL)
6bd1a22c 13536 {
10ca4b04 13537 unsigned long si;
6bd1a22c 13538
ca0e11aa
NC
13539 if (filedata->is_separate)
13540 {
13541 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
13542 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
13543 filedata->num_dynamic_syms),
13544 filedata->file_name,
13545 filedata->num_dynamic_syms);
13546 }
13547 else
13548 {
13549 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
13550 "\nSymbol table for image contains %lu entries:\n",
13551 filedata->num_dynamic_syms),
13552 filedata->num_dynamic_syms);
13553 }
10ca4b04
L
13554 if (is_32bit_elf)
13555 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13556 else
13557 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13558
978c4450
AM
13559 for (si = 0; si < filedata->num_dynamic_syms; si++)
13560 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13561 filedata->dynamic_strings,
13562 filedata->dynamic_strings_length);
252b5132 13563 }
8b73c356 13564 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13565 && filedata->section_headers != NULL)
252b5132 13566 {
b34976b6 13567 unsigned int i;
252b5132 13568
dda8d76d
NC
13569 for (i = 0, section = filedata->section_headers;
13570 i < filedata->file_header.e_shnum;
252b5132
RH
13571 i++, section++)
13572 {
2cf0635d 13573 char * strtab = NULL;
c256ffe7 13574 unsigned long int strtab_size = 0;
2cf0635d 13575 Elf_Internal_Sym * symtab;
ef3df110 13576 unsigned long si, num_syms;
252b5132 13577
2c610e4b
L
13578 if ((section->sh_type != SHT_SYMTAB
13579 && section->sh_type != SHT_DYNSYM)
13580 || (!do_syms
13581 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13582 continue;
13583
dd24e3da
NC
13584 if (section->sh_entsize == 0)
13585 {
13586 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13587 printable_section_name (filedata, section));
dd24e3da
NC
13588 continue;
13589 }
13590
d3a49aa8 13591 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13592
13593 if (filedata->is_separate)
13594 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13595 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13596 num_syms),
13597 filedata->file_name,
13598 printable_section_name (filedata, section),
13599 num_syms);
13600 else
13601 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13602 "\nSymbol table '%s' contains %lu entries:\n",
13603 num_syms),
13604 printable_section_name (filedata, section),
13605 num_syms);
dd24e3da 13606
f7a99963 13607 if (is_32bit_elf)
ca47b30c 13608 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13609 else
ca47b30c 13610 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13611
4de91c10 13612 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13613 if (symtab == NULL)
13614 continue;
13615
dda8d76d 13616 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13617 {
dda8d76d
NC
13618 strtab = filedata->string_table;
13619 strtab_size = filedata->string_table_length;
c256ffe7 13620 }
dda8d76d 13621 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13622 {
2cf0635d 13623 Elf_Internal_Shdr * string_sec;
252b5132 13624
dda8d76d 13625 string_sec = filedata->section_headers + section->sh_link;
252b5132 13626
dda8d76d 13627 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13628 1, string_sec->sh_size,
13629 _("string table"));
c256ffe7 13630 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13631 }
13632
10ca4b04
L
13633 for (si = 0; si < num_syms; si++)
13634 print_dynamic_symbol (filedata, si, symtab, section,
13635 strtab, strtab_size);
252b5132
RH
13636
13637 free (symtab);
dda8d76d 13638 if (strtab != filedata->string_table)
252b5132
RH
13639 free (strtab);
13640 }
13641 }
13642 else if (do_syms)
13643 printf
13644 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13645
978c4450 13646 if (do_histogram && filedata->buckets != NULL)
252b5132 13647 {
2cf0635d
NC
13648 unsigned long * lengths;
13649 unsigned long * counts;
66543521 13650 unsigned long hn;
625d49fc 13651 uint64_t si;
66543521
AM
13652 unsigned long maxlength = 0;
13653 unsigned long nzero_counts = 0;
13654 unsigned long nsyms = 0;
6bd6a03d 13655 char *visited;
252b5132 13656
d3a49aa8
AM
13657 printf (ngettext ("\nHistogram for bucket list length "
13658 "(total of %lu bucket):\n",
13659 "\nHistogram for bucket list length "
13660 "(total of %lu buckets):\n",
978c4450
AM
13661 (unsigned long) filedata->nbuckets),
13662 (unsigned long) filedata->nbuckets);
252b5132 13663
978c4450
AM
13664 lengths = (unsigned long *) calloc (filedata->nbuckets,
13665 sizeof (*lengths));
252b5132
RH
13666 if (lengths == NULL)
13667 {
8b73c356 13668 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13669 goto err_out;
252b5132 13670 }
978c4450
AM
13671 visited = xcmalloc (filedata->nchains, 1);
13672 memset (visited, 0, filedata->nchains);
8b73c356
NC
13673
13674 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13675 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13676 {
978c4450 13677 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13678 {
b34976b6 13679 ++nsyms;
252b5132 13680 if (maxlength < ++lengths[hn])
b34976b6 13681 ++maxlength;
978c4450 13682 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13683 {
13684 error (_("histogram chain is corrupt\n"));
13685 break;
13686 }
13687 visited[si] = 1;
252b5132
RH
13688 }
13689 }
6bd6a03d 13690 free (visited);
252b5132 13691
3f5e193b 13692 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13693 if (counts == NULL)
13694 {
b2e951ec 13695 free (lengths);
8b73c356 13696 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13697 goto err_out;
252b5132
RH
13698 }
13699
978c4450 13700 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13701 ++counts[lengths[hn]];
252b5132 13702
978c4450 13703 if (filedata->nbuckets > 0)
252b5132 13704 {
66543521
AM
13705 unsigned long i;
13706 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13707 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13708 for (i = 1; i <= maxlength; ++i)
103f02d3 13709 {
66543521
AM
13710 nzero_counts += counts[i] * i;
13711 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13712 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13713 (nzero_counts * 100.0) / nsyms);
13714 }
252b5132
RH
13715 }
13716
13717 free (counts);
13718 free (lengths);
13719 }
13720
978c4450
AM
13721 free (filedata->buckets);
13722 filedata->buckets = NULL;
13723 filedata->nbuckets = 0;
13724 free (filedata->chains);
13725 filedata->chains = NULL;
252b5132 13726
978c4450 13727 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13728 {
2cf0635d
NC
13729 unsigned long * lengths;
13730 unsigned long * counts;
fdc90cb4
JJ
13731 unsigned long hn;
13732 unsigned long maxlength = 0;
13733 unsigned long nzero_counts = 0;
13734 unsigned long nsyms = 0;
fdc90cb4 13735
f16a9783 13736 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13737 "(total of %lu bucket):\n",
f16a9783 13738 "\nHistogram for `%s' bucket list length "
d3a49aa8 13739 "(total of %lu buckets):\n",
978c4450
AM
13740 (unsigned long) filedata->ngnubuckets),
13741 GNU_HASH_SECTION_NAME (filedata),
13742 (unsigned long) filedata->ngnubuckets);
8b73c356 13743
978c4450
AM
13744 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13745 sizeof (*lengths));
fdc90cb4
JJ
13746 if (lengths == NULL)
13747 {
8b73c356 13748 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13749 goto err_out;
fdc90cb4
JJ
13750 }
13751
fdc90cb4
JJ
13752 printf (_(" Length Number %% of total Coverage\n"));
13753
978c4450
AM
13754 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13755 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 13756 {
625d49fc 13757 uint64_t off, length = 1;
fdc90cb4 13758
978c4450 13759 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13760 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13761 off < filedata->ngnuchains
13762 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13763 ++off)
fdc90cb4
JJ
13764 ++length;
13765 lengths[hn] = length;
13766 if (length > maxlength)
13767 maxlength = length;
13768 nsyms += length;
13769 }
13770
3f5e193b 13771 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13772 if (counts == NULL)
13773 {
b2e951ec 13774 free (lengths);
8b73c356 13775 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13776 goto err_out;
fdc90cb4
JJ
13777 }
13778
978c4450 13779 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13780 ++counts[lengths[hn]];
13781
978c4450 13782 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13783 {
13784 unsigned long j;
13785 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13786 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13787 for (j = 1; j <= maxlength; ++j)
13788 {
13789 nzero_counts += counts[j] * j;
13790 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13791 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13792 (nzero_counts * 100.0) / nsyms);
13793 }
13794 }
13795
13796 free (counts);
13797 free (lengths);
fdc90cb4 13798 }
978c4450
AM
13799 free (filedata->gnubuckets);
13800 filedata->gnubuckets = NULL;
13801 filedata->ngnubuckets = 0;
13802 free (filedata->gnuchains);
13803 filedata->gnuchains = NULL;
13804 filedata->ngnuchains = 0;
13805 free (filedata->mipsxlat);
13806 filedata->mipsxlat = NULL;
015dc7e1 13807 return true;
fd486f32
AM
13808
13809 err_out:
978c4450
AM
13810 free (filedata->gnubuckets);
13811 filedata->gnubuckets = NULL;
13812 filedata->ngnubuckets = 0;
13813 free (filedata->gnuchains);
13814 filedata->gnuchains = NULL;
13815 filedata->ngnuchains = 0;
13816 free (filedata->mipsxlat);
13817 filedata->mipsxlat = NULL;
13818 free (filedata->buckets);
13819 filedata->buckets = NULL;
13820 filedata->nbuckets = 0;
13821 free (filedata->chains);
13822 filedata->chains = NULL;
015dc7e1 13823 return false;
252b5132
RH
13824}
13825
015dc7e1 13826static bool
ca0e11aa 13827process_syminfo (Filedata * filedata)
252b5132 13828{
b4c96d0d 13829 unsigned int i;
252b5132 13830
978c4450 13831 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13832 || !do_dynamic)
13833 /* No syminfo, this is ok. */
015dc7e1 13834 return true;
252b5132
RH
13835
13836 /* There better should be a dynamic symbol section. */
978c4450 13837 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13838 return false;
252b5132 13839
ca0e11aa
NC
13840 if (filedata->is_separate)
13841 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13842 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13843 filedata->dynamic_syminfo_nent),
13844 filedata->file_name,
13845 filedata->dynamic_syminfo_offset,
13846 filedata->dynamic_syminfo_nent);
13847 else
d3a49aa8
AM
13848 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13849 "contains %d entry:\n",
13850 "\nDynamic info segment at offset 0x%lx "
13851 "contains %d entries:\n",
978c4450 13852 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13853 filedata->dynamic_syminfo_offset,
13854 filedata->dynamic_syminfo_nent);
252b5132
RH
13855
13856 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13857 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13858 {
978c4450 13859 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13860
31104126 13861 printf ("%4d: ", i);
978c4450 13862 if (i >= filedata->num_dynamic_syms)
4082ef84 13863 printf (_("<corrupt index>"));
84714f86
AM
13864 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13865 print_symbol (30, get_dynamic_name (filedata,
978c4450 13866 filedata->dynamic_symbols[i].st_name));
d79b3d50 13867 else
978c4450 13868 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13869 putchar (' ');
252b5132 13870
978c4450 13871 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13872 {
13873 case SYMINFO_BT_SELF:
13874 fputs ("SELF ", stdout);
13875 break;
13876 case SYMINFO_BT_PARENT:
13877 fputs ("PARENT ", stdout);
13878 break;
13879 default:
978c4450
AM
13880 if (filedata->dynamic_syminfo[i].si_boundto > 0
13881 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13882 && valid_dynamic_name (filedata,
978c4450 13883 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13884 {
84714f86 13885 print_symbol (10, get_dynamic_name (filedata,
978c4450 13886 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13887 putchar (' ' );
13888 }
252b5132 13889 else
978c4450 13890 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13891 break;
13892 }
13893
13894 if (flags & SYMINFO_FLG_DIRECT)
13895 printf (" DIRECT");
13896 if (flags & SYMINFO_FLG_PASSTHRU)
13897 printf (" PASSTHRU");
13898 if (flags & SYMINFO_FLG_COPY)
13899 printf (" COPY");
13900 if (flags & SYMINFO_FLG_LAZYLOAD)
13901 printf (" LAZYLOAD");
13902
13903 puts ("");
13904 }
13905
015dc7e1 13906 return true;
252b5132
RH
13907}
13908
75802ccb
CE
13909/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13910 is contained by the region START .. END. The types of ADDR, START
13911 and END should all be the same. Note both ADDR + NELEM and END
13912 point to just beyond the end of the regions that are being tested. */
13913#define IN_RANGE(START,END,ADDR,NELEM) \
13914 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13915
cf13d699
NC
13916/* Check to see if the given reloc needs to be handled in a target specific
13917 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13918 FALSE.
13919
13920 If called with reloc == NULL, then this is a signal that reloc processing
13921 for the current section has finished, and any saved state should be
13922 discarded. */
09c11c86 13923
015dc7e1 13924static bool
dda8d76d
NC
13925target_specific_reloc_handling (Filedata * filedata,
13926 Elf_Internal_Rela * reloc,
13927 unsigned char * start,
13928 unsigned char * end,
13929 Elf_Internal_Sym * symtab,
13930 unsigned long num_syms)
252b5132 13931{
f84ce13b
NC
13932 unsigned int reloc_type = 0;
13933 unsigned long sym_index = 0;
13934
13935 if (reloc)
13936 {
dda8d76d 13937 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13938 sym_index = get_reloc_symindex (reloc->r_info);
13939 }
252b5132 13940
dda8d76d 13941 switch (filedata->file_header.e_machine)
252b5132 13942 {
13761a11
NC
13943 case EM_MSP430:
13944 case EM_MSP430_OLD:
13945 {
13946 static Elf_Internal_Sym * saved_sym = NULL;
13947
f84ce13b
NC
13948 if (reloc == NULL)
13949 {
13950 saved_sym = NULL;
015dc7e1 13951 return true;
f84ce13b
NC
13952 }
13953
13761a11
NC
13954 switch (reloc_type)
13955 {
13956 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13957 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13958 if (uses_msp430x_relocs (filedata))
13761a11 13959 break;
1a0670f3 13960 /* Fall through. */
13761a11 13961 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13962 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13963 /* PR 21139. */
13964 if (sym_index >= num_syms)
13965 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13966 sym_index);
13967 else
13968 saved_sym = symtab + sym_index;
015dc7e1 13969 return true;
13761a11
NC
13970
13971 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13972 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13973 goto handle_sym_diff;
0b4362b0 13974
13761a11
NC
13975 case 5: /* R_MSP430_16_BYTE */
13976 case 9: /* R_MSP430_8 */
7d81bc93 13977 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13978 if (uses_msp430x_relocs (filedata))
13761a11
NC
13979 break;
13980 goto handle_sym_diff;
13981
13982 case 2: /* R_MSP430_ABS16 */
13983 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13984 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13985 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13986 break;
13987 goto handle_sym_diff;
0b4362b0 13988
13761a11
NC
13989 handle_sym_diff:
13990 if (saved_sym != NULL)
13991 {
625d49fc 13992 uint64_t value;
5a805384 13993 unsigned int reloc_size = 0;
7d81bc93
JL
13994 int leb_ret = 0;
13995 switch (reloc_type)
13996 {
13997 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13998 reloc_size = 4;
13999 break;
14000 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14001 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14002 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14003 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14004 &reloc_size, &leb_ret);
7d81bc93
JL
14005 break;
14006 default:
14007 reloc_size = 2;
14008 break;
14009 }
13761a11 14010
5a805384 14011 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
14012 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
14013 "ULEB128 value\n"),
14014 (long) reloc->r_offset);
14015 else if (sym_index >= num_syms)
f84ce13b
NC
14016 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
14017 sym_index);
03f7786e 14018 else
f84ce13b
NC
14019 {
14020 value = reloc->r_addend + (symtab[sym_index].st_value
14021 - saved_sym->st_value);
14022
b32e566b 14023 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14024 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14025 else
14026 /* PR 21137 */
14027 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
14028 (long) reloc->r_offset);
f84ce13b 14029 }
13761a11
NC
14030
14031 saved_sym = NULL;
015dc7e1 14032 return true;
13761a11
NC
14033 }
14034 break;
14035
14036 default:
14037 if (saved_sym != NULL)
071436c6 14038 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14039 break;
14040 }
14041 break;
14042 }
14043
cf13d699
NC
14044 case EM_MN10300:
14045 case EM_CYGNUS_MN10300:
14046 {
14047 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14048
f84ce13b
NC
14049 if (reloc == NULL)
14050 {
14051 saved_sym = NULL;
015dc7e1 14052 return true;
f84ce13b
NC
14053 }
14054
cf13d699
NC
14055 switch (reloc_type)
14056 {
14057 case 34: /* R_MN10300_ALIGN */
015dc7e1 14058 return true;
cf13d699 14059 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
14060 if (sym_index >= num_syms)
14061 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
14062 sym_index);
14063 else
14064 saved_sym = symtab + sym_index;
015dc7e1 14065 return true;
f84ce13b 14066
cf13d699
NC
14067 case 1: /* R_MN10300_32 */
14068 case 2: /* R_MN10300_16 */
14069 if (saved_sym != NULL)
14070 {
03f7786e 14071 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14072 uint64_t value;
252b5132 14073
f84ce13b
NC
14074 if (sym_index >= num_syms)
14075 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
14076 sym_index);
03f7786e 14077 else
f84ce13b
NC
14078 {
14079 value = reloc->r_addend + (symtab[sym_index].st_value
14080 - saved_sym->st_value);
14081
b32e566b 14082 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14083 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14084 else
14085 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
14086 (long) reloc->r_offset);
f84ce13b 14087 }
252b5132 14088
cf13d699 14089 saved_sym = NULL;
015dc7e1 14090 return true;
cf13d699
NC
14091 }
14092 break;
14093 default:
14094 if (saved_sym != NULL)
071436c6 14095 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14096 break;
14097 }
14098 break;
14099 }
6ff71e76
NC
14100
14101 case EM_RL78:
14102 {
625d49fc
AM
14103 static uint64_t saved_sym1 = 0;
14104 static uint64_t saved_sym2 = 0;
14105 static uint64_t value;
6ff71e76 14106
f84ce13b
NC
14107 if (reloc == NULL)
14108 {
14109 saved_sym1 = saved_sym2 = 0;
015dc7e1 14110 return true;
f84ce13b
NC
14111 }
14112
6ff71e76
NC
14113 switch (reloc_type)
14114 {
14115 case 0x80: /* R_RL78_SYM. */
14116 saved_sym1 = saved_sym2;
f84ce13b
NC
14117 if (sym_index >= num_syms)
14118 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
14119 sym_index);
14120 else
14121 {
14122 saved_sym2 = symtab[sym_index].st_value;
14123 saved_sym2 += reloc->r_addend;
14124 }
015dc7e1 14125 return true;
6ff71e76
NC
14126
14127 case 0x83: /* R_RL78_OPsub. */
14128 value = saved_sym1 - saved_sym2;
14129 saved_sym2 = saved_sym1 = 0;
015dc7e1 14130 return true;
6ff71e76
NC
14131 break;
14132
14133 case 0x41: /* R_RL78_ABS32. */
b32e566b 14134 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14135 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
14136 else
14137 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14138 (long) reloc->r_offset);
6ff71e76 14139 value = 0;
015dc7e1 14140 return true;
6ff71e76
NC
14141
14142 case 0x43: /* R_RL78_ABS16. */
b32e566b 14143 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14144 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
14145 else
14146 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14147 (long) reloc->r_offset);
6ff71e76 14148 value = 0;
015dc7e1 14149 return true;
6ff71e76
NC
14150
14151 default:
14152 break;
14153 }
14154 break;
14155 }
252b5132
RH
14156 }
14157
015dc7e1 14158 return false;
252b5132
RH
14159}
14160
aca88567
NC
14161/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14162 DWARF debug sections. This is a target specific test. Note - we do not
14163 go through the whole including-target-headers-multiple-times route, (as
14164 we have already done with <elf/h8.h>) because this would become very
14165 messy and even then this function would have to contain target specific
14166 information (the names of the relocs instead of their numeric values).
14167 FIXME: This is not the correct way to solve this problem. The proper way
14168 is to have target specific reloc sizing and typing functions created by
14169 the reloc-macros.h header, in the same way that it already creates the
14170 reloc naming functions. */
14171
015dc7e1 14172static bool
dda8d76d 14173is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14174{
d347c9df 14175 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14176 switch (filedata->file_header.e_machine)
aca88567 14177 {
41e92641 14178 case EM_386:
22abe556 14179 case EM_IAMCU:
41e92641 14180 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14181 case EM_68K:
14182 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14183 case EM_860:
14184 return reloc_type == 1; /* R_860_32. */
14185 case EM_960:
14186 return reloc_type == 2; /* R_960_32. */
a06ea964 14187 case EM_AARCH64:
9282b95a
JW
14188 return (reloc_type == 258
14189 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14190 case EM_BPF:
14191 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14192 case EM_ADAPTEVA_EPIPHANY:
14193 return reloc_type == 3;
aca88567 14194 case EM_ALPHA:
137b6b5f 14195 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14196 case EM_ARC:
14197 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14198 case EM_ARC_COMPACT:
14199 case EM_ARC_COMPACT2:
14200 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14201 case EM_ARM:
14202 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14203 case EM_AVR_OLD:
aca88567
NC
14204 case EM_AVR:
14205 return reloc_type == 1;
14206 case EM_BLACKFIN:
14207 return reloc_type == 0x12; /* R_byte4_data. */
14208 case EM_CRIS:
14209 return reloc_type == 3; /* R_CRIS_32. */
14210 case EM_CR16:
14211 return reloc_type == 3; /* R_CR16_NUM32. */
14212 case EM_CRX:
14213 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14214 case EM_CSKY:
14215 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14216 case EM_CYGNUS_FRV:
14217 return reloc_type == 1;
41e92641
NC
14218 case EM_CYGNUS_D10V:
14219 case EM_D10V:
14220 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14221 case EM_CYGNUS_D30V:
14222 case EM_D30V:
14223 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14224 case EM_DLX:
14225 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14226 case EM_CYGNUS_FR30:
14227 case EM_FR30:
14228 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14229 case EM_FT32:
14230 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14231 case EM_H8S:
14232 case EM_H8_300:
14233 case EM_H8_300H:
14234 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14235 case EM_IA_64:
262cdac7
AM
14236 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14237 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14238 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14239 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14240 case EM_IP2K_OLD:
14241 case EM_IP2K:
14242 return reloc_type == 2; /* R_IP2K_32. */
14243 case EM_IQ2000:
14244 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14245 case EM_LATTICEMICO32:
14246 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14247 case EM_LOONGARCH:
14248 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14249 case EM_M32C_OLD:
aca88567
NC
14250 case EM_M32C:
14251 return reloc_type == 3; /* R_M32C_32. */
14252 case EM_M32R:
14253 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14254 case EM_68HC11:
14255 case EM_68HC12:
14256 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14257 case EM_S12Z:
2849d19f
JD
14258 return reloc_type == 7 || /* R_S12Z_EXT32 */
14259 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14260 case EM_MCORE:
14261 return reloc_type == 1; /* R_MCORE_ADDR32. */
14262 case EM_CYGNUS_MEP:
14263 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14264 case EM_METAG:
14265 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14266 case EM_MICROBLAZE:
14267 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14268 case EM_MIPS:
14269 return reloc_type == 2; /* R_MIPS_32. */
14270 case EM_MMIX:
14271 return reloc_type == 4; /* R_MMIX_32. */
14272 case EM_CYGNUS_MN10200:
14273 case EM_MN10200:
14274 return reloc_type == 1; /* R_MN10200_32. */
14275 case EM_CYGNUS_MN10300:
14276 case EM_MN10300:
14277 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14278 case EM_MOXIE:
14279 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14280 case EM_MSP430_OLD:
14281 case EM_MSP430:
13761a11 14282 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14283 case EM_MT:
14284 return reloc_type == 2; /* R_MT_32. */
35c08157 14285 case EM_NDS32:
81c5e376 14286 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14287 case EM_ALTERA_NIOS2:
36591ba1 14288 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14289 case EM_NIOS32:
14290 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14291 case EM_OR1K:
14292 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14293 case EM_PARISC:
9abca702 14294 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14295 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14296 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14297 case EM_PJ:
14298 case EM_PJ_OLD:
14299 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14300 case EM_PPC64:
14301 return reloc_type == 1; /* R_PPC64_ADDR32. */
14302 case EM_PPC:
14303 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14304 case EM_TI_PRU:
14305 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14306 case EM_RISCV:
14307 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14308 case EM_RL78:
14309 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14310 case EM_RX:
14311 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14312 case EM_S370:
14313 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14314 case EM_S390_OLD:
14315 case EM_S390:
14316 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14317 case EM_SCORE:
14318 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14319 case EM_SH:
14320 return reloc_type == 1; /* R_SH_DIR32. */
14321 case EM_SPARC32PLUS:
14322 case EM_SPARCV9:
14323 case EM_SPARC:
14324 return reloc_type == 3 /* R_SPARC_32. */
14325 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14326 case EM_SPU:
14327 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14328 case EM_TI_C6000:
14329 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14330 case EM_TILEGX:
14331 return reloc_type == 2; /* R_TILEGX_32. */
14332 case EM_TILEPRO:
14333 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14334 case EM_CYGNUS_V850:
14335 case EM_V850:
14336 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14337 case EM_V800:
14338 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14339 case EM_VAX:
14340 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14341 case EM_VISIUM:
14342 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14343 case EM_WEBASSEMBLY:
14344 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14345 case EM_X86_64:
8a9036a4 14346 case EM_L1OM:
7a9068fe 14347 case EM_K1OM:
aca88567 14348 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14349 case EM_XGATE:
14350 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14351 case EM_XSTORMY16:
14352 return reloc_type == 1; /* R_XSTROMY16_32. */
14353 case EM_XTENSA_OLD:
14354 case EM_XTENSA:
14355 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14356 case EM_Z80:
14357 return reloc_type == 6; /* R_Z80_32. */
aca88567 14358 default:
bee0ee85
NC
14359 {
14360 static unsigned int prev_warn = 0;
14361
14362 /* Avoid repeating the same warning multiple times. */
dda8d76d 14363 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14364 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14365 filedata->file_header.e_machine);
14366 prev_warn = filedata->file_header.e_machine;
015dc7e1 14367 return false;
bee0ee85 14368 }
aca88567
NC
14369 }
14370}
14371
14372/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14373 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14374
015dc7e1 14375static bool
dda8d76d 14376is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14377{
dda8d76d 14378 switch (filedata->file_header.e_machine)
d347c9df 14379 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14380 {
41e92641 14381 case EM_386:
22abe556 14382 case EM_IAMCU:
3e0873ac 14383 return reloc_type == 2; /* R_386_PC32. */
aca88567 14384 case EM_68K:
3e0873ac 14385 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14386 case EM_AARCH64:
14387 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14388 case EM_ADAPTEVA_EPIPHANY:
14389 return reloc_type == 6;
aca88567
NC
14390 case EM_ALPHA:
14391 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14392 case EM_ARC_COMPACT:
14393 case EM_ARC_COMPACT2:
14394 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14395 case EM_ARM:
3e0873ac 14396 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14397 case EM_AVR_OLD:
14398 case EM_AVR:
14399 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14400 case EM_LOONGARCH:
14401 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14402 case EM_MICROBLAZE:
14403 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14404 case EM_OR1K:
14405 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14406 case EM_PARISC:
85acf597 14407 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14408 case EM_PPC:
14409 return reloc_type == 26; /* R_PPC_REL32. */
14410 case EM_PPC64:
3e0873ac 14411 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14412 case EM_RISCV:
14413 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14414 case EM_S390_OLD:
14415 case EM_S390:
3e0873ac 14416 return reloc_type == 5; /* R_390_PC32. */
aca88567 14417 case EM_SH:
3e0873ac 14418 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14419 case EM_SPARC32PLUS:
14420 case EM_SPARCV9:
14421 case EM_SPARC:
3e0873ac 14422 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14423 case EM_SPU:
14424 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14425 case EM_TILEGX:
14426 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14427 case EM_TILEPRO:
14428 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14429 case EM_VISIUM:
14430 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14431 case EM_X86_64:
8a9036a4 14432 case EM_L1OM:
7a9068fe 14433 case EM_K1OM:
3e0873ac 14434 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14435 case EM_VAX:
14436 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14437 case EM_XTENSA_OLD:
14438 case EM_XTENSA:
14439 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14440 default:
14441 /* Do not abort or issue an error message here. Not all targets use
14442 pc-relative 32-bit relocs in their DWARF debug information and we
14443 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14444 more helpful warning message will be generated by apply_relocations
14445 anyway, so just return. */
015dc7e1 14446 return false;
aca88567
NC
14447 }
14448}
14449
14450/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14451 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14452
015dc7e1 14453static bool
dda8d76d 14454is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14455{
dda8d76d 14456 switch (filedata->file_header.e_machine)
aca88567 14457 {
a06ea964
NC
14458 case EM_AARCH64:
14459 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14460 case EM_ALPHA:
14461 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14462 case EM_IA_64:
262cdac7
AM
14463 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14464 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14465 case EM_LOONGARCH:
14466 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14467 case EM_PARISC:
14468 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14469 case EM_PPC64:
14470 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14471 case EM_RISCV:
14472 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14473 case EM_SPARC32PLUS:
14474 case EM_SPARCV9:
14475 case EM_SPARC:
714da62f
NC
14476 return reloc_type == 32 /* R_SPARC_64. */
14477 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14478 case EM_X86_64:
8a9036a4 14479 case EM_L1OM:
7a9068fe 14480 case EM_K1OM:
aca88567 14481 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14482 case EM_S390_OLD:
14483 case EM_S390:
aa137e4d
NC
14484 return reloc_type == 22; /* R_S390_64. */
14485 case EM_TILEGX:
14486 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14487 case EM_MIPS:
aa137e4d 14488 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14489 default:
015dc7e1 14490 return false;
aca88567
NC
14491 }
14492}
14493
85acf597
RH
14494/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14495 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14496
015dc7e1 14497static bool
dda8d76d 14498is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14499{
dda8d76d 14500 switch (filedata->file_header.e_machine)
85acf597 14501 {
a06ea964
NC
14502 case EM_AARCH64:
14503 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14504 case EM_ALPHA:
aa137e4d 14505 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14506 case EM_IA_64:
262cdac7
AM
14507 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14508 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14509 case EM_PARISC:
aa137e4d 14510 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14511 case EM_PPC64:
aa137e4d 14512 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14513 case EM_SPARC32PLUS:
14514 case EM_SPARCV9:
14515 case EM_SPARC:
aa137e4d 14516 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14517 case EM_X86_64:
8a9036a4 14518 case EM_L1OM:
7a9068fe 14519 case EM_K1OM:
aa137e4d 14520 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14521 case EM_S390_OLD:
14522 case EM_S390:
aa137e4d
NC
14523 return reloc_type == 23; /* R_S390_PC64. */
14524 case EM_TILEGX:
14525 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14526 default:
015dc7e1 14527 return false;
85acf597
RH
14528 }
14529}
14530
4dc3c23d
AM
14531/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14532 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14533
015dc7e1 14534static bool
dda8d76d 14535is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14536{
dda8d76d 14537 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14538 {
14539 case EM_CYGNUS_MN10200:
14540 case EM_MN10200:
14541 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14542 case EM_FT32:
14543 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14544 case EM_Z80:
14545 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14546 default:
015dc7e1 14547 return false;
4dc3c23d
AM
14548 }
14549}
14550
aca88567
NC
14551/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14552 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14553
015dc7e1 14554static bool
dda8d76d 14555is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14556{
d347c9df 14557 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14558 switch (filedata->file_header.e_machine)
4b78141a 14559 {
886a2506
NC
14560 case EM_ARC:
14561 case EM_ARC_COMPACT:
14562 case EM_ARC_COMPACT2:
14563 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14564 case EM_ADAPTEVA_EPIPHANY:
14565 return reloc_type == 5;
aca88567
NC
14566 case EM_AVR_OLD:
14567 case EM_AVR:
14568 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14569 case EM_CYGNUS_D10V:
14570 case EM_D10V:
14571 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14572 case EM_FT32:
14573 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14574 case EM_H8S:
14575 case EM_H8_300:
14576 case EM_H8_300H:
aca88567
NC
14577 return reloc_type == R_H8_DIR16;
14578 case EM_IP2K_OLD:
14579 case EM_IP2K:
14580 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14581 case EM_M32C_OLD:
f4236fe4
DD
14582 case EM_M32C:
14583 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14584 case EM_CYGNUS_MN10200:
14585 case EM_MN10200:
14586 return reloc_type == 2; /* R_MN10200_16. */
14587 case EM_CYGNUS_MN10300:
14588 case EM_MN10300:
14589 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14590 case EM_MSP430:
dda8d76d 14591 if (uses_msp430x_relocs (filedata))
13761a11 14592 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14593 /* Fall through. */
78c8d46c 14594 case EM_MSP430_OLD:
aca88567 14595 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 14596 case EM_NDS32:
81c5e376 14597 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 14598 case EM_ALTERA_NIOS2:
36591ba1 14599 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14600 case EM_NIOS32:
14601 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14602 case EM_OR1K:
14603 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14604 case EM_RISCV:
14605 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14606 case EM_TI_PRU:
14607 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14608 case EM_TI_C6000:
14609 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14610 case EM_VISIUM:
14611 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
14612 case EM_XGATE:
14613 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14614 case EM_Z80:
14615 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14616 default:
015dc7e1 14617 return false;
4b78141a
NC
14618 }
14619}
14620
39e07931
AS
14621/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14622 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14623
015dc7e1 14624static bool
39e07931
AS
14625is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14626{
14627 switch (filedata->file_header.e_machine)
14628 {
14629 case EM_RISCV:
14630 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14631 case EM_Z80:
14632 return reloc_type == 1; /* R_Z80_8. */
39e07931 14633 default:
015dc7e1 14634 return false;
39e07931
AS
14635 }
14636}
14637
14638/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14639 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14640
015dc7e1 14641static bool
39e07931
AS
14642is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14643{
14644 switch (filedata->file_header.e_machine)
14645 {
14646 case EM_RISCV:
14647 return reloc_type == 53; /* R_RISCV_SET6. */
14648 default:
015dc7e1 14649 return false;
39e07931
AS
14650 }
14651}
14652
03336641
JW
14653/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14654 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14655
015dc7e1 14656static bool
03336641
JW
14657is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14658{
14659 /* Please keep this table alpha-sorted for ease of visual lookup. */
14660 switch (filedata->file_header.e_machine)
14661 {
14662 case EM_RISCV:
14663 return reloc_type == 35; /* R_RISCV_ADD32. */
14664 default:
015dc7e1 14665 return false;
03336641
JW
14666 }
14667}
14668
14669/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14670 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14671
015dc7e1 14672static bool
03336641
JW
14673is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14674{
14675 /* Please keep this table alpha-sorted for ease of visual lookup. */
14676 switch (filedata->file_header.e_machine)
14677 {
14678 case EM_RISCV:
14679 return reloc_type == 39; /* R_RISCV_SUB32. */
14680 default:
015dc7e1 14681 return false;
03336641
JW
14682 }
14683}
14684
14685/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14686 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14687
015dc7e1 14688static bool
03336641
JW
14689is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14690{
14691 /* Please keep this table alpha-sorted for ease of visual lookup. */
14692 switch (filedata->file_header.e_machine)
14693 {
14694 case EM_RISCV:
14695 return reloc_type == 36; /* R_RISCV_ADD64. */
14696 default:
015dc7e1 14697 return false;
03336641
JW
14698 }
14699}
14700
14701/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14702 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14703
015dc7e1 14704static bool
03336641
JW
14705is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14706{
14707 /* Please keep this table alpha-sorted for ease of visual lookup. */
14708 switch (filedata->file_header.e_machine)
14709 {
14710 case EM_RISCV:
14711 return reloc_type == 40; /* R_RISCV_SUB64. */
14712 default:
015dc7e1 14713 return false;
03336641
JW
14714 }
14715}
14716
14717/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14718 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14719
015dc7e1 14720static bool
03336641
JW
14721is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14722{
14723 /* Please keep this table alpha-sorted for ease of visual lookup. */
14724 switch (filedata->file_header.e_machine)
14725 {
14726 case EM_RISCV:
14727 return reloc_type == 34; /* R_RISCV_ADD16. */
14728 default:
015dc7e1 14729 return false;
03336641
JW
14730 }
14731}
14732
14733/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14734 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14735
015dc7e1 14736static bool
03336641
JW
14737is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14738{
14739 /* Please keep this table alpha-sorted for ease of visual lookup. */
14740 switch (filedata->file_header.e_machine)
14741 {
14742 case EM_RISCV:
14743 return reloc_type == 38; /* R_RISCV_SUB16. */
14744 default:
015dc7e1 14745 return false;
03336641
JW
14746 }
14747}
14748
14749/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14750 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14751
015dc7e1 14752static bool
03336641
JW
14753is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14754{
14755 /* Please keep this table alpha-sorted for ease of visual lookup. */
14756 switch (filedata->file_header.e_machine)
14757 {
14758 case EM_RISCV:
14759 return reloc_type == 33; /* R_RISCV_ADD8. */
14760 default:
015dc7e1 14761 return false;
03336641
JW
14762 }
14763}
14764
14765/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14766 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14767
015dc7e1 14768static bool
03336641
JW
14769is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14770{
14771 /* Please keep this table alpha-sorted for ease of visual lookup. */
14772 switch (filedata->file_header.e_machine)
14773 {
14774 case EM_RISCV:
14775 return reloc_type == 37; /* R_RISCV_SUB8. */
14776 default:
015dc7e1 14777 return false;
03336641
JW
14778 }
14779}
14780
39e07931
AS
14781/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14782 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14783
015dc7e1 14784static bool
39e07931
AS
14785is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14786{
14787 switch (filedata->file_header.e_machine)
14788 {
14789 case EM_RISCV:
14790 return reloc_type == 52; /* R_RISCV_SUB6. */
14791 default:
015dc7e1 14792 return false;
39e07931
AS
14793 }
14794}
14795
2a7b2e88
JK
14796/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14797 relocation entries (possibly formerly used for SHT_GROUP sections). */
14798
015dc7e1 14799static bool
dda8d76d 14800is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14801{
dda8d76d 14802 switch (filedata->file_header.e_machine)
2a7b2e88 14803 {
cb8f3167 14804 case EM_386: /* R_386_NONE. */
d347c9df 14805 case EM_68K: /* R_68K_NONE. */
cfb8c092 14806 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14807 case EM_ALPHA: /* R_ALPHA_NONE. */
14808 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14809 case EM_ARC: /* R_ARC_NONE. */
886a2506 14810 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14811 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14812 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 14813 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14814 case EM_FT32: /* R_FT32_NONE. */
14815 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14816 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14817 case EM_L1OM: /* R_X86_64_NONE. */
14818 case EM_M32R: /* R_M32R_NONE. */
14819 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14820 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14821 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14822 case EM_NIOS32: /* R_NIOS_NONE. */
14823 case EM_OR1K: /* R_OR1K_NONE. */
14824 case EM_PARISC: /* R_PARISC_NONE. */
14825 case EM_PPC64: /* R_PPC64_NONE. */
14826 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14827 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14828 case EM_S390: /* R_390_NONE. */
14829 case EM_S390_OLD:
14830 case EM_SH: /* R_SH_NONE. */
14831 case EM_SPARC32PLUS:
14832 case EM_SPARC: /* R_SPARC_NONE. */
14833 case EM_SPARCV9:
aa137e4d
NC
14834 case EM_TILEGX: /* R_TILEGX_NONE. */
14835 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14836 case EM_TI_C6000:/* R_C6000_NONE. */
14837 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 14838 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14839 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14840 return reloc_type == 0;
d347c9df 14841
a06ea964
NC
14842 case EM_AARCH64:
14843 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14844 case EM_AVR_OLD:
14845 case EM_AVR:
14846 return (reloc_type == 0 /* R_AVR_NONE. */
14847 || reloc_type == 30 /* R_AVR_DIFF8. */
14848 || reloc_type == 31 /* R_AVR_DIFF16. */
14849 || reloc_type == 32 /* R_AVR_DIFF32. */);
14850 case EM_METAG:
14851 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 14852 case EM_NDS32:
81c5e376
AM
14853 return (reloc_type == 0 /* R_NDS32_NONE. */
14854 || reloc_type == 205 /* R_NDS32_DIFF8. */
14855 || reloc_type == 206 /* R_NDS32_DIFF16. */
14856 || reloc_type == 207 /* R_NDS32_DIFF32. */
14857 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
14858 case EM_TI_PRU:
14859 return (reloc_type == 0 /* R_PRU_NONE. */
14860 || reloc_type == 65 /* R_PRU_DIFF8. */
14861 || reloc_type == 66 /* R_PRU_DIFF16. */
14862 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14863 case EM_XTENSA_OLD:
14864 case EM_XTENSA:
4dc3c23d
AM
14865 return (reloc_type == 0 /* R_XTENSA_NONE. */
14866 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14867 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14868 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14869 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14870 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14871 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14872 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14873 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14874 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14875 }
015dc7e1 14876 return false;
2a7b2e88
JK
14877}
14878
d1c4b12b
NC
14879/* Returns TRUE if there is a relocation against
14880 section NAME at OFFSET bytes. */
14881
015dc7e1 14882bool
31e5a3a3 14883reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
14884{
14885 Elf_Internal_Rela * relocs;
14886 Elf_Internal_Rela * rp;
14887
14888 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14889 return false;
d1c4b12b
NC
14890
14891 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14892
14893 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14894 if (rp->r_offset == offset)
015dc7e1 14895 return true;
d1c4b12b 14896
015dc7e1 14897 return false;
d1c4b12b
NC
14898}
14899
cf13d699 14900/* Apply relocations to a section.
32ec8896
NC
14901 Returns TRUE upon success, FALSE otherwise.
14902 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14903 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14904 will be set to the number of relocs loaded.
14905
cf13d699 14906 Note: So far support has been added only for those relocations
32ec8896
NC
14907 which can be found in debug sections. FIXME: Add support for
14908 more relocations ? */
1b315056 14909
015dc7e1 14910static bool
be7d229a
AM
14911apply_relocations (Filedata *filedata,
14912 const Elf_Internal_Shdr *section,
14913 unsigned char *start,
14914 size_t size,
14915 void **relocs_return,
14916 unsigned long *num_relocs_return)
1b315056 14917{
cf13d699 14918 Elf_Internal_Shdr * relsec;
0d2a7a93 14919 unsigned char * end = start + size;
cb8f3167 14920
d1c4b12b
NC
14921 if (relocs_return != NULL)
14922 {
14923 * (Elf_Internal_Rela **) relocs_return = NULL;
14924 * num_relocs_return = 0;
14925 }
14926
dda8d76d 14927 if (filedata->file_header.e_type != ET_REL)
32ec8896 14928 /* No relocs to apply. */
015dc7e1 14929 return true;
1b315056 14930
cf13d699 14931 /* Find the reloc section associated with the section. */
dda8d76d
NC
14932 for (relsec = filedata->section_headers;
14933 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14934 ++relsec)
252b5132 14935 {
015dc7e1 14936 bool is_rela;
41e92641 14937 unsigned long num_relocs;
2cf0635d
NC
14938 Elf_Internal_Rela * relocs;
14939 Elf_Internal_Rela * rp;
14940 Elf_Internal_Shdr * symsec;
14941 Elf_Internal_Sym * symtab;
ba5cdace 14942 unsigned long num_syms;
2cf0635d 14943 Elf_Internal_Sym * sym;
252b5132 14944
41e92641 14945 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14946 || relsec->sh_info >= filedata->file_header.e_shnum
14947 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14948 || relsec->sh_size == 0
dda8d76d 14949 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14950 continue;
428409d5 14951
a788aedd
AM
14952 symsec = filedata->section_headers + relsec->sh_link;
14953 if (symsec->sh_type != SHT_SYMTAB
14954 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14955 return false;
a788aedd 14956
41e92641
NC
14957 is_rela = relsec->sh_type == SHT_RELA;
14958
14959 if (is_rela)
14960 {
dda8d76d 14961 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14962 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14963 return false;
41e92641
NC
14964 }
14965 else
14966 {
dda8d76d 14967 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14968 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14969 return false;
41e92641
NC
14970 }
14971
14972 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14973 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14974 is_rela = false;
428409d5 14975
4de91c10 14976 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14977
41e92641 14978 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14979 {
625d49fc 14980 uint64_t addend;
015dc7e1
AM
14981 unsigned int reloc_type;
14982 unsigned int reloc_size;
14983 bool reloc_inplace = false;
14984 bool reloc_subtract = false;
14985 unsigned char *rloc;
14986 unsigned long sym_index;
4b78141a 14987
dda8d76d 14988 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14989
dda8d76d 14990 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14991 continue;
dda8d76d 14992 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14993 continue;
dda8d76d
NC
14994 else if (is_32bit_abs_reloc (filedata, reloc_type)
14995 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14996 reloc_size = 4;
dda8d76d
NC
14997 else if (is_64bit_abs_reloc (filedata, reloc_type)
14998 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14999 reloc_size = 8;
dda8d76d 15000 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15001 reloc_size = 3;
dda8d76d 15002 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15003 reloc_size = 2;
39e07931
AS
15004 else if (is_8bit_abs_reloc (filedata, reloc_type)
15005 || is_6bit_abs_reloc (filedata, reloc_type))
15006 reloc_size = 1;
03336641
JW
15007 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15008 reloc_type))
15009 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15010 {
15011 reloc_size = 4;
015dc7e1 15012 reloc_inplace = true;
03336641
JW
15013 }
15014 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15015 reloc_type))
15016 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15017 {
15018 reloc_size = 8;
015dc7e1 15019 reloc_inplace = true;
03336641
JW
15020 }
15021 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15022 reloc_type))
15023 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15024 {
15025 reloc_size = 2;
015dc7e1 15026 reloc_inplace = true;
03336641
JW
15027 }
15028 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15029 reloc_type))
15030 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15031 {
15032 reloc_size = 1;
015dc7e1 15033 reloc_inplace = true;
03336641 15034 }
39e07931
AS
15035 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
15036 reloc_type)))
15037 {
15038 reloc_size = 1;
015dc7e1 15039 reloc_inplace = true;
39e07931 15040 }
aca88567 15041 else
4b78141a 15042 {
bee0ee85 15043 static unsigned int prev_reloc = 0;
dda8d76d 15044
bee0ee85
NC
15045 if (reloc_type != prev_reloc)
15046 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15047 reloc_type, printable_section_name (filedata, section));
bee0ee85 15048 prev_reloc = reloc_type;
4b78141a
NC
15049 continue;
15050 }
103f02d3 15051
91d6fa6a 15052 rloc = start + rp->r_offset;
75802ccb 15053 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
15054 {
15055 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
15056 (unsigned long) rp->r_offset,
dda8d76d 15057 printable_section_name (filedata, section));
700dd8b7
L
15058 continue;
15059 }
103f02d3 15060
ba5cdace
NC
15061 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
15062 if (sym_index >= num_syms)
15063 {
15064 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 15065 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15066 continue;
15067 }
15068 sym = symtab + sym_index;
41e92641
NC
15069
15070 /* If the reloc has a symbol associated with it,
55f25fc3
L
15071 make sure that it is of an appropriate type.
15072
15073 Relocations against symbols without type can happen.
15074 Gcc -feliminate-dwarf2-dups may generate symbols
15075 without type for debug info.
15076
15077 Icc generates relocations against function symbols
15078 instead of local labels.
15079
15080 Relocations against object symbols can happen, eg when
15081 referencing a global array. For an example of this see
15082 the _clz.o binary in libgcc.a. */
aca88567 15083 if (sym != symtab
b8871f35 15084 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15085 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15086 {
d3a49aa8 15087 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
15088 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15089 printable_section_name (filedata, relsec),
d3a49aa8 15090 (long int)(rp - relocs));
aca88567 15091 continue;
5b18a4bc 15092 }
252b5132 15093
4dc3c23d
AM
15094 addend = 0;
15095 if (is_rela)
15096 addend += rp->r_addend;
c47320c3
AM
15097 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15098 partial_inplace. */
4dc3c23d 15099 if (!is_rela
dda8d76d 15100 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15101 && reloc_type == 1)
dda8d76d
NC
15102 || ((filedata->file_header.e_machine == EM_PJ
15103 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15104 && reloc_type == 1)
dda8d76d
NC
15105 || ((filedata->file_header.e_machine == EM_D30V
15106 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15107 && reloc_type == 12)
15108 || reloc_inplace)
39e07931
AS
15109 {
15110 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15111 addend += byte_get (rloc, reloc_size) & 0x3f;
15112 else
15113 addend += byte_get (rloc, reloc_size);
15114 }
cb8f3167 15115
dda8d76d
NC
15116 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15117 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15118 {
15119 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15120 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15121 addend -= 8;
91d6fa6a 15122 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15123 reloc_size);
15124 }
39e07931
AS
15125 else if (is_6bit_abs_reloc (filedata, reloc_type)
15126 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
15127 {
15128 if (reloc_subtract)
15129 addend -= sym->st_value;
15130 else
15131 addend += sym->st_value;
15132 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15133 byte_put (rloc, addend, reloc_size);
15134 }
03336641
JW
15135 else if (reloc_subtract)
15136 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15137 else
91d6fa6a 15138 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15139 }
252b5132 15140
5b18a4bc 15141 free (symtab);
f84ce13b
NC
15142 /* Let the target specific reloc processing code know that
15143 we have finished with these relocs. */
dda8d76d 15144 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15145
15146 if (relocs_return)
15147 {
15148 * (Elf_Internal_Rela **) relocs_return = relocs;
15149 * num_relocs_return = num_relocs;
15150 }
15151 else
15152 free (relocs);
15153
5b18a4bc
NC
15154 break;
15155 }
32ec8896 15156
015dc7e1 15157 return true;
5b18a4bc 15158}
103f02d3 15159
cf13d699 15160#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15161static bool
dda8d76d 15162disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15163{
dda8d76d 15164 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15165
74e1a04b 15166 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15167
015dc7e1 15168 return true;
cf13d699
NC
15169}
15170#endif
15171
15172/* Reads in the contents of SECTION from FILE, returning a pointer
15173 to a malloc'ed buffer or NULL if something went wrong. */
15174
15175static char *
dda8d76d 15176get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15177{
be7d229a 15178 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15179
15180 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15181 {
c6b78c96 15182 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15183 printable_section_name (filedata, section));
cf13d699
NC
15184 return NULL;
15185 }
15186
dda8d76d 15187 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15188 _("section contents"));
cf13d699
NC
15189}
15190
1f5a3546 15191/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 15192
015dc7e1 15193static bool
1f5a3546
FS
15194uncompress_section_contents (bool is_zstd, unsigned char **buffer,
15195 uint64_t uncompressed_size, uint64_t *size)
0e602686 15196{
31e5a3a3
AM
15197 uint64_t compressed_size = *size;
15198 unsigned char *compressed_buffer = *buffer;
1f5a3546 15199 unsigned char *uncompressed_buffer = xmalloc (uncompressed_size);
0e602686
NC
15200 z_stream strm;
15201 int rc;
15202
1f5a3546
FS
15203 if (is_zstd)
15204 {
15205#ifdef HAVE_ZSTD
15206 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15207 compressed_buffer, compressed_size);
15208 if (ZSTD_isError (ret))
15209 goto fail;
15210#endif
15211 }
15212 else
15213 {
15214 /* It is possible the section consists of several compressed
15215 buffers concatenated together, so we uncompress in a loop. */
15216 /* PR 18313: The state field in the z_stream structure is supposed
15217 to be invisible to the user (ie us), but some compilers will
15218 still complain about it being used without initialisation. So
15219 we first zero the entire z_stream structure and then set the fields
15220 that we need. */
15221 memset (&strm, 0, sizeof strm);
15222 strm.avail_in = compressed_size;
15223 strm.next_in = (Bytef *)compressed_buffer;
15224 strm.avail_out = uncompressed_size;
15225
15226 rc = inflateInit (&strm);
15227 while (strm.avail_in > 0)
15228 {
15229 if (rc != Z_OK)
15230 break;
15231 strm.next_out = ((Bytef *)uncompressed_buffer
15232 + (uncompressed_size - strm.avail_out));
15233 rc = inflate (&strm, Z_FINISH);
15234 if (rc != Z_STREAM_END)
15235 break;
15236 rc = inflateReset (&strm);
15237 }
15238 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15239 goto fail;
15240 }
0e602686
NC
15241
15242 *buffer = uncompressed_buffer;
15243 *size = uncompressed_size;
015dc7e1 15244 return true;
0e602686
NC
15245
15246 fail:
15247 free (uncompressed_buffer);
15248 /* Indicate decompression failure. */
15249 *buffer = NULL;
015dc7e1 15250 return false;
0e602686 15251}
dd24e3da 15252
015dc7e1 15253static bool
dda8d76d 15254dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15255{
015dc7e1 15256 Elf_Internal_Shdr *relsec;
be7d229a 15257 uint64_t num_bytes;
015dc7e1
AM
15258 unsigned char *data;
15259 unsigned char *end;
15260 unsigned char *real_start;
15261 unsigned char *start;
15262 bool some_strings_shown;
cf13d699 15263
dda8d76d 15264 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15265 if (start == NULL)
c6b78c96 15266 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15267 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15268
0e602686 15269 num_bytes = section->sh_size;
cf13d699 15270
835f2fae
NC
15271 if (filedata->is_separate)
15272 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15273 printable_section_name (filedata, section),
15274 filedata->file_name);
15275 else
15276 printf (_("\nString dump of section '%s':\n"),
15277 printable_section_name (filedata, section));
cf13d699 15278
0e602686
NC
15279 if (decompress_dumps)
15280 {
31e5a3a3
AM
15281 uint64_t new_size = num_bytes;
15282 uint64_t uncompressed_size = 0;
1f5a3546 15283 bool is_zstd = false;
0e602686
NC
15284
15285 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15286 {
15287 Elf_Internal_Chdr chdr;
15288 unsigned int compression_header_size
ebdf1ebf
NC
15289 = get_compression_header (& chdr, (unsigned char *) start,
15290 num_bytes);
5844b465
NC
15291 if (compression_header_size == 0)
15292 /* An error message will have already been generated
15293 by get_compression_header. */
15294 goto error_out;
0e602686 15295
1f5a3546
FS
15296 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
15297 ;
15298#ifdef HAVE_ZSTD
15299 else if (chdr.ch_type == ELFCOMPRESS_ZSTD)
15300 is_zstd = true;
15301#endif
15302 else
0e602686 15303 {
813dabb9 15304 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15305 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15306 goto error_out;
813dabb9 15307 }
813dabb9
L
15308 uncompressed_size = chdr.ch_size;
15309 start += compression_header_size;
15310 new_size -= compression_header_size;
0e602686
NC
15311 }
15312 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15313 {
15314 /* Read the zlib header. In this case, it should be "ZLIB"
15315 followed by the uncompressed section size, 8 bytes in
15316 big-endian order. */
15317 uncompressed_size = start[4]; uncompressed_size <<= 8;
15318 uncompressed_size += start[5]; uncompressed_size <<= 8;
15319 uncompressed_size += start[6]; uncompressed_size <<= 8;
15320 uncompressed_size += start[7]; uncompressed_size <<= 8;
15321 uncompressed_size += start[8]; uncompressed_size <<= 8;
15322 uncompressed_size += start[9]; uncompressed_size <<= 8;
15323 uncompressed_size += start[10]; uncompressed_size <<= 8;
15324 uncompressed_size += start[11];
15325 start += 12;
15326 new_size -= 12;
15327 }
15328
1835f746
NC
15329 if (uncompressed_size)
15330 {
1f5a3546
FS
15331 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
15332 &new_size))
1835f746
NC
15333 num_bytes = new_size;
15334 else
15335 {
15336 error (_("Unable to decompress section %s\n"),
dda8d76d 15337 printable_section_name (filedata, section));
f761cb13 15338 goto error_out;
1835f746
NC
15339 }
15340 }
bc303e5d
NC
15341 else
15342 start = real_start;
0e602686 15343 }
fd8008d8 15344
cf13d699
NC
15345 /* If the section being dumped has relocations against it the user might
15346 be expecting these relocations to have been applied. Check for this
15347 case and issue a warning message in order to avoid confusion.
15348 FIXME: Maybe we ought to have an option that dumps a section with
15349 relocs applied ? */
dda8d76d
NC
15350 for (relsec = filedata->section_headers;
15351 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15352 ++relsec)
15353 {
15354 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15355 || relsec->sh_info >= filedata->file_header.e_shnum
15356 || filedata->section_headers + relsec->sh_info != section
cf13d699 15357 || relsec->sh_size == 0
dda8d76d 15358 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15359 continue;
15360
15361 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15362 break;
15363 }
15364
cf13d699
NC
15365 data = start;
15366 end = start + num_bytes;
015dc7e1 15367 some_strings_shown = false;
cf13d699 15368
ba3265d0
NC
15369#ifdef HAVE_MBSTATE_T
15370 mbstate_t state;
15371 /* Initialise the multibyte conversion state. */
15372 memset (& state, 0, sizeof (state));
15373#endif
15374
015dc7e1 15375 bool continuing = false;
ba3265d0 15376
cf13d699
NC
15377 while (data < end)
15378 {
15379 while (!ISPRINT (* data))
15380 if (++ data >= end)
15381 break;
15382
15383 if (data < end)
15384 {
071436c6
NC
15385 size_t maxlen = end - data;
15386
ba3265d0
NC
15387 if (continuing)
15388 {
15389 printf (" ");
015dc7e1 15390 continuing = false;
ba3265d0
NC
15391 }
15392 else
15393 {
d1ce973e 15394 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
15395 }
15396
4082ef84
NC
15397 if (maxlen > 0)
15398 {
f3da8a96 15399 char c = 0;
ba3265d0
NC
15400
15401 while (maxlen)
15402 {
15403 c = *data++;
15404
15405 if (c == 0)
15406 break;
15407
15408 /* PR 25543: Treat new-lines as string-ending characters. */
15409 if (c == '\n')
15410 {
15411 printf ("\\n\n");
15412 if (*data != 0)
015dc7e1 15413 continuing = true;
ba3265d0
NC
15414 break;
15415 }
15416
15417 /* Do not print control characters directly as they can affect terminal
15418 settings. Such characters usually appear in the names generated
15419 by the assembler for local labels. */
15420 if (ISCNTRL (c))
15421 {
15422 printf ("^%c", c + 0x40);
15423 }
15424 else if (ISPRINT (c))
15425 {
15426 putchar (c);
15427 }
15428 else
15429 {
15430 size_t n;
15431#ifdef HAVE_MBSTATE_T
15432 wchar_t w;
15433#endif
15434 /* Let printf do the hard work of displaying multibyte characters. */
15435 printf ("%.1s", data - 1);
15436#ifdef HAVE_MBSTATE_T
15437 /* Try to find out how many bytes made up the character that was
15438 just printed. Advance the symbol pointer past the bytes that
15439 were displayed. */
15440 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15441#else
15442 n = 1;
15443#endif
15444 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15445 data += (n - 1);
15446 }
15447 }
15448
15449 if (c != '\n')
15450 putchar ('\n');
4082ef84
NC
15451 }
15452 else
15453 {
15454 printf (_("<corrupt>\n"));
15455 data = end;
15456 }
015dc7e1 15457 some_strings_shown = true;
cf13d699
NC
15458 }
15459 }
15460
15461 if (! some_strings_shown)
15462 printf (_(" No strings found in this section."));
15463
0e602686 15464 free (real_start);
cf13d699
NC
15465
15466 putchar ('\n');
015dc7e1 15467 return true;
f761cb13
AM
15468
15469error_out:
15470 free (real_start);
015dc7e1 15471 return false;
cf13d699
NC
15472}
15473
015dc7e1
AM
15474static bool
15475dump_section_as_bytes (Elf_Internal_Shdr *section,
15476 Filedata *filedata,
15477 bool relocate)
cf13d699 15478{
be7d229a
AM
15479 Elf_Internal_Shdr *relsec;
15480 size_t bytes;
15481 uint64_t section_size;
625d49fc 15482 uint64_t addr;
be7d229a
AM
15483 unsigned char *data;
15484 unsigned char *real_start;
15485 unsigned char *start;
0e602686 15486
dda8d76d 15487 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15488 if (start == NULL)
c6b78c96 15489 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15490 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15491
0e602686 15492 section_size = section->sh_size;
cf13d699 15493
835f2fae
NC
15494 if (filedata->is_separate)
15495 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15496 printable_section_name (filedata, section),
15497 filedata->file_name);
15498 else
15499 printf (_("\nHex dump of section '%s':\n"),
15500 printable_section_name (filedata, section));
cf13d699 15501
0e602686
NC
15502 if (decompress_dumps)
15503 {
31e5a3a3
AM
15504 uint64_t new_size = section_size;
15505 uint64_t uncompressed_size = 0;
1f5a3546 15506 bool is_zstd = false;
0e602686
NC
15507
15508 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15509 {
15510 Elf_Internal_Chdr chdr;
15511 unsigned int compression_header_size
ebdf1ebf 15512 = get_compression_header (& chdr, start, section_size);
0e602686 15513
5844b465
NC
15514 if (compression_header_size == 0)
15515 /* An error message will have already been generated
15516 by get_compression_header. */
15517 goto error_out;
15518
1f5a3546
FS
15519 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
15520 ;
15521#ifdef HAVE_ZSTD
15522 else if (chdr.ch_type == ELFCOMPRESS_ZSTD)
15523 is_zstd = true;
15524#endif
15525 else
0e602686 15526 {
813dabb9 15527 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15528 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15529 goto error_out;
0e602686 15530 }
813dabb9
L
15531 uncompressed_size = chdr.ch_size;
15532 start += compression_header_size;
15533 new_size -= compression_header_size;
0e602686
NC
15534 }
15535 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15536 {
15537 /* Read the zlib header. In this case, it should be "ZLIB"
15538 followed by the uncompressed section size, 8 bytes in
15539 big-endian order. */
15540 uncompressed_size = start[4]; uncompressed_size <<= 8;
15541 uncompressed_size += start[5]; uncompressed_size <<= 8;
15542 uncompressed_size += start[6]; uncompressed_size <<= 8;
15543 uncompressed_size += start[7]; uncompressed_size <<= 8;
15544 uncompressed_size += start[8]; uncompressed_size <<= 8;
15545 uncompressed_size += start[9]; uncompressed_size <<= 8;
15546 uncompressed_size += start[10]; uncompressed_size <<= 8;
15547 uncompressed_size += start[11];
15548 start += 12;
15549 new_size -= 12;
15550 }
15551
f055032e
NC
15552 if (uncompressed_size)
15553 {
1f5a3546
FS
15554 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
15555 &new_size))
bc303e5d
NC
15556 {
15557 section_size = new_size;
15558 }
f055032e
NC
15559 else
15560 {
15561 error (_("Unable to decompress section %s\n"),
dda8d76d 15562 printable_section_name (filedata, section));
bc303e5d 15563 /* FIXME: Print the section anyway ? */
f761cb13 15564 goto error_out;
f055032e
NC
15565 }
15566 }
bc303e5d
NC
15567 else
15568 start = real_start;
0e602686 15569 }
14ae95f2 15570
cf13d699
NC
15571 if (relocate)
15572 {
dda8d76d 15573 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15574 goto error_out;
cf13d699
NC
15575 }
15576 else
15577 {
15578 /* If the section being dumped has relocations against it the user might
15579 be expecting these relocations to have been applied. Check for this
15580 case and issue a warning message in order to avoid confusion.
15581 FIXME: Maybe we ought to have an option that dumps a section with
15582 relocs applied ? */
dda8d76d
NC
15583 for (relsec = filedata->section_headers;
15584 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15585 ++relsec)
15586 {
15587 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15588 || relsec->sh_info >= filedata->file_header.e_shnum
15589 || filedata->section_headers + relsec->sh_info != section
cf13d699 15590 || relsec->sh_size == 0
dda8d76d 15591 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15592 continue;
15593
15594 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15595 break;
15596 }
15597 }
15598
15599 addr = section->sh_addr;
0e602686 15600 bytes = section_size;
cf13d699
NC
15601 data = start;
15602
15603 while (bytes)
15604 {
15605 int j;
15606 int k;
15607 int lbytes;
15608
15609 lbytes = (bytes > 16 ? 16 : bytes);
15610
15611 printf (" 0x%8.8lx ", (unsigned long) addr);
15612
15613 for (j = 0; j < 16; j++)
15614 {
15615 if (j < lbytes)
15616 printf ("%2.2x", data[j]);
15617 else
15618 printf (" ");
15619
15620 if ((j & 3) == 3)
15621 printf (" ");
15622 }
15623
15624 for (j = 0; j < lbytes; j++)
15625 {
15626 k = data[j];
15627 if (k >= ' ' && k < 0x7f)
15628 printf ("%c", k);
15629 else
15630 printf (".");
15631 }
15632
15633 putchar ('\n');
15634
15635 data += lbytes;
15636 addr += lbytes;
15637 bytes -= lbytes;
15638 }
15639
0e602686 15640 free (real_start);
cf13d699
NC
15641
15642 putchar ('\n');
015dc7e1 15643 return true;
f761cb13
AM
15644
15645 error_out:
15646 free (real_start);
015dc7e1 15647 return false;
cf13d699
NC
15648}
15649
094e34f2 15650#ifdef ENABLE_LIBCTF
7d9813f1
NA
15651static ctf_sect_t *
15652shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15653{
84714f86 15654 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15655 buf->cts_size = shdr->sh_size;
15656 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15657
15658 return buf;
15659}
15660
15661/* Formatting callback function passed to ctf_dump. Returns either the pointer
15662 it is passed, or a pointer to newly-allocated storage, in which case
15663 dump_ctf() will free it when it no longer needs it. */
15664
2f6ecaed
NA
15665static char *
15666dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15667 char *s, void *arg)
7d9813f1 15668{
3e50a591 15669 const char *blanks = arg;
7d9813f1
NA
15670 char *new_s;
15671
3e50a591 15672 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15673 return s;
15674 return new_s;
15675}
15676
926c9e76
NA
15677/* Dump CTF errors/warnings. */
15678static void
139633c3 15679dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15680{
15681 ctf_next_t *it = NULL;
15682 char *errtext;
15683 int is_warning;
15684 int err;
15685
15686 /* Dump accumulated errors and warnings. */
15687 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15688 {
5e9b84f7 15689 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15690 errtext);
15691 free (errtext);
15692 }
15693 if (err != ECTF_NEXT_END)
15694 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15695}
15696
2f6ecaed
NA
15697/* Dump one CTF archive member. */
15698
80b56fad
NA
15699static void
15700dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15701 size_t member)
2f6ecaed 15702{
2f6ecaed
NA
15703 const char *things[] = {"Header", "Labels", "Data objects",
15704 "Function objects", "Variables", "Types", "Strings",
15705 ""};
15706 const char **thing;
15707 size_t i;
15708
80b56fad
NA
15709 /* Don't print out the name of the default-named archive member if it appears
15710 first in the list. The name .ctf appears everywhere, even for things that
15711 aren't really archives, so printing it out is liable to be confusing; also,
15712 the common case by far is for only one archive member to exist, and hiding
15713 it in that case seems worthwhile. */
2f6ecaed 15714
80b56fad
NA
15715 if (strcmp (name, ".ctf") != 0 || member != 0)
15716 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15717
80b56fad
NA
15718 if (ctf_parent_name (ctf) != NULL)
15719 ctf_import (ctf, parent);
2f6ecaed
NA
15720
15721 for (i = 0, thing = things; *thing[0]; thing++, i++)
15722 {
15723 ctf_dump_state_t *s = NULL;
15724 char *item;
15725
15726 printf ("\n %s:\n", *thing);
15727 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15728 (void *) " ")) != NULL)
15729 {
15730 printf ("%s\n", item);
15731 free (item);
15732 }
15733
15734 if (ctf_errno (ctf))
15735 {
15736 error (_("Iteration failed: %s, %s\n"), *thing,
15737 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15738 break;
2f6ecaed
NA
15739 }
15740 }
8b37e7b6 15741
926c9e76 15742 dump_ctf_errs (ctf);
2f6ecaed
NA
15743}
15744
015dc7e1 15745static bool
7d9813f1
NA
15746dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15747{
7d9813f1
NA
15748 Elf_Internal_Shdr * symtab_sec = NULL;
15749 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15750 void * data = NULL;
15751 void * symdata = NULL;
15752 void * strdata = NULL;
80b56fad 15753 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15754 ctf_sect_t * symsectp = NULL;
15755 ctf_sect_t * strsectp = NULL;
2f6ecaed 15756 ctf_archive_t * ctfa = NULL;
139633c3 15757 ctf_dict_t * parent = NULL;
80b56fad 15758 ctf_dict_t * fp;
7d9813f1 15759
80b56fad
NA
15760 ctf_next_t *i = NULL;
15761 const char *name;
15762 size_t member = 0;
7d9813f1 15763 int err;
015dc7e1 15764 bool ret = false;
7d9813f1
NA
15765
15766 shdr_to_ctf_sect (&ctfsect, section, filedata);
15767 data = get_section_contents (section, filedata);
15768 ctfsect.cts_data = data;
15769
616febde 15770 if (!dump_ctf_symtab_name)
3d16b64e 15771 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15772
15773 if (!dump_ctf_strtab_name)
3d16b64e 15774 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15775
15776 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15777 {
15778 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15779 {
15780 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15781 goto fail;
15782 }
15783 if ((symdata = (void *) get_data (NULL, filedata,
15784 symtab_sec->sh_offset, 1,
15785 symtab_sec->sh_size,
15786 _("symbols"))) == NULL)
15787 goto fail;
15788 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15789 symsect.cts_data = symdata;
15790 }
835f2fae 15791
df16e041 15792 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15793 {
15794 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15795 {
15796 error (_("No string table section named %s\n"),
15797 dump_ctf_strtab_name);
15798 goto fail;
15799 }
15800 if ((strdata = (void *) get_data (NULL, filedata,
15801 strtab_sec->sh_offset, 1,
15802 strtab_sec->sh_size,
15803 _("strings"))) == NULL)
15804 goto fail;
15805 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15806 strsect.cts_data = strdata;
15807 }
835f2fae 15808
2f6ecaed
NA
15809 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15810 libctf papers over the difference, so we can pretend it is always an
80b56fad 15811 archive. */
7d9813f1 15812
2f6ecaed 15813 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15814 {
926c9e76 15815 dump_ctf_errs (NULL);
7d9813f1
NA
15816 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15817 goto fail;
15818 }
15819
96c61be5
NA
15820 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15821 != ELFDATA2MSB);
15822
80b56fad
NA
15823 /* Preload the parent dict, since it will need to be imported into every
15824 child in turn. */
15825 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15826 {
926c9e76 15827 dump_ctf_errs (NULL);
2f6ecaed
NA
15828 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15829 goto fail;
7d9813f1
NA
15830 }
15831
015dc7e1 15832 ret = true;
7d9813f1 15833
835f2fae
NC
15834 if (filedata->is_separate)
15835 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15836 printable_section_name (filedata, section),
15837 filedata->file_name);
15838 else
15839 printf (_("\nDump of CTF section '%s':\n"),
15840 printable_section_name (filedata, section));
7d9813f1 15841
80b56fad
NA
15842 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15843 dump_ctf_archive_member (fp, name, parent, member++);
15844 if (err != ECTF_NEXT_END)
15845 {
15846 dump_ctf_errs (NULL);
15847 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15848 ret = false;
15849 }
7d9813f1
NA
15850
15851 fail:
139633c3 15852 ctf_dict_close (parent);
2f6ecaed 15853 ctf_close (ctfa);
7d9813f1
NA
15854 free (data);
15855 free (symdata);
15856 free (strdata);
15857 return ret;
15858}
094e34f2 15859#endif
7d9813f1 15860
015dc7e1 15861static bool
dda8d76d
NC
15862load_specific_debug_section (enum dwarf_section_display_enum debug,
15863 const Elf_Internal_Shdr * sec,
15864 void * data)
1007acb3 15865{
2cf0635d 15866 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15867 char buf [64];
dda8d76d 15868 Filedata * filedata = (Filedata *) data;
9abca702 15869
19e6b90e 15870 if (section->start != NULL)
dda8d76d
NC
15871 {
15872 /* If it is already loaded, do nothing. */
15873 if (streq (section->filename, filedata->file_name))
015dc7e1 15874 return true;
dda8d76d
NC
15875 free (section->start);
15876 }
1007acb3 15877
19e6b90e
L
15878 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15879 section->address = sec->sh_addr;
dda8d76d
NC
15880 section->filename = filedata->file_name;
15881 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15882 sec->sh_offset, 1,
15883 sec->sh_size, buf);
59245841
NC
15884 if (section->start == NULL)
15885 section->size = 0;
15886 else
15887 {
77115a4a 15888 unsigned char *start = section->start;
31e5a3a3
AM
15889 uint64_t size = sec->sh_size;
15890 uint64_t uncompressed_size = 0;
1f5a3546 15891 bool is_zstd = false;
77115a4a
L
15892
15893 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15894 {
15895 Elf_Internal_Chdr chdr;
d8024a91
NC
15896 unsigned int compression_header_size;
15897
f53be977
L
15898 if (size < (is_32bit_elf
15899 ? sizeof (Elf32_External_Chdr)
15900 : sizeof (Elf64_External_Chdr)))
d8024a91 15901 {
55be8fd0 15902 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15903 section->name);
015dc7e1 15904 return false;
d8024a91
NC
15905 }
15906
ebdf1ebf 15907 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15908 if (compression_header_size == 0)
15909 /* An error message will have already been generated
15910 by get_compression_header. */
015dc7e1 15911 return false;
d8024a91 15912
1f5a3546
FS
15913 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
15914 ;
15915#ifdef HAVE_ZSTD
15916 else if (chdr.ch_type == ELFCOMPRESS_ZSTD)
15917 is_zstd = true;
15918#endif
15919 else
813dabb9
L
15920 {
15921 warn (_("section '%s' has unsupported compress type: %d\n"),
15922 section->name, chdr.ch_type);
015dc7e1 15923 return false;
813dabb9 15924 }
dab394de 15925 uncompressed_size = chdr.ch_size;
77115a4a
L
15926 start += compression_header_size;
15927 size -= compression_header_size;
15928 }
dab394de
L
15929 else if (size > 12 && streq ((char *) start, "ZLIB"))
15930 {
15931 /* Read the zlib header. In this case, it should be "ZLIB"
15932 followed by the uncompressed section size, 8 bytes in
15933 big-endian order. */
15934 uncompressed_size = start[4]; uncompressed_size <<= 8;
15935 uncompressed_size += start[5]; uncompressed_size <<= 8;
15936 uncompressed_size += start[6]; uncompressed_size <<= 8;
15937 uncompressed_size += start[7]; uncompressed_size <<= 8;
15938 uncompressed_size += start[8]; uncompressed_size <<= 8;
15939 uncompressed_size += start[9]; uncompressed_size <<= 8;
15940 uncompressed_size += start[10]; uncompressed_size <<= 8;
15941 uncompressed_size += start[11];
15942 start += 12;
15943 size -= 12;
15944 }
15945
1835f746 15946 if (uncompressed_size)
77115a4a 15947 {
1f5a3546 15948 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
1835f746
NC
15949 &size))
15950 {
15951 /* Free the compressed buffer, update the section buffer
15952 and the section size if uncompress is successful. */
15953 free (section->start);
15954 section->start = start;
15955 }
15956 else
15957 {
15958 error (_("Unable to decompress section %s\n"),
dda8d76d 15959 printable_section_name (filedata, sec));
015dc7e1 15960 return false;
1835f746 15961 }
77115a4a 15962 }
bc303e5d 15963
77115a4a 15964 section->size = size;
59245841 15965 }
4a114e3e 15966
1b315056 15967 if (section->start == NULL)
015dc7e1 15968 return false;
1b315056 15969
19e6b90e 15970 if (debug_displays [debug].relocate)
32ec8896 15971 {
dda8d76d 15972 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15973 & section->reloc_info, & section->num_relocs))
015dc7e1 15974 return false;
32ec8896 15975 }
d1c4b12b
NC
15976 else
15977 {
15978 section->reloc_info = NULL;
15979 section->num_relocs = 0;
15980 }
1007acb3 15981
015dc7e1 15982 return true;
1007acb3
L
15983}
15984
301a9420
AM
15985#if HAVE_LIBDEBUGINFOD
15986/* Return a hex string representation of the build-id. */
15987unsigned char *
15988get_build_id (void * data)
15989{
ca0e11aa 15990 Filedata * filedata = (Filedata *) data;
301a9420
AM
15991 Elf_Internal_Shdr * shdr;
15992 unsigned long i;
15993
55be8fd0
NC
15994 /* Iterate through notes to find note.gnu.build-id.
15995 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15996 for (i = 0, shdr = filedata->section_headers;
15997 i < filedata->file_header.e_shnum && shdr != NULL;
15998 i++, shdr++)
15999 {
16000 if (shdr->sh_type != SHT_NOTE)
16001 continue;
16002
16003 char * next;
16004 char * end;
16005 size_t data_remaining;
16006 size_t min_notesz;
16007 Elf_External_Note * enote;
16008 Elf_Internal_Note inote;
16009
625d49fc
AM
16010 uint64_t offset = shdr->sh_offset;
16011 uint64_t align = shdr->sh_addralign;
16012 uint64_t length = shdr->sh_size;
301a9420
AM
16013
16014 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16015 if (enote == NULL)
16016 continue;
16017
16018 if (align < 4)
16019 align = 4;
16020 else if (align != 4 && align != 8)
f761cb13
AM
16021 {
16022 free (enote);
16023 continue;
16024 }
301a9420
AM
16025
16026 end = (char *) enote + length;
16027 data_remaining = end - (char *) enote;
16028
16029 if (!is_ia64_vms (filedata))
16030 {
16031 min_notesz = offsetof (Elf_External_Note, name);
16032 if (data_remaining < min_notesz)
16033 {
55be8fd0
NC
16034 warn (_("\
16035malformed note encountered in section %s whilst scanning for build-id note\n"),
16036 printable_section_name (filedata, shdr));
f761cb13 16037 free (enote);
55be8fd0 16038 continue;
301a9420
AM
16039 }
16040 data_remaining -= min_notesz;
16041
16042 inote.type = BYTE_GET (enote->type);
16043 inote.namesz = BYTE_GET (enote->namesz);
16044 inote.namedata = enote->name;
16045 inote.descsz = BYTE_GET (enote->descsz);
16046 inote.descdata = ((char *) enote
16047 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16048 inote.descpos = offset + (inote.descdata - (char *) enote);
16049 next = ((char *) enote
16050 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16051 }
16052 else
16053 {
16054 Elf64_External_VMS_Note *vms_enote;
16055
16056 /* PR binutils/15191
16057 Make sure that there is enough data to read. */
16058 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16059 if (data_remaining < min_notesz)
16060 {
55be8fd0
NC
16061 warn (_("\
16062malformed note encountered in section %s whilst scanning for build-id note\n"),
16063 printable_section_name (filedata, shdr));
f761cb13 16064 free (enote);
55be8fd0 16065 continue;
301a9420
AM
16066 }
16067 data_remaining -= min_notesz;
16068
16069 vms_enote = (Elf64_External_VMS_Note *) enote;
16070 inote.type = BYTE_GET (vms_enote->type);
16071 inote.namesz = BYTE_GET (vms_enote->namesz);
16072 inote.namedata = vms_enote->name;
16073 inote.descsz = BYTE_GET (vms_enote->descsz);
16074 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16075 inote.descpos = offset + (inote.descdata - (char *) enote);
16076 next = inote.descdata + align_power (inote.descsz, 3);
16077 }
16078
16079 /* Skip malformed notes. */
16080 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16081 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16082 || (size_t) (next - inote.descdata) < inote.descsz
16083 || ((size_t) (next - inote.descdata)
16084 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16085 {
55be8fd0
NC
16086 warn (_("\
16087malformed note encountered in section %s whilst scanning for build-id note\n"),
16088 printable_section_name (filedata, shdr));
f761cb13 16089 free (enote);
301a9420
AM
16090 continue;
16091 }
16092
16093 /* Check if this is the build-id note. If so then convert the build-id
16094 bytes to a hex string. */
16095 if (inote.namesz > 0
24d127aa 16096 && startswith (inote.namedata, "GNU")
301a9420
AM
16097 && inote.type == NT_GNU_BUILD_ID)
16098 {
16099 unsigned long j;
16100 char * build_id;
16101
16102 build_id = malloc (inote.descsz * 2 + 1);
16103 if (build_id == NULL)
f761cb13
AM
16104 {
16105 free (enote);
16106 return NULL;
16107 }
301a9420
AM
16108
16109 for (j = 0; j < inote.descsz; ++j)
16110 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16111 build_id[inote.descsz * 2] = '\0';
f761cb13 16112 free (enote);
301a9420 16113
55be8fd0 16114 return (unsigned char *) build_id;
301a9420 16115 }
f761cb13 16116 free (enote);
301a9420
AM
16117 }
16118
16119 return NULL;
16120}
16121#endif /* HAVE_LIBDEBUGINFOD */
16122
657d0d47
CC
16123/* If this is not NULL, load_debug_section will only look for sections
16124 within the list of sections given here. */
32ec8896 16125static unsigned int * section_subset = NULL;
657d0d47 16126
015dc7e1 16127bool
dda8d76d 16128load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16129{
2cf0635d
NC
16130 struct dwarf_section * section = &debug_displays [debug].section;
16131 Elf_Internal_Shdr * sec;
dda8d76d
NC
16132 Filedata * filedata = (Filedata *) data;
16133
e1dbfc17
L
16134 if (!dump_any_debugging)
16135 return false;
16136
f425ec66
NC
16137 /* Without section headers we cannot find any sections. */
16138 if (filedata->section_headers == NULL)
015dc7e1 16139 return false;
f425ec66 16140
9c1ce108
AM
16141 if (filedata->string_table == NULL
16142 && filedata->file_header.e_shstrndx != SHN_UNDEF
16143 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16144 {
16145 Elf_Internal_Shdr * strs;
16146
16147 /* Read in the string table, so that we have section names to scan. */
16148 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16149
4dff97b2 16150 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16151 {
9c1ce108
AM
16152 filedata->string_table
16153 = (char *) get_data (NULL, filedata, strs->sh_offset,
16154 1, strs->sh_size, _("string table"));
dda8d76d 16155
9c1ce108
AM
16156 filedata->string_table_length
16157 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16158 }
16159 }
d966045b
DJ
16160
16161 /* Locate the debug section. */
dda8d76d 16162 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16163 if (sec != NULL)
16164 section->name = section->uncompressed_name;
16165 else
16166 {
dda8d76d 16167 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16168 if (sec != NULL)
16169 section->name = section->compressed_name;
16170 }
16171 if (sec == NULL)
015dc7e1 16172 return false;
d966045b 16173
657d0d47
CC
16174 /* If we're loading from a subset of sections, and we've loaded
16175 a section matching this name before, it's likely that it's a
16176 different one. */
16177 if (section_subset != NULL)
16178 free_debug_section (debug);
16179
dda8d76d 16180 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16181}
16182
19e6b90e
L
16183void
16184free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16185{
2cf0635d 16186 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16187
19e6b90e
L
16188 if (section->start == NULL)
16189 return;
1007acb3 16190
19e6b90e
L
16191 free ((char *) section->start);
16192 section->start = NULL;
16193 section->address = 0;
16194 section->size = 0;
a788aedd 16195
9db70fc3
AM
16196 free (section->reloc_info);
16197 section->reloc_info = NULL;
16198 section->num_relocs = 0;
1007acb3
L
16199}
16200
015dc7e1 16201static bool
dda8d76d 16202display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16203{
84714f86
AM
16204 const char *name = (section_name_valid (filedata, section)
16205 ? section_name (filedata, section) : "");
16206 const char *print_name = printable_section_name (filedata, section);
be7d229a 16207 uint64_t length;
015dc7e1 16208 bool result = true;
3f5e193b 16209 int i;
1007acb3 16210
19e6b90e
L
16211 length = section->sh_size;
16212 if (length == 0)
1007acb3 16213 {
74e1a04b 16214 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16215 return true;
1007acb3 16216 }
5dff79d8
NC
16217 if (section->sh_type == SHT_NOBITS)
16218 {
16219 /* There is no point in dumping the contents of a debugging section
16220 which has the NOBITS type - the bits in the file will be random.
16221 This can happen when a file containing a .eh_frame section is
16222 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16223 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16224 print_name);
015dc7e1 16225 return false;
5dff79d8 16226 }
1007acb3 16227
24d127aa 16228 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16229 name = ".debug_info";
1007acb3 16230
19e6b90e
L
16231 /* See if we know how to display the contents of this section. */
16232 for (i = 0; i < max; i++)
d85bf2ba
NC
16233 {
16234 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16235 struct dwarf_section_display * display = debug_displays + i;
16236 struct dwarf_section * sec = & display->section;
d966045b 16237
d85bf2ba 16238 if (streq (sec->uncompressed_name, name)
24d127aa 16239 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16240 || streq (sec->compressed_name, name))
16241 {
015dc7e1 16242 bool secondary = (section != find_section (filedata, name));
1007acb3 16243
d85bf2ba
NC
16244 if (secondary)
16245 free_debug_section (id);
dda8d76d 16246
24d127aa 16247 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16248 sec->name = name;
16249 else if (streq (sec->uncompressed_name, name))
16250 sec->name = sec->uncompressed_name;
16251 else
16252 sec->name = sec->compressed_name;
657d0d47 16253
d85bf2ba
NC
16254 if (load_specific_debug_section (id, section, filedata))
16255 {
16256 /* If this debug section is part of a CU/TU set in a .dwp file,
16257 restrict load_debug_section to the sections in that set. */
16258 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16259
d85bf2ba 16260 result &= display->display (sec, filedata);
657d0d47 16261
d85bf2ba 16262 section_subset = NULL;
1007acb3 16263
44266f36 16264 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16265 free_debug_section (id);
16266 }
16267 break;
16268 }
16269 }
1007acb3 16270
19e6b90e 16271 if (i == max)
1007acb3 16272 {
74e1a04b 16273 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16274 result = false;
1007acb3
L
16275 }
16276
19e6b90e 16277 return result;
5b18a4bc 16278}
103f02d3 16279
aef1f6d0
DJ
16280/* Set DUMP_SECTS for all sections where dumps were requested
16281 based on section name. */
16282
16283static void
dda8d76d 16284initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16285{
2cf0635d 16286 struct dump_list_entry * cur;
aef1f6d0
DJ
16287
16288 for (cur = dump_sects_byname; cur; cur = cur->next)
16289 {
16290 unsigned int i;
015dc7e1 16291 bool any = false;
aef1f6d0 16292
dda8d76d 16293 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16294 if (section_name_valid (filedata, filedata->section_headers + i)
16295 && streq (section_name (filedata, filedata->section_headers + i),
16296 cur->name))
aef1f6d0 16297 {
6431e409 16298 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16299 any = true;
aef1f6d0
DJ
16300 }
16301
835f2fae
NC
16302 if (!any && !filedata->is_separate)
16303 warn (_("Section '%s' was not dumped because it does not exist\n"),
16304 cur->name);
aef1f6d0
DJ
16305 }
16306}
16307
015dc7e1 16308static bool
dda8d76d 16309process_section_contents (Filedata * filedata)
5b18a4bc 16310{
2cf0635d 16311 Elf_Internal_Shdr * section;
19e6b90e 16312 unsigned int i;
015dc7e1 16313 bool res = true;
103f02d3 16314
19e6b90e 16315 if (! do_dump)
015dc7e1 16316 return true;
103f02d3 16317
dda8d76d 16318 initialise_dumps_byname (filedata);
aef1f6d0 16319
dda8d76d 16320 for (i = 0, section = filedata->section_headers;
6431e409 16321 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16322 i++, section++)
16323 {
6431e409 16324 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16325
d6bfbc39
NC
16326 if (filedata->is_separate && ! process_links)
16327 dump &= DEBUG_DUMP;
047c3dbf 16328
19e6b90e 16329#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16330 if (dump & DISASS_DUMP)
16331 {
16332 if (! disassemble_section (section, filedata))
015dc7e1 16333 res = false;
dda8d76d 16334 }
19e6b90e 16335#endif
dda8d76d 16336 if (dump & HEX_DUMP)
32ec8896 16337 {
015dc7e1
AM
16338 if (! dump_section_as_bytes (section, filedata, false))
16339 res = false;
32ec8896 16340 }
103f02d3 16341
dda8d76d 16342 if (dump & RELOC_DUMP)
32ec8896 16343 {
015dc7e1
AM
16344 if (! dump_section_as_bytes (section, filedata, true))
16345 res = false;
32ec8896 16346 }
09c11c86 16347
dda8d76d 16348 if (dump & STRING_DUMP)
32ec8896 16349 {
dda8d76d 16350 if (! dump_section_as_strings (section, filedata))
015dc7e1 16351 res = false;
32ec8896 16352 }
cf13d699 16353
dda8d76d 16354 if (dump & DEBUG_DUMP)
32ec8896 16355 {
dda8d76d 16356 if (! display_debug_section (i, section, filedata))
015dc7e1 16357 res = false;
32ec8896 16358 }
7d9813f1 16359
094e34f2 16360#ifdef ENABLE_LIBCTF
7d9813f1
NA
16361 if (dump & CTF_DUMP)
16362 {
16363 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16364 res = false;
7d9813f1 16365 }
094e34f2 16366#endif
5b18a4bc 16367 }
103f02d3 16368
835f2fae 16369 if (! filedata->is_separate)
0ee3043f 16370 {
835f2fae
NC
16371 /* Check to see if the user requested a
16372 dump of a section that does not exist. */
16373 for (; i < filedata->dump.num_dump_sects; i++)
16374 if (filedata->dump.dump_sects[i])
16375 {
ca0e11aa 16376 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16377 res = false;
835f2fae 16378 }
0ee3043f 16379 }
32ec8896
NC
16380
16381 return res;
5b18a4bc 16382}
103f02d3 16383
5b18a4bc 16384static void
19e6b90e 16385process_mips_fpe_exception (int mask)
5b18a4bc 16386{
19e6b90e
L
16387 if (mask)
16388 {
015dc7e1 16389 bool first = true;
32ec8896 16390
19e6b90e 16391 if (mask & OEX_FPU_INEX)
015dc7e1 16392 fputs ("INEX", stdout), first = false;
19e6b90e 16393 if (mask & OEX_FPU_UFLO)
015dc7e1 16394 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16395 if (mask & OEX_FPU_OFLO)
015dc7e1 16396 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16397 if (mask & OEX_FPU_DIV0)
015dc7e1 16398 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16399 if (mask & OEX_FPU_INVAL)
16400 printf ("%sINVAL", first ? "" : "|");
16401 }
5b18a4bc 16402 else
19e6b90e 16403 fputs ("0", stdout);
5b18a4bc 16404}
103f02d3 16405
f6f0e17b
NC
16406/* Display's the value of TAG at location P. If TAG is
16407 greater than 0 it is assumed to be an unknown tag, and
16408 a message is printed to this effect. Otherwise it is
16409 assumed that a message has already been printed.
16410
16411 If the bottom bit of TAG is set it assumed to have a
16412 string value, otherwise it is assumed to have an integer
16413 value.
16414
16415 Returns an updated P pointing to the first unread byte
16416 beyond the end of TAG's value.
16417
16418 Reads at or beyond END will not be made. */
16419
16420static unsigned char *
60abdbed 16421display_tag_value (signed int tag,
f6f0e17b
NC
16422 unsigned char * p,
16423 const unsigned char * const end)
16424{
16425 unsigned long val;
16426
16427 if (tag > 0)
16428 printf (" Tag_unknown_%d: ", tag);
16429
16430 if (p >= end)
16431 {
4082ef84 16432 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16433 }
16434 else if (tag & 1)
16435 {
071436c6
NC
16436 /* PR 17531 file: 027-19978-0.004. */
16437 size_t maxlen = (end - p) - 1;
16438
16439 putchar ('"');
4082ef84
NC
16440 if (maxlen > 0)
16441 {
16442 print_symbol ((int) maxlen, (const char *) p);
16443 p += strnlen ((char *) p, maxlen) + 1;
16444 }
16445 else
16446 {
16447 printf (_("<corrupt string tag>"));
16448 p = (unsigned char *) end;
16449 }
071436c6 16450 printf ("\"\n");
f6f0e17b
NC
16451 }
16452 else
16453 {
cd30bcef 16454 READ_ULEB (val, p, end);
f6f0e17b
NC
16455 printf ("%ld (0x%lx)\n", val, val);
16456 }
16457
4082ef84 16458 assert (p <= end);
f6f0e17b
NC
16459 return p;
16460}
16461
53a346d8
CZ
16462/* ARC ABI attributes section. */
16463
16464static unsigned char *
16465display_arc_attribute (unsigned char * p,
16466 const unsigned char * const end)
16467{
16468 unsigned int tag;
53a346d8
CZ
16469 unsigned int val;
16470
cd30bcef 16471 READ_ULEB (tag, p, end);
53a346d8
CZ
16472
16473 switch (tag)
16474 {
16475 case Tag_ARC_PCS_config:
cd30bcef 16476 READ_ULEB (val, p, end);
53a346d8
CZ
16477 printf (" Tag_ARC_PCS_config: ");
16478 switch (val)
16479 {
16480 case 0:
16481 printf (_("Absent/Non standard\n"));
16482 break;
16483 case 1:
16484 printf (_("Bare metal/mwdt\n"));
16485 break;
16486 case 2:
16487 printf (_("Bare metal/newlib\n"));
16488 break;
16489 case 3:
16490 printf (_("Linux/uclibc\n"));
16491 break;
16492 case 4:
16493 printf (_("Linux/glibc\n"));
16494 break;
16495 default:
16496 printf (_("Unknown\n"));
16497 break;
16498 }
16499 break;
16500
16501 case Tag_ARC_CPU_base:
cd30bcef 16502 READ_ULEB (val, p, end);
53a346d8
CZ
16503 printf (" Tag_ARC_CPU_base: ");
16504 switch (val)
16505 {
16506 default:
16507 case TAG_CPU_NONE:
16508 printf (_("Absent\n"));
16509 break;
16510 case TAG_CPU_ARC6xx:
16511 printf ("ARC6xx\n");
16512 break;
16513 case TAG_CPU_ARC7xx:
16514 printf ("ARC7xx\n");
16515 break;
16516 case TAG_CPU_ARCEM:
16517 printf ("ARCEM\n");
16518 break;
16519 case TAG_CPU_ARCHS:
16520 printf ("ARCHS\n");
16521 break;
16522 }
16523 break;
16524
16525 case Tag_ARC_CPU_variation:
cd30bcef 16526 READ_ULEB (val, p, end);
53a346d8
CZ
16527 printf (" Tag_ARC_CPU_variation: ");
16528 switch (val)
16529 {
16530 default:
16531 if (val > 0 && val < 16)
53a346d8 16532 printf ("Core%d\n", val);
d8cbc93b
JL
16533 else
16534 printf ("Unknown\n");
16535 break;
16536
53a346d8
CZ
16537 case 0:
16538 printf (_("Absent\n"));
16539 break;
16540 }
16541 break;
16542
16543 case Tag_ARC_CPU_name:
16544 printf (" Tag_ARC_CPU_name: ");
16545 p = display_tag_value (-1, p, end);
16546 break;
16547
16548 case Tag_ARC_ABI_rf16:
cd30bcef 16549 READ_ULEB (val, p, end);
53a346d8
CZ
16550 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16551 break;
16552
16553 case Tag_ARC_ABI_osver:
cd30bcef 16554 READ_ULEB (val, p, end);
53a346d8
CZ
16555 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16556 break;
16557
16558 case Tag_ARC_ABI_pic:
16559 case Tag_ARC_ABI_sda:
cd30bcef 16560 READ_ULEB (val, p, end);
53a346d8
CZ
16561 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16562 : " Tag_ARC_ABI_pic: ");
16563 switch (val)
16564 {
16565 case 0:
16566 printf (_("Absent\n"));
16567 break;
16568 case 1:
16569 printf ("MWDT\n");
16570 break;
16571 case 2:
16572 printf ("GNU\n");
16573 break;
16574 default:
16575 printf (_("Unknown\n"));
16576 break;
16577 }
16578 break;
16579
16580 case Tag_ARC_ABI_tls:
cd30bcef 16581 READ_ULEB (val, p, end);
53a346d8
CZ
16582 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16583 break;
16584
16585 case Tag_ARC_ABI_enumsize:
cd30bcef 16586 READ_ULEB (val, p, end);
53a346d8
CZ
16587 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16588 _("smallest"));
16589 break;
16590
16591 case Tag_ARC_ABI_exceptions:
cd30bcef 16592 READ_ULEB (val, p, end);
53a346d8
CZ
16593 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16594 : _("default"));
16595 break;
16596
16597 case Tag_ARC_ABI_double_size:
cd30bcef 16598 READ_ULEB (val, p, end);
53a346d8
CZ
16599 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16600 break;
16601
16602 case Tag_ARC_ISA_config:
16603 printf (" Tag_ARC_ISA_config: ");
16604 p = display_tag_value (-1, p, end);
16605 break;
16606
16607 case Tag_ARC_ISA_apex:
16608 printf (" Tag_ARC_ISA_apex: ");
16609 p = display_tag_value (-1, p, end);
16610 break;
16611
16612 case Tag_ARC_ISA_mpy_option:
cd30bcef 16613 READ_ULEB (val, p, end);
53a346d8
CZ
16614 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16615 break;
16616
db1e1b45 16617 case Tag_ARC_ATR_version:
cd30bcef 16618 READ_ULEB (val, p, end);
db1e1b45 16619 printf (" Tag_ARC_ATR_version: %d\n", val);
16620 break;
16621
53a346d8
CZ
16622 default:
16623 return display_tag_value (tag & 1, p, end);
16624 }
16625
16626 return p;
16627}
16628
11c1ff18
PB
16629/* ARM EABI attributes section. */
16630typedef struct
16631{
70e99720 16632 unsigned int tag;
2cf0635d 16633 const char * name;
11c1ff18 16634 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16635 unsigned int type;
288f0ba2 16636 const char *const *table;
11c1ff18
PB
16637} arm_attr_public_tag;
16638
288f0ba2 16639static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16640 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16641 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16642 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16643 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16644static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16645static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16646 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16647static const char *const arm_attr_tag_FP_arch[] =
bca38921 16648 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16649 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16650static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16651static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16652 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16653 "NEON for ARMv8.1"};
288f0ba2 16654static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16655 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16656 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16657static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16658 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16659static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16660 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16661static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16662 {"Absolute", "PC-relative", "None"};
288f0ba2 16663static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16664 {"None", "direct", "GOT-indirect"};
288f0ba2 16665static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16666 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16667static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16668static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16669 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16670static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16671static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16672static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16673 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16674static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16675 {"Unused", "small", "int", "forced to int"};
288f0ba2 16676static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16677 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16678static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16679 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16680static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16681 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16682static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16683 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16684 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16685static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16686 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16687 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16688static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16689static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16690 {"Not Allowed", "Allowed"};
288f0ba2 16691static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16692 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16693static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16694 {"Follow architecture", "Allowed"};
288f0ba2 16695static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16696 {"Not Allowed", "Allowed"};
288f0ba2 16697static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16698 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16699 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16700static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16701static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16702 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16703 "TrustZone and Virtualization Extensions"};
288f0ba2 16704static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16705 {"Not Allowed", "Allowed"};
11c1ff18 16706
288f0ba2 16707static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16708 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16709
99db83d0
AC
16710static const char * arm_attr_tag_PAC_extension[] =
16711 {"No PAC/AUT instructions",
16712 "PAC/AUT instructions permitted in the NOP space",
16713 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16714
4b535030
AC
16715static const char * arm_attr_tag_BTI_extension[] =
16716 {"BTI instructions not permitted",
16717 "BTI instructions permitted in the NOP space",
16718 "BTI instructions permitted in the NOP and in the non-NOP space"};
16719
b81ee92f
AC
16720static const char * arm_attr_tag_BTI_use[] =
16721 {"Compiled without branch target enforcement",
16722 "Compiled with branch target enforcement"};
16723
c9fed665
AC
16724static const char * arm_attr_tag_PACRET_use[] =
16725 {"Compiled without return address signing and authentication",
16726 "Compiled with return address signing and authentication"};
16727
11c1ff18
PB
16728#define LOOKUP(id, name) \
16729 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16730static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16731{
16732 {4, "CPU_raw_name", 1, NULL},
16733 {5, "CPU_name", 1, NULL},
16734 LOOKUP(6, CPU_arch),
16735 {7, "CPU_arch_profile", 0, NULL},
16736 LOOKUP(8, ARM_ISA_use),
16737 LOOKUP(9, THUMB_ISA_use),
75375b3e 16738 LOOKUP(10, FP_arch),
11c1ff18 16739 LOOKUP(11, WMMX_arch),
f5f53991
AS
16740 LOOKUP(12, Advanced_SIMD_arch),
16741 LOOKUP(13, PCS_config),
11c1ff18
PB
16742 LOOKUP(14, ABI_PCS_R9_use),
16743 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16744 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16745 LOOKUP(17, ABI_PCS_GOT_use),
16746 LOOKUP(18, ABI_PCS_wchar_t),
16747 LOOKUP(19, ABI_FP_rounding),
16748 LOOKUP(20, ABI_FP_denormal),
16749 LOOKUP(21, ABI_FP_exceptions),
16750 LOOKUP(22, ABI_FP_user_exceptions),
16751 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16752 {24, "ABI_align_needed", 0, NULL},
16753 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16754 LOOKUP(26, ABI_enum_size),
16755 LOOKUP(27, ABI_HardFP_use),
16756 LOOKUP(28, ABI_VFP_args),
16757 LOOKUP(29, ABI_WMMX_args),
16758 LOOKUP(30, ABI_optimization_goals),
16759 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16760 {32, "compatibility", 0, NULL},
f5f53991 16761 LOOKUP(34, CPU_unaligned_access),
75375b3e 16762 LOOKUP(36, FP_HP_extension),
8e79c3df 16763 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16764 LOOKUP(42, MPextension_use),
16765 LOOKUP(44, DIV_use),
15afaa63 16766 LOOKUP(46, DSP_extension),
a7ad558c 16767 LOOKUP(48, MVE_arch),
99db83d0 16768 LOOKUP(50, PAC_extension),
4b535030 16769 LOOKUP(52, BTI_extension),
b81ee92f 16770 LOOKUP(74, BTI_use),
c9fed665 16771 LOOKUP(76, PACRET_use),
f5f53991
AS
16772 {64, "nodefaults", 0, NULL},
16773 {65, "also_compatible_with", 0, NULL},
16774 LOOKUP(66, T2EE_use),
16775 {67, "conformance", 1, NULL},
16776 LOOKUP(68, Virtualization_use),
cd21e546 16777 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16778};
16779#undef LOOKUP
16780
11c1ff18 16781static unsigned char *
f6f0e17b
NC
16782display_arm_attribute (unsigned char * p,
16783 const unsigned char * const end)
11c1ff18 16784{
70e99720 16785 unsigned int tag;
70e99720 16786 unsigned int val;
2cf0635d 16787 arm_attr_public_tag * attr;
11c1ff18 16788 unsigned i;
70e99720 16789 unsigned int type;
11c1ff18 16790
cd30bcef 16791 READ_ULEB (tag, p, end);
11c1ff18 16792 attr = NULL;
2cf0635d 16793 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16794 {
16795 if (arm_attr_public_tags[i].tag == tag)
16796 {
16797 attr = &arm_attr_public_tags[i];
16798 break;
16799 }
16800 }
16801
16802 if (attr)
16803 {
16804 printf (" Tag_%s: ", attr->name);
16805 switch (attr->type)
16806 {
16807 case 0:
16808 switch (tag)
16809 {
16810 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16811 READ_ULEB (val, p, end);
11c1ff18
PB
16812 switch (val)
16813 {
2b692964
NC
16814 case 0: printf (_("None\n")); break;
16815 case 'A': printf (_("Application\n")); break;
16816 case 'R': printf (_("Realtime\n")); break;
16817 case 'M': printf (_("Microcontroller\n")); break;
16818 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16819 default: printf ("??? (%d)\n", val); break;
16820 }
16821 break;
16822
75375b3e 16823 case 24: /* Tag_align_needed. */
cd30bcef 16824 READ_ULEB (val, p, end);
75375b3e
MGD
16825 switch (val)
16826 {
2b692964
NC
16827 case 0: printf (_("None\n")); break;
16828 case 1: printf (_("8-byte\n")); break;
16829 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16830 case 3: printf ("??? 3\n"); break;
16831 default:
16832 if (val <= 12)
dd24e3da 16833 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16834 1 << val);
16835 else
16836 printf ("??? (%d)\n", val);
16837 break;
16838 }
16839 break;
16840
16841 case 25: /* Tag_align_preserved. */
cd30bcef 16842 READ_ULEB (val, p, end);
75375b3e
MGD
16843 switch (val)
16844 {
2b692964
NC
16845 case 0: printf (_("None\n")); break;
16846 case 1: printf (_("8-byte, except leaf SP\n")); break;
16847 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16848 case 3: printf ("??? 3\n"); break;
16849 default:
16850 if (val <= 12)
dd24e3da 16851 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16852 1 << val);
16853 else
16854 printf ("??? (%d)\n", val);
16855 break;
16856 }
16857 break;
16858
11c1ff18 16859 case 32: /* Tag_compatibility. */
071436c6 16860 {
cd30bcef 16861 READ_ULEB (val, p, end);
071436c6 16862 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16863 if (p < end - 1)
16864 {
16865 size_t maxlen = (end - p) - 1;
16866
16867 print_symbol ((int) maxlen, (const char *) p);
16868 p += strnlen ((char *) p, maxlen) + 1;
16869 }
16870 else
16871 {
16872 printf (_("<corrupt>"));
16873 p = (unsigned char *) end;
16874 }
071436c6 16875 putchar ('\n');
071436c6 16876 }
11c1ff18
PB
16877 break;
16878
f5f53991 16879 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16880 /* PR 17531: file: 001-505008-0.01. */
16881 if (p < end)
16882 p++;
2b692964 16883 printf (_("True\n"));
f5f53991
AS
16884 break;
16885
16886 case 65: /* Tag_also_compatible_with. */
cd30bcef 16887 READ_ULEB (val, p, end);
f5f53991
AS
16888 if (val == 6 /* Tag_CPU_arch. */)
16889 {
cd30bcef 16890 READ_ULEB (val, p, end);
071436c6 16891 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16892 printf ("??? (%d)\n", val);
16893 else
16894 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16895 }
16896 else
16897 printf ("???\n");
071436c6
NC
16898 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16899 ;
f5f53991
AS
16900 break;
16901
11c1ff18 16902 default:
bee0ee85
NC
16903 printf (_("<unknown: %d>\n"), tag);
16904 break;
11c1ff18
PB
16905 }
16906 return p;
16907
16908 case 1:
f6f0e17b 16909 return display_tag_value (-1, p, end);
11c1ff18 16910 case 2:
f6f0e17b 16911 return display_tag_value (0, p, end);
11c1ff18
PB
16912
16913 default:
16914 assert (attr->type & 0x80);
cd30bcef 16915 READ_ULEB (val, p, end);
11c1ff18
PB
16916 type = attr->type & 0x7f;
16917 if (val >= type)
16918 printf ("??? (%d)\n", val);
16919 else
16920 printf ("%s\n", attr->table[val]);
16921 return p;
16922 }
16923 }
11c1ff18 16924
f6f0e17b 16925 return display_tag_value (tag, p, end);
11c1ff18
PB
16926}
16927
104d59d1 16928static unsigned char *
60bca95a 16929display_gnu_attribute (unsigned char * p,
60abdbed 16930 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16931 const unsigned char * const end)
104d59d1 16932{
cd30bcef 16933 unsigned int tag;
60abdbed 16934 unsigned int val;
104d59d1 16935
cd30bcef 16936 READ_ULEB (tag, p, end);
104d59d1
JM
16937
16938 /* Tag_compatibility is the only generic GNU attribute defined at
16939 present. */
16940 if (tag == 32)
16941 {
cd30bcef 16942 READ_ULEB (val, p, end);
071436c6
NC
16943
16944 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16945 if (p == end)
16946 {
071436c6 16947 printf (_("<corrupt>\n"));
f6f0e17b
NC
16948 warn (_("corrupt vendor attribute\n"));
16949 }
16950 else
16951 {
4082ef84
NC
16952 if (p < end - 1)
16953 {
16954 size_t maxlen = (end - p) - 1;
071436c6 16955
4082ef84
NC
16956 print_symbol ((int) maxlen, (const char *) p);
16957 p += strnlen ((char *) p, maxlen) + 1;
16958 }
16959 else
16960 {
16961 printf (_("<corrupt>"));
16962 p = (unsigned char *) end;
16963 }
071436c6 16964 putchar ('\n');
f6f0e17b 16965 }
104d59d1
JM
16966 return p;
16967 }
16968
16969 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16970 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16971
f6f0e17b 16972 return display_tag_value (tag, p, end);
104d59d1
JM
16973}
16974
85f7484a
PB
16975static unsigned char *
16976display_m68k_gnu_attribute (unsigned char * p,
16977 unsigned int tag,
16978 const unsigned char * const end)
16979{
16980 unsigned int val;
16981
16982 if (tag == Tag_GNU_M68K_ABI_FP)
16983 {
16984 printf (" Tag_GNU_M68K_ABI_FP: ");
16985 if (p == end)
16986 {
16987 printf (_("<corrupt>\n"));
16988 return p;
16989 }
16990 READ_ULEB (val, p, end);
16991
16992 if (val > 3)
16993 printf ("(%#x), ", val);
16994
16995 switch (val & 3)
16996 {
16997 case 0:
16998 printf (_("unspecified hard/soft float\n"));
16999 break;
17000 case 1:
17001 printf (_("hard float\n"));
17002 break;
17003 case 2:
17004 printf (_("soft float\n"));
17005 break;
17006 }
17007 return p;
17008 }
17009
17010 return display_tag_value (tag & 1, p, end);
17011}
17012
34c8bcba 17013static unsigned char *
f6f0e17b 17014display_power_gnu_attribute (unsigned char * p,
60abdbed 17015 unsigned int tag,
f6f0e17b 17016 const unsigned char * const end)
34c8bcba 17017{
005d79fd 17018 unsigned int val;
34c8bcba
JM
17019
17020 if (tag == Tag_GNU_Power_ABI_FP)
17021 {
34c8bcba 17022 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 17023 if (p == end)
005d79fd
AM
17024 {
17025 printf (_("<corrupt>\n"));
17026 return p;
17027 }
cd30bcef 17028 READ_ULEB (val, p, end);
60bca95a 17029
005d79fd
AM
17030 if (val > 15)
17031 printf ("(%#x), ", val);
17032
17033 switch (val & 3)
34c8bcba
JM
17034 {
17035 case 0:
005d79fd 17036 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17037 break;
17038 case 1:
005d79fd 17039 printf (_("hard float, "));
34c8bcba
JM
17040 break;
17041 case 2:
005d79fd 17042 printf (_("soft float, "));
34c8bcba 17043 break;
3c7b9897 17044 case 3:
005d79fd 17045 printf (_("single-precision hard float, "));
3c7b9897 17046 break;
005d79fd
AM
17047 }
17048
17049 switch (val & 0xC)
17050 {
17051 case 0:
17052 printf (_("unspecified long double\n"));
17053 break;
17054 case 4:
17055 printf (_("128-bit IBM long double\n"));
17056 break;
17057 case 8:
17058 printf (_("64-bit long double\n"));
17059 break;
17060 case 12:
17061 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17062 break;
17063 }
17064 return p;
005d79fd 17065 }
34c8bcba 17066
c6e65352
DJ
17067 if (tag == Tag_GNU_Power_ABI_Vector)
17068 {
c6e65352 17069 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17070 if (p == end)
005d79fd
AM
17071 {
17072 printf (_("<corrupt>\n"));
17073 return p;
17074 }
cd30bcef 17075 READ_ULEB (val, p, end);
005d79fd
AM
17076
17077 if (val > 3)
17078 printf ("(%#x), ", val);
17079
17080 switch (val & 3)
c6e65352
DJ
17081 {
17082 case 0:
005d79fd 17083 printf (_("unspecified\n"));
c6e65352
DJ
17084 break;
17085 case 1:
005d79fd 17086 printf (_("generic\n"));
c6e65352
DJ
17087 break;
17088 case 2:
17089 printf ("AltiVec\n");
17090 break;
17091 case 3:
17092 printf ("SPE\n");
17093 break;
c6e65352
DJ
17094 }
17095 return p;
005d79fd 17096 }
c6e65352 17097
f82e0623
NF
17098 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17099 {
005d79fd 17100 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17101 if (p == end)
f6f0e17b 17102 {
005d79fd 17103 printf (_("<corrupt>\n"));
f6f0e17b
NC
17104 return p;
17105 }
cd30bcef 17106 READ_ULEB (val, p, end);
0b4362b0 17107
005d79fd
AM
17108 if (val > 2)
17109 printf ("(%#x), ", val);
17110
17111 switch (val & 3)
17112 {
17113 case 0:
17114 printf (_("unspecified\n"));
17115 break;
17116 case 1:
17117 printf ("r3/r4\n");
17118 break;
17119 case 2:
17120 printf (_("memory\n"));
17121 break;
17122 case 3:
17123 printf ("???\n");
17124 break;
17125 }
f82e0623
NF
17126 return p;
17127 }
17128
f6f0e17b 17129 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17130}
17131
643f7afb
AK
17132static unsigned char *
17133display_s390_gnu_attribute (unsigned char * p,
60abdbed 17134 unsigned int tag,
643f7afb
AK
17135 const unsigned char * const end)
17136{
cd30bcef 17137 unsigned int val;
643f7afb
AK
17138
17139 if (tag == Tag_GNU_S390_ABI_Vector)
17140 {
643f7afb 17141 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17142 READ_ULEB (val, p, end);
643f7afb
AK
17143
17144 switch (val)
17145 {
17146 case 0:
17147 printf (_("any\n"));
17148 break;
17149 case 1:
17150 printf (_("software\n"));
17151 break;
17152 case 2:
17153 printf (_("hardware\n"));
17154 break;
17155 default:
17156 printf ("??? (%d)\n", val);
17157 break;
17158 }
17159 return p;
17160 }
17161
17162 return display_tag_value (tag & 1, p, end);
17163}
17164
9e8c70f9 17165static void
60abdbed 17166display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17167{
17168 if (mask)
17169 {
015dc7e1 17170 bool first = true;
071436c6 17171
9e8c70f9 17172 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17173 fputs ("mul32", stdout), first = false;
9e8c70f9 17174 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17175 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17176 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17177 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17178 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17179 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17180 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17181 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17182 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17183 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17184 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17185 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17186 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17187 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17188 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17189 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17190 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17191 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17192 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17193 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17194 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17195 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17196 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17197 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17198 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17199 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17200 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17201 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17202 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17203 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17204 }
17205 else
071436c6
NC
17206 fputc ('0', stdout);
17207 fputc ('\n', stdout);
9e8c70f9
DM
17208}
17209
3d68f91c 17210static void
60abdbed 17211display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17212{
17213 if (mask)
17214 {
015dc7e1 17215 bool first = true;
071436c6 17216
3d68f91c 17217 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17218 fputs ("fjathplus", stdout), first = false;
3d68f91c 17219 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17220 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17221 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17222 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17223 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17224 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17225 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17226 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17227 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17228 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17229 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17230 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17231 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17232 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17233 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17234 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17235 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17236 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17237 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17238 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17239 }
17240 else
071436c6
NC
17241 fputc ('0', stdout);
17242 fputc ('\n', stdout);
3d68f91c
JM
17243}
17244
9e8c70f9 17245static unsigned char *
f6f0e17b 17246display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17247 unsigned int tag,
f6f0e17b 17248 const unsigned char * const end)
9e8c70f9 17249{
cd30bcef 17250 unsigned int val;
3d68f91c 17251
9e8c70f9
DM
17252 if (tag == Tag_GNU_Sparc_HWCAPS)
17253 {
cd30bcef 17254 READ_ULEB (val, p, end);
9e8c70f9 17255 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17256 display_sparc_hwcaps (val);
17257 return p;
3d68f91c
JM
17258 }
17259 if (tag == Tag_GNU_Sparc_HWCAPS2)
17260 {
cd30bcef 17261 READ_ULEB (val, p, end);
3d68f91c
JM
17262 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17263 display_sparc_hwcaps2 (val);
17264 return p;
17265 }
9e8c70f9 17266
f6f0e17b 17267 return display_tag_value (tag, p, end);
9e8c70f9
DM
17268}
17269
351cdf24 17270static void
32ec8896 17271print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17272{
17273 switch (val)
17274 {
17275 case Val_GNU_MIPS_ABI_FP_ANY:
17276 printf (_("Hard or soft float\n"));
17277 break;
17278 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17279 printf (_("Hard float (double precision)\n"));
17280 break;
17281 case Val_GNU_MIPS_ABI_FP_SINGLE:
17282 printf (_("Hard float (single precision)\n"));
17283 break;
17284 case Val_GNU_MIPS_ABI_FP_SOFT:
17285 printf (_("Soft float\n"));
17286 break;
17287 case Val_GNU_MIPS_ABI_FP_OLD_64:
17288 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17289 break;
17290 case Val_GNU_MIPS_ABI_FP_XX:
17291 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17292 break;
17293 case Val_GNU_MIPS_ABI_FP_64:
17294 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17295 break;
17296 case Val_GNU_MIPS_ABI_FP_64A:
17297 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17298 break;
3350cc01
CM
17299 case Val_GNU_MIPS_ABI_FP_NAN2008:
17300 printf (_("NaN 2008 compatibility\n"));
17301 break;
351cdf24
MF
17302 default:
17303 printf ("??? (%d)\n", val);
17304 break;
17305 }
17306}
17307
2cf19d5c 17308static unsigned char *
f6f0e17b 17309display_mips_gnu_attribute (unsigned char * p,
60abdbed 17310 unsigned int tag,
f6f0e17b 17311 const unsigned char * const end)
2cf19d5c 17312{
2cf19d5c
JM
17313 if (tag == Tag_GNU_MIPS_ABI_FP)
17314 {
32ec8896 17315 unsigned int val;
f6f0e17b 17316
2cf19d5c 17317 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17318 READ_ULEB (val, p, end);
351cdf24 17319 print_mips_fp_abi_value (val);
2cf19d5c
JM
17320 return p;
17321 }
17322
a9f58168
CF
17323 if (tag == Tag_GNU_MIPS_ABI_MSA)
17324 {
32ec8896 17325 unsigned int val;
a9f58168 17326
a9f58168 17327 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17328 READ_ULEB (val, p, end);
a9f58168
CF
17329
17330 switch (val)
17331 {
17332 case Val_GNU_MIPS_ABI_MSA_ANY:
17333 printf (_("Any MSA or not\n"));
17334 break;
17335 case Val_GNU_MIPS_ABI_MSA_128:
17336 printf (_("128-bit MSA\n"));
17337 break;
17338 default:
17339 printf ("??? (%d)\n", val);
17340 break;
17341 }
17342 return p;
17343 }
17344
f6f0e17b 17345 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17346}
17347
59e6276b 17348static unsigned char *
f6f0e17b
NC
17349display_tic6x_attribute (unsigned char * p,
17350 const unsigned char * const end)
59e6276b 17351{
60abdbed 17352 unsigned int tag;
cd30bcef 17353 unsigned int val;
59e6276b 17354
cd30bcef 17355 READ_ULEB (tag, p, end);
59e6276b
JM
17356
17357 switch (tag)
17358 {
75fa6dc1 17359 case Tag_ISA:
75fa6dc1 17360 printf (" Tag_ISA: ");
cd30bcef 17361 READ_ULEB (val, p, end);
59e6276b
JM
17362
17363 switch (val)
17364 {
75fa6dc1 17365 case C6XABI_Tag_ISA_none:
59e6276b
JM
17366 printf (_("None\n"));
17367 break;
75fa6dc1 17368 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17369 printf ("C62x\n");
17370 break;
75fa6dc1 17371 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17372 printf ("C67x\n");
17373 break;
75fa6dc1 17374 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17375 printf ("C67x+\n");
17376 break;
75fa6dc1 17377 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17378 printf ("C64x\n");
17379 break;
75fa6dc1 17380 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17381 printf ("C64x+\n");
17382 break;
75fa6dc1 17383 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17384 printf ("C674x\n");
17385 break;
17386 default:
17387 printf ("??? (%d)\n", val);
17388 break;
17389 }
17390 return p;
17391
87779176 17392 case Tag_ABI_wchar_t:
87779176 17393 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17394 READ_ULEB (val, p, end);
87779176
JM
17395 switch (val)
17396 {
17397 case 0:
17398 printf (_("Not used\n"));
17399 break;
17400 case 1:
17401 printf (_("2 bytes\n"));
17402 break;
17403 case 2:
17404 printf (_("4 bytes\n"));
17405 break;
17406 default:
17407 printf ("??? (%d)\n", val);
17408 break;
17409 }
17410 return p;
17411
17412 case Tag_ABI_stack_align_needed:
87779176 17413 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17414 READ_ULEB (val, p, end);
87779176
JM
17415 switch (val)
17416 {
17417 case 0:
17418 printf (_("8-byte\n"));
17419 break;
17420 case 1:
17421 printf (_("16-byte\n"));
17422 break;
17423 default:
17424 printf ("??? (%d)\n", val);
17425 break;
17426 }
17427 return p;
17428
17429 case Tag_ABI_stack_align_preserved:
cd30bcef 17430 READ_ULEB (val, p, end);
87779176
JM
17431 printf (" Tag_ABI_stack_align_preserved: ");
17432 switch (val)
17433 {
17434 case 0:
17435 printf (_("8-byte\n"));
17436 break;
17437 case 1:
17438 printf (_("16-byte\n"));
17439 break;
17440 default:
17441 printf ("??? (%d)\n", val);
17442 break;
17443 }
17444 return p;
17445
b5593623 17446 case Tag_ABI_DSBT:
cd30bcef 17447 READ_ULEB (val, p, end);
b5593623
JM
17448 printf (" Tag_ABI_DSBT: ");
17449 switch (val)
17450 {
17451 case 0:
17452 printf (_("DSBT addressing not used\n"));
17453 break;
17454 case 1:
17455 printf (_("DSBT addressing used\n"));
17456 break;
17457 default:
17458 printf ("??? (%d)\n", val);
17459 break;
17460 }
17461 return p;
17462
87779176 17463 case Tag_ABI_PID:
cd30bcef 17464 READ_ULEB (val, p, end);
87779176
JM
17465 printf (" Tag_ABI_PID: ");
17466 switch (val)
17467 {
17468 case 0:
17469 printf (_("Data addressing position-dependent\n"));
17470 break;
17471 case 1:
17472 printf (_("Data addressing position-independent, GOT near DP\n"));
17473 break;
17474 case 2:
17475 printf (_("Data addressing position-independent, GOT far from DP\n"));
17476 break;
17477 default:
17478 printf ("??? (%d)\n", val);
17479 break;
17480 }
17481 return p;
17482
17483 case Tag_ABI_PIC:
cd30bcef 17484 READ_ULEB (val, p, end);
87779176
JM
17485 printf (" Tag_ABI_PIC: ");
17486 switch (val)
17487 {
17488 case 0:
17489 printf (_("Code addressing position-dependent\n"));
17490 break;
17491 case 1:
17492 printf (_("Code addressing position-independent\n"));
17493 break;
17494 default:
17495 printf ("??? (%d)\n", val);
17496 break;
17497 }
17498 return p;
17499
17500 case Tag_ABI_array_object_alignment:
cd30bcef 17501 READ_ULEB (val, p, end);
87779176
JM
17502 printf (" Tag_ABI_array_object_alignment: ");
17503 switch (val)
17504 {
17505 case 0:
17506 printf (_("8-byte\n"));
17507 break;
17508 case 1:
17509 printf (_("4-byte\n"));
17510 break;
17511 case 2:
17512 printf (_("16-byte\n"));
17513 break;
17514 default:
17515 printf ("??? (%d)\n", val);
17516 break;
17517 }
17518 return p;
17519
17520 case Tag_ABI_array_object_align_expected:
cd30bcef 17521 READ_ULEB (val, p, end);
87779176
JM
17522 printf (" Tag_ABI_array_object_align_expected: ");
17523 switch (val)
17524 {
17525 case 0:
17526 printf (_("8-byte\n"));
17527 break;
17528 case 1:
17529 printf (_("4-byte\n"));
17530 break;
17531 case 2:
17532 printf (_("16-byte\n"));
17533 break;
17534 default:
17535 printf ("??? (%d)\n", val);
17536 break;
17537 }
17538 return p;
17539
3cbd1c06 17540 case Tag_ABI_compatibility:
071436c6 17541 {
cd30bcef 17542 READ_ULEB (val, p, end);
071436c6 17543 printf (" Tag_ABI_compatibility: ");
071436c6 17544 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17545 if (p < end - 1)
17546 {
17547 size_t maxlen = (end - p) - 1;
17548
17549 print_symbol ((int) maxlen, (const char *) p);
17550 p += strnlen ((char *) p, maxlen) + 1;
17551 }
17552 else
17553 {
17554 printf (_("<corrupt>"));
17555 p = (unsigned char *) end;
17556 }
071436c6 17557 putchar ('\n');
071436c6
NC
17558 return p;
17559 }
87779176
JM
17560
17561 case Tag_ABI_conformance:
071436c6 17562 {
4082ef84
NC
17563 printf (" Tag_ABI_conformance: \"");
17564 if (p < end - 1)
17565 {
17566 size_t maxlen = (end - p) - 1;
071436c6 17567
4082ef84
NC
17568 print_symbol ((int) maxlen, (const char *) p);
17569 p += strnlen ((char *) p, maxlen) + 1;
17570 }
17571 else
17572 {
17573 printf (_("<corrupt>"));
17574 p = (unsigned char *) end;
17575 }
071436c6 17576 printf ("\"\n");
071436c6
NC
17577 return p;
17578 }
59e6276b
JM
17579 }
17580
f6f0e17b
NC
17581 return display_tag_value (tag, p, end);
17582}
59e6276b 17583
f6f0e17b 17584static void
60abdbed 17585display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17586{
17587 unsigned long addr = 0;
17588 size_t bytes = end - p;
17589
feceaa59 17590 assert (end >= p);
f6f0e17b 17591 while (bytes)
87779176 17592 {
f6f0e17b
NC
17593 int j;
17594 int k;
17595 int lbytes = (bytes > 16 ? 16 : bytes);
17596
17597 printf (" 0x%8.8lx ", addr);
17598
17599 for (j = 0; j < 16; j++)
17600 {
17601 if (j < lbytes)
17602 printf ("%2.2x", p[j]);
17603 else
17604 printf (" ");
17605
17606 if ((j & 3) == 3)
17607 printf (" ");
17608 }
17609
17610 for (j = 0; j < lbytes; j++)
17611 {
17612 k = p[j];
17613 if (k >= ' ' && k < 0x7f)
17614 printf ("%c", k);
17615 else
17616 printf (".");
17617 }
17618
17619 putchar ('\n');
17620
17621 p += lbytes;
17622 bytes -= lbytes;
17623 addr += lbytes;
87779176 17624 }
59e6276b 17625
f6f0e17b 17626 putchar ('\n');
59e6276b
JM
17627}
17628
13761a11 17629static unsigned char *
b0191216 17630display_msp430_attribute (unsigned char * p,
13761a11
NC
17631 const unsigned char * const end)
17632{
60abdbed
NC
17633 unsigned int val;
17634 unsigned int tag;
13761a11 17635
cd30bcef 17636 READ_ULEB (tag, p, end);
0b4362b0 17637
13761a11
NC
17638 switch (tag)
17639 {
17640 case OFBA_MSPABI_Tag_ISA:
13761a11 17641 printf (" Tag_ISA: ");
cd30bcef 17642 READ_ULEB (val, p, end);
13761a11
NC
17643 switch (val)
17644 {
17645 case 0: printf (_("None\n")); break;
17646 case 1: printf (_("MSP430\n")); break;
17647 case 2: printf (_("MSP430X\n")); break;
17648 default: printf ("??? (%d)\n", val); break;
17649 }
17650 break;
17651
17652 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17653 printf (" Tag_Code_Model: ");
cd30bcef 17654 READ_ULEB (val, p, end);
13761a11
NC
17655 switch (val)
17656 {
17657 case 0: printf (_("None\n")); break;
17658 case 1: printf (_("Small\n")); break;
17659 case 2: printf (_("Large\n")); break;
17660 default: printf ("??? (%d)\n", val); break;
17661 }
17662 break;
17663
17664 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17665 printf (" Tag_Data_Model: ");
cd30bcef 17666 READ_ULEB (val, p, end);
13761a11
NC
17667 switch (val)
17668 {
17669 case 0: printf (_("None\n")); break;
17670 case 1: printf (_("Small\n")); break;
17671 case 2: printf (_("Large\n")); break;
17672 case 3: printf (_("Restricted Large\n")); break;
17673 default: printf ("??? (%d)\n", val); break;
17674 }
17675 break;
17676
17677 default:
17678 printf (_(" <unknown tag %d>: "), tag);
17679
17680 if (tag & 1)
17681 {
071436c6 17682 putchar ('"');
4082ef84
NC
17683 if (p < end - 1)
17684 {
17685 size_t maxlen = (end - p) - 1;
17686
17687 print_symbol ((int) maxlen, (const char *) p);
17688 p += strnlen ((char *) p, maxlen) + 1;
17689 }
17690 else
17691 {
17692 printf (_("<corrupt>"));
17693 p = (unsigned char *) end;
17694 }
071436c6 17695 printf ("\"\n");
13761a11
NC
17696 }
17697 else
17698 {
cd30bcef 17699 READ_ULEB (val, p, end);
13761a11
NC
17700 printf ("%d (0x%x)\n", val, val);
17701 }
17702 break;
17703 }
17704
4082ef84 17705 assert (p <= end);
13761a11
NC
17706 return p;
17707}
17708
c0ea7c52
JL
17709static unsigned char *
17710display_msp430_gnu_attribute (unsigned char * p,
17711 unsigned int tag,
17712 const unsigned char * const end)
17713{
17714 if (tag == Tag_GNU_MSP430_Data_Region)
17715 {
cd30bcef 17716 unsigned int val;
c0ea7c52 17717
c0ea7c52 17718 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17719 READ_ULEB (val, p, end);
c0ea7c52
JL
17720
17721 switch (val)
17722 {
17723 case Val_GNU_MSP430_Data_Region_Any:
17724 printf (_("Any Region\n"));
17725 break;
17726 case Val_GNU_MSP430_Data_Region_Lower:
17727 printf (_("Lower Region Only\n"));
17728 break;
17729 default:
cd30bcef 17730 printf ("??? (%u)\n", val);
c0ea7c52
JL
17731 }
17732 return p;
17733 }
17734 return display_tag_value (tag & 1, p, end);
17735}
17736
2dc8dd17
JW
17737struct riscv_attr_tag_t {
17738 const char *name;
cd30bcef 17739 unsigned int tag;
2dc8dd17
JW
17740};
17741
17742static struct riscv_attr_tag_t riscv_attr_tag[] =
17743{
17744#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17745 T(arch),
17746 T(priv_spec),
17747 T(priv_spec_minor),
17748 T(priv_spec_revision),
17749 T(unaligned_access),
17750 T(stack_align),
17751#undef T
17752};
17753
17754static unsigned char *
17755display_riscv_attribute (unsigned char *p,
17756 const unsigned char * const end)
17757{
cd30bcef
AM
17758 unsigned int val;
17759 unsigned int tag;
2dc8dd17
JW
17760 struct riscv_attr_tag_t *attr = NULL;
17761 unsigned i;
17762
cd30bcef 17763 READ_ULEB (tag, p, end);
2dc8dd17
JW
17764
17765 /* Find the name of attribute. */
17766 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17767 {
17768 if (riscv_attr_tag[i].tag == tag)
17769 {
17770 attr = &riscv_attr_tag[i];
17771 break;
17772 }
17773 }
17774
17775 if (attr)
17776 printf (" %s: ", attr->name);
17777 else
17778 return display_tag_value (tag, p, end);
17779
17780 switch (tag)
17781 {
17782 case Tag_RISCV_priv_spec:
17783 case Tag_RISCV_priv_spec_minor:
17784 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17785 READ_ULEB (val, p, end);
17786 printf (_("%u\n"), val);
2dc8dd17
JW
17787 break;
17788 case Tag_RISCV_unaligned_access:
cd30bcef 17789 READ_ULEB (val, p, end);
2dc8dd17
JW
17790 switch (val)
17791 {
17792 case 0:
17793 printf (_("No unaligned access\n"));
17794 break;
17795 case 1:
17796 printf (_("Unaligned access\n"));
17797 break;
17798 }
17799 break;
17800 case Tag_RISCV_stack_align:
cd30bcef
AM
17801 READ_ULEB (val, p, end);
17802 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17803 break;
17804 case Tag_RISCV_arch:
17805 p = display_tag_value (-1, p, end);
17806 break;
17807 default:
17808 return display_tag_value (tag, p, end);
17809 }
17810
17811 return p;
17812}
17813
0861f561
CQ
17814static unsigned char *
17815display_csky_attribute (unsigned char * p,
17816 const unsigned char * const end)
17817{
17818 unsigned int tag;
17819 unsigned int val;
17820 READ_ULEB (tag, p, end);
17821
17822 if (tag >= Tag_CSKY_MAX)
17823 {
17824 return display_tag_value (-1, p, end);
17825 }
17826
17827 switch (tag)
17828 {
17829 case Tag_CSKY_ARCH_NAME:
17830 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17831 return display_tag_value (-1, p, end);
17832 case Tag_CSKY_CPU_NAME:
17833 printf (" Tag_CSKY_CPU_NAME:\t\t");
17834 return display_tag_value (-1, p, end);
17835
17836 case Tag_CSKY_ISA_FLAGS:
17837 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17838 return display_tag_value (0, p, end);
17839 case Tag_CSKY_ISA_EXT_FLAGS:
17840 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17841 return display_tag_value (0, p, end);
17842
17843 case Tag_CSKY_DSP_VERSION:
17844 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17845 READ_ULEB (val, p, end);
17846 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17847 printf ("DSP Extension\n");
17848 else if (val == VAL_CSKY_DSP_VERSION_2)
17849 printf ("DSP 2.0\n");
17850 break;
17851
17852 case Tag_CSKY_VDSP_VERSION:
17853 printf (" Tag_CSKY_VDSP_VERSION:\t");
17854 READ_ULEB (val, p, end);
17855 printf ("VDSP Version %d\n", val);
17856 break;
17857
17858 case Tag_CSKY_FPU_VERSION:
17859 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17860 READ_ULEB (val, p, end);
17861 if (val == VAL_CSKY_FPU_VERSION_1)
17862 printf ("ABIV1 FPU Version 1\n");
17863 else if (val == VAL_CSKY_FPU_VERSION_2)
17864 printf ("FPU Version 2\n");
17865 break;
17866
17867 case Tag_CSKY_FPU_ABI:
17868 printf (" Tag_CSKY_FPU_ABI:\t\t");
17869 READ_ULEB (val, p, end);
17870 if (val == VAL_CSKY_FPU_ABI_HARD)
17871 printf ("Hard\n");
17872 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17873 printf ("SoftFP\n");
17874 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17875 printf ("Soft\n");
17876 break;
17877 case Tag_CSKY_FPU_ROUNDING:
17878 READ_ULEB (val, p, end);
f253158f
NC
17879 if (val == 1)
17880 {
17881 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17882 printf ("Needed\n");
17883 }
0861f561
CQ
17884 break;
17885 case Tag_CSKY_FPU_DENORMAL:
17886 READ_ULEB (val, p, end);
f253158f
NC
17887 if (val == 1)
17888 {
17889 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17890 printf ("Needed\n");
17891 }
0861f561
CQ
17892 break;
17893 case Tag_CSKY_FPU_Exception:
17894 READ_ULEB (val, p, end);
f253158f
NC
17895 if (val == 1)
17896 {
17897 printf (" Tag_CSKY_FPU_Exception:\t");
17898 printf ("Needed\n");
17899 }
0861f561
CQ
17900 break;
17901 case Tag_CSKY_FPU_NUMBER_MODULE:
17902 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17903 return display_tag_value (-1, p, end);
17904 case Tag_CSKY_FPU_HARDFP:
17905 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17906 READ_ULEB (val, p, end);
17907 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17908 printf (" Half");
17909 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17910 printf (" Single");
17911 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17912 printf (" Double");
17913 printf ("\n");
17914 break;
17915 default:
17916 return display_tag_value (tag, p, end);
17917 }
17918 return p;
17919}
17920
015dc7e1 17921static bool
dda8d76d 17922process_attributes (Filedata * filedata,
60bca95a 17923 const char * public_name,
104d59d1 17924 unsigned int proc_type,
f6f0e17b 17925 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17926 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17927{
2cf0635d 17928 Elf_Internal_Shdr * sect;
11c1ff18 17929 unsigned i;
015dc7e1 17930 bool res = true;
11c1ff18
PB
17931
17932 /* Find the section header so that we get the size. */
dda8d76d
NC
17933 for (i = 0, sect = filedata->section_headers;
17934 i < filedata->file_header.e_shnum;
11c1ff18
PB
17935 i++, sect++)
17936 {
071436c6
NC
17937 unsigned char * contents;
17938 unsigned char * p;
17939
104d59d1 17940 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17941 continue;
17942
dda8d76d 17943 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17944 sect->sh_size, _("attributes"));
60bca95a 17945 if (contents == NULL)
32ec8896 17946 {
015dc7e1 17947 res = false;
32ec8896
NC
17948 continue;
17949 }
60bca95a 17950
11c1ff18 17951 p = contents;
60abdbed
NC
17952 /* The first character is the version of the attributes.
17953 Currently only version 1, (aka 'A') is recognised here. */
17954 if (*p != 'A')
32ec8896
NC
17955 {
17956 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17957 res = false;
32ec8896 17958 }
60abdbed 17959 else
11c1ff18 17960 {
625d49fc 17961 uint64_t section_len;
071436c6
NC
17962
17963 section_len = sect->sh_size - 1;
11c1ff18 17964 p++;
60bca95a 17965
071436c6 17966 while (section_len > 0)
11c1ff18 17967 {
625d49fc 17968 uint64_t attr_len;
e9847026 17969 unsigned int namelen;
015dc7e1
AM
17970 bool public_section;
17971 bool gnu_section;
11c1ff18 17972
071436c6 17973 if (section_len <= 4)
e0a31db1
NC
17974 {
17975 error (_("Tag section ends prematurely\n"));
015dc7e1 17976 res = false;
e0a31db1
NC
17977 break;
17978 }
071436c6 17979 attr_len = byte_get (p, 4);
11c1ff18 17980 p += 4;
60bca95a 17981
071436c6 17982 if (attr_len > section_len)
11c1ff18 17983 {
071436c6
NC
17984 error (_("Bad attribute length (%u > %u)\n"),
17985 (unsigned) attr_len, (unsigned) section_len);
17986 attr_len = section_len;
015dc7e1 17987 res = false;
11c1ff18 17988 }
74e1a04b 17989 /* PR 17531: file: 001-101425-0.004 */
071436c6 17990 else if (attr_len < 5)
74e1a04b 17991 {
071436c6 17992 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17993 res = false;
74e1a04b
NC
17994 break;
17995 }
e9847026 17996
071436c6
NC
17997 section_len -= attr_len;
17998 attr_len -= 4;
17999
18000 namelen = strnlen ((char *) p, attr_len) + 1;
18001 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
18002 {
18003 error (_("Corrupt attribute section name\n"));
015dc7e1 18004 res = false;
e9847026
NC
18005 break;
18006 }
18007
071436c6
NC
18008 printf (_("Attribute Section: "));
18009 print_symbol (INT_MAX, (const char *) p);
18010 putchar ('\n');
60bca95a
NC
18011
18012 if (public_name && streq ((char *) p, public_name))
015dc7e1 18013 public_section = true;
11c1ff18 18014 else
015dc7e1 18015 public_section = false;
60bca95a
NC
18016
18017 if (streq ((char *) p, "gnu"))
015dc7e1 18018 gnu_section = true;
104d59d1 18019 else
015dc7e1 18020 gnu_section = false;
60bca95a 18021
11c1ff18 18022 p += namelen;
071436c6 18023 attr_len -= namelen;
e0a31db1 18024
071436c6 18025 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18026 {
e0a31db1 18027 int tag;
cd30bcef 18028 unsigned int val;
625d49fc 18029 uint64_t size;
071436c6 18030 unsigned char * end;
60bca95a 18031
e0a31db1 18032 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18033 if (attr_len < 6)
e0a31db1
NC
18034 {
18035 error (_("Unused bytes at end of section\n"));
015dc7e1 18036 res = false;
e0a31db1
NC
18037 section_len = 0;
18038 break;
18039 }
18040
18041 tag = *(p++);
11c1ff18 18042 size = byte_get (p, 4);
071436c6 18043 if (size > attr_len)
11c1ff18 18044 {
e9847026 18045 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18046 (unsigned) size, (unsigned) attr_len);
015dc7e1 18047 res = false;
071436c6 18048 size = attr_len;
11c1ff18 18049 }
e0a31db1
NC
18050 /* PR binutils/17531: Safe handling of corrupt files. */
18051 if (size < 6)
18052 {
18053 error (_("Bad subsection length (%u < 6)\n"),
18054 (unsigned) size);
015dc7e1 18055 res = false;
e0a31db1
NC
18056 section_len = 0;
18057 break;
18058 }
60bca95a 18059
071436c6 18060 attr_len -= size;
11c1ff18 18061 end = p + size - 1;
071436c6 18062 assert (end <= contents + sect->sh_size);
11c1ff18 18063 p += 4;
60bca95a 18064
11c1ff18
PB
18065 switch (tag)
18066 {
18067 case 1:
2b692964 18068 printf (_("File Attributes\n"));
11c1ff18
PB
18069 break;
18070 case 2:
2b692964 18071 printf (_("Section Attributes:"));
11c1ff18
PB
18072 goto do_numlist;
18073 case 3:
2b692964 18074 printf (_("Symbol Attributes:"));
1a0670f3 18075 /* Fall through. */
11c1ff18
PB
18076 do_numlist:
18077 for (;;)
18078 {
cd30bcef 18079 READ_ULEB (val, p, end);
11c1ff18
PB
18080 if (val == 0)
18081 break;
18082 printf (" %d", val);
18083 }
18084 printf ("\n");
18085 break;
18086 default:
2b692964 18087 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18088 public_section = false;
11c1ff18
PB
18089 break;
18090 }
60bca95a 18091
071436c6 18092 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18093 {
18094 while (p < end)
f6f0e17b 18095 p = display_pub_attribute (p, end);
60abdbed 18096 assert (p == end);
104d59d1 18097 }
071436c6 18098 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18099 {
18100 while (p < end)
18101 p = display_gnu_attribute (p,
f6f0e17b
NC
18102 display_proc_gnu_attribute,
18103 end);
60abdbed 18104 assert (p == end);
11c1ff18 18105 }
071436c6 18106 else if (p < end)
11c1ff18 18107 {
071436c6 18108 printf (_(" Unknown attribute:\n"));
f6f0e17b 18109 display_raw_attribute (p, end);
11c1ff18
PB
18110 p = end;
18111 }
071436c6
NC
18112 else
18113 attr_len = 0;
11c1ff18
PB
18114 }
18115 }
18116 }
d70c5fc7 18117
60bca95a 18118 free (contents);
11c1ff18 18119 }
32ec8896
NC
18120
18121 return res;
11c1ff18
PB
18122}
18123
ccb4c951
RS
18124/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18125 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18126 and return the VMA of the next entry, or -1 if there was a problem.
18127 Does not read from DATA_END or beyond. */
ccb4c951 18128
625d49fc
AM
18129static uint64_t
18130print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18131 unsigned char * data_end)
ccb4c951
RS
18132{
18133 printf (" ");
18134 print_vma (addr, LONG_HEX);
18135 printf (" ");
18136 if (addr < pltgot + 0xfff0)
18137 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18138 else
18139 printf ("%10s", "");
18140 printf (" ");
18141 if (data == NULL)
2b692964 18142 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18143 else
18144 {
625d49fc 18145 uint64_t entry;
82b1b41b 18146 unsigned char * from = data + addr - pltgot;
ccb4c951 18147
82b1b41b
NC
18148 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18149 {
18150 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18151 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18152 return (uint64_t) -1;
82b1b41b
NC
18153 }
18154 else
18155 {
18156 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18157 print_vma (entry, LONG_HEX);
18158 }
ccb4c951
RS
18159 }
18160 return addr + (is_32bit_elf ? 4 : 8);
18161}
18162
861fb55a
DJ
18163/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18164 PLTGOT. Print the Address and Initial fields of an entry at VMA
18165 ADDR and return the VMA of the next entry. */
18166
625d49fc
AM
18167static uint64_t
18168print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18169{
18170 printf (" ");
18171 print_vma (addr, LONG_HEX);
18172 printf (" ");
18173 if (data == NULL)
2b692964 18174 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18175 else
18176 {
625d49fc 18177 uint64_t entry;
861fb55a
DJ
18178
18179 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18180 print_vma (entry, LONG_HEX);
18181 }
18182 return addr + (is_32bit_elf ? 4 : 8);
18183}
18184
351cdf24
MF
18185static void
18186print_mips_ases (unsigned int mask)
18187{
18188 if (mask & AFL_ASE_DSP)
18189 fputs ("\n\tDSP ASE", stdout);
18190 if (mask & AFL_ASE_DSPR2)
18191 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18192 if (mask & AFL_ASE_DSPR3)
18193 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18194 if (mask & AFL_ASE_EVA)
18195 fputs ("\n\tEnhanced VA Scheme", stdout);
18196 if (mask & AFL_ASE_MCU)
18197 fputs ("\n\tMCU (MicroController) ASE", stdout);
18198 if (mask & AFL_ASE_MDMX)
18199 fputs ("\n\tMDMX ASE", stdout);
18200 if (mask & AFL_ASE_MIPS3D)
18201 fputs ("\n\tMIPS-3D ASE", stdout);
18202 if (mask & AFL_ASE_MT)
18203 fputs ("\n\tMT ASE", stdout);
18204 if (mask & AFL_ASE_SMARTMIPS)
18205 fputs ("\n\tSmartMIPS ASE", stdout);
18206 if (mask & AFL_ASE_VIRT)
18207 fputs ("\n\tVZ ASE", stdout);
18208 if (mask & AFL_ASE_MSA)
18209 fputs ("\n\tMSA ASE", stdout);
18210 if (mask & AFL_ASE_MIPS16)
18211 fputs ("\n\tMIPS16 ASE", stdout);
18212 if (mask & AFL_ASE_MICROMIPS)
18213 fputs ("\n\tMICROMIPS ASE", stdout);
18214 if (mask & AFL_ASE_XPA)
18215 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18216 if (mask & AFL_ASE_MIPS16E2)
18217 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18218 if (mask & AFL_ASE_CRC)
18219 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18220 if (mask & AFL_ASE_GINV)
18221 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18222 if (mask & AFL_ASE_LOONGSON_MMI)
18223 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18224 if (mask & AFL_ASE_LOONGSON_CAM)
18225 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18226 if (mask & AFL_ASE_LOONGSON_EXT)
18227 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18228 if (mask & AFL_ASE_LOONGSON_EXT2)
18229 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18230 if (mask == 0)
18231 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18232 else if ((mask & ~AFL_ASE_MASK) != 0)
18233 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18234}
18235
18236static void
18237print_mips_isa_ext (unsigned int isa_ext)
18238{
18239 switch (isa_ext)
18240 {
18241 case 0:
18242 fputs (_("None"), stdout);
18243 break;
18244 case AFL_EXT_XLR:
18245 fputs ("RMI XLR", stdout);
18246 break;
2c629856
N
18247 case AFL_EXT_OCTEON3:
18248 fputs ("Cavium Networks Octeon3", stdout);
18249 break;
351cdf24
MF
18250 case AFL_EXT_OCTEON2:
18251 fputs ("Cavium Networks Octeon2", stdout);
18252 break;
18253 case AFL_EXT_OCTEONP:
18254 fputs ("Cavium Networks OcteonP", stdout);
18255 break;
351cdf24
MF
18256 case AFL_EXT_OCTEON:
18257 fputs ("Cavium Networks Octeon", stdout);
18258 break;
18259 case AFL_EXT_5900:
18260 fputs ("Toshiba R5900", stdout);
18261 break;
18262 case AFL_EXT_4650:
18263 fputs ("MIPS R4650", stdout);
18264 break;
18265 case AFL_EXT_4010:
18266 fputs ("LSI R4010", stdout);
18267 break;
18268 case AFL_EXT_4100:
18269 fputs ("NEC VR4100", stdout);
18270 break;
18271 case AFL_EXT_3900:
18272 fputs ("Toshiba R3900", stdout);
18273 break;
18274 case AFL_EXT_10000:
18275 fputs ("MIPS R10000", stdout);
18276 break;
18277 case AFL_EXT_SB1:
18278 fputs ("Broadcom SB-1", stdout);
18279 break;
18280 case AFL_EXT_4111:
18281 fputs ("NEC VR4111/VR4181", stdout);
18282 break;
18283 case AFL_EXT_4120:
18284 fputs ("NEC VR4120", stdout);
18285 break;
18286 case AFL_EXT_5400:
18287 fputs ("NEC VR5400", stdout);
18288 break;
18289 case AFL_EXT_5500:
18290 fputs ("NEC VR5500", stdout);
18291 break;
18292 case AFL_EXT_LOONGSON_2E:
18293 fputs ("ST Microelectronics Loongson 2E", stdout);
18294 break;
18295 case AFL_EXT_LOONGSON_2F:
18296 fputs ("ST Microelectronics Loongson 2F", stdout);
18297 break;
38bf472a
MR
18298 case AFL_EXT_INTERAPTIV_MR2:
18299 fputs ("Imagination interAptiv MR2", stdout);
18300 break;
351cdf24 18301 default:
00ac7aa0 18302 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18303 }
18304}
18305
32ec8896 18306static signed int
351cdf24
MF
18307get_mips_reg_size (int reg_size)
18308{
18309 return (reg_size == AFL_REG_NONE) ? 0
18310 : (reg_size == AFL_REG_32) ? 32
18311 : (reg_size == AFL_REG_64) ? 64
18312 : (reg_size == AFL_REG_128) ? 128
18313 : -1;
18314}
18315
015dc7e1 18316static bool
dda8d76d 18317process_mips_specific (Filedata * filedata)
5b18a4bc 18318{
2cf0635d 18319 Elf_Internal_Dyn * entry;
351cdf24 18320 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18321 size_t liblist_offset = 0;
18322 size_t liblistno = 0;
18323 size_t conflictsno = 0;
18324 size_t options_offset = 0;
18325 size_t conflicts_offset = 0;
861fb55a
DJ
18326 size_t pltrelsz = 0;
18327 size_t pltrel = 0;
625d49fc
AM
18328 uint64_t pltgot = 0;
18329 uint64_t mips_pltgot = 0;
18330 uint64_t jmprel = 0;
18331 uint64_t local_gotno = 0;
18332 uint64_t gotsym = 0;
18333 uint64_t symtabno = 0;
015dc7e1 18334 bool res = true;
103f02d3 18335
dda8d76d 18336 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18337 display_mips_gnu_attribute))
015dc7e1 18338 res = false;
2cf19d5c 18339
dda8d76d 18340 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18341
18342 if (sect != NULL)
18343 {
18344 Elf_External_ABIFlags_v0 *abiflags_ext;
18345 Elf_Internal_ABIFlags_v0 abiflags_in;
18346
18347 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18348 {
18349 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18350 res = false;
32ec8896 18351 }
351cdf24
MF
18352 else
18353 {
dda8d76d 18354 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18355 sect->sh_size, _("MIPS ABI Flags section"));
18356 if (abiflags_ext)
18357 {
18358 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18359 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18360 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18361 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18362 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18363 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18364 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18365 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18366 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18367 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18368 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18369
18370 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18371 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18372 if (abiflags_in.isa_rev > 1)
18373 printf ("r%d", abiflags_in.isa_rev);
18374 printf ("\nGPR size: %d",
18375 get_mips_reg_size (abiflags_in.gpr_size));
18376 printf ("\nCPR1 size: %d",
18377 get_mips_reg_size (abiflags_in.cpr1_size));
18378 printf ("\nCPR2 size: %d",
18379 get_mips_reg_size (abiflags_in.cpr2_size));
18380 fputs ("\nFP ABI: ", stdout);
18381 print_mips_fp_abi_value (abiflags_in.fp_abi);
18382 fputs ("ISA Extension: ", stdout);
18383 print_mips_isa_ext (abiflags_in.isa_ext);
18384 fputs ("\nASEs:", stdout);
18385 print_mips_ases (abiflags_in.ases);
18386 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18387 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18388 fputc ('\n', stdout);
18389 free (abiflags_ext);
18390 }
18391 }
18392 }
18393
19e6b90e 18394 /* We have a lot of special sections. Thanks SGI! */
978c4450 18395 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18396 {
18397 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18398 sect = find_section (filedata, ".got");
bbdd9a68
MR
18399 if (sect != NULL)
18400 {
18401 unsigned char *data_end;
18402 unsigned char *data;
625d49fc 18403 uint64_t ent, end;
bbdd9a68
MR
18404 int addr_size;
18405
18406 pltgot = sect->sh_addr;
18407
18408 ent = pltgot;
18409 addr_size = (is_32bit_elf ? 4 : 8);
18410 end = pltgot + sect->sh_size;
18411
dda8d76d 18412 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18413 end - pltgot, 1,
18414 _("Global Offset Table data"));
18415 /* PR 12855: Null data is handled gracefully throughout. */
18416 data_end = data + (end - pltgot);
18417
18418 printf (_("\nStatic GOT:\n"));
18419 printf (_(" Canonical gp value: "));
18420 print_vma (ent + 0x7ff0, LONG_HEX);
18421 printf ("\n\n");
18422
18423 /* In a dynamic binary GOT[0] is reserved for the dynamic
18424 loader to store the lazy resolver pointer, however in
18425 a static binary it may well have been omitted and GOT
18426 reduced to a table of addresses.
18427 PR 21344: Check for the entry being fully available
18428 before fetching it. */
18429 if (data
18430 && data + ent - pltgot + addr_size <= data_end
18431 && byte_get (data + ent - pltgot, addr_size) == 0)
18432 {
18433 printf (_(" Reserved entries:\n"));
18434 printf (_(" %*s %10s %*s\n"),
18435 addr_size * 2, _("Address"), _("Access"),
18436 addr_size * 2, _("Value"));
18437 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18438 printf ("\n");
625d49fc 18439 if (ent == (uint64_t) -1)
bbdd9a68
MR
18440 goto sgot_print_fail;
18441
18442 /* Check for the MSB of GOT[1] being set, identifying a
18443 GNU object. This entry will be used by some runtime
18444 loaders, to store the module pointer. Otherwise this
18445 is an ordinary local entry.
18446 PR 21344: Check for the entry being fully available
18447 before fetching it. */
18448 if (data
18449 && data + ent - pltgot + addr_size <= data_end
18450 && (byte_get (data + ent - pltgot, addr_size)
18451 >> (addr_size * 8 - 1)) != 0)
18452 {
18453 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18454 printf ("\n");
625d49fc 18455 if (ent == (uint64_t) -1)
bbdd9a68
MR
18456 goto sgot_print_fail;
18457 }
18458 printf ("\n");
18459 }
18460
f17e9d8a 18461 if (data != NULL && ent < end)
bbdd9a68
MR
18462 {
18463 printf (_(" Local entries:\n"));
18464 printf (" %*s %10s %*s\n",
18465 addr_size * 2, _("Address"), _("Access"),
18466 addr_size * 2, _("Value"));
18467 while (ent < end)
18468 {
18469 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18470 printf ("\n");
625d49fc 18471 if (ent == (uint64_t) -1)
bbdd9a68
MR
18472 goto sgot_print_fail;
18473 }
18474 printf ("\n");
18475 }
18476
18477 sgot_print_fail:
9db70fc3 18478 free (data);
bbdd9a68
MR
18479 }
18480 return res;
18481 }
252b5132 18482
978c4450 18483 for (entry = filedata->dynamic_section;
071436c6 18484 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18485 (entry < filedata->dynamic_section + filedata->dynamic_nent
18486 && entry->d_tag != DT_NULL);
071436c6 18487 ++entry)
252b5132
RH
18488 switch (entry->d_tag)
18489 {
18490 case DT_MIPS_LIBLIST:
d93f0186 18491 liblist_offset
dda8d76d 18492 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18493 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18494 break;
18495 case DT_MIPS_LIBLISTNO:
18496 liblistno = entry->d_un.d_val;
18497 break;
18498 case DT_MIPS_OPTIONS:
dda8d76d 18499 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18500 break;
18501 case DT_MIPS_CONFLICT:
d93f0186 18502 conflicts_offset
dda8d76d 18503 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18504 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18505 break;
18506 case DT_MIPS_CONFLICTNO:
18507 conflictsno = entry->d_un.d_val;
18508 break;
ccb4c951 18509 case DT_PLTGOT:
861fb55a
DJ
18510 pltgot = entry->d_un.d_ptr;
18511 break;
ccb4c951
RS
18512 case DT_MIPS_LOCAL_GOTNO:
18513 local_gotno = entry->d_un.d_val;
18514 break;
18515 case DT_MIPS_GOTSYM:
18516 gotsym = entry->d_un.d_val;
18517 break;
18518 case DT_MIPS_SYMTABNO:
18519 symtabno = entry->d_un.d_val;
18520 break;
861fb55a
DJ
18521 case DT_MIPS_PLTGOT:
18522 mips_pltgot = entry->d_un.d_ptr;
18523 break;
18524 case DT_PLTREL:
18525 pltrel = entry->d_un.d_val;
18526 break;
18527 case DT_PLTRELSZ:
18528 pltrelsz = entry->d_un.d_val;
18529 break;
18530 case DT_JMPREL:
18531 jmprel = entry->d_un.d_ptr;
18532 break;
252b5132
RH
18533 default:
18534 break;
18535 }
18536
18537 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18538 {
2cf0635d 18539 Elf32_External_Lib * elib;
252b5132
RH
18540 size_t cnt;
18541
dda8d76d 18542 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18543 sizeof (Elf32_External_Lib),
18544 liblistno,
18545 _("liblist section data"));
a6e9f9df 18546 if (elib)
252b5132 18547 {
d3a49aa8
AM
18548 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
18549 "\nSection '.liblist' contains %lu entries:\n",
18550 (unsigned long) liblistno),
a6e9f9df 18551 (unsigned long) liblistno);
2b692964 18552 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18553 stdout);
18554
18555 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18556 {
a6e9f9df 18557 Elf32_Lib liblist;
91d6fa6a 18558 time_t atime;
d5b07ef4 18559 char timebuf[128];
2cf0635d 18560 struct tm * tmp;
a6e9f9df
AM
18561
18562 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18563 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18564 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18565 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18566 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18567
91d6fa6a 18568 tmp = gmtime (&atime);
e9e44622
JJ
18569 snprintf (timebuf, sizeof (timebuf),
18570 "%04u-%02u-%02uT%02u:%02u:%02u",
18571 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18572 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18573
31104126 18574 printf ("%3lu: ", (unsigned long) cnt);
84714f86
AM
18575 if (valid_dynamic_name (filedata, liblist.l_name))
18576 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18577 else
2b692964 18578 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18579 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18580 liblist.l_version);
a6e9f9df
AM
18581
18582 if (liblist.l_flags == 0)
2b692964 18583 puts (_(" NONE"));
a6e9f9df
AM
18584 else
18585 {
18586 static const struct
252b5132 18587 {
2cf0635d 18588 const char * name;
a6e9f9df 18589 int bit;
252b5132 18590 }
a6e9f9df
AM
18591 l_flags_vals[] =
18592 {
18593 { " EXACT_MATCH", LL_EXACT_MATCH },
18594 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18595 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18596 { " EXPORTS", LL_EXPORTS },
18597 { " DELAY_LOAD", LL_DELAY_LOAD },
18598 { " DELTA", LL_DELTA }
18599 };
18600 int flags = liblist.l_flags;
18601 size_t fcnt;
18602
60bca95a 18603 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18604 if ((flags & l_flags_vals[fcnt].bit) != 0)
18605 {
18606 fputs (l_flags_vals[fcnt].name, stdout);
18607 flags ^= l_flags_vals[fcnt].bit;
18608 }
18609 if (flags != 0)
18610 printf (" %#x", (unsigned int) flags);
252b5132 18611
a6e9f9df
AM
18612 puts ("");
18613 }
252b5132 18614 }
252b5132 18615
a6e9f9df
AM
18616 free (elib);
18617 }
32ec8896 18618 else
015dc7e1 18619 res = false;
252b5132
RH
18620 }
18621
18622 if (options_offset != 0)
18623 {
2cf0635d 18624 Elf_External_Options * eopt;
252b5132
RH
18625 size_t offset;
18626 int cnt;
18627
18628 /* Find the section header so that we get the size. */
dda8d76d 18629 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18630 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18631 if (sect == NULL)
18632 {
18633 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18634 return false;
071436c6 18635 }
7fc0c668
NC
18636 /* PR 24243 */
18637 if (sect->sh_size < sizeof (* eopt))
18638 {
18639 error (_("The MIPS options section is too small.\n"));
015dc7e1 18640 return false;
7fc0c668 18641 }
252b5132 18642
dda8d76d 18643 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18644 sect->sh_size, _("options"));
a6e9f9df 18645 if (eopt)
252b5132 18646 {
fd17d1e6 18647 Elf_Internal_Options option;
76da6bbe 18648
a6e9f9df 18649 offset = cnt = 0;
82b1b41b 18650 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18651 {
2cf0635d 18652 Elf_External_Options * eoption;
fd17d1e6 18653 unsigned int optsize;
252b5132 18654
a6e9f9df 18655 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18656
fd17d1e6 18657 optsize = BYTE_GET (eoption->size);
76da6bbe 18658
82b1b41b 18659 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18660 if (optsize < sizeof (* eopt)
18661 || optsize > sect->sh_size - offset)
82b1b41b 18662 {
645f43a8 18663 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18664 optsize);
645f43a8 18665 free (eopt);
015dc7e1 18666 return false;
82b1b41b 18667 }
fd17d1e6 18668 offset += optsize;
a6e9f9df
AM
18669 ++cnt;
18670 }
252b5132 18671
d3a49aa8
AM
18672 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18673 "\nSection '%s' contains %d entries:\n",
18674 cnt),
dda8d76d 18675 printable_section_name (filedata, sect), cnt);
76da6bbe 18676
82b1b41b 18677 offset = 0;
a6e9f9df 18678 while (cnt-- > 0)
252b5132 18679 {
a6e9f9df 18680 size_t len;
fd17d1e6
AM
18681 Elf_External_Options * eoption;
18682
18683 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18684
18685 option.kind = BYTE_GET (eoption->kind);
18686 option.size = BYTE_GET (eoption->size);
18687 option.section = BYTE_GET (eoption->section);
18688 option.info = BYTE_GET (eoption->info);
a6e9f9df 18689
fd17d1e6 18690 switch (option.kind)
252b5132 18691 {
a6e9f9df
AM
18692 case ODK_NULL:
18693 /* This shouldn't happen. */
d0c4e780 18694 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18695 option.section, option.info);
a6e9f9df 18696 break;
2e6be59c 18697
a6e9f9df
AM
18698 case ODK_REGINFO:
18699 printf (" REGINFO ");
dda8d76d 18700 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18701 {
2cf0635d 18702 Elf32_External_RegInfo * ereg;
b34976b6 18703 Elf32_RegInfo reginfo;
a6e9f9df 18704
2e6be59c 18705 /* 32bit form. */
fd17d1e6
AM
18706 if (option.size < (sizeof (Elf_External_Options)
18707 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18708 {
18709 printf (_("<corrupt>\n"));
18710 error (_("Truncated MIPS REGINFO option\n"));
18711 cnt = 0;
18712 break;
18713 }
18714
fd17d1e6 18715 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18716
a6e9f9df
AM
18717 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18718 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18719 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18720 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18721 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18722 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18723
d0c4e780
AM
18724 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18725 reginfo.ri_gprmask, reginfo.ri_gp_value);
18726 printf (" "
18727 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18728 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18729 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18730 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18731 }
18732 else
18733 {
18734 /* 64 bit form. */
2cf0635d 18735 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18736 Elf64_Internal_RegInfo reginfo;
18737
fd17d1e6
AM
18738 if (option.size < (sizeof (Elf_External_Options)
18739 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18740 {
18741 printf (_("<corrupt>\n"));
18742 error (_("Truncated MIPS REGINFO option\n"));
18743 cnt = 0;
18744 break;
18745 }
18746
fd17d1e6 18747 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18748 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18749 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18750 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18751 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18752 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18753 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18754
d0c4e780
AM
18755 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18756 reginfo.ri_gprmask, reginfo.ri_gp_value);
18757 printf (" "
18758 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18759 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18760 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18761 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18762 }
fd17d1e6 18763 offset += option.size;
a6e9f9df 18764 continue;
2e6be59c 18765
a6e9f9df
AM
18766 case ODK_EXCEPTIONS:
18767 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18768 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18769 fputs (") fpe_max(", stdout);
fd17d1e6 18770 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18771 fputs (")", stdout);
18772
fd17d1e6 18773 if (option.info & OEX_PAGE0)
a6e9f9df 18774 fputs (" PAGE0", stdout);
fd17d1e6 18775 if (option.info & OEX_SMM)
a6e9f9df 18776 fputs (" SMM", stdout);
fd17d1e6 18777 if (option.info & OEX_FPDBUG)
a6e9f9df 18778 fputs (" FPDBUG", stdout);
fd17d1e6 18779 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18780 fputs (" DISMISS", stdout);
18781 break;
2e6be59c 18782
a6e9f9df
AM
18783 case ODK_PAD:
18784 fputs (" PAD ", stdout);
fd17d1e6 18785 if (option.info & OPAD_PREFIX)
a6e9f9df 18786 fputs (" PREFIX", stdout);
fd17d1e6 18787 if (option.info & OPAD_POSTFIX)
a6e9f9df 18788 fputs (" POSTFIX", stdout);
fd17d1e6 18789 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18790 fputs (" SYMBOL", stdout);
18791 break;
2e6be59c 18792
a6e9f9df
AM
18793 case ODK_HWPATCH:
18794 fputs (" HWPATCH ", stdout);
fd17d1e6 18795 if (option.info & OHW_R4KEOP)
a6e9f9df 18796 fputs (" R4KEOP", stdout);
fd17d1e6 18797 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18798 fputs (" R8KPFETCH", stdout);
fd17d1e6 18799 if (option.info & OHW_R5KEOP)
a6e9f9df 18800 fputs (" R5KEOP", stdout);
fd17d1e6 18801 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18802 fputs (" R5KCVTL", stdout);
18803 break;
2e6be59c 18804
a6e9f9df
AM
18805 case ODK_FILL:
18806 fputs (" FILL ", stdout);
18807 /* XXX Print content of info word? */
18808 break;
2e6be59c 18809
a6e9f9df
AM
18810 case ODK_TAGS:
18811 fputs (" TAGS ", stdout);
18812 /* XXX Print content of info word? */
18813 break;
2e6be59c 18814
a6e9f9df
AM
18815 case ODK_HWAND:
18816 fputs (" HWAND ", stdout);
fd17d1e6 18817 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18818 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18819 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18820 fputs (" R4KEOP_CLEAN", stdout);
18821 break;
2e6be59c 18822
a6e9f9df
AM
18823 case ODK_HWOR:
18824 fputs (" HWOR ", stdout);
fd17d1e6 18825 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18826 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18827 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18828 fputs (" R4KEOP_CLEAN", stdout);
18829 break;
2e6be59c 18830
a6e9f9df 18831 case ODK_GP_GROUP:
d0c4e780 18832 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18833 option.info & OGP_GROUP,
18834 (option.info & OGP_SELF) >> 16);
a6e9f9df 18835 break;
2e6be59c 18836
a6e9f9df 18837 case ODK_IDENT:
d0c4e780 18838 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18839 option.info & OGP_GROUP,
18840 (option.info & OGP_SELF) >> 16);
a6e9f9df 18841 break;
2e6be59c 18842
a6e9f9df
AM
18843 default:
18844 /* This shouldn't happen. */
d0c4e780 18845 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18846 option.kind, option.section, option.info);
a6e9f9df 18847 break;
252b5132 18848 }
a6e9f9df 18849
2cf0635d 18850 len = sizeof (* eopt);
fd17d1e6 18851 while (len < option.size)
82b1b41b 18852 {
fd17d1e6 18853 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18854
82b1b41b
NC
18855 if (ISPRINT (datum))
18856 printf ("%c", datum);
18857 else
18858 printf ("\\%03o", datum);
18859 len ++;
18860 }
a6e9f9df 18861 fputs ("\n", stdout);
82b1b41b 18862
fd17d1e6 18863 offset += option.size;
252b5132 18864 }
a6e9f9df 18865 free (eopt);
252b5132 18866 }
32ec8896 18867 else
015dc7e1 18868 res = false;
252b5132
RH
18869 }
18870
18871 if (conflicts_offset != 0 && conflictsno != 0)
18872 {
2cf0635d 18873 Elf32_Conflict * iconf;
252b5132
RH
18874 size_t cnt;
18875
978c4450 18876 if (filedata->dynamic_symbols == NULL)
252b5132 18877 {
591a748a 18878 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18879 return false;
252b5132
RH
18880 }
18881
7296a62a
NC
18882 /* PR 21345 - print a slightly more helpful error message
18883 if we are sure that the cmalloc will fail. */
645f43a8 18884 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18885 {
18886 error (_("Overlarge number of conflicts detected: %lx\n"),
18887 (long) conflictsno);
015dc7e1 18888 return false;
7296a62a
NC
18889 }
18890
3f5e193b 18891 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18892 if (iconf == NULL)
18893 {
8b73c356 18894 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18895 return false;
252b5132
RH
18896 }
18897
9ea033b2 18898 if (is_32bit_elf)
252b5132 18899 {
2cf0635d 18900 Elf32_External_Conflict * econf32;
a6e9f9df 18901
3f5e193b 18902 econf32 = (Elf32_External_Conflict *)
95099889
AM
18903 get_data (NULL, filedata, conflicts_offset,
18904 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18905 if (!econf32)
5a814d6d
AM
18906 {
18907 free (iconf);
015dc7e1 18908 return false;
5a814d6d 18909 }
252b5132
RH
18910
18911 for (cnt = 0; cnt < conflictsno; ++cnt)
18912 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18913
18914 free (econf32);
252b5132
RH
18915 }
18916 else
18917 {
2cf0635d 18918 Elf64_External_Conflict * econf64;
a6e9f9df 18919
3f5e193b 18920 econf64 = (Elf64_External_Conflict *)
95099889
AM
18921 get_data (NULL, filedata, conflicts_offset,
18922 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18923 if (!econf64)
5a814d6d
AM
18924 {
18925 free (iconf);
015dc7e1 18926 return false;
5a814d6d 18927 }
252b5132
RH
18928
18929 for (cnt = 0; cnt < conflictsno; ++cnt)
18930 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18931
18932 free (econf64);
252b5132
RH
18933 }
18934
d3a49aa8
AM
18935 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18936 "\nSection '.conflict' contains %lu entries:\n",
18937 (unsigned long) conflictsno),
c7e7ca54 18938 (unsigned long) conflictsno);
252b5132
RH
18939 puts (_(" Num: Index Value Name"));
18940
18941 for (cnt = 0; cnt < conflictsno; ++cnt)
18942 {
b34976b6 18943 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18944
978c4450 18945 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18946 printf (_("<corrupt symbol index>"));
d79b3d50 18947 else
e0a31db1
NC
18948 {
18949 Elf_Internal_Sym * psym;
18950
978c4450 18951 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18952 print_vma (psym->st_value, FULL_HEX);
18953 putchar (' ');
84714f86
AM
18954 if (valid_dynamic_name (filedata, psym->st_name))
18955 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18956 else
18957 printf (_("<corrupt: %14ld>"), psym->st_name);
18958 }
31104126 18959 putchar ('\n');
252b5132
RH
18960 }
18961
252b5132
RH
18962 free (iconf);
18963 }
18964
ccb4c951
RS
18965 if (pltgot != 0 && local_gotno != 0)
18966 {
625d49fc 18967 uint64_t ent, local_end, global_end;
bbeee7ea 18968 size_t i, offset;
2cf0635d 18969 unsigned char * data;
82b1b41b 18970 unsigned char * data_end;
bbeee7ea 18971 int addr_size;
ccb4c951 18972
91d6fa6a 18973 ent = pltgot;
ccb4c951
RS
18974 addr_size = (is_32bit_elf ? 4 : 8);
18975 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18976
74e1a04b
NC
18977 /* PR binutils/17533 file: 012-111227-0.004 */
18978 if (symtabno < gotsym)
18979 {
18980 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18981 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18982 return false;
74e1a04b 18983 }
82b1b41b 18984
74e1a04b 18985 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18986 /* PR 17531: file: 54c91a34. */
18987 if (global_end < local_end)
18988 {
18989 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18990 return false;
82b1b41b 18991 }
948f632f 18992
dda8d76d
NC
18993 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18994 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18995 global_end - pltgot, 1,
18996 _("Global Offset Table data"));
919383ac 18997 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18998 data_end = data + (global_end - pltgot);
59245841 18999
ccb4c951
RS
19000 printf (_("\nPrimary GOT:\n"));
19001 printf (_(" Canonical gp value: "));
19002 print_vma (pltgot + 0x7ff0, LONG_HEX);
19003 printf ("\n\n");
19004
19005 printf (_(" Reserved entries:\n"));
19006 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
19007 addr_size * 2, _("Address"), _("Access"),
19008 addr_size * 2, _("Initial"));
82b1b41b 19009 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 19010 printf (_(" Lazy resolver\n"));
625d49fc 19011 if (ent == (uint64_t) -1)
82b1b41b 19012 goto got_print_fail;
75ec1fdb 19013
c4ab9505
MR
19014 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19015 This entry will be used by some runtime loaders, to store the
19016 module pointer. Otherwise this is an ordinary local entry.
19017 PR 21344: Check for the entry being fully available before
19018 fetching it. */
19019 if (data
19020 && data + ent - pltgot + addr_size <= data_end
19021 && (byte_get (data + ent - pltgot, addr_size)
19022 >> (addr_size * 8 - 1)) != 0)
19023 {
19024 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19025 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 19026 if (ent == (uint64_t) -1)
c4ab9505 19027 goto got_print_fail;
ccb4c951
RS
19028 }
19029 printf ("\n");
19030
f17e9d8a 19031 if (data != NULL && ent < local_end)
ccb4c951
RS
19032 {
19033 printf (_(" Local entries:\n"));
cc5914eb 19034 printf (" %*s %10s %*s\n",
2b692964
NC
19035 addr_size * 2, _("Address"), _("Access"),
19036 addr_size * 2, _("Initial"));
91d6fa6a 19037 while (ent < local_end)
ccb4c951 19038 {
82b1b41b 19039 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19040 printf ("\n");
625d49fc 19041 if (ent == (uint64_t) -1)
82b1b41b 19042 goto got_print_fail;
ccb4c951
RS
19043 }
19044 printf ("\n");
19045 }
19046
f17e9d8a 19047 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19048 {
19049 int sym_width;
19050
19051 printf (_(" Global entries:\n"));
cc5914eb 19052 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19053 addr_size * 2, _("Address"),
19054 _("Access"),
2b692964 19055 addr_size * 2, _("Initial"),
9cf03b7e
NC
19056 addr_size * 2, _("Sym.Val."),
19057 _("Type"),
19058 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19059 _("Ndx"), _("Name"));
0b4362b0 19060
ccb4c951 19061 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19062
ccb4c951
RS
19063 for (i = gotsym; i < symtabno; i++)
19064 {
82b1b41b 19065 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19066 printf (" ");
e0a31db1 19067
978c4450 19068 if (filedata->dynamic_symbols == NULL)
e0a31db1 19069 printf (_("<no dynamic symbols>"));
978c4450 19070 else if (i < filedata->num_dynamic_syms)
e0a31db1 19071 {
978c4450 19072 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19073
19074 print_vma (psym->st_value, LONG_HEX);
19075 printf (" %-7s %3s ",
dda8d76d
NC
19076 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19077 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19078
84714f86 19079 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19080 print_symbol (sym_width,
84714f86 19081 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19082 else
19083 printf (_("<corrupt: %14ld>"), psym->st_name);
19084 }
ccb4c951 19085 else
7fc5ac57
JBG
19086 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
19087 (unsigned long) i);
e0a31db1 19088
ccb4c951 19089 printf ("\n");
625d49fc 19090 if (ent == (uint64_t) -1)
82b1b41b 19091 break;
ccb4c951
RS
19092 }
19093 printf ("\n");
19094 }
19095
82b1b41b 19096 got_print_fail:
9db70fc3 19097 free (data);
ccb4c951
RS
19098 }
19099
861fb55a
DJ
19100 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19101 {
625d49fc 19102 uint64_t ent, end;
861fb55a
DJ
19103 size_t offset, rel_offset;
19104 unsigned long count, i;
2cf0635d 19105 unsigned char * data;
861fb55a 19106 int addr_size, sym_width;
2cf0635d 19107 Elf_Internal_Rela * rels;
861fb55a 19108
dda8d76d 19109 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19110 if (pltrel == DT_RELA)
19111 {
dda8d76d 19112 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19113 return false;
861fb55a
DJ
19114 }
19115 else
19116 {
dda8d76d 19117 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19118 return false;
861fb55a
DJ
19119 }
19120
91d6fa6a 19121 ent = mips_pltgot;
861fb55a
DJ
19122 addr_size = (is_32bit_elf ? 4 : 8);
19123 end = mips_pltgot + (2 + count) * addr_size;
19124
dda8d76d
NC
19125 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19126 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19127 1, _("Procedure Linkage Table data"));
59245841 19128 if (data == NULL)
288f0ba2
AM
19129 {
19130 free (rels);
015dc7e1 19131 return false;
288f0ba2 19132 }
59245841 19133
9cf03b7e 19134 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19135 printf (_(" Reserved entries:\n"));
19136 printf (_(" %*s %*s Purpose\n"),
2b692964 19137 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19138 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19139 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19140 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19141 printf (_(" Module pointer\n"));
861fb55a
DJ
19142 printf ("\n");
19143
19144 printf (_(" Entries:\n"));
cc5914eb 19145 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19146 addr_size * 2, _("Address"),
19147 addr_size * 2, _("Initial"),
19148 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19149 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19150 for (i = 0; i < count; i++)
19151 {
df97ab2a 19152 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19153
91d6fa6a 19154 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19155 printf (" ");
e0a31db1 19156
978c4450 19157 if (idx >= filedata->num_dynamic_syms)
df97ab2a 19158 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 19159 else
e0a31db1 19160 {
978c4450 19161 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19162
19163 print_vma (psym->st_value, LONG_HEX);
19164 printf (" %-7s %3s ",
dda8d76d
NC
19165 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19166 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19167 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19168 print_symbol (sym_width,
84714f86 19169 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19170 else
19171 printf (_("<corrupt: %14ld>"), psym->st_name);
19172 }
861fb55a
DJ
19173 printf ("\n");
19174 }
19175 printf ("\n");
19176
9db70fc3 19177 free (data);
861fb55a
DJ
19178 free (rels);
19179 }
19180
32ec8896 19181 return res;
252b5132
RH
19182}
19183
015dc7e1 19184static bool
dda8d76d 19185process_nds32_specific (Filedata * filedata)
35c08157
KLC
19186{
19187 Elf_Internal_Shdr *sect = NULL;
19188
dda8d76d 19189 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19190 if (sect != NULL && sect->sh_size >= 4)
35c08157 19191 {
9c7b8e9b
AM
19192 unsigned char *buf;
19193 unsigned int flag;
35c08157
KLC
19194
19195 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19196 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19197 _("NDS32 elf flags section"));
35c08157 19198
9c7b8e9b 19199 if (buf == NULL)
015dc7e1 19200 return false;
32ec8896 19201
9c7b8e9b
AM
19202 flag = byte_get (buf, 4);
19203 free (buf);
19204 switch (flag & 0x3)
35c08157
KLC
19205 {
19206 case 0:
19207 printf ("(VEC_SIZE):\tNo entry.\n");
19208 break;
19209 case 1:
19210 printf ("(VEC_SIZE):\t4 bytes\n");
19211 break;
19212 case 2:
19213 printf ("(VEC_SIZE):\t16 bytes\n");
19214 break;
19215 case 3:
19216 printf ("(VEC_SIZE):\treserved\n");
19217 break;
19218 }
19219 }
19220
015dc7e1 19221 return true;
35c08157
KLC
19222}
19223
015dc7e1 19224static bool
dda8d76d 19225process_gnu_liblist (Filedata * filedata)
047b2264 19226{
2cf0635d
NC
19227 Elf_Internal_Shdr * section;
19228 Elf_Internal_Shdr * string_sec;
19229 Elf32_External_Lib * elib;
19230 char * strtab;
c256ffe7 19231 size_t strtab_size;
047b2264 19232 size_t cnt;
d3a49aa8 19233 unsigned long num_liblist;
047b2264 19234 unsigned i;
015dc7e1 19235 bool res = true;
047b2264
JJ
19236
19237 if (! do_arch)
015dc7e1 19238 return true;
047b2264 19239
dda8d76d
NC
19240 for (i = 0, section = filedata->section_headers;
19241 i < filedata->file_header.e_shnum;
b34976b6 19242 i++, section++)
047b2264
JJ
19243 {
19244 switch (section->sh_type)
19245 {
19246 case SHT_GNU_LIBLIST:
dda8d76d 19247 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19248 break;
19249
3f5e193b 19250 elib = (Elf32_External_Lib *)
dda8d76d 19251 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19252 _("liblist section data"));
047b2264
JJ
19253
19254 if (elib == NULL)
32ec8896 19255 {
015dc7e1 19256 res = false;
32ec8896
NC
19257 break;
19258 }
047b2264 19259
dda8d76d
NC
19260 string_sec = filedata->section_headers + section->sh_link;
19261 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19262 string_sec->sh_size,
19263 _("liblist string table"));
047b2264
JJ
19264 if (strtab == NULL
19265 || section->sh_entsize != sizeof (Elf32_External_Lib))
19266 {
19267 free (elib);
2842702f 19268 free (strtab);
015dc7e1 19269 res = false;
047b2264
JJ
19270 break;
19271 }
59245841 19272 strtab_size = string_sec->sh_size;
047b2264 19273
d3a49aa8
AM
19274 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19275 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
19276 "\nLibrary list section '%s' contains %lu entries:\n",
19277 num_liblist),
dda8d76d 19278 printable_section_name (filedata, section),
d3a49aa8 19279 num_liblist);
047b2264 19280
2b692964 19281 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19282
19283 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19284 ++cnt)
19285 {
19286 Elf32_Lib liblist;
91d6fa6a 19287 time_t atime;
d5b07ef4 19288 char timebuf[128];
2cf0635d 19289 struct tm * tmp;
047b2264
JJ
19290
19291 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19292 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19293 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19294 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19295 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19296
91d6fa6a 19297 tmp = gmtime (&atime);
e9e44622
JJ
19298 snprintf (timebuf, sizeof (timebuf),
19299 "%04u-%02u-%02uT%02u:%02u:%02u",
19300 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19301 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
19302
19303 printf ("%3lu: ", (unsigned long) cnt);
19304 if (do_wide)
c256ffe7 19305 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19306 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19307 else
c256ffe7 19308 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19309 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19310 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19311 liblist.l_version, liblist.l_flags);
19312 }
19313
19314 free (elib);
2842702f 19315 free (strtab);
047b2264
JJ
19316 }
19317 }
19318
32ec8896 19319 return res;
047b2264
JJ
19320}
19321
9437c45b 19322static const char *
dda8d76d 19323get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19324{
19325 static char buff[64];
103f02d3 19326
dda8d76d 19327 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19328 switch (e_type)
19329 {
57346661 19330 case NT_AUXV:
1ec5cd37 19331 return _("NT_AUXV (auxiliary vector)");
57346661 19332 case NT_PRSTATUS:
1ec5cd37 19333 return _("NT_PRSTATUS (prstatus structure)");
57346661 19334 case NT_FPREGSET:
1ec5cd37 19335 return _("NT_FPREGSET (floating point registers)");
57346661 19336 case NT_PRPSINFO:
1ec5cd37 19337 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19338 case NT_TASKSTRUCT:
1ec5cd37 19339 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19340 case NT_GDB_TDESC:
19341 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19342 case NT_PRXFPREG:
1ec5cd37 19343 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19344 case NT_PPC_VMX:
19345 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19346 case NT_PPC_VSX:
19347 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19348 case NT_PPC_TAR:
19349 return _("NT_PPC_TAR (ppc TAR register)");
19350 case NT_PPC_PPR:
19351 return _("NT_PPC_PPR (ppc PPR register)");
19352 case NT_PPC_DSCR:
19353 return _("NT_PPC_DSCR (ppc DSCR register)");
19354 case NT_PPC_EBB:
19355 return _("NT_PPC_EBB (ppc EBB registers)");
19356 case NT_PPC_PMU:
19357 return _("NT_PPC_PMU (ppc PMU registers)");
19358 case NT_PPC_TM_CGPR:
19359 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19360 case NT_PPC_TM_CFPR:
19361 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19362 case NT_PPC_TM_CVMX:
19363 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19364 case NT_PPC_TM_CVSX:
3fd21718 19365 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19366 case NT_PPC_TM_SPR:
19367 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19368 case NT_PPC_TM_CTAR:
19369 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19370 case NT_PPC_TM_CPPR:
19371 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19372 case NT_PPC_TM_CDSCR:
19373 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19374 case NT_386_TLS:
19375 return _("NT_386_TLS (x86 TLS information)");
19376 case NT_386_IOPERM:
19377 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19378 case NT_X86_XSTATE:
19379 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19380 case NT_X86_CET:
19381 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19382 case NT_S390_HIGH_GPRS:
19383 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19384 case NT_S390_TIMER:
19385 return _("NT_S390_TIMER (s390 timer register)");
19386 case NT_S390_TODCMP:
19387 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19388 case NT_S390_TODPREG:
19389 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19390 case NT_S390_CTRS:
19391 return _("NT_S390_CTRS (s390 control registers)");
19392 case NT_S390_PREFIX:
19393 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19394 case NT_S390_LAST_BREAK:
19395 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19396 case NT_S390_SYSTEM_CALL:
19397 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19398 case NT_S390_TDB:
19399 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19400 case NT_S390_VXRS_LOW:
19401 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19402 case NT_S390_VXRS_HIGH:
19403 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19404 case NT_S390_GS_CB:
19405 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19406 case NT_S390_GS_BC:
19407 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19408 case NT_ARM_VFP:
19409 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19410 case NT_ARM_TLS:
19411 return _("NT_ARM_TLS (AArch TLS registers)");
19412 case NT_ARM_HW_BREAK:
19413 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19414 case NT_ARM_HW_WATCH:
19415 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
19416 case NT_ARM_SYSTEM_CALL:
19417 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
19418 case NT_ARM_SVE:
19419 return _("NT_ARM_SVE (AArch SVE registers)");
19420 case NT_ARM_PAC_MASK:
19421 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19422 case NT_ARM_PACA_KEYS:
19423 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19424 case NT_ARM_PACG_KEYS:
19425 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19426 case NT_ARM_TAGGED_ADDR_CTRL:
19427 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
19428 case NT_ARM_PAC_ENABLED_KEYS:
19429 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19430 case NT_ARC_V2:
19431 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19432 case NT_RISCV_CSR:
19433 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19434 case NT_PSTATUS:
1ec5cd37 19435 return _("NT_PSTATUS (pstatus structure)");
57346661 19436 case NT_FPREGS:
1ec5cd37 19437 return _("NT_FPREGS (floating point registers)");
57346661 19438 case NT_PSINFO:
1ec5cd37 19439 return _("NT_PSINFO (psinfo structure)");
57346661 19440 case NT_LWPSTATUS:
1ec5cd37 19441 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19442 case NT_LWPSINFO:
1ec5cd37 19443 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19444 case NT_WIN32PSTATUS:
1ec5cd37 19445 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19446 case NT_SIGINFO:
19447 return _("NT_SIGINFO (siginfo_t data)");
19448 case NT_FILE:
19449 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19450 default:
19451 break;
19452 }
19453 else
19454 switch (e_type)
19455 {
19456 case NT_VERSION:
19457 return _("NT_VERSION (version)");
19458 case NT_ARCH:
19459 return _("NT_ARCH (architecture)");
9ef920e9 19460 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19461 return _("OPEN");
9ef920e9 19462 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19463 return _("func");
c8795e1f
NC
19464 case NT_GO_BUILDID:
19465 return _("GO BUILDID");
3ac925fc
LB
19466 case FDO_PACKAGING_METADATA:
19467 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19468 default:
19469 break;
19470 }
19471
e9e44622 19472 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19473 return buff;
779fe533
NC
19474}
19475
015dc7e1 19476static bool
9ece1fa9
TT
19477print_core_note (Elf_Internal_Note *pnote)
19478{
19479 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 19480 uint64_t count, page_size;
9ece1fa9
TT
19481 unsigned char *descdata, *filenames, *descend;
19482
19483 if (pnote->type != NT_FILE)
04ac15ab
AS
19484 {
19485 if (do_wide)
19486 printf ("\n");
015dc7e1 19487 return true;
04ac15ab 19488 }
9ece1fa9 19489
9ece1fa9
TT
19490 if (!is_32bit_elf)
19491 {
19492 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19493 /* Still "successful". */
015dc7e1 19494 return true;
9ece1fa9 19495 }
9ece1fa9
TT
19496
19497 if (pnote->descsz < 2 * addr_size)
19498 {
32ec8896 19499 error (_(" Malformed note - too short for header\n"));
015dc7e1 19500 return false;
9ece1fa9
TT
19501 }
19502
19503 descdata = (unsigned char *) pnote->descdata;
19504 descend = descdata + pnote->descsz;
19505
19506 if (descdata[pnote->descsz - 1] != '\0')
19507 {
32ec8896 19508 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19509 return false;
9ece1fa9
TT
19510 }
19511
19512 count = byte_get (descdata, addr_size);
19513 descdata += addr_size;
19514
19515 page_size = byte_get (descdata, addr_size);
19516 descdata += addr_size;
19517
625d49fc 19518 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 19519 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19520 {
32ec8896 19521 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19522 return false;
9ece1fa9
TT
19523 }
19524
19525 printf (_(" Page size: "));
19526 print_vma (page_size, DEC);
19527 printf ("\n");
19528
19529 printf (_(" %*s%*s%*s\n"),
19530 (int) (2 + 2 * addr_size), _("Start"),
19531 (int) (4 + 2 * addr_size), _("End"),
19532 (int) (4 + 2 * addr_size), _("Page Offset"));
19533 filenames = descdata + count * 3 * addr_size;
595712bb 19534 while (count-- > 0)
9ece1fa9 19535 {
625d49fc 19536 uint64_t start, end, file_ofs;
9ece1fa9
TT
19537
19538 if (filenames == descend)
19539 {
32ec8896 19540 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19541 return false;
9ece1fa9
TT
19542 }
19543
19544 start = byte_get (descdata, addr_size);
19545 descdata += addr_size;
19546 end = byte_get (descdata, addr_size);
19547 descdata += addr_size;
19548 file_ofs = byte_get (descdata, addr_size);
19549 descdata += addr_size;
19550
19551 printf (" ");
19552 print_vma (start, FULL_HEX);
19553 printf (" ");
19554 print_vma (end, FULL_HEX);
19555 printf (" ");
19556 print_vma (file_ofs, FULL_HEX);
19557 printf ("\n %s\n", filenames);
19558
19559 filenames += 1 + strlen ((char *) filenames);
19560 }
19561
015dc7e1 19562 return true;
9ece1fa9
TT
19563}
19564
1118d252
RM
19565static const char *
19566get_gnu_elf_note_type (unsigned e_type)
19567{
1449284b 19568 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19569 switch (e_type)
19570 {
19571 case NT_GNU_ABI_TAG:
19572 return _("NT_GNU_ABI_TAG (ABI version tag)");
19573 case NT_GNU_HWCAP:
19574 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19575 case NT_GNU_BUILD_ID:
19576 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19577 case NT_GNU_GOLD_VERSION:
19578 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19579 case NT_GNU_PROPERTY_TYPE_0:
19580 return _("NT_GNU_PROPERTY_TYPE_0");
19581 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19582 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19583 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19584 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19585 default:
1449284b
NC
19586 {
19587 static char buff[64];
1118d252 19588
1449284b
NC
19589 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19590 return buff;
19591 }
19592 }
1118d252
RM
19593}
19594
a9eafb08
L
19595static void
19596decode_x86_compat_isa (unsigned int bitmask)
19597{
19598 while (bitmask)
19599 {
19600 unsigned int bit = bitmask & (- bitmask);
19601
19602 bitmask &= ~ bit;
19603 switch (bit)
19604 {
19605 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19606 printf ("i486");
19607 break;
19608 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19609 printf ("586");
19610 break;
19611 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19612 printf ("686");
19613 break;
19614 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19615 printf ("SSE");
19616 break;
19617 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19618 printf ("SSE2");
19619 break;
19620 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19621 printf ("SSE3");
19622 break;
19623 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19624 printf ("SSSE3");
19625 break;
19626 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19627 printf ("SSE4_1");
19628 break;
19629 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19630 printf ("SSE4_2");
19631 break;
19632 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19633 printf ("AVX");
19634 break;
19635 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19636 printf ("AVX2");
19637 break;
19638 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19639 printf ("AVX512F");
19640 break;
19641 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19642 printf ("AVX512CD");
19643 break;
19644 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19645 printf ("AVX512ER");
19646 break;
19647 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19648 printf ("AVX512PF");
19649 break;
19650 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19651 printf ("AVX512VL");
19652 break;
19653 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19654 printf ("AVX512DQ");
19655 break;
19656 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19657 printf ("AVX512BW");
19658 break;
65b3d26e
L
19659 default:
19660 printf (_("<unknown: %x>"), bit);
19661 break;
a9eafb08
L
19662 }
19663 if (bitmask)
19664 printf (", ");
19665 }
19666}
19667
9ef920e9 19668static void
32930e4e 19669decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19670{
0a59decb 19671 if (!bitmask)
90c745dc
L
19672 {
19673 printf (_("<None>"));
19674 return;
19675 }
90c745dc 19676
9ef920e9
NC
19677 while (bitmask)
19678 {
1fc87489 19679 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19680
19681 bitmask &= ~ bit;
19682 switch (bit)
19683 {
32930e4e 19684 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19685 printf ("CMOV");
19686 break;
32930e4e 19687 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19688 printf ("SSE");
19689 break;
32930e4e 19690 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19691 printf ("SSE2");
19692 break;
32930e4e 19693 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19694 printf ("SSE3");
19695 break;
32930e4e 19696 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19697 printf ("SSSE3");
19698 break;
32930e4e 19699 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19700 printf ("SSE4_1");
19701 break;
32930e4e 19702 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19703 printf ("SSE4_2");
19704 break;
32930e4e 19705 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19706 printf ("AVX");
19707 break;
32930e4e 19708 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19709 printf ("AVX2");
19710 break;
32930e4e 19711 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19712 printf ("FMA");
19713 break;
32930e4e 19714 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19715 printf ("AVX512F");
19716 break;
32930e4e 19717 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19718 printf ("AVX512CD");
19719 break;
32930e4e 19720 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19721 printf ("AVX512ER");
19722 break;
32930e4e 19723 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19724 printf ("AVX512PF");
19725 break;
32930e4e 19726 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19727 printf ("AVX512VL");
19728 break;
32930e4e 19729 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19730 printf ("AVX512DQ");
19731 break;
32930e4e 19732 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19733 printf ("AVX512BW");
19734 break;
32930e4e 19735 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19736 printf ("AVX512_4FMAPS");
19737 break;
32930e4e 19738 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19739 printf ("AVX512_4VNNIW");
19740 break;
32930e4e 19741 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19742 printf ("AVX512_BITALG");
19743 break;
32930e4e 19744 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19745 printf ("AVX512_IFMA");
19746 break;
32930e4e 19747 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19748 printf ("AVX512_VBMI");
19749 break;
32930e4e 19750 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19751 printf ("AVX512_VBMI2");
19752 break;
32930e4e 19753 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19754 printf ("AVX512_VNNI");
19755 break;
32930e4e 19756 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19757 printf ("AVX512_BF16");
19758 break;
65b3d26e
L
19759 default:
19760 printf (_("<unknown: %x>"), bit);
19761 break;
9ef920e9
NC
19762 }
19763 if (bitmask)
19764 printf (", ");
19765 }
19766}
19767
28cdbb18
SM
19768static const char *
19769get_amdgpu_elf_note_type (unsigned int e_type)
19770{
19771 switch (e_type)
19772 {
19773 case NT_AMDGPU_METADATA:
19774 return _("NT_AMDGPU_METADATA (code object metadata)");
19775 default:
19776 {
19777 static char buf[64];
19778 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
19779 return buf;
19780 }
19781 }
19782}
19783
32930e4e
L
19784static void
19785decode_x86_isa (unsigned int bitmask)
19786{
32930e4e
L
19787 while (bitmask)
19788 {
19789 unsigned int bit = bitmask & (- bitmask);
19790
19791 bitmask &= ~ bit;
19792 switch (bit)
19793 {
b0ab0693
L
19794 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19795 printf ("x86-64-baseline");
19796 break;
32930e4e
L
19797 case GNU_PROPERTY_X86_ISA_1_V2:
19798 printf ("x86-64-v2");
19799 break;
19800 case GNU_PROPERTY_X86_ISA_1_V3:
19801 printf ("x86-64-v3");
19802 break;
19803 case GNU_PROPERTY_X86_ISA_1_V4:
19804 printf ("x86-64-v4");
19805 break;
19806 default:
19807 printf (_("<unknown: %x>"), bit);
19808 break;
19809 }
19810 if (bitmask)
19811 printf (", ");
19812 }
19813}
19814
ee2fdd6f 19815static void
a9eafb08 19816decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19817{
0a59decb 19818 if (!bitmask)
90c745dc
L
19819 {
19820 printf (_("<None>"));
19821 return;
19822 }
90c745dc 19823
ee2fdd6f
L
19824 while (bitmask)
19825 {
19826 unsigned int bit = bitmask & (- bitmask);
19827
19828 bitmask &= ~ bit;
19829 switch (bit)
19830 {
19831 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19832 printf ("IBT");
ee2fdd6f 19833 break;
48580982 19834 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19835 printf ("SHSTK");
48580982 19836 break;
279d901e
L
19837 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19838 printf ("LAM_U48");
19839 break;
19840 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19841 printf ("LAM_U57");
19842 break;
ee2fdd6f
L
19843 default:
19844 printf (_("<unknown: %x>"), bit);
19845 break;
19846 }
19847 if (bitmask)
19848 printf (", ");
19849 }
19850}
19851
a9eafb08
L
19852static void
19853decode_x86_feature_2 (unsigned int bitmask)
19854{
0a59decb 19855 if (!bitmask)
90c745dc
L
19856 {
19857 printf (_("<None>"));
19858 return;
19859 }
90c745dc 19860
a9eafb08
L
19861 while (bitmask)
19862 {
19863 unsigned int bit = bitmask & (- bitmask);
19864
19865 bitmask &= ~ bit;
19866 switch (bit)
19867 {
19868 case GNU_PROPERTY_X86_FEATURE_2_X86:
19869 printf ("x86");
19870 break;
19871 case GNU_PROPERTY_X86_FEATURE_2_X87:
19872 printf ("x87");
19873 break;
19874 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19875 printf ("MMX");
19876 break;
19877 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19878 printf ("XMM");
19879 break;
19880 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19881 printf ("YMM");
19882 break;
19883 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19884 printf ("ZMM");
19885 break;
a308b89d
L
19886 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19887 printf ("TMM");
19888 break;
32930e4e
L
19889 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19890 printf ("MASK");
19891 break;
a9eafb08
L
19892 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19893 printf ("FXSR");
19894 break;
19895 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19896 printf ("XSAVE");
19897 break;
19898 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19899 printf ("XSAVEOPT");
19900 break;
19901 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19902 printf ("XSAVEC");
19903 break;
65b3d26e
L
19904 default:
19905 printf (_("<unknown: %x>"), bit);
19906 break;
a9eafb08
L
19907 }
19908 if (bitmask)
19909 printf (", ");
19910 }
19911}
19912
cd702818
SD
19913static void
19914decode_aarch64_feature_1_and (unsigned int bitmask)
19915{
19916 while (bitmask)
19917 {
19918 unsigned int bit = bitmask & (- bitmask);
19919
19920 bitmask &= ~ bit;
19921 switch (bit)
19922 {
19923 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19924 printf ("BTI");
19925 break;
19926
19927 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19928 printf ("PAC");
19929 break;
19930
19931 default:
19932 printf (_("<unknown: %x>"), bit);
19933 break;
19934 }
19935 if (bitmask)
19936 printf (", ");
19937 }
19938}
19939
6320fd00
L
19940static void
19941decode_1_needed (unsigned int bitmask)
19942{
19943 while (bitmask)
19944 {
19945 unsigned int bit = bitmask & (- bitmask);
19946
19947 bitmask &= ~ bit;
19948 switch (bit)
19949 {
19950 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19951 printf ("indirect external access");
19952 break;
19953 default:
19954 printf (_("<unknown: %x>"), bit);
19955 break;
19956 }
19957 if (bitmask)
19958 printf (", ");
19959 }
19960}
19961
9ef920e9 19962static void
dda8d76d 19963print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19964{
19965 unsigned char * ptr = (unsigned char *) pnote->descdata;
19966 unsigned char * ptr_end = ptr + pnote->descsz;
19967 unsigned int size = is_32bit_elf ? 4 : 8;
19968
19969 printf (_(" Properties: "));
19970
1fc87489 19971 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19972 {
19973 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19974 return;
19975 }
19976
6ab2c4ed 19977 while (ptr < ptr_end)
9ef920e9 19978 {
1fc87489 19979 unsigned int j;
6ab2c4ed
MC
19980 unsigned int type;
19981 unsigned int datasz;
19982
19983 if ((size_t) (ptr_end - ptr) < 8)
19984 {
19985 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19986 break;
19987 }
19988
19989 type = byte_get (ptr, 4);
19990 datasz = byte_get (ptr + 4, 4);
9ef920e9 19991
1fc87489 19992 ptr += 8;
9ef920e9 19993
6ab2c4ed 19994 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19995 {
1fc87489
L
19996 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19997 type, datasz);
9ef920e9 19998 break;
1fc87489 19999 }
9ef920e9 20000
1fc87489
L
20001 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20002 {
dda8d76d
NC
20003 if (filedata->file_header.e_machine == EM_X86_64
20004 || filedata->file_header.e_machine == EM_IAMCU
20005 || filedata->file_header.e_machine == EM_386)
1fc87489 20006 {
aa7bca9b
L
20007 unsigned int bitmask;
20008
20009 if (datasz == 4)
0a59decb 20010 bitmask = byte_get (ptr, 4);
aa7bca9b
L
20011 else
20012 bitmask = 0;
20013
1fc87489
L
20014 switch (type)
20015 {
20016 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 20017 if (datasz != 4)
aa7bca9b
L
20018 printf (_("x86 ISA used: <corrupt length: %#x> "),
20019 datasz);
1fc87489 20020 else
aa7bca9b
L
20021 {
20022 printf ("x86 ISA used: ");
20023 decode_x86_isa (bitmask);
20024 }
1fc87489 20025 goto next;
9ef920e9 20026
1fc87489 20027 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20028 if (datasz != 4)
aa7bca9b
L
20029 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20030 datasz);
1fc87489 20031 else
aa7bca9b
L
20032 {
20033 printf ("x86 ISA needed: ");
20034 decode_x86_isa (bitmask);
20035 }
1fc87489 20036 goto next;
9ef920e9 20037
ee2fdd6f 20038 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20039 if (datasz != 4)
aa7bca9b
L
20040 printf (_("x86 feature: <corrupt length: %#x> "),
20041 datasz);
ee2fdd6f 20042 else
aa7bca9b
L
20043 {
20044 printf ("x86 feature: ");
a9eafb08
L
20045 decode_x86_feature_1 (bitmask);
20046 }
20047 goto next;
20048
20049 case GNU_PROPERTY_X86_FEATURE_2_USED:
20050 if (datasz != 4)
20051 printf (_("x86 feature used: <corrupt length: %#x> "),
20052 datasz);
20053 else
20054 {
20055 printf ("x86 feature used: ");
20056 decode_x86_feature_2 (bitmask);
20057 }
20058 goto next;
20059
20060 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20061 if (datasz != 4)
20062 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20063 else
20064 {
20065 printf ("x86 feature needed: ");
20066 decode_x86_feature_2 (bitmask);
20067 }
20068 goto next;
20069
20070 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20071 if (datasz != 4)
20072 printf (_("x86 ISA used: <corrupt length: %#x> "),
20073 datasz);
20074 else
20075 {
20076 printf ("x86 ISA used: ");
20077 decode_x86_compat_isa (bitmask);
20078 }
20079 goto next;
20080
20081 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20082 if (datasz != 4)
20083 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20084 datasz);
20085 else
20086 {
20087 printf ("x86 ISA needed: ");
20088 decode_x86_compat_isa (bitmask);
aa7bca9b 20089 }
ee2fdd6f
L
20090 goto next;
20091
32930e4e
L
20092 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20093 if (datasz != 4)
20094 printf (_("x86 ISA used: <corrupt length: %#x> "),
20095 datasz);
20096 else
20097 {
20098 printf ("x86 ISA used: ");
20099 decode_x86_compat_2_isa (bitmask);
20100 }
20101 goto next;
20102
20103 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20104 if (datasz != 4)
20105 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20106 datasz);
20107 else
20108 {
20109 printf ("x86 ISA needed: ");
20110 decode_x86_compat_2_isa (bitmask);
20111 }
20112 goto next;
20113
1fc87489
L
20114 default:
20115 break;
20116 }
20117 }
cd702818
SD
20118 else if (filedata->file_header.e_machine == EM_AARCH64)
20119 {
20120 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20121 {
20122 printf ("AArch64 feature: ");
20123 if (datasz != 4)
20124 printf (_("<corrupt length: %#x> "), datasz);
20125 else
20126 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20127 goto next;
20128 }
20129 }
1fc87489
L
20130 }
20131 else
20132 {
20133 switch (type)
9ef920e9 20134 {
1fc87489
L
20135 case GNU_PROPERTY_STACK_SIZE:
20136 printf (_("stack size: "));
20137 if (datasz != size)
20138 printf (_("<corrupt length: %#x> "), datasz);
20139 else
20140 printf ("%#lx", (unsigned long) byte_get (ptr, size));
20141 goto next;
20142
20143 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20144 printf ("no copy on protected ");
20145 if (datasz)
20146 printf (_("<corrupt length: %#x> "), datasz);
20147 goto next;
20148
20149 default:
5a767724
L
20150 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20151 && type <= GNU_PROPERTY_UINT32_AND_HI)
20152 || (type >= GNU_PROPERTY_UINT32_OR_LO
20153 && type <= GNU_PROPERTY_UINT32_OR_HI))
20154 {
6320fd00
L
20155 switch (type)
20156 {
20157 case GNU_PROPERTY_1_NEEDED:
20158 if (datasz != 4)
20159 printf (_("1_needed: <corrupt length: %#x> "),
20160 datasz);
20161 else
20162 {
20163 unsigned int bitmask = byte_get (ptr, 4);
20164 printf ("1_needed: ");
20165 decode_1_needed (bitmask);
20166 }
20167 goto next;
20168
20169 default:
20170 break;
20171 }
5a767724
L
20172 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20173 printf (_("UINT32_AND (%#x): "), type);
20174 else
20175 printf (_("UINT32_OR (%#x): "), type);
20176 if (datasz != 4)
20177 printf (_("<corrupt length: %#x> "), datasz);
20178 else
20179 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20180 goto next;
20181 }
9ef920e9
NC
20182 break;
20183 }
9ef920e9
NC
20184 }
20185
1fc87489
L
20186 if (type < GNU_PROPERTY_LOPROC)
20187 printf (_("<unknown type %#x data: "), type);
20188 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20189 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20190 else
20191 printf (_("<application-specific type %#x data: "), type);
20192 for (j = 0; j < datasz; ++j)
20193 printf ("%02x ", ptr[j] & 0xff);
20194 printf (">");
20195
dc1e8a47 20196 next:
9ef920e9 20197 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20198 if (ptr == ptr_end)
20199 break;
1fc87489 20200
6ab2c4ed
MC
20201 if (do_wide)
20202 printf (", ");
20203 else
20204 printf ("\n\t");
9ef920e9
NC
20205 }
20206
20207 printf ("\n");
20208}
20209
015dc7e1 20210static bool
dda8d76d 20211print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20212{
1449284b 20213 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20214 switch (pnote->type)
20215 {
20216 case NT_GNU_BUILD_ID:
20217 {
20218 unsigned long i;
20219
20220 printf (_(" Build ID: "));
20221 for (i = 0; i < pnote->descsz; ++i)
20222 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20223 printf ("\n");
664f90a3
TT
20224 }
20225 break;
20226
20227 case NT_GNU_ABI_TAG:
20228 {
20229 unsigned long os, major, minor, subminor;
20230 const char *osname;
20231
3102e897
NC
20232 /* PR 17531: file: 030-599401-0.004. */
20233 if (pnote->descsz < 16)
20234 {
20235 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20236 break;
20237 }
20238
664f90a3
TT
20239 os = byte_get ((unsigned char *) pnote->descdata, 4);
20240 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20241 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20242 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20243
20244 switch (os)
20245 {
20246 case GNU_ABI_TAG_LINUX:
20247 osname = "Linux";
20248 break;
20249 case GNU_ABI_TAG_HURD:
20250 osname = "Hurd";
20251 break;
20252 case GNU_ABI_TAG_SOLARIS:
20253 osname = "Solaris";
20254 break;
20255 case GNU_ABI_TAG_FREEBSD:
20256 osname = "FreeBSD";
20257 break;
20258 case GNU_ABI_TAG_NETBSD:
20259 osname = "NetBSD";
20260 break;
14ae95f2
RM
20261 case GNU_ABI_TAG_SYLLABLE:
20262 osname = "Syllable";
20263 break;
20264 case GNU_ABI_TAG_NACL:
20265 osname = "NaCl";
20266 break;
664f90a3
TT
20267 default:
20268 osname = "Unknown";
20269 break;
20270 }
20271
20272 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
20273 major, minor, subminor);
20274 }
20275 break;
926c5385
CC
20276
20277 case NT_GNU_GOLD_VERSION:
20278 {
20279 unsigned long i;
20280
20281 printf (_(" Version: "));
20282 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20283 printf ("%c", pnote->descdata[i]);
20284 printf ("\n");
20285 }
20286 break;
1449284b
NC
20287
20288 case NT_GNU_HWCAP:
20289 {
20290 unsigned long num_entries, mask;
20291
20292 /* Hardware capabilities information. Word 0 is the number of entries.
20293 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20294 is a series of entries, where each entry is a single byte followed
20295 by a nul terminated string. The byte gives the bit number to test
20296 if enabled in the bitmask. */
20297 printf (_(" Hardware Capabilities: "));
20298 if (pnote->descsz < 8)
20299 {
32ec8896 20300 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20301 return false;
1449284b
NC
20302 }
20303 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20304 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20305 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
20306 /* FIXME: Add code to display the entries... */
20307 }
20308 break;
20309
9ef920e9 20310 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20311 print_gnu_property_note (filedata, pnote);
9ef920e9 20312 break;
9abca702 20313
1449284b
NC
20314 default:
20315 /* Handle unrecognised types. An error message should have already been
20316 created by get_gnu_elf_note_type(), so all that we need to do is to
20317 display the data. */
20318 {
20319 unsigned long i;
20320
20321 printf (_(" Description data: "));
20322 for (i = 0; i < pnote->descsz; ++i)
20323 printf ("%02x ", pnote->descdata[i] & 0xff);
20324 printf ("\n");
20325 }
20326 break;
664f90a3
TT
20327 }
20328
015dc7e1 20329 return true;
664f90a3
TT
20330}
20331
685080f2
NC
20332static const char *
20333get_v850_elf_note_type (enum v850_notes n_type)
20334{
20335 static char buff[64];
20336
20337 switch (n_type)
20338 {
20339 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20340 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20341 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20342 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20343 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20344 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20345 default:
20346 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20347 return buff;
20348 }
20349}
20350
015dc7e1 20351static bool
685080f2
NC
20352print_v850_note (Elf_Internal_Note * pnote)
20353{
20354 unsigned int val;
20355
20356 if (pnote->descsz != 4)
015dc7e1 20357 return false;
32ec8896 20358
685080f2
NC
20359 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20360
20361 if (val == 0)
20362 {
20363 printf (_("not set\n"));
015dc7e1 20364 return true;
685080f2
NC
20365 }
20366
20367 switch (pnote->type)
20368 {
20369 case V850_NOTE_ALIGNMENT:
20370 switch (val)
20371 {
015dc7e1
AM
20372 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20373 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20374 }
20375 break;
14ae95f2 20376
685080f2
NC
20377 case V850_NOTE_DATA_SIZE:
20378 switch (val)
20379 {
015dc7e1
AM
20380 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20381 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20382 }
20383 break;
14ae95f2 20384
685080f2
NC
20385 case V850_NOTE_FPU_INFO:
20386 switch (val)
20387 {
015dc7e1
AM
20388 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20389 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20390 }
20391 break;
14ae95f2 20392
685080f2
NC
20393 case V850_NOTE_MMU_INFO:
20394 case V850_NOTE_CACHE_INFO:
20395 case V850_NOTE_SIMD_INFO:
20396 if (val == EF_RH850_SIMD)
20397 {
20398 printf (_("yes\n"));
015dc7e1 20399 return true;
685080f2
NC
20400 }
20401 break;
20402
20403 default:
20404 /* An 'unknown note type' message will already have been displayed. */
20405 break;
20406 }
20407
20408 printf (_("unknown value: %x\n"), val);
015dc7e1 20409 return false;
685080f2
NC
20410}
20411
015dc7e1 20412static bool
c6056a74
SF
20413process_netbsd_elf_note (Elf_Internal_Note * pnote)
20414{
20415 unsigned int version;
20416
20417 switch (pnote->type)
20418 {
20419 case NT_NETBSD_IDENT:
b966f55f
AM
20420 if (pnote->descsz < 1)
20421 break;
c6056a74
SF
20422 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20423 if ((version / 10000) % 100)
b966f55f 20424 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20425 version, version / 100000000, (version / 1000000) % 100,
20426 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20427 'A' + (version / 10000) % 26);
c6056a74
SF
20428 else
20429 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20430 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20431 (version / 100) % 100);
015dc7e1 20432 return true;
c6056a74
SF
20433
20434 case NT_NETBSD_MARCH:
9abca702 20435 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20436 pnote->descdata);
015dc7e1 20437 return true;
c6056a74 20438
9abca702 20439 case NT_NETBSD_PAX:
b966f55f
AM
20440 if (pnote->descsz < 1)
20441 break;
9abca702
CZ
20442 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20443 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20444 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20445 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20446 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20447 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20448 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20449 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20450 return true;
c6056a74 20451 }
b966f55f
AM
20452
20453 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20454 pnote->descsz, pnote->type);
015dc7e1 20455 return false;
c6056a74
SF
20456}
20457
f4ddf30f 20458static const char *
dda8d76d 20459get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20460{
f4ddf30f
JB
20461 switch (e_type)
20462 {
20463 case NT_FREEBSD_THRMISC:
20464 return _("NT_THRMISC (thrmisc structure)");
20465 case NT_FREEBSD_PROCSTAT_PROC:
20466 return _("NT_PROCSTAT_PROC (proc data)");
20467 case NT_FREEBSD_PROCSTAT_FILES:
20468 return _("NT_PROCSTAT_FILES (files data)");
20469 case NT_FREEBSD_PROCSTAT_VMMAP:
20470 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20471 case NT_FREEBSD_PROCSTAT_GROUPS:
20472 return _("NT_PROCSTAT_GROUPS (groups data)");
20473 case NT_FREEBSD_PROCSTAT_UMASK:
20474 return _("NT_PROCSTAT_UMASK (umask data)");
20475 case NT_FREEBSD_PROCSTAT_RLIMIT:
20476 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20477 case NT_FREEBSD_PROCSTAT_OSREL:
20478 return _("NT_PROCSTAT_OSREL (osreldate data)");
20479 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20480 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20481 case NT_FREEBSD_PROCSTAT_AUXV:
20482 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20483 case NT_FREEBSD_PTLWPINFO:
20484 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
20485 case NT_FREEBSD_X86_SEGBASES:
20486 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 20487 }
dda8d76d 20488 return get_note_type (filedata, e_type);
f4ddf30f
JB
20489}
20490
9437c45b 20491static const char *
dda8d76d 20492get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20493{
20494 static char buff[64];
20495
540e6170
CZ
20496 switch (e_type)
20497 {
20498 case NT_NETBSDCORE_PROCINFO:
20499 /* NetBSD core "procinfo" structure. */
20500 return _("NetBSD procinfo structure");
9437c45b 20501
540e6170
CZ
20502 case NT_NETBSDCORE_AUXV:
20503 return _("NetBSD ELF auxiliary vector data");
9437c45b 20504
06d949ec
KR
20505 case NT_NETBSDCORE_LWPSTATUS:
20506 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20507
540e6170 20508 default:
06d949ec 20509 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20510 defined for NetBSD core files. If the note type is less
20511 than the start of the machine-dependent note types, we don't
20512 understand it. */
20513
20514 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20515 {
20516 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20517 return buff;
20518 }
20519 break;
9437c45b
JT
20520 }
20521
dda8d76d 20522 switch (filedata->file_header.e_machine)
9437c45b
JT
20523 {
20524 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20525 and PT_GETFPREGS == mach+2. */
20526
20527 case EM_OLD_ALPHA:
20528 case EM_ALPHA:
20529 case EM_SPARC:
20530 case EM_SPARC32PLUS:
20531 case EM_SPARCV9:
20532 switch (e_type)
20533 {
2b692964 20534 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20535 return _("PT_GETREGS (reg structure)");
2b692964 20536 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20537 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20538 default:
20539 break;
20540 }
20541 break;
20542
c0d38b0e
CZ
20543 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20544 There's also old PT___GETREGS40 == mach + 1 for old reg
20545 structure which lacks GBR. */
20546 case EM_SH:
20547 switch (e_type)
20548 {
20549 case NT_NETBSDCORE_FIRSTMACH + 1:
20550 return _("PT___GETREGS40 (old reg structure)");
20551 case NT_NETBSDCORE_FIRSTMACH + 3:
20552 return _("PT_GETREGS (reg structure)");
20553 case NT_NETBSDCORE_FIRSTMACH + 5:
20554 return _("PT_GETFPREGS (fpreg structure)");
20555 default:
20556 break;
20557 }
20558 break;
20559
9437c45b
JT
20560 /* On all other arch's, PT_GETREGS == mach+1 and
20561 PT_GETFPREGS == mach+3. */
20562 default:
20563 switch (e_type)
20564 {
2b692964 20565 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20566 return _("PT_GETREGS (reg structure)");
2b692964 20567 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20568 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20569 default:
20570 break;
20571 }
20572 }
20573
9cf03b7e 20574 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20575 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20576 return buff;
20577}
20578
98ca73af
FC
20579static const char *
20580get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20581{
20582 switch (e_type)
20583 {
20584 case NT_OPENBSD_PROCINFO:
20585 return _("OpenBSD procinfo structure");
20586 case NT_OPENBSD_AUXV:
20587 return _("OpenBSD ELF auxiliary vector data");
20588 case NT_OPENBSD_REGS:
20589 return _("OpenBSD regular registers");
20590 case NT_OPENBSD_FPREGS:
20591 return _("OpenBSD floating point registers");
20592 case NT_OPENBSD_WCOOKIE:
20593 return _("OpenBSD window cookie");
20594 }
20595
20596 return get_note_type (filedata, e_type);
20597}
20598
70616151
TT
20599static const char *
20600get_stapsdt_note_type (unsigned e_type)
20601{
20602 static char buff[64];
20603
20604 switch (e_type)
20605 {
20606 case NT_STAPSDT:
20607 return _("NT_STAPSDT (SystemTap probe descriptors)");
20608
20609 default:
20610 break;
20611 }
20612
20613 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20614 return buff;
20615}
20616
015dc7e1 20617static bool
c6a9fc58
TT
20618print_stapsdt_note (Elf_Internal_Note *pnote)
20619{
3ca60c57
NC
20620 size_t len, maxlen;
20621 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20622 char *data = pnote->descdata;
20623 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 20624 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
20625 char *provider, *probe, *arg_fmt;
20626
3ca60c57
NC
20627 if (pnote->descsz < (addr_size * 3))
20628 goto stapdt_note_too_small;
20629
c6a9fc58
TT
20630 pc = byte_get ((unsigned char *) data, addr_size);
20631 data += addr_size;
3ca60c57 20632
c6a9fc58
TT
20633 base_addr = byte_get ((unsigned char *) data, addr_size);
20634 data += addr_size;
3ca60c57 20635
c6a9fc58
TT
20636 semaphore = byte_get ((unsigned char *) data, addr_size);
20637 data += addr_size;
20638
3ca60c57
NC
20639 if (data >= data_end)
20640 goto stapdt_note_too_small;
20641 maxlen = data_end - data;
20642 len = strnlen (data, maxlen);
20643 if (len < maxlen)
20644 {
20645 provider = data;
20646 data += len + 1;
20647 }
20648 else
20649 goto stapdt_note_too_small;
20650
20651 if (data >= data_end)
20652 goto stapdt_note_too_small;
20653 maxlen = data_end - data;
20654 len = strnlen (data, maxlen);
20655 if (len < maxlen)
20656 {
20657 probe = data;
20658 data += len + 1;
20659 }
20660 else
20661 goto stapdt_note_too_small;
9abca702 20662
3ca60c57
NC
20663 if (data >= data_end)
20664 goto stapdt_note_too_small;
20665 maxlen = data_end - data;
20666 len = strnlen (data, maxlen);
20667 if (len < maxlen)
20668 {
20669 arg_fmt = data;
20670 data += len + 1;
20671 }
20672 else
20673 goto stapdt_note_too_small;
c6a9fc58
TT
20674
20675 printf (_(" Provider: %s\n"), provider);
20676 printf (_(" Name: %s\n"), probe);
20677 printf (_(" Location: "));
20678 print_vma (pc, FULL_HEX);
20679 printf (_(", Base: "));
20680 print_vma (base_addr, FULL_HEX);
20681 printf (_(", Semaphore: "));
20682 print_vma (semaphore, FULL_HEX);
9cf03b7e 20683 printf ("\n");
c6a9fc58
TT
20684 printf (_(" Arguments: %s\n"), arg_fmt);
20685
20686 return data == data_end;
3ca60c57
NC
20687
20688 stapdt_note_too_small:
20689 printf (_(" <corrupt - note is too small>\n"));
20690 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20691 return false;
c6a9fc58
TT
20692}
20693
e5382207
LB
20694static bool
20695print_fdo_note (Elf_Internal_Note * pnote)
20696{
20697 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20698 {
20699 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20700 return true;
20701 }
20702 return false;
20703}
20704
00e98fc7
TG
20705static const char *
20706get_ia64_vms_note_type (unsigned e_type)
20707{
20708 static char buff[64];
20709
20710 switch (e_type)
20711 {
20712 case NT_VMS_MHD:
20713 return _("NT_VMS_MHD (module header)");
20714 case NT_VMS_LNM:
20715 return _("NT_VMS_LNM (language name)");
20716 case NT_VMS_SRC:
20717 return _("NT_VMS_SRC (source files)");
20718 case NT_VMS_TITLE:
9cf03b7e 20719 return "NT_VMS_TITLE";
00e98fc7
TG
20720 case NT_VMS_EIDC:
20721 return _("NT_VMS_EIDC (consistency check)");
20722 case NT_VMS_FPMODE:
20723 return _("NT_VMS_FPMODE (FP mode)");
20724 case NT_VMS_LINKTIME:
9cf03b7e 20725 return "NT_VMS_LINKTIME";
00e98fc7
TG
20726 case NT_VMS_IMGNAM:
20727 return _("NT_VMS_IMGNAM (image name)");
20728 case NT_VMS_IMGID:
20729 return _("NT_VMS_IMGID (image id)");
20730 case NT_VMS_LINKID:
20731 return _("NT_VMS_LINKID (link id)");
20732 case NT_VMS_IMGBID:
20733 return _("NT_VMS_IMGBID (build id)");
20734 case NT_VMS_GSTNAM:
20735 return _("NT_VMS_GSTNAM (sym table name)");
20736 case NT_VMS_ORIG_DYN:
9cf03b7e 20737 return "NT_VMS_ORIG_DYN";
00e98fc7 20738 case NT_VMS_PATCHTIME:
9cf03b7e 20739 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20740 default:
20741 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20742 return buff;
20743 }
20744}
20745
015dc7e1 20746static bool
00e98fc7
TG
20747print_ia64_vms_note (Elf_Internal_Note * pnote)
20748{
8d18bf79
NC
20749 int maxlen = pnote->descsz;
20750
20751 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20752 goto desc_size_fail;
20753
00e98fc7
TG
20754 switch (pnote->type)
20755 {
20756 case NT_VMS_MHD:
8d18bf79
NC
20757 if (maxlen <= 36)
20758 goto desc_size_fail;
20759
20760 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20761
20762 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20763 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20764 if (l + 34 < maxlen)
20765 {
20766 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20767 if (l + 35 < maxlen)
20768 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20769 else
20770 printf (_(" Module version : <missing>\n"));
20771 }
00e98fc7 20772 else
8d18bf79
NC
20773 {
20774 printf (_(" Module name : <missing>\n"));
20775 printf (_(" Module version : <missing>\n"));
20776 }
00e98fc7 20777 break;
8d18bf79 20778
00e98fc7 20779 case NT_VMS_LNM:
8d18bf79 20780 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20781 break;
8d18bf79 20782
00e98fc7 20783 case NT_VMS_FPMODE:
9cf03b7e 20784 printf (_(" Floating Point mode: "));
8d18bf79
NC
20785 if (maxlen < 8)
20786 goto desc_size_fail;
20787 /* FIXME: Generate an error if descsz > 8 ? */
20788
b8281767 20789 printf ("0x%016" PRIx64 "\n",
625d49fc 20790 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 20791 break;
8d18bf79 20792
00e98fc7
TG
20793 case NT_VMS_LINKTIME:
20794 printf (_(" Link time: "));
8d18bf79
NC
20795 if (maxlen < 8)
20796 goto desc_size_fail;
20797 /* FIXME: Generate an error if descsz > 8 ? */
20798
0e3c1eeb 20799 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20800 printf ("\n");
20801 break;
8d18bf79 20802
00e98fc7
TG
20803 case NT_VMS_PATCHTIME:
20804 printf (_(" Patch time: "));
8d18bf79
NC
20805 if (maxlen < 8)
20806 goto desc_size_fail;
20807 /* FIXME: Generate an error if descsz > 8 ? */
20808
0e3c1eeb 20809 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20810 printf ("\n");
20811 break;
8d18bf79 20812
00e98fc7 20813 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20814 if (maxlen < 34)
20815 goto desc_size_fail;
20816
00e98fc7 20817 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
20818 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
20819 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 20820 printf (_(" Last modified : "));
0e3c1eeb 20821 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 20822 printf (_("\n Link flags : "));
b8281767 20823 printf ("0x%016" PRIx64 "\n",
625d49fc 20824 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 20825 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 20826 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 20827 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 20828 break;
8d18bf79 20829
00e98fc7 20830 case NT_VMS_IMGNAM:
8d18bf79 20831 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20832 break;
8d18bf79 20833
00e98fc7 20834 case NT_VMS_GSTNAM:
8d18bf79 20835 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20836 break;
8d18bf79 20837
00e98fc7 20838 case NT_VMS_IMGID:
8d18bf79 20839 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20840 break;
8d18bf79 20841
00e98fc7 20842 case NT_VMS_LINKID:
8d18bf79 20843 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20844 break;
8d18bf79 20845
00e98fc7 20846 default:
015dc7e1 20847 return false;
00e98fc7 20848 }
8d18bf79 20849
015dc7e1 20850 return true;
8d18bf79
NC
20851
20852 desc_size_fail:
20853 printf (_(" <corrupt - data size is too small>\n"));
20854 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20855 return false;
00e98fc7
TG
20856}
20857
fd486f32
AM
20858struct build_attr_cache {
20859 Filedata *filedata;
20860 char *strtab;
20861 unsigned long strtablen;
20862 Elf_Internal_Sym *symtab;
20863 unsigned long nsyms;
20864} ba_cache;
20865
6f156d7a
NC
20866/* Find the symbol associated with a build attribute that is attached
20867 to address OFFSET. If PNAME is non-NULL then store the name of
20868 the symbol (if found) in the provided pointer, Returns NULL if a
20869 symbol could not be found. */
c799a79d 20870
6f156d7a 20871static Elf_Internal_Sym *
015dc7e1
AM
20872get_symbol_for_build_attribute (Filedata *filedata,
20873 unsigned long offset,
20874 bool is_open_attr,
20875 const char **pname)
9ef920e9 20876{
fd486f32
AM
20877 Elf_Internal_Sym *saved_sym = NULL;
20878 Elf_Internal_Sym *sym;
9ef920e9 20879
dda8d76d 20880 if (filedata->section_headers != NULL
fd486f32 20881 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20882 {
c799a79d 20883 Elf_Internal_Shdr * symsec;
9ef920e9 20884
fd486f32
AM
20885 free (ba_cache.strtab);
20886 ba_cache.strtab = NULL;
20887 free (ba_cache.symtab);
20888 ba_cache.symtab = NULL;
20889
c799a79d 20890 /* Load the symbol and string sections. */
dda8d76d
NC
20891 for (symsec = filedata->section_headers;
20892 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20893 symsec ++)
9ef920e9 20894 {
28d13567
AM
20895 if (symsec->sh_type == SHT_SYMTAB
20896 && get_symtab (filedata, symsec,
20897 &ba_cache.symtab, &ba_cache.nsyms,
20898 &ba_cache.strtab, &ba_cache.strtablen))
20899 break;
9ef920e9 20900 }
fd486f32 20901 ba_cache.filedata = filedata;
9ef920e9
NC
20902 }
20903
fd486f32 20904 if (ba_cache.symtab == NULL)
6f156d7a 20905 return NULL;
9ef920e9 20906
c799a79d 20907 /* Find a symbol whose value matches offset. */
fd486f32 20908 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20909 if (sym->st_value == offset)
20910 {
fd486f32 20911 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20912 /* Huh ? This should not happen. */
20913 continue;
9ef920e9 20914
fd486f32 20915 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20916 continue;
9ef920e9 20917
9b9b1092 20918 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20919 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20920 if (ba_cache.strtab[sym->st_name] == '$'
20921 && ba_cache.strtab[sym->st_name + 1] != 0
20922 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20923 continue;
20924
c799a79d
NC
20925 if (is_open_attr)
20926 {
20927 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20928 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20929 FUNC symbols entirely. */
20930 switch (ELF_ST_TYPE (sym->st_info))
20931 {
c799a79d 20932 case STT_OBJECT:
6f156d7a 20933 case STT_FILE:
c799a79d 20934 saved_sym = sym;
6f156d7a
NC
20935 if (sym->st_size)
20936 {
20937 /* If the symbol has a size associated
20938 with it then we can stop searching. */
fd486f32 20939 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20940 }
c799a79d 20941 continue;
9ef920e9 20942
c799a79d
NC
20943 case STT_FUNC:
20944 /* Ignore function symbols. */
20945 continue;
20946
20947 default:
20948 break;
20949 }
20950
20951 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20952 {
c799a79d
NC
20953 case STB_GLOBAL:
20954 if (saved_sym == NULL
20955 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20956 saved_sym = sym;
20957 break;
c871dade 20958
c799a79d
NC
20959 case STB_LOCAL:
20960 if (saved_sym == NULL)
20961 saved_sym = sym;
20962 break;
20963
20964 default:
9ef920e9
NC
20965 break;
20966 }
20967 }
c799a79d
NC
20968 else
20969 {
20970 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20971 continue;
20972
20973 saved_sym = sym;
20974 break;
20975 }
20976 }
20977
6f156d7a 20978 if (saved_sym && pname)
fd486f32 20979 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20980
20981 return saved_sym;
c799a79d
NC
20982}
20983
d20e98ab
NC
20984/* Returns true iff addr1 and addr2 are in the same section. */
20985
015dc7e1 20986static bool
d20e98ab
NC
20987same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20988{
20989 Elf_Internal_Shdr * a1;
20990 Elf_Internal_Shdr * a2;
20991
20992 a1 = find_section_by_address (filedata, addr1);
20993 a2 = find_section_by_address (filedata, addr2);
9abca702 20994
d20e98ab
NC
20995 return a1 == a2 && a1 != NULL;
20996}
20997
015dc7e1 20998static bool
dda8d76d
NC
20999print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21000 Filedata * filedata)
c799a79d 21001{
015dc7e1
AM
21002 static unsigned long global_offset = 0;
21003 static unsigned long global_end = 0;
21004 static unsigned long func_offset = 0;
21005 static unsigned long func_end = 0;
c871dade 21006
015dc7e1
AM
21007 Elf_Internal_Sym *sym;
21008 const char *name;
21009 unsigned long start;
21010 unsigned long end;
21011 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
21012
21013 switch (pnote->descsz)
c799a79d 21014 {
6f156d7a
NC
21015 case 0:
21016 /* A zero-length description means that the range of
21017 the previous note of the same type should be used. */
c799a79d 21018 if (is_open_attr)
c871dade 21019 {
6f156d7a
NC
21020 if (global_end > global_offset)
21021 printf (_(" Applies to region from %#lx to %#lx\n"),
21022 global_offset, global_end);
21023 else
21024 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
21025 }
21026 else
21027 {
6f156d7a
NC
21028 if (func_end > func_offset)
21029 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
21030 else
21031 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 21032 }
015dc7e1 21033 return true;
9ef920e9 21034
6f156d7a
NC
21035 case 4:
21036 start = byte_get ((unsigned char *) pnote->descdata, 4);
21037 end = 0;
21038 break;
21039
21040 case 8:
c74147bb
NC
21041 start = byte_get ((unsigned char *) pnote->descdata, 4);
21042 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21043 break;
21044
21045 case 16:
21046 start = byte_get ((unsigned char *) pnote->descdata, 8);
21047 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21048 break;
9abca702 21049
6f156d7a 21050 default:
c799a79d
NC
21051 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21052 printf (_(" <invalid descsz>"));
015dc7e1 21053 return false;
c799a79d
NC
21054 }
21055
6f156d7a
NC
21056 name = NULL;
21057 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21058 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21059 in order to avoid them being confused with the start address of the
21060 first function in the file... */
21061 if (sym == NULL && is_open_attr)
21062 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21063 & name);
6f156d7a
NC
21064
21065 if (end == 0 && sym != NULL && sym->st_size > 0)
21066 end = start + sym->st_size;
c799a79d
NC
21067
21068 if (is_open_attr)
21069 {
d20e98ab
NC
21070 /* FIXME: Need to properly allow for section alignment.
21071 16 is just the alignment used on x86_64. */
21072 if (global_end > 0
21073 && start > BFD_ALIGN (global_end, 16)
21074 /* Build notes are not guaranteed to be organised in order of
21075 increasing address, but we should find the all of the notes
21076 for one section in the same place. */
21077 && same_section (filedata, start, global_end))
6f156d7a
NC
21078 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
21079 global_end + 1, start - 1);
21080
21081 printf (_(" Applies to region from %#lx"), start);
21082 global_offset = start;
21083
21084 if (end)
21085 {
21086 printf (_(" to %#lx"), end);
21087 global_end = end;
21088 }
c799a79d
NC
21089 }
21090 else
21091 {
6f156d7a
NC
21092 printf (_(" Applies to region from %#lx"), start);
21093 func_offset = start;
21094
21095 if (end)
21096 {
21097 printf (_(" to %#lx"), end);
21098 func_end = end;
21099 }
c799a79d
NC
21100 }
21101
6f156d7a
NC
21102 if (sym && name)
21103 printf (_(" (%s)"), name);
21104
21105 printf ("\n");
015dc7e1 21106 return true;
9ef920e9
NC
21107}
21108
015dc7e1 21109static bool
9ef920e9
NC
21110print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21111{
1d15e434
NC
21112 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21113 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21114 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21115 char name_type;
21116 char name_attribute;
1d15e434 21117 const char * expected_types;
9ef920e9
NC
21118 const char * name = pnote->namedata;
21119 const char * text;
88305e1b 21120 signed int left;
9ef920e9
NC
21121
21122 if (name == NULL || pnote->namesz < 2)
21123 {
21124 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21125 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21126 return false;
9ef920e9
NC
21127 }
21128
6f156d7a
NC
21129 if (do_wide)
21130 left = 28;
21131 else
21132 left = 20;
88305e1b
NC
21133
21134 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21135 if (name[0] == 'G' && name[1] == 'A')
21136 {
6f156d7a
NC
21137 if (pnote->namesz < 4)
21138 {
21139 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21140 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21141 return false;
6f156d7a
NC
21142 }
21143
88305e1b
NC
21144 printf ("GA");
21145 name += 2;
21146 left -= 2;
21147 }
21148
9ef920e9
NC
21149 switch ((name_type = * name))
21150 {
21151 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21152 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21153 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21154 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21155 printf ("%c", * name);
88305e1b 21156 left --;
9ef920e9
NC
21157 break;
21158 default:
21159 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21160 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21161 return false;
9ef920e9
NC
21162 }
21163
9ef920e9
NC
21164 ++ name;
21165 text = NULL;
21166
21167 switch ((name_attribute = * name))
21168 {
21169 case GNU_BUILD_ATTRIBUTE_VERSION:
21170 text = _("<version>");
1d15e434 21171 expected_types = string_expected;
9ef920e9
NC
21172 ++ name;
21173 break;
21174 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21175 text = _("<stack prot>");
75d7d298 21176 expected_types = "!+*";
9ef920e9
NC
21177 ++ name;
21178 break;
21179 case GNU_BUILD_ATTRIBUTE_RELRO:
21180 text = _("<relro>");
1d15e434 21181 expected_types = bool_expected;
9ef920e9
NC
21182 ++ name;
21183 break;
21184 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21185 text = _("<stack size>");
1d15e434 21186 expected_types = number_expected;
9ef920e9
NC
21187 ++ name;
21188 break;
21189 case GNU_BUILD_ATTRIBUTE_TOOL:
21190 text = _("<tool>");
1d15e434 21191 expected_types = string_expected;
9ef920e9
NC
21192 ++ name;
21193 break;
21194 case GNU_BUILD_ATTRIBUTE_ABI:
21195 text = _("<ABI>");
21196 expected_types = "$*";
21197 ++ name;
21198 break;
21199 case GNU_BUILD_ATTRIBUTE_PIC:
21200 text = _("<PIC>");
1d15e434 21201 expected_types = number_expected;
9ef920e9
NC
21202 ++ name;
21203 break;
a8be5506
NC
21204 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21205 text = _("<short enum>");
1d15e434 21206 expected_types = bool_expected;
a8be5506
NC
21207 ++ name;
21208 break;
9ef920e9
NC
21209 default:
21210 if (ISPRINT (* name))
21211 {
21212 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21213
21214 if (len > left && ! do_wide)
21215 len = left;
75d7d298 21216 printf ("%.*s:", len, name);
9ef920e9 21217 left -= len;
0dd6ae21 21218 name += len;
9ef920e9
NC
21219 }
21220 else
21221 {
3e6b6445 21222 static char tmpbuf [128];
88305e1b 21223
3e6b6445
NC
21224 error (_("unrecognised byte in name field: %d\n"), * name);
21225 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21226 text = tmpbuf;
21227 name ++;
9ef920e9
NC
21228 }
21229 expected_types = "*$!+";
21230 break;
21231 }
21232
21233 if (text)
88305e1b 21234 left -= printf ("%s", text);
9ef920e9
NC
21235
21236 if (strchr (expected_types, name_type) == NULL)
75d7d298 21237 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
21238
21239 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
21240 {
21241 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
21242 (unsigned long) pnote->namesz,
21243 (long) (name - pnote->namedata));
015dc7e1 21244 return false;
9ef920e9
NC
21245 }
21246
21247 if (left < 1 && ! do_wide)
015dc7e1 21248 return true;
9ef920e9
NC
21249
21250 switch (name_type)
21251 {
21252 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21253 {
b06b2c92 21254 unsigned int bytes;
ddef72cd
NC
21255 unsigned long long val = 0;
21256 unsigned int shift = 0;
21257 char * decoded = NULL;
21258
b06b2c92
NC
21259 bytes = pnote->namesz - (name - pnote->namedata);
21260 if (bytes > 0)
21261 /* The -1 is because the name field is always 0 terminated, and we
21262 want to be able to ensure that the shift in the while loop below
21263 will not overflow. */
21264 -- bytes;
21265
ddef72cd
NC
21266 if (bytes > sizeof (val))
21267 {
3e6b6445
NC
21268 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21269 bytes);
21270 bytes = sizeof (val);
ddef72cd 21271 }
3e6b6445
NC
21272 /* We do not bother to warn if bytes == 0 as this can
21273 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21274
21275 while (bytes --)
21276 {
54b8331d 21277 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
21278
21279 val |= byte << shift;
9ef920e9
NC
21280 shift += 8;
21281 }
21282
75d7d298 21283 switch (name_attribute)
9ef920e9 21284 {
75d7d298 21285 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21286 switch (val)
21287 {
75d7d298
NC
21288 case 0: decoded = "static"; break;
21289 case 1: decoded = "pic"; break;
21290 case 2: decoded = "PIC"; break;
21291 case 3: decoded = "pie"; break;
21292 case 4: decoded = "PIE"; break;
21293 default: break;
9ef920e9 21294 }
75d7d298
NC
21295 break;
21296 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21297 switch (val)
9ef920e9 21298 {
75d7d298
NC
21299 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21300 case 0: decoded = "off"; break;
21301 case 1: decoded = "on"; break;
21302 case 2: decoded = "all"; break;
21303 case 3: decoded = "strong"; break;
21304 case 4: decoded = "explicit"; break;
21305 default: break;
9ef920e9 21306 }
75d7d298
NC
21307 break;
21308 default:
21309 break;
9ef920e9
NC
21310 }
21311
75d7d298 21312 if (decoded != NULL)
3e6b6445
NC
21313 {
21314 print_symbol (-left, decoded);
21315 left = 0;
21316 }
21317 else if (val == 0)
21318 {
21319 printf ("0x0");
21320 left -= 3;
21321 }
9ef920e9 21322 else
75d7d298
NC
21323 {
21324 if (do_wide)
ddef72cd 21325 left -= printf ("0x%llx", val);
75d7d298 21326 else
ddef72cd 21327 left -= printf ("0x%-.*llx", left, val);
75d7d298 21328 }
9ef920e9
NC
21329 }
21330 break;
21331 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21332 left -= print_symbol (- left, name);
21333 break;
21334 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21335 left -= print_symbol (- left, "true");
21336 break;
21337 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21338 left -= print_symbol (- left, "false");
21339 break;
21340 }
21341
21342 if (do_wide && left > 0)
21343 printf ("%-*s", left, " ");
9abca702 21344
015dc7e1 21345 return true;
9ef920e9
NC
21346}
21347
2952f10c
SM
21348/* Print the contents of PNOTE as hex. */
21349
21350static void
21351print_note_contents_hex (Elf_Internal_Note *pnote)
21352{
21353 if (pnote->descsz)
21354 {
21355 unsigned long i;
21356
21357 printf (_(" description data: "));
21358 for (i = 0; i < pnote->descsz; i++)
21359 printf ("%02x ", pnote->descdata[i] & 0xff);
21360 if (!do_wide)
21361 printf ("\n");
21362 }
21363
21364 if (do_wide)
21365 printf ("\n");
21366}
21367
21368#if defined HAVE_MSGPACK
21369
21370static void
21371print_indents (int n)
21372{
21373 printf (" ");
21374
21375 for (int i = 0; i < n; i++)
21376 printf (" ");
21377}
21378
21379/* Print OBJ in human-readable form. */
21380
21381static void
21382dump_msgpack_obj (const msgpack_object *obj, int indent)
21383{
21384 switch (obj->type)
21385 {
21386 case MSGPACK_OBJECT_NIL:
21387 printf ("(nil)");
21388 break;
21389
21390 case MSGPACK_OBJECT_BOOLEAN:
21391 printf ("%s", obj->via.boolean ? "true" : "false");
21392 break;
21393
21394 case MSGPACK_OBJECT_POSITIVE_INTEGER:
21395 printf ("%" PRIu64, obj->via.u64);
21396 break;
21397
21398 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
21399 printf ("%" PRIi64, obj->via.i64);
21400 break;
21401
21402 case MSGPACK_OBJECT_FLOAT32:
21403 case MSGPACK_OBJECT_FLOAT64:
21404 printf ("%f", obj->via.f64);
21405 break;
21406
21407 case MSGPACK_OBJECT_STR:
21408 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
21409 break;
21410
21411 case MSGPACK_OBJECT_ARRAY:
21412 {
21413 const msgpack_object_array *array = &obj->via.array;
21414
21415 printf ("[\n");
21416 ++indent;
21417
21418 for (uint32_t i = 0; i < array->size; ++i)
21419 {
21420 const msgpack_object *item = &array->ptr[i];
21421
21422 print_indents (indent);
21423 dump_msgpack_obj (item, indent);
21424 printf (",\n");
21425 }
21426
21427 --indent;
21428 print_indents (indent);
21429 printf ("]");
21430 break;
21431 }
21432 break;
21433
21434 case MSGPACK_OBJECT_MAP:
21435 {
21436 const msgpack_object_map *map = &obj->via.map;
21437
21438 printf ("{\n");
21439 ++indent;
21440
21441 for (uint32_t i = 0; i < map->size; ++i)
21442 {
21443 const msgpack_object_kv *kv = &map->ptr[i];
21444 const msgpack_object *key = &kv->key;
21445 const msgpack_object *val = &kv->val;
21446
21447 print_indents (indent);
21448 dump_msgpack_obj (key, indent);
21449 printf (": ");
21450 dump_msgpack_obj (val, indent);
21451
21452 printf (",\n");
21453 }
21454
21455 --indent;
21456 print_indents (indent);
21457 printf ("}");
21458
21459 break;
21460 }
21461
21462 case MSGPACK_OBJECT_BIN:
21463 printf ("(bin)");
21464 break;
21465
21466 case MSGPACK_OBJECT_EXT:
21467 printf ("(ext)");
21468 break;
21469 }
21470}
21471
21472static void
21473dump_msgpack (const msgpack_unpacked *msg)
21474{
21475 print_indents (0);
21476 dump_msgpack_obj (&msg->data, 0);
21477 printf ("\n");
21478}
21479
21480#endif /* defined HAVE_MSGPACK */
21481
21482static bool
21483print_amdgpu_note (Elf_Internal_Note *pnote)
21484{
21485#if defined HAVE_MSGPACK
21486 /* If msgpack is available, decode and dump the note's content. */
21487 bool ret;
21488 msgpack_unpacked msg;
21489 msgpack_unpack_return msgpack_ret;
21490
21491 assert (pnote->type == NT_AMDGPU_METADATA);
21492
21493 msgpack_unpacked_init (&msg);
21494 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
21495 NULL);
21496
21497 switch (msgpack_ret)
21498 {
21499 case MSGPACK_UNPACK_SUCCESS:
21500 dump_msgpack (&msg);
21501 ret = true;
21502 break;
21503
21504 default:
21505 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
21506 ret = false;
21507 break;
21508 }
21509
21510 msgpack_unpacked_destroy (&msg);
21511 return ret;
21512#else
21513 /* msgpack is not available, dump contents as hex. */
21514 print_note_contents_hex (pnote);
21515 return true;
21516#endif
21517}
21518
6d118b09
NC
21519/* Note that by the ELF standard, the name field is already null byte
21520 terminated, and namesz includes the terminating null byte.
21521 I.E. the value of namesz for the name "FSF" is 4.
21522
e3c8793a 21523 If the value of namesz is zero, there is no name present. */
9ef920e9 21524
015dc7e1 21525static bool
9ef920e9 21526process_note (Elf_Internal_Note * pnote,
dda8d76d 21527 Filedata * filedata)
779fe533 21528{
2cf0635d
NC
21529 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21530 const char * nt;
9437c45b
JT
21531
21532 if (pnote->namesz == 0)
1ec5cd37
NC
21533 /* If there is no note name, then use the default set of
21534 note type strings. */
dda8d76d 21535 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21536
24d127aa 21537 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21538 /* GNU-specific object file notes. */
21539 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21540
28cdbb18
SM
21541 else if (startswith (pnote->namedata, "AMDGPU"))
21542 /* AMDGPU-specific object file notes. */
21543 nt = get_amdgpu_elf_note_type (pnote->type);
21544
24d127aa 21545 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21546 /* FreeBSD-specific core file notes. */
dda8d76d 21547 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21548
24d127aa 21549 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21550 /* NetBSD-specific core file notes. */
dda8d76d 21551 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21552
24d127aa 21553 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21554 /* NetBSD-specific core file notes. */
21555 return process_netbsd_elf_note (pnote);
21556
24d127aa 21557 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21558 /* NetBSD-specific core file notes. */
21559 return process_netbsd_elf_note (pnote);
21560
98ca73af
FC
21561 else if (startswith (pnote->namedata, "OpenBSD"))
21562 /* OpenBSD-specific core file notes. */
21563 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21564
e9b095a5 21565 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21566 {
21567 /* SPU-specific core file notes. */
21568 nt = pnote->namedata + 4;
21569 name = "SPU";
21570 }
21571
24d127aa 21572 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21573 /* VMS/ia64-specific file notes. */
21574 nt = get_ia64_vms_note_type (pnote->type);
21575
24d127aa 21576 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21577 nt = get_stapsdt_note_type (pnote->type);
21578
9437c45b 21579 else
1ec5cd37
NC
21580 /* Don't recognize this note name; just use the default set of
21581 note type strings. */
dda8d76d 21582 nt = get_note_type (filedata, pnote->type);
9437c45b 21583
1449284b 21584 printf (" ");
9ef920e9 21585
24d127aa 21586 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21587 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21588 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21589 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21590 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21591 print_gnu_build_attribute_name (pnote);
21592 else
21593 print_symbol (-20, name);
21594
21595 if (do_wide)
21596 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21597 else
21598 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21599
24d127aa 21600 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21601 return print_ia64_vms_note (pnote);
24d127aa 21602 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21603 return print_gnu_note (filedata, pnote);
24d127aa 21604 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21605 return print_stapsdt_note (pnote);
24d127aa 21606 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21607 return print_core_note (pnote);
e5382207
LB
21608 else if (startswith (pnote->namedata, "FDO"))
21609 return print_fdo_note (pnote);
24d127aa 21610 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21611 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21612 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21613 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21614 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21615 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
21616 else if (startswith (pnote->namedata, "AMDGPU")
21617 && pnote->type == NT_AMDGPU_METADATA)
21618 return print_amdgpu_note (pnote);
779fe533 21619
2952f10c 21620 print_note_contents_hex (pnote);
015dc7e1 21621 return true;
1449284b 21622}
6d118b09 21623
015dc7e1 21624static bool
dda8d76d
NC
21625process_notes_at (Filedata * filedata,
21626 Elf_Internal_Shdr * section,
625d49fc
AM
21627 uint64_t offset,
21628 uint64_t length,
21629 uint64_t align)
779fe533 21630{
015dc7e1
AM
21631 Elf_External_Note *pnotes;
21632 Elf_External_Note *external;
21633 char *end;
21634 bool res = true;
103f02d3 21635
779fe533 21636 if (length <= 0)
015dc7e1 21637 return false;
103f02d3 21638
1449284b
NC
21639 if (section)
21640 {
dda8d76d 21641 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21642 if (pnotes)
32ec8896 21643 {
dda8d76d 21644 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21645 {
21646 free (pnotes);
015dc7e1 21647 return false;
f761cb13 21648 }
32ec8896 21649 }
1449284b
NC
21650 }
21651 else
82ed9683 21652 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21653 _("notes"));
4dff97b2 21654
dd24e3da 21655 if (pnotes == NULL)
015dc7e1 21656 return false;
779fe533 21657
103f02d3 21658 external = pnotes;
103f02d3 21659
ca0e11aa
NC
21660 if (filedata->is_separate)
21661 printf (_("In linked file '%s': "), filedata->file_name);
21662 else
21663 printf ("\n");
1449284b 21664 if (section)
ca0e11aa 21665 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21666 else
ca0e11aa 21667 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
21668 (unsigned long) offset, (unsigned long) length);
21669
82ed9683
L
21670 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21671 specifies that notes should be aligned to 4 bytes in 32-bit
21672 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21673 we also support 4 byte alignment in 64-bit objects. If section
21674 alignment is less than 4, we treate alignment as 4 bytes. */
21675 if (align < 4)
21676 align = 4;
21677 else if (align != 4 && align != 8)
21678 {
21679 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
21680 (long) align);
a788aedd 21681 free (pnotes);
015dc7e1 21682 return false;
82ed9683
L
21683 }
21684
dbe15e4e 21685 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21686
c8071705
NC
21687 end = (char *) pnotes + length;
21688 while ((char *) external < end)
779fe533 21689 {
b34976b6 21690 Elf_Internal_Note inote;
15b42fb0 21691 size_t min_notesz;
4dff97b2 21692 char * next;
2cf0635d 21693 char * temp = NULL;
c8071705 21694 size_t data_remaining = end - (char *) external;
6d118b09 21695
dda8d76d 21696 if (!is_ia64_vms (filedata))
15b42fb0 21697 {
9dd3a467
NC
21698 /* PR binutils/15191
21699 Make sure that there is enough data to read. */
15b42fb0
AM
21700 min_notesz = offsetof (Elf_External_Note, name);
21701 if (data_remaining < min_notesz)
9dd3a467 21702 {
d3a49aa8
AM
21703 warn (ngettext ("Corrupt note: only %ld byte remains, "
21704 "not enough for a full note\n",
21705 "Corrupt note: only %ld bytes remain, "
21706 "not enough for a full note\n",
21707 data_remaining),
21708 (long) data_remaining);
9dd3a467
NC
21709 break;
21710 }
5396a86e
AM
21711 data_remaining -= min_notesz;
21712
15b42fb0
AM
21713 inote.type = BYTE_GET (external->type);
21714 inote.namesz = BYTE_GET (external->namesz);
21715 inote.namedata = external->name;
21716 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21717 inote.descdata = ((char *) external
4dff97b2 21718 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21719 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21720 next = ((char *) external
4dff97b2 21721 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21722 }
00e98fc7 21723 else
15b42fb0
AM
21724 {
21725 Elf64_External_VMS_Note *vms_external;
00e98fc7 21726
9dd3a467
NC
21727 /* PR binutils/15191
21728 Make sure that there is enough data to read. */
15b42fb0
AM
21729 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21730 if (data_remaining < min_notesz)
9dd3a467 21731 {
d3a49aa8
AM
21732 warn (ngettext ("Corrupt note: only %ld byte remains, "
21733 "not enough for a full note\n",
21734 "Corrupt note: only %ld bytes remain, "
21735 "not enough for a full note\n",
21736 data_remaining),
21737 (long) data_remaining);
9dd3a467
NC
21738 break;
21739 }
5396a86e 21740 data_remaining -= min_notesz;
3e55a963 21741
15b42fb0
AM
21742 vms_external = (Elf64_External_VMS_Note *) external;
21743 inote.type = BYTE_GET (vms_external->type);
21744 inote.namesz = BYTE_GET (vms_external->namesz);
21745 inote.namedata = vms_external->name;
21746 inote.descsz = BYTE_GET (vms_external->descsz);
21747 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21748 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21749 next = inote.descdata + align_power (inote.descsz, 3);
21750 }
21751
5396a86e
AM
21752 /* PR 17531: file: 3443835e. */
21753 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21754 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21755 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21756 || (size_t) (next - inote.descdata) < inote.descsz
21757 || ((size_t) (next - inote.descdata)
21758 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21759 {
15b42fb0 21760 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 21761 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
21762 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
21763 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21764 break;
21765 }
21766
15b42fb0 21767 external = (Elf_External_Note *) next;
dd24e3da 21768
6d118b09
NC
21769 /* Verify that name is null terminated. It appears that at least
21770 one version of Linux (RedHat 6.0) generates corefiles that don't
21771 comply with the ELF spec by failing to include the null byte in
21772 namesz. */
18344509 21773 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21774 {
5396a86e 21775 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21776 {
5396a86e
AM
21777 temp = (char *) malloc (inote.namesz + 1);
21778 if (temp == NULL)
21779 {
21780 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21781 res = false;
5396a86e
AM
21782 break;
21783 }
76da6bbe 21784
5396a86e
AM
21785 memcpy (temp, inote.namedata, inote.namesz);
21786 inote.namedata = temp;
21787 }
21788 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21789 }
21790
dda8d76d 21791 if (! process_note (& inote, filedata))
015dc7e1 21792 res = false;
103f02d3 21793
9db70fc3
AM
21794 free (temp);
21795 temp = NULL;
779fe533
NC
21796 }
21797
21798 free (pnotes);
103f02d3 21799
779fe533
NC
21800 return res;
21801}
21802
015dc7e1 21803static bool
dda8d76d 21804process_corefile_note_segments (Filedata * filedata)
779fe533 21805{
015dc7e1 21806 Elf_Internal_Phdr *segment;
b34976b6 21807 unsigned int i;
015dc7e1 21808 bool res = true;
103f02d3 21809
dda8d76d 21810 if (! get_program_headers (filedata))
015dc7e1 21811 return true;
103f02d3 21812
dda8d76d
NC
21813 for (i = 0, segment = filedata->program_headers;
21814 i < filedata->file_header.e_phnum;
b34976b6 21815 i++, segment++)
779fe533
NC
21816 {
21817 if (segment->p_type == PT_NOTE)
625d49fc
AM
21818 if (! process_notes_at (filedata, NULL, segment->p_offset,
21819 segment->p_filesz, segment->p_align))
015dc7e1 21820 res = false;
779fe533 21821 }
103f02d3 21822
779fe533
NC
21823 return res;
21824}
21825
015dc7e1 21826static bool
625d49fc 21827process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
21828{
21829 Elf_External_Note * pnotes;
21830 Elf_External_Note * external;
c8071705 21831 char * end;
015dc7e1 21832 bool res = true;
685080f2
NC
21833
21834 if (length <= 0)
015dc7e1 21835 return false;
685080f2 21836
dda8d76d 21837 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21838 _("v850 notes"));
21839 if (pnotes == NULL)
015dc7e1 21840 return false;
685080f2
NC
21841
21842 external = pnotes;
c8071705 21843 end = (char*) pnotes + length;
685080f2
NC
21844
21845 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21846 (unsigned long) offset, (unsigned long) length);
21847
c8071705 21848 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21849 {
21850 Elf_External_Note * next;
21851 Elf_Internal_Note inote;
21852
21853 inote.type = BYTE_GET (external->type);
21854 inote.namesz = BYTE_GET (external->namesz);
21855 inote.namedata = external->name;
21856 inote.descsz = BYTE_GET (external->descsz);
21857 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21858 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21859
c8071705
NC
21860 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21861 {
21862 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21863 inote.descdata = inote.namedata;
21864 inote.namesz = 0;
21865 }
21866
685080f2
NC
21867 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21868
c8071705 21869 if ( ((char *) next > end)
685080f2
NC
21870 || ((char *) next < (char *) pnotes))
21871 {
21872 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21873 (unsigned long) ((char *) external - (char *) pnotes));
21874 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21875 inote.type, inote.namesz, inote.descsz);
21876 break;
21877 }
21878
21879 external = next;
21880
21881 /* Prevent out-of-bounds indexing. */
c8071705 21882 if ( inote.namedata + inote.namesz > end
685080f2
NC
21883 || inote.namedata + inote.namesz < inote.namedata)
21884 {
21885 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21886 (unsigned long) ((char *) external - (char *) pnotes));
21887 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21888 inote.type, inote.namesz, inote.descsz);
21889 break;
21890 }
21891
21892 printf (" %s: ", get_v850_elf_note_type (inote.type));
21893
21894 if (! print_v850_note (& inote))
21895 {
015dc7e1 21896 res = false;
685080f2
NC
21897 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21898 inote.namesz, inote.descsz);
21899 }
21900 }
21901
21902 free (pnotes);
21903
21904 return res;
21905}
21906
015dc7e1 21907static bool
dda8d76d 21908process_note_sections (Filedata * filedata)
1ec5cd37 21909{
015dc7e1 21910 Elf_Internal_Shdr *section;
1ec5cd37 21911 unsigned long i;
32ec8896 21912 unsigned int n = 0;
015dc7e1 21913 bool res = true;
1ec5cd37 21914
dda8d76d
NC
21915 for (i = 0, section = filedata->section_headers;
21916 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21917 i++, section++)
685080f2
NC
21918 {
21919 if (section->sh_type == SHT_NOTE)
21920 {
625d49fc
AM
21921 if (! process_notes_at (filedata, section, section->sh_offset,
21922 section->sh_size, section->sh_addralign))
015dc7e1 21923 res = false;
685080f2
NC
21924 n++;
21925 }
21926
dda8d76d
NC
21927 if (( filedata->file_header.e_machine == EM_V800
21928 || filedata->file_header.e_machine == EM_V850
21929 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21930 && section->sh_type == SHT_RENESAS_INFO)
21931 {
625d49fc
AM
21932 if (! process_v850_notes (filedata, section->sh_offset,
21933 section->sh_size))
015dc7e1 21934 res = false;
685080f2
NC
21935 n++;
21936 }
21937 }
df565f32
NC
21938
21939 if (n == 0)
21940 /* Try processing NOTE segments instead. */
dda8d76d 21941 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21942
21943 return res;
21944}
21945
015dc7e1 21946static bool
dda8d76d 21947process_notes (Filedata * filedata)
779fe533
NC
21948{
21949 /* If we have not been asked to display the notes then do nothing. */
21950 if (! do_notes)
015dc7e1 21951 return true;
103f02d3 21952
dda8d76d
NC
21953 if (filedata->file_header.e_type != ET_CORE)
21954 return process_note_sections (filedata);
103f02d3 21955
779fe533 21956 /* No program headers means no NOTE segment. */
dda8d76d
NC
21957 if (filedata->file_header.e_phnum > 0)
21958 return process_corefile_note_segments (filedata);
779fe533 21959
ca0e11aa
NC
21960 if (filedata->is_separate)
21961 printf (_("No notes found in linked file '%s'.\n"),
21962 filedata->file_name);
21963 else
21964 printf (_("No notes found file.\n"));
21965
015dc7e1 21966 return true;
779fe533
NC
21967}
21968
60abdbed
NC
21969static unsigned char *
21970display_public_gnu_attributes (unsigned char * start,
21971 const unsigned char * const end)
21972{
21973 printf (_(" Unknown GNU attribute: %s\n"), start);
21974
21975 start += strnlen ((char *) start, end - start);
21976 display_raw_attribute (start, end);
21977
21978 return (unsigned char *) end;
21979}
21980
21981static unsigned char *
21982display_generic_attribute (unsigned char * start,
21983 unsigned int tag,
21984 const unsigned char * const end)
21985{
21986 if (tag == 0)
21987 return (unsigned char *) end;
21988
21989 return display_tag_value (tag, start, end);
21990}
21991
015dc7e1 21992static bool
dda8d76d 21993process_arch_specific (Filedata * filedata)
252b5132 21994{
a952a375 21995 if (! do_arch)
015dc7e1 21996 return true;
a952a375 21997
dda8d76d 21998 switch (filedata->file_header.e_machine)
252b5132 21999 {
53a346d8
CZ
22000 case EM_ARC:
22001 case EM_ARC_COMPACT:
22002 case EM_ARC_COMPACT2:
dda8d76d 22003 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
22004 display_arc_attribute,
22005 display_generic_attribute);
11c1ff18 22006 case EM_ARM:
dda8d76d 22007 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
22008 display_arm_attribute,
22009 display_generic_attribute);
22010
252b5132 22011 case EM_MIPS:
4fe85591 22012 case EM_MIPS_RS3_LE:
dda8d76d 22013 return process_mips_specific (filedata);
60abdbed
NC
22014
22015 case EM_MSP430:
dda8d76d 22016 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 22017 display_msp430_attribute,
c0ea7c52 22018 display_msp430_gnu_attribute);
60abdbed 22019
2dc8dd17
JW
22020 case EM_RISCV:
22021 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22022 display_riscv_attribute,
22023 display_generic_attribute);
22024
35c08157 22025 case EM_NDS32:
dda8d76d 22026 return process_nds32_specific (filedata);
60abdbed 22027
85f7484a
PB
22028 case EM_68K:
22029 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22030 display_m68k_gnu_attribute);
22031
34c8bcba 22032 case EM_PPC:
b82317dd 22033 case EM_PPC64:
dda8d76d 22034 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22035 display_power_gnu_attribute);
22036
643f7afb
AK
22037 case EM_S390:
22038 case EM_S390_OLD:
dda8d76d 22039 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22040 display_s390_gnu_attribute);
22041
9e8c70f9
DM
22042 case EM_SPARC:
22043 case EM_SPARC32PLUS:
22044 case EM_SPARCV9:
dda8d76d 22045 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22046 display_sparc_gnu_attribute);
22047
59e6276b 22048 case EM_TI_C6000:
dda8d76d 22049 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22050 display_tic6x_attribute,
22051 display_generic_attribute);
22052
0861f561
CQ
22053 case EM_CSKY:
22054 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22055 display_csky_attribute, NULL);
22056
252b5132 22057 default:
dda8d76d 22058 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22059 display_public_gnu_attributes,
22060 display_generic_attribute);
252b5132 22061 }
252b5132
RH
22062}
22063
015dc7e1 22064static bool
dda8d76d 22065get_file_header (Filedata * filedata)
252b5132 22066{
9ea033b2 22067 /* Read in the identity array. */
dda8d76d 22068 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22069 return false;
252b5132 22070
9ea033b2 22071 /* Determine how to read the rest of the header. */
dda8d76d 22072 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22073 {
1a0670f3
AM
22074 default:
22075 case ELFDATANONE:
adab8cdc
AO
22076 case ELFDATA2LSB:
22077 byte_get = byte_get_little_endian;
22078 byte_put = byte_put_little_endian;
22079 break;
22080 case ELFDATA2MSB:
22081 byte_get = byte_get_big_endian;
22082 byte_put = byte_put_big_endian;
22083 break;
9ea033b2
NC
22084 }
22085
22086 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22087 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22088
22089 /* Read in the rest of the header. */
22090 if (is_32bit_elf)
22091 {
22092 Elf32_External_Ehdr ehdr32;
252b5132 22093
dda8d76d 22094 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22095 return false;
103f02d3 22096
dda8d76d
NC
22097 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22098 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22099 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22100 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22101 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22102 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22103 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22104 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22105 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22106 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22107 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22108 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22109 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22110 }
252b5132 22111 else
9ea033b2
NC
22112 {
22113 Elf64_External_Ehdr ehdr64;
a952a375 22114
dda8d76d 22115 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22116 return false;
103f02d3 22117
dda8d76d
NC
22118 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22119 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22120 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22121 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22122 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22123 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22124 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22125 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22126 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22127 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22128 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22129 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22130 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22131 }
252b5132 22132
015dc7e1 22133 return true;
252b5132
RH
22134}
22135
13acb58d
AM
22136static void
22137free_filedata (Filedata *filedata)
22138{
22139 free (filedata->program_interpreter);
13acb58d 22140 free (filedata->program_headers);
13acb58d 22141 free (filedata->section_headers);
13acb58d 22142 free (filedata->string_table);
13acb58d 22143 free (filedata->dump.dump_sects);
13acb58d 22144 free (filedata->dynamic_strings);
13acb58d 22145 free (filedata->dynamic_symbols);
13acb58d 22146 free (filedata->dynamic_syminfo);
13acb58d 22147 free (filedata->dynamic_section);
13acb58d
AM
22148
22149 while (filedata->symtab_shndx_list != NULL)
22150 {
22151 elf_section_list *next = filedata->symtab_shndx_list->next;
22152 free (filedata->symtab_shndx_list);
22153 filedata->symtab_shndx_list = next;
22154 }
22155
22156 free (filedata->section_headers_groups);
13acb58d
AM
22157
22158 if (filedata->section_groups)
22159 {
22160 size_t i;
22161 struct group_list * g;
22162 struct group_list * next;
22163
22164 for (i = 0; i < filedata->group_count; i++)
22165 {
22166 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22167 {
22168 next = g->next;
22169 free (g);
22170 }
22171 }
22172
22173 free (filedata->section_groups);
13acb58d 22174 }
066f8fbe
AM
22175 memset (&filedata->section_headers, 0,
22176 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22177}
22178
dda8d76d
NC
22179static void
22180close_file (Filedata * filedata)
22181{
22182 if (filedata)
22183 {
22184 if (filedata->handle)
22185 fclose (filedata->handle);
22186 free (filedata);
22187 }
22188}
22189
22190void
22191close_debug_file (void * data)
22192{
13acb58d 22193 free_filedata ((Filedata *) data);
dda8d76d
NC
22194 close_file ((Filedata *) data);
22195}
22196
22197static Filedata *
015dc7e1 22198open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22199{
22200 struct stat statbuf;
22201 Filedata * filedata = NULL;
22202
22203 if (stat (pathname, & statbuf) < 0
22204 || ! S_ISREG (statbuf.st_mode))
22205 goto fail;
22206
22207 filedata = calloc (1, sizeof * filedata);
22208 if (filedata == NULL)
22209 goto fail;
22210
22211 filedata->handle = fopen (pathname, "rb");
22212 if (filedata->handle == NULL)
22213 goto fail;
22214
be7d229a 22215 filedata->file_size = statbuf.st_size;
dda8d76d 22216 filedata->file_name = pathname;
ca0e11aa 22217 filedata->is_separate = is_separate;
dda8d76d
NC
22218
22219 if (! get_file_header (filedata))
22220 goto fail;
22221
4de91c10
AM
22222 if (!get_section_headers (filedata, false))
22223 goto fail;
dda8d76d
NC
22224
22225 return filedata;
22226
22227 fail:
22228 if (filedata)
22229 {
22230 if (filedata->handle)
22231 fclose (filedata->handle);
22232 free (filedata);
22233 }
22234 return NULL;
22235}
22236
22237void *
22238open_debug_file (const char * pathname)
22239{
015dc7e1 22240 return open_file (pathname, true);
dda8d76d
NC
22241}
22242
835f2fae
NC
22243static void
22244initialise_dump_sects (Filedata * filedata)
22245{
22246 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22247 Note we do this even if cmdline_dump_sects is empty because we
22248 must make sure that the dump_sets array is zeroed out before each
22249 object file is processed. */
22250 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22251 memset (filedata->dump.dump_sects, 0,
22252 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22253
22254 if (cmdline.num_dump_sects > 0)
22255 {
22256 if (filedata->dump.num_dump_sects == 0)
22257 /* A sneaky way of allocating the dump_sects array. */
22258 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22259
22260 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22261 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22262 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22263 }
22264}
22265
94585d6d
NC
22266static bool
22267might_need_separate_debug_info (Filedata * filedata)
22268{
22269 /* Debuginfo files do not need further separate file loading. */
22270 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22271 return false;
22272
22273 /* Since do_follow_links might be enabled by default, only treat it as an
22274 indication that separate files should be loaded if setting it was a
22275 deliberate user action. */
22276 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22277 return true;
22278
22279 if (process_links || do_syms || do_unwind
22280 || dump_any_debugging || do_dump || do_debugging)
22281 return true;
22282
22283 return false;
22284}
22285
fb52b2f4
NC
22286/* Process one ELF object file according to the command line options.
22287 This file may actually be stored in an archive. The file is
32ec8896
NC
22288 positioned at the start of the ELF object. Returns TRUE if no
22289 problems were encountered, FALSE otherwise. */
fb52b2f4 22290
015dc7e1 22291static bool
dda8d76d 22292process_object (Filedata * filedata)
252b5132 22293{
015dc7e1 22294 bool have_separate_files;
252b5132 22295 unsigned int i;
015dc7e1 22296 bool res;
252b5132 22297
dda8d76d 22298 if (! get_file_header (filedata))
252b5132 22299 {
dda8d76d 22300 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22301 return false;
252b5132
RH
22302 }
22303
22304 /* Initialise per file variables. */
978c4450
AM
22305 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22306 filedata->version_info[i] = 0;
252b5132 22307
978c4450
AM
22308 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22309 filedata->dynamic_info[i] = 0;
22310 filedata->dynamic_info_DT_GNU_HASH = 0;
22311 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22312
22313 /* Process the file. */
22314 if (show_name)
dda8d76d 22315 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22316
835f2fae 22317 initialise_dump_sects (filedata);
d70c5fc7 22318
4de91c10
AM
22319 /* There may be some extensions in the first section header. Don't
22320 bomb if we can't read it. */
22321 get_section_headers (filedata, true);
22322
dda8d76d 22323 if (! process_file_header (filedata))
4de91c10
AM
22324 {
22325 res = false;
22326 goto out;
22327 }
252b5132 22328
e331b18d
AM
22329 /* Throw away the single section header read above, so that we
22330 re-read the entire set. */
22331 free (filedata->section_headers);
22332 filedata->section_headers = NULL;
22333
dda8d76d 22334 if (! process_section_headers (filedata))
2f62977e 22335 {
32ec8896 22336 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22337 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22338
2f62977e 22339 if (! do_using_dynamic)
015dc7e1 22340 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22341 }
252b5132 22342
dda8d76d 22343 if (! process_section_groups (filedata))
32ec8896 22344 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22345 do_unwind = false;
d1f5c6e3 22346
93df3340
AM
22347 process_program_headers (filedata);
22348
22349 res = process_dynamic_section (filedata);
252b5132 22350
dda8d76d 22351 if (! process_relocs (filedata))
015dc7e1 22352 res = false;
252b5132 22353
dda8d76d 22354 if (! process_unwind (filedata))
015dc7e1 22355 res = false;
4d6ed7c8 22356
dda8d76d 22357 if (! process_symbol_table (filedata))
015dc7e1 22358 res = false;
252b5132 22359
0f03783c 22360 if (! process_lto_symbol_tables (filedata))
015dc7e1 22361 res = false;
b9e920ec 22362
dda8d76d 22363 if (! process_syminfo (filedata))
015dc7e1 22364 res = false;
252b5132 22365
dda8d76d 22366 if (! process_version_sections (filedata))
015dc7e1 22367 res = false;
252b5132 22368
94585d6d 22369 if (might_need_separate_debug_info (filedata))
24841daa 22370 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22371 else
015dc7e1 22372 have_separate_files = false;
dda8d76d
NC
22373
22374 if (! process_section_contents (filedata))
015dc7e1 22375 res = false;
f5842774 22376
24841daa 22377 if (have_separate_files)
dda8d76d 22378 {
24841daa
NC
22379 separate_info * d;
22380
22381 for (d = first_separate_info; d != NULL; d = d->next)
22382 {
835f2fae
NC
22383 initialise_dump_sects (d->handle);
22384
ca0e11aa 22385 if (process_links && ! process_file_header (d->handle))
015dc7e1 22386 res = false;
ca0e11aa 22387 else if (! process_section_headers (d->handle))
015dc7e1 22388 res = false;
d6bfbc39 22389 else if (! process_section_contents (d->handle))
015dc7e1 22390 res = false;
ca0e11aa
NC
22391 else if (process_links)
22392 {
ca0e11aa 22393 if (! process_section_groups (d->handle))
015dc7e1 22394 res = false;
93df3340 22395 process_program_headers (d->handle);
ca0e11aa 22396 if (! process_dynamic_section (d->handle))
015dc7e1 22397 res = false;
ca0e11aa 22398 if (! process_relocs (d->handle))
015dc7e1 22399 res = false;
ca0e11aa 22400 if (! process_unwind (d->handle))
015dc7e1 22401 res = false;
ca0e11aa 22402 if (! process_symbol_table (d->handle))
015dc7e1 22403 res = false;
ca0e11aa 22404 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22405 res = false;
ca0e11aa 22406 if (! process_syminfo (d->handle))
015dc7e1 22407 res = false;
ca0e11aa 22408 if (! process_version_sections (d->handle))
015dc7e1 22409 res = false;
ca0e11aa 22410 if (! process_notes (d->handle))
015dc7e1 22411 res = false;
ca0e11aa 22412 }
24841daa
NC
22413 }
22414
22415 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22416 }
22417
22418 if (! process_notes (filedata))
015dc7e1 22419 res = false;
103f02d3 22420
dda8d76d 22421 if (! process_gnu_liblist (filedata))
015dc7e1 22422 res = false;
047b2264 22423
dda8d76d 22424 if (! process_arch_specific (filedata))
015dc7e1 22425 res = false;
252b5132 22426
4de91c10 22427 out:
13acb58d 22428 free_filedata (filedata);
e4b17d5c 22429
19e6b90e 22430 free_debug_memory ();
18bd398b 22431
32ec8896 22432 return res;
252b5132
RH
22433}
22434
2cf0635d 22435/* Process an ELF archive.
32ec8896
NC
22436 On entry the file is positioned just after the ARMAG string.
22437 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22438
015dc7e1
AM
22439static bool
22440process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22441{
22442 struct archive_info arch;
22443 struct archive_info nested_arch;
22444 size_t got;
015dc7e1 22445 bool ret = true;
2cf0635d 22446
015dc7e1 22447 show_name = true;
2cf0635d
NC
22448
22449 /* The ARCH structure is used to hold information about this archive. */
22450 arch.file_name = NULL;
22451 arch.file = NULL;
22452 arch.index_array = NULL;
22453 arch.sym_table = NULL;
22454 arch.longnames = NULL;
22455
22456 /* The NESTED_ARCH structure is used as a single-item cache of information
22457 about a nested archive (when members of a thin archive reside within
22458 another regular archive file). */
22459 nested_arch.file_name = NULL;
22460 nested_arch.file = NULL;
22461 nested_arch.index_array = NULL;
22462 nested_arch.sym_table = NULL;
22463 nested_arch.longnames = NULL;
22464
dda8d76d 22465 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22466 filedata->file_size, is_thin_archive,
22467 do_archive_index) != 0)
2cf0635d 22468 {
015dc7e1 22469 ret = false;
2cf0635d 22470 goto out;
4145f1d5 22471 }
fb52b2f4 22472
4145f1d5
NC
22473 if (do_archive_index)
22474 {
2cf0635d 22475 if (arch.sym_table == NULL)
1cb7d8b1
AM
22476 error (_("%s: unable to dump the index as none was found\n"),
22477 filedata->file_name);
4145f1d5
NC
22478 else
22479 {
591f7597 22480 unsigned long i, l;
4145f1d5
NC
22481 unsigned long current_pos;
22482
1cb7d8b1
AM
22483 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
22484 "in the symbol table)\n"),
22485 filedata->file_name, (unsigned long) arch.index_num,
22486 arch.sym_size);
dda8d76d
NC
22487
22488 current_pos = ftell (filedata->handle);
4145f1d5 22489
2cf0635d 22490 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22491 {
1cb7d8b1
AM
22492 if (i == 0
22493 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22494 {
22495 char * member_name
22496 = get_archive_member_name_at (&arch, arch.index_array[i],
22497 &nested_arch);
2cf0635d 22498
1cb7d8b1
AM
22499 if (member_name != NULL)
22500 {
22501 char * qualified_name
22502 = make_qualified_name (&arch, &nested_arch,
22503 member_name);
2cf0635d 22504
1cb7d8b1
AM
22505 if (qualified_name != NULL)
22506 {
22507 printf (_("Contents of binary %s at offset "),
22508 qualified_name);
c2a7d3f5
NC
22509 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22510 putchar ('\n');
1cb7d8b1
AM
22511 free (qualified_name);
22512 }
fd486f32 22513 free (member_name);
4145f1d5
NC
22514 }
22515 }
2cf0635d
NC
22516
22517 if (l >= arch.sym_size)
4145f1d5 22518 {
1cb7d8b1
AM
22519 error (_("%s: end of the symbol table reached "
22520 "before the end of the index\n"),
dda8d76d 22521 filedata->file_name);
015dc7e1 22522 ret = false;
cb8f3167 22523 break;
4145f1d5 22524 }
591f7597 22525 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22526 printf ("\t%.*s\n",
22527 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22528 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22529 }
22530
67ce483b 22531 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22532 l = (l + 7) & ~ 7;
22533 else
22534 l += l & 1;
22535
2cf0635d 22536 if (l < arch.sym_size)
32ec8896 22537 {
d3a49aa8
AM
22538 error (ngettext ("%s: %ld byte remains in the symbol table, "
22539 "but without corresponding entries in "
22540 "the index table\n",
22541 "%s: %ld bytes remain in the symbol table, "
22542 "but without corresponding entries in "
22543 "the index table\n",
22544 arch.sym_size - l),
dda8d76d 22545 filedata->file_name, arch.sym_size - l);
015dc7e1 22546 ret = false;
32ec8896 22547 }
4145f1d5 22548
dda8d76d 22549 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22550 {
1cb7d8b1
AM
22551 error (_("%s: failed to seek back to start of object files "
22552 "in the archive\n"),
dda8d76d 22553 filedata->file_name);
015dc7e1 22554 ret = false;
2cf0635d 22555 goto out;
4145f1d5 22556 }
fb52b2f4 22557 }
4145f1d5
NC
22558
22559 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22560 && !do_segments && !do_header && !do_dump && !do_version
22561 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22562 && !do_section_groups && !do_dyn_syms)
2cf0635d 22563 {
015dc7e1 22564 ret = true; /* Archive index only. */
2cf0635d
NC
22565 goto out;
22566 }
fb52b2f4
NC
22567 }
22568
fb52b2f4
NC
22569 while (1)
22570 {
2cf0635d
NC
22571 char * name;
22572 size_t namelen;
22573 char * qualified_name;
22574
22575 /* Read the next archive header. */
dda8d76d 22576 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22577 {
22578 error (_("%s: failed to seek to next archive header\n"),
22579 arch.file_name);
015dc7e1 22580 ret = false;
1cb7d8b1
AM
22581 break;
22582 }
dda8d76d 22583 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22584 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22585 {
22586 if (got == 0)
2cf0635d 22587 break;
28e817cc
NC
22588 /* PR 24049 - we cannot use filedata->file_name as this will
22589 have already been freed. */
22590 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22591
015dc7e1 22592 ret = false;
1cb7d8b1
AM
22593 break;
22594 }
2cf0635d 22595 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22596 {
22597 error (_("%s: did not find a valid archive header\n"),
22598 arch.file_name);
015dc7e1 22599 ret = false;
1cb7d8b1
AM
22600 break;
22601 }
2cf0635d
NC
22602
22603 arch.next_arhdr_offset += sizeof arch.arhdr;
22604
978c4450 22605 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22606
22607 name = get_archive_member_name (&arch, &nested_arch);
22608 if (name == NULL)
fb52b2f4 22609 {
28e817cc 22610 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22611 ret = false;
d989285c 22612 break;
fb52b2f4 22613 }
2cf0635d 22614 namelen = strlen (name);
fb52b2f4 22615
2cf0635d
NC
22616 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22617 if (qualified_name == NULL)
fb52b2f4 22618 {
28e817cc 22619 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22620 free (name);
015dc7e1 22621 ret = false;
d989285c 22622 break;
fb52b2f4
NC
22623 }
22624
2cf0635d 22625 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22626 {
22627 /* This is a proxy for an external member of a thin archive. */
22628 Filedata * member_filedata;
22629 char * member_file_name = adjust_relative_path
dda8d76d 22630 (filedata->file_name, name, namelen);
32ec8896 22631
fd486f32 22632 free (name);
1cb7d8b1
AM
22633 if (member_file_name == NULL)
22634 {
fd486f32 22635 free (qualified_name);
015dc7e1 22636 ret = false;
1cb7d8b1
AM
22637 break;
22638 }
2cf0635d 22639
015dc7e1 22640 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22641 if (member_filedata == NULL)
22642 {
22643 error (_("Input file '%s' is not readable.\n"), member_file_name);
22644 free (member_file_name);
fd486f32 22645 free (qualified_name);
015dc7e1 22646 ret = false;
1cb7d8b1
AM
22647 break;
22648 }
2cf0635d 22649
978c4450 22650 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22651 member_filedata->file_name = qualified_name;
2cf0635d 22652
75a2da57
AH
22653 /* The call to process_object() expects the file to be at the beginning. */
22654 rewind (member_filedata->handle);
22655
1cb7d8b1 22656 if (! process_object (member_filedata))
015dc7e1 22657 ret = false;
2cf0635d 22658
1cb7d8b1
AM
22659 close_file (member_filedata);
22660 free (member_file_name);
1cb7d8b1 22661 }
2cf0635d 22662 else if (is_thin_archive)
1cb7d8b1
AM
22663 {
22664 Filedata thin_filedata;
eb02c04d 22665
1cb7d8b1 22666 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22667
a043396b
NC
22668 /* PR 15140: Allow for corrupt thin archives. */
22669 if (nested_arch.file == NULL)
22670 {
22671 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22672 qualified_name, name);
fd486f32
AM
22673 free (qualified_name);
22674 free (name);
015dc7e1 22675 ret = false;
a043396b
NC
22676 break;
22677 }
fd486f32 22678 free (name);
a043396b 22679
1cb7d8b1 22680 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22681 filedata->archive_file_offset
22682 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22683
1cb7d8b1
AM
22684 /* The nested archive file will have been opened and setup by
22685 get_archive_member_name. */
978c4450
AM
22686 if (fseek (nested_arch.file, filedata->archive_file_offset,
22687 SEEK_SET) != 0)
1cb7d8b1
AM
22688 {
22689 error (_("%s: failed to seek to archive member.\n"),
22690 nested_arch.file_name);
fd486f32 22691 free (qualified_name);
015dc7e1 22692 ret = false;
1cb7d8b1
AM
22693 break;
22694 }
2cf0635d 22695
dda8d76d
NC
22696 thin_filedata.handle = nested_arch.file;
22697 thin_filedata.file_name = qualified_name;
9abca702 22698
1cb7d8b1 22699 if (! process_object (& thin_filedata))
015dc7e1 22700 ret = false;
1cb7d8b1 22701 }
2cf0635d 22702 else
1cb7d8b1 22703 {
fd486f32 22704 free (name);
978c4450 22705 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22706 filedata->file_name = qualified_name;
1cb7d8b1 22707 if (! process_object (filedata))
015dc7e1 22708 ret = false;
237877b8 22709 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22710 /* Stop looping with "negative" archive_file_size. */
978c4450 22711 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22712 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22713 }
fb52b2f4 22714
2cf0635d 22715 free (qualified_name);
fb52b2f4
NC
22716 }
22717
4145f1d5 22718 out:
2cf0635d
NC
22719 if (nested_arch.file != NULL)
22720 fclose (nested_arch.file);
22721 release_archive (&nested_arch);
22722 release_archive (&arch);
fb52b2f4 22723
d989285c 22724 return ret;
fb52b2f4
NC
22725}
22726
015dc7e1 22727static bool
2cf0635d 22728process_file (char * file_name)
fb52b2f4 22729{
dda8d76d 22730 Filedata * filedata = NULL;
fb52b2f4
NC
22731 struct stat statbuf;
22732 char armag[SARMAG];
015dc7e1 22733 bool ret = true;
fb52b2f4
NC
22734
22735 if (stat (file_name, &statbuf) < 0)
22736 {
f24ddbdd
NC
22737 if (errno == ENOENT)
22738 error (_("'%s': No such file\n"), file_name);
22739 else
22740 error (_("Could not locate '%s'. System error message: %s\n"),
22741 file_name, strerror (errno));
015dc7e1 22742 return false;
f24ddbdd
NC
22743 }
22744
22745 if (! S_ISREG (statbuf.st_mode))
22746 {
22747 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22748 return false;
fb52b2f4
NC
22749 }
22750
dda8d76d
NC
22751 filedata = calloc (1, sizeof * filedata);
22752 if (filedata == NULL)
22753 {
22754 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22755 return false;
dda8d76d
NC
22756 }
22757
22758 filedata->file_name = file_name;
22759 filedata->handle = fopen (file_name, "rb");
22760 if (filedata->handle == NULL)
fb52b2f4 22761 {
f24ddbdd 22762 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22763 free (filedata);
015dc7e1 22764 return false;
fb52b2f4
NC
22765 }
22766
dda8d76d 22767 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22768 {
4145f1d5 22769 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22770 fclose (filedata->handle);
22771 free (filedata);
015dc7e1 22772 return false;
fb52b2f4
NC
22773 }
22774
be7d229a 22775 filedata->file_size = statbuf.st_size;
015dc7e1 22776 filedata->is_separate = false;
f54498b4 22777
fb52b2f4 22778 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22779 {
015dc7e1
AM
22780 if (! process_archive (filedata, false))
22781 ret = false;
32ec8896 22782 }
2cf0635d 22783 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22784 {
015dc7e1
AM
22785 if ( ! process_archive (filedata, true))
22786 ret = false;
32ec8896 22787 }
fb52b2f4
NC
22788 else
22789 {
1b513401 22790 if (do_archive_index && !check_all)
4145f1d5
NC
22791 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22792 file_name);
22793
dda8d76d 22794 rewind (filedata->handle);
978c4450 22795 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22796
dda8d76d 22797 if (! process_object (filedata))
015dc7e1 22798 ret = false;
fb52b2f4
NC
22799 }
22800
dda8d76d 22801 fclose (filedata->handle);
8fb879cd
AM
22802 free (filedata->section_headers);
22803 free (filedata->program_headers);
22804 free (filedata->string_table);
6431e409 22805 free (filedata->dump.dump_sects);
dda8d76d 22806 free (filedata);
32ec8896 22807
fd486f32 22808 free (ba_cache.strtab);
1bd6175a 22809 ba_cache.strtab = NULL;
fd486f32 22810 free (ba_cache.symtab);
1bd6175a 22811 ba_cache.symtab = NULL;
fd486f32
AM
22812 ba_cache.filedata = NULL;
22813
fb52b2f4
NC
22814 return ret;
22815}
22816
252b5132
RH
22817#ifdef SUPPORT_DISASSEMBLY
22818/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22819 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22820 symbols. */
252b5132
RH
22821
22822void
2cf0635d 22823print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22824{
22825 fprintf (outfile,"0x%8.8x", addr);
22826}
22827
e3c8793a 22828/* Needed by the i386 disassembler. */
dda8d76d 22829
252b5132
RH
22830void
22831db_task_printsym (unsigned int addr)
22832{
22833 print_address (addr, stderr);
22834}
22835#endif
22836
22837int
2cf0635d 22838main (int argc, char ** argv)
252b5132 22839{
ff78d6d6
L
22840 int err;
22841
87b9f255 22842#ifdef HAVE_LC_MESSAGES
252b5132 22843 setlocale (LC_MESSAGES, "");
3882b010 22844#endif
3882b010 22845 setlocale (LC_CTYPE, "");
252b5132
RH
22846 bindtextdomain (PACKAGE, LOCALEDIR);
22847 textdomain (PACKAGE);
22848
869b9d07
MM
22849 expandargv (&argc, &argv);
22850
dda8d76d 22851 parse_args (& cmdline, argc, argv);
59f14fc0 22852
18bd398b 22853 if (optind < (argc - 1))
1b513401
NC
22854 /* When displaying information for more than one file,
22855 prefix the information with the file name. */
015dc7e1 22856 show_name = true;
5656ba2c
L
22857 else if (optind >= argc)
22858 {
1b513401 22859 /* Ensure that the warning is always displayed. */
015dc7e1 22860 do_checks = true;
1b513401 22861
5656ba2c
L
22862 warn (_("Nothing to do.\n"));
22863 usage (stderr);
22864 }
18bd398b 22865
015dc7e1 22866 err = false;
252b5132 22867 while (optind < argc)
32ec8896 22868 if (! process_file (argv[optind++]))
015dc7e1 22869 err = true;
252b5132 22870
9db70fc3 22871 free (cmdline.dump_sects);
252b5132 22872
7d9813f1
NA
22873 free (dump_ctf_symtab_name);
22874 free (dump_ctf_strtab_name);
22875 free (dump_ctf_parent_name);
22876
32ec8896 22877 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22878}