]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
gdb/unittests: PR28413, suppress warnings generated by Gnulib
[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}"));
61865e30
NC
9919 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9920 {
9921 unsigned int count = op & 0x07;
9922
9923 printf ("pop {D8");
9924 if (count)
9925 printf ("-D%d", 8 + count);
9926 printf ("}");
9927 }
9928 else if (op >= 0xc0 && op <= 0xc5)
9929 {
9930 unsigned int count = op & 0x07;
9931
9932 printf (" pop {wR10");
9933 if (count)
9934 printf ("-wR%d", 10 + count);
9935 printf ("}");
9936 }
9937 else if (op == 0xc6)
9938 {
9939 unsigned int first, last;
9940
9941 GET_OP (op2);
9942 first = op2 >> 4;
9943 last = op2 & 0x0f;
9944 printf ("pop {wR%d", first);
9945 if (last)
9946 printf ("-wR%d", first + last);
9947 printf ("}");
9948 }
9949 else if (op == 0xc7)
9950 {
9951 GET_OP (op2);
9952 if (op2 == 0 || (op2 & 0xf0) != 0)
9953 printf (_("[Spare]"));
0b6ae522
DJ
9954 else
9955 {
61865e30 9956 unsigned int mask = op2 & 0x0f;
015dc7e1 9957 bool first = true;
61865e30
NC
9958 int i;
9959
9960 printf ("pop {");
9961 for (i = 0; i < 4; i++)
9962 if (mask & (1 << i))
9963 {
9964 if (first)
015dc7e1 9965 first = false;
61865e30
NC
9966 else
9967 printf (", ");
9968 printf ("wCGR%d", i);
9969 }
9970 printf ("}");
0b6ae522
DJ
9971 }
9972 }
61865e30 9973 else
32ec8896
NC
9974 {
9975 printf (_(" [unsupported opcode]"));
015dc7e1 9976 res = false;
32ec8896
NC
9977 }
9978
0b6ae522
DJ
9979 printf ("\n");
9980 }
32ec8896
NC
9981
9982 return res;
fa197c1c
PB
9983}
9984
015dc7e1 9985static bool
dda8d76d
NC
9986decode_tic6x_unwind_bytecode (Filedata * filedata,
9987 struct arm_unw_aux_info * aux,
948f632f
DA
9988 unsigned int word,
9989 unsigned int remaining,
9990 unsigned int more_words,
625d49fc 9991 uint64_t data_offset,
948f632f
DA
9992 Elf_Internal_Shdr * data_sec,
9993 struct arm_section * data_arm_sec)
fa197c1c
PB
9994{
9995 struct absaddr addr;
9996
9997 /* Decode the unwinding instructions. */
9998 while (1)
9999 {
10000 unsigned int op, op2;
10001
10002 ADVANCE;
10003 if (remaining == 0)
10004 break;
10005 remaining--;
10006 op = word >> 24;
10007 word <<= 8;
10008
9cf03b7e 10009 printf (" 0x%02x ", op);
fa197c1c
PB
10010
10011 if ((op & 0xc0) == 0x00)
10012 {
10013 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10014 printf (" sp = sp + %d", offset);
fa197c1c
PB
10015 }
10016 else if ((op & 0xc0) == 0x80)
10017 {
10018 GET_OP (op2);
10019 if (op == 0x80 && op2 == 0)
10020 printf (_("Refuse to unwind"));
10021 else
10022 {
10023 unsigned int mask = ((op & 0x1f) << 8) | op2;
10024 if (op & 0x20)
10025 printf ("pop compact {");
10026 else
10027 printf ("pop {");
10028
10029 decode_tic6x_unwind_regmask (mask);
10030 printf("}");
10031 }
10032 }
10033 else if ((op & 0xf0) == 0xc0)
10034 {
10035 unsigned int reg;
10036 unsigned int nregs;
10037 unsigned int i;
10038 const char *name;
a734115a
NC
10039 struct
10040 {
32ec8896
NC
10041 unsigned int offset;
10042 unsigned int reg;
fa197c1c
PB
10043 } regpos[16];
10044
10045 /* Scan entire instruction first so that GET_OP output is not
10046 interleaved with disassembly. */
10047 nregs = 0;
10048 for (i = 0; nregs < (op & 0xf); i++)
10049 {
10050 GET_OP (op2);
10051 reg = op2 >> 4;
10052 if (reg != 0xf)
10053 {
10054 regpos[nregs].offset = i * 2;
10055 regpos[nregs].reg = reg;
10056 nregs++;
10057 }
10058
10059 reg = op2 & 0xf;
10060 if (reg != 0xf)
10061 {
10062 regpos[nregs].offset = i * 2 + 1;
10063 regpos[nregs].reg = reg;
10064 nregs++;
10065 }
10066 }
10067
10068 printf (_("pop frame {"));
18344509 10069 if (nregs == 0)
fa197c1c 10070 {
18344509
NC
10071 printf (_("*corrupt* - no registers specified"));
10072 }
10073 else
10074 {
10075 reg = nregs - 1;
10076 for (i = i * 2; i > 0; i--)
fa197c1c 10077 {
18344509
NC
10078 if (regpos[reg].offset == i - 1)
10079 {
10080 name = tic6x_unwind_regnames[regpos[reg].reg];
10081 if (reg > 0)
10082 reg--;
10083 }
10084 else
10085 name = _("[pad]");
fa197c1c 10086
18344509
NC
10087 fputs (name, stdout);
10088 if (i > 1)
10089 printf (", ");
10090 }
fa197c1c
PB
10091 }
10092
10093 printf ("}");
10094 }
10095 else if (op == 0xd0)
10096 printf (" MOV FP, SP");
10097 else if (op == 0xd1)
10098 printf (" __c6xabi_pop_rts");
10099 else if (op == 0xd2)
10100 {
10101 unsigned char buf[9];
10102 unsigned int i, len;
10103 unsigned long offset;
a734115a 10104
fa197c1c
PB
10105 for (i = 0; i < sizeof (buf); i++)
10106 {
10107 GET_OP (buf[i]);
10108 if ((buf[i] & 0x80) == 0)
10109 break;
10110 }
0eff7165
NC
10111 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10112 if (i == sizeof (buf))
10113 {
0eff7165 10114 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10115 return false;
0eff7165 10116 }
948f632f 10117
015dc7e1 10118 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10119 assert (len == i + 1);
10120 offset = offset * 8 + 0x408;
10121 printf (_("sp = sp + %ld"), offset);
10122 }
10123 else if ((op & 0xf0) == 0xe0)
10124 {
10125 if ((op & 0x0f) == 7)
10126 printf (" RETURN");
10127 else
10128 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10129 }
10130 else
10131 {
10132 printf (_(" [unsupported opcode]"));
10133 }
10134 putchar ('\n');
10135 }
32ec8896 10136
015dc7e1 10137 return true;
fa197c1c
PB
10138}
10139
625d49fc
AM
10140static uint64_t
10141arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10142{
625d49fc 10143 uint64_t offset;
fa197c1c
PB
10144
10145 offset = word & 0x7fffffff;
10146 if (offset & 0x40000000)
625d49fc 10147 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10148
dda8d76d 10149 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10150 offset <<= 1;
10151
10152 return offset + where;
10153}
10154
015dc7e1 10155static bool
dda8d76d
NC
10156decode_arm_unwind (Filedata * filedata,
10157 struct arm_unw_aux_info * aux,
1b31d05e
NC
10158 unsigned int word,
10159 unsigned int remaining,
625d49fc 10160 uint64_t data_offset,
1b31d05e
NC
10161 Elf_Internal_Shdr * data_sec,
10162 struct arm_section * data_arm_sec)
fa197c1c
PB
10163{
10164 int per_index;
10165 unsigned int more_words = 0;
37e14bc3 10166 struct absaddr addr;
625d49fc 10167 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10168 bool res = true;
fa197c1c
PB
10169
10170 if (remaining == 0)
10171 {
1b31d05e
NC
10172 /* Fetch the first word.
10173 Note - when decoding an object file the address extracted
10174 here will always be 0. So we also pass in the sym_name
10175 parameter so that we can find the symbol associated with
10176 the personality routine. */
dda8d76d 10177 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10178 & word, & addr, & sym_name))
015dc7e1 10179 return false;
1b31d05e 10180
fa197c1c
PB
10181 remaining = 4;
10182 }
c93dbb25
CZ
10183 else
10184 {
10185 addr.section = SHN_UNDEF;
10186 addr.offset = 0;
10187 }
fa197c1c
PB
10188
10189 if ((word & 0x80000000) == 0)
10190 {
10191 /* Expand prel31 for personality routine. */
625d49fc 10192 uint64_t fn;
fa197c1c
PB
10193 const char *procname;
10194
dda8d76d 10195 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10196 printf (_(" Personality routine: "));
1b31d05e
NC
10197 if (fn == 0
10198 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10199 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10200 {
10201 procname = aux->strtab + sym_name;
10202 print_vma (fn, PREFIX_HEX);
10203 if (procname)
10204 {
10205 fputs (" <", stdout);
10206 fputs (procname, stdout);
10207 fputc ('>', stdout);
10208 }
10209 }
10210 else
dda8d76d 10211 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10212 fputc ('\n', stdout);
10213
10214 /* The GCC personality routines use the standard compact
10215 encoding, starting with one byte giving the number of
10216 words. */
10217 if (procname != NULL
24d127aa
ML
10218 && (startswith (procname, "__gcc_personality_v0")
10219 || startswith (procname, "__gxx_personality_v0")
10220 || startswith (procname, "__gcj_personality_v0")
10221 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10222 {
10223 remaining = 0;
10224 more_words = 1;
10225 ADVANCE;
10226 if (!remaining)
10227 {
10228 printf (_(" [Truncated data]\n"));
015dc7e1 10229 return false;
fa197c1c
PB
10230 }
10231 more_words = word >> 24;
10232 word <<= 8;
10233 remaining--;
10234 per_index = -1;
10235 }
10236 else
015dc7e1 10237 return true;
fa197c1c
PB
10238 }
10239 else
10240 {
1b31d05e 10241 /* ARM EHABI Section 6.3:
0b4362b0 10242
1b31d05e 10243 An exception-handling table entry for the compact model looks like:
0b4362b0 10244
1b31d05e
NC
10245 31 30-28 27-24 23-0
10246 -- ----- ----- ----
10247 1 0 index Data for personalityRoutine[index] */
10248
dda8d76d 10249 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10250 && (word & 0x70000000))
32ec8896
NC
10251 {
10252 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10253 res = false;
32ec8896 10254 }
1b31d05e 10255
fa197c1c 10256 per_index = (word >> 24) & 0x7f;
1b31d05e 10257 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10258 if (per_index == 0)
10259 {
10260 more_words = 0;
10261 word <<= 8;
10262 remaining--;
10263 }
10264 else if (per_index < 3)
10265 {
10266 more_words = (word >> 16) & 0xff;
10267 word <<= 16;
10268 remaining -= 2;
10269 }
10270 }
10271
dda8d76d 10272 switch (filedata->file_header.e_machine)
fa197c1c
PB
10273 {
10274 case EM_ARM:
10275 if (per_index < 3)
10276 {
dda8d76d 10277 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10278 data_offset, data_sec, data_arm_sec))
015dc7e1 10279 res = false;
fa197c1c
PB
10280 }
10281 else
1b31d05e
NC
10282 {
10283 warn (_("Unknown ARM compact model index encountered\n"));
10284 printf (_(" [reserved]\n"));
015dc7e1 10285 res = false;
1b31d05e 10286 }
fa197c1c
PB
10287 break;
10288
10289 case EM_TI_C6000:
10290 if (per_index < 3)
10291 {
dda8d76d 10292 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10293 data_offset, data_sec, data_arm_sec))
015dc7e1 10294 res = false;
fa197c1c
PB
10295 }
10296 else if (per_index < 5)
10297 {
10298 if (((word >> 17) & 0x7f) == 0x7f)
10299 printf (_(" Restore stack from frame pointer\n"));
10300 else
10301 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10302 printf (_(" Registers restored: "));
10303 if (per_index == 4)
10304 printf (" (compact) ");
10305 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10306 putchar ('\n');
10307 printf (_(" Return register: %s\n"),
10308 tic6x_unwind_regnames[word & 0xf]);
10309 }
10310 else
1b31d05e 10311 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10312 break;
10313
10314 default:
74e1a04b 10315 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10316 filedata->file_header.e_machine);
015dc7e1 10317 res = false;
fa197c1c 10318 }
0b6ae522
DJ
10319
10320 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10321
10322 return res;
0b6ae522
DJ
10323}
10324
015dc7e1 10325static bool
dda8d76d
NC
10326dump_arm_unwind (Filedata * filedata,
10327 struct arm_unw_aux_info * aux,
10328 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10329{
10330 struct arm_section exidx_arm_sec, extab_arm_sec;
10331 unsigned int i, exidx_len;
948f632f 10332 unsigned long j, nfuns;
015dc7e1 10333 bool res = true;
0b6ae522
DJ
10334
10335 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10336 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10337 exidx_len = exidx_sec->sh_size / 8;
10338
948f632f
DA
10339 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10340 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10341 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10342 aux->funtab[nfuns++] = aux->symtab[j];
10343 aux->nfuns = nfuns;
10344 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10345
0b6ae522
DJ
10346 for (i = 0; i < exidx_len; i++)
10347 {
10348 unsigned int exidx_fn, exidx_entry;
10349 struct absaddr fn_addr, entry_addr;
625d49fc 10350 uint64_t fn;
0b6ae522
DJ
10351
10352 fputc ('\n', stdout);
10353
dda8d76d 10354 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10355 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10356 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10357 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10358 {
948f632f 10359 free (aux->funtab);
1b31d05e
NC
10360 arm_free_section (& exidx_arm_sec);
10361 arm_free_section (& extab_arm_sec);
015dc7e1 10362 return false;
0b6ae522
DJ
10363 }
10364
83c257ca
NC
10365 /* ARM EHABI, Section 5:
10366 An index table entry consists of 2 words.
10367 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10368 if (exidx_fn & 0x80000000)
32ec8896
NC
10369 {
10370 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10371 res = false;
32ec8896 10372 }
83c257ca 10373
dda8d76d 10374 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10375
dda8d76d 10376 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10377 fputs (": ", stdout);
10378
10379 if (exidx_entry == 1)
10380 {
10381 print_vma (exidx_entry, PREFIX_HEX);
10382 fputs (" [cantunwind]\n", stdout);
10383 }
10384 else if (exidx_entry & 0x80000000)
10385 {
10386 print_vma (exidx_entry, PREFIX_HEX);
10387 fputc ('\n', stdout);
dda8d76d 10388 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10389 }
10390 else
10391 {
625d49fc 10392 uint64_t table, table_offset = 0;
0b6ae522
DJ
10393 Elf_Internal_Shdr *table_sec;
10394
10395 fputs ("@", stdout);
dda8d76d 10396 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10397 print_vma (table, PREFIX_HEX);
10398 printf ("\n");
10399
10400 /* Locate the matching .ARM.extab. */
10401 if (entry_addr.section != SHN_UNDEF
dda8d76d 10402 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10403 {
dda8d76d 10404 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10405 table_offset = entry_addr.offset;
1a915552 10406 /* PR 18879 */
625d49fc 10407 if (table_offset > table_sec->sh_size)
1a915552
NC
10408 {
10409 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
10410 (unsigned long) table_offset,
dda8d76d 10411 printable_section_name (filedata, table_sec));
015dc7e1 10412 res = false;
1a915552
NC
10413 continue;
10414 }
0b6ae522
DJ
10415 }
10416 else
10417 {
dda8d76d 10418 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10419 if (table_sec != NULL)
10420 table_offset = table - table_sec->sh_addr;
10421 }
32ec8896 10422
0b6ae522
DJ
10423 if (table_sec == NULL)
10424 {
10425 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
10426 (unsigned long) table);
015dc7e1 10427 res = false;
0b6ae522
DJ
10428 continue;
10429 }
32ec8896 10430
dda8d76d 10431 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10432 &extab_arm_sec))
015dc7e1 10433 res = false;
0b6ae522
DJ
10434 }
10435 }
10436
10437 printf ("\n");
10438
948f632f 10439 free (aux->funtab);
0b6ae522
DJ
10440 arm_free_section (&exidx_arm_sec);
10441 arm_free_section (&extab_arm_sec);
32ec8896
NC
10442
10443 return res;
0b6ae522
DJ
10444}
10445
fa197c1c 10446/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10447
015dc7e1 10448static bool
dda8d76d 10449arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10450{
10451 struct arm_unw_aux_info aux;
10452 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
10453 Elf_Internal_Shdr *sec;
10454 unsigned long i;
fa197c1c 10455 unsigned int sec_type;
015dc7e1 10456 bool res = true;
0b6ae522 10457
dda8d76d 10458 switch (filedata->file_header.e_machine)
fa197c1c
PB
10459 {
10460 case EM_ARM:
10461 sec_type = SHT_ARM_EXIDX;
10462 break;
10463
10464 case EM_TI_C6000:
10465 sec_type = SHT_C6000_UNWIND;
10466 break;
10467
0b4362b0 10468 default:
74e1a04b 10469 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10470 filedata->file_header.e_machine);
015dc7e1 10471 return false;
fa197c1c
PB
10472 }
10473
dda8d76d 10474 if (filedata->string_table == NULL)
015dc7e1 10475 return false;
1b31d05e
NC
10476
10477 memset (& aux, 0, sizeof (aux));
dda8d76d 10478 aux.filedata = filedata;
0b6ae522 10479
dda8d76d 10480 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10481 {
28d13567 10482 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10483 {
28d13567 10484 if (aux.symtab)
74e1a04b 10485 {
28d13567
AM
10486 error (_("Multiple symbol tables encountered\n"));
10487 free (aux.symtab);
10488 aux.symtab = NULL;
74e1a04b 10489 free (aux.strtab);
28d13567 10490 aux.strtab = NULL;
74e1a04b 10491 }
28d13567
AM
10492 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10493 &aux.strtab, &aux.strtab_size))
015dc7e1 10494 return false;
0b6ae522 10495 }
fa197c1c 10496 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10497 unwsec = sec;
10498 }
10499
1b31d05e 10500 if (unwsec == NULL)
0b6ae522 10501 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10502 else
dda8d76d 10503 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10504 {
10505 if (sec->sh_type == sec_type)
10506 {
d3a49aa8
AM
10507 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
10508 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
10509 "contains %lu entry:\n",
10510 "\nUnwind section '%s' at offset 0x%lx "
10511 "contains %lu entries:\n",
10512 num_unwind),
dda8d76d 10513 printable_section_name (filedata, sec),
1b31d05e 10514 (unsigned long) sec->sh_offset,
d3a49aa8 10515 num_unwind);
0b6ae522 10516
dda8d76d 10517 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10518 res = false;
1b31d05e
NC
10519 }
10520 }
0b6ae522 10521
9db70fc3
AM
10522 free (aux.symtab);
10523 free ((char *) aux.strtab);
32ec8896
NC
10524
10525 return res;
0b6ae522
DJ
10526}
10527
3ecc00ec
NC
10528static bool
10529no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10530{
10531 printf (_("No processor specific unwind information to decode\n"));
10532 return true;
10533}
10534
015dc7e1 10535static bool
dda8d76d 10536process_unwind (Filedata * filedata)
57346661 10537{
2cf0635d
NC
10538 struct unwind_handler
10539 {
32ec8896 10540 unsigned int machtype;
015dc7e1 10541 bool (* handler)(Filedata *);
2cf0635d
NC
10542 } handlers[] =
10543 {
0b6ae522 10544 { EM_ARM, arm_process_unwind },
57346661
AM
10545 { EM_IA_64, ia64_process_unwind },
10546 { EM_PARISC, hppa_process_unwind },
fa197c1c 10547 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10548 { EM_386, no_processor_specific_unwind },
10549 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10550 { 0, NULL }
57346661
AM
10551 };
10552 int i;
10553
10554 if (!do_unwind)
015dc7e1 10555 return true;
57346661
AM
10556
10557 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10558 if (filedata->file_header.e_machine == handlers[i].machtype)
10559 return handlers[i].handler (filedata);
57346661 10560
1b31d05e 10561 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10562 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10563 return true;
57346661
AM
10564}
10565
37c18eed
SD
10566static void
10567dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10568{
10569 switch (entry->d_tag)
10570 {
10571 case DT_AARCH64_BTI_PLT:
1dbade74 10572 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10573 break;
10574 default:
10575 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10576 break;
10577 }
10578 putchar ('\n');
10579}
10580
252b5132 10581static void
978c4450 10582dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10583{
10584 switch (entry->d_tag)
10585 {
10586 case DT_MIPS_FLAGS:
10587 if (entry->d_un.d_val == 0)
4b68bca3 10588 printf (_("NONE"));
252b5132
RH
10589 else
10590 {
10591 static const char * opts[] =
10592 {
10593 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10594 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10595 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10596 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10597 "RLD_ORDER_SAFE"
10598 };
10599 unsigned int cnt;
015dc7e1 10600 bool first = true;
2b692964 10601
60bca95a 10602 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10603 if (entry->d_un.d_val & (1 << cnt))
10604 {
10605 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10606 first = false;
252b5132 10607 }
252b5132
RH
10608 }
10609 break;
103f02d3 10610
252b5132 10611 case DT_MIPS_IVERSION:
84714f86 10612 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10613 printf (_("Interface Version: %s"),
84714f86 10614 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10615 else
f493c217 10616 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 10617 entry->d_un.d_ptr);
252b5132 10618 break;
103f02d3 10619
252b5132
RH
10620 case DT_MIPS_TIME_STAMP:
10621 {
d5b07ef4 10622 char timebuf[128];
2cf0635d 10623 struct tm * tmp;
91d6fa6a 10624 time_t atime = entry->d_un.d_val;
82b1b41b 10625
91d6fa6a 10626 tmp = gmtime (&atime);
82b1b41b
NC
10627 /* PR 17531: file: 6accc532. */
10628 if (tmp == NULL)
10629 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10630 else
10631 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10632 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10633 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10634 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10635 }
10636 break;
103f02d3 10637
252b5132
RH
10638 case DT_MIPS_RLD_VERSION:
10639 case DT_MIPS_LOCAL_GOTNO:
10640 case DT_MIPS_CONFLICTNO:
10641 case DT_MIPS_LIBLISTNO:
10642 case DT_MIPS_SYMTABNO:
10643 case DT_MIPS_UNREFEXTNO:
10644 case DT_MIPS_HIPAGENO:
10645 case DT_MIPS_DELTA_CLASS_NO:
10646 case DT_MIPS_DELTA_INSTANCE_NO:
10647 case DT_MIPS_DELTA_RELOC_NO:
10648 case DT_MIPS_DELTA_SYM_NO:
10649 case DT_MIPS_DELTA_CLASSSYM_NO:
10650 case DT_MIPS_COMPACT_SIZE:
c69075ac 10651 print_vma (entry->d_un.d_val, DEC);
252b5132 10652 break;
103f02d3 10653
f16a9783 10654 case DT_MIPS_XHASH:
978c4450
AM
10655 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10656 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10657 /* Falls through. */
10658
103f02d3 10659 default:
4b68bca3 10660 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10661 }
4b68bca3 10662 putchar ('\n');
103f02d3
UD
10663}
10664
103f02d3 10665static void
2cf0635d 10666dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10667{
10668 switch (entry->d_tag)
10669 {
10670 case DT_HP_DLD_FLAGS:
10671 {
10672 static struct
10673 {
10674 long int bit;
2cf0635d 10675 const char * str;
5e220199
NC
10676 }
10677 flags[] =
10678 {
10679 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10680 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10681 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10682 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10683 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10684 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10685 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10686 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10687 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10688 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10689 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10690 { DT_HP_GST, "HP_GST" },
10691 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10692 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10693 { DT_HP_NODELETE, "HP_NODELETE" },
10694 { DT_HP_GROUP, "HP_GROUP" },
10695 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10696 };
015dc7e1 10697 bool first = true;
5e220199 10698 size_t cnt;
625d49fc 10699 uint64_t val = entry->d_un.d_val;
103f02d3 10700
60bca95a 10701 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10702 if (val & flags[cnt].bit)
30800947
NC
10703 {
10704 if (! first)
10705 putchar (' ');
10706 fputs (flags[cnt].str, stdout);
015dc7e1 10707 first = false;
30800947
NC
10708 val ^= flags[cnt].bit;
10709 }
76da6bbe 10710
103f02d3 10711 if (val != 0 || first)
f7a99963
NC
10712 {
10713 if (! first)
10714 putchar (' ');
10715 print_vma (val, HEX);
10716 }
103f02d3
UD
10717 }
10718 break;
76da6bbe 10719
252b5132 10720 default:
f7a99963
NC
10721 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10722 break;
252b5132 10723 }
35b1837e 10724 putchar ('\n');
252b5132
RH
10725}
10726
28f997cf
TG
10727/* VMS vs Unix time offset and factor. */
10728
10729#define VMS_EPOCH_OFFSET 35067168000000000LL
10730#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10731#ifndef INT64_MIN
10732#define INT64_MIN (-9223372036854775807LL - 1)
10733#endif
28f997cf
TG
10734
10735/* Display a VMS time in a human readable format. */
10736
10737static void
0e3c1eeb 10738print_vms_time (int64_t vmstime)
28f997cf 10739{
dccc31de 10740 struct tm *tm = NULL;
28f997cf
TG
10741 time_t unxtime;
10742
dccc31de
AM
10743 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10744 {
10745 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10746 unxtime = vmstime;
10747 if (unxtime == vmstime)
10748 tm = gmtime (&unxtime);
10749 }
10750 if (tm != NULL)
10751 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10752 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10753 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 10754}
28f997cf 10755
ecc51f48 10756static void
2cf0635d 10757dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10758{
10759 switch (entry->d_tag)
10760 {
0de14b54 10761 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10762 /* First 3 slots reserved. */
ecc51f48
NC
10763 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10764 printf (" -- ");
10765 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10766 break;
10767
28f997cf 10768 case DT_IA_64_VMS_LINKTIME:
28f997cf 10769 print_vms_time (entry->d_un.d_val);
28f997cf
TG
10770 break;
10771
10772 case DT_IA_64_VMS_LNKFLAGS:
10773 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10774 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10775 printf (" CALL_DEBUG");
10776 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10777 printf (" NOP0BUFS");
10778 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10779 printf (" P0IMAGE");
10780 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10781 printf (" MKTHREADS");
10782 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10783 printf (" UPCALLS");
10784 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10785 printf (" IMGSTA");
10786 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10787 printf (" INITIALIZE");
10788 if (entry->d_un.d_val & VMS_LF_MAIN)
10789 printf (" MAIN");
10790 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10791 printf (" EXE_INIT");
10792 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10793 printf (" TBK_IN_IMG");
10794 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10795 printf (" DBG_IN_IMG");
10796 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10797 printf (" TBK_IN_DSF");
10798 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10799 printf (" DBG_IN_DSF");
10800 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10801 printf (" SIGNATURES");
10802 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10803 printf (" REL_SEG_OFF");
10804 break;
10805
bdf4d63a
JJ
10806 default:
10807 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10808 break;
ecc51f48 10809 }
bdf4d63a 10810 putchar ('\n');
ecc51f48
NC
10811}
10812
015dc7e1 10813static bool
dda8d76d 10814get_32bit_dynamic_section (Filedata * filedata)
252b5132 10815{
2cf0635d
NC
10816 Elf32_External_Dyn * edyn;
10817 Elf32_External_Dyn * ext;
10818 Elf_Internal_Dyn * entry;
103f02d3 10819
978c4450
AM
10820 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10821 filedata->dynamic_addr, 1,
10822 filedata->dynamic_size,
10823 _("dynamic section"));
a6e9f9df 10824 if (!edyn)
015dc7e1 10825 return false;
103f02d3 10826
071436c6
NC
10827 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10828 might not have the luxury of section headers. Look for the DT_NULL
10829 terminator to determine the number of entries. */
978c4450
AM
10830 for (ext = edyn, filedata->dynamic_nent = 0;
10831 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10832 ext++)
10833 {
978c4450 10834 filedata->dynamic_nent++;
ba2685cc
AM
10835 if (BYTE_GET (ext->d_tag) == DT_NULL)
10836 break;
10837 }
252b5132 10838
978c4450
AM
10839 filedata->dynamic_section
10840 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10841 if (filedata->dynamic_section == NULL)
252b5132 10842 {
8b73c356 10843 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10844 (unsigned long) filedata->dynamic_nent);
9ea033b2 10845 free (edyn);
015dc7e1 10846 return false;
9ea033b2 10847 }
252b5132 10848
978c4450
AM
10849 for (ext = edyn, entry = filedata->dynamic_section;
10850 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10851 ext++, entry++)
9ea033b2 10852 {
fb514b26
AM
10853 entry->d_tag = BYTE_GET (ext->d_tag);
10854 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10855 }
10856
9ea033b2
NC
10857 free (edyn);
10858
015dc7e1 10859 return true;
9ea033b2
NC
10860}
10861
015dc7e1 10862static bool
dda8d76d 10863get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10864{
2cf0635d
NC
10865 Elf64_External_Dyn * edyn;
10866 Elf64_External_Dyn * ext;
10867 Elf_Internal_Dyn * entry;
103f02d3 10868
071436c6 10869 /* Read in the data. */
978c4450
AM
10870 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10871 filedata->dynamic_addr, 1,
10872 filedata->dynamic_size,
10873 _("dynamic section"));
a6e9f9df 10874 if (!edyn)
015dc7e1 10875 return false;
103f02d3 10876
071436c6
NC
10877 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10878 might not have the luxury of section headers. Look for the DT_NULL
10879 terminator to determine the number of entries. */
978c4450 10880 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10881 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10882 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10883 ext++)
10884 {
978c4450 10885 filedata->dynamic_nent++;
66543521 10886 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10887 break;
10888 }
252b5132 10889
978c4450
AM
10890 filedata->dynamic_section
10891 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10892 if (filedata->dynamic_section == NULL)
252b5132 10893 {
8b73c356 10894 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10895 (unsigned long) filedata->dynamic_nent);
252b5132 10896 free (edyn);
015dc7e1 10897 return false;
252b5132
RH
10898 }
10899
071436c6 10900 /* Convert from external to internal formats. */
978c4450
AM
10901 for (ext = edyn, entry = filedata->dynamic_section;
10902 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10903 ext++, entry++)
252b5132 10904 {
66543521
AM
10905 entry->d_tag = BYTE_GET (ext->d_tag);
10906 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10907 }
10908
10909 free (edyn);
10910
015dc7e1 10911 return true;
9ea033b2
NC
10912}
10913
4de91c10
AM
10914static bool
10915get_dynamic_section (Filedata *filedata)
10916{
10917 if (filedata->dynamic_section)
10918 return true;
10919
10920 if (is_32bit_elf)
10921 return get_32bit_dynamic_section (filedata);
10922 else
10923 return get_64bit_dynamic_section (filedata);
10924}
10925
e9e44622 10926static void
625d49fc 10927print_dynamic_flags (uint64_t flags)
d1133906 10928{
015dc7e1 10929 bool first = true;
13ae64f3 10930
d1133906
NC
10931 while (flags)
10932 {
625d49fc 10933 uint64_t flag;
d1133906
NC
10934
10935 flag = flags & - flags;
10936 flags &= ~ flag;
10937
e9e44622 10938 if (first)
015dc7e1 10939 first = false;
e9e44622
JJ
10940 else
10941 putc (' ', stdout);
13ae64f3 10942
d1133906
NC
10943 switch (flag)
10944 {
e9e44622
JJ
10945 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10946 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10947 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10948 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10949 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10950 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10951 }
10952 }
e9e44622 10953 puts ("");
d1133906
NC
10954}
10955
625d49fc 10956static uint64_t *
be7d229a 10957get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
10958{
10959 unsigned char * e_data;
625d49fc 10960 uint64_t * i_data;
10ca4b04 10961
be7d229a
AM
10962 /* If size_t is smaller than uint64_t, eg because you are building
10963 on a 32-bit host, then make sure that when number is cast to
10964 size_t no information is lost. */
10965 if ((size_t) number != number
10966 || ent_size * number / ent_size != number)
10ca4b04 10967 {
be7d229a 10968 error (_("Size overflow prevents reading %" PRIu64
b8281767 10969 " elements of size %u\n"),
be7d229a 10970 number, ent_size);
10ca4b04
L
10971 return NULL;
10972 }
10973
10974 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10975 attempting to allocate memory when the read is bound to fail. */
10976 if (ent_size * number > filedata->file_size)
10977 {
b8281767 10978 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 10979 number);
10ca4b04
L
10980 return NULL;
10981 }
10982
10983 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10984 if (e_data == NULL)
10985 {
b8281767 10986 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 10987 number);
10ca4b04
L
10988 return NULL;
10989 }
10990
10991 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10992 {
b8281767 10993 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 10994 number * ent_size);
10ca4b04
L
10995 free (e_data);
10996 return NULL;
10997 }
10998
625d49fc 10999 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
11000 if (i_data == NULL)
11001 {
b8281767 11002 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 11003 number);
10ca4b04
L
11004 free (e_data);
11005 return NULL;
11006 }
11007
11008 while (number--)
11009 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11010
11011 free (e_data);
11012
11013 return i_data;
11014}
11015
11016static unsigned long
11017get_num_dynamic_syms (Filedata * filedata)
11018{
11019 unsigned long num_of_syms = 0;
11020
11021 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11022 return num_of_syms;
11023
978c4450 11024 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11025 {
11026 unsigned char nb[8];
11027 unsigned char nc[8];
11028 unsigned int hash_ent_size = 4;
11029
11030 if ((filedata->file_header.e_machine == EM_ALPHA
11031 || filedata->file_header.e_machine == EM_S390
11032 || filedata->file_header.e_machine == EM_S390_OLD)
11033 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11034 hash_ent_size = 8;
11035
11036 if (fseek (filedata->handle,
978c4450
AM
11037 (filedata->archive_file_offset
11038 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
11039 sizeof nb + sizeof nc)),
11040 SEEK_SET))
11041 {
11042 error (_("Unable to seek to start of dynamic information\n"));
11043 goto no_hash;
11044 }
11045
11046 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11047 {
11048 error (_("Failed to read in number of buckets\n"));
11049 goto no_hash;
11050 }
11051
11052 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11053 {
11054 error (_("Failed to read in number of chains\n"));
11055 goto no_hash;
11056 }
11057
978c4450
AM
11058 filedata->nbuckets = byte_get (nb, hash_ent_size);
11059 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11060
2482f306
AM
11061 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11062 {
11063 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11064 hash_ent_size);
11065 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11066 hash_ent_size);
001890e1 11067
2482f306
AM
11068 if (filedata->buckets != NULL && filedata->chains != NULL)
11069 num_of_syms = filedata->nchains;
11070 }
ceb9bf11 11071 no_hash:
10ca4b04
L
11072 if (num_of_syms == 0)
11073 {
9db70fc3
AM
11074 free (filedata->buckets);
11075 filedata->buckets = NULL;
11076 free (filedata->chains);
11077 filedata->chains = NULL;
978c4450 11078 filedata->nbuckets = 0;
10ca4b04
L
11079 }
11080 }
11081
978c4450 11082 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11083 {
11084 unsigned char nb[16];
625d49fc
AM
11085 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11086 uint64_t buckets_vma;
10ca4b04 11087 unsigned long hn;
10ca4b04
L
11088
11089 if (fseek (filedata->handle,
978c4450
AM
11090 (filedata->archive_file_offset
11091 + offset_from_vma (filedata,
11092 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
11093 sizeof nb)),
11094 SEEK_SET))
11095 {
11096 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11097 goto no_gnu_hash;
11098 }
11099
11100 if (fread (nb, 16, 1, filedata->handle) != 1)
11101 {
11102 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11103 goto no_gnu_hash;
11104 }
11105
978c4450
AM
11106 filedata->ngnubuckets = byte_get (nb, 4);
11107 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11108 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11109 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11110 if (is_32bit_elf)
11111 buckets_vma += bitmaskwords * 4;
11112 else
11113 buckets_vma += bitmaskwords * 8;
11114
11115 if (fseek (filedata->handle,
978c4450 11116 (filedata->archive_file_offset
10ca4b04
L
11117 + offset_from_vma (filedata, buckets_vma, 4)),
11118 SEEK_SET))
11119 {
11120 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11121 goto no_gnu_hash;
11122 }
11123
978c4450
AM
11124 filedata->gnubuckets
11125 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11126
978c4450 11127 if (filedata->gnubuckets == NULL)
90837ea7 11128 goto no_gnu_hash;
10ca4b04 11129
978c4450
AM
11130 for (i = 0; i < filedata->ngnubuckets; i++)
11131 if (filedata->gnubuckets[i] != 0)
10ca4b04 11132 {
978c4450 11133 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11134 goto no_gnu_hash;
10ca4b04 11135
978c4450
AM
11136 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11137 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11138 }
11139
11140 if (maxchain == 0xffffffff)
90837ea7 11141 goto no_gnu_hash;
10ca4b04 11142
978c4450 11143 maxchain -= filedata->gnusymidx;
10ca4b04
L
11144
11145 if (fseek (filedata->handle,
978c4450
AM
11146 (filedata->archive_file_offset
11147 + offset_from_vma (filedata,
11148 buckets_vma + 4 * (filedata->ngnubuckets
11149 + maxchain),
11150 4)),
10ca4b04
L
11151 SEEK_SET))
11152 {
11153 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11154 goto no_gnu_hash;
11155 }
11156
11157 do
11158 {
11159 if (fread (nb, 4, 1, filedata->handle) != 1)
11160 {
11161 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11162 goto no_gnu_hash;
11163 }
11164
11165 if (maxchain + 1 == 0)
90837ea7 11166 goto no_gnu_hash;
10ca4b04
L
11167
11168 ++maxchain;
11169 }
11170 while ((byte_get (nb, 4) & 1) == 0);
11171
11172 if (fseek (filedata->handle,
978c4450
AM
11173 (filedata->archive_file_offset
11174 + offset_from_vma (filedata, (buckets_vma
11175 + 4 * filedata->ngnubuckets),
11176 4)),
10ca4b04
L
11177 SEEK_SET))
11178 {
11179 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11180 goto no_gnu_hash;
11181 }
11182
978c4450
AM
11183 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11184 filedata->ngnuchains = maxchain;
10ca4b04 11185
978c4450 11186 if (filedata->gnuchains == NULL)
90837ea7 11187 goto no_gnu_hash;
10ca4b04 11188
978c4450 11189 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
11190 {
11191 if (fseek (filedata->handle,
978c4450 11192 (filedata->archive_file_offset
10ca4b04 11193 + offset_from_vma (filedata, (buckets_vma
978c4450 11194 + 4 * (filedata->ngnubuckets
10ca4b04
L
11195 + maxchain)), 4)),
11196 SEEK_SET))
11197 {
11198 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11199 goto no_gnu_hash;
11200 }
11201
978c4450 11202 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11203 if (filedata->mipsxlat == NULL)
11204 goto no_gnu_hash;
10ca4b04
L
11205 }
11206
978c4450
AM
11207 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11208 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11209 {
625d49fc
AM
11210 uint64_t si = filedata->gnubuckets[hn];
11211 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11212
11213 do
11214 {
978c4450 11215 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11216 {
c31ab5a0
AM
11217 if (off < filedata->ngnuchains
11218 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11219 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11220 }
11221 else
11222 {
11223 if (si >= num_of_syms)
11224 num_of_syms = si + 1;
11225 }
11226 si++;
11227 }
978c4450
AM
11228 while (off < filedata->ngnuchains
11229 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11230 }
11231
90837ea7 11232 if (num_of_syms == 0)
10ca4b04 11233 {
90837ea7 11234 no_gnu_hash:
9db70fc3
AM
11235 free (filedata->mipsxlat);
11236 filedata->mipsxlat = NULL;
11237 free (filedata->gnuchains);
11238 filedata->gnuchains = NULL;
11239 free (filedata->gnubuckets);
11240 filedata->gnubuckets = NULL;
978c4450
AM
11241 filedata->ngnubuckets = 0;
11242 filedata->ngnuchains = 0;
10ca4b04
L
11243 }
11244 }
11245
11246 return num_of_syms;
11247}
11248
b2d38a17
NC
11249/* Parse and display the contents of the dynamic section. */
11250
015dc7e1 11251static bool
dda8d76d 11252process_dynamic_section (Filedata * filedata)
9ea033b2 11253{
2cf0635d 11254 Elf_Internal_Dyn * entry;
9ea033b2 11255
93df3340 11256 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11257 {
11258 if (do_dynamic)
ca0e11aa
NC
11259 {
11260 if (filedata->is_separate)
11261 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11262 filedata->file_name);
11263 else
11264 printf (_("\nThere is no dynamic section in this file.\n"));
11265 }
9ea033b2 11266
015dc7e1 11267 return true;
9ea033b2
NC
11268 }
11269
4de91c10
AM
11270 if (!get_dynamic_section (filedata))
11271 return false;
9ea033b2 11272
252b5132 11273 /* Find the appropriate symbol table. */
978c4450 11274 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11275 {
2482f306
AM
11276 unsigned long num_of_syms;
11277
978c4450
AM
11278 for (entry = filedata->dynamic_section;
11279 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11280 ++entry)
10ca4b04 11281 if (entry->d_tag == DT_SYMTAB)
978c4450 11282 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11283 else if (entry->d_tag == DT_SYMENT)
978c4450 11284 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11285 else if (entry->d_tag == DT_HASH)
978c4450 11286 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11287 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11288 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11289 else if ((filedata->file_header.e_machine == EM_MIPS
11290 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11291 && entry->d_tag == DT_MIPS_XHASH)
11292 {
978c4450
AM
11293 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11294 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11295 }
252b5132 11296
2482f306
AM
11297 num_of_syms = get_num_dynamic_syms (filedata);
11298
11299 if (num_of_syms != 0
11300 && filedata->dynamic_symbols == NULL
11301 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11302 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11303 {
11304 Elf_Internal_Phdr *seg;
625d49fc 11305 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11306
2482f306
AM
11307 if (! get_program_headers (filedata))
11308 {
11309 error (_("Cannot interpret virtual addresses "
11310 "without program headers.\n"));
015dc7e1 11311 return false;
2482f306 11312 }
252b5132 11313
2482f306
AM
11314 for (seg = filedata->program_headers;
11315 seg < filedata->program_headers + filedata->file_header.e_phnum;
11316 ++seg)
11317 {
11318 if (seg->p_type != PT_LOAD)
11319 continue;
252b5132 11320
2482f306
AM
11321 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11322 {
11323 /* See PR 21379 for a reproducer. */
11324 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11325 return false;
2482f306 11326 }
252b5132 11327
2482f306
AM
11328 if (vma >= (seg->p_vaddr & -seg->p_align)
11329 && vma < seg->p_vaddr + seg->p_filesz)
11330 {
11331 /* Since we do not know how big the symbol table is,
11332 we default to reading in up to the end of PT_LOAD
11333 segment and processing that. This is overkill, I
11334 know, but it should work. */
11335 Elf_Internal_Shdr section;
11336 section.sh_offset = (vma - seg->p_vaddr
11337 + seg->p_offset);
11338 section.sh_size = (num_of_syms
11339 * filedata->dynamic_info[DT_SYMENT]);
11340 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11341
11342 if (do_checks
11343 && filedata->dynamic_symtab_section != NULL
11344 && ((filedata->dynamic_symtab_section->sh_offset
11345 != section.sh_offset)
11346 || (filedata->dynamic_symtab_section->sh_size
11347 != section.sh_size)
11348 || (filedata->dynamic_symtab_section->sh_entsize
11349 != section.sh_entsize)))
11350 warn (_("\
11351the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11352
2482f306
AM
11353 section.sh_name = filedata->string_table_length;
11354 filedata->dynamic_symbols
4de91c10 11355 = get_elf_symbols (filedata, &section,
2482f306
AM
11356 &filedata->num_dynamic_syms);
11357 if (filedata->dynamic_symbols == NULL
11358 || filedata->num_dynamic_syms != num_of_syms)
11359 {
11360 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11361 return false;
2482f306
AM
11362 }
11363 break;
11364 }
11365 }
11366 }
11367 }
252b5132
RH
11368
11369 /* Similarly find a string table. */
978c4450
AM
11370 if (filedata->dynamic_strings == NULL)
11371 for (entry = filedata->dynamic_section;
11372 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11373 ++entry)
11374 {
11375 if (entry->d_tag == DT_STRTAB)
978c4450 11376 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11377
10ca4b04 11378 if (entry->d_tag == DT_STRSZ)
978c4450 11379 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11380
978c4450
AM
11381 if (filedata->dynamic_info[DT_STRTAB]
11382 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
11383 {
11384 unsigned long offset;
be7d229a 11385 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11386
11387 offset = offset_from_vma (filedata,
978c4450 11388 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11389 str_tab_len);
8ac10c5b
L
11390 if (do_checks
11391 && filedata->dynamic_strtab_section
11392 && ((filedata->dynamic_strtab_section->sh_offset
11393 != (file_ptr) offset)
11394 || (filedata->dynamic_strtab_section->sh_size
11395 != str_tab_len)))
11396 warn (_("\
11397the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11398
978c4450
AM
11399 filedata->dynamic_strings
11400 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11401 _("dynamic string table"));
11402 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11403 {
11404 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11405 break;
11406 }
e3d39609 11407
978c4450 11408 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11409 break;
11410 }
11411 }
252b5132
RH
11412
11413 /* And find the syminfo section if available. */
978c4450 11414 if (filedata->dynamic_syminfo == NULL)
252b5132 11415 {
3e8bba36 11416 unsigned long syminsz = 0;
252b5132 11417
978c4450
AM
11418 for (entry = filedata->dynamic_section;
11419 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11420 ++entry)
252b5132
RH
11421 {
11422 if (entry->d_tag == DT_SYMINENT)
11423 {
11424 /* Note: these braces are necessary to avoid a syntax
11425 error from the SunOS4 C compiler. */
049b0c3a
NC
11426 /* PR binutils/17531: A corrupt file can trigger this test.
11427 So do not use an assert, instead generate an error message. */
11428 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11429 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11430 (int) entry->d_un.d_val);
252b5132
RH
11431 }
11432 else if (entry->d_tag == DT_SYMINSZ)
11433 syminsz = entry->d_un.d_val;
11434 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11435 filedata->dynamic_syminfo_offset
11436 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11437 }
11438
978c4450 11439 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11440 {
2cf0635d
NC
11441 Elf_External_Syminfo * extsyminfo;
11442 Elf_External_Syminfo * extsym;
11443 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11444
11445 /* There is a syminfo section. Read the data. */
3f5e193b 11446 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11447 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11448 1, syminsz, _("symbol information"));
a6e9f9df 11449 if (!extsyminfo)
015dc7e1 11450 return false;
252b5132 11451
978c4450 11452 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11453 {
11454 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11455 free (filedata->dynamic_syminfo);
e3d39609 11456 }
978c4450
AM
11457 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11458 if (filedata->dynamic_syminfo == NULL)
252b5132 11459 {
2482f306
AM
11460 error (_("Out of memory allocating %lu bytes "
11461 "for dynamic symbol info\n"),
8b73c356 11462 (unsigned long) syminsz);
015dc7e1 11463 return false;
252b5132
RH
11464 }
11465
2482f306
AM
11466 filedata->dynamic_syminfo_nent
11467 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11468 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11469 syminfo < (filedata->dynamic_syminfo
11470 + filedata->dynamic_syminfo_nent);
86dba8ee 11471 ++syminfo, ++extsym)
252b5132 11472 {
86dba8ee
AM
11473 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11474 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11475 }
11476
11477 free (extsyminfo);
11478 }
11479 }
11480
978c4450 11481 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11482 {
f253158f
NC
11483 if (filedata->is_separate)
11484 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
11485 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
11486 (unsigned long) filedata->dynamic_nent),
11487 filedata->file_name,
11488 filedata->dynamic_addr,
11489 (unsigned long) filedata->dynamic_nent);
84a9f195
SM
11490 else
11491 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
11492 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
11493 (unsigned long) filedata->dynamic_nent),
11494 filedata->dynamic_addr,
11495 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11496 }
252b5132
RH
11497 if (do_dynamic)
11498 printf (_(" Tag Type Name/Value\n"));
11499
978c4450
AM
11500 for (entry = filedata->dynamic_section;
11501 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11502 entry++)
252b5132
RH
11503 {
11504 if (do_dynamic)
f7a99963 11505 {
2cf0635d 11506 const char * dtype;
e699b9ff 11507
f7a99963
NC
11508 putchar (' ');
11509 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11510 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11511 printf (" (%s)%*s", dtype,
32ec8896 11512 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11513 }
252b5132
RH
11514
11515 switch (entry->d_tag)
11516 {
d1133906
NC
11517 case DT_FLAGS:
11518 if (do_dynamic)
e9e44622 11519 print_dynamic_flags (entry->d_un.d_val);
d1133906 11520 break;
76da6bbe 11521
252b5132
RH
11522 case DT_AUXILIARY:
11523 case DT_FILTER:
019148e4
L
11524 case DT_CONFIG:
11525 case DT_DEPAUDIT:
11526 case DT_AUDIT:
252b5132
RH
11527 if (do_dynamic)
11528 {
019148e4 11529 switch (entry->d_tag)
b34976b6 11530 {
019148e4
L
11531 case DT_AUXILIARY:
11532 printf (_("Auxiliary library"));
11533 break;
11534
11535 case DT_FILTER:
11536 printf (_("Filter library"));
11537 break;
11538
b34976b6 11539 case DT_CONFIG:
019148e4
L
11540 printf (_("Configuration file"));
11541 break;
11542
11543 case DT_DEPAUDIT:
11544 printf (_("Dependency audit library"));
11545 break;
11546
11547 case DT_AUDIT:
11548 printf (_("Audit library"));
11549 break;
11550 }
252b5132 11551
84714f86 11552 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11553 printf (": [%s]\n",
84714f86 11554 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11555 else
f7a99963
NC
11556 {
11557 printf (": ");
11558 print_vma (entry->d_un.d_val, PREFIX_HEX);
11559 putchar ('\n');
11560 }
252b5132
RH
11561 }
11562 break;
11563
dcefbbbd 11564 case DT_FEATURE:
252b5132
RH
11565 if (do_dynamic)
11566 {
11567 printf (_("Flags:"));
86f55779 11568
252b5132
RH
11569 if (entry->d_un.d_val == 0)
11570 printf (_(" None\n"));
11571 else
11572 {
11573 unsigned long int val = entry->d_un.d_val;
86f55779 11574
252b5132
RH
11575 if (val & DTF_1_PARINIT)
11576 {
11577 printf (" PARINIT");
11578 val ^= DTF_1_PARINIT;
11579 }
dcefbbbd
L
11580 if (val & DTF_1_CONFEXP)
11581 {
11582 printf (" CONFEXP");
11583 val ^= DTF_1_CONFEXP;
11584 }
252b5132
RH
11585 if (val != 0)
11586 printf (" %lx", val);
11587 puts ("");
11588 }
11589 }
11590 break;
11591
11592 case DT_POSFLAG_1:
11593 if (do_dynamic)
11594 {
11595 printf (_("Flags:"));
86f55779 11596
252b5132
RH
11597 if (entry->d_un.d_val == 0)
11598 printf (_(" None\n"));
11599 else
11600 {
11601 unsigned long int val = entry->d_un.d_val;
86f55779 11602
252b5132
RH
11603 if (val & DF_P1_LAZYLOAD)
11604 {
11605 printf (" LAZYLOAD");
11606 val ^= DF_P1_LAZYLOAD;
11607 }
11608 if (val & DF_P1_GROUPPERM)
11609 {
11610 printf (" GROUPPERM");
11611 val ^= DF_P1_GROUPPERM;
11612 }
11613 if (val != 0)
11614 printf (" %lx", val);
11615 puts ("");
11616 }
11617 }
11618 break;
11619
11620 case DT_FLAGS_1:
11621 if (do_dynamic)
11622 {
11623 printf (_("Flags:"));
11624 if (entry->d_un.d_val == 0)
11625 printf (_(" None\n"));
11626 else
11627 {
11628 unsigned long int val = entry->d_un.d_val;
86f55779 11629
252b5132
RH
11630 if (val & DF_1_NOW)
11631 {
11632 printf (" NOW");
11633 val ^= DF_1_NOW;
11634 }
11635 if (val & DF_1_GLOBAL)
11636 {
11637 printf (" GLOBAL");
11638 val ^= DF_1_GLOBAL;
11639 }
11640 if (val & DF_1_GROUP)
11641 {
11642 printf (" GROUP");
11643 val ^= DF_1_GROUP;
11644 }
11645 if (val & DF_1_NODELETE)
11646 {
11647 printf (" NODELETE");
11648 val ^= DF_1_NODELETE;
11649 }
11650 if (val & DF_1_LOADFLTR)
11651 {
11652 printf (" LOADFLTR");
11653 val ^= DF_1_LOADFLTR;
11654 }
11655 if (val & DF_1_INITFIRST)
11656 {
11657 printf (" INITFIRST");
11658 val ^= DF_1_INITFIRST;
11659 }
11660 if (val & DF_1_NOOPEN)
11661 {
11662 printf (" NOOPEN");
11663 val ^= DF_1_NOOPEN;
11664 }
11665 if (val & DF_1_ORIGIN)
11666 {
11667 printf (" ORIGIN");
11668 val ^= DF_1_ORIGIN;
11669 }
11670 if (val & DF_1_DIRECT)
11671 {
11672 printf (" DIRECT");
11673 val ^= DF_1_DIRECT;
11674 }
11675 if (val & DF_1_TRANS)
11676 {
11677 printf (" TRANS");
11678 val ^= DF_1_TRANS;
11679 }
11680 if (val & DF_1_INTERPOSE)
11681 {
11682 printf (" INTERPOSE");
11683 val ^= DF_1_INTERPOSE;
11684 }
f7db6139 11685 if (val & DF_1_NODEFLIB)
dcefbbbd 11686 {
f7db6139
L
11687 printf (" NODEFLIB");
11688 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11689 }
11690 if (val & DF_1_NODUMP)
11691 {
11692 printf (" NODUMP");
11693 val ^= DF_1_NODUMP;
11694 }
34b60028 11695 if (val & DF_1_CONFALT)
dcefbbbd 11696 {
34b60028
L
11697 printf (" CONFALT");
11698 val ^= DF_1_CONFALT;
11699 }
11700 if (val & DF_1_ENDFILTEE)
11701 {
11702 printf (" ENDFILTEE");
11703 val ^= DF_1_ENDFILTEE;
11704 }
11705 if (val & DF_1_DISPRELDNE)
11706 {
11707 printf (" DISPRELDNE");
11708 val ^= DF_1_DISPRELDNE;
11709 }
11710 if (val & DF_1_DISPRELPND)
11711 {
11712 printf (" DISPRELPND");
11713 val ^= DF_1_DISPRELPND;
11714 }
11715 if (val & DF_1_NODIRECT)
11716 {
11717 printf (" NODIRECT");
11718 val ^= DF_1_NODIRECT;
11719 }
11720 if (val & DF_1_IGNMULDEF)
11721 {
11722 printf (" IGNMULDEF");
11723 val ^= DF_1_IGNMULDEF;
11724 }
11725 if (val & DF_1_NOKSYMS)
11726 {
11727 printf (" NOKSYMS");
11728 val ^= DF_1_NOKSYMS;
11729 }
11730 if (val & DF_1_NOHDR)
11731 {
11732 printf (" NOHDR");
11733 val ^= DF_1_NOHDR;
11734 }
11735 if (val & DF_1_EDITED)
11736 {
11737 printf (" EDITED");
11738 val ^= DF_1_EDITED;
11739 }
11740 if (val & DF_1_NORELOC)
11741 {
11742 printf (" NORELOC");
11743 val ^= DF_1_NORELOC;
11744 }
11745 if (val & DF_1_SYMINTPOSE)
11746 {
11747 printf (" SYMINTPOSE");
11748 val ^= DF_1_SYMINTPOSE;
11749 }
11750 if (val & DF_1_GLOBAUDIT)
11751 {
11752 printf (" GLOBAUDIT");
11753 val ^= DF_1_GLOBAUDIT;
11754 }
11755 if (val & DF_1_SINGLETON)
11756 {
11757 printf (" SINGLETON");
11758 val ^= DF_1_SINGLETON;
dcefbbbd 11759 }
5c383f02
RO
11760 if (val & DF_1_STUB)
11761 {
11762 printf (" STUB");
11763 val ^= DF_1_STUB;
11764 }
11765 if (val & DF_1_PIE)
11766 {
11767 printf (" PIE");
11768 val ^= DF_1_PIE;
11769 }
b1202ffa
L
11770 if (val & DF_1_KMOD)
11771 {
11772 printf (" KMOD");
11773 val ^= DF_1_KMOD;
11774 }
11775 if (val & DF_1_WEAKFILTER)
11776 {
11777 printf (" WEAKFILTER");
11778 val ^= DF_1_WEAKFILTER;
11779 }
11780 if (val & DF_1_NOCOMMON)
11781 {
11782 printf (" NOCOMMON");
11783 val ^= DF_1_NOCOMMON;
11784 }
252b5132
RH
11785 if (val != 0)
11786 printf (" %lx", val);
11787 puts ("");
11788 }
11789 }
11790 break;
11791
11792 case DT_PLTREL:
978c4450 11793 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11794 if (do_dynamic)
dda8d76d 11795 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11796 break;
11797
11798 case DT_NULL :
11799 case DT_NEEDED :
11800 case DT_PLTGOT :
11801 case DT_HASH :
11802 case DT_STRTAB :
11803 case DT_SYMTAB :
11804 case DT_RELA :
11805 case DT_INIT :
11806 case DT_FINI :
11807 case DT_SONAME :
11808 case DT_RPATH :
11809 case DT_SYMBOLIC:
11810 case DT_REL :
a7fd1186 11811 case DT_RELR :
252b5132
RH
11812 case DT_DEBUG :
11813 case DT_TEXTREL :
11814 case DT_JMPREL :
019148e4 11815 case DT_RUNPATH :
978c4450 11816 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11817
11818 if (do_dynamic)
11819 {
84714f86 11820 const char *name;
252b5132 11821
84714f86
AM
11822 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11823 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11824 else
d79b3d50 11825 name = NULL;
252b5132
RH
11826
11827 if (name)
11828 {
11829 switch (entry->d_tag)
11830 {
11831 case DT_NEEDED:
11832 printf (_("Shared library: [%s]"), name);
11833
13acb58d
AM
11834 if (filedata->program_interpreter
11835 && streq (name, filedata->program_interpreter))
f7a99963 11836 printf (_(" program interpreter"));
252b5132
RH
11837 break;
11838
11839 case DT_SONAME:
f7a99963 11840 printf (_("Library soname: [%s]"), name);
252b5132
RH
11841 break;
11842
11843 case DT_RPATH:
f7a99963 11844 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11845 break;
11846
019148e4
L
11847 case DT_RUNPATH:
11848 printf (_("Library runpath: [%s]"), name);
11849 break;
11850
252b5132 11851 default:
f7a99963
NC
11852 print_vma (entry->d_un.d_val, PREFIX_HEX);
11853 break;
252b5132
RH
11854 }
11855 }
11856 else
f7a99963
NC
11857 print_vma (entry->d_un.d_val, PREFIX_HEX);
11858
11859 putchar ('\n');
252b5132
RH
11860 }
11861 break;
11862
11863 case DT_PLTRELSZ:
11864 case DT_RELASZ :
11865 case DT_STRSZ :
11866 case DT_RELSZ :
11867 case DT_RELAENT :
a7fd1186
FS
11868 case DT_RELRENT :
11869 case DT_RELRSZ :
252b5132
RH
11870 case DT_SYMENT :
11871 case DT_RELENT :
978c4450 11872 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11873 /* Fall through. */
252b5132
RH
11874 case DT_PLTPADSZ:
11875 case DT_MOVEENT :
11876 case DT_MOVESZ :
04d8355a 11877 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11878 case DT_INIT_ARRAYSZ:
11879 case DT_FINI_ARRAYSZ:
047b2264
JJ
11880 case DT_GNU_CONFLICTSZ:
11881 case DT_GNU_LIBLISTSZ:
252b5132 11882 if (do_dynamic)
f7a99963
NC
11883 {
11884 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11885 printf (_(" (bytes)\n"));
f7a99963 11886 }
252b5132
RH
11887 break;
11888
11889 case DT_VERDEFNUM:
11890 case DT_VERNEEDNUM:
11891 case DT_RELACOUNT:
11892 case DT_RELCOUNT:
11893 if (do_dynamic)
f7a99963
NC
11894 {
11895 print_vma (entry->d_un.d_val, UNSIGNED);
11896 putchar ('\n');
11897 }
252b5132
RH
11898 break;
11899
11900 case DT_SYMINSZ:
11901 case DT_SYMINENT:
11902 case DT_SYMINFO:
11903 case DT_USED:
11904 case DT_INIT_ARRAY:
11905 case DT_FINI_ARRAY:
11906 if (do_dynamic)
11907 {
d79b3d50 11908 if (entry->d_tag == DT_USED
84714f86 11909 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11910 {
84714f86
AM
11911 const char *name
11912 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11913
b34976b6 11914 if (*name)
252b5132
RH
11915 {
11916 printf (_("Not needed object: [%s]\n"), name);
11917 break;
11918 }
11919 }
103f02d3 11920
f7a99963
NC
11921 print_vma (entry->d_un.d_val, PREFIX_HEX);
11922 putchar ('\n');
252b5132
RH
11923 }
11924 break;
11925
11926 case DT_BIND_NOW:
11927 /* The value of this entry is ignored. */
35b1837e
AM
11928 if (do_dynamic)
11929 putchar ('\n');
252b5132 11930 break;
103f02d3 11931
047b2264
JJ
11932 case DT_GNU_PRELINKED:
11933 if (do_dynamic)
11934 {
2cf0635d 11935 struct tm * tmp;
91d6fa6a 11936 time_t atime = entry->d_un.d_val;
047b2264 11937
91d6fa6a 11938 tmp = gmtime (&atime);
071436c6
NC
11939 /* PR 17533 file: 041-1244816-0.004. */
11940 if (tmp == NULL)
5a2cbcf4
L
11941 printf (_("<corrupt time val: %lx"),
11942 (unsigned long) atime);
071436c6
NC
11943 else
11944 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11945 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11946 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11947
11948 }
11949 break;
11950
fdc90cb4 11951 case DT_GNU_HASH:
978c4450 11952 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11953 if (do_dynamic)
11954 {
11955 print_vma (entry->d_un.d_val, PREFIX_HEX);
11956 putchar ('\n');
11957 }
11958 break;
11959
a5da3dee
VDM
11960 case DT_GNU_FLAGS_1:
11961 if (do_dynamic)
11962 {
11963 printf (_("Flags:"));
11964 if (entry->d_un.d_val == 0)
11965 printf (_(" None\n"));
11966 else
11967 {
11968 unsigned long int val = entry->d_un.d_val;
11969
11970 if (val & DF_GNU_1_UNIQUE)
11971 {
11972 printf (" UNIQUE");
11973 val ^= DF_GNU_1_UNIQUE;
11974 }
11975 if (val != 0)
11976 printf (" %lx", val);
11977 puts ("");
11978 }
11979 }
11980 break;
11981
252b5132
RH
11982 default:
11983 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11984 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11985 = entry->d_un.d_val;
252b5132
RH
11986
11987 if (do_dynamic)
11988 {
dda8d76d 11989 switch (filedata->file_header.e_machine)
252b5132 11990 {
37c18eed
SD
11991 case EM_AARCH64:
11992 dynamic_section_aarch64_val (entry);
11993 break;
252b5132 11994 case EM_MIPS:
4fe85591 11995 case EM_MIPS_RS3_LE:
978c4450 11996 dynamic_section_mips_val (filedata, entry);
252b5132 11997 break;
103f02d3 11998 case EM_PARISC:
b2d38a17 11999 dynamic_section_parisc_val (entry);
103f02d3 12000 break;
ecc51f48 12001 case EM_IA_64:
b2d38a17 12002 dynamic_section_ia64_val (entry);
ecc51f48 12003 break;
252b5132 12004 default:
f7a99963
NC
12005 print_vma (entry->d_un.d_val, PREFIX_HEX);
12006 putchar ('\n');
252b5132
RH
12007 }
12008 }
12009 break;
12010 }
12011 }
12012
015dc7e1 12013 return true;
252b5132
RH
12014}
12015
12016static char *
d3ba0551 12017get_ver_flags (unsigned int flags)
252b5132 12018{
6d4f21f6 12019 static char buff[128];
252b5132
RH
12020
12021 buff[0] = 0;
12022
12023 if (flags == 0)
12024 return _("none");
12025
12026 if (flags & VER_FLG_BASE)
7bb1ad17 12027 strcat (buff, "BASE");
252b5132
RH
12028
12029 if (flags & VER_FLG_WEAK)
12030 {
12031 if (flags & VER_FLG_BASE)
7bb1ad17 12032 strcat (buff, " | ");
252b5132 12033
7bb1ad17 12034 strcat (buff, "WEAK");
252b5132
RH
12035 }
12036
44ec90b9
RO
12037 if (flags & VER_FLG_INFO)
12038 {
12039 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12040 strcat (buff, " | ");
44ec90b9 12041
7bb1ad17 12042 strcat (buff, "INFO");
44ec90b9
RO
12043 }
12044
12045 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12046 {
12047 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12048 strcat (buff, " | ");
12049
12050 strcat (buff, _("<unknown>"));
12051 }
252b5132
RH
12052
12053 return buff;
12054}
12055
12056/* Display the contents of the version sections. */
98fb390a 12057
015dc7e1 12058static bool
dda8d76d 12059process_version_sections (Filedata * filedata)
252b5132 12060{
2cf0635d 12061 Elf_Internal_Shdr * section;
b34976b6 12062 unsigned i;
015dc7e1 12063 bool found = false;
252b5132
RH
12064
12065 if (! do_version)
015dc7e1 12066 return true;
252b5132 12067
dda8d76d
NC
12068 for (i = 0, section = filedata->section_headers;
12069 i < filedata->file_header.e_shnum;
b34976b6 12070 i++, section++)
252b5132
RH
12071 {
12072 switch (section->sh_type)
12073 {
12074 case SHT_GNU_verdef:
12075 {
2cf0635d 12076 Elf_External_Verdef * edefs;
452bf675
AM
12077 unsigned long idx;
12078 unsigned long cnt;
2cf0635d 12079 char * endbuf;
252b5132 12080
015dc7e1 12081 found = true;
252b5132 12082
ca0e11aa
NC
12083 if (filedata->is_separate)
12084 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12085 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12086 section->sh_info),
12087 filedata->file_name,
12088 printable_section_name (filedata, section),
12089 section->sh_info);
12090 else
12091 printf (ngettext ("\nVersion definition section '%s' "
12092 "contains %u entry:\n",
12093 "\nVersion definition section '%s' "
12094 "contains %u entries:\n",
12095 section->sh_info),
12096 printable_section_name (filedata, section),
12097 section->sh_info);
047c3dbf 12098
625d49fc 12099 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
233f82cf 12100 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12101 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12102 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12103
3f5e193b 12104 edefs = (Elf_External_Verdef *)
dda8d76d 12105 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12106 _("version definition section"));
a6e9f9df
AM
12107 if (!edefs)
12108 break;
59245841 12109 endbuf = (char *) edefs + section->sh_size;
252b5132 12110
1445030f 12111 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12112 {
2cf0635d
NC
12113 char * vstart;
12114 Elf_External_Verdef * edef;
b34976b6 12115 Elf_Internal_Verdef ent;
2cf0635d 12116 Elf_External_Verdaux * eaux;
b34976b6 12117 Elf_Internal_Verdaux aux;
452bf675 12118 unsigned long isum;
b34976b6 12119 int j;
103f02d3 12120
252b5132 12121 vstart = ((char *) edefs) + idx;
54806181
AM
12122 if (vstart + sizeof (*edef) > endbuf)
12123 break;
252b5132
RH
12124
12125 edef = (Elf_External_Verdef *) vstart;
12126
12127 ent.vd_version = BYTE_GET (edef->vd_version);
12128 ent.vd_flags = BYTE_GET (edef->vd_flags);
12129 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12130 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12131 ent.vd_hash = BYTE_GET (edef->vd_hash);
12132 ent.vd_aux = BYTE_GET (edef->vd_aux);
12133 ent.vd_next = BYTE_GET (edef->vd_next);
12134
452bf675 12135 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
12136 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12137
12138 printf (_(" Index: %d Cnt: %d "),
12139 ent.vd_ndx, ent.vd_cnt);
12140
452bf675 12141 /* Check for overflow. */
1445030f 12142 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12143 break;
12144
252b5132
RH
12145 vstart += ent.vd_aux;
12146
1445030f
AM
12147 if (vstart + sizeof (*eaux) > endbuf)
12148 break;
252b5132
RH
12149 eaux = (Elf_External_Verdaux *) vstart;
12150
12151 aux.vda_name = BYTE_GET (eaux->vda_name);
12152 aux.vda_next = BYTE_GET (eaux->vda_next);
12153
84714f86 12154 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12155 printf (_("Name: %s\n"),
84714f86 12156 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12157 else
12158 printf (_("Name index: %ld\n"), aux.vda_name);
12159
12160 isum = idx + ent.vd_aux;
12161
b34976b6 12162 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12163 {
1445030f
AM
12164 if (aux.vda_next < sizeof (*eaux)
12165 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12166 {
12167 warn (_("Invalid vda_next field of %lx\n"),
12168 aux.vda_next);
12169 j = ent.vd_cnt;
12170 break;
12171 }
dd24e3da 12172 /* Check for overflow. */
7e26601c 12173 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12174 break;
12175
252b5132
RH
12176 isum += aux.vda_next;
12177 vstart += aux.vda_next;
12178
54806181
AM
12179 if (vstart + sizeof (*eaux) > endbuf)
12180 break;
1445030f 12181 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12182
12183 aux.vda_name = BYTE_GET (eaux->vda_name);
12184 aux.vda_next = BYTE_GET (eaux->vda_next);
12185
84714f86 12186 if (valid_dynamic_name (filedata, aux.vda_name))
452bf675 12187 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450 12188 isum, j,
84714f86 12189 get_dynamic_name (filedata, aux.vda_name));
252b5132 12190 else
452bf675 12191 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
12192 isum, j, aux.vda_name);
12193 }
dd24e3da 12194
54806181
AM
12195 if (j < ent.vd_cnt)
12196 printf (_(" Version def aux past end of section\n"));
252b5132 12197
c9f02c3e
MR
12198 /* PR 17531:
12199 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12200 if (ent.vd_next < sizeof (*edef)
12201 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12202 {
12203 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12204 cnt = section->sh_info;
12205 break;
12206 }
452bf675 12207 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12208 break;
12209
252b5132
RH
12210 idx += ent.vd_next;
12211 }
dd24e3da 12212
54806181
AM
12213 if (cnt < section->sh_info)
12214 printf (_(" Version definition past end of section\n"));
252b5132
RH
12215
12216 free (edefs);
12217 }
12218 break;
103f02d3 12219
252b5132
RH
12220 case SHT_GNU_verneed:
12221 {
2cf0635d 12222 Elf_External_Verneed * eneed;
452bf675
AM
12223 unsigned long idx;
12224 unsigned long cnt;
2cf0635d 12225 char * endbuf;
252b5132 12226
015dc7e1 12227 found = true;
252b5132 12228
ca0e11aa
NC
12229 if (filedata->is_separate)
12230 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12231 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12232 section->sh_info),
12233 filedata->file_name,
12234 printable_section_name (filedata, section),
12235 section->sh_info);
12236 else
12237 printf (ngettext ("\nVersion needs section '%s' "
12238 "contains %u entry:\n",
12239 "\nVersion needs section '%s' "
12240 "contains %u entries:\n",
12241 section->sh_info),
12242 printable_section_name (filedata, section),
12243 section->sh_info);
047c3dbf 12244
625d49fc 12245 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
72de5009 12246 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12247 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12248 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12249
dda8d76d 12250 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12251 section->sh_offset, 1,
12252 section->sh_size,
9cf03b7e 12253 _("Version Needs section"));
a6e9f9df
AM
12254 if (!eneed)
12255 break;
59245841 12256 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12257
12258 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12259 {
2cf0635d 12260 Elf_External_Verneed * entry;
b34976b6 12261 Elf_Internal_Verneed ent;
452bf675 12262 unsigned long isum;
b34976b6 12263 int j;
2cf0635d 12264 char * vstart;
252b5132
RH
12265
12266 vstart = ((char *) eneed) + idx;
54806181
AM
12267 if (vstart + sizeof (*entry) > endbuf)
12268 break;
252b5132
RH
12269
12270 entry = (Elf_External_Verneed *) vstart;
12271
12272 ent.vn_version = BYTE_GET (entry->vn_version);
12273 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12274 ent.vn_file = BYTE_GET (entry->vn_file);
12275 ent.vn_aux = BYTE_GET (entry->vn_aux);
12276 ent.vn_next = BYTE_GET (entry->vn_next);
12277
452bf675 12278 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 12279
84714f86 12280 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12281 printf (_(" File: %s"),
84714f86 12282 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12283 else
12284 printf (_(" File: %lx"), ent.vn_file);
12285
12286 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12287
dd24e3da 12288 /* Check for overflow. */
7e26601c 12289 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12290 break;
252b5132
RH
12291 vstart += ent.vn_aux;
12292
12293 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12294 {
2cf0635d 12295 Elf_External_Vernaux * eaux;
b34976b6 12296 Elf_Internal_Vernaux aux;
252b5132 12297
54806181
AM
12298 if (vstart + sizeof (*eaux) > endbuf)
12299 break;
252b5132
RH
12300 eaux = (Elf_External_Vernaux *) vstart;
12301
12302 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12303 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12304 aux.vna_other = BYTE_GET (eaux->vna_other);
12305 aux.vna_name = BYTE_GET (eaux->vna_name);
12306 aux.vna_next = BYTE_GET (eaux->vna_next);
12307
84714f86 12308 if (valid_dynamic_name (filedata, aux.vna_name))
452bf675 12309 printf (_(" %#06lx: Name: %s"),
84714f86 12310 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12311 else
452bf675 12312 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
12313 isum, aux.vna_name);
12314
12315 printf (_(" Flags: %s Version: %d\n"),
12316 get_ver_flags (aux.vna_flags), aux.vna_other);
12317
1445030f
AM
12318 if (aux.vna_next < sizeof (*eaux)
12319 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12320 {
12321 warn (_("Invalid vna_next field of %lx\n"),
12322 aux.vna_next);
12323 j = ent.vn_cnt;
12324 break;
12325 }
1445030f
AM
12326 /* Check for overflow. */
12327 if (aux.vna_next > (size_t) (endbuf - vstart))
12328 break;
252b5132
RH
12329 isum += aux.vna_next;
12330 vstart += aux.vna_next;
12331 }
9cf03b7e 12332
54806181 12333 if (j < ent.vn_cnt)
f9a6a8f0 12334 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12335
1445030f
AM
12336 if (ent.vn_next < sizeof (*entry)
12337 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12338 {
452bf675 12339 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12340 cnt = section->sh_info;
12341 break;
12342 }
1445030f
AM
12343 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12344 break;
252b5132
RH
12345 idx += ent.vn_next;
12346 }
9cf03b7e 12347
54806181 12348 if (cnt < section->sh_info)
9cf03b7e 12349 warn (_("Missing Version Needs information\n"));
103f02d3 12350
252b5132
RH
12351 free (eneed);
12352 }
12353 break;
12354
12355 case SHT_GNU_versym:
12356 {
2cf0635d 12357 Elf_Internal_Shdr * link_section;
8b73c356
NC
12358 size_t total;
12359 unsigned int cnt;
2cf0635d
NC
12360 unsigned char * edata;
12361 unsigned short * data;
12362 char * strtab;
12363 Elf_Internal_Sym * symbols;
12364 Elf_Internal_Shdr * string_sec;
ba5cdace 12365 unsigned long num_syms;
d3ba0551 12366 long off;
252b5132 12367
dda8d76d 12368 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12369 break;
12370
dda8d76d 12371 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12372 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12373
dda8d76d 12374 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12375 break;
12376
015dc7e1 12377 found = true;
252b5132 12378
4de91c10 12379 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12380 if (symbols == NULL)
12381 break;
252b5132 12382
dda8d76d 12383 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12384
dda8d76d 12385 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12386 string_sec->sh_size,
12387 _("version string table"));
a6e9f9df 12388 if (!strtab)
0429c154
MS
12389 {
12390 free (symbols);
12391 break;
12392 }
252b5132 12393
ca0e11aa
NC
12394 if (filedata->is_separate)
12395 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
12396 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
12397 total),
12398 filedata->file_name,
12399 printable_section_name (filedata, section),
12400 (unsigned long) total);
12401 else
12402 printf (ngettext ("\nVersion symbols section '%s' "
12403 "contains %lu entry:\n",
12404 "\nVersion symbols section '%s' "
12405 "contains %lu entries:\n",
12406 total),
12407 printable_section_name (filedata, section),
12408 (unsigned long) total);
252b5132 12409
625d49fc 12410 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
72de5009 12411 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12412 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12413 printable_section_name (filedata, link_section));
252b5132 12414
dda8d76d 12415 off = offset_from_vma (filedata,
978c4450 12416 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12417 total * sizeof (short));
95099889
AM
12418 edata = (unsigned char *) get_data (NULL, filedata, off,
12419 sizeof (short), total,
12420 _("version symbol data"));
a6e9f9df
AM
12421 if (!edata)
12422 {
12423 free (strtab);
0429c154 12424 free (symbols);
a6e9f9df
AM
12425 break;
12426 }
252b5132 12427
3f5e193b 12428 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12429
12430 for (cnt = total; cnt --;)
b34976b6
AM
12431 data[cnt] = byte_get (edata + cnt * sizeof (short),
12432 sizeof (short));
252b5132
RH
12433
12434 free (edata);
12435
12436 for (cnt = 0; cnt < total; cnt += 4)
12437 {
12438 int j, nn;
ab273396
AM
12439 char *name;
12440 char *invalid = _("*invalid*");
252b5132
RH
12441
12442 printf (" %03x:", cnt);
12443
12444 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12445 switch (data[cnt + j])
252b5132
RH
12446 {
12447 case 0:
12448 fputs (_(" 0 (*local*) "), stdout);
12449 break;
12450
12451 case 1:
12452 fputs (_(" 1 (*global*) "), stdout);
12453 break;
12454
12455 default:
c244d050
NC
12456 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12457 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12458
dd24e3da 12459 /* If this index value is greater than the size of the symbols
ba5cdace
NC
12460 array, break to avoid an out-of-bounds read. */
12461 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
12462 {
12463 warn (_("invalid index into symbol array\n"));
12464 break;
12465 }
12466
ab273396 12467 name = NULL;
978c4450 12468 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12469 {
b34976b6
AM
12470 Elf_Internal_Verneed ivn;
12471 unsigned long offset;
252b5132 12472
d93f0186 12473 offset = offset_from_vma
978c4450
AM
12474 (filedata,
12475 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12476 sizeof (Elf_External_Verneed));
252b5132 12477
b34976b6 12478 do
252b5132 12479 {
b34976b6
AM
12480 Elf_Internal_Vernaux ivna;
12481 Elf_External_Verneed evn;
12482 Elf_External_Vernaux evna;
12483 unsigned long a_off;
252b5132 12484
dda8d76d 12485 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12486 _("version need")) == NULL)
12487 break;
0b4362b0 12488
252b5132
RH
12489 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12490 ivn.vn_next = BYTE_GET (evn.vn_next);
12491
12492 a_off = offset + ivn.vn_aux;
12493
12494 do
12495 {
dda8d76d 12496 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12497 1, _("version need aux (2)")) == NULL)
12498 {
12499 ivna.vna_next = 0;
12500 ivna.vna_other = 0;
12501 }
12502 else
12503 {
12504 ivna.vna_next = BYTE_GET (evna.vna_next);
12505 ivna.vna_other = BYTE_GET (evna.vna_other);
12506 }
252b5132
RH
12507
12508 a_off += ivna.vna_next;
12509 }
b34976b6 12510 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12511 && ivna.vna_next != 0);
12512
b34976b6 12513 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12514 {
12515 ivna.vna_name = BYTE_GET (evna.vna_name);
12516
54806181 12517 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12518 name = invalid;
54806181
AM
12519 else
12520 name = strtab + ivna.vna_name;
252b5132
RH
12521 break;
12522 }
12523
12524 offset += ivn.vn_next;
12525 }
12526 while (ivn.vn_next);
12527 }
00d93f34 12528
ab273396 12529 if (data[cnt + j] != 0x8001
978c4450 12530 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12531 {
b34976b6
AM
12532 Elf_Internal_Verdef ivd;
12533 Elf_External_Verdef evd;
12534 unsigned long offset;
252b5132 12535
d93f0186 12536 offset = offset_from_vma
978c4450
AM
12537 (filedata,
12538 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12539 sizeof evd);
252b5132
RH
12540
12541 do
12542 {
dda8d76d 12543 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12544 _("version def")) == NULL)
12545 {
12546 ivd.vd_next = 0;
948f632f 12547 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12548 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12549 break;
59245841
NC
12550 }
12551 else
12552 {
12553 ivd.vd_next = BYTE_GET (evd.vd_next);
12554 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12555 }
252b5132
RH
12556
12557 offset += ivd.vd_next;
12558 }
c244d050 12559 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12560 && ivd.vd_next != 0);
12561
c244d050 12562 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12563 {
b34976b6
AM
12564 Elf_External_Verdaux evda;
12565 Elf_Internal_Verdaux ivda;
252b5132
RH
12566
12567 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12568
dda8d76d 12569 if (get_data (&evda, filedata,
59245841
NC
12570 offset - ivd.vd_next + ivd.vd_aux,
12571 sizeof (evda), 1,
12572 _("version def aux")) == NULL)
12573 break;
252b5132
RH
12574
12575 ivda.vda_name = BYTE_GET (evda.vda_name);
12576
54806181 12577 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12578 name = invalid;
12579 else if (name != NULL && name != invalid)
12580 name = _("*both*");
54806181
AM
12581 else
12582 name = strtab + ivda.vda_name;
252b5132
RH
12583 }
12584 }
ab273396
AM
12585 if (name != NULL)
12586 nn += printf ("(%s%-*s",
12587 name,
12588 12 - (int) strlen (name),
12589 ")");
252b5132
RH
12590
12591 if (nn < 18)
12592 printf ("%*c", 18 - nn, ' ');
12593 }
12594
12595 putchar ('\n');
12596 }
12597
12598 free (data);
12599 free (strtab);
12600 free (symbols);
12601 }
12602 break;
103f02d3 12603
252b5132
RH
12604 default:
12605 break;
12606 }
12607 }
12608
12609 if (! found)
ca0e11aa
NC
12610 {
12611 if (filedata->is_separate)
12612 printf (_("\nNo version information found in linked file '%s'.\n"),
12613 filedata->file_name);
12614 else
12615 printf (_("\nNo version information found in this file.\n"));
12616 }
252b5132 12617
015dc7e1 12618 return true;
252b5132
RH
12619}
12620
d1133906 12621static const char *
dda8d76d 12622get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12623{
89246a0e 12624 static char buff[64];
252b5132
RH
12625
12626 switch (binding)
12627 {
b34976b6
AM
12628 case STB_LOCAL: return "LOCAL";
12629 case STB_GLOBAL: return "GLOBAL";
12630 case STB_WEAK: return "WEAK";
252b5132
RH
12631 default:
12632 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12633 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12634 binding);
252b5132 12635 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12636 {
12637 if (binding == STB_GNU_UNIQUE
df3a023b 12638 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12639 return "UNIQUE";
12640 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12641 }
252b5132 12642 else
e9e44622 12643 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12644 return buff;
12645 }
12646}
12647
d1133906 12648static const char *
dda8d76d 12649get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12650{
89246a0e 12651 static char buff[64];
252b5132
RH
12652
12653 switch (type)
12654 {
b34976b6
AM
12655 case STT_NOTYPE: return "NOTYPE";
12656 case STT_OBJECT: return "OBJECT";
12657 case STT_FUNC: return "FUNC";
12658 case STT_SECTION: return "SECTION";
12659 case STT_FILE: return "FILE";
12660 case STT_COMMON: return "COMMON";
12661 case STT_TLS: return "TLS";
15ab5209
DB
12662 case STT_RELC: return "RELC";
12663 case STT_SRELC: return "SRELC";
252b5132
RH
12664 default:
12665 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12666 {
dda8d76d 12667 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12668 return "THUMB_FUNC";
103f02d3 12669
dda8d76d 12670 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12671 return "REGISTER";
12672
dda8d76d 12673 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12674 return "PARISC_MILLI";
12675
e9e44622 12676 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12677 }
252b5132 12678 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12679 {
dda8d76d 12680 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12681 {
12682 if (type == STT_HP_OPAQUE)
12683 return "HP_OPAQUE";
12684 if (type == STT_HP_STUB)
12685 return "HP_STUB";
12686 }
12687
d8045f23 12688 if (type == STT_GNU_IFUNC
dda8d76d 12689 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12690 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12691 return "IFUNC";
12692
e9e44622 12693 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12694 }
252b5132 12695 else
e9e44622 12696 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12697 return buff;
12698 }
12699}
12700
d1133906 12701static const char *
d3ba0551 12702get_symbol_visibility (unsigned int visibility)
d1133906
NC
12703{
12704 switch (visibility)
12705 {
b34976b6
AM
12706 case STV_DEFAULT: return "DEFAULT";
12707 case STV_INTERNAL: return "INTERNAL";
12708 case STV_HIDDEN: return "HIDDEN";
d1133906 12709 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12710 default:
27a45f42 12711 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12712 return _("<unknown>");
d1133906
NC
12713 }
12714}
12715
2057d69d
CZ
12716static const char *
12717get_alpha_symbol_other (unsigned int other)
9abca702 12718{
2057d69d
CZ
12719 switch (other)
12720 {
12721 case STO_ALPHA_NOPV: return "NOPV";
12722 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12723 default:
27a45f42 12724 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12725 return _("<unknown>");
9abca702 12726 }
2057d69d
CZ
12727}
12728
fd85a6a1
NC
12729static const char *
12730get_solaris_symbol_visibility (unsigned int visibility)
12731{
12732 switch (visibility)
12733 {
12734 case 4: return "EXPORTED";
12735 case 5: return "SINGLETON";
12736 case 6: return "ELIMINATE";
12737 default: return get_symbol_visibility (visibility);
12738 }
12739}
12740
2301ed1c
SN
12741static const char *
12742get_aarch64_symbol_other (unsigned int other)
12743{
12744 static char buf[32];
12745
12746 if (other & STO_AARCH64_VARIANT_PCS)
12747 {
12748 other &= ~STO_AARCH64_VARIANT_PCS;
12749 if (other == 0)
12750 return "VARIANT_PCS";
12751 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12752 return buf;
12753 }
12754 return NULL;
12755}
12756
5e2b0d47
NC
12757static const char *
12758get_mips_symbol_other (unsigned int other)
12759{
12760 switch (other)
12761 {
32ec8896
NC
12762 case STO_OPTIONAL: return "OPTIONAL";
12763 case STO_MIPS_PLT: return "MIPS PLT";
12764 case STO_MIPS_PIC: return "MIPS PIC";
12765 case STO_MICROMIPS: return "MICROMIPS";
12766 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12767 case STO_MIPS16: return "MIPS16";
12768 default: return NULL;
5e2b0d47
NC
12769 }
12770}
12771
28f997cf 12772static const char *
dda8d76d 12773get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12774{
dda8d76d 12775 if (is_ia64_vms (filedata))
28f997cf
TG
12776 {
12777 static char res[32];
12778
12779 res[0] = 0;
12780
12781 /* Function types is for images and .STB files only. */
dda8d76d 12782 switch (filedata->file_header.e_type)
28f997cf
TG
12783 {
12784 case ET_DYN:
12785 case ET_EXEC:
12786 switch (VMS_ST_FUNC_TYPE (other))
12787 {
12788 case VMS_SFT_CODE_ADDR:
12789 strcat (res, " CA");
12790 break;
12791 case VMS_SFT_SYMV_IDX:
12792 strcat (res, " VEC");
12793 break;
12794 case VMS_SFT_FD:
12795 strcat (res, " FD");
12796 break;
12797 case VMS_SFT_RESERVE:
12798 strcat (res, " RSV");
12799 break;
12800 default:
bee0ee85
NC
12801 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12802 VMS_ST_FUNC_TYPE (other));
12803 strcat (res, " <unknown>");
12804 break;
28f997cf
TG
12805 }
12806 break;
12807 default:
12808 break;
12809 }
12810 switch (VMS_ST_LINKAGE (other))
12811 {
12812 case VMS_STL_IGNORE:
12813 strcat (res, " IGN");
12814 break;
12815 case VMS_STL_RESERVE:
12816 strcat (res, " RSV");
12817 break;
12818 case VMS_STL_STD:
12819 strcat (res, " STD");
12820 break;
12821 case VMS_STL_LNK:
12822 strcat (res, " LNK");
12823 break;
12824 default:
bee0ee85
NC
12825 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12826 VMS_ST_LINKAGE (other));
12827 strcat (res, " <unknown>");
12828 break;
28f997cf
TG
12829 }
12830
12831 if (res[0] != 0)
12832 return res + 1;
12833 else
12834 return res;
12835 }
12836 return NULL;
12837}
12838
6911b7dc
AM
12839static const char *
12840get_ppc64_symbol_other (unsigned int other)
12841{
14732552
AM
12842 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12843 return NULL;
12844
12845 other >>= STO_PPC64_LOCAL_BIT;
12846 if (other <= 6)
6911b7dc 12847 {
89246a0e 12848 static char buf[64];
14732552
AM
12849 if (other >= 2)
12850 other = ppc64_decode_local_entry (other);
12851 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12852 return buf;
12853 }
12854 return NULL;
12855}
12856
8155b853
NC
12857static const char *
12858get_riscv_symbol_other (unsigned int other)
12859{
12860 static char buf[32];
12861 buf[0] = 0;
12862
12863 if (other & STO_RISCV_VARIANT_CC)
12864 {
12865 strcat (buf, _(" VARIANT_CC"));
12866 other &= ~STO_RISCV_VARIANT_CC;
12867 }
12868
12869 if (other != 0)
12870 snprintf (buf, sizeof buf, " %x", other);
12871
12872
12873 if (buf[0] != 0)
12874 return buf + 1;
12875 else
12876 return buf;
12877}
12878
5e2b0d47 12879static const char *
dda8d76d 12880get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12881{
12882 const char * result = NULL;
89246a0e 12883 static char buff [64];
5e2b0d47
NC
12884
12885 if (other == 0)
12886 return "";
12887
dda8d76d 12888 switch (filedata->file_header.e_machine)
5e2b0d47 12889 {
2057d69d
CZ
12890 case EM_ALPHA:
12891 result = get_alpha_symbol_other (other);
12892 break;
2301ed1c
SN
12893 case EM_AARCH64:
12894 result = get_aarch64_symbol_other (other);
12895 break;
5e2b0d47
NC
12896 case EM_MIPS:
12897 result = get_mips_symbol_other (other);
28f997cf
TG
12898 break;
12899 case EM_IA_64:
dda8d76d 12900 result = get_ia64_symbol_other (filedata, other);
28f997cf 12901 break;
6911b7dc
AM
12902 case EM_PPC64:
12903 result = get_ppc64_symbol_other (other);
12904 break;
8155b853
NC
12905 case EM_RISCV:
12906 result = get_riscv_symbol_other (other);
12907 break;
5e2b0d47 12908 default:
fd85a6a1 12909 result = NULL;
5e2b0d47
NC
12910 break;
12911 }
12912
12913 if (result)
12914 return result;
12915
12916 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12917 return buff;
12918}
12919
d1133906 12920static const char *
dda8d76d 12921get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12922{
b34976b6 12923 static char buff[32];
5cf1065c 12924
252b5132
RH
12925 switch (type)
12926 {
b34976b6
AM
12927 case SHN_UNDEF: return "UND";
12928 case SHN_ABS: return "ABS";
12929 case SHN_COMMON: return "COM";
252b5132 12930 default:
9ce701e2 12931 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12932 && filedata->file_header.e_machine == EM_IA_64
12933 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12934 return "ANSI_COM";
12935 else if ((filedata->file_header.e_machine == EM_X86_64
12936 || filedata->file_header.e_machine == EM_L1OM
12937 || filedata->file_header.e_machine == EM_K1OM)
12938 && type == SHN_X86_64_LCOMMON)
12939 return "LARGE_COM";
12940 else if ((type == SHN_MIPS_SCOMMON
12941 && filedata->file_header.e_machine == EM_MIPS)
12942 || (type == SHN_TIC6X_SCOMMON
12943 && filedata->file_header.e_machine == EM_TI_C6000))
12944 return "SCOM";
12945 else if (type == SHN_MIPS_SUNDEFINED
12946 && filedata->file_header.e_machine == EM_MIPS)
12947 return "SUND";
12948 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12949 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12950 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12951 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12952 else if (type >= SHN_LORESERVE)
12953 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12954 else if (filedata->file_header.e_shnum != 0
12955 && type >= filedata->file_header.e_shnum)
12956 sprintf (buff, _("bad section index[%3d]"), type);
12957 else
12958 sprintf (buff, "%3d", type);
12959 break;
fd85a6a1
NC
12960 }
12961
10ca4b04 12962 return buff;
6bd1a22c
L
12963}
12964
bb4d2ac2 12965static const char *
dda8d76d 12966get_symbol_version_string (Filedata * filedata,
015dc7e1 12967 bool is_dynsym,
1449284b
NC
12968 const char * strtab,
12969 unsigned long int strtab_size,
12970 unsigned int si,
12971 Elf_Internal_Sym * psym,
12972 enum versioned_symbol_info * sym_info,
12973 unsigned short * vna_other)
bb4d2ac2 12974{
ab273396
AM
12975 unsigned char data[2];
12976 unsigned short vers_data;
12977 unsigned long offset;
7a815dd5 12978 unsigned short max_vd_ndx;
bb4d2ac2 12979
ab273396 12980 if (!is_dynsym
978c4450 12981 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12982 return NULL;
bb4d2ac2 12983
978c4450
AM
12984 offset = offset_from_vma (filedata,
12985 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12986 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12987
dda8d76d 12988 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12989 sizeof (data), 1, _("version data")) == NULL)
12990 return NULL;
12991
12992 vers_data = byte_get (data, 2);
bb4d2ac2 12993
1f6f5dba 12994 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12995 return NULL;
bb4d2ac2 12996
0b8b7609 12997 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12998 max_vd_ndx = 0;
12999
ab273396
AM
13000 /* Usually we'd only see verdef for defined symbols, and verneed for
13001 undefined symbols. However, symbols defined by the linker in
13002 .dynbss for variables copied from a shared library in order to
13003 avoid text relocations are defined yet have verneed. We could
13004 use a heuristic to detect the special case, for example, check
13005 for verneed first on symbols defined in SHT_NOBITS sections, but
13006 it is simpler and more reliable to just look for both verdef and
13007 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13008
ab273396
AM
13009 if (psym->st_shndx != SHN_UNDEF
13010 && vers_data != 0x8001
978c4450 13011 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13012 {
13013 Elf_Internal_Verdef ivd;
13014 Elf_Internal_Verdaux ivda;
13015 Elf_External_Verdaux evda;
13016 unsigned long off;
bb4d2ac2 13017
dda8d76d 13018 off = offset_from_vma (filedata,
978c4450 13019 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13020 sizeof (Elf_External_Verdef));
13021
13022 do
bb4d2ac2 13023 {
ab273396
AM
13024 Elf_External_Verdef evd;
13025
dda8d76d 13026 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13027 _("version def")) == NULL)
13028 {
13029 ivd.vd_ndx = 0;
13030 ivd.vd_aux = 0;
13031 ivd.vd_next = 0;
1f6f5dba 13032 ivd.vd_flags = 0;
ab273396
AM
13033 }
13034 else
bb4d2ac2 13035 {
ab273396
AM
13036 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13037 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13038 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13039 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13040 }
bb4d2ac2 13041
7a815dd5
L
13042 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13043 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13044
ab273396
AM
13045 off += ivd.vd_next;
13046 }
13047 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13048
ab273396
AM
13049 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13050 {
9abca702 13051 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13052 return NULL;
13053
ab273396
AM
13054 off -= ivd.vd_next;
13055 off += ivd.vd_aux;
bb4d2ac2 13056
dda8d76d 13057 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13058 _("version def aux")) != NULL)
13059 {
13060 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13061
ab273396 13062 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13063 return (ivda.vda_name < strtab_size
13064 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13065 }
13066 }
13067 }
bb4d2ac2 13068
978c4450 13069 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13070 {
13071 Elf_External_Verneed evn;
13072 Elf_Internal_Verneed ivn;
13073 Elf_Internal_Vernaux ivna;
bb4d2ac2 13074
dda8d76d 13075 offset = offset_from_vma (filedata,
978c4450 13076 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13077 sizeof evn);
13078 do
13079 {
13080 unsigned long vna_off;
bb4d2ac2 13081
dda8d76d 13082 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13083 _("version need")) == NULL)
13084 {
13085 ivna.vna_next = 0;
13086 ivna.vna_other = 0;
13087 ivna.vna_name = 0;
13088 break;
13089 }
bb4d2ac2 13090
ab273396
AM
13091 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13092 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13093
ab273396 13094 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13095
ab273396
AM
13096 do
13097 {
13098 Elf_External_Vernaux evna;
bb4d2ac2 13099
dda8d76d 13100 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13101 _("version need aux (3)")) == NULL)
bb4d2ac2 13102 {
ab273396
AM
13103 ivna.vna_next = 0;
13104 ivna.vna_other = 0;
13105 ivna.vna_name = 0;
bb4d2ac2 13106 }
bb4d2ac2 13107 else
bb4d2ac2 13108 {
ab273396
AM
13109 ivna.vna_other = BYTE_GET (evna.vna_other);
13110 ivna.vna_next = BYTE_GET (evna.vna_next);
13111 ivna.vna_name = BYTE_GET (evna.vna_name);
13112 }
bb4d2ac2 13113
ab273396
AM
13114 vna_off += ivna.vna_next;
13115 }
13116 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13117
ab273396
AM
13118 if (ivna.vna_other == vers_data)
13119 break;
bb4d2ac2 13120
ab273396
AM
13121 offset += ivn.vn_next;
13122 }
13123 while (ivn.vn_next != 0);
bb4d2ac2 13124
ab273396
AM
13125 if (ivna.vna_other == vers_data)
13126 {
13127 *sym_info = symbol_undefined;
13128 *vna_other = ivna.vna_other;
13129 return (ivna.vna_name < strtab_size
13130 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13131 }
7a815dd5
L
13132 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13133 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13134 return _("<corrupt>");
bb4d2ac2 13135 }
ab273396 13136 return NULL;
bb4d2ac2
L
13137}
13138
047c3dbf
NL
13139/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13140
13141static unsigned int
625d49fc 13142print_dynamic_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13143{
13144 switch (base)
13145 {
13146 case 8:
13147 return print_vma (vma, OCTAL_5);
13148
13149 case 10:
13150 return print_vma (vma, UNSIGNED_5);
13151
13152 case 16:
13153 return print_vma (vma, PREFIX_HEX_5);
13154
13155 case 0:
13156 default:
13157 return print_vma (vma, DEC_5);
13158 }
13159}
13160
10ca4b04
L
13161static void
13162print_dynamic_symbol (Filedata *filedata, unsigned long si,
13163 Elf_Internal_Sym *symtab,
13164 Elf_Internal_Shdr *section,
13165 char *strtab, size_t strtab_size)
252b5132 13166{
10ca4b04
L
13167 const char *version_string;
13168 enum versioned_symbol_info sym_info;
13169 unsigned short vna_other;
23356397
NC
13170 bool is_valid;
13171 const char * sstr;
10ca4b04 13172 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13173
10ca4b04
L
13174 printf ("%6ld: ", si);
13175 print_vma (psym->st_value, LONG_HEX);
13176 putchar (' ');
047c3dbf 13177 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13178 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13179 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13180 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13181 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13182 else
252b5132 13183 {
10ca4b04 13184 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13185
10ca4b04
L
13186 printf (" %-7s", get_symbol_visibility (vis));
13187 /* Check to see if any other bits in the st_other field are set.
13188 Note - displaying this information disrupts the layout of the
13189 table being generated, but for the moment this case is very rare. */
13190 if (psym->st_other ^ vis)
13191 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13192 }
10ca4b04 13193 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13194
23356397
NC
13195 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13196 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13197 && filedata->section_headers != NULL
23356397
NC
13198 && psym->st_name == 0)
13199 {
84714f86
AM
13200 is_valid
13201 = section_name_valid (filedata,
13202 filedata->section_headers + psym->st_shndx);
23356397 13203 sstr = is_valid ?
84714f86
AM
13204 section_name_print (filedata,
13205 filedata->section_headers + psym->st_shndx)
23356397
NC
13206 : _("<corrupt>");
13207 }
13208 else
13209 {
84714f86 13210 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13211 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13212 }
10ca4b04
L
13213
13214 version_string
13215 = get_symbol_version_string (filedata,
13216 (section == NULL
13217 || section->sh_type == SHT_DYNSYM),
13218 strtab, strtab_size, si,
13219 psym, &sym_info, &vna_other);
b9e920ec 13220
0942c7ab
NC
13221 int len_avail = 21;
13222 if (! do_wide && version_string != NULL)
13223 {
ddb43bab 13224 char buffer[16];
0942c7ab 13225
ddb43bab 13226 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13227
13228 if (sym_info == symbol_undefined)
13229 len_avail -= sprintf (buffer," (%d)", vna_other);
13230 else if (sym_info != symbol_hidden)
13231 len_avail -= 1;
13232 }
13233
13234 print_symbol (len_avail, sstr);
b9e920ec 13235
10ca4b04
L
13236 if (version_string)
13237 {
13238 if (sym_info == symbol_undefined)
13239 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13240 else
10ca4b04
L
13241 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13242 version_string);
13243 }
6bd1a22c 13244
10ca4b04 13245 putchar ('\n');
6bd1a22c 13246
10ca4b04
L
13247 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13248 && section != NULL
13249 && si >= section->sh_info
13250 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13251 && filedata->file_header.e_machine != EM_MIPS
13252 /* Solaris binaries have been found to violate this requirement as
13253 well. Not sure if this is a bug or an ABI requirement. */
13254 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
13255 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
13256 si, printable_section_name (filedata, section), section->sh_info);
13257}
f16a9783 13258
0f03783c
NC
13259static const char *
13260get_lto_kind (unsigned int kind)
13261{
13262 switch (kind)
13263 {
13264 case 0: return "DEF";
13265 case 1: return "WEAKDEF";
13266 case 2: return "UNDEF";
13267 case 3: return "WEAKUNDEF";
13268 case 4: return "COMMON";
13269 default:
13270 break;
13271 }
13272
13273 static char buffer[30];
13274 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13275 sprintf (buffer, "<unknown: %u>", kind);
13276 return buffer;
13277}
13278
13279static const char *
13280get_lto_visibility (unsigned int visibility)
13281{
13282 switch (visibility)
13283 {
13284 case 0: return "DEFAULT";
13285 case 1: return "PROTECTED";
13286 case 2: return "INTERNAL";
13287 case 3: return "HIDDEN";
13288 default:
13289 break;
13290 }
13291
13292 static char buffer[30];
13293 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13294 sprintf (buffer, "<unknown: %u>", visibility);
13295 return buffer;
13296}
13297
13298static const char *
13299get_lto_sym_type (unsigned int sym_type)
13300{
13301 switch (sym_type)
13302 {
13303 case 0: return "UNKNOWN";
13304 case 1: return "FUNCTION";
13305 case 2: return "VARIABLE";
13306 default:
13307 break;
13308 }
13309
13310 static char buffer[30];
13311 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13312 sprintf (buffer, "<unknown: %u>", sym_type);
13313 return buffer;
13314}
13315
13316/* Display an LTO format symbol table.
13317 FIXME: The format of LTO symbol tables is not formalized.
13318 So this code could need changing in the future. */
13319
015dc7e1 13320static bool
0f03783c
NC
13321display_lto_symtab (Filedata * filedata,
13322 Elf_Internal_Shdr * section)
13323{
13324 if (section->sh_size == 0)
13325 {
ca0e11aa
NC
13326 if (filedata->is_separate)
13327 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13328 printable_section_name (filedata, section),
13329 filedata->file_name);
13330 else
13331 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13332 printable_section_name (filedata, section));
047c3dbf 13333
015dc7e1 13334 return true;
0f03783c
NC
13335 }
13336
13337 if (section->sh_size > filedata->file_size)
13338 {
13339 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
13340 printable_section_name (filedata, section),
13341 (unsigned long) section->sh_size);
015dc7e1 13342 return false;
0f03783c
NC
13343 }
13344
13345 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13346 section->sh_size, 1, _("LTO symbols"));
13347 if (alloced_data == NULL)
015dc7e1 13348 return false;
0f03783c
NC
13349
13350 /* Look for extended data for the symbol table. */
13351 Elf_Internal_Shdr * ext;
13352 void * ext_data_orig = NULL;
13353 char * ext_data = NULL;
13354 char * ext_data_end = NULL;
13355 char * ext_name = NULL;
13356
13357 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13358 (section_name (filedata, section)
13359 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13360 && ext_name != NULL /* Paranoia. */
13361 && (ext = find_section (filedata, ext_name)) != NULL)
13362 {
13363 if (ext->sh_size < 3)
13364 error (_("LTO Symbol extension table '%s' is empty!\n"),
13365 printable_section_name (filedata, ext));
13366 else
13367 {
13368 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13369 ext->sh_size, 1,
13370 _("LTO ext symbol data"));
13371 if (ext_data != NULL)
13372 {
13373 ext_data_end = ext_data + ext->sh_size;
13374 if (* ext_data++ != 1)
13375 error (_("Unexpected version number in symbol extension table\n"));
13376 }
13377 }
13378 }
b9e920ec 13379
0f03783c
NC
13380 const unsigned char * data = (const unsigned char *) alloced_data;
13381 const unsigned char * end = data + section->sh_size;
13382
ca0e11aa
NC
13383 if (filedata->is_separate)
13384 printf (_("\nIn linked file '%s': "), filedata->file_name);
13385 else
13386 printf ("\n");
13387
0f03783c
NC
13388 if (ext_data_orig != NULL)
13389 {
13390 if (do_wide)
ca0e11aa 13391 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13392 printable_section_name (filedata, section),
13393 printable_section_name (filedata, ext));
13394 else
13395 {
ca0e11aa 13396 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13397 printable_section_name (filedata, section));
13398 printf (_(" and extension table '%s' contain:\n"),
13399 printable_section_name (filedata, ext));
13400 }
13401 }
13402 else
ca0e11aa 13403 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13404 printable_section_name (filedata, section));
b9e920ec 13405
0f03783c 13406 /* FIXME: Add a wide version. */
b9e920ec 13407 if (ext_data_orig != NULL)
0f03783c
NC
13408 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13409 else
13410 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13411
13412 /* FIXME: We do not handle style prefixes. */
13413
13414 while (data < end)
13415 {
13416 const unsigned char * sym_name = data;
13417 data += strnlen ((const char *) sym_name, end - data) + 1;
13418 if (data >= end)
13419 goto fail;
13420
13421 const unsigned char * comdat_key = data;
13422 data += strnlen ((const char *) comdat_key, end - data) + 1;
13423 if (data >= end)
13424 goto fail;
13425
13426 if (data + 2 + 8 + 4 > end)
13427 goto fail;
13428
13429 unsigned int kind = *data++;
13430 unsigned int visibility = *data++;
13431
928c411d 13432 uint64_t size = byte_get (data, 8);
0f03783c
NC
13433 data += 8;
13434
928c411d 13435 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13436 data += 4;
13437
13438 if (ext_data != NULL)
13439 {
13440 if (ext_data < (ext_data_end - 1))
13441 {
13442 unsigned int sym_type = * ext_data ++;
13443 unsigned int sec_kind = * ext_data ++;
13444
31e5a3a3 13445 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
13446 * comdat_key == 0 ? "-" : (char *) comdat_key,
13447 get_lto_kind (kind),
13448 get_lto_visibility (visibility),
31e5a3a3
AM
13449 size,
13450 slot,
0f03783c 13451 get_lto_sym_type (sym_type),
31e5a3a3 13452 sec_kind);
0f03783c
NC
13453 print_symbol (6, (const char *) sym_name);
13454 }
13455 else
13456 {
13457 error (_("Ran out of LTO symbol extension data\n"));
13458 ext_data = NULL;
13459 /* FIXME: return FAIL result ? */
13460 }
13461 }
13462 else
13463 {
31e5a3a3 13464 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
13465 * comdat_key == 0 ? "-" : (char *) comdat_key,
13466 get_lto_kind (kind),
13467 get_lto_visibility (visibility),
31e5a3a3
AM
13468 size,
13469 slot);
0f03783c
NC
13470 print_symbol (21, (const char *) sym_name);
13471 }
13472 putchar ('\n');
13473 }
13474
13475 if (ext_data != NULL && ext_data < ext_data_end)
13476 {
13477 error (_("Data remains in the LTO symbol extension table\n"));
13478 goto fail;
13479 }
13480
13481 free (alloced_data);
13482 free (ext_data_orig);
13483 free (ext_name);
015dc7e1 13484 return true;
b9e920ec 13485
0f03783c
NC
13486 fail:
13487 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13488 free (alloced_data);
13489 free (ext_data_orig);
13490 free (ext_name);
015dc7e1 13491 return false;
0f03783c
NC
13492}
13493
13494/* Display LTO symbol tables. */
13495
015dc7e1 13496static bool
0f03783c
NC
13497process_lto_symbol_tables (Filedata * filedata)
13498{
13499 Elf_Internal_Shdr * section;
13500 unsigned int i;
015dc7e1 13501 bool res = true;
0f03783c
NC
13502
13503 if (!do_lto_syms)
015dc7e1 13504 return true;
0f03783c
NC
13505
13506 if (filedata->section_headers == NULL)
015dc7e1 13507 return true;
0f03783c
NC
13508
13509 for (i = 0, section = filedata->section_headers;
13510 i < filedata->file_header.e_shnum;
13511 i++, section++)
84714f86
AM
13512 if (section_name_valid (filedata, section)
13513 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13514 res &= display_lto_symtab (filedata, section);
13515
b9e920ec 13516 return res;
0f03783c
NC
13517}
13518
10ca4b04 13519/* Dump the symbol table. */
0f03783c 13520
015dc7e1 13521static bool
10ca4b04
L
13522process_symbol_table (Filedata * filedata)
13523{
13524 Elf_Internal_Shdr * section;
f16a9783 13525
10ca4b04 13526 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13527 return true;
6bd1a22c 13528
978c4450 13529 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13530 && do_syms
13531 && do_using_dynamic
978c4450
AM
13532 && filedata->dynamic_strings != NULL
13533 && filedata->dynamic_symbols != NULL)
6bd1a22c 13534 {
10ca4b04 13535 unsigned long si;
6bd1a22c 13536
ca0e11aa
NC
13537 if (filedata->is_separate)
13538 {
13539 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
13540 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
13541 filedata->num_dynamic_syms),
13542 filedata->file_name,
13543 filedata->num_dynamic_syms);
13544 }
13545 else
13546 {
13547 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
13548 "\nSymbol table for image contains %lu entries:\n",
13549 filedata->num_dynamic_syms),
13550 filedata->num_dynamic_syms);
13551 }
10ca4b04
L
13552 if (is_32bit_elf)
13553 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13554 else
13555 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13556
978c4450
AM
13557 for (si = 0; si < filedata->num_dynamic_syms; si++)
13558 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13559 filedata->dynamic_strings,
13560 filedata->dynamic_strings_length);
252b5132 13561 }
8b73c356 13562 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13563 && filedata->section_headers != NULL)
252b5132 13564 {
b34976b6 13565 unsigned int i;
252b5132 13566
dda8d76d
NC
13567 for (i = 0, section = filedata->section_headers;
13568 i < filedata->file_header.e_shnum;
252b5132
RH
13569 i++, section++)
13570 {
2cf0635d 13571 char * strtab = NULL;
c256ffe7 13572 unsigned long int strtab_size = 0;
2cf0635d 13573 Elf_Internal_Sym * symtab;
ef3df110 13574 unsigned long si, num_syms;
252b5132 13575
2c610e4b
L
13576 if ((section->sh_type != SHT_SYMTAB
13577 && section->sh_type != SHT_DYNSYM)
13578 || (!do_syms
13579 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13580 continue;
13581
dd24e3da
NC
13582 if (section->sh_entsize == 0)
13583 {
13584 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13585 printable_section_name (filedata, section));
dd24e3da
NC
13586 continue;
13587 }
13588
d3a49aa8 13589 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13590
13591 if (filedata->is_separate)
13592 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13593 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13594 num_syms),
13595 filedata->file_name,
13596 printable_section_name (filedata, section),
13597 num_syms);
13598 else
13599 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13600 "\nSymbol table '%s' contains %lu entries:\n",
13601 num_syms),
13602 printable_section_name (filedata, section),
13603 num_syms);
dd24e3da 13604
f7a99963 13605 if (is_32bit_elf)
ca47b30c 13606 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13607 else
ca47b30c 13608 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13609
4de91c10 13610 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13611 if (symtab == NULL)
13612 continue;
13613
dda8d76d 13614 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13615 {
dda8d76d
NC
13616 strtab = filedata->string_table;
13617 strtab_size = filedata->string_table_length;
c256ffe7 13618 }
dda8d76d 13619 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13620 {
2cf0635d 13621 Elf_Internal_Shdr * string_sec;
252b5132 13622
dda8d76d 13623 string_sec = filedata->section_headers + section->sh_link;
252b5132 13624
dda8d76d 13625 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13626 1, string_sec->sh_size,
13627 _("string table"));
c256ffe7 13628 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13629 }
13630
10ca4b04
L
13631 for (si = 0; si < num_syms; si++)
13632 print_dynamic_symbol (filedata, si, symtab, section,
13633 strtab, strtab_size);
252b5132
RH
13634
13635 free (symtab);
dda8d76d 13636 if (strtab != filedata->string_table)
252b5132
RH
13637 free (strtab);
13638 }
13639 }
13640 else if (do_syms)
13641 printf
13642 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13643
978c4450 13644 if (do_histogram && filedata->buckets != NULL)
252b5132 13645 {
2cf0635d
NC
13646 unsigned long * lengths;
13647 unsigned long * counts;
66543521 13648 unsigned long hn;
625d49fc 13649 uint64_t si;
66543521
AM
13650 unsigned long maxlength = 0;
13651 unsigned long nzero_counts = 0;
13652 unsigned long nsyms = 0;
6bd6a03d 13653 char *visited;
252b5132 13654
d3a49aa8
AM
13655 printf (ngettext ("\nHistogram for bucket list length "
13656 "(total of %lu bucket):\n",
13657 "\nHistogram for bucket list length "
13658 "(total of %lu buckets):\n",
978c4450
AM
13659 (unsigned long) filedata->nbuckets),
13660 (unsigned long) filedata->nbuckets);
252b5132 13661
978c4450
AM
13662 lengths = (unsigned long *) calloc (filedata->nbuckets,
13663 sizeof (*lengths));
252b5132
RH
13664 if (lengths == NULL)
13665 {
8b73c356 13666 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13667 goto err_out;
252b5132 13668 }
978c4450
AM
13669 visited = xcmalloc (filedata->nchains, 1);
13670 memset (visited, 0, filedata->nchains);
8b73c356
NC
13671
13672 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13673 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13674 {
978c4450 13675 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13676 {
b34976b6 13677 ++nsyms;
252b5132 13678 if (maxlength < ++lengths[hn])
b34976b6 13679 ++maxlength;
978c4450 13680 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13681 {
13682 error (_("histogram chain is corrupt\n"));
13683 break;
13684 }
13685 visited[si] = 1;
252b5132
RH
13686 }
13687 }
6bd6a03d 13688 free (visited);
252b5132 13689
3f5e193b 13690 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13691 if (counts == NULL)
13692 {
b2e951ec 13693 free (lengths);
8b73c356 13694 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13695 goto err_out;
252b5132
RH
13696 }
13697
978c4450 13698 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13699 ++counts[lengths[hn]];
252b5132 13700
978c4450 13701 if (filedata->nbuckets > 0)
252b5132 13702 {
66543521
AM
13703 unsigned long i;
13704 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13705 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13706 for (i = 1; i <= maxlength; ++i)
103f02d3 13707 {
66543521
AM
13708 nzero_counts += counts[i] * i;
13709 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13710 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13711 (nzero_counts * 100.0) / nsyms);
13712 }
252b5132
RH
13713 }
13714
13715 free (counts);
13716 free (lengths);
13717 }
13718
978c4450
AM
13719 free (filedata->buckets);
13720 filedata->buckets = NULL;
13721 filedata->nbuckets = 0;
13722 free (filedata->chains);
13723 filedata->chains = NULL;
252b5132 13724
978c4450 13725 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13726 {
2cf0635d
NC
13727 unsigned long * lengths;
13728 unsigned long * counts;
fdc90cb4
JJ
13729 unsigned long hn;
13730 unsigned long maxlength = 0;
13731 unsigned long nzero_counts = 0;
13732 unsigned long nsyms = 0;
fdc90cb4 13733
f16a9783 13734 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13735 "(total of %lu bucket):\n",
f16a9783 13736 "\nHistogram for `%s' bucket list length "
d3a49aa8 13737 "(total of %lu buckets):\n",
978c4450
AM
13738 (unsigned long) filedata->ngnubuckets),
13739 GNU_HASH_SECTION_NAME (filedata),
13740 (unsigned long) filedata->ngnubuckets);
8b73c356 13741
978c4450
AM
13742 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13743 sizeof (*lengths));
fdc90cb4
JJ
13744 if (lengths == NULL)
13745 {
8b73c356 13746 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13747 goto err_out;
fdc90cb4
JJ
13748 }
13749
fdc90cb4
JJ
13750 printf (_(" Length Number %% of total Coverage\n"));
13751
978c4450
AM
13752 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13753 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 13754 {
625d49fc 13755 uint64_t off, length = 1;
fdc90cb4 13756
978c4450 13757 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13758 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13759 off < filedata->ngnuchains
13760 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13761 ++off)
fdc90cb4
JJ
13762 ++length;
13763 lengths[hn] = length;
13764 if (length > maxlength)
13765 maxlength = length;
13766 nsyms += length;
13767 }
13768
3f5e193b 13769 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13770 if (counts == NULL)
13771 {
b2e951ec 13772 free (lengths);
8b73c356 13773 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13774 goto err_out;
fdc90cb4
JJ
13775 }
13776
978c4450 13777 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13778 ++counts[lengths[hn]];
13779
978c4450 13780 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13781 {
13782 unsigned long j;
13783 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13784 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13785 for (j = 1; j <= maxlength; ++j)
13786 {
13787 nzero_counts += counts[j] * j;
13788 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13789 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13790 (nzero_counts * 100.0) / nsyms);
13791 }
13792 }
13793
13794 free (counts);
13795 free (lengths);
fdc90cb4 13796 }
978c4450
AM
13797 free (filedata->gnubuckets);
13798 filedata->gnubuckets = NULL;
13799 filedata->ngnubuckets = 0;
13800 free (filedata->gnuchains);
13801 filedata->gnuchains = NULL;
13802 filedata->ngnuchains = 0;
13803 free (filedata->mipsxlat);
13804 filedata->mipsxlat = NULL;
015dc7e1 13805 return true;
fd486f32
AM
13806
13807 err_out:
978c4450
AM
13808 free (filedata->gnubuckets);
13809 filedata->gnubuckets = NULL;
13810 filedata->ngnubuckets = 0;
13811 free (filedata->gnuchains);
13812 filedata->gnuchains = NULL;
13813 filedata->ngnuchains = 0;
13814 free (filedata->mipsxlat);
13815 filedata->mipsxlat = NULL;
13816 free (filedata->buckets);
13817 filedata->buckets = NULL;
13818 filedata->nbuckets = 0;
13819 free (filedata->chains);
13820 filedata->chains = NULL;
015dc7e1 13821 return false;
252b5132
RH
13822}
13823
015dc7e1 13824static bool
ca0e11aa 13825process_syminfo (Filedata * filedata)
252b5132 13826{
b4c96d0d 13827 unsigned int i;
252b5132 13828
978c4450 13829 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13830 || !do_dynamic)
13831 /* No syminfo, this is ok. */
015dc7e1 13832 return true;
252b5132
RH
13833
13834 /* There better should be a dynamic symbol section. */
978c4450 13835 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13836 return false;
252b5132 13837
ca0e11aa
NC
13838 if (filedata->is_separate)
13839 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13840 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13841 filedata->dynamic_syminfo_nent),
13842 filedata->file_name,
13843 filedata->dynamic_syminfo_offset,
13844 filedata->dynamic_syminfo_nent);
13845 else
d3a49aa8
AM
13846 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13847 "contains %d entry:\n",
13848 "\nDynamic info segment at offset 0x%lx "
13849 "contains %d entries:\n",
978c4450 13850 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13851 filedata->dynamic_syminfo_offset,
13852 filedata->dynamic_syminfo_nent);
252b5132
RH
13853
13854 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13855 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13856 {
978c4450 13857 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13858
31104126 13859 printf ("%4d: ", i);
978c4450 13860 if (i >= filedata->num_dynamic_syms)
4082ef84 13861 printf (_("<corrupt index>"));
84714f86
AM
13862 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13863 print_symbol (30, get_dynamic_name (filedata,
978c4450 13864 filedata->dynamic_symbols[i].st_name));
d79b3d50 13865 else
978c4450 13866 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13867 putchar (' ');
252b5132 13868
978c4450 13869 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13870 {
13871 case SYMINFO_BT_SELF:
13872 fputs ("SELF ", stdout);
13873 break;
13874 case SYMINFO_BT_PARENT:
13875 fputs ("PARENT ", stdout);
13876 break;
13877 default:
978c4450
AM
13878 if (filedata->dynamic_syminfo[i].si_boundto > 0
13879 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13880 && valid_dynamic_name (filedata,
978c4450 13881 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13882 {
84714f86 13883 print_symbol (10, get_dynamic_name (filedata,
978c4450 13884 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13885 putchar (' ' );
13886 }
252b5132 13887 else
978c4450 13888 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13889 break;
13890 }
13891
13892 if (flags & SYMINFO_FLG_DIRECT)
13893 printf (" DIRECT");
13894 if (flags & SYMINFO_FLG_PASSTHRU)
13895 printf (" PASSTHRU");
13896 if (flags & SYMINFO_FLG_COPY)
13897 printf (" COPY");
13898 if (flags & SYMINFO_FLG_LAZYLOAD)
13899 printf (" LAZYLOAD");
13900
13901 puts ("");
13902 }
13903
015dc7e1 13904 return true;
252b5132
RH
13905}
13906
75802ccb
CE
13907/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13908 is contained by the region START .. END. The types of ADDR, START
13909 and END should all be the same. Note both ADDR + NELEM and END
13910 point to just beyond the end of the regions that are being tested. */
13911#define IN_RANGE(START,END,ADDR,NELEM) \
13912 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13913
cf13d699
NC
13914/* Check to see if the given reloc needs to be handled in a target specific
13915 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13916 FALSE.
13917
13918 If called with reloc == NULL, then this is a signal that reloc processing
13919 for the current section has finished, and any saved state should be
13920 discarded. */
09c11c86 13921
015dc7e1 13922static bool
dda8d76d
NC
13923target_specific_reloc_handling (Filedata * filedata,
13924 Elf_Internal_Rela * reloc,
13925 unsigned char * start,
13926 unsigned char * end,
13927 Elf_Internal_Sym * symtab,
13928 unsigned long num_syms)
252b5132 13929{
f84ce13b
NC
13930 unsigned int reloc_type = 0;
13931 unsigned long sym_index = 0;
13932
13933 if (reloc)
13934 {
dda8d76d 13935 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13936 sym_index = get_reloc_symindex (reloc->r_info);
13937 }
252b5132 13938
dda8d76d 13939 switch (filedata->file_header.e_machine)
252b5132 13940 {
13761a11
NC
13941 case EM_MSP430:
13942 case EM_MSP430_OLD:
13943 {
13944 static Elf_Internal_Sym * saved_sym = NULL;
13945
f84ce13b
NC
13946 if (reloc == NULL)
13947 {
13948 saved_sym = NULL;
015dc7e1 13949 return true;
f84ce13b
NC
13950 }
13951
13761a11
NC
13952 switch (reloc_type)
13953 {
13954 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13955 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13956 if (uses_msp430x_relocs (filedata))
13761a11 13957 break;
1a0670f3 13958 /* Fall through. */
13761a11 13959 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13960 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13961 /* PR 21139. */
13962 if (sym_index >= num_syms)
13963 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13964 sym_index);
13965 else
13966 saved_sym = symtab + sym_index;
015dc7e1 13967 return true;
13761a11
NC
13968
13969 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13970 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13971 goto handle_sym_diff;
0b4362b0 13972
13761a11
NC
13973 case 5: /* R_MSP430_16_BYTE */
13974 case 9: /* R_MSP430_8 */
7d81bc93 13975 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13976 if (uses_msp430x_relocs (filedata))
13761a11
NC
13977 break;
13978 goto handle_sym_diff;
13979
13980 case 2: /* R_MSP430_ABS16 */
13981 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13982 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13983 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13984 break;
13985 goto handle_sym_diff;
0b4362b0 13986
13761a11
NC
13987 handle_sym_diff:
13988 if (saved_sym != NULL)
13989 {
625d49fc 13990 uint64_t value;
5a805384 13991 unsigned int reloc_size = 0;
7d81bc93
JL
13992 int leb_ret = 0;
13993 switch (reloc_type)
13994 {
13995 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13996 reloc_size = 4;
13997 break;
13998 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13999 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14000 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14001 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14002 &reloc_size, &leb_ret);
7d81bc93
JL
14003 break;
14004 default:
14005 reloc_size = 2;
14006 break;
14007 }
13761a11 14008
5a805384 14009 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
14010 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
14011 "ULEB128 value\n"),
14012 (long) reloc->r_offset);
14013 else if (sym_index >= num_syms)
f84ce13b
NC
14014 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
14015 sym_index);
03f7786e 14016 else
f84ce13b
NC
14017 {
14018 value = reloc->r_addend + (symtab[sym_index].st_value
14019 - saved_sym->st_value);
14020
b32e566b 14021 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14022 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14023 else
14024 /* PR 21137 */
14025 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
14026 (long) reloc->r_offset);
f84ce13b 14027 }
13761a11
NC
14028
14029 saved_sym = NULL;
015dc7e1 14030 return true;
13761a11
NC
14031 }
14032 break;
14033
14034 default:
14035 if (saved_sym != NULL)
071436c6 14036 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14037 break;
14038 }
14039 break;
14040 }
14041
cf13d699
NC
14042 case EM_MN10300:
14043 case EM_CYGNUS_MN10300:
14044 {
14045 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14046
f84ce13b
NC
14047 if (reloc == NULL)
14048 {
14049 saved_sym = NULL;
015dc7e1 14050 return true;
f84ce13b
NC
14051 }
14052
cf13d699
NC
14053 switch (reloc_type)
14054 {
14055 case 34: /* R_MN10300_ALIGN */
015dc7e1 14056 return true;
cf13d699 14057 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
14058 if (sym_index >= num_syms)
14059 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
14060 sym_index);
14061 else
14062 saved_sym = symtab + sym_index;
015dc7e1 14063 return true;
f84ce13b 14064
cf13d699
NC
14065 case 1: /* R_MN10300_32 */
14066 case 2: /* R_MN10300_16 */
14067 if (saved_sym != NULL)
14068 {
03f7786e 14069 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14070 uint64_t value;
252b5132 14071
f84ce13b
NC
14072 if (sym_index >= num_syms)
14073 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
14074 sym_index);
03f7786e 14075 else
f84ce13b
NC
14076 {
14077 value = reloc->r_addend + (symtab[sym_index].st_value
14078 - saved_sym->st_value);
14079
b32e566b 14080 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14081 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14082 else
14083 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
14084 (long) reloc->r_offset);
f84ce13b 14085 }
252b5132 14086
cf13d699 14087 saved_sym = NULL;
015dc7e1 14088 return true;
cf13d699
NC
14089 }
14090 break;
14091 default:
14092 if (saved_sym != NULL)
071436c6 14093 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14094 break;
14095 }
14096 break;
14097 }
6ff71e76
NC
14098
14099 case EM_RL78:
14100 {
625d49fc
AM
14101 static uint64_t saved_sym1 = 0;
14102 static uint64_t saved_sym2 = 0;
14103 static uint64_t value;
6ff71e76 14104
f84ce13b
NC
14105 if (reloc == NULL)
14106 {
14107 saved_sym1 = saved_sym2 = 0;
015dc7e1 14108 return true;
f84ce13b
NC
14109 }
14110
6ff71e76
NC
14111 switch (reloc_type)
14112 {
14113 case 0x80: /* R_RL78_SYM. */
14114 saved_sym1 = saved_sym2;
f84ce13b
NC
14115 if (sym_index >= num_syms)
14116 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
14117 sym_index);
14118 else
14119 {
14120 saved_sym2 = symtab[sym_index].st_value;
14121 saved_sym2 += reloc->r_addend;
14122 }
015dc7e1 14123 return true;
6ff71e76
NC
14124
14125 case 0x83: /* R_RL78_OPsub. */
14126 value = saved_sym1 - saved_sym2;
14127 saved_sym2 = saved_sym1 = 0;
015dc7e1 14128 return true;
6ff71e76
NC
14129 break;
14130
14131 case 0x41: /* R_RL78_ABS32. */
b32e566b 14132 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14133 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
14134 else
14135 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14136 (long) reloc->r_offset);
6ff71e76 14137 value = 0;
015dc7e1 14138 return true;
6ff71e76
NC
14139
14140 case 0x43: /* R_RL78_ABS16. */
b32e566b 14141 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14142 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
14143 else
14144 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14145 (long) reloc->r_offset);
6ff71e76 14146 value = 0;
015dc7e1 14147 return true;
6ff71e76
NC
14148
14149 default:
14150 break;
14151 }
14152 break;
14153 }
252b5132
RH
14154 }
14155
015dc7e1 14156 return false;
252b5132
RH
14157}
14158
aca88567
NC
14159/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14160 DWARF debug sections. This is a target specific test. Note - we do not
14161 go through the whole including-target-headers-multiple-times route, (as
14162 we have already done with <elf/h8.h>) because this would become very
14163 messy and even then this function would have to contain target specific
14164 information (the names of the relocs instead of their numeric values).
14165 FIXME: This is not the correct way to solve this problem. The proper way
14166 is to have target specific reloc sizing and typing functions created by
14167 the reloc-macros.h header, in the same way that it already creates the
14168 reloc naming functions. */
14169
015dc7e1 14170static bool
dda8d76d 14171is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14172{
d347c9df 14173 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14174 switch (filedata->file_header.e_machine)
aca88567 14175 {
41e92641 14176 case EM_386:
22abe556 14177 case EM_IAMCU:
41e92641 14178 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14179 case EM_68K:
14180 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14181 case EM_860:
14182 return reloc_type == 1; /* R_860_32. */
14183 case EM_960:
14184 return reloc_type == 2; /* R_960_32. */
a06ea964 14185 case EM_AARCH64:
9282b95a
JW
14186 return (reloc_type == 258
14187 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14188 case EM_BPF:
14189 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14190 case EM_ADAPTEVA_EPIPHANY:
14191 return reloc_type == 3;
aca88567 14192 case EM_ALPHA:
137b6b5f 14193 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14194 case EM_ARC:
14195 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14196 case EM_ARC_COMPACT:
14197 case EM_ARC_COMPACT2:
14198 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14199 case EM_ARM:
14200 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14201 case EM_AVR_OLD:
aca88567
NC
14202 case EM_AVR:
14203 return reloc_type == 1;
14204 case EM_BLACKFIN:
14205 return reloc_type == 0x12; /* R_byte4_data. */
14206 case EM_CRIS:
14207 return reloc_type == 3; /* R_CRIS_32. */
14208 case EM_CR16:
14209 return reloc_type == 3; /* R_CR16_NUM32. */
14210 case EM_CRX:
14211 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14212 case EM_CSKY:
14213 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14214 case EM_CYGNUS_FRV:
14215 return reloc_type == 1;
41e92641
NC
14216 case EM_CYGNUS_D10V:
14217 case EM_D10V:
14218 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14219 case EM_CYGNUS_D30V:
14220 case EM_D30V:
14221 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14222 case EM_DLX:
14223 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14224 case EM_CYGNUS_FR30:
14225 case EM_FR30:
14226 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14227 case EM_FT32:
14228 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14229 case EM_H8S:
14230 case EM_H8_300:
14231 case EM_H8_300H:
14232 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14233 case EM_IA_64:
262cdac7
AM
14234 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14235 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14236 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14237 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14238 case EM_IP2K_OLD:
14239 case EM_IP2K:
14240 return reloc_type == 2; /* R_IP2K_32. */
14241 case EM_IQ2000:
14242 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14243 case EM_LATTICEMICO32:
14244 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14245 case EM_LOONGARCH:
14246 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14247 case EM_M32C_OLD:
aca88567
NC
14248 case EM_M32C:
14249 return reloc_type == 3; /* R_M32C_32. */
14250 case EM_M32R:
14251 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14252 case EM_68HC11:
14253 case EM_68HC12:
14254 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14255 case EM_S12Z:
2849d19f
JD
14256 return reloc_type == 7 || /* R_S12Z_EXT32 */
14257 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14258 case EM_MCORE:
14259 return reloc_type == 1; /* R_MCORE_ADDR32. */
14260 case EM_CYGNUS_MEP:
14261 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14262 case EM_METAG:
14263 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14264 case EM_MICROBLAZE:
14265 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14266 case EM_MIPS:
14267 return reloc_type == 2; /* R_MIPS_32. */
14268 case EM_MMIX:
14269 return reloc_type == 4; /* R_MMIX_32. */
14270 case EM_CYGNUS_MN10200:
14271 case EM_MN10200:
14272 return reloc_type == 1; /* R_MN10200_32. */
14273 case EM_CYGNUS_MN10300:
14274 case EM_MN10300:
14275 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14276 case EM_MOXIE:
14277 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14278 case EM_MSP430_OLD:
14279 case EM_MSP430:
13761a11 14280 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14281 case EM_MT:
14282 return reloc_type == 2; /* R_MT_32. */
35c08157 14283 case EM_NDS32:
81c5e376 14284 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14285 case EM_ALTERA_NIOS2:
36591ba1 14286 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14287 case EM_NIOS32:
14288 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14289 case EM_OR1K:
14290 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14291 case EM_PARISC:
9abca702 14292 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14293 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14294 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14295 case EM_PJ:
14296 case EM_PJ_OLD:
14297 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14298 case EM_PPC64:
14299 return reloc_type == 1; /* R_PPC64_ADDR32. */
14300 case EM_PPC:
14301 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14302 case EM_TI_PRU:
14303 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14304 case EM_RISCV:
14305 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14306 case EM_RL78:
14307 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14308 case EM_RX:
14309 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14310 case EM_S370:
14311 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14312 case EM_S390_OLD:
14313 case EM_S390:
14314 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14315 case EM_SCORE:
14316 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14317 case EM_SH:
14318 return reloc_type == 1; /* R_SH_DIR32. */
14319 case EM_SPARC32PLUS:
14320 case EM_SPARCV9:
14321 case EM_SPARC:
14322 return reloc_type == 3 /* R_SPARC_32. */
14323 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14324 case EM_SPU:
14325 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14326 case EM_TI_C6000:
14327 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14328 case EM_TILEGX:
14329 return reloc_type == 2; /* R_TILEGX_32. */
14330 case EM_TILEPRO:
14331 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14332 case EM_CYGNUS_V850:
14333 case EM_V850:
14334 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14335 case EM_V800:
14336 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14337 case EM_VAX:
14338 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14339 case EM_VISIUM:
14340 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14341 case EM_WEBASSEMBLY:
14342 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14343 case EM_X86_64:
8a9036a4 14344 case EM_L1OM:
7a9068fe 14345 case EM_K1OM:
aca88567 14346 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14347 case EM_XGATE:
14348 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14349 case EM_XSTORMY16:
14350 return reloc_type == 1; /* R_XSTROMY16_32. */
14351 case EM_XTENSA_OLD:
14352 case EM_XTENSA:
14353 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14354 case EM_Z80:
14355 return reloc_type == 6; /* R_Z80_32. */
aca88567 14356 default:
bee0ee85
NC
14357 {
14358 static unsigned int prev_warn = 0;
14359
14360 /* Avoid repeating the same warning multiple times. */
dda8d76d 14361 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14362 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14363 filedata->file_header.e_machine);
14364 prev_warn = filedata->file_header.e_machine;
015dc7e1 14365 return false;
bee0ee85 14366 }
aca88567
NC
14367 }
14368}
14369
14370/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14371 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14372
015dc7e1 14373static bool
dda8d76d 14374is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14375{
dda8d76d 14376 switch (filedata->file_header.e_machine)
d347c9df 14377 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14378 {
41e92641 14379 case EM_386:
22abe556 14380 case EM_IAMCU:
3e0873ac 14381 return reloc_type == 2; /* R_386_PC32. */
aca88567 14382 case EM_68K:
3e0873ac 14383 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14384 case EM_AARCH64:
14385 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14386 case EM_ADAPTEVA_EPIPHANY:
14387 return reloc_type == 6;
aca88567
NC
14388 case EM_ALPHA:
14389 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14390 case EM_ARC_COMPACT:
14391 case EM_ARC_COMPACT2:
14392 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14393 case EM_ARM:
3e0873ac 14394 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14395 case EM_AVR_OLD:
14396 case EM_AVR:
14397 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14398 case EM_LOONGARCH:
14399 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14400 case EM_MICROBLAZE:
14401 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14402 case EM_OR1K:
14403 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14404 case EM_PARISC:
85acf597 14405 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14406 case EM_PPC:
14407 return reloc_type == 26; /* R_PPC_REL32. */
14408 case EM_PPC64:
3e0873ac 14409 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14410 case EM_RISCV:
14411 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14412 case EM_S390_OLD:
14413 case EM_S390:
3e0873ac 14414 return reloc_type == 5; /* R_390_PC32. */
aca88567 14415 case EM_SH:
3e0873ac 14416 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14417 case EM_SPARC32PLUS:
14418 case EM_SPARCV9:
14419 case EM_SPARC:
3e0873ac 14420 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14421 case EM_SPU:
14422 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14423 case EM_TILEGX:
14424 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14425 case EM_TILEPRO:
14426 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14427 case EM_VISIUM:
14428 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14429 case EM_X86_64:
8a9036a4 14430 case EM_L1OM:
7a9068fe 14431 case EM_K1OM:
3e0873ac 14432 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14433 case EM_VAX:
14434 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14435 case EM_XTENSA_OLD:
14436 case EM_XTENSA:
14437 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14438 default:
14439 /* Do not abort or issue an error message here. Not all targets use
14440 pc-relative 32-bit relocs in their DWARF debug information and we
14441 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14442 more helpful warning message will be generated by apply_relocations
14443 anyway, so just return. */
015dc7e1 14444 return false;
aca88567
NC
14445 }
14446}
14447
14448/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14449 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14450
015dc7e1 14451static bool
dda8d76d 14452is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14453{
dda8d76d 14454 switch (filedata->file_header.e_machine)
aca88567 14455 {
a06ea964
NC
14456 case EM_AARCH64:
14457 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14458 case EM_ALPHA:
14459 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14460 case EM_IA_64:
262cdac7
AM
14461 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14462 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14463 case EM_LOONGARCH:
14464 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14465 case EM_PARISC:
14466 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14467 case EM_PPC64:
14468 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14469 case EM_RISCV:
14470 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14471 case EM_SPARC32PLUS:
14472 case EM_SPARCV9:
14473 case EM_SPARC:
714da62f
NC
14474 return reloc_type == 32 /* R_SPARC_64. */
14475 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14476 case EM_X86_64:
8a9036a4 14477 case EM_L1OM:
7a9068fe 14478 case EM_K1OM:
aca88567 14479 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14480 case EM_S390_OLD:
14481 case EM_S390:
aa137e4d
NC
14482 return reloc_type == 22; /* R_S390_64. */
14483 case EM_TILEGX:
14484 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14485 case EM_MIPS:
aa137e4d 14486 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14487 default:
015dc7e1 14488 return false;
aca88567
NC
14489 }
14490}
14491
85acf597
RH
14492/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14493 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14494
015dc7e1 14495static bool
dda8d76d 14496is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14497{
dda8d76d 14498 switch (filedata->file_header.e_machine)
85acf597 14499 {
a06ea964
NC
14500 case EM_AARCH64:
14501 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14502 case EM_ALPHA:
aa137e4d 14503 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14504 case EM_IA_64:
262cdac7
AM
14505 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14506 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14507 case EM_PARISC:
aa137e4d 14508 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14509 case EM_PPC64:
aa137e4d 14510 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14511 case EM_SPARC32PLUS:
14512 case EM_SPARCV9:
14513 case EM_SPARC:
aa137e4d 14514 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14515 case EM_X86_64:
8a9036a4 14516 case EM_L1OM:
7a9068fe 14517 case EM_K1OM:
aa137e4d 14518 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14519 case EM_S390_OLD:
14520 case EM_S390:
aa137e4d
NC
14521 return reloc_type == 23; /* R_S390_PC64. */
14522 case EM_TILEGX:
14523 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14524 default:
015dc7e1 14525 return false;
85acf597
RH
14526 }
14527}
14528
4dc3c23d
AM
14529/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14530 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14531
015dc7e1 14532static bool
dda8d76d 14533is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14534{
dda8d76d 14535 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14536 {
14537 case EM_CYGNUS_MN10200:
14538 case EM_MN10200:
14539 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14540 case EM_FT32:
14541 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14542 case EM_Z80:
14543 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14544 default:
015dc7e1 14545 return false;
4dc3c23d
AM
14546 }
14547}
14548
aca88567
NC
14549/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14550 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14551
015dc7e1 14552static bool
dda8d76d 14553is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14554{
d347c9df 14555 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14556 switch (filedata->file_header.e_machine)
4b78141a 14557 {
886a2506
NC
14558 case EM_ARC:
14559 case EM_ARC_COMPACT:
14560 case EM_ARC_COMPACT2:
14561 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14562 case EM_ADAPTEVA_EPIPHANY:
14563 return reloc_type == 5;
aca88567
NC
14564 case EM_AVR_OLD:
14565 case EM_AVR:
14566 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14567 case EM_CYGNUS_D10V:
14568 case EM_D10V:
14569 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14570 case EM_FT32:
14571 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14572 case EM_H8S:
14573 case EM_H8_300:
14574 case EM_H8_300H:
aca88567
NC
14575 return reloc_type == R_H8_DIR16;
14576 case EM_IP2K_OLD:
14577 case EM_IP2K:
14578 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14579 case EM_M32C_OLD:
f4236fe4
DD
14580 case EM_M32C:
14581 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14582 case EM_CYGNUS_MN10200:
14583 case EM_MN10200:
14584 return reloc_type == 2; /* R_MN10200_16. */
14585 case EM_CYGNUS_MN10300:
14586 case EM_MN10300:
14587 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14588 case EM_MSP430:
dda8d76d 14589 if (uses_msp430x_relocs (filedata))
13761a11 14590 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14591 /* Fall through. */
78c8d46c 14592 case EM_MSP430_OLD:
aca88567 14593 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 14594 case EM_NDS32:
81c5e376 14595 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 14596 case EM_ALTERA_NIOS2:
36591ba1 14597 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14598 case EM_NIOS32:
14599 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14600 case EM_OR1K:
14601 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14602 case EM_RISCV:
14603 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14604 case EM_TI_PRU:
14605 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14606 case EM_TI_C6000:
14607 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14608 case EM_VISIUM:
14609 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
14610 case EM_XGATE:
14611 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14612 case EM_Z80:
14613 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14614 default:
015dc7e1 14615 return false;
4b78141a
NC
14616 }
14617}
14618
39e07931
AS
14619/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14620 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14621
015dc7e1 14622static bool
39e07931
AS
14623is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14624{
14625 switch (filedata->file_header.e_machine)
14626 {
14627 case EM_RISCV:
14628 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14629 case EM_Z80:
14630 return reloc_type == 1; /* R_Z80_8. */
39e07931 14631 default:
015dc7e1 14632 return false;
39e07931
AS
14633 }
14634}
14635
14636/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14637 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14638
015dc7e1 14639static bool
39e07931
AS
14640is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14641{
14642 switch (filedata->file_header.e_machine)
14643 {
14644 case EM_RISCV:
14645 return reloc_type == 53; /* R_RISCV_SET6. */
14646 default:
015dc7e1 14647 return false;
39e07931
AS
14648 }
14649}
14650
03336641
JW
14651/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14652 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14653
015dc7e1 14654static bool
03336641
JW
14655is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14656{
14657 /* Please keep this table alpha-sorted for ease of visual lookup. */
14658 switch (filedata->file_header.e_machine)
14659 {
14660 case EM_RISCV:
14661 return reloc_type == 35; /* R_RISCV_ADD32. */
14662 default:
015dc7e1 14663 return false;
03336641
JW
14664 }
14665}
14666
14667/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14668 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14669
015dc7e1 14670static bool
03336641
JW
14671is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14672{
14673 /* Please keep this table alpha-sorted for ease of visual lookup. */
14674 switch (filedata->file_header.e_machine)
14675 {
14676 case EM_RISCV:
14677 return reloc_type == 39; /* R_RISCV_SUB32. */
14678 default:
015dc7e1 14679 return false;
03336641
JW
14680 }
14681}
14682
14683/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14684 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14685
015dc7e1 14686static bool
03336641
JW
14687is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14688{
14689 /* Please keep this table alpha-sorted for ease of visual lookup. */
14690 switch (filedata->file_header.e_machine)
14691 {
14692 case EM_RISCV:
14693 return reloc_type == 36; /* R_RISCV_ADD64. */
14694 default:
015dc7e1 14695 return false;
03336641
JW
14696 }
14697}
14698
14699/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14700 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14701
015dc7e1 14702static bool
03336641
JW
14703is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14704{
14705 /* Please keep this table alpha-sorted for ease of visual lookup. */
14706 switch (filedata->file_header.e_machine)
14707 {
14708 case EM_RISCV:
14709 return reloc_type == 40; /* R_RISCV_SUB64. */
14710 default:
015dc7e1 14711 return false;
03336641
JW
14712 }
14713}
14714
14715/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14716 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14717
015dc7e1 14718static bool
03336641
JW
14719is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14720{
14721 /* Please keep this table alpha-sorted for ease of visual lookup. */
14722 switch (filedata->file_header.e_machine)
14723 {
14724 case EM_RISCV:
14725 return reloc_type == 34; /* R_RISCV_ADD16. */
14726 default:
015dc7e1 14727 return false;
03336641
JW
14728 }
14729}
14730
14731/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14732 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14733
015dc7e1 14734static bool
03336641
JW
14735is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14736{
14737 /* Please keep this table alpha-sorted for ease of visual lookup. */
14738 switch (filedata->file_header.e_machine)
14739 {
14740 case EM_RISCV:
14741 return reloc_type == 38; /* R_RISCV_SUB16. */
14742 default:
015dc7e1 14743 return false;
03336641
JW
14744 }
14745}
14746
14747/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14748 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14749
015dc7e1 14750static bool
03336641
JW
14751is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14752{
14753 /* Please keep this table alpha-sorted for ease of visual lookup. */
14754 switch (filedata->file_header.e_machine)
14755 {
14756 case EM_RISCV:
14757 return reloc_type == 33; /* R_RISCV_ADD8. */
14758 default:
015dc7e1 14759 return false;
03336641
JW
14760 }
14761}
14762
14763/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14764 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14765
015dc7e1 14766static bool
03336641
JW
14767is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14768{
14769 /* Please keep this table alpha-sorted for ease of visual lookup. */
14770 switch (filedata->file_header.e_machine)
14771 {
14772 case EM_RISCV:
14773 return reloc_type == 37; /* R_RISCV_SUB8. */
14774 default:
015dc7e1 14775 return false;
03336641
JW
14776 }
14777}
14778
39e07931
AS
14779/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14780 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14781
015dc7e1 14782static bool
39e07931
AS
14783is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14784{
14785 switch (filedata->file_header.e_machine)
14786 {
14787 case EM_RISCV:
14788 return reloc_type == 52; /* R_RISCV_SUB6. */
14789 default:
015dc7e1 14790 return false;
39e07931
AS
14791 }
14792}
14793
2a7b2e88
JK
14794/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14795 relocation entries (possibly formerly used for SHT_GROUP sections). */
14796
015dc7e1 14797static bool
dda8d76d 14798is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14799{
dda8d76d 14800 switch (filedata->file_header.e_machine)
2a7b2e88 14801 {
cb8f3167 14802 case EM_386: /* R_386_NONE. */
d347c9df 14803 case EM_68K: /* R_68K_NONE. */
cfb8c092 14804 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14805 case EM_ALPHA: /* R_ALPHA_NONE. */
14806 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14807 case EM_ARC: /* R_ARC_NONE. */
886a2506 14808 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14809 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14810 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 14811 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14812 case EM_FT32: /* R_FT32_NONE. */
14813 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14814 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14815 case EM_L1OM: /* R_X86_64_NONE. */
14816 case EM_M32R: /* R_M32R_NONE. */
14817 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14818 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14819 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14820 case EM_NIOS32: /* R_NIOS_NONE. */
14821 case EM_OR1K: /* R_OR1K_NONE. */
14822 case EM_PARISC: /* R_PARISC_NONE. */
14823 case EM_PPC64: /* R_PPC64_NONE. */
14824 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14825 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14826 case EM_S390: /* R_390_NONE. */
14827 case EM_S390_OLD:
14828 case EM_SH: /* R_SH_NONE. */
14829 case EM_SPARC32PLUS:
14830 case EM_SPARC: /* R_SPARC_NONE. */
14831 case EM_SPARCV9:
aa137e4d
NC
14832 case EM_TILEGX: /* R_TILEGX_NONE. */
14833 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14834 case EM_TI_C6000:/* R_C6000_NONE. */
14835 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 14836 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14837 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14838 return reloc_type == 0;
d347c9df 14839
a06ea964
NC
14840 case EM_AARCH64:
14841 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14842 case EM_AVR_OLD:
14843 case EM_AVR:
14844 return (reloc_type == 0 /* R_AVR_NONE. */
14845 || reloc_type == 30 /* R_AVR_DIFF8. */
14846 || reloc_type == 31 /* R_AVR_DIFF16. */
14847 || reloc_type == 32 /* R_AVR_DIFF32. */);
14848 case EM_METAG:
14849 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 14850 case EM_NDS32:
81c5e376
AM
14851 return (reloc_type == 0 /* R_NDS32_NONE. */
14852 || reloc_type == 205 /* R_NDS32_DIFF8. */
14853 || reloc_type == 206 /* R_NDS32_DIFF16. */
14854 || reloc_type == 207 /* R_NDS32_DIFF32. */
14855 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
14856 case EM_TI_PRU:
14857 return (reloc_type == 0 /* R_PRU_NONE. */
14858 || reloc_type == 65 /* R_PRU_DIFF8. */
14859 || reloc_type == 66 /* R_PRU_DIFF16. */
14860 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14861 case EM_XTENSA_OLD:
14862 case EM_XTENSA:
4dc3c23d
AM
14863 return (reloc_type == 0 /* R_XTENSA_NONE. */
14864 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14865 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14866 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14867 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14868 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14869 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14870 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14871 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14872 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14873 }
015dc7e1 14874 return false;
2a7b2e88
JK
14875}
14876
d1c4b12b
NC
14877/* Returns TRUE if there is a relocation against
14878 section NAME at OFFSET bytes. */
14879
015dc7e1 14880bool
31e5a3a3 14881reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
14882{
14883 Elf_Internal_Rela * relocs;
14884 Elf_Internal_Rela * rp;
14885
14886 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14887 return false;
d1c4b12b
NC
14888
14889 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14890
14891 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14892 if (rp->r_offset == offset)
015dc7e1 14893 return true;
d1c4b12b 14894
015dc7e1 14895 return false;
d1c4b12b
NC
14896}
14897
cf13d699 14898/* Apply relocations to a section.
32ec8896
NC
14899 Returns TRUE upon success, FALSE otherwise.
14900 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14901 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14902 will be set to the number of relocs loaded.
14903
cf13d699 14904 Note: So far support has been added only for those relocations
32ec8896
NC
14905 which can be found in debug sections. FIXME: Add support for
14906 more relocations ? */
1b315056 14907
015dc7e1 14908static bool
be7d229a
AM
14909apply_relocations (Filedata *filedata,
14910 const Elf_Internal_Shdr *section,
14911 unsigned char *start,
14912 size_t size,
14913 void **relocs_return,
14914 unsigned long *num_relocs_return)
1b315056 14915{
cf13d699 14916 Elf_Internal_Shdr * relsec;
0d2a7a93 14917 unsigned char * end = start + size;
cb8f3167 14918
d1c4b12b
NC
14919 if (relocs_return != NULL)
14920 {
14921 * (Elf_Internal_Rela **) relocs_return = NULL;
14922 * num_relocs_return = 0;
14923 }
14924
dda8d76d 14925 if (filedata->file_header.e_type != ET_REL)
32ec8896 14926 /* No relocs to apply. */
015dc7e1 14927 return true;
1b315056 14928
cf13d699 14929 /* Find the reloc section associated with the section. */
dda8d76d
NC
14930 for (relsec = filedata->section_headers;
14931 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14932 ++relsec)
252b5132 14933 {
015dc7e1 14934 bool is_rela;
41e92641 14935 unsigned long num_relocs;
2cf0635d
NC
14936 Elf_Internal_Rela * relocs;
14937 Elf_Internal_Rela * rp;
14938 Elf_Internal_Shdr * symsec;
14939 Elf_Internal_Sym * symtab;
ba5cdace 14940 unsigned long num_syms;
2cf0635d 14941 Elf_Internal_Sym * sym;
252b5132 14942
41e92641 14943 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14944 || relsec->sh_info >= filedata->file_header.e_shnum
14945 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14946 || relsec->sh_size == 0
dda8d76d 14947 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14948 continue;
428409d5 14949
a788aedd
AM
14950 symsec = filedata->section_headers + relsec->sh_link;
14951 if (symsec->sh_type != SHT_SYMTAB
14952 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14953 return false;
a788aedd 14954
41e92641
NC
14955 is_rela = relsec->sh_type == SHT_RELA;
14956
14957 if (is_rela)
14958 {
dda8d76d 14959 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14960 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14961 return false;
41e92641
NC
14962 }
14963 else
14964 {
dda8d76d 14965 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14966 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14967 return false;
41e92641
NC
14968 }
14969
14970 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14971 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14972 is_rela = false;
428409d5 14973
4de91c10 14974 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14975
41e92641 14976 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14977 {
625d49fc 14978 uint64_t addend;
015dc7e1
AM
14979 unsigned int reloc_type;
14980 unsigned int reloc_size;
14981 bool reloc_inplace = false;
14982 bool reloc_subtract = false;
14983 unsigned char *rloc;
14984 unsigned long sym_index;
4b78141a 14985
dda8d76d 14986 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14987
dda8d76d 14988 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14989 continue;
dda8d76d 14990 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14991 continue;
dda8d76d
NC
14992 else if (is_32bit_abs_reloc (filedata, reloc_type)
14993 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14994 reloc_size = 4;
dda8d76d
NC
14995 else if (is_64bit_abs_reloc (filedata, reloc_type)
14996 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14997 reloc_size = 8;
dda8d76d 14998 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14999 reloc_size = 3;
dda8d76d 15000 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15001 reloc_size = 2;
39e07931
AS
15002 else if (is_8bit_abs_reloc (filedata, reloc_type)
15003 || is_6bit_abs_reloc (filedata, reloc_type))
15004 reloc_size = 1;
03336641
JW
15005 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15006 reloc_type))
15007 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15008 {
15009 reloc_size = 4;
015dc7e1 15010 reloc_inplace = true;
03336641
JW
15011 }
15012 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15013 reloc_type))
15014 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15015 {
15016 reloc_size = 8;
015dc7e1 15017 reloc_inplace = true;
03336641
JW
15018 }
15019 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15020 reloc_type))
15021 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15022 {
15023 reloc_size = 2;
015dc7e1 15024 reloc_inplace = true;
03336641
JW
15025 }
15026 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15027 reloc_type))
15028 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15029 {
15030 reloc_size = 1;
015dc7e1 15031 reloc_inplace = true;
03336641 15032 }
39e07931
AS
15033 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
15034 reloc_type)))
15035 {
15036 reloc_size = 1;
015dc7e1 15037 reloc_inplace = true;
39e07931 15038 }
aca88567 15039 else
4b78141a 15040 {
bee0ee85 15041 static unsigned int prev_reloc = 0;
dda8d76d 15042
bee0ee85
NC
15043 if (reloc_type != prev_reloc)
15044 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15045 reloc_type, printable_section_name (filedata, section));
bee0ee85 15046 prev_reloc = reloc_type;
4b78141a
NC
15047 continue;
15048 }
103f02d3 15049
91d6fa6a 15050 rloc = start + rp->r_offset;
75802ccb 15051 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
15052 {
15053 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
15054 (unsigned long) rp->r_offset,
dda8d76d 15055 printable_section_name (filedata, section));
700dd8b7
L
15056 continue;
15057 }
103f02d3 15058
ba5cdace
NC
15059 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
15060 if (sym_index >= num_syms)
15061 {
15062 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 15063 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15064 continue;
15065 }
15066 sym = symtab + sym_index;
41e92641
NC
15067
15068 /* If the reloc has a symbol associated with it,
55f25fc3
L
15069 make sure that it is of an appropriate type.
15070
15071 Relocations against symbols without type can happen.
15072 Gcc -feliminate-dwarf2-dups may generate symbols
15073 without type for debug info.
15074
15075 Icc generates relocations against function symbols
15076 instead of local labels.
15077
15078 Relocations against object symbols can happen, eg when
15079 referencing a global array. For an example of this see
15080 the _clz.o binary in libgcc.a. */
aca88567 15081 if (sym != symtab
b8871f35 15082 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15083 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15084 {
d3a49aa8 15085 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
15086 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15087 printable_section_name (filedata, relsec),
d3a49aa8 15088 (long int)(rp - relocs));
aca88567 15089 continue;
5b18a4bc 15090 }
252b5132 15091
4dc3c23d
AM
15092 addend = 0;
15093 if (is_rela)
15094 addend += rp->r_addend;
c47320c3
AM
15095 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15096 partial_inplace. */
4dc3c23d 15097 if (!is_rela
dda8d76d 15098 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15099 && reloc_type == 1)
dda8d76d
NC
15100 || ((filedata->file_header.e_machine == EM_PJ
15101 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15102 && reloc_type == 1)
dda8d76d
NC
15103 || ((filedata->file_header.e_machine == EM_D30V
15104 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15105 && reloc_type == 12)
15106 || reloc_inplace)
39e07931
AS
15107 {
15108 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15109 addend += byte_get (rloc, reloc_size) & 0x3f;
15110 else
15111 addend += byte_get (rloc, reloc_size);
15112 }
cb8f3167 15113
dda8d76d
NC
15114 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15115 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15116 {
15117 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15118 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15119 addend -= 8;
91d6fa6a 15120 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15121 reloc_size);
15122 }
39e07931
AS
15123 else if (is_6bit_abs_reloc (filedata, reloc_type)
15124 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
15125 {
15126 if (reloc_subtract)
15127 addend -= sym->st_value;
15128 else
15129 addend += sym->st_value;
15130 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15131 byte_put (rloc, addend, reloc_size);
15132 }
03336641
JW
15133 else if (reloc_subtract)
15134 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15135 else
91d6fa6a 15136 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15137 }
252b5132 15138
5b18a4bc 15139 free (symtab);
f84ce13b
NC
15140 /* Let the target specific reloc processing code know that
15141 we have finished with these relocs. */
dda8d76d 15142 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15143
15144 if (relocs_return)
15145 {
15146 * (Elf_Internal_Rela **) relocs_return = relocs;
15147 * num_relocs_return = num_relocs;
15148 }
15149 else
15150 free (relocs);
15151
5b18a4bc
NC
15152 break;
15153 }
32ec8896 15154
015dc7e1 15155 return true;
5b18a4bc 15156}
103f02d3 15157
cf13d699 15158#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15159static bool
dda8d76d 15160disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15161{
dda8d76d 15162 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15163
74e1a04b 15164 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15165
015dc7e1 15166 return true;
cf13d699
NC
15167}
15168#endif
15169
15170/* Reads in the contents of SECTION from FILE, returning a pointer
15171 to a malloc'ed buffer or NULL if something went wrong. */
15172
15173static char *
dda8d76d 15174get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15175{
be7d229a 15176 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15177
15178 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15179 {
c6b78c96 15180 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15181 printable_section_name (filedata, section));
cf13d699
NC
15182 return NULL;
15183 }
15184
dda8d76d 15185 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15186 _("section contents"));
cf13d699
NC
15187}
15188
1f5a3546 15189/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 15190
015dc7e1 15191static bool
1f5a3546
FS
15192uncompress_section_contents (bool is_zstd, unsigned char **buffer,
15193 uint64_t uncompressed_size, uint64_t *size)
0e602686 15194{
31e5a3a3
AM
15195 uint64_t compressed_size = *size;
15196 unsigned char *compressed_buffer = *buffer;
1f5a3546 15197 unsigned char *uncompressed_buffer = xmalloc (uncompressed_size);
0e602686
NC
15198 z_stream strm;
15199 int rc;
15200
1f5a3546
FS
15201 if (is_zstd)
15202 {
15203#ifdef HAVE_ZSTD
15204 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15205 compressed_buffer, compressed_size);
15206 if (ZSTD_isError (ret))
15207 goto fail;
15208#endif
15209 }
15210 else
15211 {
15212 /* It is possible the section consists of several compressed
15213 buffers concatenated together, so we uncompress in a loop. */
15214 /* PR 18313: The state field in the z_stream structure is supposed
15215 to be invisible to the user (ie us), but some compilers will
15216 still complain about it being used without initialisation. So
15217 we first zero the entire z_stream structure and then set the fields
15218 that we need. */
15219 memset (&strm, 0, sizeof strm);
15220 strm.avail_in = compressed_size;
15221 strm.next_in = (Bytef *)compressed_buffer;
15222 strm.avail_out = uncompressed_size;
15223
15224 rc = inflateInit (&strm);
15225 while (strm.avail_in > 0)
15226 {
15227 if (rc != Z_OK)
15228 break;
15229 strm.next_out = ((Bytef *)uncompressed_buffer
15230 + (uncompressed_size - strm.avail_out));
15231 rc = inflate (&strm, Z_FINISH);
15232 if (rc != Z_STREAM_END)
15233 break;
15234 rc = inflateReset (&strm);
15235 }
15236 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15237 goto fail;
15238 }
0e602686
NC
15239
15240 *buffer = uncompressed_buffer;
15241 *size = uncompressed_size;
015dc7e1 15242 return true;
0e602686
NC
15243
15244 fail:
15245 free (uncompressed_buffer);
15246 /* Indicate decompression failure. */
15247 *buffer = NULL;
015dc7e1 15248 return false;
0e602686 15249}
dd24e3da 15250
015dc7e1 15251static bool
dda8d76d 15252dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15253{
015dc7e1 15254 Elf_Internal_Shdr *relsec;
be7d229a 15255 uint64_t num_bytes;
015dc7e1
AM
15256 unsigned char *data;
15257 unsigned char *end;
15258 unsigned char *real_start;
15259 unsigned char *start;
15260 bool some_strings_shown;
cf13d699 15261
dda8d76d 15262 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15263 if (start == NULL)
c6b78c96 15264 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15265 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15266
0e602686 15267 num_bytes = section->sh_size;
cf13d699 15268
835f2fae
NC
15269 if (filedata->is_separate)
15270 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15271 printable_section_name (filedata, section),
15272 filedata->file_name);
15273 else
15274 printf (_("\nString dump of section '%s':\n"),
15275 printable_section_name (filedata, section));
cf13d699 15276
0e602686
NC
15277 if (decompress_dumps)
15278 {
31e5a3a3
AM
15279 uint64_t new_size = num_bytes;
15280 uint64_t uncompressed_size = 0;
1f5a3546 15281 bool is_zstd = false;
0e602686
NC
15282
15283 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15284 {
15285 Elf_Internal_Chdr chdr;
15286 unsigned int compression_header_size
ebdf1ebf
NC
15287 = get_compression_header (& chdr, (unsigned char *) start,
15288 num_bytes);
5844b465
NC
15289 if (compression_header_size == 0)
15290 /* An error message will have already been generated
15291 by get_compression_header. */
15292 goto error_out;
0e602686 15293
1f5a3546
FS
15294 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
15295 ;
15296#ifdef HAVE_ZSTD
15297 else if (chdr.ch_type == ELFCOMPRESS_ZSTD)
15298 is_zstd = true;
15299#endif
15300 else
0e602686 15301 {
813dabb9 15302 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15303 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15304 goto error_out;
813dabb9 15305 }
813dabb9
L
15306 uncompressed_size = chdr.ch_size;
15307 start += compression_header_size;
15308 new_size -= compression_header_size;
0e602686
NC
15309 }
15310 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15311 {
15312 /* Read the zlib header. In this case, it should be "ZLIB"
15313 followed by the uncompressed section size, 8 bytes in
15314 big-endian order. */
15315 uncompressed_size = start[4]; uncompressed_size <<= 8;
15316 uncompressed_size += start[5]; uncompressed_size <<= 8;
15317 uncompressed_size += start[6]; uncompressed_size <<= 8;
15318 uncompressed_size += start[7]; uncompressed_size <<= 8;
15319 uncompressed_size += start[8]; uncompressed_size <<= 8;
15320 uncompressed_size += start[9]; uncompressed_size <<= 8;
15321 uncompressed_size += start[10]; uncompressed_size <<= 8;
15322 uncompressed_size += start[11];
15323 start += 12;
15324 new_size -= 12;
15325 }
15326
1835f746
NC
15327 if (uncompressed_size)
15328 {
1f5a3546
FS
15329 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
15330 &new_size))
1835f746
NC
15331 num_bytes = new_size;
15332 else
15333 {
15334 error (_("Unable to decompress section %s\n"),
dda8d76d 15335 printable_section_name (filedata, section));
f761cb13 15336 goto error_out;
1835f746
NC
15337 }
15338 }
bc303e5d
NC
15339 else
15340 start = real_start;
0e602686 15341 }
fd8008d8 15342
cf13d699
NC
15343 /* If the section being dumped has relocations against it the user might
15344 be expecting these relocations to have been applied. Check for this
15345 case and issue a warning message in order to avoid confusion.
15346 FIXME: Maybe we ought to have an option that dumps a section with
15347 relocs applied ? */
dda8d76d
NC
15348 for (relsec = filedata->section_headers;
15349 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15350 ++relsec)
15351 {
15352 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15353 || relsec->sh_info >= filedata->file_header.e_shnum
15354 || filedata->section_headers + relsec->sh_info != section
cf13d699 15355 || relsec->sh_size == 0
dda8d76d 15356 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15357 continue;
15358
15359 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15360 break;
15361 }
15362
cf13d699
NC
15363 data = start;
15364 end = start + num_bytes;
015dc7e1 15365 some_strings_shown = false;
cf13d699 15366
ba3265d0
NC
15367#ifdef HAVE_MBSTATE_T
15368 mbstate_t state;
15369 /* Initialise the multibyte conversion state. */
15370 memset (& state, 0, sizeof (state));
15371#endif
15372
015dc7e1 15373 bool continuing = false;
ba3265d0 15374
cf13d699
NC
15375 while (data < end)
15376 {
15377 while (!ISPRINT (* data))
15378 if (++ data >= end)
15379 break;
15380
15381 if (data < end)
15382 {
071436c6
NC
15383 size_t maxlen = end - data;
15384
ba3265d0
NC
15385 if (continuing)
15386 {
15387 printf (" ");
015dc7e1 15388 continuing = false;
ba3265d0
NC
15389 }
15390 else
15391 {
d1ce973e 15392 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
15393 }
15394
4082ef84
NC
15395 if (maxlen > 0)
15396 {
f3da8a96 15397 char c = 0;
ba3265d0
NC
15398
15399 while (maxlen)
15400 {
15401 c = *data++;
15402
15403 if (c == 0)
15404 break;
15405
15406 /* PR 25543: Treat new-lines as string-ending characters. */
15407 if (c == '\n')
15408 {
15409 printf ("\\n\n");
15410 if (*data != 0)
015dc7e1 15411 continuing = true;
ba3265d0
NC
15412 break;
15413 }
15414
15415 /* Do not print control characters directly as they can affect terminal
15416 settings. Such characters usually appear in the names generated
15417 by the assembler for local labels. */
15418 if (ISCNTRL (c))
15419 {
15420 printf ("^%c", c + 0x40);
15421 }
15422 else if (ISPRINT (c))
15423 {
15424 putchar (c);
15425 }
15426 else
15427 {
15428 size_t n;
15429#ifdef HAVE_MBSTATE_T
15430 wchar_t w;
15431#endif
15432 /* Let printf do the hard work of displaying multibyte characters. */
15433 printf ("%.1s", data - 1);
15434#ifdef HAVE_MBSTATE_T
15435 /* Try to find out how many bytes made up the character that was
15436 just printed. Advance the symbol pointer past the bytes that
15437 were displayed. */
15438 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15439#else
15440 n = 1;
15441#endif
15442 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15443 data += (n - 1);
15444 }
15445 }
15446
15447 if (c != '\n')
15448 putchar ('\n');
4082ef84
NC
15449 }
15450 else
15451 {
15452 printf (_("<corrupt>\n"));
15453 data = end;
15454 }
015dc7e1 15455 some_strings_shown = true;
cf13d699
NC
15456 }
15457 }
15458
15459 if (! some_strings_shown)
15460 printf (_(" No strings found in this section."));
15461
0e602686 15462 free (real_start);
cf13d699
NC
15463
15464 putchar ('\n');
015dc7e1 15465 return true;
f761cb13
AM
15466
15467error_out:
15468 free (real_start);
015dc7e1 15469 return false;
cf13d699
NC
15470}
15471
015dc7e1
AM
15472static bool
15473dump_section_as_bytes (Elf_Internal_Shdr *section,
15474 Filedata *filedata,
15475 bool relocate)
cf13d699 15476{
be7d229a
AM
15477 Elf_Internal_Shdr *relsec;
15478 size_t bytes;
15479 uint64_t section_size;
625d49fc 15480 uint64_t addr;
be7d229a
AM
15481 unsigned char *data;
15482 unsigned char *real_start;
15483 unsigned char *start;
0e602686 15484
dda8d76d 15485 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15486 if (start == NULL)
c6b78c96 15487 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15488 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15489
0e602686 15490 section_size = section->sh_size;
cf13d699 15491
835f2fae
NC
15492 if (filedata->is_separate)
15493 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15494 printable_section_name (filedata, section),
15495 filedata->file_name);
15496 else
15497 printf (_("\nHex dump of section '%s':\n"),
15498 printable_section_name (filedata, section));
cf13d699 15499
0e602686
NC
15500 if (decompress_dumps)
15501 {
31e5a3a3
AM
15502 uint64_t new_size = section_size;
15503 uint64_t uncompressed_size = 0;
1f5a3546 15504 bool is_zstd = false;
0e602686
NC
15505
15506 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15507 {
15508 Elf_Internal_Chdr chdr;
15509 unsigned int compression_header_size
ebdf1ebf 15510 = get_compression_header (& chdr, start, section_size);
0e602686 15511
5844b465
NC
15512 if (compression_header_size == 0)
15513 /* An error message will have already been generated
15514 by get_compression_header. */
15515 goto error_out;
15516
1f5a3546
FS
15517 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
15518 ;
15519#ifdef HAVE_ZSTD
15520 else if (chdr.ch_type == ELFCOMPRESS_ZSTD)
15521 is_zstd = true;
15522#endif
15523 else
0e602686 15524 {
813dabb9 15525 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15526 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15527 goto error_out;
0e602686 15528 }
813dabb9
L
15529 uncompressed_size = chdr.ch_size;
15530 start += compression_header_size;
15531 new_size -= compression_header_size;
0e602686
NC
15532 }
15533 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15534 {
15535 /* Read the zlib header. In this case, it should be "ZLIB"
15536 followed by the uncompressed section size, 8 bytes in
15537 big-endian order. */
15538 uncompressed_size = start[4]; uncompressed_size <<= 8;
15539 uncompressed_size += start[5]; uncompressed_size <<= 8;
15540 uncompressed_size += start[6]; uncompressed_size <<= 8;
15541 uncompressed_size += start[7]; uncompressed_size <<= 8;
15542 uncompressed_size += start[8]; uncompressed_size <<= 8;
15543 uncompressed_size += start[9]; uncompressed_size <<= 8;
15544 uncompressed_size += start[10]; uncompressed_size <<= 8;
15545 uncompressed_size += start[11];
15546 start += 12;
15547 new_size -= 12;
15548 }
15549
f055032e
NC
15550 if (uncompressed_size)
15551 {
1f5a3546
FS
15552 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
15553 &new_size))
bc303e5d
NC
15554 {
15555 section_size = new_size;
15556 }
f055032e
NC
15557 else
15558 {
15559 error (_("Unable to decompress section %s\n"),
dda8d76d 15560 printable_section_name (filedata, section));
bc303e5d 15561 /* FIXME: Print the section anyway ? */
f761cb13 15562 goto error_out;
f055032e
NC
15563 }
15564 }
bc303e5d
NC
15565 else
15566 start = real_start;
0e602686 15567 }
14ae95f2 15568
cf13d699
NC
15569 if (relocate)
15570 {
dda8d76d 15571 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15572 goto error_out;
cf13d699
NC
15573 }
15574 else
15575 {
15576 /* If the section being dumped has relocations against it the user might
15577 be expecting these relocations to have been applied. Check for this
15578 case and issue a warning message in order to avoid confusion.
15579 FIXME: Maybe we ought to have an option that dumps a section with
15580 relocs applied ? */
dda8d76d
NC
15581 for (relsec = filedata->section_headers;
15582 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15583 ++relsec)
15584 {
15585 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15586 || relsec->sh_info >= filedata->file_header.e_shnum
15587 || filedata->section_headers + relsec->sh_info != section
cf13d699 15588 || relsec->sh_size == 0
dda8d76d 15589 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15590 continue;
15591
15592 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15593 break;
15594 }
15595 }
15596
15597 addr = section->sh_addr;
0e602686 15598 bytes = section_size;
cf13d699
NC
15599 data = start;
15600
15601 while (bytes)
15602 {
15603 int j;
15604 int k;
15605 int lbytes;
15606
15607 lbytes = (bytes > 16 ? 16 : bytes);
15608
15609 printf (" 0x%8.8lx ", (unsigned long) addr);
15610
15611 for (j = 0; j < 16; j++)
15612 {
15613 if (j < lbytes)
15614 printf ("%2.2x", data[j]);
15615 else
15616 printf (" ");
15617
15618 if ((j & 3) == 3)
15619 printf (" ");
15620 }
15621
15622 for (j = 0; j < lbytes; j++)
15623 {
15624 k = data[j];
15625 if (k >= ' ' && k < 0x7f)
15626 printf ("%c", k);
15627 else
15628 printf (".");
15629 }
15630
15631 putchar ('\n');
15632
15633 data += lbytes;
15634 addr += lbytes;
15635 bytes -= lbytes;
15636 }
15637
0e602686 15638 free (real_start);
cf13d699
NC
15639
15640 putchar ('\n');
015dc7e1 15641 return true;
f761cb13
AM
15642
15643 error_out:
15644 free (real_start);
015dc7e1 15645 return false;
cf13d699
NC
15646}
15647
094e34f2 15648#ifdef ENABLE_LIBCTF
7d9813f1
NA
15649static ctf_sect_t *
15650shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15651{
84714f86 15652 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15653 buf->cts_size = shdr->sh_size;
15654 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15655
15656 return buf;
15657}
15658
15659/* Formatting callback function passed to ctf_dump. Returns either the pointer
15660 it is passed, or a pointer to newly-allocated storage, in which case
15661 dump_ctf() will free it when it no longer needs it. */
15662
2f6ecaed
NA
15663static char *
15664dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15665 char *s, void *arg)
7d9813f1 15666{
3e50a591 15667 const char *blanks = arg;
7d9813f1
NA
15668 char *new_s;
15669
3e50a591 15670 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15671 return s;
15672 return new_s;
15673}
15674
926c9e76
NA
15675/* Dump CTF errors/warnings. */
15676static void
139633c3 15677dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15678{
15679 ctf_next_t *it = NULL;
15680 char *errtext;
15681 int is_warning;
15682 int err;
15683
15684 /* Dump accumulated errors and warnings. */
15685 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15686 {
5e9b84f7 15687 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15688 errtext);
15689 free (errtext);
15690 }
15691 if (err != ECTF_NEXT_END)
15692 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15693}
15694
2f6ecaed
NA
15695/* Dump one CTF archive member. */
15696
80b56fad
NA
15697static void
15698dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15699 size_t member)
2f6ecaed 15700{
2f6ecaed
NA
15701 const char *things[] = {"Header", "Labels", "Data objects",
15702 "Function objects", "Variables", "Types", "Strings",
15703 ""};
15704 const char **thing;
15705 size_t i;
15706
80b56fad
NA
15707 /* Don't print out the name of the default-named archive member if it appears
15708 first in the list. The name .ctf appears everywhere, even for things that
15709 aren't really archives, so printing it out is liable to be confusing; also,
15710 the common case by far is for only one archive member to exist, and hiding
15711 it in that case seems worthwhile. */
2f6ecaed 15712
80b56fad
NA
15713 if (strcmp (name, ".ctf") != 0 || member != 0)
15714 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15715
80b56fad
NA
15716 if (ctf_parent_name (ctf) != NULL)
15717 ctf_import (ctf, parent);
2f6ecaed
NA
15718
15719 for (i = 0, thing = things; *thing[0]; thing++, i++)
15720 {
15721 ctf_dump_state_t *s = NULL;
15722 char *item;
15723
15724 printf ("\n %s:\n", *thing);
15725 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15726 (void *) " ")) != NULL)
15727 {
15728 printf ("%s\n", item);
15729 free (item);
15730 }
15731
15732 if (ctf_errno (ctf))
15733 {
15734 error (_("Iteration failed: %s, %s\n"), *thing,
15735 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15736 break;
2f6ecaed
NA
15737 }
15738 }
8b37e7b6 15739
926c9e76 15740 dump_ctf_errs (ctf);
2f6ecaed
NA
15741}
15742
015dc7e1 15743static bool
7d9813f1
NA
15744dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15745{
7d9813f1
NA
15746 Elf_Internal_Shdr * symtab_sec = NULL;
15747 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15748 void * data = NULL;
15749 void * symdata = NULL;
15750 void * strdata = NULL;
80b56fad 15751 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15752 ctf_sect_t * symsectp = NULL;
15753 ctf_sect_t * strsectp = NULL;
2f6ecaed 15754 ctf_archive_t * ctfa = NULL;
139633c3 15755 ctf_dict_t * parent = NULL;
80b56fad 15756 ctf_dict_t * fp;
7d9813f1 15757
80b56fad
NA
15758 ctf_next_t *i = NULL;
15759 const char *name;
15760 size_t member = 0;
7d9813f1 15761 int err;
015dc7e1 15762 bool ret = false;
7d9813f1
NA
15763
15764 shdr_to_ctf_sect (&ctfsect, section, filedata);
15765 data = get_section_contents (section, filedata);
15766 ctfsect.cts_data = data;
15767
616febde 15768 if (!dump_ctf_symtab_name)
3d16b64e 15769 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15770
15771 if (!dump_ctf_strtab_name)
3d16b64e 15772 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15773
15774 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15775 {
15776 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15777 {
15778 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15779 goto fail;
15780 }
15781 if ((symdata = (void *) get_data (NULL, filedata,
15782 symtab_sec->sh_offset, 1,
15783 symtab_sec->sh_size,
15784 _("symbols"))) == NULL)
15785 goto fail;
15786 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15787 symsect.cts_data = symdata;
15788 }
835f2fae 15789
df16e041 15790 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15791 {
15792 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15793 {
15794 error (_("No string table section named %s\n"),
15795 dump_ctf_strtab_name);
15796 goto fail;
15797 }
15798 if ((strdata = (void *) get_data (NULL, filedata,
15799 strtab_sec->sh_offset, 1,
15800 strtab_sec->sh_size,
15801 _("strings"))) == NULL)
15802 goto fail;
15803 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15804 strsect.cts_data = strdata;
15805 }
835f2fae 15806
2f6ecaed
NA
15807 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15808 libctf papers over the difference, so we can pretend it is always an
80b56fad 15809 archive. */
7d9813f1 15810
2f6ecaed 15811 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15812 {
926c9e76 15813 dump_ctf_errs (NULL);
7d9813f1
NA
15814 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15815 goto fail;
15816 }
15817
96c61be5
NA
15818 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15819 != ELFDATA2MSB);
15820
80b56fad
NA
15821 /* Preload the parent dict, since it will need to be imported into every
15822 child in turn. */
15823 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15824 {
926c9e76 15825 dump_ctf_errs (NULL);
2f6ecaed
NA
15826 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15827 goto fail;
7d9813f1
NA
15828 }
15829
015dc7e1 15830 ret = true;
7d9813f1 15831
835f2fae
NC
15832 if (filedata->is_separate)
15833 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15834 printable_section_name (filedata, section),
15835 filedata->file_name);
15836 else
15837 printf (_("\nDump of CTF section '%s':\n"),
15838 printable_section_name (filedata, section));
7d9813f1 15839
80b56fad
NA
15840 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15841 dump_ctf_archive_member (fp, name, parent, member++);
15842 if (err != ECTF_NEXT_END)
15843 {
15844 dump_ctf_errs (NULL);
15845 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15846 ret = false;
15847 }
7d9813f1
NA
15848
15849 fail:
139633c3 15850 ctf_dict_close (parent);
2f6ecaed 15851 ctf_close (ctfa);
7d9813f1
NA
15852 free (data);
15853 free (symdata);
15854 free (strdata);
15855 return ret;
15856}
094e34f2 15857#endif
7d9813f1 15858
015dc7e1 15859static bool
dda8d76d
NC
15860load_specific_debug_section (enum dwarf_section_display_enum debug,
15861 const Elf_Internal_Shdr * sec,
15862 void * data)
1007acb3 15863{
2cf0635d 15864 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15865 char buf [64];
dda8d76d 15866 Filedata * filedata = (Filedata *) data;
9abca702 15867
19e6b90e 15868 if (section->start != NULL)
dda8d76d
NC
15869 {
15870 /* If it is already loaded, do nothing. */
15871 if (streq (section->filename, filedata->file_name))
015dc7e1 15872 return true;
dda8d76d
NC
15873 free (section->start);
15874 }
1007acb3 15875
19e6b90e
L
15876 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15877 section->address = sec->sh_addr;
dda8d76d
NC
15878 section->filename = filedata->file_name;
15879 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15880 sec->sh_offset, 1,
15881 sec->sh_size, buf);
59245841
NC
15882 if (section->start == NULL)
15883 section->size = 0;
15884 else
15885 {
77115a4a 15886 unsigned char *start = section->start;
31e5a3a3
AM
15887 uint64_t size = sec->sh_size;
15888 uint64_t uncompressed_size = 0;
1f5a3546 15889 bool is_zstd = false;
77115a4a
L
15890
15891 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15892 {
15893 Elf_Internal_Chdr chdr;
d8024a91
NC
15894 unsigned int compression_header_size;
15895
f53be977
L
15896 if (size < (is_32bit_elf
15897 ? sizeof (Elf32_External_Chdr)
15898 : sizeof (Elf64_External_Chdr)))
d8024a91 15899 {
55be8fd0 15900 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15901 section->name);
015dc7e1 15902 return false;
d8024a91
NC
15903 }
15904
ebdf1ebf 15905 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15906 if (compression_header_size == 0)
15907 /* An error message will have already been generated
15908 by get_compression_header. */
015dc7e1 15909 return false;
d8024a91 15910
1f5a3546
FS
15911 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
15912 ;
15913#ifdef HAVE_ZSTD
15914 else if (chdr.ch_type == ELFCOMPRESS_ZSTD)
15915 is_zstd = true;
15916#endif
15917 else
813dabb9
L
15918 {
15919 warn (_("section '%s' has unsupported compress type: %d\n"),
15920 section->name, chdr.ch_type);
015dc7e1 15921 return false;
813dabb9 15922 }
dab394de 15923 uncompressed_size = chdr.ch_size;
77115a4a
L
15924 start += compression_header_size;
15925 size -= compression_header_size;
15926 }
dab394de
L
15927 else if (size > 12 && streq ((char *) start, "ZLIB"))
15928 {
15929 /* Read the zlib header. In this case, it should be "ZLIB"
15930 followed by the uncompressed section size, 8 bytes in
15931 big-endian order. */
15932 uncompressed_size = start[4]; uncompressed_size <<= 8;
15933 uncompressed_size += start[5]; uncompressed_size <<= 8;
15934 uncompressed_size += start[6]; uncompressed_size <<= 8;
15935 uncompressed_size += start[7]; uncompressed_size <<= 8;
15936 uncompressed_size += start[8]; uncompressed_size <<= 8;
15937 uncompressed_size += start[9]; uncompressed_size <<= 8;
15938 uncompressed_size += start[10]; uncompressed_size <<= 8;
15939 uncompressed_size += start[11];
15940 start += 12;
15941 size -= 12;
15942 }
15943
1835f746 15944 if (uncompressed_size)
77115a4a 15945 {
1f5a3546 15946 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
1835f746
NC
15947 &size))
15948 {
15949 /* Free the compressed buffer, update the section buffer
15950 and the section size if uncompress is successful. */
15951 free (section->start);
15952 section->start = start;
15953 }
15954 else
15955 {
15956 error (_("Unable to decompress section %s\n"),
dda8d76d 15957 printable_section_name (filedata, sec));
015dc7e1 15958 return false;
1835f746 15959 }
77115a4a 15960 }
bc303e5d 15961
77115a4a 15962 section->size = size;
59245841 15963 }
4a114e3e 15964
1b315056 15965 if (section->start == NULL)
015dc7e1 15966 return false;
1b315056 15967
19e6b90e 15968 if (debug_displays [debug].relocate)
32ec8896 15969 {
dda8d76d 15970 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15971 & section->reloc_info, & section->num_relocs))
015dc7e1 15972 return false;
32ec8896 15973 }
d1c4b12b
NC
15974 else
15975 {
15976 section->reloc_info = NULL;
15977 section->num_relocs = 0;
15978 }
1007acb3 15979
015dc7e1 15980 return true;
1007acb3
L
15981}
15982
301a9420
AM
15983#if HAVE_LIBDEBUGINFOD
15984/* Return a hex string representation of the build-id. */
15985unsigned char *
15986get_build_id (void * data)
15987{
ca0e11aa 15988 Filedata * filedata = (Filedata *) data;
301a9420
AM
15989 Elf_Internal_Shdr * shdr;
15990 unsigned long i;
15991
55be8fd0
NC
15992 /* Iterate through notes to find note.gnu.build-id.
15993 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15994 for (i = 0, shdr = filedata->section_headers;
15995 i < filedata->file_header.e_shnum && shdr != NULL;
15996 i++, shdr++)
15997 {
15998 if (shdr->sh_type != SHT_NOTE)
15999 continue;
16000
16001 char * next;
16002 char * end;
16003 size_t data_remaining;
16004 size_t min_notesz;
16005 Elf_External_Note * enote;
16006 Elf_Internal_Note inote;
16007
625d49fc
AM
16008 uint64_t offset = shdr->sh_offset;
16009 uint64_t align = shdr->sh_addralign;
16010 uint64_t length = shdr->sh_size;
301a9420
AM
16011
16012 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16013 if (enote == NULL)
16014 continue;
16015
16016 if (align < 4)
16017 align = 4;
16018 else if (align != 4 && align != 8)
f761cb13
AM
16019 {
16020 free (enote);
16021 continue;
16022 }
301a9420
AM
16023
16024 end = (char *) enote + length;
16025 data_remaining = end - (char *) enote;
16026
16027 if (!is_ia64_vms (filedata))
16028 {
16029 min_notesz = offsetof (Elf_External_Note, name);
16030 if (data_remaining < min_notesz)
16031 {
55be8fd0
NC
16032 warn (_("\
16033malformed note encountered in section %s whilst scanning for build-id note\n"),
16034 printable_section_name (filedata, shdr));
f761cb13 16035 free (enote);
55be8fd0 16036 continue;
301a9420
AM
16037 }
16038 data_remaining -= min_notesz;
16039
16040 inote.type = BYTE_GET (enote->type);
16041 inote.namesz = BYTE_GET (enote->namesz);
16042 inote.namedata = enote->name;
16043 inote.descsz = BYTE_GET (enote->descsz);
16044 inote.descdata = ((char *) enote
16045 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16046 inote.descpos = offset + (inote.descdata - (char *) enote);
16047 next = ((char *) enote
16048 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16049 }
16050 else
16051 {
16052 Elf64_External_VMS_Note *vms_enote;
16053
16054 /* PR binutils/15191
16055 Make sure that there is enough data to read. */
16056 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16057 if (data_remaining < min_notesz)
16058 {
55be8fd0
NC
16059 warn (_("\
16060malformed note encountered in section %s whilst scanning for build-id note\n"),
16061 printable_section_name (filedata, shdr));
f761cb13 16062 free (enote);
55be8fd0 16063 continue;
301a9420
AM
16064 }
16065 data_remaining -= min_notesz;
16066
16067 vms_enote = (Elf64_External_VMS_Note *) enote;
16068 inote.type = BYTE_GET (vms_enote->type);
16069 inote.namesz = BYTE_GET (vms_enote->namesz);
16070 inote.namedata = vms_enote->name;
16071 inote.descsz = BYTE_GET (vms_enote->descsz);
16072 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16073 inote.descpos = offset + (inote.descdata - (char *) enote);
16074 next = inote.descdata + align_power (inote.descsz, 3);
16075 }
16076
16077 /* Skip malformed notes. */
16078 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16079 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16080 || (size_t) (next - inote.descdata) < inote.descsz
16081 || ((size_t) (next - inote.descdata)
16082 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16083 {
55be8fd0
NC
16084 warn (_("\
16085malformed note encountered in section %s whilst scanning for build-id note\n"),
16086 printable_section_name (filedata, shdr));
f761cb13 16087 free (enote);
301a9420
AM
16088 continue;
16089 }
16090
16091 /* Check if this is the build-id note. If so then convert the build-id
16092 bytes to a hex string. */
16093 if (inote.namesz > 0
24d127aa 16094 && startswith (inote.namedata, "GNU")
301a9420
AM
16095 && inote.type == NT_GNU_BUILD_ID)
16096 {
16097 unsigned long j;
16098 char * build_id;
16099
16100 build_id = malloc (inote.descsz * 2 + 1);
16101 if (build_id == NULL)
f761cb13
AM
16102 {
16103 free (enote);
16104 return NULL;
16105 }
301a9420
AM
16106
16107 for (j = 0; j < inote.descsz; ++j)
16108 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16109 build_id[inote.descsz * 2] = '\0';
f761cb13 16110 free (enote);
301a9420 16111
55be8fd0 16112 return (unsigned char *) build_id;
301a9420 16113 }
f761cb13 16114 free (enote);
301a9420
AM
16115 }
16116
16117 return NULL;
16118}
16119#endif /* HAVE_LIBDEBUGINFOD */
16120
657d0d47
CC
16121/* If this is not NULL, load_debug_section will only look for sections
16122 within the list of sections given here. */
32ec8896 16123static unsigned int * section_subset = NULL;
657d0d47 16124
015dc7e1 16125bool
dda8d76d 16126load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16127{
2cf0635d
NC
16128 struct dwarf_section * section = &debug_displays [debug].section;
16129 Elf_Internal_Shdr * sec;
dda8d76d
NC
16130 Filedata * filedata = (Filedata *) data;
16131
e1dbfc17
L
16132 if (!dump_any_debugging)
16133 return false;
16134
f425ec66
NC
16135 /* Without section headers we cannot find any sections. */
16136 if (filedata->section_headers == NULL)
015dc7e1 16137 return false;
f425ec66 16138
9c1ce108
AM
16139 if (filedata->string_table == NULL
16140 && filedata->file_header.e_shstrndx != SHN_UNDEF
16141 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16142 {
16143 Elf_Internal_Shdr * strs;
16144
16145 /* Read in the string table, so that we have section names to scan. */
16146 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16147
4dff97b2 16148 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16149 {
9c1ce108
AM
16150 filedata->string_table
16151 = (char *) get_data (NULL, filedata, strs->sh_offset,
16152 1, strs->sh_size, _("string table"));
dda8d76d 16153
9c1ce108
AM
16154 filedata->string_table_length
16155 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16156 }
16157 }
d966045b
DJ
16158
16159 /* Locate the debug section. */
dda8d76d 16160 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16161 if (sec != NULL)
16162 section->name = section->uncompressed_name;
16163 else
16164 {
dda8d76d 16165 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16166 if (sec != NULL)
16167 section->name = section->compressed_name;
16168 }
16169 if (sec == NULL)
015dc7e1 16170 return false;
d966045b 16171
657d0d47
CC
16172 /* If we're loading from a subset of sections, and we've loaded
16173 a section matching this name before, it's likely that it's a
16174 different one. */
16175 if (section_subset != NULL)
16176 free_debug_section (debug);
16177
dda8d76d 16178 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16179}
16180
19e6b90e
L
16181void
16182free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16183{
2cf0635d 16184 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16185
19e6b90e
L
16186 if (section->start == NULL)
16187 return;
1007acb3 16188
19e6b90e
L
16189 free ((char *) section->start);
16190 section->start = NULL;
16191 section->address = 0;
16192 section->size = 0;
a788aedd 16193
9db70fc3
AM
16194 free (section->reloc_info);
16195 section->reloc_info = NULL;
16196 section->num_relocs = 0;
1007acb3
L
16197}
16198
015dc7e1 16199static bool
dda8d76d 16200display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16201{
84714f86
AM
16202 const char *name = (section_name_valid (filedata, section)
16203 ? section_name (filedata, section) : "");
16204 const char *print_name = printable_section_name (filedata, section);
be7d229a 16205 uint64_t length;
015dc7e1 16206 bool result = true;
3f5e193b 16207 int i;
1007acb3 16208
19e6b90e
L
16209 length = section->sh_size;
16210 if (length == 0)
1007acb3 16211 {
74e1a04b 16212 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16213 return true;
1007acb3 16214 }
5dff79d8
NC
16215 if (section->sh_type == SHT_NOBITS)
16216 {
16217 /* There is no point in dumping the contents of a debugging section
16218 which has the NOBITS type - the bits in the file will be random.
16219 This can happen when a file containing a .eh_frame section is
16220 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16221 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16222 print_name);
015dc7e1 16223 return false;
5dff79d8 16224 }
1007acb3 16225
24d127aa 16226 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16227 name = ".debug_info";
1007acb3 16228
19e6b90e
L
16229 /* See if we know how to display the contents of this section. */
16230 for (i = 0; i < max; i++)
d85bf2ba
NC
16231 {
16232 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16233 struct dwarf_section_display * display = debug_displays + i;
16234 struct dwarf_section * sec = & display->section;
d966045b 16235
d85bf2ba 16236 if (streq (sec->uncompressed_name, name)
24d127aa 16237 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16238 || streq (sec->compressed_name, name))
16239 {
015dc7e1 16240 bool secondary = (section != find_section (filedata, name));
1007acb3 16241
d85bf2ba
NC
16242 if (secondary)
16243 free_debug_section (id);
dda8d76d 16244
24d127aa 16245 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16246 sec->name = name;
16247 else if (streq (sec->uncompressed_name, name))
16248 sec->name = sec->uncompressed_name;
16249 else
16250 sec->name = sec->compressed_name;
657d0d47 16251
d85bf2ba
NC
16252 if (load_specific_debug_section (id, section, filedata))
16253 {
16254 /* If this debug section is part of a CU/TU set in a .dwp file,
16255 restrict load_debug_section to the sections in that set. */
16256 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16257
d85bf2ba 16258 result &= display->display (sec, filedata);
657d0d47 16259
d85bf2ba 16260 section_subset = NULL;
1007acb3 16261
44266f36 16262 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16263 free_debug_section (id);
16264 }
16265 break;
16266 }
16267 }
1007acb3 16268
19e6b90e 16269 if (i == max)
1007acb3 16270 {
74e1a04b 16271 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16272 result = false;
1007acb3
L
16273 }
16274
19e6b90e 16275 return result;
5b18a4bc 16276}
103f02d3 16277
aef1f6d0
DJ
16278/* Set DUMP_SECTS for all sections where dumps were requested
16279 based on section name. */
16280
16281static void
dda8d76d 16282initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16283{
2cf0635d 16284 struct dump_list_entry * cur;
aef1f6d0
DJ
16285
16286 for (cur = dump_sects_byname; cur; cur = cur->next)
16287 {
16288 unsigned int i;
015dc7e1 16289 bool any = false;
aef1f6d0 16290
dda8d76d 16291 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16292 if (section_name_valid (filedata, filedata->section_headers + i)
16293 && streq (section_name (filedata, filedata->section_headers + i),
16294 cur->name))
aef1f6d0 16295 {
6431e409 16296 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16297 any = true;
aef1f6d0
DJ
16298 }
16299
835f2fae
NC
16300 if (!any && !filedata->is_separate)
16301 warn (_("Section '%s' was not dumped because it does not exist\n"),
16302 cur->name);
aef1f6d0
DJ
16303 }
16304}
16305
015dc7e1 16306static bool
dda8d76d 16307process_section_contents (Filedata * filedata)
5b18a4bc 16308{
2cf0635d 16309 Elf_Internal_Shdr * section;
19e6b90e 16310 unsigned int i;
015dc7e1 16311 bool res = true;
103f02d3 16312
19e6b90e 16313 if (! do_dump)
015dc7e1 16314 return true;
103f02d3 16315
dda8d76d 16316 initialise_dumps_byname (filedata);
aef1f6d0 16317
dda8d76d 16318 for (i = 0, section = filedata->section_headers;
6431e409 16319 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16320 i++, section++)
16321 {
6431e409 16322 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16323
d6bfbc39
NC
16324 if (filedata->is_separate && ! process_links)
16325 dump &= DEBUG_DUMP;
047c3dbf 16326
19e6b90e 16327#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16328 if (dump & DISASS_DUMP)
16329 {
16330 if (! disassemble_section (section, filedata))
015dc7e1 16331 res = false;
dda8d76d 16332 }
19e6b90e 16333#endif
dda8d76d 16334 if (dump & HEX_DUMP)
32ec8896 16335 {
015dc7e1
AM
16336 if (! dump_section_as_bytes (section, filedata, false))
16337 res = false;
32ec8896 16338 }
103f02d3 16339
dda8d76d 16340 if (dump & RELOC_DUMP)
32ec8896 16341 {
015dc7e1
AM
16342 if (! dump_section_as_bytes (section, filedata, true))
16343 res = false;
32ec8896 16344 }
09c11c86 16345
dda8d76d 16346 if (dump & STRING_DUMP)
32ec8896 16347 {
dda8d76d 16348 if (! dump_section_as_strings (section, filedata))
015dc7e1 16349 res = false;
32ec8896 16350 }
cf13d699 16351
dda8d76d 16352 if (dump & DEBUG_DUMP)
32ec8896 16353 {
dda8d76d 16354 if (! display_debug_section (i, section, filedata))
015dc7e1 16355 res = false;
32ec8896 16356 }
7d9813f1 16357
094e34f2 16358#ifdef ENABLE_LIBCTF
7d9813f1
NA
16359 if (dump & CTF_DUMP)
16360 {
16361 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16362 res = false;
7d9813f1 16363 }
094e34f2 16364#endif
5b18a4bc 16365 }
103f02d3 16366
835f2fae 16367 if (! filedata->is_separate)
0ee3043f 16368 {
835f2fae
NC
16369 /* Check to see if the user requested a
16370 dump of a section that does not exist. */
16371 for (; i < filedata->dump.num_dump_sects; i++)
16372 if (filedata->dump.dump_sects[i])
16373 {
ca0e11aa 16374 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16375 res = false;
835f2fae 16376 }
0ee3043f 16377 }
32ec8896
NC
16378
16379 return res;
5b18a4bc 16380}
103f02d3 16381
5b18a4bc 16382static void
19e6b90e 16383process_mips_fpe_exception (int mask)
5b18a4bc 16384{
19e6b90e
L
16385 if (mask)
16386 {
015dc7e1 16387 bool first = true;
32ec8896 16388
19e6b90e 16389 if (mask & OEX_FPU_INEX)
015dc7e1 16390 fputs ("INEX", stdout), first = false;
19e6b90e 16391 if (mask & OEX_FPU_UFLO)
015dc7e1 16392 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16393 if (mask & OEX_FPU_OFLO)
015dc7e1 16394 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16395 if (mask & OEX_FPU_DIV0)
015dc7e1 16396 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16397 if (mask & OEX_FPU_INVAL)
16398 printf ("%sINVAL", first ? "" : "|");
16399 }
5b18a4bc 16400 else
19e6b90e 16401 fputs ("0", stdout);
5b18a4bc 16402}
103f02d3 16403
f6f0e17b
NC
16404/* Display's the value of TAG at location P. If TAG is
16405 greater than 0 it is assumed to be an unknown tag, and
16406 a message is printed to this effect. Otherwise it is
16407 assumed that a message has already been printed.
16408
16409 If the bottom bit of TAG is set it assumed to have a
16410 string value, otherwise it is assumed to have an integer
16411 value.
16412
16413 Returns an updated P pointing to the first unread byte
16414 beyond the end of TAG's value.
16415
16416 Reads at or beyond END will not be made. */
16417
16418static unsigned char *
60abdbed 16419display_tag_value (signed int tag,
f6f0e17b
NC
16420 unsigned char * p,
16421 const unsigned char * const end)
16422{
16423 unsigned long val;
16424
16425 if (tag > 0)
16426 printf (" Tag_unknown_%d: ", tag);
16427
16428 if (p >= end)
16429 {
4082ef84 16430 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16431 }
16432 else if (tag & 1)
16433 {
071436c6
NC
16434 /* PR 17531 file: 027-19978-0.004. */
16435 size_t maxlen = (end - p) - 1;
16436
16437 putchar ('"');
4082ef84
NC
16438 if (maxlen > 0)
16439 {
16440 print_symbol ((int) maxlen, (const char *) p);
16441 p += strnlen ((char *) p, maxlen) + 1;
16442 }
16443 else
16444 {
16445 printf (_("<corrupt string tag>"));
16446 p = (unsigned char *) end;
16447 }
071436c6 16448 printf ("\"\n");
f6f0e17b
NC
16449 }
16450 else
16451 {
cd30bcef 16452 READ_ULEB (val, p, end);
f6f0e17b
NC
16453 printf ("%ld (0x%lx)\n", val, val);
16454 }
16455
4082ef84 16456 assert (p <= end);
f6f0e17b
NC
16457 return p;
16458}
16459
53a346d8
CZ
16460/* ARC ABI attributes section. */
16461
16462static unsigned char *
16463display_arc_attribute (unsigned char * p,
16464 const unsigned char * const end)
16465{
16466 unsigned int tag;
53a346d8
CZ
16467 unsigned int val;
16468
cd30bcef 16469 READ_ULEB (tag, p, end);
53a346d8
CZ
16470
16471 switch (tag)
16472 {
16473 case Tag_ARC_PCS_config:
cd30bcef 16474 READ_ULEB (val, p, end);
53a346d8
CZ
16475 printf (" Tag_ARC_PCS_config: ");
16476 switch (val)
16477 {
16478 case 0:
16479 printf (_("Absent/Non standard\n"));
16480 break;
16481 case 1:
16482 printf (_("Bare metal/mwdt\n"));
16483 break;
16484 case 2:
16485 printf (_("Bare metal/newlib\n"));
16486 break;
16487 case 3:
16488 printf (_("Linux/uclibc\n"));
16489 break;
16490 case 4:
16491 printf (_("Linux/glibc\n"));
16492 break;
16493 default:
16494 printf (_("Unknown\n"));
16495 break;
16496 }
16497 break;
16498
16499 case Tag_ARC_CPU_base:
cd30bcef 16500 READ_ULEB (val, p, end);
53a346d8
CZ
16501 printf (" Tag_ARC_CPU_base: ");
16502 switch (val)
16503 {
16504 default:
16505 case TAG_CPU_NONE:
16506 printf (_("Absent\n"));
16507 break;
16508 case TAG_CPU_ARC6xx:
16509 printf ("ARC6xx\n");
16510 break;
16511 case TAG_CPU_ARC7xx:
16512 printf ("ARC7xx\n");
16513 break;
16514 case TAG_CPU_ARCEM:
16515 printf ("ARCEM\n");
16516 break;
16517 case TAG_CPU_ARCHS:
16518 printf ("ARCHS\n");
16519 break;
16520 }
16521 break;
16522
16523 case Tag_ARC_CPU_variation:
cd30bcef 16524 READ_ULEB (val, p, end);
53a346d8
CZ
16525 printf (" Tag_ARC_CPU_variation: ");
16526 switch (val)
16527 {
16528 default:
16529 if (val > 0 && val < 16)
53a346d8 16530 printf ("Core%d\n", val);
d8cbc93b
JL
16531 else
16532 printf ("Unknown\n");
16533 break;
16534
53a346d8
CZ
16535 case 0:
16536 printf (_("Absent\n"));
16537 break;
16538 }
16539 break;
16540
16541 case Tag_ARC_CPU_name:
16542 printf (" Tag_ARC_CPU_name: ");
16543 p = display_tag_value (-1, p, end);
16544 break;
16545
16546 case Tag_ARC_ABI_rf16:
cd30bcef 16547 READ_ULEB (val, p, end);
53a346d8
CZ
16548 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16549 break;
16550
16551 case Tag_ARC_ABI_osver:
cd30bcef 16552 READ_ULEB (val, p, end);
53a346d8
CZ
16553 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16554 break;
16555
16556 case Tag_ARC_ABI_pic:
16557 case Tag_ARC_ABI_sda:
cd30bcef 16558 READ_ULEB (val, p, end);
53a346d8
CZ
16559 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16560 : " Tag_ARC_ABI_pic: ");
16561 switch (val)
16562 {
16563 case 0:
16564 printf (_("Absent\n"));
16565 break;
16566 case 1:
16567 printf ("MWDT\n");
16568 break;
16569 case 2:
16570 printf ("GNU\n");
16571 break;
16572 default:
16573 printf (_("Unknown\n"));
16574 break;
16575 }
16576 break;
16577
16578 case Tag_ARC_ABI_tls:
cd30bcef 16579 READ_ULEB (val, p, end);
53a346d8
CZ
16580 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16581 break;
16582
16583 case Tag_ARC_ABI_enumsize:
cd30bcef 16584 READ_ULEB (val, p, end);
53a346d8
CZ
16585 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16586 _("smallest"));
16587 break;
16588
16589 case Tag_ARC_ABI_exceptions:
cd30bcef 16590 READ_ULEB (val, p, end);
53a346d8
CZ
16591 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16592 : _("default"));
16593 break;
16594
16595 case Tag_ARC_ABI_double_size:
cd30bcef 16596 READ_ULEB (val, p, end);
53a346d8
CZ
16597 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16598 break;
16599
16600 case Tag_ARC_ISA_config:
16601 printf (" Tag_ARC_ISA_config: ");
16602 p = display_tag_value (-1, p, end);
16603 break;
16604
16605 case Tag_ARC_ISA_apex:
16606 printf (" Tag_ARC_ISA_apex: ");
16607 p = display_tag_value (-1, p, end);
16608 break;
16609
16610 case Tag_ARC_ISA_mpy_option:
cd30bcef 16611 READ_ULEB (val, p, end);
53a346d8
CZ
16612 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16613 break;
16614
db1e1b45 16615 case Tag_ARC_ATR_version:
cd30bcef 16616 READ_ULEB (val, p, end);
db1e1b45 16617 printf (" Tag_ARC_ATR_version: %d\n", val);
16618 break;
16619
53a346d8
CZ
16620 default:
16621 return display_tag_value (tag & 1, p, end);
16622 }
16623
16624 return p;
16625}
16626
11c1ff18
PB
16627/* ARM EABI attributes section. */
16628typedef struct
16629{
70e99720 16630 unsigned int tag;
2cf0635d 16631 const char * name;
11c1ff18 16632 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16633 unsigned int type;
288f0ba2 16634 const char *const *table;
11c1ff18
PB
16635} arm_attr_public_tag;
16636
288f0ba2 16637static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16638 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16639 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16640 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16641 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16642static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16643static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16644 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16645static const char *const arm_attr_tag_FP_arch[] =
bca38921 16646 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16647 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16648static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16649static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16650 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16651 "NEON for ARMv8.1"};
288f0ba2 16652static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16653 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16654 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16655static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16656 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16657static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16658 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16659static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16660 {"Absolute", "PC-relative", "None"};
288f0ba2 16661static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16662 {"None", "direct", "GOT-indirect"};
288f0ba2 16663static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16664 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16665static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16666static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16667 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16668static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16669static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16670static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16671 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16672static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16673 {"Unused", "small", "int", "forced to int"};
288f0ba2 16674static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16675 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16676static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16677 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16678static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16679 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16680static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16681 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16682 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16683static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16684 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16685 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16686static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16687static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16688 {"Not Allowed", "Allowed"};
288f0ba2 16689static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16690 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16691static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16692 {"Follow architecture", "Allowed"};
288f0ba2 16693static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16694 {"Not Allowed", "Allowed"};
288f0ba2 16695static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16696 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16697 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16698static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16699static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16700 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16701 "TrustZone and Virtualization Extensions"};
288f0ba2 16702static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16703 {"Not Allowed", "Allowed"};
11c1ff18 16704
288f0ba2 16705static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16706 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16707
99db83d0
AC
16708static const char * arm_attr_tag_PAC_extension[] =
16709 {"No PAC/AUT instructions",
16710 "PAC/AUT instructions permitted in the NOP space",
16711 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16712
4b535030
AC
16713static const char * arm_attr_tag_BTI_extension[] =
16714 {"BTI instructions not permitted",
16715 "BTI instructions permitted in the NOP space",
16716 "BTI instructions permitted in the NOP and in the non-NOP space"};
16717
b81ee92f
AC
16718static const char * arm_attr_tag_BTI_use[] =
16719 {"Compiled without branch target enforcement",
16720 "Compiled with branch target enforcement"};
16721
c9fed665
AC
16722static const char * arm_attr_tag_PACRET_use[] =
16723 {"Compiled without return address signing and authentication",
16724 "Compiled with return address signing and authentication"};
16725
11c1ff18
PB
16726#define LOOKUP(id, name) \
16727 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16728static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16729{
16730 {4, "CPU_raw_name", 1, NULL},
16731 {5, "CPU_name", 1, NULL},
16732 LOOKUP(6, CPU_arch),
16733 {7, "CPU_arch_profile", 0, NULL},
16734 LOOKUP(8, ARM_ISA_use),
16735 LOOKUP(9, THUMB_ISA_use),
75375b3e 16736 LOOKUP(10, FP_arch),
11c1ff18 16737 LOOKUP(11, WMMX_arch),
f5f53991
AS
16738 LOOKUP(12, Advanced_SIMD_arch),
16739 LOOKUP(13, PCS_config),
11c1ff18
PB
16740 LOOKUP(14, ABI_PCS_R9_use),
16741 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16742 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16743 LOOKUP(17, ABI_PCS_GOT_use),
16744 LOOKUP(18, ABI_PCS_wchar_t),
16745 LOOKUP(19, ABI_FP_rounding),
16746 LOOKUP(20, ABI_FP_denormal),
16747 LOOKUP(21, ABI_FP_exceptions),
16748 LOOKUP(22, ABI_FP_user_exceptions),
16749 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16750 {24, "ABI_align_needed", 0, NULL},
16751 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16752 LOOKUP(26, ABI_enum_size),
16753 LOOKUP(27, ABI_HardFP_use),
16754 LOOKUP(28, ABI_VFP_args),
16755 LOOKUP(29, ABI_WMMX_args),
16756 LOOKUP(30, ABI_optimization_goals),
16757 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16758 {32, "compatibility", 0, NULL},
f5f53991 16759 LOOKUP(34, CPU_unaligned_access),
75375b3e 16760 LOOKUP(36, FP_HP_extension),
8e79c3df 16761 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16762 LOOKUP(42, MPextension_use),
16763 LOOKUP(44, DIV_use),
15afaa63 16764 LOOKUP(46, DSP_extension),
a7ad558c 16765 LOOKUP(48, MVE_arch),
99db83d0 16766 LOOKUP(50, PAC_extension),
4b535030 16767 LOOKUP(52, BTI_extension),
b81ee92f 16768 LOOKUP(74, BTI_use),
c9fed665 16769 LOOKUP(76, PACRET_use),
f5f53991
AS
16770 {64, "nodefaults", 0, NULL},
16771 {65, "also_compatible_with", 0, NULL},
16772 LOOKUP(66, T2EE_use),
16773 {67, "conformance", 1, NULL},
16774 LOOKUP(68, Virtualization_use),
cd21e546 16775 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16776};
16777#undef LOOKUP
16778
11c1ff18 16779static unsigned char *
f6f0e17b
NC
16780display_arm_attribute (unsigned char * p,
16781 const unsigned char * const end)
11c1ff18 16782{
70e99720 16783 unsigned int tag;
70e99720 16784 unsigned int val;
2cf0635d 16785 arm_attr_public_tag * attr;
11c1ff18 16786 unsigned i;
70e99720 16787 unsigned int type;
11c1ff18 16788
cd30bcef 16789 READ_ULEB (tag, p, end);
11c1ff18 16790 attr = NULL;
2cf0635d 16791 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16792 {
16793 if (arm_attr_public_tags[i].tag == tag)
16794 {
16795 attr = &arm_attr_public_tags[i];
16796 break;
16797 }
16798 }
16799
16800 if (attr)
16801 {
16802 printf (" Tag_%s: ", attr->name);
16803 switch (attr->type)
16804 {
16805 case 0:
16806 switch (tag)
16807 {
16808 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16809 READ_ULEB (val, p, end);
11c1ff18
PB
16810 switch (val)
16811 {
2b692964
NC
16812 case 0: printf (_("None\n")); break;
16813 case 'A': printf (_("Application\n")); break;
16814 case 'R': printf (_("Realtime\n")); break;
16815 case 'M': printf (_("Microcontroller\n")); break;
16816 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16817 default: printf ("??? (%d)\n", val); break;
16818 }
16819 break;
16820
75375b3e 16821 case 24: /* Tag_align_needed. */
cd30bcef 16822 READ_ULEB (val, p, end);
75375b3e
MGD
16823 switch (val)
16824 {
2b692964
NC
16825 case 0: printf (_("None\n")); break;
16826 case 1: printf (_("8-byte\n")); break;
16827 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16828 case 3: printf ("??? 3\n"); break;
16829 default:
16830 if (val <= 12)
dd24e3da 16831 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16832 1 << val);
16833 else
16834 printf ("??? (%d)\n", val);
16835 break;
16836 }
16837 break;
16838
16839 case 25: /* Tag_align_preserved. */
cd30bcef 16840 READ_ULEB (val, p, end);
75375b3e
MGD
16841 switch (val)
16842 {
2b692964
NC
16843 case 0: printf (_("None\n")); break;
16844 case 1: printf (_("8-byte, except leaf SP\n")); break;
16845 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16846 case 3: printf ("??? 3\n"); break;
16847 default:
16848 if (val <= 12)
dd24e3da 16849 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16850 1 << val);
16851 else
16852 printf ("??? (%d)\n", val);
16853 break;
16854 }
16855 break;
16856
11c1ff18 16857 case 32: /* Tag_compatibility. */
071436c6 16858 {
cd30bcef 16859 READ_ULEB (val, p, end);
071436c6 16860 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16861 if (p < end - 1)
16862 {
16863 size_t maxlen = (end - p) - 1;
16864
16865 print_symbol ((int) maxlen, (const char *) p);
16866 p += strnlen ((char *) p, maxlen) + 1;
16867 }
16868 else
16869 {
16870 printf (_("<corrupt>"));
16871 p = (unsigned char *) end;
16872 }
071436c6 16873 putchar ('\n');
071436c6 16874 }
11c1ff18
PB
16875 break;
16876
f5f53991 16877 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16878 /* PR 17531: file: 001-505008-0.01. */
16879 if (p < end)
16880 p++;
2b692964 16881 printf (_("True\n"));
f5f53991
AS
16882 break;
16883
16884 case 65: /* Tag_also_compatible_with. */
cd30bcef 16885 READ_ULEB (val, p, end);
f5f53991
AS
16886 if (val == 6 /* Tag_CPU_arch. */)
16887 {
cd30bcef 16888 READ_ULEB (val, p, end);
071436c6 16889 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16890 printf ("??? (%d)\n", val);
16891 else
16892 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16893 }
16894 else
16895 printf ("???\n");
071436c6
NC
16896 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16897 ;
f5f53991
AS
16898 break;
16899
11c1ff18 16900 default:
bee0ee85
NC
16901 printf (_("<unknown: %d>\n"), tag);
16902 break;
11c1ff18
PB
16903 }
16904 return p;
16905
16906 case 1:
f6f0e17b 16907 return display_tag_value (-1, p, end);
11c1ff18 16908 case 2:
f6f0e17b 16909 return display_tag_value (0, p, end);
11c1ff18
PB
16910
16911 default:
16912 assert (attr->type & 0x80);
cd30bcef 16913 READ_ULEB (val, p, end);
11c1ff18
PB
16914 type = attr->type & 0x7f;
16915 if (val >= type)
16916 printf ("??? (%d)\n", val);
16917 else
16918 printf ("%s\n", attr->table[val]);
16919 return p;
16920 }
16921 }
11c1ff18 16922
f6f0e17b 16923 return display_tag_value (tag, p, end);
11c1ff18
PB
16924}
16925
104d59d1 16926static unsigned char *
60bca95a 16927display_gnu_attribute (unsigned char * p,
60abdbed 16928 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16929 const unsigned char * const end)
104d59d1 16930{
cd30bcef 16931 unsigned int tag;
60abdbed 16932 unsigned int val;
104d59d1 16933
cd30bcef 16934 READ_ULEB (tag, p, end);
104d59d1
JM
16935
16936 /* Tag_compatibility is the only generic GNU attribute defined at
16937 present. */
16938 if (tag == 32)
16939 {
cd30bcef 16940 READ_ULEB (val, p, end);
071436c6
NC
16941
16942 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16943 if (p == end)
16944 {
071436c6 16945 printf (_("<corrupt>\n"));
f6f0e17b
NC
16946 warn (_("corrupt vendor attribute\n"));
16947 }
16948 else
16949 {
4082ef84
NC
16950 if (p < end - 1)
16951 {
16952 size_t maxlen = (end - p) - 1;
071436c6 16953
4082ef84
NC
16954 print_symbol ((int) maxlen, (const char *) p);
16955 p += strnlen ((char *) p, maxlen) + 1;
16956 }
16957 else
16958 {
16959 printf (_("<corrupt>"));
16960 p = (unsigned char *) end;
16961 }
071436c6 16962 putchar ('\n');
f6f0e17b 16963 }
104d59d1
JM
16964 return p;
16965 }
16966
16967 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16968 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16969
f6f0e17b 16970 return display_tag_value (tag, p, end);
104d59d1
JM
16971}
16972
85f7484a
PB
16973static unsigned char *
16974display_m68k_gnu_attribute (unsigned char * p,
16975 unsigned int tag,
16976 const unsigned char * const end)
16977{
16978 unsigned int val;
16979
16980 if (tag == Tag_GNU_M68K_ABI_FP)
16981 {
16982 printf (" Tag_GNU_M68K_ABI_FP: ");
16983 if (p == end)
16984 {
16985 printf (_("<corrupt>\n"));
16986 return p;
16987 }
16988 READ_ULEB (val, p, end);
16989
16990 if (val > 3)
16991 printf ("(%#x), ", val);
16992
16993 switch (val & 3)
16994 {
16995 case 0:
16996 printf (_("unspecified hard/soft float\n"));
16997 break;
16998 case 1:
16999 printf (_("hard float\n"));
17000 break;
17001 case 2:
17002 printf (_("soft float\n"));
17003 break;
17004 }
17005 return p;
17006 }
17007
17008 return display_tag_value (tag & 1, p, end);
17009}
17010
34c8bcba 17011static unsigned char *
f6f0e17b 17012display_power_gnu_attribute (unsigned char * p,
60abdbed 17013 unsigned int tag,
f6f0e17b 17014 const unsigned char * const end)
34c8bcba 17015{
005d79fd 17016 unsigned int val;
34c8bcba
JM
17017
17018 if (tag == Tag_GNU_Power_ABI_FP)
17019 {
34c8bcba 17020 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 17021 if (p == end)
005d79fd
AM
17022 {
17023 printf (_("<corrupt>\n"));
17024 return p;
17025 }
cd30bcef 17026 READ_ULEB (val, p, end);
60bca95a 17027
005d79fd
AM
17028 if (val > 15)
17029 printf ("(%#x), ", val);
17030
17031 switch (val & 3)
34c8bcba
JM
17032 {
17033 case 0:
005d79fd 17034 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17035 break;
17036 case 1:
005d79fd 17037 printf (_("hard float, "));
34c8bcba
JM
17038 break;
17039 case 2:
005d79fd 17040 printf (_("soft float, "));
34c8bcba 17041 break;
3c7b9897 17042 case 3:
005d79fd 17043 printf (_("single-precision hard float, "));
3c7b9897 17044 break;
005d79fd
AM
17045 }
17046
17047 switch (val & 0xC)
17048 {
17049 case 0:
17050 printf (_("unspecified long double\n"));
17051 break;
17052 case 4:
17053 printf (_("128-bit IBM long double\n"));
17054 break;
17055 case 8:
17056 printf (_("64-bit long double\n"));
17057 break;
17058 case 12:
17059 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17060 break;
17061 }
17062 return p;
005d79fd 17063 }
34c8bcba 17064
c6e65352
DJ
17065 if (tag == Tag_GNU_Power_ABI_Vector)
17066 {
c6e65352 17067 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17068 if (p == end)
005d79fd
AM
17069 {
17070 printf (_("<corrupt>\n"));
17071 return p;
17072 }
cd30bcef 17073 READ_ULEB (val, p, end);
005d79fd
AM
17074
17075 if (val > 3)
17076 printf ("(%#x), ", val);
17077
17078 switch (val & 3)
c6e65352
DJ
17079 {
17080 case 0:
005d79fd 17081 printf (_("unspecified\n"));
c6e65352
DJ
17082 break;
17083 case 1:
005d79fd 17084 printf (_("generic\n"));
c6e65352
DJ
17085 break;
17086 case 2:
17087 printf ("AltiVec\n");
17088 break;
17089 case 3:
17090 printf ("SPE\n");
17091 break;
c6e65352
DJ
17092 }
17093 return p;
005d79fd 17094 }
c6e65352 17095
f82e0623
NF
17096 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17097 {
005d79fd 17098 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17099 if (p == end)
f6f0e17b 17100 {
005d79fd 17101 printf (_("<corrupt>\n"));
f6f0e17b
NC
17102 return p;
17103 }
cd30bcef 17104 READ_ULEB (val, p, end);
0b4362b0 17105
005d79fd
AM
17106 if (val > 2)
17107 printf ("(%#x), ", val);
17108
17109 switch (val & 3)
17110 {
17111 case 0:
17112 printf (_("unspecified\n"));
17113 break;
17114 case 1:
17115 printf ("r3/r4\n");
17116 break;
17117 case 2:
17118 printf (_("memory\n"));
17119 break;
17120 case 3:
17121 printf ("???\n");
17122 break;
17123 }
f82e0623
NF
17124 return p;
17125 }
17126
f6f0e17b 17127 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17128}
17129
643f7afb
AK
17130static unsigned char *
17131display_s390_gnu_attribute (unsigned char * p,
60abdbed 17132 unsigned int tag,
643f7afb
AK
17133 const unsigned char * const end)
17134{
cd30bcef 17135 unsigned int val;
643f7afb
AK
17136
17137 if (tag == Tag_GNU_S390_ABI_Vector)
17138 {
643f7afb 17139 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17140 READ_ULEB (val, p, end);
643f7afb
AK
17141
17142 switch (val)
17143 {
17144 case 0:
17145 printf (_("any\n"));
17146 break;
17147 case 1:
17148 printf (_("software\n"));
17149 break;
17150 case 2:
17151 printf (_("hardware\n"));
17152 break;
17153 default:
17154 printf ("??? (%d)\n", val);
17155 break;
17156 }
17157 return p;
17158 }
17159
17160 return display_tag_value (tag & 1, p, end);
17161}
17162
9e8c70f9 17163static void
60abdbed 17164display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17165{
17166 if (mask)
17167 {
015dc7e1 17168 bool first = true;
071436c6 17169
9e8c70f9 17170 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17171 fputs ("mul32", stdout), first = false;
9e8c70f9 17172 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17173 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17174 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17175 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17176 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17177 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17178 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17179 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17180 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17181 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17182 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17183 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17184 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17185 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17186 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17187 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17188 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17189 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17190 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17191 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17192 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17193 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17194 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17195 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17196 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17197 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17198 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17199 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17200 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17201 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17202 }
17203 else
071436c6
NC
17204 fputc ('0', stdout);
17205 fputc ('\n', stdout);
9e8c70f9
DM
17206}
17207
3d68f91c 17208static void
60abdbed 17209display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17210{
17211 if (mask)
17212 {
015dc7e1 17213 bool first = true;
071436c6 17214
3d68f91c 17215 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17216 fputs ("fjathplus", stdout), first = false;
3d68f91c 17217 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17218 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17219 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17220 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17221 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17222 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17223 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17224 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17225 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17226 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17227 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17228 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17229 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17230 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17231 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17232 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17233 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17234 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17235 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17236 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17237 }
17238 else
071436c6
NC
17239 fputc ('0', stdout);
17240 fputc ('\n', stdout);
3d68f91c
JM
17241}
17242
9e8c70f9 17243static unsigned char *
f6f0e17b 17244display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17245 unsigned int tag,
f6f0e17b 17246 const unsigned char * const end)
9e8c70f9 17247{
cd30bcef 17248 unsigned int val;
3d68f91c 17249
9e8c70f9
DM
17250 if (tag == Tag_GNU_Sparc_HWCAPS)
17251 {
cd30bcef 17252 READ_ULEB (val, p, end);
9e8c70f9 17253 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17254 display_sparc_hwcaps (val);
17255 return p;
3d68f91c
JM
17256 }
17257 if (tag == Tag_GNU_Sparc_HWCAPS2)
17258 {
cd30bcef 17259 READ_ULEB (val, p, end);
3d68f91c
JM
17260 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17261 display_sparc_hwcaps2 (val);
17262 return p;
17263 }
9e8c70f9 17264
f6f0e17b 17265 return display_tag_value (tag, p, end);
9e8c70f9
DM
17266}
17267
351cdf24 17268static void
32ec8896 17269print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17270{
17271 switch (val)
17272 {
17273 case Val_GNU_MIPS_ABI_FP_ANY:
17274 printf (_("Hard or soft float\n"));
17275 break;
17276 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17277 printf (_("Hard float (double precision)\n"));
17278 break;
17279 case Val_GNU_MIPS_ABI_FP_SINGLE:
17280 printf (_("Hard float (single precision)\n"));
17281 break;
17282 case Val_GNU_MIPS_ABI_FP_SOFT:
17283 printf (_("Soft float\n"));
17284 break;
17285 case Val_GNU_MIPS_ABI_FP_OLD_64:
17286 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17287 break;
17288 case Val_GNU_MIPS_ABI_FP_XX:
17289 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17290 break;
17291 case Val_GNU_MIPS_ABI_FP_64:
17292 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17293 break;
17294 case Val_GNU_MIPS_ABI_FP_64A:
17295 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17296 break;
3350cc01
CM
17297 case Val_GNU_MIPS_ABI_FP_NAN2008:
17298 printf (_("NaN 2008 compatibility\n"));
17299 break;
351cdf24
MF
17300 default:
17301 printf ("??? (%d)\n", val);
17302 break;
17303 }
17304}
17305
2cf19d5c 17306static unsigned char *
f6f0e17b 17307display_mips_gnu_attribute (unsigned char * p,
60abdbed 17308 unsigned int tag,
f6f0e17b 17309 const unsigned char * const end)
2cf19d5c 17310{
2cf19d5c
JM
17311 if (tag == Tag_GNU_MIPS_ABI_FP)
17312 {
32ec8896 17313 unsigned int val;
f6f0e17b 17314
2cf19d5c 17315 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17316 READ_ULEB (val, p, end);
351cdf24 17317 print_mips_fp_abi_value (val);
2cf19d5c
JM
17318 return p;
17319 }
17320
a9f58168
CF
17321 if (tag == Tag_GNU_MIPS_ABI_MSA)
17322 {
32ec8896 17323 unsigned int val;
a9f58168 17324
a9f58168 17325 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17326 READ_ULEB (val, p, end);
a9f58168
CF
17327
17328 switch (val)
17329 {
17330 case Val_GNU_MIPS_ABI_MSA_ANY:
17331 printf (_("Any MSA or not\n"));
17332 break;
17333 case Val_GNU_MIPS_ABI_MSA_128:
17334 printf (_("128-bit MSA\n"));
17335 break;
17336 default:
17337 printf ("??? (%d)\n", val);
17338 break;
17339 }
17340 return p;
17341 }
17342
f6f0e17b 17343 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17344}
17345
59e6276b 17346static unsigned char *
f6f0e17b
NC
17347display_tic6x_attribute (unsigned char * p,
17348 const unsigned char * const end)
59e6276b 17349{
60abdbed 17350 unsigned int tag;
cd30bcef 17351 unsigned int val;
59e6276b 17352
cd30bcef 17353 READ_ULEB (tag, p, end);
59e6276b
JM
17354
17355 switch (tag)
17356 {
75fa6dc1 17357 case Tag_ISA:
75fa6dc1 17358 printf (" Tag_ISA: ");
cd30bcef 17359 READ_ULEB (val, p, end);
59e6276b
JM
17360
17361 switch (val)
17362 {
75fa6dc1 17363 case C6XABI_Tag_ISA_none:
59e6276b
JM
17364 printf (_("None\n"));
17365 break;
75fa6dc1 17366 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17367 printf ("C62x\n");
17368 break;
75fa6dc1 17369 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17370 printf ("C67x\n");
17371 break;
75fa6dc1 17372 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17373 printf ("C67x+\n");
17374 break;
75fa6dc1 17375 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17376 printf ("C64x\n");
17377 break;
75fa6dc1 17378 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17379 printf ("C64x+\n");
17380 break;
75fa6dc1 17381 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17382 printf ("C674x\n");
17383 break;
17384 default:
17385 printf ("??? (%d)\n", val);
17386 break;
17387 }
17388 return p;
17389
87779176 17390 case Tag_ABI_wchar_t:
87779176 17391 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17392 READ_ULEB (val, p, end);
87779176
JM
17393 switch (val)
17394 {
17395 case 0:
17396 printf (_("Not used\n"));
17397 break;
17398 case 1:
17399 printf (_("2 bytes\n"));
17400 break;
17401 case 2:
17402 printf (_("4 bytes\n"));
17403 break;
17404 default:
17405 printf ("??? (%d)\n", val);
17406 break;
17407 }
17408 return p;
17409
17410 case Tag_ABI_stack_align_needed:
87779176 17411 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17412 READ_ULEB (val, p, end);
87779176
JM
17413 switch (val)
17414 {
17415 case 0:
17416 printf (_("8-byte\n"));
17417 break;
17418 case 1:
17419 printf (_("16-byte\n"));
17420 break;
17421 default:
17422 printf ("??? (%d)\n", val);
17423 break;
17424 }
17425 return p;
17426
17427 case Tag_ABI_stack_align_preserved:
cd30bcef 17428 READ_ULEB (val, p, end);
87779176
JM
17429 printf (" Tag_ABI_stack_align_preserved: ");
17430 switch (val)
17431 {
17432 case 0:
17433 printf (_("8-byte\n"));
17434 break;
17435 case 1:
17436 printf (_("16-byte\n"));
17437 break;
17438 default:
17439 printf ("??? (%d)\n", val);
17440 break;
17441 }
17442 return p;
17443
b5593623 17444 case Tag_ABI_DSBT:
cd30bcef 17445 READ_ULEB (val, p, end);
b5593623
JM
17446 printf (" Tag_ABI_DSBT: ");
17447 switch (val)
17448 {
17449 case 0:
17450 printf (_("DSBT addressing not used\n"));
17451 break;
17452 case 1:
17453 printf (_("DSBT addressing used\n"));
17454 break;
17455 default:
17456 printf ("??? (%d)\n", val);
17457 break;
17458 }
17459 return p;
17460
87779176 17461 case Tag_ABI_PID:
cd30bcef 17462 READ_ULEB (val, p, end);
87779176
JM
17463 printf (" Tag_ABI_PID: ");
17464 switch (val)
17465 {
17466 case 0:
17467 printf (_("Data addressing position-dependent\n"));
17468 break;
17469 case 1:
17470 printf (_("Data addressing position-independent, GOT near DP\n"));
17471 break;
17472 case 2:
17473 printf (_("Data addressing position-independent, GOT far from DP\n"));
17474 break;
17475 default:
17476 printf ("??? (%d)\n", val);
17477 break;
17478 }
17479 return p;
17480
17481 case Tag_ABI_PIC:
cd30bcef 17482 READ_ULEB (val, p, end);
87779176
JM
17483 printf (" Tag_ABI_PIC: ");
17484 switch (val)
17485 {
17486 case 0:
17487 printf (_("Code addressing position-dependent\n"));
17488 break;
17489 case 1:
17490 printf (_("Code addressing position-independent\n"));
17491 break;
17492 default:
17493 printf ("??? (%d)\n", val);
17494 break;
17495 }
17496 return p;
17497
17498 case Tag_ABI_array_object_alignment:
cd30bcef 17499 READ_ULEB (val, p, end);
87779176
JM
17500 printf (" Tag_ABI_array_object_alignment: ");
17501 switch (val)
17502 {
17503 case 0:
17504 printf (_("8-byte\n"));
17505 break;
17506 case 1:
17507 printf (_("4-byte\n"));
17508 break;
17509 case 2:
17510 printf (_("16-byte\n"));
17511 break;
17512 default:
17513 printf ("??? (%d)\n", val);
17514 break;
17515 }
17516 return p;
17517
17518 case Tag_ABI_array_object_align_expected:
cd30bcef 17519 READ_ULEB (val, p, end);
87779176
JM
17520 printf (" Tag_ABI_array_object_align_expected: ");
17521 switch (val)
17522 {
17523 case 0:
17524 printf (_("8-byte\n"));
17525 break;
17526 case 1:
17527 printf (_("4-byte\n"));
17528 break;
17529 case 2:
17530 printf (_("16-byte\n"));
17531 break;
17532 default:
17533 printf ("??? (%d)\n", val);
17534 break;
17535 }
17536 return p;
17537
3cbd1c06 17538 case Tag_ABI_compatibility:
071436c6 17539 {
cd30bcef 17540 READ_ULEB (val, p, end);
071436c6 17541 printf (" Tag_ABI_compatibility: ");
071436c6 17542 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17543 if (p < end - 1)
17544 {
17545 size_t maxlen = (end - p) - 1;
17546
17547 print_symbol ((int) maxlen, (const char *) p);
17548 p += strnlen ((char *) p, maxlen) + 1;
17549 }
17550 else
17551 {
17552 printf (_("<corrupt>"));
17553 p = (unsigned char *) end;
17554 }
071436c6 17555 putchar ('\n');
071436c6
NC
17556 return p;
17557 }
87779176
JM
17558
17559 case Tag_ABI_conformance:
071436c6 17560 {
4082ef84
NC
17561 printf (" Tag_ABI_conformance: \"");
17562 if (p < end - 1)
17563 {
17564 size_t maxlen = (end - p) - 1;
071436c6 17565
4082ef84
NC
17566 print_symbol ((int) maxlen, (const char *) p);
17567 p += strnlen ((char *) p, maxlen) + 1;
17568 }
17569 else
17570 {
17571 printf (_("<corrupt>"));
17572 p = (unsigned char *) end;
17573 }
071436c6 17574 printf ("\"\n");
071436c6
NC
17575 return p;
17576 }
59e6276b
JM
17577 }
17578
f6f0e17b
NC
17579 return display_tag_value (tag, p, end);
17580}
59e6276b 17581
f6f0e17b 17582static void
60abdbed 17583display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17584{
17585 unsigned long addr = 0;
17586 size_t bytes = end - p;
17587
feceaa59 17588 assert (end >= p);
f6f0e17b 17589 while (bytes)
87779176 17590 {
f6f0e17b
NC
17591 int j;
17592 int k;
17593 int lbytes = (bytes > 16 ? 16 : bytes);
17594
17595 printf (" 0x%8.8lx ", addr);
17596
17597 for (j = 0; j < 16; j++)
17598 {
17599 if (j < lbytes)
17600 printf ("%2.2x", p[j]);
17601 else
17602 printf (" ");
17603
17604 if ((j & 3) == 3)
17605 printf (" ");
17606 }
17607
17608 for (j = 0; j < lbytes; j++)
17609 {
17610 k = p[j];
17611 if (k >= ' ' && k < 0x7f)
17612 printf ("%c", k);
17613 else
17614 printf (".");
17615 }
17616
17617 putchar ('\n');
17618
17619 p += lbytes;
17620 bytes -= lbytes;
17621 addr += lbytes;
87779176 17622 }
59e6276b 17623
f6f0e17b 17624 putchar ('\n');
59e6276b
JM
17625}
17626
13761a11 17627static unsigned char *
b0191216 17628display_msp430_attribute (unsigned char * p,
13761a11
NC
17629 const unsigned char * const end)
17630{
60abdbed
NC
17631 unsigned int val;
17632 unsigned int tag;
13761a11 17633
cd30bcef 17634 READ_ULEB (tag, p, end);
0b4362b0 17635
13761a11
NC
17636 switch (tag)
17637 {
17638 case OFBA_MSPABI_Tag_ISA:
13761a11 17639 printf (" Tag_ISA: ");
cd30bcef 17640 READ_ULEB (val, p, end);
13761a11
NC
17641 switch (val)
17642 {
17643 case 0: printf (_("None\n")); break;
17644 case 1: printf (_("MSP430\n")); break;
17645 case 2: printf (_("MSP430X\n")); break;
17646 default: printf ("??? (%d)\n", val); break;
17647 }
17648 break;
17649
17650 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17651 printf (" Tag_Code_Model: ");
cd30bcef 17652 READ_ULEB (val, p, end);
13761a11
NC
17653 switch (val)
17654 {
17655 case 0: printf (_("None\n")); break;
17656 case 1: printf (_("Small\n")); break;
17657 case 2: printf (_("Large\n")); break;
17658 default: printf ("??? (%d)\n", val); break;
17659 }
17660 break;
17661
17662 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17663 printf (" Tag_Data_Model: ");
cd30bcef 17664 READ_ULEB (val, p, end);
13761a11
NC
17665 switch (val)
17666 {
17667 case 0: printf (_("None\n")); break;
17668 case 1: printf (_("Small\n")); break;
17669 case 2: printf (_("Large\n")); break;
17670 case 3: printf (_("Restricted Large\n")); break;
17671 default: printf ("??? (%d)\n", val); break;
17672 }
17673 break;
17674
17675 default:
17676 printf (_(" <unknown tag %d>: "), tag);
17677
17678 if (tag & 1)
17679 {
071436c6 17680 putchar ('"');
4082ef84
NC
17681 if (p < end - 1)
17682 {
17683 size_t maxlen = (end - p) - 1;
17684
17685 print_symbol ((int) maxlen, (const char *) p);
17686 p += strnlen ((char *) p, maxlen) + 1;
17687 }
17688 else
17689 {
17690 printf (_("<corrupt>"));
17691 p = (unsigned char *) end;
17692 }
071436c6 17693 printf ("\"\n");
13761a11
NC
17694 }
17695 else
17696 {
cd30bcef 17697 READ_ULEB (val, p, end);
13761a11
NC
17698 printf ("%d (0x%x)\n", val, val);
17699 }
17700 break;
17701 }
17702
4082ef84 17703 assert (p <= end);
13761a11
NC
17704 return p;
17705}
17706
c0ea7c52
JL
17707static unsigned char *
17708display_msp430_gnu_attribute (unsigned char * p,
17709 unsigned int tag,
17710 const unsigned char * const end)
17711{
17712 if (tag == Tag_GNU_MSP430_Data_Region)
17713 {
cd30bcef 17714 unsigned int val;
c0ea7c52 17715
c0ea7c52 17716 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17717 READ_ULEB (val, p, end);
c0ea7c52
JL
17718
17719 switch (val)
17720 {
17721 case Val_GNU_MSP430_Data_Region_Any:
17722 printf (_("Any Region\n"));
17723 break;
17724 case Val_GNU_MSP430_Data_Region_Lower:
17725 printf (_("Lower Region Only\n"));
17726 break;
17727 default:
cd30bcef 17728 printf ("??? (%u)\n", val);
c0ea7c52
JL
17729 }
17730 return p;
17731 }
17732 return display_tag_value (tag & 1, p, end);
17733}
17734
2dc8dd17
JW
17735struct riscv_attr_tag_t {
17736 const char *name;
cd30bcef 17737 unsigned int tag;
2dc8dd17
JW
17738};
17739
17740static struct riscv_attr_tag_t riscv_attr_tag[] =
17741{
17742#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17743 T(arch),
17744 T(priv_spec),
17745 T(priv_spec_minor),
17746 T(priv_spec_revision),
17747 T(unaligned_access),
17748 T(stack_align),
17749#undef T
17750};
17751
17752static unsigned char *
17753display_riscv_attribute (unsigned char *p,
17754 const unsigned char * const end)
17755{
cd30bcef
AM
17756 unsigned int val;
17757 unsigned int tag;
2dc8dd17
JW
17758 struct riscv_attr_tag_t *attr = NULL;
17759 unsigned i;
17760
cd30bcef 17761 READ_ULEB (tag, p, end);
2dc8dd17
JW
17762
17763 /* Find the name of attribute. */
17764 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17765 {
17766 if (riscv_attr_tag[i].tag == tag)
17767 {
17768 attr = &riscv_attr_tag[i];
17769 break;
17770 }
17771 }
17772
17773 if (attr)
17774 printf (" %s: ", attr->name);
17775 else
17776 return display_tag_value (tag, p, end);
17777
17778 switch (tag)
17779 {
17780 case Tag_RISCV_priv_spec:
17781 case Tag_RISCV_priv_spec_minor:
17782 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17783 READ_ULEB (val, p, end);
17784 printf (_("%u\n"), val);
2dc8dd17
JW
17785 break;
17786 case Tag_RISCV_unaligned_access:
cd30bcef 17787 READ_ULEB (val, p, end);
2dc8dd17
JW
17788 switch (val)
17789 {
17790 case 0:
17791 printf (_("No unaligned access\n"));
17792 break;
17793 case 1:
17794 printf (_("Unaligned access\n"));
17795 break;
17796 }
17797 break;
17798 case Tag_RISCV_stack_align:
cd30bcef
AM
17799 READ_ULEB (val, p, end);
17800 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17801 break;
17802 case Tag_RISCV_arch:
17803 p = display_tag_value (-1, p, end);
17804 break;
17805 default:
17806 return display_tag_value (tag, p, end);
17807 }
17808
17809 return p;
17810}
17811
0861f561
CQ
17812static unsigned char *
17813display_csky_attribute (unsigned char * p,
17814 const unsigned char * const end)
17815{
17816 unsigned int tag;
17817 unsigned int val;
17818 READ_ULEB (tag, p, end);
17819
17820 if (tag >= Tag_CSKY_MAX)
17821 {
17822 return display_tag_value (-1, p, end);
17823 }
17824
17825 switch (tag)
17826 {
17827 case Tag_CSKY_ARCH_NAME:
17828 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17829 return display_tag_value (-1, p, end);
17830 case Tag_CSKY_CPU_NAME:
17831 printf (" Tag_CSKY_CPU_NAME:\t\t");
17832 return display_tag_value (-1, p, end);
17833
17834 case Tag_CSKY_ISA_FLAGS:
17835 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17836 return display_tag_value (0, p, end);
17837 case Tag_CSKY_ISA_EXT_FLAGS:
17838 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17839 return display_tag_value (0, p, end);
17840
17841 case Tag_CSKY_DSP_VERSION:
17842 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17843 READ_ULEB (val, p, end);
17844 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17845 printf ("DSP Extension\n");
17846 else if (val == VAL_CSKY_DSP_VERSION_2)
17847 printf ("DSP 2.0\n");
17848 break;
17849
17850 case Tag_CSKY_VDSP_VERSION:
17851 printf (" Tag_CSKY_VDSP_VERSION:\t");
17852 READ_ULEB (val, p, end);
17853 printf ("VDSP Version %d\n", val);
17854 break;
17855
17856 case Tag_CSKY_FPU_VERSION:
17857 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17858 READ_ULEB (val, p, end);
17859 if (val == VAL_CSKY_FPU_VERSION_1)
17860 printf ("ABIV1 FPU Version 1\n");
17861 else if (val == VAL_CSKY_FPU_VERSION_2)
17862 printf ("FPU Version 2\n");
17863 break;
17864
17865 case Tag_CSKY_FPU_ABI:
17866 printf (" Tag_CSKY_FPU_ABI:\t\t");
17867 READ_ULEB (val, p, end);
17868 if (val == VAL_CSKY_FPU_ABI_HARD)
17869 printf ("Hard\n");
17870 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17871 printf ("SoftFP\n");
17872 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17873 printf ("Soft\n");
17874 break;
17875 case Tag_CSKY_FPU_ROUNDING:
17876 READ_ULEB (val, p, end);
f253158f
NC
17877 if (val == 1)
17878 {
17879 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17880 printf ("Needed\n");
17881 }
0861f561
CQ
17882 break;
17883 case Tag_CSKY_FPU_DENORMAL:
17884 READ_ULEB (val, p, end);
f253158f
NC
17885 if (val == 1)
17886 {
17887 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17888 printf ("Needed\n");
17889 }
0861f561
CQ
17890 break;
17891 case Tag_CSKY_FPU_Exception:
17892 READ_ULEB (val, p, end);
f253158f
NC
17893 if (val == 1)
17894 {
17895 printf (" Tag_CSKY_FPU_Exception:\t");
17896 printf ("Needed\n");
17897 }
0861f561
CQ
17898 break;
17899 case Tag_CSKY_FPU_NUMBER_MODULE:
17900 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17901 return display_tag_value (-1, p, end);
17902 case Tag_CSKY_FPU_HARDFP:
17903 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17904 READ_ULEB (val, p, end);
17905 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17906 printf (" Half");
17907 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17908 printf (" Single");
17909 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17910 printf (" Double");
17911 printf ("\n");
17912 break;
17913 default:
17914 return display_tag_value (tag, p, end);
17915 }
17916 return p;
17917}
17918
015dc7e1 17919static bool
dda8d76d 17920process_attributes (Filedata * filedata,
60bca95a 17921 const char * public_name,
104d59d1 17922 unsigned int proc_type,
f6f0e17b 17923 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17924 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17925{
2cf0635d 17926 Elf_Internal_Shdr * sect;
11c1ff18 17927 unsigned i;
015dc7e1 17928 bool res = true;
11c1ff18
PB
17929
17930 /* Find the section header so that we get the size. */
dda8d76d
NC
17931 for (i = 0, sect = filedata->section_headers;
17932 i < filedata->file_header.e_shnum;
11c1ff18
PB
17933 i++, sect++)
17934 {
071436c6
NC
17935 unsigned char * contents;
17936 unsigned char * p;
17937
104d59d1 17938 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17939 continue;
17940
dda8d76d 17941 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17942 sect->sh_size, _("attributes"));
60bca95a 17943 if (contents == NULL)
32ec8896 17944 {
015dc7e1 17945 res = false;
32ec8896
NC
17946 continue;
17947 }
60bca95a 17948
11c1ff18 17949 p = contents;
60abdbed
NC
17950 /* The first character is the version of the attributes.
17951 Currently only version 1, (aka 'A') is recognised here. */
17952 if (*p != 'A')
32ec8896
NC
17953 {
17954 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17955 res = false;
32ec8896 17956 }
60abdbed 17957 else
11c1ff18 17958 {
625d49fc 17959 uint64_t section_len;
071436c6
NC
17960
17961 section_len = sect->sh_size - 1;
11c1ff18 17962 p++;
60bca95a 17963
071436c6 17964 while (section_len > 0)
11c1ff18 17965 {
625d49fc 17966 uint64_t attr_len;
e9847026 17967 unsigned int namelen;
015dc7e1
AM
17968 bool public_section;
17969 bool gnu_section;
11c1ff18 17970
071436c6 17971 if (section_len <= 4)
e0a31db1
NC
17972 {
17973 error (_("Tag section ends prematurely\n"));
015dc7e1 17974 res = false;
e0a31db1
NC
17975 break;
17976 }
071436c6 17977 attr_len = byte_get (p, 4);
11c1ff18 17978 p += 4;
60bca95a 17979
071436c6 17980 if (attr_len > section_len)
11c1ff18 17981 {
071436c6
NC
17982 error (_("Bad attribute length (%u > %u)\n"),
17983 (unsigned) attr_len, (unsigned) section_len);
17984 attr_len = section_len;
015dc7e1 17985 res = false;
11c1ff18 17986 }
74e1a04b 17987 /* PR 17531: file: 001-101425-0.004 */
071436c6 17988 else if (attr_len < 5)
74e1a04b 17989 {
071436c6 17990 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17991 res = false;
74e1a04b
NC
17992 break;
17993 }
e9847026 17994
071436c6
NC
17995 section_len -= attr_len;
17996 attr_len -= 4;
17997
17998 namelen = strnlen ((char *) p, attr_len) + 1;
17999 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
18000 {
18001 error (_("Corrupt attribute section name\n"));
015dc7e1 18002 res = false;
e9847026
NC
18003 break;
18004 }
18005
071436c6
NC
18006 printf (_("Attribute Section: "));
18007 print_symbol (INT_MAX, (const char *) p);
18008 putchar ('\n');
60bca95a
NC
18009
18010 if (public_name && streq ((char *) p, public_name))
015dc7e1 18011 public_section = true;
11c1ff18 18012 else
015dc7e1 18013 public_section = false;
60bca95a
NC
18014
18015 if (streq ((char *) p, "gnu"))
015dc7e1 18016 gnu_section = true;
104d59d1 18017 else
015dc7e1 18018 gnu_section = false;
60bca95a 18019
11c1ff18 18020 p += namelen;
071436c6 18021 attr_len -= namelen;
e0a31db1 18022
071436c6 18023 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18024 {
e0a31db1 18025 int tag;
cd30bcef 18026 unsigned int val;
625d49fc 18027 uint64_t size;
071436c6 18028 unsigned char * end;
60bca95a 18029
e0a31db1 18030 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18031 if (attr_len < 6)
e0a31db1
NC
18032 {
18033 error (_("Unused bytes at end of section\n"));
015dc7e1 18034 res = false;
e0a31db1
NC
18035 section_len = 0;
18036 break;
18037 }
18038
18039 tag = *(p++);
11c1ff18 18040 size = byte_get (p, 4);
071436c6 18041 if (size > attr_len)
11c1ff18 18042 {
e9847026 18043 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18044 (unsigned) size, (unsigned) attr_len);
015dc7e1 18045 res = false;
071436c6 18046 size = attr_len;
11c1ff18 18047 }
e0a31db1
NC
18048 /* PR binutils/17531: Safe handling of corrupt files. */
18049 if (size < 6)
18050 {
18051 error (_("Bad subsection length (%u < 6)\n"),
18052 (unsigned) size);
015dc7e1 18053 res = false;
e0a31db1
NC
18054 section_len = 0;
18055 break;
18056 }
60bca95a 18057
071436c6 18058 attr_len -= size;
11c1ff18 18059 end = p + size - 1;
071436c6 18060 assert (end <= contents + sect->sh_size);
11c1ff18 18061 p += 4;
60bca95a 18062
11c1ff18
PB
18063 switch (tag)
18064 {
18065 case 1:
2b692964 18066 printf (_("File Attributes\n"));
11c1ff18
PB
18067 break;
18068 case 2:
2b692964 18069 printf (_("Section Attributes:"));
11c1ff18
PB
18070 goto do_numlist;
18071 case 3:
2b692964 18072 printf (_("Symbol Attributes:"));
1a0670f3 18073 /* Fall through. */
11c1ff18
PB
18074 do_numlist:
18075 for (;;)
18076 {
cd30bcef 18077 READ_ULEB (val, p, end);
11c1ff18
PB
18078 if (val == 0)
18079 break;
18080 printf (" %d", val);
18081 }
18082 printf ("\n");
18083 break;
18084 default:
2b692964 18085 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18086 public_section = false;
11c1ff18
PB
18087 break;
18088 }
60bca95a 18089
071436c6 18090 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18091 {
18092 while (p < end)
f6f0e17b 18093 p = display_pub_attribute (p, end);
60abdbed 18094 assert (p == end);
104d59d1 18095 }
071436c6 18096 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18097 {
18098 while (p < end)
18099 p = display_gnu_attribute (p,
f6f0e17b
NC
18100 display_proc_gnu_attribute,
18101 end);
60abdbed 18102 assert (p == end);
11c1ff18 18103 }
071436c6 18104 else if (p < end)
11c1ff18 18105 {
071436c6 18106 printf (_(" Unknown attribute:\n"));
f6f0e17b 18107 display_raw_attribute (p, end);
11c1ff18
PB
18108 p = end;
18109 }
071436c6
NC
18110 else
18111 attr_len = 0;
11c1ff18
PB
18112 }
18113 }
18114 }
d70c5fc7 18115
60bca95a 18116 free (contents);
11c1ff18 18117 }
32ec8896
NC
18118
18119 return res;
11c1ff18
PB
18120}
18121
ccb4c951
RS
18122/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18123 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18124 and return the VMA of the next entry, or -1 if there was a problem.
18125 Does not read from DATA_END or beyond. */
ccb4c951 18126
625d49fc
AM
18127static uint64_t
18128print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18129 unsigned char * data_end)
ccb4c951
RS
18130{
18131 printf (" ");
18132 print_vma (addr, LONG_HEX);
18133 printf (" ");
18134 if (addr < pltgot + 0xfff0)
18135 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18136 else
18137 printf ("%10s", "");
18138 printf (" ");
18139 if (data == NULL)
2b692964 18140 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18141 else
18142 {
625d49fc 18143 uint64_t entry;
82b1b41b 18144 unsigned char * from = data + addr - pltgot;
ccb4c951 18145
82b1b41b
NC
18146 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18147 {
18148 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18149 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18150 return (uint64_t) -1;
82b1b41b
NC
18151 }
18152 else
18153 {
18154 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18155 print_vma (entry, LONG_HEX);
18156 }
ccb4c951
RS
18157 }
18158 return addr + (is_32bit_elf ? 4 : 8);
18159}
18160
861fb55a
DJ
18161/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18162 PLTGOT. Print the Address and Initial fields of an entry at VMA
18163 ADDR and return the VMA of the next entry. */
18164
625d49fc
AM
18165static uint64_t
18166print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18167{
18168 printf (" ");
18169 print_vma (addr, LONG_HEX);
18170 printf (" ");
18171 if (data == NULL)
2b692964 18172 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18173 else
18174 {
625d49fc 18175 uint64_t entry;
861fb55a
DJ
18176
18177 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18178 print_vma (entry, LONG_HEX);
18179 }
18180 return addr + (is_32bit_elf ? 4 : 8);
18181}
18182
351cdf24
MF
18183static void
18184print_mips_ases (unsigned int mask)
18185{
18186 if (mask & AFL_ASE_DSP)
18187 fputs ("\n\tDSP ASE", stdout);
18188 if (mask & AFL_ASE_DSPR2)
18189 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18190 if (mask & AFL_ASE_DSPR3)
18191 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18192 if (mask & AFL_ASE_EVA)
18193 fputs ("\n\tEnhanced VA Scheme", stdout);
18194 if (mask & AFL_ASE_MCU)
18195 fputs ("\n\tMCU (MicroController) ASE", stdout);
18196 if (mask & AFL_ASE_MDMX)
18197 fputs ("\n\tMDMX ASE", stdout);
18198 if (mask & AFL_ASE_MIPS3D)
18199 fputs ("\n\tMIPS-3D ASE", stdout);
18200 if (mask & AFL_ASE_MT)
18201 fputs ("\n\tMT ASE", stdout);
18202 if (mask & AFL_ASE_SMARTMIPS)
18203 fputs ("\n\tSmartMIPS ASE", stdout);
18204 if (mask & AFL_ASE_VIRT)
18205 fputs ("\n\tVZ ASE", stdout);
18206 if (mask & AFL_ASE_MSA)
18207 fputs ("\n\tMSA ASE", stdout);
18208 if (mask & AFL_ASE_MIPS16)
18209 fputs ("\n\tMIPS16 ASE", stdout);
18210 if (mask & AFL_ASE_MICROMIPS)
18211 fputs ("\n\tMICROMIPS ASE", stdout);
18212 if (mask & AFL_ASE_XPA)
18213 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18214 if (mask & AFL_ASE_MIPS16E2)
18215 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18216 if (mask & AFL_ASE_CRC)
18217 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18218 if (mask & AFL_ASE_GINV)
18219 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18220 if (mask & AFL_ASE_LOONGSON_MMI)
18221 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18222 if (mask & AFL_ASE_LOONGSON_CAM)
18223 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18224 if (mask & AFL_ASE_LOONGSON_EXT)
18225 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18226 if (mask & AFL_ASE_LOONGSON_EXT2)
18227 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18228 if (mask == 0)
18229 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18230 else if ((mask & ~AFL_ASE_MASK) != 0)
18231 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18232}
18233
18234static void
18235print_mips_isa_ext (unsigned int isa_ext)
18236{
18237 switch (isa_ext)
18238 {
18239 case 0:
18240 fputs (_("None"), stdout);
18241 break;
18242 case AFL_EXT_XLR:
18243 fputs ("RMI XLR", stdout);
18244 break;
2c629856
N
18245 case AFL_EXT_OCTEON3:
18246 fputs ("Cavium Networks Octeon3", stdout);
18247 break;
351cdf24
MF
18248 case AFL_EXT_OCTEON2:
18249 fputs ("Cavium Networks Octeon2", stdout);
18250 break;
18251 case AFL_EXT_OCTEONP:
18252 fputs ("Cavium Networks OcteonP", stdout);
18253 break;
351cdf24
MF
18254 case AFL_EXT_OCTEON:
18255 fputs ("Cavium Networks Octeon", stdout);
18256 break;
18257 case AFL_EXT_5900:
18258 fputs ("Toshiba R5900", stdout);
18259 break;
18260 case AFL_EXT_4650:
18261 fputs ("MIPS R4650", stdout);
18262 break;
18263 case AFL_EXT_4010:
18264 fputs ("LSI R4010", stdout);
18265 break;
18266 case AFL_EXT_4100:
18267 fputs ("NEC VR4100", stdout);
18268 break;
18269 case AFL_EXT_3900:
18270 fputs ("Toshiba R3900", stdout);
18271 break;
18272 case AFL_EXT_10000:
18273 fputs ("MIPS R10000", stdout);
18274 break;
18275 case AFL_EXT_SB1:
18276 fputs ("Broadcom SB-1", stdout);
18277 break;
18278 case AFL_EXT_4111:
18279 fputs ("NEC VR4111/VR4181", stdout);
18280 break;
18281 case AFL_EXT_4120:
18282 fputs ("NEC VR4120", stdout);
18283 break;
18284 case AFL_EXT_5400:
18285 fputs ("NEC VR5400", stdout);
18286 break;
18287 case AFL_EXT_5500:
18288 fputs ("NEC VR5500", stdout);
18289 break;
18290 case AFL_EXT_LOONGSON_2E:
18291 fputs ("ST Microelectronics Loongson 2E", stdout);
18292 break;
18293 case AFL_EXT_LOONGSON_2F:
18294 fputs ("ST Microelectronics Loongson 2F", stdout);
18295 break;
38bf472a
MR
18296 case AFL_EXT_INTERAPTIV_MR2:
18297 fputs ("Imagination interAptiv MR2", stdout);
18298 break;
351cdf24 18299 default:
00ac7aa0 18300 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18301 }
18302}
18303
32ec8896 18304static signed int
351cdf24
MF
18305get_mips_reg_size (int reg_size)
18306{
18307 return (reg_size == AFL_REG_NONE) ? 0
18308 : (reg_size == AFL_REG_32) ? 32
18309 : (reg_size == AFL_REG_64) ? 64
18310 : (reg_size == AFL_REG_128) ? 128
18311 : -1;
18312}
18313
015dc7e1 18314static bool
dda8d76d 18315process_mips_specific (Filedata * filedata)
5b18a4bc 18316{
2cf0635d 18317 Elf_Internal_Dyn * entry;
351cdf24 18318 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18319 size_t liblist_offset = 0;
18320 size_t liblistno = 0;
18321 size_t conflictsno = 0;
18322 size_t options_offset = 0;
18323 size_t conflicts_offset = 0;
861fb55a
DJ
18324 size_t pltrelsz = 0;
18325 size_t pltrel = 0;
625d49fc
AM
18326 uint64_t pltgot = 0;
18327 uint64_t mips_pltgot = 0;
18328 uint64_t jmprel = 0;
18329 uint64_t local_gotno = 0;
18330 uint64_t gotsym = 0;
18331 uint64_t symtabno = 0;
015dc7e1 18332 bool res = true;
103f02d3 18333
dda8d76d 18334 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18335 display_mips_gnu_attribute))
015dc7e1 18336 res = false;
2cf19d5c 18337
dda8d76d 18338 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18339
18340 if (sect != NULL)
18341 {
18342 Elf_External_ABIFlags_v0 *abiflags_ext;
18343 Elf_Internal_ABIFlags_v0 abiflags_in;
18344
18345 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18346 {
18347 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18348 res = false;
32ec8896 18349 }
351cdf24
MF
18350 else
18351 {
dda8d76d 18352 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18353 sect->sh_size, _("MIPS ABI Flags section"));
18354 if (abiflags_ext)
18355 {
18356 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18357 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18358 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18359 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18360 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18361 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18362 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18363 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18364 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18365 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18366 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18367
18368 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18369 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18370 if (abiflags_in.isa_rev > 1)
18371 printf ("r%d", abiflags_in.isa_rev);
18372 printf ("\nGPR size: %d",
18373 get_mips_reg_size (abiflags_in.gpr_size));
18374 printf ("\nCPR1 size: %d",
18375 get_mips_reg_size (abiflags_in.cpr1_size));
18376 printf ("\nCPR2 size: %d",
18377 get_mips_reg_size (abiflags_in.cpr2_size));
18378 fputs ("\nFP ABI: ", stdout);
18379 print_mips_fp_abi_value (abiflags_in.fp_abi);
18380 fputs ("ISA Extension: ", stdout);
18381 print_mips_isa_ext (abiflags_in.isa_ext);
18382 fputs ("\nASEs:", stdout);
18383 print_mips_ases (abiflags_in.ases);
18384 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18385 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18386 fputc ('\n', stdout);
18387 free (abiflags_ext);
18388 }
18389 }
18390 }
18391
19e6b90e 18392 /* We have a lot of special sections. Thanks SGI! */
978c4450 18393 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18394 {
18395 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18396 sect = find_section (filedata, ".got");
bbdd9a68
MR
18397 if (sect != NULL)
18398 {
18399 unsigned char *data_end;
18400 unsigned char *data;
625d49fc 18401 uint64_t ent, end;
bbdd9a68
MR
18402 int addr_size;
18403
18404 pltgot = sect->sh_addr;
18405
18406 ent = pltgot;
18407 addr_size = (is_32bit_elf ? 4 : 8);
18408 end = pltgot + sect->sh_size;
18409
dda8d76d 18410 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18411 end - pltgot, 1,
18412 _("Global Offset Table data"));
18413 /* PR 12855: Null data is handled gracefully throughout. */
18414 data_end = data + (end - pltgot);
18415
18416 printf (_("\nStatic GOT:\n"));
18417 printf (_(" Canonical gp value: "));
18418 print_vma (ent + 0x7ff0, LONG_HEX);
18419 printf ("\n\n");
18420
18421 /* In a dynamic binary GOT[0] is reserved for the dynamic
18422 loader to store the lazy resolver pointer, however in
18423 a static binary it may well have been omitted and GOT
18424 reduced to a table of addresses.
18425 PR 21344: Check for the entry being fully available
18426 before fetching it. */
18427 if (data
18428 && data + ent - pltgot + addr_size <= data_end
18429 && byte_get (data + ent - pltgot, addr_size) == 0)
18430 {
18431 printf (_(" Reserved entries:\n"));
18432 printf (_(" %*s %10s %*s\n"),
18433 addr_size * 2, _("Address"), _("Access"),
18434 addr_size * 2, _("Value"));
18435 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18436 printf ("\n");
625d49fc 18437 if (ent == (uint64_t) -1)
bbdd9a68
MR
18438 goto sgot_print_fail;
18439
18440 /* Check for the MSB of GOT[1] being set, identifying a
18441 GNU object. This entry will be used by some runtime
18442 loaders, to store the module pointer. Otherwise this
18443 is an ordinary local entry.
18444 PR 21344: Check for the entry being fully available
18445 before fetching it. */
18446 if (data
18447 && data + ent - pltgot + addr_size <= data_end
18448 && (byte_get (data + ent - pltgot, addr_size)
18449 >> (addr_size * 8 - 1)) != 0)
18450 {
18451 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18452 printf ("\n");
625d49fc 18453 if (ent == (uint64_t) -1)
bbdd9a68
MR
18454 goto sgot_print_fail;
18455 }
18456 printf ("\n");
18457 }
18458
f17e9d8a 18459 if (data != NULL && ent < end)
bbdd9a68
MR
18460 {
18461 printf (_(" Local entries:\n"));
18462 printf (" %*s %10s %*s\n",
18463 addr_size * 2, _("Address"), _("Access"),
18464 addr_size * 2, _("Value"));
18465 while (ent < end)
18466 {
18467 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18468 printf ("\n");
625d49fc 18469 if (ent == (uint64_t) -1)
bbdd9a68
MR
18470 goto sgot_print_fail;
18471 }
18472 printf ("\n");
18473 }
18474
18475 sgot_print_fail:
9db70fc3 18476 free (data);
bbdd9a68
MR
18477 }
18478 return res;
18479 }
252b5132 18480
978c4450 18481 for (entry = filedata->dynamic_section;
071436c6 18482 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18483 (entry < filedata->dynamic_section + filedata->dynamic_nent
18484 && entry->d_tag != DT_NULL);
071436c6 18485 ++entry)
252b5132
RH
18486 switch (entry->d_tag)
18487 {
18488 case DT_MIPS_LIBLIST:
d93f0186 18489 liblist_offset
dda8d76d 18490 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18491 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18492 break;
18493 case DT_MIPS_LIBLISTNO:
18494 liblistno = entry->d_un.d_val;
18495 break;
18496 case DT_MIPS_OPTIONS:
dda8d76d 18497 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18498 break;
18499 case DT_MIPS_CONFLICT:
d93f0186 18500 conflicts_offset
dda8d76d 18501 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18502 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18503 break;
18504 case DT_MIPS_CONFLICTNO:
18505 conflictsno = entry->d_un.d_val;
18506 break;
ccb4c951 18507 case DT_PLTGOT:
861fb55a
DJ
18508 pltgot = entry->d_un.d_ptr;
18509 break;
ccb4c951
RS
18510 case DT_MIPS_LOCAL_GOTNO:
18511 local_gotno = entry->d_un.d_val;
18512 break;
18513 case DT_MIPS_GOTSYM:
18514 gotsym = entry->d_un.d_val;
18515 break;
18516 case DT_MIPS_SYMTABNO:
18517 symtabno = entry->d_un.d_val;
18518 break;
861fb55a
DJ
18519 case DT_MIPS_PLTGOT:
18520 mips_pltgot = entry->d_un.d_ptr;
18521 break;
18522 case DT_PLTREL:
18523 pltrel = entry->d_un.d_val;
18524 break;
18525 case DT_PLTRELSZ:
18526 pltrelsz = entry->d_un.d_val;
18527 break;
18528 case DT_JMPREL:
18529 jmprel = entry->d_un.d_ptr;
18530 break;
252b5132
RH
18531 default:
18532 break;
18533 }
18534
18535 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18536 {
2cf0635d 18537 Elf32_External_Lib * elib;
252b5132
RH
18538 size_t cnt;
18539
dda8d76d 18540 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18541 sizeof (Elf32_External_Lib),
18542 liblistno,
18543 _("liblist section data"));
a6e9f9df 18544 if (elib)
252b5132 18545 {
d3a49aa8
AM
18546 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
18547 "\nSection '.liblist' contains %lu entries:\n",
18548 (unsigned long) liblistno),
a6e9f9df 18549 (unsigned long) liblistno);
2b692964 18550 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18551 stdout);
18552
18553 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18554 {
a6e9f9df 18555 Elf32_Lib liblist;
91d6fa6a 18556 time_t atime;
d5b07ef4 18557 char timebuf[128];
2cf0635d 18558 struct tm * tmp;
a6e9f9df
AM
18559
18560 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18561 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18562 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18563 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18564 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18565
91d6fa6a 18566 tmp = gmtime (&atime);
e9e44622
JJ
18567 snprintf (timebuf, sizeof (timebuf),
18568 "%04u-%02u-%02uT%02u:%02u:%02u",
18569 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18570 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18571
31104126 18572 printf ("%3lu: ", (unsigned long) cnt);
84714f86
AM
18573 if (valid_dynamic_name (filedata, liblist.l_name))
18574 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18575 else
2b692964 18576 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18577 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18578 liblist.l_version);
a6e9f9df
AM
18579
18580 if (liblist.l_flags == 0)
2b692964 18581 puts (_(" NONE"));
a6e9f9df
AM
18582 else
18583 {
18584 static const struct
252b5132 18585 {
2cf0635d 18586 const char * name;
a6e9f9df 18587 int bit;
252b5132 18588 }
a6e9f9df
AM
18589 l_flags_vals[] =
18590 {
18591 { " EXACT_MATCH", LL_EXACT_MATCH },
18592 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18593 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18594 { " EXPORTS", LL_EXPORTS },
18595 { " DELAY_LOAD", LL_DELAY_LOAD },
18596 { " DELTA", LL_DELTA }
18597 };
18598 int flags = liblist.l_flags;
18599 size_t fcnt;
18600
60bca95a 18601 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18602 if ((flags & l_flags_vals[fcnt].bit) != 0)
18603 {
18604 fputs (l_flags_vals[fcnt].name, stdout);
18605 flags ^= l_flags_vals[fcnt].bit;
18606 }
18607 if (flags != 0)
18608 printf (" %#x", (unsigned int) flags);
252b5132 18609
a6e9f9df
AM
18610 puts ("");
18611 }
252b5132 18612 }
252b5132 18613
a6e9f9df
AM
18614 free (elib);
18615 }
32ec8896 18616 else
015dc7e1 18617 res = false;
252b5132
RH
18618 }
18619
18620 if (options_offset != 0)
18621 {
2cf0635d 18622 Elf_External_Options * eopt;
252b5132
RH
18623 size_t offset;
18624 int cnt;
18625
18626 /* Find the section header so that we get the size. */
dda8d76d 18627 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18628 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18629 if (sect == NULL)
18630 {
18631 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18632 return false;
071436c6 18633 }
7fc0c668
NC
18634 /* PR 24243 */
18635 if (sect->sh_size < sizeof (* eopt))
18636 {
18637 error (_("The MIPS options section is too small.\n"));
015dc7e1 18638 return false;
7fc0c668 18639 }
252b5132 18640
dda8d76d 18641 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18642 sect->sh_size, _("options"));
a6e9f9df 18643 if (eopt)
252b5132 18644 {
fd17d1e6 18645 Elf_Internal_Options option;
76da6bbe 18646
a6e9f9df 18647 offset = cnt = 0;
82b1b41b 18648 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18649 {
2cf0635d 18650 Elf_External_Options * eoption;
fd17d1e6 18651 unsigned int optsize;
252b5132 18652
a6e9f9df 18653 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18654
fd17d1e6 18655 optsize = BYTE_GET (eoption->size);
76da6bbe 18656
82b1b41b 18657 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18658 if (optsize < sizeof (* eopt)
18659 || optsize > sect->sh_size - offset)
82b1b41b 18660 {
645f43a8 18661 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18662 optsize);
645f43a8 18663 free (eopt);
015dc7e1 18664 return false;
82b1b41b 18665 }
fd17d1e6 18666 offset += optsize;
a6e9f9df
AM
18667 ++cnt;
18668 }
252b5132 18669
d3a49aa8
AM
18670 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18671 "\nSection '%s' contains %d entries:\n",
18672 cnt),
dda8d76d 18673 printable_section_name (filedata, sect), cnt);
76da6bbe 18674
82b1b41b 18675 offset = 0;
a6e9f9df 18676 while (cnt-- > 0)
252b5132 18677 {
a6e9f9df 18678 size_t len;
fd17d1e6
AM
18679 Elf_External_Options * eoption;
18680
18681 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18682
18683 option.kind = BYTE_GET (eoption->kind);
18684 option.size = BYTE_GET (eoption->size);
18685 option.section = BYTE_GET (eoption->section);
18686 option.info = BYTE_GET (eoption->info);
a6e9f9df 18687
fd17d1e6 18688 switch (option.kind)
252b5132 18689 {
a6e9f9df
AM
18690 case ODK_NULL:
18691 /* This shouldn't happen. */
d0c4e780 18692 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18693 option.section, option.info);
a6e9f9df 18694 break;
2e6be59c 18695
a6e9f9df
AM
18696 case ODK_REGINFO:
18697 printf (" REGINFO ");
dda8d76d 18698 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18699 {
2cf0635d 18700 Elf32_External_RegInfo * ereg;
b34976b6 18701 Elf32_RegInfo reginfo;
a6e9f9df 18702
2e6be59c 18703 /* 32bit form. */
fd17d1e6
AM
18704 if (option.size < (sizeof (Elf_External_Options)
18705 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18706 {
18707 printf (_("<corrupt>\n"));
18708 error (_("Truncated MIPS REGINFO option\n"));
18709 cnt = 0;
18710 break;
18711 }
18712
fd17d1e6 18713 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18714
a6e9f9df
AM
18715 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18716 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18717 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18718 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18719 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18720 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18721
d0c4e780
AM
18722 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18723 reginfo.ri_gprmask, reginfo.ri_gp_value);
18724 printf (" "
18725 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18726 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18727 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18728 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18729 }
18730 else
18731 {
18732 /* 64 bit form. */
2cf0635d 18733 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18734 Elf64_Internal_RegInfo reginfo;
18735
fd17d1e6
AM
18736 if (option.size < (sizeof (Elf_External_Options)
18737 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18738 {
18739 printf (_("<corrupt>\n"));
18740 error (_("Truncated MIPS REGINFO option\n"));
18741 cnt = 0;
18742 break;
18743 }
18744
fd17d1e6 18745 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18746 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18747 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18748 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18749 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18750 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18751 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18752
d0c4e780
AM
18753 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18754 reginfo.ri_gprmask, reginfo.ri_gp_value);
18755 printf (" "
18756 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18757 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18758 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18759 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18760 }
fd17d1e6 18761 offset += option.size;
a6e9f9df 18762 continue;
2e6be59c 18763
a6e9f9df
AM
18764 case ODK_EXCEPTIONS:
18765 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18766 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18767 fputs (") fpe_max(", stdout);
fd17d1e6 18768 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18769 fputs (")", stdout);
18770
fd17d1e6 18771 if (option.info & OEX_PAGE0)
a6e9f9df 18772 fputs (" PAGE0", stdout);
fd17d1e6 18773 if (option.info & OEX_SMM)
a6e9f9df 18774 fputs (" SMM", stdout);
fd17d1e6 18775 if (option.info & OEX_FPDBUG)
a6e9f9df 18776 fputs (" FPDBUG", stdout);
fd17d1e6 18777 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18778 fputs (" DISMISS", stdout);
18779 break;
2e6be59c 18780
a6e9f9df
AM
18781 case ODK_PAD:
18782 fputs (" PAD ", stdout);
fd17d1e6 18783 if (option.info & OPAD_PREFIX)
a6e9f9df 18784 fputs (" PREFIX", stdout);
fd17d1e6 18785 if (option.info & OPAD_POSTFIX)
a6e9f9df 18786 fputs (" POSTFIX", stdout);
fd17d1e6 18787 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18788 fputs (" SYMBOL", stdout);
18789 break;
2e6be59c 18790
a6e9f9df
AM
18791 case ODK_HWPATCH:
18792 fputs (" HWPATCH ", stdout);
fd17d1e6 18793 if (option.info & OHW_R4KEOP)
a6e9f9df 18794 fputs (" R4KEOP", stdout);
fd17d1e6 18795 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18796 fputs (" R8KPFETCH", stdout);
fd17d1e6 18797 if (option.info & OHW_R5KEOP)
a6e9f9df 18798 fputs (" R5KEOP", stdout);
fd17d1e6 18799 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18800 fputs (" R5KCVTL", stdout);
18801 break;
2e6be59c 18802
a6e9f9df
AM
18803 case ODK_FILL:
18804 fputs (" FILL ", stdout);
18805 /* XXX Print content of info word? */
18806 break;
2e6be59c 18807
a6e9f9df
AM
18808 case ODK_TAGS:
18809 fputs (" TAGS ", stdout);
18810 /* XXX Print content of info word? */
18811 break;
2e6be59c 18812
a6e9f9df
AM
18813 case ODK_HWAND:
18814 fputs (" HWAND ", stdout);
fd17d1e6 18815 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18816 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18817 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18818 fputs (" R4KEOP_CLEAN", stdout);
18819 break;
2e6be59c 18820
a6e9f9df
AM
18821 case ODK_HWOR:
18822 fputs (" HWOR ", stdout);
fd17d1e6 18823 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18824 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18825 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18826 fputs (" R4KEOP_CLEAN", stdout);
18827 break;
2e6be59c 18828
a6e9f9df 18829 case ODK_GP_GROUP:
d0c4e780 18830 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18831 option.info & OGP_GROUP,
18832 (option.info & OGP_SELF) >> 16);
a6e9f9df 18833 break;
2e6be59c 18834
a6e9f9df 18835 case ODK_IDENT:
d0c4e780 18836 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18837 option.info & OGP_GROUP,
18838 (option.info & OGP_SELF) >> 16);
a6e9f9df 18839 break;
2e6be59c 18840
a6e9f9df
AM
18841 default:
18842 /* This shouldn't happen. */
d0c4e780 18843 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18844 option.kind, option.section, option.info);
a6e9f9df 18845 break;
252b5132 18846 }
a6e9f9df 18847
2cf0635d 18848 len = sizeof (* eopt);
fd17d1e6 18849 while (len < option.size)
82b1b41b 18850 {
fd17d1e6 18851 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18852
82b1b41b
NC
18853 if (ISPRINT (datum))
18854 printf ("%c", datum);
18855 else
18856 printf ("\\%03o", datum);
18857 len ++;
18858 }
a6e9f9df 18859 fputs ("\n", stdout);
82b1b41b 18860
fd17d1e6 18861 offset += option.size;
252b5132 18862 }
a6e9f9df 18863 free (eopt);
252b5132 18864 }
32ec8896 18865 else
015dc7e1 18866 res = false;
252b5132
RH
18867 }
18868
18869 if (conflicts_offset != 0 && conflictsno != 0)
18870 {
2cf0635d 18871 Elf32_Conflict * iconf;
252b5132
RH
18872 size_t cnt;
18873
978c4450 18874 if (filedata->dynamic_symbols == NULL)
252b5132 18875 {
591a748a 18876 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18877 return false;
252b5132
RH
18878 }
18879
7296a62a
NC
18880 /* PR 21345 - print a slightly more helpful error message
18881 if we are sure that the cmalloc will fail. */
645f43a8 18882 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18883 {
18884 error (_("Overlarge number of conflicts detected: %lx\n"),
18885 (long) conflictsno);
015dc7e1 18886 return false;
7296a62a
NC
18887 }
18888
3f5e193b 18889 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18890 if (iconf == NULL)
18891 {
8b73c356 18892 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18893 return false;
252b5132
RH
18894 }
18895
9ea033b2 18896 if (is_32bit_elf)
252b5132 18897 {
2cf0635d 18898 Elf32_External_Conflict * econf32;
a6e9f9df 18899
3f5e193b 18900 econf32 = (Elf32_External_Conflict *)
95099889
AM
18901 get_data (NULL, filedata, conflicts_offset,
18902 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18903 if (!econf32)
5a814d6d
AM
18904 {
18905 free (iconf);
015dc7e1 18906 return false;
5a814d6d 18907 }
252b5132
RH
18908
18909 for (cnt = 0; cnt < conflictsno; ++cnt)
18910 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18911
18912 free (econf32);
252b5132
RH
18913 }
18914 else
18915 {
2cf0635d 18916 Elf64_External_Conflict * econf64;
a6e9f9df 18917
3f5e193b 18918 econf64 = (Elf64_External_Conflict *)
95099889
AM
18919 get_data (NULL, filedata, conflicts_offset,
18920 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18921 if (!econf64)
5a814d6d
AM
18922 {
18923 free (iconf);
015dc7e1 18924 return false;
5a814d6d 18925 }
252b5132
RH
18926
18927 for (cnt = 0; cnt < conflictsno; ++cnt)
18928 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18929
18930 free (econf64);
252b5132
RH
18931 }
18932
d3a49aa8
AM
18933 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18934 "\nSection '.conflict' contains %lu entries:\n",
18935 (unsigned long) conflictsno),
c7e7ca54 18936 (unsigned long) conflictsno);
252b5132
RH
18937 puts (_(" Num: Index Value Name"));
18938
18939 for (cnt = 0; cnt < conflictsno; ++cnt)
18940 {
b34976b6 18941 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18942
978c4450 18943 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18944 printf (_("<corrupt symbol index>"));
d79b3d50 18945 else
e0a31db1
NC
18946 {
18947 Elf_Internal_Sym * psym;
18948
978c4450 18949 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18950 print_vma (psym->st_value, FULL_HEX);
18951 putchar (' ');
84714f86
AM
18952 if (valid_dynamic_name (filedata, psym->st_name))
18953 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18954 else
18955 printf (_("<corrupt: %14ld>"), psym->st_name);
18956 }
31104126 18957 putchar ('\n');
252b5132
RH
18958 }
18959
252b5132
RH
18960 free (iconf);
18961 }
18962
ccb4c951
RS
18963 if (pltgot != 0 && local_gotno != 0)
18964 {
625d49fc 18965 uint64_t ent, local_end, global_end;
bbeee7ea 18966 size_t i, offset;
2cf0635d 18967 unsigned char * data;
82b1b41b 18968 unsigned char * data_end;
bbeee7ea 18969 int addr_size;
ccb4c951 18970
91d6fa6a 18971 ent = pltgot;
ccb4c951
RS
18972 addr_size = (is_32bit_elf ? 4 : 8);
18973 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18974
74e1a04b
NC
18975 /* PR binutils/17533 file: 012-111227-0.004 */
18976 if (symtabno < gotsym)
18977 {
18978 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18979 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18980 return false;
74e1a04b 18981 }
82b1b41b 18982
74e1a04b 18983 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18984 /* PR 17531: file: 54c91a34. */
18985 if (global_end < local_end)
18986 {
18987 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18988 return false;
82b1b41b 18989 }
948f632f 18990
dda8d76d
NC
18991 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18992 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18993 global_end - pltgot, 1,
18994 _("Global Offset Table data"));
919383ac 18995 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18996 data_end = data + (global_end - pltgot);
59245841 18997
ccb4c951
RS
18998 printf (_("\nPrimary GOT:\n"));
18999 printf (_(" Canonical gp value: "));
19000 print_vma (pltgot + 0x7ff0, LONG_HEX);
19001 printf ("\n\n");
19002
19003 printf (_(" Reserved entries:\n"));
19004 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
19005 addr_size * 2, _("Address"), _("Access"),
19006 addr_size * 2, _("Initial"));
82b1b41b 19007 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 19008 printf (_(" Lazy resolver\n"));
625d49fc 19009 if (ent == (uint64_t) -1)
82b1b41b 19010 goto got_print_fail;
75ec1fdb 19011
c4ab9505
MR
19012 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19013 This entry will be used by some runtime loaders, to store the
19014 module pointer. Otherwise this is an ordinary local entry.
19015 PR 21344: Check for the entry being fully available before
19016 fetching it. */
19017 if (data
19018 && data + ent - pltgot + addr_size <= data_end
19019 && (byte_get (data + ent - pltgot, addr_size)
19020 >> (addr_size * 8 - 1)) != 0)
19021 {
19022 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19023 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 19024 if (ent == (uint64_t) -1)
c4ab9505 19025 goto got_print_fail;
ccb4c951
RS
19026 }
19027 printf ("\n");
19028
f17e9d8a 19029 if (data != NULL && ent < local_end)
ccb4c951
RS
19030 {
19031 printf (_(" Local entries:\n"));
cc5914eb 19032 printf (" %*s %10s %*s\n",
2b692964
NC
19033 addr_size * 2, _("Address"), _("Access"),
19034 addr_size * 2, _("Initial"));
91d6fa6a 19035 while (ent < local_end)
ccb4c951 19036 {
82b1b41b 19037 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19038 printf ("\n");
625d49fc 19039 if (ent == (uint64_t) -1)
82b1b41b 19040 goto got_print_fail;
ccb4c951
RS
19041 }
19042 printf ("\n");
19043 }
19044
f17e9d8a 19045 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19046 {
19047 int sym_width;
19048
19049 printf (_(" Global entries:\n"));
cc5914eb 19050 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19051 addr_size * 2, _("Address"),
19052 _("Access"),
2b692964 19053 addr_size * 2, _("Initial"),
9cf03b7e
NC
19054 addr_size * 2, _("Sym.Val."),
19055 _("Type"),
19056 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19057 _("Ndx"), _("Name"));
0b4362b0 19058
ccb4c951 19059 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19060
ccb4c951
RS
19061 for (i = gotsym; i < symtabno; i++)
19062 {
82b1b41b 19063 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19064 printf (" ");
e0a31db1 19065
978c4450 19066 if (filedata->dynamic_symbols == NULL)
e0a31db1 19067 printf (_("<no dynamic symbols>"));
978c4450 19068 else if (i < filedata->num_dynamic_syms)
e0a31db1 19069 {
978c4450 19070 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19071
19072 print_vma (psym->st_value, LONG_HEX);
19073 printf (" %-7s %3s ",
dda8d76d
NC
19074 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19075 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19076
84714f86 19077 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19078 print_symbol (sym_width,
84714f86 19079 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19080 else
19081 printf (_("<corrupt: %14ld>"), psym->st_name);
19082 }
ccb4c951 19083 else
7fc5ac57
JBG
19084 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
19085 (unsigned long) i);
e0a31db1 19086
ccb4c951 19087 printf ("\n");
625d49fc 19088 if (ent == (uint64_t) -1)
82b1b41b 19089 break;
ccb4c951
RS
19090 }
19091 printf ("\n");
19092 }
19093
82b1b41b 19094 got_print_fail:
9db70fc3 19095 free (data);
ccb4c951
RS
19096 }
19097
861fb55a
DJ
19098 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19099 {
625d49fc 19100 uint64_t ent, end;
861fb55a
DJ
19101 size_t offset, rel_offset;
19102 unsigned long count, i;
2cf0635d 19103 unsigned char * data;
861fb55a 19104 int addr_size, sym_width;
2cf0635d 19105 Elf_Internal_Rela * rels;
861fb55a 19106
dda8d76d 19107 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19108 if (pltrel == DT_RELA)
19109 {
dda8d76d 19110 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19111 return false;
861fb55a
DJ
19112 }
19113 else
19114 {
dda8d76d 19115 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19116 return false;
861fb55a
DJ
19117 }
19118
91d6fa6a 19119 ent = mips_pltgot;
861fb55a
DJ
19120 addr_size = (is_32bit_elf ? 4 : 8);
19121 end = mips_pltgot + (2 + count) * addr_size;
19122
dda8d76d
NC
19123 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19124 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19125 1, _("Procedure Linkage Table data"));
59245841 19126 if (data == NULL)
288f0ba2
AM
19127 {
19128 free (rels);
015dc7e1 19129 return false;
288f0ba2 19130 }
59245841 19131
9cf03b7e 19132 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19133 printf (_(" Reserved entries:\n"));
19134 printf (_(" %*s %*s Purpose\n"),
2b692964 19135 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19136 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19137 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19138 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19139 printf (_(" Module pointer\n"));
861fb55a
DJ
19140 printf ("\n");
19141
19142 printf (_(" Entries:\n"));
cc5914eb 19143 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19144 addr_size * 2, _("Address"),
19145 addr_size * 2, _("Initial"),
19146 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19147 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19148 for (i = 0; i < count; i++)
19149 {
df97ab2a 19150 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19151
91d6fa6a 19152 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19153 printf (" ");
e0a31db1 19154
978c4450 19155 if (idx >= filedata->num_dynamic_syms)
df97ab2a 19156 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 19157 else
e0a31db1 19158 {
978c4450 19159 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19160
19161 print_vma (psym->st_value, LONG_HEX);
19162 printf (" %-7s %3s ",
dda8d76d
NC
19163 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19164 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19165 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19166 print_symbol (sym_width,
84714f86 19167 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19168 else
19169 printf (_("<corrupt: %14ld>"), psym->st_name);
19170 }
861fb55a
DJ
19171 printf ("\n");
19172 }
19173 printf ("\n");
19174
9db70fc3 19175 free (data);
861fb55a
DJ
19176 free (rels);
19177 }
19178
32ec8896 19179 return res;
252b5132
RH
19180}
19181
015dc7e1 19182static bool
dda8d76d 19183process_nds32_specific (Filedata * filedata)
35c08157
KLC
19184{
19185 Elf_Internal_Shdr *sect = NULL;
19186
dda8d76d 19187 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19188 if (sect != NULL && sect->sh_size >= 4)
35c08157 19189 {
9c7b8e9b
AM
19190 unsigned char *buf;
19191 unsigned int flag;
35c08157
KLC
19192
19193 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19194 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19195 _("NDS32 elf flags section"));
35c08157 19196
9c7b8e9b 19197 if (buf == NULL)
015dc7e1 19198 return false;
32ec8896 19199
9c7b8e9b
AM
19200 flag = byte_get (buf, 4);
19201 free (buf);
19202 switch (flag & 0x3)
35c08157
KLC
19203 {
19204 case 0:
19205 printf ("(VEC_SIZE):\tNo entry.\n");
19206 break;
19207 case 1:
19208 printf ("(VEC_SIZE):\t4 bytes\n");
19209 break;
19210 case 2:
19211 printf ("(VEC_SIZE):\t16 bytes\n");
19212 break;
19213 case 3:
19214 printf ("(VEC_SIZE):\treserved\n");
19215 break;
19216 }
19217 }
19218
015dc7e1 19219 return true;
35c08157
KLC
19220}
19221
015dc7e1 19222static bool
dda8d76d 19223process_gnu_liblist (Filedata * filedata)
047b2264 19224{
2cf0635d
NC
19225 Elf_Internal_Shdr * section;
19226 Elf_Internal_Shdr * string_sec;
19227 Elf32_External_Lib * elib;
19228 char * strtab;
c256ffe7 19229 size_t strtab_size;
047b2264 19230 size_t cnt;
d3a49aa8 19231 unsigned long num_liblist;
047b2264 19232 unsigned i;
015dc7e1 19233 bool res = true;
047b2264
JJ
19234
19235 if (! do_arch)
015dc7e1 19236 return true;
047b2264 19237
dda8d76d
NC
19238 for (i = 0, section = filedata->section_headers;
19239 i < filedata->file_header.e_shnum;
b34976b6 19240 i++, section++)
047b2264
JJ
19241 {
19242 switch (section->sh_type)
19243 {
19244 case SHT_GNU_LIBLIST:
dda8d76d 19245 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19246 break;
19247
3f5e193b 19248 elib = (Elf32_External_Lib *)
dda8d76d 19249 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19250 _("liblist section data"));
047b2264
JJ
19251
19252 if (elib == NULL)
32ec8896 19253 {
015dc7e1 19254 res = false;
32ec8896
NC
19255 break;
19256 }
047b2264 19257
dda8d76d
NC
19258 string_sec = filedata->section_headers + section->sh_link;
19259 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19260 string_sec->sh_size,
19261 _("liblist string table"));
047b2264
JJ
19262 if (strtab == NULL
19263 || section->sh_entsize != sizeof (Elf32_External_Lib))
19264 {
19265 free (elib);
2842702f 19266 free (strtab);
015dc7e1 19267 res = false;
047b2264
JJ
19268 break;
19269 }
59245841 19270 strtab_size = string_sec->sh_size;
047b2264 19271
d3a49aa8
AM
19272 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19273 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
19274 "\nLibrary list section '%s' contains %lu entries:\n",
19275 num_liblist),
dda8d76d 19276 printable_section_name (filedata, section),
d3a49aa8 19277 num_liblist);
047b2264 19278
2b692964 19279 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19280
19281 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19282 ++cnt)
19283 {
19284 Elf32_Lib liblist;
91d6fa6a 19285 time_t atime;
d5b07ef4 19286 char timebuf[128];
2cf0635d 19287 struct tm * tmp;
047b2264
JJ
19288
19289 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19290 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19291 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19292 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19293 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19294
91d6fa6a 19295 tmp = gmtime (&atime);
e9e44622
JJ
19296 snprintf (timebuf, sizeof (timebuf),
19297 "%04u-%02u-%02uT%02u:%02u:%02u",
19298 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19299 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
19300
19301 printf ("%3lu: ", (unsigned long) cnt);
19302 if (do_wide)
c256ffe7 19303 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19304 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19305 else
c256ffe7 19306 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19307 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19308 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19309 liblist.l_version, liblist.l_flags);
19310 }
19311
19312 free (elib);
2842702f 19313 free (strtab);
047b2264
JJ
19314 }
19315 }
19316
32ec8896 19317 return res;
047b2264
JJ
19318}
19319
9437c45b 19320static const char *
dda8d76d 19321get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19322{
19323 static char buff[64];
103f02d3 19324
dda8d76d 19325 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19326 switch (e_type)
19327 {
57346661 19328 case NT_AUXV:
1ec5cd37 19329 return _("NT_AUXV (auxiliary vector)");
57346661 19330 case NT_PRSTATUS:
1ec5cd37 19331 return _("NT_PRSTATUS (prstatus structure)");
57346661 19332 case NT_FPREGSET:
1ec5cd37 19333 return _("NT_FPREGSET (floating point registers)");
57346661 19334 case NT_PRPSINFO:
1ec5cd37 19335 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19336 case NT_TASKSTRUCT:
1ec5cd37 19337 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19338 case NT_GDB_TDESC:
19339 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19340 case NT_PRXFPREG:
1ec5cd37 19341 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19342 case NT_PPC_VMX:
19343 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19344 case NT_PPC_VSX:
19345 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19346 case NT_PPC_TAR:
19347 return _("NT_PPC_TAR (ppc TAR register)");
19348 case NT_PPC_PPR:
19349 return _("NT_PPC_PPR (ppc PPR register)");
19350 case NT_PPC_DSCR:
19351 return _("NT_PPC_DSCR (ppc DSCR register)");
19352 case NT_PPC_EBB:
19353 return _("NT_PPC_EBB (ppc EBB registers)");
19354 case NT_PPC_PMU:
19355 return _("NT_PPC_PMU (ppc PMU registers)");
19356 case NT_PPC_TM_CGPR:
19357 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19358 case NT_PPC_TM_CFPR:
19359 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19360 case NT_PPC_TM_CVMX:
19361 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19362 case NT_PPC_TM_CVSX:
3fd21718 19363 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19364 case NT_PPC_TM_SPR:
19365 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19366 case NT_PPC_TM_CTAR:
19367 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19368 case NT_PPC_TM_CPPR:
19369 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19370 case NT_PPC_TM_CDSCR:
19371 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19372 case NT_386_TLS:
19373 return _("NT_386_TLS (x86 TLS information)");
19374 case NT_386_IOPERM:
19375 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19376 case NT_X86_XSTATE:
19377 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19378 case NT_X86_CET:
19379 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19380 case NT_S390_HIGH_GPRS:
19381 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19382 case NT_S390_TIMER:
19383 return _("NT_S390_TIMER (s390 timer register)");
19384 case NT_S390_TODCMP:
19385 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19386 case NT_S390_TODPREG:
19387 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19388 case NT_S390_CTRS:
19389 return _("NT_S390_CTRS (s390 control registers)");
19390 case NT_S390_PREFIX:
19391 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19392 case NT_S390_LAST_BREAK:
19393 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19394 case NT_S390_SYSTEM_CALL:
19395 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19396 case NT_S390_TDB:
19397 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19398 case NT_S390_VXRS_LOW:
19399 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19400 case NT_S390_VXRS_HIGH:
19401 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19402 case NT_S390_GS_CB:
19403 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19404 case NT_S390_GS_BC:
19405 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19406 case NT_ARM_VFP:
19407 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19408 case NT_ARM_TLS:
19409 return _("NT_ARM_TLS (AArch TLS registers)");
19410 case NT_ARM_HW_BREAK:
19411 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19412 case NT_ARM_HW_WATCH:
19413 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
19414 case NT_ARM_SYSTEM_CALL:
19415 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
19416 case NT_ARM_SVE:
19417 return _("NT_ARM_SVE (AArch SVE registers)");
19418 case NT_ARM_PAC_MASK:
19419 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19420 case NT_ARM_PACA_KEYS:
19421 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19422 case NT_ARM_PACG_KEYS:
19423 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19424 case NT_ARM_TAGGED_ADDR_CTRL:
19425 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
19426 case NT_ARM_PAC_ENABLED_KEYS:
19427 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19428 case NT_ARC_V2:
19429 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19430 case NT_RISCV_CSR:
19431 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19432 case NT_PSTATUS:
1ec5cd37 19433 return _("NT_PSTATUS (pstatus structure)");
57346661 19434 case NT_FPREGS:
1ec5cd37 19435 return _("NT_FPREGS (floating point registers)");
57346661 19436 case NT_PSINFO:
1ec5cd37 19437 return _("NT_PSINFO (psinfo structure)");
57346661 19438 case NT_LWPSTATUS:
1ec5cd37 19439 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19440 case NT_LWPSINFO:
1ec5cd37 19441 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19442 case NT_WIN32PSTATUS:
1ec5cd37 19443 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19444 case NT_SIGINFO:
19445 return _("NT_SIGINFO (siginfo_t data)");
19446 case NT_FILE:
19447 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19448 default:
19449 break;
19450 }
19451 else
19452 switch (e_type)
19453 {
19454 case NT_VERSION:
19455 return _("NT_VERSION (version)");
19456 case NT_ARCH:
19457 return _("NT_ARCH (architecture)");
9ef920e9 19458 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19459 return _("OPEN");
9ef920e9 19460 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19461 return _("func");
c8795e1f
NC
19462 case NT_GO_BUILDID:
19463 return _("GO BUILDID");
3ac925fc
LB
19464 case FDO_PACKAGING_METADATA:
19465 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19466 default:
19467 break;
19468 }
19469
e9e44622 19470 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19471 return buff;
779fe533
NC
19472}
19473
015dc7e1 19474static bool
9ece1fa9
TT
19475print_core_note (Elf_Internal_Note *pnote)
19476{
19477 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 19478 uint64_t count, page_size;
9ece1fa9
TT
19479 unsigned char *descdata, *filenames, *descend;
19480
19481 if (pnote->type != NT_FILE)
04ac15ab
AS
19482 {
19483 if (do_wide)
19484 printf ("\n");
015dc7e1 19485 return true;
04ac15ab 19486 }
9ece1fa9 19487
9ece1fa9
TT
19488 if (!is_32bit_elf)
19489 {
19490 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19491 /* Still "successful". */
015dc7e1 19492 return true;
9ece1fa9 19493 }
9ece1fa9
TT
19494
19495 if (pnote->descsz < 2 * addr_size)
19496 {
32ec8896 19497 error (_(" Malformed note - too short for header\n"));
015dc7e1 19498 return false;
9ece1fa9
TT
19499 }
19500
19501 descdata = (unsigned char *) pnote->descdata;
19502 descend = descdata + pnote->descsz;
19503
19504 if (descdata[pnote->descsz - 1] != '\0')
19505 {
32ec8896 19506 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19507 return false;
9ece1fa9
TT
19508 }
19509
19510 count = byte_get (descdata, addr_size);
19511 descdata += addr_size;
19512
19513 page_size = byte_get (descdata, addr_size);
19514 descdata += addr_size;
19515
625d49fc 19516 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 19517 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19518 {
32ec8896 19519 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19520 return false;
9ece1fa9
TT
19521 }
19522
19523 printf (_(" Page size: "));
19524 print_vma (page_size, DEC);
19525 printf ("\n");
19526
19527 printf (_(" %*s%*s%*s\n"),
19528 (int) (2 + 2 * addr_size), _("Start"),
19529 (int) (4 + 2 * addr_size), _("End"),
19530 (int) (4 + 2 * addr_size), _("Page Offset"));
19531 filenames = descdata + count * 3 * addr_size;
595712bb 19532 while (count-- > 0)
9ece1fa9 19533 {
625d49fc 19534 uint64_t start, end, file_ofs;
9ece1fa9
TT
19535
19536 if (filenames == descend)
19537 {
32ec8896 19538 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19539 return false;
9ece1fa9
TT
19540 }
19541
19542 start = byte_get (descdata, addr_size);
19543 descdata += addr_size;
19544 end = byte_get (descdata, addr_size);
19545 descdata += addr_size;
19546 file_ofs = byte_get (descdata, addr_size);
19547 descdata += addr_size;
19548
19549 printf (" ");
19550 print_vma (start, FULL_HEX);
19551 printf (" ");
19552 print_vma (end, FULL_HEX);
19553 printf (" ");
19554 print_vma (file_ofs, FULL_HEX);
19555 printf ("\n %s\n", filenames);
19556
19557 filenames += 1 + strlen ((char *) filenames);
19558 }
19559
015dc7e1 19560 return true;
9ece1fa9
TT
19561}
19562
1118d252
RM
19563static const char *
19564get_gnu_elf_note_type (unsigned e_type)
19565{
1449284b 19566 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19567 switch (e_type)
19568 {
19569 case NT_GNU_ABI_TAG:
19570 return _("NT_GNU_ABI_TAG (ABI version tag)");
19571 case NT_GNU_HWCAP:
19572 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19573 case NT_GNU_BUILD_ID:
19574 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19575 case NT_GNU_GOLD_VERSION:
19576 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19577 case NT_GNU_PROPERTY_TYPE_0:
19578 return _("NT_GNU_PROPERTY_TYPE_0");
19579 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19580 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19581 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19582 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19583 default:
1449284b
NC
19584 {
19585 static char buff[64];
1118d252 19586
1449284b
NC
19587 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19588 return buff;
19589 }
19590 }
1118d252
RM
19591}
19592
a9eafb08
L
19593static void
19594decode_x86_compat_isa (unsigned int bitmask)
19595{
19596 while (bitmask)
19597 {
19598 unsigned int bit = bitmask & (- bitmask);
19599
19600 bitmask &= ~ bit;
19601 switch (bit)
19602 {
19603 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19604 printf ("i486");
19605 break;
19606 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19607 printf ("586");
19608 break;
19609 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19610 printf ("686");
19611 break;
19612 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19613 printf ("SSE");
19614 break;
19615 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19616 printf ("SSE2");
19617 break;
19618 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19619 printf ("SSE3");
19620 break;
19621 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19622 printf ("SSSE3");
19623 break;
19624 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19625 printf ("SSE4_1");
19626 break;
19627 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19628 printf ("SSE4_2");
19629 break;
19630 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19631 printf ("AVX");
19632 break;
19633 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19634 printf ("AVX2");
19635 break;
19636 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19637 printf ("AVX512F");
19638 break;
19639 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19640 printf ("AVX512CD");
19641 break;
19642 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19643 printf ("AVX512ER");
19644 break;
19645 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19646 printf ("AVX512PF");
19647 break;
19648 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19649 printf ("AVX512VL");
19650 break;
19651 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19652 printf ("AVX512DQ");
19653 break;
19654 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19655 printf ("AVX512BW");
19656 break;
65b3d26e
L
19657 default:
19658 printf (_("<unknown: %x>"), bit);
19659 break;
a9eafb08
L
19660 }
19661 if (bitmask)
19662 printf (", ");
19663 }
19664}
19665
9ef920e9 19666static void
32930e4e 19667decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19668{
0a59decb 19669 if (!bitmask)
90c745dc
L
19670 {
19671 printf (_("<None>"));
19672 return;
19673 }
90c745dc 19674
9ef920e9
NC
19675 while (bitmask)
19676 {
1fc87489 19677 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19678
19679 bitmask &= ~ bit;
19680 switch (bit)
19681 {
32930e4e 19682 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19683 printf ("CMOV");
19684 break;
32930e4e 19685 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19686 printf ("SSE");
19687 break;
32930e4e 19688 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19689 printf ("SSE2");
19690 break;
32930e4e 19691 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19692 printf ("SSE3");
19693 break;
32930e4e 19694 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19695 printf ("SSSE3");
19696 break;
32930e4e 19697 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19698 printf ("SSE4_1");
19699 break;
32930e4e 19700 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19701 printf ("SSE4_2");
19702 break;
32930e4e 19703 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19704 printf ("AVX");
19705 break;
32930e4e 19706 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19707 printf ("AVX2");
19708 break;
32930e4e 19709 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19710 printf ("FMA");
19711 break;
32930e4e 19712 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19713 printf ("AVX512F");
19714 break;
32930e4e 19715 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19716 printf ("AVX512CD");
19717 break;
32930e4e 19718 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19719 printf ("AVX512ER");
19720 break;
32930e4e 19721 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19722 printf ("AVX512PF");
19723 break;
32930e4e 19724 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19725 printf ("AVX512VL");
19726 break;
32930e4e 19727 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19728 printf ("AVX512DQ");
19729 break;
32930e4e 19730 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19731 printf ("AVX512BW");
19732 break;
32930e4e 19733 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19734 printf ("AVX512_4FMAPS");
19735 break;
32930e4e 19736 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19737 printf ("AVX512_4VNNIW");
19738 break;
32930e4e 19739 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19740 printf ("AVX512_BITALG");
19741 break;
32930e4e 19742 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19743 printf ("AVX512_IFMA");
19744 break;
32930e4e 19745 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19746 printf ("AVX512_VBMI");
19747 break;
32930e4e 19748 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19749 printf ("AVX512_VBMI2");
19750 break;
32930e4e 19751 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19752 printf ("AVX512_VNNI");
19753 break;
32930e4e 19754 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19755 printf ("AVX512_BF16");
19756 break;
65b3d26e
L
19757 default:
19758 printf (_("<unknown: %x>"), bit);
19759 break;
9ef920e9
NC
19760 }
19761 if (bitmask)
19762 printf (", ");
19763 }
19764}
19765
28cdbb18
SM
19766static const char *
19767get_amdgpu_elf_note_type (unsigned int e_type)
19768{
19769 switch (e_type)
19770 {
19771 case NT_AMDGPU_METADATA:
19772 return _("NT_AMDGPU_METADATA (code object metadata)");
19773 default:
19774 {
19775 static char buf[64];
19776 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
19777 return buf;
19778 }
19779 }
19780}
19781
32930e4e
L
19782static void
19783decode_x86_isa (unsigned int bitmask)
19784{
32930e4e
L
19785 while (bitmask)
19786 {
19787 unsigned int bit = bitmask & (- bitmask);
19788
19789 bitmask &= ~ bit;
19790 switch (bit)
19791 {
b0ab0693
L
19792 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19793 printf ("x86-64-baseline");
19794 break;
32930e4e
L
19795 case GNU_PROPERTY_X86_ISA_1_V2:
19796 printf ("x86-64-v2");
19797 break;
19798 case GNU_PROPERTY_X86_ISA_1_V3:
19799 printf ("x86-64-v3");
19800 break;
19801 case GNU_PROPERTY_X86_ISA_1_V4:
19802 printf ("x86-64-v4");
19803 break;
19804 default:
19805 printf (_("<unknown: %x>"), bit);
19806 break;
19807 }
19808 if (bitmask)
19809 printf (", ");
19810 }
19811}
19812
ee2fdd6f 19813static void
a9eafb08 19814decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19815{
0a59decb 19816 if (!bitmask)
90c745dc
L
19817 {
19818 printf (_("<None>"));
19819 return;
19820 }
90c745dc 19821
ee2fdd6f
L
19822 while (bitmask)
19823 {
19824 unsigned int bit = bitmask & (- bitmask);
19825
19826 bitmask &= ~ bit;
19827 switch (bit)
19828 {
19829 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19830 printf ("IBT");
ee2fdd6f 19831 break;
48580982 19832 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19833 printf ("SHSTK");
48580982 19834 break;
279d901e
L
19835 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19836 printf ("LAM_U48");
19837 break;
19838 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19839 printf ("LAM_U57");
19840 break;
ee2fdd6f
L
19841 default:
19842 printf (_("<unknown: %x>"), bit);
19843 break;
19844 }
19845 if (bitmask)
19846 printf (", ");
19847 }
19848}
19849
a9eafb08
L
19850static void
19851decode_x86_feature_2 (unsigned int bitmask)
19852{
0a59decb 19853 if (!bitmask)
90c745dc
L
19854 {
19855 printf (_("<None>"));
19856 return;
19857 }
90c745dc 19858
a9eafb08
L
19859 while (bitmask)
19860 {
19861 unsigned int bit = bitmask & (- bitmask);
19862
19863 bitmask &= ~ bit;
19864 switch (bit)
19865 {
19866 case GNU_PROPERTY_X86_FEATURE_2_X86:
19867 printf ("x86");
19868 break;
19869 case GNU_PROPERTY_X86_FEATURE_2_X87:
19870 printf ("x87");
19871 break;
19872 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19873 printf ("MMX");
19874 break;
19875 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19876 printf ("XMM");
19877 break;
19878 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19879 printf ("YMM");
19880 break;
19881 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19882 printf ("ZMM");
19883 break;
a308b89d
L
19884 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19885 printf ("TMM");
19886 break;
32930e4e
L
19887 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19888 printf ("MASK");
19889 break;
a9eafb08
L
19890 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19891 printf ("FXSR");
19892 break;
19893 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19894 printf ("XSAVE");
19895 break;
19896 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19897 printf ("XSAVEOPT");
19898 break;
19899 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19900 printf ("XSAVEC");
19901 break;
65b3d26e
L
19902 default:
19903 printf (_("<unknown: %x>"), bit);
19904 break;
a9eafb08
L
19905 }
19906 if (bitmask)
19907 printf (", ");
19908 }
19909}
19910
cd702818
SD
19911static void
19912decode_aarch64_feature_1_and (unsigned int bitmask)
19913{
19914 while (bitmask)
19915 {
19916 unsigned int bit = bitmask & (- bitmask);
19917
19918 bitmask &= ~ bit;
19919 switch (bit)
19920 {
19921 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19922 printf ("BTI");
19923 break;
19924
19925 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19926 printf ("PAC");
19927 break;
19928
19929 default:
19930 printf (_("<unknown: %x>"), bit);
19931 break;
19932 }
19933 if (bitmask)
19934 printf (", ");
19935 }
19936}
19937
6320fd00
L
19938static void
19939decode_1_needed (unsigned int bitmask)
19940{
19941 while (bitmask)
19942 {
19943 unsigned int bit = bitmask & (- bitmask);
19944
19945 bitmask &= ~ bit;
19946 switch (bit)
19947 {
19948 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19949 printf ("indirect external access");
19950 break;
19951 default:
19952 printf (_("<unknown: %x>"), bit);
19953 break;
19954 }
19955 if (bitmask)
19956 printf (", ");
19957 }
19958}
19959
9ef920e9 19960static void
dda8d76d 19961print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19962{
19963 unsigned char * ptr = (unsigned char *) pnote->descdata;
19964 unsigned char * ptr_end = ptr + pnote->descsz;
19965 unsigned int size = is_32bit_elf ? 4 : 8;
19966
19967 printf (_(" Properties: "));
19968
1fc87489 19969 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19970 {
19971 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19972 return;
19973 }
19974
6ab2c4ed 19975 while (ptr < ptr_end)
9ef920e9 19976 {
1fc87489 19977 unsigned int j;
6ab2c4ed
MC
19978 unsigned int type;
19979 unsigned int datasz;
19980
19981 if ((size_t) (ptr_end - ptr) < 8)
19982 {
19983 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19984 break;
19985 }
19986
19987 type = byte_get (ptr, 4);
19988 datasz = byte_get (ptr + 4, 4);
9ef920e9 19989
1fc87489 19990 ptr += 8;
9ef920e9 19991
6ab2c4ed 19992 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19993 {
1fc87489
L
19994 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19995 type, datasz);
9ef920e9 19996 break;
1fc87489 19997 }
9ef920e9 19998
1fc87489
L
19999 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20000 {
dda8d76d
NC
20001 if (filedata->file_header.e_machine == EM_X86_64
20002 || filedata->file_header.e_machine == EM_IAMCU
20003 || filedata->file_header.e_machine == EM_386)
1fc87489 20004 {
aa7bca9b
L
20005 unsigned int bitmask;
20006
20007 if (datasz == 4)
0a59decb 20008 bitmask = byte_get (ptr, 4);
aa7bca9b
L
20009 else
20010 bitmask = 0;
20011
1fc87489
L
20012 switch (type)
20013 {
20014 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 20015 if (datasz != 4)
aa7bca9b
L
20016 printf (_("x86 ISA used: <corrupt length: %#x> "),
20017 datasz);
1fc87489 20018 else
aa7bca9b
L
20019 {
20020 printf ("x86 ISA used: ");
20021 decode_x86_isa (bitmask);
20022 }
1fc87489 20023 goto next;
9ef920e9 20024
1fc87489 20025 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20026 if (datasz != 4)
aa7bca9b
L
20027 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20028 datasz);
1fc87489 20029 else
aa7bca9b
L
20030 {
20031 printf ("x86 ISA needed: ");
20032 decode_x86_isa (bitmask);
20033 }
1fc87489 20034 goto next;
9ef920e9 20035
ee2fdd6f 20036 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20037 if (datasz != 4)
aa7bca9b
L
20038 printf (_("x86 feature: <corrupt length: %#x> "),
20039 datasz);
ee2fdd6f 20040 else
aa7bca9b
L
20041 {
20042 printf ("x86 feature: ");
a9eafb08
L
20043 decode_x86_feature_1 (bitmask);
20044 }
20045 goto next;
20046
20047 case GNU_PROPERTY_X86_FEATURE_2_USED:
20048 if (datasz != 4)
20049 printf (_("x86 feature used: <corrupt length: %#x> "),
20050 datasz);
20051 else
20052 {
20053 printf ("x86 feature used: ");
20054 decode_x86_feature_2 (bitmask);
20055 }
20056 goto next;
20057
20058 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20059 if (datasz != 4)
20060 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20061 else
20062 {
20063 printf ("x86 feature needed: ");
20064 decode_x86_feature_2 (bitmask);
20065 }
20066 goto next;
20067
20068 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20069 if (datasz != 4)
20070 printf (_("x86 ISA used: <corrupt length: %#x> "),
20071 datasz);
20072 else
20073 {
20074 printf ("x86 ISA used: ");
20075 decode_x86_compat_isa (bitmask);
20076 }
20077 goto next;
20078
20079 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20080 if (datasz != 4)
20081 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20082 datasz);
20083 else
20084 {
20085 printf ("x86 ISA needed: ");
20086 decode_x86_compat_isa (bitmask);
aa7bca9b 20087 }
ee2fdd6f
L
20088 goto next;
20089
32930e4e
L
20090 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20091 if (datasz != 4)
20092 printf (_("x86 ISA used: <corrupt length: %#x> "),
20093 datasz);
20094 else
20095 {
20096 printf ("x86 ISA used: ");
20097 decode_x86_compat_2_isa (bitmask);
20098 }
20099 goto next;
20100
20101 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20102 if (datasz != 4)
20103 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20104 datasz);
20105 else
20106 {
20107 printf ("x86 ISA needed: ");
20108 decode_x86_compat_2_isa (bitmask);
20109 }
20110 goto next;
20111
1fc87489
L
20112 default:
20113 break;
20114 }
20115 }
cd702818
SD
20116 else if (filedata->file_header.e_machine == EM_AARCH64)
20117 {
20118 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20119 {
20120 printf ("AArch64 feature: ");
20121 if (datasz != 4)
20122 printf (_("<corrupt length: %#x> "), datasz);
20123 else
20124 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20125 goto next;
20126 }
20127 }
1fc87489
L
20128 }
20129 else
20130 {
20131 switch (type)
9ef920e9 20132 {
1fc87489
L
20133 case GNU_PROPERTY_STACK_SIZE:
20134 printf (_("stack size: "));
20135 if (datasz != size)
20136 printf (_("<corrupt length: %#x> "), datasz);
20137 else
20138 printf ("%#lx", (unsigned long) byte_get (ptr, size));
20139 goto next;
20140
20141 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20142 printf ("no copy on protected ");
20143 if (datasz)
20144 printf (_("<corrupt length: %#x> "), datasz);
20145 goto next;
20146
20147 default:
5a767724
L
20148 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20149 && type <= GNU_PROPERTY_UINT32_AND_HI)
20150 || (type >= GNU_PROPERTY_UINT32_OR_LO
20151 && type <= GNU_PROPERTY_UINT32_OR_HI))
20152 {
6320fd00
L
20153 switch (type)
20154 {
20155 case GNU_PROPERTY_1_NEEDED:
20156 if (datasz != 4)
20157 printf (_("1_needed: <corrupt length: %#x> "),
20158 datasz);
20159 else
20160 {
20161 unsigned int bitmask = byte_get (ptr, 4);
20162 printf ("1_needed: ");
20163 decode_1_needed (bitmask);
20164 }
20165 goto next;
20166
20167 default:
20168 break;
20169 }
5a767724
L
20170 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20171 printf (_("UINT32_AND (%#x): "), type);
20172 else
20173 printf (_("UINT32_OR (%#x): "), type);
20174 if (datasz != 4)
20175 printf (_("<corrupt length: %#x> "), datasz);
20176 else
20177 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20178 goto next;
20179 }
9ef920e9
NC
20180 break;
20181 }
9ef920e9
NC
20182 }
20183
1fc87489
L
20184 if (type < GNU_PROPERTY_LOPROC)
20185 printf (_("<unknown type %#x data: "), type);
20186 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20187 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20188 else
20189 printf (_("<application-specific type %#x data: "), type);
20190 for (j = 0; j < datasz; ++j)
20191 printf ("%02x ", ptr[j] & 0xff);
20192 printf (">");
20193
dc1e8a47 20194 next:
9ef920e9 20195 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20196 if (ptr == ptr_end)
20197 break;
1fc87489 20198
6ab2c4ed
MC
20199 if (do_wide)
20200 printf (", ");
20201 else
20202 printf ("\n\t");
9ef920e9
NC
20203 }
20204
20205 printf ("\n");
20206}
20207
015dc7e1 20208static bool
dda8d76d 20209print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20210{
1449284b 20211 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20212 switch (pnote->type)
20213 {
20214 case NT_GNU_BUILD_ID:
20215 {
20216 unsigned long i;
20217
20218 printf (_(" Build ID: "));
20219 for (i = 0; i < pnote->descsz; ++i)
20220 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20221 printf ("\n");
664f90a3
TT
20222 }
20223 break;
20224
20225 case NT_GNU_ABI_TAG:
20226 {
20227 unsigned long os, major, minor, subminor;
20228 const char *osname;
20229
3102e897
NC
20230 /* PR 17531: file: 030-599401-0.004. */
20231 if (pnote->descsz < 16)
20232 {
20233 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20234 break;
20235 }
20236
664f90a3
TT
20237 os = byte_get ((unsigned char *) pnote->descdata, 4);
20238 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20239 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20240 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20241
20242 switch (os)
20243 {
20244 case GNU_ABI_TAG_LINUX:
20245 osname = "Linux";
20246 break;
20247 case GNU_ABI_TAG_HURD:
20248 osname = "Hurd";
20249 break;
20250 case GNU_ABI_TAG_SOLARIS:
20251 osname = "Solaris";
20252 break;
20253 case GNU_ABI_TAG_FREEBSD:
20254 osname = "FreeBSD";
20255 break;
20256 case GNU_ABI_TAG_NETBSD:
20257 osname = "NetBSD";
20258 break;
14ae95f2
RM
20259 case GNU_ABI_TAG_SYLLABLE:
20260 osname = "Syllable";
20261 break;
20262 case GNU_ABI_TAG_NACL:
20263 osname = "NaCl";
20264 break;
664f90a3
TT
20265 default:
20266 osname = "Unknown";
20267 break;
20268 }
20269
20270 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
20271 major, minor, subminor);
20272 }
20273 break;
926c5385
CC
20274
20275 case NT_GNU_GOLD_VERSION:
20276 {
20277 unsigned long i;
20278
20279 printf (_(" Version: "));
20280 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20281 printf ("%c", pnote->descdata[i]);
20282 printf ("\n");
20283 }
20284 break;
1449284b
NC
20285
20286 case NT_GNU_HWCAP:
20287 {
20288 unsigned long num_entries, mask;
20289
20290 /* Hardware capabilities information. Word 0 is the number of entries.
20291 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20292 is a series of entries, where each entry is a single byte followed
20293 by a nul terminated string. The byte gives the bit number to test
20294 if enabled in the bitmask. */
20295 printf (_(" Hardware Capabilities: "));
20296 if (pnote->descsz < 8)
20297 {
32ec8896 20298 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20299 return false;
1449284b
NC
20300 }
20301 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20302 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20303 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
20304 /* FIXME: Add code to display the entries... */
20305 }
20306 break;
20307
9ef920e9 20308 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20309 print_gnu_property_note (filedata, pnote);
9ef920e9 20310 break;
9abca702 20311
1449284b
NC
20312 default:
20313 /* Handle unrecognised types. An error message should have already been
20314 created by get_gnu_elf_note_type(), so all that we need to do is to
20315 display the data. */
20316 {
20317 unsigned long i;
20318
20319 printf (_(" Description data: "));
20320 for (i = 0; i < pnote->descsz; ++i)
20321 printf ("%02x ", pnote->descdata[i] & 0xff);
20322 printf ("\n");
20323 }
20324 break;
664f90a3
TT
20325 }
20326
015dc7e1 20327 return true;
664f90a3
TT
20328}
20329
685080f2
NC
20330static const char *
20331get_v850_elf_note_type (enum v850_notes n_type)
20332{
20333 static char buff[64];
20334
20335 switch (n_type)
20336 {
20337 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20338 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20339 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20340 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20341 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20342 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20343 default:
20344 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20345 return buff;
20346 }
20347}
20348
015dc7e1 20349static bool
685080f2
NC
20350print_v850_note (Elf_Internal_Note * pnote)
20351{
20352 unsigned int val;
20353
20354 if (pnote->descsz != 4)
015dc7e1 20355 return false;
32ec8896 20356
685080f2
NC
20357 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20358
20359 if (val == 0)
20360 {
20361 printf (_("not set\n"));
015dc7e1 20362 return true;
685080f2
NC
20363 }
20364
20365 switch (pnote->type)
20366 {
20367 case V850_NOTE_ALIGNMENT:
20368 switch (val)
20369 {
015dc7e1
AM
20370 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20371 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20372 }
20373 break;
14ae95f2 20374
685080f2
NC
20375 case V850_NOTE_DATA_SIZE:
20376 switch (val)
20377 {
015dc7e1
AM
20378 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20379 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20380 }
20381 break;
14ae95f2 20382
685080f2
NC
20383 case V850_NOTE_FPU_INFO:
20384 switch (val)
20385 {
015dc7e1
AM
20386 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20387 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20388 }
20389 break;
14ae95f2 20390
685080f2
NC
20391 case V850_NOTE_MMU_INFO:
20392 case V850_NOTE_CACHE_INFO:
20393 case V850_NOTE_SIMD_INFO:
20394 if (val == EF_RH850_SIMD)
20395 {
20396 printf (_("yes\n"));
015dc7e1 20397 return true;
685080f2
NC
20398 }
20399 break;
20400
20401 default:
20402 /* An 'unknown note type' message will already have been displayed. */
20403 break;
20404 }
20405
20406 printf (_("unknown value: %x\n"), val);
015dc7e1 20407 return false;
685080f2
NC
20408}
20409
015dc7e1 20410static bool
c6056a74
SF
20411process_netbsd_elf_note (Elf_Internal_Note * pnote)
20412{
20413 unsigned int version;
20414
20415 switch (pnote->type)
20416 {
20417 case NT_NETBSD_IDENT:
b966f55f
AM
20418 if (pnote->descsz < 1)
20419 break;
c6056a74
SF
20420 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20421 if ((version / 10000) % 100)
b966f55f 20422 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20423 version, version / 100000000, (version / 1000000) % 100,
20424 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20425 'A' + (version / 10000) % 26);
c6056a74
SF
20426 else
20427 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20428 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20429 (version / 100) % 100);
015dc7e1 20430 return true;
c6056a74
SF
20431
20432 case NT_NETBSD_MARCH:
9abca702 20433 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20434 pnote->descdata);
015dc7e1 20435 return true;
c6056a74 20436
9abca702 20437 case NT_NETBSD_PAX:
b966f55f
AM
20438 if (pnote->descsz < 1)
20439 break;
9abca702
CZ
20440 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20441 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20442 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20443 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20444 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20445 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20446 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20447 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20448 return true;
c6056a74 20449 }
b966f55f
AM
20450
20451 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20452 pnote->descsz, pnote->type);
015dc7e1 20453 return false;
c6056a74
SF
20454}
20455
f4ddf30f 20456static const char *
dda8d76d 20457get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20458{
f4ddf30f
JB
20459 switch (e_type)
20460 {
20461 case NT_FREEBSD_THRMISC:
20462 return _("NT_THRMISC (thrmisc structure)");
20463 case NT_FREEBSD_PROCSTAT_PROC:
20464 return _("NT_PROCSTAT_PROC (proc data)");
20465 case NT_FREEBSD_PROCSTAT_FILES:
20466 return _("NT_PROCSTAT_FILES (files data)");
20467 case NT_FREEBSD_PROCSTAT_VMMAP:
20468 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20469 case NT_FREEBSD_PROCSTAT_GROUPS:
20470 return _("NT_PROCSTAT_GROUPS (groups data)");
20471 case NT_FREEBSD_PROCSTAT_UMASK:
20472 return _("NT_PROCSTAT_UMASK (umask data)");
20473 case NT_FREEBSD_PROCSTAT_RLIMIT:
20474 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20475 case NT_FREEBSD_PROCSTAT_OSREL:
20476 return _("NT_PROCSTAT_OSREL (osreldate data)");
20477 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20478 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20479 case NT_FREEBSD_PROCSTAT_AUXV:
20480 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20481 case NT_FREEBSD_PTLWPINFO:
20482 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
20483 case NT_FREEBSD_X86_SEGBASES:
20484 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 20485 }
dda8d76d 20486 return get_note_type (filedata, e_type);
f4ddf30f
JB
20487}
20488
9437c45b 20489static const char *
dda8d76d 20490get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20491{
20492 static char buff[64];
20493
540e6170
CZ
20494 switch (e_type)
20495 {
20496 case NT_NETBSDCORE_PROCINFO:
20497 /* NetBSD core "procinfo" structure. */
20498 return _("NetBSD procinfo structure");
9437c45b 20499
540e6170
CZ
20500 case NT_NETBSDCORE_AUXV:
20501 return _("NetBSD ELF auxiliary vector data");
9437c45b 20502
06d949ec
KR
20503 case NT_NETBSDCORE_LWPSTATUS:
20504 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20505
540e6170 20506 default:
06d949ec 20507 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20508 defined for NetBSD core files. If the note type is less
20509 than the start of the machine-dependent note types, we don't
20510 understand it. */
20511
20512 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20513 {
20514 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20515 return buff;
20516 }
20517 break;
9437c45b
JT
20518 }
20519
dda8d76d 20520 switch (filedata->file_header.e_machine)
9437c45b
JT
20521 {
20522 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20523 and PT_GETFPREGS == mach+2. */
20524
20525 case EM_OLD_ALPHA:
20526 case EM_ALPHA:
20527 case EM_SPARC:
20528 case EM_SPARC32PLUS:
20529 case EM_SPARCV9:
20530 switch (e_type)
20531 {
2b692964 20532 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20533 return _("PT_GETREGS (reg structure)");
2b692964 20534 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20535 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20536 default:
20537 break;
20538 }
20539 break;
20540
c0d38b0e
CZ
20541 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20542 There's also old PT___GETREGS40 == mach + 1 for old reg
20543 structure which lacks GBR. */
20544 case EM_SH:
20545 switch (e_type)
20546 {
20547 case NT_NETBSDCORE_FIRSTMACH + 1:
20548 return _("PT___GETREGS40 (old reg structure)");
20549 case NT_NETBSDCORE_FIRSTMACH + 3:
20550 return _("PT_GETREGS (reg structure)");
20551 case NT_NETBSDCORE_FIRSTMACH + 5:
20552 return _("PT_GETFPREGS (fpreg structure)");
20553 default:
20554 break;
20555 }
20556 break;
20557
9437c45b
JT
20558 /* On all other arch's, PT_GETREGS == mach+1 and
20559 PT_GETFPREGS == mach+3. */
20560 default:
20561 switch (e_type)
20562 {
2b692964 20563 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20564 return _("PT_GETREGS (reg structure)");
2b692964 20565 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20566 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20567 default:
20568 break;
20569 }
20570 }
20571
9cf03b7e 20572 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20573 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20574 return buff;
20575}
20576
98ca73af
FC
20577static const char *
20578get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20579{
20580 switch (e_type)
20581 {
20582 case NT_OPENBSD_PROCINFO:
20583 return _("OpenBSD procinfo structure");
20584 case NT_OPENBSD_AUXV:
20585 return _("OpenBSD ELF auxiliary vector data");
20586 case NT_OPENBSD_REGS:
20587 return _("OpenBSD regular registers");
20588 case NT_OPENBSD_FPREGS:
20589 return _("OpenBSD floating point registers");
20590 case NT_OPENBSD_WCOOKIE:
20591 return _("OpenBSD window cookie");
20592 }
20593
20594 return get_note_type (filedata, e_type);
20595}
20596
70616151
TT
20597static const char *
20598get_stapsdt_note_type (unsigned e_type)
20599{
20600 static char buff[64];
20601
20602 switch (e_type)
20603 {
20604 case NT_STAPSDT:
20605 return _("NT_STAPSDT (SystemTap probe descriptors)");
20606
20607 default:
20608 break;
20609 }
20610
20611 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20612 return buff;
20613}
20614
015dc7e1 20615static bool
c6a9fc58
TT
20616print_stapsdt_note (Elf_Internal_Note *pnote)
20617{
3ca60c57
NC
20618 size_t len, maxlen;
20619 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20620 char *data = pnote->descdata;
20621 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 20622 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
20623 char *provider, *probe, *arg_fmt;
20624
3ca60c57
NC
20625 if (pnote->descsz < (addr_size * 3))
20626 goto stapdt_note_too_small;
20627
c6a9fc58
TT
20628 pc = byte_get ((unsigned char *) data, addr_size);
20629 data += addr_size;
3ca60c57 20630
c6a9fc58
TT
20631 base_addr = byte_get ((unsigned char *) data, addr_size);
20632 data += addr_size;
3ca60c57 20633
c6a9fc58
TT
20634 semaphore = byte_get ((unsigned char *) data, addr_size);
20635 data += addr_size;
20636
3ca60c57
NC
20637 if (data >= data_end)
20638 goto stapdt_note_too_small;
20639 maxlen = data_end - data;
20640 len = strnlen (data, maxlen);
20641 if (len < maxlen)
20642 {
20643 provider = data;
20644 data += len + 1;
20645 }
20646 else
20647 goto stapdt_note_too_small;
20648
20649 if (data >= data_end)
20650 goto stapdt_note_too_small;
20651 maxlen = data_end - data;
20652 len = strnlen (data, maxlen);
20653 if (len < maxlen)
20654 {
20655 probe = data;
20656 data += len + 1;
20657 }
20658 else
20659 goto stapdt_note_too_small;
9abca702 20660
3ca60c57
NC
20661 if (data >= data_end)
20662 goto stapdt_note_too_small;
20663 maxlen = data_end - data;
20664 len = strnlen (data, maxlen);
20665 if (len < maxlen)
20666 {
20667 arg_fmt = data;
20668 data += len + 1;
20669 }
20670 else
20671 goto stapdt_note_too_small;
c6a9fc58
TT
20672
20673 printf (_(" Provider: %s\n"), provider);
20674 printf (_(" Name: %s\n"), probe);
20675 printf (_(" Location: "));
20676 print_vma (pc, FULL_HEX);
20677 printf (_(", Base: "));
20678 print_vma (base_addr, FULL_HEX);
20679 printf (_(", Semaphore: "));
20680 print_vma (semaphore, FULL_HEX);
9cf03b7e 20681 printf ("\n");
c6a9fc58
TT
20682 printf (_(" Arguments: %s\n"), arg_fmt);
20683
20684 return data == data_end;
3ca60c57
NC
20685
20686 stapdt_note_too_small:
20687 printf (_(" <corrupt - note is too small>\n"));
20688 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20689 return false;
c6a9fc58
TT
20690}
20691
e5382207
LB
20692static bool
20693print_fdo_note (Elf_Internal_Note * pnote)
20694{
20695 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20696 {
20697 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20698 return true;
20699 }
20700 return false;
20701}
20702
00e98fc7
TG
20703static const char *
20704get_ia64_vms_note_type (unsigned e_type)
20705{
20706 static char buff[64];
20707
20708 switch (e_type)
20709 {
20710 case NT_VMS_MHD:
20711 return _("NT_VMS_MHD (module header)");
20712 case NT_VMS_LNM:
20713 return _("NT_VMS_LNM (language name)");
20714 case NT_VMS_SRC:
20715 return _("NT_VMS_SRC (source files)");
20716 case NT_VMS_TITLE:
9cf03b7e 20717 return "NT_VMS_TITLE";
00e98fc7
TG
20718 case NT_VMS_EIDC:
20719 return _("NT_VMS_EIDC (consistency check)");
20720 case NT_VMS_FPMODE:
20721 return _("NT_VMS_FPMODE (FP mode)");
20722 case NT_VMS_LINKTIME:
9cf03b7e 20723 return "NT_VMS_LINKTIME";
00e98fc7
TG
20724 case NT_VMS_IMGNAM:
20725 return _("NT_VMS_IMGNAM (image name)");
20726 case NT_VMS_IMGID:
20727 return _("NT_VMS_IMGID (image id)");
20728 case NT_VMS_LINKID:
20729 return _("NT_VMS_LINKID (link id)");
20730 case NT_VMS_IMGBID:
20731 return _("NT_VMS_IMGBID (build id)");
20732 case NT_VMS_GSTNAM:
20733 return _("NT_VMS_GSTNAM (sym table name)");
20734 case NT_VMS_ORIG_DYN:
9cf03b7e 20735 return "NT_VMS_ORIG_DYN";
00e98fc7 20736 case NT_VMS_PATCHTIME:
9cf03b7e 20737 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20738 default:
20739 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20740 return buff;
20741 }
20742}
20743
015dc7e1 20744static bool
00e98fc7
TG
20745print_ia64_vms_note (Elf_Internal_Note * pnote)
20746{
8d18bf79
NC
20747 int maxlen = pnote->descsz;
20748
20749 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20750 goto desc_size_fail;
20751
00e98fc7
TG
20752 switch (pnote->type)
20753 {
20754 case NT_VMS_MHD:
8d18bf79
NC
20755 if (maxlen <= 36)
20756 goto desc_size_fail;
20757
20758 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20759
20760 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20761 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20762 if (l + 34 < maxlen)
20763 {
20764 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20765 if (l + 35 < maxlen)
20766 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20767 else
20768 printf (_(" Module version : <missing>\n"));
20769 }
00e98fc7 20770 else
8d18bf79
NC
20771 {
20772 printf (_(" Module name : <missing>\n"));
20773 printf (_(" Module version : <missing>\n"));
20774 }
00e98fc7 20775 break;
8d18bf79 20776
00e98fc7 20777 case NT_VMS_LNM:
8d18bf79 20778 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20779 break;
8d18bf79 20780
00e98fc7 20781 case NT_VMS_FPMODE:
9cf03b7e 20782 printf (_(" Floating Point mode: "));
8d18bf79
NC
20783 if (maxlen < 8)
20784 goto desc_size_fail;
20785 /* FIXME: Generate an error if descsz > 8 ? */
20786
b8281767 20787 printf ("0x%016" PRIx64 "\n",
625d49fc 20788 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 20789 break;
8d18bf79 20790
00e98fc7
TG
20791 case NT_VMS_LINKTIME:
20792 printf (_(" Link time: "));
8d18bf79
NC
20793 if (maxlen < 8)
20794 goto desc_size_fail;
20795 /* FIXME: Generate an error if descsz > 8 ? */
20796
0e3c1eeb 20797 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20798 printf ("\n");
20799 break;
8d18bf79 20800
00e98fc7
TG
20801 case NT_VMS_PATCHTIME:
20802 printf (_(" Patch time: "));
8d18bf79
NC
20803 if (maxlen < 8)
20804 goto desc_size_fail;
20805 /* FIXME: Generate an error if descsz > 8 ? */
20806
0e3c1eeb 20807 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20808 printf ("\n");
20809 break;
8d18bf79 20810
00e98fc7 20811 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20812 if (maxlen < 34)
20813 goto desc_size_fail;
20814
00e98fc7 20815 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
20816 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
20817 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 20818 printf (_(" Last modified : "));
0e3c1eeb 20819 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 20820 printf (_("\n Link flags : "));
b8281767 20821 printf ("0x%016" PRIx64 "\n",
625d49fc 20822 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 20823 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 20824 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 20825 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 20826 break;
8d18bf79 20827
00e98fc7 20828 case NT_VMS_IMGNAM:
8d18bf79 20829 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20830 break;
8d18bf79 20831
00e98fc7 20832 case NT_VMS_GSTNAM:
8d18bf79 20833 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20834 break;
8d18bf79 20835
00e98fc7 20836 case NT_VMS_IMGID:
8d18bf79 20837 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20838 break;
8d18bf79 20839
00e98fc7 20840 case NT_VMS_LINKID:
8d18bf79 20841 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20842 break;
8d18bf79 20843
00e98fc7 20844 default:
015dc7e1 20845 return false;
00e98fc7 20846 }
8d18bf79 20847
015dc7e1 20848 return true;
8d18bf79
NC
20849
20850 desc_size_fail:
20851 printf (_(" <corrupt - data size is too small>\n"));
20852 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20853 return false;
00e98fc7
TG
20854}
20855
fd486f32
AM
20856struct build_attr_cache {
20857 Filedata *filedata;
20858 char *strtab;
20859 unsigned long strtablen;
20860 Elf_Internal_Sym *symtab;
20861 unsigned long nsyms;
20862} ba_cache;
20863
6f156d7a
NC
20864/* Find the symbol associated with a build attribute that is attached
20865 to address OFFSET. If PNAME is non-NULL then store the name of
20866 the symbol (if found) in the provided pointer, Returns NULL if a
20867 symbol could not be found. */
c799a79d 20868
6f156d7a 20869static Elf_Internal_Sym *
015dc7e1
AM
20870get_symbol_for_build_attribute (Filedata *filedata,
20871 unsigned long offset,
20872 bool is_open_attr,
20873 const char **pname)
9ef920e9 20874{
fd486f32
AM
20875 Elf_Internal_Sym *saved_sym = NULL;
20876 Elf_Internal_Sym *sym;
9ef920e9 20877
dda8d76d 20878 if (filedata->section_headers != NULL
fd486f32 20879 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20880 {
c799a79d 20881 Elf_Internal_Shdr * symsec;
9ef920e9 20882
fd486f32
AM
20883 free (ba_cache.strtab);
20884 ba_cache.strtab = NULL;
20885 free (ba_cache.symtab);
20886 ba_cache.symtab = NULL;
20887
c799a79d 20888 /* Load the symbol and string sections. */
dda8d76d
NC
20889 for (symsec = filedata->section_headers;
20890 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20891 symsec ++)
9ef920e9 20892 {
28d13567
AM
20893 if (symsec->sh_type == SHT_SYMTAB
20894 && get_symtab (filedata, symsec,
20895 &ba_cache.symtab, &ba_cache.nsyms,
20896 &ba_cache.strtab, &ba_cache.strtablen))
20897 break;
9ef920e9 20898 }
fd486f32 20899 ba_cache.filedata = filedata;
9ef920e9
NC
20900 }
20901
fd486f32 20902 if (ba_cache.symtab == NULL)
6f156d7a 20903 return NULL;
9ef920e9 20904
c799a79d 20905 /* Find a symbol whose value matches offset. */
fd486f32 20906 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20907 if (sym->st_value == offset)
20908 {
fd486f32 20909 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20910 /* Huh ? This should not happen. */
20911 continue;
9ef920e9 20912
fd486f32 20913 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20914 continue;
9ef920e9 20915
9b9b1092 20916 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20917 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20918 if (ba_cache.strtab[sym->st_name] == '$'
20919 && ba_cache.strtab[sym->st_name + 1] != 0
20920 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20921 continue;
20922
c799a79d
NC
20923 if (is_open_attr)
20924 {
20925 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20926 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20927 FUNC symbols entirely. */
20928 switch (ELF_ST_TYPE (sym->st_info))
20929 {
c799a79d 20930 case STT_OBJECT:
6f156d7a 20931 case STT_FILE:
c799a79d 20932 saved_sym = sym;
6f156d7a
NC
20933 if (sym->st_size)
20934 {
20935 /* If the symbol has a size associated
20936 with it then we can stop searching. */
fd486f32 20937 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20938 }
c799a79d 20939 continue;
9ef920e9 20940
c799a79d
NC
20941 case STT_FUNC:
20942 /* Ignore function symbols. */
20943 continue;
20944
20945 default:
20946 break;
20947 }
20948
20949 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20950 {
c799a79d
NC
20951 case STB_GLOBAL:
20952 if (saved_sym == NULL
20953 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20954 saved_sym = sym;
20955 break;
c871dade 20956
c799a79d
NC
20957 case STB_LOCAL:
20958 if (saved_sym == NULL)
20959 saved_sym = sym;
20960 break;
20961
20962 default:
9ef920e9
NC
20963 break;
20964 }
20965 }
c799a79d
NC
20966 else
20967 {
20968 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20969 continue;
20970
20971 saved_sym = sym;
20972 break;
20973 }
20974 }
20975
6f156d7a 20976 if (saved_sym && pname)
fd486f32 20977 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20978
20979 return saved_sym;
c799a79d
NC
20980}
20981
d20e98ab
NC
20982/* Returns true iff addr1 and addr2 are in the same section. */
20983
015dc7e1 20984static bool
d20e98ab
NC
20985same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20986{
20987 Elf_Internal_Shdr * a1;
20988 Elf_Internal_Shdr * a2;
20989
20990 a1 = find_section_by_address (filedata, addr1);
20991 a2 = find_section_by_address (filedata, addr2);
9abca702 20992
d20e98ab
NC
20993 return a1 == a2 && a1 != NULL;
20994}
20995
015dc7e1 20996static bool
dda8d76d
NC
20997print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20998 Filedata * filedata)
c799a79d 20999{
015dc7e1
AM
21000 static unsigned long global_offset = 0;
21001 static unsigned long global_end = 0;
21002 static unsigned long func_offset = 0;
21003 static unsigned long func_end = 0;
c871dade 21004
015dc7e1
AM
21005 Elf_Internal_Sym *sym;
21006 const char *name;
21007 unsigned long start;
21008 unsigned long end;
21009 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
21010
21011 switch (pnote->descsz)
c799a79d 21012 {
6f156d7a
NC
21013 case 0:
21014 /* A zero-length description means that the range of
21015 the previous note of the same type should be used. */
c799a79d 21016 if (is_open_attr)
c871dade 21017 {
6f156d7a
NC
21018 if (global_end > global_offset)
21019 printf (_(" Applies to region from %#lx to %#lx\n"),
21020 global_offset, global_end);
21021 else
21022 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
21023 }
21024 else
21025 {
6f156d7a
NC
21026 if (func_end > func_offset)
21027 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
21028 else
21029 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 21030 }
015dc7e1 21031 return true;
9ef920e9 21032
6f156d7a
NC
21033 case 4:
21034 start = byte_get ((unsigned char *) pnote->descdata, 4);
21035 end = 0;
21036 break;
21037
21038 case 8:
c74147bb
NC
21039 start = byte_get ((unsigned char *) pnote->descdata, 4);
21040 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21041 break;
21042
21043 case 16:
21044 start = byte_get ((unsigned char *) pnote->descdata, 8);
21045 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21046 break;
9abca702 21047
6f156d7a 21048 default:
c799a79d
NC
21049 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21050 printf (_(" <invalid descsz>"));
015dc7e1 21051 return false;
c799a79d
NC
21052 }
21053
6f156d7a
NC
21054 name = NULL;
21055 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21056 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21057 in order to avoid them being confused with the start address of the
21058 first function in the file... */
21059 if (sym == NULL && is_open_attr)
21060 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21061 & name);
6f156d7a
NC
21062
21063 if (end == 0 && sym != NULL && sym->st_size > 0)
21064 end = start + sym->st_size;
c799a79d
NC
21065
21066 if (is_open_attr)
21067 {
d20e98ab
NC
21068 /* FIXME: Need to properly allow for section alignment.
21069 16 is just the alignment used on x86_64. */
21070 if (global_end > 0
21071 && start > BFD_ALIGN (global_end, 16)
21072 /* Build notes are not guaranteed to be organised in order of
21073 increasing address, but we should find the all of the notes
21074 for one section in the same place. */
21075 && same_section (filedata, start, global_end))
6f156d7a
NC
21076 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
21077 global_end + 1, start - 1);
21078
21079 printf (_(" Applies to region from %#lx"), start);
21080 global_offset = start;
21081
21082 if (end)
21083 {
21084 printf (_(" to %#lx"), end);
21085 global_end = end;
21086 }
c799a79d
NC
21087 }
21088 else
21089 {
6f156d7a
NC
21090 printf (_(" Applies to region from %#lx"), start);
21091 func_offset = start;
21092
21093 if (end)
21094 {
21095 printf (_(" to %#lx"), end);
21096 func_end = end;
21097 }
c799a79d
NC
21098 }
21099
6f156d7a
NC
21100 if (sym && name)
21101 printf (_(" (%s)"), name);
21102
21103 printf ("\n");
015dc7e1 21104 return true;
9ef920e9
NC
21105}
21106
015dc7e1 21107static bool
9ef920e9
NC
21108print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21109{
1d15e434
NC
21110 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21111 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21112 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21113 char name_type;
21114 char name_attribute;
1d15e434 21115 const char * expected_types;
9ef920e9
NC
21116 const char * name = pnote->namedata;
21117 const char * text;
88305e1b 21118 signed int left;
9ef920e9
NC
21119
21120 if (name == NULL || pnote->namesz < 2)
21121 {
21122 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21123 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21124 return false;
9ef920e9
NC
21125 }
21126
6f156d7a
NC
21127 if (do_wide)
21128 left = 28;
21129 else
21130 left = 20;
88305e1b
NC
21131
21132 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21133 if (name[0] == 'G' && name[1] == 'A')
21134 {
6f156d7a
NC
21135 if (pnote->namesz < 4)
21136 {
21137 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21138 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21139 return false;
6f156d7a
NC
21140 }
21141
88305e1b
NC
21142 printf ("GA");
21143 name += 2;
21144 left -= 2;
21145 }
21146
9ef920e9
NC
21147 switch ((name_type = * name))
21148 {
21149 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21150 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21151 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21152 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21153 printf ("%c", * name);
88305e1b 21154 left --;
9ef920e9
NC
21155 break;
21156 default:
21157 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21158 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21159 return false;
9ef920e9
NC
21160 }
21161
9ef920e9
NC
21162 ++ name;
21163 text = NULL;
21164
21165 switch ((name_attribute = * name))
21166 {
21167 case GNU_BUILD_ATTRIBUTE_VERSION:
21168 text = _("<version>");
1d15e434 21169 expected_types = string_expected;
9ef920e9
NC
21170 ++ name;
21171 break;
21172 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21173 text = _("<stack prot>");
75d7d298 21174 expected_types = "!+*";
9ef920e9
NC
21175 ++ name;
21176 break;
21177 case GNU_BUILD_ATTRIBUTE_RELRO:
21178 text = _("<relro>");
1d15e434 21179 expected_types = bool_expected;
9ef920e9
NC
21180 ++ name;
21181 break;
21182 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21183 text = _("<stack size>");
1d15e434 21184 expected_types = number_expected;
9ef920e9
NC
21185 ++ name;
21186 break;
21187 case GNU_BUILD_ATTRIBUTE_TOOL:
21188 text = _("<tool>");
1d15e434 21189 expected_types = string_expected;
9ef920e9
NC
21190 ++ name;
21191 break;
21192 case GNU_BUILD_ATTRIBUTE_ABI:
21193 text = _("<ABI>");
21194 expected_types = "$*";
21195 ++ name;
21196 break;
21197 case GNU_BUILD_ATTRIBUTE_PIC:
21198 text = _("<PIC>");
1d15e434 21199 expected_types = number_expected;
9ef920e9
NC
21200 ++ name;
21201 break;
a8be5506
NC
21202 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21203 text = _("<short enum>");
1d15e434 21204 expected_types = bool_expected;
a8be5506
NC
21205 ++ name;
21206 break;
9ef920e9
NC
21207 default:
21208 if (ISPRINT (* name))
21209 {
21210 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21211
21212 if (len > left && ! do_wide)
21213 len = left;
75d7d298 21214 printf ("%.*s:", len, name);
9ef920e9 21215 left -= len;
0dd6ae21 21216 name += len;
9ef920e9
NC
21217 }
21218 else
21219 {
3e6b6445 21220 static char tmpbuf [128];
88305e1b 21221
3e6b6445
NC
21222 error (_("unrecognised byte in name field: %d\n"), * name);
21223 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21224 text = tmpbuf;
21225 name ++;
9ef920e9
NC
21226 }
21227 expected_types = "*$!+";
21228 break;
21229 }
21230
21231 if (text)
88305e1b 21232 left -= printf ("%s", text);
9ef920e9
NC
21233
21234 if (strchr (expected_types, name_type) == NULL)
75d7d298 21235 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
21236
21237 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
21238 {
21239 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
21240 (unsigned long) pnote->namesz,
21241 (long) (name - pnote->namedata));
015dc7e1 21242 return false;
9ef920e9
NC
21243 }
21244
21245 if (left < 1 && ! do_wide)
015dc7e1 21246 return true;
9ef920e9
NC
21247
21248 switch (name_type)
21249 {
21250 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21251 {
b06b2c92 21252 unsigned int bytes;
ddef72cd
NC
21253 unsigned long long val = 0;
21254 unsigned int shift = 0;
21255 char * decoded = NULL;
21256
b06b2c92
NC
21257 bytes = pnote->namesz - (name - pnote->namedata);
21258 if (bytes > 0)
21259 /* The -1 is because the name field is always 0 terminated, and we
21260 want to be able to ensure that the shift in the while loop below
21261 will not overflow. */
21262 -- bytes;
21263
ddef72cd
NC
21264 if (bytes > sizeof (val))
21265 {
3e6b6445
NC
21266 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21267 bytes);
21268 bytes = sizeof (val);
ddef72cd 21269 }
3e6b6445
NC
21270 /* We do not bother to warn if bytes == 0 as this can
21271 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21272
21273 while (bytes --)
21274 {
54b8331d 21275 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
21276
21277 val |= byte << shift;
9ef920e9
NC
21278 shift += 8;
21279 }
21280
75d7d298 21281 switch (name_attribute)
9ef920e9 21282 {
75d7d298 21283 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21284 switch (val)
21285 {
75d7d298
NC
21286 case 0: decoded = "static"; break;
21287 case 1: decoded = "pic"; break;
21288 case 2: decoded = "PIC"; break;
21289 case 3: decoded = "pie"; break;
21290 case 4: decoded = "PIE"; break;
21291 default: break;
9ef920e9 21292 }
75d7d298
NC
21293 break;
21294 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21295 switch (val)
9ef920e9 21296 {
75d7d298
NC
21297 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21298 case 0: decoded = "off"; break;
21299 case 1: decoded = "on"; break;
21300 case 2: decoded = "all"; break;
21301 case 3: decoded = "strong"; break;
21302 case 4: decoded = "explicit"; break;
21303 default: break;
9ef920e9 21304 }
75d7d298
NC
21305 break;
21306 default:
21307 break;
9ef920e9
NC
21308 }
21309
75d7d298 21310 if (decoded != NULL)
3e6b6445
NC
21311 {
21312 print_symbol (-left, decoded);
21313 left = 0;
21314 }
21315 else if (val == 0)
21316 {
21317 printf ("0x0");
21318 left -= 3;
21319 }
9ef920e9 21320 else
75d7d298
NC
21321 {
21322 if (do_wide)
ddef72cd 21323 left -= printf ("0x%llx", val);
75d7d298 21324 else
ddef72cd 21325 left -= printf ("0x%-.*llx", left, val);
75d7d298 21326 }
9ef920e9
NC
21327 }
21328 break;
21329 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21330 left -= print_symbol (- left, name);
21331 break;
21332 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21333 left -= print_symbol (- left, "true");
21334 break;
21335 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21336 left -= print_symbol (- left, "false");
21337 break;
21338 }
21339
21340 if (do_wide && left > 0)
21341 printf ("%-*s", left, " ");
9abca702 21342
015dc7e1 21343 return true;
9ef920e9
NC
21344}
21345
2952f10c
SM
21346/* Print the contents of PNOTE as hex. */
21347
21348static void
21349print_note_contents_hex (Elf_Internal_Note *pnote)
21350{
21351 if (pnote->descsz)
21352 {
21353 unsigned long i;
21354
21355 printf (_(" description data: "));
21356 for (i = 0; i < pnote->descsz; i++)
21357 printf ("%02x ", pnote->descdata[i] & 0xff);
21358 if (!do_wide)
21359 printf ("\n");
21360 }
21361
21362 if (do_wide)
21363 printf ("\n");
21364}
21365
21366#if defined HAVE_MSGPACK
21367
21368static void
21369print_indents (int n)
21370{
21371 printf (" ");
21372
21373 for (int i = 0; i < n; i++)
21374 printf (" ");
21375}
21376
21377/* Print OBJ in human-readable form. */
21378
21379static void
21380dump_msgpack_obj (const msgpack_object *obj, int indent)
21381{
21382 switch (obj->type)
21383 {
21384 case MSGPACK_OBJECT_NIL:
21385 printf ("(nil)");
21386 break;
21387
21388 case MSGPACK_OBJECT_BOOLEAN:
21389 printf ("%s", obj->via.boolean ? "true" : "false");
21390 break;
21391
21392 case MSGPACK_OBJECT_POSITIVE_INTEGER:
21393 printf ("%" PRIu64, obj->via.u64);
21394 break;
21395
21396 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
21397 printf ("%" PRIi64, obj->via.i64);
21398 break;
21399
21400 case MSGPACK_OBJECT_FLOAT32:
21401 case MSGPACK_OBJECT_FLOAT64:
21402 printf ("%f", obj->via.f64);
21403 break;
21404
21405 case MSGPACK_OBJECT_STR:
21406 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
21407 break;
21408
21409 case MSGPACK_OBJECT_ARRAY:
21410 {
21411 const msgpack_object_array *array = &obj->via.array;
21412
21413 printf ("[\n");
21414 ++indent;
21415
21416 for (uint32_t i = 0; i < array->size; ++i)
21417 {
21418 const msgpack_object *item = &array->ptr[i];
21419
21420 print_indents (indent);
21421 dump_msgpack_obj (item, indent);
21422 printf (",\n");
21423 }
21424
21425 --indent;
21426 print_indents (indent);
21427 printf ("]");
21428 break;
21429 }
21430 break;
21431
21432 case MSGPACK_OBJECT_MAP:
21433 {
21434 const msgpack_object_map *map = &obj->via.map;
21435
21436 printf ("{\n");
21437 ++indent;
21438
21439 for (uint32_t i = 0; i < map->size; ++i)
21440 {
21441 const msgpack_object_kv *kv = &map->ptr[i];
21442 const msgpack_object *key = &kv->key;
21443 const msgpack_object *val = &kv->val;
21444
21445 print_indents (indent);
21446 dump_msgpack_obj (key, indent);
21447 printf (": ");
21448 dump_msgpack_obj (val, indent);
21449
21450 printf (",\n");
21451 }
21452
21453 --indent;
21454 print_indents (indent);
21455 printf ("}");
21456
21457 break;
21458 }
21459
21460 case MSGPACK_OBJECT_BIN:
21461 printf ("(bin)");
21462 break;
21463
21464 case MSGPACK_OBJECT_EXT:
21465 printf ("(ext)");
21466 break;
21467 }
21468}
21469
21470static void
21471dump_msgpack (const msgpack_unpacked *msg)
21472{
21473 print_indents (0);
21474 dump_msgpack_obj (&msg->data, 0);
21475 printf ("\n");
21476}
21477
21478#endif /* defined HAVE_MSGPACK */
21479
21480static bool
21481print_amdgpu_note (Elf_Internal_Note *pnote)
21482{
21483#if defined HAVE_MSGPACK
21484 /* If msgpack is available, decode and dump the note's content. */
21485 bool ret;
21486 msgpack_unpacked msg;
21487 msgpack_unpack_return msgpack_ret;
21488
21489 assert (pnote->type == NT_AMDGPU_METADATA);
21490
21491 msgpack_unpacked_init (&msg);
21492 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
21493 NULL);
21494
21495 switch (msgpack_ret)
21496 {
21497 case MSGPACK_UNPACK_SUCCESS:
21498 dump_msgpack (&msg);
21499 ret = true;
21500 break;
21501
21502 default:
21503 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
21504 ret = false;
21505 break;
21506 }
21507
21508 msgpack_unpacked_destroy (&msg);
21509 return ret;
21510#else
21511 /* msgpack is not available, dump contents as hex. */
21512 print_note_contents_hex (pnote);
21513 return true;
21514#endif
21515}
21516
6d118b09
NC
21517/* Note that by the ELF standard, the name field is already null byte
21518 terminated, and namesz includes the terminating null byte.
21519 I.E. the value of namesz for the name "FSF" is 4.
21520
e3c8793a 21521 If the value of namesz is zero, there is no name present. */
9ef920e9 21522
015dc7e1 21523static bool
9ef920e9 21524process_note (Elf_Internal_Note * pnote,
dda8d76d 21525 Filedata * filedata)
779fe533 21526{
2cf0635d
NC
21527 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21528 const char * nt;
9437c45b
JT
21529
21530 if (pnote->namesz == 0)
1ec5cd37
NC
21531 /* If there is no note name, then use the default set of
21532 note type strings. */
dda8d76d 21533 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21534
24d127aa 21535 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21536 /* GNU-specific object file notes. */
21537 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21538
28cdbb18
SM
21539 else if (startswith (pnote->namedata, "AMDGPU"))
21540 /* AMDGPU-specific object file notes. */
21541 nt = get_amdgpu_elf_note_type (pnote->type);
21542
24d127aa 21543 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21544 /* FreeBSD-specific core file notes. */
dda8d76d 21545 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21546
24d127aa 21547 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21548 /* NetBSD-specific core file notes. */
dda8d76d 21549 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21550
24d127aa 21551 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21552 /* NetBSD-specific core file notes. */
21553 return process_netbsd_elf_note (pnote);
21554
24d127aa 21555 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21556 /* NetBSD-specific core file notes. */
21557 return process_netbsd_elf_note (pnote);
21558
98ca73af
FC
21559 else if (startswith (pnote->namedata, "OpenBSD"))
21560 /* OpenBSD-specific core file notes. */
21561 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21562
e9b095a5 21563 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21564 {
21565 /* SPU-specific core file notes. */
21566 nt = pnote->namedata + 4;
21567 name = "SPU";
21568 }
21569
24d127aa 21570 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21571 /* VMS/ia64-specific file notes. */
21572 nt = get_ia64_vms_note_type (pnote->type);
21573
24d127aa 21574 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21575 nt = get_stapsdt_note_type (pnote->type);
21576
9437c45b 21577 else
1ec5cd37
NC
21578 /* Don't recognize this note name; just use the default set of
21579 note type strings. */
dda8d76d 21580 nt = get_note_type (filedata, pnote->type);
9437c45b 21581
1449284b 21582 printf (" ");
9ef920e9 21583
24d127aa 21584 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21585 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21586 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21587 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21588 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21589 print_gnu_build_attribute_name (pnote);
21590 else
21591 print_symbol (-20, name);
21592
21593 if (do_wide)
21594 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21595 else
21596 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21597
24d127aa 21598 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21599 return print_ia64_vms_note (pnote);
24d127aa 21600 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21601 return print_gnu_note (filedata, pnote);
24d127aa 21602 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21603 return print_stapsdt_note (pnote);
24d127aa 21604 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21605 return print_core_note (pnote);
e5382207
LB
21606 else if (startswith (pnote->namedata, "FDO"))
21607 return print_fdo_note (pnote);
24d127aa 21608 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21609 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21610 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21611 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21612 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21613 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
21614 else if (startswith (pnote->namedata, "AMDGPU")
21615 && pnote->type == NT_AMDGPU_METADATA)
21616 return print_amdgpu_note (pnote);
779fe533 21617
2952f10c 21618 print_note_contents_hex (pnote);
015dc7e1 21619 return true;
1449284b 21620}
6d118b09 21621
015dc7e1 21622static bool
dda8d76d
NC
21623process_notes_at (Filedata * filedata,
21624 Elf_Internal_Shdr * section,
625d49fc
AM
21625 uint64_t offset,
21626 uint64_t length,
21627 uint64_t align)
779fe533 21628{
015dc7e1
AM
21629 Elf_External_Note *pnotes;
21630 Elf_External_Note *external;
21631 char *end;
21632 bool res = true;
103f02d3 21633
779fe533 21634 if (length <= 0)
015dc7e1 21635 return false;
103f02d3 21636
1449284b
NC
21637 if (section)
21638 {
dda8d76d 21639 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21640 if (pnotes)
32ec8896 21641 {
dda8d76d 21642 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21643 {
21644 free (pnotes);
015dc7e1 21645 return false;
f761cb13 21646 }
32ec8896 21647 }
1449284b
NC
21648 }
21649 else
82ed9683 21650 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21651 _("notes"));
4dff97b2 21652
dd24e3da 21653 if (pnotes == NULL)
015dc7e1 21654 return false;
779fe533 21655
103f02d3 21656 external = pnotes;
103f02d3 21657
ca0e11aa
NC
21658 if (filedata->is_separate)
21659 printf (_("In linked file '%s': "), filedata->file_name);
21660 else
21661 printf ("\n");
1449284b 21662 if (section)
ca0e11aa 21663 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21664 else
ca0e11aa 21665 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
21666 (unsigned long) offset, (unsigned long) length);
21667
82ed9683
L
21668 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21669 specifies that notes should be aligned to 4 bytes in 32-bit
21670 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21671 we also support 4 byte alignment in 64-bit objects. If section
21672 alignment is less than 4, we treate alignment as 4 bytes. */
21673 if (align < 4)
21674 align = 4;
21675 else if (align != 4 && align != 8)
21676 {
21677 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
21678 (long) align);
a788aedd 21679 free (pnotes);
015dc7e1 21680 return false;
82ed9683
L
21681 }
21682
dbe15e4e 21683 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21684
c8071705
NC
21685 end = (char *) pnotes + length;
21686 while ((char *) external < end)
779fe533 21687 {
b34976b6 21688 Elf_Internal_Note inote;
15b42fb0 21689 size_t min_notesz;
4dff97b2 21690 char * next;
2cf0635d 21691 char * temp = NULL;
c8071705 21692 size_t data_remaining = end - (char *) external;
6d118b09 21693
dda8d76d 21694 if (!is_ia64_vms (filedata))
15b42fb0 21695 {
9dd3a467
NC
21696 /* PR binutils/15191
21697 Make sure that there is enough data to read. */
15b42fb0
AM
21698 min_notesz = offsetof (Elf_External_Note, name);
21699 if (data_remaining < min_notesz)
9dd3a467 21700 {
d3a49aa8
AM
21701 warn (ngettext ("Corrupt note: only %ld byte remains, "
21702 "not enough for a full note\n",
21703 "Corrupt note: only %ld bytes remain, "
21704 "not enough for a full note\n",
21705 data_remaining),
21706 (long) data_remaining);
9dd3a467
NC
21707 break;
21708 }
5396a86e
AM
21709 data_remaining -= min_notesz;
21710
15b42fb0
AM
21711 inote.type = BYTE_GET (external->type);
21712 inote.namesz = BYTE_GET (external->namesz);
21713 inote.namedata = external->name;
21714 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21715 inote.descdata = ((char *) external
4dff97b2 21716 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21717 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21718 next = ((char *) external
4dff97b2 21719 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21720 }
00e98fc7 21721 else
15b42fb0
AM
21722 {
21723 Elf64_External_VMS_Note *vms_external;
00e98fc7 21724
9dd3a467
NC
21725 /* PR binutils/15191
21726 Make sure that there is enough data to read. */
15b42fb0
AM
21727 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21728 if (data_remaining < min_notesz)
9dd3a467 21729 {
d3a49aa8
AM
21730 warn (ngettext ("Corrupt note: only %ld byte remains, "
21731 "not enough for a full note\n",
21732 "Corrupt note: only %ld bytes remain, "
21733 "not enough for a full note\n",
21734 data_remaining),
21735 (long) data_remaining);
9dd3a467
NC
21736 break;
21737 }
5396a86e 21738 data_remaining -= min_notesz;
3e55a963 21739
15b42fb0
AM
21740 vms_external = (Elf64_External_VMS_Note *) external;
21741 inote.type = BYTE_GET (vms_external->type);
21742 inote.namesz = BYTE_GET (vms_external->namesz);
21743 inote.namedata = vms_external->name;
21744 inote.descsz = BYTE_GET (vms_external->descsz);
21745 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21746 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21747 next = inote.descdata + align_power (inote.descsz, 3);
21748 }
21749
5396a86e
AM
21750 /* PR 17531: file: 3443835e. */
21751 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21752 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21753 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21754 || (size_t) (next - inote.descdata) < inote.descsz
21755 || ((size_t) (next - inote.descdata)
21756 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21757 {
15b42fb0 21758 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 21759 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
21760 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
21761 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21762 break;
21763 }
21764
15b42fb0 21765 external = (Elf_External_Note *) next;
dd24e3da 21766
6d118b09
NC
21767 /* Verify that name is null terminated. It appears that at least
21768 one version of Linux (RedHat 6.0) generates corefiles that don't
21769 comply with the ELF spec by failing to include the null byte in
21770 namesz. */
18344509 21771 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21772 {
5396a86e 21773 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21774 {
5396a86e
AM
21775 temp = (char *) malloc (inote.namesz + 1);
21776 if (temp == NULL)
21777 {
21778 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21779 res = false;
5396a86e
AM
21780 break;
21781 }
76da6bbe 21782
5396a86e
AM
21783 memcpy (temp, inote.namedata, inote.namesz);
21784 inote.namedata = temp;
21785 }
21786 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21787 }
21788
dda8d76d 21789 if (! process_note (& inote, filedata))
015dc7e1 21790 res = false;
103f02d3 21791
9db70fc3
AM
21792 free (temp);
21793 temp = NULL;
779fe533
NC
21794 }
21795
21796 free (pnotes);
103f02d3 21797
779fe533
NC
21798 return res;
21799}
21800
015dc7e1 21801static bool
dda8d76d 21802process_corefile_note_segments (Filedata * filedata)
779fe533 21803{
015dc7e1 21804 Elf_Internal_Phdr *segment;
b34976b6 21805 unsigned int i;
015dc7e1 21806 bool res = true;
103f02d3 21807
dda8d76d 21808 if (! get_program_headers (filedata))
015dc7e1 21809 return true;
103f02d3 21810
dda8d76d
NC
21811 for (i = 0, segment = filedata->program_headers;
21812 i < filedata->file_header.e_phnum;
b34976b6 21813 i++, segment++)
779fe533
NC
21814 {
21815 if (segment->p_type == PT_NOTE)
625d49fc
AM
21816 if (! process_notes_at (filedata, NULL, segment->p_offset,
21817 segment->p_filesz, segment->p_align))
015dc7e1 21818 res = false;
779fe533 21819 }
103f02d3 21820
779fe533
NC
21821 return res;
21822}
21823
015dc7e1 21824static bool
625d49fc 21825process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
21826{
21827 Elf_External_Note * pnotes;
21828 Elf_External_Note * external;
c8071705 21829 char * end;
015dc7e1 21830 bool res = true;
685080f2
NC
21831
21832 if (length <= 0)
015dc7e1 21833 return false;
685080f2 21834
dda8d76d 21835 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21836 _("v850 notes"));
21837 if (pnotes == NULL)
015dc7e1 21838 return false;
685080f2
NC
21839
21840 external = pnotes;
c8071705 21841 end = (char*) pnotes + length;
685080f2
NC
21842
21843 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21844 (unsigned long) offset, (unsigned long) length);
21845
c8071705 21846 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21847 {
21848 Elf_External_Note * next;
21849 Elf_Internal_Note inote;
21850
21851 inote.type = BYTE_GET (external->type);
21852 inote.namesz = BYTE_GET (external->namesz);
21853 inote.namedata = external->name;
21854 inote.descsz = BYTE_GET (external->descsz);
21855 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21856 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21857
c8071705
NC
21858 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21859 {
21860 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21861 inote.descdata = inote.namedata;
21862 inote.namesz = 0;
21863 }
21864
685080f2
NC
21865 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21866
c8071705 21867 if ( ((char *) next > end)
685080f2
NC
21868 || ((char *) next < (char *) pnotes))
21869 {
21870 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21871 (unsigned long) ((char *) external - (char *) pnotes));
21872 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21873 inote.type, inote.namesz, inote.descsz);
21874 break;
21875 }
21876
21877 external = next;
21878
21879 /* Prevent out-of-bounds indexing. */
c8071705 21880 if ( inote.namedata + inote.namesz > end
685080f2
NC
21881 || inote.namedata + inote.namesz < inote.namedata)
21882 {
21883 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21884 (unsigned long) ((char *) external - (char *) pnotes));
21885 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21886 inote.type, inote.namesz, inote.descsz);
21887 break;
21888 }
21889
21890 printf (" %s: ", get_v850_elf_note_type (inote.type));
21891
21892 if (! print_v850_note (& inote))
21893 {
015dc7e1 21894 res = false;
685080f2
NC
21895 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21896 inote.namesz, inote.descsz);
21897 }
21898 }
21899
21900 free (pnotes);
21901
21902 return res;
21903}
21904
015dc7e1 21905static bool
dda8d76d 21906process_note_sections (Filedata * filedata)
1ec5cd37 21907{
015dc7e1 21908 Elf_Internal_Shdr *section;
1ec5cd37 21909 unsigned long i;
32ec8896 21910 unsigned int n = 0;
015dc7e1 21911 bool res = true;
1ec5cd37 21912
dda8d76d
NC
21913 for (i = 0, section = filedata->section_headers;
21914 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21915 i++, section++)
685080f2
NC
21916 {
21917 if (section->sh_type == SHT_NOTE)
21918 {
625d49fc
AM
21919 if (! process_notes_at (filedata, section, section->sh_offset,
21920 section->sh_size, section->sh_addralign))
015dc7e1 21921 res = false;
685080f2
NC
21922 n++;
21923 }
21924
dda8d76d
NC
21925 if (( filedata->file_header.e_machine == EM_V800
21926 || filedata->file_header.e_machine == EM_V850
21927 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21928 && section->sh_type == SHT_RENESAS_INFO)
21929 {
625d49fc
AM
21930 if (! process_v850_notes (filedata, section->sh_offset,
21931 section->sh_size))
015dc7e1 21932 res = false;
685080f2
NC
21933 n++;
21934 }
21935 }
df565f32
NC
21936
21937 if (n == 0)
21938 /* Try processing NOTE segments instead. */
dda8d76d 21939 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21940
21941 return res;
21942}
21943
015dc7e1 21944static bool
dda8d76d 21945process_notes (Filedata * filedata)
779fe533
NC
21946{
21947 /* If we have not been asked to display the notes then do nothing. */
21948 if (! do_notes)
015dc7e1 21949 return true;
103f02d3 21950
dda8d76d
NC
21951 if (filedata->file_header.e_type != ET_CORE)
21952 return process_note_sections (filedata);
103f02d3 21953
779fe533 21954 /* No program headers means no NOTE segment. */
dda8d76d
NC
21955 if (filedata->file_header.e_phnum > 0)
21956 return process_corefile_note_segments (filedata);
779fe533 21957
ca0e11aa
NC
21958 if (filedata->is_separate)
21959 printf (_("No notes found in linked file '%s'.\n"),
21960 filedata->file_name);
21961 else
21962 printf (_("No notes found file.\n"));
21963
015dc7e1 21964 return true;
779fe533
NC
21965}
21966
60abdbed
NC
21967static unsigned char *
21968display_public_gnu_attributes (unsigned char * start,
21969 const unsigned char * const end)
21970{
21971 printf (_(" Unknown GNU attribute: %s\n"), start);
21972
21973 start += strnlen ((char *) start, end - start);
21974 display_raw_attribute (start, end);
21975
21976 return (unsigned char *) end;
21977}
21978
21979static unsigned char *
21980display_generic_attribute (unsigned char * start,
21981 unsigned int tag,
21982 const unsigned char * const end)
21983{
21984 if (tag == 0)
21985 return (unsigned char *) end;
21986
21987 return display_tag_value (tag, start, end);
21988}
21989
015dc7e1 21990static bool
dda8d76d 21991process_arch_specific (Filedata * filedata)
252b5132 21992{
a952a375 21993 if (! do_arch)
015dc7e1 21994 return true;
a952a375 21995
dda8d76d 21996 switch (filedata->file_header.e_machine)
252b5132 21997 {
53a346d8
CZ
21998 case EM_ARC:
21999 case EM_ARC_COMPACT:
22000 case EM_ARC_COMPACT2:
dda8d76d 22001 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
22002 display_arc_attribute,
22003 display_generic_attribute);
11c1ff18 22004 case EM_ARM:
dda8d76d 22005 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
22006 display_arm_attribute,
22007 display_generic_attribute);
22008
252b5132 22009 case EM_MIPS:
4fe85591 22010 case EM_MIPS_RS3_LE:
dda8d76d 22011 return process_mips_specific (filedata);
60abdbed
NC
22012
22013 case EM_MSP430:
dda8d76d 22014 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 22015 display_msp430_attribute,
c0ea7c52 22016 display_msp430_gnu_attribute);
60abdbed 22017
2dc8dd17
JW
22018 case EM_RISCV:
22019 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22020 display_riscv_attribute,
22021 display_generic_attribute);
22022
35c08157 22023 case EM_NDS32:
dda8d76d 22024 return process_nds32_specific (filedata);
60abdbed 22025
85f7484a
PB
22026 case EM_68K:
22027 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22028 display_m68k_gnu_attribute);
22029
34c8bcba 22030 case EM_PPC:
b82317dd 22031 case EM_PPC64:
dda8d76d 22032 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22033 display_power_gnu_attribute);
22034
643f7afb
AK
22035 case EM_S390:
22036 case EM_S390_OLD:
dda8d76d 22037 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22038 display_s390_gnu_attribute);
22039
9e8c70f9
DM
22040 case EM_SPARC:
22041 case EM_SPARC32PLUS:
22042 case EM_SPARCV9:
dda8d76d 22043 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22044 display_sparc_gnu_attribute);
22045
59e6276b 22046 case EM_TI_C6000:
dda8d76d 22047 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22048 display_tic6x_attribute,
22049 display_generic_attribute);
22050
0861f561
CQ
22051 case EM_CSKY:
22052 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22053 display_csky_attribute, NULL);
22054
252b5132 22055 default:
dda8d76d 22056 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22057 display_public_gnu_attributes,
22058 display_generic_attribute);
252b5132 22059 }
252b5132
RH
22060}
22061
015dc7e1 22062static bool
dda8d76d 22063get_file_header (Filedata * filedata)
252b5132 22064{
9ea033b2 22065 /* Read in the identity array. */
dda8d76d 22066 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22067 return false;
252b5132 22068
9ea033b2 22069 /* Determine how to read the rest of the header. */
dda8d76d 22070 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22071 {
1a0670f3
AM
22072 default:
22073 case ELFDATANONE:
adab8cdc
AO
22074 case ELFDATA2LSB:
22075 byte_get = byte_get_little_endian;
22076 byte_put = byte_put_little_endian;
22077 break;
22078 case ELFDATA2MSB:
22079 byte_get = byte_get_big_endian;
22080 byte_put = byte_put_big_endian;
22081 break;
9ea033b2
NC
22082 }
22083
22084 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22085 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22086
22087 /* Read in the rest of the header. */
22088 if (is_32bit_elf)
22089 {
22090 Elf32_External_Ehdr ehdr32;
252b5132 22091
dda8d76d 22092 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22093 return false;
103f02d3 22094
dda8d76d
NC
22095 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22096 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22097 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22098 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22099 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22100 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22101 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22102 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22103 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22104 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22105 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22106 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22107 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22108 }
252b5132 22109 else
9ea033b2
NC
22110 {
22111 Elf64_External_Ehdr ehdr64;
a952a375 22112
dda8d76d 22113 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22114 return false;
103f02d3 22115
dda8d76d
NC
22116 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22117 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22118 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22119 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22120 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22121 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22122 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22123 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22124 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22125 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22126 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22127 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22128 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22129 }
252b5132 22130
015dc7e1 22131 return true;
252b5132
RH
22132}
22133
13acb58d
AM
22134static void
22135free_filedata (Filedata *filedata)
22136{
22137 free (filedata->program_interpreter);
13acb58d 22138 free (filedata->program_headers);
13acb58d 22139 free (filedata->section_headers);
13acb58d 22140 free (filedata->string_table);
13acb58d 22141 free (filedata->dump.dump_sects);
13acb58d 22142 free (filedata->dynamic_strings);
13acb58d 22143 free (filedata->dynamic_symbols);
13acb58d 22144 free (filedata->dynamic_syminfo);
13acb58d 22145 free (filedata->dynamic_section);
13acb58d
AM
22146
22147 while (filedata->symtab_shndx_list != NULL)
22148 {
22149 elf_section_list *next = filedata->symtab_shndx_list->next;
22150 free (filedata->symtab_shndx_list);
22151 filedata->symtab_shndx_list = next;
22152 }
22153
22154 free (filedata->section_headers_groups);
13acb58d
AM
22155
22156 if (filedata->section_groups)
22157 {
22158 size_t i;
22159 struct group_list * g;
22160 struct group_list * next;
22161
22162 for (i = 0; i < filedata->group_count; i++)
22163 {
22164 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22165 {
22166 next = g->next;
22167 free (g);
22168 }
22169 }
22170
22171 free (filedata->section_groups);
13acb58d 22172 }
066f8fbe
AM
22173 memset (&filedata->section_headers, 0,
22174 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22175}
22176
dda8d76d
NC
22177static void
22178close_file (Filedata * filedata)
22179{
22180 if (filedata)
22181 {
22182 if (filedata->handle)
22183 fclose (filedata->handle);
22184 free (filedata);
22185 }
22186}
22187
22188void
22189close_debug_file (void * data)
22190{
13acb58d 22191 free_filedata ((Filedata *) data);
dda8d76d
NC
22192 close_file ((Filedata *) data);
22193}
22194
22195static Filedata *
015dc7e1 22196open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22197{
22198 struct stat statbuf;
22199 Filedata * filedata = NULL;
22200
22201 if (stat (pathname, & statbuf) < 0
22202 || ! S_ISREG (statbuf.st_mode))
22203 goto fail;
22204
22205 filedata = calloc (1, sizeof * filedata);
22206 if (filedata == NULL)
22207 goto fail;
22208
22209 filedata->handle = fopen (pathname, "rb");
22210 if (filedata->handle == NULL)
22211 goto fail;
22212
be7d229a 22213 filedata->file_size = statbuf.st_size;
dda8d76d 22214 filedata->file_name = pathname;
ca0e11aa 22215 filedata->is_separate = is_separate;
dda8d76d
NC
22216
22217 if (! get_file_header (filedata))
22218 goto fail;
22219
4de91c10
AM
22220 if (!get_section_headers (filedata, false))
22221 goto fail;
dda8d76d
NC
22222
22223 return filedata;
22224
22225 fail:
22226 if (filedata)
22227 {
22228 if (filedata->handle)
22229 fclose (filedata->handle);
22230 free (filedata);
22231 }
22232 return NULL;
22233}
22234
22235void *
22236open_debug_file (const char * pathname)
22237{
015dc7e1 22238 return open_file (pathname, true);
dda8d76d
NC
22239}
22240
835f2fae
NC
22241static void
22242initialise_dump_sects (Filedata * filedata)
22243{
22244 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22245 Note we do this even if cmdline_dump_sects is empty because we
22246 must make sure that the dump_sets array is zeroed out before each
22247 object file is processed. */
22248 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22249 memset (filedata->dump.dump_sects, 0,
22250 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22251
22252 if (cmdline.num_dump_sects > 0)
22253 {
22254 if (filedata->dump.num_dump_sects == 0)
22255 /* A sneaky way of allocating the dump_sects array. */
22256 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22257
22258 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22259 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22260 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22261 }
22262}
22263
94585d6d
NC
22264static bool
22265might_need_separate_debug_info (Filedata * filedata)
22266{
22267 /* Debuginfo files do not need further separate file loading. */
22268 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22269 return false;
22270
22271 /* Since do_follow_links might be enabled by default, only treat it as an
22272 indication that separate files should be loaded if setting it was a
22273 deliberate user action. */
22274 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22275 return true;
22276
22277 if (process_links || do_syms || do_unwind
22278 || dump_any_debugging || do_dump || do_debugging)
22279 return true;
22280
22281 return false;
22282}
22283
fb52b2f4
NC
22284/* Process one ELF object file according to the command line options.
22285 This file may actually be stored in an archive. The file is
32ec8896
NC
22286 positioned at the start of the ELF object. Returns TRUE if no
22287 problems were encountered, FALSE otherwise. */
fb52b2f4 22288
015dc7e1 22289static bool
dda8d76d 22290process_object (Filedata * filedata)
252b5132 22291{
015dc7e1 22292 bool have_separate_files;
252b5132 22293 unsigned int i;
015dc7e1 22294 bool res;
252b5132 22295
dda8d76d 22296 if (! get_file_header (filedata))
252b5132 22297 {
dda8d76d 22298 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22299 return false;
252b5132
RH
22300 }
22301
22302 /* Initialise per file variables. */
978c4450
AM
22303 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22304 filedata->version_info[i] = 0;
252b5132 22305
978c4450
AM
22306 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22307 filedata->dynamic_info[i] = 0;
22308 filedata->dynamic_info_DT_GNU_HASH = 0;
22309 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22310
22311 /* Process the file. */
22312 if (show_name)
dda8d76d 22313 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22314
835f2fae 22315 initialise_dump_sects (filedata);
d70c5fc7 22316
4de91c10
AM
22317 /* There may be some extensions in the first section header. Don't
22318 bomb if we can't read it. */
22319 get_section_headers (filedata, true);
22320
dda8d76d 22321 if (! process_file_header (filedata))
4de91c10
AM
22322 {
22323 res = false;
22324 goto out;
22325 }
252b5132 22326
e331b18d
AM
22327 /* Throw away the single section header read above, so that we
22328 re-read the entire set. */
22329 free (filedata->section_headers);
22330 filedata->section_headers = NULL;
22331
dda8d76d 22332 if (! process_section_headers (filedata))
2f62977e 22333 {
32ec8896 22334 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22335 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22336
2f62977e 22337 if (! do_using_dynamic)
015dc7e1 22338 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22339 }
252b5132 22340
dda8d76d 22341 if (! process_section_groups (filedata))
32ec8896 22342 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22343 do_unwind = false;
d1f5c6e3 22344
93df3340
AM
22345 process_program_headers (filedata);
22346
22347 res = process_dynamic_section (filedata);
252b5132 22348
dda8d76d 22349 if (! process_relocs (filedata))
015dc7e1 22350 res = false;
252b5132 22351
dda8d76d 22352 if (! process_unwind (filedata))
015dc7e1 22353 res = false;
4d6ed7c8 22354
dda8d76d 22355 if (! process_symbol_table (filedata))
015dc7e1 22356 res = false;
252b5132 22357
0f03783c 22358 if (! process_lto_symbol_tables (filedata))
015dc7e1 22359 res = false;
b9e920ec 22360
dda8d76d 22361 if (! process_syminfo (filedata))
015dc7e1 22362 res = false;
252b5132 22363
dda8d76d 22364 if (! process_version_sections (filedata))
015dc7e1 22365 res = false;
252b5132 22366
94585d6d 22367 if (might_need_separate_debug_info (filedata))
24841daa 22368 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22369 else
015dc7e1 22370 have_separate_files = false;
dda8d76d
NC
22371
22372 if (! process_section_contents (filedata))
015dc7e1 22373 res = false;
f5842774 22374
24841daa 22375 if (have_separate_files)
dda8d76d 22376 {
24841daa
NC
22377 separate_info * d;
22378
22379 for (d = first_separate_info; d != NULL; d = d->next)
22380 {
835f2fae
NC
22381 initialise_dump_sects (d->handle);
22382
ca0e11aa 22383 if (process_links && ! process_file_header (d->handle))
015dc7e1 22384 res = false;
ca0e11aa 22385 else if (! process_section_headers (d->handle))
015dc7e1 22386 res = false;
d6bfbc39 22387 else if (! process_section_contents (d->handle))
015dc7e1 22388 res = false;
ca0e11aa
NC
22389 else if (process_links)
22390 {
ca0e11aa 22391 if (! process_section_groups (d->handle))
015dc7e1 22392 res = false;
93df3340 22393 process_program_headers (d->handle);
ca0e11aa 22394 if (! process_dynamic_section (d->handle))
015dc7e1 22395 res = false;
ca0e11aa 22396 if (! process_relocs (d->handle))
015dc7e1 22397 res = false;
ca0e11aa 22398 if (! process_unwind (d->handle))
015dc7e1 22399 res = false;
ca0e11aa 22400 if (! process_symbol_table (d->handle))
015dc7e1 22401 res = false;
ca0e11aa 22402 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22403 res = false;
ca0e11aa 22404 if (! process_syminfo (d->handle))
015dc7e1 22405 res = false;
ca0e11aa 22406 if (! process_version_sections (d->handle))
015dc7e1 22407 res = false;
ca0e11aa 22408 if (! process_notes (d->handle))
015dc7e1 22409 res = false;
ca0e11aa 22410 }
24841daa
NC
22411 }
22412
22413 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22414 }
22415
22416 if (! process_notes (filedata))
015dc7e1 22417 res = false;
103f02d3 22418
dda8d76d 22419 if (! process_gnu_liblist (filedata))
015dc7e1 22420 res = false;
047b2264 22421
dda8d76d 22422 if (! process_arch_specific (filedata))
015dc7e1 22423 res = false;
252b5132 22424
4de91c10 22425 out:
13acb58d 22426 free_filedata (filedata);
e4b17d5c 22427
19e6b90e 22428 free_debug_memory ();
18bd398b 22429
32ec8896 22430 return res;
252b5132
RH
22431}
22432
2cf0635d 22433/* Process an ELF archive.
32ec8896
NC
22434 On entry the file is positioned just after the ARMAG string.
22435 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22436
015dc7e1
AM
22437static bool
22438process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22439{
22440 struct archive_info arch;
22441 struct archive_info nested_arch;
22442 size_t got;
015dc7e1 22443 bool ret = true;
2cf0635d 22444
015dc7e1 22445 show_name = true;
2cf0635d
NC
22446
22447 /* The ARCH structure is used to hold information about this archive. */
22448 arch.file_name = NULL;
22449 arch.file = NULL;
22450 arch.index_array = NULL;
22451 arch.sym_table = NULL;
22452 arch.longnames = NULL;
22453
22454 /* The NESTED_ARCH structure is used as a single-item cache of information
22455 about a nested archive (when members of a thin archive reside within
22456 another regular archive file). */
22457 nested_arch.file_name = NULL;
22458 nested_arch.file = NULL;
22459 nested_arch.index_array = NULL;
22460 nested_arch.sym_table = NULL;
22461 nested_arch.longnames = NULL;
22462
dda8d76d 22463 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22464 filedata->file_size, is_thin_archive,
22465 do_archive_index) != 0)
2cf0635d 22466 {
015dc7e1 22467 ret = false;
2cf0635d 22468 goto out;
4145f1d5 22469 }
fb52b2f4 22470
4145f1d5
NC
22471 if (do_archive_index)
22472 {
2cf0635d 22473 if (arch.sym_table == NULL)
1cb7d8b1
AM
22474 error (_("%s: unable to dump the index as none was found\n"),
22475 filedata->file_name);
4145f1d5
NC
22476 else
22477 {
591f7597 22478 unsigned long i, l;
4145f1d5
NC
22479 unsigned long current_pos;
22480
1cb7d8b1
AM
22481 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
22482 "in the symbol table)\n"),
22483 filedata->file_name, (unsigned long) arch.index_num,
22484 arch.sym_size);
dda8d76d
NC
22485
22486 current_pos = ftell (filedata->handle);
4145f1d5 22487
2cf0635d 22488 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22489 {
1cb7d8b1
AM
22490 if (i == 0
22491 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22492 {
22493 char * member_name
22494 = get_archive_member_name_at (&arch, arch.index_array[i],
22495 &nested_arch);
2cf0635d 22496
1cb7d8b1
AM
22497 if (member_name != NULL)
22498 {
22499 char * qualified_name
22500 = make_qualified_name (&arch, &nested_arch,
22501 member_name);
2cf0635d 22502
1cb7d8b1
AM
22503 if (qualified_name != NULL)
22504 {
22505 printf (_("Contents of binary %s at offset "),
22506 qualified_name);
c2a7d3f5
NC
22507 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22508 putchar ('\n');
1cb7d8b1
AM
22509 free (qualified_name);
22510 }
fd486f32 22511 free (member_name);
4145f1d5
NC
22512 }
22513 }
2cf0635d
NC
22514
22515 if (l >= arch.sym_size)
4145f1d5 22516 {
1cb7d8b1
AM
22517 error (_("%s: end of the symbol table reached "
22518 "before the end of the index\n"),
dda8d76d 22519 filedata->file_name);
015dc7e1 22520 ret = false;
cb8f3167 22521 break;
4145f1d5 22522 }
591f7597 22523 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22524 printf ("\t%.*s\n",
22525 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22526 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22527 }
22528
67ce483b 22529 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22530 l = (l + 7) & ~ 7;
22531 else
22532 l += l & 1;
22533
2cf0635d 22534 if (l < arch.sym_size)
32ec8896 22535 {
d3a49aa8
AM
22536 error (ngettext ("%s: %ld byte remains in the symbol table, "
22537 "but without corresponding entries in "
22538 "the index table\n",
22539 "%s: %ld bytes remain in the symbol table, "
22540 "but without corresponding entries in "
22541 "the index table\n",
22542 arch.sym_size - l),
dda8d76d 22543 filedata->file_name, arch.sym_size - l);
015dc7e1 22544 ret = false;
32ec8896 22545 }
4145f1d5 22546
dda8d76d 22547 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22548 {
1cb7d8b1
AM
22549 error (_("%s: failed to seek back to start of object files "
22550 "in the archive\n"),
dda8d76d 22551 filedata->file_name);
015dc7e1 22552 ret = false;
2cf0635d 22553 goto out;
4145f1d5 22554 }
fb52b2f4 22555 }
4145f1d5
NC
22556
22557 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22558 && !do_segments && !do_header && !do_dump && !do_version
22559 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22560 && !do_section_groups && !do_dyn_syms)
2cf0635d 22561 {
015dc7e1 22562 ret = true; /* Archive index only. */
2cf0635d
NC
22563 goto out;
22564 }
fb52b2f4
NC
22565 }
22566
fb52b2f4
NC
22567 while (1)
22568 {
2cf0635d
NC
22569 char * name;
22570 size_t namelen;
22571 char * qualified_name;
22572
22573 /* Read the next archive header. */
dda8d76d 22574 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22575 {
22576 error (_("%s: failed to seek to next archive header\n"),
22577 arch.file_name);
015dc7e1 22578 ret = false;
1cb7d8b1
AM
22579 break;
22580 }
dda8d76d 22581 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22582 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22583 {
22584 if (got == 0)
2cf0635d 22585 break;
28e817cc
NC
22586 /* PR 24049 - we cannot use filedata->file_name as this will
22587 have already been freed. */
22588 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22589
015dc7e1 22590 ret = false;
1cb7d8b1
AM
22591 break;
22592 }
2cf0635d 22593 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22594 {
22595 error (_("%s: did not find a valid archive header\n"),
22596 arch.file_name);
015dc7e1 22597 ret = false;
1cb7d8b1
AM
22598 break;
22599 }
2cf0635d
NC
22600
22601 arch.next_arhdr_offset += sizeof arch.arhdr;
22602
978c4450 22603 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22604
22605 name = get_archive_member_name (&arch, &nested_arch);
22606 if (name == NULL)
fb52b2f4 22607 {
28e817cc 22608 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22609 ret = false;
d989285c 22610 break;
fb52b2f4 22611 }
2cf0635d 22612 namelen = strlen (name);
fb52b2f4 22613
2cf0635d
NC
22614 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22615 if (qualified_name == NULL)
fb52b2f4 22616 {
28e817cc 22617 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22618 free (name);
015dc7e1 22619 ret = false;
d989285c 22620 break;
fb52b2f4
NC
22621 }
22622
2cf0635d 22623 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22624 {
22625 /* This is a proxy for an external member of a thin archive. */
22626 Filedata * member_filedata;
22627 char * member_file_name = adjust_relative_path
dda8d76d 22628 (filedata->file_name, name, namelen);
32ec8896 22629
fd486f32 22630 free (name);
1cb7d8b1
AM
22631 if (member_file_name == NULL)
22632 {
fd486f32 22633 free (qualified_name);
015dc7e1 22634 ret = false;
1cb7d8b1
AM
22635 break;
22636 }
2cf0635d 22637
015dc7e1 22638 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22639 if (member_filedata == NULL)
22640 {
22641 error (_("Input file '%s' is not readable.\n"), member_file_name);
22642 free (member_file_name);
fd486f32 22643 free (qualified_name);
015dc7e1 22644 ret = false;
1cb7d8b1
AM
22645 break;
22646 }
2cf0635d 22647
978c4450 22648 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22649 member_filedata->file_name = qualified_name;
2cf0635d 22650
75a2da57
AH
22651 /* The call to process_object() expects the file to be at the beginning. */
22652 rewind (member_filedata->handle);
22653
1cb7d8b1 22654 if (! process_object (member_filedata))
015dc7e1 22655 ret = false;
2cf0635d 22656
1cb7d8b1
AM
22657 close_file (member_filedata);
22658 free (member_file_name);
1cb7d8b1 22659 }
2cf0635d 22660 else if (is_thin_archive)
1cb7d8b1
AM
22661 {
22662 Filedata thin_filedata;
eb02c04d 22663
1cb7d8b1 22664 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22665
a043396b
NC
22666 /* PR 15140: Allow for corrupt thin archives. */
22667 if (nested_arch.file == NULL)
22668 {
22669 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22670 qualified_name, name);
fd486f32
AM
22671 free (qualified_name);
22672 free (name);
015dc7e1 22673 ret = false;
a043396b
NC
22674 break;
22675 }
fd486f32 22676 free (name);
a043396b 22677
1cb7d8b1 22678 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22679 filedata->archive_file_offset
22680 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22681
1cb7d8b1
AM
22682 /* The nested archive file will have been opened and setup by
22683 get_archive_member_name. */
978c4450
AM
22684 if (fseek (nested_arch.file, filedata->archive_file_offset,
22685 SEEK_SET) != 0)
1cb7d8b1
AM
22686 {
22687 error (_("%s: failed to seek to archive member.\n"),
22688 nested_arch.file_name);
fd486f32 22689 free (qualified_name);
015dc7e1 22690 ret = false;
1cb7d8b1
AM
22691 break;
22692 }
2cf0635d 22693
dda8d76d
NC
22694 thin_filedata.handle = nested_arch.file;
22695 thin_filedata.file_name = qualified_name;
9abca702 22696
1cb7d8b1 22697 if (! process_object (& thin_filedata))
015dc7e1 22698 ret = false;
1cb7d8b1 22699 }
2cf0635d 22700 else
1cb7d8b1 22701 {
fd486f32 22702 free (name);
978c4450 22703 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22704 filedata->file_name = qualified_name;
1cb7d8b1 22705 if (! process_object (filedata))
015dc7e1 22706 ret = false;
237877b8 22707 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22708 /* Stop looping with "negative" archive_file_size. */
978c4450 22709 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22710 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22711 }
fb52b2f4 22712
2cf0635d 22713 free (qualified_name);
fb52b2f4
NC
22714 }
22715
4145f1d5 22716 out:
2cf0635d
NC
22717 if (nested_arch.file != NULL)
22718 fclose (nested_arch.file);
22719 release_archive (&nested_arch);
22720 release_archive (&arch);
fb52b2f4 22721
d989285c 22722 return ret;
fb52b2f4
NC
22723}
22724
015dc7e1 22725static bool
2cf0635d 22726process_file (char * file_name)
fb52b2f4 22727{
dda8d76d 22728 Filedata * filedata = NULL;
fb52b2f4
NC
22729 struct stat statbuf;
22730 char armag[SARMAG];
015dc7e1 22731 bool ret = true;
fb52b2f4
NC
22732
22733 if (stat (file_name, &statbuf) < 0)
22734 {
f24ddbdd
NC
22735 if (errno == ENOENT)
22736 error (_("'%s': No such file\n"), file_name);
22737 else
22738 error (_("Could not locate '%s'. System error message: %s\n"),
22739 file_name, strerror (errno));
015dc7e1 22740 return false;
f24ddbdd
NC
22741 }
22742
22743 if (! S_ISREG (statbuf.st_mode))
22744 {
22745 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22746 return false;
fb52b2f4
NC
22747 }
22748
dda8d76d
NC
22749 filedata = calloc (1, sizeof * filedata);
22750 if (filedata == NULL)
22751 {
22752 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22753 return false;
dda8d76d
NC
22754 }
22755
22756 filedata->file_name = file_name;
22757 filedata->handle = fopen (file_name, "rb");
22758 if (filedata->handle == NULL)
fb52b2f4 22759 {
f24ddbdd 22760 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22761 free (filedata);
015dc7e1 22762 return false;
fb52b2f4
NC
22763 }
22764
dda8d76d 22765 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22766 {
4145f1d5 22767 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22768 fclose (filedata->handle);
22769 free (filedata);
015dc7e1 22770 return false;
fb52b2f4
NC
22771 }
22772
be7d229a 22773 filedata->file_size = statbuf.st_size;
015dc7e1 22774 filedata->is_separate = false;
f54498b4 22775
fb52b2f4 22776 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22777 {
015dc7e1
AM
22778 if (! process_archive (filedata, false))
22779 ret = false;
32ec8896 22780 }
2cf0635d 22781 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22782 {
015dc7e1
AM
22783 if ( ! process_archive (filedata, true))
22784 ret = false;
32ec8896 22785 }
fb52b2f4
NC
22786 else
22787 {
1b513401 22788 if (do_archive_index && !check_all)
4145f1d5
NC
22789 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22790 file_name);
22791
dda8d76d 22792 rewind (filedata->handle);
978c4450 22793 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22794
dda8d76d 22795 if (! process_object (filedata))
015dc7e1 22796 ret = false;
fb52b2f4
NC
22797 }
22798
dda8d76d 22799 fclose (filedata->handle);
8fb879cd
AM
22800 free (filedata->section_headers);
22801 free (filedata->program_headers);
22802 free (filedata->string_table);
6431e409 22803 free (filedata->dump.dump_sects);
dda8d76d 22804 free (filedata);
32ec8896 22805
fd486f32 22806 free (ba_cache.strtab);
1bd6175a 22807 ba_cache.strtab = NULL;
fd486f32 22808 free (ba_cache.symtab);
1bd6175a 22809 ba_cache.symtab = NULL;
fd486f32
AM
22810 ba_cache.filedata = NULL;
22811
fb52b2f4
NC
22812 return ret;
22813}
22814
252b5132
RH
22815#ifdef SUPPORT_DISASSEMBLY
22816/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22817 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22818 symbols. */
252b5132
RH
22819
22820void
2cf0635d 22821print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22822{
22823 fprintf (outfile,"0x%8.8x", addr);
22824}
22825
e3c8793a 22826/* Needed by the i386 disassembler. */
dda8d76d 22827
252b5132
RH
22828void
22829db_task_printsym (unsigned int addr)
22830{
22831 print_address (addr, stderr);
22832}
22833#endif
22834
22835int
2cf0635d 22836main (int argc, char ** argv)
252b5132 22837{
ff78d6d6
L
22838 int err;
22839
87b9f255 22840#ifdef HAVE_LC_MESSAGES
252b5132 22841 setlocale (LC_MESSAGES, "");
3882b010 22842#endif
3882b010 22843 setlocale (LC_CTYPE, "");
252b5132
RH
22844 bindtextdomain (PACKAGE, LOCALEDIR);
22845 textdomain (PACKAGE);
22846
869b9d07
MM
22847 expandargv (&argc, &argv);
22848
dda8d76d 22849 parse_args (& cmdline, argc, argv);
59f14fc0 22850
18bd398b 22851 if (optind < (argc - 1))
1b513401
NC
22852 /* When displaying information for more than one file,
22853 prefix the information with the file name. */
015dc7e1 22854 show_name = true;
5656ba2c
L
22855 else if (optind >= argc)
22856 {
1b513401 22857 /* Ensure that the warning is always displayed. */
015dc7e1 22858 do_checks = true;
1b513401 22859
5656ba2c
L
22860 warn (_("Nothing to do.\n"));
22861 usage (stderr);
22862 }
18bd398b 22863
015dc7e1 22864 err = false;
252b5132 22865 while (optind < argc)
32ec8896 22866 if (! process_file (argv[optind++]))
015dc7e1 22867 err = true;
252b5132 22868
9db70fc3 22869 free (cmdline.dump_sects);
252b5132 22870
7d9813f1
NA
22871 free (dump_ctf_symtab_name);
22872 free (dump_ctf_strtab_name);
22873 free (dump_ctf_parent_name);
22874
32ec8896 22875 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22876}