]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
bpf: include, bfd, opcodes: add EF_BPF_CPUVER ELF header flags
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
d87bef3a 2 Copyright (C) 1998-2023 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"
42b6953b 66#include "sframe-api.h"
79bc120c 67#include "demangle.h"
252b5132
RH
68
69#include "elf/common.h"
70#include "elf/external.h"
71#include "elf/internal.h"
252b5132 72
4b78141a
NC
73
74/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
75 we can obtain the H8 reloc numbers. We need these for the
76 get_reloc_size() function. We include h8.h again after defining
77 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
78
79#include "elf/h8.h"
80#undef _ELF_H8_H
81
82/* Undo the effects of #including reloc-macros.h. */
83
84#undef START_RELOC_NUMBERS
85#undef RELOC_NUMBER
86#undef FAKE_RELOC
87#undef EMPTY_RELOC
88#undef END_RELOC_NUMBERS
89#undef _RELOC_MACROS_H
90
252b5132
RH
91/* The following headers use the elf/reloc-macros.h file to
92 automatically generate relocation recognition functions
93 such as elf_mips_reloc_type() */
94
95#define RELOC_MACROS_GEN_FUNC
96
a06ea964 97#include "elf/aarch64.h"
252b5132 98#include "elf/alpha.h"
c077c580 99#include "elf/amdgpu.h"
3b16e843 100#include "elf/arc.h"
252b5132 101#include "elf/arm.h"
3b16e843 102#include "elf/avr.h"
1d65ded4 103#include "elf/bfin.h"
60bca95a 104#include "elf/cr16.h"
3b16e843 105#include "elf/cris.h"
1c0d3aa6 106#include "elf/crx.h"
b8891f8d 107#include "elf/csky.h"
252b5132
RH
108#include "elf/d10v.h"
109#include "elf/d30v.h"
d172d4ba 110#include "elf/dlx.h"
aca4efc7 111#include "elf/bpf.h"
cfb8c092 112#include "elf/epiphany.h"
252b5132 113#include "elf/fr30.h"
5c70f934 114#include "elf/frv.h"
3f8107ab 115#include "elf/ft32.h"
3b16e843
NC
116#include "elf/h8.h"
117#include "elf/hppa.h"
118#include "elf/i386.h"
f954747f
AM
119#include "elf/i370.h"
120#include "elf/i860.h"
121#include "elf/i960.h"
3b16e843 122#include "elf/ia64.h"
1e4cf259 123#include "elf/ip2k.h"
84e94c90 124#include "elf/lm32.h"
1c0d3aa6 125#include "elf/iq2000.h"
49f58d10 126#include "elf/m32c.h"
3b16e843
NC
127#include "elf/m32r.h"
128#include "elf/m68k.h"
75751cd9 129#include "elf/m68hc11.h"
7b4ae824 130#include "elf/s12z.h"
252b5132 131#include "elf/mcore.h"
15ab5209 132#include "elf/mep.h"
a3c62988 133#include "elf/metag.h"
7ba29e2a 134#include "elf/microblaze.h"
3b16e843 135#include "elf/mips.h"
3c3bdf30 136#include "elf/mmix.h"
3b16e843
NC
137#include "elf/mn10200.h"
138#include "elf/mn10300.h"
5506d11a 139#include "elf/moxie.h"
4970f871 140#include "elf/mt.h"
2469cfa2 141#include "elf/msp430.h"
35c08157 142#include "elf/nds32.h"
fe944acf 143#include "elf/nfp.h"
13761a11 144#include "elf/nios2.h"
73589c9d 145#include "elf/or1k.h"
7d466069 146#include "elf/pj.h"
3b16e843 147#include "elf/ppc.h"
c833c019 148#include "elf/ppc64.h"
2b100bb5 149#include "elf/pru.h"
03336641 150#include "elf/riscv.h"
99c513f6 151#include "elf/rl78.h"
c7927a3c 152#include "elf/rx.h"
a85d7ed0 153#include "elf/s390.h"
1c0d3aa6 154#include "elf/score.h"
3b16e843
NC
155#include "elf/sh.h"
156#include "elf/sparc.h"
e9f53129 157#include "elf/spu.h"
40b36596 158#include "elf/tic6x.h"
aa137e4d
NC
159#include "elf/tilegx.h"
160#include "elf/tilepro.h"
3b16e843 161#include "elf/v850.h"
179d3252 162#include "elf/vax.h"
619ed720 163#include "elf/visium.h"
f96bd6c2 164#include "elf/wasm32.h"
3b16e843 165#include "elf/x86-64.h"
f6c1a2d5 166#include "elf/xgate.h"
93fbbb04 167#include "elf/xstormy16.h"
88da6820 168#include "elf/xtensa.h"
6655dba2 169#include "elf/z80.h"
e9a0721f 170#include "elf/loongarch.h"
1e18ffc9 171#include "elf/bpf.h"
252b5132 172
252b5132 173#include "getopt.h"
566b0d53 174#include "libiberty.h"
09c11c86 175#include "safe-ctype.h"
2cf0635d 176#include "filenames.h"
252b5132 177
15b42fb0
AM
178#ifndef offsetof
179#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
180#endif
181
6a40cf0c
NC
182typedef struct elf_section_list
183{
dda8d76d
NC
184 Elf_Internal_Shdr * hdr;
185 struct elf_section_list * next;
6a40cf0c
NC
186} elf_section_list;
187
dda8d76d
NC
188/* Flag bits indicating particular types of dump. */
189#define HEX_DUMP (1 << 0) /* The -x command line switch. */
190#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
191#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
192#define STRING_DUMP (1 << 3) /* The -p command line switch. */
193#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 194#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
42b6953b 195#define SFRAME_DUMP (1 << 6) /* The --sframe command line switch. */
dda8d76d
NC
196
197typedef unsigned char dump_type;
198
199/* A linked list of the section names for which dumps were requested. */
200struct dump_list_entry
201{
202 char * name;
203 dump_type type;
204 struct dump_list_entry * next;
205};
206
6431e409
AM
207/* A dynamic array of flags indicating for which sections a dump
208 has been requested via command line switches. */
1b513401
NC
209struct dump_data
210{
6431e409
AM
211 dump_type * dump_sects;
212 unsigned int num_dump_sects;
213};
214
215static struct dump_data cmdline;
216
217static struct dump_list_entry * dump_sects_byname;
218
2cf0635d 219char * program_name = "readelf";
dda8d76d 220
015dc7e1
AM
221static bool show_name = false;
222static bool do_dynamic = false;
223static bool do_syms = false;
224static bool do_dyn_syms = false;
225static bool do_lto_syms = false;
226static bool do_reloc = false;
227static bool do_sections = false;
228static bool do_section_groups = false;
229static bool do_section_details = false;
230static bool do_segments = false;
231static bool do_unwind = false;
232static bool do_using_dynamic = false;
233static bool do_header = false;
234static bool do_dump = false;
235static bool do_version = false;
236static bool do_histogram = false;
237static bool do_debugging = false;
238static bool do_ctf = false;
42b6953b 239static bool do_sframe = false;
015dc7e1
AM
240static bool do_arch = false;
241static bool do_notes = false;
242static bool do_archive_index = false;
243static bool check_all = false;
244static bool is_32bit_elf = false;
245static bool decompress_dumps = false;
246static bool do_not_show_symbol_truncation = false;
247static bool do_demangle = false; /* Pretty print C++ symbol names. */
248static bool process_links = false;
e1dbfc17 249static bool dump_any_debugging = false;
79bc120c 250static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 251static int sym_base = 0;
252b5132 252
7d9813f1
NA
253static char *dump_ctf_parent_name;
254static char *dump_ctf_symtab_name;
255static char *dump_ctf_strtab_name;
256
e4b17d5c
L
257struct group_list
258{
dda8d76d
NC
259 struct group_list * next;
260 unsigned int section_index;
e4b17d5c
L
261};
262
263struct group
264{
dda8d76d
NC
265 struct group_list * root;
266 unsigned int group_index;
e4b17d5c
L
267};
268
978c4450
AM
269typedef struct filedata
270{
271 const char * file_name;
015dc7e1 272 bool is_separate;
978c4450 273 FILE * handle;
be7d229a 274 uint64_t file_size;
978c4450 275 Elf_Internal_Ehdr file_header;
26c527e6
AM
276 uint64_t archive_file_offset;
277 uint64_t archive_file_size;
066f8fbe 278 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
279 Elf_Internal_Shdr * section_headers;
280 Elf_Internal_Phdr * program_headers;
281 char * string_table;
26c527e6
AM
282 uint64_t string_table_length;
283 uint64_t dynamic_addr;
be7d229a 284 uint64_t dynamic_size;
26c527e6 285 uint64_t dynamic_nent;
978c4450 286 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 287 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450 288 char * dynamic_strings;
26c527e6 289 uint64_t dynamic_strings_length;
8ac10c5b 290 Elf_Internal_Shdr * dynamic_symtab_section;
26c527e6 291 uint64_t num_dynamic_syms;
978c4450 292 Elf_Internal_Sym * dynamic_symbols;
26c527e6 293 uint64_t version_info[16];
978c4450
AM
294 unsigned int dynamic_syminfo_nent;
295 Elf_Internal_Syminfo * dynamic_syminfo;
26c527e6 296 uint64_t dynamic_syminfo_offset;
be7d229a
AM
297 uint64_t nbuckets;
298 uint64_t nchains;
625d49fc
AM
299 uint64_t * buckets;
300 uint64_t * chains;
be7d229a
AM
301 uint64_t ngnubuckets;
302 uint64_t ngnuchains;
625d49fc
AM
303 uint64_t * gnubuckets;
304 uint64_t * gnuchains;
305 uint64_t * mipsxlat;
306 uint64_t gnusymidx;
13acb58d 307 char * program_interpreter;
bc227f4c 308 uint64_t dynamic_info[DT_RELRENT + 1];
625d49fc
AM
309 uint64_t dynamic_info_DT_GNU_HASH;
310 uint64_t dynamic_info_DT_MIPS_XHASH;
978c4450
AM
311 elf_section_list * symtab_shndx_list;
312 size_t group_count;
313 struct group * section_groups;
314 struct group ** section_headers_groups;
315 /* A dynamic array of flags indicating for which sections a dump of
316 some kind has been requested. It is reset on a per-object file
317 basis and then initialised from the cmdline_dump_sects array,
318 the results of interpreting the -w switch, and the
319 dump_sects_byname list. */
320 struct dump_data dump;
321} Filedata;
aef1f6d0 322
c256ffe7 323/* How to print a vma value. */
843dd992
NC
324typedef enum print_mode
325{
326 HEX,
047c3dbf 327 HEX_5,
843dd992
NC
328 DEC,
329 DEC_5,
330 UNSIGNED,
047c3dbf 331 UNSIGNED_5,
843dd992 332 PREFIX_HEX,
047c3dbf 333 PREFIX_HEX_5,
843dd992 334 FULL_HEX,
047c3dbf
NL
335 LONG_HEX,
336 OCTAL,
337 OCTAL_5
843dd992
NC
338}
339print_mode;
340
b3aa80b4
NC
341typedef enum unicode_display_type
342{
343 unicode_default = 0,
344 unicode_locale,
345 unicode_escape,
346 unicode_hex,
347 unicode_highlight,
348 unicode_invalid
349} unicode_display_type;
350
351static unicode_display_type unicode_display = unicode_default;
352
a7fd1186
FS
353typedef enum
354{
355 reltype_unknown,
356 reltype_rel,
357 reltype_rela,
358 reltype_relr
359} relocation_type;
360
bb4d2ac2
L
361/* Versioned symbol info. */
362enum versioned_symbol_info
363{
364 symbol_undefined,
365 symbol_hidden,
366 symbol_public
367};
368
63cf857e
AM
369static int
370fseek64 (FILE *stream, int64_t offset, int whence)
371{
372#if defined (HAVE_FSEEKO64)
373 off64_t o = offset;
374 if (o != offset)
375 {
376 errno = EINVAL;
377 return -1;
378 }
379 return fseeko64 (stream, o, whence);
380#elif defined (HAVE_FSEEKO)
381 off_t o = offset;
382 if (o != offset)
383 {
384 errno = EINVAL;
385 return -1;
386 }
387 return fseeko (stream, o, whence);
388#else
389 long o = offset;
390 if (o != offset)
391 {
392 errno = EINVAL;
393 return -1;
394 }
395 return fseek (stream, o, whence);
396#endif
397}
398
32ec8896 399static const char * get_symbol_version_string
26c527e6 400 (Filedata *, bool, const char *, size_t, unsigned,
32ec8896 401 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 402
9c19a809
NC
403#define UNKNOWN -1
404
84714f86
AM
405static inline const char *
406section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
407{
408 return filedata->string_table + hdr->sh_name;
409}
b9e920ec 410
84714f86
AM
411static inline bool
412section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
413{
414 return (hdr != NULL
415 && filedata->string_table != NULL
416 && hdr->sh_name < filedata->string_table_length);
417}
b9e920ec 418
84714f86
AM
419static inline const char *
420section_name_print (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
421{
422 if (hdr == NULL)
423 return _("<none>");
424 if (filedata->string_table == NULL)
425 return _("<no-strings>");
426 if (hdr->sh_name >= filedata->string_table_length)
427 return _("<corrupt>");
428 return section_name (filedata, hdr);
429}
252b5132 430
ee42cf8c 431#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 432
84714f86
AM
433static inline bool
434valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
435{
436 return strtab != NULL && offset < strtab_size;
437}
438
439static inline bool
440valid_dynamic_name (const Filedata *filedata, uint64_t offset)
441{
442 return valid_symbol_name (filedata->dynamic_strings,
443 filedata->dynamic_strings_length, offset);
444}
445
d79b3d50
NC
446/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
447 already been called and verified that the string exists. */
84714f86
AM
448static inline const char *
449get_dynamic_name (const Filedata *filedata, size_t offset)
450{
451 return filedata->dynamic_strings + offset;
452}
18bd398b 453
61865e30
NC
454#define REMOVE_ARCH_BITS(ADDR) \
455 do \
456 { \
dda8d76d 457 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
458 (ADDR) &= ~1; \
459 } \
460 while (0)
f16a9783
MS
461
462/* Get the correct GNU hash section name. */
978c4450
AM
463#define GNU_HASH_SECTION_NAME(filedata) \
464 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 465\f
dda8d76d
NC
466/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
467 OFFSET + the offset of the current archive member, if we are examining an
468 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
469 allocate a buffer using malloc and fill that. In either case return the
470 pointer to the start of the retrieved data or NULL if something went wrong.
471 If something does go wrong and REASON is not NULL then emit an error
472 message using REASON as part of the context. */
59245841 473
c256ffe7 474static void *
be7d229a
AM
475get_data (void *var,
476 Filedata *filedata,
26c527e6 477 uint64_t offset,
be7d229a
AM
478 uint64_t size,
479 uint64_t nmemb,
480 const char *reason)
a6e9f9df 481{
2cf0635d 482 void * mvar;
be7d229a 483 uint64_t amt = size * nmemb;
a6e9f9df 484
c256ffe7 485 if (size == 0 || nmemb == 0)
a6e9f9df
AM
486 return NULL;
487
be7d229a
AM
488 /* If size_t is smaller than uint64_t, eg because you are building
489 on a 32-bit host, then make sure that when the sizes are cast to
490 size_t no information is lost. */
7c1c1904
AM
491 if ((size_t) size != size
492 || (size_t) nmemb != nmemb
be7d229a
AM
493 || (size_t) amt != amt
494 || amt / size != nmemb
495 || (size_t) amt + 1 == 0)
57028622
NC
496 {
497 if (reason)
b8281767
AM
498 error (_("Size overflow prevents reading %" PRIu64
499 " elements of size %" PRIu64 " for %s\n"),
be7d229a 500 nmemb, size, reason);
57028622
NC
501 return NULL;
502 }
503
c22b42ce 504 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 505 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
506 if (filedata->archive_file_offset > filedata->file_size
507 || offset > filedata->file_size - filedata->archive_file_offset
508 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 509 {
049b0c3a 510 if (reason)
b8281767 511 error (_("Reading %" PRIu64 " bytes extends past end of file for %s\n"),
be7d229a 512 amt, reason);
a6e9f9df
AM
513 return NULL;
514 }
515
63cf857e
AM
516 if (fseek64 (filedata->handle, filedata->archive_file_offset + offset,
517 SEEK_SET))
071436c6
NC
518 {
519 if (reason)
26c527e6 520 error (_("Unable to seek to %#" PRIx64 " for %s\n"),
978c4450 521 filedata->archive_file_offset + offset, reason);
071436c6
NC
522 return NULL;
523 }
524
a6e9f9df
AM
525 mvar = var;
526 if (mvar == NULL)
527 {
7c1c1904
AM
528 /* + 1 so that we can '\0' terminate invalid string table sections. */
529 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
530
531 if (mvar == NULL)
532 {
049b0c3a 533 if (reason)
b8281767 534 error (_("Out of memory allocating %" PRIu64 " bytes for %s\n"),
be7d229a 535 amt, reason);
a6e9f9df
AM
536 return NULL;
537 }
c256ffe7 538
c9c1d674 539 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
540 }
541
dda8d76d 542 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 543 {
049b0c3a 544 if (reason)
b8281767 545 error (_("Unable to read in %" PRIu64 " bytes of %s\n"),
be7d229a 546 amt, reason);
a6e9f9df
AM
547 if (mvar != var)
548 free (mvar);
549 return NULL;
550 }
551
552 return mvar;
553}
554
32ec8896
NC
555/* Print a VMA value in the MODE specified.
556 Returns the number of characters displayed. */
cb8f3167 557
32ec8896 558static unsigned int
625d49fc 559print_vma (uint64_t vma, print_mode mode)
66543521 560{
32ec8896 561 unsigned int nc = 0;
66543521 562
14a91970 563 switch (mode)
66543521 564 {
14a91970
AM
565 case FULL_HEX:
566 nc = printf ("0x");
1a0670f3 567 /* Fall through. */
14a91970 568 case LONG_HEX:
f493c217 569 if (!is_32bit_elf)
625d49fc
AM
570 return nc + printf ("%16.16" PRIx64, vma);
571 return nc + printf ("%8.8" PRIx64, vma);
b19aac67 572
14a91970
AM
573 case DEC_5:
574 if (vma <= 99999)
625d49fc 575 return printf ("%5" PRId64, vma);
1a0670f3 576 /* Fall through. */
14a91970
AM
577 case PREFIX_HEX:
578 nc = printf ("0x");
1a0670f3 579 /* Fall through. */
14a91970 580 case HEX:
625d49fc 581 return nc + printf ("%" PRIx64, vma);
b19aac67 582
047c3dbf
NL
583 case PREFIX_HEX_5:
584 nc = printf ("0x");
585 /* Fall through. */
586 case HEX_5:
625d49fc 587 return nc + printf ("%05" PRIx64, vma);
047c3dbf 588
14a91970 589 case DEC:
625d49fc 590 return printf ("%" PRId64, vma);
b19aac67 591
14a91970 592 case UNSIGNED:
625d49fc 593 return printf ("%" PRIu64, vma);
32ec8896 594
047c3dbf 595 case UNSIGNED_5:
625d49fc 596 return printf ("%5" PRIu64, vma);
047c3dbf
NL
597
598 case OCTAL:
625d49fc 599 return printf ("%" PRIo64, vma);
047c3dbf
NL
600
601 case OCTAL_5:
625d49fc 602 return printf ("%5" PRIo64, vma);
047c3dbf 603
32ec8896
NC
604 default:
605 /* FIXME: Report unrecognised mode ? */
606 return 0;
f7a99963 607 }
f7a99963
NC
608}
609
047c3dbf 610
7bfd842d 611/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 612 multibye characters (assuming the host environment supports them).
31104126 613
7bfd842d
NC
614 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
615
0942c7ab
NC
616 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
617 abs(WIDTH) - 5 characters followed by "[...]".
618
7bfd842d
NC
619 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
620 padding as necessary.
171191ba
NC
621
622 Returns the number of emitted characters. */
623
624static unsigned int
0942c7ab 625print_symbol (signed int width, const char * symbol)
31104126 626{
015dc7e1
AM
627 bool extra_padding = false;
628 bool do_dots = false;
32ec8896 629 signed int num_printed = 0;
3bfcb652 630#ifdef HAVE_MBSTATE_T
7bfd842d 631 mbstate_t state;
3bfcb652 632#endif
32ec8896 633 unsigned int width_remaining;
79bc120c 634 const void * alloced_symbol = NULL;
961c521f 635
7bfd842d 636 if (width < 0)
961c521f 637 {
88305e1b 638 /* Keep the width positive. This helps the code below. */
961c521f 639 width = - width;
015dc7e1 640 extra_padding = true;
0b4362b0 641 }
56d8f8a9
NC
642 else if (width == 0)
643 return 0;
961c521f 644
7bfd842d
NC
645 if (do_wide)
646 /* Set the remaining width to a very large value.
647 This simplifies the code below. */
648 width_remaining = INT_MAX;
649 else
0942c7ab
NC
650 {
651 width_remaining = width;
652 if (! do_not_show_symbol_truncation
653 && (int) strlen (symbol) > width)
654 {
655 width_remaining -= 5;
656 if ((int) width_remaining < 0)
657 width_remaining = 0;
015dc7e1 658 do_dots = true;
0942c7ab
NC
659 }
660 }
cb8f3167 661
3bfcb652 662#ifdef HAVE_MBSTATE_T
7bfd842d
NC
663 /* Initialise the multibyte conversion state. */
664 memset (& state, 0, sizeof (state));
3bfcb652 665#endif
961c521f 666
79bc120c
NC
667 if (do_demangle && *symbol)
668 {
669 const char * res = cplus_demangle (symbol, demangle_flags);
670
671 if (res != NULL)
672 alloced_symbol = symbol = res;
673 }
674
7bfd842d
NC
675 while (width_remaining)
676 {
677 size_t n;
7bfd842d 678 const char c = *symbol++;
961c521f 679
7bfd842d 680 if (c == 0)
961c521f
NC
681 break;
682
b3aa80b4
NC
683 if (ISPRINT (c))
684 {
685 putchar (c);
686 width_remaining --;
687 num_printed ++;
688 }
689 else if (ISCNTRL (c))
961c521f 690 {
b3aa80b4
NC
691 /* Do not print control characters directly as they can affect terminal
692 settings. Such characters usually appear in the names generated
693 by the assembler for local labels. */
694
7bfd842d 695 if (width_remaining < 2)
961c521f
NC
696 break;
697
7bfd842d
NC
698 printf ("^%c", c + 0x40);
699 width_remaining -= 2;
171191ba 700 num_printed += 2;
961c521f 701 }
b3aa80b4 702 else if (c == 0x7f)
7bfd842d 703 {
b3aa80b4
NC
704 if (width_remaining < 5)
705 break;
706 printf ("<DEL>");
707 width_remaining -= 5;
708 num_printed += 5;
709 }
710 else if (unicode_display != unicode_locale
711 && unicode_display != unicode_default)
712 {
713 /* Display unicode characters as something else. */
714 unsigned char bytes[4];
715 bool is_utf8;
795588ae 716 unsigned int nbytes;
b3aa80b4
NC
717
718 bytes[0] = c;
719
720 if (bytes[0] < 0xc0)
721 {
722 nbytes = 1;
723 is_utf8 = false;
724 }
725 else
726 {
727 bytes[1] = *symbol++;
728
729 if ((bytes[1] & 0xc0) != 0x80)
730 {
731 is_utf8 = false;
732 /* Do not consume this character. It may only
733 be the first byte in the sequence that was
734 corrupt. */
735 --symbol;
736 nbytes = 1;
737 }
738 else if ((bytes[0] & 0x20) == 0)
739 {
740 is_utf8 = true;
741 nbytes = 2;
742 }
743 else
744 {
745 bytes[2] = *symbol++;
746
747 if ((bytes[2] & 0xc0) != 0x80)
748 {
749 is_utf8 = false;
750 symbol -= 2;
751 nbytes = 1;
752 }
753 else if ((bytes[0] & 0x10) == 0)
754 {
755 is_utf8 = true;
756 nbytes = 3;
757 }
758 else
759 {
760 bytes[3] = *symbol++;
761
762 nbytes = 4;
763
764 if ((bytes[3] & 0xc0) != 0x80)
765 {
766 is_utf8 = false;
767 symbol -= 3;
768 nbytes = 1;
769 }
770 else
771 is_utf8 = true;
772 }
773 }
774 }
775
776 if (unicode_display == unicode_invalid)
777 is_utf8 = false;
778
779 if (unicode_display == unicode_hex || ! is_utf8)
780 {
795588ae 781 unsigned int i;
b3aa80b4
NC
782
783 if (width_remaining < (nbytes * 2) + 2)
784 break;
785
786 putchar (is_utf8 ? '<' : '{');
787 printf ("0x");
788 for (i = 0; i < nbytes; i++)
789 printf ("%02x", bytes[i]);
790 putchar (is_utf8 ? '>' : '}');
791 }
792 else
793 {
794 if (unicode_display == unicode_highlight && isatty (1))
795 printf ("\x1B[31;47m"); /* Red. */
796
797 switch (nbytes)
798 {
799 case 2:
800 if (width_remaining < 6)
801 break;
802 printf ("\\u%02x%02x",
803 (bytes[0] & 0x1c) >> 2,
804 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
805 break;
806 case 3:
807 if (width_remaining < 6)
808 break;
809 printf ("\\u%02x%02x",
810 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
811 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
812 break;
813 case 4:
814 if (width_remaining < 8)
815 break;
816 printf ("\\u%02x%02x%02x",
817 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
818 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
819 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
820
821 break;
822 default:
823 /* URG. */
824 break;
825 }
826
827 if (unicode_display == unicode_highlight && isatty (1))
828 printf ("\033[0m"); /* Default colour. */
829 }
830
831 if (bytes[nbytes - 1] == 0)
832 break;
7bfd842d 833 }
961c521f
NC
834 else
835 {
3bfcb652
NC
836#ifdef HAVE_MBSTATE_T
837 wchar_t w;
838#endif
7bfd842d
NC
839 /* Let printf do the hard work of displaying multibyte characters. */
840 printf ("%.1s", symbol - 1);
841 width_remaining --;
842 num_printed ++;
843
3bfcb652 844#ifdef HAVE_MBSTATE_T
7bfd842d
NC
845 /* Try to find out how many bytes made up the character that was
846 just printed. Advance the symbol pointer past the bytes that
847 were displayed. */
848 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
849#else
850 n = 1;
851#endif
7bfd842d
NC
852 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
853 symbol += (n - 1);
961c521f 854 }
961c521f 855 }
171191ba 856
0942c7ab
NC
857 if (do_dots)
858 num_printed += printf ("[...]");
859
7bfd842d 860 if (extra_padding && num_printed < width)
171191ba
NC
861 {
862 /* Fill in the remaining spaces. */
7bfd842d
NC
863 printf ("%-*s", width - num_printed, " ");
864 num_printed = width;
171191ba
NC
865 }
866
79bc120c 867 free ((void *) alloced_symbol);
171191ba 868 return num_printed;
31104126
NC
869}
870
1449284b 871/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
872 the given section's name. Like print_symbol, except that it does not try
873 to print multibyte characters, it just interprets them as hex values. */
874
875static const char *
dda8d76d 876printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 877{
ca0e11aa 878#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 879 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
84714f86 880 const char * name = section_name_print (filedata, sec);
74e1a04b
NC
881 char * buf = sec_name_buf;
882 char c;
883 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
884
885 while ((c = * name ++) != 0)
886 {
887 if (ISCNTRL (c))
888 {
889 if (remaining < 2)
890 break;
948f632f 891
74e1a04b
NC
892 * buf ++ = '^';
893 * buf ++ = c + 0x40;
894 remaining -= 2;
895 }
896 else if (ISPRINT (c))
897 {
898 * buf ++ = c;
899 remaining -= 1;
900 }
901 else
902 {
903 static char hex[17] = "0123456789ABCDEF";
904
905 if (remaining < 4)
906 break;
907 * buf ++ = '<';
908 * buf ++ = hex[(c & 0xf0) >> 4];
909 * buf ++ = hex[c & 0x0f];
910 * buf ++ = '>';
911 remaining -= 4;
912 }
913
914 if (remaining == 0)
915 break;
916 }
917
918 * buf = 0;
919 return sec_name_buf;
920}
921
922static const char *
26c527e6 923printable_section_name_from_index (Filedata *filedata, size_t ndx)
74e1a04b 924{
dda8d76d 925 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
926 return _("<corrupt>");
927
dda8d76d 928 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
929}
930
89fac5e3
RS
931/* Return a pointer to section NAME, or NULL if no such section exists. */
932
933static Elf_Internal_Shdr *
dda8d76d 934find_section (Filedata * filedata, const char * name)
89fac5e3
RS
935{
936 unsigned int i;
937
68807c3c
NC
938 if (filedata->section_headers == NULL)
939 return NULL;
dda8d76d
NC
940
941 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
942 if (section_name_valid (filedata, filedata->section_headers + i)
943 && streq (section_name (filedata, filedata->section_headers + i),
944 name))
dda8d76d 945 return filedata->section_headers + i;
89fac5e3
RS
946
947 return NULL;
948}
949
0b6ae522
DJ
950/* Return a pointer to a section containing ADDR, or NULL if no such
951 section exists. */
952
953static Elf_Internal_Shdr *
625d49fc 954find_section_by_address (Filedata * filedata, uint64_t addr)
0b6ae522
DJ
955{
956 unsigned int i;
957
68807c3c
NC
958 if (filedata->section_headers == NULL)
959 return NULL;
960
dda8d76d 961 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 962 {
dda8d76d
NC
963 Elf_Internal_Shdr *sec = filedata->section_headers + i;
964
0b6ae522
DJ
965 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
966 return sec;
967 }
968
969 return NULL;
970}
971
071436c6 972static Elf_Internal_Shdr *
dda8d76d 973find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
974{
975 unsigned int i;
976
68807c3c
NC
977 if (filedata->section_headers == NULL)
978 return NULL;
979
dda8d76d 980 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 981 {
dda8d76d
NC
982 Elf_Internal_Shdr *sec = filedata->section_headers + i;
983
071436c6
NC
984 if (sec->sh_type == type)
985 return sec;
986 }
987
988 return NULL;
989}
990
657d0d47
CC
991/* Return a pointer to section NAME, or NULL if no such section exists,
992 restricted to the list of sections given in SET. */
993
994static Elf_Internal_Shdr *
dda8d76d 995find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
996{
997 unsigned int i;
998
68807c3c
NC
999 if (filedata->section_headers == NULL)
1000 return NULL;
1001
657d0d47
CC
1002 if (set != NULL)
1003 {
1004 while ((i = *set++) > 0)
b814a36d
NC
1005 {
1006 /* See PR 21156 for a reproducer. */
dda8d76d 1007 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
1008 continue; /* FIXME: Should we issue an error message ? */
1009
84714f86
AM
1010 if (section_name_valid (filedata, filedata->section_headers + i)
1011 && streq (section_name (filedata, filedata->section_headers + i),
1012 name))
dda8d76d 1013 return filedata->section_headers + i;
b814a36d 1014 }
657d0d47
CC
1015 }
1016
dda8d76d 1017 return find_section (filedata, name);
657d0d47
CC
1018}
1019
32ec8896 1020/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
1021 This OS has so many departures from the ELF standard that we test it at
1022 many places. */
1023
015dc7e1 1024static inline bool
dda8d76d 1025is_ia64_vms (Filedata * filedata)
28f997cf 1026{
dda8d76d
NC
1027 return filedata->file_header.e_machine == EM_IA_64
1028 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
1029}
1030
bcedfee6 1031/* Guess the relocation size commonly used by the specific machines. */
252b5132 1032
015dc7e1 1033static bool
2dc4cec1 1034guess_is_rela (unsigned int e_machine)
252b5132 1035{
9c19a809 1036 switch (e_machine)
252b5132
RH
1037 {
1038 /* Targets that use REL relocations. */
252b5132 1039 case EM_386:
22abe556 1040 case EM_IAMCU:
f954747f 1041 case EM_960:
e9f53129 1042 case EM_ARM:
2b0337b0 1043 case EM_D10V:
252b5132 1044 case EM_CYGNUS_D10V:
e9f53129 1045 case EM_DLX:
252b5132 1046 case EM_MIPS:
4fe85591 1047 case EM_MIPS_RS3_LE:
e9f53129 1048 case EM_CYGNUS_M32R:
1c0d3aa6 1049 case EM_SCORE:
f6c1a2d5 1050 case EM_XGATE:
fe944acf 1051 case EM_NFP:
aca4efc7 1052 case EM_BPF:
015dc7e1 1053 return false;
103f02d3 1054
252b5132
RH
1055 /* Targets that use RELA relocations. */
1056 case EM_68K:
f954747f 1057 case EM_860:
a06ea964 1058 case EM_AARCH64:
cfb8c092 1059 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1060 case EM_ALPHA:
1061 case EM_ALTERA_NIOS2:
886a2506
NC
1062 case EM_ARC:
1063 case EM_ARC_COMPACT:
1064 case EM_ARC_COMPACT2:
13aa307c
CZ
1065 case EM_ARC_COMPACT3:
1066 case EM_ARC_COMPACT3_64:
e9f53129
AM
1067 case EM_AVR:
1068 case EM_AVR_OLD:
1069 case EM_BLACKFIN:
60bca95a 1070 case EM_CR16:
e9f53129
AM
1071 case EM_CRIS:
1072 case EM_CRX:
b8891f8d 1073 case EM_CSKY:
2b0337b0 1074 case EM_D30V:
252b5132 1075 case EM_CYGNUS_D30V:
2b0337b0 1076 case EM_FR30:
3f8107ab 1077 case EM_FT32:
252b5132 1078 case EM_CYGNUS_FR30:
5c70f934 1079 case EM_CYGNUS_FRV:
e9f53129
AM
1080 case EM_H8S:
1081 case EM_H8_300:
1082 case EM_H8_300H:
800eeca4 1083 case EM_IA_64:
1e4cf259
NC
1084 case EM_IP2K:
1085 case EM_IP2K_OLD:
3b36097d 1086 case EM_IQ2000:
84e94c90 1087 case EM_LATTICEMICO32:
ff7eeb89 1088 case EM_M32C_OLD:
49f58d10 1089 case EM_M32C:
e9f53129
AM
1090 case EM_M32R:
1091 case EM_MCORE:
15ab5209 1092 case EM_CYGNUS_MEP:
a3c62988 1093 case EM_METAG:
e9f53129
AM
1094 case EM_MMIX:
1095 case EM_MN10200:
1096 case EM_CYGNUS_MN10200:
1097 case EM_MN10300:
1098 case EM_CYGNUS_MN10300:
5506d11a 1099 case EM_MOXIE:
e9f53129
AM
1100 case EM_MSP430:
1101 case EM_MSP430_OLD:
d031aafb 1102 case EM_MT:
35c08157 1103 case EM_NDS32:
64fd6348 1104 case EM_NIOS32:
73589c9d 1105 case EM_OR1K:
e9f53129
AM
1106 case EM_PPC64:
1107 case EM_PPC:
2b100bb5 1108 case EM_TI_PRU:
e23eba97 1109 case EM_RISCV:
99c513f6 1110 case EM_RL78:
c7927a3c 1111 case EM_RX:
e9f53129
AM
1112 case EM_S390:
1113 case EM_S390_OLD:
1114 case EM_SH:
1115 case EM_SPARC:
1116 case EM_SPARC32PLUS:
1117 case EM_SPARCV9:
1118 case EM_SPU:
40b36596 1119 case EM_TI_C6000:
aa137e4d
NC
1120 case EM_TILEGX:
1121 case EM_TILEPRO:
708e2187 1122 case EM_V800:
e9f53129
AM
1123 case EM_V850:
1124 case EM_CYGNUS_V850:
1125 case EM_VAX:
619ed720 1126 case EM_VISIUM:
e9f53129 1127 case EM_X86_64:
8a9036a4 1128 case EM_L1OM:
7a9068fe 1129 case EM_K1OM:
e9f53129
AM
1130 case EM_XSTORMY16:
1131 case EM_XTENSA:
1132 case EM_XTENSA_OLD:
7ba29e2a
NC
1133 case EM_MICROBLAZE:
1134 case EM_MICROBLAZE_OLD:
f96bd6c2 1135 case EM_WEBASSEMBLY:
015dc7e1 1136 return true;
103f02d3 1137
e9f53129
AM
1138 case EM_68HC05:
1139 case EM_68HC08:
1140 case EM_68HC11:
1141 case EM_68HC16:
1142 case EM_FX66:
1143 case EM_ME16:
d1133906 1144 case EM_MMA:
d1133906
NC
1145 case EM_NCPU:
1146 case EM_NDR1:
e9f53129 1147 case EM_PCP:
d1133906 1148 case EM_ST100:
e9f53129 1149 case EM_ST19:
d1133906 1150 case EM_ST7:
e9f53129
AM
1151 case EM_ST9PLUS:
1152 case EM_STARCORE:
d1133906 1153 case EM_SVX:
e9f53129 1154 case EM_TINYJ:
9c19a809
NC
1155 default:
1156 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1157 return false;
9c19a809
NC
1158 }
1159}
252b5132 1160
dda8d76d 1161/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1162 Returns TRUE upon success, FALSE otherwise. If successful then a
1163 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1164 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1165 responsibility to free the allocated buffer. */
1166
015dc7e1 1167static bool
26c527e6
AM
1168slurp_rela_relocs (Filedata *filedata,
1169 uint64_t rel_offset,
1170 uint64_t rel_size,
1171 Elf_Internal_Rela **relasp,
1172 uint64_t *nrelasp)
9c19a809 1173{
2cf0635d 1174 Elf_Internal_Rela * relas;
26c527e6 1175 uint64_t nrelas;
4d6ed7c8 1176 unsigned int i;
252b5132 1177
4d6ed7c8
NC
1178 if (is_32bit_elf)
1179 {
2cf0635d 1180 Elf32_External_Rela * erelas;
103f02d3 1181
dda8d76d 1182 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1183 rel_size, _("32-bit relocation data"));
a6e9f9df 1184 if (!erelas)
015dc7e1 1185 return false;
252b5132 1186
4d6ed7c8 1187 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1188
3f5e193b
NC
1189 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1190 sizeof (Elf_Internal_Rela));
103f02d3 1191
4d6ed7c8
NC
1192 if (relas == NULL)
1193 {
c256ffe7 1194 free (erelas);
591a748a 1195 error (_("out of memory parsing relocs\n"));
015dc7e1 1196 return false;
4d6ed7c8 1197 }
103f02d3 1198
4d6ed7c8
NC
1199 for (i = 0; i < nrelas; i++)
1200 {
1201 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1202 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1203 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1204 }
103f02d3 1205
4d6ed7c8
NC
1206 free (erelas);
1207 }
1208 else
1209 {
2cf0635d 1210 Elf64_External_Rela * erelas;
103f02d3 1211
dda8d76d 1212 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1213 rel_size, _("64-bit relocation data"));
a6e9f9df 1214 if (!erelas)
015dc7e1 1215 return false;
4d6ed7c8
NC
1216
1217 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1218
3f5e193b
NC
1219 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1220 sizeof (Elf_Internal_Rela));
103f02d3 1221
4d6ed7c8
NC
1222 if (relas == NULL)
1223 {
c256ffe7 1224 free (erelas);
591a748a 1225 error (_("out of memory parsing relocs\n"));
015dc7e1 1226 return false;
9c19a809 1227 }
4d6ed7c8
NC
1228
1229 for (i = 0; i < nrelas; i++)
9c19a809 1230 {
66543521
AM
1231 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1232 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1233 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a 1234
dda8d76d
NC
1235 if (filedata->file_header.e_machine == EM_MIPS
1236 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1237 {
1238 /* In little-endian objects, r_info isn't really a
1239 64-bit little-endian value: it has a 32-bit
1240 little-endian symbol index followed by four
1241 individual byte fields. Reorder INFO
1242 accordingly. */
625d49fc 1243 uint64_t inf = relas[i].r_info;
91d6fa6a
NC
1244 inf = (((inf & 0xffffffff) << 32)
1245 | ((inf >> 56) & 0xff)
1246 | ((inf >> 40) & 0xff00)
1247 | ((inf >> 24) & 0xff0000)
1248 | ((inf >> 8) & 0xff000000));
1249 relas[i].r_info = inf;
861fb55a 1250 }
4d6ed7c8 1251 }
103f02d3 1252
4d6ed7c8
NC
1253 free (erelas);
1254 }
32ec8896 1255
4d6ed7c8
NC
1256 *relasp = relas;
1257 *nrelasp = nrelas;
015dc7e1 1258 return true;
4d6ed7c8 1259}
103f02d3 1260
dda8d76d 1261/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1262 Returns TRUE upon success, FALSE otherwise. If successful then a
1263 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1264 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1265 responsibility to free the allocated buffer. */
1266
015dc7e1 1267static bool
26c527e6
AM
1268slurp_rel_relocs (Filedata *filedata,
1269 uint64_t rel_offset,
1270 uint64_t rel_size,
1271 Elf_Internal_Rela **relsp,
1272 uint64_t *nrelsp)
4d6ed7c8 1273{
2cf0635d 1274 Elf_Internal_Rela * rels;
26c527e6 1275 uint64_t nrels;
4d6ed7c8 1276 unsigned int i;
103f02d3 1277
4d6ed7c8
NC
1278 if (is_32bit_elf)
1279 {
2cf0635d 1280 Elf32_External_Rel * erels;
103f02d3 1281
dda8d76d 1282 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1283 rel_size, _("32-bit relocation data"));
a6e9f9df 1284 if (!erels)
015dc7e1 1285 return false;
103f02d3 1286
4d6ed7c8 1287 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1288
3f5e193b 1289 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1290
4d6ed7c8
NC
1291 if (rels == NULL)
1292 {
c256ffe7 1293 free (erels);
591a748a 1294 error (_("out of memory parsing relocs\n"));
015dc7e1 1295 return false;
4d6ed7c8
NC
1296 }
1297
1298 for (i = 0; i < nrels; i++)
1299 {
1300 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1301 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1302 rels[i].r_addend = 0;
9ea033b2 1303 }
4d6ed7c8
NC
1304
1305 free (erels);
9c19a809
NC
1306 }
1307 else
1308 {
2cf0635d 1309 Elf64_External_Rel * erels;
9ea033b2 1310
dda8d76d 1311 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1312 rel_size, _("64-bit relocation data"));
a6e9f9df 1313 if (!erels)
015dc7e1 1314 return false;
103f02d3 1315
4d6ed7c8 1316 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1317
3f5e193b 1318 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1319
4d6ed7c8 1320 if (rels == NULL)
9c19a809 1321 {
c256ffe7 1322 free (erels);
591a748a 1323 error (_("out of memory parsing relocs\n"));
015dc7e1 1324 return false;
4d6ed7c8 1325 }
103f02d3 1326
4d6ed7c8
NC
1327 for (i = 0; i < nrels; i++)
1328 {
66543521
AM
1329 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1330 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1331 rels[i].r_addend = 0;
861fb55a 1332
dda8d76d
NC
1333 if (filedata->file_header.e_machine == EM_MIPS
1334 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1335 {
1336 /* In little-endian objects, r_info isn't really a
1337 64-bit little-endian value: it has a 32-bit
1338 little-endian symbol index followed by four
1339 individual byte fields. Reorder INFO
1340 accordingly. */
625d49fc 1341 uint64_t inf = rels[i].r_info;
91d6fa6a
NC
1342 inf = (((inf & 0xffffffff) << 32)
1343 | ((inf >> 56) & 0xff)
1344 | ((inf >> 40) & 0xff00)
1345 | ((inf >> 24) & 0xff0000)
1346 | ((inf >> 8) & 0xff000000));
1347 rels[i].r_info = inf;
861fb55a 1348 }
4d6ed7c8 1349 }
103f02d3 1350
4d6ed7c8
NC
1351 free (erels);
1352 }
32ec8896 1353
4d6ed7c8
NC
1354 *relsp = rels;
1355 *nrelsp = nrels;
015dc7e1 1356 return true;
4d6ed7c8 1357}
103f02d3 1358
a7fd1186 1359static bool
26c527e6
AM
1360slurp_relr_relocs (Filedata *filedata,
1361 uint64_t relr_offset,
1362 uint64_t relr_size,
1363 uint64_t **relrsp,
1364 uint64_t *nrelrsp)
a7fd1186
FS
1365{
1366 void *relrs;
1367 size_t size = 0, nentries, i;
625d49fc 1368 uint64_t base = 0, addr, entry;
a7fd1186
FS
1369
1370 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1371 _("RELR relocation data"));
1372 if (!relrs)
1373 return false;
1374
1375 if (is_32bit_elf)
1376 nentries = relr_size / sizeof (Elf32_External_Relr);
1377 else
1378 nentries = relr_size / sizeof (Elf64_External_Relr);
1379 for (i = 0; i < nentries; i++)
1380 {
1381 if (is_32bit_elf)
1382 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1383 else
1384 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1385 if ((entry & 1) == 0)
1386 size++;
1387 else
1388 while ((entry >>= 1) != 0)
1389 if ((entry & 1) == 1)
1390 size++;
1391 }
1392
625d49fc 1393 *relrsp = malloc (size * sizeof (**relrsp));
a7fd1186
FS
1394 if (*relrsp == NULL)
1395 {
1396 free (relrs);
1397 error (_("out of memory parsing relocs\n"));
1398 return false;
1399 }
1400
1401 size = 0;
1402 for (i = 0; i < nentries; i++)
1403 {
625d49fc 1404 const uint64_t entry_bytes = is_32bit_elf ? 4 : 8;
a7fd1186
FS
1405
1406 if (is_32bit_elf)
1407 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1408 else
1409 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1410 if ((entry & 1) == 0)
1411 {
1412 (*relrsp)[size++] = entry;
1413 base = entry + entry_bytes;
1414 }
1415 else
1416 {
1417 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1418 if ((entry & 1) != 0)
1419 (*relrsp)[size++] = addr;
1420 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1421 }
1422 }
1423
1424 *nrelrsp = size;
1425 free (relrs);
1426 return true;
1427}
1428
aca88567
NC
1429/* Returns the reloc type extracted from the reloc info field. */
1430
1431static unsigned int
625d49fc 1432get_reloc_type (Filedata * filedata, uint64_t reloc_info)
aca88567
NC
1433{
1434 if (is_32bit_elf)
1435 return ELF32_R_TYPE (reloc_info);
1436
dda8d76d 1437 switch (filedata->file_header.e_machine)
aca88567
NC
1438 {
1439 case EM_MIPS:
1440 /* Note: We assume that reloc_info has already been adjusted for us. */
1441 return ELF64_MIPS_R_TYPE (reloc_info);
1442
1443 case EM_SPARCV9:
1444 return ELF64_R_TYPE_ID (reloc_info);
1445
1446 default:
1447 return ELF64_R_TYPE (reloc_info);
1448 }
1449}
1450
1451/* Return the symbol index extracted from the reloc info field. */
1452
625d49fc
AM
1453static uint64_t
1454get_reloc_symindex (uint64_t reloc_info)
aca88567
NC
1455{
1456 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1457}
1458
015dc7e1 1459static inline bool
dda8d76d 1460uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1461{
1462 return
dda8d76d 1463 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1464 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1465 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1466 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1467 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1468}
1469
d3ba0551
AM
1470/* Display the contents of the relocation data found at the specified
1471 offset. */
ee42cf8c 1472
015dc7e1 1473static bool
26c527e6
AM
1474dump_relocations (Filedata *filedata,
1475 uint64_t rel_offset,
1476 uint64_t rel_size,
1477 Elf_Internal_Sym *symtab,
1478 uint64_t nsyms,
1479 char *strtab,
1480 uint64_t strtablen,
1481 relocation_type rel_type,
1482 bool is_dynsym)
1483{
1484 size_t i;
2cf0635d 1485 Elf_Internal_Rela * rels;
015dc7e1 1486 bool res = true;
103f02d3 1487
a7fd1186
FS
1488 if (rel_type == reltype_unknown)
1489 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1490
a7fd1186 1491 if (rel_type == reltype_rela)
4d6ed7c8 1492 {
dda8d76d 1493 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1494 return false;
4d6ed7c8 1495 }
a7fd1186 1496 else if (rel_type == reltype_rel)
4d6ed7c8 1497 {
dda8d76d 1498 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1499 return false;
252b5132 1500 }
a7fd1186
FS
1501 else if (rel_type == reltype_relr)
1502 {
625d49fc 1503 uint64_t * relrs;
a7fd1186 1504 const char *format
b8281767 1505 = is_32bit_elf ? "%08" PRIx64 "\n" : "%016" PRIx64 "\n";
a7fd1186
FS
1506
1507 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1508 &rel_size))
1509 return false;
1510
26c527e6
AM
1511 printf (ngettext (" %" PRIu64 " offset\n",
1512 " %" PRIu64 " offsets\n", rel_size),
b8281767 1513 rel_size);
a7fd1186 1514 for (i = 0; i < rel_size; i++)
625d49fc 1515 printf (format, relrs[i]);
a7fd1186
FS
1516 free (relrs);
1517 return true;
1518 }
252b5132 1519
410f7a12
L
1520 if (is_32bit_elf)
1521 {
a7fd1186 1522 if (rel_type == reltype_rela)
2c71103e
NC
1523 {
1524 if (do_wide)
1525 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1526 else
1527 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1528 }
410f7a12 1529 else
2c71103e
NC
1530 {
1531 if (do_wide)
1532 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1533 else
1534 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1535 }
410f7a12 1536 }
252b5132 1537 else
410f7a12 1538 {
a7fd1186 1539 if (rel_type == reltype_rela)
2c71103e
NC
1540 {
1541 if (do_wide)
8beeaeb7 1542 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1543 else
1544 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1545 }
410f7a12 1546 else
2c71103e
NC
1547 {
1548 if (do_wide)
8beeaeb7 1549 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1550 else
1551 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1552 }
410f7a12 1553 }
252b5132
RH
1554
1555 for (i = 0; i < rel_size; i++)
1556 {
2cf0635d 1557 const char * rtype;
625d49fc
AM
1558 uint64_t offset;
1559 uint64_t inf;
1560 uint64_t symtab_index;
1561 uint64_t type;
103f02d3 1562
b34976b6 1563 offset = rels[i].r_offset;
91d6fa6a 1564 inf = rels[i].r_info;
103f02d3 1565
dda8d76d 1566 type = get_reloc_type (filedata, inf);
91d6fa6a 1567 symtab_index = get_reloc_symindex (inf);
252b5132 1568
410f7a12
L
1569 if (is_32bit_elf)
1570 {
39dbeff8
AM
1571 printf ("%8.8lx %8.8lx ",
1572 (unsigned long) offset & 0xffffffff,
91d6fa6a 1573 (unsigned long) inf & 0xffffffff);
410f7a12
L
1574 }
1575 else
1576 {
39dbeff8 1577 printf (do_wide
b8281767
AM
1578 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
1579 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
625d49fc 1580 offset, inf);
410f7a12 1581 }
103f02d3 1582
dda8d76d 1583 switch (filedata->file_header.e_machine)
252b5132
RH
1584 {
1585 default:
1586 rtype = NULL;
1587 break;
1588
a06ea964
NC
1589 case EM_AARCH64:
1590 rtype = elf_aarch64_reloc_type (type);
1591 break;
1592
2b0337b0 1593 case EM_M32R:
252b5132 1594 case EM_CYGNUS_M32R:
9ea033b2 1595 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1596 break;
1597
1598 case EM_386:
22abe556 1599 case EM_IAMCU:
9ea033b2 1600 rtype = elf_i386_reloc_type (type);
252b5132
RH
1601 break;
1602
ba2685cc
AM
1603 case EM_68HC11:
1604 case EM_68HC12:
1605 rtype = elf_m68hc11_reloc_type (type);
1606 break;
75751cd9 1607
7b4ae824
JD
1608 case EM_S12Z:
1609 rtype = elf_s12z_reloc_type (type);
1610 break;
1611
252b5132 1612 case EM_68K:
9ea033b2 1613 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1614 break;
1615
f954747f
AM
1616 case EM_960:
1617 rtype = elf_i960_reloc_type (type);
1618 break;
1619
adde6300 1620 case EM_AVR:
2b0337b0 1621 case EM_AVR_OLD:
adde6300
AM
1622 rtype = elf_avr_reloc_type (type);
1623 break;
1624
9ea033b2
NC
1625 case EM_OLD_SPARCV9:
1626 case EM_SPARC32PLUS:
1627 case EM_SPARCV9:
252b5132 1628 case EM_SPARC:
9ea033b2 1629 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1630 break;
1631
e9f53129
AM
1632 case EM_SPU:
1633 rtype = elf_spu_reloc_type (type);
1634 break;
1635
708e2187
NC
1636 case EM_V800:
1637 rtype = v800_reloc_type (type);
1638 break;
2b0337b0 1639 case EM_V850:
252b5132 1640 case EM_CYGNUS_V850:
9ea033b2 1641 rtype = v850_reloc_type (type);
252b5132
RH
1642 break;
1643
2b0337b0 1644 case EM_D10V:
252b5132 1645 case EM_CYGNUS_D10V:
9ea033b2 1646 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1647 break;
1648
2b0337b0 1649 case EM_D30V:
252b5132 1650 case EM_CYGNUS_D30V:
9ea033b2 1651 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1652 break;
1653
d172d4ba
NC
1654 case EM_DLX:
1655 rtype = elf_dlx_reloc_type (type);
1656 break;
1657
252b5132 1658 case EM_SH:
9ea033b2 1659 rtype = elf_sh_reloc_type (type);
252b5132
RH
1660 break;
1661
2b0337b0 1662 case EM_MN10300:
252b5132 1663 case EM_CYGNUS_MN10300:
9ea033b2 1664 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1665 break;
1666
2b0337b0 1667 case EM_MN10200:
252b5132 1668 case EM_CYGNUS_MN10200:
9ea033b2 1669 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1670 break;
1671
2b0337b0 1672 case EM_FR30:
252b5132 1673 case EM_CYGNUS_FR30:
9ea033b2 1674 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1675 break;
1676
ba2685cc
AM
1677 case EM_CYGNUS_FRV:
1678 rtype = elf_frv_reloc_type (type);
1679 break;
5c70f934 1680
b8891f8d
AJ
1681 case EM_CSKY:
1682 rtype = elf_csky_reloc_type (type);
1683 break;
1684
3f8107ab
AM
1685 case EM_FT32:
1686 rtype = elf_ft32_reloc_type (type);
1687 break;
1688
252b5132 1689 case EM_MCORE:
9ea033b2 1690 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1691 break;
1692
3c3bdf30
NC
1693 case EM_MMIX:
1694 rtype = elf_mmix_reloc_type (type);
1695 break;
1696
5506d11a
AM
1697 case EM_MOXIE:
1698 rtype = elf_moxie_reloc_type (type);
1699 break;
1700
2469cfa2 1701 case EM_MSP430:
dda8d76d 1702 if (uses_msp430x_relocs (filedata))
13761a11
NC
1703 {
1704 rtype = elf_msp430x_reloc_type (type);
1705 break;
1706 }
1a0670f3 1707 /* Fall through. */
2469cfa2
NC
1708 case EM_MSP430_OLD:
1709 rtype = elf_msp430_reloc_type (type);
1710 break;
1711
35c08157
KLC
1712 case EM_NDS32:
1713 rtype = elf_nds32_reloc_type (type);
1714 break;
1715
252b5132 1716 case EM_PPC:
9ea033b2 1717 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1718 break;
1719
c833c019
AM
1720 case EM_PPC64:
1721 rtype = elf_ppc64_reloc_type (type);
1722 break;
1723
252b5132 1724 case EM_MIPS:
4fe85591 1725 case EM_MIPS_RS3_LE:
9ea033b2 1726 rtype = elf_mips_reloc_type (type);
252b5132
RH
1727 break;
1728
e23eba97
NC
1729 case EM_RISCV:
1730 rtype = elf_riscv_reloc_type (type);
1731 break;
1732
252b5132 1733 case EM_ALPHA:
9ea033b2 1734 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1735 break;
1736
1737 case EM_ARM:
9ea033b2 1738 rtype = elf_arm_reloc_type (type);
252b5132
RH
1739 break;
1740
584da044 1741 case EM_ARC:
886a2506
NC
1742 case EM_ARC_COMPACT:
1743 case EM_ARC_COMPACT2:
13aa307c
CZ
1744 case EM_ARC_COMPACT3:
1745 case EM_ARC_COMPACT3_64:
9ea033b2 1746 rtype = elf_arc_reloc_type (type);
252b5132
RH
1747 break;
1748
1749 case EM_PARISC:
69e617ca 1750 rtype = elf_hppa_reloc_type (type);
252b5132 1751 break;
7d466069 1752
b8720f9d
JL
1753 case EM_H8_300:
1754 case EM_H8_300H:
1755 case EM_H8S:
1756 rtype = elf_h8_reloc_type (type);
1757 break;
1758
73589c9d
CS
1759 case EM_OR1K:
1760 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1761 break;
1762
7d466069 1763 case EM_PJ:
2b0337b0 1764 case EM_PJ_OLD:
7d466069
ILT
1765 rtype = elf_pj_reloc_type (type);
1766 break;
800eeca4
JW
1767 case EM_IA_64:
1768 rtype = elf_ia64_reloc_type (type);
1769 break;
1b61cf92
HPN
1770
1771 case EM_CRIS:
1772 rtype = elf_cris_reloc_type (type);
1773 break;
535c37ff 1774
f954747f
AM
1775 case EM_860:
1776 rtype = elf_i860_reloc_type (type);
1777 break;
1778
bcedfee6 1779 case EM_X86_64:
8a9036a4 1780 case EM_L1OM:
7a9068fe 1781 case EM_K1OM:
bcedfee6
NC
1782 rtype = elf_x86_64_reloc_type (type);
1783 break;
a85d7ed0 1784
f954747f
AM
1785 case EM_S370:
1786 rtype = i370_reloc_type (type);
1787 break;
1788
53c7db4b
KH
1789 case EM_S390_OLD:
1790 case EM_S390:
1791 rtype = elf_s390_reloc_type (type);
1792 break;
93fbbb04 1793
1c0d3aa6
NC
1794 case EM_SCORE:
1795 rtype = elf_score_reloc_type (type);
1796 break;
1797
93fbbb04
GK
1798 case EM_XSTORMY16:
1799 rtype = elf_xstormy16_reloc_type (type);
1800 break;
179d3252 1801
1fe1f39c
NC
1802 case EM_CRX:
1803 rtype = elf_crx_reloc_type (type);
1804 break;
1805
179d3252
JT
1806 case EM_VAX:
1807 rtype = elf_vax_reloc_type (type);
1808 break;
1e4cf259 1809
619ed720
EB
1810 case EM_VISIUM:
1811 rtype = elf_visium_reloc_type (type);
1812 break;
1813
aca4efc7
JM
1814 case EM_BPF:
1815 rtype = elf_bpf_reloc_type (type);
1816 break;
1817
cfb8c092
NC
1818 case EM_ADAPTEVA_EPIPHANY:
1819 rtype = elf_epiphany_reloc_type (type);
1820 break;
1821
1e4cf259
NC
1822 case EM_IP2K:
1823 case EM_IP2K_OLD:
1824 rtype = elf_ip2k_reloc_type (type);
1825 break;
3b36097d
SC
1826
1827 case EM_IQ2000:
1828 rtype = elf_iq2000_reloc_type (type);
1829 break;
88da6820
NC
1830
1831 case EM_XTENSA_OLD:
1832 case EM_XTENSA:
1833 rtype = elf_xtensa_reloc_type (type);
1834 break;
a34e3ecb 1835
84e94c90
NC
1836 case EM_LATTICEMICO32:
1837 rtype = elf_lm32_reloc_type (type);
1838 break;
1839
ff7eeb89 1840 case EM_M32C_OLD:
49f58d10
JB
1841 case EM_M32C:
1842 rtype = elf_m32c_reloc_type (type);
1843 break;
1844
d031aafb
NS
1845 case EM_MT:
1846 rtype = elf_mt_reloc_type (type);
a34e3ecb 1847 break;
1d65ded4
CM
1848
1849 case EM_BLACKFIN:
1850 rtype = elf_bfin_reloc_type (type);
1851 break;
15ab5209
DB
1852
1853 case EM_CYGNUS_MEP:
1854 rtype = elf_mep_reloc_type (type);
1855 break;
60bca95a
NC
1856
1857 case EM_CR16:
1858 rtype = elf_cr16_reloc_type (type);
1859 break;
dd24e3da 1860
7ba29e2a
NC
1861 case EM_MICROBLAZE:
1862 case EM_MICROBLAZE_OLD:
1863 rtype = elf_microblaze_reloc_type (type);
1864 break;
c7927a3c 1865
99c513f6
DD
1866 case EM_RL78:
1867 rtype = elf_rl78_reloc_type (type);
1868 break;
1869
c7927a3c
NC
1870 case EM_RX:
1871 rtype = elf_rx_reloc_type (type);
1872 break;
c29aca4a 1873
a3c62988
NC
1874 case EM_METAG:
1875 rtype = elf_metag_reloc_type (type);
1876 break;
1877
40b36596
JM
1878 case EM_TI_C6000:
1879 rtype = elf_tic6x_reloc_type (type);
1880 break;
aa137e4d
NC
1881
1882 case EM_TILEGX:
1883 rtype = elf_tilegx_reloc_type (type);
1884 break;
1885
1886 case EM_TILEPRO:
1887 rtype = elf_tilepro_reloc_type (type);
1888 break;
f6c1a2d5 1889
f96bd6c2
PC
1890 case EM_WEBASSEMBLY:
1891 rtype = elf_wasm32_reloc_type (type);
1892 break;
1893
f6c1a2d5
NC
1894 case EM_XGATE:
1895 rtype = elf_xgate_reloc_type (type);
1896 break;
36591ba1
SL
1897
1898 case EM_ALTERA_NIOS2:
1899 rtype = elf_nios2_reloc_type (type);
1900 break;
2b100bb5
DD
1901
1902 case EM_TI_PRU:
1903 rtype = elf_pru_reloc_type (type);
1904 break;
fe944acf
FT
1905
1906 case EM_NFP:
1907 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1908 rtype = elf_nfp3200_reloc_type (type);
1909 else
1910 rtype = elf_nfp_reloc_type (type);
1911 break;
6655dba2
SB
1912
1913 case EM_Z80:
1914 rtype = elf_z80_reloc_type (type);
1915 break;
e9a0721f 1916
1917 case EM_LOONGARCH:
1918 rtype = elf_loongarch_reloc_type (type);
1919 break;
1920
0c857ef4
SM
1921 case EM_AMDGPU:
1922 rtype = elf_amdgpu_reloc_type (type);
1923 break;
252b5132
RH
1924 }
1925
1926 if (rtype == NULL)
39dbeff8 1927 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1928 else
5c144731 1929 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1930
dda8d76d 1931 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1932 && rtype != NULL
7ace3541 1933 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 1934 && rel_type == reltype_rela)
7ace3541
RH
1935 {
1936 switch (rels[i].r_addend)
1937 {
1938 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1939 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1940 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1941 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1942 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1943 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1944 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1945 default: rtype = NULL;
1946 }
32ec8896 1947
7ace3541
RH
1948 if (rtype)
1949 printf (" (%s)", rtype);
1950 else
1951 {
1952 putchar (' ');
26c527e6
AM
1953 printf (_("<unknown addend: %" PRIx64 ">"),
1954 rels[i].r_addend);
015dc7e1 1955 res = false;
7ace3541
RH
1956 }
1957 }
1958 else if (symtab_index)
252b5132 1959 {
af3fc3bc 1960 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1961 {
27a45f42
AS
1962 error (_(" bad symbol index: %08lx in reloc\n"),
1963 (unsigned long) symtab_index);
015dc7e1 1964 res = false;
32ec8896 1965 }
af3fc3bc 1966 else
19936277 1967 {
2cf0635d 1968 Elf_Internal_Sym * psym;
bb4d2ac2
L
1969 const char * version_string;
1970 enum versioned_symbol_info sym_info;
1971 unsigned short vna_other;
19936277 1972
af3fc3bc 1973 psym = symtab + symtab_index;
103f02d3 1974
bb4d2ac2 1975 version_string
dda8d76d 1976 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1977 strtab, strtablen,
1978 symtab_index,
1979 psym,
1980 &sym_info,
1981 &vna_other);
1982
af3fc3bc 1983 printf (" ");
171191ba 1984
d8045f23
NC
1985 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1986 {
1987 const char * name;
1988 unsigned int len;
1989 unsigned int width = is_32bit_elf ? 8 : 14;
1990
1991 /* Relocations against GNU_IFUNC symbols do not use the value
1992 of the symbol as the address to relocate against. Instead
1993 they invoke the function named by the symbol and use its
1994 result as the address for relocation.
1995
1996 To indicate this to the user, do not display the value of
1997 the symbol in the "Symbols's Value" field. Instead show
1998 its name followed by () as a hint that the symbol is
1999 invoked. */
2000
2001 if (strtab == NULL
2002 || psym->st_name == 0
2003 || psym->st_name >= strtablen)
2004 name = "??";
2005 else
2006 name = strtab + psym->st_name;
2007
2008 len = print_symbol (width, name);
bb4d2ac2
L
2009 if (version_string)
2010 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2011 version_string);
d8045f23
NC
2012 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2013 }
2014 else
2015 {
2016 print_vma (psym->st_value, LONG_HEX);
171191ba 2017
d8045f23
NC
2018 printf (is_32bit_elf ? " " : " ");
2019 }
103f02d3 2020
af3fc3bc 2021 if (psym->st_name == 0)
f1ef08cb 2022 {
2cf0635d 2023 const char * sec_name = "<null>";
f1ef08cb
AM
2024 char name_buf[40];
2025
2026 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
2027 {
b9af6379
AM
2028 if (psym->st_shndx < filedata->file_header.e_shnum
2029 && filedata->section_headers != NULL)
84714f86
AM
2030 sec_name = section_name_print (filedata,
2031 filedata->section_headers
b9e920ec 2032 + psym->st_shndx);
f1ef08cb
AM
2033 else if (psym->st_shndx == SHN_ABS)
2034 sec_name = "ABS";
2035 else if (psym->st_shndx == SHN_COMMON)
2036 sec_name = "COMMON";
dda8d76d 2037 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 2038 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 2039 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 2040 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 2041 sec_name = "SCOMMON";
dda8d76d 2042 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
2043 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
2044 sec_name = "SUNDEF";
dda8d76d
NC
2045 else if ((filedata->file_header.e_machine == EM_X86_64
2046 || filedata->file_header.e_machine == EM_L1OM
2047 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
2048 && psym->st_shndx == SHN_X86_64_LCOMMON)
2049 sec_name = "LARGE_COMMON";
dda8d76d
NC
2050 else if (filedata->file_header.e_machine == EM_IA_64
2051 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
2052 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
2053 sec_name = "ANSI_COM";
dda8d76d 2054 else if (is_ia64_vms (filedata)
148b93f2
NC
2055 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
2056 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
2057 else
2058 {
2059 sprintf (name_buf, "<section 0x%x>",
2060 (unsigned int) psym->st_shndx);
2061 sec_name = name_buf;
2062 }
2063 }
2064 print_symbol (22, sec_name);
2065 }
af3fc3bc 2066 else if (strtab == NULL)
d79b3d50 2067 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2068 else if (psym->st_name >= strtablen)
32ec8896 2069 {
27a45f42
AS
2070 error (_("<corrupt string table index: %3ld>\n"),
2071 psym->st_name);
015dc7e1 2072 res = false;
32ec8896 2073 }
af3fc3bc 2074 else
bb4d2ac2
L
2075 {
2076 print_symbol (22, strtab + psym->st_name);
2077 if (version_string)
2078 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2079 version_string);
2080 }
103f02d3 2081
a7fd1186 2082 if (rel_type == reltype_rela)
171191ba 2083 {
625d49fc 2084 uint64_t off = rels[i].r_addend;
171191ba 2085
625d49fc
AM
2086 if ((int64_t) off < 0)
2087 printf (" - %" PRIx64, -off);
171191ba 2088 else
625d49fc 2089 printf (" + %" PRIx64, off);
171191ba 2090 }
19936277 2091 }
252b5132 2092 }
a7fd1186 2093 else if (rel_type == reltype_rela)
f7a99963 2094 {
625d49fc 2095 uint64_t off = rels[i].r_addend;
e04d7088
L
2096
2097 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
625d49fc
AM
2098 if ((int64_t) off < 0)
2099 printf ("-%" PRIx64, -off);
e04d7088 2100 else
625d49fc 2101 printf ("%" PRIx64, off);
f7a99963 2102 }
252b5132 2103
dda8d76d 2104 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2105 && rtype != NULL
2106 && streq (rtype, "R_SPARC_OLO10"))
26c527e6 2107 printf (" + %" PRIx64, ELF64_R_TYPE_DATA (inf));
351b4b40 2108
252b5132 2109 putchar ('\n');
2c71103e 2110
dda8d76d 2111 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2112 {
625d49fc
AM
2113 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2114 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2115 const char * rtype2 = elf_mips_reloc_type (type2);
2116 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2117
2c71103e
NC
2118 printf (" Type2: ");
2119
2120 if (rtype2 == NULL)
39dbeff8
AM
2121 printf (_("unrecognized: %-7lx"),
2122 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2123 else
2124 printf ("%-17.17s", rtype2);
2125
18bd398b 2126 printf ("\n Type3: ");
2c71103e
NC
2127
2128 if (rtype3 == NULL)
39dbeff8
AM
2129 printf (_("unrecognized: %-7lx"),
2130 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2131 else
2132 printf ("%-17.17s", rtype3);
2133
53c7db4b 2134 putchar ('\n');
2c71103e 2135 }
252b5132
RH
2136 }
2137
c8286bd1 2138 free (rels);
32ec8896
NC
2139
2140 return res;
252b5132
RH
2141}
2142
37c18eed
SD
2143static const char *
2144get_aarch64_dynamic_type (unsigned long type)
2145{
2146 switch (type)
2147 {
2148 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2149 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2150 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2151 default:
2152 return NULL;
2153 }
2154}
2155
252b5132 2156static const char *
d3ba0551 2157get_mips_dynamic_type (unsigned long type)
252b5132
RH
2158{
2159 switch (type)
2160 {
2161 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2162 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2163 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2164 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2165 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2166 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2167 case DT_MIPS_MSYM: return "MIPS_MSYM";
2168 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2169 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2170 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2171 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2172 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2173 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2174 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2175 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2176 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2177 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2178 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2179 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2180 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2181 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2182 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2183 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2184 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2185 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2186 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2187 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2188 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2189 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2190 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2191 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2192 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2193 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2194 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2195 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2196 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2197 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2198 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2199 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2200 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2201 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2202 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2203 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2204 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2205 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2206 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2207 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2208 default:
2209 return NULL;
2210 }
2211}
2212
9a097730 2213static const char *
d3ba0551 2214get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2215{
2216 switch (type)
2217 {
2218 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2219 default:
2220 return NULL;
2221 }
103f02d3
UD
2222}
2223
7490d522
AM
2224static const char *
2225get_ppc_dynamic_type (unsigned long type)
2226{
2227 switch (type)
2228 {
a7f2871e 2229 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2230 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2231 default:
2232 return NULL;
2233 }
2234}
2235
f1cb7e17 2236static const char *
d3ba0551 2237get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2238{
2239 switch (type)
2240 {
a7f2871e
AM
2241 case DT_PPC64_GLINK: return "PPC64_GLINK";
2242 case DT_PPC64_OPD: return "PPC64_OPD";
2243 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2244 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2245 default:
2246 return NULL;
2247 }
2248}
2249
103f02d3 2250static const char *
d3ba0551 2251get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2252{
2253 switch (type)
2254 {
2255 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2256 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2257 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2258 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2259 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2260 case DT_HP_PREINIT: return "HP_PREINIT";
2261 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2262 case DT_HP_NEEDED: return "HP_NEEDED";
2263 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2264 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2265 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2266 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2267 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2268 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2269 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2270 case DT_HP_FILTERED: return "HP_FILTERED";
2271 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2272 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2273 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2274 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2275 case DT_PLT: return "PLT";
2276 case DT_PLT_SIZE: return "PLT_SIZE";
2277 case DT_DLT: return "DLT";
2278 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2279 default:
2280 return NULL;
2281 }
2282}
9a097730 2283
ecc51f48 2284static const char *
d3ba0551 2285get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2286{
2287 switch (type)
2288 {
148b93f2
NC
2289 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2290 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2291 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2292 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2293 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2294 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2295 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2296 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2297 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2298 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2299 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2300 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2301 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2302 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2303 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2304 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2305 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2306 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2307 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2308 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2309 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2310 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2311 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2312 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2313 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2314 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2315 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2316 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2317 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2318 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2319 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2320 default:
2321 return NULL;
2322 }
2323}
2324
fd85a6a1
NC
2325static const char *
2326get_solaris_section_type (unsigned long type)
2327{
2328 switch (type)
2329 {
2330 case 0x6fffffee: return "SUNW_ancillary";
2331 case 0x6fffffef: return "SUNW_capchain";
2332 case 0x6ffffff0: return "SUNW_capinfo";
2333 case 0x6ffffff1: return "SUNW_symsort";
2334 case 0x6ffffff2: return "SUNW_tlssort";
2335 case 0x6ffffff3: return "SUNW_LDYNSYM";
2336 case 0x6ffffff4: return "SUNW_dof";
2337 case 0x6ffffff5: return "SUNW_cap";
2338 case 0x6ffffff6: return "SUNW_SIGNATURE";
2339 case 0x6ffffff7: return "SUNW_ANNOTATE";
2340 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2341 case 0x6ffffff9: return "SUNW_DEBUG";
2342 case 0x6ffffffa: return "SUNW_move";
2343 case 0x6ffffffb: return "SUNW_COMDAT";
2344 case 0x6ffffffc: return "SUNW_syminfo";
2345 case 0x6ffffffd: return "SUNW_verdef";
2346 case 0x6ffffffe: return "SUNW_verneed";
2347 case 0x6fffffff: return "SUNW_versym";
2348 case 0x70000000: return "SPARC_GOTDATA";
2349 default: return NULL;
2350 }
2351}
2352
fabcb361
RH
2353static const char *
2354get_alpha_dynamic_type (unsigned long type)
2355{
2356 switch (type)
2357 {
2358 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2359 default: return NULL;
fabcb361
RH
2360 }
2361}
2362
1c0d3aa6
NC
2363static const char *
2364get_score_dynamic_type (unsigned long type)
2365{
2366 switch (type)
2367 {
2368 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2369 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2370 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2371 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2372 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2373 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2374 default: return NULL;
1c0d3aa6
NC
2375 }
2376}
2377
40b36596
JM
2378static const char *
2379get_tic6x_dynamic_type (unsigned long type)
2380{
2381 switch (type)
2382 {
2383 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2384 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2385 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2386 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2387 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2388 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2389 default: return NULL;
40b36596
JM
2390 }
2391}
1c0d3aa6 2392
36591ba1
SL
2393static const char *
2394get_nios2_dynamic_type (unsigned long type)
2395{
2396 switch (type)
2397 {
2398 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2399 default: return NULL;
36591ba1
SL
2400 }
2401}
2402
fd85a6a1
NC
2403static const char *
2404get_solaris_dynamic_type (unsigned long type)
2405{
2406 switch (type)
2407 {
2408 case 0x6000000d: return "SUNW_AUXILIARY";
2409 case 0x6000000e: return "SUNW_RTLDINF";
2410 case 0x6000000f: return "SUNW_FILTER";
2411 case 0x60000010: return "SUNW_CAP";
2412 case 0x60000011: return "SUNW_SYMTAB";
2413 case 0x60000012: return "SUNW_SYMSZ";
2414 case 0x60000013: return "SUNW_SORTENT";
2415 case 0x60000014: return "SUNW_SYMSORT";
2416 case 0x60000015: return "SUNW_SYMSORTSZ";
2417 case 0x60000016: return "SUNW_TLSSORT";
2418 case 0x60000017: return "SUNW_TLSSORTSZ";
2419 case 0x60000018: return "SUNW_CAPINFO";
2420 case 0x60000019: return "SUNW_STRPAD";
2421 case 0x6000001a: return "SUNW_CAPCHAIN";
2422 case 0x6000001b: return "SUNW_LDMACH";
2423 case 0x6000001d: return "SUNW_CAPCHAINENT";
2424 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2425 case 0x60000021: return "SUNW_PARENT";
2426 case 0x60000023: return "SUNW_ASLR";
2427 case 0x60000025: return "SUNW_RELAX";
2428 case 0x60000029: return "SUNW_NXHEAP";
2429 case 0x6000002b: return "SUNW_NXSTACK";
2430
2431 case 0x70000001: return "SPARC_REGISTER";
2432 case 0x7ffffffd: return "AUXILIARY";
2433 case 0x7ffffffe: return "USED";
2434 case 0x7fffffff: return "FILTER";
2435
15f205b1 2436 default: return NULL;
fd85a6a1
NC
2437 }
2438}
2439
8155b853
NC
2440static const char *
2441get_riscv_dynamic_type (unsigned long type)
2442{
2443 switch (type)
2444 {
2445 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2446 default:
2447 return NULL;
2448 }
2449}
2450
252b5132 2451static const char *
dda8d76d 2452get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2453{
e9e44622 2454 static char buff[64];
252b5132
RH
2455
2456 switch (type)
2457 {
2458 case DT_NULL: return "NULL";
2459 case DT_NEEDED: return "NEEDED";
2460 case DT_PLTRELSZ: return "PLTRELSZ";
2461 case DT_PLTGOT: return "PLTGOT";
2462 case DT_HASH: return "HASH";
2463 case DT_STRTAB: return "STRTAB";
2464 case DT_SYMTAB: return "SYMTAB";
2465 case DT_RELA: return "RELA";
2466 case DT_RELASZ: return "RELASZ";
2467 case DT_RELAENT: return "RELAENT";
2468 case DT_STRSZ: return "STRSZ";
2469 case DT_SYMENT: return "SYMENT";
2470 case DT_INIT: return "INIT";
2471 case DT_FINI: return "FINI";
2472 case DT_SONAME: return "SONAME";
2473 case DT_RPATH: return "RPATH";
2474 case DT_SYMBOLIC: return "SYMBOLIC";
2475 case DT_REL: return "REL";
2476 case DT_RELSZ: return "RELSZ";
2477 case DT_RELENT: return "RELENT";
dd207c13
FS
2478 case DT_RELR: return "RELR";
2479 case DT_RELRSZ: return "RELRSZ";
2480 case DT_RELRENT: return "RELRENT";
252b5132
RH
2481 case DT_PLTREL: return "PLTREL";
2482 case DT_DEBUG: return "DEBUG";
2483 case DT_TEXTREL: return "TEXTREL";
2484 case DT_JMPREL: return "JMPREL";
2485 case DT_BIND_NOW: return "BIND_NOW";
2486 case DT_INIT_ARRAY: return "INIT_ARRAY";
2487 case DT_FINI_ARRAY: return "FINI_ARRAY";
2488 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2489 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2490 case DT_RUNPATH: return "RUNPATH";
2491 case DT_FLAGS: return "FLAGS";
2d0e6f43 2492
d1133906
NC
2493 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2494 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2495 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2496
05107a46 2497 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2498 case DT_PLTPADSZ: return "PLTPADSZ";
2499 case DT_MOVEENT: return "MOVEENT";
2500 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2501 case DT_FEATURE: return "FEATURE";
252b5132
RH
2502 case DT_POSFLAG_1: return "POSFLAG_1";
2503 case DT_SYMINSZ: return "SYMINSZ";
2504 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2505
252b5132 2506 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2507 case DT_CONFIG: return "CONFIG";
2508 case DT_DEPAUDIT: return "DEPAUDIT";
2509 case DT_AUDIT: return "AUDIT";
2510 case DT_PLTPAD: return "PLTPAD";
2511 case DT_MOVETAB: return "MOVETAB";
252b5132 2512 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2513
252b5132 2514 case DT_VERSYM: return "VERSYM";
103f02d3 2515
67a4f2b7
AO
2516 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2517 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2518 case DT_RELACOUNT: return "RELACOUNT";
2519 case DT_RELCOUNT: return "RELCOUNT";
2520 case DT_FLAGS_1: return "FLAGS_1";
2521 case DT_VERDEF: return "VERDEF";
2522 case DT_VERDEFNUM: return "VERDEFNUM";
2523 case DT_VERNEED: return "VERNEED";
2524 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2525
019148e4 2526 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2527 case DT_USED: return "USED";
2528 case DT_FILTER: return "FILTER";
103f02d3 2529
047b2264
JJ
2530 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2531 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2532 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2533 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2534 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2535 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2536 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2537
252b5132
RH
2538 default:
2539 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2540 {
2cf0635d 2541 const char * result;
103f02d3 2542
dda8d76d 2543 switch (filedata->file_header.e_machine)
252b5132 2544 {
37c18eed
SD
2545 case EM_AARCH64:
2546 result = get_aarch64_dynamic_type (type);
2547 break;
252b5132 2548 case EM_MIPS:
4fe85591 2549 case EM_MIPS_RS3_LE:
252b5132
RH
2550 result = get_mips_dynamic_type (type);
2551 break;
9a097730
RH
2552 case EM_SPARCV9:
2553 result = get_sparc64_dynamic_type (type);
2554 break;
7490d522
AM
2555 case EM_PPC:
2556 result = get_ppc_dynamic_type (type);
2557 break;
f1cb7e17
AM
2558 case EM_PPC64:
2559 result = get_ppc64_dynamic_type (type);
2560 break;
ecc51f48
NC
2561 case EM_IA_64:
2562 result = get_ia64_dynamic_type (type);
2563 break;
fabcb361
RH
2564 case EM_ALPHA:
2565 result = get_alpha_dynamic_type (type);
2566 break;
1c0d3aa6
NC
2567 case EM_SCORE:
2568 result = get_score_dynamic_type (type);
2569 break;
40b36596
JM
2570 case EM_TI_C6000:
2571 result = get_tic6x_dynamic_type (type);
2572 break;
36591ba1
SL
2573 case EM_ALTERA_NIOS2:
2574 result = get_nios2_dynamic_type (type);
2575 break;
8155b853
NC
2576 case EM_RISCV:
2577 result = get_riscv_dynamic_type (type);
2578 break;
252b5132 2579 default:
dda8d76d 2580 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2581 result = get_solaris_dynamic_type (type);
2582 else
2583 result = NULL;
252b5132
RH
2584 break;
2585 }
2586
2587 if (result != NULL)
2588 return result;
2589
e9e44622 2590 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2591 }
eec8f817 2592 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2593 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2594 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2595 {
2cf0635d 2596 const char * result;
103f02d3 2597
dda8d76d 2598 switch (filedata->file_header.e_machine)
103f02d3
UD
2599 {
2600 case EM_PARISC:
2601 result = get_parisc_dynamic_type (type);
2602 break;
148b93f2
NC
2603 case EM_IA_64:
2604 result = get_ia64_dynamic_type (type);
2605 break;
103f02d3 2606 default:
dda8d76d 2607 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2608 result = get_solaris_dynamic_type (type);
2609 else
2610 result = NULL;
103f02d3
UD
2611 break;
2612 }
2613
2614 if (result != NULL)
2615 return result;
2616
e9e44622
JJ
2617 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2618 type);
103f02d3 2619 }
252b5132 2620 else
e9e44622 2621 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2622
252b5132
RH
2623 return buff;
2624 }
2625}
2626
93df3340
AM
2627static bool get_program_headers (Filedata *);
2628static bool get_dynamic_section (Filedata *);
2629
2630static void
2631locate_dynamic_section (Filedata *filedata)
2632{
26c527e6 2633 uint64_t dynamic_addr = 0;
be7d229a 2634 uint64_t dynamic_size = 0;
93df3340
AM
2635
2636 if (filedata->file_header.e_phnum != 0
2637 && get_program_headers (filedata))
2638 {
2639 Elf_Internal_Phdr *segment;
2640 unsigned int i;
2641
2642 for (i = 0, segment = filedata->program_headers;
2643 i < filedata->file_header.e_phnum;
2644 i++, segment++)
2645 {
2646 if (segment->p_type == PT_DYNAMIC)
2647 {
2648 dynamic_addr = segment->p_offset;
2649 dynamic_size = segment->p_filesz;
2650
2651 if (filedata->section_headers != NULL)
2652 {
2653 Elf_Internal_Shdr *sec;
2654
2655 sec = find_section (filedata, ".dynamic");
2656 if (sec != NULL)
2657 {
2658 if (sec->sh_size == 0
2659 || sec->sh_type == SHT_NOBITS)
2660 {
2661 dynamic_addr = 0;
2662 dynamic_size = 0;
2663 }
2664 else
2665 {
2666 dynamic_addr = sec->sh_offset;
2667 dynamic_size = sec->sh_size;
2668 }
2669 }
2670 }
2671
2672 if (dynamic_addr > filedata->file_size
2673 || (dynamic_size > filedata->file_size - dynamic_addr))
2674 {
2675 dynamic_addr = 0;
2676 dynamic_size = 0;
2677 }
2678 break;
2679 }
2680 }
2681 }
2682 filedata->dynamic_addr = dynamic_addr;
2683 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2684}
2685
2686static bool
2687is_pie (Filedata *filedata)
2688{
2689 Elf_Internal_Dyn *entry;
2690
2691 if (filedata->dynamic_size == 0)
2692 locate_dynamic_section (filedata);
2693 if (filedata->dynamic_size <= 1)
2694 return false;
2695
2696 if (!get_dynamic_section (filedata))
2697 return false;
2698
2699 for (entry = filedata->dynamic_section;
2700 entry < filedata->dynamic_section + filedata->dynamic_nent;
2701 entry++)
2702 {
2703 if (entry->d_tag == DT_FLAGS_1)
2704 {
2705 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2706 return true;
2707 break;
2708 }
2709 }
2710 return false;
2711}
2712
252b5132 2713static char *
93df3340 2714get_file_type (Filedata *filedata)
252b5132 2715{
93df3340 2716 unsigned e_type = filedata->file_header.e_type;
89246a0e 2717 static char buff[64];
252b5132
RH
2718
2719 switch (e_type)
2720 {
32ec8896
NC
2721 case ET_NONE: return _("NONE (None)");
2722 case ET_REL: return _("REL (Relocatable file)");
2723 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2724 case ET_DYN:
2725 if (is_pie (filedata))
2726 return _("DYN (Position-Independent Executable file)");
2727 else
2728 return _("DYN (Shared object file)");
32ec8896 2729 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2730
2731 default:
2732 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2733 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2734 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2735 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2736 else
e9e44622 2737 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2738 return buff;
2739 }
2740}
2741
2742static char *
d3ba0551 2743get_machine_name (unsigned e_machine)
252b5132 2744{
b34976b6 2745 static char buff[64]; /* XXX */
252b5132
RH
2746
2747 switch (e_machine)
2748 {
55e22ca8
NC
2749 /* Please keep this switch table sorted by increasing EM_ value. */
2750 /* 0 */
c45021f2
NC
2751 case EM_NONE: return _("None");
2752 case EM_M32: return "WE32100";
2753 case EM_SPARC: return "Sparc";
2754 case EM_386: return "Intel 80386";
2755 case EM_68K: return "MC68000";
2756 case EM_88K: return "MC88000";
22abe556 2757 case EM_IAMCU: return "Intel MCU";
fb70ec17 2758 case EM_860: return "Intel 80860";
c45021f2
NC
2759 case EM_MIPS: return "MIPS R3000";
2760 case EM_S370: return "IBM System/370";
55e22ca8 2761 /* 10 */
7036c0e1 2762 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2763 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2764 case EM_PARISC: return "HPPA";
55e22ca8 2765 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2766 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2767 case EM_960: return "Intel 80960";
c45021f2 2768 case EM_PPC: return "PowerPC";
55e22ca8 2769 /* 20 */
285d1771 2770 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2771 case EM_S390_OLD:
2772 case EM_S390: return "IBM S/390";
2773 case EM_SPU: return "SPU";
2774 /* 30 */
2775 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2776 case EM_FR20: return "Fujitsu FR20";
2777 case EM_RH32: return "TRW RH32";
b34976b6 2778 case EM_MCORE: return "MCORE";
55e22ca8 2779 /* 40 */
7036c0e1
AJ
2780 case EM_ARM: return "ARM";
2781 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2782 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2783 case EM_SPARCV9: return "Sparc v9";
2784 case EM_TRICORE: return "Siemens Tricore";
584da044 2785 case EM_ARC: return "ARC";
c2dcd04e
NC
2786 case EM_H8_300: return "Renesas H8/300";
2787 case EM_H8_300H: return "Renesas H8/300H";
2788 case EM_H8S: return "Renesas H8S";
2789 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2790 /* 50 */
30800947 2791 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2792 case EM_MIPS_X: return "Stanford MIPS-X";
2793 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2794 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2795 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2796 case EM_PCP: return "Siemens PCP";
2797 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2798 case EM_NDR1: return "Denso NDR1 microprocesspr";
2799 case EM_STARCORE: return "Motorola Star*Core processor";
2800 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2801 /* 60 */
7036c0e1
AJ
2802 case EM_ST100: return "STMicroelectronics ST100 processor";
2803 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2804 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2805 case EM_PDSP: return "Sony DSP processor";
2806 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2807 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2808 case EM_FX66: return "Siemens FX66 microcontroller";
2809 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2810 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2811 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2812 /* 70 */
7036c0e1
AJ
2813 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2814 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2815 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2816 case EM_SVX: return "Silicon Graphics SVx";
2817 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2818 case EM_VAX: return "Digital VAX";
1b61cf92 2819 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2820 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2821 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2822 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2823 /* 80 */
b34976b6 2824 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2825 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2826 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2827 case EM_AVR_OLD:
2828 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2829 case EM_CYGNUS_FR30:
2830 case EM_FR30: return "Fujitsu FR30";
2831 case EM_CYGNUS_D10V:
2832 case EM_D10V: return "d10v";
2833 case EM_CYGNUS_D30V:
2834 case EM_D30V: return "d30v";
2835 case EM_CYGNUS_V850:
2836 case EM_V850: return "Renesas V850";
2837 case EM_CYGNUS_M32R:
2838 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2839 case EM_CYGNUS_MN10300:
2840 case EM_MN10300: return "mn10300";
2841 /* 90 */
2842 case EM_CYGNUS_MN10200:
2843 case EM_MN10200: return "mn10200";
2844 case EM_PJ: return "picoJava";
73589c9d 2845 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2846 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2847 case EM_XTENSA_OLD:
2848 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2849 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2850 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2851 case EM_NS32K: return "National Semiconductor 32000 series";
2852 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2853 case EM_SNP1K: return "Trebia SNP 1000 processor";
2854 /* 100 */
9abca702 2855 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2856 case EM_IP2K_OLD:
2857 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2858 case EM_MAX: return "MAX Processor";
2859 case EM_CR: return "National Semiconductor CompactRISC";
2860 case EM_F2MC16: return "Fujitsu F2MC16";
2861 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2862 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2863 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2864 case EM_SEP: return "Sharp embedded microprocessor";
2865 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2866 /* 110 */
11636f9e
JM
2867 case EM_UNICORE: return "Unicore";
2868 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2869 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2870 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2871 case EM_CRX: return "National Semiconductor CRX microprocessor";
2872 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2873 case EM_C166:
d70c5fc7 2874 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2875 case EM_M16C: return "Renesas M16C series microprocessors";
2876 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2877 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2878 /* 120 */
2879 case EM_M32C: return "Renesas M32c";
2880 /* 130 */
11636f9e
JM
2881 case EM_TSK3000: return "Altium TSK3000 core";
2882 case EM_RS08: return "Freescale RS08 embedded processor";
2883 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2884 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2885 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2886 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2887 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2888 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2889 /* 140 */
11636f9e
JM
2890 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2891 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2892 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2893 case EM_TI_PRU: return "TI PRU I/O processor";
2894 /* 160 */
11636f9e
JM
2895 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2896 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2897 case EM_R32C: return "Renesas R32C series microprocessors";
2898 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2899 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2900 case EM_8051: return "Intel 8051 and variants";
2901 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2902 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2903 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2904 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2905 /* 170 */
11636f9e
JM
2906 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2907 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2908 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2909 case EM_RX: return "Renesas RX";
a3c62988 2910 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2911 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2912 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2913 case EM_CR16:
2914 case EM_MICROBLAZE:
2915 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2916 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2917 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2918 /* 180 */
2919 case EM_L1OM: return "Intel L1OM";
2920 case EM_K1OM: return "Intel K1OM";
2921 case EM_INTEL182: return "Intel (reserved)";
2922 case EM_AARCH64: return "AArch64";
2923 case EM_ARM184: return "ARM (reserved)";
2924 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2925 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2926 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2927 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2928 /* 190 */
11636f9e 2929 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2930 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2931 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2932 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2933 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2934 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2935 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2936 case EM_RL78: return "Renesas RL78";
6d913794 2937 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2938 case EM_78K0R: return "Renesas 78K0R";
2939 /* 200 */
6d913794 2940 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2941 case EM_BA1: return "Beyond BA1 CPU architecture";
2942 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2943 case EM_XCORE: return "XMOS xCORE processor family";
2944 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2945 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2946 /* 210 */
6d913794
NC
2947 case EM_KM32: return "KM211 KM32 32-bit processor";
2948 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2949 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2950 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2951 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2952 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2953 case EM_COGE: return "Cognitive Smart Memory Processor";
2954 case EM_COOL: return "Bluechip Systems CoolEngine";
2955 case EM_NORC: return "Nanoradio Optimized RISC";
2956 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2957 /* 220 */
15f205b1 2958 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2959 case EM_VISIUM: return "CDS VISIUMcore processor";
2960 case EM_FT32: return "FTDI Chip FT32";
2961 case EM_MOXIE: return "Moxie";
2962 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2963 /* 230 (all reserved) */
2964 /* 240 */
55e22ca8
NC
2965 case EM_RISCV: return "RISC-V";
2966 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2967 case EM_CEVA: return "CEVA Processor Architecture Family";
2968 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2969 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2970 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2971 case EM_IMG1: return "Imagination Technologies";
2972 /* 250 */
fe944acf 2973 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2974 case EM_VE: return "NEC Vector Engine";
2975 case EM_CSKY: return "C-SKY";
13aa307c 2976 case EM_ARC_COMPACT3_64: return "Synopsys ARCv3 64-bit processor";
4cf2ad72 2977 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
13aa307c 2978 case EM_ARC_COMPACT3: return "Synopsys ARCv3 32-bit processor";
4cf2ad72
CC
2979 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2980 case EM_65816: return "WDC 65816/65C816";
01a8c731 2981 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2982 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2983
2984 /* Large numbers... */
2985 case EM_MT: return "Morpho Techologies MT processor";
2986 case EM_ALPHA: return "Alpha";
2987 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2988 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2989 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2990 case EM_IQ2000: return "Vitesse IQ2000";
2991 case EM_M32C_OLD:
2992 case EM_NIOS32: return "Altera Nios";
2993 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2994 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2995 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2996 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2997
252b5132 2998 default:
35d9dd2f 2999 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
3000 return buff;
3001 }
3002}
3003
a9522a21
AB
3004static void
3005decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
3006{
3007 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3008 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3009 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3010 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3011 architectures.
3012
3013 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3014 but also sets a specific architecture type in the e_flags field.
3015
3016 However, when decoding the flags we don't worry if we see an
3017 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3018 ARCEM architecture type. */
3019
3020 switch (e_flags & EF_ARC_MACH_MSK)
3021 {
3022 /* We only expect these to occur for EM_ARC_COMPACT2. */
3023 case EF_ARC_CPU_ARCV2EM:
3024 strcat (buf, ", ARC EM");
3025 break;
3026 case EF_ARC_CPU_ARCV2HS:
3027 strcat (buf, ", ARC HS");
3028 break;
3029
3030 /* We only expect these to occur for EM_ARC_COMPACT. */
3031 case E_ARC_MACH_ARC600:
3032 strcat (buf, ", ARC600");
3033 break;
3034 case E_ARC_MACH_ARC601:
3035 strcat (buf, ", ARC601");
3036 break;
3037 case E_ARC_MACH_ARC700:
3038 strcat (buf, ", ARC700");
3039 break;
3040
3041 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3042 new ELF with new architecture being read by an old version of
3043 readelf, or (c) An ELF built with non-GNU compiler that does not
3044 set the architecture in the e_flags. */
3045 default:
3046 if (e_machine == EM_ARC_COMPACT)
3047 strcat (buf, ", Unknown ARCompact");
3048 else
3049 strcat (buf, ", Unknown ARC");
3050 break;
3051 }
3052
3053 switch (e_flags & EF_ARC_OSABI_MSK)
3054 {
3055 case E_ARC_OSABI_ORIG:
3056 strcat (buf, ", (ABI:legacy)");
3057 break;
3058 case E_ARC_OSABI_V2:
3059 strcat (buf, ", (ABI:v2)");
3060 break;
3061 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3062 case E_ARC_OSABI_V3:
3063 strcat (buf, ", v3 no-legacy-syscalls ABI");
3064 break;
53a346d8
CZ
3065 case E_ARC_OSABI_V4:
3066 strcat (buf, ", v4 ABI");
3067 break;
a9522a21
AB
3068 default:
3069 strcat (buf, ", unrecognised ARC OSABI flag");
3070 break;
3071 }
3072}
3073
f3485b74 3074static void
d3ba0551 3075decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
3076{
3077 unsigned eabi;
015dc7e1 3078 bool unknown = false;
f3485b74
NC
3079
3080 eabi = EF_ARM_EABI_VERSION (e_flags);
3081 e_flags &= ~ EF_ARM_EABIMASK;
3082
3083 /* Handle "generic" ARM flags. */
3084 if (e_flags & EF_ARM_RELEXEC)
3085 {
3086 strcat (buf, ", relocatable executable");
3087 e_flags &= ~ EF_ARM_RELEXEC;
3088 }
76da6bbe 3089
18a20338
CL
3090 if (e_flags & EF_ARM_PIC)
3091 {
3092 strcat (buf, ", position independent");
3093 e_flags &= ~ EF_ARM_PIC;
3094 }
3095
f3485b74
NC
3096 /* Now handle EABI specific flags. */
3097 switch (eabi)
3098 {
3099 default:
2c71103e 3100 strcat (buf, ", <unrecognized EABI>");
f3485b74 3101 if (e_flags)
015dc7e1 3102 unknown = true;
f3485b74
NC
3103 break;
3104
3105 case EF_ARM_EABI_VER1:
a5bcd848 3106 strcat (buf, ", Version1 EABI");
f3485b74
NC
3107 while (e_flags)
3108 {
3109 unsigned flag;
76da6bbe 3110
f3485b74
NC
3111 /* Process flags one bit at a time. */
3112 flag = e_flags & - e_flags;
3113 e_flags &= ~ flag;
76da6bbe 3114
f3485b74
NC
3115 switch (flag)
3116 {
a5bcd848 3117 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
3118 strcat (buf, ", sorted symbol tables");
3119 break;
76da6bbe 3120
f3485b74 3121 default:
015dc7e1 3122 unknown = true;
f3485b74
NC
3123 break;
3124 }
3125 }
3126 break;
76da6bbe 3127
a5bcd848
PB
3128 case EF_ARM_EABI_VER2:
3129 strcat (buf, ", Version2 EABI");
3130 while (e_flags)
3131 {
3132 unsigned flag;
3133
3134 /* Process flags one bit at a time. */
3135 flag = e_flags & - e_flags;
3136 e_flags &= ~ flag;
3137
3138 switch (flag)
3139 {
3140 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3141 strcat (buf, ", sorted symbol tables");
3142 break;
3143
3144 case EF_ARM_DYNSYMSUSESEGIDX:
3145 strcat (buf, ", dynamic symbols use segment index");
3146 break;
3147
3148 case EF_ARM_MAPSYMSFIRST:
3149 strcat (buf, ", mapping symbols precede others");
3150 break;
3151
3152 default:
015dc7e1 3153 unknown = true;
a5bcd848
PB
3154 break;
3155 }
3156 }
3157 break;
3158
d507cf36
PB
3159 case EF_ARM_EABI_VER3:
3160 strcat (buf, ", Version3 EABI");
8cb51566
PB
3161 break;
3162
3163 case EF_ARM_EABI_VER4:
3164 strcat (buf, ", Version4 EABI");
3bfcb652
NC
3165 while (e_flags)
3166 {
3167 unsigned flag;
3168
3169 /* Process flags one bit at a time. */
3170 flag = e_flags & - e_flags;
3171 e_flags &= ~ flag;
3172
3173 switch (flag)
3174 {
3175 case EF_ARM_BE8:
3176 strcat (buf, ", BE8");
3177 break;
3178
3179 case EF_ARM_LE8:
3180 strcat (buf, ", LE8");
3181 break;
3182
3183 default:
015dc7e1 3184 unknown = true;
3bfcb652
NC
3185 break;
3186 }
3bfcb652
NC
3187 }
3188 break;
3a4a14e9
PB
3189
3190 case EF_ARM_EABI_VER5:
3191 strcat (buf, ", Version5 EABI");
d507cf36
PB
3192 while (e_flags)
3193 {
3194 unsigned flag;
3195
3196 /* Process flags one bit at a time. */
3197 flag = e_flags & - e_flags;
3198 e_flags &= ~ flag;
3199
3200 switch (flag)
3201 {
3202 case EF_ARM_BE8:
3203 strcat (buf, ", BE8");
3204 break;
3205
3206 case EF_ARM_LE8:
3207 strcat (buf, ", LE8");
3208 break;
3209
3bfcb652
NC
3210 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3211 strcat (buf, ", soft-float ABI");
3212 break;
3213
3214 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3215 strcat (buf, ", hard-float ABI");
3216 break;
3217
d507cf36 3218 default:
015dc7e1 3219 unknown = true;
d507cf36
PB
3220 break;
3221 }
3222 }
3223 break;
3224
f3485b74 3225 case EF_ARM_EABI_UNKNOWN:
a5bcd848 3226 strcat (buf, ", GNU EABI");
f3485b74
NC
3227 while (e_flags)
3228 {
3229 unsigned flag;
76da6bbe 3230
f3485b74
NC
3231 /* Process flags one bit at a time. */
3232 flag = e_flags & - e_flags;
3233 e_flags &= ~ flag;
76da6bbe 3234
f3485b74
NC
3235 switch (flag)
3236 {
a5bcd848 3237 case EF_ARM_INTERWORK:
f3485b74
NC
3238 strcat (buf, ", interworking enabled");
3239 break;
76da6bbe 3240
a5bcd848 3241 case EF_ARM_APCS_26:
f3485b74
NC
3242 strcat (buf, ", uses APCS/26");
3243 break;
76da6bbe 3244
a5bcd848 3245 case EF_ARM_APCS_FLOAT:
f3485b74
NC
3246 strcat (buf, ", uses APCS/float");
3247 break;
76da6bbe 3248
a5bcd848 3249 case EF_ARM_PIC:
f3485b74
NC
3250 strcat (buf, ", position independent");
3251 break;
76da6bbe 3252
a5bcd848 3253 case EF_ARM_ALIGN8:
f3485b74
NC
3254 strcat (buf, ", 8 bit structure alignment");
3255 break;
76da6bbe 3256
a5bcd848 3257 case EF_ARM_NEW_ABI:
f3485b74
NC
3258 strcat (buf, ", uses new ABI");
3259 break;
76da6bbe 3260
a5bcd848 3261 case EF_ARM_OLD_ABI:
f3485b74
NC
3262 strcat (buf, ", uses old ABI");
3263 break;
76da6bbe 3264
a5bcd848 3265 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
3266 strcat (buf, ", software FP");
3267 break;
76da6bbe 3268
90e01f86
ILT
3269 case EF_ARM_VFP_FLOAT:
3270 strcat (buf, ", VFP");
3271 break;
3272
fde78edd
NC
3273 case EF_ARM_MAVERICK_FLOAT:
3274 strcat (buf, ", Maverick FP");
3275 break;
3276
f3485b74 3277 default:
015dc7e1 3278 unknown = true;
f3485b74
NC
3279 break;
3280 }
3281 }
3282 }
f3485b74
NC
3283
3284 if (unknown)
2b692964 3285 strcat (buf,_(", <unknown>"));
f3485b74
NC
3286}
3287
343433df
AB
3288static void
3289decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
3290{
3291 --size; /* Leave space for null terminator. */
3292
3293 switch (e_flags & EF_AVR_MACH)
3294 {
3295 case E_AVR_MACH_AVR1:
3296 strncat (buf, ", avr:1", size);
3297 break;
3298 case E_AVR_MACH_AVR2:
3299 strncat (buf, ", avr:2", size);
3300 break;
3301 case E_AVR_MACH_AVR25:
3302 strncat (buf, ", avr:25", size);
3303 break;
3304 case E_AVR_MACH_AVR3:
3305 strncat (buf, ", avr:3", size);
3306 break;
3307 case E_AVR_MACH_AVR31:
3308 strncat (buf, ", avr:31", size);
3309 break;
3310 case E_AVR_MACH_AVR35:
3311 strncat (buf, ", avr:35", size);
3312 break;
3313 case E_AVR_MACH_AVR4:
3314 strncat (buf, ", avr:4", size);
3315 break;
3316 case E_AVR_MACH_AVR5:
3317 strncat (buf, ", avr:5", size);
3318 break;
3319 case E_AVR_MACH_AVR51:
3320 strncat (buf, ", avr:51", size);
3321 break;
3322 case E_AVR_MACH_AVR6:
3323 strncat (buf, ", avr:6", size);
3324 break;
3325 case E_AVR_MACH_AVRTINY:
3326 strncat (buf, ", avr:100", size);
3327 break;
3328 case E_AVR_MACH_XMEGA1:
3329 strncat (buf, ", avr:101", size);
3330 break;
3331 case E_AVR_MACH_XMEGA2:
3332 strncat (buf, ", avr:102", size);
3333 break;
3334 case E_AVR_MACH_XMEGA3:
3335 strncat (buf, ", avr:103", size);
3336 break;
3337 case E_AVR_MACH_XMEGA4:
3338 strncat (buf, ", avr:104", size);
3339 break;
3340 case E_AVR_MACH_XMEGA5:
3341 strncat (buf, ", avr:105", size);
3342 break;
3343 case E_AVR_MACH_XMEGA6:
3344 strncat (buf, ", avr:106", size);
3345 break;
3346 case E_AVR_MACH_XMEGA7:
3347 strncat (buf, ", avr:107", size);
3348 break;
3349 default:
3350 strncat (buf, ", avr:<unknown>", size);
3351 break;
3352 }
3353
3354 size -= strlen (buf);
3355 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3356 strncat (buf, ", link-relax", size);
3357}
3358
35c08157
KLC
3359static void
3360decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
3361{
3362 unsigned abi;
3363 unsigned arch;
3364 unsigned config;
3365 unsigned version;
015dc7e1 3366 bool has_fpu = false;
32ec8896 3367 unsigned int r = 0;
35c08157
KLC
3368
3369 static const char *ABI_STRINGS[] =
3370 {
3371 "ABI v0", /* use r5 as return register; only used in N1213HC */
3372 "ABI v1", /* use r0 as return register */
3373 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3374 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3375 "AABI",
3376 "ABI2 FP+"
35c08157
KLC
3377 };
3378 static const char *VER_STRINGS[] =
3379 {
3380 "Andes ELF V1.3 or older",
3381 "Andes ELF V1.3.1",
3382 "Andes ELF V1.4"
3383 };
3384 static const char *ARCH_STRINGS[] =
3385 {
3386 "",
3387 "Andes Star v1.0",
3388 "Andes Star v2.0",
3389 "Andes Star v3.0",
3390 "Andes Star v3.0m"
3391 };
3392
3393 abi = EF_NDS_ABI & e_flags;
3394 arch = EF_NDS_ARCH & e_flags;
3395 config = EF_NDS_INST & e_flags;
3396 version = EF_NDS32_ELF_VERSION & e_flags;
3397
3398 memset (buf, 0, size);
3399
3400 switch (abi)
3401 {
3402 case E_NDS_ABI_V0:
3403 case E_NDS_ABI_V1:
3404 case E_NDS_ABI_V2:
3405 case E_NDS_ABI_V2FP:
3406 case E_NDS_ABI_AABI:
40c7a7cb 3407 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3408 /* In case there are holes in the array. */
3409 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3410 break;
3411
3412 default:
3413 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3414 break;
3415 }
3416
3417 switch (version)
3418 {
3419 case E_NDS32_ELF_VER_1_2:
3420 case E_NDS32_ELF_VER_1_3:
3421 case E_NDS32_ELF_VER_1_4:
3422 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3423 break;
3424
3425 default:
3426 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3427 break;
3428 }
3429
3430 if (E_NDS_ABI_V0 == abi)
3431 {
3432 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3433 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3434 if (arch == E_NDS_ARCH_STAR_V1_0)
3435 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3436 return;
3437 }
3438
3439 switch (arch)
3440 {
3441 case E_NDS_ARCH_STAR_V1_0:
3442 case E_NDS_ARCH_STAR_V2_0:
3443 case E_NDS_ARCH_STAR_V3_0:
3444 case E_NDS_ARCH_STAR_V3_M:
3445 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3446 break;
3447
3448 default:
3449 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3450 /* ARCH version determines how the e_flags are interpreted.
3451 If it is unknown, we cannot proceed. */
3452 return;
3453 }
3454
3455 /* Newer ABI; Now handle architecture specific flags. */
3456 if (arch == E_NDS_ARCH_STAR_V1_0)
3457 {
3458 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3459 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3460
3461 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3462 r += snprintf (buf + r, size -r, ", MAC");
3463
3464 if (config & E_NDS32_HAS_DIV_INST)
3465 r += snprintf (buf + r, size -r, ", DIV");
3466
3467 if (config & E_NDS32_HAS_16BIT_INST)
3468 r += snprintf (buf + r, size -r, ", 16b");
3469 }
3470 else
3471 {
3472 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3473 {
3474 if (version <= E_NDS32_ELF_VER_1_3)
3475 r += snprintf (buf + r, size -r, ", [B8]");
3476 else
3477 r += snprintf (buf + r, size -r, ", EX9");
3478 }
3479
3480 if (config & E_NDS32_HAS_MAC_DX_INST)
3481 r += snprintf (buf + r, size -r, ", MAC_DX");
3482
3483 if (config & E_NDS32_HAS_DIV_DX_INST)
3484 r += snprintf (buf + r, size -r, ", DIV_DX");
3485
3486 if (config & E_NDS32_HAS_16BIT_INST)
3487 {
3488 if (version <= E_NDS32_ELF_VER_1_3)
3489 r += snprintf (buf + r, size -r, ", 16b");
3490 else
3491 r += snprintf (buf + r, size -r, ", IFC");
3492 }
3493 }
3494
3495 if (config & E_NDS32_HAS_EXT_INST)
3496 r += snprintf (buf + r, size -r, ", PERF1");
3497
3498 if (config & E_NDS32_HAS_EXT2_INST)
3499 r += snprintf (buf + r, size -r, ", PERF2");
3500
3501 if (config & E_NDS32_HAS_FPU_INST)
3502 {
015dc7e1 3503 has_fpu = true;
35c08157
KLC
3504 r += snprintf (buf + r, size -r, ", FPU_SP");
3505 }
3506
3507 if (config & E_NDS32_HAS_FPU_DP_INST)
3508 {
015dc7e1 3509 has_fpu = true;
35c08157
KLC
3510 r += snprintf (buf + r, size -r, ", FPU_DP");
3511 }
3512
3513 if (config & E_NDS32_HAS_FPU_MAC_INST)
3514 {
015dc7e1 3515 has_fpu = true;
35c08157
KLC
3516 r += snprintf (buf + r, size -r, ", FPU_MAC");
3517 }
3518
3519 if (has_fpu)
3520 {
3521 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3522 {
3523 case E_NDS32_FPU_REG_8SP_4DP:
3524 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3525 break;
3526 case E_NDS32_FPU_REG_16SP_8DP:
3527 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3528 break;
3529 case E_NDS32_FPU_REG_32SP_16DP:
3530 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3531 break;
3532 case E_NDS32_FPU_REG_32SP_32DP:
3533 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3534 break;
3535 }
3536 }
3537
3538 if (config & E_NDS32_HAS_AUDIO_INST)
3539 r += snprintf (buf + r, size -r, ", AUDIO");
3540
3541 if (config & E_NDS32_HAS_STRING_INST)
3542 r += snprintf (buf + r, size -r, ", STR");
3543
3544 if (config & E_NDS32_HAS_REDUCED_REGS)
3545 r += snprintf (buf + r, size -r, ", 16REG");
3546
3547 if (config & E_NDS32_HAS_VIDEO_INST)
3548 {
3549 if (version <= E_NDS32_ELF_VER_1_3)
3550 r += snprintf (buf + r, size -r, ", VIDEO");
3551 else
3552 r += snprintf (buf + r, size -r, ", SATURATION");
3553 }
3554
3555 if (config & E_NDS32_HAS_ENCRIPT_INST)
3556 r += snprintf (buf + r, size -r, ", ENCRP");
3557
3558 if (config & E_NDS32_HAS_L2C_INST)
3559 r += snprintf (buf + r, size -r, ", L2C");
3560}
3561
c077c580
SM
3562static void
3563decode_AMDGPU_machine_flags (Filedata *filedata, unsigned int e_flags,
3564 char *buf)
3565{
3566 unsigned char *e_ident = filedata->file_header.e_ident;
3567 unsigned char osabi = e_ident[EI_OSABI];
3568 unsigned char abiversion = e_ident[EI_ABIVERSION];
3569 unsigned int mach;
3570
3571 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
3572 it has been deprecated for a while.
3573
3574 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
3575 of writing, they use the same flags as HSA v3, so the code below uses that
3576 assumption. */
3577 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
3578 return;
3579
3580 mach = e_flags & EF_AMDGPU_MACH;
3581 switch (mach)
3582 {
3583#define AMDGPU_CASE(code, string) \
3584 case code: strcat (buf, ", " string); break;
3585 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
3586 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
3587 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
3588 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
3589 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
3590 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
3591 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
3592 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
3593 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
3594 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
3595 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
3596 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
3597 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
3598 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
3599 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
3600 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
3601 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
3602 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
3603 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
3604 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
3605 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
3606 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
3607 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
3608 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
3609 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
3610 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
3611 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
3612 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
3613 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
3614 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
3615 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
3616 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
3617 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
3618 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
3619 default:
3620 sprintf (buf, _(", <unknown AMDGPU GPU type: %#x>"), mach);
3621 break;
3622#undef AMDGPU_CASE
3623 }
3624
3625 buf += strlen (buf);
3626 e_flags &= ~EF_AMDGPU_MACH;
3627
3628 if ((osabi == ELFOSABI_AMDGPU_HSA
3629 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
3630 || osabi != ELFOSABI_AMDGPU_HSA)
3631 {
3632 /* For HSA v3 and other OS ABIs. */
3633 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
3634 {
3635 strcat (buf, ", xnack on");
3636 buf += strlen (buf);
3637 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
3638 }
3639
3640 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
3641 {
3642 strcat (buf, ", sramecc on");
3643 buf += strlen (buf);
3644 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
3645 }
3646 }
3647 else
3648 {
3649 /* For HSA v4+. */
3650 int xnack, sramecc;
3651
3652 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
3653 switch (xnack)
3654 {
3655 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
3656 break;
3657
3658 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
3659 strcat (buf, ", xnack any");
3660 break;
3661
3662 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
3663 strcat (buf, ", xnack off");
3664 break;
3665
3666 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
3667 strcat (buf, ", xnack on");
3668 break;
3669
3670 default:
3671 sprintf (buf, _(", <unknown xnack value: %#x>"), xnack);
3672 break;
3673 }
3674
3675 buf += strlen (buf);
3676 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
3677
3678 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
3679 switch (sramecc)
3680 {
3681 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
3682 break;
3683
3684 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
3685 strcat (buf, ", sramecc any");
3686 break;
3687
3688 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
3689 strcat (buf, ", sramecc off");
3690 break;
3691
3692 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
3693 strcat (buf, ", sramecc on");
3694 break;
3695
3696 default:
3697 sprintf (buf, _(", <unknown sramecc value: %#x>"), sramecc);
3698 break;
3699 }
3700
3701 buf += strlen (buf);
3702 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
3703 }
3704
3705 if (e_flags != 0)
3706 sprintf (buf, _(", unknown flags bits: %#x"), e_flags);
3707}
3708
252b5132 3709static char *
dda8d76d 3710get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3711{
b34976b6 3712 static char buf[1024];
252b5132
RH
3713
3714 buf[0] = '\0';
76da6bbe 3715
252b5132
RH
3716 if (e_flags)
3717 {
3718 switch (e_machine)
3719 {
3720 default:
3721 break;
3722
13aa307c
CZ
3723 case EM_ARC_COMPACT3:
3724 strcat (buf, ", HS5x");
3725 break;
3726
3727 case EM_ARC_COMPACT3_64:
3728 strcat (buf, ", HS6x");
3729 break;
3730
886a2506 3731 case EM_ARC_COMPACT2:
886a2506 3732 case EM_ARC_COMPACT:
a9522a21
AB
3733 decode_ARC_machine_flags (e_flags, e_machine, buf);
3734 break;
886a2506 3735
f3485b74
NC
3736 case EM_ARM:
3737 decode_ARM_machine_flags (e_flags, buf);
3738 break;
76da6bbe 3739
343433df
AB
3740 case EM_AVR:
3741 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3742 break;
3743
781303ce
MF
3744 case EM_BLACKFIN:
3745 if (e_flags & EF_BFIN_PIC)
3746 strcat (buf, ", PIC");
3747
3748 if (e_flags & EF_BFIN_FDPIC)
3749 strcat (buf, ", FDPIC");
3750
3751 if (e_flags & EF_BFIN_CODE_IN_L1)
3752 strcat (buf, ", code in L1");
3753
3754 if (e_flags & EF_BFIN_DATA_IN_L1)
3755 strcat (buf, ", data in L1");
3756
3757 break;
3758
ec2dfb42
AO
3759 case EM_CYGNUS_FRV:
3760 switch (e_flags & EF_FRV_CPU_MASK)
3761 {
3762 case EF_FRV_CPU_GENERIC:
3763 break;
3764
3765 default:
3766 strcat (buf, ", fr???");
3767 break;
57346661 3768
ec2dfb42
AO
3769 case EF_FRV_CPU_FR300:
3770 strcat (buf, ", fr300");
3771 break;
3772
3773 case EF_FRV_CPU_FR400:
3774 strcat (buf, ", fr400");
3775 break;
3776 case EF_FRV_CPU_FR405:
3777 strcat (buf, ", fr405");
3778 break;
3779
3780 case EF_FRV_CPU_FR450:
3781 strcat (buf, ", fr450");
3782 break;
3783
3784 case EF_FRV_CPU_FR500:
3785 strcat (buf, ", fr500");
3786 break;
3787 case EF_FRV_CPU_FR550:
3788 strcat (buf, ", fr550");
3789 break;
3790
3791 case EF_FRV_CPU_SIMPLE:
3792 strcat (buf, ", simple");
3793 break;
3794 case EF_FRV_CPU_TOMCAT:
3795 strcat (buf, ", tomcat");
3796 break;
3797 }
1c877e87 3798 break;
ec2dfb42 3799
53c7db4b 3800 case EM_68K:
425c6cb0 3801 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3802 strcat (buf, ", m68000");
425c6cb0 3803 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3804 strcat (buf, ", cpu32");
3805 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3806 strcat (buf, ", fido_a");
425c6cb0 3807 else
266abb8f 3808 {
2cf0635d
NC
3809 char const * isa = _("unknown");
3810 char const * mac = _("unknown mac");
3811 char const * additional = NULL;
0112cd26 3812
c694fd50 3813 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3814 {
c694fd50 3815 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3816 isa = "A";
3817 additional = ", nodiv";
3818 break;
c694fd50 3819 case EF_M68K_CF_ISA_A:
266abb8f
NS
3820 isa = "A";
3821 break;
c694fd50 3822 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3823 isa = "A+";
3824 break;
c694fd50 3825 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3826 isa = "B";
3827 additional = ", nousp";
3828 break;
c694fd50 3829 case EF_M68K_CF_ISA_B:
266abb8f
NS
3830 isa = "B";
3831 break;
f608cd77
NS
3832 case EF_M68K_CF_ISA_C:
3833 isa = "C";
3834 break;
3835 case EF_M68K_CF_ISA_C_NODIV:
3836 isa = "C";
3837 additional = ", nodiv";
3838 break;
266abb8f
NS
3839 }
3840 strcat (buf, ", cf, isa ");
3841 strcat (buf, isa);
0b2e31dc
NS
3842 if (additional)
3843 strcat (buf, additional);
c694fd50 3844 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3845 strcat (buf, ", float");
c694fd50 3846 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3847 {
3848 case 0:
3849 mac = NULL;
3850 break;
c694fd50 3851 case EF_M68K_CF_MAC:
266abb8f
NS
3852 mac = "mac";
3853 break;
c694fd50 3854 case EF_M68K_CF_EMAC:
266abb8f
NS
3855 mac = "emac";
3856 break;
f608cd77
NS
3857 case EF_M68K_CF_EMAC_B:
3858 mac = "emac_b";
3859 break;
266abb8f
NS
3860 }
3861 if (mac)
3862 {
3863 strcat (buf, ", ");
3864 strcat (buf, mac);
3865 }
266abb8f 3866 }
53c7db4b 3867 break;
33c63f9d 3868
c077c580
SM
3869 case EM_AMDGPU:
3870 decode_AMDGPU_machine_flags (filedata, e_flags, buf);
3871 break;
3872
153a2776
NC
3873 case EM_CYGNUS_MEP:
3874 switch (e_flags & EF_MEP_CPU_MASK)
3875 {
3876 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3877 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3878 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3879 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3880 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3881 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3882 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3883 }
3884
3885 switch (e_flags & EF_MEP_COP_MASK)
3886 {
3887 case EF_MEP_COP_NONE: break;
3888 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3889 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3890 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3891 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3892 default: strcat (buf, _("<unknown MeP copro type>")); break;
3893 }
3894
3895 if (e_flags & EF_MEP_LIBRARY)
3896 strcat (buf, ", Built for Library");
3897
3898 if (e_flags & EF_MEP_INDEX_MASK)
3899 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3900 e_flags & EF_MEP_INDEX_MASK);
3901
3902 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3903 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3904 e_flags & ~ EF_MEP_ALL_FLAGS);
3905 break;
3906
252b5132
RH
3907 case EM_PPC:
3908 if (e_flags & EF_PPC_EMB)
3909 strcat (buf, ", emb");
3910
3911 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3912 strcat (buf, _(", relocatable"));
252b5132
RH
3913
3914 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3915 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3916 break;
3917
ee67d69a
AM
3918 case EM_PPC64:
3919 if (e_flags & EF_PPC64_ABI)
3920 {
3921 char abi[] = ", abiv0";
3922
3923 abi[6] += e_flags & EF_PPC64_ABI;
3924 strcat (buf, abi);
3925 }
3926 break;
3927
708e2187
NC
3928 case EM_V800:
3929 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3930 strcat (buf, ", RH850 ABI");
0b4362b0 3931
708e2187
NC
3932 if (e_flags & EF_V800_850E3)
3933 strcat (buf, ", V3 architecture");
3934
3935 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3936 strcat (buf, ", FPU not used");
3937
3938 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3939 strcat (buf, ", regmode: COMMON");
3940
3941 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3942 strcat (buf, ", r4 not used");
3943
3944 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3945 strcat (buf, ", r30 not used");
3946
3947 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3948 strcat (buf, ", r5 not used");
3949
3950 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3951 strcat (buf, ", r2 not used");
3952
3953 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3954 {
3955 switch (e_flags & - e_flags)
3956 {
3957 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3958 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3959 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3960 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3961 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3962 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3963 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3964 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3965 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3966 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3967 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3968 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3969 default: break;
3970 }
3971 }
3972 break;
3973
2b0337b0 3974 case EM_V850:
252b5132
RH
3975 case EM_CYGNUS_V850:
3976 switch (e_flags & EF_V850_ARCH)
3977 {
78c8d46c
NC
3978 case E_V850E3V5_ARCH:
3979 strcat (buf, ", v850e3v5");
3980 break;
1cd986c5
NC
3981 case E_V850E2V3_ARCH:
3982 strcat (buf, ", v850e2v3");
3983 break;
3984 case E_V850E2_ARCH:
3985 strcat (buf, ", v850e2");
3986 break;
3987 case E_V850E1_ARCH:
3988 strcat (buf, ", v850e1");
8ad30312 3989 break;
252b5132
RH
3990 case E_V850E_ARCH:
3991 strcat (buf, ", v850e");
3992 break;
252b5132
RH
3993 case E_V850_ARCH:
3994 strcat (buf, ", v850");
3995 break;
3996 default:
2b692964 3997 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3998 break;
3999 }
4000 break;
4001
2b0337b0 4002 case EM_M32R:
252b5132
RH
4003 case EM_CYGNUS_M32R:
4004 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
4005 strcat (buf, ", m32r");
252b5132
RH
4006 break;
4007
4008 case EM_MIPS:
4fe85591 4009 case EM_MIPS_RS3_LE:
252b5132
RH
4010 if (e_flags & EF_MIPS_NOREORDER)
4011 strcat (buf, ", noreorder");
4012
4013 if (e_flags & EF_MIPS_PIC)
4014 strcat (buf, ", pic");
4015
4016 if (e_flags & EF_MIPS_CPIC)
4017 strcat (buf, ", cpic");
4018
d1bdd336
TS
4019 if (e_flags & EF_MIPS_UCODE)
4020 strcat (buf, ", ugen_reserved");
4021
252b5132
RH
4022 if (e_flags & EF_MIPS_ABI2)
4023 strcat (buf, ", abi2");
4024
43521d43
TS
4025 if (e_flags & EF_MIPS_OPTIONS_FIRST)
4026 strcat (buf, ", odk first");
4027
a5d22d2a
TS
4028 if (e_flags & EF_MIPS_32BITMODE)
4029 strcat (buf, ", 32bitmode");
4030
ba92f887
MR
4031 if (e_flags & EF_MIPS_NAN2008)
4032 strcat (buf, ", nan2008");
4033
fef1b0b3
SE
4034 if (e_flags & EF_MIPS_FP64)
4035 strcat (buf, ", fp64");
4036
156c2f8b
NC
4037 switch ((e_flags & EF_MIPS_MACH))
4038 {
4039 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
4040 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
4041 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 4042 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
4043 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
4044 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
4045 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
4046 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 4047 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 4048 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 4049 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
4050 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
4051 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 4052 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 4053 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 4054 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 4055 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 4056 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 4057 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 4058 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 4059 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
df18f71b 4060 case E_MIPS_MACH_ALLEGREX: strcat(buf, ", allegrex"); break;
43521d43
TS
4061 case 0:
4062 /* We simply ignore the field in this case to avoid confusion:
4063 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4064 extension. */
4065 break;
2b692964 4066 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 4067 }
43521d43
TS
4068
4069 switch ((e_flags & EF_MIPS_ABI))
4070 {
4071 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
4072 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
4073 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
4074 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
4075 case 0:
4076 /* We simply ignore the field in this case to avoid confusion:
4077 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4078 This means it is likely to be an o32 file, but not for
4079 sure. */
4080 break;
2b692964 4081 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
4082 }
4083
4084 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4085 strcat (buf, ", mdmx");
4086
4087 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4088 strcat (buf, ", mips16");
4089
df58fc94
RS
4090 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4091 strcat (buf, ", micromips");
4092
43521d43
TS
4093 switch ((e_flags & EF_MIPS_ARCH))
4094 {
4095 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
4096 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
4097 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
4098 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
4099 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
4100 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 4101 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 4102 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 4103 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 4104 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 4105 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 4106 default: strcat (buf, _(", unknown ISA")); break;
43521d43 4107 }
252b5132 4108 break;
351b4b40 4109
35c08157
KLC
4110 case EM_NDS32:
4111 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
4112 break;
4113
fe944acf
FT
4114 case EM_NFP:
4115 switch (EF_NFP_MACH (e_flags))
4116 {
4117 case E_NFP_MACH_3200:
4118 strcat (buf, ", NFP-32xx");
4119 break;
4120 case E_NFP_MACH_6000:
4121 strcat (buf, ", NFP-6xxx");
4122 break;
4123 }
4124 break;
4125
e23eba97
NC
4126 case EM_RISCV:
4127 if (e_flags & EF_RISCV_RVC)
4128 strcat (buf, ", RVC");
2922d21d 4129
7f999549
JW
4130 if (e_flags & EF_RISCV_RVE)
4131 strcat (buf, ", RVE");
4132
96462b01
S
4133 if (e_flags & EF_RISCV_TSO)
4134 strcat (buf, ", TSO");
4135
2922d21d
AW
4136 switch (e_flags & EF_RISCV_FLOAT_ABI)
4137 {
4138 case EF_RISCV_FLOAT_ABI_SOFT:
4139 strcat (buf, ", soft-float ABI");
4140 break;
4141
4142 case EF_RISCV_FLOAT_ABI_SINGLE:
4143 strcat (buf, ", single-float ABI");
4144 break;
4145
4146 case EF_RISCV_FLOAT_ABI_DOUBLE:
4147 strcat (buf, ", double-float ABI");
4148 break;
4149
4150 case EF_RISCV_FLOAT_ABI_QUAD:
4151 strcat (buf, ", quad-float ABI");
4152 break;
4153 }
e23eba97
NC
4154 break;
4155
ccde1100
AO
4156 case EM_SH:
4157 switch ((e_flags & EF_SH_MACH_MASK))
4158 {
4159 case EF_SH1: strcat (buf, ", sh1"); break;
4160 case EF_SH2: strcat (buf, ", sh2"); break;
4161 case EF_SH3: strcat (buf, ", sh3"); break;
4162 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
4163 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
4164 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
4165 case EF_SH3E: strcat (buf, ", sh3e"); break;
4166 case EF_SH4: strcat (buf, ", sh4"); break;
4167 case EF_SH5: strcat (buf, ", sh5"); break;
4168 case EF_SH2E: strcat (buf, ", sh2e"); break;
4169 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 4170 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
4171 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
4172 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 4173 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
4174 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
4175 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
4176 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
4177 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
4178 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
4179 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 4180 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
4181 }
4182
cec6a5b8
MR
4183 if (e_flags & EF_SH_PIC)
4184 strcat (buf, ", pic");
4185
4186 if (e_flags & EF_SH_FDPIC)
4187 strcat (buf, ", fdpic");
ccde1100 4188 break;
948f632f 4189
73589c9d
CS
4190 case EM_OR1K:
4191 if (e_flags & EF_OR1K_NODELAY)
4192 strcat (buf, ", no delay");
4193 break;
57346661 4194
1e18ffc9
JM
4195 case EM_BPF:
4196 sprintf (buf + strlen (buf), ", CPU Version: %u",
4197 e_flags & EF_BPF_CPUVER);
4198 break;
4199
351b4b40
RH
4200 case EM_SPARCV9:
4201 if (e_flags & EF_SPARC_32PLUS)
4202 strcat (buf, ", v8+");
4203
4204 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
4205 strcat (buf, ", ultrasparcI");
4206
4207 if (e_flags & EF_SPARC_SUN_US3)
4208 strcat (buf, ", ultrasparcIII");
351b4b40
RH
4209
4210 if (e_flags & EF_SPARC_HAL_R1)
4211 strcat (buf, ", halr1");
4212
4213 if (e_flags & EF_SPARC_LEDATA)
4214 strcat (buf, ", ledata");
4215
4216 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4217 strcat (buf, ", tso");
4218
4219 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4220 strcat (buf, ", pso");
4221
4222 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4223 strcat (buf, ", rmo");
4224 break;
7d466069 4225
103f02d3
UD
4226 case EM_PARISC:
4227 switch (e_flags & EF_PARISC_ARCH)
4228 {
4229 case EFA_PARISC_1_0:
4230 strcpy (buf, ", PA-RISC 1.0");
4231 break;
4232 case EFA_PARISC_1_1:
4233 strcpy (buf, ", PA-RISC 1.1");
4234 break;
4235 case EFA_PARISC_2_0:
4236 strcpy (buf, ", PA-RISC 2.0");
4237 break;
4238 default:
4239 break;
4240 }
4241 if (e_flags & EF_PARISC_TRAPNIL)
4242 strcat (buf, ", trapnil");
4243 if (e_flags & EF_PARISC_EXT)
4244 strcat (buf, ", ext");
4245 if (e_flags & EF_PARISC_LSB)
4246 strcat (buf, ", lsb");
4247 if (e_flags & EF_PARISC_WIDE)
4248 strcat (buf, ", wide");
4249 if (e_flags & EF_PARISC_NO_KABP)
4250 strcat (buf, ", no kabp");
4251 if (e_flags & EF_PARISC_LAZYSWAP)
4252 strcat (buf, ", lazyswap");
30800947 4253 break;
76da6bbe 4254
7d466069 4255 case EM_PJ:
2b0337b0 4256 case EM_PJ_OLD:
7d466069
ILT
4257 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4258 strcat (buf, ", new calling convention");
4259
4260 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4261 strcat (buf, ", gnu calling convention");
4262 break;
4d6ed7c8
NC
4263
4264 case EM_IA_64:
4265 if ((e_flags & EF_IA_64_ABI64))
4266 strcat (buf, ", 64-bit");
4267 else
4268 strcat (buf, ", 32-bit");
4269 if ((e_flags & EF_IA_64_REDUCEDFP))
4270 strcat (buf, ", reduced fp model");
4271 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4272 strcat (buf, ", no function descriptors, constant gp");
4273 else if ((e_flags & EF_IA_64_CONS_GP))
4274 strcat (buf, ", constant gp");
4275 if ((e_flags & EF_IA_64_ABSOLUTE))
4276 strcat (buf, ", absolute");
dda8d76d 4277 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
4278 {
4279 if ((e_flags & EF_IA_64_VMS_LINKAGES))
4280 strcat (buf, ", vms_linkages");
4281 switch ((e_flags & EF_IA_64_VMS_COMCOD))
4282 {
4283 case EF_IA_64_VMS_COMCOD_SUCCESS:
4284 break;
4285 case EF_IA_64_VMS_COMCOD_WARNING:
4286 strcat (buf, ", warning");
4287 break;
4288 case EF_IA_64_VMS_COMCOD_ERROR:
4289 strcat (buf, ", error");
4290 break;
4291 case EF_IA_64_VMS_COMCOD_ABORT:
4292 strcat (buf, ", abort");
4293 break;
4294 default:
bee0ee85
NC
4295 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
4296 e_flags & EF_IA_64_VMS_COMCOD);
4297 strcat (buf, ", <unknown>");
28f997cf
TG
4298 }
4299 }
4d6ed7c8 4300 break;
179d3252
JT
4301
4302 case EM_VAX:
4303 if ((e_flags & EF_VAX_NONPIC))
4304 strcat (buf, ", non-PIC");
4305 if ((e_flags & EF_VAX_DFLOAT))
4306 strcat (buf, ", D-Float");
4307 if ((e_flags & EF_VAX_GFLOAT))
4308 strcat (buf, ", G-Float");
4309 break;
c7927a3c 4310
619ed720
EB
4311 case EM_VISIUM:
4312 if (e_flags & EF_VISIUM_ARCH_MCM)
4313 strcat (buf, ", mcm");
4314 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4315 strcat (buf, ", mcm24");
4316 if (e_flags & EF_VISIUM_ARCH_GR6)
4317 strcat (buf, ", gr6");
4318 break;
4319
4046d87a 4320 case EM_RL78:
1740ba0c
NC
4321 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4322 {
4323 case E_FLAG_RL78_ANY_CPU: break;
4324 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
4325 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
4326 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
4327 }
856ea05c
KP
4328 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4329 strcat (buf, ", 64-bit doubles");
4046d87a 4330 break;
0b4362b0 4331
c7927a3c
NC
4332 case EM_RX:
4333 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4334 strcat (buf, ", 64-bit doubles");
4335 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 4336 strcat (buf, ", dsp");
d4cb0ea0 4337 if (e_flags & E_FLAG_RX_PID)
0b4362b0 4338 strcat (buf, ", pid");
708e2187
NC
4339 if (e_flags & E_FLAG_RX_ABI)
4340 strcat (buf, ", RX ABI");
3525236c
NC
4341 if (e_flags & E_FLAG_RX_SINSNS_SET)
4342 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
4343 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
4344 if (e_flags & E_FLAG_RX_V2)
4345 strcat (buf, ", V2");
f87673e0
YS
4346 if (e_flags & E_FLAG_RX_V3)
4347 strcat (buf, ", V3");
d4cb0ea0 4348 break;
55786da2
AK
4349
4350 case EM_S390:
4351 if (e_flags & EF_S390_HIGH_GPRS)
4352 strcat (buf, ", highgprs");
d4cb0ea0 4353 break;
40b36596
JM
4354
4355 case EM_TI_C6000:
4356 if ((e_flags & EF_C6000_REL))
4357 strcat (buf, ", relocatable module");
d4cb0ea0 4358 break;
13761a11
NC
4359
4360 case EM_MSP430:
4361 strcat (buf, _(": architecture variant: "));
4362 switch (e_flags & EF_MSP430_MACH)
4363 {
4364 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
4365 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
4366 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
4367 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
4368 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
4369 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
4370 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
4371 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
4372 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
4373 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
4374 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
4375 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
4376 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
4377 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
4378 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
4379 default:
4380 strcat (buf, _(": unknown")); break;
4381 }
4382
4383 if (e_flags & ~ EF_MSP430_MACH)
4384 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
4385 break;
4386
4387 case EM_Z80:
4388 switch (e_flags & EF_Z80_MACH_MSK)
4389 {
4390 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
4391 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
4392 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
4393 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
4394 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
4395 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 4396 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
4397 default:
4398 strcat (buf, _(", unknown")); break;
4399 }
4400 break;
e9a0721f 4401 case EM_LOONGARCH:
e9a0721f 4402 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
4403 strcat (buf, ", SOFT-FLOAT");
4404 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
4405 strcat (buf, ", SINGLE-FLOAT");
4406 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
4407 strcat (buf, ", DOUBLE-FLOAT");
4408
c4a7e6b5 4409 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
4410 strcat (buf, ", OBJ-v0");
4411 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
4412 strcat (buf, ", OBJ-v1");
4413
e9a0721f 4414 break;
252b5132
RH
4415 }
4416 }
4417
4418 return buf;
4419}
4420
252b5132 4421static const char *
dda8d76d 4422get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4423{
4424 static char buff[32];
4425
4426 switch (osabi)
4427 {
4428 case ELFOSABI_NONE: return "UNIX - System V";
4429 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4430 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4431 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4432 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4433 case ELFOSABI_AIX: return "UNIX - AIX";
4434 case ELFOSABI_IRIX: return "UNIX - IRIX";
4435 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4436 case ELFOSABI_TRU64: return "UNIX - TRU64";
4437 case ELFOSABI_MODESTO: return "Novell - Modesto";
4438 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4439 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4440 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4441 case ELFOSABI_AROS: return "AROS";
11636f9e 4442 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4443 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4444 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4445 default:
40b36596 4446 if (osabi >= 64)
dda8d76d 4447 switch (filedata->file_header.e_machine)
40b36596 4448 {
37870be8
SM
4449 case EM_AMDGPU:
4450 switch (osabi)
4451 {
4452 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4453 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4454 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4455 default:
4456 break;
4457 }
4458 break;
4459
40b36596
JM
4460 case EM_ARM:
4461 switch (osabi)
4462 {
4463 case ELFOSABI_ARM: return "ARM";
18a20338 4464 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4465 default:
4466 break;
4467 }
4468 break;
4469
4470 case EM_MSP430:
4471 case EM_MSP430_OLD:
619ed720 4472 case EM_VISIUM:
40b36596
JM
4473 switch (osabi)
4474 {
4475 case ELFOSABI_STANDALONE: return _("Standalone App");
4476 default:
4477 break;
4478 }
4479 break;
4480
4481 case EM_TI_C6000:
4482 switch (osabi)
4483 {
4484 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4485 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4486 default:
4487 break;
4488 }
4489 break;
4490
4491 default:
4492 break;
4493 }
e9e44622 4494 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4495 return buff;
4496 }
4497}
4498
a06ea964
NC
4499static const char *
4500get_aarch64_segment_type (unsigned long type)
4501{
4502 switch (type)
4503 {
32ec8896 4504 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4505 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4506 default: return NULL;
a06ea964 4507 }
a06ea964
NC
4508}
4509
b294bdf8
MM
4510static const char *
4511get_arm_segment_type (unsigned long type)
4512{
4513 switch (type)
4514 {
32ec8896
NC
4515 case PT_ARM_EXIDX: return "EXIDX";
4516 default: return NULL;
b294bdf8 4517 }
b294bdf8
MM
4518}
4519
b4cbbe8f
AK
4520static const char *
4521get_s390_segment_type (unsigned long type)
4522{
4523 switch (type)
4524 {
4525 case PT_S390_PGSTE: return "S390_PGSTE";
4526 default: return NULL;
4527 }
4528}
4529
d3ba0551
AM
4530static const char *
4531get_mips_segment_type (unsigned long type)
252b5132
RH
4532{
4533 switch (type)
4534 {
32ec8896
NC
4535 case PT_MIPS_REGINFO: return "REGINFO";
4536 case PT_MIPS_RTPROC: return "RTPROC";
4537 case PT_MIPS_OPTIONS: return "OPTIONS";
4538 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4539 default: return NULL;
252b5132 4540 }
252b5132
RH
4541}
4542
103f02d3 4543static const char *
d3ba0551 4544get_parisc_segment_type (unsigned long type)
103f02d3
UD
4545{
4546 switch (type)
4547 {
103f02d3
UD
4548 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4549 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4550 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4551 default: return NULL;
103f02d3 4552 }
103f02d3
UD
4553}
4554
4d6ed7c8 4555static const char *
d3ba0551 4556get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4557{
4558 switch (type)
4559 {
4560 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4561 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4562 default: return NULL;
4d6ed7c8 4563 }
4d6ed7c8
NC
4564}
4565
40b36596
JM
4566static const char *
4567get_tic6x_segment_type (unsigned long type)
4568{
4569 switch (type)
4570 {
32ec8896
NC
4571 case PT_C6000_PHATTR: return "C6000_PHATTR";
4572 default: return NULL;
40b36596 4573 }
40b36596
JM
4574}
4575
fbc95f1e
KC
4576static const char *
4577get_riscv_segment_type (unsigned long type)
4578{
4579 switch (type)
4580 {
4581 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4582 default: return NULL;
4583 }
4584}
4585
df3a023b
AM
4586static const char *
4587get_hpux_segment_type (unsigned long type, unsigned e_machine)
4588{
4589 if (e_machine == EM_PARISC)
4590 switch (type)
4591 {
4592 case PT_HP_TLS: return "HP_TLS";
4593 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4594 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4595 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4596 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4597 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4598 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4599 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4600 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4601 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4602 case PT_HP_PARALLEL: return "HP_PARALLEL";
4603 case PT_HP_FASTBIND: return "HP_FASTBIND";
4604 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4605 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4606 case PT_HP_STACK: return "HP_STACK";
4607 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4608 default: return NULL;
4609 }
4610
4611 if (e_machine == EM_IA_64)
4612 switch (type)
4613 {
4614 case PT_HP_TLS: return "HP_TLS";
4615 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4616 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4617 case PT_IA_64_HP_STACK: return "HP_STACK";
4618 default: return NULL;
4619 }
4620
4621 return NULL;
4622}
4623
5522f910
NC
4624static const char *
4625get_solaris_segment_type (unsigned long type)
4626{
4627 switch (type)
4628 {
4629 case 0x6464e550: return "PT_SUNW_UNWIND";
4630 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4631 case 0x6ffffff7: return "PT_LOSUNW";
4632 case 0x6ffffffa: return "PT_SUNWBSS";
4633 case 0x6ffffffb: return "PT_SUNWSTACK";
4634 case 0x6ffffffc: return "PT_SUNWDTRACE";
4635 case 0x6ffffffd: return "PT_SUNWCAP";
4636 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4637 default: return NULL;
5522f910
NC
4638 }
4639}
4640
252b5132 4641static const char *
dda8d76d 4642get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4643{
b34976b6 4644 static char buff[32];
252b5132
RH
4645
4646 switch (p_type)
4647 {
b34976b6
AM
4648 case PT_NULL: return "NULL";
4649 case PT_LOAD: return "LOAD";
252b5132 4650 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4651 case PT_INTERP: return "INTERP";
4652 case PT_NOTE: return "NOTE";
4653 case PT_SHLIB: return "SHLIB";
4654 case PT_PHDR: return "PHDR";
13ae64f3 4655 case PT_TLS: return "TLS";
32ec8896 4656 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4657 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4658 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4659 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
cf0e0a0b 4660 case PT_GNU_SFRAME: return "GNU_SFRAME";
65765700 4661
80251d41 4662 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
3eba3ef3
NC
4663 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4664 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4665 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4666
252b5132 4667 default:
df3a023b 4668 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4669 {
2cf0635d 4670 const char * result;
103f02d3 4671
dda8d76d 4672 switch (filedata->file_header.e_machine)
252b5132 4673 {
a06ea964
NC
4674 case EM_AARCH64:
4675 result = get_aarch64_segment_type (p_type);
4676 break;
b294bdf8
MM
4677 case EM_ARM:
4678 result = get_arm_segment_type (p_type);
4679 break;
252b5132 4680 case EM_MIPS:
4fe85591 4681 case EM_MIPS_RS3_LE:
252b5132
RH
4682 result = get_mips_segment_type (p_type);
4683 break;
103f02d3
UD
4684 case EM_PARISC:
4685 result = get_parisc_segment_type (p_type);
4686 break;
4d6ed7c8
NC
4687 case EM_IA_64:
4688 result = get_ia64_segment_type (p_type);
4689 break;
40b36596
JM
4690 case EM_TI_C6000:
4691 result = get_tic6x_segment_type (p_type);
4692 break;
b4cbbe8f
AK
4693 case EM_S390:
4694 case EM_S390_OLD:
4695 result = get_s390_segment_type (p_type);
4696 break;
fbc95f1e
KC
4697 case EM_RISCV:
4698 result = get_riscv_segment_type (p_type);
4699 break;
252b5132
RH
4700 default:
4701 result = NULL;
4702 break;
4703 }
103f02d3 4704
252b5132
RH
4705 if (result != NULL)
4706 return result;
103f02d3 4707
1a9ccd70 4708 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4709 }
4710 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4711 {
df3a023b 4712 const char * result = NULL;
103f02d3 4713
df3a023b 4714 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4715 {
df3a023b
AM
4716 case ELFOSABI_GNU:
4717 case ELFOSABI_FREEBSD:
4718 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4719 {
4720 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4721 result = buff;
4722 }
103f02d3 4723 break;
df3a023b
AM
4724 case ELFOSABI_HPUX:
4725 result = get_hpux_segment_type (p_type,
4726 filedata->file_header.e_machine);
4727 break;
4728 case ELFOSABI_SOLARIS:
4729 result = get_solaris_segment_type (p_type);
00428cca 4730 break;
103f02d3 4731 default:
103f02d3
UD
4732 break;
4733 }
103f02d3
UD
4734 if (result != NULL)
4735 return result;
4736
1a9ccd70 4737 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4738 }
252b5132 4739 else
e9e44622 4740 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4741
4742 return buff;
4743 }
4744}
4745
53a346d8
CZ
4746static const char *
4747get_arc_section_type_name (unsigned int sh_type)
4748{
4749 switch (sh_type)
4750 {
4751 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4752 default:
4753 break;
4754 }
4755 return NULL;
4756}
4757
252b5132 4758static const char *
d3ba0551 4759get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4760{
4761 switch (sh_type)
4762 {
b34976b6
AM
4763 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4764 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4765 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4766 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4767 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4768 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4769 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4770 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4771 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4772 case SHT_MIPS_RELD: return "MIPS_RELD";
4773 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4774 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4775 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4776 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4777 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4778 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4779 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4780 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4781 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4782 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4783 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4784 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4785 case SHT_MIPS_LINE: return "MIPS_LINE";
4786 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4787 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4788 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4789 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4790 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4791 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4792 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4793 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4794 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4795 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4796 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4797 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4798 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4799 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4800 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4801 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4802 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4803 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4804 default:
4805 break;
4806 }
4807 return NULL;
4808}
4809
103f02d3 4810static const char *
d3ba0551 4811get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4812{
4813 switch (sh_type)
4814 {
4815 case SHT_PARISC_EXT: return "PARISC_EXT";
4816 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4817 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4818 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4819 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4820 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4821 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4822 default: return NULL;
103f02d3 4823 }
103f02d3
UD
4824}
4825
4d6ed7c8 4826static const char *
dda8d76d 4827get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4828{
18bd398b 4829 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4830 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4831 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4832
4d6ed7c8
NC
4833 switch (sh_type)
4834 {
148b93f2
NC
4835 case SHT_IA_64_EXT: return "IA_64_EXT";
4836 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4837 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4838 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4839 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4840 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4841 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4842 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4843 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4844 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4845 default:
4846 break;
4847 }
4848 return NULL;
4849}
4850
d2b2c203
DJ
4851static const char *
4852get_x86_64_section_type_name (unsigned int sh_type)
4853{
4854 switch (sh_type)
4855 {
4856 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4857 default: return NULL;
d2b2c203 4858 }
d2b2c203
DJ
4859}
4860
a06ea964
NC
4861static const char *
4862get_aarch64_section_type_name (unsigned int sh_type)
4863{
4864 switch (sh_type)
4865 {
32ec8896
NC
4866 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4867 default: return NULL;
a06ea964 4868 }
a06ea964
NC
4869}
4870
40a18ebd
NC
4871static const char *
4872get_arm_section_type_name (unsigned int sh_type)
4873{
4874 switch (sh_type)
4875 {
7f6fed87
NC
4876 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4877 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4878 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4879 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4880 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4881 default: return NULL;
40a18ebd 4882 }
40a18ebd
NC
4883}
4884
40b36596
JM
4885static const char *
4886get_tic6x_section_type_name (unsigned int sh_type)
4887{
4888 switch (sh_type)
4889 {
32ec8896
NC
4890 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4891 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4892 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4893 case SHT_TI_ICODE: return "TI_ICODE";
4894 case SHT_TI_XREF: return "TI_XREF";
4895 case SHT_TI_HANDLER: return "TI_HANDLER";
4896 case SHT_TI_INITINFO: return "TI_INITINFO";
4897 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4898 default: return NULL;
40b36596 4899 }
40b36596
JM
4900}
4901
13761a11 4902static const char *
b0191216 4903get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4904{
4905 switch (sh_type)
4906 {
32ec8896
NC
4907 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4908 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4909 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4910 default: return NULL;
13761a11
NC
4911 }
4912}
4913
fe944acf
FT
4914static const char *
4915get_nfp_section_type_name (unsigned int sh_type)
4916{
4917 switch (sh_type)
4918 {
4919 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4920 case SHT_NFP_INITREG: return "NFP_INITREG";
4921 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4922 default: return NULL;
4923 }
4924}
4925
685080f2
NC
4926static const char *
4927get_v850_section_type_name (unsigned int sh_type)
4928{
4929 switch (sh_type)
4930 {
32ec8896
NC
4931 case SHT_V850_SCOMMON: return "V850 Small Common";
4932 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4933 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4934 case SHT_RENESAS_IOP: return "RENESAS IOP";
4935 case SHT_RENESAS_INFO: return "RENESAS INFO";
4936 default: return NULL;
685080f2
NC
4937 }
4938}
4939
2dc8dd17
JW
4940static const char *
4941get_riscv_section_type_name (unsigned int sh_type)
4942{
4943 switch (sh_type)
4944 {
4945 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4946 default: return NULL;
4947 }
4948}
4949
0861f561
CQ
4950static const char *
4951get_csky_section_type_name (unsigned int sh_type)
4952{
4953 switch (sh_type)
4954 {
4955 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4956 default: return NULL;
4957 }
4958}
4959
252b5132 4960static const char *
dda8d76d 4961get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4962{
b34976b6 4963 static char buff[32];
9fb71ee4 4964 const char * result;
252b5132
RH
4965
4966 switch (sh_type)
4967 {
4968 case SHT_NULL: return "NULL";
4969 case SHT_PROGBITS: return "PROGBITS";
4970 case SHT_SYMTAB: return "SYMTAB";
4971 case SHT_STRTAB: return "STRTAB";
4972 case SHT_RELA: return "RELA";
dd207c13 4973 case SHT_RELR: return "RELR";
252b5132
RH
4974 case SHT_HASH: return "HASH";
4975 case SHT_DYNAMIC: return "DYNAMIC";
4976 case SHT_NOTE: return "NOTE";
4977 case SHT_NOBITS: return "NOBITS";
4978 case SHT_REL: return "REL";
4979 case SHT_SHLIB: return "SHLIB";
4980 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4981 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4982 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4983 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4984 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4985 case SHT_GROUP: return "GROUP";
67ce483b 4986 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4987 case SHT_GNU_verdef: return "VERDEF";
4988 case SHT_GNU_verneed: return "VERNEED";
4989 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4990 case 0x6ffffff0: return "VERSYM";
4991 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4992 case 0x7ffffffd: return "AUXILIARY";
4993 case 0x7fffffff: return "FILTER";
047b2264 4994 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4995
4996 default:
4997 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4998 {
dda8d76d 4999 switch (filedata->file_header.e_machine)
252b5132 5000 {
53a346d8
CZ
5001 case EM_ARC:
5002 case EM_ARC_COMPACT:
5003 case EM_ARC_COMPACT2:
13aa307c
CZ
5004 case EM_ARC_COMPACT3:
5005 case EM_ARC_COMPACT3_64:
53a346d8
CZ
5006 result = get_arc_section_type_name (sh_type);
5007 break;
252b5132 5008 case EM_MIPS:
4fe85591 5009 case EM_MIPS_RS3_LE:
252b5132
RH
5010 result = get_mips_section_type_name (sh_type);
5011 break;
103f02d3
UD
5012 case EM_PARISC:
5013 result = get_parisc_section_type_name (sh_type);
5014 break;
4d6ed7c8 5015 case EM_IA_64:
dda8d76d 5016 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 5017 break;
d2b2c203 5018 case EM_X86_64:
8a9036a4 5019 case EM_L1OM:
7a9068fe 5020 case EM_K1OM:
d2b2c203
DJ
5021 result = get_x86_64_section_type_name (sh_type);
5022 break;
a06ea964
NC
5023 case EM_AARCH64:
5024 result = get_aarch64_section_type_name (sh_type);
5025 break;
40a18ebd
NC
5026 case EM_ARM:
5027 result = get_arm_section_type_name (sh_type);
5028 break;
40b36596
JM
5029 case EM_TI_C6000:
5030 result = get_tic6x_section_type_name (sh_type);
5031 break;
13761a11 5032 case EM_MSP430:
b0191216 5033 result = get_msp430_section_type_name (sh_type);
13761a11 5034 break;
fe944acf
FT
5035 case EM_NFP:
5036 result = get_nfp_section_type_name (sh_type);
5037 break;
685080f2
NC
5038 case EM_V800:
5039 case EM_V850:
5040 case EM_CYGNUS_V850:
5041 result = get_v850_section_type_name (sh_type);
5042 break;
2dc8dd17
JW
5043 case EM_RISCV:
5044 result = get_riscv_section_type_name (sh_type);
5045 break;
0861f561
CQ
5046 case EM_CSKY:
5047 result = get_csky_section_type_name (sh_type);
5048 break;
252b5132
RH
5049 default:
5050 result = NULL;
5051 break;
5052 }
5053
5054 if (result != NULL)
5055 return result;
5056
9fb71ee4 5057 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5058 }
5059 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5060 {
dda8d76d 5061 switch (filedata->file_header.e_machine)
148b93f2
NC
5062 {
5063 case EM_IA_64:
dda8d76d 5064 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5065 break;
5066 default:
dda8d76d 5067 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5068 result = get_solaris_section_type (sh_type);
5069 else
1b4b80bf
NC
5070 {
5071 switch (sh_type)
5072 {
5073 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5074 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5075 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5076 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5077 default:
5078 result = NULL;
5079 break;
5080 }
5081 }
148b93f2
NC
5082 break;
5083 }
5084
5085 if (result != NULL)
5086 return result;
5087
9fb71ee4 5088 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5089 }
252b5132 5090 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5091 {
dda8d76d 5092 switch (filedata->file_header.e_machine)
685080f2
NC
5093 {
5094 case EM_V800:
5095 case EM_V850:
5096 case EM_CYGNUS_V850:
9fb71ee4 5097 result = get_v850_section_type_name (sh_type);
a9fb83be 5098 break;
685080f2 5099 default:
9fb71ee4 5100 result = NULL;
685080f2
NC
5101 break;
5102 }
5103
9fb71ee4
NC
5104 if (result != NULL)
5105 return result;
5106
5107 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5108 }
252b5132 5109 else
a7dbfd1c
NC
5110 /* This message is probably going to be displayed in a 15
5111 character wide field, so put the hex value first. */
5112 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5113
252b5132
RH
5114 return buff;
5115 }
5116}
5117
79bc120c
NC
5118enum long_option_values
5119{
5120 OPTION_DEBUG_DUMP = 512,
5121 OPTION_DYN_SYMS,
0f03783c 5122 OPTION_LTO_SYMS,
79bc120c
NC
5123 OPTION_DWARF_DEPTH,
5124 OPTION_DWARF_START,
5125 OPTION_DWARF_CHECK,
5126 OPTION_CTF_DUMP,
5127 OPTION_CTF_PARENT,
5128 OPTION_CTF_SYMBOLS,
5129 OPTION_CTF_STRINGS,
42b6953b 5130 OPTION_SFRAME_DUMP,
79bc120c
NC
5131 OPTION_WITH_SYMBOL_VERSIONS,
5132 OPTION_RECURSE_LIMIT,
5133 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
5134 OPTION_NO_DEMANGLING,
5135 OPTION_SYM_BASE
79bc120c 5136};
2979dc34 5137
85b1c36d 5138static struct option options[] =
252b5132 5139{
79bc120c
NC
5140 /* Note - This table is alpha-sorted on the 'val'
5141 field in order to make adding new options easier. */
5142 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5143 {"all", no_argument, 0, 'a'},
79bc120c
NC
5144 {"demangle", optional_argument, 0, 'C'},
5145 {"archive-index", no_argument, 0, 'c'},
5146 {"use-dynamic", no_argument, 0, 'D'},
5147 {"dynamic", no_argument, 0, 'd'},
b34976b6 5148 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5149 {"section-groups", no_argument, 0, 'g'},
5150 {"help", no_argument, 0, 'H'},
5151 {"file-header", no_argument, 0, 'h'},
b34976b6 5152 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5153 {"lint", no_argument, 0, 'L'},
5154 {"enable-checks", no_argument, 0, 'L'},
5155 {"program-headers", no_argument, 0, 'l'},
b34976b6 5156 {"segments", no_argument, 0, 'l'},
595cf52e 5157 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5158 {"notes", no_argument, 0, 'n'},
ca0e11aa 5159 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5160 {"string-dump", required_argument, 0, 'p'},
5161 {"relocated-dump", required_argument, 0, 'R'},
5162 {"relocs", no_argument, 0, 'r'},
5163 {"section-headers", no_argument, 0, 'S'},
5164 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5165 {"symbols", no_argument, 0, 's'},
5166 {"syms", no_argument, 0, 's'},
79bc120c
NC
5167 {"silent-truncation",no_argument, 0, 'T'},
5168 {"section-details", no_argument, 0, 't'},
b3aa80b4 5169 {"unicode", required_argument, NULL, 'U'},
09c11c86 5170 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5171 {"version-info", no_argument, 0, 'V'},
5172 {"version", no_argument, 0, 'v'},
5173 {"wide", no_argument, 0, 'W'},
b34976b6 5174 {"hex-dump", required_argument, 0, 'x'},
0e602686 5175 {"decompress", no_argument, 0, 'z'},
252b5132 5176
79bc120c
NC
5177 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5178 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5179 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5180 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5181 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5182 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5183 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5184 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5185 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5186 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5187#ifdef ENABLE_LIBCTF
d344b407 5188 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5189 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5190 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5191 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5192#endif
42b6953b 5193 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
047c3dbf 5194 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5195
b34976b6 5196 {0, no_argument, 0, 0}
252b5132
RH
5197};
5198
5199static void
2cf0635d 5200usage (FILE * stream)
252b5132 5201{
92f01d61
JM
5202 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5203 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5204 fprintf (stream, _(" Options are:\n"));
5205 fprintf (stream, _("\
5206 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5207 fprintf (stream, _("\
5208 -h --file-header Display the ELF file header\n"));
5209 fprintf (stream, _("\
5210 -l --program-headers Display the program headers\n"));
5211 fprintf (stream, _("\
5212 --segments An alias for --program-headers\n"));
5213 fprintf (stream, _("\
5214 -S --section-headers Display the sections' header\n"));
5215 fprintf (stream, _("\
5216 --sections An alias for --section-headers\n"));
5217 fprintf (stream, _("\
5218 -g --section-groups Display the section groups\n"));
5219 fprintf (stream, _("\
5220 -t --section-details Display the section details\n"));
5221 fprintf (stream, _("\
5222 -e --headers Equivalent to: -h -l -S\n"));
5223 fprintf (stream, _("\
5224 -s --syms Display the symbol table\n"));
5225 fprintf (stream, _("\
5226 --symbols An alias for --syms\n"));
5227 fprintf (stream, _("\
5228 --dyn-syms Display the dynamic symbol table\n"));
5229 fprintf (stream, _("\
5230 --lto-syms Display LTO symbol tables\n"));
5231 fprintf (stream, _("\
047c3dbf
NL
5232 --sym-base=[0|8|10|16] \n\
5233 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5234 mixed (the default), octal, decimal, hexadecimal.\n"));
5235 fprintf (stream, _("\
0d646226
AM
5236 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5237 display_demangler_styles (stream, _("\
5238 STYLE can be "));
d6249f5f
AM
5239 fprintf (stream, _("\
5240 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5241 fprintf (stream, _("\
5242 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5243 fprintf (stream, _("\
5244 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5245 fprintf (stream, _("\
5246 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5247 Display unicode characters as determined by the current locale\n\
5248 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5249 escape sequences, or treat them as invalid and display as\n\
5250 \"{hex sequences}\"\n"));
d6249f5f
AM
5251 fprintf (stream, _("\
5252 -n --notes Display the core notes (if present)\n"));
5253 fprintf (stream, _("\
5254 -r --relocs Display the relocations (if present)\n"));
5255 fprintf (stream, _("\
5256 -u --unwind Display the unwind info (if present)\n"));
5257 fprintf (stream, _("\
5258 -d --dynamic Display the dynamic section (if present)\n"));
5259 fprintf (stream, _("\
5260 -V --version-info Display the version sections (if present)\n"));
5261 fprintf (stream, _("\
5262 -A --arch-specific Display architecture specific information (if any)\n"));
5263 fprintf (stream, _("\
5264 -c --archive-index Display the symbol/file index in an archive\n"));
5265 fprintf (stream, _("\
5266 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5267 fprintf (stream, _("\
5268 -L --lint|--enable-checks\n\
5269 Display warning messages for possible problems\n"));
5270 fprintf (stream, _("\
09c11c86 5271 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5272 Dump the contents of section <number|name> as bytes\n"));
5273 fprintf (stream, _("\
09c11c86 5274 -p --string-dump=<number|name>\n\
d6249f5f
AM
5275 Dump the contents of section <number|name> as strings\n"));
5276 fprintf (stream, _("\
cf13d699 5277 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5278 Dump the relocated contents of section <number|name>\n"));
5279 fprintf (stream, _("\
5280 -z --decompress Decompress section before dumping it\n"));
5281 fprintf (stream, _("\
5282 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5283 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5284 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5285 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5286 U/=trace_info]\n\
5287 Display the contents of DWARF debug sections\n"));
5288 fprintf (stream, _("\
5289 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5290 debuginfo files\n"));
5291 fprintf (stream, _("\
5292 -P --process-links Display the contents of non-debug sections in separate\n\
5293 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5294#if DEFAULT_FOR_FOLLOW_LINKS
5295 fprintf (stream, _("\
d6249f5f
AM
5296 -wK --debug-dump=follow-links\n\
5297 Follow links to separate debug info files (default)\n"));
5298 fprintf (stream, _("\
5299 -wN --debug-dump=no-follow-links\n\
5300 Do not follow links to separate debug info files\n"));
c46b7066
NC
5301#else
5302 fprintf (stream, _("\
d6249f5f
AM
5303 -wK --debug-dump=follow-links\n\
5304 Follow links to separate debug info files\n"));
5305 fprintf (stream, _("\
5306 -wN --debug-dump=no-follow-links\n\
5307 Do not follow links to separate debug info files\n\
5308 (default)\n"));
bed566bb
NC
5309#endif
5310#if HAVE_LIBDEBUGINFOD
5311 fprintf (stream, _("\
5312 -wD --debug-dump=use-debuginfod\n\
5313 When following links, also query debuginfod servers (default)\n"));
5314 fprintf (stream, _("\
5315 -wE --debug-dump=do-not-use-debuginfod\n\
5316 When following links, do not query debuginfod servers\n"));
c46b7066 5317#endif
fd2f0033 5318 fprintf (stream, _("\
d6249f5f
AM
5319 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5320 fprintf (stream, _("\
5321 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5322#ifdef ENABLE_LIBCTF
7d9813f1 5323 fprintf (stream, _("\
d6249f5f
AM
5324 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5325 fprintf (stream, _("\
80b56fad 5326 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5327 fprintf (stream, _("\
7d9813f1 5328 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5329 Use section <number|name> as the CTF external symtab\n"));
5330 fprintf (stream, _("\
7d9813f1 5331 --ctf-strings=<number|name>\n\
d6249f5f 5332 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5333#endif
42b6953b
IB
5334 fprintf (stream, _("\
5335 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
7d9813f1 5336
252b5132 5337#ifdef SUPPORT_DISASSEMBLY
92f01d61 5338 fprintf (stream, _("\
09c11c86
NC
5339 -i --instruction-dump=<number|name>\n\
5340 Disassemble the contents of section <number|name>\n"));
252b5132 5341#endif
92f01d61 5342 fprintf (stream, _("\
d6249f5f
AM
5343 -I --histogram Display histogram of bucket list lengths\n"));
5344 fprintf (stream, _("\
5345 -W --wide Allow output width to exceed 80 characters\n"));
5346 fprintf (stream, _("\
5347 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5348 fprintf (stream, _("\
5349 @<file> Read options from <file>\n"));
5350 fprintf (stream, _("\
5351 -H --help Display this information\n"));
5352 fprintf (stream, _("\
8b53311e 5353 -v --version Display the version number of readelf\n"));
1118d252 5354
92f01d61
JM
5355 if (REPORT_BUGS_TO[0] && stream == stdout)
5356 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5357
92f01d61 5358 exit (stream == stdout ? 0 : 1);
252b5132
RH
5359}
5360
18bd398b
NC
5361/* Record the fact that the user wants the contents of section number
5362 SECTION to be displayed using the method(s) encoded as flags bits
5363 in TYPE. Note, TYPE can be zero if we are creating the array for
5364 the first time. */
5365
252b5132 5366static void
6431e409
AM
5367request_dump_bynumber (struct dump_data *dumpdata,
5368 unsigned int section, dump_type type)
252b5132 5369{
6431e409 5370 if (section >= dumpdata->num_dump_sects)
252b5132 5371 {
2cf0635d 5372 dump_type * new_dump_sects;
252b5132 5373
3f5e193b 5374 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5375 sizeof (* new_dump_sects));
252b5132
RH
5376
5377 if (new_dump_sects == NULL)
591a748a 5378 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5379 else
5380 {
6431e409 5381 if (dumpdata->dump_sects)
21b65bac
NC
5382 {
5383 /* Copy current flag settings. */
6431e409
AM
5384 memcpy (new_dump_sects, dumpdata->dump_sects,
5385 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5386
6431e409 5387 free (dumpdata->dump_sects);
21b65bac 5388 }
252b5132 5389
6431e409
AM
5390 dumpdata->dump_sects = new_dump_sects;
5391 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5392 }
5393 }
5394
6431e409
AM
5395 if (dumpdata->dump_sects)
5396 dumpdata->dump_sects[section] |= type;
252b5132
RH
5397}
5398
aef1f6d0
DJ
5399/* Request a dump by section name. */
5400
5401static void
2cf0635d 5402request_dump_byname (const char * section, dump_type type)
aef1f6d0 5403{
2cf0635d 5404 struct dump_list_entry * new_request;
aef1f6d0 5405
3f5e193b
NC
5406 new_request = (struct dump_list_entry *)
5407 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5408 if (!new_request)
591a748a 5409 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5410
5411 new_request->name = strdup (section);
5412 if (!new_request->name)
591a748a 5413 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5414
5415 new_request->type = type;
5416
5417 new_request->next = dump_sects_byname;
5418 dump_sects_byname = new_request;
5419}
5420
cf13d699 5421static inline void
6431e409 5422request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5423{
5424 int section;
5425 char * cp;
5426
015dc7e1 5427 do_dump = true;
cf13d699
NC
5428 section = strtoul (optarg, & cp, 0);
5429
5430 if (! *cp && section >= 0)
6431e409 5431 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5432 else
5433 request_dump_byname (optarg, type);
5434}
5435
252b5132 5436static void
6431e409 5437parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5438{
5439 int c;
5440
5441 if (argc < 2)
92f01d61 5442 usage (stderr);
252b5132
RH
5443
5444 while ((c = getopt_long
b3aa80b4 5445 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5446 {
252b5132
RH
5447 switch (c)
5448 {
5449 case 0:
5450 /* Long options. */
5451 break;
5452 case 'H':
92f01d61 5453 usage (stdout);
252b5132
RH
5454 break;
5455
5456 case 'a':
015dc7e1
AM
5457 do_syms = true;
5458 do_reloc = true;
5459 do_unwind = true;
5460 do_dynamic = true;
5461 do_header = true;
5462 do_sections = true;
5463 do_section_groups = true;
5464 do_segments = true;
5465 do_version = true;
5466 do_histogram = true;
5467 do_arch = true;
5468 do_notes = true;
252b5132 5469 break;
79bc120c 5470
f5842774 5471 case 'g':
015dc7e1 5472 do_section_groups = true;
f5842774 5473 break;
5477e8a0 5474 case 't':
595cf52e 5475 case 'N':
015dc7e1
AM
5476 do_sections = true;
5477 do_section_details = true;
595cf52e 5478 break;
252b5132 5479 case 'e':
015dc7e1
AM
5480 do_header = true;
5481 do_sections = true;
5482 do_segments = true;
252b5132 5483 break;
a952a375 5484 case 'A':
015dc7e1 5485 do_arch = true;
a952a375 5486 break;
252b5132 5487 case 'D':
015dc7e1 5488 do_using_dynamic = true;
252b5132
RH
5489 break;
5490 case 'r':
015dc7e1 5491 do_reloc = true;
252b5132 5492 break;
4d6ed7c8 5493 case 'u':
015dc7e1 5494 do_unwind = true;
4d6ed7c8 5495 break;
252b5132 5496 case 'h':
015dc7e1 5497 do_header = true;
252b5132
RH
5498 break;
5499 case 'l':
015dc7e1 5500 do_segments = true;
252b5132
RH
5501 break;
5502 case 's':
015dc7e1 5503 do_syms = true;
252b5132
RH
5504 break;
5505 case 'S':
015dc7e1 5506 do_sections = true;
252b5132
RH
5507 break;
5508 case 'd':
015dc7e1 5509 do_dynamic = true;
252b5132 5510 break;
a952a375 5511 case 'I':
015dc7e1 5512 do_histogram = true;
a952a375 5513 break;
779fe533 5514 case 'n':
015dc7e1 5515 do_notes = true;
779fe533 5516 break;
4145f1d5 5517 case 'c':
015dc7e1 5518 do_archive_index = true;
4145f1d5 5519 break;
1b513401 5520 case 'L':
015dc7e1 5521 do_checks = true;
1b513401 5522 break;
ca0e11aa 5523 case 'P':
015dc7e1
AM
5524 process_links = true;
5525 do_follow_links = true;
e1dbfc17 5526 dump_any_debugging = true;
ca0e11aa 5527 break;
252b5132 5528 case 'x':
6431e409 5529 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5530 break;
09c11c86 5531 case 'p':
6431e409 5532 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5533 break;
5534 case 'R':
6431e409 5535 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5536 break;
0e602686 5537 case 'z':
015dc7e1 5538 decompress_dumps = true;
0e602686 5539 break;
252b5132 5540 case 'w':
0f03783c 5541 if (optarg == NULL)
613ff48b 5542 {
015dc7e1 5543 do_debugging = true;
94585d6d
NC
5544 do_dump = true;
5545 dump_any_debugging = true;
613ff48b
CC
5546 dwarf_select_sections_all ();
5547 }
252b5132
RH
5548 else
5549 {
015dc7e1 5550 do_debugging = false;
94585d6d
NC
5551 if (dwarf_select_sections_by_letters (optarg))
5552 {
5553 do_dump = true;
5554 dump_any_debugging = true;
5555 }
252b5132
RH
5556 }
5557 break;
2979dc34 5558 case OPTION_DEBUG_DUMP:
0f03783c 5559 if (optarg == NULL)
d6249f5f 5560 {
94585d6d 5561 do_dump = true;
d6249f5f 5562 do_debugging = true;
94585d6d 5563 dump_any_debugging = true;
d6249f5f
AM
5564 dwarf_select_sections_all ();
5565 }
2979dc34
JJ
5566 else
5567 {
015dc7e1 5568 do_debugging = false;
94585d6d
NC
5569 if (dwarf_select_sections_by_names (optarg))
5570 {
5571 do_dump = true;
5572 dump_any_debugging = true;
5573 }
2979dc34
JJ
5574 }
5575 break;
fd2f0033
TT
5576 case OPTION_DWARF_DEPTH:
5577 {
5578 char *cp;
5579
5580 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5581 }
5582 break;
5583 case OPTION_DWARF_START:
5584 {
5585 char *cp;
5586
5587 dwarf_start_die = strtoul (optarg, & cp, 0);
5588 }
5589 break;
4723351a 5590 case OPTION_DWARF_CHECK:
015dc7e1 5591 dwarf_check = true;
4723351a 5592 break;
7d9813f1 5593 case OPTION_CTF_DUMP:
015dc7e1 5594 do_ctf = true;
6431e409 5595 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5596 break;
5597 case OPTION_CTF_SYMBOLS:
df16e041 5598 free (dump_ctf_symtab_name);
7d9813f1
NA
5599 dump_ctf_symtab_name = strdup (optarg);
5600 break;
5601 case OPTION_CTF_STRINGS:
df16e041 5602 free (dump_ctf_strtab_name);
7d9813f1
NA
5603 dump_ctf_strtab_name = strdup (optarg);
5604 break;
5605 case OPTION_CTF_PARENT:
df16e041 5606 free (dump_ctf_parent_name);
7d9813f1
NA
5607 dump_ctf_parent_name = strdup (optarg);
5608 break;
42b6953b
IB
5609 case OPTION_SFRAME_DUMP:
5610 do_sframe = true;
5611 /* Providing section name is optional. request_dump (), however,
5612 thrives on non NULL optarg. Handle it explicitly here. */
5613 if (optarg != NULL)
5614 request_dump (dumpdata, SFRAME_DUMP);
5615 else
5616 {
5617 do_dump = true;
5618 const char *sframe_sec_name = strdup (".sframe");
5619 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
5620 }
5621 break;
2c610e4b 5622 case OPTION_DYN_SYMS:
015dc7e1 5623 do_dyn_syms = true;
2c610e4b 5624 break;
0f03783c 5625 case OPTION_LTO_SYMS:
015dc7e1 5626 do_lto_syms = true;
0f03783c 5627 break;
252b5132
RH
5628#ifdef SUPPORT_DISASSEMBLY
5629 case 'i':
6431e409 5630 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5631 break;
252b5132
RH
5632#endif
5633 case 'v':
5634 print_version (program_name);
5635 break;
5636 case 'V':
015dc7e1 5637 do_version = true;
252b5132 5638 break;
d974e256 5639 case 'W':
015dc7e1 5640 do_wide = true;
d974e256 5641 break;
0942c7ab 5642 case 'T':
015dc7e1 5643 do_not_show_symbol_truncation = true;
0942c7ab 5644 break;
79bc120c 5645 case 'C':
015dc7e1 5646 do_demangle = true;
79bc120c
NC
5647 if (optarg != NULL)
5648 {
5649 enum demangling_styles style;
5650
5651 style = cplus_demangle_name_to_style (optarg);
5652 if (style == unknown_demangling)
5653 error (_("unknown demangling style `%s'"), optarg);
5654
5655 cplus_demangle_set_style (style);
5656 }
5657 break;
5658 case OPTION_NO_DEMANGLING:
015dc7e1 5659 do_demangle = false;
79bc120c
NC
5660 break;
5661 case OPTION_RECURSE_LIMIT:
5662 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5663 break;
5664 case OPTION_NO_RECURSE_LIMIT:
5665 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5666 break;
5667 case OPTION_WITH_SYMBOL_VERSIONS:
5668 /* Ignored for backward compatibility. */
5669 break;
b9e920ec 5670
b3aa80b4
NC
5671 case 'U':
5672 if (optarg == NULL)
5673 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5674 else if (streq (optarg, "default") || streq (optarg, "d"))
5675 unicode_display = unicode_default;
5676 else if (streq (optarg, "locale") || streq (optarg, "l"))
5677 unicode_display = unicode_locale;
5678 else if (streq (optarg, "escape") || streq (optarg, "e"))
5679 unicode_display = unicode_escape;
5680 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5681 unicode_display = unicode_invalid;
5682 else if (streq (optarg, "hex") || streq (optarg, "x"))
5683 unicode_display = unicode_hex;
5684 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5685 unicode_display = unicode_highlight;
5686 else
5687 error (_("invalid argument to -U/--unicode: %s"), optarg);
5688 break;
5689
047c3dbf
NL
5690 case OPTION_SYM_BASE:
5691 sym_base = 0;
5692 if (optarg != NULL)
5693 {
5694 sym_base = strtoul (optarg, NULL, 0);
5695 switch (sym_base)
5696 {
5697 case 0:
5698 case 8:
5699 case 10:
5700 case 16:
5701 break;
5702
5703 default:
5704 sym_base = 0;
5705 break;
5706 }
5707 }
5708 break;
5709
252b5132 5710 default:
252b5132
RH
5711 /* xgettext:c-format */
5712 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5713 /* Fall through. */
252b5132 5714 case '?':
92f01d61 5715 usage (stderr);
252b5132
RH
5716 }
5717 }
5718
4d6ed7c8 5719 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5720 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5721 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5722 && !do_section_groups && !do_archive_index
0f03783c 5723 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5724 {
5725 if (do_checks)
5726 {
015dc7e1
AM
5727 check_all = true;
5728 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5729 do_segments = do_header = do_dump = do_version = true;
5730 do_histogram = do_debugging = do_arch = do_notes = true;
5731 do_section_groups = do_archive_index = do_dyn_syms = true;
5732 do_lto_syms = true;
1b513401
NC
5733 }
5734 else
5735 usage (stderr);
5736 }
252b5132
RH
5737}
5738
5739static const char *
d3ba0551 5740get_elf_class (unsigned int elf_class)
252b5132 5741{
b34976b6 5742 static char buff[32];
103f02d3 5743
252b5132
RH
5744 switch (elf_class)
5745 {
5746 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5747 case ELFCLASS32: return "ELF32";
5748 case ELFCLASS64: return "ELF64";
ab5e7794 5749 default:
e9e44622 5750 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5751 return buff;
252b5132
RH
5752 }
5753}
5754
5755static const char *
d3ba0551 5756get_data_encoding (unsigned int encoding)
252b5132 5757{
b34976b6 5758 static char buff[32];
103f02d3 5759
252b5132
RH
5760 switch (encoding)
5761 {
5762 case ELFDATANONE: return _("none");
33c63f9d
CM
5763 case ELFDATA2LSB: return _("2's complement, little endian");
5764 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5765 default:
e9e44622 5766 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5767 return buff;
252b5132
RH
5768 }
5769}
5770
521f7268
NC
5771static bool
5772check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
5773{
5774 if (header->e_ident[EI_MAG0] == ELFMAG0
5775 && header->e_ident[EI_MAG1] == ELFMAG1
5776 && header->e_ident[EI_MAG2] == ELFMAG2
5777 && header->e_ident[EI_MAG3] == ELFMAG3)
5778 return true;
5779
5780 /* Some compilers produce object files that are not in the ELF file format.
5781 As an aid to users of readelf, try to identify these cases and suggest
5782 alternative tools.
5783
5784 FIXME: It is not clear if all four bytes are used as constant magic
5785 valus by all compilers. It may be necessary to recode this function if
5786 different tools use different length sequences. */
5787
5788 static struct
5789 {
5790 unsigned char magic[4];
5791 const char * obj_message;
5792 const char * ar_message;
5793 }
5794 known_magic[] =
5795 {
5796 { { 'B', 'C', 0xc0, 0xde },
5797 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
5798 N_("This is a LLVM bitcode file - try extracing and then using llvm-bcanalyzer\n")
5799 },
5800 { { 'g', 'o', ' ', 'o' },
5801 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
5802 NULL
5803 }
5804 };
5805 int i;
5806
5807 for (i = ARRAY_SIZE (known_magic); i--;)
5808 {
5809 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
5810 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
5811 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
5812 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
5813 {
5814 /* Some compiler's analyzer tools do not handle archives,
5815 so we provide two different kinds of error message. */
5816 if (filedata->archive_file_size > 0
5817 && known_magic[i].ar_message != NULL)
b3ea2010 5818 error ("%s", known_magic[i].ar_message);
521f7268 5819 else
b3ea2010 5820 error ("%s", known_magic[i].obj_message);
521f7268
NC
5821 return false;
5822 }
5823 }
5824
5825 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
5826 return false;
5827}
5828
dda8d76d 5829/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5830
015dc7e1 5831static bool
dda8d76d 5832process_file_header (Filedata * filedata)
252b5132 5833{
dda8d76d
NC
5834 Elf_Internal_Ehdr * header = & filedata->file_header;
5835
521f7268
NC
5836 if (! check_magic_number (filedata, header))
5837 return false;
252b5132 5838
ca0e11aa
NC
5839 if (! filedata->is_separate)
5840 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5841
252b5132
RH
5842 if (do_header)
5843 {
32ec8896 5844 unsigned i;
252b5132 5845
ca0e11aa
NC
5846 if (filedata->is_separate)
5847 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5848 else
5849 printf (_("ELF Header:\n"));
252b5132 5850 printf (_(" Magic: "));
b34976b6 5851 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5852 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5853 printf ("\n");
5854 printf (_(" Class: %s\n"),
dda8d76d 5855 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5856 printf (_(" Data: %s\n"),
dda8d76d 5857 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5858 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5859 header->e_ident[EI_VERSION],
5860 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5861 ? _(" (current)")
dda8d76d 5862 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5863 ? _(" <unknown>")
789be9f7 5864 : "")));
252b5132 5865 printf (_(" OS/ABI: %s\n"),
dda8d76d 5866 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5867 printf (_(" ABI Version: %d\n"),
dda8d76d 5868 header->e_ident[EI_ABIVERSION]);
252b5132 5869 printf (_(" Type: %s\n"),
93df3340 5870 get_file_type (filedata));
252b5132 5871 printf (_(" Machine: %s\n"),
dda8d76d 5872 get_machine_name (header->e_machine));
252b5132 5873 printf (_(" Version: 0x%lx\n"),
e8a64888 5874 header->e_version);
76da6bbe 5875
f7a99963 5876 printf (_(" Entry point address: "));
e8a64888 5877 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5878 printf (_("\n Start of program headers: "));
e8a64888 5879 print_vma (header->e_phoff, DEC);
f7a99963 5880 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5881 print_vma (header->e_shoff, DEC);
f7a99963 5882 printf (_(" (bytes into file)\n"));
76da6bbe 5883
252b5132 5884 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5885 header->e_flags,
dda8d76d 5886 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5887 printf (_(" Size of this header: %u (bytes)\n"),
5888 header->e_ehsize);
5889 printf (_(" Size of program headers: %u (bytes)\n"),
5890 header->e_phentsize);
5891 printf (_(" Number of program headers: %u"),
5892 header->e_phnum);
dda8d76d
NC
5893 if (filedata->section_headers != NULL
5894 && header->e_phnum == PN_XNUM
5895 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5896 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5897 putc ('\n', stdout);
e8a64888
AM
5898 printf (_(" Size of section headers: %u (bytes)\n"),
5899 header->e_shentsize);
5900 printf (_(" Number of section headers: %u"),
5901 header->e_shnum);
dda8d76d 5902 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5903 {
5904 header->e_shnum = filedata->section_headers[0].sh_size;
5905 printf (" (%u)", header->e_shnum);
5906 }
560f3c1c 5907 putc ('\n', stdout);
e8a64888
AM
5908 printf (_(" Section header string table index: %u"),
5909 header->e_shstrndx);
dda8d76d
NC
5910 if (filedata->section_headers != NULL
5911 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5912 {
5913 header->e_shstrndx = filedata->section_headers[0].sh_link;
5914 printf (" (%u)", header->e_shstrndx);
5915 }
5916 if (header->e_shstrndx != SHN_UNDEF
5917 && header->e_shstrndx >= header->e_shnum)
5918 {
5919 header->e_shstrndx = SHN_UNDEF;
5920 printf (_(" <corrupt: out of range>"));
5921 }
560f3c1c
AM
5922 putc ('\n', stdout);
5923 }
5924
dda8d76d 5925 if (filedata->section_headers != NULL)
560f3c1c 5926 {
dda8d76d
NC
5927 if (header->e_phnum == PN_XNUM
5928 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5929 {
5930 /* Throw away any cached read of PN_XNUM headers. */
5931 free (filedata->program_headers);
5932 filedata->program_headers = NULL;
5933 header->e_phnum = filedata->section_headers[0].sh_info;
5934 }
dda8d76d
NC
5935 if (header->e_shnum == SHN_UNDEF)
5936 header->e_shnum = filedata->section_headers[0].sh_size;
5937 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5938 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5939 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5940 header->e_shstrndx = SHN_UNDEF;
252b5132 5941 }
103f02d3 5942
015dc7e1 5943 return true;
9ea033b2
NC
5944}
5945
dda8d76d
NC
5946/* Read in the program headers from FILEDATA and store them in PHEADERS.
5947 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5948
015dc7e1 5949static bool
dda8d76d 5950get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5951{
2cf0635d
NC
5952 Elf32_External_Phdr * phdrs;
5953 Elf32_External_Phdr * external;
5954 Elf_Internal_Phdr * internal;
b34976b6 5955 unsigned int i;
dda8d76d
NC
5956 unsigned int size = filedata->file_header.e_phentsize;
5957 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5958
5959 /* PR binutils/17531: Cope with unexpected section header sizes. */
5960 if (size == 0 || num == 0)
015dc7e1 5961 return false;
e0a31db1
NC
5962 if (size < sizeof * phdrs)
5963 {
5964 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5965 return false;
e0a31db1
NC
5966 }
5967 if (size > sizeof * phdrs)
5968 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5969
dda8d76d 5970 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5971 size, num, _("program headers"));
5972 if (phdrs == NULL)
015dc7e1 5973 return false;
9ea033b2 5974
91d6fa6a 5975 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5976 i < filedata->file_header.e_phnum;
b34976b6 5977 i++, internal++, external++)
252b5132 5978 {
9ea033b2
NC
5979 internal->p_type = BYTE_GET (external->p_type);
5980 internal->p_offset = BYTE_GET (external->p_offset);
5981 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5982 internal->p_paddr = BYTE_GET (external->p_paddr);
5983 internal->p_filesz = BYTE_GET (external->p_filesz);
5984 internal->p_memsz = BYTE_GET (external->p_memsz);
5985 internal->p_flags = BYTE_GET (external->p_flags);
5986 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5987 }
5988
9ea033b2 5989 free (phdrs);
015dc7e1 5990 return true;
252b5132
RH
5991}
5992
dda8d76d
NC
5993/* Read in the program headers from FILEDATA and store them in PHEADERS.
5994 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5995
015dc7e1 5996static bool
dda8d76d 5997get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5998{
2cf0635d
NC
5999 Elf64_External_Phdr * phdrs;
6000 Elf64_External_Phdr * external;
6001 Elf_Internal_Phdr * internal;
b34976b6 6002 unsigned int i;
dda8d76d
NC
6003 unsigned int size = filedata->file_header.e_phentsize;
6004 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6005
6006 /* PR binutils/17531: Cope with unexpected section header sizes. */
6007 if (size == 0 || num == 0)
015dc7e1 6008 return false;
e0a31db1
NC
6009 if (size < sizeof * phdrs)
6010 {
6011 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6012 return false;
e0a31db1
NC
6013 }
6014 if (size > sizeof * phdrs)
6015 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6016
dda8d76d 6017 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 6018 size, num, _("program headers"));
a6e9f9df 6019 if (!phdrs)
015dc7e1 6020 return false;
9ea033b2 6021
91d6fa6a 6022 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6023 i < filedata->file_header.e_phnum;
b34976b6 6024 i++, internal++, external++)
9ea033b2
NC
6025 {
6026 internal->p_type = BYTE_GET (external->p_type);
6027 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
6028 internal->p_offset = BYTE_GET (external->p_offset);
6029 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6030 internal->p_paddr = BYTE_GET (external->p_paddr);
6031 internal->p_filesz = BYTE_GET (external->p_filesz);
6032 internal->p_memsz = BYTE_GET (external->p_memsz);
6033 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
6034 }
6035
6036 free (phdrs);
015dc7e1 6037 return true;
9ea033b2 6038}
252b5132 6039
32ec8896 6040/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 6041
015dc7e1 6042static bool
dda8d76d 6043get_program_headers (Filedata * filedata)
d93f0186 6044{
2cf0635d 6045 Elf_Internal_Phdr * phdrs;
d93f0186
NC
6046
6047 /* Check cache of prior read. */
dda8d76d 6048 if (filedata->program_headers != NULL)
015dc7e1 6049 return true;
d93f0186 6050
82156ab7
NC
6051 /* Be kind to memory checkers by looking for
6052 e_phnum values which we know must be invalid. */
dda8d76d 6053 if (filedata->file_header.e_phnum
82156ab7 6054 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 6055 >= filedata->file_size)
82156ab7
NC
6056 {
6057 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 6058 filedata->file_header.e_phnum);
015dc7e1 6059 return false;
82156ab7 6060 }
d93f0186 6061
dda8d76d 6062 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 6063 sizeof (Elf_Internal_Phdr));
d93f0186
NC
6064 if (phdrs == NULL)
6065 {
8b73c356 6066 error (_("Out of memory reading %u program headers\n"),
dda8d76d 6067 filedata->file_header.e_phnum);
015dc7e1 6068 return false;
d93f0186
NC
6069 }
6070
6071 if (is_32bit_elf
dda8d76d
NC
6072 ? get_32bit_program_headers (filedata, phdrs)
6073 : get_64bit_program_headers (filedata, phdrs))
d93f0186 6074 {
dda8d76d 6075 filedata->program_headers = phdrs;
015dc7e1 6076 return true;
d93f0186
NC
6077 }
6078
6079 free (phdrs);
015dc7e1 6080 return false;
d93f0186
NC
6081}
6082
93df3340 6083/* Print program header info and locate dynamic section. */
2f62977e 6084
93df3340 6085static void
dda8d76d 6086process_program_headers (Filedata * filedata)
252b5132 6087{
2cf0635d 6088 Elf_Internal_Phdr * segment;
b34976b6 6089 unsigned int i;
1a9ccd70 6090 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6091
dda8d76d 6092 if (filedata->file_header.e_phnum == 0)
252b5132 6093 {
82f2dbf7 6094 /* PR binutils/12467. */
dda8d76d 6095 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6096 warn (_("possibly corrupt ELF header - it has a non-zero program"
6097 " header offset, but no program headers\n"));
82f2dbf7 6098 else if (do_segments)
ca0e11aa
NC
6099 {
6100 if (filedata->is_separate)
6101 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6102 filedata->file_name);
6103 else
6104 printf (_("\nThere are no program headers in this file.\n"));
6105 }
93df3340 6106 goto no_headers;
252b5132
RH
6107 }
6108
6109 if (do_segments && !do_header)
6110 {
ca0e11aa
NC
6111 if (filedata->is_separate)
6112 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6113 filedata->file_name, get_file_type (filedata));
ca0e11aa 6114 else
93df3340 6115 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6116 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6117 filedata->file_header.e_entry);
b8281767
AM
6118 printf (ngettext ("There is %d program header,"
6119 " starting at offset %" PRIu64 "\n",
6120 "There are %d program headers,"
6121 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6122 filedata->file_header.e_phnum),
6123 filedata->file_header.e_phnum,
625d49fc 6124 filedata->file_header.e_phoff);
252b5132
RH
6125 }
6126
dda8d76d 6127 if (! get_program_headers (filedata))
93df3340 6128 goto no_headers;
103f02d3 6129
252b5132
RH
6130 if (do_segments)
6131 {
dda8d76d 6132 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6133 printf (_("\nProgram Headers:\n"));
6134 else
6135 printf (_("\nProgram Headers:\n"));
76da6bbe 6136
f7a99963
NC
6137 if (is_32bit_elf)
6138 printf
6139 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6140 else if (do_wide)
6141 printf
6142 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6143 else
6144 {
6145 printf
6146 (_(" Type Offset VirtAddr PhysAddr\n"));
6147 printf
6148 (_(" FileSiz MemSiz Flags Align\n"));
6149 }
252b5132
RH
6150 }
6151
26c527e6 6152 uint64_t dynamic_addr = 0;
be7d229a 6153 uint64_t dynamic_size = 0;
dda8d76d
NC
6154 for (i = 0, segment = filedata->program_headers;
6155 i < filedata->file_header.e_phnum;
b34976b6 6156 i++, segment++)
252b5132
RH
6157 {
6158 if (do_segments)
6159 {
dda8d76d 6160 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6161
6162 if (is_32bit_elf)
6163 {
6164 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6165 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6166 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6167 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6168 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6169 printf ("%c%c%c ",
6170 (segment->p_flags & PF_R ? 'R' : ' '),
6171 (segment->p_flags & PF_W ? 'W' : ' '),
6172 (segment->p_flags & PF_X ? 'E' : ' '));
6173 printf ("%#lx", (unsigned long) segment->p_align);
6174 }
d974e256
JJ
6175 else if (do_wide)
6176 {
6177 if ((unsigned long) segment->p_offset == segment->p_offset)
6178 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6179 else
6180 {
6181 print_vma (segment->p_offset, FULL_HEX);
6182 putchar (' ');
6183 }
6184
6185 print_vma (segment->p_vaddr, FULL_HEX);
6186 putchar (' ');
6187 print_vma (segment->p_paddr, FULL_HEX);
6188 putchar (' ');
6189
6190 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6191 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6192 else
6193 {
6194 print_vma (segment->p_filesz, FULL_HEX);
6195 putchar (' ');
6196 }
6197
6198 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6199 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6200 else
6201 {
f48e6c45 6202 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6203 }
6204
6205 printf (" %c%c%c ",
6206 (segment->p_flags & PF_R ? 'R' : ' '),
6207 (segment->p_flags & PF_W ? 'W' : ' '),
6208 (segment->p_flags & PF_X ? 'E' : ' '));
6209
6210 if ((unsigned long) segment->p_align == segment->p_align)
6211 printf ("%#lx", (unsigned long) segment->p_align);
6212 else
6213 {
6214 print_vma (segment->p_align, PREFIX_HEX);
6215 }
6216 }
f7a99963
NC
6217 else
6218 {
6219 print_vma (segment->p_offset, FULL_HEX);
6220 putchar (' ');
6221 print_vma (segment->p_vaddr, FULL_HEX);
6222 putchar (' ');
6223 print_vma (segment->p_paddr, FULL_HEX);
6224 printf ("\n ");
6225 print_vma (segment->p_filesz, FULL_HEX);
6226 putchar (' ');
6227 print_vma (segment->p_memsz, FULL_HEX);
6228 printf (" %c%c%c ",
6229 (segment->p_flags & PF_R ? 'R' : ' '),
6230 (segment->p_flags & PF_W ? 'W' : ' '),
6231 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6232 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6233 }
252b5132 6234
1a9ccd70
NC
6235 putc ('\n', stdout);
6236 }
f54498b4 6237
252b5132
RH
6238 switch (segment->p_type)
6239 {
1a9ccd70 6240 case PT_LOAD:
502d895c
NC
6241#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6242 required by the ELF standard, several programs, including the Linux
6243 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6244 if (previous_load
6245 && previous_load->p_vaddr > segment->p_vaddr)
6246 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6247#endif
1a9ccd70
NC
6248 if (segment->p_memsz < segment->p_filesz)
6249 error (_("the segment's file size is larger than its memory size\n"));
6250 previous_load = segment;
6251 break;
6252
6253 case PT_PHDR:
6254 /* PR 20815 - Verify that the program header is loaded into memory. */
6255 if (i > 0 && previous_load != NULL)
6256 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6257 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6258 {
6259 unsigned int j;
6260
dda8d76d 6261 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6262 {
6263 Elf_Internal_Phdr *load = filedata->program_headers + j;
6264 if (load->p_type == PT_LOAD
6265 && load->p_offset <= segment->p_offset
6266 && (load->p_offset + load->p_filesz
6267 >= segment->p_offset + segment->p_filesz)
6268 && load->p_vaddr <= segment->p_vaddr
6269 && (load->p_vaddr + load->p_filesz
6270 >= segment->p_vaddr + segment->p_filesz))
6271 break;
6272 }
dda8d76d 6273 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6274 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6275 }
6276 break;
6277
252b5132 6278 case PT_DYNAMIC:
93df3340 6279 if (dynamic_addr)
252b5132
RH
6280 error (_("more than one dynamic segment\n"));
6281
20737c13
AM
6282 /* By default, assume that the .dynamic section is the first
6283 section in the DYNAMIC segment. */
93df3340
AM
6284 dynamic_addr = segment->p_offset;
6285 dynamic_size = segment->p_filesz;
20737c13 6286
b2d38a17
NC
6287 /* Try to locate the .dynamic section. If there is
6288 a section header table, we can easily locate it. */
dda8d76d 6289 if (filedata->section_headers != NULL)
b2d38a17 6290 {
2cf0635d 6291 Elf_Internal_Shdr * sec;
b2d38a17 6292
dda8d76d 6293 sec = find_section (filedata, ".dynamic");
89fac5e3 6294 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6295 {
93df3340
AM
6296 /* A corresponding .dynamic section is expected, but on
6297 IA-64/OpenVMS it is OK for it to be missing. */
6298 if (!is_ia64_vms (filedata))
6299 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6300 break;
6301 }
6302
42bb2e33 6303 if (sec->sh_type == SHT_NOBITS)
20737c13 6304 {
93df3340
AM
6305 dynamic_addr = 0;
6306 dynamic_size = 0;
20737c13
AM
6307 break;
6308 }
42bb2e33 6309
93df3340
AM
6310 dynamic_addr = sec->sh_offset;
6311 dynamic_size = sec->sh_size;
b2d38a17 6312
8ac10c5b
L
6313 /* The PT_DYNAMIC segment, which is used by the run-time
6314 loader, should exactly match the .dynamic section. */
6315 if (do_checks
93df3340
AM
6316 && (dynamic_addr != segment->p_offset
6317 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6318 warn (_("\
6319the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6320 }
39e224f6
MW
6321
6322 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6323 segment. Check this after matching against the section headers
6324 so we don't warn on debuginfo file (which have NOBITS .dynamic
6325 sections). */
93df3340
AM
6326 if (dynamic_addr > filedata->file_size
6327 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6328 {
6329 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6330 dynamic_addr = 0;
6331 dynamic_size = 0;
39e224f6 6332 }
252b5132
RH
6333 break;
6334
6335 case PT_INTERP:
13acb58d
AM
6336 if (segment->p_offset >= filedata->file_size
6337 || segment->p_filesz > filedata->file_size - segment->p_offset
6338 || segment->p_filesz - 1 >= (size_t) -2
63cf857e
AM
6339 || fseek64 (filedata->handle,
6340 filedata->archive_file_offset + segment->p_offset,
6341 SEEK_SET))
252b5132
RH
6342 error (_("Unable to find program interpreter name\n"));
6343 else
6344 {
13acb58d
AM
6345 size_t len = segment->p_filesz;
6346 free (filedata->program_interpreter);
6347 filedata->program_interpreter = xmalloc (len + 1);
6348 len = fread (filedata->program_interpreter, 1, len,
6349 filedata->handle);
6350 filedata->program_interpreter[len] = 0;
252b5132
RH
6351
6352 if (do_segments)
f54498b4 6353 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6354 filedata->program_interpreter);
252b5132
RH
6355 }
6356 break;
6357 }
252b5132
RH
6358 }
6359
dda8d76d
NC
6360 if (do_segments
6361 && filedata->section_headers != NULL
6362 && filedata->string_table != NULL)
252b5132
RH
6363 {
6364 printf (_("\n Section to Segment mapping:\n"));
6365 printf (_(" Segment Sections...\n"));
6366
dda8d76d 6367 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6368 {
9ad5cbcf 6369 unsigned int j;
2cf0635d 6370 Elf_Internal_Shdr * section;
252b5132 6371
dda8d76d
NC
6372 segment = filedata->program_headers + i;
6373 section = filedata->section_headers + 1;
252b5132
RH
6374
6375 printf (" %2.2d ", i);
6376
dda8d76d 6377 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6378 {
f4638467
AM
6379 if (!ELF_TBSS_SPECIAL (section, segment)
6380 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6381 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6382 }
6383
6384 putc ('\n',stdout);
6385 }
6386 }
6387
93df3340
AM
6388 filedata->dynamic_addr = dynamic_addr;
6389 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6390 return;
6391
6392 no_headers:
6393 filedata->dynamic_addr = 0;
6394 filedata->dynamic_size = 1;
252b5132
RH
6395}
6396
6397
d93f0186
NC
6398/* Find the file offset corresponding to VMA by using the program headers. */
6399
26c527e6 6400static int64_t
625d49fc 6401offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 6402{
2cf0635d 6403 Elf_Internal_Phdr * seg;
d93f0186 6404
dda8d76d 6405 if (! get_program_headers (filedata))
d93f0186
NC
6406 {
6407 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6408 return (long) vma;
6409 }
6410
dda8d76d
NC
6411 for (seg = filedata->program_headers;
6412 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6413 ++seg)
6414 {
6415 if (seg->p_type != PT_LOAD)
6416 continue;
6417
6418 if (vma >= (seg->p_vaddr & -seg->p_align)
6419 && vma + size <= seg->p_vaddr + seg->p_filesz)
6420 return vma - seg->p_vaddr + seg->p_offset;
6421 }
6422
26c527e6
AM
6423 warn (_("Virtual address %#" PRIx64
6424 " not located in any PT_LOAD segment.\n"), vma);
6425 return vma;
d93f0186
NC
6426}
6427
6428
dda8d76d
NC
6429/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6430 If PROBE is true, this is just a probe and we do not generate any error
6431 messages if the load fails. */
049b0c3a 6432
015dc7e1
AM
6433static bool
6434get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6435{
2cf0635d
NC
6436 Elf32_External_Shdr * shdrs;
6437 Elf_Internal_Shdr * internal;
dda8d76d
NC
6438 unsigned int i;
6439 unsigned int size = filedata->file_header.e_shentsize;
6440 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6441
6442 /* PR binutils/17531: Cope with unexpected section header sizes. */
6443 if (size == 0 || num == 0)
015dc7e1 6444 return false;
907b52f4
NC
6445
6446 /* The section header cannot be at the start of the file - that is
6447 where the ELF file header is located. A file with absolutely no
6448 sections in it will use a shoff of 0. */
6449 if (filedata->file_header.e_shoff == 0)
6450 return false;
6451
049b0c3a
NC
6452 if (size < sizeof * shdrs)
6453 {
6454 if (! probe)
6455 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6456 return false;
049b0c3a
NC
6457 }
6458 if (!probe && size > sizeof * shdrs)
6459 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6460
dda8d76d 6461 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6462 size, num,
6463 probe ? NULL : _("section headers"));
6464 if (shdrs == NULL)
015dc7e1 6465 return false;
252b5132 6466
dda8d76d
NC
6467 filedata->section_headers = (Elf_Internal_Shdr *)
6468 cmalloc (num, sizeof (Elf_Internal_Shdr));
6469 if (filedata->section_headers == NULL)
252b5132 6470 {
049b0c3a 6471 if (!probe)
8b73c356 6472 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6473 free (shdrs);
015dc7e1 6474 return false;
252b5132
RH
6475 }
6476
dda8d76d 6477 for (i = 0, internal = filedata->section_headers;
560f3c1c 6478 i < num;
b34976b6 6479 i++, internal++)
252b5132
RH
6480 {
6481 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6482 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6483 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6484 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6485 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6486 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6487 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6488 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6489 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6490 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6491 if (!probe && internal->sh_link > num)
6492 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6493 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6494 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6495 }
6496
6497 free (shdrs);
015dc7e1 6498 return true;
252b5132
RH
6499}
6500
dda8d76d
NC
6501/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6502
015dc7e1
AM
6503static bool
6504get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6505{
dda8d76d
NC
6506 Elf64_External_Shdr * shdrs;
6507 Elf_Internal_Shdr * internal;
6508 unsigned int i;
6509 unsigned int size = filedata->file_header.e_shentsize;
6510 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6511
6512 /* PR binutils/17531: Cope with unexpected section header sizes. */
6513 if (size == 0 || num == 0)
015dc7e1 6514 return false;
dda8d76d 6515
907b52f4
NC
6516 /* The section header cannot be at the start of the file - that is
6517 where the ELF file header is located. A file with absolutely no
6518 sections in it will use a shoff of 0. */
6519 if (filedata->file_header.e_shoff == 0)
6520 return false;
6521
049b0c3a
NC
6522 if (size < sizeof * shdrs)
6523 {
6524 if (! probe)
6525 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6526 return false;
049b0c3a 6527 }
dda8d76d 6528
049b0c3a
NC
6529 if (! probe && size > sizeof * shdrs)
6530 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6531
dda8d76d
NC
6532 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6533 filedata->file_header.e_shoff,
049b0c3a
NC
6534 size, num,
6535 probe ? NULL : _("section headers"));
6536 if (shdrs == NULL)
015dc7e1 6537 return false;
9ea033b2 6538
dda8d76d
NC
6539 filedata->section_headers = (Elf_Internal_Shdr *)
6540 cmalloc (num, sizeof (Elf_Internal_Shdr));
6541 if (filedata->section_headers == NULL)
9ea033b2 6542 {
049b0c3a 6543 if (! probe)
8b73c356 6544 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6545 free (shdrs);
015dc7e1 6546 return false;
9ea033b2
NC
6547 }
6548
dda8d76d 6549 for (i = 0, internal = filedata->section_headers;
560f3c1c 6550 i < num;
b34976b6 6551 i++, internal++)
9ea033b2
NC
6552 {
6553 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6554 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6555 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6556 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6557 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6558 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6559 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6560 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6561 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6562 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6563 if (!probe && internal->sh_link > num)
6564 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6565 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6566 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6567 }
6568
6569 free (shdrs);
015dc7e1 6570 return true;
9ea033b2
NC
6571}
6572
4de91c10
AM
6573static bool
6574get_section_headers (Filedata *filedata, bool probe)
6575{
6576 if (filedata->section_headers != NULL)
6577 return true;
6578
4de91c10
AM
6579 if (is_32bit_elf)
6580 return get_32bit_section_headers (filedata, probe);
6581 else
6582 return get_64bit_section_headers (filedata, probe);
6583}
6584
252b5132 6585static Elf_Internal_Sym *
26c527e6
AM
6586get_32bit_elf_symbols (Filedata *filedata,
6587 Elf_Internal_Shdr *section,
6588 uint64_t *num_syms_return)
252b5132 6589{
26c527e6 6590 uint64_t number = 0;
dd24e3da 6591 Elf32_External_Sym * esyms = NULL;
ba5cdace 6592 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6593 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6594 Elf_Internal_Sym * psym;
b34976b6 6595 unsigned int j;
e3d39609 6596 elf_section_list * entry;
252b5132 6597
c9c1d674
EG
6598 if (section->sh_size == 0)
6599 {
6600 if (num_syms_return != NULL)
6601 * num_syms_return = 0;
6602 return NULL;
6603 }
6604
dd24e3da 6605 /* Run some sanity checks first. */
c9c1d674 6606 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6607 {
26c527e6 6608 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 6609 printable_section_name (filedata, section),
26c527e6 6610 section->sh_entsize);
ba5cdace 6611 goto exit_point;
dd24e3da
NC
6612 }
6613
dda8d76d 6614 if (section->sh_size > filedata->file_size)
f54498b4 6615 {
26c527e6 6616 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 6617 printable_section_name (filedata, section),
26c527e6 6618 section->sh_size);
f54498b4
NC
6619 goto exit_point;
6620 }
6621
dd24e3da
NC
6622 number = section->sh_size / section->sh_entsize;
6623
6624 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6625 {
26c527e6
AM
6626 error (_("Size (%#" PRIx64 ") of section %s "
6627 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
6628 section->sh_size,
dda8d76d 6629 printable_section_name (filedata, section),
26c527e6 6630 section->sh_entsize);
ba5cdace 6631 goto exit_point;
dd24e3da
NC
6632 }
6633
dda8d76d 6634 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6635 section->sh_size, _("symbols"));
dd24e3da 6636 if (esyms == NULL)
ba5cdace 6637 goto exit_point;
252b5132 6638
e3d39609 6639 shndx = NULL;
978c4450 6640 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 6641 {
26c527e6 6642 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
6643 continue;
6644
6645 if (shndx != NULL)
6646 {
6647 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6648 free (shndx);
6649 }
6650
6651 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6652 entry->hdr->sh_offset,
6653 1, entry->hdr->sh_size,
6654 _("symbol table section indices"));
6655 if (shndx == NULL)
6656 goto exit_point;
6657
6658 /* PR17531: file: heap-buffer-overflow */
6659 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6660 {
26c527e6 6661 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 6662 printable_section_name (filedata, entry->hdr),
26c527e6
AM
6663 entry->hdr->sh_size,
6664 section->sh_size);
e3d39609 6665 goto exit_point;
c9c1d674 6666 }
e3d39609 6667 }
9ad5cbcf 6668
3f5e193b 6669 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6670
6671 if (isyms == NULL)
6672 {
26c527e6 6673 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
dd24e3da 6674 goto exit_point;
252b5132
RH
6675 }
6676
dd24e3da 6677 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6678 {
6679 psym->st_name = BYTE_GET (esyms[j].st_name);
6680 psym->st_value = BYTE_GET (esyms[j].st_value);
6681 psym->st_size = BYTE_GET (esyms[j].st_size);
6682 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6683 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6684 psym->st_shndx
6685 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6686 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6687 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6688 psym->st_info = BYTE_GET (esyms[j].st_info);
6689 psym->st_other = BYTE_GET (esyms[j].st_other);
6690 }
6691
dd24e3da 6692 exit_point:
e3d39609
NC
6693 free (shndx);
6694 free (esyms);
252b5132 6695
ba5cdace
NC
6696 if (num_syms_return != NULL)
6697 * num_syms_return = isyms == NULL ? 0 : number;
6698
252b5132
RH
6699 return isyms;
6700}
6701
9ea033b2 6702static Elf_Internal_Sym *
26c527e6
AM
6703get_64bit_elf_symbols (Filedata *filedata,
6704 Elf_Internal_Shdr *section,
6705 uint64_t *num_syms_return)
9ea033b2 6706{
26c527e6 6707 uint64_t number = 0;
ba5cdace
NC
6708 Elf64_External_Sym * esyms = NULL;
6709 Elf_External_Sym_Shndx * shndx = NULL;
6710 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6711 Elf_Internal_Sym * psym;
b34976b6 6712 unsigned int j;
e3d39609 6713 elf_section_list * entry;
9ea033b2 6714
c9c1d674
EG
6715 if (section->sh_size == 0)
6716 {
6717 if (num_syms_return != NULL)
6718 * num_syms_return = 0;
6719 return NULL;
6720 }
6721
dd24e3da 6722 /* Run some sanity checks first. */
c9c1d674 6723 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6724 {
26c527e6 6725 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 6726 printable_section_name (filedata, section),
26c527e6 6727 section->sh_entsize);
ba5cdace 6728 goto exit_point;
dd24e3da
NC
6729 }
6730
dda8d76d 6731 if (section->sh_size > filedata->file_size)
f54498b4 6732 {
26c527e6 6733 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 6734 printable_section_name (filedata, section),
26c527e6 6735 section->sh_size);
f54498b4
NC
6736 goto exit_point;
6737 }
6738
dd24e3da
NC
6739 number = section->sh_size / section->sh_entsize;
6740
6741 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6742 {
26c527e6
AM
6743 error (_("Size (%#" PRIx64 ") of section %s "
6744 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
6745 section->sh_size,
dda8d76d 6746 printable_section_name (filedata, section),
26c527e6 6747 section->sh_entsize);
ba5cdace 6748 goto exit_point;
dd24e3da
NC
6749 }
6750
dda8d76d 6751 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6752 section->sh_size, _("symbols"));
a6e9f9df 6753 if (!esyms)
ba5cdace 6754 goto exit_point;
9ea033b2 6755
e3d39609 6756 shndx = NULL;
978c4450 6757 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 6758 {
26c527e6 6759 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
6760 continue;
6761
6762 if (shndx != NULL)
6763 {
6764 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6765 free (shndx);
c9c1d674 6766 }
e3d39609
NC
6767
6768 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6769 entry->hdr->sh_offset,
6770 1, entry->hdr->sh_size,
6771 _("symbol table section indices"));
6772 if (shndx == NULL)
6773 goto exit_point;
6774
6775 /* PR17531: file: heap-buffer-overflow */
6776 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6777 {
26c527e6 6778 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 6779 printable_section_name (filedata, entry->hdr),
26c527e6
AM
6780 entry->hdr->sh_size,
6781 section->sh_size);
e3d39609
NC
6782 goto exit_point;
6783 }
6784 }
9ad5cbcf 6785
3f5e193b 6786 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6787
6788 if (isyms == NULL)
6789 {
26c527e6 6790 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
ba5cdace 6791 goto exit_point;
9ea033b2
NC
6792 }
6793
ba5cdace 6794 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6795 {
6796 psym->st_name = BYTE_GET (esyms[j].st_name);
6797 psym->st_info = BYTE_GET (esyms[j].st_info);
6798 psym->st_other = BYTE_GET (esyms[j].st_other);
6799 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6800
4fbb74a6 6801 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6802 psym->st_shndx
6803 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6804 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6805 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6806
66543521
AM
6807 psym->st_value = BYTE_GET (esyms[j].st_value);
6808 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6809 }
6810
ba5cdace 6811 exit_point:
e3d39609
NC
6812 free (shndx);
6813 free (esyms);
ba5cdace
NC
6814
6815 if (num_syms_return != NULL)
6816 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6817
6818 return isyms;
6819}
6820
4de91c10
AM
6821static Elf_Internal_Sym *
6822get_elf_symbols (Filedata *filedata,
6823 Elf_Internal_Shdr *section,
26c527e6 6824 uint64_t *num_syms_return)
4de91c10
AM
6825{
6826 if (is_32bit_elf)
6827 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6828 else
6829 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6830}
6831
d1133906 6832static const char *
625d49fc 6833get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 6834{
5477e8a0 6835 static char buff[1024];
2cf0635d 6836 char * p = buff;
32ec8896
NC
6837 unsigned int field_size = is_32bit_elf ? 8 : 16;
6838 signed int sindex;
6839 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
6840 uint64_t os_flags = 0;
6841 uint64_t proc_flags = 0;
6842 uint64_t unknown_flags = 0;
148b93f2 6843 static const struct
5477e8a0 6844 {
2cf0635d 6845 const char * str;
32ec8896 6846 unsigned int len;
5477e8a0
L
6847 }
6848 flags [] =
6849 {
cfcac11d
NC
6850 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6851 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6852 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6853 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6854 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6855 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6856 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6857 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6858 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6859 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6860 /* IA-64 specific. */
6861 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6862 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6863 /* IA-64 OpenVMS specific. */
6864 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6865 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6866 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6867 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6868 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6869 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6870 /* Generic. */
cfcac11d 6871 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6872 /* SPARC specific. */
77115a4a 6873 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6874 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6875 /* ARM specific. */
6876 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6877 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6878 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6879 /* GNU specific. */
6880 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6881 /* VLE specific. */
6882 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6883 /* GNU specific. */
6884 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6885 };
6886
6887 if (do_section_details)
6888 {
8d5ff12c
L
6889 sprintf (buff, "[%*.*lx]: ",
6890 field_size, field_size, (unsigned long) sh_flags);
6891 p += field_size + 4;
5477e8a0 6892 }
76da6bbe 6893
d1133906
NC
6894 while (sh_flags)
6895 {
625d49fc 6896 uint64_t flag;
d1133906
NC
6897
6898 flag = sh_flags & - sh_flags;
6899 sh_flags &= ~ flag;
76da6bbe 6900
5477e8a0 6901 if (do_section_details)
d1133906 6902 {
5477e8a0
L
6903 switch (flag)
6904 {
91d6fa6a
NC
6905 case SHF_WRITE: sindex = 0; break;
6906 case SHF_ALLOC: sindex = 1; break;
6907 case SHF_EXECINSTR: sindex = 2; break;
6908 case SHF_MERGE: sindex = 3; break;
6909 case SHF_STRINGS: sindex = 4; break;
6910 case SHF_INFO_LINK: sindex = 5; break;
6911 case SHF_LINK_ORDER: sindex = 6; break;
6912 case SHF_OS_NONCONFORMING: sindex = 7; break;
6913 case SHF_GROUP: sindex = 8; break;
6914 case SHF_TLS: sindex = 9; break;
18ae9cc1 6915 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6916 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6917
5477e8a0 6918 default:
91d6fa6a 6919 sindex = -1;
dda8d76d 6920 switch (filedata->file_header.e_machine)
148b93f2 6921 {
cfcac11d 6922 case EM_IA_64:
148b93f2 6923 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6924 sindex = 10;
148b93f2 6925 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6926 sindex = 11;
dda8d76d 6927 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6928 switch (flag)
6929 {
91d6fa6a
NC
6930 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6931 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6932 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6933 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6934 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6935 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6936 default: break;
6937 }
cfcac11d
NC
6938 break;
6939
caa83f8b 6940 case EM_386:
22abe556 6941 case EM_IAMCU:
caa83f8b 6942 case EM_X86_64:
7f502d6c 6943 case EM_L1OM:
7a9068fe 6944 case EM_K1OM:
cfcac11d
NC
6945 case EM_OLD_SPARCV9:
6946 case EM_SPARC32PLUS:
6947 case EM_SPARCV9:
6948 case EM_SPARC:
18ae9cc1 6949 if (flag == SHF_ORDERED)
91d6fa6a 6950 sindex = 19;
cfcac11d 6951 break;
ac4c9b04
MG
6952
6953 case EM_ARM:
6954 switch (flag)
6955 {
6956 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6957 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6958 case SHF_COMDEF: sindex = 23; break;
6959 default: break;
6960 }
6961 break;
83eef883
AFB
6962 case EM_PPC:
6963 if (flag == SHF_PPC_VLE)
6964 sindex = 25;
6965 break;
99fabbc9
JL
6966 default:
6967 break;
6968 }
ac4c9b04 6969
99fabbc9
JL
6970 switch (filedata->file_header.e_ident[EI_OSABI])
6971 {
6972 case ELFOSABI_GNU:
6973 case ELFOSABI_FREEBSD:
6974 if (flag == SHF_GNU_RETAIN)
6975 sindex = 26;
6976 /* Fall through */
6977 case ELFOSABI_NONE:
6978 if (flag == SHF_GNU_MBIND)
6979 /* We should not recognize SHF_GNU_MBIND for
6980 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6981 not set the EI_OSABI header byte. */
6982 sindex = 24;
6983 break;
cfcac11d
NC
6984 default:
6985 break;
148b93f2 6986 }
99fabbc9 6987 break;
5477e8a0
L
6988 }
6989
91d6fa6a 6990 if (sindex != -1)
5477e8a0 6991 {
8d5ff12c
L
6992 if (p != buff + field_size + 4)
6993 {
6994 if (size < (10 + 2))
bee0ee85
NC
6995 {
6996 warn (_("Internal error: not enough buffer room for section flag info"));
6997 return _("<unknown>");
6998 }
8d5ff12c
L
6999 size -= 2;
7000 *p++ = ',';
7001 *p++ = ' ';
7002 }
7003
91d6fa6a
NC
7004 size -= flags [sindex].len;
7005 p = stpcpy (p, flags [sindex].str);
5477e8a0 7006 }
3b22753a 7007 else if (flag & SHF_MASKOS)
8d5ff12c 7008 os_flags |= flag;
d1133906 7009 else if (flag & SHF_MASKPROC)
8d5ff12c 7010 proc_flags |= flag;
d1133906 7011 else
8d5ff12c 7012 unknown_flags |= flag;
5477e8a0
L
7013 }
7014 else
7015 {
7016 switch (flag)
7017 {
7018 case SHF_WRITE: *p = 'W'; break;
7019 case SHF_ALLOC: *p = 'A'; break;
7020 case SHF_EXECINSTR: *p = 'X'; break;
7021 case SHF_MERGE: *p = 'M'; break;
7022 case SHF_STRINGS: *p = 'S'; break;
7023 case SHF_INFO_LINK: *p = 'I'; break;
7024 case SHF_LINK_ORDER: *p = 'L'; break;
7025 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7026 case SHF_GROUP: *p = 'G'; break;
7027 case SHF_TLS: *p = 'T'; break;
18ae9cc1 7028 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 7029 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
7030
7031 default:
dda8d76d
NC
7032 if ((filedata->file_header.e_machine == EM_X86_64
7033 || filedata->file_header.e_machine == EM_L1OM
7034 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
7035 && flag == SHF_X86_64_LARGE)
7036 *p = 'l';
dda8d76d 7037 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 7038 && flag == SHF_ARM_PURECODE)
99fabbc9 7039 *p = 'y';
dda8d76d 7040 else if (filedata->file_header.e_machine == EM_PPC
83eef883 7041 && flag == SHF_PPC_VLE)
99fabbc9 7042 *p = 'v';
5477e8a0
L
7043 else if (flag & SHF_MASKOS)
7044 {
99fabbc9
JL
7045 switch (filedata->file_header.e_ident[EI_OSABI])
7046 {
7047 case ELFOSABI_GNU:
7048 case ELFOSABI_FREEBSD:
7049 if (flag == SHF_GNU_RETAIN)
7050 {
7051 *p = 'R';
7052 break;
7053 }
7054 /* Fall through */
7055 case ELFOSABI_NONE:
7056 if (flag == SHF_GNU_MBIND)
7057 {
7058 /* We should not recognize SHF_GNU_MBIND for
7059 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7060 not set the EI_OSABI header byte. */
7061 *p = 'D';
7062 break;
7063 }
7064 /* Fall through */
7065 default:
7066 *p = 'o';
7067 sh_flags &= ~SHF_MASKOS;
7068 break;
7069 }
5477e8a0
L
7070 }
7071 else if (flag & SHF_MASKPROC)
7072 {
7073 *p = 'p';
7074 sh_flags &= ~ SHF_MASKPROC;
7075 }
7076 else
7077 *p = 'x';
7078 break;
7079 }
7080 p++;
d1133906
NC
7081 }
7082 }
76da6bbe 7083
8d5ff12c
L
7084 if (do_section_details)
7085 {
7086 if (os_flags)
7087 {
7088 size -= 5 + field_size;
7089 if (p != buff + field_size + 4)
7090 {
7091 if (size < (2 + 1))
bee0ee85
NC
7092 {
7093 warn (_("Internal error: not enough buffer room for section flag info"));
7094 return _("<unknown>");
7095 }
8d5ff12c
L
7096 size -= 2;
7097 *p++ = ',';
7098 *p++ = ' ';
7099 }
7100 sprintf (p, "OS (%*.*lx)", field_size, field_size,
7101 (unsigned long) os_flags);
7102 p += 5 + field_size;
7103 }
7104 if (proc_flags)
7105 {
7106 size -= 7 + field_size;
7107 if (p != buff + field_size + 4)
7108 {
7109 if (size < (2 + 1))
bee0ee85
NC
7110 {
7111 warn (_("Internal error: not enough buffer room for section flag info"));
7112 return _("<unknown>");
7113 }
8d5ff12c
L
7114 size -= 2;
7115 *p++ = ',';
7116 *p++ = ' ';
7117 }
7118 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7119 (unsigned long) proc_flags);
7120 p += 7 + field_size;
7121 }
7122 if (unknown_flags)
7123 {
7124 size -= 10 + field_size;
7125 if (p != buff + field_size + 4)
7126 {
7127 if (size < (2 + 1))
bee0ee85
NC
7128 {
7129 warn (_("Internal error: not enough buffer room for section flag info"));
7130 return _("<unknown>");
7131 }
8d5ff12c
L
7132 size -= 2;
7133 *p++ = ',';
7134 *p++ = ' ';
7135 }
2b692964 7136 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
7137 (unsigned long) unknown_flags);
7138 p += 10 + field_size;
7139 }
7140 }
7141
e9e44622 7142 *p = '\0';
d1133906
NC
7143 return buff;
7144}
7145
5844b465 7146static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7147get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7148 uint64_t size)
77115a4a
L
7149{
7150 if (is_32bit_elf)
7151 {
7152 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7153
ebdf1ebf
NC
7154 if (size < sizeof (* echdr))
7155 {
7156 error (_("Compressed section is too small even for a compression header\n"));
7157 return 0;
7158 }
7159
77115a4a
L
7160 chdr->ch_type = BYTE_GET (echdr->ch_type);
7161 chdr->ch_size = BYTE_GET (echdr->ch_size);
7162 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7163 return sizeof (*echdr);
7164 }
7165 else
7166 {
7167 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7168
ebdf1ebf
NC
7169 if (size < sizeof (* echdr))
7170 {
7171 error (_("Compressed section is too small even for a compression header\n"));
7172 return 0;
7173 }
7174
77115a4a
L
7175 chdr->ch_type = BYTE_GET (echdr->ch_type);
7176 chdr->ch_size = BYTE_GET (echdr->ch_size);
7177 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7178 return sizeof (*echdr);
7179 }
7180}
7181
015dc7e1 7182static bool
dda8d76d 7183process_section_headers (Filedata * filedata)
252b5132 7184{
2cf0635d 7185 Elf_Internal_Shdr * section;
b34976b6 7186 unsigned int i;
252b5132 7187
dda8d76d 7188 if (filedata->file_header.e_shnum == 0)
252b5132 7189 {
82f2dbf7 7190 /* PR binutils/12467. */
dda8d76d 7191 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7192 {
7193 warn (_("possibly corrupt ELF file header - it has a non-zero"
7194 " section header offset, but no section headers\n"));
015dc7e1 7195 return false;
32ec8896 7196 }
82f2dbf7 7197 else if (do_sections)
252b5132
RH
7198 printf (_("\nThere are no sections in this file.\n"));
7199
015dc7e1 7200 return true;
252b5132
RH
7201 }
7202
7203 if (do_sections && !do_header)
ca0e11aa
NC
7204 {
7205 if (filedata->is_separate && process_links)
7206 printf (_("In linked file '%s': "), filedata->file_name);
7207 if (! filedata->is_separate || process_links)
7208 printf (ngettext ("There is %d section header, "
26c527e6 7209 "starting at offset %#" PRIx64 ":\n",
ca0e11aa 7210 "There are %d section headers, "
26c527e6 7211 "starting at offset %#" PRIx64 ":\n",
ca0e11aa
NC
7212 filedata->file_header.e_shnum),
7213 filedata->file_header.e_shnum,
26c527e6 7214 filedata->file_header.e_shoff);
ca0e11aa 7215 }
252b5132 7216
4de91c10
AM
7217 if (!get_section_headers (filedata, false))
7218 return false;
252b5132
RH
7219
7220 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7221 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7222 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7223 {
dda8d76d 7224 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7225
c256ffe7
JJ
7226 if (section->sh_size != 0)
7227 {
dda8d76d
NC
7228 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7229 1, section->sh_size,
7230 _("string table"));
0de14b54 7231
dda8d76d 7232 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7233 }
252b5132
RH
7234 }
7235
7236 /* Scan the sections for the dynamic symbol table
e3c8793a 7237 and dynamic string table and debug sections. */
89fac5e3 7238 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7239 switch (filedata->file_header.e_machine)
89fac5e3
RS
7240 {
7241 case EM_MIPS:
7242 case EM_MIPS_RS3_LE:
7243 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7244 FDE addresses. However, the ABI also has a semi-official ILP32
7245 variant for which the normal FDE address size rules apply.
7246
7247 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7248 section, where XX is the size of longs in bits. Unfortunately,
7249 earlier compilers provided no way of distinguishing ILP32 objects
7250 from LP64 objects, so if there's any doubt, we should assume that
7251 the official LP64 form is being used. */
dda8d76d
NC
7252 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7253 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7254 eh_addr_size = 8;
7255 break;
0f56a26a
DD
7256
7257 case EM_H8_300:
7258 case EM_H8_300H:
dda8d76d 7259 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7260 {
7261 case E_H8_MACH_H8300:
7262 case E_H8_MACH_H8300HN:
7263 case E_H8_MACH_H8300SN:
7264 case E_H8_MACH_H8300SXN:
7265 eh_addr_size = 2;
7266 break;
7267 case E_H8_MACH_H8300H:
7268 case E_H8_MACH_H8300S:
7269 case E_H8_MACH_H8300SX:
7270 eh_addr_size = 4;
7271 break;
7272 }
f4236fe4
DD
7273 break;
7274
ff7eeb89 7275 case EM_M32C_OLD:
f4236fe4 7276 case EM_M32C:
dda8d76d 7277 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7278 {
7279 case EF_M32C_CPU_M16C:
7280 eh_addr_size = 2;
7281 break;
7282 }
7283 break;
89fac5e3
RS
7284 }
7285
76ca31c0
NC
7286#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7287 do \
7288 { \
be7d229a 7289 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7290 if (section->sh_entsize != expected_entsize) \
9dd3a467 7291 { \
f493c217 7292 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7293 i, section->sh_entsize); \
f493c217 7294 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7295 expected_entsize); \
9dd3a467 7296 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7297 } \
7298 } \
08d8fa11 7299 while (0)
9dd3a467
NC
7300
7301#define CHECK_ENTSIZE(section, i, type) \
1b513401 7302 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7303 sizeof (Elf64_External_##type))
7304
dda8d76d
NC
7305 for (i = 0, section = filedata->section_headers;
7306 i < filedata->file_header.e_shnum;
b34976b6 7307 i++, section++)
252b5132 7308 {
84714f86 7309 const char *name = section_name_print (filedata, section);
252b5132 7310
1b513401
NC
7311 /* Run some sanity checks on the headers and
7312 possibly fill in some file data as well. */
7313 switch (section->sh_type)
252b5132 7314 {
1b513401 7315 case SHT_DYNSYM:
978c4450 7316 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7317 {
7318 error (_("File contains multiple dynamic symbol tables\n"));
7319 continue;
7320 }
7321
08d8fa11 7322 CHECK_ENTSIZE (section, i, Sym);
978c4450 7323 filedata->dynamic_symbols
4de91c10 7324 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7325 filedata->dynamic_symtab_section = section;
1b513401
NC
7326 break;
7327
7328 case SHT_STRTAB:
7329 if (streq (name, ".dynstr"))
252b5132 7330 {
1b513401
NC
7331 if (filedata->dynamic_strings != NULL)
7332 {
7333 error (_("File contains multiple dynamic string tables\n"));
7334 continue;
7335 }
7336
7337 filedata->dynamic_strings
7338 = (char *) get_data (NULL, filedata, section->sh_offset,
7339 1, section->sh_size, _("dynamic strings"));
7340 filedata->dynamic_strings_length
7341 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7342 filedata->dynamic_strtab_section = section;
252b5132 7343 }
1b513401
NC
7344 break;
7345
7346 case SHT_SYMTAB_SHNDX:
7347 {
7348 elf_section_list * entry = xmalloc (sizeof * entry);
7349
7350 entry->hdr = section;
7351 entry->next = filedata->symtab_shndx_list;
7352 filedata->symtab_shndx_list = entry;
7353 }
7354 break;
7355
7356 case SHT_SYMTAB:
7357 CHECK_ENTSIZE (section, i, Sym);
7358 break;
7359
7360 case SHT_GROUP:
7361 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7362 break;
252b5132 7363
1b513401
NC
7364 case SHT_REL:
7365 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7366 if (do_checks && section->sh_size == 0)
1b513401
NC
7367 warn (_("Section '%s': zero-sized relocation section\n"), name);
7368 break;
7369
7370 case SHT_RELA:
7371 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7372 if (do_checks && section->sh_size == 0)
1b513401
NC
7373 warn (_("Section '%s': zero-sized relocation section\n"), name);
7374 break;
7375
682351b9
AM
7376 case SHT_RELR:
7377 CHECK_ENTSIZE (section, i, Relr);
7378 break;
7379
1b513401
NC
7380 case SHT_NOTE:
7381 case SHT_PROGBITS:
546cb2d8
NC
7382 /* Having a zero sized section is not illegal according to the
7383 ELF standard, but it might be an indication that something
7384 is wrong. So issue a warning if we are running in lint mode. */
7385 if (do_checks && section->sh_size == 0)
1b513401
NC
7386 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7387 break;
7388
7389 default:
7390 break;
7391 }
7392
7393 if ((do_debugging || do_debug_info || do_debug_abbrevs
7394 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7395 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7396 || do_debug_str || do_debug_str_offsets || do_debug_loc
7397 || do_debug_ranges
1b513401 7398 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7399 && (startswith (name, ".debug_")
7400 || startswith (name, ".zdebug_")))
252b5132 7401 {
1b315056
CS
7402 if (name[1] == 'z')
7403 name += sizeof (".zdebug_") - 1;
7404 else
7405 name += sizeof (".debug_") - 1;
252b5132
RH
7406
7407 if (do_debugging
24d127aa
ML
7408 || (do_debug_info && startswith (name, "info"))
7409 || (do_debug_info && startswith (name, "types"))
7410 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7411 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7412 || (do_debug_lines && startswith (name, "line."))
7413 || (do_debug_pubnames && startswith (name, "pubnames"))
7414 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7415 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7416 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7417 || (do_debug_aranges && startswith (name, "aranges"))
7418 || (do_debug_ranges && startswith (name, "ranges"))
7419 || (do_debug_ranges && startswith (name, "rnglists"))
7420 || (do_debug_frames && startswith (name, "frame"))
7421 || (do_debug_macinfo && startswith (name, "macinfo"))
7422 || (do_debug_macinfo && startswith (name, "macro"))
7423 || (do_debug_str && startswith (name, "str"))
7424 || (do_debug_links && startswith (name, "sup"))
7425 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7426 || (do_debug_loc && startswith (name, "loc"))
7427 || (do_debug_loc && startswith (name, "loclists"))
7428 || (do_debug_addr && startswith (name, "addr"))
7429 || (do_debug_cu_index && startswith (name, "cu_index"))
7430 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7431 )
6431e409 7432 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7433 }
a262ae96 7434 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7435 else if ((do_debugging || do_debug_info)
24d127aa 7436 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7437 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7438 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7439 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7440 else if (do_gdb_index && (streq (name, ".gdb_index")
7441 || streq (name, ".debug_names")))
6431e409 7442 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7443 /* Trace sections for Itanium VMS. */
7444 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7445 || do_trace_aranges)
24d127aa 7446 && startswith (name, ".trace_"))
6f875884
TG
7447 {
7448 name += sizeof (".trace_") - 1;
7449
7450 if (do_debugging
7451 || (do_trace_info && streq (name, "info"))
7452 || (do_trace_abbrevs && streq (name, "abbrev"))
7453 || (do_trace_aranges && streq (name, "aranges"))
7454 )
6431e409 7455 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7456 }
dda8d76d 7457 else if ((do_debugging || do_debug_links)
24d127aa
ML
7458 && (startswith (name, ".gnu_debuglink")
7459 || startswith (name, ".gnu_debugaltlink")))
6431e409 7460 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7461 }
7462
7463 if (! do_sections)
015dc7e1 7464 return true;
252b5132 7465
ca0e11aa 7466 if (filedata->is_separate && ! process_links)
015dc7e1 7467 return true;
ca0e11aa
NC
7468
7469 if (filedata->is_separate)
7470 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7471 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7472 printf (_("\nSection Headers:\n"));
7473 else
7474 printf (_("\nSection Header:\n"));
76da6bbe 7475
f7a99963 7476 if (is_32bit_elf)
595cf52e 7477 {
5477e8a0 7478 if (do_section_details)
595cf52e
L
7479 {
7480 printf (_(" [Nr] Name\n"));
5477e8a0 7481 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7482 }
7483 else
7484 printf
7485 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7486 }
d974e256 7487 else if (do_wide)
595cf52e 7488 {
5477e8a0 7489 if (do_section_details)
595cf52e
L
7490 {
7491 printf (_(" [Nr] Name\n"));
5477e8a0 7492 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7493 }
7494 else
7495 printf
7496 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7497 }
f7a99963
NC
7498 else
7499 {
5477e8a0 7500 if (do_section_details)
595cf52e
L
7501 {
7502 printf (_(" [Nr] Name\n"));
5477e8a0
L
7503 printf (_(" Type Address Offset Link\n"));
7504 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7505 }
7506 else
7507 {
7508 printf (_(" [Nr] Name Type Address Offset\n"));
7509 printf (_(" Size EntSize Flags Link Info Align\n"));
7510 }
f7a99963 7511 }
252b5132 7512
5477e8a0
L
7513 if (do_section_details)
7514 printf (_(" Flags\n"));
7515
dda8d76d
NC
7516 for (i = 0, section = filedata->section_headers;
7517 i < filedata->file_header.e_shnum;
b34976b6 7518 i++, section++)
252b5132 7519 {
dd905818
NC
7520 /* Run some sanity checks on the section header. */
7521
7522 /* Check the sh_link field. */
7523 switch (section->sh_type)
7524 {
285e3f99
AM
7525 case SHT_REL:
7526 case SHT_RELA:
7527 if (section->sh_link == 0
7528 && (filedata->file_header.e_type == ET_EXEC
7529 || filedata->file_header.e_type == ET_DYN))
7530 /* A dynamic relocation section where all entries use a
7531 zero symbol index need not specify a symtab section. */
7532 break;
7533 /* Fall through. */
dd905818
NC
7534 case SHT_SYMTAB_SHNDX:
7535 case SHT_GROUP:
7536 case SHT_HASH:
7537 case SHT_GNU_HASH:
7538 case SHT_GNU_versym:
285e3f99 7539 if (section->sh_link == 0
dda8d76d
NC
7540 || section->sh_link >= filedata->file_header.e_shnum
7541 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7542 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7543 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7544 i, section->sh_link);
7545 break;
7546
7547 case SHT_DYNAMIC:
7548 case SHT_SYMTAB:
7549 case SHT_DYNSYM:
7550 case SHT_GNU_verneed:
7551 case SHT_GNU_verdef:
7552 case SHT_GNU_LIBLIST:
285e3f99 7553 if (section->sh_link == 0
dda8d76d
NC
7554 || section->sh_link >= filedata->file_header.e_shnum
7555 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7556 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7557 i, section->sh_link);
7558 break;
7559
7560 case SHT_INIT_ARRAY:
7561 case SHT_FINI_ARRAY:
7562 case SHT_PREINIT_ARRAY:
7563 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7564 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7565 i, section->sh_link);
7566 break;
7567
7568 default:
7569 /* FIXME: Add support for target specific section types. */
7570#if 0 /* Currently we do not check other section types as there are too
7571 many special cases. Stab sections for example have a type
7572 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7573 section. */
7574 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7575 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7576 i, section->sh_link);
7577#endif
7578 break;
7579 }
7580
7581 /* Check the sh_info field. */
7582 switch (section->sh_type)
7583 {
7584 case SHT_REL:
7585 case SHT_RELA:
285e3f99
AM
7586 if (section->sh_info == 0
7587 && (filedata->file_header.e_type == ET_EXEC
7588 || filedata->file_header.e_type == ET_DYN))
7589 /* Dynamic relocations apply to segments, so they do not
7590 need to specify the section they relocate. */
7591 break;
7592 if (section->sh_info == 0
dda8d76d
NC
7593 || section->sh_info >= filedata->file_header.e_shnum
7594 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7595 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7596 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7597 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7598 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7599 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7600 /* FIXME: Are other section types valid ? */
dda8d76d 7601 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7602 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7603 i, section->sh_info);
dd905818
NC
7604 break;
7605
7606 case SHT_DYNAMIC:
7607 case SHT_HASH:
7608 case SHT_SYMTAB_SHNDX:
7609 case SHT_INIT_ARRAY:
7610 case SHT_FINI_ARRAY:
7611 case SHT_PREINIT_ARRAY:
7612 if (section->sh_info != 0)
7613 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7614 i, section->sh_info);
7615 break;
7616
7617 case SHT_GROUP:
7618 case SHT_SYMTAB:
7619 case SHT_DYNSYM:
7620 /* A symbol index - we assume that it is valid. */
7621 break;
7622
7623 default:
7624 /* FIXME: Add support for target specific section types. */
7625 if (section->sh_type == SHT_NOBITS)
7626 /* NOBITS section headers with non-zero sh_info fields can be
7627 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7628 information. The stripped sections have their headers
7629 preserved but their types set to SHT_NOBITS. So do not check
7630 this type of section. */
dd905818
NC
7631 ;
7632 else if (section->sh_flags & SHF_INFO_LINK)
7633 {
dda8d76d 7634 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7635 warn (_("[%2u]: Expected link to another section in info field"), i);
7636 }
a91e1603
L
7637 else if (section->sh_type < SHT_LOOS
7638 && (section->sh_flags & SHF_GNU_MBIND) == 0
7639 && section->sh_info != 0)
dd905818
NC
7640 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7641 i, section->sh_info);
7642 break;
7643 }
7644
3e6b6445 7645 /* Check the sh_size field. */
dda8d76d 7646 if (section->sh_size > filedata->file_size
3e6b6445
NC
7647 && section->sh_type != SHT_NOBITS
7648 && section->sh_type != SHT_NULL
7649 && section->sh_type < SHT_LOOS)
7650 warn (_("Size of section %u is larger than the entire file!\n"), i);
7651
7bfd842d 7652 printf (" [%2u] ", i);
5477e8a0 7653 if (do_section_details)
dda8d76d 7654 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7655 else
84714f86 7656 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7657
ea52a088 7658 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7659 get_section_type_name (filedata, section->sh_type));
0b4362b0 7660
f7a99963
NC
7661 if (is_32bit_elf)
7662 {
cfcac11d
NC
7663 const char * link_too_big = NULL;
7664
f7a99963 7665 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7666
f7a99963
NC
7667 printf ( " %6.6lx %6.6lx %2.2lx",
7668 (unsigned long) section->sh_offset,
7669 (unsigned long) section->sh_size,
7670 (unsigned long) section->sh_entsize);
d1133906 7671
5477e8a0
L
7672 if (do_section_details)
7673 fputs (" ", stdout);
7674 else
dda8d76d 7675 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7676
dda8d76d 7677 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7678 {
7679 link_too_big = "";
7680 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7681 an error but it can have special values in Solaris binaries. */
dda8d76d 7682 switch (filedata->file_header.e_machine)
cfcac11d 7683 {
caa83f8b 7684 case EM_386:
22abe556 7685 case EM_IAMCU:
caa83f8b 7686 case EM_X86_64:
7f502d6c 7687 case EM_L1OM:
7a9068fe 7688 case EM_K1OM:
cfcac11d
NC
7689 case EM_OLD_SPARCV9:
7690 case EM_SPARC32PLUS:
7691 case EM_SPARCV9:
7692 case EM_SPARC:
7693 if (section->sh_link == (SHN_BEFORE & 0xffff))
7694 link_too_big = "BEFORE";
7695 else if (section->sh_link == (SHN_AFTER & 0xffff))
7696 link_too_big = "AFTER";
7697 break;
7698 default:
7699 break;
7700 }
7701 }
7702
7703 if (do_section_details)
7704 {
7705 if (link_too_big != NULL && * link_too_big)
7706 printf ("<%s> ", link_too_big);
7707 else
7708 printf ("%2u ", section->sh_link);
7709 printf ("%3u %2lu\n", section->sh_info,
7710 (unsigned long) section->sh_addralign);
7711 }
7712 else
7713 printf ("%2u %3u %2lu\n",
7714 section->sh_link,
7715 section->sh_info,
7716 (unsigned long) section->sh_addralign);
7717
7718 if (link_too_big && ! * link_too_big)
7719 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7720 i, section->sh_link);
f7a99963 7721 }
d974e256
JJ
7722 else if (do_wide)
7723 {
7724 print_vma (section->sh_addr, LONG_HEX);
7725
7726 if ((long) section->sh_offset == section->sh_offset)
7727 printf (" %6.6lx", (unsigned long) section->sh_offset);
7728 else
7729 {
7730 putchar (' ');
7731 print_vma (section->sh_offset, LONG_HEX);
7732 }
7733
7734 if ((unsigned long) section->sh_size == section->sh_size)
7735 printf (" %6.6lx", (unsigned long) section->sh_size);
7736 else
7737 {
7738 putchar (' ');
7739 print_vma (section->sh_size, LONG_HEX);
7740 }
7741
7742 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7743 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7744 else
7745 {
7746 putchar (' ');
7747 print_vma (section->sh_entsize, LONG_HEX);
7748 }
7749
5477e8a0
L
7750 if (do_section_details)
7751 fputs (" ", stdout);
7752 else
dda8d76d 7753 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7754
72de5009 7755 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7756
7757 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7758 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7759 else
7760 {
7761 print_vma (section->sh_addralign, DEC);
7762 putchar ('\n');
7763 }
7764 }
5477e8a0 7765 else if (do_section_details)
595cf52e 7766 {
55cc53e9 7767 putchar (' ');
595cf52e
L
7768 print_vma (section->sh_addr, LONG_HEX);
7769 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7770 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7771 else
7772 {
7773 printf (" ");
7774 print_vma (section->sh_offset, LONG_HEX);
7775 }
72de5009 7776 printf (" %u\n ", section->sh_link);
595cf52e 7777 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7778 putchar (' ');
595cf52e
L
7779 print_vma (section->sh_entsize, LONG_HEX);
7780
72de5009
AM
7781 printf (" %-16u %lu\n",
7782 section->sh_info,
595cf52e
L
7783 (unsigned long) section->sh_addralign);
7784 }
f7a99963
NC
7785 else
7786 {
7787 putchar (' ');
7788 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7789 if ((long) section->sh_offset == section->sh_offset)
7790 printf (" %8.8lx", (unsigned long) section->sh_offset);
7791 else
7792 {
7793 printf (" ");
7794 print_vma (section->sh_offset, LONG_HEX);
7795 }
f7a99963
NC
7796 printf ("\n ");
7797 print_vma (section->sh_size, LONG_HEX);
7798 printf (" ");
7799 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7800
dda8d76d 7801 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7802
72de5009
AM
7803 printf (" %2u %3u %lu\n",
7804 section->sh_link,
7805 section->sh_info,
f7a99963
NC
7806 (unsigned long) section->sh_addralign);
7807 }
5477e8a0
L
7808
7809 if (do_section_details)
77115a4a 7810 {
dda8d76d 7811 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7812 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7813 {
7814 /* Minimum section size is 12 bytes for 32-bit compression
7815 header + 12 bytes for compressed data header. */
7816 unsigned char buf[24];
d8024a91 7817
77115a4a 7818 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7819 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7820 sizeof (buf), _("compression header")))
7821 {
7822 Elf_Internal_Chdr chdr;
d8024a91 7823
5844b465
NC
7824 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7825 printf (_(" [<corrupt>]\n"));
77115a4a 7826 else
5844b465 7827 {
89dbeac7 7828 if (chdr.ch_type == ch_compress_zlib)
5844b465 7829 printf (" ZLIB, ");
89dbeac7 7830 else if (chdr.ch_type == ch_compress_zstd)
1369522f 7831 printf (" ZSTD, ");
5844b465
NC
7832 else
7833 printf (_(" [<unknown>: 0x%x], "),
7834 chdr.ch_type);
7835 print_vma (chdr.ch_size, LONG_HEX);
7836 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7837 }
77115a4a
L
7838 }
7839 }
7840 }
252b5132
RH
7841 }
7842
5477e8a0 7843 if (!do_section_details)
3dbcc61d 7844 {
9fb71ee4
NC
7845 /* The ordering of the letters shown here matches the ordering of the
7846 corresponding SHF_xxx values, and hence the order in which these
7847 letters will be displayed to the user. */
7848 printf (_("Key to Flags:\n\
7849 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7850 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7851 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7852 switch (filedata->file_header.e_ident[EI_OSABI])
7853 {
7854 case ELFOSABI_GNU:
7855 case ELFOSABI_FREEBSD:
7856 printf (_("R (retain), "));
7857 /* Fall through */
7858 case ELFOSABI_NONE:
7859 printf (_("D (mbind), "));
7860 break;
7861 default:
7862 break;
7863 }
dda8d76d
NC
7864 if (filedata->file_header.e_machine == EM_X86_64
7865 || filedata->file_header.e_machine == EM_L1OM
7866 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7867 printf (_("l (large), "));
dda8d76d 7868 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7869 printf (_("y (purecode), "));
dda8d76d 7870 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7871 printf (_("v (VLE), "));
9fb71ee4 7872 printf ("p (processor specific)\n");
0b4362b0 7873 }
d1133906 7874
015dc7e1 7875 return true;
252b5132
RH
7876}
7877
015dc7e1 7878static bool
28d13567 7879get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
26c527e6
AM
7880 Elf_Internal_Sym **symtab, uint64_t *nsyms,
7881 char **strtab, uint64_t *strtablen)
28d13567
AM
7882{
7883 *strtab = NULL;
7884 *strtablen = 0;
4de91c10 7885 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7886
7887 if (*symtab == NULL)
015dc7e1 7888 return false;
28d13567
AM
7889
7890 if (symsec->sh_link != 0)
7891 {
7892 Elf_Internal_Shdr *strsec;
7893
7894 if (symsec->sh_link >= filedata->file_header.e_shnum)
7895 {
7896 error (_("Bad sh_link in symbol table section\n"));
7897 free (*symtab);
7898 *symtab = NULL;
7899 *nsyms = 0;
015dc7e1 7900 return false;
28d13567
AM
7901 }
7902
7903 strsec = filedata->section_headers + symsec->sh_link;
7904
7905 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7906 1, strsec->sh_size, _("string table"));
7907 if (*strtab == NULL)
7908 {
7909 free (*symtab);
7910 *symtab = NULL;
7911 *nsyms = 0;
015dc7e1 7912 return false;
28d13567
AM
7913 }
7914 *strtablen = strsec->sh_size;
7915 }
015dc7e1 7916 return true;
28d13567
AM
7917}
7918
f5842774
L
7919static const char *
7920get_group_flags (unsigned int flags)
7921{
1449284b 7922 static char buff[128];
220453ec 7923
6d913794
NC
7924 if (flags == 0)
7925 return "";
7926 else if (flags == GRP_COMDAT)
7927 return "COMDAT ";
f5842774 7928
89246a0e
AM
7929 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7930 flags,
7931 flags & GRP_MASKOS ? _("<OS specific>") : "",
7932 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7933 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7934 ? _("<unknown>") : ""));
6d913794 7935
f5842774
L
7936 return buff;
7937}
7938
015dc7e1 7939static bool
dda8d76d 7940process_section_groups (Filedata * filedata)
f5842774 7941{
2cf0635d 7942 Elf_Internal_Shdr * section;
f5842774 7943 unsigned int i;
2cf0635d
NC
7944 struct group * group;
7945 Elf_Internal_Shdr * symtab_sec;
7946 Elf_Internal_Shdr * strtab_sec;
7947 Elf_Internal_Sym * symtab;
26c527e6 7948 uint64_t num_syms;
2cf0635d 7949 char * strtab;
c256ffe7 7950 size_t strtab_size;
d1f5c6e3
L
7951
7952 /* Don't process section groups unless needed. */
7953 if (!do_unwind && !do_section_groups)
015dc7e1 7954 return true;
f5842774 7955
dda8d76d 7956 if (filedata->file_header.e_shnum == 0)
f5842774
L
7957 {
7958 if (do_section_groups)
ca0e11aa
NC
7959 {
7960 if (filedata->is_separate)
7961 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7962 filedata->file_name);
7963 else
7964 printf (_("\nThere are no section groups in this file.\n"));
7965 }
015dc7e1 7966 return true;
f5842774
L
7967 }
7968
dda8d76d 7969 if (filedata->section_headers == NULL)
f5842774
L
7970 {
7971 error (_("Section headers are not available!\n"));
fa1908fd 7972 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7973 return false;
f5842774
L
7974 }
7975
978c4450
AM
7976 filedata->section_headers_groups
7977 = (struct group **) calloc (filedata->file_header.e_shnum,
7978 sizeof (struct group *));
e4b17d5c 7979
978c4450 7980 if (filedata->section_headers_groups == NULL)
e4b17d5c 7981 {
8b73c356 7982 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7983 filedata->file_header.e_shnum);
015dc7e1 7984 return false;
e4b17d5c
L
7985 }
7986
f5842774 7987 /* Scan the sections for the group section. */
978c4450 7988 filedata->group_count = 0;
dda8d76d
NC
7989 for (i = 0, section = filedata->section_headers;
7990 i < filedata->file_header.e_shnum;
f5842774 7991 i++, section++)
e4b17d5c 7992 if (section->sh_type == SHT_GROUP)
978c4450 7993 filedata->group_count++;
e4b17d5c 7994
978c4450 7995 if (filedata->group_count == 0)
d1f5c6e3
L
7996 {
7997 if (do_section_groups)
ca0e11aa
NC
7998 {
7999 if (filedata->is_separate)
8000 printf (_("\nThere are no section groups in linked file '%s'.\n"),
8001 filedata->file_name);
8002 else
8003 printf (_("\nThere are no section groups in this file.\n"));
8004 }
d1f5c6e3 8005
015dc7e1 8006 return true;
d1f5c6e3
L
8007 }
8008
978c4450
AM
8009 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8010 sizeof (struct group));
e4b17d5c 8011
978c4450 8012 if (filedata->section_groups == NULL)
e4b17d5c 8013 {
26c527e6 8014 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
015dc7e1 8015 return false;
e4b17d5c
L
8016 }
8017
d1f5c6e3
L
8018 symtab_sec = NULL;
8019 strtab_sec = NULL;
8020 symtab = NULL;
ba5cdace 8021 num_syms = 0;
d1f5c6e3 8022 strtab = NULL;
c256ffe7 8023 strtab_size = 0;
ca0e11aa
NC
8024
8025 if (filedata->is_separate)
8026 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 8027
978c4450 8028 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 8029 i < filedata->file_header.e_shnum;
e4b17d5c 8030 i++, section++)
f5842774
L
8031 {
8032 if (section->sh_type == SHT_GROUP)
8033 {
dda8d76d 8034 const char * name = printable_section_name (filedata, section);
74e1a04b 8035 const char * group_name;
2cf0635d
NC
8036 unsigned char * start;
8037 unsigned char * indices;
f5842774 8038 unsigned int entry, j, size;
2cf0635d
NC
8039 Elf_Internal_Shdr * sec;
8040 Elf_Internal_Sym * sym;
f5842774
L
8041
8042 /* Get the symbol table. */
dda8d76d
NC
8043 if (section->sh_link >= filedata->file_header.e_shnum
8044 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 8045 != SHT_SYMTAB))
f5842774
L
8046 {
8047 error (_("Bad sh_link in group section `%s'\n"), name);
8048 continue;
8049 }
d1f5c6e3
L
8050
8051 if (symtab_sec != sec)
8052 {
8053 symtab_sec = sec;
9db70fc3 8054 free (symtab);
4de91c10 8055 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 8056 }
f5842774 8057
dd24e3da
NC
8058 if (symtab == NULL)
8059 {
8060 error (_("Corrupt header in group section `%s'\n"), name);
8061 continue;
8062 }
8063
ba5cdace
NC
8064 if (section->sh_info >= num_syms)
8065 {
8066 error (_("Bad sh_info in group section `%s'\n"), name);
8067 continue;
8068 }
8069
f5842774
L
8070 sym = symtab + section->sh_info;
8071
8072 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8073 {
4fbb74a6 8074 if (sym->st_shndx == 0
dda8d76d 8075 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
8076 {
8077 error (_("Bad sh_info in group section `%s'\n"), name);
8078 continue;
8079 }
ba2685cc 8080
84714f86
AM
8081 group_name = section_name_print (filedata,
8082 filedata->section_headers
b9e920ec 8083 + sym->st_shndx);
c256ffe7 8084 strtab_sec = NULL;
9db70fc3 8085 free (strtab);
f5842774 8086 strtab = NULL;
c256ffe7 8087 strtab_size = 0;
f5842774
L
8088 }
8089 else
8090 {
8091 /* Get the string table. */
dda8d76d 8092 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8093 {
8094 strtab_sec = NULL;
9db70fc3 8095 free (strtab);
c256ffe7
JJ
8096 strtab = NULL;
8097 strtab_size = 0;
8098 }
8099 else if (strtab_sec
dda8d76d 8100 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8101 {
8102 strtab_sec = sec;
9db70fc3 8103 free (strtab);
071436c6 8104
dda8d76d 8105 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8106 1, strtab_sec->sh_size,
8107 _("string table"));
c256ffe7 8108 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8109 }
c256ffe7 8110 group_name = sym->st_name < strtab_size
2b692964 8111 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8112 }
8113
c9c1d674
EG
8114 /* PR 17531: file: loop. */
8115 if (section->sh_entsize > section->sh_size)
8116 {
26c527e6
AM
8117 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8118 " which is larger than its size (%#" PRIx64 ")\n"),
dda8d76d 8119 printable_section_name (filedata, section),
26c527e6
AM
8120 section->sh_entsize,
8121 section->sh_size);
61dd8e19 8122 continue;
c9c1d674
EG
8123 }
8124
dda8d76d 8125 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8126 1, section->sh_size,
8127 _("section data"));
59245841
NC
8128 if (start == NULL)
8129 continue;
f5842774
L
8130
8131 indices = start;
8132 size = (section->sh_size / section->sh_entsize) - 1;
8133 entry = byte_get (indices, 4);
8134 indices += 4;
e4b17d5c
L
8135
8136 if (do_section_groups)
8137 {
2b692964 8138 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8139 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8140
e4b17d5c
L
8141 printf (_(" [Index] Name\n"));
8142 }
8143
8144 group->group_index = i;
8145
f5842774
L
8146 for (j = 0; j < size; j++)
8147 {
2cf0635d 8148 struct group_list * g;
e4b17d5c 8149
f5842774
L
8150 entry = byte_get (indices, 4);
8151 indices += 4;
8152
dda8d76d 8153 if (entry >= filedata->file_header.e_shnum)
391cb864 8154 {
57028622
NC
8155 static unsigned num_group_errors = 0;
8156
8157 if (num_group_errors ++ < 10)
8158 {
8159 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8160 entry, i, filedata->file_header.e_shnum - 1);
57028622 8161 if (num_group_errors == 10)
67ce483b 8162 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8163 }
391cb864
L
8164 continue;
8165 }
391cb864 8166
978c4450 8167 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8168 {
d1f5c6e3
L
8169 if (entry)
8170 {
57028622
NC
8171 static unsigned num_errs = 0;
8172
8173 if (num_errs ++ < 10)
8174 {
8175 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8176 entry, i,
978c4450 8177 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8178 if (num_errs == 10)
8179 warn (_("Further error messages about already contained group sections suppressed\n"));
8180 }
d1f5c6e3
L
8181 continue;
8182 }
8183 else
8184 {
8185 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8186 section group. We just warn it the first time
d1f5c6e3 8187 and ignore it afterwards. */
015dc7e1 8188 static bool warned = false;
d1f5c6e3
L
8189 if (!warned)
8190 {
8191 error (_("section 0 in group section [%5u]\n"),
978c4450 8192 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8193 warned = true;
d1f5c6e3
L
8194 }
8195 }
e4b17d5c
L
8196 }
8197
978c4450 8198 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8199
8200 if (do_section_groups)
8201 {
dda8d76d
NC
8202 sec = filedata->section_headers + entry;
8203 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8204 }
8205
3f5e193b 8206 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8207 g->section_index = entry;
8208 g->next = group->root;
8209 group->root = g;
f5842774
L
8210 }
8211
9db70fc3 8212 free (start);
e4b17d5c
L
8213
8214 group++;
f5842774
L
8215 }
8216 }
8217
9db70fc3
AM
8218 free (symtab);
8219 free (strtab);
015dc7e1 8220 return true;
f5842774
L
8221}
8222
28f997cf
TG
8223/* Data used to display dynamic fixups. */
8224
8225struct ia64_vms_dynfixup
8226{
625d49fc
AM
8227 uint64_t needed_ident; /* Library ident number. */
8228 uint64_t needed; /* Index in the dstrtab of the library name. */
8229 uint64_t fixup_needed; /* Index of the library. */
8230 uint64_t fixup_rela_cnt; /* Number of fixups. */
8231 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8232};
8233
8234/* Data used to display dynamic relocations. */
8235
8236struct ia64_vms_dynimgrela
8237{
625d49fc
AM
8238 uint64_t img_rela_cnt; /* Number of relocations. */
8239 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8240};
8241
8242/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8243 library). */
8244
015dc7e1 8245static bool
dda8d76d
NC
8246dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8247 struct ia64_vms_dynfixup * fixup,
8248 const char * strtab,
8249 unsigned int strtab_sz)
28f997cf 8250{
32ec8896 8251 Elf64_External_VMS_IMAGE_FIXUP * imfs;
26c527e6 8252 size_t i;
32ec8896 8253 const char * lib_name;
28f997cf 8254
978c4450
AM
8255 imfs = get_data (NULL, filedata,
8256 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8257 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8258 _("dynamic section image fixups"));
8259 if (!imfs)
015dc7e1 8260 return false;
28f997cf
TG
8261
8262 if (fixup->needed < strtab_sz)
8263 lib_name = strtab + fixup->needed;
8264 else
8265 {
26c527e6
AM
8266 warn (_("corrupt library name index of %#" PRIx64
8267 " found in dynamic entry"), fixup->needed);
28f997cf
TG
8268 lib_name = "???";
8269 }
736990c4 8270
26c527e6
AM
8271 printf (_("\nImage fixups for needed library #%" PRId64
8272 ": %s - ident: %" PRIx64 "\n"),
8273 fixup->fixup_needed, lib_name, fixup->needed_ident);
28f997cf
TG
8274 printf
8275 (_("Seg Offset Type SymVec DataType\n"));
8276
26c527e6 8277 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
28f997cf
TG
8278 {
8279 unsigned int type;
8280 const char *rtype;
8281
8282 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8283 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8284 type = BYTE_GET (imfs [i].type);
8285 rtype = elf_ia64_reloc_type (type);
8286 if (rtype == NULL)
f493c217 8287 printf ("0x%08x ", type);
28f997cf 8288 else
f493c217 8289 printf ("%-32s ", rtype);
28f997cf
TG
8290 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8291 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8292 }
8293
8294 free (imfs);
015dc7e1 8295 return true;
28f997cf
TG
8296}
8297
8298/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8299
015dc7e1 8300static bool
dda8d76d 8301dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8302{
8303 Elf64_External_VMS_IMAGE_RELA *imrs;
26c527e6 8304 size_t i;
28f997cf 8305
978c4450
AM
8306 imrs = get_data (NULL, filedata,
8307 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8308 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8309 _("dynamic section image relocations"));
28f997cf 8310 if (!imrs)
015dc7e1 8311 return false;
28f997cf
TG
8312
8313 printf (_("\nImage relocs\n"));
8314 printf
8315 (_("Seg Offset Type Addend Seg Sym Off\n"));
8316
26c527e6 8317 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
28f997cf
TG
8318 {
8319 unsigned int type;
8320 const char *rtype;
8321
8322 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8323 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8324 type = BYTE_GET (imrs [i].type);
8325 rtype = elf_ia64_reloc_type (type);
8326 if (rtype == NULL)
8327 printf ("0x%08x ", type);
8328 else
8329 printf ("%-31s ", rtype);
8330 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8331 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8332 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8333 }
8334
8335 free (imrs);
015dc7e1 8336 return true;
28f997cf
TG
8337}
8338
8339/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8340
015dc7e1 8341static bool
dda8d76d 8342process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8343{
8344 struct ia64_vms_dynfixup fixup;
8345 struct ia64_vms_dynimgrela imgrela;
8346 Elf_Internal_Dyn *entry;
625d49fc
AM
8347 uint64_t strtab_off = 0;
8348 uint64_t strtab_sz = 0;
28f997cf 8349 char *strtab = NULL;
015dc7e1 8350 bool res = true;
28f997cf
TG
8351
8352 memset (&fixup, 0, sizeof (fixup));
8353 memset (&imgrela, 0, sizeof (imgrela));
8354
8355 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8356 for (entry = filedata->dynamic_section;
8357 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8358 entry++)
8359 {
8360 switch (entry->d_tag)
8361 {
8362 case DT_IA_64_VMS_STRTAB_OFFSET:
8363 strtab_off = entry->d_un.d_val;
8364 break;
8365 case DT_STRSZ:
8366 strtab_sz = entry->d_un.d_val;
8367 if (strtab == NULL)
978c4450
AM
8368 strtab = get_data (NULL, filedata,
8369 filedata->dynamic_addr + strtab_off,
28f997cf 8370 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8371 if (strtab == NULL)
8372 strtab_sz = 0;
28f997cf
TG
8373 break;
8374
8375 case DT_IA_64_VMS_NEEDED_IDENT:
8376 fixup.needed_ident = entry->d_un.d_val;
8377 break;
8378 case DT_NEEDED:
8379 fixup.needed = entry->d_un.d_val;
8380 break;
8381 case DT_IA_64_VMS_FIXUP_NEEDED:
8382 fixup.fixup_needed = entry->d_un.d_val;
8383 break;
8384 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8385 fixup.fixup_rela_cnt = entry->d_un.d_val;
8386 break;
8387 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8388 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8389 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8390 res = false;
28f997cf 8391 break;
28f997cf
TG
8392 case DT_IA_64_VMS_IMG_RELA_CNT:
8393 imgrela.img_rela_cnt = entry->d_un.d_val;
8394 break;
8395 case DT_IA_64_VMS_IMG_RELA_OFF:
8396 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8397 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8398 res = false;
28f997cf
TG
8399 break;
8400
8401 default:
8402 break;
8403 }
8404 }
8405
9db70fc3 8406 free (strtab);
28f997cf
TG
8407
8408 return res;
8409}
8410
85b1c36d 8411static struct
566b0d53 8412{
2cf0635d 8413 const char * name;
566b0d53
L
8414 int reloc;
8415 int size;
a7fd1186 8416 relocation_type rel_type;
32ec8896
NC
8417}
8418 dynamic_relocations [] =
566b0d53 8419{
a7fd1186
FS
8420 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8421 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8422 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8423 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8424};
8425
252b5132 8426/* Process the reloc section. */
18bd398b 8427
015dc7e1 8428static bool
dda8d76d 8429process_relocs (Filedata * filedata)
252b5132 8430{
26c527e6
AM
8431 uint64_t rel_size;
8432 uint64_t rel_offset;
252b5132 8433
252b5132 8434 if (!do_reloc)
015dc7e1 8435 return true;
252b5132
RH
8436
8437 if (do_using_dynamic)
8438 {
a7fd1186 8439 relocation_type rel_type;
2cf0635d 8440 const char * name;
015dc7e1 8441 bool has_dynamic_reloc;
566b0d53 8442 unsigned int i;
0de14b54 8443
015dc7e1 8444 has_dynamic_reloc = false;
252b5132 8445
566b0d53 8446 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8447 {
a7fd1186 8448 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8449 name = dynamic_relocations [i].name;
978c4450
AM
8450 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8451 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8452
32ec8896 8453 if (rel_size)
015dc7e1 8454 has_dynamic_reloc = true;
566b0d53 8455
a7fd1186 8456 if (rel_type == reltype_unknown)
aa903cfb 8457 {
566b0d53 8458 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8459 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8460 {
8461 case DT_REL:
a7fd1186 8462 rel_type = reltype_rel;
566b0d53
L
8463 break;
8464 case DT_RELA:
a7fd1186 8465 rel_type = reltype_rela;
566b0d53
L
8466 break;
8467 }
aa903cfb 8468 }
252b5132 8469
566b0d53
L
8470 if (rel_size)
8471 {
ca0e11aa
NC
8472 if (filedata->is_separate)
8473 printf
26c527e6
AM
8474 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
8475 " contains %" PRId64 " bytes:\n"),
ca0e11aa
NC
8476 filedata->file_name, name, rel_offset, rel_size);
8477 else
8478 printf
26c527e6
AM
8479 (_("\n'%s' relocation section at offset %#" PRIx64
8480 " contains %" PRId64 " bytes:\n"),
ca0e11aa 8481 name, rel_offset, rel_size);
252b5132 8482
dda8d76d
NC
8483 dump_relocations (filedata,
8484 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8485 rel_size,
978c4450
AM
8486 filedata->dynamic_symbols,
8487 filedata->num_dynamic_syms,
8488 filedata->dynamic_strings,
8489 filedata->dynamic_strings_length,
a7fd1186 8490 rel_type, true /* is_dynamic */);
566b0d53 8491 }
252b5132 8492 }
566b0d53 8493
dda8d76d
NC
8494 if (is_ia64_vms (filedata))
8495 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8496 has_dynamic_reloc = true;
28f997cf 8497
566b0d53 8498 if (! has_dynamic_reloc)
ca0e11aa
NC
8499 {
8500 if (filedata->is_separate)
8501 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8502 filedata->file_name);
8503 else
8504 printf (_("\nThere are no dynamic relocations in this file.\n"));
8505 }
252b5132
RH
8506 }
8507 else
8508 {
2cf0635d 8509 Elf_Internal_Shdr * section;
26c527e6 8510 size_t i;
015dc7e1 8511 bool found = false;
252b5132 8512
dda8d76d
NC
8513 for (i = 0, section = filedata->section_headers;
8514 i < filedata->file_header.e_shnum;
b34976b6 8515 i++, section++)
252b5132
RH
8516 {
8517 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8518 && section->sh_type != SHT_REL
8519 && section->sh_type != SHT_RELR)
252b5132
RH
8520 continue;
8521
8522 rel_offset = section->sh_offset;
8523 rel_size = section->sh_size;
8524
8525 if (rel_size)
8526 {
a7fd1186 8527 relocation_type rel_type;
26c527e6 8528 uint64_t num_rela;
103f02d3 8529
ca0e11aa
NC
8530 if (filedata->is_separate)
8531 printf (_("\nIn linked file '%s' relocation section "),
8532 filedata->file_name);
8533 else
8534 printf (_("\nRelocation section "));
252b5132 8535
dda8d76d 8536 if (filedata->string_table == NULL)
19936277 8537 printf ("%d", section->sh_name);
252b5132 8538 else
dda8d76d 8539 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8540
d3a49aa8 8541 num_rela = rel_size / section->sh_entsize;
26c527e6
AM
8542 printf (ngettext (" at offset %#" PRIx64
8543 " contains %" PRIu64 " entry:\n",
8544 " at offset %#" PRIx64
8545 " contains %" PRId64 " entries:\n",
d3a49aa8
AM
8546 num_rela),
8547 rel_offset, num_rela);
252b5132 8548
a7fd1186
FS
8549 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8550 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8551
4fbb74a6 8552 if (section->sh_link != 0
dda8d76d 8553 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8554 {
26c527e6
AM
8555 Elf_Internal_Shdr *symsec;
8556 Elf_Internal_Sym *symtab;
8557 uint64_t nsyms;
8558 uint64_t strtablen = 0;
8559 char *strtab = NULL;
57346661 8560
dda8d76d 8561 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8562 if (symsec->sh_type != SHT_SYMTAB
8563 && symsec->sh_type != SHT_DYNSYM)
8564 continue;
8565
28d13567
AM
8566 if (!get_symtab (filedata, symsec,
8567 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8568 continue;
252b5132 8569
dda8d76d 8570 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8571 symtab, nsyms, strtab, strtablen,
a7fd1186 8572 rel_type,
bb4d2ac2 8573 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8574 free (strtab);
d79b3d50
NC
8575 free (symtab);
8576 }
8577 else
dda8d76d 8578 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8579 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8580
015dc7e1 8581 found = true;
252b5132
RH
8582 }
8583 }
8584
8585 if (! found)
45ac8f4f
NC
8586 {
8587 /* Users sometimes forget the -D option, so try to be helpful. */
8588 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8589 {
978c4450 8590 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8591 {
ca0e11aa
NC
8592 if (filedata->is_separate)
8593 printf (_("\nThere are no static relocations in linked file '%s'."),
8594 filedata->file_name);
8595 else
8596 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8597 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8598
8599 break;
8600 }
8601 }
8602 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8603 {
8604 if (filedata->is_separate)
8605 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8606 filedata->file_name);
8607 else
8608 printf (_("\nThere are no relocations in this file.\n"));
8609 }
45ac8f4f 8610 }
252b5132
RH
8611 }
8612
015dc7e1 8613 return true;
252b5132
RH
8614}
8615
4d6ed7c8
NC
8616/* An absolute address consists of a section and an offset. If the
8617 section is NULL, the offset itself is the address, otherwise, the
8618 address equals to LOAD_ADDRESS(section) + offset. */
8619
8620struct absaddr
948f632f
DA
8621{
8622 unsigned short section;
625d49fc 8623 uint64_t offset;
948f632f 8624};
4d6ed7c8 8625
948f632f
DA
8626/* Find the nearest symbol at or below ADDR. Returns the symbol
8627 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8628
4d6ed7c8 8629static void
26c527e6
AM
8630find_symbol_for_address (Filedata *filedata,
8631 Elf_Internal_Sym *symtab,
8632 uint64_t nsyms,
8633 const char *strtab,
8634 uint64_t strtab_size,
8635 struct absaddr addr,
8636 const char **symname,
8637 uint64_t *offset)
4d6ed7c8 8638{
625d49fc 8639 uint64_t dist = 0x100000;
2cf0635d 8640 Elf_Internal_Sym * sym;
948f632f
DA
8641 Elf_Internal_Sym * beg;
8642 Elf_Internal_Sym * end;
2cf0635d 8643 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8644
0b6ae522 8645 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8646 beg = symtab;
8647 end = symtab + nsyms;
0b6ae522 8648
948f632f 8649 while (beg < end)
4d6ed7c8 8650 {
625d49fc 8651 uint64_t value;
948f632f
DA
8652
8653 sym = beg + (end - beg) / 2;
0b6ae522 8654
948f632f 8655 value = sym->st_value;
0b6ae522
DJ
8656 REMOVE_ARCH_BITS (value);
8657
948f632f 8658 if (sym->st_name != 0
4d6ed7c8 8659 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8660 && addr.offset >= value
8661 && addr.offset - value < dist)
4d6ed7c8
NC
8662 {
8663 best = sym;
0b6ae522 8664 dist = addr.offset - value;
4d6ed7c8
NC
8665 if (!dist)
8666 break;
8667 }
948f632f
DA
8668
8669 if (addr.offset < value)
8670 end = sym;
8671 else
8672 beg = sym + 1;
4d6ed7c8 8673 }
1b31d05e 8674
4d6ed7c8
NC
8675 if (best)
8676 {
57346661 8677 *symname = (best->st_name >= strtab_size
2b692964 8678 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8679 *offset = dist;
8680 return;
8681 }
1b31d05e 8682
4d6ed7c8
NC
8683 *symname = NULL;
8684 *offset = addr.offset;
8685}
8686
32ec8896 8687static /* signed */ int
948f632f
DA
8688symcmp (const void *p, const void *q)
8689{
8690 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8691 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8692
8693 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8694}
8695
8696/* Process the unwind section. */
8697
8698#include "unwind-ia64.h"
8699
8700struct ia64_unw_table_entry
8701{
8702 struct absaddr start;
8703 struct absaddr end;
8704 struct absaddr info;
8705};
8706
8707struct ia64_unw_aux_info
8708{
32ec8896 8709 struct ia64_unw_table_entry * table; /* Unwind table. */
26c527e6 8710 uint64_t table_len; /* Length of unwind table. */
32ec8896 8711 unsigned char * info; /* Unwind info. */
26c527e6 8712 uint64_t info_size; /* Size of unwind info. */
625d49fc
AM
8713 uint64_t info_addr; /* Starting address of unwind info. */
8714 uint64_t seg_base; /* Starting address of segment. */
32ec8896 8715 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 8716 uint64_t nsyms; /* Number of symbols. */
32ec8896 8717 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 8718 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 8719 char * strtab; /* The string table. */
26c527e6 8720 uint64_t strtab_size; /* Size of string table. */
948f632f
DA
8721};
8722
015dc7e1 8723static bool
dda8d76d 8724dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8725{
2cf0635d 8726 struct ia64_unw_table_entry * tp;
26c527e6 8727 size_t j, nfuns;
4d6ed7c8 8728 int in_body;
015dc7e1 8729 bool res = true;
7036c0e1 8730
948f632f
DA
8731 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8732 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8733 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8734 aux->funtab[nfuns++] = aux->symtab[j];
8735 aux->nfuns = nfuns;
8736 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8737
4d6ed7c8
NC
8738 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8739 {
625d49fc
AM
8740 uint64_t stamp;
8741 uint64_t offset;
2cf0635d
NC
8742 const unsigned char * dp;
8743 const unsigned char * head;
53774b7e 8744 const unsigned char * end;
2cf0635d 8745 const char * procname;
4d6ed7c8 8746
dda8d76d 8747 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8748 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8749
8750 fputs ("\n<", stdout);
8751
8752 if (procname)
8753 {
8754 fputs (procname, stdout);
8755
8756 if (offset)
26c527e6 8757 printf ("+%" PRIx64, offset);
4d6ed7c8
NC
8758 }
8759
8760 fputs (">: [", stdout);
8761 print_vma (tp->start.offset, PREFIX_HEX);
8762 fputc ('-', stdout);
8763 print_vma (tp->end.offset, PREFIX_HEX);
26c527e6
AM
8764 printf ("], info at +0x%" PRIx64 "\n",
8765 tp->info.offset - aux->seg_base);
4d6ed7c8 8766
53774b7e
NC
8767 /* PR 17531: file: 86232b32. */
8768 if (aux->info == NULL)
8769 continue;
8770
97c0a079
AM
8771 offset = tp->info.offset;
8772 if (tp->info.section)
8773 {
8774 if (tp->info.section >= filedata->file_header.e_shnum)
8775 {
26c527e6
AM
8776 warn (_("Invalid section %u in table entry %td\n"),
8777 tp->info.section, tp - aux->table);
015dc7e1 8778 res = false;
97c0a079
AM
8779 continue;
8780 }
8781 offset += filedata->section_headers[tp->info.section].sh_addr;
8782 }
8783 offset -= aux->info_addr;
53774b7e 8784 /* PR 17531: file: 0997b4d1. */
90679903
AM
8785 if (offset >= aux->info_size
8786 || aux->info_size - offset < 8)
53774b7e 8787 {
26c527e6
AM
8788 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
8789 tp->info.offset, tp - aux->table);
015dc7e1 8790 res = false;
53774b7e
NC
8791 continue;
8792 }
8793
97c0a079 8794 head = aux->info + offset;
a4a00738 8795 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8796
86f55779 8797 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8798 (unsigned) UNW_VER (stamp),
8799 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8800 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8801 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8802 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8803
8804 if (UNW_VER (stamp) != 1)
8805 {
2b692964 8806 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8807 continue;
8808 }
8809
8810 in_body = 0;
53774b7e
NC
8811 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8812 /* PR 17531: file: 16ceda89. */
8813 if (end > aux->info + aux->info_size)
8814 end = aux->info + aux->info_size;
8815 for (dp = head + 8; dp < end;)
b4477bc8 8816 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8817 }
948f632f
DA
8818
8819 free (aux->funtab);
32ec8896
NC
8820
8821 return res;
4d6ed7c8
NC
8822}
8823
015dc7e1 8824static bool
dda8d76d
NC
8825slurp_ia64_unwind_table (Filedata * filedata,
8826 struct ia64_unw_aux_info * aux,
8827 Elf_Internal_Shdr * sec)
4d6ed7c8 8828{
26c527e6 8829 uint64_t size, nrelas, i;
2cf0635d
NC
8830 Elf_Internal_Phdr * seg;
8831 struct ia64_unw_table_entry * tep;
8832 Elf_Internal_Shdr * relsec;
8833 Elf_Internal_Rela * rela;
8834 Elf_Internal_Rela * rp;
8835 unsigned char * table;
8836 unsigned char * tp;
8837 Elf_Internal_Sym * sym;
8838 const char * relname;
4d6ed7c8 8839
53774b7e
NC
8840 aux->table_len = 0;
8841
4d6ed7c8
NC
8842 /* First, find the starting address of the segment that includes
8843 this section: */
8844
dda8d76d 8845 if (filedata->file_header.e_phnum)
4d6ed7c8 8846 {
dda8d76d 8847 if (! get_program_headers (filedata))
015dc7e1 8848 return false;
4d6ed7c8 8849
dda8d76d
NC
8850 for (seg = filedata->program_headers;
8851 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8852 ++seg)
4d6ed7c8
NC
8853 {
8854 if (seg->p_type != PT_LOAD)
8855 continue;
8856
8857 if (sec->sh_addr >= seg->p_vaddr
8858 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8859 {
8860 aux->seg_base = seg->p_vaddr;
8861 break;
8862 }
8863 }
4d6ed7c8
NC
8864 }
8865
8866 /* Second, build the unwind table from the contents of the unwind section: */
8867 size = sec->sh_size;
dda8d76d 8868 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8869 _("unwind table"));
a6e9f9df 8870 if (!table)
015dc7e1 8871 return false;
4d6ed7c8 8872
53774b7e 8873 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8874 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8875 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8876 tep = aux->table;
53774b7e
NC
8877
8878 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8879 {
8880 tep->start.section = SHN_UNDEF;
8881 tep->end.section = SHN_UNDEF;
8882 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8883 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8884 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8885 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8886 tep->start.offset += aux->seg_base;
8887 tep->end.offset += aux->seg_base;
8888 tep->info.offset += aux->seg_base;
8889 }
8890 free (table);
8891
41e92641 8892 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8893 for (relsec = filedata->section_headers;
8894 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8895 ++relsec)
8896 {
8897 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8898 || relsec->sh_info >= filedata->file_header.e_shnum
8899 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8900 continue;
8901
dda8d76d 8902 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8903 & rela, & nrelas))
53774b7e
NC
8904 {
8905 free (aux->table);
8906 aux->table = NULL;
8907 aux->table_len = 0;
015dc7e1 8908 return false;
53774b7e 8909 }
4d6ed7c8
NC
8910
8911 for (rp = rela; rp < rela + nrelas; ++rp)
8912 {
4770fb94 8913 unsigned int sym_ndx;
726bd37d
AM
8914 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8915 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8916
82b1b41b
NC
8917 /* PR 17531: file: 9fa67536. */
8918 if (relname == NULL)
8919 {
726bd37d 8920 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8921 continue;
8922 }
948f632f 8923
24d127aa 8924 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8925 {
82b1b41b 8926 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8927 continue;
8928 }
8929
89fac5e3 8930 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8931
53774b7e
NC
8932 /* PR 17531: file: 5bc8d9bf. */
8933 if (i >= aux->table_len)
8934 {
26c527e6
AM
8935 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
8936 i);
53774b7e
NC
8937 continue;
8938 }
8939
4770fb94
AM
8940 sym_ndx = get_reloc_symindex (rp->r_info);
8941 if (sym_ndx >= aux->nsyms)
8942 {
8943 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8944 sym_ndx);
8945 continue;
8946 }
8947 sym = aux->symtab + sym_ndx;
8948
53774b7e 8949 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8950 {
8951 case 0:
8952 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8953 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8954 break;
8955 case 1:
8956 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8957 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8958 break;
8959 case 2:
8960 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8961 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8962 break;
8963 default:
8964 break;
8965 }
8966 }
8967
8968 free (rela);
8969 }
8970
015dc7e1 8971 return true;
4d6ed7c8
NC
8972}
8973
015dc7e1 8974static bool
dda8d76d 8975ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8976{
2cf0635d
NC
8977 Elf_Internal_Shdr * sec;
8978 Elf_Internal_Shdr * unwsec = NULL;
26c527e6 8979 uint64_t i, unwcount = 0, unwstart = 0;
57346661 8980 struct ia64_unw_aux_info aux;
015dc7e1 8981 bool res = true;
f1467e33 8982
4d6ed7c8
NC
8983 memset (& aux, 0, sizeof (aux));
8984
dda8d76d 8985 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8986 {
28d13567 8987 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8988 {
28d13567 8989 if (aux.symtab)
4082ef84 8990 {
28d13567
AM
8991 error (_("Multiple symbol tables encountered\n"));
8992 free (aux.symtab);
8993 aux.symtab = NULL;
4082ef84 8994 free (aux.strtab);
28d13567 8995 aux.strtab = NULL;
4082ef84 8996 }
28d13567
AM
8997 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8998 &aux.strtab, &aux.strtab_size))
015dc7e1 8999 return false;
4d6ed7c8
NC
9000 }
9001 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
9002 unwcount++;
9003 }
9004
9005 if (!unwcount)
9006 printf (_("\nThere are no unwind sections in this file.\n"));
9007
9008 while (unwcount-- > 0)
9009 {
84714f86 9010 const char *suffix;
579f31ac
JJ
9011 size_t len, len2;
9012
dda8d76d
NC
9013 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
9014 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
9015 if (sec->sh_type == SHT_IA_64_UNWIND)
9016 {
9017 unwsec = sec;
9018 break;
9019 }
4082ef84
NC
9020 /* We have already counted the number of SHT_IA64_UNWIND
9021 sections so the loop above should never fail. */
9022 assert (unwsec != NULL);
579f31ac
JJ
9023
9024 unwstart = i + 1;
9025 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9026
e4b17d5c
L
9027 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9028 {
9029 /* We need to find which section group it is in. */
4082ef84 9030 struct group_list * g;
e4b17d5c 9031
978c4450
AM
9032 if (filedata->section_headers_groups == NULL
9033 || filedata->section_headers_groups[i] == NULL)
dda8d76d 9034 i = filedata->file_header.e_shnum;
4082ef84 9035 else
e4b17d5c 9036 {
978c4450 9037 g = filedata->section_headers_groups[i]->root;
18bd398b 9038
4082ef84
NC
9039 for (; g != NULL; g = g->next)
9040 {
dda8d76d 9041 sec = filedata->section_headers + g->section_index;
e4b17d5c 9042
84714f86
AM
9043 if (section_name_valid (filedata, sec)
9044 && streq (section_name (filedata, sec),
9045 ELF_STRING_ia64_unwind_info))
4082ef84
NC
9046 break;
9047 }
9048
9049 if (g == NULL)
dda8d76d 9050 i = filedata->file_header.e_shnum;
4082ef84 9051 }
e4b17d5c 9052 }
84714f86
AM
9053 else if (section_name_valid (filedata, unwsec)
9054 && startswith (section_name (filedata, unwsec),
e9b095a5 9055 ELF_STRING_ia64_unwind_once))
579f31ac 9056 {
18bd398b 9057 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 9058 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 9059 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9060 for (i = 0, sec = filedata->section_headers;
9061 i < filedata->file_header.e_shnum;
579f31ac 9062 ++i, ++sec)
84714f86
AM
9063 if (section_name_valid (filedata, sec)
9064 && startswith (section_name (filedata, sec),
e9b095a5 9065 ELF_STRING_ia64_unwind_info_once)
84714f86 9066 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9067 break;
9068 }
9069 else
9070 {
9071 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 9072 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
9073 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9074 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9075 suffix = "";
84714f86
AM
9076 if (section_name_valid (filedata, unwsec)
9077 && startswith (section_name (filedata, unwsec),
9078 ELF_STRING_ia64_unwind))
9079 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9080 for (i = 0, sec = filedata->section_headers;
9081 i < filedata->file_header.e_shnum;
579f31ac 9082 ++i, ++sec)
84714f86
AM
9083 if (section_name_valid (filedata, sec)
9084 && startswith (section_name (filedata, sec),
9085 ELF_STRING_ia64_unwind_info)
9086 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9087 break;
9088 }
9089
dda8d76d 9090 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
9091 {
9092 printf (_("\nCould not find unwind info section for "));
9093
dda8d76d 9094 if (filedata->string_table == NULL)
579f31ac
JJ
9095 printf ("%d", unwsec->sh_name);
9096 else
dda8d76d 9097 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9098 }
9099 else
4d6ed7c8 9100 {
4d6ed7c8 9101 aux.info_addr = sec->sh_addr;
dda8d76d 9102 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9103 sec->sh_size,
9104 _("unwind info"));
59245841 9105 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9106
579f31ac 9107 printf (_("\nUnwind section "));
4d6ed7c8 9108
dda8d76d 9109 if (filedata->string_table == NULL)
579f31ac
JJ
9110 printf ("%d", unwsec->sh_name);
9111 else
dda8d76d 9112 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9113
26c527e6
AM
9114 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9115 unwsec->sh_offset,
9116 unwsec->sh_size / (3 * eh_addr_size));
4d6ed7c8 9117
dda8d76d 9118 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9119 && aux.table_len > 0)
dda8d76d 9120 dump_ia64_unwind (filedata, & aux);
579f31ac 9121
9db70fc3
AM
9122 free ((char *) aux.table);
9123 free ((char *) aux.info);
579f31ac
JJ
9124 aux.table = NULL;
9125 aux.info = NULL;
9126 }
4d6ed7c8 9127 }
4d6ed7c8 9128
9db70fc3
AM
9129 free (aux.symtab);
9130 free ((char *) aux.strtab);
32ec8896
NC
9131
9132 return res;
4d6ed7c8
NC
9133}
9134
3f5e193b 9135struct hppa_unw_table_entry
32ec8896
NC
9136{
9137 struct absaddr start;
9138 struct absaddr end;
9139 unsigned int Cannot_unwind:1; /* 0 */
9140 unsigned int Millicode:1; /* 1 */
9141 unsigned int Millicode_save_sr0:1; /* 2 */
9142 unsigned int Region_description:2; /* 3..4 */
9143 unsigned int reserved1:1; /* 5 */
9144 unsigned int Entry_SR:1; /* 6 */
9145 unsigned int Entry_FR:4; /* Number saved 7..10 */
9146 unsigned int Entry_GR:5; /* Number saved 11..15 */
9147 unsigned int Args_stored:1; /* 16 */
9148 unsigned int Variable_Frame:1; /* 17 */
9149 unsigned int Separate_Package_Body:1; /* 18 */
9150 unsigned int Frame_Extension_Millicode:1; /* 19 */
9151 unsigned int Stack_Overflow_Check:1; /* 20 */
9152 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9153 unsigned int Ada_Region:1; /* 22 */
9154 unsigned int cxx_info:1; /* 23 */
9155 unsigned int cxx_try_catch:1; /* 24 */
9156 unsigned int sched_entry_seq:1; /* 25 */
9157 unsigned int reserved2:1; /* 26 */
9158 unsigned int Save_SP:1; /* 27 */
9159 unsigned int Save_RP:1; /* 28 */
9160 unsigned int Save_MRP_in_frame:1; /* 29 */
9161 unsigned int extn_ptr_defined:1; /* 30 */
9162 unsigned int Cleanup_defined:1; /* 31 */
9163
9164 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9165 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9166 unsigned int Large_frame:1; /* 2 */
9167 unsigned int Pseudo_SP_Set:1; /* 3 */
9168 unsigned int reserved4:1; /* 4 */
9169 unsigned int Total_frame_size:27; /* 5..31 */
9170};
3f5e193b 9171
57346661 9172struct hppa_unw_aux_info
948f632f 9173{
32ec8896 9174 struct hppa_unw_table_entry * table; /* Unwind table. */
26c527e6 9175 uint64_t table_len; /* Length of unwind table. */
625d49fc 9176 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9177 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9178 uint64_t nsyms; /* Number of symbols. */
32ec8896 9179 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9180 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9181 char * strtab; /* The string table. */
26c527e6 9182 uint64_t strtab_size; /* Size of string table. */
948f632f 9183};
57346661 9184
015dc7e1 9185static bool
dda8d76d 9186dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9187{
2cf0635d 9188 struct hppa_unw_table_entry * tp;
26c527e6 9189 uint64_t j, nfuns;
015dc7e1 9190 bool res = true;
948f632f
DA
9191
9192 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9193 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9194 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9195 aux->funtab[nfuns++] = aux->symtab[j];
9196 aux->nfuns = nfuns;
9197 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9198
57346661
AM
9199 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9200 {
625d49fc 9201 uint64_t offset;
2cf0635d 9202 const char * procname;
57346661 9203
dda8d76d 9204 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9205 aux->strtab_size, tp->start, &procname,
9206 &offset);
9207
9208 fputs ("\n<", stdout);
9209
9210 if (procname)
9211 {
9212 fputs (procname, stdout);
9213
9214 if (offset)
26c527e6 9215 printf ("+%" PRIx64, offset);
57346661
AM
9216 }
9217
9218 fputs (">: [", stdout);
9219 print_vma (tp->start.offset, PREFIX_HEX);
9220 fputc ('-', stdout);
9221 print_vma (tp->end.offset, PREFIX_HEX);
9222 printf ("]\n\t");
9223
18bd398b
NC
9224#define PF(_m) if (tp->_m) printf (#_m " ");
9225#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9226 PF(Cannot_unwind);
9227 PF(Millicode);
9228 PF(Millicode_save_sr0);
18bd398b 9229 /* PV(Region_description); */
57346661
AM
9230 PF(Entry_SR);
9231 PV(Entry_FR);
9232 PV(Entry_GR);
9233 PF(Args_stored);
9234 PF(Variable_Frame);
9235 PF(Separate_Package_Body);
9236 PF(Frame_Extension_Millicode);
9237 PF(Stack_Overflow_Check);
9238 PF(Two_Instruction_SP_Increment);
9239 PF(Ada_Region);
9240 PF(cxx_info);
9241 PF(cxx_try_catch);
9242 PF(sched_entry_seq);
9243 PF(Save_SP);
9244 PF(Save_RP);
9245 PF(Save_MRP_in_frame);
9246 PF(extn_ptr_defined);
9247 PF(Cleanup_defined);
9248 PF(MPE_XL_interrupt_marker);
9249 PF(HP_UX_interrupt_marker);
9250 PF(Large_frame);
9251 PF(Pseudo_SP_Set);
9252 PV(Total_frame_size);
9253#undef PF
9254#undef PV
9255 }
9256
18bd398b 9257 printf ("\n");
948f632f
DA
9258
9259 free (aux->funtab);
32ec8896
NC
9260
9261 return res;
57346661
AM
9262}
9263
015dc7e1 9264static bool
dda8d76d
NC
9265slurp_hppa_unwind_table (Filedata * filedata,
9266 struct hppa_unw_aux_info * aux,
9267 Elf_Internal_Shdr * sec)
57346661 9268{
26c527e6 9269 uint64_t size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9270 Elf_Internal_Phdr * seg;
9271 struct hppa_unw_table_entry * tep;
9272 Elf_Internal_Shdr * relsec;
9273 Elf_Internal_Rela * rela;
9274 Elf_Internal_Rela * rp;
9275 unsigned char * table;
9276 unsigned char * tp;
9277 Elf_Internal_Sym * sym;
9278 const char * relname;
57346661 9279
57346661
AM
9280 /* First, find the starting address of the segment that includes
9281 this section. */
dda8d76d 9282 if (filedata->file_header.e_phnum)
57346661 9283 {
dda8d76d 9284 if (! get_program_headers (filedata))
015dc7e1 9285 return false;
57346661 9286
dda8d76d
NC
9287 for (seg = filedata->program_headers;
9288 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9289 ++seg)
9290 {
9291 if (seg->p_type != PT_LOAD)
9292 continue;
9293
9294 if (sec->sh_addr >= seg->p_vaddr
9295 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9296 {
9297 aux->seg_base = seg->p_vaddr;
9298 break;
9299 }
9300 }
9301 }
9302
9303 /* Second, build the unwind table from the contents of the unwind
9304 section. */
9305 size = sec->sh_size;
dda8d76d 9306 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9307 _("unwind table"));
57346661 9308 if (!table)
015dc7e1 9309 return false;
57346661 9310
1c0751b2
DA
9311 unw_ent_size = 16;
9312 nentries = size / unw_ent_size;
9313 size = unw_ent_size * nentries;
57346661 9314
e3fdc001 9315 aux->table_len = nentries;
3f5e193b
NC
9316 tep = aux->table = (struct hppa_unw_table_entry *)
9317 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9318
1c0751b2 9319 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9320 {
9321 unsigned int tmp1, tmp2;
9322
9323 tep->start.section = SHN_UNDEF;
9324 tep->end.section = SHN_UNDEF;
9325
1c0751b2
DA
9326 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9327 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9328 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9329 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9330
9331 tep->start.offset += aux->seg_base;
9332 tep->end.offset += aux->seg_base;
57346661
AM
9333
9334 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9335 tep->Millicode = (tmp1 >> 30) & 0x1;
9336 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9337 tep->Region_description = (tmp1 >> 27) & 0x3;
9338 tep->reserved1 = (tmp1 >> 26) & 0x1;
9339 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9340 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9341 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9342 tep->Args_stored = (tmp1 >> 15) & 0x1;
9343 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9344 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9345 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9346 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9347 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9348 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9349 tep->cxx_info = (tmp1 >> 8) & 0x1;
9350 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9351 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9352 tep->reserved2 = (tmp1 >> 5) & 0x1;
9353 tep->Save_SP = (tmp1 >> 4) & 0x1;
9354 tep->Save_RP = (tmp1 >> 3) & 0x1;
9355 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9356 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9357 tep->Cleanup_defined = tmp1 & 0x1;
9358
9359 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9360 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9361 tep->Large_frame = (tmp2 >> 29) & 0x1;
9362 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9363 tep->reserved4 = (tmp2 >> 27) & 0x1;
9364 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9365 }
9366 free (table);
9367
9368 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9369 for (relsec = filedata->section_headers;
9370 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9371 ++relsec)
9372 {
9373 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9374 || relsec->sh_info >= filedata->file_header.e_shnum
9375 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9376 continue;
9377
dda8d76d 9378 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9379 & rela, & nrelas))
015dc7e1 9380 return false;
57346661
AM
9381
9382 for (rp = rela; rp < rela + nrelas; ++rp)
9383 {
4770fb94 9384 unsigned int sym_ndx;
726bd37d
AM
9385 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9386 relname = elf_hppa_reloc_type (r_type);
57346661 9387
726bd37d
AM
9388 if (relname == NULL)
9389 {
9390 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9391 continue;
9392 }
9393
57346661 9394 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9395 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9396 {
726bd37d 9397 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9398 continue;
9399 }
9400
9401 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9402 if (i >= aux->table_len)
9403 {
26c527e6
AM
9404 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9405 i);
726bd37d
AM
9406 continue;
9407 }
57346661 9408
4770fb94
AM
9409 sym_ndx = get_reloc_symindex (rp->r_info);
9410 if (sym_ndx >= aux->nsyms)
9411 {
9412 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9413 sym_ndx);
9414 continue;
9415 }
9416 sym = aux->symtab + sym_ndx;
9417
43f6cd05 9418 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9419 {
9420 case 0:
9421 aux->table[i].start.section = sym->st_shndx;
1e456d54 9422 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9423 break;
9424 case 1:
9425 aux->table[i].end.section = sym->st_shndx;
1e456d54 9426 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9427 break;
9428 default:
9429 break;
9430 }
9431 }
9432
9433 free (rela);
9434 }
9435
015dc7e1 9436 return true;
57346661
AM
9437}
9438
015dc7e1 9439static bool
dda8d76d 9440hppa_process_unwind (Filedata * filedata)
57346661 9441{
57346661 9442 struct hppa_unw_aux_info aux;
2cf0635d 9443 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9444 Elf_Internal_Shdr * sec;
26c527e6 9445 size_t i;
015dc7e1 9446 bool res = true;
57346661 9447
dda8d76d 9448 if (filedata->string_table == NULL)
015dc7e1 9449 return false;
1b31d05e
NC
9450
9451 memset (& aux, 0, sizeof (aux));
57346661 9452
dda8d76d 9453 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9454 {
28d13567 9455 if (sec->sh_type == SHT_SYMTAB)
57346661 9456 {
28d13567 9457 if (aux.symtab)
4082ef84 9458 {
28d13567
AM
9459 error (_("Multiple symbol tables encountered\n"));
9460 free (aux.symtab);
9461 aux.symtab = NULL;
4082ef84 9462 free (aux.strtab);
28d13567 9463 aux.strtab = NULL;
4082ef84 9464 }
28d13567
AM
9465 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9466 &aux.strtab, &aux.strtab_size))
015dc7e1 9467 return false;
57346661 9468 }
84714f86
AM
9469 else if (section_name_valid (filedata, sec)
9470 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9471 unwsec = sec;
9472 }
9473
9474 if (!unwsec)
9475 printf (_("\nThere are no unwind sections in this file.\n"));
9476
dda8d76d 9477 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9478 {
84714f86
AM
9479 if (section_name_valid (filedata, sec)
9480 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9481 {
26c527e6 9482 uint64_t num_unwind = sec->sh_size / 16;
dda8d76d 9483
26c527e6
AM
9484 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
9485 "contains %" PRIu64 " entry:\n",
9486 "\nUnwind section '%s' at offset %#" PRIx64 " "
9487 "contains %" PRIu64 " entries:\n",
d3a49aa8 9488 num_unwind),
dda8d76d 9489 printable_section_name (filedata, sec),
26c527e6 9490 sec->sh_offset,
d3a49aa8 9491 num_unwind);
57346661 9492
dda8d76d 9493 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9494 res = false;
66b09c7e
S
9495
9496 if (res && aux.table_len > 0)
32ec8896 9497 {
dda8d76d 9498 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9499 res = false;
32ec8896 9500 }
57346661 9501
9db70fc3 9502 free ((char *) aux.table);
57346661
AM
9503 aux.table = NULL;
9504 }
9505 }
9506
9db70fc3
AM
9507 free (aux.symtab);
9508 free ((char *) aux.strtab);
32ec8896
NC
9509
9510 return res;
57346661
AM
9511}
9512
0b6ae522
DJ
9513struct arm_section
9514{
a734115a
NC
9515 unsigned char * data; /* The unwind data. */
9516 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9517 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
26c527e6 9518 uint64_t nrelas; /* The number of relocations. */
a734115a
NC
9519 unsigned int rel_type; /* REL or RELA ? */
9520 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9521};
9522
9523struct arm_unw_aux_info
9524{
dda8d76d 9525 Filedata * filedata; /* The file containing the unwind sections. */
a734115a 9526 Elf_Internal_Sym * symtab; /* The file's symbol table. */
26c527e6 9527 uint64_t nsyms; /* Number of symbols. */
948f632f 9528 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9529 uint64_t nfuns; /* Number of these symbols. */
a734115a 9530 char * strtab; /* The file's string table. */
26c527e6 9531 uint64_t strtab_size; /* Size of string table. */
0b6ae522
DJ
9532};
9533
9534static const char *
dda8d76d
NC
9535arm_print_vma_and_name (Filedata * filedata,
9536 struct arm_unw_aux_info * aux,
625d49fc 9537 uint64_t fn,
dda8d76d 9538 struct absaddr addr)
0b6ae522
DJ
9539{
9540 const char *procname;
625d49fc 9541 uint64_t sym_offset;
0b6ae522
DJ
9542
9543 if (addr.section == SHN_UNDEF)
9544 addr.offset = fn;
9545
dda8d76d 9546 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9547 aux->strtab_size, addr, &procname,
9548 &sym_offset);
9549
9550 print_vma (fn, PREFIX_HEX);
9551
9552 if (procname)
9553 {
9554 fputs (" <", stdout);
9555 fputs (procname, stdout);
9556
9557 if (sym_offset)
26c527e6 9558 printf ("+0x%" PRIx64, sym_offset);
0b6ae522
DJ
9559 fputc ('>', stdout);
9560 }
9561
9562 return procname;
9563}
9564
9565static void
9566arm_free_section (struct arm_section *arm_sec)
9567{
9db70fc3
AM
9568 free (arm_sec->data);
9569 free (arm_sec->rela);
0b6ae522
DJ
9570}
9571
a734115a
NC
9572/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9573 cached section and install SEC instead.
9574 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9575 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9576 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9577 relocation's offset in ADDR.
1b31d05e
NC
9578 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9579 into the string table of the symbol associated with the reloc. If no
9580 reloc was applied store -1 there.
9581 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9582
015dc7e1 9583static bool
dda8d76d
NC
9584get_unwind_section_word (Filedata * filedata,
9585 struct arm_unw_aux_info * aux,
1b31d05e
NC
9586 struct arm_section * arm_sec,
9587 Elf_Internal_Shdr * sec,
625d49fc 9588 uint64_t word_offset,
1b31d05e
NC
9589 unsigned int * wordp,
9590 struct absaddr * addr,
625d49fc 9591 uint64_t * sym_name)
0b6ae522
DJ
9592{
9593 Elf_Internal_Rela *rp;
9594 Elf_Internal_Sym *sym;
9595 const char * relname;
9596 unsigned int word;
015dc7e1 9597 bool wrapped;
0b6ae522 9598
e0a31db1 9599 if (sec == NULL || arm_sec == NULL)
015dc7e1 9600 return false;
e0a31db1 9601
0b6ae522
DJ
9602 addr->section = SHN_UNDEF;
9603 addr->offset = 0;
9604
1b31d05e 9605 if (sym_name != NULL)
625d49fc 9606 *sym_name = (uint64_t) -1;
1b31d05e 9607
a734115a 9608 /* If necessary, update the section cache. */
0b6ae522
DJ
9609 if (sec != arm_sec->sec)
9610 {
9611 Elf_Internal_Shdr *relsec;
9612
9613 arm_free_section (arm_sec);
9614
9615 arm_sec->sec = sec;
dda8d76d 9616 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9617 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9618 arm_sec->rela = NULL;
9619 arm_sec->nrelas = 0;
9620
dda8d76d
NC
9621 for (relsec = filedata->section_headers;
9622 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9623 ++relsec)
9624 {
dda8d76d
NC
9625 if (relsec->sh_info >= filedata->file_header.e_shnum
9626 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9627 /* PR 15745: Check the section type as well. */
9628 || (relsec->sh_type != SHT_REL
9629 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9630 continue;
9631
a734115a 9632 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9633 if (relsec->sh_type == SHT_REL)
9634 {
dda8d76d 9635 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9636 relsec->sh_size,
9637 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9638 return false;
0b6ae522 9639 }
1ae40aa4 9640 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9641 {
dda8d76d 9642 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9643 relsec->sh_size,
9644 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9645 return false;
0b6ae522 9646 }
1ae40aa4 9647 break;
0b6ae522
DJ
9648 }
9649
9650 arm_sec->next_rela = arm_sec->rela;
9651 }
9652
a734115a 9653 /* If there is no unwind data we can do nothing. */
0b6ae522 9654 if (arm_sec->data == NULL)
015dc7e1 9655 return false;
0b6ae522 9656
e0a31db1 9657 /* If the offset is invalid then fail. */
f32ba729
NC
9658 if (/* PR 21343 *//* PR 18879 */
9659 sec->sh_size < 4
625d49fc 9660 || word_offset > sec->sh_size - 4)
015dc7e1 9661 return false;
e0a31db1 9662
a734115a 9663 /* Get the word at the required offset. */
0b6ae522
DJ
9664 word = byte_get (arm_sec->data + word_offset, 4);
9665
0eff7165
NC
9666 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9667 if (arm_sec->rela == NULL)
9668 {
9669 * wordp = word;
015dc7e1 9670 return true;
0eff7165
NC
9671 }
9672
a734115a 9673 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9674 wrapped = false;
0b6ae522
DJ
9675 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9676 {
625d49fc 9677 uint64_t prelval, offset;
0b6ae522
DJ
9678
9679 if (rp->r_offset > word_offset && !wrapped)
9680 {
9681 rp = arm_sec->rela;
015dc7e1 9682 wrapped = true;
0b6ae522
DJ
9683 }
9684 if (rp->r_offset > word_offset)
9685 break;
9686
9687 if (rp->r_offset & 3)
9688 {
26c527e6
AM
9689 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
9690 rp->r_offset);
0b6ae522
DJ
9691 continue;
9692 }
9693
9694 if (rp->r_offset < word_offset)
9695 continue;
9696
74e1a04b
NC
9697 /* PR 17531: file: 027-161405-0.004 */
9698 if (aux->symtab == NULL)
9699 continue;
9700
0b6ae522
DJ
9701 if (arm_sec->rel_type == SHT_REL)
9702 {
9703 offset = word & 0x7fffffff;
9704 if (offset & 0x40000000)
625d49fc 9705 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 9706 }
a734115a 9707 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9708 offset = rp->r_addend;
a734115a 9709 else
74e1a04b
NC
9710 {
9711 error (_("Unknown section relocation type %d encountered\n"),
9712 arm_sec->rel_type);
9713 break;
9714 }
0b6ae522 9715
071436c6
NC
9716 /* PR 17531 file: 027-1241568-0.004. */
9717 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9718 {
26c527e6
AM
9719 error (_("Bad symbol index in unwind relocation "
9720 "(%" PRIu64 " > %" PRIu64 ")\n"),
9721 ELF32_R_SYM (rp->r_info), aux->nsyms);
071436c6
NC
9722 break;
9723 }
9724
9725 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9726 offset += sym->st_value;
9727 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9728
a734115a 9729 /* Check that we are processing the expected reloc type. */
dda8d76d 9730 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9731 {
9732 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9733 if (relname == NULL)
9734 {
9735 warn (_("Skipping unknown ARM relocation type: %d\n"),
9736 (int) ELF32_R_TYPE (rp->r_info));
9737 continue;
9738 }
a734115a
NC
9739
9740 if (streq (relname, "R_ARM_NONE"))
9741 continue;
0b4362b0 9742
a734115a
NC
9743 if (! streq (relname, "R_ARM_PREL31"))
9744 {
071436c6 9745 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9746 continue;
9747 }
9748 }
dda8d76d 9749 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9750 {
9751 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9752 if (relname == NULL)
9753 {
9754 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9755 (int) ELF32_R_TYPE (rp->r_info));
9756 continue;
9757 }
0b4362b0 9758
a734115a
NC
9759 if (streq (relname, "R_C6000_NONE"))
9760 continue;
9761
9762 if (! streq (relname, "R_C6000_PREL31"))
9763 {
071436c6 9764 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9765 continue;
9766 }
9767
9768 prelval >>= 1;
9769 }
9770 else
74e1a04b
NC
9771 {
9772 /* This function currently only supports ARM and TI unwinders. */
9773 warn (_("Only TI and ARM unwinders are currently supported\n"));
9774 break;
9775 }
fa197c1c 9776
625d49fc 9777 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
9778 addr->section = sym->st_shndx;
9779 addr->offset = offset;
74e1a04b 9780
1b31d05e
NC
9781 if (sym_name)
9782 * sym_name = sym->st_name;
0b6ae522
DJ
9783 break;
9784 }
9785
9786 *wordp = word;
9787 arm_sec->next_rela = rp;
9788
015dc7e1 9789 return true;
0b6ae522
DJ
9790}
9791
a734115a
NC
9792static const char *tic6x_unwind_regnames[16] =
9793{
0b4362b0
RM
9794 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9795 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9796 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9797};
fa197c1c 9798
0b6ae522 9799static void
fa197c1c 9800decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9801{
fa197c1c
PB
9802 int i;
9803
9804 for (i = 12; mask; mask >>= 1, i--)
9805 {
9806 if (mask & 1)
9807 {
9808 fputs (tic6x_unwind_regnames[i], stdout);
9809 if (mask > 1)
9810 fputs (", ", stdout);
9811 }
9812 }
9813}
0b6ae522
DJ
9814
9815#define ADVANCE \
9816 if (remaining == 0 && more_words) \
9817 { \
9818 data_offset += 4; \
dda8d76d 9819 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9820 data_offset, & word, & addr, NULL)) \
015dc7e1 9821 return false; \
0b6ae522
DJ
9822 remaining = 4; \
9823 more_words--; \
9824 } \
9825
9826#define GET_OP(OP) \
9827 ADVANCE; \
9828 if (remaining) \
9829 { \
9830 remaining--; \
9831 (OP) = word >> 24; \
9832 word <<= 8; \
9833 } \
9834 else \
9835 { \
2b692964 9836 printf (_("[Truncated opcode]\n")); \
015dc7e1 9837 return false; \
0b6ae522 9838 } \
cc5914eb 9839 printf ("0x%02x ", OP)
0b6ae522 9840
015dc7e1 9841static bool
dda8d76d
NC
9842decode_arm_unwind_bytecode (Filedata * filedata,
9843 struct arm_unw_aux_info * aux,
948f632f
DA
9844 unsigned int word,
9845 unsigned int remaining,
9846 unsigned int more_words,
625d49fc 9847 uint64_t data_offset,
948f632f
DA
9848 Elf_Internal_Shdr * data_sec,
9849 struct arm_section * data_arm_sec)
fa197c1c
PB
9850{
9851 struct absaddr addr;
015dc7e1 9852 bool res = true;
0b6ae522
DJ
9853
9854 /* Decode the unwinding instructions. */
9855 while (1)
9856 {
9857 unsigned int op, op2;
9858
9859 ADVANCE;
9860 if (remaining == 0)
9861 break;
9862 remaining--;
9863 op = word >> 24;
9864 word <<= 8;
9865
cc5914eb 9866 printf (" 0x%02x ", op);
0b6ae522
DJ
9867
9868 if ((op & 0xc0) == 0x00)
9869 {
9870 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9871
cc5914eb 9872 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9873 }
9874 else if ((op & 0xc0) == 0x40)
9875 {
9876 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9877
cc5914eb 9878 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9879 }
9880 else if ((op & 0xf0) == 0x80)
9881 {
9882 GET_OP (op2);
9883 if (op == 0x80 && op2 == 0)
9884 printf (_("Refuse to unwind"));
9885 else
9886 {
9887 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9888 bool first = true;
0b6ae522 9889 int i;
2b692964 9890
0b6ae522
DJ
9891 printf ("pop {");
9892 for (i = 0; i < 12; i++)
9893 if (mask & (1 << i))
9894 {
9895 if (first)
015dc7e1 9896 first = false;
0b6ae522
DJ
9897 else
9898 printf (", ");
9899 printf ("r%d", 4 + i);
9900 }
9901 printf ("}");
9902 }
9903 }
9904 else if ((op & 0xf0) == 0x90)
9905 {
9906 if (op == 0x9d || op == 0x9f)
9907 printf (_(" [Reserved]"));
9908 else
cc5914eb 9909 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9910 }
9911 else if ((op & 0xf0) == 0xa0)
9912 {
9913 int end = 4 + (op & 0x07);
015dc7e1 9914 bool first = true;
0b6ae522 9915 int i;
61865e30 9916
0b6ae522
DJ
9917 printf (" pop {");
9918 for (i = 4; i <= end; i++)
9919 {
9920 if (first)
015dc7e1 9921 first = false;
0b6ae522
DJ
9922 else
9923 printf (", ");
9924 printf ("r%d", i);
9925 }
9926 if (op & 0x08)
9927 {
1b31d05e 9928 if (!first)
0b6ae522
DJ
9929 printf (", ");
9930 printf ("r14");
9931 }
9932 printf ("}");
9933 }
9934 else if (op == 0xb0)
9935 printf (_(" finish"));
9936 else if (op == 0xb1)
9937 {
9938 GET_OP (op2);
9939 if (op2 == 0 || (op2 & 0xf0) != 0)
9940 printf (_("[Spare]"));
9941 else
9942 {
9943 unsigned int mask = op2 & 0x0f;
015dc7e1 9944 bool first = true;
0b6ae522 9945 int i;
61865e30 9946
0b6ae522
DJ
9947 printf ("pop {");
9948 for (i = 0; i < 12; i++)
9949 if (mask & (1 << i))
9950 {
9951 if (first)
015dc7e1 9952 first = false;
0b6ae522
DJ
9953 else
9954 printf (", ");
9955 printf ("r%d", i);
9956 }
9957 printf ("}");
9958 }
9959 }
9960 else if (op == 0xb2)
9961 {
b115cf96 9962 unsigned char buf[9];
0b6ae522 9963 unsigned int i, len;
26c527e6 9964 uint64_t offset;
61865e30 9965
b115cf96 9966 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9967 {
9968 GET_OP (buf[i]);
9969 if ((buf[i] & 0x80) == 0)
9970 break;
9971 }
4082ef84 9972 if (i == sizeof (buf))
32ec8896 9973 {
27a45f42 9974 error (_("corrupt change to vsp\n"));
015dc7e1 9975 res = false;
32ec8896 9976 }
4082ef84
NC
9977 else
9978 {
015dc7e1 9979 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9980 assert (len == i + 1);
9981 offset = offset * 4 + 0x204;
26c527e6 9982 printf ("vsp = vsp + %" PRId64, offset);
4082ef84 9983 }
0b6ae522 9984 }
61865e30 9985 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9986 {
61865e30
NC
9987 unsigned int first, last;
9988
9989 GET_OP (op2);
9990 first = op2 >> 4;
9991 last = op2 & 0x0f;
9992 if (op == 0xc8)
9993 first = first + 16;
9994 printf ("pop {D%d", first);
9995 if (last)
9996 printf ("-D%d", first + last);
9997 printf ("}");
9998 }
09854a88
TB
9999 else if (op == 0xb4)
10000 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
10001 else if (op == 0xb5)
10002 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
10003 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
10004 {
10005 unsigned int count = op & 0x07;
10006
10007 printf ("pop {D8");
10008 if (count)
10009 printf ("-D%d", 8 + count);
10010 printf ("}");
10011 }
10012 else if (op >= 0xc0 && op <= 0xc5)
10013 {
10014 unsigned int count = op & 0x07;
10015
10016 printf (" pop {wR10");
10017 if (count)
10018 printf ("-wR%d", 10 + count);
10019 printf ("}");
10020 }
10021 else if (op == 0xc6)
10022 {
10023 unsigned int first, last;
10024
10025 GET_OP (op2);
10026 first = op2 >> 4;
10027 last = op2 & 0x0f;
10028 printf ("pop {wR%d", first);
10029 if (last)
10030 printf ("-wR%d", first + last);
10031 printf ("}");
10032 }
10033 else if (op == 0xc7)
10034 {
10035 GET_OP (op2);
10036 if (op2 == 0 || (op2 & 0xf0) != 0)
10037 printf (_("[Spare]"));
0b6ae522
DJ
10038 else
10039 {
61865e30 10040 unsigned int mask = op2 & 0x0f;
015dc7e1 10041 bool first = true;
61865e30
NC
10042 int i;
10043
10044 printf ("pop {");
10045 for (i = 0; i < 4; i++)
10046 if (mask & (1 << i))
10047 {
10048 if (first)
015dc7e1 10049 first = false;
61865e30
NC
10050 else
10051 printf (", ");
10052 printf ("wCGR%d", i);
10053 }
10054 printf ("}");
0b6ae522
DJ
10055 }
10056 }
61865e30 10057 else
32ec8896
NC
10058 {
10059 printf (_(" [unsupported opcode]"));
015dc7e1 10060 res = false;
32ec8896
NC
10061 }
10062
0b6ae522
DJ
10063 printf ("\n");
10064 }
32ec8896
NC
10065
10066 return res;
fa197c1c
PB
10067}
10068
015dc7e1 10069static bool
dda8d76d
NC
10070decode_tic6x_unwind_bytecode (Filedata * filedata,
10071 struct arm_unw_aux_info * aux,
948f632f
DA
10072 unsigned int word,
10073 unsigned int remaining,
10074 unsigned int more_words,
625d49fc 10075 uint64_t data_offset,
948f632f
DA
10076 Elf_Internal_Shdr * data_sec,
10077 struct arm_section * data_arm_sec)
fa197c1c
PB
10078{
10079 struct absaddr addr;
10080
10081 /* Decode the unwinding instructions. */
10082 while (1)
10083 {
10084 unsigned int op, op2;
10085
10086 ADVANCE;
10087 if (remaining == 0)
10088 break;
10089 remaining--;
10090 op = word >> 24;
10091 word <<= 8;
10092
9cf03b7e 10093 printf (" 0x%02x ", op);
fa197c1c
PB
10094
10095 if ((op & 0xc0) == 0x00)
10096 {
10097 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10098 printf (" sp = sp + %d", offset);
fa197c1c
PB
10099 }
10100 else if ((op & 0xc0) == 0x80)
10101 {
10102 GET_OP (op2);
10103 if (op == 0x80 && op2 == 0)
10104 printf (_("Refuse to unwind"));
10105 else
10106 {
10107 unsigned int mask = ((op & 0x1f) << 8) | op2;
10108 if (op & 0x20)
10109 printf ("pop compact {");
10110 else
10111 printf ("pop {");
10112
10113 decode_tic6x_unwind_regmask (mask);
10114 printf("}");
10115 }
10116 }
10117 else if ((op & 0xf0) == 0xc0)
10118 {
10119 unsigned int reg;
10120 unsigned int nregs;
10121 unsigned int i;
10122 const char *name;
a734115a
NC
10123 struct
10124 {
32ec8896
NC
10125 unsigned int offset;
10126 unsigned int reg;
fa197c1c
PB
10127 } regpos[16];
10128
10129 /* Scan entire instruction first so that GET_OP output is not
10130 interleaved with disassembly. */
10131 nregs = 0;
10132 for (i = 0; nregs < (op & 0xf); i++)
10133 {
10134 GET_OP (op2);
10135 reg = op2 >> 4;
10136 if (reg != 0xf)
10137 {
10138 regpos[nregs].offset = i * 2;
10139 regpos[nregs].reg = reg;
10140 nregs++;
10141 }
10142
10143 reg = op2 & 0xf;
10144 if (reg != 0xf)
10145 {
10146 regpos[nregs].offset = i * 2 + 1;
10147 regpos[nregs].reg = reg;
10148 nregs++;
10149 }
10150 }
10151
10152 printf (_("pop frame {"));
18344509 10153 if (nregs == 0)
fa197c1c 10154 {
18344509
NC
10155 printf (_("*corrupt* - no registers specified"));
10156 }
10157 else
10158 {
10159 reg = nregs - 1;
10160 for (i = i * 2; i > 0; i--)
fa197c1c 10161 {
18344509
NC
10162 if (regpos[reg].offset == i - 1)
10163 {
10164 name = tic6x_unwind_regnames[regpos[reg].reg];
10165 if (reg > 0)
10166 reg--;
10167 }
10168 else
10169 name = _("[pad]");
fa197c1c 10170
18344509
NC
10171 fputs (name, stdout);
10172 if (i > 1)
10173 printf (", ");
10174 }
fa197c1c
PB
10175 }
10176
10177 printf ("}");
10178 }
10179 else if (op == 0xd0)
10180 printf (" MOV FP, SP");
10181 else if (op == 0xd1)
10182 printf (" __c6xabi_pop_rts");
10183 else if (op == 0xd2)
10184 {
10185 unsigned char buf[9];
10186 unsigned int i, len;
26c527e6 10187 uint64_t offset;
a734115a 10188
fa197c1c
PB
10189 for (i = 0; i < sizeof (buf); i++)
10190 {
10191 GET_OP (buf[i]);
10192 if ((buf[i] & 0x80) == 0)
10193 break;
10194 }
0eff7165
NC
10195 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10196 if (i == sizeof (buf))
10197 {
0eff7165 10198 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10199 return false;
0eff7165 10200 }
948f632f 10201
015dc7e1 10202 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10203 assert (len == i + 1);
10204 offset = offset * 8 + 0x408;
26c527e6 10205 printf (_("sp = sp + %" PRId64), offset);
fa197c1c
PB
10206 }
10207 else if ((op & 0xf0) == 0xe0)
10208 {
10209 if ((op & 0x0f) == 7)
10210 printf (" RETURN");
10211 else
10212 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10213 }
10214 else
10215 {
10216 printf (_(" [unsupported opcode]"));
10217 }
10218 putchar ('\n');
10219 }
32ec8896 10220
015dc7e1 10221 return true;
fa197c1c
PB
10222}
10223
625d49fc
AM
10224static uint64_t
10225arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10226{
625d49fc 10227 uint64_t offset;
fa197c1c
PB
10228
10229 offset = word & 0x7fffffff;
10230 if (offset & 0x40000000)
625d49fc 10231 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10232
dda8d76d 10233 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10234 offset <<= 1;
10235
10236 return offset + where;
10237}
10238
015dc7e1 10239static bool
dda8d76d
NC
10240decode_arm_unwind (Filedata * filedata,
10241 struct arm_unw_aux_info * aux,
1b31d05e
NC
10242 unsigned int word,
10243 unsigned int remaining,
625d49fc 10244 uint64_t data_offset,
1b31d05e
NC
10245 Elf_Internal_Shdr * data_sec,
10246 struct arm_section * data_arm_sec)
fa197c1c
PB
10247{
10248 int per_index;
10249 unsigned int more_words = 0;
37e14bc3 10250 struct absaddr addr;
625d49fc 10251 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10252 bool res = true;
fa197c1c
PB
10253
10254 if (remaining == 0)
10255 {
1b31d05e
NC
10256 /* Fetch the first word.
10257 Note - when decoding an object file the address extracted
10258 here will always be 0. So we also pass in the sym_name
10259 parameter so that we can find the symbol associated with
10260 the personality routine. */
dda8d76d 10261 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10262 & word, & addr, & sym_name))
015dc7e1 10263 return false;
1b31d05e 10264
fa197c1c
PB
10265 remaining = 4;
10266 }
c93dbb25
CZ
10267 else
10268 {
10269 addr.section = SHN_UNDEF;
10270 addr.offset = 0;
10271 }
fa197c1c
PB
10272
10273 if ((word & 0x80000000) == 0)
10274 {
10275 /* Expand prel31 for personality routine. */
625d49fc 10276 uint64_t fn;
fa197c1c
PB
10277 const char *procname;
10278
dda8d76d 10279 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10280 printf (_(" Personality routine: "));
1b31d05e
NC
10281 if (fn == 0
10282 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10283 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10284 {
10285 procname = aux->strtab + sym_name;
10286 print_vma (fn, PREFIX_HEX);
10287 if (procname)
10288 {
10289 fputs (" <", stdout);
10290 fputs (procname, stdout);
10291 fputc ('>', stdout);
10292 }
10293 }
10294 else
dda8d76d 10295 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10296 fputc ('\n', stdout);
10297
10298 /* The GCC personality routines use the standard compact
10299 encoding, starting with one byte giving the number of
10300 words. */
10301 if (procname != NULL
24d127aa
ML
10302 && (startswith (procname, "__gcc_personality_v0")
10303 || startswith (procname, "__gxx_personality_v0")
10304 || startswith (procname, "__gcj_personality_v0")
10305 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10306 {
10307 remaining = 0;
10308 more_words = 1;
10309 ADVANCE;
10310 if (!remaining)
10311 {
10312 printf (_(" [Truncated data]\n"));
015dc7e1 10313 return false;
fa197c1c
PB
10314 }
10315 more_words = word >> 24;
10316 word <<= 8;
10317 remaining--;
10318 per_index = -1;
10319 }
10320 else
015dc7e1 10321 return true;
fa197c1c
PB
10322 }
10323 else
10324 {
1b31d05e 10325 /* ARM EHABI Section 6.3:
0b4362b0 10326
1b31d05e 10327 An exception-handling table entry for the compact model looks like:
0b4362b0 10328
1b31d05e
NC
10329 31 30-28 27-24 23-0
10330 -- ----- ----- ----
10331 1 0 index Data for personalityRoutine[index] */
10332
dda8d76d 10333 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10334 && (word & 0x70000000))
32ec8896
NC
10335 {
10336 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10337 res = false;
32ec8896 10338 }
1b31d05e 10339
fa197c1c 10340 per_index = (word >> 24) & 0x7f;
1b31d05e 10341 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10342 if (per_index == 0)
10343 {
10344 more_words = 0;
10345 word <<= 8;
10346 remaining--;
10347 }
10348 else if (per_index < 3)
10349 {
10350 more_words = (word >> 16) & 0xff;
10351 word <<= 16;
10352 remaining -= 2;
10353 }
10354 }
10355
dda8d76d 10356 switch (filedata->file_header.e_machine)
fa197c1c
PB
10357 {
10358 case EM_ARM:
10359 if (per_index < 3)
10360 {
dda8d76d 10361 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10362 data_offset, data_sec, data_arm_sec))
015dc7e1 10363 res = false;
fa197c1c
PB
10364 }
10365 else
1b31d05e
NC
10366 {
10367 warn (_("Unknown ARM compact model index encountered\n"));
10368 printf (_(" [reserved]\n"));
015dc7e1 10369 res = false;
1b31d05e 10370 }
fa197c1c
PB
10371 break;
10372
10373 case EM_TI_C6000:
10374 if (per_index < 3)
10375 {
dda8d76d 10376 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10377 data_offset, data_sec, data_arm_sec))
015dc7e1 10378 res = false;
fa197c1c
PB
10379 }
10380 else if (per_index < 5)
10381 {
10382 if (((word >> 17) & 0x7f) == 0x7f)
10383 printf (_(" Restore stack from frame pointer\n"));
10384 else
10385 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10386 printf (_(" Registers restored: "));
10387 if (per_index == 4)
10388 printf (" (compact) ");
10389 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10390 putchar ('\n');
10391 printf (_(" Return register: %s\n"),
10392 tic6x_unwind_regnames[word & 0xf]);
10393 }
10394 else
1b31d05e 10395 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10396 break;
10397
10398 default:
74e1a04b 10399 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10400 filedata->file_header.e_machine);
015dc7e1 10401 res = false;
fa197c1c 10402 }
0b6ae522
DJ
10403
10404 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10405
10406 return res;
0b6ae522
DJ
10407}
10408
015dc7e1 10409static bool
dda8d76d
NC
10410dump_arm_unwind (Filedata * filedata,
10411 struct arm_unw_aux_info * aux,
10412 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10413{
10414 struct arm_section exidx_arm_sec, extab_arm_sec;
10415 unsigned int i, exidx_len;
26c527e6 10416 uint64_t j, nfuns;
015dc7e1 10417 bool res = true;
0b6ae522
DJ
10418
10419 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10420 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10421 exidx_len = exidx_sec->sh_size / 8;
10422
948f632f
DA
10423 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10424 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10425 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10426 aux->funtab[nfuns++] = aux->symtab[j];
10427 aux->nfuns = nfuns;
10428 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10429
0b6ae522
DJ
10430 for (i = 0; i < exidx_len; i++)
10431 {
10432 unsigned int exidx_fn, exidx_entry;
10433 struct absaddr fn_addr, entry_addr;
625d49fc 10434 uint64_t fn;
0b6ae522
DJ
10435
10436 fputc ('\n', stdout);
10437
dda8d76d 10438 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10439 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10440 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10441 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10442 {
948f632f 10443 free (aux->funtab);
1b31d05e
NC
10444 arm_free_section (& exidx_arm_sec);
10445 arm_free_section (& extab_arm_sec);
015dc7e1 10446 return false;
0b6ae522
DJ
10447 }
10448
83c257ca
NC
10449 /* ARM EHABI, Section 5:
10450 An index table entry consists of 2 words.
10451 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10452 if (exidx_fn & 0x80000000)
32ec8896
NC
10453 {
10454 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10455 res = false;
32ec8896 10456 }
83c257ca 10457
dda8d76d 10458 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10459
dda8d76d 10460 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10461 fputs (": ", stdout);
10462
10463 if (exidx_entry == 1)
10464 {
10465 print_vma (exidx_entry, PREFIX_HEX);
10466 fputs (" [cantunwind]\n", stdout);
10467 }
10468 else if (exidx_entry & 0x80000000)
10469 {
10470 print_vma (exidx_entry, PREFIX_HEX);
10471 fputc ('\n', stdout);
dda8d76d 10472 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10473 }
10474 else
10475 {
625d49fc 10476 uint64_t table, table_offset = 0;
0b6ae522
DJ
10477 Elf_Internal_Shdr *table_sec;
10478
10479 fputs ("@", stdout);
dda8d76d 10480 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10481 print_vma (table, PREFIX_HEX);
10482 printf ("\n");
10483
10484 /* Locate the matching .ARM.extab. */
10485 if (entry_addr.section != SHN_UNDEF
dda8d76d 10486 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10487 {
dda8d76d 10488 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10489 table_offset = entry_addr.offset;
1a915552 10490 /* PR 18879 */
625d49fc 10491 if (table_offset > table_sec->sh_size)
1a915552 10492 {
26c527e6
AM
10493 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
10494 table_offset,
dda8d76d 10495 printable_section_name (filedata, table_sec));
015dc7e1 10496 res = false;
1a915552
NC
10497 continue;
10498 }
0b6ae522
DJ
10499 }
10500 else
10501 {
dda8d76d 10502 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10503 if (table_sec != NULL)
10504 table_offset = table - table_sec->sh_addr;
10505 }
32ec8896 10506
0b6ae522
DJ
10507 if (table_sec == NULL)
10508 {
26c527e6
AM
10509 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
10510 table);
015dc7e1 10511 res = false;
0b6ae522
DJ
10512 continue;
10513 }
32ec8896 10514
dda8d76d 10515 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10516 &extab_arm_sec))
015dc7e1 10517 res = false;
0b6ae522
DJ
10518 }
10519 }
10520
10521 printf ("\n");
10522
948f632f 10523 free (aux->funtab);
0b6ae522
DJ
10524 arm_free_section (&exidx_arm_sec);
10525 arm_free_section (&extab_arm_sec);
32ec8896
NC
10526
10527 return res;
0b6ae522
DJ
10528}
10529
fa197c1c 10530/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10531
015dc7e1 10532static bool
dda8d76d 10533arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10534{
10535 struct arm_unw_aux_info aux;
10536 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522 10537 Elf_Internal_Shdr *sec;
26c527e6 10538 size_t i;
fa197c1c 10539 unsigned int sec_type;
015dc7e1 10540 bool res = true;
0b6ae522 10541
dda8d76d 10542 switch (filedata->file_header.e_machine)
fa197c1c
PB
10543 {
10544 case EM_ARM:
10545 sec_type = SHT_ARM_EXIDX;
10546 break;
10547
10548 case EM_TI_C6000:
10549 sec_type = SHT_C6000_UNWIND;
10550 break;
10551
0b4362b0 10552 default:
74e1a04b 10553 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10554 filedata->file_header.e_machine);
015dc7e1 10555 return false;
fa197c1c
PB
10556 }
10557
dda8d76d 10558 if (filedata->string_table == NULL)
015dc7e1 10559 return false;
1b31d05e
NC
10560
10561 memset (& aux, 0, sizeof (aux));
dda8d76d 10562 aux.filedata = filedata;
0b6ae522 10563
dda8d76d 10564 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10565 {
28d13567 10566 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10567 {
28d13567 10568 if (aux.symtab)
74e1a04b 10569 {
28d13567
AM
10570 error (_("Multiple symbol tables encountered\n"));
10571 free (aux.symtab);
10572 aux.symtab = NULL;
74e1a04b 10573 free (aux.strtab);
28d13567 10574 aux.strtab = NULL;
74e1a04b 10575 }
28d13567
AM
10576 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10577 &aux.strtab, &aux.strtab_size))
015dc7e1 10578 return false;
0b6ae522 10579 }
fa197c1c 10580 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10581 unwsec = sec;
10582 }
10583
1b31d05e 10584 if (unwsec == NULL)
0b6ae522 10585 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10586 else
dda8d76d 10587 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10588 {
10589 if (sec->sh_type == sec_type)
10590 {
26c527e6
AM
10591 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
10592 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
10593 "contains %" PRIu64 " entry:\n",
10594 "\nUnwind section '%s' at offset %#" PRIx64 " "
10595 "contains %" PRIu64 " entries:\n",
d3a49aa8 10596 num_unwind),
dda8d76d 10597 printable_section_name (filedata, sec),
26c527e6 10598 sec->sh_offset,
d3a49aa8 10599 num_unwind);
0b6ae522 10600
dda8d76d 10601 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10602 res = false;
1b31d05e
NC
10603 }
10604 }
0b6ae522 10605
9db70fc3
AM
10606 free (aux.symtab);
10607 free ((char *) aux.strtab);
32ec8896
NC
10608
10609 return res;
0b6ae522
DJ
10610}
10611
3ecc00ec
NC
10612static bool
10613no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10614{
10615 printf (_("No processor specific unwind information to decode\n"));
10616 return true;
10617}
10618
015dc7e1 10619static bool
dda8d76d 10620process_unwind (Filedata * filedata)
57346661 10621{
2cf0635d
NC
10622 struct unwind_handler
10623 {
32ec8896 10624 unsigned int machtype;
015dc7e1 10625 bool (* handler)(Filedata *);
2cf0635d
NC
10626 } handlers[] =
10627 {
0b6ae522 10628 { EM_ARM, arm_process_unwind },
57346661
AM
10629 { EM_IA_64, ia64_process_unwind },
10630 { EM_PARISC, hppa_process_unwind },
fa197c1c 10631 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10632 { EM_386, no_processor_specific_unwind },
10633 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10634 { 0, NULL }
57346661
AM
10635 };
10636 int i;
10637
10638 if (!do_unwind)
015dc7e1 10639 return true;
57346661
AM
10640
10641 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10642 if (filedata->file_header.e_machine == handlers[i].machtype)
10643 return handlers[i].handler (filedata);
57346661 10644
1b31d05e 10645 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10646 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10647 return true;
57346661
AM
10648}
10649
37c18eed
SD
10650static void
10651dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10652{
10653 switch (entry->d_tag)
10654 {
10655 case DT_AARCH64_BTI_PLT:
1dbade74 10656 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10657 break;
10658 default:
10659 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10660 break;
10661 }
10662 putchar ('\n');
10663}
10664
252b5132 10665static void
978c4450 10666dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10667{
10668 switch (entry->d_tag)
10669 {
10670 case DT_MIPS_FLAGS:
10671 if (entry->d_un.d_val == 0)
4b68bca3 10672 printf (_("NONE"));
252b5132
RH
10673 else
10674 {
10675 static const char * opts[] =
10676 {
10677 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10678 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10679 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10680 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10681 "RLD_ORDER_SAFE"
10682 };
10683 unsigned int cnt;
015dc7e1 10684 bool first = true;
2b692964 10685
60bca95a 10686 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10687 if (entry->d_un.d_val & (1 << cnt))
10688 {
10689 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10690 first = false;
252b5132 10691 }
252b5132
RH
10692 }
10693 break;
103f02d3 10694
252b5132 10695 case DT_MIPS_IVERSION:
84714f86 10696 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10697 printf (_("Interface Version: %s"),
84714f86 10698 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10699 else
f493c217 10700 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 10701 entry->d_un.d_ptr);
252b5132 10702 break;
103f02d3 10703
252b5132
RH
10704 case DT_MIPS_TIME_STAMP:
10705 {
d5b07ef4 10706 char timebuf[128];
2cf0635d 10707 struct tm * tmp;
91d6fa6a 10708 time_t atime = entry->d_un.d_val;
82b1b41b 10709
91d6fa6a 10710 tmp = gmtime (&atime);
82b1b41b
NC
10711 /* PR 17531: file: 6accc532. */
10712 if (tmp == NULL)
10713 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10714 else
10715 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10716 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10717 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10718 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10719 }
10720 break;
103f02d3 10721
252b5132
RH
10722 case DT_MIPS_RLD_VERSION:
10723 case DT_MIPS_LOCAL_GOTNO:
10724 case DT_MIPS_CONFLICTNO:
10725 case DT_MIPS_LIBLISTNO:
10726 case DT_MIPS_SYMTABNO:
10727 case DT_MIPS_UNREFEXTNO:
10728 case DT_MIPS_HIPAGENO:
10729 case DT_MIPS_DELTA_CLASS_NO:
10730 case DT_MIPS_DELTA_INSTANCE_NO:
10731 case DT_MIPS_DELTA_RELOC_NO:
10732 case DT_MIPS_DELTA_SYM_NO:
10733 case DT_MIPS_DELTA_CLASSSYM_NO:
10734 case DT_MIPS_COMPACT_SIZE:
c69075ac 10735 print_vma (entry->d_un.d_val, DEC);
252b5132 10736 break;
103f02d3 10737
f16a9783 10738 case DT_MIPS_XHASH:
978c4450
AM
10739 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10740 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10741 /* Falls through. */
10742
103f02d3 10743 default:
4b68bca3 10744 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10745 }
4b68bca3 10746 putchar ('\n');
103f02d3
UD
10747}
10748
103f02d3 10749static void
2cf0635d 10750dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10751{
10752 switch (entry->d_tag)
10753 {
10754 case DT_HP_DLD_FLAGS:
10755 {
10756 static struct
10757 {
26c527e6 10758 unsigned int bit;
2cf0635d 10759 const char * str;
5e220199
NC
10760 }
10761 flags[] =
10762 {
10763 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10764 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10765 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10766 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10767 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10768 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10769 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10770 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10771 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10772 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10773 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10774 { DT_HP_GST, "HP_GST" },
10775 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10776 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10777 { DT_HP_NODELETE, "HP_NODELETE" },
10778 { DT_HP_GROUP, "HP_GROUP" },
10779 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10780 };
015dc7e1 10781 bool first = true;
5e220199 10782 size_t cnt;
625d49fc 10783 uint64_t val = entry->d_un.d_val;
103f02d3 10784
60bca95a 10785 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10786 if (val & flags[cnt].bit)
30800947
NC
10787 {
10788 if (! first)
10789 putchar (' ');
10790 fputs (flags[cnt].str, stdout);
015dc7e1 10791 first = false;
30800947
NC
10792 val ^= flags[cnt].bit;
10793 }
76da6bbe 10794
103f02d3 10795 if (val != 0 || first)
f7a99963
NC
10796 {
10797 if (! first)
10798 putchar (' ');
10799 print_vma (val, HEX);
10800 }
103f02d3
UD
10801 }
10802 break;
76da6bbe 10803
252b5132 10804 default:
f7a99963
NC
10805 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10806 break;
252b5132 10807 }
35b1837e 10808 putchar ('\n');
252b5132
RH
10809}
10810
28f997cf
TG
10811/* VMS vs Unix time offset and factor. */
10812
10813#define VMS_EPOCH_OFFSET 35067168000000000LL
10814#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10815#ifndef INT64_MIN
10816#define INT64_MIN (-9223372036854775807LL - 1)
10817#endif
28f997cf
TG
10818
10819/* Display a VMS time in a human readable format. */
10820
10821static void
0e3c1eeb 10822print_vms_time (int64_t vmstime)
28f997cf 10823{
dccc31de 10824 struct tm *tm = NULL;
28f997cf
TG
10825 time_t unxtime;
10826
dccc31de
AM
10827 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10828 {
10829 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10830 unxtime = vmstime;
10831 if (unxtime == vmstime)
10832 tm = gmtime (&unxtime);
10833 }
10834 if (tm != NULL)
10835 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10836 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10837 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 10838}
28f997cf 10839
ecc51f48 10840static void
2cf0635d 10841dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10842{
10843 switch (entry->d_tag)
10844 {
0de14b54 10845 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10846 /* First 3 slots reserved. */
ecc51f48
NC
10847 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10848 printf (" -- ");
10849 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10850 break;
10851
28f997cf 10852 case DT_IA_64_VMS_LINKTIME:
28f997cf 10853 print_vms_time (entry->d_un.d_val);
28f997cf
TG
10854 break;
10855
10856 case DT_IA_64_VMS_LNKFLAGS:
10857 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10858 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10859 printf (" CALL_DEBUG");
10860 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10861 printf (" NOP0BUFS");
10862 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10863 printf (" P0IMAGE");
10864 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10865 printf (" MKTHREADS");
10866 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10867 printf (" UPCALLS");
10868 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10869 printf (" IMGSTA");
10870 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10871 printf (" INITIALIZE");
10872 if (entry->d_un.d_val & VMS_LF_MAIN)
10873 printf (" MAIN");
10874 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10875 printf (" EXE_INIT");
10876 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10877 printf (" TBK_IN_IMG");
10878 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10879 printf (" DBG_IN_IMG");
10880 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10881 printf (" TBK_IN_DSF");
10882 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10883 printf (" DBG_IN_DSF");
10884 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10885 printf (" SIGNATURES");
10886 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10887 printf (" REL_SEG_OFF");
10888 break;
10889
bdf4d63a
JJ
10890 default:
10891 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10892 break;
ecc51f48 10893 }
bdf4d63a 10894 putchar ('\n');
ecc51f48
NC
10895}
10896
015dc7e1 10897static bool
dda8d76d 10898get_32bit_dynamic_section (Filedata * filedata)
252b5132 10899{
2cf0635d
NC
10900 Elf32_External_Dyn * edyn;
10901 Elf32_External_Dyn * ext;
10902 Elf_Internal_Dyn * entry;
103f02d3 10903
978c4450
AM
10904 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10905 filedata->dynamic_addr, 1,
10906 filedata->dynamic_size,
10907 _("dynamic section"));
a6e9f9df 10908 if (!edyn)
015dc7e1 10909 return false;
103f02d3 10910
071436c6
NC
10911 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10912 might not have the luxury of section headers. Look for the DT_NULL
10913 terminator to determine the number of entries. */
978c4450
AM
10914 for (ext = edyn, filedata->dynamic_nent = 0;
10915 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10916 ext++)
10917 {
978c4450 10918 filedata->dynamic_nent++;
ba2685cc
AM
10919 if (BYTE_GET (ext->d_tag) == DT_NULL)
10920 break;
10921 }
252b5132 10922
978c4450
AM
10923 filedata->dynamic_section
10924 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10925 if (filedata->dynamic_section == NULL)
252b5132 10926 {
26c527e6
AM
10927 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
10928 filedata->dynamic_nent);
9ea033b2 10929 free (edyn);
015dc7e1 10930 return false;
9ea033b2 10931 }
252b5132 10932
978c4450
AM
10933 for (ext = edyn, entry = filedata->dynamic_section;
10934 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10935 ext++, entry++)
9ea033b2 10936 {
fb514b26
AM
10937 entry->d_tag = BYTE_GET (ext->d_tag);
10938 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10939 }
10940
9ea033b2
NC
10941 free (edyn);
10942
015dc7e1 10943 return true;
9ea033b2
NC
10944}
10945
015dc7e1 10946static bool
dda8d76d 10947get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10948{
2cf0635d
NC
10949 Elf64_External_Dyn * edyn;
10950 Elf64_External_Dyn * ext;
10951 Elf_Internal_Dyn * entry;
103f02d3 10952
071436c6 10953 /* Read in the data. */
978c4450
AM
10954 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10955 filedata->dynamic_addr, 1,
10956 filedata->dynamic_size,
10957 _("dynamic section"));
a6e9f9df 10958 if (!edyn)
015dc7e1 10959 return false;
103f02d3 10960
071436c6
NC
10961 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10962 might not have the luxury of section headers. Look for the DT_NULL
10963 terminator to determine the number of entries. */
978c4450 10964 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10965 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10966 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10967 ext++)
10968 {
978c4450 10969 filedata->dynamic_nent++;
66543521 10970 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10971 break;
10972 }
252b5132 10973
978c4450
AM
10974 filedata->dynamic_section
10975 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10976 if (filedata->dynamic_section == NULL)
252b5132 10977 {
26c527e6
AM
10978 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
10979 filedata->dynamic_nent);
252b5132 10980 free (edyn);
015dc7e1 10981 return false;
252b5132
RH
10982 }
10983
071436c6 10984 /* Convert from external to internal formats. */
978c4450
AM
10985 for (ext = edyn, entry = filedata->dynamic_section;
10986 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10987 ext++, entry++)
252b5132 10988 {
66543521
AM
10989 entry->d_tag = BYTE_GET (ext->d_tag);
10990 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10991 }
10992
10993 free (edyn);
10994
015dc7e1 10995 return true;
9ea033b2
NC
10996}
10997
4de91c10
AM
10998static bool
10999get_dynamic_section (Filedata *filedata)
11000{
11001 if (filedata->dynamic_section)
11002 return true;
11003
11004 if (is_32bit_elf)
11005 return get_32bit_dynamic_section (filedata);
11006 else
11007 return get_64bit_dynamic_section (filedata);
11008}
11009
e9e44622 11010static void
625d49fc 11011print_dynamic_flags (uint64_t flags)
d1133906 11012{
015dc7e1 11013 bool first = true;
13ae64f3 11014
d1133906
NC
11015 while (flags)
11016 {
625d49fc 11017 uint64_t flag;
d1133906
NC
11018
11019 flag = flags & - flags;
11020 flags &= ~ flag;
11021
e9e44622 11022 if (first)
015dc7e1 11023 first = false;
e9e44622
JJ
11024 else
11025 putc (' ', stdout);
13ae64f3 11026
d1133906
NC
11027 switch (flag)
11028 {
e9e44622
JJ
11029 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11030 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11031 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11032 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11033 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 11034 default: fputs (_("unknown"), stdout); break;
d1133906
NC
11035 }
11036 }
e9e44622 11037 puts ("");
d1133906
NC
11038}
11039
625d49fc 11040static uint64_t *
be7d229a 11041get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
11042{
11043 unsigned char * e_data;
625d49fc 11044 uint64_t * i_data;
10ca4b04 11045
be7d229a
AM
11046 /* If size_t is smaller than uint64_t, eg because you are building
11047 on a 32-bit host, then make sure that when number is cast to
11048 size_t no information is lost. */
11049 if ((size_t) number != number
11050 || ent_size * number / ent_size != number)
10ca4b04 11051 {
be7d229a 11052 error (_("Size overflow prevents reading %" PRIu64
b8281767 11053 " elements of size %u\n"),
be7d229a 11054 number, ent_size);
10ca4b04
L
11055 return NULL;
11056 }
11057
11058 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11059 attempting to allocate memory when the read is bound to fail. */
11060 if (ent_size * number > filedata->file_size)
11061 {
b8281767 11062 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 11063 number);
10ca4b04
L
11064 return NULL;
11065 }
11066
11067 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11068 if (e_data == NULL)
11069 {
b8281767 11070 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 11071 number);
10ca4b04
L
11072 return NULL;
11073 }
11074
11075 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11076 {
b8281767 11077 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 11078 number * ent_size);
10ca4b04
L
11079 free (e_data);
11080 return NULL;
11081 }
11082
625d49fc 11083 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
11084 if (i_data == NULL)
11085 {
b8281767 11086 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 11087 number);
10ca4b04
L
11088 free (e_data);
11089 return NULL;
11090 }
11091
11092 while (number--)
11093 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11094
11095 free (e_data);
11096
11097 return i_data;
11098}
11099
26c527e6 11100static uint64_t
10ca4b04
L
11101get_num_dynamic_syms (Filedata * filedata)
11102{
26c527e6 11103 uint64_t num_of_syms = 0;
10ca4b04
L
11104
11105 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11106 return num_of_syms;
11107
978c4450 11108 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11109 {
11110 unsigned char nb[8];
11111 unsigned char nc[8];
11112 unsigned int hash_ent_size = 4;
11113
11114 if ((filedata->file_header.e_machine == EM_ALPHA
11115 || filedata->file_header.e_machine == EM_S390
11116 || filedata->file_header.e_machine == EM_S390_OLD)
11117 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11118 hash_ent_size = 8;
11119
63cf857e
AM
11120 if (fseek64 (filedata->handle,
11121 (filedata->archive_file_offset
11122 + offset_from_vma (filedata,
11123 filedata->dynamic_info[DT_HASH],
11124 sizeof nb + sizeof nc)),
11125 SEEK_SET))
10ca4b04
L
11126 {
11127 error (_("Unable to seek to start of dynamic information\n"));
11128 goto no_hash;
11129 }
11130
11131 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11132 {
11133 error (_("Failed to read in number of buckets\n"));
11134 goto no_hash;
11135 }
11136
11137 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11138 {
11139 error (_("Failed to read in number of chains\n"));
11140 goto no_hash;
11141 }
11142
978c4450
AM
11143 filedata->nbuckets = byte_get (nb, hash_ent_size);
11144 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11145
2482f306
AM
11146 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11147 {
11148 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11149 hash_ent_size);
11150 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11151 hash_ent_size);
001890e1 11152
2482f306
AM
11153 if (filedata->buckets != NULL && filedata->chains != NULL)
11154 num_of_syms = filedata->nchains;
11155 }
ceb9bf11 11156 no_hash:
10ca4b04
L
11157 if (num_of_syms == 0)
11158 {
9db70fc3
AM
11159 free (filedata->buckets);
11160 filedata->buckets = NULL;
11161 free (filedata->chains);
11162 filedata->chains = NULL;
978c4450 11163 filedata->nbuckets = 0;
10ca4b04
L
11164 }
11165 }
11166
978c4450 11167 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11168 {
11169 unsigned char nb[16];
625d49fc
AM
11170 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11171 uint64_t buckets_vma;
26c527e6 11172 uint64_t hn;
10ca4b04 11173
63cf857e
AM
11174 if (fseek64 (filedata->handle,
11175 (filedata->archive_file_offset
11176 + offset_from_vma (filedata,
11177 filedata->dynamic_info_DT_GNU_HASH,
11178 sizeof nb)),
11179 SEEK_SET))
10ca4b04
L
11180 {
11181 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11182 goto no_gnu_hash;
11183 }
11184
11185 if (fread (nb, 16, 1, filedata->handle) != 1)
11186 {
11187 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11188 goto no_gnu_hash;
11189 }
11190
978c4450
AM
11191 filedata->ngnubuckets = byte_get (nb, 4);
11192 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11193 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11194 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11195 if (is_32bit_elf)
11196 buckets_vma += bitmaskwords * 4;
11197 else
11198 buckets_vma += bitmaskwords * 8;
11199
63cf857e
AM
11200 if (fseek64 (filedata->handle,
11201 (filedata->archive_file_offset
11202 + offset_from_vma (filedata, buckets_vma, 4)),
11203 SEEK_SET))
10ca4b04
L
11204 {
11205 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11206 goto no_gnu_hash;
11207 }
11208
978c4450
AM
11209 filedata->gnubuckets
11210 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11211
978c4450 11212 if (filedata->gnubuckets == NULL)
90837ea7 11213 goto no_gnu_hash;
10ca4b04 11214
978c4450
AM
11215 for (i = 0; i < filedata->ngnubuckets; i++)
11216 if (filedata->gnubuckets[i] != 0)
10ca4b04 11217 {
978c4450 11218 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11219 goto no_gnu_hash;
10ca4b04 11220
978c4450
AM
11221 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11222 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11223 }
11224
11225 if (maxchain == 0xffffffff)
90837ea7 11226 goto no_gnu_hash;
10ca4b04 11227
978c4450 11228 maxchain -= filedata->gnusymidx;
10ca4b04 11229
63cf857e
AM
11230 if (fseek64 (filedata->handle,
11231 (filedata->archive_file_offset
11232 + offset_from_vma (filedata,
11233 buckets_vma + 4 * (filedata->ngnubuckets
11234 + maxchain),
11235 4)),
11236 SEEK_SET))
10ca4b04
L
11237 {
11238 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11239 goto no_gnu_hash;
11240 }
11241
11242 do
11243 {
11244 if (fread (nb, 4, 1, filedata->handle) != 1)
11245 {
11246 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11247 goto no_gnu_hash;
11248 }
11249
11250 if (maxchain + 1 == 0)
90837ea7 11251 goto no_gnu_hash;
10ca4b04
L
11252
11253 ++maxchain;
11254 }
11255 while ((byte_get (nb, 4) & 1) == 0);
11256
63cf857e
AM
11257 if (fseek64 (filedata->handle,
11258 (filedata->archive_file_offset
11259 + offset_from_vma (filedata, (buckets_vma
11260 + 4 * filedata->ngnubuckets),
11261 4)),
11262 SEEK_SET))
10ca4b04
L
11263 {
11264 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11265 goto no_gnu_hash;
11266 }
11267
978c4450
AM
11268 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11269 filedata->ngnuchains = maxchain;
10ca4b04 11270
978c4450 11271 if (filedata->gnuchains == NULL)
90837ea7 11272 goto no_gnu_hash;
10ca4b04 11273
978c4450 11274 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11275 {
63cf857e
AM
11276 if (fseek64 (filedata->handle,
11277 (filedata->archive_file_offset
11278 + offset_from_vma (filedata, (buckets_vma
11279 + 4 * (filedata->ngnubuckets
11280 + maxchain)), 4)),
11281 SEEK_SET))
10ca4b04
L
11282 {
11283 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11284 goto no_gnu_hash;
11285 }
11286
978c4450 11287 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11288 if (filedata->mipsxlat == NULL)
11289 goto no_gnu_hash;
10ca4b04
L
11290 }
11291
978c4450
AM
11292 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11293 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11294 {
625d49fc
AM
11295 uint64_t si = filedata->gnubuckets[hn];
11296 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11297
11298 do
11299 {
978c4450 11300 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11301 {
c31ab5a0
AM
11302 if (off < filedata->ngnuchains
11303 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11304 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11305 }
11306 else
11307 {
11308 if (si >= num_of_syms)
11309 num_of_syms = si + 1;
11310 }
11311 si++;
11312 }
978c4450
AM
11313 while (off < filedata->ngnuchains
11314 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11315 }
11316
90837ea7 11317 if (num_of_syms == 0)
10ca4b04 11318 {
90837ea7 11319 no_gnu_hash:
9db70fc3
AM
11320 free (filedata->mipsxlat);
11321 filedata->mipsxlat = NULL;
11322 free (filedata->gnuchains);
11323 filedata->gnuchains = NULL;
11324 free (filedata->gnubuckets);
11325 filedata->gnubuckets = NULL;
978c4450
AM
11326 filedata->ngnubuckets = 0;
11327 filedata->ngnuchains = 0;
10ca4b04
L
11328 }
11329 }
11330
11331 return num_of_syms;
11332}
11333
b2d38a17
NC
11334/* Parse and display the contents of the dynamic section. */
11335
015dc7e1 11336static bool
dda8d76d 11337process_dynamic_section (Filedata * filedata)
9ea033b2 11338{
2cf0635d 11339 Elf_Internal_Dyn * entry;
9ea033b2 11340
93df3340 11341 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11342 {
11343 if (do_dynamic)
ca0e11aa
NC
11344 {
11345 if (filedata->is_separate)
11346 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11347 filedata->file_name);
11348 else
11349 printf (_("\nThere is no dynamic section in this file.\n"));
11350 }
9ea033b2 11351
015dc7e1 11352 return true;
9ea033b2
NC
11353 }
11354
4de91c10
AM
11355 if (!get_dynamic_section (filedata))
11356 return false;
9ea033b2 11357
252b5132 11358 /* Find the appropriate symbol table. */
978c4450 11359 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11360 {
26c527e6 11361 uint64_t num_of_syms;
2482f306 11362
978c4450
AM
11363 for (entry = filedata->dynamic_section;
11364 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11365 ++entry)
10ca4b04 11366 if (entry->d_tag == DT_SYMTAB)
978c4450 11367 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11368 else if (entry->d_tag == DT_SYMENT)
978c4450 11369 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11370 else if (entry->d_tag == DT_HASH)
978c4450 11371 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11372 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11373 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11374 else if ((filedata->file_header.e_machine == EM_MIPS
11375 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11376 && entry->d_tag == DT_MIPS_XHASH)
11377 {
978c4450
AM
11378 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11379 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11380 }
252b5132 11381
2482f306
AM
11382 num_of_syms = get_num_dynamic_syms (filedata);
11383
11384 if (num_of_syms != 0
11385 && filedata->dynamic_symbols == NULL
11386 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11387 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11388 {
11389 Elf_Internal_Phdr *seg;
625d49fc 11390 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11391
2482f306
AM
11392 if (! get_program_headers (filedata))
11393 {
11394 error (_("Cannot interpret virtual addresses "
11395 "without program headers.\n"));
015dc7e1 11396 return false;
2482f306 11397 }
252b5132 11398
2482f306
AM
11399 for (seg = filedata->program_headers;
11400 seg < filedata->program_headers + filedata->file_header.e_phnum;
11401 ++seg)
11402 {
11403 if (seg->p_type != PT_LOAD)
11404 continue;
252b5132 11405
2482f306
AM
11406 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11407 {
11408 /* See PR 21379 for a reproducer. */
11409 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11410 return false;
2482f306 11411 }
252b5132 11412
2482f306
AM
11413 if (vma >= (seg->p_vaddr & -seg->p_align)
11414 && vma < seg->p_vaddr + seg->p_filesz)
11415 {
11416 /* Since we do not know how big the symbol table is,
11417 we default to reading in up to the end of PT_LOAD
11418 segment and processing that. This is overkill, I
11419 know, but it should work. */
11420 Elf_Internal_Shdr section;
11421 section.sh_offset = (vma - seg->p_vaddr
11422 + seg->p_offset);
11423 section.sh_size = (num_of_syms
11424 * filedata->dynamic_info[DT_SYMENT]);
11425 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11426
11427 if (do_checks
11428 && filedata->dynamic_symtab_section != NULL
11429 && ((filedata->dynamic_symtab_section->sh_offset
11430 != section.sh_offset)
11431 || (filedata->dynamic_symtab_section->sh_size
11432 != section.sh_size)
11433 || (filedata->dynamic_symtab_section->sh_entsize
11434 != section.sh_entsize)))
11435 warn (_("\
11436the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11437
2482f306
AM
11438 section.sh_name = filedata->string_table_length;
11439 filedata->dynamic_symbols
4de91c10 11440 = get_elf_symbols (filedata, &section,
2482f306
AM
11441 &filedata->num_dynamic_syms);
11442 if (filedata->dynamic_symbols == NULL
11443 || filedata->num_dynamic_syms != num_of_syms)
11444 {
11445 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11446 return false;
2482f306
AM
11447 }
11448 break;
11449 }
11450 }
11451 }
11452 }
252b5132
RH
11453
11454 /* Similarly find a string table. */
978c4450
AM
11455 if (filedata->dynamic_strings == NULL)
11456 for (entry = filedata->dynamic_section;
11457 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11458 ++entry)
11459 {
11460 if (entry->d_tag == DT_STRTAB)
978c4450 11461 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11462
10ca4b04 11463 if (entry->d_tag == DT_STRSZ)
978c4450 11464 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11465
978c4450
AM
11466 if (filedata->dynamic_info[DT_STRTAB]
11467 && filedata->dynamic_info[DT_STRSZ])
10ca4b04 11468 {
26c527e6 11469 uint64_t offset;
be7d229a 11470 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11471
11472 offset = offset_from_vma (filedata,
978c4450 11473 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11474 str_tab_len);
8ac10c5b
L
11475 if (do_checks
11476 && filedata->dynamic_strtab_section
11477 && ((filedata->dynamic_strtab_section->sh_offset
11478 != (file_ptr) offset)
11479 || (filedata->dynamic_strtab_section->sh_size
11480 != str_tab_len)))
11481 warn (_("\
11482the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11483
978c4450
AM
11484 filedata->dynamic_strings
11485 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11486 _("dynamic string table"));
11487 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11488 {
11489 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11490 break;
11491 }
e3d39609 11492
978c4450 11493 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11494 break;
11495 }
11496 }
252b5132
RH
11497
11498 /* And find the syminfo section if available. */
978c4450 11499 if (filedata->dynamic_syminfo == NULL)
252b5132 11500 {
26c527e6 11501 uint64_t syminsz = 0;
252b5132 11502
978c4450
AM
11503 for (entry = filedata->dynamic_section;
11504 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11505 ++entry)
252b5132
RH
11506 {
11507 if (entry->d_tag == DT_SYMINENT)
11508 {
11509 /* Note: these braces are necessary to avoid a syntax
11510 error from the SunOS4 C compiler. */
049b0c3a
NC
11511 /* PR binutils/17531: A corrupt file can trigger this test.
11512 So do not use an assert, instead generate an error message. */
11513 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11514 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11515 (int) entry->d_un.d_val);
252b5132
RH
11516 }
11517 else if (entry->d_tag == DT_SYMINSZ)
11518 syminsz = entry->d_un.d_val;
11519 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11520 filedata->dynamic_syminfo_offset
11521 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11522 }
11523
978c4450 11524 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11525 {
2cf0635d
NC
11526 Elf_External_Syminfo * extsyminfo;
11527 Elf_External_Syminfo * extsym;
11528 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11529
11530 /* There is a syminfo section. Read the data. */
3f5e193b 11531 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11532 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11533 1, syminsz, _("symbol information"));
a6e9f9df 11534 if (!extsyminfo)
015dc7e1 11535 return false;
252b5132 11536
978c4450 11537 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11538 {
11539 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11540 free (filedata->dynamic_syminfo);
e3d39609 11541 }
978c4450
AM
11542 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11543 if (filedata->dynamic_syminfo == NULL)
252b5132 11544 {
26c527e6
AM
11545 error (_("Out of memory allocating %" PRIu64
11546 " bytes for dynamic symbol info\n"),
11547 syminsz);
015dc7e1 11548 return false;
252b5132
RH
11549 }
11550
2482f306
AM
11551 filedata->dynamic_syminfo_nent
11552 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11553 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11554 syminfo < (filedata->dynamic_syminfo
11555 + filedata->dynamic_syminfo_nent);
86dba8ee 11556 ++syminfo, ++extsym)
252b5132 11557 {
86dba8ee
AM
11558 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11559 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11560 }
11561
11562 free (extsyminfo);
11563 }
11564 }
11565
978c4450 11566 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11567 {
f253158f 11568 if (filedata->is_separate)
26c527e6
AM
11569 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
11570 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
11571 filedata->dynamic_nent),
f253158f
NC
11572 filedata->file_name,
11573 filedata->dynamic_addr,
26c527e6 11574 filedata->dynamic_nent);
84a9f195 11575 else
02da71ee 11576 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
26c527e6
AM
11577 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
11578 filedata->dynamic_nent),
84a9f195 11579 filedata->dynamic_addr,
26c527e6 11580 filedata->dynamic_nent);
ca0e11aa 11581 }
252b5132
RH
11582 if (do_dynamic)
11583 printf (_(" Tag Type Name/Value\n"));
11584
978c4450
AM
11585 for (entry = filedata->dynamic_section;
11586 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11587 entry++)
252b5132
RH
11588 {
11589 if (do_dynamic)
f7a99963 11590 {
2cf0635d 11591 const char * dtype;
e699b9ff 11592
f7a99963
NC
11593 putchar (' ');
11594 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11595 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11596 printf (" (%s)%*s", dtype,
32ec8896 11597 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11598 }
252b5132
RH
11599
11600 switch (entry->d_tag)
11601 {
d1133906
NC
11602 case DT_FLAGS:
11603 if (do_dynamic)
e9e44622 11604 print_dynamic_flags (entry->d_un.d_val);
d1133906 11605 break;
76da6bbe 11606
252b5132
RH
11607 case DT_AUXILIARY:
11608 case DT_FILTER:
019148e4
L
11609 case DT_CONFIG:
11610 case DT_DEPAUDIT:
11611 case DT_AUDIT:
252b5132
RH
11612 if (do_dynamic)
11613 {
019148e4 11614 switch (entry->d_tag)
b34976b6 11615 {
019148e4
L
11616 case DT_AUXILIARY:
11617 printf (_("Auxiliary library"));
11618 break;
11619
11620 case DT_FILTER:
11621 printf (_("Filter library"));
11622 break;
11623
b34976b6 11624 case DT_CONFIG:
019148e4
L
11625 printf (_("Configuration file"));
11626 break;
11627
11628 case DT_DEPAUDIT:
11629 printf (_("Dependency audit library"));
11630 break;
11631
11632 case DT_AUDIT:
11633 printf (_("Audit library"));
11634 break;
11635 }
252b5132 11636
84714f86 11637 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11638 printf (": [%s]\n",
84714f86 11639 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11640 else
f7a99963
NC
11641 {
11642 printf (": ");
11643 print_vma (entry->d_un.d_val, PREFIX_HEX);
11644 putchar ('\n');
11645 }
252b5132
RH
11646 }
11647 break;
11648
dcefbbbd 11649 case DT_FEATURE:
252b5132
RH
11650 if (do_dynamic)
11651 {
11652 printf (_("Flags:"));
86f55779 11653
252b5132
RH
11654 if (entry->d_un.d_val == 0)
11655 printf (_(" None\n"));
11656 else
11657 {
26c527e6 11658 uint64_t val = entry->d_un.d_val;
86f55779 11659
252b5132
RH
11660 if (val & DTF_1_PARINIT)
11661 {
11662 printf (" PARINIT");
11663 val ^= DTF_1_PARINIT;
11664 }
dcefbbbd
L
11665 if (val & DTF_1_CONFEXP)
11666 {
11667 printf (" CONFEXP");
11668 val ^= DTF_1_CONFEXP;
11669 }
252b5132 11670 if (val != 0)
26c527e6 11671 printf (" %" PRIx64, val);
252b5132
RH
11672 puts ("");
11673 }
11674 }
11675 break;
11676
11677 case DT_POSFLAG_1:
11678 if (do_dynamic)
11679 {
11680 printf (_("Flags:"));
86f55779 11681
252b5132
RH
11682 if (entry->d_un.d_val == 0)
11683 printf (_(" None\n"));
11684 else
11685 {
26c527e6 11686 uint64_t val = entry->d_un.d_val;
86f55779 11687
252b5132
RH
11688 if (val & DF_P1_LAZYLOAD)
11689 {
11690 printf (" LAZYLOAD");
11691 val ^= DF_P1_LAZYLOAD;
11692 }
11693 if (val & DF_P1_GROUPPERM)
11694 {
11695 printf (" GROUPPERM");
11696 val ^= DF_P1_GROUPPERM;
11697 }
11698 if (val != 0)
26c527e6 11699 printf (" %" PRIx64, val);
252b5132
RH
11700 puts ("");
11701 }
11702 }
11703 break;
11704
11705 case DT_FLAGS_1:
11706 if (do_dynamic)
11707 {
11708 printf (_("Flags:"));
11709 if (entry->d_un.d_val == 0)
11710 printf (_(" None\n"));
11711 else
11712 {
26c527e6 11713 uint64_t val = entry->d_un.d_val;
86f55779 11714
252b5132
RH
11715 if (val & DF_1_NOW)
11716 {
11717 printf (" NOW");
11718 val ^= DF_1_NOW;
11719 }
11720 if (val & DF_1_GLOBAL)
11721 {
11722 printf (" GLOBAL");
11723 val ^= DF_1_GLOBAL;
11724 }
11725 if (val & DF_1_GROUP)
11726 {
11727 printf (" GROUP");
11728 val ^= DF_1_GROUP;
11729 }
11730 if (val & DF_1_NODELETE)
11731 {
11732 printf (" NODELETE");
11733 val ^= DF_1_NODELETE;
11734 }
11735 if (val & DF_1_LOADFLTR)
11736 {
11737 printf (" LOADFLTR");
11738 val ^= DF_1_LOADFLTR;
11739 }
11740 if (val & DF_1_INITFIRST)
11741 {
11742 printf (" INITFIRST");
11743 val ^= DF_1_INITFIRST;
11744 }
11745 if (val & DF_1_NOOPEN)
11746 {
11747 printf (" NOOPEN");
11748 val ^= DF_1_NOOPEN;
11749 }
11750 if (val & DF_1_ORIGIN)
11751 {
11752 printf (" ORIGIN");
11753 val ^= DF_1_ORIGIN;
11754 }
11755 if (val & DF_1_DIRECT)
11756 {
11757 printf (" DIRECT");
11758 val ^= DF_1_DIRECT;
11759 }
11760 if (val & DF_1_TRANS)
11761 {
11762 printf (" TRANS");
11763 val ^= DF_1_TRANS;
11764 }
11765 if (val & DF_1_INTERPOSE)
11766 {
11767 printf (" INTERPOSE");
11768 val ^= DF_1_INTERPOSE;
11769 }
f7db6139 11770 if (val & DF_1_NODEFLIB)
dcefbbbd 11771 {
f7db6139
L
11772 printf (" NODEFLIB");
11773 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11774 }
11775 if (val & DF_1_NODUMP)
11776 {
11777 printf (" NODUMP");
11778 val ^= DF_1_NODUMP;
11779 }
34b60028 11780 if (val & DF_1_CONFALT)
dcefbbbd 11781 {
34b60028
L
11782 printf (" CONFALT");
11783 val ^= DF_1_CONFALT;
11784 }
11785 if (val & DF_1_ENDFILTEE)
11786 {
11787 printf (" ENDFILTEE");
11788 val ^= DF_1_ENDFILTEE;
11789 }
11790 if (val & DF_1_DISPRELDNE)
11791 {
11792 printf (" DISPRELDNE");
11793 val ^= DF_1_DISPRELDNE;
11794 }
11795 if (val & DF_1_DISPRELPND)
11796 {
11797 printf (" DISPRELPND");
11798 val ^= DF_1_DISPRELPND;
11799 }
11800 if (val & DF_1_NODIRECT)
11801 {
11802 printf (" NODIRECT");
11803 val ^= DF_1_NODIRECT;
11804 }
11805 if (val & DF_1_IGNMULDEF)
11806 {
11807 printf (" IGNMULDEF");
11808 val ^= DF_1_IGNMULDEF;
11809 }
11810 if (val & DF_1_NOKSYMS)
11811 {
11812 printf (" NOKSYMS");
11813 val ^= DF_1_NOKSYMS;
11814 }
11815 if (val & DF_1_NOHDR)
11816 {
11817 printf (" NOHDR");
11818 val ^= DF_1_NOHDR;
11819 }
11820 if (val & DF_1_EDITED)
11821 {
11822 printf (" EDITED");
11823 val ^= DF_1_EDITED;
11824 }
11825 if (val & DF_1_NORELOC)
11826 {
11827 printf (" NORELOC");
11828 val ^= DF_1_NORELOC;
11829 }
11830 if (val & DF_1_SYMINTPOSE)
11831 {
11832 printf (" SYMINTPOSE");
11833 val ^= DF_1_SYMINTPOSE;
11834 }
11835 if (val & DF_1_GLOBAUDIT)
11836 {
11837 printf (" GLOBAUDIT");
11838 val ^= DF_1_GLOBAUDIT;
11839 }
11840 if (val & DF_1_SINGLETON)
11841 {
11842 printf (" SINGLETON");
11843 val ^= DF_1_SINGLETON;
dcefbbbd 11844 }
5c383f02
RO
11845 if (val & DF_1_STUB)
11846 {
11847 printf (" STUB");
11848 val ^= DF_1_STUB;
11849 }
11850 if (val & DF_1_PIE)
11851 {
11852 printf (" PIE");
11853 val ^= DF_1_PIE;
11854 }
b1202ffa
L
11855 if (val & DF_1_KMOD)
11856 {
11857 printf (" KMOD");
11858 val ^= DF_1_KMOD;
11859 }
11860 if (val & DF_1_WEAKFILTER)
11861 {
11862 printf (" WEAKFILTER");
11863 val ^= DF_1_WEAKFILTER;
11864 }
11865 if (val & DF_1_NOCOMMON)
11866 {
11867 printf (" NOCOMMON");
11868 val ^= DF_1_NOCOMMON;
11869 }
252b5132 11870 if (val != 0)
26c527e6 11871 printf (" %" PRIx64, val);
252b5132
RH
11872 puts ("");
11873 }
11874 }
11875 break;
11876
11877 case DT_PLTREL:
978c4450 11878 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11879 if (do_dynamic)
dda8d76d 11880 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11881 break;
11882
11883 case DT_NULL :
11884 case DT_NEEDED :
11885 case DT_PLTGOT :
11886 case DT_HASH :
11887 case DT_STRTAB :
11888 case DT_SYMTAB :
11889 case DT_RELA :
11890 case DT_INIT :
11891 case DT_FINI :
11892 case DT_SONAME :
11893 case DT_RPATH :
11894 case DT_SYMBOLIC:
11895 case DT_REL :
a7fd1186 11896 case DT_RELR :
252b5132
RH
11897 case DT_DEBUG :
11898 case DT_TEXTREL :
11899 case DT_JMPREL :
019148e4 11900 case DT_RUNPATH :
978c4450 11901 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11902
11903 if (do_dynamic)
11904 {
84714f86 11905 const char *name;
252b5132 11906
84714f86
AM
11907 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11908 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11909 else
d79b3d50 11910 name = NULL;
252b5132
RH
11911
11912 if (name)
11913 {
11914 switch (entry->d_tag)
11915 {
11916 case DT_NEEDED:
11917 printf (_("Shared library: [%s]"), name);
11918
13acb58d
AM
11919 if (filedata->program_interpreter
11920 && streq (name, filedata->program_interpreter))
f7a99963 11921 printf (_(" program interpreter"));
252b5132
RH
11922 break;
11923
11924 case DT_SONAME:
f7a99963 11925 printf (_("Library soname: [%s]"), name);
252b5132
RH
11926 break;
11927
11928 case DT_RPATH:
f7a99963 11929 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11930 break;
11931
019148e4
L
11932 case DT_RUNPATH:
11933 printf (_("Library runpath: [%s]"), name);
11934 break;
11935
252b5132 11936 default:
f7a99963
NC
11937 print_vma (entry->d_un.d_val, PREFIX_HEX);
11938 break;
252b5132
RH
11939 }
11940 }
11941 else
f7a99963
NC
11942 print_vma (entry->d_un.d_val, PREFIX_HEX);
11943
11944 putchar ('\n');
252b5132
RH
11945 }
11946 break;
11947
11948 case DT_PLTRELSZ:
11949 case DT_RELASZ :
11950 case DT_STRSZ :
11951 case DT_RELSZ :
11952 case DT_RELAENT :
a7fd1186
FS
11953 case DT_RELRENT :
11954 case DT_RELRSZ :
252b5132
RH
11955 case DT_SYMENT :
11956 case DT_RELENT :
978c4450 11957 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11958 /* Fall through. */
252b5132
RH
11959 case DT_PLTPADSZ:
11960 case DT_MOVEENT :
11961 case DT_MOVESZ :
04d8355a 11962 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11963 case DT_INIT_ARRAYSZ:
11964 case DT_FINI_ARRAYSZ:
047b2264
JJ
11965 case DT_GNU_CONFLICTSZ:
11966 case DT_GNU_LIBLISTSZ:
252b5132 11967 if (do_dynamic)
f7a99963
NC
11968 {
11969 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11970 printf (_(" (bytes)\n"));
f7a99963 11971 }
252b5132
RH
11972 break;
11973
11974 case DT_VERDEFNUM:
11975 case DT_VERNEEDNUM:
11976 case DT_RELACOUNT:
11977 case DT_RELCOUNT:
11978 if (do_dynamic)
f7a99963
NC
11979 {
11980 print_vma (entry->d_un.d_val, UNSIGNED);
11981 putchar ('\n');
11982 }
252b5132
RH
11983 break;
11984
11985 case DT_SYMINSZ:
11986 case DT_SYMINENT:
11987 case DT_SYMINFO:
11988 case DT_USED:
11989 case DT_INIT_ARRAY:
11990 case DT_FINI_ARRAY:
11991 if (do_dynamic)
11992 {
d79b3d50 11993 if (entry->d_tag == DT_USED
84714f86 11994 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11995 {
84714f86
AM
11996 const char *name
11997 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11998
b34976b6 11999 if (*name)
252b5132
RH
12000 {
12001 printf (_("Not needed object: [%s]\n"), name);
12002 break;
12003 }
12004 }
103f02d3 12005
f7a99963
NC
12006 print_vma (entry->d_un.d_val, PREFIX_HEX);
12007 putchar ('\n');
252b5132
RH
12008 }
12009 break;
12010
12011 case DT_BIND_NOW:
12012 /* The value of this entry is ignored. */
35b1837e
AM
12013 if (do_dynamic)
12014 putchar ('\n');
252b5132 12015 break;
103f02d3 12016
047b2264
JJ
12017 case DT_GNU_PRELINKED:
12018 if (do_dynamic)
12019 {
2cf0635d 12020 struct tm * tmp;
91d6fa6a 12021 time_t atime = entry->d_un.d_val;
047b2264 12022
91d6fa6a 12023 tmp = gmtime (&atime);
071436c6
NC
12024 /* PR 17533 file: 041-1244816-0.004. */
12025 if (tmp == NULL)
26c527e6
AM
12026 printf (_("<corrupt time val: %" PRIx64),
12027 (uint64_t) atime);
071436c6
NC
12028 else
12029 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12030 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12031 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12032
12033 }
12034 break;
12035
fdc90cb4 12036 case DT_GNU_HASH:
978c4450 12037 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
12038 if (do_dynamic)
12039 {
12040 print_vma (entry->d_un.d_val, PREFIX_HEX);
12041 putchar ('\n');
12042 }
12043 break;
12044
a5da3dee
VDM
12045 case DT_GNU_FLAGS_1:
12046 if (do_dynamic)
12047 {
12048 printf (_("Flags:"));
12049 if (entry->d_un.d_val == 0)
12050 printf (_(" None\n"));
12051 else
12052 {
26c527e6 12053 uint64_t val = entry->d_un.d_val;
a5da3dee
VDM
12054
12055 if (val & DF_GNU_1_UNIQUE)
12056 {
12057 printf (" UNIQUE");
12058 val ^= DF_GNU_1_UNIQUE;
12059 }
12060 if (val != 0)
26c527e6 12061 printf (" %" PRIx64, val);
a5da3dee
VDM
12062 puts ("");
12063 }
12064 }
12065 break;
12066
252b5132
RH
12067 default:
12068 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
12069 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12070 = entry->d_un.d_val;
252b5132
RH
12071
12072 if (do_dynamic)
12073 {
dda8d76d 12074 switch (filedata->file_header.e_machine)
252b5132 12075 {
37c18eed
SD
12076 case EM_AARCH64:
12077 dynamic_section_aarch64_val (entry);
12078 break;
252b5132 12079 case EM_MIPS:
4fe85591 12080 case EM_MIPS_RS3_LE:
978c4450 12081 dynamic_section_mips_val (filedata, entry);
252b5132 12082 break;
103f02d3 12083 case EM_PARISC:
b2d38a17 12084 dynamic_section_parisc_val (entry);
103f02d3 12085 break;
ecc51f48 12086 case EM_IA_64:
b2d38a17 12087 dynamic_section_ia64_val (entry);
ecc51f48 12088 break;
252b5132 12089 default:
f7a99963
NC
12090 print_vma (entry->d_un.d_val, PREFIX_HEX);
12091 putchar ('\n');
252b5132
RH
12092 }
12093 }
12094 break;
12095 }
12096 }
12097
015dc7e1 12098 return true;
252b5132
RH
12099}
12100
12101static char *
d3ba0551 12102get_ver_flags (unsigned int flags)
252b5132 12103{
6d4f21f6 12104 static char buff[128];
252b5132
RH
12105
12106 buff[0] = 0;
12107
12108 if (flags == 0)
12109 return _("none");
12110
12111 if (flags & VER_FLG_BASE)
7bb1ad17 12112 strcat (buff, "BASE");
252b5132
RH
12113
12114 if (flags & VER_FLG_WEAK)
12115 {
12116 if (flags & VER_FLG_BASE)
7bb1ad17 12117 strcat (buff, " | ");
252b5132 12118
7bb1ad17 12119 strcat (buff, "WEAK");
252b5132
RH
12120 }
12121
44ec90b9
RO
12122 if (flags & VER_FLG_INFO)
12123 {
12124 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12125 strcat (buff, " | ");
44ec90b9 12126
7bb1ad17 12127 strcat (buff, "INFO");
44ec90b9
RO
12128 }
12129
12130 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12131 {
12132 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12133 strcat (buff, " | ");
12134
12135 strcat (buff, _("<unknown>"));
12136 }
252b5132
RH
12137
12138 return buff;
12139}
12140
12141/* Display the contents of the version sections. */
98fb390a 12142
015dc7e1 12143static bool
dda8d76d 12144process_version_sections (Filedata * filedata)
252b5132 12145{
2cf0635d 12146 Elf_Internal_Shdr * section;
b34976b6 12147 unsigned i;
015dc7e1 12148 bool found = false;
252b5132
RH
12149
12150 if (! do_version)
015dc7e1 12151 return true;
252b5132 12152
dda8d76d
NC
12153 for (i = 0, section = filedata->section_headers;
12154 i < filedata->file_header.e_shnum;
b34976b6 12155 i++, section++)
252b5132
RH
12156 {
12157 switch (section->sh_type)
12158 {
12159 case SHT_GNU_verdef:
12160 {
2cf0635d 12161 Elf_External_Verdef * edefs;
26c527e6
AM
12162 size_t idx;
12163 size_t cnt;
2cf0635d 12164 char * endbuf;
252b5132 12165
015dc7e1 12166 found = true;
252b5132 12167
ca0e11aa
NC
12168 if (filedata->is_separate)
12169 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12170 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12171 section->sh_info),
12172 filedata->file_name,
12173 printable_section_name (filedata, section),
12174 section->sh_info);
12175 else
12176 printf (ngettext ("\nVersion definition section '%s' "
12177 "contains %u entry:\n",
12178 "\nVersion definition section '%s' "
12179 "contains %u entries:\n",
12180 section->sh_info),
12181 printable_section_name (filedata, section),
12182 section->sh_info);
047c3dbf 12183
625d49fc 12184 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12185 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12186 section->sh_offset, section->sh_link,
dda8d76d 12187 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12188
3f5e193b 12189 edefs = (Elf_External_Verdef *)
dda8d76d 12190 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12191 _("version definition section"));
a6e9f9df
AM
12192 if (!edefs)
12193 break;
59245841 12194 endbuf = (char *) edefs + section->sh_size;
252b5132 12195
1445030f 12196 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12197 {
2cf0635d
NC
12198 char * vstart;
12199 Elf_External_Verdef * edef;
b34976b6 12200 Elf_Internal_Verdef ent;
2cf0635d 12201 Elf_External_Verdaux * eaux;
b34976b6 12202 Elf_Internal_Verdaux aux;
26c527e6 12203 size_t isum;
b34976b6 12204 int j;
103f02d3 12205
252b5132 12206 vstart = ((char *) edefs) + idx;
54806181
AM
12207 if (vstart + sizeof (*edef) > endbuf)
12208 break;
252b5132
RH
12209
12210 edef = (Elf_External_Verdef *) vstart;
12211
12212 ent.vd_version = BYTE_GET (edef->vd_version);
12213 ent.vd_flags = BYTE_GET (edef->vd_flags);
12214 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12215 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12216 ent.vd_hash = BYTE_GET (edef->vd_hash);
12217 ent.vd_aux = BYTE_GET (edef->vd_aux);
12218 ent.vd_next = BYTE_GET (edef->vd_next);
12219
26c527e6 12220 printf (_(" %#06zx: Rev: %d Flags: %s"),
252b5132
RH
12221 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12222
12223 printf (_(" Index: %d Cnt: %d "),
12224 ent.vd_ndx, ent.vd_cnt);
12225
452bf675 12226 /* Check for overflow. */
1445030f 12227 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12228 break;
12229
252b5132
RH
12230 vstart += ent.vd_aux;
12231
1445030f
AM
12232 if (vstart + sizeof (*eaux) > endbuf)
12233 break;
252b5132
RH
12234 eaux = (Elf_External_Verdaux *) vstart;
12235
12236 aux.vda_name = BYTE_GET (eaux->vda_name);
12237 aux.vda_next = BYTE_GET (eaux->vda_next);
12238
84714f86 12239 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12240 printf (_("Name: %s\n"),
84714f86 12241 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12242 else
12243 printf (_("Name index: %ld\n"), aux.vda_name);
12244
12245 isum = idx + ent.vd_aux;
12246
b34976b6 12247 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12248 {
1445030f
AM
12249 if (aux.vda_next < sizeof (*eaux)
12250 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12251 {
12252 warn (_("Invalid vda_next field of %lx\n"),
12253 aux.vda_next);
12254 j = ent.vd_cnt;
12255 break;
12256 }
dd24e3da 12257 /* Check for overflow. */
7e26601c 12258 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12259 break;
12260
252b5132
RH
12261 isum += aux.vda_next;
12262 vstart += aux.vda_next;
12263
54806181
AM
12264 if (vstart + sizeof (*eaux) > endbuf)
12265 break;
1445030f 12266 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12267
12268 aux.vda_name = BYTE_GET (eaux->vda_name);
12269 aux.vda_next = BYTE_GET (eaux->vda_next);
12270
84714f86 12271 if (valid_dynamic_name (filedata, aux.vda_name))
26c527e6 12272 printf (_(" %#06zx: Parent %d: %s\n"),
978c4450 12273 isum, j,
84714f86 12274 get_dynamic_name (filedata, aux.vda_name));
252b5132 12275 else
26c527e6 12276 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
252b5132
RH
12277 isum, j, aux.vda_name);
12278 }
dd24e3da 12279
54806181
AM
12280 if (j < ent.vd_cnt)
12281 printf (_(" Version def aux past end of section\n"));
252b5132 12282
c9f02c3e
MR
12283 /* PR 17531:
12284 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12285 if (ent.vd_next < sizeof (*edef)
12286 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12287 {
12288 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12289 cnt = section->sh_info;
12290 break;
12291 }
452bf675 12292 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12293 break;
12294
252b5132
RH
12295 idx += ent.vd_next;
12296 }
dd24e3da 12297
54806181
AM
12298 if (cnt < section->sh_info)
12299 printf (_(" Version definition past end of section\n"));
252b5132
RH
12300
12301 free (edefs);
12302 }
12303 break;
103f02d3 12304
252b5132
RH
12305 case SHT_GNU_verneed:
12306 {
2cf0635d 12307 Elf_External_Verneed * eneed;
26c527e6
AM
12308 size_t idx;
12309 size_t cnt;
2cf0635d 12310 char * endbuf;
252b5132 12311
015dc7e1 12312 found = true;
252b5132 12313
ca0e11aa
NC
12314 if (filedata->is_separate)
12315 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12316 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12317 section->sh_info),
12318 filedata->file_name,
12319 printable_section_name (filedata, section),
12320 section->sh_info);
12321 else
12322 printf (ngettext ("\nVersion needs section '%s' "
12323 "contains %u entry:\n",
12324 "\nVersion needs section '%s' "
12325 "contains %u entries:\n",
12326 section->sh_info),
12327 printable_section_name (filedata, section),
12328 section->sh_info);
047c3dbf 12329
625d49fc 12330 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12331 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12332 section->sh_offset, section->sh_link,
dda8d76d 12333 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12334
dda8d76d 12335 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12336 section->sh_offset, 1,
12337 section->sh_size,
9cf03b7e 12338 _("Version Needs section"));
a6e9f9df
AM
12339 if (!eneed)
12340 break;
59245841 12341 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12342
12343 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12344 {
2cf0635d 12345 Elf_External_Verneed * entry;
b34976b6 12346 Elf_Internal_Verneed ent;
26c527e6 12347 size_t isum;
b34976b6 12348 int j;
2cf0635d 12349 char * vstart;
252b5132
RH
12350
12351 vstart = ((char *) eneed) + idx;
54806181
AM
12352 if (vstart + sizeof (*entry) > endbuf)
12353 break;
252b5132
RH
12354
12355 entry = (Elf_External_Verneed *) vstart;
12356
12357 ent.vn_version = BYTE_GET (entry->vn_version);
12358 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12359 ent.vn_file = BYTE_GET (entry->vn_file);
12360 ent.vn_aux = BYTE_GET (entry->vn_aux);
12361 ent.vn_next = BYTE_GET (entry->vn_next);
12362
26c527e6 12363 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
252b5132 12364
84714f86 12365 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12366 printf (_(" File: %s"),
84714f86 12367 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12368 else
12369 printf (_(" File: %lx"), ent.vn_file);
12370
12371 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12372
dd24e3da 12373 /* Check for overflow. */
7e26601c 12374 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12375 break;
252b5132
RH
12376 vstart += ent.vn_aux;
12377
12378 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12379 {
2cf0635d 12380 Elf_External_Vernaux * eaux;
b34976b6 12381 Elf_Internal_Vernaux aux;
252b5132 12382
54806181
AM
12383 if (vstart + sizeof (*eaux) > endbuf)
12384 break;
252b5132
RH
12385 eaux = (Elf_External_Vernaux *) vstart;
12386
12387 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12388 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12389 aux.vna_other = BYTE_GET (eaux->vna_other);
12390 aux.vna_name = BYTE_GET (eaux->vna_name);
12391 aux.vna_next = BYTE_GET (eaux->vna_next);
12392
84714f86 12393 if (valid_dynamic_name (filedata, aux.vna_name))
26c527e6 12394 printf (_(" %#06zx: Name: %s"),
84714f86 12395 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12396 else
26c527e6 12397 printf (_(" %#06zx: Name index: %lx"),
252b5132
RH
12398 isum, aux.vna_name);
12399
12400 printf (_(" Flags: %s Version: %d\n"),
12401 get_ver_flags (aux.vna_flags), aux.vna_other);
12402
1445030f
AM
12403 if (aux.vna_next < sizeof (*eaux)
12404 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12405 {
12406 warn (_("Invalid vna_next field of %lx\n"),
12407 aux.vna_next);
12408 j = ent.vn_cnt;
12409 break;
12410 }
1445030f
AM
12411 /* Check for overflow. */
12412 if (aux.vna_next > (size_t) (endbuf - vstart))
12413 break;
252b5132
RH
12414 isum += aux.vna_next;
12415 vstart += aux.vna_next;
12416 }
9cf03b7e 12417
54806181 12418 if (j < ent.vn_cnt)
f9a6a8f0 12419 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12420
1445030f
AM
12421 if (ent.vn_next < sizeof (*entry)
12422 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12423 {
452bf675 12424 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12425 cnt = section->sh_info;
12426 break;
12427 }
1445030f
AM
12428 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12429 break;
252b5132
RH
12430 idx += ent.vn_next;
12431 }
9cf03b7e 12432
54806181 12433 if (cnt < section->sh_info)
9cf03b7e 12434 warn (_("Missing Version Needs information\n"));
103f02d3 12435
252b5132
RH
12436 free (eneed);
12437 }
12438 break;
12439
12440 case SHT_GNU_versym:
12441 {
2cf0635d 12442 Elf_Internal_Shdr * link_section;
26c527e6 12443 uint64_t total;
8b73c356 12444 unsigned int cnt;
2cf0635d
NC
12445 unsigned char * edata;
12446 unsigned short * data;
12447 char * strtab;
12448 Elf_Internal_Sym * symbols;
12449 Elf_Internal_Shdr * string_sec;
26c527e6
AM
12450 uint64_t num_syms;
12451 uint64_t off;
252b5132 12452
dda8d76d 12453 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12454 break;
12455
dda8d76d 12456 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12457 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12458
dda8d76d 12459 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12460 break;
12461
015dc7e1 12462 found = true;
252b5132 12463
4de91c10 12464 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12465 if (symbols == NULL)
12466 break;
252b5132 12467
dda8d76d 12468 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12469
dda8d76d 12470 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12471 string_sec->sh_size,
12472 _("version string table"));
a6e9f9df 12473 if (!strtab)
0429c154
MS
12474 {
12475 free (symbols);
12476 break;
12477 }
252b5132 12478
ca0e11aa 12479 if (filedata->is_separate)
26c527e6
AM
12480 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
12481 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12482 total),
12483 filedata->file_name,
12484 printable_section_name (filedata, section),
26c527e6 12485 total);
ca0e11aa
NC
12486 else
12487 printf (ngettext ("\nVersion symbols section '%s' "
26c527e6 12488 "contains %" PRIu64 " entry:\n",
ca0e11aa 12489 "\nVersion symbols section '%s' "
26c527e6 12490 "contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12491 total),
12492 printable_section_name (filedata, section),
26c527e6 12493 total);
252b5132 12494
625d49fc 12495 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12496 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12497 section->sh_offset, section->sh_link,
dda8d76d 12498 printable_section_name (filedata, link_section));
252b5132 12499
dda8d76d 12500 off = offset_from_vma (filedata,
978c4450 12501 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12502 total * sizeof (short));
95099889
AM
12503 edata = (unsigned char *) get_data (NULL, filedata, off,
12504 sizeof (short), total,
12505 _("version symbol data"));
a6e9f9df
AM
12506 if (!edata)
12507 {
12508 free (strtab);
0429c154 12509 free (symbols);
a6e9f9df
AM
12510 break;
12511 }
252b5132 12512
3f5e193b 12513 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12514
12515 for (cnt = total; cnt --;)
b34976b6
AM
12516 data[cnt] = byte_get (edata + cnt * sizeof (short),
12517 sizeof (short));
252b5132
RH
12518
12519 free (edata);
12520
12521 for (cnt = 0; cnt < total; cnt += 4)
12522 {
12523 int j, nn;
ab273396
AM
12524 char *name;
12525 char *invalid = _("*invalid*");
252b5132
RH
12526
12527 printf (" %03x:", cnt);
12528
12529 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12530 switch (data[cnt + j])
252b5132
RH
12531 {
12532 case 0:
12533 fputs (_(" 0 (*local*) "), stdout);
12534 break;
12535
12536 case 1:
12537 fputs (_(" 1 (*global*) "), stdout);
12538 break;
12539
12540 default:
c244d050
NC
12541 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12542 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12543
dd24e3da 12544 /* If this index value is greater than the size of the symbols
ba5cdace 12545 array, break to avoid an out-of-bounds read. */
26c527e6 12546 if (cnt + j >= num_syms)
dd24e3da
NC
12547 {
12548 warn (_("invalid index into symbol array\n"));
12549 break;
12550 }
12551
ab273396 12552 name = NULL;
978c4450 12553 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12554 {
b34976b6 12555 Elf_Internal_Verneed ivn;
26c527e6 12556 uint64_t offset;
252b5132 12557
d93f0186 12558 offset = offset_from_vma
978c4450
AM
12559 (filedata,
12560 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12561 sizeof (Elf_External_Verneed));
252b5132 12562
b34976b6 12563 do
252b5132 12564 {
b34976b6
AM
12565 Elf_Internal_Vernaux ivna;
12566 Elf_External_Verneed evn;
12567 Elf_External_Vernaux evna;
26c527e6 12568 uint64_t a_off;
252b5132 12569
dda8d76d 12570 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12571 _("version need")) == NULL)
12572 break;
0b4362b0 12573
252b5132
RH
12574 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12575 ivn.vn_next = BYTE_GET (evn.vn_next);
12576
12577 a_off = offset + ivn.vn_aux;
12578
12579 do
12580 {
dda8d76d 12581 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12582 1, _("version need aux (2)")) == NULL)
12583 {
12584 ivna.vna_next = 0;
12585 ivna.vna_other = 0;
12586 }
12587 else
12588 {
12589 ivna.vna_next = BYTE_GET (evna.vna_next);
12590 ivna.vna_other = BYTE_GET (evna.vna_other);
12591 }
252b5132
RH
12592
12593 a_off += ivna.vna_next;
12594 }
b34976b6 12595 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12596 && ivna.vna_next != 0);
12597
b34976b6 12598 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12599 {
12600 ivna.vna_name = BYTE_GET (evna.vna_name);
12601
54806181 12602 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12603 name = invalid;
54806181
AM
12604 else
12605 name = strtab + ivna.vna_name;
252b5132
RH
12606 break;
12607 }
12608
12609 offset += ivn.vn_next;
12610 }
12611 while (ivn.vn_next);
12612 }
00d93f34 12613
ab273396 12614 if (data[cnt + j] != 0x8001
978c4450 12615 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12616 {
b34976b6
AM
12617 Elf_Internal_Verdef ivd;
12618 Elf_External_Verdef evd;
26c527e6 12619 uint64_t offset;
252b5132 12620
d93f0186 12621 offset = offset_from_vma
978c4450
AM
12622 (filedata,
12623 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12624 sizeof evd);
252b5132
RH
12625
12626 do
12627 {
dda8d76d 12628 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12629 _("version def")) == NULL)
12630 {
12631 ivd.vd_next = 0;
948f632f 12632 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12633 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12634 break;
59245841
NC
12635 }
12636 else
12637 {
12638 ivd.vd_next = BYTE_GET (evd.vd_next);
12639 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12640 }
252b5132
RH
12641
12642 offset += ivd.vd_next;
12643 }
c244d050 12644 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12645 && ivd.vd_next != 0);
12646
c244d050 12647 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12648 {
b34976b6
AM
12649 Elf_External_Verdaux evda;
12650 Elf_Internal_Verdaux ivda;
252b5132
RH
12651
12652 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12653
dda8d76d 12654 if (get_data (&evda, filedata,
59245841
NC
12655 offset - ivd.vd_next + ivd.vd_aux,
12656 sizeof (evda), 1,
12657 _("version def aux")) == NULL)
12658 break;
252b5132
RH
12659
12660 ivda.vda_name = BYTE_GET (evda.vda_name);
12661
54806181 12662 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12663 name = invalid;
12664 else if (name != NULL && name != invalid)
12665 name = _("*both*");
54806181
AM
12666 else
12667 name = strtab + ivda.vda_name;
252b5132
RH
12668 }
12669 }
ab273396
AM
12670 if (name != NULL)
12671 nn += printf ("(%s%-*s",
12672 name,
12673 12 - (int) strlen (name),
12674 ")");
252b5132
RH
12675
12676 if (nn < 18)
12677 printf ("%*c", 18 - nn, ' ');
12678 }
12679
12680 putchar ('\n');
12681 }
12682
12683 free (data);
12684 free (strtab);
12685 free (symbols);
12686 }
12687 break;
103f02d3 12688
252b5132
RH
12689 default:
12690 break;
12691 }
12692 }
12693
12694 if (! found)
ca0e11aa
NC
12695 {
12696 if (filedata->is_separate)
12697 printf (_("\nNo version information found in linked file '%s'.\n"),
12698 filedata->file_name);
12699 else
12700 printf (_("\nNo version information found in this file.\n"));
12701 }
252b5132 12702
015dc7e1 12703 return true;
252b5132
RH
12704}
12705
d1133906 12706static const char *
dda8d76d 12707get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12708{
89246a0e 12709 static char buff[64];
252b5132
RH
12710
12711 switch (binding)
12712 {
b34976b6
AM
12713 case STB_LOCAL: return "LOCAL";
12714 case STB_GLOBAL: return "GLOBAL";
12715 case STB_WEAK: return "WEAK";
252b5132
RH
12716 default:
12717 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12718 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12719 binding);
252b5132 12720 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12721 {
12722 if (binding == STB_GNU_UNIQUE
df3a023b 12723 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12724 return "UNIQUE";
12725 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12726 }
252b5132 12727 else
e9e44622 12728 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12729 return buff;
12730 }
12731}
12732
d1133906 12733static const char *
dda8d76d 12734get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12735{
89246a0e 12736 static char buff[64];
252b5132
RH
12737
12738 switch (type)
12739 {
b34976b6
AM
12740 case STT_NOTYPE: return "NOTYPE";
12741 case STT_OBJECT: return "OBJECT";
12742 case STT_FUNC: return "FUNC";
12743 case STT_SECTION: return "SECTION";
12744 case STT_FILE: return "FILE";
12745 case STT_COMMON: return "COMMON";
12746 case STT_TLS: return "TLS";
15ab5209
DB
12747 case STT_RELC: return "RELC";
12748 case STT_SRELC: return "SRELC";
252b5132
RH
12749 default:
12750 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12751 {
dda8d76d 12752 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12753 return "THUMB_FUNC";
103f02d3 12754
dda8d76d 12755 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12756 return "REGISTER";
12757
dda8d76d 12758 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12759 return "PARISC_MILLI";
12760
e9e44622 12761 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12762 }
252b5132 12763 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12764 {
dda8d76d 12765 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12766 {
12767 if (type == STT_HP_OPAQUE)
12768 return "HP_OPAQUE";
12769 if (type == STT_HP_STUB)
12770 return "HP_STUB";
12771 }
12772
8654c01f
ML
12773 if (type == STT_GNU_IFUNC
12774 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
12775 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
12776 return "IFUNC";
12777
e9e44622 12778 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12779 }
252b5132 12780 else
e9e44622 12781 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12782 return buff;
12783 }
12784}
12785
d1133906 12786static const char *
d3ba0551 12787get_symbol_visibility (unsigned int visibility)
d1133906
NC
12788{
12789 switch (visibility)
12790 {
b34976b6
AM
12791 case STV_DEFAULT: return "DEFAULT";
12792 case STV_INTERNAL: return "INTERNAL";
12793 case STV_HIDDEN: return "HIDDEN";
d1133906 12794 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12795 default:
27a45f42 12796 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12797 return _("<unknown>");
d1133906
NC
12798 }
12799}
12800
2057d69d
CZ
12801static const char *
12802get_alpha_symbol_other (unsigned int other)
9abca702 12803{
2057d69d
CZ
12804 switch (other)
12805 {
12806 case STO_ALPHA_NOPV: return "NOPV";
12807 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12808 default:
27a45f42 12809 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12810 return _("<unknown>");
9abca702 12811 }
2057d69d
CZ
12812}
12813
fd85a6a1
NC
12814static const char *
12815get_solaris_symbol_visibility (unsigned int visibility)
12816{
12817 switch (visibility)
12818 {
12819 case 4: return "EXPORTED";
12820 case 5: return "SINGLETON";
12821 case 6: return "ELIMINATE";
12822 default: return get_symbol_visibility (visibility);
12823 }
12824}
12825
2301ed1c
SN
12826static const char *
12827get_aarch64_symbol_other (unsigned int other)
12828{
12829 static char buf[32];
12830
12831 if (other & STO_AARCH64_VARIANT_PCS)
12832 {
12833 other &= ~STO_AARCH64_VARIANT_PCS;
12834 if (other == 0)
12835 return "VARIANT_PCS";
12836 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12837 return buf;
12838 }
12839 return NULL;
12840}
12841
5e2b0d47
NC
12842static const char *
12843get_mips_symbol_other (unsigned int other)
12844{
12845 switch (other)
12846 {
32ec8896
NC
12847 case STO_OPTIONAL: return "OPTIONAL";
12848 case STO_MIPS_PLT: return "MIPS PLT";
12849 case STO_MIPS_PIC: return "MIPS PIC";
12850 case STO_MICROMIPS: return "MICROMIPS";
12851 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12852 case STO_MIPS16: return "MIPS16";
12853 default: return NULL;
5e2b0d47
NC
12854 }
12855}
12856
28f997cf 12857static const char *
dda8d76d 12858get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12859{
dda8d76d 12860 if (is_ia64_vms (filedata))
28f997cf
TG
12861 {
12862 static char res[32];
12863
12864 res[0] = 0;
12865
12866 /* Function types is for images and .STB files only. */
dda8d76d 12867 switch (filedata->file_header.e_type)
28f997cf
TG
12868 {
12869 case ET_DYN:
12870 case ET_EXEC:
12871 switch (VMS_ST_FUNC_TYPE (other))
12872 {
12873 case VMS_SFT_CODE_ADDR:
12874 strcat (res, " CA");
12875 break;
12876 case VMS_SFT_SYMV_IDX:
12877 strcat (res, " VEC");
12878 break;
12879 case VMS_SFT_FD:
12880 strcat (res, " FD");
12881 break;
12882 case VMS_SFT_RESERVE:
12883 strcat (res, " RSV");
12884 break;
12885 default:
bee0ee85
NC
12886 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12887 VMS_ST_FUNC_TYPE (other));
12888 strcat (res, " <unknown>");
12889 break;
28f997cf
TG
12890 }
12891 break;
12892 default:
12893 break;
12894 }
12895 switch (VMS_ST_LINKAGE (other))
12896 {
12897 case VMS_STL_IGNORE:
12898 strcat (res, " IGN");
12899 break;
12900 case VMS_STL_RESERVE:
12901 strcat (res, " RSV");
12902 break;
12903 case VMS_STL_STD:
12904 strcat (res, " STD");
12905 break;
12906 case VMS_STL_LNK:
12907 strcat (res, " LNK");
12908 break;
12909 default:
bee0ee85
NC
12910 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12911 VMS_ST_LINKAGE (other));
12912 strcat (res, " <unknown>");
12913 break;
28f997cf
TG
12914 }
12915
12916 if (res[0] != 0)
12917 return res + 1;
12918 else
12919 return res;
12920 }
12921 return NULL;
12922}
12923
6911b7dc
AM
12924static const char *
12925get_ppc64_symbol_other (unsigned int other)
12926{
14732552
AM
12927 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12928 return NULL;
12929
12930 other >>= STO_PPC64_LOCAL_BIT;
12931 if (other <= 6)
6911b7dc 12932 {
89246a0e 12933 static char buf[64];
14732552
AM
12934 if (other >= 2)
12935 other = ppc64_decode_local_entry (other);
12936 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12937 return buf;
12938 }
12939 return NULL;
12940}
12941
8155b853
NC
12942static const char *
12943get_riscv_symbol_other (unsigned int other)
12944{
12945 static char buf[32];
12946 buf[0] = 0;
12947
12948 if (other & STO_RISCV_VARIANT_CC)
12949 {
12950 strcat (buf, _(" VARIANT_CC"));
12951 other &= ~STO_RISCV_VARIANT_CC;
12952 }
12953
12954 if (other != 0)
12955 snprintf (buf, sizeof buf, " %x", other);
12956
12957
12958 if (buf[0] != 0)
12959 return buf + 1;
12960 else
12961 return buf;
12962}
12963
5e2b0d47 12964static const char *
dda8d76d 12965get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12966{
12967 const char * result = NULL;
89246a0e 12968 static char buff [64];
5e2b0d47
NC
12969
12970 if (other == 0)
12971 return "";
12972
dda8d76d 12973 switch (filedata->file_header.e_machine)
5e2b0d47 12974 {
2057d69d
CZ
12975 case EM_ALPHA:
12976 result = get_alpha_symbol_other (other);
12977 break;
2301ed1c
SN
12978 case EM_AARCH64:
12979 result = get_aarch64_symbol_other (other);
12980 break;
5e2b0d47
NC
12981 case EM_MIPS:
12982 result = get_mips_symbol_other (other);
28f997cf
TG
12983 break;
12984 case EM_IA_64:
dda8d76d 12985 result = get_ia64_symbol_other (filedata, other);
28f997cf 12986 break;
6911b7dc
AM
12987 case EM_PPC64:
12988 result = get_ppc64_symbol_other (other);
12989 break;
8155b853
NC
12990 case EM_RISCV:
12991 result = get_riscv_symbol_other (other);
12992 break;
5e2b0d47 12993 default:
fd85a6a1 12994 result = NULL;
5e2b0d47
NC
12995 break;
12996 }
12997
12998 if (result)
12999 return result;
13000
13001 snprintf (buff, sizeof buff, _("<other>: %x"), other);
13002 return buff;
13003}
13004
d1133906 13005static const char *
dda8d76d 13006get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 13007{
b34976b6 13008 static char buff[32];
5cf1065c 13009
252b5132
RH
13010 switch (type)
13011 {
b34976b6
AM
13012 case SHN_UNDEF: return "UND";
13013 case SHN_ABS: return "ABS";
13014 case SHN_COMMON: return "COM";
252b5132 13015 default:
9ce701e2 13016 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
13017 && filedata->file_header.e_machine == EM_IA_64
13018 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
13019 return "ANSI_COM";
13020 else if ((filedata->file_header.e_machine == EM_X86_64
13021 || filedata->file_header.e_machine == EM_L1OM
13022 || filedata->file_header.e_machine == EM_K1OM)
13023 && type == SHN_X86_64_LCOMMON)
13024 return "LARGE_COM";
13025 else if ((type == SHN_MIPS_SCOMMON
13026 && filedata->file_header.e_machine == EM_MIPS)
13027 || (type == SHN_TIC6X_SCOMMON
13028 && filedata->file_header.e_machine == EM_TI_C6000))
13029 return "SCOM";
13030 else if (type == SHN_MIPS_SUNDEFINED
13031 && filedata->file_header.e_machine == EM_MIPS)
13032 return "SUND";
13033 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
13034 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
13035 else if (type >= SHN_LOOS && type <= SHN_HIOS)
13036 sprintf (buff, "OS [0x%04x]", type & 0xffff);
13037 else if (type >= SHN_LORESERVE)
13038 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
13039 else if (filedata->file_header.e_shnum != 0
13040 && type >= filedata->file_header.e_shnum)
13041 sprintf (buff, _("bad section index[%3d]"), type);
13042 else
13043 sprintf (buff, "%3d", type);
13044 break;
fd85a6a1
NC
13045 }
13046
10ca4b04 13047 return buff;
6bd1a22c
L
13048}
13049
bb4d2ac2 13050static const char *
26c527e6
AM
13051get_symbol_version_string (Filedata *filedata,
13052 bool is_dynsym,
13053 const char *strtab,
13054 size_t strtab_size,
13055 unsigned int si,
13056 Elf_Internal_Sym *psym,
13057 enum versioned_symbol_info *sym_info,
13058 unsigned short *vna_other)
bb4d2ac2 13059{
ab273396
AM
13060 unsigned char data[2];
13061 unsigned short vers_data;
26c527e6 13062 uint64_t offset;
7a815dd5 13063 unsigned short max_vd_ndx;
bb4d2ac2 13064
ab273396 13065 if (!is_dynsym
978c4450 13066 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 13067 return NULL;
bb4d2ac2 13068
978c4450
AM
13069 offset = offset_from_vma (filedata,
13070 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 13071 sizeof data + si * sizeof (vers_data));
bb4d2ac2 13072
dda8d76d 13073 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
13074 sizeof (data), 1, _("version data")) == NULL)
13075 return NULL;
13076
13077 vers_data = byte_get (data, 2);
bb4d2ac2 13078
1f6f5dba 13079 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 13080 return NULL;
bb4d2ac2 13081
0b8b7609 13082 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
13083 max_vd_ndx = 0;
13084
ab273396
AM
13085 /* Usually we'd only see verdef for defined symbols, and verneed for
13086 undefined symbols. However, symbols defined by the linker in
13087 .dynbss for variables copied from a shared library in order to
13088 avoid text relocations are defined yet have verneed. We could
13089 use a heuristic to detect the special case, for example, check
13090 for verneed first on symbols defined in SHT_NOBITS sections, but
13091 it is simpler and more reliable to just look for both verdef and
13092 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13093
ab273396
AM
13094 if (psym->st_shndx != SHN_UNDEF
13095 && vers_data != 0x8001
978c4450 13096 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13097 {
13098 Elf_Internal_Verdef ivd;
13099 Elf_Internal_Verdaux ivda;
13100 Elf_External_Verdaux evda;
26c527e6 13101 uint64_t off;
bb4d2ac2 13102
dda8d76d 13103 off = offset_from_vma (filedata,
978c4450 13104 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13105 sizeof (Elf_External_Verdef));
13106
13107 do
bb4d2ac2 13108 {
ab273396
AM
13109 Elf_External_Verdef evd;
13110
dda8d76d 13111 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13112 _("version def")) == NULL)
13113 {
13114 ivd.vd_ndx = 0;
13115 ivd.vd_aux = 0;
13116 ivd.vd_next = 0;
1f6f5dba 13117 ivd.vd_flags = 0;
ab273396
AM
13118 }
13119 else
bb4d2ac2 13120 {
ab273396
AM
13121 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13122 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13123 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13124 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13125 }
bb4d2ac2 13126
7a815dd5
L
13127 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13128 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13129
ab273396
AM
13130 off += ivd.vd_next;
13131 }
13132 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13133
ab273396
AM
13134 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13135 {
9abca702 13136 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13137 return NULL;
13138
ab273396
AM
13139 off -= ivd.vd_next;
13140 off += ivd.vd_aux;
bb4d2ac2 13141
dda8d76d 13142 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13143 _("version def aux")) != NULL)
13144 {
13145 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13146
ab273396 13147 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13148 return (ivda.vda_name < strtab_size
13149 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13150 }
13151 }
13152 }
bb4d2ac2 13153
978c4450 13154 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13155 {
13156 Elf_External_Verneed evn;
13157 Elf_Internal_Verneed ivn;
13158 Elf_Internal_Vernaux ivna;
bb4d2ac2 13159
dda8d76d 13160 offset = offset_from_vma (filedata,
978c4450 13161 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13162 sizeof evn);
13163 do
13164 {
26c527e6 13165 uint64_t vna_off;
bb4d2ac2 13166
dda8d76d 13167 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13168 _("version need")) == NULL)
13169 {
13170 ivna.vna_next = 0;
13171 ivna.vna_other = 0;
13172 ivna.vna_name = 0;
13173 break;
13174 }
bb4d2ac2 13175
ab273396
AM
13176 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13177 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13178
ab273396 13179 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13180
ab273396
AM
13181 do
13182 {
13183 Elf_External_Vernaux evna;
bb4d2ac2 13184
dda8d76d 13185 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13186 _("version need aux (3)")) == NULL)
bb4d2ac2 13187 {
ab273396
AM
13188 ivna.vna_next = 0;
13189 ivna.vna_other = 0;
13190 ivna.vna_name = 0;
bb4d2ac2 13191 }
bb4d2ac2 13192 else
bb4d2ac2 13193 {
ab273396
AM
13194 ivna.vna_other = BYTE_GET (evna.vna_other);
13195 ivna.vna_next = BYTE_GET (evna.vna_next);
13196 ivna.vna_name = BYTE_GET (evna.vna_name);
13197 }
bb4d2ac2 13198
ab273396
AM
13199 vna_off += ivna.vna_next;
13200 }
13201 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13202
ab273396
AM
13203 if (ivna.vna_other == vers_data)
13204 break;
bb4d2ac2 13205
ab273396
AM
13206 offset += ivn.vn_next;
13207 }
13208 while (ivn.vn_next != 0);
bb4d2ac2 13209
ab273396
AM
13210 if (ivna.vna_other == vers_data)
13211 {
13212 *sym_info = symbol_undefined;
13213 *vna_other = ivna.vna_other;
13214 return (ivna.vna_name < strtab_size
13215 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13216 }
7a815dd5
L
13217 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13218 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13219 return _("<corrupt>");
bb4d2ac2 13220 }
ab273396 13221 return NULL;
bb4d2ac2
L
13222}
13223
047c3dbf
NL
13224/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13225
13226static unsigned int
625d49fc 13227print_dynamic_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13228{
13229 switch (base)
13230 {
13231 case 8:
13232 return print_vma (vma, OCTAL_5);
13233
13234 case 10:
13235 return print_vma (vma, UNSIGNED_5);
13236
13237 case 16:
13238 return print_vma (vma, PREFIX_HEX_5);
13239
13240 case 0:
13241 default:
13242 return print_vma (vma, DEC_5);
13243 }
13244}
13245
10ca4b04 13246static void
26c527e6 13247print_dynamic_symbol (Filedata *filedata, uint64_t si,
10ca4b04
L
13248 Elf_Internal_Sym *symtab,
13249 Elf_Internal_Shdr *section,
13250 char *strtab, size_t strtab_size)
252b5132 13251{
10ca4b04
L
13252 const char *version_string;
13253 enum versioned_symbol_info sym_info;
13254 unsigned short vna_other;
23356397
NC
13255 bool is_valid;
13256 const char * sstr;
10ca4b04 13257 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13258
26c527e6 13259 printf ("%6" PRId64 ": ", si);
10ca4b04
L
13260 print_vma (psym->st_value, LONG_HEX);
13261 putchar (' ');
047c3dbf 13262 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13263 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13264 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13265 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13266 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13267 else
252b5132 13268 {
10ca4b04 13269 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13270
10ca4b04
L
13271 printf (" %-7s", get_symbol_visibility (vis));
13272 /* Check to see if any other bits in the st_other field are set.
13273 Note - displaying this information disrupts the layout of the
13274 table being generated, but for the moment this case is very rare. */
13275 if (psym->st_other ^ vis)
13276 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13277 }
10ca4b04 13278 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13279
23356397
NC
13280 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13281 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13282 && filedata->section_headers != NULL
23356397
NC
13283 && psym->st_name == 0)
13284 {
84714f86
AM
13285 is_valid
13286 = section_name_valid (filedata,
13287 filedata->section_headers + psym->st_shndx);
23356397 13288 sstr = is_valid ?
84714f86
AM
13289 section_name_print (filedata,
13290 filedata->section_headers + psym->st_shndx)
23356397
NC
13291 : _("<corrupt>");
13292 }
13293 else
13294 {
84714f86 13295 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13296 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13297 }
10ca4b04
L
13298
13299 version_string
13300 = get_symbol_version_string (filedata,
13301 (section == NULL
13302 || section->sh_type == SHT_DYNSYM),
13303 strtab, strtab_size, si,
13304 psym, &sym_info, &vna_other);
b9e920ec 13305
0942c7ab
NC
13306 int len_avail = 21;
13307 if (! do_wide && version_string != NULL)
13308 {
ddb43bab 13309 char buffer[16];
0942c7ab 13310
ddb43bab 13311 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13312
13313 if (sym_info == symbol_undefined)
13314 len_avail -= sprintf (buffer," (%d)", vna_other);
13315 else if (sym_info != symbol_hidden)
13316 len_avail -= 1;
13317 }
13318
13319 print_symbol (len_avail, sstr);
b9e920ec 13320
10ca4b04
L
13321 if (version_string)
13322 {
13323 if (sym_info == symbol_undefined)
13324 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13325 else
10ca4b04
L
13326 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13327 version_string);
13328 }
6bd1a22c 13329
10ca4b04 13330 putchar ('\n');
6bd1a22c 13331
10ca4b04
L
13332 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13333 && section != NULL
13334 && si >= section->sh_info
13335 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13336 && filedata->file_header.e_machine != EM_MIPS
13337 /* Solaris binaries have been found to violate this requirement as
13338 well. Not sure if this is a bug or an ABI requirement. */
13339 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
26c527e6 13340 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
10ca4b04
L
13341 si, printable_section_name (filedata, section), section->sh_info);
13342}
f16a9783 13343
0f03783c
NC
13344static const char *
13345get_lto_kind (unsigned int kind)
13346{
13347 switch (kind)
13348 {
13349 case 0: return "DEF";
13350 case 1: return "WEAKDEF";
13351 case 2: return "UNDEF";
13352 case 3: return "WEAKUNDEF";
13353 case 4: return "COMMON";
13354 default:
13355 break;
13356 }
13357
13358 static char buffer[30];
13359 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13360 sprintf (buffer, "<unknown: %u>", kind);
13361 return buffer;
13362}
13363
13364static const char *
13365get_lto_visibility (unsigned int visibility)
13366{
13367 switch (visibility)
13368 {
13369 case 0: return "DEFAULT";
13370 case 1: return "PROTECTED";
13371 case 2: return "INTERNAL";
13372 case 3: return "HIDDEN";
13373 default:
13374 break;
13375 }
13376
13377 static char buffer[30];
13378 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13379 sprintf (buffer, "<unknown: %u>", visibility);
13380 return buffer;
13381}
13382
13383static const char *
13384get_lto_sym_type (unsigned int sym_type)
13385{
13386 switch (sym_type)
13387 {
13388 case 0: return "UNKNOWN";
13389 case 1: return "FUNCTION";
13390 case 2: return "VARIABLE";
13391 default:
13392 break;
13393 }
13394
13395 static char buffer[30];
13396 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13397 sprintf (buffer, "<unknown: %u>", sym_type);
13398 return buffer;
13399}
13400
13401/* Display an LTO format symbol table.
13402 FIXME: The format of LTO symbol tables is not formalized.
13403 So this code could need changing in the future. */
13404
015dc7e1 13405static bool
0f03783c
NC
13406display_lto_symtab (Filedata * filedata,
13407 Elf_Internal_Shdr * section)
13408{
13409 if (section->sh_size == 0)
13410 {
ca0e11aa
NC
13411 if (filedata->is_separate)
13412 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13413 printable_section_name (filedata, section),
13414 filedata->file_name);
13415 else
13416 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13417 printable_section_name (filedata, section));
047c3dbf 13418
015dc7e1 13419 return true;
0f03783c
NC
13420 }
13421
13422 if (section->sh_size > filedata->file_size)
13423 {
26c527e6 13424 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
0f03783c 13425 printable_section_name (filedata, section),
26c527e6 13426 section->sh_size);
015dc7e1 13427 return false;
0f03783c
NC
13428 }
13429
13430 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13431 section->sh_size, 1, _("LTO symbols"));
13432 if (alloced_data == NULL)
015dc7e1 13433 return false;
0f03783c
NC
13434
13435 /* Look for extended data for the symbol table. */
13436 Elf_Internal_Shdr * ext;
13437 void * ext_data_orig = NULL;
13438 char * ext_data = NULL;
13439 char * ext_data_end = NULL;
13440 char * ext_name = NULL;
13441
13442 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13443 (section_name (filedata, section)
13444 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13445 && ext_name != NULL /* Paranoia. */
13446 && (ext = find_section (filedata, ext_name)) != NULL)
13447 {
13448 if (ext->sh_size < 3)
13449 error (_("LTO Symbol extension table '%s' is empty!\n"),
13450 printable_section_name (filedata, ext));
13451 else
13452 {
13453 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13454 ext->sh_size, 1,
13455 _("LTO ext symbol data"));
13456 if (ext_data != NULL)
13457 {
13458 ext_data_end = ext_data + ext->sh_size;
13459 if (* ext_data++ != 1)
13460 error (_("Unexpected version number in symbol extension table\n"));
13461 }
13462 }
13463 }
b9e920ec 13464
0f03783c
NC
13465 const unsigned char * data = (const unsigned char *) alloced_data;
13466 const unsigned char * end = data + section->sh_size;
13467
ca0e11aa
NC
13468 if (filedata->is_separate)
13469 printf (_("\nIn linked file '%s': "), filedata->file_name);
13470 else
13471 printf ("\n");
13472
0f03783c
NC
13473 if (ext_data_orig != NULL)
13474 {
13475 if (do_wide)
ca0e11aa 13476 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13477 printable_section_name (filedata, section),
13478 printable_section_name (filedata, ext));
13479 else
13480 {
ca0e11aa 13481 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13482 printable_section_name (filedata, section));
13483 printf (_(" and extension table '%s' contain:\n"),
13484 printable_section_name (filedata, ext));
13485 }
13486 }
13487 else
ca0e11aa 13488 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13489 printable_section_name (filedata, section));
b9e920ec 13490
0f03783c 13491 /* FIXME: Add a wide version. */
b9e920ec 13492 if (ext_data_orig != NULL)
0f03783c
NC
13493 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13494 else
13495 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13496
13497 /* FIXME: We do not handle style prefixes. */
13498
13499 while (data < end)
13500 {
13501 const unsigned char * sym_name = data;
13502 data += strnlen ((const char *) sym_name, end - data) + 1;
13503 if (data >= end)
13504 goto fail;
13505
13506 const unsigned char * comdat_key = data;
13507 data += strnlen ((const char *) comdat_key, end - data) + 1;
13508 if (data >= end)
13509 goto fail;
13510
13511 if (data + 2 + 8 + 4 > end)
13512 goto fail;
13513
13514 unsigned int kind = *data++;
13515 unsigned int visibility = *data++;
13516
928c411d 13517 uint64_t size = byte_get (data, 8);
0f03783c
NC
13518 data += 8;
13519
928c411d 13520 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13521 data += 4;
13522
13523 if (ext_data != NULL)
13524 {
13525 if (ext_data < (ext_data_end - 1))
13526 {
13527 unsigned int sym_type = * ext_data ++;
13528 unsigned int sec_kind = * ext_data ++;
13529
31e5a3a3 13530 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
13531 * comdat_key == 0 ? "-" : (char *) comdat_key,
13532 get_lto_kind (kind),
13533 get_lto_visibility (visibility),
31e5a3a3
AM
13534 size,
13535 slot,
0f03783c 13536 get_lto_sym_type (sym_type),
31e5a3a3 13537 sec_kind);
0f03783c
NC
13538 print_symbol (6, (const char *) sym_name);
13539 }
13540 else
13541 {
13542 error (_("Ran out of LTO symbol extension data\n"));
13543 ext_data = NULL;
13544 /* FIXME: return FAIL result ? */
13545 }
13546 }
13547 else
13548 {
31e5a3a3 13549 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
13550 * comdat_key == 0 ? "-" : (char *) comdat_key,
13551 get_lto_kind (kind),
13552 get_lto_visibility (visibility),
31e5a3a3
AM
13553 size,
13554 slot);
0f03783c
NC
13555 print_symbol (21, (const char *) sym_name);
13556 }
13557 putchar ('\n');
13558 }
13559
13560 if (ext_data != NULL && ext_data < ext_data_end)
13561 {
13562 error (_("Data remains in the LTO symbol extension table\n"));
13563 goto fail;
13564 }
13565
13566 free (alloced_data);
13567 free (ext_data_orig);
13568 free (ext_name);
015dc7e1 13569 return true;
b9e920ec 13570
0f03783c
NC
13571 fail:
13572 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13573 free (alloced_data);
13574 free (ext_data_orig);
13575 free (ext_name);
015dc7e1 13576 return false;
0f03783c
NC
13577}
13578
13579/* Display LTO symbol tables. */
13580
015dc7e1 13581static bool
0f03783c
NC
13582process_lto_symbol_tables (Filedata * filedata)
13583{
13584 Elf_Internal_Shdr * section;
13585 unsigned int i;
015dc7e1 13586 bool res = true;
0f03783c
NC
13587
13588 if (!do_lto_syms)
015dc7e1 13589 return true;
0f03783c
NC
13590
13591 if (filedata->section_headers == NULL)
015dc7e1 13592 return true;
0f03783c
NC
13593
13594 for (i = 0, section = filedata->section_headers;
13595 i < filedata->file_header.e_shnum;
13596 i++, section++)
84714f86
AM
13597 if (section_name_valid (filedata, section)
13598 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13599 res &= display_lto_symtab (filedata, section);
13600
b9e920ec 13601 return res;
0f03783c
NC
13602}
13603
10ca4b04 13604/* Dump the symbol table. */
0f03783c 13605
015dc7e1 13606static bool
10ca4b04
L
13607process_symbol_table (Filedata * filedata)
13608{
13609 Elf_Internal_Shdr * section;
f16a9783 13610
10ca4b04 13611 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13612 return true;
6bd1a22c 13613
978c4450 13614 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13615 && do_syms
13616 && do_using_dynamic
978c4450
AM
13617 && filedata->dynamic_strings != NULL
13618 && filedata->dynamic_symbols != NULL)
6bd1a22c 13619 {
26c527e6 13620 uint64_t si;
6bd1a22c 13621
ca0e11aa
NC
13622 if (filedata->is_separate)
13623 {
26c527e6
AM
13624 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
13625 " contains %" PRIu64 " entry:\n",
13626 "\nIn linked file '%s' the dynamic symbol table"
13627 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13628 filedata->num_dynamic_syms),
13629 filedata->file_name,
13630 filedata->num_dynamic_syms);
13631 }
13632 else
13633 {
26c527e6
AM
13634 printf (ngettext ("\nSymbol table for image contains %" PRIu64
13635 " entry:\n",
13636 "\nSymbol table for image contains %" PRIu64
13637 " entries:\n",
ca0e11aa
NC
13638 filedata->num_dynamic_syms),
13639 filedata->num_dynamic_syms);
13640 }
10ca4b04
L
13641 if (is_32bit_elf)
13642 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13643 else
13644 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13645
978c4450
AM
13646 for (si = 0; si < filedata->num_dynamic_syms; si++)
13647 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13648 filedata->dynamic_strings,
13649 filedata->dynamic_strings_length);
252b5132 13650 }
8b73c356 13651 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13652 && filedata->section_headers != NULL)
252b5132 13653 {
b34976b6 13654 unsigned int i;
252b5132 13655
dda8d76d
NC
13656 for (i = 0, section = filedata->section_headers;
13657 i < filedata->file_header.e_shnum;
252b5132
RH
13658 i++, section++)
13659 {
2cf0635d 13660 char * strtab = NULL;
26c527e6 13661 uint64_t strtab_size = 0;
2cf0635d 13662 Elf_Internal_Sym * symtab;
26c527e6 13663 uint64_t si, num_syms;
252b5132 13664
2c610e4b
L
13665 if ((section->sh_type != SHT_SYMTAB
13666 && section->sh_type != SHT_DYNSYM)
13667 || (!do_syms
13668 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13669 continue;
13670
dd24e3da
NC
13671 if (section->sh_entsize == 0)
13672 {
13673 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13674 printable_section_name (filedata, section));
dd24e3da
NC
13675 continue;
13676 }
13677
d3a49aa8 13678 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13679
13680 if (filedata->is_separate)
26c527e6
AM
13681 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
13682 " contains %" PRIu64 " entry:\n",
13683 "\nIn linked file '%s' symbol section '%s'"
13684 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13685 num_syms),
13686 filedata->file_name,
13687 printable_section_name (filedata, section),
13688 num_syms);
13689 else
26c527e6
AM
13690 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
13691 " entry:\n",
13692 "\nSymbol table '%s' contains %" PRIu64
13693 " entries:\n",
ca0e11aa
NC
13694 num_syms),
13695 printable_section_name (filedata, section),
13696 num_syms);
dd24e3da 13697
f7a99963 13698 if (is_32bit_elf)
ca47b30c 13699 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13700 else
ca47b30c 13701 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13702
4de91c10 13703 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13704 if (symtab == NULL)
13705 continue;
13706
dda8d76d 13707 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13708 {
dda8d76d
NC
13709 strtab = filedata->string_table;
13710 strtab_size = filedata->string_table_length;
c256ffe7 13711 }
dda8d76d 13712 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13713 {
2cf0635d 13714 Elf_Internal_Shdr * string_sec;
252b5132 13715
dda8d76d 13716 string_sec = filedata->section_headers + section->sh_link;
252b5132 13717
dda8d76d 13718 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13719 1, string_sec->sh_size,
13720 _("string table"));
c256ffe7 13721 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13722 }
13723
10ca4b04
L
13724 for (si = 0; si < num_syms; si++)
13725 print_dynamic_symbol (filedata, si, symtab, section,
13726 strtab, strtab_size);
252b5132
RH
13727
13728 free (symtab);
dda8d76d 13729 if (strtab != filedata->string_table)
252b5132
RH
13730 free (strtab);
13731 }
13732 }
13733 else if (do_syms)
13734 printf
13735 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13736
978c4450 13737 if (do_histogram && filedata->buckets != NULL)
252b5132 13738 {
26c527e6
AM
13739 uint64_t *lengths;
13740 uint64_t *counts;
13741 uint64_t hn;
625d49fc 13742 uint64_t si;
26c527e6
AM
13743 uint64_t maxlength = 0;
13744 uint64_t nzero_counts = 0;
13745 uint64_t nsyms = 0;
6bd6a03d 13746 char *visited;
252b5132 13747
d3a49aa8 13748 printf (ngettext ("\nHistogram for bucket list length "
26c527e6 13749 "(total of %" PRIu64 " bucket):\n",
d3a49aa8 13750 "\nHistogram for bucket list length "
26c527e6
AM
13751 "(total of %" PRIu64 " buckets):\n",
13752 filedata->nbuckets),
13753 filedata->nbuckets);
252b5132 13754
26c527e6 13755 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
252b5132
RH
13756 if (lengths == NULL)
13757 {
8b73c356 13758 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13759 goto err_out;
252b5132 13760 }
978c4450
AM
13761 visited = xcmalloc (filedata->nchains, 1);
13762 memset (visited, 0, filedata->nchains);
8b73c356
NC
13763
13764 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13765 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13766 {
978c4450 13767 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13768 {
b34976b6 13769 ++nsyms;
252b5132 13770 if (maxlength < ++lengths[hn])
b34976b6 13771 ++maxlength;
978c4450 13772 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13773 {
13774 error (_("histogram chain is corrupt\n"));
13775 break;
13776 }
13777 visited[si] = 1;
252b5132
RH
13778 }
13779 }
6bd6a03d 13780 free (visited);
252b5132 13781
26c527e6 13782 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13783 if (counts == NULL)
13784 {
b2e951ec 13785 free (lengths);
8b73c356 13786 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13787 goto err_out;
252b5132
RH
13788 }
13789
978c4450 13790 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13791 ++counts[lengths[hn]];
252b5132 13792
978c4450 13793 if (filedata->nbuckets > 0)
252b5132 13794 {
26c527e6
AM
13795 uint64_t i;
13796 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 13797 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13798 for (i = 1; i <= maxlength; ++i)
103f02d3 13799 {
66543521 13800 nzero_counts += counts[i] * i;
26c527e6 13801 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 13802 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13803 (nzero_counts * 100.0) / nsyms);
13804 }
252b5132
RH
13805 }
13806
13807 free (counts);
13808 free (lengths);
13809 }
13810
978c4450
AM
13811 free (filedata->buckets);
13812 filedata->buckets = NULL;
13813 filedata->nbuckets = 0;
13814 free (filedata->chains);
13815 filedata->chains = NULL;
252b5132 13816
978c4450 13817 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13818 {
26c527e6
AM
13819 uint64_t *lengths;
13820 uint64_t *counts;
13821 uint64_t hn;
13822 uint64_t maxlength = 0;
13823 uint64_t nzero_counts = 0;
13824 uint64_t nsyms = 0;
fdc90cb4 13825
f16a9783 13826 printf (ngettext ("\nHistogram for `%s' bucket list length "
26c527e6 13827 "(total of %" PRIu64 " bucket):\n",
f16a9783 13828 "\nHistogram for `%s' bucket list length "
26c527e6
AM
13829 "(total of %" PRIu64 " buckets):\n",
13830 filedata->ngnubuckets),
978c4450 13831 GNU_HASH_SECTION_NAME (filedata),
26c527e6 13832 filedata->ngnubuckets);
8b73c356 13833
26c527e6 13834 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
13835 if (lengths == NULL)
13836 {
8b73c356 13837 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13838 goto err_out;
fdc90cb4
JJ
13839 }
13840
fdc90cb4
JJ
13841 printf (_(" Length Number %% of total Coverage\n"));
13842
978c4450
AM
13843 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13844 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 13845 {
625d49fc 13846 uint64_t off, length = 1;
fdc90cb4 13847
978c4450 13848 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13849 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13850 off < filedata->ngnuchains
13851 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13852 ++off)
fdc90cb4
JJ
13853 ++length;
13854 lengths[hn] = length;
13855 if (length > maxlength)
13856 maxlength = length;
13857 nsyms += length;
13858 }
13859
26c527e6 13860 counts = calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13861 if (counts == NULL)
13862 {
b2e951ec 13863 free (lengths);
8b73c356 13864 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13865 goto err_out;
fdc90cb4
JJ
13866 }
13867
978c4450 13868 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13869 ++counts[lengths[hn]];
13870
978c4450 13871 if (filedata->ngnubuckets > 0)
fdc90cb4 13872 {
26c527e6
AM
13873 uint64_t j;
13874 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 13875 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13876 for (j = 1; j <= maxlength; ++j)
13877 {
13878 nzero_counts += counts[j] * j;
26c527e6 13879 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 13880 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13881 (nzero_counts * 100.0) / nsyms);
13882 }
13883 }
13884
13885 free (counts);
13886 free (lengths);
fdc90cb4 13887 }
978c4450
AM
13888 free (filedata->gnubuckets);
13889 filedata->gnubuckets = NULL;
13890 filedata->ngnubuckets = 0;
13891 free (filedata->gnuchains);
13892 filedata->gnuchains = NULL;
13893 filedata->ngnuchains = 0;
13894 free (filedata->mipsxlat);
13895 filedata->mipsxlat = NULL;
015dc7e1 13896 return true;
fd486f32
AM
13897
13898 err_out:
978c4450
AM
13899 free (filedata->gnubuckets);
13900 filedata->gnubuckets = NULL;
13901 filedata->ngnubuckets = 0;
13902 free (filedata->gnuchains);
13903 filedata->gnuchains = NULL;
13904 filedata->ngnuchains = 0;
13905 free (filedata->mipsxlat);
13906 filedata->mipsxlat = NULL;
13907 free (filedata->buckets);
13908 filedata->buckets = NULL;
13909 filedata->nbuckets = 0;
13910 free (filedata->chains);
13911 filedata->chains = NULL;
015dc7e1 13912 return false;
252b5132
RH
13913}
13914
015dc7e1 13915static bool
ca0e11aa 13916process_syminfo (Filedata * filedata)
252b5132 13917{
b4c96d0d 13918 unsigned int i;
252b5132 13919
978c4450 13920 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13921 || !do_dynamic)
13922 /* No syminfo, this is ok. */
015dc7e1 13923 return true;
252b5132
RH
13924
13925 /* There better should be a dynamic symbol section. */
978c4450 13926 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13927 return false;
252b5132 13928
ca0e11aa 13929 if (filedata->is_separate)
26c527e6
AM
13930 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
13931 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
ca0e11aa
NC
13932 filedata->dynamic_syminfo_nent),
13933 filedata->file_name,
13934 filedata->dynamic_syminfo_offset,
13935 filedata->dynamic_syminfo_nent);
13936 else
26c527e6
AM
13937 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
13938 " contains %d entry:\n",
13939 "\nDynamic info segment at offset %#" PRIx64
13940 " contains %d entries:\n",
978c4450 13941 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13942 filedata->dynamic_syminfo_offset,
13943 filedata->dynamic_syminfo_nent);
252b5132
RH
13944
13945 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13946 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13947 {
978c4450 13948 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13949
31104126 13950 printf ("%4d: ", i);
978c4450 13951 if (i >= filedata->num_dynamic_syms)
4082ef84 13952 printf (_("<corrupt index>"));
84714f86
AM
13953 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13954 print_symbol (30, get_dynamic_name (filedata,
978c4450 13955 filedata->dynamic_symbols[i].st_name));
d79b3d50 13956 else
978c4450 13957 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13958 putchar (' ');
252b5132 13959
978c4450 13960 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13961 {
13962 case SYMINFO_BT_SELF:
13963 fputs ("SELF ", stdout);
13964 break;
13965 case SYMINFO_BT_PARENT:
13966 fputs ("PARENT ", stdout);
13967 break;
13968 default:
978c4450
AM
13969 if (filedata->dynamic_syminfo[i].si_boundto > 0
13970 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13971 && valid_dynamic_name (filedata,
978c4450 13972 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13973 {
84714f86 13974 print_symbol (10, get_dynamic_name (filedata,
978c4450 13975 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13976 putchar (' ' );
13977 }
252b5132 13978 else
978c4450 13979 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13980 break;
13981 }
13982
13983 if (flags & SYMINFO_FLG_DIRECT)
13984 printf (" DIRECT");
13985 if (flags & SYMINFO_FLG_PASSTHRU)
13986 printf (" PASSTHRU");
13987 if (flags & SYMINFO_FLG_COPY)
13988 printf (" COPY");
13989 if (flags & SYMINFO_FLG_LAZYLOAD)
13990 printf (" LAZYLOAD");
13991
13992 puts ("");
13993 }
13994
015dc7e1 13995 return true;
252b5132
RH
13996}
13997
75802ccb
CE
13998/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13999 is contained by the region START .. END. The types of ADDR, START
14000 and END should all be the same. Note both ADDR + NELEM and END
14001 point to just beyond the end of the regions that are being tested. */
14002#define IN_RANGE(START,END,ADDR,NELEM) \
14003 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 14004
cf13d699
NC
14005/* Check to see if the given reloc needs to be handled in a target specific
14006 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
14007 FALSE.
14008
14009 If called with reloc == NULL, then this is a signal that reloc processing
14010 for the current section has finished, and any saved state should be
14011 discarded. */
09c11c86 14012
015dc7e1 14013static bool
26c527e6
AM
14014target_specific_reloc_handling (Filedata *filedata,
14015 Elf_Internal_Rela *reloc,
14016 unsigned char *start,
14017 unsigned char *end,
14018 Elf_Internal_Sym *symtab,
14019 uint64_t num_syms)
252b5132 14020{
f84ce13b 14021 unsigned int reloc_type = 0;
26c527e6 14022 uint64_t sym_index = 0;
f84ce13b
NC
14023
14024 if (reloc)
14025 {
dda8d76d 14026 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
14027 sym_index = get_reloc_symindex (reloc->r_info);
14028 }
252b5132 14029
dda8d76d 14030 switch (filedata->file_header.e_machine)
252b5132 14031 {
76244462 14032 case EM_LOONGARCH:
14033 {
14034 switch (reloc_type)
14035 {
14036 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
14037 at assembly time. */
14038 case 107: /* R_LARCH_ADD_ULEB128. */
14039 case 108: /* R_LARCH_SUB_ULEB128. */
14040 {
d3f34076 14041 uint64_t value = 0;
76244462 14042 unsigned int reloc_size = 0;
14043 int leb_ret = 0;
14044
89c70cd3
AM
14045 if (reloc->r_offset < (size_t) (end - start))
14046 value = read_leb128 (start + reloc->r_offset, end, false,
14047 &reloc_size, &leb_ret);
76244462 14048 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14049 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
14050 "ULEB128 value\n"),
14051 (long) reloc->r_offset);
14052
74a965d8
AM
14053 else if (sym_index >= num_syms)
14054 error (_("%s reloc contains invalid symbol index "
14055 "%" PRIu64 "\n"),
14056 (reloc_type == 107
14057 ? "R_LARCH_ADD_ULEB128"
14058 : "R_LARCH_SUB_ULEB128"),
14059 sym_index);
14060 else
76244462 14061 {
74a965d8
AM
14062 if (reloc_type == 107)
14063 value += reloc->r_addend + symtab[sym_index].st_value;
14064 else
14065 value -= reloc->r_addend + symtab[sym_index].st_value;
14066
14067 /* Write uleb128 value to p. */
14068 bfd_byte *p = start + reloc->r_offset;
14069 do
14070 {
14071 bfd_byte c = value & 0x7f;
14072 value >>= 7;
14073 if (--reloc_size != 0)
14074 c |= 0x80;
14075 *p++ = c;
14076 }
14077 while (reloc_size);
76244462 14078 }
76244462 14079
14080 return true;
14081 }
14082 }
14083 break;
14084 }
14085
13761a11
NC
14086 case EM_MSP430:
14087 case EM_MSP430_OLD:
14088 {
14089 static Elf_Internal_Sym * saved_sym = NULL;
14090
f84ce13b
NC
14091 if (reloc == NULL)
14092 {
14093 saved_sym = NULL;
015dc7e1 14094 return true;
f84ce13b
NC
14095 }
14096
13761a11
NC
14097 switch (reloc_type)
14098 {
14099 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 14100 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 14101 if (uses_msp430x_relocs (filedata))
13761a11 14102 break;
1a0670f3 14103 /* Fall through. */
13761a11 14104 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 14105 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
14106 /* PR 21139. */
14107 if (sym_index >= num_syms)
74a965d8
AM
14108 error (_("%s reloc contains invalid symbol index "
14109 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
f84ce13b
NC
14110 else
14111 saved_sym = symtab + sym_index;
015dc7e1 14112 return true;
13761a11
NC
14113
14114 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14115 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14116 goto handle_sym_diff;
0b4362b0 14117
13761a11
NC
14118 case 5: /* R_MSP430_16_BYTE */
14119 case 9: /* R_MSP430_8 */
7d81bc93 14120 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 14121 if (uses_msp430x_relocs (filedata))
13761a11
NC
14122 break;
14123 goto handle_sym_diff;
14124
14125 case 2: /* R_MSP430_ABS16 */
14126 case 15: /* R_MSP430X_ABS16 */
7d81bc93 14127 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 14128 if (! uses_msp430x_relocs (filedata))
13761a11
NC
14129 break;
14130 goto handle_sym_diff;
0b4362b0 14131
13761a11
NC
14132 handle_sym_diff:
14133 if (saved_sym != NULL)
14134 {
625d49fc 14135 uint64_t value;
5a805384 14136 unsigned int reloc_size = 0;
7d81bc93
JL
14137 int leb_ret = 0;
14138 switch (reloc_type)
14139 {
14140 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14141 reloc_size = 4;
14142 break;
14143 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14144 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14145 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14146 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14147 &reloc_size, &leb_ret);
7d81bc93
JL
14148 break;
14149 default:
14150 reloc_size = 2;
14151 break;
14152 }
13761a11 14153
5a805384 14154 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
14155 error (_("MSP430 ULEB128 field at %#" PRIx64
14156 " contains invalid ULEB128 value\n"),
14157 reloc->r_offset);
7d81bc93 14158 else if (sym_index >= num_syms)
74a965d8
AM
14159 error (_("%s reloc contains invalid symbol index "
14160 "%" PRIu64 "\n"), "MSP430", sym_index);
03f7786e 14161 else
f84ce13b
NC
14162 {
14163 value = reloc->r_addend + (symtab[sym_index].st_value
14164 - saved_sym->st_value);
14165
b32e566b 14166 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14167 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14168 else
14169 /* PR 21137 */
26c527e6
AM
14170 error (_("MSP430 sym diff reloc contains invalid offset: "
14171 "%#" PRIx64 "\n"),
14172 reloc->r_offset);
f84ce13b 14173 }
13761a11
NC
14174
14175 saved_sym = NULL;
015dc7e1 14176 return true;
13761a11
NC
14177 }
14178 break;
14179
14180 default:
14181 if (saved_sym != NULL)
071436c6 14182 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14183 break;
14184 }
14185 break;
14186 }
14187
cf13d699
NC
14188 case EM_MN10300:
14189 case EM_CYGNUS_MN10300:
14190 {
14191 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14192
f84ce13b
NC
14193 if (reloc == NULL)
14194 {
14195 saved_sym = NULL;
015dc7e1 14196 return true;
f84ce13b
NC
14197 }
14198
cf13d699
NC
14199 switch (reloc_type)
14200 {
14201 case 34: /* R_MN10300_ALIGN */
015dc7e1 14202 return true;
cf13d699 14203 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 14204 if (sym_index >= num_syms)
74a965d8
AM
14205 error (_("%s reloc contains invalid symbol index "
14206 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
f84ce13b
NC
14207 else
14208 saved_sym = symtab + sym_index;
015dc7e1 14209 return true;
f84ce13b 14210
cf13d699
NC
14211 case 1: /* R_MN10300_32 */
14212 case 2: /* R_MN10300_16 */
14213 if (saved_sym != NULL)
14214 {
03f7786e 14215 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14216 uint64_t value;
252b5132 14217
f84ce13b 14218 if (sym_index >= num_syms)
74a965d8
AM
14219 error (_("%s reloc contains invalid symbol index "
14220 "%" PRIu64 "\n"), "MN10300", sym_index);
03f7786e 14221 else
f84ce13b
NC
14222 {
14223 value = reloc->r_addend + (symtab[sym_index].st_value
14224 - saved_sym->st_value);
14225
b32e566b 14226 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14227 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 14228 else
26c527e6
AM
14229 error (_("MN10300 sym diff reloc contains invalid offset:"
14230 " %#" PRIx64 "\n"),
14231 reloc->r_offset);
f84ce13b 14232 }
252b5132 14233
cf13d699 14234 saved_sym = NULL;
015dc7e1 14235 return true;
cf13d699
NC
14236 }
14237 break;
14238 default:
14239 if (saved_sym != NULL)
071436c6 14240 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14241 break;
14242 }
14243 break;
14244 }
6ff71e76
NC
14245
14246 case EM_RL78:
14247 {
625d49fc
AM
14248 static uint64_t saved_sym1 = 0;
14249 static uint64_t saved_sym2 = 0;
14250 static uint64_t value;
6ff71e76 14251
f84ce13b
NC
14252 if (reloc == NULL)
14253 {
14254 saved_sym1 = saved_sym2 = 0;
015dc7e1 14255 return true;
f84ce13b
NC
14256 }
14257
6ff71e76
NC
14258 switch (reloc_type)
14259 {
14260 case 0x80: /* R_RL78_SYM. */
14261 saved_sym1 = saved_sym2;
f84ce13b 14262 if (sym_index >= num_syms)
74a965d8
AM
14263 error (_("%s reloc contains invalid symbol index "
14264 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
f84ce13b
NC
14265 else
14266 {
14267 saved_sym2 = symtab[sym_index].st_value;
14268 saved_sym2 += reloc->r_addend;
14269 }
015dc7e1 14270 return true;
6ff71e76
NC
14271
14272 case 0x83: /* R_RL78_OPsub. */
14273 value = saved_sym1 - saved_sym2;
14274 saved_sym2 = saved_sym1 = 0;
015dc7e1 14275 return true;
6ff71e76
NC
14276 break;
14277
14278 case 0x41: /* R_RL78_ABS32. */
b32e566b 14279 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14280 byte_put (start + reloc->r_offset, value, 4);
b32e566b 14281 else
26c527e6
AM
14282 error (_("RL78 sym diff reloc contains invalid offset: "
14283 "%#" PRIx64 "\n"),
14284 reloc->r_offset);
6ff71e76 14285 value = 0;
015dc7e1 14286 return true;
6ff71e76
NC
14287
14288 case 0x43: /* R_RL78_ABS16. */
b32e566b 14289 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14290 byte_put (start + reloc->r_offset, value, 2);
b32e566b 14291 else
26c527e6
AM
14292 error (_("RL78 sym diff reloc contains invalid offset: "
14293 "%#" PRIx64 "\n"),
14294 reloc->r_offset);
6ff71e76 14295 value = 0;
015dc7e1 14296 return true;
6ff71e76
NC
14297
14298 default:
14299 break;
14300 }
14301 break;
14302 }
252b5132
RH
14303 }
14304
015dc7e1 14305 return false;
252b5132
RH
14306}
14307
aca88567
NC
14308/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14309 DWARF debug sections. This is a target specific test. Note - we do not
14310 go through the whole including-target-headers-multiple-times route, (as
14311 we have already done with <elf/h8.h>) because this would become very
14312 messy and even then this function would have to contain target specific
14313 information (the names of the relocs instead of their numeric values).
14314 FIXME: This is not the correct way to solve this problem. The proper way
14315 is to have target specific reloc sizing and typing functions created by
14316 the reloc-macros.h header, in the same way that it already creates the
14317 reloc naming functions. */
14318
015dc7e1 14319static bool
dda8d76d 14320is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14321{
d347c9df 14322 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14323 switch (filedata->file_header.e_machine)
aca88567 14324 {
41e92641 14325 case EM_386:
22abe556 14326 case EM_IAMCU:
41e92641 14327 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14328 case EM_68K:
14329 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14330 case EM_860:
14331 return reloc_type == 1; /* R_860_32. */
14332 case EM_960:
14333 return reloc_type == 2; /* R_960_32. */
a06ea964 14334 case EM_AARCH64:
9282b95a
JW
14335 return (reloc_type == 258
14336 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14337 case EM_BPF:
14338 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14339 case EM_ADAPTEVA_EPIPHANY:
14340 return reloc_type == 3;
aca88567 14341 case EM_ALPHA:
137b6b5f 14342 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14343 case EM_ARC:
14344 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14345 case EM_ARC_COMPACT:
14346 case EM_ARC_COMPACT2:
13aa307c
CZ
14347 case EM_ARC_COMPACT3:
14348 case EM_ARC_COMPACT3_64:
886a2506 14349 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14350 case EM_ARM:
14351 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14352 case EM_AVR_OLD:
aca88567
NC
14353 case EM_AVR:
14354 return reloc_type == 1;
14355 case EM_BLACKFIN:
14356 return reloc_type == 0x12; /* R_byte4_data. */
14357 case EM_CRIS:
14358 return reloc_type == 3; /* R_CRIS_32. */
14359 case EM_CR16:
14360 return reloc_type == 3; /* R_CR16_NUM32. */
14361 case EM_CRX:
14362 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14363 case EM_CSKY:
14364 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14365 case EM_CYGNUS_FRV:
14366 return reloc_type == 1;
41e92641
NC
14367 case EM_CYGNUS_D10V:
14368 case EM_D10V:
14369 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14370 case EM_CYGNUS_D30V:
14371 case EM_D30V:
14372 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14373 case EM_DLX:
14374 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14375 case EM_CYGNUS_FR30:
14376 case EM_FR30:
14377 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14378 case EM_FT32:
14379 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14380 case EM_H8S:
14381 case EM_H8_300:
14382 case EM_H8_300H:
14383 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14384 case EM_IA_64:
262cdac7
AM
14385 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14386 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14387 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14388 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14389 case EM_IP2K_OLD:
14390 case EM_IP2K:
14391 return reloc_type == 2; /* R_IP2K_32. */
14392 case EM_IQ2000:
14393 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14394 case EM_LATTICEMICO32:
14395 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14396 case EM_LOONGARCH:
14397 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14398 case EM_M32C_OLD:
aca88567
NC
14399 case EM_M32C:
14400 return reloc_type == 3; /* R_M32C_32. */
14401 case EM_M32R:
14402 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14403 case EM_68HC11:
14404 case EM_68HC12:
14405 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14406 case EM_S12Z:
2849d19f
JD
14407 return reloc_type == 7 || /* R_S12Z_EXT32 */
14408 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14409 case EM_MCORE:
14410 return reloc_type == 1; /* R_MCORE_ADDR32. */
14411 case EM_CYGNUS_MEP:
14412 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14413 case EM_METAG:
14414 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14415 case EM_MICROBLAZE:
14416 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14417 case EM_MIPS:
14418 return reloc_type == 2; /* R_MIPS_32. */
14419 case EM_MMIX:
14420 return reloc_type == 4; /* R_MMIX_32. */
14421 case EM_CYGNUS_MN10200:
14422 case EM_MN10200:
14423 return reloc_type == 1; /* R_MN10200_32. */
14424 case EM_CYGNUS_MN10300:
14425 case EM_MN10300:
14426 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14427 case EM_MOXIE:
14428 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14429 case EM_MSP430_OLD:
14430 case EM_MSP430:
13761a11 14431 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14432 case EM_MT:
14433 return reloc_type == 2; /* R_MT_32. */
35c08157 14434 case EM_NDS32:
81c5e376 14435 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14436 case EM_ALTERA_NIOS2:
36591ba1 14437 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14438 case EM_NIOS32:
14439 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14440 case EM_OR1K:
14441 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14442 case EM_PARISC:
9abca702 14443 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14444 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14445 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14446 case EM_PJ:
14447 case EM_PJ_OLD:
14448 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14449 case EM_PPC64:
14450 return reloc_type == 1; /* R_PPC64_ADDR32. */
14451 case EM_PPC:
14452 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14453 case EM_TI_PRU:
14454 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14455 case EM_RISCV:
14456 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14457 case EM_RL78:
14458 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14459 case EM_RX:
14460 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14461 case EM_S370:
14462 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14463 case EM_S390_OLD:
14464 case EM_S390:
14465 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14466 case EM_SCORE:
14467 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14468 case EM_SH:
14469 return reloc_type == 1; /* R_SH_DIR32. */
14470 case EM_SPARC32PLUS:
14471 case EM_SPARCV9:
14472 case EM_SPARC:
14473 return reloc_type == 3 /* R_SPARC_32. */
14474 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14475 case EM_SPU:
14476 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14477 case EM_TI_C6000:
14478 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14479 case EM_TILEGX:
14480 return reloc_type == 2; /* R_TILEGX_32. */
14481 case EM_TILEPRO:
14482 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14483 case EM_CYGNUS_V850:
14484 case EM_V850:
14485 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14486 case EM_V800:
14487 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14488 case EM_VAX:
14489 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14490 case EM_VISIUM:
14491 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14492 case EM_WEBASSEMBLY:
14493 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14494 case EM_X86_64:
8a9036a4 14495 case EM_L1OM:
7a9068fe 14496 case EM_K1OM:
aca88567 14497 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14498 case EM_XGATE:
14499 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14500 case EM_XSTORMY16:
14501 return reloc_type == 1; /* R_XSTROMY16_32. */
14502 case EM_XTENSA_OLD:
14503 case EM_XTENSA:
14504 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14505 case EM_Z80:
14506 return reloc_type == 6; /* R_Z80_32. */
aca88567 14507 default:
bee0ee85
NC
14508 {
14509 static unsigned int prev_warn = 0;
14510
14511 /* Avoid repeating the same warning multiple times. */
dda8d76d 14512 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14513 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14514 filedata->file_header.e_machine);
14515 prev_warn = filedata->file_header.e_machine;
015dc7e1 14516 return false;
bee0ee85 14517 }
aca88567
NC
14518 }
14519}
14520
14521/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14522 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14523
015dc7e1 14524static bool
dda8d76d 14525is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14526{
dda8d76d 14527 switch (filedata->file_header.e_machine)
d347c9df 14528 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14529 {
41e92641 14530 case EM_386:
22abe556 14531 case EM_IAMCU:
3e0873ac 14532 return reloc_type == 2; /* R_386_PC32. */
aca88567 14533 case EM_68K:
3e0873ac 14534 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14535 case EM_AARCH64:
14536 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14537 case EM_ADAPTEVA_EPIPHANY:
14538 return reloc_type == 6;
aca88567
NC
14539 case EM_ALPHA:
14540 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14541 case EM_ARC_COMPACT:
14542 case EM_ARC_COMPACT2:
13aa307c
CZ
14543 case EM_ARC_COMPACT3:
14544 case EM_ARC_COMPACT3_64:
726c18e1 14545 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14546 case EM_ARM:
3e0873ac 14547 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14548 case EM_AVR_OLD:
14549 case EM_AVR:
14550 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14551 case EM_LOONGARCH:
14552 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14553 case EM_MICROBLAZE:
14554 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14555 case EM_OR1K:
14556 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14557 case EM_PARISC:
85acf597 14558 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14559 case EM_PPC:
14560 return reloc_type == 26; /* R_PPC_REL32. */
14561 case EM_PPC64:
3e0873ac 14562 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14563 case EM_RISCV:
14564 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14565 case EM_S390_OLD:
14566 case EM_S390:
3e0873ac 14567 return reloc_type == 5; /* R_390_PC32. */
aca88567 14568 case EM_SH:
3e0873ac 14569 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14570 case EM_SPARC32PLUS:
14571 case EM_SPARCV9:
14572 case EM_SPARC:
3e0873ac 14573 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14574 case EM_SPU:
14575 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14576 case EM_TILEGX:
14577 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14578 case EM_TILEPRO:
14579 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14580 case EM_VISIUM:
14581 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14582 case EM_X86_64:
8a9036a4 14583 case EM_L1OM:
7a9068fe 14584 case EM_K1OM:
3e0873ac 14585 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14586 case EM_VAX:
14587 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14588 case EM_XTENSA_OLD:
14589 case EM_XTENSA:
14590 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14591 default:
14592 /* Do not abort or issue an error message here. Not all targets use
14593 pc-relative 32-bit relocs in their DWARF debug information and we
14594 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14595 more helpful warning message will be generated by apply_relocations
14596 anyway, so just return. */
015dc7e1 14597 return false;
aca88567
NC
14598 }
14599}
14600
14601/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14602 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14603
015dc7e1 14604static bool
dda8d76d 14605is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14606{
dda8d76d 14607 switch (filedata->file_header.e_machine)
aca88567 14608 {
a06ea964
NC
14609 case EM_AARCH64:
14610 return reloc_type == 257; /* R_AARCH64_ABS64. */
13aa307c
CZ
14611 case EM_ARC_COMPACT3_64:
14612 return reloc_type == 5; /* R_ARC_64. */
aca88567
NC
14613 case EM_ALPHA:
14614 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14615 case EM_IA_64:
262cdac7
AM
14616 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14617 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14618 case EM_LOONGARCH:
14619 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14620 case EM_PARISC:
14621 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14622 case EM_PPC64:
14623 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14624 case EM_RISCV:
14625 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14626 case EM_SPARC32PLUS:
14627 case EM_SPARCV9:
14628 case EM_SPARC:
714da62f
NC
14629 return reloc_type == 32 /* R_SPARC_64. */
14630 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14631 case EM_X86_64:
8a9036a4 14632 case EM_L1OM:
7a9068fe 14633 case EM_K1OM:
aca88567 14634 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14635 case EM_S390_OLD:
14636 case EM_S390:
aa137e4d
NC
14637 return reloc_type == 22; /* R_S390_64. */
14638 case EM_TILEGX:
14639 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14640 case EM_MIPS:
aa137e4d 14641 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14642 default:
015dc7e1 14643 return false;
aca88567
NC
14644 }
14645}
14646
85acf597
RH
14647/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14648 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14649
015dc7e1 14650static bool
dda8d76d 14651is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14652{
dda8d76d 14653 switch (filedata->file_header.e_machine)
85acf597 14654 {
a06ea964
NC
14655 case EM_AARCH64:
14656 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14657 case EM_ALPHA:
aa137e4d 14658 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14659 case EM_IA_64:
262cdac7
AM
14660 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14661 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14662 case EM_PARISC:
aa137e4d 14663 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14664 case EM_PPC64:
aa137e4d 14665 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14666 case EM_SPARC32PLUS:
14667 case EM_SPARCV9:
14668 case EM_SPARC:
aa137e4d 14669 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14670 case EM_X86_64:
8a9036a4 14671 case EM_L1OM:
7a9068fe 14672 case EM_K1OM:
aa137e4d 14673 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14674 case EM_S390_OLD:
14675 case EM_S390:
aa137e4d
NC
14676 return reloc_type == 23; /* R_S390_PC64. */
14677 case EM_TILEGX:
14678 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14679 default:
015dc7e1 14680 return false;
85acf597
RH
14681 }
14682}
14683
4dc3c23d
AM
14684/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14685 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14686
015dc7e1 14687static bool
dda8d76d 14688is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14689{
dda8d76d 14690 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14691 {
14692 case EM_CYGNUS_MN10200:
14693 case EM_MN10200:
14694 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14695 case EM_FT32:
14696 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14697 case EM_Z80:
14698 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14699 default:
015dc7e1 14700 return false;
4dc3c23d
AM
14701 }
14702}
14703
aca88567
NC
14704/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14705 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14706
015dc7e1 14707static bool
dda8d76d 14708is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14709{
d347c9df 14710 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14711 switch (filedata->file_header.e_machine)
4b78141a 14712 {
886a2506
NC
14713 case EM_ARC:
14714 case EM_ARC_COMPACT:
14715 case EM_ARC_COMPACT2:
13aa307c
CZ
14716 case EM_ARC_COMPACT3:
14717 case EM_ARC_COMPACT3_64:
886a2506 14718 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14719 case EM_ADAPTEVA_EPIPHANY:
14720 return reloc_type == 5;
aca88567
NC
14721 case EM_AVR_OLD:
14722 case EM_AVR:
14723 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14724 case EM_CYGNUS_D10V:
14725 case EM_D10V:
14726 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14727 case EM_FT32:
14728 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14729 case EM_H8S:
14730 case EM_H8_300:
14731 case EM_H8_300H:
aca88567
NC
14732 return reloc_type == R_H8_DIR16;
14733 case EM_IP2K_OLD:
14734 case EM_IP2K:
14735 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14736 case EM_M32C_OLD:
f4236fe4
DD
14737 case EM_M32C:
14738 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14739 case EM_CYGNUS_MN10200:
14740 case EM_MN10200:
14741 return reloc_type == 2; /* R_MN10200_16. */
14742 case EM_CYGNUS_MN10300:
14743 case EM_MN10300:
14744 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14745 case EM_MSP430:
dda8d76d 14746 if (uses_msp430x_relocs (filedata))
13761a11 14747 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14748 /* Fall through. */
78c8d46c 14749 case EM_MSP430_OLD:
aca88567 14750 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 14751 case EM_NDS32:
81c5e376 14752 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 14753 case EM_ALTERA_NIOS2:
36591ba1 14754 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14755 case EM_NIOS32:
14756 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14757 case EM_OR1K:
14758 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14759 case EM_RISCV:
14760 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14761 case EM_TI_PRU:
14762 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14763 case EM_TI_C6000:
14764 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14765 case EM_VISIUM:
14766 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
14767 case EM_XGATE:
14768 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14769 case EM_Z80:
14770 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14771 default:
015dc7e1 14772 return false;
4b78141a
NC
14773 }
14774}
14775
39e07931
AS
14776/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14777 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14778
015dc7e1 14779static bool
39e07931
AS
14780is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14781{
14782 switch (filedata->file_header.e_machine)
14783 {
14784 case EM_RISCV:
14785 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14786 case EM_Z80:
14787 return reloc_type == 1; /* R_Z80_8. */
39e07931 14788 default:
015dc7e1 14789 return false;
39e07931
AS
14790 }
14791}
14792
14793/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14794 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14795
015dc7e1 14796static bool
39e07931
AS
14797is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14798{
14799 switch (filedata->file_header.e_machine)
14800 {
14801 case EM_RISCV:
14802 return reloc_type == 53; /* R_RISCV_SET6. */
14803 default:
015dc7e1 14804 return false;
39e07931
AS
14805 }
14806}
14807
03336641
JW
14808/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14809 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14810
015dc7e1 14811static bool
03336641
JW
14812is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14813{
14814 /* Please keep this table alpha-sorted for ease of visual lookup. */
14815 switch (filedata->file_header.e_machine)
14816 {
76244462 14817 case EM_LOONGARCH:
14818 return reloc_type == 50; /* R_LARCH_ADD32. */
03336641
JW
14819 case EM_RISCV:
14820 return reloc_type == 35; /* R_RISCV_ADD32. */
14821 default:
015dc7e1 14822 return false;
03336641
JW
14823 }
14824}
14825
14826/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14827 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14828
015dc7e1 14829static bool
03336641
JW
14830is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14831{
14832 /* Please keep this table alpha-sorted for ease of visual lookup. */
14833 switch (filedata->file_header.e_machine)
14834 {
76244462 14835 case EM_LOONGARCH:
14836 return reloc_type == 55; /* R_LARCH_SUB32. */
03336641
JW
14837 case EM_RISCV:
14838 return reloc_type == 39; /* R_RISCV_SUB32. */
14839 default:
015dc7e1 14840 return false;
03336641
JW
14841 }
14842}
14843
14844/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14845 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14846
015dc7e1 14847static bool
03336641
JW
14848is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14849{
14850 /* Please keep this table alpha-sorted for ease of visual lookup. */
14851 switch (filedata->file_header.e_machine)
14852 {
76244462 14853 case EM_LOONGARCH:
14854 return reloc_type == 51; /* R_LARCH_ADD64. */
03336641
JW
14855 case EM_RISCV:
14856 return reloc_type == 36; /* R_RISCV_ADD64. */
14857 default:
015dc7e1 14858 return false;
03336641
JW
14859 }
14860}
14861
14862/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14863 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14864
015dc7e1 14865static bool
03336641
JW
14866is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14867{
14868 /* Please keep this table alpha-sorted for ease of visual lookup. */
14869 switch (filedata->file_header.e_machine)
14870 {
76244462 14871 case EM_LOONGARCH:
14872 return reloc_type == 56; /* R_LARCH_SUB64. */
03336641
JW
14873 case EM_RISCV:
14874 return reloc_type == 40; /* R_RISCV_SUB64. */
14875 default:
015dc7e1 14876 return false;
03336641
JW
14877 }
14878}
14879
14880/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14881 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14882
015dc7e1 14883static bool
03336641
JW
14884is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14885{
14886 /* Please keep this table alpha-sorted for ease of visual lookup. */
14887 switch (filedata->file_header.e_machine)
14888 {
76244462 14889 case EM_LOONGARCH:
14890 return reloc_type == 48; /* R_LARCH_ADD16. */
03336641
JW
14891 case EM_RISCV:
14892 return reloc_type == 34; /* R_RISCV_ADD16. */
14893 default:
015dc7e1 14894 return false;
03336641
JW
14895 }
14896}
14897
14898/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14899 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14900
015dc7e1 14901static bool
03336641
JW
14902is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14903{
14904 /* Please keep this table alpha-sorted for ease of visual lookup. */
14905 switch (filedata->file_header.e_machine)
14906 {
76244462 14907 case EM_LOONGARCH:
14908 return reloc_type == 53; /* R_LARCH_SUB16. */
03336641
JW
14909 case EM_RISCV:
14910 return reloc_type == 38; /* R_RISCV_SUB16. */
14911 default:
015dc7e1 14912 return false;
03336641
JW
14913 }
14914}
14915
14916/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14917 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14918
015dc7e1 14919static bool
03336641
JW
14920is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14921{
14922 /* Please keep this table alpha-sorted for ease of visual lookup. */
14923 switch (filedata->file_header.e_machine)
14924 {
76244462 14925 case EM_LOONGARCH:
14926 return reloc_type == 47; /* R_LARCH_ADD8. */
03336641
JW
14927 case EM_RISCV:
14928 return reloc_type == 33; /* R_RISCV_ADD8. */
14929 default:
015dc7e1 14930 return false;
03336641
JW
14931 }
14932}
14933
14934/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14935 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14936
015dc7e1 14937static bool
03336641
JW
14938is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14939{
14940 /* Please keep this table alpha-sorted for ease of visual lookup. */
14941 switch (filedata->file_header.e_machine)
14942 {
76244462 14943 case EM_LOONGARCH:
14944 return reloc_type == 52; /* R_LARCH_SUB8. */
03336641
JW
14945 case EM_RISCV:
14946 return reloc_type == 37; /* R_RISCV_SUB8. */
14947 default:
015dc7e1 14948 return false;
03336641
JW
14949 }
14950}
14951
76244462 14952/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14953 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
14954
14955static bool
14956is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14957{
14958 switch (filedata->file_header.e_machine)
14959 {
14960 case EM_LOONGARCH:
14961 return reloc_type == 105; /* R_LARCH_ADD6. */
14962 default:
14963 return false;
14964 }
14965}
14966
39e07931
AS
14967/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14968 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14969
015dc7e1 14970static bool
39e07931
AS
14971is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14972{
14973 switch (filedata->file_header.e_machine)
14974 {
76244462 14975 case EM_LOONGARCH:
14976 return reloc_type == 106; /* R_LARCH_SUB6. */
39e07931
AS
14977 case EM_RISCV:
14978 return reloc_type == 52; /* R_RISCV_SUB6. */
14979 default:
015dc7e1 14980 return false;
39e07931
AS
14981 }
14982}
14983
2a7b2e88
JK
14984/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14985 relocation entries (possibly formerly used for SHT_GROUP sections). */
14986
015dc7e1 14987static bool
dda8d76d 14988is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14989{
dda8d76d 14990 switch (filedata->file_header.e_machine)
2a7b2e88 14991 {
cb8f3167 14992 case EM_386: /* R_386_NONE. */
d347c9df 14993 case EM_68K: /* R_68K_NONE. */
cfb8c092 14994 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14995 case EM_ALPHA: /* R_ALPHA_NONE. */
14996 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14997 case EM_ARC: /* R_ARC_NONE. */
886a2506 14998 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14999 case EM_ARC_COMPACT: /* R_ARC_NONE. */
13aa307c
CZ
15000 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
15001 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
cb8f3167 15002 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 15003 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
15004 case EM_FT32: /* R_FT32_NONE. */
15005 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 15006 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
15007 case EM_L1OM: /* R_X86_64_NONE. */
15008 case EM_M32R: /* R_M32R_NONE. */
15009 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 15010 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 15011 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
15012 case EM_NIOS32: /* R_NIOS_NONE. */
15013 case EM_OR1K: /* R_OR1K_NONE. */
15014 case EM_PARISC: /* R_PARISC_NONE. */
15015 case EM_PPC64: /* R_PPC64_NONE. */
15016 case EM_PPC: /* R_PPC_NONE. */
e23eba97 15017 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
15018 case EM_S390: /* R_390_NONE. */
15019 case EM_S390_OLD:
15020 case EM_SH: /* R_SH_NONE. */
15021 case EM_SPARC32PLUS:
15022 case EM_SPARC: /* R_SPARC_NONE. */
15023 case EM_SPARCV9:
aa137e4d
NC
15024 case EM_TILEGX: /* R_TILEGX_NONE. */
15025 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
15026 case EM_TI_C6000:/* R_C6000_NONE. */
15027 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 15028 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 15029 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 15030 return reloc_type == 0;
d347c9df 15031
a06ea964
NC
15032 case EM_AARCH64:
15033 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
15034 case EM_AVR_OLD:
15035 case EM_AVR:
15036 return (reloc_type == 0 /* R_AVR_NONE. */
15037 || reloc_type == 30 /* R_AVR_DIFF8. */
15038 || reloc_type == 31 /* R_AVR_DIFF16. */
15039 || reloc_type == 32 /* R_AVR_DIFF32. */);
15040 case EM_METAG:
15041 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 15042 case EM_NDS32:
81c5e376
AM
15043 return (reloc_type == 0 /* R_NDS32_NONE. */
15044 || reloc_type == 205 /* R_NDS32_DIFF8. */
15045 || reloc_type == 206 /* R_NDS32_DIFF16. */
15046 || reloc_type == 207 /* R_NDS32_DIFF32. */
15047 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
15048 case EM_TI_PRU:
15049 return (reloc_type == 0 /* R_PRU_NONE. */
15050 || reloc_type == 65 /* R_PRU_DIFF8. */
15051 || reloc_type == 66 /* R_PRU_DIFF16. */
15052 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
15053 case EM_XTENSA_OLD:
15054 case EM_XTENSA:
4dc3c23d
AM
15055 return (reloc_type == 0 /* R_XTENSA_NONE. */
15056 || reloc_type == 17 /* R_XTENSA_DIFF8. */
15057 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
15058 || reloc_type == 19 /* R_XTENSA_DIFF32. */
15059 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
15060 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
15061 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
15062 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
15063 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
15064 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 15065 }
015dc7e1 15066 return false;
2a7b2e88
JK
15067}
15068
d1c4b12b
NC
15069/* Returns TRUE if there is a relocation against
15070 section NAME at OFFSET bytes. */
15071
015dc7e1 15072bool
31e5a3a3 15073reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
15074{
15075 Elf_Internal_Rela * relocs;
15076 Elf_Internal_Rela * rp;
15077
15078 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 15079 return false;
d1c4b12b
NC
15080
15081 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
15082
15083 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
15084 if (rp->r_offset == offset)
015dc7e1 15085 return true;
d1c4b12b 15086
015dc7e1 15087 return false;
d1c4b12b
NC
15088}
15089
cf13d699 15090/* Apply relocations to a section.
32ec8896
NC
15091 Returns TRUE upon success, FALSE otherwise.
15092 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
15093 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
15094 will be set to the number of relocs loaded.
15095
cf13d699 15096 Note: So far support has been added only for those relocations
32ec8896
NC
15097 which can be found in debug sections. FIXME: Add support for
15098 more relocations ? */
1b315056 15099
015dc7e1 15100static bool
be7d229a
AM
15101apply_relocations (Filedata *filedata,
15102 const Elf_Internal_Shdr *section,
15103 unsigned char *start,
15104 size_t size,
15105 void **relocs_return,
26c527e6 15106 uint64_t *num_relocs_return)
1b315056 15107{
cf13d699 15108 Elf_Internal_Shdr * relsec;
0d2a7a93 15109 unsigned char * end = start + size;
cb8f3167 15110
d1c4b12b
NC
15111 if (relocs_return != NULL)
15112 {
15113 * (Elf_Internal_Rela **) relocs_return = NULL;
15114 * num_relocs_return = 0;
15115 }
15116
dda8d76d 15117 if (filedata->file_header.e_type != ET_REL)
32ec8896 15118 /* No relocs to apply. */
015dc7e1 15119 return true;
1b315056 15120
cf13d699 15121 /* Find the reloc section associated with the section. */
dda8d76d
NC
15122 for (relsec = filedata->section_headers;
15123 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 15124 ++relsec)
252b5132 15125 {
015dc7e1 15126 bool is_rela;
26c527e6 15127 uint64_t num_relocs;
2cf0635d
NC
15128 Elf_Internal_Rela * relocs;
15129 Elf_Internal_Rela * rp;
15130 Elf_Internal_Shdr * symsec;
15131 Elf_Internal_Sym * symtab;
26c527e6 15132 uint64_t num_syms;
2cf0635d 15133 Elf_Internal_Sym * sym;
252b5132 15134
41e92641 15135 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15136 || relsec->sh_info >= filedata->file_header.e_shnum
15137 || filedata->section_headers + relsec->sh_info != section
c256ffe7 15138 || relsec->sh_size == 0
dda8d76d 15139 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 15140 continue;
428409d5 15141
a788aedd
AM
15142 symsec = filedata->section_headers + relsec->sh_link;
15143 if (symsec->sh_type != SHT_SYMTAB
15144 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 15145 return false;
a788aedd 15146
41e92641
NC
15147 is_rela = relsec->sh_type == SHT_RELA;
15148
15149 if (is_rela)
15150 {
dda8d76d 15151 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 15152 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15153 return false;
41e92641
NC
15154 }
15155 else
15156 {
dda8d76d 15157 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 15158 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15159 return false;
41e92641
NC
15160 }
15161
15162 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 15163 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 15164 is_rela = false;
428409d5 15165
4de91c10 15166 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 15167
41e92641 15168 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 15169 {
625d49fc 15170 uint64_t addend;
015dc7e1
AM
15171 unsigned int reloc_type;
15172 unsigned int reloc_size;
15173 bool reloc_inplace = false;
15174 bool reloc_subtract = false;
15175 unsigned char *rloc;
26c527e6 15176 uint64_t sym_index;
4b78141a 15177
dda8d76d 15178 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 15179
dda8d76d 15180 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 15181 continue;
dda8d76d 15182 else if (is_none_reloc (filedata, reloc_type))
98fb390a 15183 continue;
dda8d76d
NC
15184 else if (is_32bit_abs_reloc (filedata, reloc_type)
15185 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 15186 reloc_size = 4;
dda8d76d
NC
15187 else if (is_64bit_abs_reloc (filedata, reloc_type)
15188 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 15189 reloc_size = 8;
dda8d76d 15190 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15191 reloc_size = 3;
dda8d76d 15192 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15193 reloc_size = 2;
39e07931
AS
15194 else if (is_8bit_abs_reloc (filedata, reloc_type)
15195 || is_6bit_abs_reloc (filedata, reloc_type))
15196 reloc_size = 1;
03336641
JW
15197 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15198 reloc_type))
15199 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15200 {
15201 reloc_size = 4;
015dc7e1 15202 reloc_inplace = true;
03336641
JW
15203 }
15204 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15205 reloc_type))
15206 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15207 {
15208 reloc_size = 8;
015dc7e1 15209 reloc_inplace = true;
03336641
JW
15210 }
15211 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15212 reloc_type))
15213 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15214 {
15215 reloc_size = 2;
015dc7e1 15216 reloc_inplace = true;
03336641
JW
15217 }
15218 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15219 reloc_type))
15220 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15221 {
15222 reloc_size = 1;
015dc7e1 15223 reloc_inplace = true;
03336641 15224 }
39e07931 15225 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
76244462 15226 reloc_type))
15227 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15228 {
15229 reloc_size = 1;
015dc7e1 15230 reloc_inplace = true;
39e07931 15231 }
aca88567 15232 else
4b78141a 15233 {
bee0ee85 15234 static unsigned int prev_reloc = 0;
dda8d76d 15235
bee0ee85
NC
15236 if (reloc_type != prev_reloc)
15237 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15238 reloc_type, printable_section_name (filedata, section));
bee0ee85 15239 prev_reloc = reloc_type;
4b78141a
NC
15240 continue;
15241 }
103f02d3 15242
91d6fa6a 15243 rloc = start + rp->r_offset;
75802ccb 15244 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 15245 {
26c527e6
AM
15246 warn (_("skipping invalid relocation offset %#" PRIx64
15247 " in section %s\n"),
15248 rp->r_offset,
dda8d76d 15249 printable_section_name (filedata, section));
700dd8b7
L
15250 continue;
15251 }
103f02d3 15252
26c527e6 15253 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
15254 if (sym_index >= num_syms)
15255 {
26c527e6
AM
15256 warn (_("skipping invalid relocation symbol index %#" PRIx64
15257 " in section %s\n"),
dda8d76d 15258 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15259 continue;
15260 }
15261 sym = symtab + sym_index;
41e92641
NC
15262
15263 /* If the reloc has a symbol associated with it,
55f25fc3
L
15264 make sure that it is of an appropriate type.
15265
15266 Relocations against symbols without type can happen.
15267 Gcc -feliminate-dwarf2-dups may generate symbols
15268 without type for debug info.
15269
15270 Icc generates relocations against function symbols
15271 instead of local labels.
15272
15273 Relocations against object symbols can happen, eg when
15274 referencing a global array. For an example of this see
15275 the _clz.o binary in libgcc.a. */
aca88567 15276 if (sym != symtab
b8871f35 15277 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15278 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15279 {
26c527e6 15280 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
15281 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15282 printable_section_name (filedata, relsec),
26c527e6 15283 rp - relocs);
aca88567 15284 continue;
5b18a4bc 15285 }
252b5132 15286
4dc3c23d
AM
15287 addend = 0;
15288 if (is_rela)
15289 addend += rp->r_addend;
c47320c3
AM
15290 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15291 partial_inplace. */
4dc3c23d 15292 if (!is_rela
dda8d76d 15293 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15294 && reloc_type == 1)
dda8d76d
NC
15295 || ((filedata->file_header.e_machine == EM_PJ
15296 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15297 && reloc_type == 1)
dda8d76d
NC
15298 || ((filedata->file_header.e_machine == EM_D30V
15299 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15300 && reloc_type == 12)
15301 || reloc_inplace)
39e07931
AS
15302 {
15303 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15304 addend += byte_get (rloc, reloc_size) & 0x3f;
15305 else
15306 addend += byte_get (rloc, reloc_size);
15307 }
cb8f3167 15308
dda8d76d
NC
15309 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15310 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15311 {
15312 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15313 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15314 addend -= 8;
91d6fa6a 15315 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15316 reloc_size);
15317 }
39e07931 15318 else if (is_6bit_abs_reloc (filedata, reloc_type)
76244462 15319 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
15320 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15321 {
15322 if (reloc_subtract)
15323 addend -= sym->st_value;
15324 else
15325 addend += sym->st_value;
15326 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15327 byte_put (rloc, addend, reloc_size);
15328 }
03336641
JW
15329 else if (reloc_subtract)
15330 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15331 else
91d6fa6a 15332 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15333 }
252b5132 15334
5b18a4bc 15335 free (symtab);
f84ce13b
NC
15336 /* Let the target specific reloc processing code know that
15337 we have finished with these relocs. */
dda8d76d 15338 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15339
15340 if (relocs_return)
15341 {
15342 * (Elf_Internal_Rela **) relocs_return = relocs;
15343 * num_relocs_return = num_relocs;
15344 }
15345 else
15346 free (relocs);
15347
5b18a4bc
NC
15348 break;
15349 }
32ec8896 15350
015dc7e1 15351 return true;
5b18a4bc 15352}
103f02d3 15353
cf13d699 15354#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15355static bool
dda8d76d 15356disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15357{
dda8d76d 15358 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15359
74e1a04b 15360 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15361
015dc7e1 15362 return true;
cf13d699
NC
15363}
15364#endif
15365
15366/* Reads in the contents of SECTION from FILE, returning a pointer
15367 to a malloc'ed buffer or NULL if something went wrong. */
15368
15369static char *
dda8d76d 15370get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15371{
be7d229a 15372 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15373
15374 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15375 {
c6b78c96 15376 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15377 printable_section_name (filedata, section));
cf13d699
NC
15378 return NULL;
15379 }
15380
dda8d76d 15381 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15382 _("section contents"));
cf13d699
NC
15383}
15384
1f5a3546 15385/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 15386
015dc7e1 15387static bool
45f5fe46
NC
15388uncompress_section_contents (bool is_zstd,
15389 unsigned char ** buffer,
15390 uint64_t uncompressed_size,
15391 uint64_t * size,
15392 uint64_t file_size)
0e602686 15393{
31e5a3a3
AM
15394 uint64_t compressed_size = *size;
15395 unsigned char *compressed_buffer = *buffer;
45f5fe46 15396 unsigned char *uncompressed_buffer = NULL;
0e602686
NC
15397 z_stream strm;
15398 int rc;
15399
45f5fe46
NC
15400 /* Similar to _bfd_section_size_insane() in the BFD library we expect an
15401 upper limit of ~10x compression. Any compression larger than that is
15402 thought to be due to fuzzing of the compression header. */
15403 if (uncompressed_size > file_size * 10)
15404 {
15405 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
15406 uncompressed_size);
15407 goto fail;
15408 }
15409
15410 uncompressed_buffer = xmalloc (uncompressed_size);
15411
1f5a3546
FS
15412 if (is_zstd)
15413 {
15414#ifdef HAVE_ZSTD
15415 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15416 compressed_buffer, compressed_size);
15417 if (ZSTD_isError (ret))
15418 goto fail;
15419#endif
15420 }
15421 else
15422 {
15423 /* It is possible the section consists of several compressed
15424 buffers concatenated together, so we uncompress in a loop. */
15425 /* PR 18313: The state field in the z_stream structure is supposed
15426 to be invisible to the user (ie us), but some compilers will
15427 still complain about it being used without initialisation. So
15428 we first zero the entire z_stream structure and then set the fields
15429 that we need. */
15430 memset (&strm, 0, sizeof strm);
15431 strm.avail_in = compressed_size;
15432 strm.next_in = (Bytef *)compressed_buffer;
15433 strm.avail_out = uncompressed_size;
15434
15435 rc = inflateInit (&strm);
15436 while (strm.avail_in > 0)
15437 {
15438 if (rc != Z_OK)
15439 break;
15440 strm.next_out = ((Bytef *)uncompressed_buffer
15441 + (uncompressed_size - strm.avail_out));
15442 rc = inflate (&strm, Z_FINISH);
15443 if (rc != Z_STREAM_END)
15444 break;
15445 rc = inflateReset (&strm);
15446 }
15447 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15448 goto fail;
15449 }
0e602686
NC
15450
15451 *buffer = uncompressed_buffer;
15452 *size = uncompressed_size;
015dc7e1 15453 return true;
0e602686
NC
15454
15455 fail:
15456 free (uncompressed_buffer);
15457 /* Indicate decompression failure. */
15458 *buffer = NULL;
015dc7e1 15459 return false;
0e602686 15460}
dd24e3da 15461
015dc7e1 15462static bool
dda8d76d 15463dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15464{
015dc7e1 15465 Elf_Internal_Shdr *relsec;
be7d229a 15466 uint64_t num_bytes;
015dc7e1
AM
15467 unsigned char *data;
15468 unsigned char *end;
15469 unsigned char *real_start;
15470 unsigned char *start;
15471 bool some_strings_shown;
cf13d699 15472
dda8d76d 15473 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15474 if (start == NULL)
c6b78c96 15475 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15476 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15477
0e602686 15478 num_bytes = section->sh_size;
cf13d699 15479
835f2fae
NC
15480 if (filedata->is_separate)
15481 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15482 printable_section_name (filedata, section),
15483 filedata->file_name);
15484 else
15485 printf (_("\nString dump of section '%s':\n"),
15486 printable_section_name (filedata, section));
cf13d699 15487
0e602686
NC
15488 if (decompress_dumps)
15489 {
31e5a3a3
AM
15490 uint64_t new_size = num_bytes;
15491 uint64_t uncompressed_size = 0;
1f5a3546 15492 bool is_zstd = false;
0e602686
NC
15493
15494 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15495 {
15496 Elf_Internal_Chdr chdr;
15497 unsigned int compression_header_size
ebdf1ebf
NC
15498 = get_compression_header (& chdr, (unsigned char *) start,
15499 num_bytes);
5844b465
NC
15500 if (compression_header_size == 0)
15501 /* An error message will have already been generated
15502 by get_compression_header. */
15503 goto error_out;
0e602686 15504
89dbeac7 15505 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
15506 ;
15507#ifdef HAVE_ZSTD
89dbeac7 15508 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
15509 is_zstd = true;
15510#endif
15511 else
0e602686 15512 {
813dabb9 15513 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15514 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15515 goto error_out;
813dabb9 15516 }
813dabb9
L
15517 uncompressed_size = chdr.ch_size;
15518 start += compression_header_size;
15519 new_size -= compression_header_size;
0e602686
NC
15520 }
15521 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15522 {
15523 /* Read the zlib header. In this case, it should be "ZLIB"
15524 followed by the uncompressed section size, 8 bytes in
15525 big-endian order. */
15526 uncompressed_size = start[4]; uncompressed_size <<= 8;
15527 uncompressed_size += start[5]; uncompressed_size <<= 8;
15528 uncompressed_size += start[6]; uncompressed_size <<= 8;
15529 uncompressed_size += start[7]; uncompressed_size <<= 8;
15530 uncompressed_size += start[8]; uncompressed_size <<= 8;
15531 uncompressed_size += start[9]; uncompressed_size <<= 8;
15532 uncompressed_size += start[10]; uncompressed_size <<= 8;
15533 uncompressed_size += start[11];
15534 start += 12;
15535 new_size -= 12;
15536 }
15537
1835f746
NC
15538 if (uncompressed_size)
15539 {
1f5a3546 15540 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 15541 &new_size, filedata->file_size))
1835f746
NC
15542 num_bytes = new_size;
15543 else
15544 {
15545 error (_("Unable to decompress section %s\n"),
dda8d76d 15546 printable_section_name (filedata, section));
f761cb13 15547 goto error_out;
1835f746
NC
15548 }
15549 }
bc303e5d
NC
15550 else
15551 start = real_start;
0e602686 15552 }
fd8008d8 15553
cf13d699
NC
15554 /* If the section being dumped has relocations against it the user might
15555 be expecting these relocations to have been applied. Check for this
15556 case and issue a warning message in order to avoid confusion.
15557 FIXME: Maybe we ought to have an option that dumps a section with
15558 relocs applied ? */
dda8d76d
NC
15559 for (relsec = filedata->section_headers;
15560 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15561 ++relsec)
15562 {
15563 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15564 || relsec->sh_info >= filedata->file_header.e_shnum
15565 || filedata->section_headers + relsec->sh_info != section
cf13d699 15566 || relsec->sh_size == 0
dda8d76d 15567 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15568 continue;
15569
15570 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15571 break;
15572 }
15573
cf13d699
NC
15574 data = start;
15575 end = start + num_bytes;
015dc7e1 15576 some_strings_shown = false;
cf13d699 15577
ba3265d0
NC
15578#ifdef HAVE_MBSTATE_T
15579 mbstate_t state;
15580 /* Initialise the multibyte conversion state. */
15581 memset (& state, 0, sizeof (state));
15582#endif
15583
015dc7e1 15584 bool continuing = false;
ba3265d0 15585
cf13d699
NC
15586 while (data < end)
15587 {
15588 while (!ISPRINT (* data))
15589 if (++ data >= end)
15590 break;
15591
15592 if (data < end)
15593 {
071436c6
NC
15594 size_t maxlen = end - data;
15595
ba3265d0
NC
15596 if (continuing)
15597 {
15598 printf (" ");
015dc7e1 15599 continuing = false;
ba3265d0
NC
15600 }
15601 else
15602 {
26c527e6 15603 printf (" [%6tx] ", data - start);
ba3265d0
NC
15604 }
15605
4082ef84
NC
15606 if (maxlen > 0)
15607 {
f3da8a96 15608 char c = 0;
ba3265d0
NC
15609
15610 while (maxlen)
15611 {
15612 c = *data++;
15613
15614 if (c == 0)
15615 break;
15616
15617 /* PR 25543: Treat new-lines as string-ending characters. */
15618 if (c == '\n')
15619 {
15620 printf ("\\n\n");
15621 if (*data != 0)
015dc7e1 15622 continuing = true;
ba3265d0
NC
15623 break;
15624 }
15625
15626 /* Do not print control characters directly as they can affect terminal
15627 settings. Such characters usually appear in the names generated
15628 by the assembler for local labels. */
15629 if (ISCNTRL (c))
15630 {
15631 printf ("^%c", c + 0x40);
15632 }
15633 else if (ISPRINT (c))
15634 {
15635 putchar (c);
15636 }
15637 else
15638 {
15639 size_t n;
15640#ifdef HAVE_MBSTATE_T
15641 wchar_t w;
15642#endif
15643 /* Let printf do the hard work of displaying multibyte characters. */
15644 printf ("%.1s", data - 1);
15645#ifdef HAVE_MBSTATE_T
15646 /* Try to find out how many bytes made up the character that was
15647 just printed. Advance the symbol pointer past the bytes that
15648 were displayed. */
15649 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15650#else
15651 n = 1;
15652#endif
15653 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15654 data += (n - 1);
15655 }
15656 }
15657
15658 if (c != '\n')
15659 putchar ('\n');
4082ef84
NC
15660 }
15661 else
15662 {
15663 printf (_("<corrupt>\n"));
15664 data = end;
15665 }
015dc7e1 15666 some_strings_shown = true;
cf13d699
NC
15667 }
15668 }
15669
15670 if (! some_strings_shown)
15671 printf (_(" No strings found in this section."));
15672
0e602686 15673 free (real_start);
cf13d699
NC
15674
15675 putchar ('\n');
015dc7e1 15676 return true;
f761cb13
AM
15677
15678error_out:
15679 free (real_start);
015dc7e1 15680 return false;
cf13d699
NC
15681}
15682
015dc7e1
AM
15683static bool
15684dump_section_as_bytes (Elf_Internal_Shdr *section,
15685 Filedata *filedata,
15686 bool relocate)
cf13d699 15687{
be7d229a
AM
15688 Elf_Internal_Shdr *relsec;
15689 size_t bytes;
15690 uint64_t section_size;
625d49fc 15691 uint64_t addr;
be7d229a
AM
15692 unsigned char *data;
15693 unsigned char *real_start;
15694 unsigned char *start;
0e602686 15695
dda8d76d 15696 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15697 if (start == NULL)
c6b78c96 15698 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15699 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15700
0e602686 15701 section_size = section->sh_size;
cf13d699 15702
835f2fae
NC
15703 if (filedata->is_separate)
15704 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15705 printable_section_name (filedata, section),
15706 filedata->file_name);
15707 else
15708 printf (_("\nHex dump of section '%s':\n"),
15709 printable_section_name (filedata, section));
cf13d699 15710
0e602686
NC
15711 if (decompress_dumps)
15712 {
31e5a3a3
AM
15713 uint64_t new_size = section_size;
15714 uint64_t uncompressed_size = 0;
1f5a3546 15715 bool is_zstd = false;
0e602686
NC
15716
15717 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15718 {
15719 Elf_Internal_Chdr chdr;
15720 unsigned int compression_header_size
ebdf1ebf 15721 = get_compression_header (& chdr, start, section_size);
0e602686 15722
5844b465
NC
15723 if (compression_header_size == 0)
15724 /* An error message will have already been generated
15725 by get_compression_header. */
15726 goto error_out;
15727
89dbeac7 15728 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
15729 ;
15730#ifdef HAVE_ZSTD
89dbeac7 15731 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
15732 is_zstd = true;
15733#endif
15734 else
0e602686 15735 {
813dabb9 15736 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15737 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15738 goto error_out;
0e602686 15739 }
813dabb9
L
15740 uncompressed_size = chdr.ch_size;
15741 start += compression_header_size;
15742 new_size -= compression_header_size;
0e602686
NC
15743 }
15744 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15745 {
15746 /* Read the zlib header. In this case, it should be "ZLIB"
15747 followed by the uncompressed section size, 8 bytes in
15748 big-endian order. */
15749 uncompressed_size = start[4]; uncompressed_size <<= 8;
15750 uncompressed_size += start[5]; uncompressed_size <<= 8;
15751 uncompressed_size += start[6]; uncompressed_size <<= 8;
15752 uncompressed_size += start[7]; uncompressed_size <<= 8;
15753 uncompressed_size += start[8]; uncompressed_size <<= 8;
15754 uncompressed_size += start[9]; uncompressed_size <<= 8;
15755 uncompressed_size += start[10]; uncompressed_size <<= 8;
15756 uncompressed_size += start[11];
15757 start += 12;
15758 new_size -= 12;
15759 }
15760
f055032e
NC
15761 if (uncompressed_size)
15762 {
1f5a3546 15763 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 15764 &new_size, filedata->file_size))
bc303e5d
NC
15765 {
15766 section_size = new_size;
15767 }
f055032e
NC
15768 else
15769 {
15770 error (_("Unable to decompress section %s\n"),
dda8d76d 15771 printable_section_name (filedata, section));
bc303e5d 15772 /* FIXME: Print the section anyway ? */
f761cb13 15773 goto error_out;
f055032e
NC
15774 }
15775 }
bc303e5d
NC
15776 else
15777 start = real_start;
0e602686 15778 }
14ae95f2 15779
cf13d699
NC
15780 if (relocate)
15781 {
dda8d76d 15782 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15783 goto error_out;
cf13d699
NC
15784 }
15785 else
15786 {
15787 /* If the section being dumped has relocations against it the user might
15788 be expecting these relocations to have been applied. Check for this
15789 case and issue a warning message in order to avoid confusion.
15790 FIXME: Maybe we ought to have an option that dumps a section with
15791 relocs applied ? */
dda8d76d
NC
15792 for (relsec = filedata->section_headers;
15793 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15794 ++relsec)
15795 {
15796 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15797 || relsec->sh_info >= filedata->file_header.e_shnum
15798 || filedata->section_headers + relsec->sh_info != section
cf13d699 15799 || relsec->sh_size == 0
dda8d76d 15800 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15801 continue;
15802
15803 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15804 break;
15805 }
15806 }
15807
15808 addr = section->sh_addr;
0e602686 15809 bytes = section_size;
cf13d699
NC
15810 data = start;
15811
15812 while (bytes)
15813 {
15814 int j;
15815 int k;
15816 int lbytes;
15817
15818 lbytes = (bytes > 16 ? 16 : bytes);
15819
26c527e6 15820 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
15821
15822 for (j = 0; j < 16; j++)
15823 {
15824 if (j < lbytes)
15825 printf ("%2.2x", data[j]);
15826 else
15827 printf (" ");
15828
15829 if ((j & 3) == 3)
15830 printf (" ");
15831 }
15832
15833 for (j = 0; j < lbytes; j++)
15834 {
15835 k = data[j];
15836 if (k >= ' ' && k < 0x7f)
15837 printf ("%c", k);
15838 else
15839 printf (".");
15840 }
15841
15842 putchar ('\n');
15843
15844 data += lbytes;
15845 addr += lbytes;
15846 bytes -= lbytes;
15847 }
15848
0e602686 15849 free (real_start);
cf13d699
NC
15850
15851 putchar ('\n');
015dc7e1 15852 return true;
f761cb13
AM
15853
15854 error_out:
15855 free (real_start);
015dc7e1 15856 return false;
cf13d699
NC
15857}
15858
094e34f2 15859#ifdef ENABLE_LIBCTF
7d9813f1
NA
15860static ctf_sect_t *
15861shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15862{
84714f86 15863 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15864 buf->cts_size = shdr->sh_size;
15865 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15866
15867 return buf;
15868}
15869
15870/* Formatting callback function passed to ctf_dump. Returns either the pointer
15871 it is passed, or a pointer to newly-allocated storage, in which case
15872 dump_ctf() will free it when it no longer needs it. */
15873
2f6ecaed
NA
15874static char *
15875dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15876 char *s, void *arg)
7d9813f1 15877{
3e50a591 15878 const char *blanks = arg;
7d9813f1
NA
15879 char *new_s;
15880
3e50a591 15881 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15882 return s;
15883 return new_s;
15884}
15885
926c9e76
NA
15886/* Dump CTF errors/warnings. */
15887static void
139633c3 15888dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15889{
15890 ctf_next_t *it = NULL;
15891 char *errtext;
15892 int is_warning;
15893 int err;
15894
15895 /* Dump accumulated errors and warnings. */
15896 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15897 {
5e9b84f7 15898 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15899 errtext);
15900 free (errtext);
15901 }
15902 if (err != ECTF_NEXT_END)
15903 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15904}
15905
2f6ecaed
NA
15906/* Dump one CTF archive member. */
15907
80b56fad
NA
15908static void
15909dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15910 size_t member)
2f6ecaed 15911{
2f6ecaed
NA
15912 const char *things[] = {"Header", "Labels", "Data objects",
15913 "Function objects", "Variables", "Types", "Strings",
15914 ""};
15915 const char **thing;
15916 size_t i;
15917
80b56fad
NA
15918 /* Don't print out the name of the default-named archive member if it appears
15919 first in the list. The name .ctf appears everywhere, even for things that
15920 aren't really archives, so printing it out is liable to be confusing; also,
15921 the common case by far is for only one archive member to exist, and hiding
15922 it in that case seems worthwhile. */
2f6ecaed 15923
80b56fad
NA
15924 if (strcmp (name, ".ctf") != 0 || member != 0)
15925 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15926
80b56fad
NA
15927 if (ctf_parent_name (ctf) != NULL)
15928 ctf_import (ctf, parent);
2f6ecaed
NA
15929
15930 for (i = 0, thing = things; *thing[0]; thing++, i++)
15931 {
15932 ctf_dump_state_t *s = NULL;
15933 char *item;
15934
15935 printf ("\n %s:\n", *thing);
15936 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15937 (void *) " ")) != NULL)
15938 {
15939 printf ("%s\n", item);
15940 free (item);
15941 }
15942
15943 if (ctf_errno (ctf))
15944 {
15945 error (_("Iteration failed: %s, %s\n"), *thing,
15946 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15947 break;
2f6ecaed
NA
15948 }
15949 }
8b37e7b6 15950
926c9e76 15951 dump_ctf_errs (ctf);
2f6ecaed
NA
15952}
15953
015dc7e1 15954static bool
7d9813f1
NA
15955dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15956{
7d9813f1
NA
15957 Elf_Internal_Shdr * symtab_sec = NULL;
15958 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15959 void * data = NULL;
15960 void * symdata = NULL;
15961 void * strdata = NULL;
80b56fad 15962 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15963 ctf_sect_t * symsectp = NULL;
15964 ctf_sect_t * strsectp = NULL;
2f6ecaed 15965 ctf_archive_t * ctfa = NULL;
139633c3 15966 ctf_dict_t * parent = NULL;
80b56fad 15967 ctf_dict_t * fp;
7d9813f1 15968
80b56fad
NA
15969 ctf_next_t *i = NULL;
15970 const char *name;
15971 size_t member = 0;
7d9813f1 15972 int err;
015dc7e1 15973 bool ret = false;
7d9813f1
NA
15974
15975 shdr_to_ctf_sect (&ctfsect, section, filedata);
15976 data = get_section_contents (section, filedata);
15977 ctfsect.cts_data = data;
15978
616febde 15979 if (!dump_ctf_symtab_name)
3d16b64e 15980 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15981
15982 if (!dump_ctf_strtab_name)
3d16b64e 15983 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15984
15985 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15986 {
15987 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15988 {
15989 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15990 goto fail;
15991 }
15992 if ((symdata = (void *) get_data (NULL, filedata,
15993 symtab_sec->sh_offset, 1,
15994 symtab_sec->sh_size,
15995 _("symbols"))) == NULL)
15996 goto fail;
15997 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15998 symsect.cts_data = symdata;
15999 }
835f2fae 16000
df16e041 16001 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
16002 {
16003 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
16004 {
16005 error (_("No string table section named %s\n"),
16006 dump_ctf_strtab_name);
16007 goto fail;
16008 }
16009 if ((strdata = (void *) get_data (NULL, filedata,
16010 strtab_sec->sh_offset, 1,
16011 strtab_sec->sh_size,
16012 _("strings"))) == NULL)
16013 goto fail;
16014 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
16015 strsect.cts_data = strdata;
16016 }
835f2fae 16017
2f6ecaed
NA
16018 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
16019 libctf papers over the difference, so we can pretend it is always an
80b56fad 16020 archive. */
7d9813f1 16021
2f6ecaed 16022 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 16023 {
926c9e76 16024 dump_ctf_errs (NULL);
7d9813f1
NA
16025 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16026 goto fail;
16027 }
16028
96c61be5
NA
16029 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
16030 != ELFDATA2MSB);
16031
80b56fad
NA
16032 /* Preload the parent dict, since it will need to be imported into every
16033 child in turn. */
16034 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 16035 {
926c9e76 16036 dump_ctf_errs (NULL);
2f6ecaed
NA
16037 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16038 goto fail;
7d9813f1
NA
16039 }
16040
015dc7e1 16041 ret = true;
7d9813f1 16042
835f2fae
NC
16043 if (filedata->is_separate)
16044 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
16045 printable_section_name (filedata, section),
16046 filedata->file_name);
16047 else
16048 printf (_("\nDump of CTF section '%s':\n"),
16049 printable_section_name (filedata, section));
7d9813f1 16050
80b56fad
NA
16051 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
16052 dump_ctf_archive_member (fp, name, parent, member++);
16053 if (err != ECTF_NEXT_END)
16054 {
16055 dump_ctf_errs (NULL);
16056 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
16057 ret = false;
16058 }
7d9813f1
NA
16059
16060 fail:
139633c3 16061 ctf_dict_close (parent);
2f6ecaed 16062 ctf_close (ctfa);
7d9813f1
NA
16063 free (data);
16064 free (symdata);
16065 free (strdata);
16066 return ret;
16067}
094e34f2 16068#endif
7d9813f1 16069
42b6953b
IB
16070static bool
16071dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
16072{
16073 void * data = NULL;
16074 sframe_decoder_ctx *sfd_ctx = NULL;
16075 const char *print_name = printable_section_name (filedata, section);
16076
16077 bool ret = true;
16078 size_t sf_size;
16079 int err = 0;
16080
16081 if (strcmp (print_name, "") == 0)
16082 {
16083 error (_("Section name must be provided \n"));
16084 ret = false;
16085 return ret;
16086 }
16087
16088 data = get_section_contents (section, filedata);
16089 sf_size = section->sh_size;
16090 /* Decode the contents of the section. */
16091 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
16092 if (!sfd_ctx)
16093 {
16094 ret = false;
16095 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
16096 goto fail;
16097 }
16098
16099 printf (_("Contents of the SFrame section %s:"), print_name);
16100 /* Dump the contents as text. */
16101 dump_sframe (sfd_ctx, section->sh_addr);
16102
16103 fail:
16104 free (data);
16105 return ret;
16106}
16107
015dc7e1 16108static bool
dda8d76d
NC
16109load_specific_debug_section (enum dwarf_section_display_enum debug,
16110 const Elf_Internal_Shdr * sec,
16111 void * data)
1007acb3 16112{
2cf0635d 16113 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 16114 char buf [64];
dda8d76d 16115 Filedata * filedata = (Filedata *) data;
9abca702 16116
19e6b90e 16117 if (section->start != NULL)
dda8d76d
NC
16118 {
16119 /* If it is already loaded, do nothing. */
16120 if (streq (section->filename, filedata->file_name))
015dc7e1 16121 return true;
dda8d76d
NC
16122 free (section->start);
16123 }
1007acb3 16124
19e6b90e
L
16125 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16126 section->address = sec->sh_addr;
dda8d76d
NC
16127 section->filename = filedata->file_name;
16128 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
16129 sec->sh_offset, 1,
16130 sec->sh_size, buf);
59245841
NC
16131 if (section->start == NULL)
16132 section->size = 0;
16133 else
16134 {
77115a4a 16135 unsigned char *start = section->start;
31e5a3a3
AM
16136 uint64_t size = sec->sh_size;
16137 uint64_t uncompressed_size = 0;
1f5a3546 16138 bool is_zstd = false;
77115a4a
L
16139
16140 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16141 {
16142 Elf_Internal_Chdr chdr;
d8024a91
NC
16143 unsigned int compression_header_size;
16144
f53be977
L
16145 if (size < (is_32bit_elf
16146 ? sizeof (Elf32_External_Chdr)
16147 : sizeof (Elf64_External_Chdr)))
d8024a91 16148 {
55be8fd0 16149 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 16150 section->name);
015dc7e1 16151 return false;
d8024a91
NC
16152 }
16153
ebdf1ebf 16154 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
16155 if (compression_header_size == 0)
16156 /* An error message will have already been generated
16157 by get_compression_header. */
015dc7e1 16158 return false;
d8024a91 16159
89dbeac7 16160 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16161 ;
16162#ifdef HAVE_ZSTD
89dbeac7 16163 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16164 is_zstd = true;
16165#endif
16166 else
813dabb9
L
16167 {
16168 warn (_("section '%s' has unsupported compress type: %d\n"),
16169 section->name, chdr.ch_type);
015dc7e1 16170 return false;
813dabb9 16171 }
dab394de 16172 uncompressed_size = chdr.ch_size;
77115a4a
L
16173 start += compression_header_size;
16174 size -= compression_header_size;
16175 }
dab394de
L
16176 else if (size > 12 && streq ((char *) start, "ZLIB"))
16177 {
16178 /* Read the zlib header. In this case, it should be "ZLIB"
16179 followed by the uncompressed section size, 8 bytes in
16180 big-endian order. */
16181 uncompressed_size = start[4]; uncompressed_size <<= 8;
16182 uncompressed_size += start[5]; uncompressed_size <<= 8;
16183 uncompressed_size += start[6]; uncompressed_size <<= 8;
16184 uncompressed_size += start[7]; uncompressed_size <<= 8;
16185 uncompressed_size += start[8]; uncompressed_size <<= 8;
16186 uncompressed_size += start[9]; uncompressed_size <<= 8;
16187 uncompressed_size += start[10]; uncompressed_size <<= 8;
16188 uncompressed_size += start[11];
16189 start += 12;
16190 size -= 12;
16191 }
16192
1835f746 16193 if (uncompressed_size)
77115a4a 16194 {
1f5a3546 16195 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16196 &size, filedata->file_size))
1835f746
NC
16197 {
16198 /* Free the compressed buffer, update the section buffer
16199 and the section size if uncompress is successful. */
16200 free (section->start);
16201 section->start = start;
16202 }
16203 else
16204 {
16205 error (_("Unable to decompress section %s\n"),
dda8d76d 16206 printable_section_name (filedata, sec));
015dc7e1 16207 return false;
1835f746 16208 }
77115a4a 16209 }
bc303e5d 16210
77115a4a 16211 section->size = size;
59245841 16212 }
4a114e3e 16213
1b315056 16214 if (section->start == NULL)
015dc7e1 16215 return false;
1b315056 16216
19e6b90e 16217 if (debug_displays [debug].relocate)
32ec8896 16218 {
dda8d76d 16219 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 16220 & section->reloc_info, & section->num_relocs))
015dc7e1 16221 return false;
32ec8896 16222 }
d1c4b12b
NC
16223 else
16224 {
16225 section->reloc_info = NULL;
16226 section->num_relocs = 0;
16227 }
1007acb3 16228
015dc7e1 16229 return true;
1007acb3
L
16230}
16231
301a9420
AM
16232#if HAVE_LIBDEBUGINFOD
16233/* Return a hex string representation of the build-id. */
16234unsigned char *
16235get_build_id (void * data)
16236{
ca0e11aa 16237 Filedata * filedata = (Filedata *) data;
301a9420 16238 Elf_Internal_Shdr * shdr;
26c527e6 16239 size_t i;
301a9420 16240
55be8fd0
NC
16241 /* Iterate through notes to find note.gnu.build-id.
16242 FIXME: Only the first note in any note section is examined. */
301a9420
AM
16243 for (i = 0, shdr = filedata->section_headers;
16244 i < filedata->file_header.e_shnum && shdr != NULL;
16245 i++, shdr++)
16246 {
16247 if (shdr->sh_type != SHT_NOTE)
16248 continue;
16249
16250 char * next;
16251 char * end;
16252 size_t data_remaining;
16253 size_t min_notesz;
16254 Elf_External_Note * enote;
16255 Elf_Internal_Note inote;
16256
625d49fc
AM
16257 uint64_t offset = shdr->sh_offset;
16258 uint64_t align = shdr->sh_addralign;
16259 uint64_t length = shdr->sh_size;
301a9420
AM
16260
16261 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16262 if (enote == NULL)
16263 continue;
16264
16265 if (align < 4)
16266 align = 4;
16267 else if (align != 4 && align != 8)
f761cb13
AM
16268 {
16269 free (enote);
16270 continue;
16271 }
301a9420
AM
16272
16273 end = (char *) enote + length;
16274 data_remaining = end - (char *) enote;
16275
16276 if (!is_ia64_vms (filedata))
16277 {
16278 min_notesz = offsetof (Elf_External_Note, name);
16279 if (data_remaining < min_notesz)
16280 {
55be8fd0
NC
16281 warn (_("\
16282malformed note encountered in section %s whilst scanning for build-id note\n"),
16283 printable_section_name (filedata, shdr));
f761cb13 16284 free (enote);
55be8fd0 16285 continue;
301a9420
AM
16286 }
16287 data_remaining -= min_notesz;
16288
16289 inote.type = BYTE_GET (enote->type);
16290 inote.namesz = BYTE_GET (enote->namesz);
16291 inote.namedata = enote->name;
16292 inote.descsz = BYTE_GET (enote->descsz);
16293 inote.descdata = ((char *) enote
16294 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16295 inote.descpos = offset + (inote.descdata - (char *) enote);
16296 next = ((char *) enote
16297 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16298 }
16299 else
16300 {
16301 Elf64_External_VMS_Note *vms_enote;
16302
16303 /* PR binutils/15191
16304 Make sure that there is enough data to read. */
16305 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16306 if (data_remaining < min_notesz)
16307 {
55be8fd0
NC
16308 warn (_("\
16309malformed note encountered in section %s whilst scanning for build-id note\n"),
16310 printable_section_name (filedata, shdr));
f761cb13 16311 free (enote);
55be8fd0 16312 continue;
301a9420
AM
16313 }
16314 data_remaining -= min_notesz;
16315
16316 vms_enote = (Elf64_External_VMS_Note *) enote;
16317 inote.type = BYTE_GET (vms_enote->type);
16318 inote.namesz = BYTE_GET (vms_enote->namesz);
16319 inote.namedata = vms_enote->name;
16320 inote.descsz = BYTE_GET (vms_enote->descsz);
16321 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16322 inote.descpos = offset + (inote.descdata - (char *) enote);
16323 next = inote.descdata + align_power (inote.descsz, 3);
16324 }
16325
16326 /* Skip malformed notes. */
16327 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16328 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16329 || (size_t) (next - inote.descdata) < inote.descsz
16330 || ((size_t) (next - inote.descdata)
16331 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16332 {
55be8fd0
NC
16333 warn (_("\
16334malformed note encountered in section %s whilst scanning for build-id note\n"),
16335 printable_section_name (filedata, shdr));
f761cb13 16336 free (enote);
301a9420
AM
16337 continue;
16338 }
16339
16340 /* Check if this is the build-id note. If so then convert the build-id
16341 bytes to a hex string. */
16342 if (inote.namesz > 0
24d127aa 16343 && startswith (inote.namedata, "GNU")
301a9420
AM
16344 && inote.type == NT_GNU_BUILD_ID)
16345 {
26c527e6 16346 size_t j;
301a9420
AM
16347 char * build_id;
16348
16349 build_id = malloc (inote.descsz * 2 + 1);
16350 if (build_id == NULL)
f761cb13
AM
16351 {
16352 free (enote);
16353 return NULL;
16354 }
301a9420
AM
16355
16356 for (j = 0; j < inote.descsz; ++j)
16357 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16358 build_id[inote.descsz * 2] = '\0';
f761cb13 16359 free (enote);
301a9420 16360
55be8fd0 16361 return (unsigned char *) build_id;
301a9420 16362 }
f761cb13 16363 free (enote);
301a9420
AM
16364 }
16365
16366 return NULL;
16367}
16368#endif /* HAVE_LIBDEBUGINFOD */
16369
657d0d47
CC
16370/* If this is not NULL, load_debug_section will only look for sections
16371 within the list of sections given here. */
32ec8896 16372static unsigned int * section_subset = NULL;
657d0d47 16373
015dc7e1 16374bool
dda8d76d 16375load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16376{
2cf0635d
NC
16377 struct dwarf_section * section = &debug_displays [debug].section;
16378 Elf_Internal_Shdr * sec;
dda8d76d
NC
16379 Filedata * filedata = (Filedata *) data;
16380
e1dbfc17
L
16381 if (!dump_any_debugging)
16382 return false;
16383
f425ec66
NC
16384 /* Without section headers we cannot find any sections. */
16385 if (filedata->section_headers == NULL)
015dc7e1 16386 return false;
f425ec66 16387
9c1ce108
AM
16388 if (filedata->string_table == NULL
16389 && filedata->file_header.e_shstrndx != SHN_UNDEF
16390 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16391 {
16392 Elf_Internal_Shdr * strs;
16393
16394 /* Read in the string table, so that we have section names to scan. */
16395 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16396
4dff97b2 16397 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16398 {
9c1ce108
AM
16399 filedata->string_table
16400 = (char *) get_data (NULL, filedata, strs->sh_offset,
16401 1, strs->sh_size, _("string table"));
dda8d76d 16402
9c1ce108
AM
16403 filedata->string_table_length
16404 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16405 }
16406 }
d966045b
DJ
16407
16408 /* Locate the debug section. */
dda8d76d 16409 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16410 if (sec != NULL)
16411 section->name = section->uncompressed_name;
16412 else
16413 {
dda8d76d 16414 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16415 if (sec != NULL)
16416 section->name = section->compressed_name;
16417 }
16418 if (sec == NULL)
015dc7e1 16419 return false;
d966045b 16420
657d0d47
CC
16421 /* If we're loading from a subset of sections, and we've loaded
16422 a section matching this name before, it's likely that it's a
16423 different one. */
16424 if (section_subset != NULL)
16425 free_debug_section (debug);
16426
dda8d76d 16427 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16428}
16429
19e6b90e
L
16430void
16431free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16432{
2cf0635d 16433 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16434
19e6b90e
L
16435 if (section->start == NULL)
16436 return;
1007acb3 16437
19e6b90e
L
16438 free ((char *) section->start);
16439 section->start = NULL;
16440 section->address = 0;
16441 section->size = 0;
a788aedd 16442
9db70fc3
AM
16443 free (section->reloc_info);
16444 section->reloc_info = NULL;
16445 section->num_relocs = 0;
1007acb3
L
16446}
16447
015dc7e1 16448static bool
dda8d76d 16449display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16450{
84714f86
AM
16451 const char *name = (section_name_valid (filedata, section)
16452 ? section_name (filedata, section) : "");
16453 const char *print_name = printable_section_name (filedata, section);
be7d229a 16454 uint64_t length;
015dc7e1 16455 bool result = true;
3f5e193b 16456 int i;
1007acb3 16457
19e6b90e
L
16458 length = section->sh_size;
16459 if (length == 0)
1007acb3 16460 {
74e1a04b 16461 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16462 return true;
1007acb3 16463 }
5dff79d8
NC
16464 if (section->sh_type == SHT_NOBITS)
16465 {
16466 /* There is no point in dumping the contents of a debugging section
16467 which has the NOBITS type - the bits in the file will be random.
16468 This can happen when a file containing a .eh_frame section is
16469 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16470 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16471 print_name);
015dc7e1 16472 return false;
5dff79d8 16473 }
1007acb3 16474
24d127aa 16475 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16476 name = ".debug_info";
1007acb3 16477
19e6b90e
L
16478 /* See if we know how to display the contents of this section. */
16479 for (i = 0; i < max; i++)
d85bf2ba
NC
16480 {
16481 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16482 struct dwarf_section_display * display = debug_displays + i;
16483 struct dwarf_section * sec = & display->section;
d966045b 16484
d85bf2ba 16485 if (streq (sec->uncompressed_name, name)
24d127aa 16486 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16487 || streq (sec->compressed_name, name))
16488 {
015dc7e1 16489 bool secondary = (section != find_section (filedata, name));
1007acb3 16490
d85bf2ba
NC
16491 if (secondary)
16492 free_debug_section (id);
dda8d76d 16493
24d127aa 16494 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16495 sec->name = name;
16496 else if (streq (sec->uncompressed_name, name))
16497 sec->name = sec->uncompressed_name;
16498 else
16499 sec->name = sec->compressed_name;
657d0d47 16500
d85bf2ba
NC
16501 if (load_specific_debug_section (id, section, filedata))
16502 {
16503 /* If this debug section is part of a CU/TU set in a .dwp file,
16504 restrict load_debug_section to the sections in that set. */
16505 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16506
d85bf2ba 16507 result &= display->display (sec, filedata);
657d0d47 16508
d85bf2ba 16509 section_subset = NULL;
1007acb3 16510
44266f36 16511 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16512 free_debug_section (id);
16513 }
16514 break;
16515 }
16516 }
1007acb3 16517
19e6b90e 16518 if (i == max)
1007acb3 16519 {
74e1a04b 16520 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16521 result = false;
1007acb3
L
16522 }
16523
19e6b90e 16524 return result;
5b18a4bc 16525}
103f02d3 16526
aef1f6d0
DJ
16527/* Set DUMP_SECTS for all sections where dumps were requested
16528 based on section name. */
16529
16530static void
dda8d76d 16531initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16532{
2cf0635d 16533 struct dump_list_entry * cur;
aef1f6d0
DJ
16534
16535 for (cur = dump_sects_byname; cur; cur = cur->next)
16536 {
16537 unsigned int i;
015dc7e1 16538 bool any = false;
aef1f6d0 16539
dda8d76d 16540 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16541 if (section_name_valid (filedata, filedata->section_headers + i)
16542 && streq (section_name (filedata, filedata->section_headers + i),
16543 cur->name))
aef1f6d0 16544 {
6431e409 16545 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16546 any = true;
aef1f6d0
DJ
16547 }
16548
835f2fae
NC
16549 if (!any && !filedata->is_separate)
16550 warn (_("Section '%s' was not dumped because it does not exist\n"),
16551 cur->name);
aef1f6d0
DJ
16552 }
16553}
16554
015dc7e1 16555static bool
dda8d76d 16556process_section_contents (Filedata * filedata)
5b18a4bc 16557{
2cf0635d 16558 Elf_Internal_Shdr * section;
19e6b90e 16559 unsigned int i;
015dc7e1 16560 bool res = true;
103f02d3 16561
19e6b90e 16562 if (! do_dump)
015dc7e1 16563 return true;
103f02d3 16564
dda8d76d 16565 initialise_dumps_byname (filedata);
aef1f6d0 16566
dda8d76d 16567 for (i = 0, section = filedata->section_headers;
6431e409 16568 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16569 i++, section++)
16570 {
6431e409 16571 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16572
d6bfbc39
NC
16573 if (filedata->is_separate && ! process_links)
16574 dump &= DEBUG_DUMP;
047c3dbf 16575
19e6b90e 16576#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16577 if (dump & DISASS_DUMP)
16578 {
16579 if (! disassemble_section (section, filedata))
015dc7e1 16580 res = false;
dda8d76d 16581 }
19e6b90e 16582#endif
dda8d76d 16583 if (dump & HEX_DUMP)
32ec8896 16584 {
015dc7e1
AM
16585 if (! dump_section_as_bytes (section, filedata, false))
16586 res = false;
32ec8896 16587 }
103f02d3 16588
dda8d76d 16589 if (dump & RELOC_DUMP)
32ec8896 16590 {
015dc7e1
AM
16591 if (! dump_section_as_bytes (section, filedata, true))
16592 res = false;
32ec8896 16593 }
09c11c86 16594
dda8d76d 16595 if (dump & STRING_DUMP)
32ec8896 16596 {
dda8d76d 16597 if (! dump_section_as_strings (section, filedata))
015dc7e1 16598 res = false;
32ec8896 16599 }
cf13d699 16600
dda8d76d 16601 if (dump & DEBUG_DUMP)
32ec8896 16602 {
dda8d76d 16603 if (! display_debug_section (i, section, filedata))
015dc7e1 16604 res = false;
32ec8896 16605 }
7d9813f1 16606
094e34f2 16607#ifdef ENABLE_LIBCTF
7d9813f1
NA
16608 if (dump & CTF_DUMP)
16609 {
16610 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16611 res = false;
7d9813f1 16612 }
094e34f2 16613#endif
42b6953b
IB
16614 if (dump & SFRAME_DUMP)
16615 {
16616 if (! dump_section_as_sframe (section, filedata))
16617 res = false;
16618 }
5b18a4bc 16619 }
103f02d3 16620
835f2fae 16621 if (! filedata->is_separate)
0ee3043f 16622 {
835f2fae
NC
16623 /* Check to see if the user requested a
16624 dump of a section that does not exist. */
16625 for (; i < filedata->dump.num_dump_sects; i++)
16626 if (filedata->dump.dump_sects[i])
16627 {
ca0e11aa 16628 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16629 res = false;
835f2fae 16630 }
0ee3043f 16631 }
32ec8896
NC
16632
16633 return res;
5b18a4bc 16634}
103f02d3 16635
5b18a4bc 16636static void
19e6b90e 16637process_mips_fpe_exception (int mask)
5b18a4bc 16638{
19e6b90e
L
16639 if (mask)
16640 {
015dc7e1 16641 bool first = true;
32ec8896 16642
19e6b90e 16643 if (mask & OEX_FPU_INEX)
015dc7e1 16644 fputs ("INEX", stdout), first = false;
19e6b90e 16645 if (mask & OEX_FPU_UFLO)
015dc7e1 16646 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16647 if (mask & OEX_FPU_OFLO)
015dc7e1 16648 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16649 if (mask & OEX_FPU_DIV0)
015dc7e1 16650 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16651 if (mask & OEX_FPU_INVAL)
16652 printf ("%sINVAL", first ? "" : "|");
16653 }
5b18a4bc 16654 else
19e6b90e 16655 fputs ("0", stdout);
5b18a4bc 16656}
103f02d3 16657
f6f0e17b
NC
16658/* Display's the value of TAG at location P. If TAG is
16659 greater than 0 it is assumed to be an unknown tag, and
16660 a message is printed to this effect. Otherwise it is
16661 assumed that a message has already been printed.
16662
16663 If the bottom bit of TAG is set it assumed to have a
16664 string value, otherwise it is assumed to have an integer
16665 value.
16666
16667 Returns an updated P pointing to the first unread byte
16668 beyond the end of TAG's value.
16669
16670 Reads at or beyond END will not be made. */
16671
16672static unsigned char *
60abdbed 16673display_tag_value (signed int tag,
f6f0e17b
NC
16674 unsigned char * p,
16675 const unsigned char * const end)
16676{
26c527e6 16677 uint64_t val;
f6f0e17b
NC
16678
16679 if (tag > 0)
16680 printf (" Tag_unknown_%d: ", tag);
16681
16682 if (p >= end)
16683 {
4082ef84 16684 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16685 }
16686 else if (tag & 1)
16687 {
071436c6
NC
16688 /* PR 17531 file: 027-19978-0.004. */
16689 size_t maxlen = (end - p) - 1;
16690
16691 putchar ('"');
4082ef84
NC
16692 if (maxlen > 0)
16693 {
16694 print_symbol ((int) maxlen, (const char *) p);
16695 p += strnlen ((char *) p, maxlen) + 1;
16696 }
16697 else
16698 {
16699 printf (_("<corrupt string tag>"));
16700 p = (unsigned char *) end;
16701 }
071436c6 16702 printf ("\"\n");
f6f0e17b
NC
16703 }
16704 else
16705 {
cd30bcef 16706 READ_ULEB (val, p, end);
26c527e6 16707 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
16708 }
16709
4082ef84 16710 assert (p <= end);
f6f0e17b
NC
16711 return p;
16712}
16713
53a346d8
CZ
16714/* ARC ABI attributes section. */
16715
16716static unsigned char *
16717display_arc_attribute (unsigned char * p,
16718 const unsigned char * const end)
16719{
16720 unsigned int tag;
53a346d8
CZ
16721 unsigned int val;
16722
cd30bcef 16723 READ_ULEB (tag, p, end);
53a346d8
CZ
16724
16725 switch (tag)
16726 {
16727 case Tag_ARC_PCS_config:
cd30bcef 16728 READ_ULEB (val, p, end);
53a346d8
CZ
16729 printf (" Tag_ARC_PCS_config: ");
16730 switch (val)
16731 {
16732 case 0:
16733 printf (_("Absent/Non standard\n"));
16734 break;
16735 case 1:
16736 printf (_("Bare metal/mwdt\n"));
16737 break;
16738 case 2:
16739 printf (_("Bare metal/newlib\n"));
16740 break;
16741 case 3:
16742 printf (_("Linux/uclibc\n"));
16743 break;
16744 case 4:
16745 printf (_("Linux/glibc\n"));
16746 break;
16747 default:
16748 printf (_("Unknown\n"));
16749 break;
16750 }
16751 break;
16752
16753 case Tag_ARC_CPU_base:
cd30bcef 16754 READ_ULEB (val, p, end);
53a346d8
CZ
16755 printf (" Tag_ARC_CPU_base: ");
16756 switch (val)
16757 {
16758 default:
16759 case TAG_CPU_NONE:
16760 printf (_("Absent\n"));
16761 break;
16762 case TAG_CPU_ARC6xx:
16763 printf ("ARC6xx\n");
16764 break;
16765 case TAG_CPU_ARC7xx:
16766 printf ("ARC7xx\n");
16767 break;
16768 case TAG_CPU_ARCEM:
16769 printf ("ARCEM\n");
16770 break;
16771 case TAG_CPU_ARCHS:
16772 printf ("ARCHS\n");
16773 break;
16774 }
16775 break;
16776
16777 case Tag_ARC_CPU_variation:
cd30bcef 16778 READ_ULEB (val, p, end);
53a346d8
CZ
16779 printf (" Tag_ARC_CPU_variation: ");
16780 switch (val)
16781 {
16782 default:
16783 if (val > 0 && val < 16)
53a346d8 16784 printf ("Core%d\n", val);
d8cbc93b
JL
16785 else
16786 printf ("Unknown\n");
16787 break;
16788
53a346d8
CZ
16789 case 0:
16790 printf (_("Absent\n"));
16791 break;
16792 }
16793 break;
16794
16795 case Tag_ARC_CPU_name:
16796 printf (" Tag_ARC_CPU_name: ");
16797 p = display_tag_value (-1, p, end);
16798 break;
16799
16800 case Tag_ARC_ABI_rf16:
cd30bcef 16801 READ_ULEB (val, p, end);
53a346d8
CZ
16802 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16803 break;
16804
16805 case Tag_ARC_ABI_osver:
cd30bcef 16806 READ_ULEB (val, p, end);
53a346d8
CZ
16807 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16808 break;
16809
16810 case Tag_ARC_ABI_pic:
16811 case Tag_ARC_ABI_sda:
cd30bcef 16812 READ_ULEB (val, p, end);
53a346d8
CZ
16813 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16814 : " Tag_ARC_ABI_pic: ");
16815 switch (val)
16816 {
16817 case 0:
16818 printf (_("Absent\n"));
16819 break;
16820 case 1:
16821 printf ("MWDT\n");
16822 break;
16823 case 2:
16824 printf ("GNU\n");
16825 break;
16826 default:
16827 printf (_("Unknown\n"));
16828 break;
16829 }
16830 break;
16831
16832 case Tag_ARC_ABI_tls:
cd30bcef 16833 READ_ULEB (val, p, end);
53a346d8
CZ
16834 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16835 break;
16836
16837 case Tag_ARC_ABI_enumsize:
cd30bcef 16838 READ_ULEB (val, p, end);
53a346d8
CZ
16839 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16840 _("smallest"));
16841 break;
16842
16843 case Tag_ARC_ABI_exceptions:
cd30bcef 16844 READ_ULEB (val, p, end);
53a346d8
CZ
16845 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16846 : _("default"));
16847 break;
16848
16849 case Tag_ARC_ABI_double_size:
cd30bcef 16850 READ_ULEB (val, p, end);
53a346d8
CZ
16851 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16852 break;
16853
16854 case Tag_ARC_ISA_config:
16855 printf (" Tag_ARC_ISA_config: ");
16856 p = display_tag_value (-1, p, end);
16857 break;
16858
16859 case Tag_ARC_ISA_apex:
16860 printf (" Tag_ARC_ISA_apex: ");
16861 p = display_tag_value (-1, p, end);
16862 break;
16863
16864 case Tag_ARC_ISA_mpy_option:
cd30bcef 16865 READ_ULEB (val, p, end);
53a346d8
CZ
16866 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16867 break;
16868
db1e1b45 16869 case Tag_ARC_ATR_version:
cd30bcef 16870 READ_ULEB (val, p, end);
db1e1b45 16871 printf (" Tag_ARC_ATR_version: %d\n", val);
16872 break;
16873
53a346d8
CZ
16874 default:
16875 return display_tag_value (tag & 1, p, end);
16876 }
16877
16878 return p;
16879}
16880
11c1ff18
PB
16881/* ARM EABI attributes section. */
16882typedef struct
16883{
70e99720 16884 unsigned int tag;
2cf0635d 16885 const char * name;
11c1ff18 16886 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16887 unsigned int type;
288f0ba2 16888 const char *const *table;
11c1ff18
PB
16889} arm_attr_public_tag;
16890
288f0ba2 16891static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16892 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16893 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16894 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16895 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16896static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16897static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16898 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16899static const char *const arm_attr_tag_FP_arch[] =
bca38921 16900 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16901 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16902static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16903static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16904 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16905 "NEON for ARMv8.1"};
288f0ba2 16906static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16907 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16908 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16909static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16910 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16911static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16912 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16913static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16914 {"Absolute", "PC-relative", "None"};
288f0ba2 16915static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16916 {"None", "direct", "GOT-indirect"};
288f0ba2 16917static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16918 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16919static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16920static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16921 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16922static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16923static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16924static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16925 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16926static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16927 {"Unused", "small", "int", "forced to int"};
288f0ba2 16928static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16929 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16930static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16931 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16932static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16933 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16934static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16935 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16936 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16937static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16938 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16939 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16940static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16941static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16942 {"Not Allowed", "Allowed"};
288f0ba2 16943static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16944 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16945static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16946 {"Follow architecture", "Allowed"};
288f0ba2 16947static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16948 {"Not Allowed", "Allowed"};
288f0ba2 16949static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16950 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16951 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16952static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16953static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16954 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16955 "TrustZone and Virtualization Extensions"};
288f0ba2 16956static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16957 {"Not Allowed", "Allowed"};
11c1ff18 16958
288f0ba2 16959static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16960 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16961
99db83d0
AC
16962static const char * arm_attr_tag_PAC_extension[] =
16963 {"No PAC/AUT instructions",
16964 "PAC/AUT instructions permitted in the NOP space",
16965 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16966
4b535030
AC
16967static const char * arm_attr_tag_BTI_extension[] =
16968 {"BTI instructions not permitted",
16969 "BTI instructions permitted in the NOP space",
16970 "BTI instructions permitted in the NOP and in the non-NOP space"};
16971
b81ee92f
AC
16972static const char * arm_attr_tag_BTI_use[] =
16973 {"Compiled without branch target enforcement",
16974 "Compiled with branch target enforcement"};
16975
c9fed665
AC
16976static const char * arm_attr_tag_PACRET_use[] =
16977 {"Compiled without return address signing and authentication",
16978 "Compiled with return address signing and authentication"};
16979
11c1ff18
PB
16980#define LOOKUP(id, name) \
16981 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16982static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16983{
16984 {4, "CPU_raw_name", 1, NULL},
16985 {5, "CPU_name", 1, NULL},
16986 LOOKUP(6, CPU_arch),
16987 {7, "CPU_arch_profile", 0, NULL},
16988 LOOKUP(8, ARM_ISA_use),
16989 LOOKUP(9, THUMB_ISA_use),
75375b3e 16990 LOOKUP(10, FP_arch),
11c1ff18 16991 LOOKUP(11, WMMX_arch),
f5f53991
AS
16992 LOOKUP(12, Advanced_SIMD_arch),
16993 LOOKUP(13, PCS_config),
11c1ff18
PB
16994 LOOKUP(14, ABI_PCS_R9_use),
16995 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16996 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16997 LOOKUP(17, ABI_PCS_GOT_use),
16998 LOOKUP(18, ABI_PCS_wchar_t),
16999 LOOKUP(19, ABI_FP_rounding),
17000 LOOKUP(20, ABI_FP_denormal),
17001 LOOKUP(21, ABI_FP_exceptions),
17002 LOOKUP(22, ABI_FP_user_exceptions),
17003 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
17004 {24, "ABI_align_needed", 0, NULL},
17005 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
17006 LOOKUP(26, ABI_enum_size),
17007 LOOKUP(27, ABI_HardFP_use),
17008 LOOKUP(28, ABI_VFP_args),
17009 LOOKUP(29, ABI_WMMX_args),
17010 LOOKUP(30, ABI_optimization_goals),
17011 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 17012 {32, "compatibility", 0, NULL},
f5f53991 17013 LOOKUP(34, CPU_unaligned_access),
75375b3e 17014 LOOKUP(36, FP_HP_extension),
8e79c3df 17015 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
17016 LOOKUP(42, MPextension_use),
17017 LOOKUP(44, DIV_use),
15afaa63 17018 LOOKUP(46, DSP_extension),
a7ad558c 17019 LOOKUP(48, MVE_arch),
99db83d0 17020 LOOKUP(50, PAC_extension),
4b535030 17021 LOOKUP(52, BTI_extension),
b81ee92f 17022 LOOKUP(74, BTI_use),
c9fed665 17023 LOOKUP(76, PACRET_use),
f5f53991
AS
17024 {64, "nodefaults", 0, NULL},
17025 {65, "also_compatible_with", 0, NULL},
17026 LOOKUP(66, T2EE_use),
17027 {67, "conformance", 1, NULL},
17028 LOOKUP(68, Virtualization_use),
cd21e546 17029 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
17030};
17031#undef LOOKUP
17032
11c1ff18 17033static unsigned char *
f6f0e17b
NC
17034display_arm_attribute (unsigned char * p,
17035 const unsigned char * const end)
11c1ff18 17036{
70e99720 17037 unsigned int tag;
70e99720 17038 unsigned int val;
2cf0635d 17039 arm_attr_public_tag * attr;
11c1ff18 17040 unsigned i;
70e99720 17041 unsigned int type;
11c1ff18 17042
cd30bcef 17043 READ_ULEB (tag, p, end);
11c1ff18 17044 attr = NULL;
2cf0635d 17045 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
17046 {
17047 if (arm_attr_public_tags[i].tag == tag)
17048 {
17049 attr = &arm_attr_public_tags[i];
17050 break;
17051 }
17052 }
17053
17054 if (attr)
17055 {
17056 printf (" Tag_%s: ", attr->name);
17057 switch (attr->type)
17058 {
17059 case 0:
17060 switch (tag)
17061 {
17062 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 17063 READ_ULEB (val, p, end);
11c1ff18
PB
17064 switch (val)
17065 {
2b692964
NC
17066 case 0: printf (_("None\n")); break;
17067 case 'A': printf (_("Application\n")); break;
17068 case 'R': printf (_("Realtime\n")); break;
17069 case 'M': printf (_("Microcontroller\n")); break;
17070 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
17071 default: printf ("??? (%d)\n", val); break;
17072 }
17073 break;
17074
75375b3e 17075 case 24: /* Tag_align_needed. */
cd30bcef 17076 READ_ULEB (val, p, end);
75375b3e
MGD
17077 switch (val)
17078 {
2b692964
NC
17079 case 0: printf (_("None\n")); break;
17080 case 1: printf (_("8-byte\n")); break;
17081 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
17082 case 3: printf ("??? 3\n"); break;
17083 default:
17084 if (val <= 12)
dd24e3da 17085 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17086 1 << val);
17087 else
17088 printf ("??? (%d)\n", val);
17089 break;
17090 }
17091 break;
17092
17093 case 25: /* Tag_align_preserved. */
cd30bcef 17094 READ_ULEB (val, p, end);
75375b3e
MGD
17095 switch (val)
17096 {
2b692964
NC
17097 case 0: printf (_("None\n")); break;
17098 case 1: printf (_("8-byte, except leaf SP\n")); break;
17099 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
17100 case 3: printf ("??? 3\n"); break;
17101 default:
17102 if (val <= 12)
dd24e3da 17103 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17104 1 << val);
17105 else
17106 printf ("??? (%d)\n", val);
17107 break;
17108 }
17109 break;
17110
11c1ff18 17111 case 32: /* Tag_compatibility. */
071436c6 17112 {
cd30bcef 17113 READ_ULEB (val, p, end);
071436c6 17114 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17115 if (p < end - 1)
17116 {
17117 size_t maxlen = (end - p) - 1;
17118
17119 print_symbol ((int) maxlen, (const char *) p);
17120 p += strnlen ((char *) p, maxlen) + 1;
17121 }
17122 else
17123 {
17124 printf (_("<corrupt>"));
17125 p = (unsigned char *) end;
17126 }
071436c6 17127 putchar ('\n');
071436c6 17128 }
11c1ff18
PB
17129 break;
17130
f5f53991 17131 case 64: /* Tag_nodefaults. */
541a3cbd
NC
17132 /* PR 17531: file: 001-505008-0.01. */
17133 if (p < end)
17134 p++;
2b692964 17135 printf (_("True\n"));
f5f53991
AS
17136 break;
17137
17138 case 65: /* Tag_also_compatible_with. */
cd30bcef 17139 READ_ULEB (val, p, end);
f5f53991
AS
17140 if (val == 6 /* Tag_CPU_arch. */)
17141 {
cd30bcef 17142 READ_ULEB (val, p, end);
071436c6 17143 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
17144 printf ("??? (%d)\n", val);
17145 else
17146 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17147 }
17148 else
17149 printf ("???\n");
071436c6
NC
17150 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17151 ;
f5f53991
AS
17152 break;
17153
11c1ff18 17154 default:
bee0ee85
NC
17155 printf (_("<unknown: %d>\n"), tag);
17156 break;
11c1ff18
PB
17157 }
17158 return p;
17159
17160 case 1:
f6f0e17b 17161 return display_tag_value (-1, p, end);
11c1ff18 17162 case 2:
f6f0e17b 17163 return display_tag_value (0, p, end);
11c1ff18
PB
17164
17165 default:
17166 assert (attr->type & 0x80);
cd30bcef 17167 READ_ULEB (val, p, end);
11c1ff18
PB
17168 type = attr->type & 0x7f;
17169 if (val >= type)
17170 printf ("??? (%d)\n", val);
17171 else
17172 printf ("%s\n", attr->table[val]);
17173 return p;
17174 }
17175 }
11c1ff18 17176
f6f0e17b 17177 return display_tag_value (tag, p, end);
11c1ff18
PB
17178}
17179
104d59d1 17180static unsigned char *
60bca95a 17181display_gnu_attribute (unsigned char * p,
60abdbed 17182 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 17183 const unsigned char * const end)
104d59d1 17184{
cd30bcef 17185 unsigned int tag;
60abdbed 17186 unsigned int val;
104d59d1 17187
cd30bcef 17188 READ_ULEB (tag, p, end);
104d59d1
JM
17189
17190 /* Tag_compatibility is the only generic GNU attribute defined at
17191 present. */
17192 if (tag == 32)
17193 {
cd30bcef 17194 READ_ULEB (val, p, end);
071436c6
NC
17195
17196 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
17197 if (p == end)
17198 {
071436c6 17199 printf (_("<corrupt>\n"));
f6f0e17b
NC
17200 warn (_("corrupt vendor attribute\n"));
17201 }
17202 else
17203 {
4082ef84
NC
17204 if (p < end - 1)
17205 {
17206 size_t maxlen = (end - p) - 1;
071436c6 17207
4082ef84
NC
17208 print_symbol ((int) maxlen, (const char *) p);
17209 p += strnlen ((char *) p, maxlen) + 1;
17210 }
17211 else
17212 {
17213 printf (_("<corrupt>"));
17214 p = (unsigned char *) end;
17215 }
071436c6 17216 putchar ('\n');
f6f0e17b 17217 }
104d59d1
JM
17218 return p;
17219 }
17220
17221 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 17222 return display_proc_gnu_attribute (p, tag, end);
104d59d1 17223
f6f0e17b 17224 return display_tag_value (tag, p, end);
104d59d1
JM
17225}
17226
85f7484a
PB
17227static unsigned char *
17228display_m68k_gnu_attribute (unsigned char * p,
17229 unsigned int tag,
17230 const unsigned char * const end)
17231{
17232 unsigned int val;
17233
17234 if (tag == Tag_GNU_M68K_ABI_FP)
17235 {
17236 printf (" Tag_GNU_M68K_ABI_FP: ");
17237 if (p == end)
17238 {
17239 printf (_("<corrupt>\n"));
17240 return p;
17241 }
17242 READ_ULEB (val, p, end);
17243
17244 if (val > 3)
17245 printf ("(%#x), ", val);
17246
17247 switch (val & 3)
17248 {
17249 case 0:
17250 printf (_("unspecified hard/soft float\n"));
17251 break;
17252 case 1:
17253 printf (_("hard float\n"));
17254 break;
17255 case 2:
17256 printf (_("soft float\n"));
17257 break;
17258 }
17259 return p;
17260 }
17261
17262 return display_tag_value (tag & 1, p, end);
17263}
17264
34c8bcba 17265static unsigned char *
f6f0e17b 17266display_power_gnu_attribute (unsigned char * p,
60abdbed 17267 unsigned int tag,
f6f0e17b 17268 const unsigned char * const end)
34c8bcba 17269{
005d79fd 17270 unsigned int val;
34c8bcba
JM
17271
17272 if (tag == Tag_GNU_Power_ABI_FP)
17273 {
34c8bcba 17274 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 17275 if (p == end)
005d79fd
AM
17276 {
17277 printf (_("<corrupt>\n"));
17278 return p;
17279 }
cd30bcef 17280 READ_ULEB (val, p, end);
60bca95a 17281
005d79fd
AM
17282 if (val > 15)
17283 printf ("(%#x), ", val);
17284
17285 switch (val & 3)
34c8bcba
JM
17286 {
17287 case 0:
005d79fd 17288 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17289 break;
17290 case 1:
005d79fd 17291 printf (_("hard float, "));
34c8bcba
JM
17292 break;
17293 case 2:
005d79fd 17294 printf (_("soft float, "));
34c8bcba 17295 break;
3c7b9897 17296 case 3:
005d79fd 17297 printf (_("single-precision hard float, "));
3c7b9897 17298 break;
005d79fd
AM
17299 }
17300
17301 switch (val & 0xC)
17302 {
17303 case 0:
17304 printf (_("unspecified long double\n"));
17305 break;
17306 case 4:
17307 printf (_("128-bit IBM long double\n"));
17308 break;
17309 case 8:
17310 printf (_("64-bit long double\n"));
17311 break;
17312 case 12:
17313 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17314 break;
17315 }
17316 return p;
005d79fd 17317 }
34c8bcba 17318
c6e65352
DJ
17319 if (tag == Tag_GNU_Power_ABI_Vector)
17320 {
c6e65352 17321 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17322 if (p == end)
005d79fd
AM
17323 {
17324 printf (_("<corrupt>\n"));
17325 return p;
17326 }
cd30bcef 17327 READ_ULEB (val, p, end);
005d79fd
AM
17328
17329 if (val > 3)
17330 printf ("(%#x), ", val);
17331
17332 switch (val & 3)
c6e65352
DJ
17333 {
17334 case 0:
005d79fd 17335 printf (_("unspecified\n"));
c6e65352
DJ
17336 break;
17337 case 1:
005d79fd 17338 printf (_("generic\n"));
c6e65352
DJ
17339 break;
17340 case 2:
17341 printf ("AltiVec\n");
17342 break;
17343 case 3:
17344 printf ("SPE\n");
17345 break;
c6e65352
DJ
17346 }
17347 return p;
005d79fd 17348 }
c6e65352 17349
f82e0623
NF
17350 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17351 {
005d79fd 17352 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17353 if (p == end)
f6f0e17b 17354 {
005d79fd 17355 printf (_("<corrupt>\n"));
f6f0e17b
NC
17356 return p;
17357 }
cd30bcef 17358 READ_ULEB (val, p, end);
0b4362b0 17359
005d79fd
AM
17360 if (val > 2)
17361 printf ("(%#x), ", val);
17362
17363 switch (val & 3)
17364 {
17365 case 0:
17366 printf (_("unspecified\n"));
17367 break;
17368 case 1:
17369 printf ("r3/r4\n");
17370 break;
17371 case 2:
17372 printf (_("memory\n"));
17373 break;
17374 case 3:
17375 printf ("???\n");
17376 break;
17377 }
f82e0623
NF
17378 return p;
17379 }
17380
f6f0e17b 17381 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17382}
17383
643f7afb
AK
17384static unsigned char *
17385display_s390_gnu_attribute (unsigned char * p,
60abdbed 17386 unsigned int tag,
643f7afb
AK
17387 const unsigned char * const end)
17388{
cd30bcef 17389 unsigned int val;
643f7afb
AK
17390
17391 if (tag == Tag_GNU_S390_ABI_Vector)
17392 {
643f7afb 17393 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17394 READ_ULEB (val, p, end);
643f7afb
AK
17395
17396 switch (val)
17397 {
17398 case 0:
17399 printf (_("any\n"));
17400 break;
17401 case 1:
17402 printf (_("software\n"));
17403 break;
17404 case 2:
17405 printf (_("hardware\n"));
17406 break;
17407 default:
17408 printf ("??? (%d)\n", val);
17409 break;
17410 }
17411 return p;
17412 }
17413
17414 return display_tag_value (tag & 1, p, end);
17415}
17416
9e8c70f9 17417static void
60abdbed 17418display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17419{
17420 if (mask)
17421 {
015dc7e1 17422 bool first = true;
071436c6 17423
9e8c70f9 17424 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17425 fputs ("mul32", stdout), first = false;
9e8c70f9 17426 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17427 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17428 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17429 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17430 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17431 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17432 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17433 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17434 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17435 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17436 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17437 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17438 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17439 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17440 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17441 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17442 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17443 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17444 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17445 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17446 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17447 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17448 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17449 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17450 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17451 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17452 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17453 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17454 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17455 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17456 }
17457 else
071436c6
NC
17458 fputc ('0', stdout);
17459 fputc ('\n', stdout);
9e8c70f9
DM
17460}
17461
3d68f91c 17462static void
60abdbed 17463display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17464{
17465 if (mask)
17466 {
015dc7e1 17467 bool first = true;
071436c6 17468
3d68f91c 17469 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17470 fputs ("fjathplus", stdout), first = false;
3d68f91c 17471 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17472 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17473 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17474 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17475 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17476 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17477 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17478 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17479 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17480 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17481 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17482 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17483 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17484 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17485 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17486 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17487 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17488 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17489 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17490 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17491 }
17492 else
071436c6
NC
17493 fputc ('0', stdout);
17494 fputc ('\n', stdout);
3d68f91c
JM
17495}
17496
9e8c70f9 17497static unsigned char *
f6f0e17b 17498display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17499 unsigned int tag,
f6f0e17b 17500 const unsigned char * const end)
9e8c70f9 17501{
cd30bcef 17502 unsigned int val;
3d68f91c 17503
9e8c70f9
DM
17504 if (tag == Tag_GNU_Sparc_HWCAPS)
17505 {
cd30bcef 17506 READ_ULEB (val, p, end);
9e8c70f9 17507 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17508 display_sparc_hwcaps (val);
17509 return p;
3d68f91c
JM
17510 }
17511 if (tag == Tag_GNU_Sparc_HWCAPS2)
17512 {
cd30bcef 17513 READ_ULEB (val, p, end);
3d68f91c
JM
17514 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17515 display_sparc_hwcaps2 (val);
17516 return p;
17517 }
9e8c70f9 17518
f6f0e17b 17519 return display_tag_value (tag, p, end);
9e8c70f9
DM
17520}
17521
351cdf24 17522static void
32ec8896 17523print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17524{
17525 switch (val)
17526 {
17527 case Val_GNU_MIPS_ABI_FP_ANY:
17528 printf (_("Hard or soft float\n"));
17529 break;
17530 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17531 printf (_("Hard float (double precision)\n"));
17532 break;
17533 case Val_GNU_MIPS_ABI_FP_SINGLE:
17534 printf (_("Hard float (single precision)\n"));
17535 break;
17536 case Val_GNU_MIPS_ABI_FP_SOFT:
17537 printf (_("Soft float\n"));
17538 break;
17539 case Val_GNU_MIPS_ABI_FP_OLD_64:
17540 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17541 break;
17542 case Val_GNU_MIPS_ABI_FP_XX:
17543 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17544 break;
17545 case Val_GNU_MIPS_ABI_FP_64:
17546 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17547 break;
17548 case Val_GNU_MIPS_ABI_FP_64A:
17549 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17550 break;
3350cc01
CM
17551 case Val_GNU_MIPS_ABI_FP_NAN2008:
17552 printf (_("NaN 2008 compatibility\n"));
17553 break;
351cdf24
MF
17554 default:
17555 printf ("??? (%d)\n", val);
17556 break;
17557 }
17558}
17559
2cf19d5c 17560static unsigned char *
f6f0e17b 17561display_mips_gnu_attribute (unsigned char * p,
60abdbed 17562 unsigned int tag,
f6f0e17b 17563 const unsigned char * const end)
2cf19d5c 17564{
2cf19d5c
JM
17565 if (tag == Tag_GNU_MIPS_ABI_FP)
17566 {
32ec8896 17567 unsigned int val;
f6f0e17b 17568
2cf19d5c 17569 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17570 READ_ULEB (val, p, end);
351cdf24 17571 print_mips_fp_abi_value (val);
2cf19d5c
JM
17572 return p;
17573 }
17574
a9f58168
CF
17575 if (tag == Tag_GNU_MIPS_ABI_MSA)
17576 {
32ec8896 17577 unsigned int val;
a9f58168 17578
a9f58168 17579 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17580 READ_ULEB (val, p, end);
a9f58168
CF
17581
17582 switch (val)
17583 {
17584 case Val_GNU_MIPS_ABI_MSA_ANY:
17585 printf (_("Any MSA or not\n"));
17586 break;
17587 case Val_GNU_MIPS_ABI_MSA_128:
17588 printf (_("128-bit MSA\n"));
17589 break;
17590 default:
17591 printf ("??? (%d)\n", val);
17592 break;
17593 }
17594 return p;
17595 }
17596
f6f0e17b 17597 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17598}
17599
59e6276b 17600static unsigned char *
f6f0e17b
NC
17601display_tic6x_attribute (unsigned char * p,
17602 const unsigned char * const end)
59e6276b 17603{
60abdbed 17604 unsigned int tag;
cd30bcef 17605 unsigned int val;
59e6276b 17606
cd30bcef 17607 READ_ULEB (tag, p, end);
59e6276b
JM
17608
17609 switch (tag)
17610 {
75fa6dc1 17611 case Tag_ISA:
75fa6dc1 17612 printf (" Tag_ISA: ");
cd30bcef 17613 READ_ULEB (val, p, end);
59e6276b
JM
17614
17615 switch (val)
17616 {
75fa6dc1 17617 case C6XABI_Tag_ISA_none:
59e6276b
JM
17618 printf (_("None\n"));
17619 break;
75fa6dc1 17620 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17621 printf ("C62x\n");
17622 break;
75fa6dc1 17623 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17624 printf ("C67x\n");
17625 break;
75fa6dc1 17626 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17627 printf ("C67x+\n");
17628 break;
75fa6dc1 17629 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17630 printf ("C64x\n");
17631 break;
75fa6dc1 17632 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17633 printf ("C64x+\n");
17634 break;
75fa6dc1 17635 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17636 printf ("C674x\n");
17637 break;
17638 default:
17639 printf ("??? (%d)\n", val);
17640 break;
17641 }
17642 return p;
17643
87779176 17644 case Tag_ABI_wchar_t:
87779176 17645 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17646 READ_ULEB (val, p, end);
87779176
JM
17647 switch (val)
17648 {
17649 case 0:
17650 printf (_("Not used\n"));
17651 break;
17652 case 1:
17653 printf (_("2 bytes\n"));
17654 break;
17655 case 2:
17656 printf (_("4 bytes\n"));
17657 break;
17658 default:
17659 printf ("??? (%d)\n", val);
17660 break;
17661 }
17662 return p;
17663
17664 case Tag_ABI_stack_align_needed:
87779176 17665 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17666 READ_ULEB (val, p, end);
87779176
JM
17667 switch (val)
17668 {
17669 case 0:
17670 printf (_("8-byte\n"));
17671 break;
17672 case 1:
17673 printf (_("16-byte\n"));
17674 break;
17675 default:
17676 printf ("??? (%d)\n", val);
17677 break;
17678 }
17679 return p;
17680
17681 case Tag_ABI_stack_align_preserved:
cd30bcef 17682 READ_ULEB (val, p, end);
87779176
JM
17683 printf (" Tag_ABI_stack_align_preserved: ");
17684 switch (val)
17685 {
17686 case 0:
17687 printf (_("8-byte\n"));
17688 break;
17689 case 1:
17690 printf (_("16-byte\n"));
17691 break;
17692 default:
17693 printf ("??? (%d)\n", val);
17694 break;
17695 }
17696 return p;
17697
b5593623 17698 case Tag_ABI_DSBT:
cd30bcef 17699 READ_ULEB (val, p, end);
b5593623
JM
17700 printf (" Tag_ABI_DSBT: ");
17701 switch (val)
17702 {
17703 case 0:
17704 printf (_("DSBT addressing not used\n"));
17705 break;
17706 case 1:
17707 printf (_("DSBT addressing used\n"));
17708 break;
17709 default:
17710 printf ("??? (%d)\n", val);
17711 break;
17712 }
17713 return p;
17714
87779176 17715 case Tag_ABI_PID:
cd30bcef 17716 READ_ULEB (val, p, end);
87779176
JM
17717 printf (" Tag_ABI_PID: ");
17718 switch (val)
17719 {
17720 case 0:
17721 printf (_("Data addressing position-dependent\n"));
17722 break;
17723 case 1:
17724 printf (_("Data addressing position-independent, GOT near DP\n"));
17725 break;
17726 case 2:
17727 printf (_("Data addressing position-independent, GOT far from DP\n"));
17728 break;
17729 default:
17730 printf ("??? (%d)\n", val);
17731 break;
17732 }
17733 return p;
17734
17735 case Tag_ABI_PIC:
cd30bcef 17736 READ_ULEB (val, p, end);
87779176
JM
17737 printf (" Tag_ABI_PIC: ");
17738 switch (val)
17739 {
17740 case 0:
17741 printf (_("Code addressing position-dependent\n"));
17742 break;
17743 case 1:
17744 printf (_("Code addressing position-independent\n"));
17745 break;
17746 default:
17747 printf ("??? (%d)\n", val);
17748 break;
17749 }
17750 return p;
17751
17752 case Tag_ABI_array_object_alignment:
cd30bcef 17753 READ_ULEB (val, p, end);
87779176
JM
17754 printf (" Tag_ABI_array_object_alignment: ");
17755 switch (val)
17756 {
17757 case 0:
17758 printf (_("8-byte\n"));
17759 break;
17760 case 1:
17761 printf (_("4-byte\n"));
17762 break;
17763 case 2:
17764 printf (_("16-byte\n"));
17765 break;
17766 default:
17767 printf ("??? (%d)\n", val);
17768 break;
17769 }
17770 return p;
17771
17772 case Tag_ABI_array_object_align_expected:
cd30bcef 17773 READ_ULEB (val, p, end);
87779176
JM
17774 printf (" Tag_ABI_array_object_align_expected: ");
17775 switch (val)
17776 {
17777 case 0:
17778 printf (_("8-byte\n"));
17779 break;
17780 case 1:
17781 printf (_("4-byte\n"));
17782 break;
17783 case 2:
17784 printf (_("16-byte\n"));
17785 break;
17786 default:
17787 printf ("??? (%d)\n", val);
17788 break;
17789 }
17790 return p;
17791
3cbd1c06 17792 case Tag_ABI_compatibility:
071436c6 17793 {
cd30bcef 17794 READ_ULEB (val, p, end);
071436c6 17795 printf (" Tag_ABI_compatibility: ");
071436c6 17796 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17797 if (p < end - 1)
17798 {
17799 size_t maxlen = (end - p) - 1;
17800
17801 print_symbol ((int) maxlen, (const char *) p);
17802 p += strnlen ((char *) p, maxlen) + 1;
17803 }
17804 else
17805 {
17806 printf (_("<corrupt>"));
17807 p = (unsigned char *) end;
17808 }
071436c6 17809 putchar ('\n');
071436c6
NC
17810 return p;
17811 }
87779176
JM
17812
17813 case Tag_ABI_conformance:
071436c6 17814 {
4082ef84
NC
17815 printf (" Tag_ABI_conformance: \"");
17816 if (p < end - 1)
17817 {
17818 size_t maxlen = (end - p) - 1;
071436c6 17819
4082ef84
NC
17820 print_symbol ((int) maxlen, (const char *) p);
17821 p += strnlen ((char *) p, maxlen) + 1;
17822 }
17823 else
17824 {
17825 printf (_("<corrupt>"));
17826 p = (unsigned char *) end;
17827 }
071436c6 17828 printf ("\"\n");
071436c6
NC
17829 return p;
17830 }
59e6276b
JM
17831 }
17832
f6f0e17b
NC
17833 return display_tag_value (tag, p, end);
17834}
59e6276b 17835
f6f0e17b 17836static void
60abdbed 17837display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 17838{
26c527e6 17839 uint64_t addr = 0;
f6f0e17b
NC
17840 size_t bytes = end - p;
17841
feceaa59 17842 assert (end >= p);
f6f0e17b 17843 while (bytes)
87779176 17844 {
f6f0e17b
NC
17845 int j;
17846 int k;
17847 int lbytes = (bytes > 16 ? 16 : bytes);
17848
26c527e6 17849 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
17850
17851 for (j = 0; j < 16; j++)
17852 {
17853 if (j < lbytes)
17854 printf ("%2.2x", p[j]);
17855 else
17856 printf (" ");
17857
17858 if ((j & 3) == 3)
17859 printf (" ");
17860 }
17861
17862 for (j = 0; j < lbytes; j++)
17863 {
17864 k = p[j];
17865 if (k >= ' ' && k < 0x7f)
17866 printf ("%c", k);
17867 else
17868 printf (".");
17869 }
17870
17871 putchar ('\n');
17872
17873 p += lbytes;
17874 bytes -= lbytes;
17875 addr += lbytes;
87779176 17876 }
59e6276b 17877
f6f0e17b 17878 putchar ('\n');
59e6276b
JM
17879}
17880
13761a11 17881static unsigned char *
b0191216 17882display_msp430_attribute (unsigned char * p,
26c527e6 17883 const unsigned char * const end)
13761a11 17884{
26c527e6
AM
17885 uint64_t val;
17886 uint64_t tag;
13761a11 17887
cd30bcef 17888 READ_ULEB (tag, p, end);
0b4362b0 17889
13761a11
NC
17890 switch (tag)
17891 {
17892 case OFBA_MSPABI_Tag_ISA:
13761a11 17893 printf (" Tag_ISA: ");
cd30bcef 17894 READ_ULEB (val, p, end);
13761a11
NC
17895 switch (val)
17896 {
17897 case 0: printf (_("None\n")); break;
17898 case 1: printf (_("MSP430\n")); break;
17899 case 2: printf (_("MSP430X\n")); break;
26c527e6 17900 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17901 }
17902 break;
17903
17904 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17905 printf (" Tag_Code_Model: ");
cd30bcef 17906 READ_ULEB (val, p, end);
13761a11
NC
17907 switch (val)
17908 {
17909 case 0: printf (_("None\n")); break;
17910 case 1: printf (_("Small\n")); break;
17911 case 2: printf (_("Large\n")); break;
26c527e6 17912 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17913 }
17914 break;
17915
17916 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17917 printf (" Tag_Data_Model: ");
cd30bcef 17918 READ_ULEB (val, p, end);
13761a11
NC
17919 switch (val)
17920 {
17921 case 0: printf (_("None\n")); break;
17922 case 1: printf (_("Small\n")); break;
17923 case 2: printf (_("Large\n")); break;
17924 case 3: printf (_("Restricted Large\n")); break;
26c527e6 17925 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17926 }
17927 break;
17928
17929 default:
26c527e6 17930 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
17931
17932 if (tag & 1)
17933 {
071436c6 17934 putchar ('"');
4082ef84
NC
17935 if (p < end - 1)
17936 {
17937 size_t maxlen = (end - p) - 1;
17938
17939 print_symbol ((int) maxlen, (const char *) p);
17940 p += strnlen ((char *) p, maxlen) + 1;
17941 }
17942 else
17943 {
17944 printf (_("<corrupt>"));
17945 p = (unsigned char *) end;
17946 }
071436c6 17947 printf ("\"\n");
13761a11
NC
17948 }
17949 else
17950 {
cd30bcef 17951 READ_ULEB (val, p, end);
26c527e6 17952 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
17953 }
17954 break;
17955 }
17956
4082ef84 17957 assert (p <= end);
13761a11
NC
17958 return p;
17959}
17960
c0ea7c52
JL
17961static unsigned char *
17962display_msp430_gnu_attribute (unsigned char * p,
17963 unsigned int tag,
17964 const unsigned char * const end)
17965{
17966 if (tag == Tag_GNU_MSP430_Data_Region)
17967 {
26c527e6 17968 uint64_t val;
c0ea7c52 17969
c0ea7c52 17970 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17971 READ_ULEB (val, p, end);
c0ea7c52
JL
17972
17973 switch (val)
17974 {
17975 case Val_GNU_MSP430_Data_Region_Any:
17976 printf (_("Any Region\n"));
17977 break;
17978 case Val_GNU_MSP430_Data_Region_Lower:
17979 printf (_("Lower Region Only\n"));
17980 break;
17981 default:
26c527e6 17982 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
17983 }
17984 return p;
17985 }
17986 return display_tag_value (tag & 1, p, end);
17987}
17988
2dc8dd17
JW
17989struct riscv_attr_tag_t {
17990 const char *name;
cd30bcef 17991 unsigned int tag;
2dc8dd17
JW
17992};
17993
17994static struct riscv_attr_tag_t riscv_attr_tag[] =
17995{
17996#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17997 T(arch),
17998 T(priv_spec),
17999 T(priv_spec_minor),
18000 T(priv_spec_revision),
18001 T(unaligned_access),
18002 T(stack_align),
18003#undef T
18004};
18005
18006static unsigned char *
18007display_riscv_attribute (unsigned char *p,
18008 const unsigned char * const end)
18009{
26c527e6
AM
18010 uint64_t val;
18011 uint64_t tag;
2dc8dd17
JW
18012 struct riscv_attr_tag_t *attr = NULL;
18013 unsigned i;
18014
cd30bcef 18015 READ_ULEB (tag, p, end);
2dc8dd17
JW
18016
18017 /* Find the name of attribute. */
18018 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
18019 {
18020 if (riscv_attr_tag[i].tag == tag)
18021 {
18022 attr = &riscv_attr_tag[i];
18023 break;
18024 }
18025 }
18026
18027 if (attr)
18028 printf (" %s: ", attr->name);
18029 else
18030 return display_tag_value (tag, p, end);
18031
18032 switch (tag)
18033 {
18034 case Tag_RISCV_priv_spec:
18035 case Tag_RISCV_priv_spec_minor:
18036 case Tag_RISCV_priv_spec_revision:
cd30bcef 18037 READ_ULEB (val, p, end);
26c527e6 18038 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
18039 break;
18040 case Tag_RISCV_unaligned_access:
cd30bcef 18041 READ_ULEB (val, p, end);
2dc8dd17
JW
18042 switch (val)
18043 {
18044 case 0:
18045 printf (_("No unaligned access\n"));
18046 break;
18047 case 1:
18048 printf (_("Unaligned access\n"));
18049 break;
18050 }
18051 break;
18052 case Tag_RISCV_stack_align:
cd30bcef 18053 READ_ULEB (val, p, end);
26c527e6 18054 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
18055 break;
18056 case Tag_RISCV_arch:
18057 p = display_tag_value (-1, p, end);
18058 break;
18059 default:
18060 return display_tag_value (tag, p, end);
18061 }
18062
18063 return p;
18064}
18065
0861f561
CQ
18066static unsigned char *
18067display_csky_attribute (unsigned char * p,
18068 const unsigned char * const end)
18069{
26c527e6
AM
18070 uint64_t tag;
18071 uint64_t val;
0861f561
CQ
18072 READ_ULEB (tag, p, end);
18073
18074 if (tag >= Tag_CSKY_MAX)
18075 {
18076 return display_tag_value (-1, p, end);
18077 }
18078
18079 switch (tag)
18080 {
18081 case Tag_CSKY_ARCH_NAME:
18082 printf (" Tag_CSKY_ARCH_NAME:\t\t");
18083 return display_tag_value (-1, p, end);
18084 case Tag_CSKY_CPU_NAME:
18085 printf (" Tag_CSKY_CPU_NAME:\t\t");
18086 return display_tag_value (-1, p, end);
18087
18088 case Tag_CSKY_ISA_FLAGS:
18089 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
18090 return display_tag_value (0, p, end);
18091 case Tag_CSKY_ISA_EXT_FLAGS:
18092 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
18093 return display_tag_value (0, p, end);
18094
18095 case Tag_CSKY_DSP_VERSION:
18096 printf (" Tag_CSKY_DSP_VERSION:\t\t");
18097 READ_ULEB (val, p, end);
18098 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
18099 printf ("DSP Extension\n");
18100 else if (val == VAL_CSKY_DSP_VERSION_2)
18101 printf ("DSP 2.0\n");
18102 break;
18103
18104 case Tag_CSKY_VDSP_VERSION:
18105 printf (" Tag_CSKY_VDSP_VERSION:\t");
18106 READ_ULEB (val, p, end);
26c527e6 18107 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
18108 break;
18109
18110 case Tag_CSKY_FPU_VERSION:
18111 printf (" Tag_CSKY_FPU_VERSION:\t\t");
18112 READ_ULEB (val, p, end);
18113 if (val == VAL_CSKY_FPU_VERSION_1)
18114 printf ("ABIV1 FPU Version 1\n");
18115 else if (val == VAL_CSKY_FPU_VERSION_2)
18116 printf ("FPU Version 2\n");
18117 break;
18118
18119 case Tag_CSKY_FPU_ABI:
18120 printf (" Tag_CSKY_FPU_ABI:\t\t");
18121 READ_ULEB (val, p, end);
18122 if (val == VAL_CSKY_FPU_ABI_HARD)
18123 printf ("Hard\n");
18124 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18125 printf ("SoftFP\n");
18126 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18127 printf ("Soft\n");
18128 break;
18129 case Tag_CSKY_FPU_ROUNDING:
18130 READ_ULEB (val, p, end);
f253158f
NC
18131 if (val == 1)
18132 {
18133 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18134 printf ("Needed\n");
18135 }
0861f561
CQ
18136 break;
18137 case Tag_CSKY_FPU_DENORMAL:
18138 READ_ULEB (val, p, end);
f253158f
NC
18139 if (val == 1)
18140 {
18141 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18142 printf ("Needed\n");
18143 }
0861f561
CQ
18144 break;
18145 case Tag_CSKY_FPU_Exception:
18146 READ_ULEB (val, p, end);
f253158f
NC
18147 if (val == 1)
18148 {
18149 printf (" Tag_CSKY_FPU_Exception:\t");
18150 printf ("Needed\n");
18151 }
0861f561
CQ
18152 break;
18153 case Tag_CSKY_FPU_NUMBER_MODULE:
18154 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18155 return display_tag_value (-1, p, end);
18156 case Tag_CSKY_FPU_HARDFP:
18157 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18158 READ_ULEB (val, p, end);
18159 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18160 printf (" Half");
18161 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18162 printf (" Single");
18163 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18164 printf (" Double");
18165 printf ("\n");
18166 break;
18167 default:
18168 return display_tag_value (tag, p, end);
18169 }
18170 return p;
18171}
18172
015dc7e1 18173static bool
dda8d76d 18174process_attributes (Filedata * filedata,
60bca95a 18175 const char * public_name,
104d59d1 18176 unsigned int proc_type,
f6f0e17b 18177 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 18178 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 18179{
2cf0635d 18180 Elf_Internal_Shdr * sect;
11c1ff18 18181 unsigned i;
015dc7e1 18182 bool res = true;
11c1ff18
PB
18183
18184 /* Find the section header so that we get the size. */
dda8d76d
NC
18185 for (i = 0, sect = filedata->section_headers;
18186 i < filedata->file_header.e_shnum;
11c1ff18
PB
18187 i++, sect++)
18188 {
071436c6
NC
18189 unsigned char * contents;
18190 unsigned char * p;
18191
104d59d1 18192 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
18193 continue;
18194
dda8d76d 18195 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 18196 sect->sh_size, _("attributes"));
60bca95a 18197 if (contents == NULL)
32ec8896 18198 {
015dc7e1 18199 res = false;
32ec8896
NC
18200 continue;
18201 }
60bca95a 18202
11c1ff18 18203 p = contents;
60abdbed
NC
18204 /* The first character is the version of the attributes.
18205 Currently only version 1, (aka 'A') is recognised here. */
18206 if (*p != 'A')
32ec8896
NC
18207 {
18208 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 18209 res = false;
32ec8896 18210 }
60abdbed 18211 else
11c1ff18 18212 {
625d49fc 18213 uint64_t section_len;
071436c6
NC
18214
18215 section_len = sect->sh_size - 1;
11c1ff18 18216 p++;
60bca95a 18217
071436c6 18218 while (section_len > 0)
11c1ff18 18219 {
625d49fc 18220 uint64_t attr_len;
e9847026 18221 unsigned int namelen;
015dc7e1
AM
18222 bool public_section;
18223 bool gnu_section;
11c1ff18 18224
071436c6 18225 if (section_len <= 4)
e0a31db1
NC
18226 {
18227 error (_("Tag section ends prematurely\n"));
015dc7e1 18228 res = false;
e0a31db1
NC
18229 break;
18230 }
071436c6 18231 attr_len = byte_get (p, 4);
11c1ff18 18232 p += 4;
60bca95a 18233
071436c6 18234 if (attr_len > section_len)
11c1ff18 18235 {
071436c6
NC
18236 error (_("Bad attribute length (%u > %u)\n"),
18237 (unsigned) attr_len, (unsigned) section_len);
18238 attr_len = section_len;
015dc7e1 18239 res = false;
11c1ff18 18240 }
74e1a04b 18241 /* PR 17531: file: 001-101425-0.004 */
071436c6 18242 else if (attr_len < 5)
74e1a04b 18243 {
071436c6 18244 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 18245 res = false;
74e1a04b
NC
18246 break;
18247 }
e9847026 18248
071436c6
NC
18249 section_len -= attr_len;
18250 attr_len -= 4;
18251
18252 namelen = strnlen ((char *) p, attr_len) + 1;
18253 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
18254 {
18255 error (_("Corrupt attribute section name\n"));
015dc7e1 18256 res = false;
e9847026
NC
18257 break;
18258 }
18259
071436c6
NC
18260 printf (_("Attribute Section: "));
18261 print_symbol (INT_MAX, (const char *) p);
18262 putchar ('\n');
60bca95a
NC
18263
18264 if (public_name && streq ((char *) p, public_name))
015dc7e1 18265 public_section = true;
11c1ff18 18266 else
015dc7e1 18267 public_section = false;
60bca95a
NC
18268
18269 if (streq ((char *) p, "gnu"))
015dc7e1 18270 gnu_section = true;
104d59d1 18271 else
015dc7e1 18272 gnu_section = false;
60bca95a 18273
11c1ff18 18274 p += namelen;
071436c6 18275 attr_len -= namelen;
e0a31db1 18276
071436c6 18277 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18278 {
e0a31db1 18279 int tag;
cd30bcef 18280 unsigned int val;
625d49fc 18281 uint64_t size;
071436c6 18282 unsigned char * end;
60bca95a 18283
e0a31db1 18284 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18285 if (attr_len < 6)
e0a31db1
NC
18286 {
18287 error (_("Unused bytes at end of section\n"));
015dc7e1 18288 res = false;
e0a31db1
NC
18289 section_len = 0;
18290 break;
18291 }
18292
18293 tag = *(p++);
11c1ff18 18294 size = byte_get (p, 4);
071436c6 18295 if (size > attr_len)
11c1ff18 18296 {
e9847026 18297 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18298 (unsigned) size, (unsigned) attr_len);
015dc7e1 18299 res = false;
071436c6 18300 size = attr_len;
11c1ff18 18301 }
e0a31db1
NC
18302 /* PR binutils/17531: Safe handling of corrupt files. */
18303 if (size < 6)
18304 {
18305 error (_("Bad subsection length (%u < 6)\n"),
18306 (unsigned) size);
015dc7e1 18307 res = false;
e0a31db1
NC
18308 section_len = 0;
18309 break;
18310 }
60bca95a 18311
071436c6 18312 attr_len -= size;
11c1ff18 18313 end = p + size - 1;
071436c6 18314 assert (end <= contents + sect->sh_size);
11c1ff18 18315 p += 4;
60bca95a 18316
11c1ff18
PB
18317 switch (tag)
18318 {
18319 case 1:
2b692964 18320 printf (_("File Attributes\n"));
11c1ff18
PB
18321 break;
18322 case 2:
2b692964 18323 printf (_("Section Attributes:"));
11c1ff18
PB
18324 goto do_numlist;
18325 case 3:
2b692964 18326 printf (_("Symbol Attributes:"));
1a0670f3 18327 /* Fall through. */
11c1ff18
PB
18328 do_numlist:
18329 for (;;)
18330 {
cd30bcef 18331 READ_ULEB (val, p, end);
11c1ff18
PB
18332 if (val == 0)
18333 break;
18334 printf (" %d", val);
18335 }
18336 printf ("\n");
18337 break;
18338 default:
2b692964 18339 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18340 public_section = false;
11c1ff18
PB
18341 break;
18342 }
60bca95a 18343
071436c6 18344 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18345 {
18346 while (p < end)
f6f0e17b 18347 p = display_pub_attribute (p, end);
60abdbed 18348 assert (p == end);
104d59d1 18349 }
071436c6 18350 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18351 {
18352 while (p < end)
18353 p = display_gnu_attribute (p,
f6f0e17b
NC
18354 display_proc_gnu_attribute,
18355 end);
60abdbed 18356 assert (p == end);
11c1ff18 18357 }
071436c6 18358 else if (p < end)
11c1ff18 18359 {
071436c6 18360 printf (_(" Unknown attribute:\n"));
f6f0e17b 18361 display_raw_attribute (p, end);
11c1ff18
PB
18362 p = end;
18363 }
071436c6
NC
18364 else
18365 attr_len = 0;
11c1ff18
PB
18366 }
18367 }
18368 }
d70c5fc7 18369
60bca95a 18370 free (contents);
11c1ff18 18371 }
32ec8896
NC
18372
18373 return res;
11c1ff18
PB
18374}
18375
ccb4c951
RS
18376/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18377 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18378 and return the VMA of the next entry, or -1 if there was a problem.
18379 Does not read from DATA_END or beyond. */
ccb4c951 18380
625d49fc
AM
18381static uint64_t
18382print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18383 unsigned char * data_end)
ccb4c951
RS
18384{
18385 printf (" ");
18386 print_vma (addr, LONG_HEX);
18387 printf (" ");
18388 if (addr < pltgot + 0xfff0)
18389 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18390 else
18391 printf ("%10s", "");
18392 printf (" ");
18393 if (data == NULL)
2b692964 18394 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18395 else
18396 {
625d49fc 18397 uint64_t entry;
82b1b41b 18398 unsigned char * from = data + addr - pltgot;
ccb4c951 18399
82b1b41b
NC
18400 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18401 {
18402 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18403 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18404 return (uint64_t) -1;
82b1b41b
NC
18405 }
18406 else
18407 {
18408 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18409 print_vma (entry, LONG_HEX);
18410 }
ccb4c951
RS
18411 }
18412 return addr + (is_32bit_elf ? 4 : 8);
18413}
18414
861fb55a
DJ
18415/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18416 PLTGOT. Print the Address and Initial fields of an entry at VMA
18417 ADDR and return the VMA of the next entry. */
18418
625d49fc
AM
18419static uint64_t
18420print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18421{
18422 printf (" ");
18423 print_vma (addr, LONG_HEX);
18424 printf (" ");
18425 if (data == NULL)
2b692964 18426 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18427 else
18428 {
625d49fc 18429 uint64_t entry;
861fb55a
DJ
18430
18431 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18432 print_vma (entry, LONG_HEX);
18433 }
18434 return addr + (is_32bit_elf ? 4 : 8);
18435}
18436
351cdf24
MF
18437static void
18438print_mips_ases (unsigned int mask)
18439{
18440 if (mask & AFL_ASE_DSP)
18441 fputs ("\n\tDSP ASE", stdout);
18442 if (mask & AFL_ASE_DSPR2)
18443 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18444 if (mask & AFL_ASE_DSPR3)
18445 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18446 if (mask & AFL_ASE_EVA)
18447 fputs ("\n\tEnhanced VA Scheme", stdout);
18448 if (mask & AFL_ASE_MCU)
18449 fputs ("\n\tMCU (MicroController) ASE", stdout);
18450 if (mask & AFL_ASE_MDMX)
18451 fputs ("\n\tMDMX ASE", stdout);
18452 if (mask & AFL_ASE_MIPS3D)
18453 fputs ("\n\tMIPS-3D ASE", stdout);
18454 if (mask & AFL_ASE_MT)
18455 fputs ("\n\tMT ASE", stdout);
18456 if (mask & AFL_ASE_SMARTMIPS)
18457 fputs ("\n\tSmartMIPS ASE", stdout);
18458 if (mask & AFL_ASE_VIRT)
18459 fputs ("\n\tVZ ASE", stdout);
18460 if (mask & AFL_ASE_MSA)
18461 fputs ("\n\tMSA ASE", stdout);
18462 if (mask & AFL_ASE_MIPS16)
18463 fputs ("\n\tMIPS16 ASE", stdout);
18464 if (mask & AFL_ASE_MICROMIPS)
18465 fputs ("\n\tMICROMIPS ASE", stdout);
18466 if (mask & AFL_ASE_XPA)
18467 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18468 if (mask & AFL_ASE_MIPS16E2)
18469 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18470 if (mask & AFL_ASE_CRC)
18471 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18472 if (mask & AFL_ASE_GINV)
18473 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18474 if (mask & AFL_ASE_LOONGSON_MMI)
18475 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18476 if (mask & AFL_ASE_LOONGSON_CAM)
18477 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18478 if (mask & AFL_ASE_LOONGSON_EXT)
18479 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18480 if (mask & AFL_ASE_LOONGSON_EXT2)
18481 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18482 if (mask == 0)
18483 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18484 else if ((mask & ~AFL_ASE_MASK) != 0)
18485 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18486}
18487
18488static void
18489print_mips_isa_ext (unsigned int isa_ext)
18490{
18491 switch (isa_ext)
18492 {
18493 case 0:
18494 fputs (_("None"), stdout);
18495 break;
18496 case AFL_EXT_XLR:
18497 fputs ("RMI XLR", stdout);
18498 break;
2c629856
N
18499 case AFL_EXT_OCTEON3:
18500 fputs ("Cavium Networks Octeon3", stdout);
18501 break;
351cdf24
MF
18502 case AFL_EXT_OCTEON2:
18503 fputs ("Cavium Networks Octeon2", stdout);
18504 break;
18505 case AFL_EXT_OCTEONP:
18506 fputs ("Cavium Networks OcteonP", stdout);
18507 break;
351cdf24
MF
18508 case AFL_EXT_OCTEON:
18509 fputs ("Cavium Networks Octeon", stdout);
18510 break;
18511 case AFL_EXT_5900:
18512 fputs ("Toshiba R5900", stdout);
18513 break;
18514 case AFL_EXT_4650:
18515 fputs ("MIPS R4650", stdout);
18516 break;
18517 case AFL_EXT_4010:
18518 fputs ("LSI R4010", stdout);
18519 break;
18520 case AFL_EXT_4100:
18521 fputs ("NEC VR4100", stdout);
18522 break;
18523 case AFL_EXT_3900:
18524 fputs ("Toshiba R3900", stdout);
18525 break;
18526 case AFL_EXT_10000:
18527 fputs ("MIPS R10000", stdout);
18528 break;
18529 case AFL_EXT_SB1:
18530 fputs ("Broadcom SB-1", stdout);
18531 break;
18532 case AFL_EXT_4111:
18533 fputs ("NEC VR4111/VR4181", stdout);
18534 break;
18535 case AFL_EXT_4120:
18536 fputs ("NEC VR4120", stdout);
18537 break;
18538 case AFL_EXT_5400:
18539 fputs ("NEC VR5400", stdout);
18540 break;
18541 case AFL_EXT_5500:
18542 fputs ("NEC VR5500", stdout);
18543 break;
18544 case AFL_EXT_LOONGSON_2E:
18545 fputs ("ST Microelectronics Loongson 2E", stdout);
18546 break;
18547 case AFL_EXT_LOONGSON_2F:
18548 fputs ("ST Microelectronics Loongson 2F", stdout);
18549 break;
38bf472a
MR
18550 case AFL_EXT_INTERAPTIV_MR2:
18551 fputs ("Imagination interAptiv MR2", stdout);
18552 break;
351cdf24 18553 default:
00ac7aa0 18554 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18555 }
18556}
18557
32ec8896 18558static signed int
351cdf24
MF
18559get_mips_reg_size (int reg_size)
18560{
18561 return (reg_size == AFL_REG_NONE) ? 0
18562 : (reg_size == AFL_REG_32) ? 32
18563 : (reg_size == AFL_REG_64) ? 64
18564 : (reg_size == AFL_REG_128) ? 128
18565 : -1;
18566}
18567
015dc7e1 18568static bool
dda8d76d 18569process_mips_specific (Filedata * filedata)
5b18a4bc 18570{
2cf0635d 18571 Elf_Internal_Dyn * entry;
351cdf24 18572 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18573 size_t liblist_offset = 0;
18574 size_t liblistno = 0;
18575 size_t conflictsno = 0;
18576 size_t options_offset = 0;
18577 size_t conflicts_offset = 0;
861fb55a
DJ
18578 size_t pltrelsz = 0;
18579 size_t pltrel = 0;
625d49fc
AM
18580 uint64_t pltgot = 0;
18581 uint64_t mips_pltgot = 0;
18582 uint64_t jmprel = 0;
18583 uint64_t local_gotno = 0;
18584 uint64_t gotsym = 0;
18585 uint64_t symtabno = 0;
015dc7e1 18586 bool res = true;
103f02d3 18587
dda8d76d 18588 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18589 display_mips_gnu_attribute))
015dc7e1 18590 res = false;
2cf19d5c 18591
dda8d76d 18592 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18593
18594 if (sect != NULL)
18595 {
18596 Elf_External_ABIFlags_v0 *abiflags_ext;
18597 Elf_Internal_ABIFlags_v0 abiflags_in;
18598
18599 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18600 {
18601 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18602 res = false;
32ec8896 18603 }
351cdf24
MF
18604 else
18605 {
dda8d76d 18606 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18607 sect->sh_size, _("MIPS ABI Flags section"));
18608 if (abiflags_ext)
18609 {
18610 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18611 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18612 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18613 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18614 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18615 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18616 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18617 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18618 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18619 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18620 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18621
18622 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18623 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18624 if (abiflags_in.isa_rev > 1)
18625 printf ("r%d", abiflags_in.isa_rev);
18626 printf ("\nGPR size: %d",
18627 get_mips_reg_size (abiflags_in.gpr_size));
18628 printf ("\nCPR1 size: %d",
18629 get_mips_reg_size (abiflags_in.cpr1_size));
18630 printf ("\nCPR2 size: %d",
18631 get_mips_reg_size (abiflags_in.cpr2_size));
18632 fputs ("\nFP ABI: ", stdout);
18633 print_mips_fp_abi_value (abiflags_in.fp_abi);
18634 fputs ("ISA Extension: ", stdout);
18635 print_mips_isa_ext (abiflags_in.isa_ext);
18636 fputs ("\nASEs:", stdout);
18637 print_mips_ases (abiflags_in.ases);
18638 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18639 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18640 fputc ('\n', stdout);
18641 free (abiflags_ext);
18642 }
18643 }
18644 }
18645
19e6b90e 18646 /* We have a lot of special sections. Thanks SGI! */
978c4450 18647 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18648 {
18649 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18650 sect = find_section (filedata, ".got");
bbdd9a68
MR
18651 if (sect != NULL)
18652 {
18653 unsigned char *data_end;
18654 unsigned char *data;
625d49fc 18655 uint64_t ent, end;
bbdd9a68
MR
18656 int addr_size;
18657
18658 pltgot = sect->sh_addr;
18659
18660 ent = pltgot;
18661 addr_size = (is_32bit_elf ? 4 : 8);
18662 end = pltgot + sect->sh_size;
18663
dda8d76d 18664 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18665 end - pltgot, 1,
18666 _("Global Offset Table data"));
18667 /* PR 12855: Null data is handled gracefully throughout. */
18668 data_end = data + (end - pltgot);
18669
18670 printf (_("\nStatic GOT:\n"));
18671 printf (_(" Canonical gp value: "));
18672 print_vma (ent + 0x7ff0, LONG_HEX);
18673 printf ("\n\n");
18674
18675 /* In a dynamic binary GOT[0] is reserved for the dynamic
18676 loader to store the lazy resolver pointer, however in
18677 a static binary it may well have been omitted and GOT
18678 reduced to a table of addresses.
18679 PR 21344: Check for the entry being fully available
18680 before fetching it. */
18681 if (data
18682 && data + ent - pltgot + addr_size <= data_end
18683 && byte_get (data + ent - pltgot, addr_size) == 0)
18684 {
18685 printf (_(" Reserved entries:\n"));
18686 printf (_(" %*s %10s %*s\n"),
18687 addr_size * 2, _("Address"), _("Access"),
18688 addr_size * 2, _("Value"));
18689 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18690 printf ("\n");
625d49fc 18691 if (ent == (uint64_t) -1)
bbdd9a68
MR
18692 goto sgot_print_fail;
18693
18694 /* Check for the MSB of GOT[1] being set, identifying a
18695 GNU object. This entry will be used by some runtime
18696 loaders, to store the module pointer. Otherwise this
18697 is an ordinary local entry.
18698 PR 21344: Check for the entry being fully available
18699 before fetching it. */
18700 if (data
18701 && data + ent - pltgot + addr_size <= data_end
18702 && (byte_get (data + ent - pltgot, addr_size)
18703 >> (addr_size * 8 - 1)) != 0)
18704 {
18705 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18706 printf ("\n");
625d49fc 18707 if (ent == (uint64_t) -1)
bbdd9a68
MR
18708 goto sgot_print_fail;
18709 }
18710 printf ("\n");
18711 }
18712
f17e9d8a 18713 if (data != NULL && ent < end)
bbdd9a68
MR
18714 {
18715 printf (_(" Local entries:\n"));
18716 printf (" %*s %10s %*s\n",
18717 addr_size * 2, _("Address"), _("Access"),
18718 addr_size * 2, _("Value"));
18719 while (ent < end)
18720 {
18721 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18722 printf ("\n");
625d49fc 18723 if (ent == (uint64_t) -1)
bbdd9a68
MR
18724 goto sgot_print_fail;
18725 }
18726 printf ("\n");
18727 }
18728
18729 sgot_print_fail:
9db70fc3 18730 free (data);
bbdd9a68
MR
18731 }
18732 return res;
18733 }
252b5132 18734
978c4450 18735 for (entry = filedata->dynamic_section;
071436c6 18736 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18737 (entry < filedata->dynamic_section + filedata->dynamic_nent
18738 && entry->d_tag != DT_NULL);
071436c6 18739 ++entry)
252b5132
RH
18740 switch (entry->d_tag)
18741 {
18742 case DT_MIPS_LIBLIST:
d93f0186 18743 liblist_offset
dda8d76d 18744 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18745 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18746 break;
18747 case DT_MIPS_LIBLISTNO:
18748 liblistno = entry->d_un.d_val;
18749 break;
18750 case DT_MIPS_OPTIONS:
dda8d76d 18751 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18752 break;
18753 case DT_MIPS_CONFLICT:
d93f0186 18754 conflicts_offset
dda8d76d 18755 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18756 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18757 break;
18758 case DT_MIPS_CONFLICTNO:
18759 conflictsno = entry->d_un.d_val;
18760 break;
ccb4c951 18761 case DT_PLTGOT:
861fb55a
DJ
18762 pltgot = entry->d_un.d_ptr;
18763 break;
ccb4c951
RS
18764 case DT_MIPS_LOCAL_GOTNO:
18765 local_gotno = entry->d_un.d_val;
18766 break;
18767 case DT_MIPS_GOTSYM:
18768 gotsym = entry->d_un.d_val;
18769 break;
18770 case DT_MIPS_SYMTABNO:
18771 symtabno = entry->d_un.d_val;
18772 break;
861fb55a
DJ
18773 case DT_MIPS_PLTGOT:
18774 mips_pltgot = entry->d_un.d_ptr;
18775 break;
18776 case DT_PLTREL:
18777 pltrel = entry->d_un.d_val;
18778 break;
18779 case DT_PLTRELSZ:
18780 pltrelsz = entry->d_un.d_val;
18781 break;
18782 case DT_JMPREL:
18783 jmprel = entry->d_un.d_ptr;
18784 break;
252b5132
RH
18785 default:
18786 break;
18787 }
18788
18789 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18790 {
2cf0635d 18791 Elf32_External_Lib * elib;
252b5132
RH
18792 size_t cnt;
18793
dda8d76d 18794 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18795 sizeof (Elf32_External_Lib),
18796 liblistno,
18797 _("liblist section data"));
a6e9f9df 18798 if (elib)
252b5132 18799 {
26c527e6
AM
18800 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
18801 "\nSection '.liblist' contains %zu entries:\n",
18802 liblistno),
18803 liblistno);
2b692964 18804 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18805 stdout);
18806
18807 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18808 {
a6e9f9df 18809 Elf32_Lib liblist;
91d6fa6a 18810 time_t atime;
d5b07ef4 18811 char timebuf[128];
2cf0635d 18812 struct tm * tmp;
a6e9f9df
AM
18813
18814 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18815 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18816 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18817 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18818 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18819
91d6fa6a 18820 tmp = gmtime (&atime);
e9e44622
JJ
18821 snprintf (timebuf, sizeof (timebuf),
18822 "%04u-%02u-%02uT%02u:%02u:%02u",
18823 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18824 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18825
26c527e6 18826 printf ("%3zu: ", cnt);
84714f86
AM
18827 if (valid_dynamic_name (filedata, liblist.l_name))
18828 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18829 else
2b692964 18830 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18831 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18832 liblist.l_version);
a6e9f9df
AM
18833
18834 if (liblist.l_flags == 0)
2b692964 18835 puts (_(" NONE"));
a6e9f9df
AM
18836 else
18837 {
18838 static const struct
252b5132 18839 {
2cf0635d 18840 const char * name;
a6e9f9df 18841 int bit;
252b5132 18842 }
a6e9f9df
AM
18843 l_flags_vals[] =
18844 {
18845 { " EXACT_MATCH", LL_EXACT_MATCH },
18846 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18847 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18848 { " EXPORTS", LL_EXPORTS },
18849 { " DELAY_LOAD", LL_DELAY_LOAD },
18850 { " DELTA", LL_DELTA }
18851 };
18852 int flags = liblist.l_flags;
18853 size_t fcnt;
18854
60bca95a 18855 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18856 if ((flags & l_flags_vals[fcnt].bit) != 0)
18857 {
18858 fputs (l_flags_vals[fcnt].name, stdout);
18859 flags ^= l_flags_vals[fcnt].bit;
18860 }
18861 if (flags != 0)
18862 printf (" %#x", (unsigned int) flags);
252b5132 18863
a6e9f9df
AM
18864 puts ("");
18865 }
252b5132 18866 }
252b5132 18867
a6e9f9df
AM
18868 free (elib);
18869 }
32ec8896 18870 else
015dc7e1 18871 res = false;
252b5132
RH
18872 }
18873
18874 if (options_offset != 0)
18875 {
2cf0635d 18876 Elf_External_Options * eopt;
252b5132
RH
18877 size_t offset;
18878 int cnt;
18879
18880 /* Find the section header so that we get the size. */
dda8d76d 18881 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18882 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18883 if (sect == NULL)
18884 {
18885 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18886 return false;
071436c6 18887 }
7fc0c668
NC
18888 /* PR 24243 */
18889 if (sect->sh_size < sizeof (* eopt))
18890 {
18891 error (_("The MIPS options section is too small.\n"));
015dc7e1 18892 return false;
7fc0c668 18893 }
252b5132 18894
dda8d76d 18895 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18896 sect->sh_size, _("options"));
a6e9f9df 18897 if (eopt)
252b5132 18898 {
fd17d1e6 18899 Elf_Internal_Options option;
76da6bbe 18900
a6e9f9df 18901 offset = cnt = 0;
82b1b41b 18902 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18903 {
2cf0635d 18904 Elf_External_Options * eoption;
fd17d1e6 18905 unsigned int optsize;
252b5132 18906
a6e9f9df 18907 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18908
fd17d1e6 18909 optsize = BYTE_GET (eoption->size);
76da6bbe 18910
82b1b41b 18911 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18912 if (optsize < sizeof (* eopt)
18913 || optsize > sect->sh_size - offset)
82b1b41b 18914 {
645f43a8 18915 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18916 optsize);
645f43a8 18917 free (eopt);
015dc7e1 18918 return false;
82b1b41b 18919 }
fd17d1e6 18920 offset += optsize;
a6e9f9df
AM
18921 ++cnt;
18922 }
252b5132 18923
d3a49aa8
AM
18924 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18925 "\nSection '%s' contains %d entries:\n",
18926 cnt),
dda8d76d 18927 printable_section_name (filedata, sect), cnt);
76da6bbe 18928
82b1b41b 18929 offset = 0;
a6e9f9df 18930 while (cnt-- > 0)
252b5132 18931 {
a6e9f9df 18932 size_t len;
fd17d1e6
AM
18933 Elf_External_Options * eoption;
18934
18935 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18936
18937 option.kind = BYTE_GET (eoption->kind);
18938 option.size = BYTE_GET (eoption->size);
18939 option.section = BYTE_GET (eoption->section);
18940 option.info = BYTE_GET (eoption->info);
a6e9f9df 18941
fd17d1e6 18942 switch (option.kind)
252b5132 18943 {
a6e9f9df
AM
18944 case ODK_NULL:
18945 /* This shouldn't happen. */
d0c4e780 18946 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18947 option.section, option.info);
a6e9f9df 18948 break;
2e6be59c 18949
a6e9f9df
AM
18950 case ODK_REGINFO:
18951 printf (" REGINFO ");
dda8d76d 18952 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18953 {
2cf0635d 18954 Elf32_External_RegInfo * ereg;
b34976b6 18955 Elf32_RegInfo reginfo;
a6e9f9df 18956
2e6be59c 18957 /* 32bit form. */
fd17d1e6
AM
18958 if (option.size < (sizeof (Elf_External_Options)
18959 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18960 {
18961 printf (_("<corrupt>\n"));
18962 error (_("Truncated MIPS REGINFO option\n"));
18963 cnt = 0;
18964 break;
18965 }
18966
fd17d1e6 18967 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18968
a6e9f9df
AM
18969 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18970 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18971 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18972 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18973 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18974 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18975
d0c4e780
AM
18976 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18977 reginfo.ri_gprmask, reginfo.ri_gp_value);
18978 printf (" "
18979 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18980 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18981 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18982 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18983 }
18984 else
18985 {
18986 /* 64 bit form. */
2cf0635d 18987 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18988 Elf64_Internal_RegInfo reginfo;
18989
fd17d1e6
AM
18990 if (option.size < (sizeof (Elf_External_Options)
18991 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18992 {
18993 printf (_("<corrupt>\n"));
18994 error (_("Truncated MIPS REGINFO option\n"));
18995 cnt = 0;
18996 break;
18997 }
18998
fd17d1e6 18999 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
19000 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19001 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19002 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19003 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19004 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 19005 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 19006
d0c4e780
AM
19007 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
19008 reginfo.ri_gprmask, reginfo.ri_gp_value);
19009 printf (" "
19010 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19011 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19012 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19013 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19014 }
fd17d1e6 19015 offset += option.size;
a6e9f9df 19016 continue;
2e6be59c 19017
a6e9f9df
AM
19018 case ODK_EXCEPTIONS:
19019 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 19020 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 19021 fputs (") fpe_max(", stdout);
fd17d1e6 19022 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
19023 fputs (")", stdout);
19024
fd17d1e6 19025 if (option.info & OEX_PAGE0)
a6e9f9df 19026 fputs (" PAGE0", stdout);
fd17d1e6 19027 if (option.info & OEX_SMM)
a6e9f9df 19028 fputs (" SMM", stdout);
fd17d1e6 19029 if (option.info & OEX_FPDBUG)
a6e9f9df 19030 fputs (" FPDBUG", stdout);
fd17d1e6 19031 if (option.info & OEX_DISMISS)
a6e9f9df
AM
19032 fputs (" DISMISS", stdout);
19033 break;
2e6be59c 19034
a6e9f9df
AM
19035 case ODK_PAD:
19036 fputs (" PAD ", stdout);
fd17d1e6 19037 if (option.info & OPAD_PREFIX)
a6e9f9df 19038 fputs (" PREFIX", stdout);
fd17d1e6 19039 if (option.info & OPAD_POSTFIX)
a6e9f9df 19040 fputs (" POSTFIX", stdout);
fd17d1e6 19041 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
19042 fputs (" SYMBOL", stdout);
19043 break;
2e6be59c 19044
a6e9f9df
AM
19045 case ODK_HWPATCH:
19046 fputs (" HWPATCH ", stdout);
fd17d1e6 19047 if (option.info & OHW_R4KEOP)
a6e9f9df 19048 fputs (" R4KEOP", stdout);
fd17d1e6 19049 if (option.info & OHW_R8KPFETCH)
a6e9f9df 19050 fputs (" R8KPFETCH", stdout);
fd17d1e6 19051 if (option.info & OHW_R5KEOP)
a6e9f9df 19052 fputs (" R5KEOP", stdout);
fd17d1e6 19053 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
19054 fputs (" R5KCVTL", stdout);
19055 break;
2e6be59c 19056
a6e9f9df
AM
19057 case ODK_FILL:
19058 fputs (" FILL ", stdout);
19059 /* XXX Print content of info word? */
19060 break;
2e6be59c 19061
a6e9f9df
AM
19062 case ODK_TAGS:
19063 fputs (" TAGS ", stdout);
19064 /* XXX Print content of info word? */
19065 break;
2e6be59c 19066
a6e9f9df
AM
19067 case ODK_HWAND:
19068 fputs (" HWAND ", stdout);
fd17d1e6 19069 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19070 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19071 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19072 fputs (" R4KEOP_CLEAN", stdout);
19073 break;
2e6be59c 19074
a6e9f9df
AM
19075 case ODK_HWOR:
19076 fputs (" HWOR ", stdout);
fd17d1e6 19077 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19078 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19079 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19080 fputs (" R4KEOP_CLEAN", stdout);
19081 break;
2e6be59c 19082
a6e9f9df 19083 case ODK_GP_GROUP:
d0c4e780 19084 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
19085 option.info & OGP_GROUP,
19086 (option.info & OGP_SELF) >> 16);
a6e9f9df 19087 break;
2e6be59c 19088
a6e9f9df 19089 case ODK_IDENT:
d0c4e780 19090 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
19091 option.info & OGP_GROUP,
19092 (option.info & OGP_SELF) >> 16);
a6e9f9df 19093 break;
2e6be59c 19094
a6e9f9df
AM
19095 default:
19096 /* This shouldn't happen. */
d0c4e780 19097 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 19098 option.kind, option.section, option.info);
a6e9f9df 19099 break;
252b5132 19100 }
a6e9f9df 19101
2cf0635d 19102 len = sizeof (* eopt);
fd17d1e6 19103 while (len < option.size)
82b1b41b 19104 {
fd17d1e6 19105 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 19106
82b1b41b
NC
19107 if (ISPRINT (datum))
19108 printf ("%c", datum);
19109 else
19110 printf ("\\%03o", datum);
19111 len ++;
19112 }
a6e9f9df 19113 fputs ("\n", stdout);
82b1b41b 19114
fd17d1e6 19115 offset += option.size;
252b5132 19116 }
a6e9f9df 19117 free (eopt);
252b5132 19118 }
32ec8896 19119 else
015dc7e1 19120 res = false;
252b5132
RH
19121 }
19122
19123 if (conflicts_offset != 0 && conflictsno != 0)
19124 {
2cf0635d 19125 Elf32_Conflict * iconf;
252b5132
RH
19126 size_t cnt;
19127
978c4450 19128 if (filedata->dynamic_symbols == NULL)
252b5132 19129 {
591a748a 19130 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 19131 return false;
252b5132
RH
19132 }
19133
7296a62a
NC
19134 /* PR 21345 - print a slightly more helpful error message
19135 if we are sure that the cmalloc will fail. */
645f43a8 19136 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 19137 {
26c527e6
AM
19138 error (_("Overlarge number of conflicts detected: %zx\n"),
19139 conflictsno);
015dc7e1 19140 return false;
7296a62a
NC
19141 }
19142
3f5e193b 19143 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
19144 if (iconf == NULL)
19145 {
8b73c356 19146 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 19147 return false;
252b5132
RH
19148 }
19149
9ea033b2 19150 if (is_32bit_elf)
252b5132 19151 {
2cf0635d 19152 Elf32_External_Conflict * econf32;
a6e9f9df 19153
3f5e193b 19154 econf32 = (Elf32_External_Conflict *)
95099889
AM
19155 get_data (NULL, filedata, conflicts_offset,
19156 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 19157 if (!econf32)
5a814d6d
AM
19158 {
19159 free (iconf);
015dc7e1 19160 return false;
5a814d6d 19161 }
252b5132
RH
19162
19163 for (cnt = 0; cnt < conflictsno; ++cnt)
19164 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
19165
19166 free (econf32);
252b5132
RH
19167 }
19168 else
19169 {
2cf0635d 19170 Elf64_External_Conflict * econf64;
a6e9f9df 19171
3f5e193b 19172 econf64 = (Elf64_External_Conflict *)
95099889
AM
19173 get_data (NULL, filedata, conflicts_offset,
19174 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 19175 if (!econf64)
5a814d6d
AM
19176 {
19177 free (iconf);
015dc7e1 19178 return false;
5a814d6d 19179 }
252b5132
RH
19180
19181 for (cnt = 0; cnt < conflictsno; ++cnt)
19182 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
19183
19184 free (econf64);
252b5132
RH
19185 }
19186
26c527e6
AM
19187 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19188 "\nSection '.conflict' contains %zu entries:\n",
19189 conflictsno),
19190 conflictsno);
252b5132
RH
19191 puts (_(" Num: Index Value Name"));
19192
19193 for (cnt = 0; cnt < conflictsno; ++cnt)
19194 {
26c527e6 19195 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 19196
978c4450 19197 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 19198 printf (_("<corrupt symbol index>"));
d79b3d50 19199 else
e0a31db1
NC
19200 {
19201 Elf_Internal_Sym * psym;
19202
978c4450 19203 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
19204 print_vma (psym->st_value, FULL_HEX);
19205 putchar (' ');
84714f86
AM
19206 if (valid_dynamic_name (filedata, psym->st_name))
19207 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19208 else
19209 printf (_("<corrupt: %14ld>"), psym->st_name);
19210 }
31104126 19211 putchar ('\n');
252b5132
RH
19212 }
19213
252b5132
RH
19214 free (iconf);
19215 }
19216
ccb4c951
RS
19217 if (pltgot != 0 && local_gotno != 0)
19218 {
625d49fc 19219 uint64_t ent, local_end, global_end;
bbeee7ea 19220 size_t i, offset;
2cf0635d 19221 unsigned char * data;
82b1b41b 19222 unsigned char * data_end;
bbeee7ea 19223 int addr_size;
ccb4c951 19224
91d6fa6a 19225 ent = pltgot;
ccb4c951
RS
19226 addr_size = (is_32bit_elf ? 4 : 8);
19227 local_end = pltgot + local_gotno * addr_size;
ccb4c951 19228
74e1a04b
NC
19229 /* PR binutils/17533 file: 012-111227-0.004 */
19230 if (symtabno < gotsym)
19231 {
26c527e6
AM
19232 error (_("The GOT symbol offset (%" PRIu64
19233 ") is greater than the symbol table size (%" PRIu64 ")\n"),
19234 gotsym, symtabno);
015dc7e1 19235 return false;
74e1a04b 19236 }
82b1b41b 19237
74e1a04b 19238 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
19239 /* PR 17531: file: 54c91a34. */
19240 if (global_end < local_end)
19241 {
26c527e6 19242 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 19243 return false;
82b1b41b 19244 }
948f632f 19245
dda8d76d
NC
19246 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
19247 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
19248 global_end - pltgot, 1,
19249 _("Global Offset Table data"));
919383ac 19250 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 19251 data_end = data + (global_end - pltgot);
59245841 19252
ccb4c951
RS
19253 printf (_("\nPrimary GOT:\n"));
19254 printf (_(" Canonical gp value: "));
19255 print_vma (pltgot + 0x7ff0, LONG_HEX);
19256 printf ("\n\n");
19257
19258 printf (_(" Reserved entries:\n"));
19259 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
19260 addr_size * 2, _("Address"), _("Access"),
19261 addr_size * 2, _("Initial"));
82b1b41b 19262 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 19263 printf (_(" Lazy resolver\n"));
625d49fc 19264 if (ent == (uint64_t) -1)
82b1b41b 19265 goto got_print_fail;
75ec1fdb 19266
c4ab9505
MR
19267 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19268 This entry will be used by some runtime loaders, to store the
19269 module pointer. Otherwise this is an ordinary local entry.
19270 PR 21344: Check for the entry being fully available before
19271 fetching it. */
19272 if (data
19273 && data + ent - pltgot + addr_size <= data_end
19274 && (byte_get (data + ent - pltgot, addr_size)
19275 >> (addr_size * 8 - 1)) != 0)
19276 {
19277 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19278 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 19279 if (ent == (uint64_t) -1)
c4ab9505 19280 goto got_print_fail;
ccb4c951
RS
19281 }
19282 printf ("\n");
19283
f17e9d8a 19284 if (data != NULL && ent < local_end)
ccb4c951
RS
19285 {
19286 printf (_(" Local entries:\n"));
cc5914eb 19287 printf (" %*s %10s %*s\n",
2b692964
NC
19288 addr_size * 2, _("Address"), _("Access"),
19289 addr_size * 2, _("Initial"));
91d6fa6a 19290 while (ent < local_end)
ccb4c951 19291 {
82b1b41b 19292 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19293 printf ("\n");
625d49fc 19294 if (ent == (uint64_t) -1)
82b1b41b 19295 goto got_print_fail;
ccb4c951
RS
19296 }
19297 printf ("\n");
19298 }
19299
f17e9d8a 19300 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19301 {
19302 int sym_width;
19303
19304 printf (_(" Global entries:\n"));
cc5914eb 19305 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19306 addr_size * 2, _("Address"),
19307 _("Access"),
2b692964 19308 addr_size * 2, _("Initial"),
9cf03b7e
NC
19309 addr_size * 2, _("Sym.Val."),
19310 _("Type"),
19311 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19312 _("Ndx"), _("Name"));
0b4362b0 19313
ccb4c951 19314 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19315
ccb4c951
RS
19316 for (i = gotsym; i < symtabno; i++)
19317 {
82b1b41b 19318 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19319 printf (" ");
e0a31db1 19320
978c4450 19321 if (filedata->dynamic_symbols == NULL)
e0a31db1 19322 printf (_("<no dynamic symbols>"));
978c4450 19323 else if (i < filedata->num_dynamic_syms)
e0a31db1 19324 {
978c4450 19325 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19326
19327 print_vma (psym->st_value, LONG_HEX);
19328 printf (" %-7s %3s ",
dda8d76d
NC
19329 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19330 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19331
84714f86 19332 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19333 print_symbol (sym_width,
84714f86 19334 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19335 else
19336 printf (_("<corrupt: %14ld>"), psym->st_name);
19337 }
ccb4c951 19338 else
26c527e6
AM
19339 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
19340 i);
e0a31db1 19341
ccb4c951 19342 printf ("\n");
625d49fc 19343 if (ent == (uint64_t) -1)
82b1b41b 19344 break;
ccb4c951
RS
19345 }
19346 printf ("\n");
19347 }
19348
82b1b41b 19349 got_print_fail:
9db70fc3 19350 free (data);
ccb4c951
RS
19351 }
19352
861fb55a
DJ
19353 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19354 {
625d49fc 19355 uint64_t ent, end;
26c527e6
AM
19356 uint64_t offset, rel_offset;
19357 uint64_t count, i;
2cf0635d 19358 unsigned char * data;
861fb55a 19359 int addr_size, sym_width;
2cf0635d 19360 Elf_Internal_Rela * rels;
861fb55a 19361
dda8d76d 19362 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19363 if (pltrel == DT_RELA)
19364 {
dda8d76d 19365 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19366 return false;
861fb55a
DJ
19367 }
19368 else
19369 {
dda8d76d 19370 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19371 return false;
861fb55a
DJ
19372 }
19373
91d6fa6a 19374 ent = mips_pltgot;
861fb55a
DJ
19375 addr_size = (is_32bit_elf ? 4 : 8);
19376 end = mips_pltgot + (2 + count) * addr_size;
19377
dda8d76d
NC
19378 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19379 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19380 1, _("Procedure Linkage Table data"));
59245841 19381 if (data == NULL)
288f0ba2
AM
19382 {
19383 free (rels);
015dc7e1 19384 return false;
288f0ba2 19385 }
59245841 19386
9cf03b7e 19387 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19388 printf (_(" Reserved entries:\n"));
19389 printf (_(" %*s %*s Purpose\n"),
2b692964 19390 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19391 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19392 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19393 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19394 printf (_(" Module pointer\n"));
861fb55a
DJ
19395 printf ("\n");
19396
19397 printf (_(" Entries:\n"));
cc5914eb 19398 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19399 addr_size * 2, _("Address"),
19400 addr_size * 2, _("Initial"),
19401 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19402 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19403 for (i = 0; i < count; i++)
19404 {
26c527e6 19405 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19406
91d6fa6a 19407 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19408 printf (" ");
e0a31db1 19409
978c4450 19410 if (idx >= filedata->num_dynamic_syms)
26c527e6 19411 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 19412 else
e0a31db1 19413 {
978c4450 19414 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19415
19416 print_vma (psym->st_value, LONG_HEX);
19417 printf (" %-7s %3s ",
dda8d76d
NC
19418 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19419 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19420 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19421 print_symbol (sym_width,
84714f86 19422 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19423 else
19424 printf (_("<corrupt: %14ld>"), psym->st_name);
19425 }
861fb55a
DJ
19426 printf ("\n");
19427 }
19428 printf ("\n");
19429
9db70fc3 19430 free (data);
861fb55a
DJ
19431 free (rels);
19432 }
19433
32ec8896 19434 return res;
252b5132
RH
19435}
19436
015dc7e1 19437static bool
dda8d76d 19438process_nds32_specific (Filedata * filedata)
35c08157
KLC
19439{
19440 Elf_Internal_Shdr *sect = NULL;
19441
dda8d76d 19442 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19443 if (sect != NULL && sect->sh_size >= 4)
35c08157 19444 {
9c7b8e9b
AM
19445 unsigned char *buf;
19446 unsigned int flag;
35c08157
KLC
19447
19448 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19449 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19450 _("NDS32 elf flags section"));
35c08157 19451
9c7b8e9b 19452 if (buf == NULL)
015dc7e1 19453 return false;
32ec8896 19454
9c7b8e9b
AM
19455 flag = byte_get (buf, 4);
19456 free (buf);
19457 switch (flag & 0x3)
35c08157
KLC
19458 {
19459 case 0:
19460 printf ("(VEC_SIZE):\tNo entry.\n");
19461 break;
19462 case 1:
19463 printf ("(VEC_SIZE):\t4 bytes\n");
19464 break;
19465 case 2:
19466 printf ("(VEC_SIZE):\t16 bytes\n");
19467 break;
19468 case 3:
19469 printf ("(VEC_SIZE):\treserved\n");
19470 break;
19471 }
19472 }
19473
015dc7e1 19474 return true;
35c08157
KLC
19475}
19476
015dc7e1 19477static bool
dda8d76d 19478process_gnu_liblist (Filedata * filedata)
047b2264 19479{
2cf0635d
NC
19480 Elf_Internal_Shdr * section;
19481 Elf_Internal_Shdr * string_sec;
19482 Elf32_External_Lib * elib;
19483 char * strtab;
c256ffe7 19484 size_t strtab_size;
047b2264 19485 size_t cnt;
26c527e6 19486 uint64_t num_liblist;
047b2264 19487 unsigned i;
015dc7e1 19488 bool res = true;
047b2264
JJ
19489
19490 if (! do_arch)
015dc7e1 19491 return true;
047b2264 19492
dda8d76d
NC
19493 for (i = 0, section = filedata->section_headers;
19494 i < filedata->file_header.e_shnum;
b34976b6 19495 i++, section++)
047b2264
JJ
19496 {
19497 switch (section->sh_type)
19498 {
19499 case SHT_GNU_LIBLIST:
dda8d76d 19500 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19501 break;
19502
3f5e193b 19503 elib = (Elf32_External_Lib *)
dda8d76d 19504 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19505 _("liblist section data"));
047b2264
JJ
19506
19507 if (elib == NULL)
32ec8896 19508 {
015dc7e1 19509 res = false;
32ec8896
NC
19510 break;
19511 }
047b2264 19512
dda8d76d
NC
19513 string_sec = filedata->section_headers + section->sh_link;
19514 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19515 string_sec->sh_size,
19516 _("liblist string table"));
047b2264
JJ
19517 if (strtab == NULL
19518 || section->sh_entsize != sizeof (Elf32_External_Lib))
19519 {
19520 free (elib);
2842702f 19521 free (strtab);
015dc7e1 19522 res = false;
047b2264
JJ
19523 break;
19524 }
59245841 19525 strtab_size = string_sec->sh_size;
047b2264 19526
d3a49aa8 19527 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
19528 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
19529 " entries:\n",
19530 "\nLibrary list section '%s' contains %" PRIu64
19531 " entries:\n",
d3a49aa8 19532 num_liblist),
dda8d76d 19533 printable_section_name (filedata, section),
d3a49aa8 19534 num_liblist);
047b2264 19535
2b692964 19536 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19537
19538 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19539 ++cnt)
19540 {
19541 Elf32_Lib liblist;
91d6fa6a 19542 time_t atime;
d5b07ef4 19543 char timebuf[128];
2cf0635d 19544 struct tm * tmp;
047b2264
JJ
19545
19546 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19547 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19548 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19549 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19550 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19551
91d6fa6a 19552 tmp = gmtime (&atime);
e9e44622
JJ
19553 snprintf (timebuf, sizeof (timebuf),
19554 "%04u-%02u-%02uT%02u:%02u:%02u",
19555 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19556 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 19557
26c527e6 19558 printf ("%3zu: ", cnt);
047b2264 19559 if (do_wide)
c256ffe7 19560 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19561 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19562 else
c256ffe7 19563 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19564 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19565 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19566 liblist.l_version, liblist.l_flags);
19567 }
19568
19569 free (elib);
2842702f 19570 free (strtab);
047b2264
JJ
19571 }
19572 }
19573
32ec8896 19574 return res;
047b2264
JJ
19575}
19576
9437c45b 19577static const char *
dda8d76d 19578get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19579{
19580 static char buff[64];
103f02d3 19581
dda8d76d 19582 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19583 switch (e_type)
19584 {
57346661 19585 case NT_AUXV:
1ec5cd37 19586 return _("NT_AUXV (auxiliary vector)");
57346661 19587 case NT_PRSTATUS:
1ec5cd37 19588 return _("NT_PRSTATUS (prstatus structure)");
57346661 19589 case NT_FPREGSET:
1ec5cd37 19590 return _("NT_FPREGSET (floating point registers)");
57346661 19591 case NT_PRPSINFO:
1ec5cd37 19592 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19593 case NT_TASKSTRUCT:
1ec5cd37 19594 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19595 case NT_GDB_TDESC:
19596 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19597 case NT_PRXFPREG:
1ec5cd37 19598 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19599 case NT_PPC_VMX:
19600 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19601 case NT_PPC_VSX:
19602 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19603 case NT_PPC_TAR:
19604 return _("NT_PPC_TAR (ppc TAR register)");
19605 case NT_PPC_PPR:
19606 return _("NT_PPC_PPR (ppc PPR register)");
19607 case NT_PPC_DSCR:
19608 return _("NT_PPC_DSCR (ppc DSCR register)");
19609 case NT_PPC_EBB:
19610 return _("NT_PPC_EBB (ppc EBB registers)");
19611 case NT_PPC_PMU:
19612 return _("NT_PPC_PMU (ppc PMU registers)");
19613 case NT_PPC_TM_CGPR:
19614 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19615 case NT_PPC_TM_CFPR:
19616 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19617 case NT_PPC_TM_CVMX:
19618 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19619 case NT_PPC_TM_CVSX:
3fd21718 19620 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19621 case NT_PPC_TM_SPR:
19622 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19623 case NT_PPC_TM_CTAR:
19624 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19625 case NT_PPC_TM_CPPR:
19626 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19627 case NT_PPC_TM_CDSCR:
19628 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19629 case NT_386_TLS:
19630 return _("NT_386_TLS (x86 TLS information)");
19631 case NT_386_IOPERM:
19632 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19633 case NT_X86_XSTATE:
19634 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19635 case NT_X86_CET:
19636 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19637 case NT_S390_HIGH_GPRS:
19638 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19639 case NT_S390_TIMER:
19640 return _("NT_S390_TIMER (s390 timer register)");
19641 case NT_S390_TODCMP:
19642 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19643 case NT_S390_TODPREG:
19644 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19645 case NT_S390_CTRS:
19646 return _("NT_S390_CTRS (s390 control registers)");
19647 case NT_S390_PREFIX:
19648 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19649 case NT_S390_LAST_BREAK:
19650 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19651 case NT_S390_SYSTEM_CALL:
19652 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19653 case NT_S390_TDB:
19654 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19655 case NT_S390_VXRS_LOW:
19656 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19657 case NT_S390_VXRS_HIGH:
19658 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19659 case NT_S390_GS_CB:
19660 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19661 case NT_S390_GS_BC:
19662 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19663 case NT_ARM_VFP:
19664 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19665 case NT_ARM_TLS:
19666 return _("NT_ARM_TLS (AArch TLS registers)");
19667 case NT_ARM_HW_BREAK:
19668 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19669 case NT_ARM_HW_WATCH:
19670 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
19671 case NT_ARM_SYSTEM_CALL:
19672 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
19673 case NT_ARM_SVE:
19674 return _("NT_ARM_SVE (AArch SVE registers)");
19675 case NT_ARM_PAC_MASK:
19676 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19677 case NT_ARM_PACA_KEYS:
19678 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19679 case NT_ARM_PACG_KEYS:
19680 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19681 case NT_ARM_TAGGED_ADDR_CTRL:
19682 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
a8f175d9
LM
19683 case NT_ARM_SSVE:
19684 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
19685 case NT_ARM_ZA:
19686 return _("NT_ARM_ZA (AArch64 SME ZA register)");
3af2785c
LM
19687 case NT_ARM_PAC_ENABLED_KEYS:
19688 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19689 case NT_ARC_V2:
19690 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19691 case NT_RISCV_CSR:
19692 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19693 case NT_PSTATUS:
1ec5cd37 19694 return _("NT_PSTATUS (pstatus structure)");
57346661 19695 case NT_FPREGS:
1ec5cd37 19696 return _("NT_FPREGS (floating point registers)");
57346661 19697 case NT_PSINFO:
1ec5cd37 19698 return _("NT_PSINFO (psinfo structure)");
57346661 19699 case NT_LWPSTATUS:
1ec5cd37 19700 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19701 case NT_LWPSINFO:
1ec5cd37 19702 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19703 case NT_WIN32PSTATUS:
1ec5cd37 19704 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19705 case NT_SIGINFO:
19706 return _("NT_SIGINFO (siginfo_t data)");
19707 case NT_FILE:
19708 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19709 default:
19710 break;
19711 }
19712 else
19713 switch (e_type)
19714 {
19715 case NT_VERSION:
19716 return _("NT_VERSION (version)");
19717 case NT_ARCH:
19718 return _("NT_ARCH (architecture)");
9ef920e9 19719 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19720 return _("OPEN");
9ef920e9 19721 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19722 return _("func");
c8795e1f
NC
19723 case NT_GO_BUILDID:
19724 return _("GO BUILDID");
3ac925fc
LB
19725 case FDO_PACKAGING_METADATA:
19726 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19727 default:
19728 break;
19729 }
19730
e9e44622 19731 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19732 return buff;
779fe533
NC
19733}
19734
015dc7e1 19735static bool
9ece1fa9
TT
19736print_core_note (Elf_Internal_Note *pnote)
19737{
19738 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 19739 uint64_t count, page_size;
9ece1fa9
TT
19740 unsigned char *descdata, *filenames, *descend;
19741
19742 if (pnote->type != NT_FILE)
04ac15ab
AS
19743 {
19744 if (do_wide)
19745 printf ("\n");
015dc7e1 19746 return true;
04ac15ab 19747 }
9ece1fa9 19748
9ece1fa9
TT
19749 if (!is_32bit_elf)
19750 {
19751 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19752 /* Still "successful". */
015dc7e1 19753 return true;
9ece1fa9 19754 }
9ece1fa9
TT
19755
19756 if (pnote->descsz < 2 * addr_size)
19757 {
32ec8896 19758 error (_(" Malformed note - too short for header\n"));
015dc7e1 19759 return false;
9ece1fa9
TT
19760 }
19761
19762 descdata = (unsigned char *) pnote->descdata;
19763 descend = descdata + pnote->descsz;
19764
19765 if (descdata[pnote->descsz - 1] != '\0')
19766 {
32ec8896 19767 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19768 return false;
9ece1fa9
TT
19769 }
19770
19771 count = byte_get (descdata, addr_size);
19772 descdata += addr_size;
19773
19774 page_size = byte_get (descdata, addr_size);
19775 descdata += addr_size;
19776
625d49fc 19777 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 19778 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19779 {
32ec8896 19780 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19781 return false;
9ece1fa9
TT
19782 }
19783
19784 printf (_(" Page size: "));
19785 print_vma (page_size, DEC);
19786 printf ("\n");
19787
19788 printf (_(" %*s%*s%*s\n"),
19789 (int) (2 + 2 * addr_size), _("Start"),
19790 (int) (4 + 2 * addr_size), _("End"),
19791 (int) (4 + 2 * addr_size), _("Page Offset"));
19792 filenames = descdata + count * 3 * addr_size;
595712bb 19793 while (count-- > 0)
9ece1fa9 19794 {
625d49fc 19795 uint64_t start, end, file_ofs;
9ece1fa9
TT
19796
19797 if (filenames == descend)
19798 {
32ec8896 19799 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19800 return false;
9ece1fa9
TT
19801 }
19802
19803 start = byte_get (descdata, addr_size);
19804 descdata += addr_size;
19805 end = byte_get (descdata, addr_size);
19806 descdata += addr_size;
19807 file_ofs = byte_get (descdata, addr_size);
19808 descdata += addr_size;
19809
19810 printf (" ");
19811 print_vma (start, FULL_HEX);
19812 printf (" ");
19813 print_vma (end, FULL_HEX);
19814 printf (" ");
19815 print_vma (file_ofs, FULL_HEX);
19816 printf ("\n %s\n", filenames);
19817
19818 filenames += 1 + strlen ((char *) filenames);
19819 }
19820
015dc7e1 19821 return true;
9ece1fa9
TT
19822}
19823
1118d252
RM
19824static const char *
19825get_gnu_elf_note_type (unsigned e_type)
19826{
1449284b 19827 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19828 switch (e_type)
19829 {
19830 case NT_GNU_ABI_TAG:
19831 return _("NT_GNU_ABI_TAG (ABI version tag)");
19832 case NT_GNU_HWCAP:
19833 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19834 case NT_GNU_BUILD_ID:
19835 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19836 case NT_GNU_GOLD_VERSION:
19837 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19838 case NT_GNU_PROPERTY_TYPE_0:
19839 return _("NT_GNU_PROPERTY_TYPE_0");
19840 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19841 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19842 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19843 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19844 default:
1449284b
NC
19845 {
19846 static char buff[64];
1118d252 19847
1449284b
NC
19848 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19849 return buff;
19850 }
19851 }
1118d252
RM
19852}
19853
a9eafb08
L
19854static void
19855decode_x86_compat_isa (unsigned int bitmask)
19856{
19857 while (bitmask)
19858 {
19859 unsigned int bit = bitmask & (- bitmask);
19860
19861 bitmask &= ~ bit;
19862 switch (bit)
19863 {
19864 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19865 printf ("i486");
19866 break;
19867 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19868 printf ("586");
19869 break;
19870 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19871 printf ("686");
19872 break;
19873 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19874 printf ("SSE");
19875 break;
19876 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19877 printf ("SSE2");
19878 break;
19879 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19880 printf ("SSE3");
19881 break;
19882 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19883 printf ("SSSE3");
19884 break;
19885 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19886 printf ("SSE4_1");
19887 break;
19888 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19889 printf ("SSE4_2");
19890 break;
19891 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19892 printf ("AVX");
19893 break;
19894 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19895 printf ("AVX2");
19896 break;
19897 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19898 printf ("AVX512F");
19899 break;
19900 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19901 printf ("AVX512CD");
19902 break;
19903 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19904 printf ("AVX512ER");
19905 break;
19906 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19907 printf ("AVX512PF");
19908 break;
19909 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19910 printf ("AVX512VL");
19911 break;
19912 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19913 printf ("AVX512DQ");
19914 break;
19915 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19916 printf ("AVX512BW");
19917 break;
65b3d26e
L
19918 default:
19919 printf (_("<unknown: %x>"), bit);
19920 break;
a9eafb08
L
19921 }
19922 if (bitmask)
19923 printf (", ");
19924 }
19925}
19926
9ef920e9 19927static void
32930e4e 19928decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19929{
0a59decb 19930 if (!bitmask)
90c745dc
L
19931 {
19932 printf (_("<None>"));
19933 return;
19934 }
90c745dc 19935
9ef920e9
NC
19936 while (bitmask)
19937 {
1fc87489 19938 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19939
19940 bitmask &= ~ bit;
19941 switch (bit)
19942 {
32930e4e 19943 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19944 printf ("CMOV");
19945 break;
32930e4e 19946 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19947 printf ("SSE");
19948 break;
32930e4e 19949 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19950 printf ("SSE2");
19951 break;
32930e4e 19952 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19953 printf ("SSE3");
19954 break;
32930e4e 19955 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19956 printf ("SSSE3");
19957 break;
32930e4e 19958 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19959 printf ("SSE4_1");
19960 break;
32930e4e 19961 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19962 printf ("SSE4_2");
19963 break;
32930e4e 19964 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19965 printf ("AVX");
19966 break;
32930e4e 19967 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19968 printf ("AVX2");
19969 break;
32930e4e 19970 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19971 printf ("FMA");
19972 break;
32930e4e 19973 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19974 printf ("AVX512F");
19975 break;
32930e4e 19976 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19977 printf ("AVX512CD");
19978 break;
32930e4e 19979 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19980 printf ("AVX512ER");
19981 break;
32930e4e 19982 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19983 printf ("AVX512PF");
19984 break;
32930e4e 19985 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19986 printf ("AVX512VL");
19987 break;
32930e4e 19988 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19989 printf ("AVX512DQ");
19990 break;
32930e4e 19991 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19992 printf ("AVX512BW");
19993 break;
32930e4e 19994 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19995 printf ("AVX512_4FMAPS");
19996 break;
32930e4e 19997 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19998 printf ("AVX512_4VNNIW");
19999 break;
32930e4e 20000 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
20001 printf ("AVX512_BITALG");
20002 break;
32930e4e 20003 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
20004 printf ("AVX512_IFMA");
20005 break;
32930e4e 20006 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
20007 printf ("AVX512_VBMI");
20008 break;
32930e4e 20009 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
20010 printf ("AVX512_VBMI2");
20011 break;
32930e4e 20012 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
20013 printf ("AVX512_VNNI");
20014 break;
32930e4e 20015 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
20016 printf ("AVX512_BF16");
20017 break;
65b3d26e
L
20018 default:
20019 printf (_("<unknown: %x>"), bit);
20020 break;
9ef920e9
NC
20021 }
20022 if (bitmask)
20023 printf (", ");
20024 }
20025}
20026
28cdbb18
SM
20027static const char *
20028get_amdgpu_elf_note_type (unsigned int e_type)
20029{
20030 switch (e_type)
20031 {
20032 case NT_AMDGPU_METADATA:
20033 return _("NT_AMDGPU_METADATA (code object metadata)");
20034 default:
20035 {
20036 static char buf[64];
20037 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
20038 return buf;
20039 }
20040 }
20041}
20042
32930e4e
L
20043static void
20044decode_x86_isa (unsigned int bitmask)
20045{
32930e4e
L
20046 while (bitmask)
20047 {
20048 unsigned int bit = bitmask & (- bitmask);
20049
20050 bitmask &= ~ bit;
20051 switch (bit)
20052 {
b0ab0693
L
20053 case GNU_PROPERTY_X86_ISA_1_BASELINE:
20054 printf ("x86-64-baseline");
20055 break;
32930e4e
L
20056 case GNU_PROPERTY_X86_ISA_1_V2:
20057 printf ("x86-64-v2");
20058 break;
20059 case GNU_PROPERTY_X86_ISA_1_V3:
20060 printf ("x86-64-v3");
20061 break;
20062 case GNU_PROPERTY_X86_ISA_1_V4:
20063 printf ("x86-64-v4");
20064 break;
20065 default:
20066 printf (_("<unknown: %x>"), bit);
20067 break;
20068 }
20069 if (bitmask)
20070 printf (", ");
20071 }
20072}
20073
ee2fdd6f 20074static void
a9eafb08 20075decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 20076{
0a59decb 20077 if (!bitmask)
90c745dc
L
20078 {
20079 printf (_("<None>"));
20080 return;
20081 }
90c745dc 20082
ee2fdd6f
L
20083 while (bitmask)
20084 {
20085 unsigned int bit = bitmask & (- bitmask);
20086
20087 bitmask &= ~ bit;
20088 switch (bit)
20089 {
20090 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 20091 printf ("IBT");
ee2fdd6f 20092 break;
48580982 20093 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 20094 printf ("SHSTK");
48580982 20095 break;
279d901e
L
20096 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
20097 printf ("LAM_U48");
20098 break;
20099 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
20100 printf ("LAM_U57");
20101 break;
ee2fdd6f
L
20102 default:
20103 printf (_("<unknown: %x>"), bit);
20104 break;
20105 }
20106 if (bitmask)
20107 printf (", ");
20108 }
20109}
20110
a9eafb08
L
20111static void
20112decode_x86_feature_2 (unsigned int bitmask)
20113{
0a59decb 20114 if (!bitmask)
90c745dc
L
20115 {
20116 printf (_("<None>"));
20117 return;
20118 }
90c745dc 20119
a9eafb08
L
20120 while (bitmask)
20121 {
20122 unsigned int bit = bitmask & (- bitmask);
20123
20124 bitmask &= ~ bit;
20125 switch (bit)
20126 {
20127 case GNU_PROPERTY_X86_FEATURE_2_X86:
20128 printf ("x86");
20129 break;
20130 case GNU_PROPERTY_X86_FEATURE_2_X87:
20131 printf ("x87");
20132 break;
20133 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20134 printf ("MMX");
20135 break;
20136 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20137 printf ("XMM");
20138 break;
20139 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20140 printf ("YMM");
20141 break;
20142 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20143 printf ("ZMM");
20144 break;
a308b89d
L
20145 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20146 printf ("TMM");
20147 break;
32930e4e
L
20148 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20149 printf ("MASK");
20150 break;
a9eafb08
L
20151 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20152 printf ("FXSR");
20153 break;
20154 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20155 printf ("XSAVE");
20156 break;
20157 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20158 printf ("XSAVEOPT");
20159 break;
20160 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20161 printf ("XSAVEC");
20162 break;
65b3d26e
L
20163 default:
20164 printf (_("<unknown: %x>"), bit);
20165 break;
a9eafb08
L
20166 }
20167 if (bitmask)
20168 printf (", ");
20169 }
20170}
20171
cd702818
SD
20172static void
20173decode_aarch64_feature_1_and (unsigned int bitmask)
20174{
20175 while (bitmask)
20176 {
20177 unsigned int bit = bitmask & (- bitmask);
20178
20179 bitmask &= ~ bit;
20180 switch (bit)
20181 {
20182 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20183 printf ("BTI");
20184 break;
20185
20186 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20187 printf ("PAC");
20188 break;
20189
20190 default:
20191 printf (_("<unknown: %x>"), bit);
20192 break;
20193 }
20194 if (bitmask)
20195 printf (", ");
20196 }
20197}
20198
6320fd00
L
20199static void
20200decode_1_needed (unsigned int bitmask)
20201{
20202 while (bitmask)
20203 {
20204 unsigned int bit = bitmask & (- bitmask);
20205
20206 bitmask &= ~ bit;
20207 switch (bit)
20208 {
20209 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20210 printf ("indirect external access");
20211 break;
20212 default:
20213 printf (_("<unknown: %x>"), bit);
20214 break;
20215 }
20216 if (bitmask)
20217 printf (", ");
20218 }
20219}
20220
9ef920e9 20221static void
dda8d76d 20222print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
20223{
20224 unsigned char * ptr = (unsigned char *) pnote->descdata;
20225 unsigned char * ptr_end = ptr + pnote->descsz;
20226 unsigned int size = is_32bit_elf ? 4 : 8;
20227
20228 printf (_(" Properties: "));
20229
1fc87489 20230 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
20231 {
20232 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
20233 return;
20234 }
20235
6ab2c4ed 20236 while (ptr < ptr_end)
9ef920e9 20237 {
1fc87489 20238 unsigned int j;
6ab2c4ed
MC
20239 unsigned int type;
20240 unsigned int datasz;
20241
20242 if ((size_t) (ptr_end - ptr) < 8)
20243 {
20244 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
20245 break;
20246 }
20247
20248 type = byte_get (ptr, 4);
20249 datasz = byte_get (ptr + 4, 4);
9ef920e9 20250
1fc87489 20251 ptr += 8;
9ef920e9 20252
6ab2c4ed 20253 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 20254 {
1fc87489
L
20255 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
20256 type, datasz);
9ef920e9 20257 break;
1fc87489 20258 }
9ef920e9 20259
1fc87489
L
20260 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20261 {
dda8d76d
NC
20262 if (filedata->file_header.e_machine == EM_X86_64
20263 || filedata->file_header.e_machine == EM_IAMCU
20264 || filedata->file_header.e_machine == EM_386)
1fc87489 20265 {
aa7bca9b
L
20266 unsigned int bitmask;
20267
20268 if (datasz == 4)
0a59decb 20269 bitmask = byte_get (ptr, 4);
aa7bca9b
L
20270 else
20271 bitmask = 0;
20272
1fc87489
L
20273 switch (type)
20274 {
20275 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 20276 if (datasz != 4)
aa7bca9b
L
20277 printf (_("x86 ISA used: <corrupt length: %#x> "),
20278 datasz);
1fc87489 20279 else
aa7bca9b
L
20280 {
20281 printf ("x86 ISA used: ");
20282 decode_x86_isa (bitmask);
20283 }
1fc87489 20284 goto next;
9ef920e9 20285
1fc87489 20286 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20287 if (datasz != 4)
aa7bca9b
L
20288 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20289 datasz);
1fc87489 20290 else
aa7bca9b
L
20291 {
20292 printf ("x86 ISA needed: ");
20293 decode_x86_isa (bitmask);
20294 }
1fc87489 20295 goto next;
9ef920e9 20296
ee2fdd6f 20297 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20298 if (datasz != 4)
aa7bca9b
L
20299 printf (_("x86 feature: <corrupt length: %#x> "),
20300 datasz);
ee2fdd6f 20301 else
aa7bca9b
L
20302 {
20303 printf ("x86 feature: ");
a9eafb08
L
20304 decode_x86_feature_1 (bitmask);
20305 }
20306 goto next;
20307
20308 case GNU_PROPERTY_X86_FEATURE_2_USED:
20309 if (datasz != 4)
20310 printf (_("x86 feature used: <corrupt length: %#x> "),
20311 datasz);
20312 else
20313 {
20314 printf ("x86 feature used: ");
20315 decode_x86_feature_2 (bitmask);
20316 }
20317 goto next;
20318
20319 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20320 if (datasz != 4)
20321 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20322 else
20323 {
20324 printf ("x86 feature needed: ");
20325 decode_x86_feature_2 (bitmask);
20326 }
20327 goto next;
20328
20329 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20330 if (datasz != 4)
20331 printf (_("x86 ISA used: <corrupt length: %#x> "),
20332 datasz);
20333 else
20334 {
20335 printf ("x86 ISA used: ");
20336 decode_x86_compat_isa (bitmask);
20337 }
20338 goto next;
20339
20340 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20341 if (datasz != 4)
20342 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20343 datasz);
20344 else
20345 {
20346 printf ("x86 ISA needed: ");
20347 decode_x86_compat_isa (bitmask);
aa7bca9b 20348 }
ee2fdd6f
L
20349 goto next;
20350
32930e4e
L
20351 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20352 if (datasz != 4)
20353 printf (_("x86 ISA used: <corrupt length: %#x> "),
20354 datasz);
20355 else
20356 {
20357 printf ("x86 ISA used: ");
20358 decode_x86_compat_2_isa (bitmask);
20359 }
20360 goto next;
20361
20362 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20363 if (datasz != 4)
20364 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20365 datasz);
20366 else
20367 {
20368 printf ("x86 ISA needed: ");
20369 decode_x86_compat_2_isa (bitmask);
20370 }
20371 goto next;
20372
1fc87489
L
20373 default:
20374 break;
20375 }
20376 }
cd702818
SD
20377 else if (filedata->file_header.e_machine == EM_AARCH64)
20378 {
20379 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20380 {
20381 printf ("AArch64 feature: ");
20382 if (datasz != 4)
20383 printf (_("<corrupt length: %#x> "), datasz);
20384 else
20385 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20386 goto next;
20387 }
20388 }
1fc87489
L
20389 }
20390 else
20391 {
20392 switch (type)
9ef920e9 20393 {
1fc87489
L
20394 case GNU_PROPERTY_STACK_SIZE:
20395 printf (_("stack size: "));
20396 if (datasz != size)
20397 printf (_("<corrupt length: %#x> "), datasz);
20398 else
26c527e6 20399 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
20400 goto next;
20401
20402 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20403 printf ("no copy on protected ");
20404 if (datasz)
20405 printf (_("<corrupt length: %#x> "), datasz);
20406 goto next;
20407
20408 default:
5a767724
L
20409 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20410 && type <= GNU_PROPERTY_UINT32_AND_HI)
20411 || (type >= GNU_PROPERTY_UINT32_OR_LO
20412 && type <= GNU_PROPERTY_UINT32_OR_HI))
20413 {
6320fd00
L
20414 switch (type)
20415 {
20416 case GNU_PROPERTY_1_NEEDED:
20417 if (datasz != 4)
20418 printf (_("1_needed: <corrupt length: %#x> "),
20419 datasz);
20420 else
20421 {
20422 unsigned int bitmask = byte_get (ptr, 4);
20423 printf ("1_needed: ");
20424 decode_1_needed (bitmask);
20425 }
20426 goto next;
20427
20428 default:
20429 break;
20430 }
5a767724
L
20431 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20432 printf (_("UINT32_AND (%#x): "), type);
20433 else
20434 printf (_("UINT32_OR (%#x): "), type);
20435 if (datasz != 4)
20436 printf (_("<corrupt length: %#x> "), datasz);
20437 else
20438 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20439 goto next;
20440 }
9ef920e9
NC
20441 break;
20442 }
9ef920e9
NC
20443 }
20444
1fc87489
L
20445 if (type < GNU_PROPERTY_LOPROC)
20446 printf (_("<unknown type %#x data: "), type);
20447 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20448 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20449 else
20450 printf (_("<application-specific type %#x data: "), type);
20451 for (j = 0; j < datasz; ++j)
20452 printf ("%02x ", ptr[j] & 0xff);
20453 printf (">");
20454
dc1e8a47 20455 next:
9ef920e9 20456 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20457 if (ptr == ptr_end)
20458 break;
1fc87489 20459
6ab2c4ed
MC
20460 if (do_wide)
20461 printf (", ");
20462 else
20463 printf ("\n\t");
9ef920e9
NC
20464 }
20465
20466 printf ("\n");
20467}
20468
015dc7e1 20469static bool
dda8d76d 20470print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20471{
1449284b 20472 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20473 switch (pnote->type)
20474 {
20475 case NT_GNU_BUILD_ID:
20476 {
26c527e6 20477 size_t i;
664f90a3
TT
20478
20479 printf (_(" Build ID: "));
20480 for (i = 0; i < pnote->descsz; ++i)
20481 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20482 printf ("\n");
664f90a3
TT
20483 }
20484 break;
20485
20486 case NT_GNU_ABI_TAG:
20487 {
26c527e6 20488 unsigned int os, major, minor, subminor;
664f90a3
TT
20489 const char *osname;
20490
3102e897
NC
20491 /* PR 17531: file: 030-599401-0.004. */
20492 if (pnote->descsz < 16)
20493 {
20494 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20495 break;
20496 }
20497
664f90a3
TT
20498 os = byte_get ((unsigned char *) pnote->descdata, 4);
20499 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20500 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20501 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20502
20503 switch (os)
20504 {
20505 case GNU_ABI_TAG_LINUX:
20506 osname = "Linux";
20507 break;
20508 case GNU_ABI_TAG_HURD:
20509 osname = "Hurd";
20510 break;
20511 case GNU_ABI_TAG_SOLARIS:
20512 osname = "Solaris";
20513 break;
20514 case GNU_ABI_TAG_FREEBSD:
20515 osname = "FreeBSD";
20516 break;
20517 case GNU_ABI_TAG_NETBSD:
20518 osname = "NetBSD";
20519 break;
14ae95f2
RM
20520 case GNU_ABI_TAG_SYLLABLE:
20521 osname = "Syllable";
20522 break;
20523 case GNU_ABI_TAG_NACL:
20524 osname = "NaCl";
20525 break;
664f90a3
TT
20526 default:
20527 osname = "Unknown";
20528 break;
20529 }
20530
26c527e6 20531 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
20532 major, minor, subminor);
20533 }
20534 break;
926c5385
CC
20535
20536 case NT_GNU_GOLD_VERSION:
20537 {
26c527e6 20538 size_t i;
926c5385
CC
20539
20540 printf (_(" Version: "));
20541 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20542 printf ("%c", pnote->descdata[i]);
20543 printf ("\n");
20544 }
20545 break;
1449284b
NC
20546
20547 case NT_GNU_HWCAP:
20548 {
26c527e6 20549 unsigned int num_entries, mask;
1449284b
NC
20550
20551 /* Hardware capabilities information. Word 0 is the number of entries.
20552 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20553 is a series of entries, where each entry is a single byte followed
20554 by a nul terminated string. The byte gives the bit number to test
20555 if enabled in the bitmask. */
20556 printf (_(" Hardware Capabilities: "));
20557 if (pnote->descsz < 8)
20558 {
32ec8896 20559 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20560 return false;
1449284b
NC
20561 }
20562 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20563 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 20564 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
20565 /* FIXME: Add code to display the entries... */
20566 }
20567 break;
20568
9ef920e9 20569 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20570 print_gnu_property_note (filedata, pnote);
9ef920e9 20571 break;
9abca702 20572
1449284b
NC
20573 default:
20574 /* Handle unrecognised types. An error message should have already been
20575 created by get_gnu_elf_note_type(), so all that we need to do is to
20576 display the data. */
20577 {
26c527e6 20578 size_t i;
1449284b
NC
20579
20580 printf (_(" Description data: "));
20581 for (i = 0; i < pnote->descsz; ++i)
20582 printf ("%02x ", pnote->descdata[i] & 0xff);
20583 printf ("\n");
20584 }
20585 break;
664f90a3
TT
20586 }
20587
015dc7e1 20588 return true;
664f90a3
TT
20589}
20590
685080f2
NC
20591static const char *
20592get_v850_elf_note_type (enum v850_notes n_type)
20593{
20594 static char buff[64];
20595
20596 switch (n_type)
20597 {
20598 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20599 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20600 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20601 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20602 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20603 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20604 default:
20605 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20606 return buff;
20607 }
20608}
20609
015dc7e1 20610static bool
685080f2
NC
20611print_v850_note (Elf_Internal_Note * pnote)
20612{
20613 unsigned int val;
20614
20615 if (pnote->descsz != 4)
015dc7e1 20616 return false;
32ec8896 20617
685080f2
NC
20618 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20619
20620 if (val == 0)
20621 {
20622 printf (_("not set\n"));
015dc7e1 20623 return true;
685080f2
NC
20624 }
20625
20626 switch (pnote->type)
20627 {
20628 case V850_NOTE_ALIGNMENT:
20629 switch (val)
20630 {
015dc7e1
AM
20631 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20632 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20633 }
20634 break;
14ae95f2 20635
685080f2
NC
20636 case V850_NOTE_DATA_SIZE:
20637 switch (val)
20638 {
015dc7e1
AM
20639 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20640 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20641 }
20642 break;
14ae95f2 20643
685080f2
NC
20644 case V850_NOTE_FPU_INFO:
20645 switch (val)
20646 {
015dc7e1
AM
20647 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20648 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20649 }
20650 break;
14ae95f2 20651
685080f2
NC
20652 case V850_NOTE_MMU_INFO:
20653 case V850_NOTE_CACHE_INFO:
20654 case V850_NOTE_SIMD_INFO:
20655 if (val == EF_RH850_SIMD)
20656 {
20657 printf (_("yes\n"));
015dc7e1 20658 return true;
685080f2
NC
20659 }
20660 break;
20661
20662 default:
20663 /* An 'unknown note type' message will already have been displayed. */
20664 break;
20665 }
20666
20667 printf (_("unknown value: %x\n"), val);
015dc7e1 20668 return false;
685080f2
NC
20669}
20670
015dc7e1 20671static bool
c6056a74
SF
20672process_netbsd_elf_note (Elf_Internal_Note * pnote)
20673{
20674 unsigned int version;
20675
20676 switch (pnote->type)
20677 {
20678 case NT_NETBSD_IDENT:
b966f55f
AM
20679 if (pnote->descsz < 1)
20680 break;
c6056a74
SF
20681 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20682 if ((version / 10000) % 100)
b966f55f 20683 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20684 version, version / 100000000, (version / 1000000) % 100,
20685 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20686 'A' + (version / 10000) % 26);
c6056a74
SF
20687 else
20688 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20689 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20690 (version / 100) % 100);
015dc7e1 20691 return true;
c6056a74
SF
20692
20693 case NT_NETBSD_MARCH:
9abca702 20694 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20695 pnote->descdata);
015dc7e1 20696 return true;
c6056a74 20697
9abca702 20698 case NT_NETBSD_PAX:
b966f55f
AM
20699 if (pnote->descsz < 1)
20700 break;
9abca702
CZ
20701 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20702 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20703 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20704 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20705 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20706 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20707 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20708 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20709 return true;
c6056a74 20710 }
b966f55f
AM
20711
20712 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20713 pnote->descsz, pnote->type);
015dc7e1 20714 return false;
c6056a74
SF
20715}
20716
f4ddf30f 20717static const char *
dda8d76d 20718get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20719{
f4ddf30f
JB
20720 switch (e_type)
20721 {
20722 case NT_FREEBSD_THRMISC:
20723 return _("NT_THRMISC (thrmisc structure)");
20724 case NT_FREEBSD_PROCSTAT_PROC:
20725 return _("NT_PROCSTAT_PROC (proc data)");
20726 case NT_FREEBSD_PROCSTAT_FILES:
20727 return _("NT_PROCSTAT_FILES (files data)");
20728 case NT_FREEBSD_PROCSTAT_VMMAP:
20729 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20730 case NT_FREEBSD_PROCSTAT_GROUPS:
20731 return _("NT_PROCSTAT_GROUPS (groups data)");
20732 case NT_FREEBSD_PROCSTAT_UMASK:
20733 return _("NT_PROCSTAT_UMASK (umask data)");
20734 case NT_FREEBSD_PROCSTAT_RLIMIT:
20735 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20736 case NT_FREEBSD_PROCSTAT_OSREL:
20737 return _("NT_PROCSTAT_OSREL (osreldate data)");
20738 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20739 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20740 case NT_FREEBSD_PROCSTAT_AUXV:
20741 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20742 case NT_FREEBSD_PTLWPINFO:
20743 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
20744 case NT_FREEBSD_X86_SEGBASES:
20745 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 20746 }
dda8d76d 20747 return get_note_type (filedata, e_type);
f4ddf30f
JB
20748}
20749
9437c45b 20750static const char *
dda8d76d 20751get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20752{
20753 static char buff[64];
20754
540e6170
CZ
20755 switch (e_type)
20756 {
20757 case NT_NETBSDCORE_PROCINFO:
20758 /* NetBSD core "procinfo" structure. */
20759 return _("NetBSD procinfo structure");
9437c45b 20760
540e6170
CZ
20761 case NT_NETBSDCORE_AUXV:
20762 return _("NetBSD ELF auxiliary vector data");
9437c45b 20763
06d949ec
KR
20764 case NT_NETBSDCORE_LWPSTATUS:
20765 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20766
540e6170 20767 default:
06d949ec 20768 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20769 defined for NetBSD core files. If the note type is less
20770 than the start of the machine-dependent note types, we don't
20771 understand it. */
20772
20773 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20774 {
20775 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20776 return buff;
20777 }
20778 break;
9437c45b
JT
20779 }
20780
dda8d76d 20781 switch (filedata->file_header.e_machine)
9437c45b
JT
20782 {
20783 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20784 and PT_GETFPREGS == mach+2. */
20785
20786 case EM_OLD_ALPHA:
20787 case EM_ALPHA:
20788 case EM_SPARC:
20789 case EM_SPARC32PLUS:
20790 case EM_SPARCV9:
20791 switch (e_type)
20792 {
2b692964 20793 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20794 return _("PT_GETREGS (reg structure)");
2b692964 20795 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20796 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20797 default:
20798 break;
20799 }
20800 break;
20801
c0d38b0e
CZ
20802 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20803 There's also old PT___GETREGS40 == mach + 1 for old reg
20804 structure which lacks GBR. */
20805 case EM_SH:
20806 switch (e_type)
20807 {
20808 case NT_NETBSDCORE_FIRSTMACH + 1:
20809 return _("PT___GETREGS40 (old reg structure)");
20810 case NT_NETBSDCORE_FIRSTMACH + 3:
20811 return _("PT_GETREGS (reg structure)");
20812 case NT_NETBSDCORE_FIRSTMACH + 5:
20813 return _("PT_GETFPREGS (fpreg structure)");
20814 default:
20815 break;
20816 }
20817 break;
20818
9437c45b
JT
20819 /* On all other arch's, PT_GETREGS == mach+1 and
20820 PT_GETFPREGS == mach+3. */
20821 default:
20822 switch (e_type)
20823 {
2b692964 20824 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20825 return _("PT_GETREGS (reg structure)");
2b692964 20826 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20827 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20828 default:
20829 break;
20830 }
20831 }
20832
9cf03b7e 20833 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20834 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20835 return buff;
20836}
20837
98ca73af
FC
20838static const char *
20839get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20840{
20841 switch (e_type)
20842 {
20843 case NT_OPENBSD_PROCINFO:
20844 return _("OpenBSD procinfo structure");
20845 case NT_OPENBSD_AUXV:
20846 return _("OpenBSD ELF auxiliary vector data");
20847 case NT_OPENBSD_REGS:
20848 return _("OpenBSD regular registers");
20849 case NT_OPENBSD_FPREGS:
20850 return _("OpenBSD floating point registers");
20851 case NT_OPENBSD_WCOOKIE:
20852 return _("OpenBSD window cookie");
20853 }
20854
20855 return get_note_type (filedata, e_type);
20856}
20857
e263a66b
CC
20858static const char *
20859get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
20860{
20861 switch (e_type)
20862 {
20863 case QNT_DEBUG_FULLPATH:
20864 return _("QNX debug fullpath");
20865 case QNT_DEBUG_RELOC:
20866 return _("QNX debug relocation");
20867 case QNT_STACK:
20868 return _("QNX stack");
20869 case QNT_GENERATOR:
20870 return _("QNX generator");
20871 case QNT_DEFAULT_LIB:
20872 return _("QNX default library");
20873 case QNT_CORE_SYSINFO:
20874 return _("QNX core sysinfo");
20875 case QNT_CORE_INFO:
20876 return _("QNX core info");
20877 case QNT_CORE_STATUS:
20878 return _("QNX core status");
20879 case QNT_CORE_GREG:
20880 return _("QNX general registers");
20881 case QNT_CORE_FPREG:
20882 return _("QNX floating point registers");
20883 case QNT_LINK_MAP:
20884 return _("QNX link map");
20885 }
20886
20887 return get_note_type (filedata, e_type);
20888}
20889
70616151
TT
20890static const char *
20891get_stapsdt_note_type (unsigned e_type)
20892{
20893 static char buff[64];
20894
20895 switch (e_type)
20896 {
20897 case NT_STAPSDT:
20898 return _("NT_STAPSDT (SystemTap probe descriptors)");
20899
20900 default:
20901 break;
20902 }
20903
20904 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20905 return buff;
20906}
20907
015dc7e1 20908static bool
c6a9fc58
TT
20909print_stapsdt_note (Elf_Internal_Note *pnote)
20910{
3ca60c57 20911 size_t len, maxlen;
26c527e6 20912 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20913 char *data = pnote->descdata;
20914 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 20915 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
20916 char *provider, *probe, *arg_fmt;
20917
3ca60c57
NC
20918 if (pnote->descsz < (addr_size * 3))
20919 goto stapdt_note_too_small;
20920
c6a9fc58
TT
20921 pc = byte_get ((unsigned char *) data, addr_size);
20922 data += addr_size;
3ca60c57 20923
c6a9fc58
TT
20924 base_addr = byte_get ((unsigned char *) data, addr_size);
20925 data += addr_size;
3ca60c57 20926
c6a9fc58
TT
20927 semaphore = byte_get ((unsigned char *) data, addr_size);
20928 data += addr_size;
20929
3ca60c57
NC
20930 if (data >= data_end)
20931 goto stapdt_note_too_small;
20932 maxlen = data_end - data;
20933 len = strnlen (data, maxlen);
20934 if (len < maxlen)
20935 {
20936 provider = data;
20937 data += len + 1;
20938 }
20939 else
20940 goto stapdt_note_too_small;
20941
20942 if (data >= data_end)
20943 goto stapdt_note_too_small;
20944 maxlen = data_end - data;
20945 len = strnlen (data, maxlen);
20946 if (len < maxlen)
20947 {
20948 probe = data;
20949 data += len + 1;
20950 }
20951 else
20952 goto stapdt_note_too_small;
9abca702 20953
3ca60c57
NC
20954 if (data >= data_end)
20955 goto stapdt_note_too_small;
20956 maxlen = data_end - data;
20957 len = strnlen (data, maxlen);
20958 if (len < maxlen)
20959 {
20960 arg_fmt = data;
20961 data += len + 1;
20962 }
20963 else
20964 goto stapdt_note_too_small;
c6a9fc58
TT
20965
20966 printf (_(" Provider: %s\n"), provider);
20967 printf (_(" Name: %s\n"), probe);
20968 printf (_(" Location: "));
20969 print_vma (pc, FULL_HEX);
20970 printf (_(", Base: "));
20971 print_vma (base_addr, FULL_HEX);
20972 printf (_(", Semaphore: "));
20973 print_vma (semaphore, FULL_HEX);
9cf03b7e 20974 printf ("\n");
c6a9fc58
TT
20975 printf (_(" Arguments: %s\n"), arg_fmt);
20976
20977 return data == data_end;
3ca60c57
NC
20978
20979 stapdt_note_too_small:
20980 printf (_(" <corrupt - note is too small>\n"));
20981 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20982 return false;
c6a9fc58
TT
20983}
20984
e5382207
LB
20985static bool
20986print_fdo_note (Elf_Internal_Note * pnote)
20987{
20988 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20989 {
20990 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20991 return true;
20992 }
20993 return false;
20994}
20995
00e98fc7
TG
20996static const char *
20997get_ia64_vms_note_type (unsigned e_type)
20998{
20999 static char buff[64];
21000
21001 switch (e_type)
21002 {
21003 case NT_VMS_MHD:
21004 return _("NT_VMS_MHD (module header)");
21005 case NT_VMS_LNM:
21006 return _("NT_VMS_LNM (language name)");
21007 case NT_VMS_SRC:
21008 return _("NT_VMS_SRC (source files)");
21009 case NT_VMS_TITLE:
9cf03b7e 21010 return "NT_VMS_TITLE";
00e98fc7
TG
21011 case NT_VMS_EIDC:
21012 return _("NT_VMS_EIDC (consistency check)");
21013 case NT_VMS_FPMODE:
21014 return _("NT_VMS_FPMODE (FP mode)");
21015 case NT_VMS_LINKTIME:
9cf03b7e 21016 return "NT_VMS_LINKTIME";
00e98fc7
TG
21017 case NT_VMS_IMGNAM:
21018 return _("NT_VMS_IMGNAM (image name)");
21019 case NT_VMS_IMGID:
21020 return _("NT_VMS_IMGID (image id)");
21021 case NT_VMS_LINKID:
21022 return _("NT_VMS_LINKID (link id)");
21023 case NT_VMS_IMGBID:
21024 return _("NT_VMS_IMGBID (build id)");
21025 case NT_VMS_GSTNAM:
21026 return _("NT_VMS_GSTNAM (sym table name)");
21027 case NT_VMS_ORIG_DYN:
9cf03b7e 21028 return "NT_VMS_ORIG_DYN";
00e98fc7 21029 case NT_VMS_PATCHTIME:
9cf03b7e 21030 return "NT_VMS_PATCHTIME";
00e98fc7
TG
21031 default:
21032 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21033 return buff;
21034 }
21035}
21036
015dc7e1 21037static bool
00e98fc7
TG
21038print_ia64_vms_note (Elf_Internal_Note * pnote)
21039{
26c527e6 21040 unsigned int maxlen = pnote->descsz;
8d18bf79 21041
26c527e6 21042 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
21043 goto desc_size_fail;
21044
00e98fc7
TG
21045 switch (pnote->type)
21046 {
21047 case NT_VMS_MHD:
8d18bf79
NC
21048 if (maxlen <= 36)
21049 goto desc_size_fail;
21050
26c527e6 21051 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
21052
21053 printf (_(" Creation date : %.17s\n"), pnote->descdata);
21054 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
21055 if (l + 34 < maxlen)
21056 {
21057 printf (_(" Module name : %s\n"), pnote->descdata + 34);
21058 if (l + 35 < maxlen)
21059 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
21060 else
21061 printf (_(" Module version : <missing>\n"));
21062 }
00e98fc7 21063 else
8d18bf79
NC
21064 {
21065 printf (_(" Module name : <missing>\n"));
21066 printf (_(" Module version : <missing>\n"));
21067 }
00e98fc7 21068 break;
8d18bf79 21069
00e98fc7 21070 case NT_VMS_LNM:
8d18bf79 21071 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21072 break;
8d18bf79 21073
00e98fc7 21074 case NT_VMS_FPMODE:
9cf03b7e 21075 printf (_(" Floating Point mode: "));
8d18bf79
NC
21076 if (maxlen < 8)
21077 goto desc_size_fail;
21078 /* FIXME: Generate an error if descsz > 8 ? */
21079
b8281767 21080 printf ("0x%016" PRIx64 "\n",
625d49fc 21081 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 21082 break;
8d18bf79 21083
00e98fc7
TG
21084 case NT_VMS_LINKTIME:
21085 printf (_(" Link time: "));
8d18bf79
NC
21086 if (maxlen < 8)
21087 goto desc_size_fail;
21088 /* FIXME: Generate an error if descsz > 8 ? */
21089
0e3c1eeb 21090 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21091 printf ("\n");
21092 break;
8d18bf79 21093
00e98fc7
TG
21094 case NT_VMS_PATCHTIME:
21095 printf (_(" Patch time: "));
8d18bf79
NC
21096 if (maxlen < 8)
21097 goto desc_size_fail;
21098 /* FIXME: Generate an error if descsz > 8 ? */
21099
0e3c1eeb 21100 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21101 printf ("\n");
21102 break;
8d18bf79 21103
00e98fc7 21104 case NT_VMS_ORIG_DYN:
8d18bf79
NC
21105 if (maxlen < 34)
21106 goto desc_size_fail;
21107
00e98fc7 21108 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
21109 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
21110 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 21111 printf (_(" Last modified : "));
0e3c1eeb 21112 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 21113 printf (_("\n Link flags : "));
b8281767 21114 printf ("0x%016" PRIx64 "\n",
625d49fc 21115 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 21116 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 21117 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 21118 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 21119 break;
8d18bf79 21120
00e98fc7 21121 case NT_VMS_IMGNAM:
8d18bf79 21122 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21123 break;
8d18bf79 21124
00e98fc7 21125 case NT_VMS_GSTNAM:
8d18bf79 21126 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21127 break;
8d18bf79 21128
00e98fc7 21129 case NT_VMS_IMGID:
8d18bf79 21130 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21131 break;
8d18bf79 21132
00e98fc7 21133 case NT_VMS_LINKID:
8d18bf79 21134 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21135 break;
8d18bf79 21136
00e98fc7 21137 default:
015dc7e1 21138 return false;
00e98fc7 21139 }
8d18bf79 21140
015dc7e1 21141 return true;
8d18bf79
NC
21142
21143 desc_size_fail:
21144 printf (_(" <corrupt - data size is too small>\n"));
21145 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 21146 return false;
00e98fc7
TG
21147}
21148
fd486f32
AM
21149struct build_attr_cache {
21150 Filedata *filedata;
21151 char *strtab;
26c527e6 21152 uint64_t strtablen;
fd486f32 21153 Elf_Internal_Sym *symtab;
26c527e6 21154 uint64_t nsyms;
fd486f32
AM
21155} ba_cache;
21156
6f156d7a
NC
21157/* Find the symbol associated with a build attribute that is attached
21158 to address OFFSET. If PNAME is non-NULL then store the name of
21159 the symbol (if found) in the provided pointer, Returns NULL if a
21160 symbol could not be found. */
c799a79d 21161
6f156d7a 21162static Elf_Internal_Sym *
015dc7e1 21163get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 21164 uint64_t offset,
015dc7e1
AM
21165 bool is_open_attr,
21166 const char **pname)
9ef920e9 21167{
fd486f32
AM
21168 Elf_Internal_Sym *saved_sym = NULL;
21169 Elf_Internal_Sym *sym;
9ef920e9 21170
dda8d76d 21171 if (filedata->section_headers != NULL
fd486f32 21172 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 21173 {
c799a79d 21174 Elf_Internal_Shdr * symsec;
9ef920e9 21175
fd486f32
AM
21176 free (ba_cache.strtab);
21177 ba_cache.strtab = NULL;
21178 free (ba_cache.symtab);
21179 ba_cache.symtab = NULL;
21180
c799a79d 21181 /* Load the symbol and string sections. */
dda8d76d
NC
21182 for (symsec = filedata->section_headers;
21183 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 21184 symsec ++)
9ef920e9 21185 {
28d13567
AM
21186 if (symsec->sh_type == SHT_SYMTAB
21187 && get_symtab (filedata, symsec,
21188 &ba_cache.symtab, &ba_cache.nsyms,
21189 &ba_cache.strtab, &ba_cache.strtablen))
21190 break;
9ef920e9 21191 }
fd486f32 21192 ba_cache.filedata = filedata;
9ef920e9
NC
21193 }
21194
fd486f32 21195 if (ba_cache.symtab == NULL)
6f156d7a 21196 return NULL;
9ef920e9 21197
c799a79d 21198 /* Find a symbol whose value matches offset. */
fd486f32 21199 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
21200 if (sym->st_value == offset)
21201 {
fd486f32 21202 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
21203 /* Huh ? This should not happen. */
21204 continue;
9ef920e9 21205
fd486f32 21206 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 21207 continue;
9ef920e9 21208
9b9b1092 21209 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 21210 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
21211 if (ba_cache.strtab[sym->st_name] == '$'
21212 && ba_cache.strtab[sym->st_name + 1] != 0
21213 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
21214 continue;
21215
c799a79d
NC
21216 if (is_open_attr)
21217 {
21218 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
21219 and FILE or OBJECT symbols over NOTYPE symbols. We skip
21220 FUNC symbols entirely. */
21221 switch (ELF_ST_TYPE (sym->st_info))
21222 {
c799a79d 21223 case STT_OBJECT:
6f156d7a 21224 case STT_FILE:
c799a79d 21225 saved_sym = sym;
6f156d7a
NC
21226 if (sym->st_size)
21227 {
21228 /* If the symbol has a size associated
21229 with it then we can stop searching. */
fd486f32 21230 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 21231 }
c799a79d 21232 continue;
9ef920e9 21233
c799a79d
NC
21234 case STT_FUNC:
21235 /* Ignore function symbols. */
21236 continue;
21237
21238 default:
21239 break;
21240 }
21241
21242 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 21243 {
c799a79d
NC
21244 case STB_GLOBAL:
21245 if (saved_sym == NULL
21246 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
21247 saved_sym = sym;
21248 break;
c871dade 21249
c799a79d
NC
21250 case STB_LOCAL:
21251 if (saved_sym == NULL)
21252 saved_sym = sym;
21253 break;
21254
21255 default:
9ef920e9
NC
21256 break;
21257 }
21258 }
c799a79d
NC
21259 else
21260 {
21261 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
21262 continue;
21263
21264 saved_sym = sym;
21265 break;
21266 }
21267 }
21268
6f156d7a 21269 if (saved_sym && pname)
fd486f32 21270 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
21271
21272 return saved_sym;
c799a79d
NC
21273}
21274
d20e98ab
NC
21275/* Returns true iff addr1 and addr2 are in the same section. */
21276
015dc7e1 21277static bool
26c527e6 21278same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
21279{
21280 Elf_Internal_Shdr * a1;
21281 Elf_Internal_Shdr * a2;
21282
21283 a1 = find_section_by_address (filedata, addr1);
21284 a2 = find_section_by_address (filedata, addr2);
9abca702 21285
d20e98ab
NC
21286 return a1 == a2 && a1 != NULL;
21287}
21288
015dc7e1 21289static bool
dda8d76d
NC
21290print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21291 Filedata * filedata)
c799a79d 21292{
26c527e6
AM
21293 static uint64_t global_offset = 0;
21294 static uint64_t global_end = 0;
21295 static uint64_t func_offset = 0;
21296 static uint64_t func_end = 0;
c871dade 21297
015dc7e1
AM
21298 Elf_Internal_Sym *sym;
21299 const char *name;
26c527e6
AM
21300 uint64_t start;
21301 uint64_t end;
015dc7e1 21302 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
21303
21304 switch (pnote->descsz)
c799a79d 21305 {
6f156d7a
NC
21306 case 0:
21307 /* A zero-length description means that the range of
21308 the previous note of the same type should be used. */
c799a79d 21309 if (is_open_attr)
c871dade 21310 {
6f156d7a 21311 if (global_end > global_offset)
26c527e6
AM
21312 printf (_(" Applies to region from %#" PRIx64
21313 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 21314 else
26c527e6
AM
21315 printf (_(" Applies to region from %#" PRIx64
21316 "\n"), global_offset);
c799a79d
NC
21317 }
21318 else
21319 {
6f156d7a 21320 if (func_end > func_offset)
26c527e6
AM
21321 printf (_(" Applies to region from %#" PRIx64
21322 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 21323 else
26c527e6
AM
21324 printf (_(" Applies to region from %#" PRIx64
21325 "\n"), func_offset);
c871dade 21326 }
015dc7e1 21327 return true;
9ef920e9 21328
6f156d7a
NC
21329 case 4:
21330 start = byte_get ((unsigned char *) pnote->descdata, 4);
21331 end = 0;
21332 break;
21333
21334 case 8:
c74147bb
NC
21335 start = byte_get ((unsigned char *) pnote->descdata, 4);
21336 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21337 break;
21338
21339 case 16:
21340 start = byte_get ((unsigned char *) pnote->descdata, 8);
21341 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21342 break;
9abca702 21343
6f156d7a 21344 default:
c799a79d
NC
21345 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21346 printf (_(" <invalid descsz>"));
015dc7e1 21347 return false;
c799a79d
NC
21348 }
21349
6f156d7a
NC
21350 name = NULL;
21351 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21352 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21353 in order to avoid them being confused with the start address of the
21354 first function in the file... */
21355 if (sym == NULL && is_open_attr)
21356 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21357 & name);
6f156d7a
NC
21358
21359 if (end == 0 && sym != NULL && sym->st_size > 0)
21360 end = start + sym->st_size;
c799a79d
NC
21361
21362 if (is_open_attr)
21363 {
d20e98ab
NC
21364 /* FIXME: Need to properly allow for section alignment.
21365 16 is just the alignment used on x86_64. */
21366 if (global_end > 0
21367 && start > BFD_ALIGN (global_end, 16)
21368 /* Build notes are not guaranteed to be organised in order of
21369 increasing address, but we should find the all of the notes
21370 for one section in the same place. */
21371 && same_section (filedata, start, global_end))
26c527e6
AM
21372 warn (_("Gap in build notes detected from %#" PRIx64
21373 " to %#" PRIx64 "\n"),
6f156d7a
NC
21374 global_end + 1, start - 1);
21375
26c527e6 21376 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21377 global_offset = start;
21378
21379 if (end)
21380 {
26c527e6 21381 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21382 global_end = end;
21383 }
c799a79d
NC
21384 }
21385 else
21386 {
26c527e6 21387 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21388 func_offset = start;
21389
21390 if (end)
21391 {
26c527e6 21392 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21393 func_end = end;
21394 }
c799a79d
NC
21395 }
21396
6f156d7a
NC
21397 if (sym && name)
21398 printf (_(" (%s)"), name);
21399
21400 printf ("\n");
015dc7e1 21401 return true;
9ef920e9
NC
21402}
21403
015dc7e1 21404static bool
9ef920e9
NC
21405print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21406{
1d15e434
NC
21407 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21408 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21409 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21410 char name_type;
21411 char name_attribute;
1d15e434 21412 const char * expected_types;
9ef920e9
NC
21413 const char * name = pnote->namedata;
21414 const char * text;
88305e1b 21415 signed int left;
9ef920e9
NC
21416
21417 if (name == NULL || pnote->namesz < 2)
21418 {
21419 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21420 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21421 return false;
9ef920e9
NC
21422 }
21423
6f156d7a
NC
21424 if (do_wide)
21425 left = 28;
21426 else
21427 left = 20;
88305e1b
NC
21428
21429 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21430 if (name[0] == 'G' && name[1] == 'A')
21431 {
6f156d7a
NC
21432 if (pnote->namesz < 4)
21433 {
21434 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21435 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21436 return false;
6f156d7a
NC
21437 }
21438
88305e1b
NC
21439 printf ("GA");
21440 name += 2;
21441 left -= 2;
21442 }
21443
9ef920e9
NC
21444 switch ((name_type = * name))
21445 {
21446 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21447 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21448 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21449 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21450 printf ("%c", * name);
88305e1b 21451 left --;
9ef920e9
NC
21452 break;
21453 default:
21454 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21455 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21456 return false;
9ef920e9
NC
21457 }
21458
9ef920e9
NC
21459 ++ name;
21460 text = NULL;
21461
21462 switch ((name_attribute = * name))
21463 {
21464 case GNU_BUILD_ATTRIBUTE_VERSION:
21465 text = _("<version>");
1d15e434 21466 expected_types = string_expected;
9ef920e9
NC
21467 ++ name;
21468 break;
21469 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21470 text = _("<stack prot>");
75d7d298 21471 expected_types = "!+*";
9ef920e9
NC
21472 ++ name;
21473 break;
21474 case GNU_BUILD_ATTRIBUTE_RELRO:
21475 text = _("<relro>");
1d15e434 21476 expected_types = bool_expected;
9ef920e9
NC
21477 ++ name;
21478 break;
21479 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21480 text = _("<stack size>");
1d15e434 21481 expected_types = number_expected;
9ef920e9
NC
21482 ++ name;
21483 break;
21484 case GNU_BUILD_ATTRIBUTE_TOOL:
21485 text = _("<tool>");
1d15e434 21486 expected_types = string_expected;
9ef920e9
NC
21487 ++ name;
21488 break;
21489 case GNU_BUILD_ATTRIBUTE_ABI:
21490 text = _("<ABI>");
21491 expected_types = "$*";
21492 ++ name;
21493 break;
21494 case GNU_BUILD_ATTRIBUTE_PIC:
21495 text = _("<PIC>");
1d15e434 21496 expected_types = number_expected;
9ef920e9
NC
21497 ++ name;
21498 break;
a8be5506
NC
21499 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21500 text = _("<short enum>");
1d15e434 21501 expected_types = bool_expected;
a8be5506
NC
21502 ++ name;
21503 break;
9ef920e9
NC
21504 default:
21505 if (ISPRINT (* name))
21506 {
21507 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21508
21509 if (len > left && ! do_wide)
21510 len = left;
75d7d298 21511 printf ("%.*s:", len, name);
9ef920e9 21512 left -= len;
0dd6ae21 21513 name += len;
9ef920e9
NC
21514 }
21515 else
21516 {
3e6b6445 21517 static char tmpbuf [128];
88305e1b 21518
3e6b6445
NC
21519 error (_("unrecognised byte in name field: %d\n"), * name);
21520 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21521 text = tmpbuf;
21522 name ++;
9ef920e9
NC
21523 }
21524 expected_types = "*$!+";
21525 break;
21526 }
21527
21528 if (text)
88305e1b 21529 left -= printf ("%s", text);
9ef920e9
NC
21530
21531 if (strchr (expected_types, name_type) == NULL)
75d7d298 21532 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 21533
26c527e6 21534 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 21535 {
26c527e6
AM
21536 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
21537 pnote->namesz,
21538 name - pnote->namedata);
015dc7e1 21539 return false;
9ef920e9
NC
21540 }
21541
21542 if (left < 1 && ! do_wide)
015dc7e1 21543 return true;
9ef920e9
NC
21544
21545 switch (name_type)
21546 {
21547 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21548 {
26c527e6
AM
21549 unsigned int bytes;
21550 uint64_t val = 0;
21551 unsigned int shift = 0;
21552 char *decoded = NULL;
ddef72cd 21553
b06b2c92
NC
21554 bytes = pnote->namesz - (name - pnote->namedata);
21555 if (bytes > 0)
21556 /* The -1 is because the name field is always 0 terminated, and we
21557 want to be able to ensure that the shift in the while loop below
21558 will not overflow. */
21559 -- bytes;
21560
ddef72cd
NC
21561 if (bytes > sizeof (val))
21562 {
3e6b6445
NC
21563 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21564 bytes);
21565 bytes = sizeof (val);
ddef72cd 21566 }
3e6b6445
NC
21567 /* We do not bother to warn if bytes == 0 as this can
21568 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21569
21570 while (bytes --)
21571 {
26c527e6 21572 uint64_t byte = *name++ & 0xff;
79a964dc
NC
21573
21574 val |= byte << shift;
9ef920e9
NC
21575 shift += 8;
21576 }
21577
75d7d298 21578 switch (name_attribute)
9ef920e9 21579 {
75d7d298 21580 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21581 switch (val)
21582 {
75d7d298
NC
21583 case 0: decoded = "static"; break;
21584 case 1: decoded = "pic"; break;
21585 case 2: decoded = "PIC"; break;
21586 case 3: decoded = "pie"; break;
21587 case 4: decoded = "PIE"; break;
21588 default: break;
9ef920e9 21589 }
75d7d298
NC
21590 break;
21591 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21592 switch (val)
9ef920e9 21593 {
75d7d298
NC
21594 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21595 case 0: decoded = "off"; break;
21596 case 1: decoded = "on"; break;
21597 case 2: decoded = "all"; break;
21598 case 3: decoded = "strong"; break;
21599 case 4: decoded = "explicit"; break;
21600 default: break;
9ef920e9 21601 }
75d7d298
NC
21602 break;
21603 default:
21604 break;
9ef920e9
NC
21605 }
21606
75d7d298 21607 if (decoded != NULL)
3e6b6445
NC
21608 {
21609 print_symbol (-left, decoded);
21610 left = 0;
21611 }
21612 else if (val == 0)
21613 {
21614 printf ("0x0");
21615 left -= 3;
21616 }
9ef920e9 21617 else
75d7d298
NC
21618 {
21619 if (do_wide)
26c527e6 21620 left -= printf ("0x%" PRIx64, val);
75d7d298 21621 else
26c527e6 21622 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 21623 }
9ef920e9
NC
21624 }
21625 break;
21626 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21627 left -= print_symbol (- left, name);
21628 break;
21629 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21630 left -= print_symbol (- left, "true");
21631 break;
21632 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21633 left -= print_symbol (- left, "false");
21634 break;
21635 }
21636
21637 if (do_wide && left > 0)
21638 printf ("%-*s", left, " ");
9abca702 21639
015dc7e1 21640 return true;
9ef920e9
NC
21641}
21642
2952f10c
SM
21643/* Print the contents of PNOTE as hex. */
21644
21645static void
21646print_note_contents_hex (Elf_Internal_Note *pnote)
21647{
21648 if (pnote->descsz)
21649 {
26c527e6 21650 size_t i;
2952f10c
SM
21651
21652 printf (_(" description data: "));
21653 for (i = 0; i < pnote->descsz; i++)
21654 printf ("%02x ", pnote->descdata[i] & 0xff);
21655 if (!do_wide)
21656 printf ("\n");
21657 }
21658
21659 if (do_wide)
21660 printf ("\n");
21661}
21662
21663#if defined HAVE_MSGPACK
21664
21665static void
21666print_indents (int n)
21667{
21668 printf (" ");
21669
21670 for (int i = 0; i < n; i++)
21671 printf (" ");
21672}
21673
21674/* Print OBJ in human-readable form. */
21675
21676static void
21677dump_msgpack_obj (const msgpack_object *obj, int indent)
21678{
21679 switch (obj->type)
21680 {
21681 case MSGPACK_OBJECT_NIL:
21682 printf ("(nil)");
21683 break;
21684
21685 case MSGPACK_OBJECT_BOOLEAN:
21686 printf ("%s", obj->via.boolean ? "true" : "false");
21687 break;
21688
21689 case MSGPACK_OBJECT_POSITIVE_INTEGER:
21690 printf ("%" PRIu64, obj->via.u64);
21691 break;
21692
21693 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
21694 printf ("%" PRIi64, obj->via.i64);
21695 break;
21696
21697 case MSGPACK_OBJECT_FLOAT32:
21698 case MSGPACK_OBJECT_FLOAT64:
21699 printf ("%f", obj->via.f64);
21700 break;
21701
21702 case MSGPACK_OBJECT_STR:
21703 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
21704 break;
21705
21706 case MSGPACK_OBJECT_ARRAY:
21707 {
21708 const msgpack_object_array *array = &obj->via.array;
21709
21710 printf ("[\n");
21711 ++indent;
21712
21713 for (uint32_t i = 0; i < array->size; ++i)
21714 {
21715 const msgpack_object *item = &array->ptr[i];
21716
21717 print_indents (indent);
21718 dump_msgpack_obj (item, indent);
21719 printf (",\n");
21720 }
21721
21722 --indent;
21723 print_indents (indent);
21724 printf ("]");
21725 break;
21726 }
21727 break;
21728
21729 case MSGPACK_OBJECT_MAP:
21730 {
21731 const msgpack_object_map *map = &obj->via.map;
21732
21733 printf ("{\n");
21734 ++indent;
21735
21736 for (uint32_t i = 0; i < map->size; ++i)
21737 {
21738 const msgpack_object_kv *kv = &map->ptr[i];
21739 const msgpack_object *key = &kv->key;
21740 const msgpack_object *val = &kv->val;
21741
21742 print_indents (indent);
21743 dump_msgpack_obj (key, indent);
21744 printf (": ");
21745 dump_msgpack_obj (val, indent);
21746
21747 printf (",\n");
21748 }
21749
21750 --indent;
21751 print_indents (indent);
21752 printf ("}");
21753
21754 break;
21755 }
21756
21757 case MSGPACK_OBJECT_BIN:
21758 printf ("(bin)");
21759 break;
21760
21761 case MSGPACK_OBJECT_EXT:
21762 printf ("(ext)");
21763 break;
21764 }
21765}
21766
21767static void
21768dump_msgpack (const msgpack_unpacked *msg)
21769{
21770 print_indents (0);
21771 dump_msgpack_obj (&msg->data, 0);
21772 printf ("\n");
21773}
21774
21775#endif /* defined HAVE_MSGPACK */
21776
21777static bool
21778print_amdgpu_note (Elf_Internal_Note *pnote)
21779{
21780#if defined HAVE_MSGPACK
21781 /* If msgpack is available, decode and dump the note's content. */
21782 bool ret;
21783 msgpack_unpacked msg;
21784 msgpack_unpack_return msgpack_ret;
21785
21786 assert (pnote->type == NT_AMDGPU_METADATA);
21787
21788 msgpack_unpacked_init (&msg);
21789 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
21790 NULL);
21791
21792 switch (msgpack_ret)
21793 {
21794 case MSGPACK_UNPACK_SUCCESS:
21795 dump_msgpack (&msg);
21796 ret = true;
21797 break;
21798
21799 default:
21800 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
21801 ret = false;
21802 break;
21803 }
21804
21805 msgpack_unpacked_destroy (&msg);
21806 return ret;
21807#else
21808 /* msgpack is not available, dump contents as hex. */
21809 print_note_contents_hex (pnote);
21810 return true;
21811#endif
21812}
21813
e263a66b
CC
21814static bool
21815print_qnx_note (Elf_Internal_Note *pnote)
21816{
21817 switch (pnote->type)
21818 {
21819 case QNT_STACK:
21820 if (pnote->descsz != 12)
21821 goto desc_size_fail;
21822
21823 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
21824 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
21825 printf (_(" Stack allocated: %" PRIx32 "\n"),
21826 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
21827 printf (_(" Executable: %s\n"),
21828 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
21829 break;
21830
21831 default:
21832 print_note_contents_hex(pnote);
21833 }
21834 return true;
21835
21836desc_size_fail:
21837 printf (_(" <corrupt - data size is too small>\n"));
21838 error (_("corrupt QNX note: data size is too small\n"));
21839 return false;
21840}
21841
21842
6d118b09
NC
21843/* Note that by the ELF standard, the name field is already null byte
21844 terminated, and namesz includes the terminating null byte.
21845 I.E. the value of namesz for the name "FSF" is 4.
21846
e3c8793a 21847 If the value of namesz is zero, there is no name present. */
9ef920e9 21848
015dc7e1 21849static bool
9ef920e9 21850process_note (Elf_Internal_Note * pnote,
dda8d76d 21851 Filedata * filedata)
779fe533 21852{
2cf0635d
NC
21853 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21854 const char * nt;
9437c45b
JT
21855
21856 if (pnote->namesz == 0)
1ec5cd37
NC
21857 /* If there is no note name, then use the default set of
21858 note type strings. */
dda8d76d 21859 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21860
24d127aa 21861 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21862 /* GNU-specific object file notes. */
21863 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21864
28cdbb18
SM
21865 else if (startswith (pnote->namedata, "AMDGPU"))
21866 /* AMDGPU-specific object file notes. */
21867 nt = get_amdgpu_elf_note_type (pnote->type);
21868
24d127aa 21869 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21870 /* FreeBSD-specific core file notes. */
dda8d76d 21871 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21872
24d127aa 21873 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21874 /* NetBSD-specific core file notes. */
dda8d76d 21875 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21876
24d127aa 21877 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21878 /* NetBSD-specific core file notes. */
21879 return process_netbsd_elf_note (pnote);
21880
24d127aa 21881 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21882 /* NetBSD-specific core file notes. */
21883 return process_netbsd_elf_note (pnote);
21884
98ca73af
FC
21885 else if (startswith (pnote->namedata, "OpenBSD"))
21886 /* OpenBSD-specific core file notes. */
21887 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21888
e263a66b
CC
21889 else if (startswith (pnote->namedata, "QNX"))
21890 /* QNX-specific core file notes. */
21891 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
21892
e9b095a5 21893 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21894 {
21895 /* SPU-specific core file notes. */
21896 nt = pnote->namedata + 4;
21897 name = "SPU";
21898 }
21899
24d127aa 21900 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21901 /* VMS/ia64-specific file notes. */
21902 nt = get_ia64_vms_note_type (pnote->type);
21903
24d127aa 21904 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21905 nt = get_stapsdt_note_type (pnote->type);
21906
9437c45b 21907 else
1ec5cd37
NC
21908 /* Don't recognize this note name; just use the default set of
21909 note type strings. */
dda8d76d 21910 nt = get_note_type (filedata, pnote->type);
9437c45b 21911
1449284b 21912 printf (" ");
9ef920e9 21913
24d127aa 21914 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21915 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21916 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21917 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21918 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21919 print_gnu_build_attribute_name (pnote);
21920 else
21921 print_symbol (-20, name);
21922
21923 if (do_wide)
21924 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21925 else
21926 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21927
24d127aa 21928 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21929 return print_ia64_vms_note (pnote);
24d127aa 21930 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21931 return print_gnu_note (filedata, pnote);
24d127aa 21932 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21933 return print_stapsdt_note (pnote);
24d127aa 21934 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21935 return print_core_note (pnote);
e5382207
LB
21936 else if (startswith (pnote->namedata, "FDO"))
21937 return print_fdo_note (pnote);
24d127aa 21938 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21939 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21940 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21941 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21942 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21943 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
21944 else if (startswith (pnote->namedata, "AMDGPU")
21945 && pnote->type == NT_AMDGPU_METADATA)
21946 return print_amdgpu_note (pnote);
e263a66b
CC
21947 else if (startswith (pnote->namedata, "QNX"))
21948 return print_qnx_note (pnote);
779fe533 21949
2952f10c 21950 print_note_contents_hex (pnote);
015dc7e1 21951 return true;
1449284b 21952}
6d118b09 21953
015dc7e1 21954static bool
dda8d76d
NC
21955process_notes_at (Filedata * filedata,
21956 Elf_Internal_Shdr * section,
625d49fc
AM
21957 uint64_t offset,
21958 uint64_t length,
21959 uint64_t align)
779fe533 21960{
015dc7e1
AM
21961 Elf_External_Note *pnotes;
21962 Elf_External_Note *external;
21963 char *end;
21964 bool res = true;
103f02d3 21965
779fe533 21966 if (length <= 0)
015dc7e1 21967 return false;
103f02d3 21968
1449284b
NC
21969 if (section)
21970 {
dda8d76d 21971 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21972 if (pnotes)
32ec8896 21973 {
dda8d76d 21974 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21975 {
21976 free (pnotes);
015dc7e1 21977 return false;
f761cb13 21978 }
32ec8896 21979 }
1449284b
NC
21980 }
21981 else
82ed9683 21982 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21983 _("notes"));
4dff97b2 21984
dd24e3da 21985 if (pnotes == NULL)
015dc7e1 21986 return false;
779fe533 21987
103f02d3 21988 external = pnotes;
103f02d3 21989
ca0e11aa
NC
21990 if (filedata->is_separate)
21991 printf (_("In linked file '%s': "), filedata->file_name);
21992 else
21993 printf ("\n");
1449284b 21994 if (section)
ca0e11aa 21995 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21996 else
26c527e6
AM
21997 printf (_("Displaying notes found at file offset 0x%08" PRIx64
21998 " with length 0x%08" PRIx64 ":\n"),
21999 offset, length);
1449284b 22000
82ed9683
L
22001 /* NB: Some note sections may have alignment value of 0 or 1. gABI
22002 specifies that notes should be aligned to 4 bytes in 32-bit
22003 objects and to 8 bytes in 64-bit objects. As a Linux extension,
22004 we also support 4 byte alignment in 64-bit objects. If section
22005 alignment is less than 4, we treate alignment as 4 bytes. */
22006 if (align < 4)
22007 align = 4;
22008 else if (align != 4 && align != 8)
22009 {
26c527e6
AM
22010 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
22011 align);
a788aedd 22012 free (pnotes);
015dc7e1 22013 return false;
82ed9683
L
22014 }
22015
dbe15e4e 22016 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 22017
c8071705
NC
22018 end = (char *) pnotes + length;
22019 while ((char *) external < end)
779fe533 22020 {
b34976b6 22021 Elf_Internal_Note inote;
15b42fb0 22022 size_t min_notesz;
4dff97b2 22023 char * next;
2cf0635d 22024 char * temp = NULL;
c8071705 22025 size_t data_remaining = end - (char *) external;
6d118b09 22026
dda8d76d 22027 if (!is_ia64_vms (filedata))
15b42fb0 22028 {
9dd3a467
NC
22029 /* PR binutils/15191
22030 Make sure that there is enough data to read. */
15b42fb0
AM
22031 min_notesz = offsetof (Elf_External_Note, name);
22032 if (data_remaining < min_notesz)
9dd3a467 22033 {
26c527e6 22034 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22035 "not enough for a full note\n",
26c527e6 22036 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22037 "not enough for a full note\n",
22038 data_remaining),
26c527e6 22039 data_remaining);
9dd3a467
NC
22040 break;
22041 }
5396a86e
AM
22042 data_remaining -= min_notesz;
22043
15b42fb0
AM
22044 inote.type = BYTE_GET (external->type);
22045 inote.namesz = BYTE_GET (external->namesz);
22046 inote.namedata = external->name;
22047 inote.descsz = BYTE_GET (external->descsz);
276da9b3 22048 inote.descdata = ((char *) external
4dff97b2 22049 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 22050 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 22051 next = ((char *) external
4dff97b2 22052 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 22053 }
00e98fc7 22054 else
15b42fb0
AM
22055 {
22056 Elf64_External_VMS_Note *vms_external;
00e98fc7 22057
9dd3a467
NC
22058 /* PR binutils/15191
22059 Make sure that there is enough data to read. */
15b42fb0
AM
22060 min_notesz = offsetof (Elf64_External_VMS_Note, name);
22061 if (data_remaining < min_notesz)
9dd3a467 22062 {
26c527e6 22063 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22064 "not enough for a full note\n",
26c527e6 22065 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22066 "not enough for a full note\n",
22067 data_remaining),
26c527e6 22068 data_remaining);
9dd3a467
NC
22069 break;
22070 }
5396a86e 22071 data_remaining -= min_notesz;
3e55a963 22072
15b42fb0
AM
22073 vms_external = (Elf64_External_VMS_Note *) external;
22074 inote.type = BYTE_GET (vms_external->type);
22075 inote.namesz = BYTE_GET (vms_external->namesz);
22076 inote.namedata = vms_external->name;
22077 inote.descsz = BYTE_GET (vms_external->descsz);
22078 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
22079 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22080 next = inote.descdata + align_power (inote.descsz, 3);
22081 }
22082
5396a86e
AM
22083 /* PR 17531: file: 3443835e. */
22084 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
22085 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
22086 || (size_t) (inote.descdata - inote.namedata) > data_remaining
22087 || (size_t) (next - inote.descdata) < inote.descsz
22088 || ((size_t) (next - inote.descdata)
22089 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 22090 {
26c527e6
AM
22091 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
22092 (char *) external - (char *) pnotes);
22093 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 22094 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
22095 break;
22096 }
22097
15b42fb0 22098 external = (Elf_External_Note *) next;
dd24e3da 22099
6d118b09
NC
22100 /* Verify that name is null terminated. It appears that at least
22101 one version of Linux (RedHat 6.0) generates corefiles that don't
22102 comply with the ELF spec by failing to include the null byte in
22103 namesz. */
18344509 22104 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 22105 {
5396a86e 22106 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 22107 {
5396a86e
AM
22108 temp = (char *) malloc (inote.namesz + 1);
22109 if (temp == NULL)
22110 {
22111 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 22112 res = false;
5396a86e
AM
22113 break;
22114 }
76da6bbe 22115
5396a86e
AM
22116 memcpy (temp, inote.namedata, inote.namesz);
22117 inote.namedata = temp;
22118 }
22119 inote.namedata[inote.namesz] = 0;
6d118b09
NC
22120 }
22121
dda8d76d 22122 if (! process_note (& inote, filedata))
015dc7e1 22123 res = false;
103f02d3 22124
9db70fc3
AM
22125 free (temp);
22126 temp = NULL;
779fe533
NC
22127 }
22128
22129 free (pnotes);
103f02d3 22130
779fe533
NC
22131 return res;
22132}
22133
015dc7e1 22134static bool
dda8d76d 22135process_corefile_note_segments (Filedata * filedata)
779fe533 22136{
015dc7e1 22137 Elf_Internal_Phdr *segment;
b34976b6 22138 unsigned int i;
015dc7e1 22139 bool res = true;
103f02d3 22140
dda8d76d 22141 if (! get_program_headers (filedata))
015dc7e1 22142 return true;
103f02d3 22143
dda8d76d
NC
22144 for (i = 0, segment = filedata->program_headers;
22145 i < filedata->file_header.e_phnum;
b34976b6 22146 i++, segment++)
779fe533
NC
22147 {
22148 if (segment->p_type == PT_NOTE)
625d49fc
AM
22149 if (! process_notes_at (filedata, NULL, segment->p_offset,
22150 segment->p_filesz, segment->p_align))
015dc7e1 22151 res = false;
779fe533 22152 }
103f02d3 22153
779fe533
NC
22154 return res;
22155}
22156
015dc7e1 22157static bool
625d49fc 22158process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
22159{
22160 Elf_External_Note * pnotes;
22161 Elf_External_Note * external;
c8071705 22162 char * end;
015dc7e1 22163 bool res = true;
685080f2
NC
22164
22165 if (length <= 0)
015dc7e1 22166 return false;
685080f2 22167
dda8d76d 22168 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
22169 _("v850 notes"));
22170 if (pnotes == NULL)
015dc7e1 22171 return false;
685080f2
NC
22172
22173 external = pnotes;
c8071705 22174 end = (char*) pnotes + length;
685080f2 22175
26c527e6
AM
22176 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22177 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22178 offset, length);
685080f2 22179
c8071705 22180 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
22181 {
22182 Elf_External_Note * next;
22183 Elf_Internal_Note inote;
22184
22185 inote.type = BYTE_GET (external->type);
22186 inote.namesz = BYTE_GET (external->namesz);
22187 inote.namedata = external->name;
22188 inote.descsz = BYTE_GET (external->descsz);
22189 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22190 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22191
c8071705
NC
22192 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22193 {
22194 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22195 inote.descdata = inote.namedata;
22196 inote.namesz = 0;
22197 }
22198
685080f2
NC
22199 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22200
c8071705 22201 if ( ((char *) next > end)
685080f2
NC
22202 || ((char *) next < (char *) pnotes))
22203 {
26c527e6
AM
22204 warn (_("corrupt descsz found in note at offset %#tx\n"),
22205 (char *) external - (char *) pnotes);
22206 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22207 inote.type, inote.namesz, inote.descsz);
22208 break;
22209 }
22210
22211 external = next;
22212
22213 /* Prevent out-of-bounds indexing. */
c8071705 22214 if ( inote.namedata + inote.namesz > end
685080f2
NC
22215 || inote.namedata + inote.namesz < inote.namedata)
22216 {
26c527e6
AM
22217 warn (_("corrupt namesz found in note at offset %#zx\n"),
22218 (char *) external - (char *) pnotes);
22219 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22220 inote.type, inote.namesz, inote.descsz);
22221 break;
22222 }
22223
22224 printf (" %s: ", get_v850_elf_note_type (inote.type));
22225
22226 if (! print_v850_note (& inote))
22227 {
015dc7e1 22228 res = false;
26c527e6 22229 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
22230 inote.namesz, inote.descsz);
22231 }
22232 }
22233
22234 free (pnotes);
22235
22236 return res;
22237}
22238
015dc7e1 22239static bool
dda8d76d 22240process_note_sections (Filedata * filedata)
1ec5cd37 22241{
015dc7e1 22242 Elf_Internal_Shdr *section;
26c527e6 22243 size_t i;
32ec8896 22244 unsigned int n = 0;
015dc7e1 22245 bool res = true;
1ec5cd37 22246
dda8d76d
NC
22247 for (i = 0, section = filedata->section_headers;
22248 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 22249 i++, section++)
685080f2
NC
22250 {
22251 if (section->sh_type == SHT_NOTE)
22252 {
625d49fc
AM
22253 if (! process_notes_at (filedata, section, section->sh_offset,
22254 section->sh_size, section->sh_addralign))
015dc7e1 22255 res = false;
685080f2
NC
22256 n++;
22257 }
22258
dda8d76d
NC
22259 if (( filedata->file_header.e_machine == EM_V800
22260 || filedata->file_header.e_machine == EM_V850
22261 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
22262 && section->sh_type == SHT_RENESAS_INFO)
22263 {
625d49fc
AM
22264 if (! process_v850_notes (filedata, section->sh_offset,
22265 section->sh_size))
015dc7e1 22266 res = false;
685080f2
NC
22267 n++;
22268 }
22269 }
df565f32
NC
22270
22271 if (n == 0)
22272 /* Try processing NOTE segments instead. */
dda8d76d 22273 return process_corefile_note_segments (filedata);
1ec5cd37
NC
22274
22275 return res;
22276}
22277
015dc7e1 22278static bool
dda8d76d 22279process_notes (Filedata * filedata)
779fe533
NC
22280{
22281 /* If we have not been asked to display the notes then do nothing. */
22282 if (! do_notes)
015dc7e1 22283 return true;
103f02d3 22284
dda8d76d
NC
22285 if (filedata->file_header.e_type != ET_CORE)
22286 return process_note_sections (filedata);
103f02d3 22287
779fe533 22288 /* No program headers means no NOTE segment. */
dda8d76d
NC
22289 if (filedata->file_header.e_phnum > 0)
22290 return process_corefile_note_segments (filedata);
779fe533 22291
ca0e11aa
NC
22292 if (filedata->is_separate)
22293 printf (_("No notes found in linked file '%s'.\n"),
22294 filedata->file_name);
22295 else
22296 printf (_("No notes found file.\n"));
22297
015dc7e1 22298 return true;
779fe533
NC
22299}
22300
60abdbed
NC
22301static unsigned char *
22302display_public_gnu_attributes (unsigned char * start,
22303 const unsigned char * const end)
22304{
22305 printf (_(" Unknown GNU attribute: %s\n"), start);
22306
22307 start += strnlen ((char *) start, end - start);
22308 display_raw_attribute (start, end);
22309
22310 return (unsigned char *) end;
22311}
22312
22313static unsigned char *
22314display_generic_attribute (unsigned char * start,
22315 unsigned int tag,
22316 const unsigned char * const end)
22317{
22318 if (tag == 0)
22319 return (unsigned char *) end;
22320
22321 return display_tag_value (tag, start, end);
22322}
22323
015dc7e1 22324static bool
dda8d76d 22325process_arch_specific (Filedata * filedata)
252b5132 22326{
a952a375 22327 if (! do_arch)
015dc7e1 22328 return true;
a952a375 22329
dda8d76d 22330 switch (filedata->file_header.e_machine)
252b5132 22331 {
53a346d8
CZ
22332 case EM_ARC:
22333 case EM_ARC_COMPACT:
22334 case EM_ARC_COMPACT2:
13aa307c
CZ
22335 case EM_ARC_COMPACT3:
22336 case EM_ARC_COMPACT3_64:
dda8d76d 22337 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
22338 display_arc_attribute,
22339 display_generic_attribute);
11c1ff18 22340 case EM_ARM:
dda8d76d 22341 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
22342 display_arm_attribute,
22343 display_generic_attribute);
22344
252b5132 22345 case EM_MIPS:
4fe85591 22346 case EM_MIPS_RS3_LE:
dda8d76d 22347 return process_mips_specific (filedata);
60abdbed
NC
22348
22349 case EM_MSP430:
dda8d76d 22350 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 22351 display_msp430_attribute,
c0ea7c52 22352 display_msp430_gnu_attribute);
60abdbed 22353
2dc8dd17
JW
22354 case EM_RISCV:
22355 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22356 display_riscv_attribute,
22357 display_generic_attribute);
22358
35c08157 22359 case EM_NDS32:
dda8d76d 22360 return process_nds32_specific (filedata);
60abdbed 22361
85f7484a
PB
22362 case EM_68K:
22363 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22364 display_m68k_gnu_attribute);
22365
34c8bcba 22366 case EM_PPC:
b82317dd 22367 case EM_PPC64:
dda8d76d 22368 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22369 display_power_gnu_attribute);
22370
643f7afb
AK
22371 case EM_S390:
22372 case EM_S390_OLD:
dda8d76d 22373 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22374 display_s390_gnu_attribute);
22375
9e8c70f9
DM
22376 case EM_SPARC:
22377 case EM_SPARC32PLUS:
22378 case EM_SPARCV9:
dda8d76d 22379 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22380 display_sparc_gnu_attribute);
22381
59e6276b 22382 case EM_TI_C6000:
dda8d76d 22383 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22384 display_tic6x_attribute,
22385 display_generic_attribute);
22386
0861f561
CQ
22387 case EM_CSKY:
22388 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22389 display_csky_attribute, NULL);
22390
252b5132 22391 default:
dda8d76d 22392 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22393 display_public_gnu_attributes,
22394 display_generic_attribute);
252b5132 22395 }
252b5132
RH
22396}
22397
015dc7e1 22398static bool
dda8d76d 22399get_file_header (Filedata * filedata)
252b5132 22400{
9ea033b2 22401 /* Read in the identity array. */
dda8d76d 22402 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22403 return false;
252b5132 22404
9ea033b2 22405 /* Determine how to read the rest of the header. */
dda8d76d 22406 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22407 {
1a0670f3
AM
22408 default:
22409 case ELFDATANONE:
adab8cdc
AO
22410 case ELFDATA2LSB:
22411 byte_get = byte_get_little_endian;
22412 byte_put = byte_put_little_endian;
22413 break;
22414 case ELFDATA2MSB:
22415 byte_get = byte_get_big_endian;
22416 byte_put = byte_put_big_endian;
22417 break;
9ea033b2
NC
22418 }
22419
22420 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22421 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22422
22423 /* Read in the rest of the header. */
22424 if (is_32bit_elf)
22425 {
22426 Elf32_External_Ehdr ehdr32;
252b5132 22427
dda8d76d 22428 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22429 return false;
103f02d3 22430
dda8d76d
NC
22431 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22432 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22433 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22434 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22435 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22436 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22437 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22438 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22439 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22440 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22441 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22442 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22443 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22444 }
252b5132 22445 else
9ea033b2
NC
22446 {
22447 Elf64_External_Ehdr ehdr64;
a952a375 22448
dda8d76d 22449 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22450 return false;
103f02d3 22451
dda8d76d
NC
22452 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22453 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22454 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22455 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22456 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22457 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22458 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22459 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22460 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22461 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22462 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22463 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22464 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22465 }
252b5132 22466
015dc7e1 22467 return true;
252b5132
RH
22468}
22469
13acb58d
AM
22470static void
22471free_filedata (Filedata *filedata)
22472{
22473 free (filedata->program_interpreter);
13acb58d 22474 free (filedata->program_headers);
13acb58d 22475 free (filedata->section_headers);
13acb58d 22476 free (filedata->string_table);
13acb58d 22477 free (filedata->dump.dump_sects);
13acb58d 22478 free (filedata->dynamic_strings);
13acb58d 22479 free (filedata->dynamic_symbols);
13acb58d 22480 free (filedata->dynamic_syminfo);
13acb58d 22481 free (filedata->dynamic_section);
13acb58d
AM
22482
22483 while (filedata->symtab_shndx_list != NULL)
22484 {
22485 elf_section_list *next = filedata->symtab_shndx_list->next;
22486 free (filedata->symtab_shndx_list);
22487 filedata->symtab_shndx_list = next;
22488 }
22489
22490 free (filedata->section_headers_groups);
13acb58d
AM
22491
22492 if (filedata->section_groups)
22493 {
22494 size_t i;
22495 struct group_list * g;
22496 struct group_list * next;
22497
22498 for (i = 0; i < filedata->group_count; i++)
22499 {
22500 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22501 {
22502 next = g->next;
22503 free (g);
22504 }
22505 }
22506
22507 free (filedata->section_groups);
13acb58d 22508 }
066f8fbe
AM
22509 memset (&filedata->section_headers, 0,
22510 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22511}
22512
dda8d76d
NC
22513static void
22514close_file (Filedata * filedata)
22515{
22516 if (filedata)
22517 {
22518 if (filedata->handle)
22519 fclose (filedata->handle);
22520 free (filedata);
22521 }
22522}
22523
22524void
22525close_debug_file (void * data)
22526{
13acb58d 22527 free_filedata ((Filedata *) data);
dda8d76d
NC
22528 close_file ((Filedata *) data);
22529}
22530
22531static Filedata *
015dc7e1 22532open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22533{
22534 struct stat statbuf;
22535 Filedata * filedata = NULL;
22536
22537 if (stat (pathname, & statbuf) < 0
22538 || ! S_ISREG (statbuf.st_mode))
22539 goto fail;
22540
22541 filedata = calloc (1, sizeof * filedata);
22542 if (filedata == NULL)
22543 goto fail;
22544
22545 filedata->handle = fopen (pathname, "rb");
22546 if (filedata->handle == NULL)
22547 goto fail;
22548
be7d229a 22549 filedata->file_size = statbuf.st_size;
dda8d76d 22550 filedata->file_name = pathname;
ca0e11aa 22551 filedata->is_separate = is_separate;
dda8d76d
NC
22552
22553 if (! get_file_header (filedata))
22554 goto fail;
22555
4de91c10
AM
22556 if (!get_section_headers (filedata, false))
22557 goto fail;
dda8d76d
NC
22558
22559 return filedata;
22560
22561 fail:
22562 if (filedata)
22563 {
22564 if (filedata->handle)
22565 fclose (filedata->handle);
22566 free (filedata);
22567 }
22568 return NULL;
22569}
22570
22571void *
22572open_debug_file (const char * pathname)
22573{
015dc7e1 22574 return open_file (pathname, true);
dda8d76d
NC
22575}
22576
835f2fae
NC
22577static void
22578initialise_dump_sects (Filedata * filedata)
22579{
22580 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22581 Note we do this even if cmdline_dump_sects is empty because we
22582 must make sure that the dump_sets array is zeroed out before each
22583 object file is processed. */
22584 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22585 memset (filedata->dump.dump_sects, 0,
22586 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22587
22588 if (cmdline.num_dump_sects > 0)
22589 {
22590 if (filedata->dump.num_dump_sects == 0)
22591 /* A sneaky way of allocating the dump_sects array. */
22592 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22593
22594 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22595 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22596 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22597 }
22598}
22599
94585d6d
NC
22600static bool
22601might_need_separate_debug_info (Filedata * filedata)
22602{
22603 /* Debuginfo files do not need further separate file loading. */
22604 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22605 return false;
22606
22607 /* Since do_follow_links might be enabled by default, only treat it as an
22608 indication that separate files should be loaded if setting it was a
22609 deliberate user action. */
22610 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22611 return true;
22612
22613 if (process_links || do_syms || do_unwind
22614 || dump_any_debugging || do_dump || do_debugging)
22615 return true;
22616
22617 return false;
22618}
22619
fb52b2f4
NC
22620/* Process one ELF object file according to the command line options.
22621 This file may actually be stored in an archive. The file is
32ec8896
NC
22622 positioned at the start of the ELF object. Returns TRUE if no
22623 problems were encountered, FALSE otherwise. */
fb52b2f4 22624
015dc7e1 22625static bool
dda8d76d 22626process_object (Filedata * filedata)
252b5132 22627{
015dc7e1 22628 bool have_separate_files;
252b5132 22629 unsigned int i;
015dc7e1 22630 bool res;
252b5132 22631
dda8d76d 22632 if (! get_file_header (filedata))
252b5132 22633 {
dda8d76d 22634 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22635 return false;
252b5132
RH
22636 }
22637
22638 /* Initialise per file variables. */
978c4450
AM
22639 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22640 filedata->version_info[i] = 0;
252b5132 22641
978c4450
AM
22642 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22643 filedata->dynamic_info[i] = 0;
22644 filedata->dynamic_info_DT_GNU_HASH = 0;
22645 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22646
22647 /* Process the file. */
22648 if (show_name)
dda8d76d 22649 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22650
835f2fae 22651 initialise_dump_sects (filedata);
d70c5fc7 22652
4de91c10
AM
22653 /* There may be some extensions in the first section header. Don't
22654 bomb if we can't read it. */
22655 get_section_headers (filedata, true);
22656
dda8d76d 22657 if (! process_file_header (filedata))
4de91c10
AM
22658 {
22659 res = false;
22660 goto out;
22661 }
252b5132 22662
e331b18d
AM
22663 /* Throw away the single section header read above, so that we
22664 re-read the entire set. */
22665 free (filedata->section_headers);
22666 filedata->section_headers = NULL;
22667
dda8d76d 22668 if (! process_section_headers (filedata))
2f62977e 22669 {
32ec8896 22670 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22671 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22672
2f62977e 22673 if (! do_using_dynamic)
015dc7e1 22674 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22675 }
252b5132 22676
dda8d76d 22677 if (! process_section_groups (filedata))
32ec8896 22678 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22679 do_unwind = false;
d1f5c6e3 22680
93df3340
AM
22681 process_program_headers (filedata);
22682
22683 res = process_dynamic_section (filedata);
252b5132 22684
dda8d76d 22685 if (! process_relocs (filedata))
015dc7e1 22686 res = false;
252b5132 22687
dda8d76d 22688 if (! process_unwind (filedata))
015dc7e1 22689 res = false;
4d6ed7c8 22690
dda8d76d 22691 if (! process_symbol_table (filedata))
015dc7e1 22692 res = false;
252b5132 22693
0f03783c 22694 if (! process_lto_symbol_tables (filedata))
015dc7e1 22695 res = false;
b9e920ec 22696
dda8d76d 22697 if (! process_syminfo (filedata))
015dc7e1 22698 res = false;
252b5132 22699
dda8d76d 22700 if (! process_version_sections (filedata))
015dc7e1 22701 res = false;
252b5132 22702
94585d6d 22703 if (might_need_separate_debug_info (filedata))
24841daa 22704 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22705 else
015dc7e1 22706 have_separate_files = false;
dda8d76d
NC
22707
22708 if (! process_section_contents (filedata))
015dc7e1 22709 res = false;
f5842774 22710
24841daa 22711 if (have_separate_files)
dda8d76d 22712 {
24841daa
NC
22713 separate_info * d;
22714
22715 for (d = first_separate_info; d != NULL; d = d->next)
22716 {
835f2fae
NC
22717 initialise_dump_sects (d->handle);
22718
ca0e11aa 22719 if (process_links && ! process_file_header (d->handle))
015dc7e1 22720 res = false;
ca0e11aa 22721 else if (! process_section_headers (d->handle))
015dc7e1 22722 res = false;
d6bfbc39 22723 else if (! process_section_contents (d->handle))
015dc7e1 22724 res = false;
ca0e11aa
NC
22725 else if (process_links)
22726 {
ca0e11aa 22727 if (! process_section_groups (d->handle))
015dc7e1 22728 res = false;
93df3340 22729 process_program_headers (d->handle);
ca0e11aa 22730 if (! process_dynamic_section (d->handle))
015dc7e1 22731 res = false;
ca0e11aa 22732 if (! process_relocs (d->handle))
015dc7e1 22733 res = false;
ca0e11aa 22734 if (! process_unwind (d->handle))
015dc7e1 22735 res = false;
ca0e11aa 22736 if (! process_symbol_table (d->handle))
015dc7e1 22737 res = false;
ca0e11aa 22738 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22739 res = false;
ca0e11aa 22740 if (! process_syminfo (d->handle))
015dc7e1 22741 res = false;
ca0e11aa 22742 if (! process_version_sections (d->handle))
015dc7e1 22743 res = false;
ca0e11aa 22744 if (! process_notes (d->handle))
015dc7e1 22745 res = false;
ca0e11aa 22746 }
24841daa
NC
22747 }
22748
22749 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22750 }
22751
22752 if (! process_notes (filedata))
015dc7e1 22753 res = false;
103f02d3 22754
dda8d76d 22755 if (! process_gnu_liblist (filedata))
015dc7e1 22756 res = false;
047b2264 22757
dda8d76d 22758 if (! process_arch_specific (filedata))
015dc7e1 22759 res = false;
252b5132 22760
4de91c10 22761 out:
13acb58d 22762 free_filedata (filedata);
e4b17d5c 22763
19e6b90e 22764 free_debug_memory ();
18bd398b 22765
32ec8896 22766 return res;
252b5132
RH
22767}
22768
2cf0635d 22769/* Process an ELF archive.
32ec8896
NC
22770 On entry the file is positioned just after the ARMAG string.
22771 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22772
015dc7e1
AM
22773static bool
22774process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22775{
22776 struct archive_info arch;
22777 struct archive_info nested_arch;
22778 size_t got;
015dc7e1 22779 bool ret = true;
2cf0635d 22780
015dc7e1 22781 show_name = true;
2cf0635d
NC
22782
22783 /* The ARCH structure is used to hold information about this archive. */
22784 arch.file_name = NULL;
22785 arch.file = NULL;
22786 arch.index_array = NULL;
22787 arch.sym_table = NULL;
22788 arch.longnames = NULL;
22789
22790 /* The NESTED_ARCH structure is used as a single-item cache of information
22791 about a nested archive (when members of a thin archive reside within
22792 another regular archive file). */
22793 nested_arch.file_name = NULL;
22794 nested_arch.file = NULL;
22795 nested_arch.index_array = NULL;
22796 nested_arch.sym_table = NULL;
22797 nested_arch.longnames = NULL;
22798
dda8d76d 22799 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22800 filedata->file_size, is_thin_archive,
22801 do_archive_index) != 0)
2cf0635d 22802 {
015dc7e1 22803 ret = false;
2cf0635d 22804 goto out;
4145f1d5 22805 }
fb52b2f4 22806
4145f1d5
NC
22807 if (do_archive_index)
22808 {
2cf0635d 22809 if (arch.sym_table == NULL)
1cb7d8b1
AM
22810 error (_("%s: unable to dump the index as none was found\n"),
22811 filedata->file_name);
4145f1d5
NC
22812 else
22813 {
26c527e6
AM
22814 uint64_t i, l;
22815 uint64_t current_pos;
4145f1d5 22816
26c527e6
AM
22817 printf (_("Index of archive %s: (%" PRIu64 " entries,"
22818 " %#" PRIx64 " bytes in the symbol table)\n"),
22819 filedata->file_name, arch.index_num,
1cb7d8b1 22820 arch.sym_size);
dda8d76d
NC
22821
22822 current_pos = ftell (filedata->handle);
4145f1d5 22823
2cf0635d 22824 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22825 {
1cb7d8b1
AM
22826 if (i == 0
22827 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22828 {
22829 char * member_name
22830 = get_archive_member_name_at (&arch, arch.index_array[i],
22831 &nested_arch);
2cf0635d 22832
1cb7d8b1
AM
22833 if (member_name != NULL)
22834 {
22835 char * qualified_name
22836 = make_qualified_name (&arch, &nested_arch,
22837 member_name);
2cf0635d 22838
1cb7d8b1
AM
22839 if (qualified_name != NULL)
22840 {
22841 printf (_("Contents of binary %s at offset "),
22842 qualified_name);
c2a7d3f5
NC
22843 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22844 putchar ('\n');
1cb7d8b1
AM
22845 free (qualified_name);
22846 }
fd486f32 22847 free (member_name);
4145f1d5
NC
22848 }
22849 }
2cf0635d
NC
22850
22851 if (l >= arch.sym_size)
4145f1d5 22852 {
1cb7d8b1
AM
22853 error (_("%s: end of the symbol table reached "
22854 "before the end of the index\n"),
dda8d76d 22855 filedata->file_name);
015dc7e1 22856 ret = false;
cb8f3167 22857 break;
4145f1d5 22858 }
591f7597 22859 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22860 printf ("\t%.*s\n",
22861 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22862 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22863 }
22864
67ce483b 22865 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22866 l = (l + 7) & ~ 7;
22867 else
22868 l += l & 1;
22869
2cf0635d 22870 if (l < arch.sym_size)
32ec8896 22871 {
26c527e6 22872 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
22873 "but without corresponding entries in "
22874 "the index table\n",
26c527e6 22875 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
22876 "but without corresponding entries in "
22877 "the index table\n",
22878 arch.sym_size - l),
dda8d76d 22879 filedata->file_name, arch.sym_size - l);
015dc7e1 22880 ret = false;
32ec8896 22881 }
4145f1d5 22882
63cf857e 22883 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22884 {
1cb7d8b1
AM
22885 error (_("%s: failed to seek back to start of object files "
22886 "in the archive\n"),
dda8d76d 22887 filedata->file_name);
015dc7e1 22888 ret = false;
2cf0635d 22889 goto out;
4145f1d5 22890 }
fb52b2f4 22891 }
4145f1d5
NC
22892
22893 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22894 && !do_segments && !do_header && !do_dump && !do_version
22895 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22896 && !do_section_groups && !do_dyn_syms)
2cf0635d 22897 {
015dc7e1 22898 ret = true; /* Archive index only. */
2cf0635d
NC
22899 goto out;
22900 }
fb52b2f4
NC
22901 }
22902
fb52b2f4
NC
22903 while (1)
22904 {
2cf0635d
NC
22905 char * name;
22906 size_t namelen;
22907 char * qualified_name;
22908
22909 /* Read the next archive header. */
63cf857e 22910 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22911 {
22912 error (_("%s: failed to seek to next archive header\n"),
22913 arch.file_name);
015dc7e1 22914 ret = false;
1cb7d8b1
AM
22915 break;
22916 }
dda8d76d 22917 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22918 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22919 {
22920 if (got == 0)
2cf0635d 22921 break;
28e817cc
NC
22922 /* PR 24049 - we cannot use filedata->file_name as this will
22923 have already been freed. */
22924 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22925
015dc7e1 22926 ret = false;
1cb7d8b1
AM
22927 break;
22928 }
2cf0635d 22929 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22930 {
22931 error (_("%s: did not find a valid archive header\n"),
22932 arch.file_name);
015dc7e1 22933 ret = false;
1cb7d8b1
AM
22934 break;
22935 }
2cf0635d
NC
22936
22937 arch.next_arhdr_offset += sizeof arch.arhdr;
22938
978c4450 22939 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22940
22941 name = get_archive_member_name (&arch, &nested_arch);
22942 if (name == NULL)
fb52b2f4 22943 {
28e817cc 22944 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22945 ret = false;
d989285c 22946 break;
fb52b2f4 22947 }
2cf0635d 22948 namelen = strlen (name);
fb52b2f4 22949
2cf0635d
NC
22950 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22951 if (qualified_name == NULL)
fb52b2f4 22952 {
28e817cc 22953 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22954 free (name);
015dc7e1 22955 ret = false;
d989285c 22956 break;
fb52b2f4
NC
22957 }
22958
2cf0635d 22959 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22960 {
22961 /* This is a proxy for an external member of a thin archive. */
22962 Filedata * member_filedata;
22963 char * member_file_name = adjust_relative_path
dda8d76d 22964 (filedata->file_name, name, namelen);
32ec8896 22965
fd486f32 22966 free (name);
1cb7d8b1
AM
22967 if (member_file_name == NULL)
22968 {
fd486f32 22969 free (qualified_name);
015dc7e1 22970 ret = false;
1cb7d8b1
AM
22971 break;
22972 }
2cf0635d 22973
015dc7e1 22974 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22975 if (member_filedata == NULL)
22976 {
22977 error (_("Input file '%s' is not readable.\n"), member_file_name);
22978 free (member_file_name);
fd486f32 22979 free (qualified_name);
015dc7e1 22980 ret = false;
1cb7d8b1
AM
22981 break;
22982 }
2cf0635d 22983
978c4450 22984 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22985 member_filedata->file_name = qualified_name;
2cf0635d 22986
75a2da57
AH
22987 /* The call to process_object() expects the file to be at the beginning. */
22988 rewind (member_filedata->handle);
22989
1cb7d8b1 22990 if (! process_object (member_filedata))
015dc7e1 22991 ret = false;
2cf0635d 22992
1cb7d8b1
AM
22993 close_file (member_filedata);
22994 free (member_file_name);
1cb7d8b1 22995 }
2cf0635d 22996 else if (is_thin_archive)
1cb7d8b1
AM
22997 {
22998 Filedata thin_filedata;
eb02c04d 22999
1cb7d8b1 23000 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 23001
a043396b
NC
23002 /* PR 15140: Allow for corrupt thin archives. */
23003 if (nested_arch.file == NULL)
23004 {
23005 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 23006 qualified_name, name);
fd486f32
AM
23007 free (qualified_name);
23008 free (name);
015dc7e1 23009 ret = false;
a043396b
NC
23010 break;
23011 }
fd486f32 23012 free (name);
a043396b 23013
1cb7d8b1 23014 /* This is a proxy for a member of a nested archive. */
978c4450
AM
23015 filedata->archive_file_offset
23016 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 23017
1cb7d8b1
AM
23018 /* The nested archive file will have been opened and setup by
23019 get_archive_member_name. */
63cf857e
AM
23020 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
23021 SEEK_SET) != 0)
1cb7d8b1
AM
23022 {
23023 error (_("%s: failed to seek to archive member.\n"),
23024 nested_arch.file_name);
fd486f32 23025 free (qualified_name);
015dc7e1 23026 ret = false;
1cb7d8b1
AM
23027 break;
23028 }
2cf0635d 23029
dda8d76d
NC
23030 thin_filedata.handle = nested_arch.file;
23031 thin_filedata.file_name = qualified_name;
9abca702 23032
1cb7d8b1 23033 if (! process_object (& thin_filedata))
015dc7e1 23034 ret = false;
1cb7d8b1 23035 }
2cf0635d 23036 else
1cb7d8b1 23037 {
fd486f32 23038 free (name);
978c4450 23039 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 23040 filedata->file_name = qualified_name;
1cb7d8b1 23041 if (! process_object (filedata))
015dc7e1 23042 ret = false;
237877b8 23043 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 23044 /* Stop looping with "negative" archive_file_size. */
978c4450 23045 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 23046 arch.next_arhdr_offset = -1ul;
1cb7d8b1 23047 }
fb52b2f4 23048
2cf0635d 23049 free (qualified_name);
fb52b2f4
NC
23050 }
23051
4145f1d5 23052 out:
2cf0635d
NC
23053 if (nested_arch.file != NULL)
23054 fclose (nested_arch.file);
23055 release_archive (&nested_arch);
23056 release_archive (&arch);
fb52b2f4 23057
d989285c 23058 return ret;
fb52b2f4
NC
23059}
23060
015dc7e1 23061static bool
2cf0635d 23062process_file (char * file_name)
fb52b2f4 23063{
dda8d76d 23064 Filedata * filedata = NULL;
fb52b2f4
NC
23065 struct stat statbuf;
23066 char armag[SARMAG];
015dc7e1 23067 bool ret = true;
fb52b2f4
NC
23068
23069 if (stat (file_name, &statbuf) < 0)
23070 {
f24ddbdd
NC
23071 if (errno == ENOENT)
23072 error (_("'%s': No such file\n"), file_name);
23073 else
23074 error (_("Could not locate '%s'. System error message: %s\n"),
23075 file_name, strerror (errno));
015dc7e1 23076 return false;
f24ddbdd
NC
23077 }
23078
23079 if (! S_ISREG (statbuf.st_mode))
23080 {
23081 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 23082 return false;
fb52b2f4
NC
23083 }
23084
dda8d76d
NC
23085 filedata = calloc (1, sizeof * filedata);
23086 if (filedata == NULL)
23087 {
23088 error (_("Out of memory allocating file data structure\n"));
015dc7e1 23089 return false;
dda8d76d
NC
23090 }
23091
23092 filedata->file_name = file_name;
23093 filedata->handle = fopen (file_name, "rb");
23094 if (filedata->handle == NULL)
fb52b2f4 23095 {
f24ddbdd 23096 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 23097 free (filedata);
015dc7e1 23098 return false;
fb52b2f4
NC
23099 }
23100
dda8d76d 23101 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 23102 {
4145f1d5 23103 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
23104 fclose (filedata->handle);
23105 free (filedata);
015dc7e1 23106 return false;
fb52b2f4
NC
23107 }
23108
be7d229a 23109 filedata->file_size = statbuf.st_size;
015dc7e1 23110 filedata->is_separate = false;
f54498b4 23111
fb52b2f4 23112 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 23113 {
015dc7e1
AM
23114 if (! process_archive (filedata, false))
23115 ret = false;
32ec8896 23116 }
2cf0635d 23117 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 23118 {
015dc7e1
AM
23119 if ( ! process_archive (filedata, true))
23120 ret = false;
32ec8896 23121 }
fb52b2f4
NC
23122 else
23123 {
1b513401 23124 if (do_archive_index && !check_all)
4145f1d5
NC
23125 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23126 file_name);
23127
dda8d76d 23128 rewind (filedata->handle);
978c4450 23129 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 23130
dda8d76d 23131 if (! process_object (filedata))
015dc7e1 23132 ret = false;
fb52b2f4
NC
23133 }
23134
dda8d76d 23135 fclose (filedata->handle);
8fb879cd
AM
23136 free (filedata->section_headers);
23137 free (filedata->program_headers);
23138 free (filedata->string_table);
6431e409 23139 free (filedata->dump.dump_sects);
dda8d76d 23140 free (filedata);
32ec8896 23141
fd486f32 23142 free (ba_cache.strtab);
1bd6175a 23143 ba_cache.strtab = NULL;
fd486f32 23144 free (ba_cache.symtab);
1bd6175a 23145 ba_cache.symtab = NULL;
fd486f32
AM
23146 ba_cache.filedata = NULL;
23147
fb52b2f4
NC
23148 return ret;
23149}
23150
252b5132
RH
23151#ifdef SUPPORT_DISASSEMBLY
23152/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 23153 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 23154 symbols. */
252b5132
RH
23155
23156void
2cf0635d 23157print_address (unsigned int addr, FILE * outfile)
252b5132
RH
23158{
23159 fprintf (outfile,"0x%8.8x", addr);
23160}
23161
e3c8793a 23162/* Needed by the i386 disassembler. */
dda8d76d 23163
252b5132
RH
23164void
23165db_task_printsym (unsigned int addr)
23166{
23167 print_address (addr, stderr);
23168}
23169#endif
23170
23171int
2cf0635d 23172main (int argc, char ** argv)
252b5132 23173{
ff78d6d6
L
23174 int err;
23175
87b9f255 23176#ifdef HAVE_LC_MESSAGES
252b5132 23177 setlocale (LC_MESSAGES, "");
3882b010 23178#endif
3882b010 23179 setlocale (LC_CTYPE, "");
252b5132
RH
23180 bindtextdomain (PACKAGE, LOCALEDIR);
23181 textdomain (PACKAGE);
23182
869b9d07
MM
23183 expandargv (&argc, &argv);
23184
dda8d76d 23185 parse_args (& cmdline, argc, argv);
59f14fc0 23186
18bd398b 23187 if (optind < (argc - 1))
1b513401
NC
23188 /* When displaying information for more than one file,
23189 prefix the information with the file name. */
015dc7e1 23190 show_name = true;
5656ba2c
L
23191 else if (optind >= argc)
23192 {
1b513401 23193 /* Ensure that the warning is always displayed. */
015dc7e1 23194 do_checks = true;
1b513401 23195
5656ba2c
L
23196 warn (_("Nothing to do.\n"));
23197 usage (stderr);
23198 }
18bd398b 23199
015dc7e1 23200 err = false;
252b5132 23201 while (optind < argc)
32ec8896 23202 if (! process_file (argv[optind++]))
015dc7e1 23203 err = true;
252b5132 23204
9db70fc3 23205 free (cmdline.dump_sects);
252b5132 23206
7d9813f1
NA
23207 free (dump_ctf_symtab_name);
23208 free (dump_ctf_strtab_name);
23209 free (dump_ctf_parent_name);
23210
32ec8896 23211 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 23212}