]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Remove fall-back prune_warnings
[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"
b5c37946 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:
b5c37946
SJ
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:
b5c37946
SJ
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";
b5c37946 2976 case EM_ARC_COMPACT3_64: return "Synopsys ARCv3 64-bit processor";
4cf2ad72 2977 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
b5c37946 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
f8c4789c
AM
3004static char *
3005decode_ARC_machine_flags (char *out, unsigned e_flags, unsigned e_machine)
a9522a21
AB
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:
f8c4789c 3024 out = stpcpy (out, ", ARC EM");
a9522a21
AB
3025 break;
3026 case EF_ARC_CPU_ARCV2HS:
f8c4789c 3027 out = stpcpy (out, ", ARC HS");
a9522a21
AB
3028 break;
3029
3030 /* We only expect these to occur for EM_ARC_COMPACT. */
3031 case E_ARC_MACH_ARC600:
f8c4789c 3032 out = stpcpy (out, ", ARC600");
a9522a21
AB
3033 break;
3034 case E_ARC_MACH_ARC601:
f8c4789c 3035 out = stpcpy (out, ", ARC601");
a9522a21
AB
3036 break;
3037 case E_ARC_MACH_ARC700:
f8c4789c 3038 out = stpcpy (out, ", ARC700");
a9522a21
AB
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)
f8c4789c 3047 out = stpcpy (out, ", Unknown ARCompact");
a9522a21 3048 else
f8c4789c 3049 out = stpcpy (out, ", Unknown ARC");
a9522a21
AB
3050 break;
3051 }
3052
3053 switch (e_flags & EF_ARC_OSABI_MSK)
3054 {
3055 case E_ARC_OSABI_ORIG:
f8c4789c 3056 out = stpcpy (out, ", (ABI:legacy)");
a9522a21
AB
3057 break;
3058 case E_ARC_OSABI_V2:
f8c4789c 3059 out = stpcpy (out, ", (ABI:v2)");
a9522a21
AB
3060 break;
3061 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3062 case E_ARC_OSABI_V3:
f8c4789c 3063 out = stpcpy (out, ", v3 no-legacy-syscalls ABI");
a9522a21 3064 break;
53a346d8 3065 case E_ARC_OSABI_V4:
f8c4789c 3066 out = stpcpy (out, ", v4 ABI");
53a346d8 3067 break;
a9522a21 3068 default:
f8c4789c 3069 out = stpcpy (out, ", unrecognised ARC OSABI flag");
a9522a21
AB
3070 break;
3071 }
f8c4789c 3072 return out;
a9522a21
AB
3073}
3074
f8c4789c
AM
3075static char *
3076decode_ARM_machine_flags (char *out, unsigned e_flags)
f3485b74
NC
3077{
3078 unsigned eabi;
015dc7e1 3079 bool unknown = false;
f3485b74
NC
3080
3081 eabi = EF_ARM_EABI_VERSION (e_flags);
3082 e_flags &= ~ EF_ARM_EABIMASK;
3083
3084 /* Handle "generic" ARM flags. */
3085 if (e_flags & EF_ARM_RELEXEC)
3086 {
f8c4789c 3087 out = stpcpy (out, ", relocatable executable");
f3485b74
NC
3088 e_flags &= ~ EF_ARM_RELEXEC;
3089 }
76da6bbe 3090
18a20338
CL
3091 if (e_flags & EF_ARM_PIC)
3092 {
f8c4789c 3093 out = stpcpy (out, ", position independent");
18a20338
CL
3094 e_flags &= ~ EF_ARM_PIC;
3095 }
3096
f3485b74
NC
3097 /* Now handle EABI specific flags. */
3098 switch (eabi)
3099 {
3100 default:
f8c4789c 3101 out = stpcpy (out, ", <unrecognized EABI>");
f3485b74 3102 if (e_flags)
015dc7e1 3103 unknown = true;
f3485b74
NC
3104 break;
3105
3106 case EF_ARM_EABI_VER1:
f8c4789c 3107 out = stpcpy (out, ", Version1 EABI");
f3485b74
NC
3108 while (e_flags)
3109 {
3110 unsigned flag;
76da6bbe 3111
f3485b74
NC
3112 /* Process flags one bit at a time. */
3113 flag = e_flags & - e_flags;
3114 e_flags &= ~ flag;
76da6bbe 3115
f3485b74
NC
3116 switch (flag)
3117 {
a5bcd848 3118 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3119 out = stpcpy (out, ", sorted symbol tables");
f3485b74 3120 break;
76da6bbe 3121
f3485b74 3122 default:
015dc7e1 3123 unknown = true;
f3485b74
NC
3124 break;
3125 }
3126 }
3127 break;
76da6bbe 3128
a5bcd848 3129 case EF_ARM_EABI_VER2:
f8c4789c 3130 out = stpcpy (out, ", Version2 EABI");
a5bcd848
PB
3131 while (e_flags)
3132 {
3133 unsigned flag;
3134
3135 /* Process flags one bit at a time. */
3136 flag = e_flags & - e_flags;
3137 e_flags &= ~ flag;
3138
3139 switch (flag)
3140 {
3141 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3142 out = stpcpy (out, ", sorted symbol tables");
a5bcd848
PB
3143 break;
3144
3145 case EF_ARM_DYNSYMSUSESEGIDX:
f8c4789c 3146 out = stpcpy (out, ", dynamic symbols use segment index");
a5bcd848
PB
3147 break;
3148
3149 case EF_ARM_MAPSYMSFIRST:
f8c4789c 3150 out = stpcpy (out, ", mapping symbols precede others");
a5bcd848
PB
3151 break;
3152
3153 default:
015dc7e1 3154 unknown = true;
a5bcd848
PB
3155 break;
3156 }
3157 }
3158 break;
3159
d507cf36 3160 case EF_ARM_EABI_VER3:
f8c4789c 3161 out = stpcpy (out, ", Version3 EABI");
8cb51566
PB
3162 break;
3163
3164 case EF_ARM_EABI_VER4:
f8c4789c 3165 out = stpcpy (out, ", Version4 EABI");
3bfcb652
NC
3166 while (e_flags)
3167 {
3168 unsigned flag;
3169
3170 /* Process flags one bit at a time. */
3171 flag = e_flags & - e_flags;
3172 e_flags &= ~ flag;
3173
3174 switch (flag)
3175 {
3176 case EF_ARM_BE8:
f8c4789c 3177 out = stpcpy (out, ", BE8");
3bfcb652
NC
3178 break;
3179
3180 case EF_ARM_LE8:
f8c4789c 3181 out = stpcpy (out, ", LE8");
3bfcb652
NC
3182 break;
3183
3184 default:
015dc7e1 3185 unknown = true;
3bfcb652
NC
3186 break;
3187 }
3bfcb652
NC
3188 }
3189 break;
3a4a14e9
PB
3190
3191 case EF_ARM_EABI_VER5:
f8c4789c 3192 out = stpcpy (out, ", Version5 EABI");
d507cf36
PB
3193 while (e_flags)
3194 {
3195 unsigned flag;
3196
3197 /* Process flags one bit at a time. */
3198 flag = e_flags & - e_flags;
3199 e_flags &= ~ flag;
3200
3201 switch (flag)
3202 {
3203 case EF_ARM_BE8:
f8c4789c 3204 out = stpcpy (out, ", BE8");
d507cf36
PB
3205 break;
3206
3207 case EF_ARM_LE8:
f8c4789c 3208 out = stpcpy (out, ", LE8");
d507cf36
PB
3209 break;
3210
3bfcb652 3211 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
f8c4789c 3212 out = stpcpy (out, ", soft-float ABI");
3bfcb652
NC
3213 break;
3214
3215 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
f8c4789c 3216 out = stpcpy (out, ", hard-float ABI");
3bfcb652
NC
3217 break;
3218
d507cf36 3219 default:
015dc7e1 3220 unknown = true;
d507cf36
PB
3221 break;
3222 }
3223 }
3224 break;
3225
f3485b74 3226 case EF_ARM_EABI_UNKNOWN:
f8c4789c 3227 out = stpcpy (out, ", GNU EABI");
f3485b74
NC
3228 while (e_flags)
3229 {
3230 unsigned flag;
76da6bbe 3231
f3485b74
NC
3232 /* Process flags one bit at a time. */
3233 flag = e_flags & - e_flags;
3234 e_flags &= ~ flag;
76da6bbe 3235
f3485b74
NC
3236 switch (flag)
3237 {
a5bcd848 3238 case EF_ARM_INTERWORK:
f8c4789c 3239 out = stpcpy (out, ", interworking enabled");
f3485b74 3240 break;
76da6bbe 3241
a5bcd848 3242 case EF_ARM_APCS_26:
f8c4789c 3243 out = stpcpy (out, ", uses APCS/26");
f3485b74 3244 break;
76da6bbe 3245
a5bcd848 3246 case EF_ARM_APCS_FLOAT:
f8c4789c 3247 out = stpcpy (out, ", uses APCS/float");
f3485b74 3248 break;
76da6bbe 3249
a5bcd848 3250 case EF_ARM_PIC:
f8c4789c 3251 out = stpcpy (out, ", position independent");
f3485b74 3252 break;
76da6bbe 3253
a5bcd848 3254 case EF_ARM_ALIGN8:
f8c4789c 3255 out = stpcpy (out, ", 8 bit structure alignment");
f3485b74 3256 break;
76da6bbe 3257
a5bcd848 3258 case EF_ARM_NEW_ABI:
f8c4789c 3259 out = stpcpy (out, ", uses new ABI");
f3485b74 3260 break;
76da6bbe 3261
a5bcd848 3262 case EF_ARM_OLD_ABI:
f8c4789c 3263 out = stpcpy (out, ", uses old ABI");
f3485b74 3264 break;
76da6bbe 3265
a5bcd848 3266 case EF_ARM_SOFT_FLOAT:
f8c4789c 3267 out = stpcpy (out, ", software FP");
f3485b74 3268 break;
76da6bbe 3269
90e01f86 3270 case EF_ARM_VFP_FLOAT:
f8c4789c 3271 out = stpcpy (out, ", VFP");
90e01f86
ILT
3272 break;
3273
fde78edd 3274 case EF_ARM_MAVERICK_FLOAT:
f8c4789c 3275 out = stpcpy (out, ", Maverick FP");
fde78edd
NC
3276 break;
3277
f3485b74 3278 default:
015dc7e1 3279 unknown = true;
f3485b74
NC
3280 break;
3281 }
3282 }
3283 }
f3485b74
NC
3284
3285 if (unknown)
f8c4789c
AM
3286 out = stpcpy (out,_(", <unknown>"));
3287 return out;
f3485b74
NC
3288}
3289
f8c4789c
AM
3290static char *
3291decode_AVR_machine_flags (char *out, unsigned e_flags)
343433df 3292{
343433df
AB
3293 switch (e_flags & EF_AVR_MACH)
3294 {
3295 case E_AVR_MACH_AVR1:
f8c4789c 3296 out = stpcpy (out, ", avr:1");
343433df
AB
3297 break;
3298 case E_AVR_MACH_AVR2:
f8c4789c 3299 out = stpcpy (out, ", avr:2");
343433df
AB
3300 break;
3301 case E_AVR_MACH_AVR25:
f8c4789c 3302 out = stpcpy (out, ", avr:25");
343433df
AB
3303 break;
3304 case E_AVR_MACH_AVR3:
f8c4789c 3305 out = stpcpy (out, ", avr:3");
343433df
AB
3306 break;
3307 case E_AVR_MACH_AVR31:
f8c4789c 3308 out = stpcpy (out, ", avr:31");
343433df
AB
3309 break;
3310 case E_AVR_MACH_AVR35:
f8c4789c 3311 out = stpcpy (out, ", avr:35");
343433df
AB
3312 break;
3313 case E_AVR_MACH_AVR4:
f8c4789c 3314 out = stpcpy (out, ", avr:4");
343433df
AB
3315 break;
3316 case E_AVR_MACH_AVR5:
f8c4789c 3317 out = stpcpy (out, ", avr:5");
343433df
AB
3318 break;
3319 case E_AVR_MACH_AVR51:
f8c4789c 3320 out = stpcpy (out, ", avr:51");
343433df
AB
3321 break;
3322 case E_AVR_MACH_AVR6:
f8c4789c 3323 out = stpcpy (out, ", avr:6");
343433df
AB
3324 break;
3325 case E_AVR_MACH_AVRTINY:
f8c4789c 3326 out = stpcpy (out, ", avr:100");
343433df
AB
3327 break;
3328 case E_AVR_MACH_XMEGA1:
f8c4789c 3329 out = stpcpy (out, ", avr:101");
343433df
AB
3330 break;
3331 case E_AVR_MACH_XMEGA2:
f8c4789c 3332 out = stpcpy (out, ", avr:102");
343433df
AB
3333 break;
3334 case E_AVR_MACH_XMEGA3:
f8c4789c 3335 out = stpcpy (out, ", avr:103");
343433df
AB
3336 break;
3337 case E_AVR_MACH_XMEGA4:
f8c4789c 3338 out = stpcpy (out, ", avr:104");
343433df
AB
3339 break;
3340 case E_AVR_MACH_XMEGA5:
f8c4789c 3341 out = stpcpy (out, ", avr:105");
343433df
AB
3342 break;
3343 case E_AVR_MACH_XMEGA6:
f8c4789c 3344 out = stpcpy (out, ", avr:106");
343433df
AB
3345 break;
3346 case E_AVR_MACH_XMEGA7:
f8c4789c 3347 out = stpcpy (out, ", avr:107");
343433df
AB
3348 break;
3349 default:
f8c4789c 3350 out = stpcpy (out, ", avr:<unknown>");
343433df
AB
3351 break;
3352 }
3353
343433df 3354 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
f8c4789c
AM
3355 out = stpcpy (out, ", link-relax");
3356 return out;
343433df
AB
3357}
3358
f8c4789c
AM
3359static char *
3360decode_BLACKFIN_machine_flags (char *out, unsigned e_flags)
3361{
3362 if (e_flags & EF_BFIN_PIC)
3363 out = stpcpy (out, ", PIC");
3364
3365 if (e_flags & EF_BFIN_FDPIC)
3366 out = stpcpy (out, ", FDPIC");
3367
3368 if (e_flags & EF_BFIN_CODE_IN_L1)
3369 out = stpcpy (out, ", code in L1");
3370
3371 if (e_flags & EF_BFIN_DATA_IN_L1)
3372 out = stpcpy (out, ", data in L1");
3373 return out;
3374}
3375
3376static char *
3377decode_FRV_machine_flags (char *out, unsigned e_flags)
3378{
3379 switch (e_flags & EF_FRV_CPU_MASK)
3380 {
3381 case EF_FRV_CPU_GENERIC:
3382 break;
3383
3384 default:
3385 out = stpcpy (out, ", fr???");
3386 break;
3387
3388 case EF_FRV_CPU_FR300:
3389 out = stpcpy (out, ", fr300");
3390 break;
3391
3392 case EF_FRV_CPU_FR400:
3393 out = stpcpy (out, ", fr400");
3394 break;
3395 case EF_FRV_CPU_FR405:
3396 out = stpcpy (out, ", fr405");
3397 break;
3398
3399 case EF_FRV_CPU_FR450:
3400 out = stpcpy (out, ", fr450");
3401 break;
3402
3403 case EF_FRV_CPU_FR500:
3404 out = stpcpy (out, ", fr500");
3405 break;
3406 case EF_FRV_CPU_FR550:
3407 out = stpcpy (out, ", fr550");
3408 break;
3409
3410 case EF_FRV_CPU_SIMPLE:
3411 out = stpcpy (out, ", simple");
3412 break;
3413 case EF_FRV_CPU_TOMCAT:
3414 out = stpcpy (out, ", tomcat");
3415 break;
3416 }
3417 return out;
3418}
3419
3420static char *
3421decode_IA64_machine_flags (char *out, unsigned e_flags, Filedata *filedata)
3422{
3423 if ((e_flags & EF_IA_64_ABI64))
3424 out = stpcpy (out, ", 64-bit");
3425 else
3426 out = stpcpy (out, ", 32-bit");
3427 if ((e_flags & EF_IA_64_REDUCEDFP))
3428 out = stpcpy (out, ", reduced fp model");
3429 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3430 out = stpcpy (out, ", no function descriptors, constant gp");
3431 else if ((e_flags & EF_IA_64_CONS_GP))
3432 out = stpcpy (out, ", constant gp");
3433 if ((e_flags & EF_IA_64_ABSOLUTE))
3434 out = stpcpy (out, ", absolute");
3435 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3436 {
3437 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3438 out = stpcpy (out, ", vms_linkages");
3439 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3440 {
3441 case EF_IA_64_VMS_COMCOD_SUCCESS:
3442 break;
3443 case EF_IA_64_VMS_COMCOD_WARNING:
3444 out = stpcpy (out, ", warning");
3445 break;
3446 case EF_IA_64_VMS_COMCOD_ERROR:
3447 out = stpcpy (out, ", error");
3448 break;
3449 case EF_IA_64_VMS_COMCOD_ABORT:
3450 out = stpcpy (out, ", abort");
3451 break;
3452 default:
3453 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3454 e_flags & EF_IA_64_VMS_COMCOD);
3455 out = stpcpy (out, ", <unknown>");
3456 }
3457 }
3458 return out;
3459}
3460
3461static char *
3462decode_LOONGARCH_machine_flags (char *out, unsigned int e_flags)
3463{
3464 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
3465 out = stpcpy (out, ", SOFT-FLOAT");
3466 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
3467 out = stpcpy (out, ", SINGLE-FLOAT");
3468 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
3469 out = stpcpy (out, ", DOUBLE-FLOAT");
3470
3471 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
3472 out = stpcpy (out, ", OBJ-v0");
3473 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
3474 out = stpcpy (out, ", OBJ-v1");
3475 return out;
3476}
3477
3478static char *
3479decode_M68K_machine_flags (char *out, unsigned int e_flags)
3480{
3481 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
3482 out = stpcpy (out, ", m68000");
3483 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3484 out = stpcpy (out, ", cpu32");
3485 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3486 out = stpcpy (out, ", fido_a");
3487 else
3488 {
3489 char const *isa = _("unknown");
3490 char const *mac = _("unknown mac");
3491 char const *additional = NULL;
3492
3493 switch (e_flags & EF_M68K_CF_ISA_MASK)
3494 {
3495 case EF_M68K_CF_ISA_A_NODIV:
3496 isa = "A";
3497 additional = ", nodiv";
3498 break;
3499 case EF_M68K_CF_ISA_A:
3500 isa = "A";
3501 break;
3502 case EF_M68K_CF_ISA_A_PLUS:
3503 isa = "A+";
3504 break;
3505 case EF_M68K_CF_ISA_B_NOUSP:
3506 isa = "B";
3507 additional = ", nousp";
3508 break;
3509 case EF_M68K_CF_ISA_B:
3510 isa = "B";
3511 break;
3512 case EF_M68K_CF_ISA_C:
3513 isa = "C";
3514 break;
3515 case EF_M68K_CF_ISA_C_NODIV:
3516 isa = "C";
3517 additional = ", nodiv";
3518 break;
3519 }
3520 out = stpcpy (out, ", cf, isa ");
3521 out = stpcpy (out, isa);
3522 if (additional)
3523 out = stpcpy (out, additional);
3524 if (e_flags & EF_M68K_CF_FLOAT)
3525 out = stpcpy (out, ", float");
3526 switch (e_flags & EF_M68K_CF_MAC_MASK)
3527 {
3528 case 0:
3529 mac = NULL;
3530 break;
3531 case EF_M68K_CF_MAC:
3532 mac = "mac";
3533 break;
3534 case EF_M68K_CF_EMAC:
3535 mac = "emac";
3536 break;
3537 case EF_M68K_CF_EMAC_B:
3538 mac = "emac_b";
3539 break;
3540 }
3541 if (mac)
3542 {
3543 out = stpcpy (out, ", ");
3544 out = stpcpy (out, mac);
3545 }
3546 }
3547 return out;
3548}
3549
3550static char *
3551decode_MeP_machine_flags (char *out, unsigned int e_flags)
3552{
3553 switch (e_flags & EF_MEP_CPU_MASK)
3554 {
3555 case EF_MEP_CPU_MEP:
3556 out = stpcpy (out, ", generic MeP");
3557 break;
3558 case EF_MEP_CPU_C2:
3559 out = stpcpy (out, ", MeP C2");
3560 break;
3561 case EF_MEP_CPU_C3:
3562 out = stpcpy (out, ", MeP C3");
3563 break;
3564 case EF_MEP_CPU_C4:
3565 out = stpcpy (out, ", MeP C4");
3566 break;
3567 case EF_MEP_CPU_C5:
3568 out = stpcpy (out, ", MeP C5");
3569 break;
3570 case EF_MEP_CPU_H1:
3571 out = stpcpy (out, ", MeP H1");
3572 break;
3573 default:
3574 out = stpcpy (out, _(", <unknown MeP cpu type>"));
3575 break;
3576 }
3577
3578 switch (e_flags & EF_MEP_COP_MASK)
3579 {
3580 case EF_MEP_COP_NONE:
3581 break;
3582 case EF_MEP_COP_AVC:
3583 out = stpcpy (out, ", AVC coprocessor");
3584 break;
3585 case EF_MEP_COP_AVC2:
3586 out = stpcpy (out, ", AVC2 coprocessor");
3587 break;
3588 case EF_MEP_COP_FMAX:
3589 out = stpcpy (out, ", FMAX coprocessor");
3590 break;
3591 case EF_MEP_COP_IVC2:
3592 out = stpcpy (out, ", IVC2 coprocessor");
3593 break;
3594 default:
3595 out = stpcpy (out, _("<unknown MeP copro type>"));
3596 break;
3597 }
3598
3599 if (e_flags & EF_MEP_LIBRARY)
3600 out = stpcpy (out, ", Built for Library");
3601
3602 if (e_flags & EF_MEP_INDEX_MASK)
3603 out += sprintf (out, ", Configuration Index: %#x",
3604 e_flags & EF_MEP_INDEX_MASK);
3605
3606 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3607 out += sprintf (out, _(", unknown flags bits: %#x"),
3608 e_flags & ~ EF_MEP_ALL_FLAGS);
3609 return out;
3610}
3611
3612static char *
3613decode_MIPS_machine_flags (char *out, unsigned int e_flags)
3614{
3615 if (e_flags & EF_MIPS_NOREORDER)
3616 out = stpcpy (out, ", noreorder");
3617
3618 if (e_flags & EF_MIPS_PIC)
3619 out = stpcpy (out, ", pic");
3620
3621 if (e_flags & EF_MIPS_CPIC)
3622 out = stpcpy (out, ", cpic");
3623
3624 if (e_flags & EF_MIPS_UCODE)
3625 out = stpcpy (out, ", ugen_reserved");
3626
3627 if (e_flags & EF_MIPS_ABI2)
3628 out = stpcpy (out, ", abi2");
3629
3630 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3631 out = stpcpy (out, ", odk first");
3632
3633 if (e_flags & EF_MIPS_32BITMODE)
3634 out = stpcpy (out, ", 32bitmode");
3635
3636 if (e_flags & EF_MIPS_NAN2008)
3637 out = stpcpy (out, ", nan2008");
3638
3639 if (e_flags & EF_MIPS_FP64)
3640 out = stpcpy (out, ", fp64");
3641
3642 switch ((e_flags & EF_MIPS_MACH))
3643 {
3644 case E_MIPS_MACH_3900:
3645 out = stpcpy (out, ", 3900");
3646 break;
3647 case E_MIPS_MACH_4010:
3648 out = stpcpy (out, ", 4010");
3649 break;
3650 case E_MIPS_MACH_4100:
3651 out = stpcpy (out, ", 4100");
3652 break;
3653 case E_MIPS_MACH_4111:
3654 out = stpcpy (out, ", 4111");
3655 break;
3656 case E_MIPS_MACH_4120:
3657 out = stpcpy (out, ", 4120");
3658 break;
3659 case E_MIPS_MACH_4650:
3660 out = stpcpy (out, ", 4650");
3661 break;
3662 case E_MIPS_MACH_5400:
3663 out = stpcpy (out, ", 5400");
3664 break;
3665 case E_MIPS_MACH_5500:
3666 out = stpcpy (out, ", 5500");
3667 break;
3668 case E_MIPS_MACH_5900:
3669 out = stpcpy (out, ", 5900");
3670 break;
3671 case E_MIPS_MACH_SB1:
3672 out = stpcpy (out, ", sb1");
3673 break;
3674 case E_MIPS_MACH_9000:
3675 out = stpcpy (out, ", 9000");
3676 break;
3677 case E_MIPS_MACH_LS2E:
3678 out = stpcpy (out, ", loongson-2e");
3679 break;
3680 case E_MIPS_MACH_LS2F:
3681 out = stpcpy (out, ", loongson-2f");
3682 break;
3683 case E_MIPS_MACH_GS464:
3684 out = stpcpy (out, ", gs464");
3685 break;
3686 case E_MIPS_MACH_GS464E:
3687 out = stpcpy (out, ", gs464e");
3688 break;
3689 case E_MIPS_MACH_GS264E:
3690 out = stpcpy (out, ", gs264e");
3691 break;
3692 case E_MIPS_MACH_OCTEON:
3693 out = stpcpy (out, ", octeon");
3694 break;
3695 case E_MIPS_MACH_OCTEON2:
3696 out = stpcpy (out, ", octeon2");
3697 break;
3698 case E_MIPS_MACH_OCTEON3:
3699 out = stpcpy (out, ", octeon3");
3700 break;
3701 case E_MIPS_MACH_XLR:
3702 out = stpcpy (out, ", xlr");
3703 break;
3704 case E_MIPS_MACH_IAMR2:
3705 out = stpcpy (out, ", interaptiv-mr2");
3706 break;
3707 case E_MIPS_MACH_ALLEGREX:
3708 out = stpcpy (out, ", allegrex");
3709 break;
3710 case 0:
3711 /* We simply ignore the field in this case to avoid confusion:
3712 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3713 extension. */
3714 break;
3715 default:
3716 out = stpcpy (out, _(", unknown CPU"));
3717 break;
3718 }
3719
3720 switch ((e_flags & EF_MIPS_ABI))
3721 {
3722 case E_MIPS_ABI_O32:
3723 out = stpcpy (out, ", o32");
3724 break;
3725 case E_MIPS_ABI_O64:
3726 out = stpcpy (out, ", o64");
3727 break;
3728 case E_MIPS_ABI_EABI32:
3729 out = stpcpy (out, ", eabi32");
3730 break;
3731 case E_MIPS_ABI_EABI64:
3732 out = stpcpy (out, ", eabi64");
3733 break;
3734 case 0:
3735 /* We simply ignore the field in this case to avoid confusion:
3736 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3737 This means it is likely to be an o32 file, but not for
3738 sure. */
3739 break;
3740 default:
3741 out = stpcpy (out, _(", unknown ABI"));
3742 break;
3743 }
3744
3745 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3746 out = stpcpy (out, ", mdmx");
3747
3748 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3749 out = stpcpy (out, ", mips16");
3750
3751 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3752 out = stpcpy (out, ", micromips");
3753
3754 switch ((e_flags & EF_MIPS_ARCH))
3755 {
3756 case E_MIPS_ARCH_1:
3757 out = stpcpy (out, ", mips1");
3758 break;
3759 case E_MIPS_ARCH_2:
3760 out = stpcpy (out, ", mips2");
3761 break;
3762 case E_MIPS_ARCH_3:
3763 out = stpcpy (out, ", mips3");
3764 break;
3765 case E_MIPS_ARCH_4:
3766 out = stpcpy (out, ", mips4");
3767 break;
3768 case E_MIPS_ARCH_5:
3769 out = stpcpy (out, ", mips5");
3770 break;
3771 case E_MIPS_ARCH_32:
3772 out = stpcpy (out, ", mips32");
3773 break;
3774 case E_MIPS_ARCH_32R2:
3775 out = stpcpy (out, ", mips32r2");
3776 break;
3777 case E_MIPS_ARCH_32R6:
3778 out = stpcpy (out, ", mips32r6");
3779 break;
3780 case E_MIPS_ARCH_64:
3781 out = stpcpy (out, ", mips64");
3782 break;
3783 case E_MIPS_ARCH_64R2:
3784 out = stpcpy (out, ", mips64r2");
3785 break;
3786 case E_MIPS_ARCH_64R6:
3787 out = stpcpy (out, ", mips64r6");
3788 break;
3789 default:
3790 out = stpcpy (out, _(", unknown ISA"));
3791 break;
3792 }
3793 return out;
3794}
3795
3796static char *
3797decode_MSP430_machine_flags (char *out, unsigned e_flags)
3798{
3799 out = stpcpy (out, _(": architecture variant: "));
3800 switch (e_flags & EF_MSP430_MACH)
3801 {
3802 case E_MSP430_MACH_MSP430x11:
3803 out = stpcpy (out, "MSP430x11");
3804 break;
3805 case E_MSP430_MACH_MSP430x11x1:
3806 out = stpcpy (out, "MSP430x11x1 ");
3807 break;
3808 case E_MSP430_MACH_MSP430x12:
3809 out = stpcpy (out, "MSP430x12");
3810 break;
3811 case E_MSP430_MACH_MSP430x13:
3812 out = stpcpy (out, "MSP430x13");
3813 break;
3814 case E_MSP430_MACH_MSP430x14:
3815 out = stpcpy (out, "MSP430x14");
3816 break;
3817 case E_MSP430_MACH_MSP430x15:
3818 out = stpcpy (out, "MSP430x15");
3819 break;
3820 case E_MSP430_MACH_MSP430x16:
3821 out = stpcpy (out, "MSP430x16");
3822 break;
3823 case E_MSP430_MACH_MSP430x31:
3824 out = stpcpy (out, "MSP430x31");
3825 break;
3826 case E_MSP430_MACH_MSP430x32:
3827 out = stpcpy (out, "MSP430x32");
3828 break;
3829 case E_MSP430_MACH_MSP430x33:
3830 out = stpcpy (out, "MSP430x33");
3831 break;
3832 case E_MSP430_MACH_MSP430x41:
3833 out = stpcpy (out, "MSP430x41");
3834 break;
3835 case E_MSP430_MACH_MSP430x42:
3836 out = stpcpy (out, "MSP430x42");
3837 break;
3838 case E_MSP430_MACH_MSP430x43:
3839 out = stpcpy (out, "MSP430x43");
3840 break;
3841 case E_MSP430_MACH_MSP430x44:
3842 out = stpcpy (out, "MSP430x44");
3843 break;
3844 case E_MSP430_MACH_MSP430X :
3845 out = stpcpy (out, "MSP430X");
3846 break;
3847 default:
3848 out = stpcpy (out, _(": unknown"));
3849 break;
3850 }
3851
3852 if (e_flags & ~ EF_MSP430_MACH)
3853 out = stpcpy (out, _(": unknown extra flag bits also present"));
3854 return out;
3855}
3856
3857static char *
3858decode_NDS32_machine_flags (char *out, unsigned e_flags)
35c08157
KLC
3859{
3860 unsigned abi;
3861 unsigned arch;
3862 unsigned config;
3863 unsigned version;
015dc7e1 3864 bool has_fpu = false;
35c08157
KLC
3865
3866 static const char *ABI_STRINGS[] =
3867 {
3868 "ABI v0", /* use r5 as return register; only used in N1213HC */
3869 "ABI v1", /* use r0 as return register */
3870 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3871 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3872 "AABI",
3873 "ABI2 FP+"
35c08157
KLC
3874 };
3875 static const char *VER_STRINGS[] =
3876 {
3877 "Andes ELF V1.3 or older",
3878 "Andes ELF V1.3.1",
3879 "Andes ELF V1.4"
3880 };
3881 static const char *ARCH_STRINGS[] =
3882 {
3883 "",
3884 "Andes Star v1.0",
3885 "Andes Star v2.0",
3886 "Andes Star v3.0",
3887 "Andes Star v3.0m"
3888 };
3889
3890 abi = EF_NDS_ABI & e_flags;
3891 arch = EF_NDS_ARCH & e_flags;
3892 config = EF_NDS_INST & e_flags;
3893 version = EF_NDS32_ELF_VERSION & e_flags;
3894
35c08157
KLC
3895 switch (abi)
3896 {
3897 case E_NDS_ABI_V0:
3898 case E_NDS_ABI_V1:
3899 case E_NDS_ABI_V2:
3900 case E_NDS_ABI_V2FP:
3901 case E_NDS_ABI_AABI:
40c7a7cb 3902 case E_NDS_ABI_V2FP_PLUS:
35c08157 3903 /* In case there are holes in the array. */
f8c4789c 3904 out += sprintf (out, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
35c08157
KLC
3905 break;
3906
3907 default:
f8c4789c 3908 out = stpcpy (out, ", <unrecognized ABI>");
35c08157
KLC
3909 break;
3910 }
3911
3912 switch (version)
3913 {
3914 case E_NDS32_ELF_VER_1_2:
3915 case E_NDS32_ELF_VER_1_3:
3916 case E_NDS32_ELF_VER_1_4:
f8c4789c 3917 out += sprintf (out, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
35c08157
KLC
3918 break;
3919
3920 default:
f8c4789c 3921 out = stpcpy (out, ", <unrecognized ELF version number>");
35c08157
KLC
3922 break;
3923 }
3924
3925 if (E_NDS_ABI_V0 == abi)
3926 {
3927 /* OLD ABI; only used in N1213HC, has performance extension 1. */
f8c4789c 3928 out = stpcpy (out, ", Andes Star v1.0, N1213HC, MAC, PERF1");
35c08157 3929 if (arch == E_NDS_ARCH_STAR_V1_0)
f8c4789c
AM
3930 out = stpcpy (out, ", 16b"); /* has 16-bit instructions */
3931 return out;
35c08157
KLC
3932 }
3933
3934 switch (arch)
3935 {
3936 case E_NDS_ARCH_STAR_V1_0:
3937 case E_NDS_ARCH_STAR_V2_0:
3938 case E_NDS_ARCH_STAR_V3_0:
3939 case E_NDS_ARCH_STAR_V3_M:
f8c4789c 3940 out += sprintf (out, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
35c08157
KLC
3941 break;
3942
3943 default:
f8c4789c 3944 out = stpcpy (out, ", <unrecognized architecture>");
35c08157
KLC
3945 /* ARCH version determines how the e_flags are interpreted.
3946 If it is unknown, we cannot proceed. */
f8c4789c 3947 return out;
35c08157
KLC
3948 }
3949
3950 /* Newer ABI; Now handle architecture specific flags. */
3951 if (arch == E_NDS_ARCH_STAR_V1_0)
3952 {
3953 if (config & E_NDS32_HAS_MFUSR_PC_INST)
f8c4789c 3954 out = stpcpy (out, ", MFUSR_PC");
35c08157
KLC
3955
3956 if (!(config & E_NDS32_HAS_NO_MAC_INST))
f8c4789c 3957 out = stpcpy (out, ", MAC");
35c08157
KLC
3958
3959 if (config & E_NDS32_HAS_DIV_INST)
f8c4789c 3960 out = stpcpy (out, ", DIV");
35c08157
KLC
3961
3962 if (config & E_NDS32_HAS_16BIT_INST)
f8c4789c 3963 out = stpcpy (out, ", 16b");
35c08157
KLC
3964 }
3965 else
3966 {
3967 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3968 {
3969 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 3970 out = stpcpy (out, ", [B8]");
35c08157 3971 else
f8c4789c 3972 out = stpcpy (out, ", EX9");
35c08157
KLC
3973 }
3974
3975 if (config & E_NDS32_HAS_MAC_DX_INST)
f8c4789c 3976 out = stpcpy (out, ", MAC_DX");
35c08157
KLC
3977
3978 if (config & E_NDS32_HAS_DIV_DX_INST)
f8c4789c 3979 out = stpcpy (out, ", DIV_DX");
35c08157
KLC
3980
3981 if (config & E_NDS32_HAS_16BIT_INST)
3982 {
3983 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 3984 out = stpcpy (out, ", 16b");
35c08157 3985 else
f8c4789c 3986 out = stpcpy (out, ", IFC");
35c08157
KLC
3987 }
3988 }
3989
3990 if (config & E_NDS32_HAS_EXT_INST)
f8c4789c 3991 out = stpcpy (out, ", PERF1");
35c08157
KLC
3992
3993 if (config & E_NDS32_HAS_EXT2_INST)
f8c4789c 3994 out = stpcpy (out, ", PERF2");
35c08157
KLC
3995
3996 if (config & E_NDS32_HAS_FPU_INST)
3997 {
015dc7e1 3998 has_fpu = true;
f8c4789c 3999 out = stpcpy (out, ", FPU_SP");
35c08157
KLC
4000 }
4001
4002 if (config & E_NDS32_HAS_FPU_DP_INST)
4003 {
015dc7e1 4004 has_fpu = true;
f8c4789c 4005 out = stpcpy (out, ", FPU_DP");
35c08157
KLC
4006 }
4007
4008 if (config & E_NDS32_HAS_FPU_MAC_INST)
4009 {
015dc7e1 4010 has_fpu = true;
f8c4789c 4011 out = stpcpy (out, ", FPU_MAC");
35c08157
KLC
4012 }
4013
4014 if (has_fpu)
4015 {
4016 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
4017 {
4018 case E_NDS32_FPU_REG_8SP_4DP:
f8c4789c 4019 out = stpcpy (out, ", FPU_REG:8/4");
35c08157
KLC
4020 break;
4021 case E_NDS32_FPU_REG_16SP_8DP:
f8c4789c 4022 out = stpcpy (out, ", FPU_REG:16/8");
35c08157
KLC
4023 break;
4024 case E_NDS32_FPU_REG_32SP_16DP:
f8c4789c 4025 out = stpcpy (out, ", FPU_REG:32/16");
35c08157
KLC
4026 break;
4027 case E_NDS32_FPU_REG_32SP_32DP:
f8c4789c 4028 out = stpcpy (out, ", FPU_REG:32/32");
35c08157
KLC
4029 break;
4030 }
4031 }
4032
4033 if (config & E_NDS32_HAS_AUDIO_INST)
f8c4789c 4034 out = stpcpy (out, ", AUDIO");
35c08157
KLC
4035
4036 if (config & E_NDS32_HAS_STRING_INST)
f8c4789c 4037 out = stpcpy (out, ", STR");
35c08157
KLC
4038
4039 if (config & E_NDS32_HAS_REDUCED_REGS)
f8c4789c 4040 out = stpcpy (out, ", 16REG");
35c08157
KLC
4041
4042 if (config & E_NDS32_HAS_VIDEO_INST)
4043 {
4044 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4045 out = stpcpy (out, ", VIDEO");
35c08157 4046 else
f8c4789c 4047 out = stpcpy (out, ", SATURATION");
35c08157
KLC
4048 }
4049
4050 if (config & E_NDS32_HAS_ENCRIPT_INST)
f8c4789c 4051 out = stpcpy (out, ", ENCRP");
35c08157
KLC
4052
4053 if (config & E_NDS32_HAS_L2C_INST)
f8c4789c
AM
4054 out = stpcpy (out, ", L2C");
4055
4056 return out;
35c08157
KLC
4057}
4058
f8c4789c
AM
4059static char *
4060decode_PARISC_machine_flags (char *out, unsigned e_flags)
4061{
4062 switch (e_flags & EF_PARISC_ARCH)
4063 {
4064 case EFA_PARISC_1_0:
4065 out = stpcpy (out, ", PA-RISC 1.0");
4066 break;
4067 case EFA_PARISC_1_1:
4068 out = stpcpy (out, ", PA-RISC 1.1");
4069 break;
4070 case EFA_PARISC_2_0:
4071 out = stpcpy (out, ", PA-RISC 2.0");
4072 break;
4073 default:
4074 break;
4075 }
4076 if (e_flags & EF_PARISC_TRAPNIL)
4077 out = stpcpy (out, ", trapnil");
4078 if (e_flags & EF_PARISC_EXT)
4079 out = stpcpy (out, ", ext");
4080 if (e_flags & EF_PARISC_LSB)
4081 out = stpcpy (out, ", lsb");
4082 if (e_flags & EF_PARISC_WIDE)
4083 out = stpcpy (out, ", wide");
4084 if (e_flags & EF_PARISC_NO_KABP)
4085 out = stpcpy (out, ", no kabp");
4086 if (e_flags & EF_PARISC_LAZYSWAP)
4087 out = stpcpy (out, ", lazyswap");
4088 return out;
4089}
4090
4091static char *
4092decode_RISCV_machine_flags (char *out, unsigned e_flags)
4093{
4094 if (e_flags & EF_RISCV_RVC)
4095 out = stpcpy (out, ", RVC");
4096
4097 if (e_flags & EF_RISCV_RVE)
4098 out = stpcpy (out, ", RVE");
4099
4100 if (e_flags & EF_RISCV_TSO)
4101 out = stpcpy (out, ", TSO");
4102
4103 switch (e_flags & EF_RISCV_FLOAT_ABI)
4104 {
4105 case EF_RISCV_FLOAT_ABI_SOFT:
4106 out = stpcpy (out, ", soft-float ABI");
4107 break;
4108
4109 case EF_RISCV_FLOAT_ABI_SINGLE:
4110 out = stpcpy (out, ", single-float ABI");
4111 break;
4112
4113 case EF_RISCV_FLOAT_ABI_DOUBLE:
4114 out = stpcpy (out, ", double-float ABI");
4115 break;
4116
4117 case EF_RISCV_FLOAT_ABI_QUAD:
4118 out = stpcpy (out, ", quad-float ABI");
4119 break;
4120 }
4121 return out;
4122}
4123
4124static char *
4125decode_RL78_machine_flags (char *out, unsigned e_flags)
4126{
4127 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4128 {
4129 case E_FLAG_RL78_ANY_CPU:
4130 break;
4131 case E_FLAG_RL78_G10:
4132 out = stpcpy (out, ", G10");
4133 break;
4134 case E_FLAG_RL78_G13:
4135 out = stpcpy (out, ", G13");
4136 break;
4137 case E_FLAG_RL78_G14:
4138 out = stpcpy (out, ", G14");
4139 break;
4140 }
4141 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4142 out = stpcpy (out, ", 64-bit doubles");
4143 return out;
4144}
4145
4146static char *
4147decode_RX_machine_flags (char *out, unsigned e_flags)
4148{
4149 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4150 out = stpcpy (out, ", 64-bit doubles");
4151 if (e_flags & E_FLAG_RX_DSP)
4152 out = stpcpy (out, ", dsp");
4153 if (e_flags & E_FLAG_RX_PID)
4154 out = stpcpy (out, ", pid");
4155 if (e_flags & E_FLAG_RX_ABI)
4156 out = stpcpy (out, ", RX ABI");
4157 if (e_flags & E_FLAG_RX_SINSNS_SET)
4158 out = stpcpy (out, (e_flags & E_FLAG_RX_SINSNS_YES
4159 ? ", uses String instructions"
4160 : ", bans String instructions"));
4161 if (e_flags & E_FLAG_RX_V2)
4162 out = stpcpy (out, ", V2");
4163 if (e_flags & E_FLAG_RX_V3)
4164 out = stpcpy (out, ", V3");
4165 return out;
4166}
4167
4168static char *
4169decode_SH_machine_flags (char *out, unsigned e_flags)
4170{
4171 switch ((e_flags & EF_SH_MACH_MASK))
4172 {
4173 case EF_SH1:
4174 out = stpcpy (out, ", sh1");
4175 break;
4176 case EF_SH2:
4177 out = stpcpy (out, ", sh2");
4178 break;
4179 case EF_SH3:
4180 out = stpcpy (out, ", sh3");
4181 break;
4182 case EF_SH_DSP:
4183 out = stpcpy (out, ", sh-dsp");
4184 break;
4185 case EF_SH3_DSP:
4186 out = stpcpy (out, ", sh3-dsp");
4187 break;
4188 case EF_SH4AL_DSP:
4189 out = stpcpy (out, ", sh4al-dsp");
4190 break;
4191 case EF_SH3E:
4192 out = stpcpy (out, ", sh3e");
4193 break;
4194 case EF_SH4:
4195 out = stpcpy (out, ", sh4");
4196 break;
4197 case EF_SH5:
4198 out = stpcpy (out, ", sh5");
4199 break;
4200 case EF_SH2E:
4201 out = stpcpy (out, ", sh2e");
4202 break;
4203 case EF_SH4A:
4204 out = stpcpy (out, ", sh4a");
4205 break;
4206 case EF_SH2A:
4207 out = stpcpy (out, ", sh2a");
4208 break;
4209 case EF_SH4_NOFPU:
4210 out = stpcpy (out, ", sh4-nofpu");
4211 break;
4212 case EF_SH4A_NOFPU:
4213 out = stpcpy (out, ", sh4a-nofpu");
4214 break;
4215 case EF_SH2A_NOFPU:
4216 out = stpcpy (out, ", sh2a-nofpu");
4217 break;
4218 case EF_SH3_NOMMU:
4219 out = stpcpy (out, ", sh3-nommu");
4220 break;
4221 case EF_SH4_NOMMU_NOFPU:
4222 out = stpcpy (out, ", sh4-nommu-nofpu");
4223 break;
4224 case EF_SH2A_SH4_NOFPU:
4225 out = stpcpy (out, ", sh2a-nofpu-or-sh4-nommu-nofpu");
4226 break;
4227 case EF_SH2A_SH3_NOFPU:
4228 out = stpcpy (out, ", sh2a-nofpu-or-sh3-nommu");
4229 break;
4230 case EF_SH2A_SH4:
4231 out = stpcpy (out, ", sh2a-or-sh4");
4232 break;
4233 case EF_SH2A_SH3E:
4234 out = stpcpy (out, ", sh2a-or-sh3e");
4235 break;
4236 default:
4237 out = stpcpy (out, _(", unknown ISA"));
4238 break;
4239 }
4240
4241 if (e_flags & EF_SH_PIC)
4242 out = stpcpy (out, ", pic");
4243
4244 if (e_flags & EF_SH_FDPIC)
4245 out = stpcpy (out, ", fdpic");
4246 return out;
4247}
4248
4249static char *
4250decode_SPARC_machine_flags (char *out, unsigned e_flags)
4251{
4252 if (e_flags & EF_SPARC_32PLUS)
4253 out = stpcpy (out, ", v8+");
4254
4255 if (e_flags & EF_SPARC_SUN_US1)
4256 out = stpcpy (out, ", ultrasparcI");
4257
4258 if (e_flags & EF_SPARC_SUN_US3)
4259 out = stpcpy (out, ", ultrasparcIII");
4260
4261 if (e_flags & EF_SPARC_HAL_R1)
4262 out = stpcpy (out, ", halr1");
4263
4264 if (e_flags & EF_SPARC_LEDATA)
4265 out = stpcpy (out, ", ledata");
4266
4267 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4268 out = stpcpy (out, ", tso");
4269
4270 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4271 out = stpcpy (out, ", pso");
4272
4273 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4274 out = stpcpy (out, ", rmo");
4275 return out;
4276}
4277
4278static char *
4279decode_V800_machine_flags (char *out, unsigned int e_flags)
4280{
4281 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
4282 out = stpcpy (out, ", RH850 ABI");
4283
4284 if (e_flags & EF_V800_850E3)
4285 out = stpcpy (out, ", V3 architecture");
4286
4287 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
4288 out = stpcpy (out, ", FPU not used");
4289
4290 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
4291 out = stpcpy (out, ", regmode: COMMON");
4292
4293 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
4294 out = stpcpy (out, ", r4 not used");
4295
4296 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
4297 out = stpcpy (out, ", r30 not used");
4298
4299 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
4300 out = stpcpy (out, ", r5 not used");
4301
4302 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
4303 out = stpcpy (out, ", r2 not used");
4304
4305 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
4306 {
4307 switch (e_flags & - e_flags)
4308 {
4309 case EF_RH850_FPU_DOUBLE:
4310 out = stpcpy (out, ", double precision FPU");
4311 break;
4312 case EF_RH850_FPU_SINGLE:
4313 out = stpcpy (out, ", single precision FPU");
4314 break;
4315 case EF_RH850_REGMODE22:
4316 out = stpcpy (out, ", regmode:22");
4317 break;
4318 case EF_RH850_REGMODE32:
4319 out = stpcpy (out, ", regmode:23");
4320 break;
4321 case EF_RH850_GP_FIX:
4322 out = stpcpy (out, ", r4 fixed");
4323 break;
4324 case EF_RH850_GP_NOFIX:
4325 out = stpcpy (out, ", r4 free");
4326 break;
4327 case EF_RH850_EP_FIX:
4328 out = stpcpy (out, ", r30 fixed");
4329 break;
4330 case EF_RH850_EP_NOFIX:
4331 out = stpcpy (out, ", r30 free");
4332 break;
4333 case EF_RH850_TP_FIX:
4334 out = stpcpy (out, ", r5 fixed");
4335 break;
4336 case EF_RH850_TP_NOFIX:
4337 out = stpcpy (out, ", r5 free");
4338 break;
4339 case EF_RH850_REG2_RESERVE:
4340 out = stpcpy (out, ", r2 fixed");
4341 break;
4342 case EF_RH850_REG2_NORESERVE:
4343 out = stpcpy (out, ", r2 free");
4344 break;
4345 default:
4346 break;
4347 }
4348 }
4349 return out;
4350}
4351
4352static char *
4353decode_V850_machine_flags (char *out, unsigned int e_flags)
4354{
4355 switch (e_flags & EF_V850_ARCH)
4356 {
4357 case E_V850E3V5_ARCH:
4358 out = stpcpy (out, ", v850e3v5");
4359 break;
4360 case E_V850E2V3_ARCH:
4361 out = stpcpy (out, ", v850e2v3");
4362 break;
4363 case E_V850E2_ARCH:
4364 out = stpcpy (out, ", v850e2");
4365 break;
4366 case E_V850E1_ARCH:
4367 out = stpcpy (out, ", v850e1");
4368 break;
4369 case E_V850E_ARCH:
4370 out = stpcpy (out, ", v850e");
4371 break;
4372 case E_V850_ARCH:
4373 out = stpcpy (out, ", v850");
4374 break;
4375 default:
4376 out = stpcpy (out, _(", unknown v850 architecture variant"));
4377 break;
4378 }
4379 return out;
4380}
4381
4382static char *
4383decode_Z80_machine_flags (char *out, unsigned int e_flags)
4384{
4385 switch (e_flags & EF_Z80_MACH_MSK)
4386 {
4387 case EF_Z80_MACH_Z80:
4388 out = stpcpy (out, ", Z80");
4389 break;
4390 case EF_Z80_MACH_Z180:
4391 out = stpcpy (out, ", Z180");
4392 break;
4393 case EF_Z80_MACH_R800:
4394 out = stpcpy (out, ", R800");
4395 break;
4396 case EF_Z80_MACH_EZ80_Z80:
4397 out = stpcpy (out, ", EZ80");
4398 break;
4399 case EF_Z80_MACH_EZ80_ADL:
4400 out = stpcpy (out, ", EZ80, ADL");
4401 break;
4402 case EF_Z80_MACH_GBZ80:
4403 out = stpcpy (out, ", GBZ80");
4404 break;
4405 case EF_Z80_MACH_Z80N:
4406 out = stpcpy (out, ", Z80N");
4407 break;
4408 default:
4409 out = stpcpy (out, _(", unknown"));
4410 break;
4411 }
4412 return out;
4413}
4414
4415static char *
4416decode_AMDGPU_machine_flags (char *out, unsigned int e_flags, Filedata *filedata)
c077c580
SM
4417{
4418 unsigned char *e_ident = filedata->file_header.e_ident;
4419 unsigned char osabi = e_ident[EI_OSABI];
4420 unsigned char abiversion = e_ident[EI_ABIVERSION];
4421 unsigned int mach;
4422
4423 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
4424 it has been deprecated for a while.
4425
4426 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
4427 of writing, they use the same flags as HSA v3, so the code below uses that
4428 assumption. */
4429 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
f8c4789c 4430 return out;
c077c580
SM
4431
4432 mach = e_flags & EF_AMDGPU_MACH;
4433 switch (mach)
4434 {
4435#define AMDGPU_CASE(code, string) \
f8c4789c 4436 case code: out = stpcpy (out, ", " string); break;
c077c580
SM
4437 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
4438 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
4439 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
4440 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
4441 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
4442 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
4443 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
4444 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
4445 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
4446 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
4447 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
4448 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
4449 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
4450 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
4451 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
4452 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
4453 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
4454 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
4455 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
4456 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
4457 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
4458 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
4459 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
4460 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
4461 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
4462 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
4463 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
4464 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
4465 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
4466 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
4467 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
4468 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
4469 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
4470 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
4471 default:
f8c4789c 4472 out += sprintf (out, _(", <unknown AMDGPU GPU type: %#x>"), mach);
c077c580
SM
4473 break;
4474#undef AMDGPU_CASE
4475 }
4476
c077c580
SM
4477 e_flags &= ~EF_AMDGPU_MACH;
4478
4479 if ((osabi == ELFOSABI_AMDGPU_HSA
4480 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
4481 || osabi != ELFOSABI_AMDGPU_HSA)
4482 {
4483 /* For HSA v3 and other OS ABIs. */
4484 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
4485 {
f8c4789c 4486 out = stpcpy (out, ", xnack on");
c077c580
SM
4487 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
4488 }
4489
4490 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
4491 {
f8c4789c 4492 out = stpcpy (out, ", sramecc on");
c077c580
SM
4493 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
4494 }
4495 }
4496 else
4497 {
4498 /* For HSA v4+. */
4499 int xnack, sramecc;
4500
4501 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
4502 switch (xnack)
4503 {
4504 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
4505 break;
4506
4507 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
f8c4789c 4508 out = stpcpy (out, ", xnack any");
c077c580
SM
4509 break;
4510
4511 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
f8c4789c 4512 out = stpcpy (out, ", xnack off");
c077c580
SM
4513 break;
4514
4515 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
f8c4789c 4516 out = stpcpy (out, ", xnack on");
c077c580
SM
4517 break;
4518
4519 default:
f8c4789c 4520 out += sprintf (out, _(", <unknown xnack value: %#x>"), xnack);
c077c580
SM
4521 break;
4522 }
4523
c077c580
SM
4524 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
4525
4526 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
4527 switch (sramecc)
4528 {
4529 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
4530 break;
4531
4532 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
f8c4789c 4533 out = stpcpy (out, ", sramecc any");
c077c580
SM
4534 break;
4535
4536 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
f8c4789c 4537 out = stpcpy (out, ", sramecc off");
c077c580
SM
4538 break;
4539
4540 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
f8c4789c 4541 out = stpcpy (out, ", sramecc on");
c077c580
SM
4542 break;
4543
4544 default:
f8c4789c 4545 out += sprintf (out, _(", <unknown sramecc value: %#x>"), sramecc);
c077c580
SM
4546 break;
4547 }
4548
c077c580
SM
4549 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
4550 }
4551
4552 if (e_flags != 0)
f8c4789c
AM
4553 out += sprintf (out, _(", unknown flags bits: %#x"), e_flags);
4554 return out;
c077c580
SM
4555}
4556
252b5132 4557static char *
dda8d76d 4558get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 4559{
b34976b6 4560 static char buf[1024];
f8c4789c 4561 char *out = buf;
252b5132
RH
4562
4563 buf[0] = '\0';
76da6bbe 4564
252b5132
RH
4565 if (e_flags)
4566 {
4567 switch (e_machine)
4568 {
4569 default:
4570 break;
4571
b5c37946 4572 case EM_ARC_COMPACT3:
f8c4789c 4573 out = stpcpy (out, ", HS5x");
b5c37946
SJ
4574 break;
4575
4576 case EM_ARC_COMPACT3_64:
f8c4789c 4577 out = stpcpy (out, ", HS6x");
b5c37946
SJ
4578 break;
4579
886a2506 4580 case EM_ARC_COMPACT2:
886a2506 4581 case EM_ARC_COMPACT:
f8c4789c
AM
4582 out = decode_ARC_machine_flags (out, e_flags, e_machine);
4583 break;
886a2506 4584
f3485b74 4585 case EM_ARM:
f8c4789c 4586 out = decode_ARM_machine_flags (out, e_flags);
f3485b74 4587 break;
76da6bbe 4588
f8c4789c
AM
4589 case EM_AVR:
4590 out = decode_AVR_machine_flags (out, e_flags);
4591 break;
343433df 4592
781303ce 4593 case EM_BLACKFIN:
f8c4789c 4594 out = decode_BLACKFIN_machine_flags (out, e_flags);
781303ce
MF
4595 break;
4596
ec2dfb42 4597 case EM_CYGNUS_FRV:
f8c4789c 4598 out = decode_FRV_machine_flags (out, e_flags);
1c877e87 4599 break;
ec2dfb42 4600
53c7db4b 4601 case EM_68K:
f8c4789c 4602 out = decode_M68K_machine_flags (out, e_flags);
53c7db4b 4603 break;
33c63f9d 4604
c077c580 4605 case EM_AMDGPU:
f8c4789c 4606 out = decode_AMDGPU_machine_flags (out, e_flags, filedata);
c077c580
SM
4607 break;
4608
153a2776 4609 case EM_CYGNUS_MEP:
f8c4789c 4610 out = decode_MeP_machine_flags (out, e_flags);
153a2776
NC
4611 break;
4612
252b5132
RH
4613 case EM_PPC:
4614 if (e_flags & EF_PPC_EMB)
f8c4789c 4615 out = stpcpy (out, ", emb");
252b5132
RH
4616
4617 if (e_flags & EF_PPC_RELOCATABLE)
f8c4789c 4618 out = stpcpy (out, _(", relocatable"));
252b5132
RH
4619
4620 if (e_flags & EF_PPC_RELOCATABLE_LIB)
f8c4789c 4621 out = stpcpy (out, _(", relocatable-lib"));
252b5132
RH
4622 break;
4623
ee67d69a
AM
4624 case EM_PPC64:
4625 if (e_flags & EF_PPC64_ABI)
f8c4789c 4626 out += sprintf (out, ", abiv%d", e_flags & EF_PPC64_ABI);
ee67d69a
AM
4627 break;
4628
708e2187 4629 case EM_V800:
f8c4789c 4630 out = decode_V800_machine_flags (out, e_flags);
708e2187
NC
4631 break;
4632
2b0337b0 4633 case EM_V850:
252b5132 4634 case EM_CYGNUS_V850:
f8c4789c 4635 out = decode_V850_machine_flags (out, e_flags);
252b5132
RH
4636 break;
4637
2b0337b0 4638 case EM_M32R:
252b5132
RH
4639 case EM_CYGNUS_M32R:
4640 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
f8c4789c 4641 out = stpcpy (out, ", m32r");
252b5132
RH
4642 break;
4643
4644 case EM_MIPS:
4fe85591 4645 case EM_MIPS_RS3_LE:
f8c4789c 4646 out = decode_MIPS_machine_flags (out, e_flags);
252b5132 4647 break;
351b4b40 4648
35c08157 4649 case EM_NDS32:
f8c4789c 4650 out = decode_NDS32_machine_flags (out, e_flags);
35c08157
KLC
4651 break;
4652
fe944acf
FT
4653 case EM_NFP:
4654 switch (EF_NFP_MACH (e_flags))
4655 {
4656 case E_NFP_MACH_3200:
f8c4789c 4657 out = stpcpy (out, ", NFP-32xx");
fe944acf
FT
4658 break;
4659 case E_NFP_MACH_6000:
f8c4789c 4660 out = stpcpy (out, ", NFP-6xxx");
fe944acf
FT
4661 break;
4662 }
4663 break;
4664
e23eba97 4665 case EM_RISCV:
f8c4789c 4666 out = decode_RISCV_machine_flags (out, e_flags);
e23eba97
NC
4667 break;
4668
ccde1100 4669 case EM_SH:
f8c4789c 4670 out = decode_SH_machine_flags (out, e_flags);
ccde1100 4671 break;
948f632f 4672
f8c4789c
AM
4673 case EM_OR1K:
4674 if (e_flags & EF_OR1K_NODELAY)
4675 out = stpcpy (out, ", no delay");
4676 break;
57346661 4677
f8c4789c
AM
4678 case EM_BPF:
4679 out += sprintf (out, ", CPU Version: %u", e_flags & EF_BPF_CPUVER);
4680 break;
b5c37946 4681
351b4b40 4682 case EM_SPARCV9:
f8c4789c 4683 out = decode_SPARC_machine_flags (out, e_flags);
351b4b40 4684 break;
7d466069 4685
103f02d3 4686 case EM_PARISC:
f8c4789c 4687 out = decode_PARISC_machine_flags (out, e_flags);
30800947 4688 break;
76da6bbe 4689
7d466069 4690 case EM_PJ:
2b0337b0 4691 case EM_PJ_OLD:
7d466069 4692 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
f8c4789c 4693 out = stpcpy (out, ", new calling convention");
7d466069
ILT
4694
4695 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
f8c4789c 4696 out = stpcpy (out, ", gnu calling convention");
7d466069 4697 break;
4d6ed7c8
NC
4698
4699 case EM_IA_64:
f8c4789c 4700 out = decode_IA64_machine_flags (out, e_flags, filedata);
4d6ed7c8 4701 break;
179d3252
JT
4702
4703 case EM_VAX:
4704 if ((e_flags & EF_VAX_NONPIC))
f8c4789c 4705 out = stpcpy (out, ", non-PIC");
179d3252 4706 if ((e_flags & EF_VAX_DFLOAT))
f8c4789c 4707 out = stpcpy (out, ", D-Float");
179d3252 4708 if ((e_flags & EF_VAX_GFLOAT))
f8c4789c 4709 out = stpcpy (out, ", G-Float");
179d3252 4710 break;
c7927a3c 4711
f8c4789c 4712 case EM_VISIUM:
619ed720 4713 if (e_flags & EF_VISIUM_ARCH_MCM)
f8c4789c 4714 out = stpcpy (out, ", mcm");
619ed720 4715 else if (e_flags & EF_VISIUM_ARCH_MCM24)
f8c4789c 4716 out = stpcpy (out, ", mcm24");
619ed720 4717 if (e_flags & EF_VISIUM_ARCH_GR6)
f8c4789c 4718 out = stpcpy (out, ", gr6");
619ed720
EB
4719 break;
4720
4046d87a 4721 case EM_RL78:
f8c4789c 4722 out = decode_RL78_machine_flags (out, e_flags);
4046d87a 4723 break;
0b4362b0 4724
c7927a3c 4725 case EM_RX:
f8c4789c 4726 out = decode_RX_machine_flags (out, e_flags);
d4cb0ea0 4727 break;
55786da2
AK
4728
4729 case EM_S390:
4730 if (e_flags & EF_S390_HIGH_GPRS)
f8c4789c 4731 out = stpcpy (out, ", highgprs");
d4cb0ea0 4732 break;
40b36596
JM
4733
4734 case EM_TI_C6000:
4735 if ((e_flags & EF_C6000_REL))
f8c4789c 4736 out = stpcpy (out, ", relocatable module");
d4cb0ea0 4737 break;
13761a11
NC
4738
4739 case EM_MSP430:
f8c4789c 4740 out = decode_MSP430_machine_flags (out, e_flags);
6655dba2
SB
4741 break;
4742
4743 case EM_Z80:
f8c4789c 4744 out = decode_Z80_machine_flags (out, e_flags);
6655dba2 4745 break;
c4a7e6b5 4746
f8c4789c
AM
4747 case EM_LOONGARCH:
4748 out = decode_LOONGARCH_machine_flags (out, e_flags);
e9a0721f 4749 break;
252b5132
RH
4750 }
4751 }
4752
4753 return buf;
4754}
4755
252b5132 4756static const char *
dda8d76d 4757get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4758{
4759 static char buff[32];
4760
4761 switch (osabi)
4762 {
4763 case ELFOSABI_NONE: return "UNIX - System V";
4764 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4765 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4766 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4767 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4768 case ELFOSABI_AIX: return "UNIX - AIX";
4769 case ELFOSABI_IRIX: return "UNIX - IRIX";
4770 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4771 case ELFOSABI_TRU64: return "UNIX - TRU64";
4772 case ELFOSABI_MODESTO: return "Novell - Modesto";
4773 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4774 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4775 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4776 case ELFOSABI_AROS: return "AROS";
11636f9e 4777 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4778 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4779 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4780 default:
40b36596 4781 if (osabi >= 64)
dda8d76d 4782 switch (filedata->file_header.e_machine)
40b36596 4783 {
37870be8
SM
4784 case EM_AMDGPU:
4785 switch (osabi)
4786 {
4787 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4788 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4789 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4790 default:
4791 break;
4792 }
4793 break;
4794
40b36596
JM
4795 case EM_ARM:
4796 switch (osabi)
4797 {
4798 case ELFOSABI_ARM: return "ARM";
18a20338 4799 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4800 default:
4801 break;
4802 }
4803 break;
4804
4805 case EM_MSP430:
4806 case EM_MSP430_OLD:
619ed720 4807 case EM_VISIUM:
40b36596
JM
4808 switch (osabi)
4809 {
4810 case ELFOSABI_STANDALONE: return _("Standalone App");
4811 default:
4812 break;
4813 }
4814 break;
4815
4816 case EM_TI_C6000:
4817 switch (osabi)
4818 {
4819 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4820 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4821 default:
4822 break;
4823 }
4824 break;
4825
4826 default:
4827 break;
4828 }
e9e44622 4829 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4830 return buff;
4831 }
4832}
4833
a06ea964
NC
4834static const char *
4835get_aarch64_segment_type (unsigned long type)
4836{
4837 switch (type)
4838 {
32ec8896 4839 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4840 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4841 default: return NULL;
a06ea964 4842 }
a06ea964
NC
4843}
4844
b294bdf8
MM
4845static const char *
4846get_arm_segment_type (unsigned long type)
4847{
4848 switch (type)
4849 {
32ec8896
NC
4850 case PT_ARM_EXIDX: return "EXIDX";
4851 default: return NULL;
b294bdf8 4852 }
b294bdf8
MM
4853}
4854
b4cbbe8f
AK
4855static const char *
4856get_s390_segment_type (unsigned long type)
4857{
4858 switch (type)
4859 {
4860 case PT_S390_PGSTE: return "S390_PGSTE";
4861 default: return NULL;
4862 }
4863}
4864
d3ba0551
AM
4865static const char *
4866get_mips_segment_type (unsigned long type)
252b5132
RH
4867{
4868 switch (type)
4869 {
32ec8896
NC
4870 case PT_MIPS_REGINFO: return "REGINFO";
4871 case PT_MIPS_RTPROC: return "RTPROC";
4872 case PT_MIPS_OPTIONS: return "OPTIONS";
4873 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4874 default: return NULL;
252b5132 4875 }
252b5132
RH
4876}
4877
103f02d3 4878static const char *
d3ba0551 4879get_parisc_segment_type (unsigned long type)
103f02d3
UD
4880{
4881 switch (type)
4882 {
103f02d3
UD
4883 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4884 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4885 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4886 default: return NULL;
103f02d3 4887 }
103f02d3
UD
4888}
4889
4d6ed7c8 4890static const char *
d3ba0551 4891get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4892{
4893 switch (type)
4894 {
4895 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4896 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4897 default: return NULL;
4d6ed7c8 4898 }
4d6ed7c8
NC
4899}
4900
40b36596
JM
4901static const char *
4902get_tic6x_segment_type (unsigned long type)
4903{
4904 switch (type)
4905 {
32ec8896
NC
4906 case PT_C6000_PHATTR: return "C6000_PHATTR";
4907 default: return NULL;
40b36596 4908 }
40b36596
JM
4909}
4910
fbc95f1e
KC
4911static const char *
4912get_riscv_segment_type (unsigned long type)
4913{
4914 switch (type)
4915 {
4916 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4917 default: return NULL;
4918 }
4919}
4920
df3a023b
AM
4921static const char *
4922get_hpux_segment_type (unsigned long type, unsigned e_machine)
4923{
4924 if (e_machine == EM_PARISC)
4925 switch (type)
4926 {
4927 case PT_HP_TLS: return "HP_TLS";
4928 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4929 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4930 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4931 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4932 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4933 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4934 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4935 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4936 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4937 case PT_HP_PARALLEL: return "HP_PARALLEL";
4938 case PT_HP_FASTBIND: return "HP_FASTBIND";
4939 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4940 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4941 case PT_HP_STACK: return "HP_STACK";
4942 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4943 default: return NULL;
4944 }
4945
4946 if (e_machine == EM_IA_64)
4947 switch (type)
4948 {
4949 case PT_HP_TLS: return "HP_TLS";
4950 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4951 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4952 case PT_IA_64_HP_STACK: return "HP_STACK";
4953 default: return NULL;
4954 }
4955
4956 return NULL;
4957}
4958
5522f910
NC
4959static const char *
4960get_solaris_segment_type (unsigned long type)
4961{
4962 switch (type)
4963 {
4964 case 0x6464e550: return "PT_SUNW_UNWIND";
4965 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4966 case 0x6ffffff7: return "PT_LOSUNW";
4967 case 0x6ffffffa: return "PT_SUNWBSS";
4968 case 0x6ffffffb: return "PT_SUNWSTACK";
4969 case 0x6ffffffc: return "PT_SUNWDTRACE";
4970 case 0x6ffffffd: return "PT_SUNWCAP";
4971 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4972 default: return NULL;
5522f910
NC
4973 }
4974}
4975
252b5132 4976static const char *
dda8d76d 4977get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4978{
b34976b6 4979 static char buff[32];
252b5132
RH
4980
4981 switch (p_type)
4982 {
b34976b6
AM
4983 case PT_NULL: return "NULL";
4984 case PT_LOAD: return "LOAD";
252b5132 4985 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4986 case PT_INTERP: return "INTERP";
4987 case PT_NOTE: return "NOTE";
4988 case PT_SHLIB: return "SHLIB";
4989 case PT_PHDR: return "PHDR";
13ae64f3 4990 case PT_TLS: return "TLS";
32ec8896 4991 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4992 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4993 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4994 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
cf0e0a0b 4995 case PT_GNU_SFRAME: return "GNU_SFRAME";
65765700 4996
80251d41 4997 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
3eba3ef3
NC
4998 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4999 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
5000 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 5001
252b5132 5002 default:
df3a023b 5003 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 5004 {
2cf0635d 5005 const char * result;
103f02d3 5006
dda8d76d 5007 switch (filedata->file_header.e_machine)
252b5132 5008 {
a06ea964
NC
5009 case EM_AARCH64:
5010 result = get_aarch64_segment_type (p_type);
5011 break;
b294bdf8
MM
5012 case EM_ARM:
5013 result = get_arm_segment_type (p_type);
5014 break;
252b5132 5015 case EM_MIPS:
4fe85591 5016 case EM_MIPS_RS3_LE:
252b5132
RH
5017 result = get_mips_segment_type (p_type);
5018 break;
103f02d3
UD
5019 case EM_PARISC:
5020 result = get_parisc_segment_type (p_type);
5021 break;
4d6ed7c8
NC
5022 case EM_IA_64:
5023 result = get_ia64_segment_type (p_type);
5024 break;
40b36596
JM
5025 case EM_TI_C6000:
5026 result = get_tic6x_segment_type (p_type);
5027 break;
b4cbbe8f
AK
5028 case EM_S390:
5029 case EM_S390_OLD:
5030 result = get_s390_segment_type (p_type);
5031 break;
fbc95f1e
KC
5032 case EM_RISCV:
5033 result = get_riscv_segment_type (p_type);
5034 break;
252b5132
RH
5035 default:
5036 result = NULL;
5037 break;
5038 }
103f02d3 5039
252b5132
RH
5040 if (result != NULL)
5041 return result;
103f02d3 5042
1a9ccd70 5043 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
5044 }
5045 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 5046 {
df3a023b 5047 const char * result = NULL;
103f02d3 5048
df3a023b 5049 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 5050 {
df3a023b
AM
5051 case ELFOSABI_GNU:
5052 case ELFOSABI_FREEBSD:
5053 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
5054 {
5055 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
5056 result = buff;
5057 }
103f02d3 5058 break;
df3a023b
AM
5059 case ELFOSABI_HPUX:
5060 result = get_hpux_segment_type (p_type,
5061 filedata->file_header.e_machine);
5062 break;
5063 case ELFOSABI_SOLARIS:
5064 result = get_solaris_segment_type (p_type);
00428cca 5065 break;
103f02d3 5066 default:
103f02d3
UD
5067 break;
5068 }
103f02d3
UD
5069 if (result != NULL)
5070 return result;
5071
1a9ccd70 5072 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 5073 }
252b5132 5074 else
e9e44622 5075 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
5076
5077 return buff;
5078 }
5079}
5080
53a346d8
CZ
5081static const char *
5082get_arc_section_type_name (unsigned int sh_type)
5083{
5084 switch (sh_type)
5085 {
5086 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
5087 default:
5088 break;
5089 }
5090 return NULL;
5091}
5092
252b5132 5093static const char *
d3ba0551 5094get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
5095{
5096 switch (sh_type)
5097 {
b34976b6
AM
5098 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
5099 case SHT_MIPS_MSYM: return "MIPS_MSYM";
5100 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
5101 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
5102 case SHT_MIPS_UCODE: return "MIPS_UCODE";
5103 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
5104 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
5105 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
5106 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
5107 case SHT_MIPS_RELD: return "MIPS_RELD";
5108 case SHT_MIPS_IFACE: return "MIPS_IFACE";
5109 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
5110 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
5111 case SHT_MIPS_SHDR: return "MIPS_SHDR";
5112 case SHT_MIPS_FDESC: return "MIPS_FDESC";
5113 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
5114 case SHT_MIPS_DENSE: return "MIPS_DENSE";
5115 case SHT_MIPS_PDESC: return "MIPS_PDESC";
5116 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
5117 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
5118 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
5119 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
5120 case SHT_MIPS_LINE: return "MIPS_LINE";
5121 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
5122 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
5123 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
5124 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
5125 case SHT_MIPS_DWARF: return "MIPS_DWARF";
5126 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
5127 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
5128 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
5129 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
5130 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
5131 case SHT_MIPS_XLATE: return "MIPS_XLATE";
5132 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
5133 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
5134 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
5135 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 5136 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 5137 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 5138 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
5139 default:
5140 break;
5141 }
5142 return NULL;
5143}
5144
103f02d3 5145static const char *
d3ba0551 5146get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
5147{
5148 switch (sh_type)
5149 {
5150 case SHT_PARISC_EXT: return "PARISC_EXT";
5151 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
5152 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
5153 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
5154 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
5155 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 5156 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 5157 default: return NULL;
103f02d3 5158 }
103f02d3
UD
5159}
5160
4d6ed7c8 5161static const char *
dda8d76d 5162get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 5163{
18bd398b 5164 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 5165 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 5166 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 5167
4d6ed7c8
NC
5168 switch (sh_type)
5169 {
148b93f2
NC
5170 case SHT_IA_64_EXT: return "IA_64_EXT";
5171 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
5172 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
5173 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
5174 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
5175 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
5176 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
5177 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
5178 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
5179 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
5180 default:
5181 break;
5182 }
5183 return NULL;
5184}
5185
d2b2c203
DJ
5186static const char *
5187get_x86_64_section_type_name (unsigned int sh_type)
5188{
5189 switch (sh_type)
5190 {
5191 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 5192 default: return NULL;
d2b2c203 5193 }
d2b2c203
DJ
5194}
5195
a06ea964
NC
5196static const char *
5197get_aarch64_section_type_name (unsigned int sh_type)
5198{
5199 switch (sh_type)
5200 {
32ec8896
NC
5201 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
5202 default: return NULL;
a06ea964 5203 }
a06ea964
NC
5204}
5205
40a18ebd
NC
5206static const char *
5207get_arm_section_type_name (unsigned int sh_type)
5208{
5209 switch (sh_type)
5210 {
7f6fed87
NC
5211 case SHT_ARM_EXIDX: return "ARM_EXIDX";
5212 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
5213 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
5214 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
5215 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 5216 default: return NULL;
40a18ebd 5217 }
40a18ebd
NC
5218}
5219
40b36596
JM
5220static const char *
5221get_tic6x_section_type_name (unsigned int sh_type)
5222{
5223 switch (sh_type)
5224 {
32ec8896
NC
5225 case SHT_C6000_UNWIND: return "C6000_UNWIND";
5226 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
5227 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
5228 case SHT_TI_ICODE: return "TI_ICODE";
5229 case SHT_TI_XREF: return "TI_XREF";
5230 case SHT_TI_HANDLER: return "TI_HANDLER";
5231 case SHT_TI_INITINFO: return "TI_INITINFO";
5232 case SHT_TI_PHATTRS: return "TI_PHATTRS";
5233 default: return NULL;
40b36596 5234 }
40b36596
JM
5235}
5236
13761a11 5237static const char *
b0191216 5238get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
5239{
5240 switch (sh_type)
5241 {
32ec8896
NC
5242 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
5243 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
5244 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
5245 default: return NULL;
13761a11
NC
5246 }
5247}
5248
fe944acf
FT
5249static const char *
5250get_nfp_section_type_name (unsigned int sh_type)
5251{
5252 switch (sh_type)
5253 {
5254 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
5255 case SHT_NFP_INITREG: return "NFP_INITREG";
5256 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
5257 default: return NULL;
5258 }
5259}
5260
685080f2
NC
5261static const char *
5262get_v850_section_type_name (unsigned int sh_type)
5263{
5264 switch (sh_type)
5265 {
32ec8896
NC
5266 case SHT_V850_SCOMMON: return "V850 Small Common";
5267 case SHT_V850_TCOMMON: return "V850 Tiny Common";
5268 case SHT_V850_ZCOMMON: return "V850 Zero Common";
5269 case SHT_RENESAS_IOP: return "RENESAS IOP";
5270 case SHT_RENESAS_INFO: return "RENESAS INFO";
5271 default: return NULL;
685080f2
NC
5272 }
5273}
5274
2dc8dd17
JW
5275static const char *
5276get_riscv_section_type_name (unsigned int sh_type)
5277{
5278 switch (sh_type)
5279 {
5280 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5281 default: return NULL;
5282 }
5283}
5284
0861f561
CQ
5285static const char *
5286get_csky_section_type_name (unsigned int sh_type)
5287{
5288 switch (sh_type)
5289 {
5290 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
5291 default: return NULL;
5292 }
5293}
5294
252b5132 5295static const char *
dda8d76d 5296get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 5297{
b34976b6 5298 static char buff[32];
9fb71ee4 5299 const char * result;
252b5132
RH
5300
5301 switch (sh_type)
5302 {
5303 case SHT_NULL: return "NULL";
5304 case SHT_PROGBITS: return "PROGBITS";
5305 case SHT_SYMTAB: return "SYMTAB";
5306 case SHT_STRTAB: return "STRTAB";
5307 case SHT_RELA: return "RELA";
dd207c13 5308 case SHT_RELR: return "RELR";
252b5132
RH
5309 case SHT_HASH: return "HASH";
5310 case SHT_DYNAMIC: return "DYNAMIC";
5311 case SHT_NOTE: return "NOTE";
5312 case SHT_NOBITS: return "NOBITS";
5313 case SHT_REL: return "REL";
5314 case SHT_SHLIB: return "SHLIB";
5315 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
5316 case SHT_INIT_ARRAY: return "INIT_ARRAY";
5317 case SHT_FINI_ARRAY: return "FINI_ARRAY";
5318 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 5319 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 5320 case SHT_GROUP: return "GROUP";
67ce483b 5321 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
5322 case SHT_GNU_verdef: return "VERDEF";
5323 case SHT_GNU_verneed: return "VERNEED";
5324 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
5325 case 0x6ffffff0: return "VERSYM";
5326 case 0x6ffffffc: return "VERDEF";
252b5132
RH
5327 case 0x7ffffffd: return "AUXILIARY";
5328 case 0x7fffffff: return "FILTER";
047b2264 5329 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
5330
5331 default:
5332 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
5333 {
dda8d76d 5334 switch (filedata->file_header.e_machine)
252b5132 5335 {
53a346d8
CZ
5336 case EM_ARC:
5337 case EM_ARC_COMPACT:
5338 case EM_ARC_COMPACT2:
b5c37946
SJ
5339 case EM_ARC_COMPACT3:
5340 case EM_ARC_COMPACT3_64:
53a346d8
CZ
5341 result = get_arc_section_type_name (sh_type);
5342 break;
252b5132 5343 case EM_MIPS:
4fe85591 5344 case EM_MIPS_RS3_LE:
252b5132
RH
5345 result = get_mips_section_type_name (sh_type);
5346 break;
103f02d3
UD
5347 case EM_PARISC:
5348 result = get_parisc_section_type_name (sh_type);
5349 break;
4d6ed7c8 5350 case EM_IA_64:
dda8d76d 5351 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 5352 break;
d2b2c203 5353 case EM_X86_64:
8a9036a4 5354 case EM_L1OM:
7a9068fe 5355 case EM_K1OM:
d2b2c203
DJ
5356 result = get_x86_64_section_type_name (sh_type);
5357 break;
a06ea964
NC
5358 case EM_AARCH64:
5359 result = get_aarch64_section_type_name (sh_type);
5360 break;
40a18ebd
NC
5361 case EM_ARM:
5362 result = get_arm_section_type_name (sh_type);
5363 break;
40b36596
JM
5364 case EM_TI_C6000:
5365 result = get_tic6x_section_type_name (sh_type);
5366 break;
13761a11 5367 case EM_MSP430:
b0191216 5368 result = get_msp430_section_type_name (sh_type);
13761a11 5369 break;
fe944acf
FT
5370 case EM_NFP:
5371 result = get_nfp_section_type_name (sh_type);
5372 break;
685080f2
NC
5373 case EM_V800:
5374 case EM_V850:
5375 case EM_CYGNUS_V850:
5376 result = get_v850_section_type_name (sh_type);
5377 break;
2dc8dd17
JW
5378 case EM_RISCV:
5379 result = get_riscv_section_type_name (sh_type);
5380 break;
0861f561
CQ
5381 case EM_CSKY:
5382 result = get_csky_section_type_name (sh_type);
5383 break;
252b5132
RH
5384 default:
5385 result = NULL;
5386 break;
5387 }
5388
5389 if (result != NULL)
5390 return result;
5391
9fb71ee4 5392 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5393 }
5394 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5395 {
dda8d76d 5396 switch (filedata->file_header.e_machine)
148b93f2
NC
5397 {
5398 case EM_IA_64:
dda8d76d 5399 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5400 break;
5401 default:
dda8d76d 5402 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5403 result = get_solaris_section_type (sh_type);
5404 else
1b4b80bf
NC
5405 {
5406 switch (sh_type)
5407 {
5408 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5409 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5410 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5411 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5412 default:
5413 result = NULL;
5414 break;
5415 }
5416 }
148b93f2
NC
5417 break;
5418 }
5419
5420 if (result != NULL)
5421 return result;
5422
9fb71ee4 5423 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5424 }
252b5132 5425 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5426 {
dda8d76d 5427 switch (filedata->file_header.e_machine)
685080f2
NC
5428 {
5429 case EM_V800:
5430 case EM_V850:
5431 case EM_CYGNUS_V850:
9fb71ee4 5432 result = get_v850_section_type_name (sh_type);
a9fb83be 5433 break;
685080f2 5434 default:
9fb71ee4 5435 result = NULL;
685080f2
NC
5436 break;
5437 }
5438
9fb71ee4
NC
5439 if (result != NULL)
5440 return result;
5441
5442 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5443 }
252b5132 5444 else
a7dbfd1c
NC
5445 /* This message is probably going to be displayed in a 15
5446 character wide field, so put the hex value first. */
5447 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5448
252b5132
RH
5449 return buff;
5450 }
5451}
5452
79bc120c
NC
5453enum long_option_values
5454{
5455 OPTION_DEBUG_DUMP = 512,
5456 OPTION_DYN_SYMS,
0f03783c 5457 OPTION_LTO_SYMS,
79bc120c
NC
5458 OPTION_DWARF_DEPTH,
5459 OPTION_DWARF_START,
5460 OPTION_DWARF_CHECK,
5461 OPTION_CTF_DUMP,
5462 OPTION_CTF_PARENT,
5463 OPTION_CTF_SYMBOLS,
5464 OPTION_CTF_STRINGS,
42b6953b 5465 OPTION_SFRAME_DUMP,
79bc120c
NC
5466 OPTION_WITH_SYMBOL_VERSIONS,
5467 OPTION_RECURSE_LIMIT,
5468 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
5469 OPTION_NO_DEMANGLING,
5470 OPTION_SYM_BASE
79bc120c 5471};
2979dc34 5472
85b1c36d 5473static struct option options[] =
252b5132 5474{
79bc120c
NC
5475 /* Note - This table is alpha-sorted on the 'val'
5476 field in order to make adding new options easier. */
5477 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5478 {"all", no_argument, 0, 'a'},
79bc120c
NC
5479 {"demangle", optional_argument, 0, 'C'},
5480 {"archive-index", no_argument, 0, 'c'},
5481 {"use-dynamic", no_argument, 0, 'D'},
5482 {"dynamic", no_argument, 0, 'd'},
b34976b6 5483 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5484 {"section-groups", no_argument, 0, 'g'},
5485 {"help", no_argument, 0, 'H'},
5486 {"file-header", no_argument, 0, 'h'},
b34976b6 5487 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5488 {"lint", no_argument, 0, 'L'},
5489 {"enable-checks", no_argument, 0, 'L'},
5490 {"program-headers", no_argument, 0, 'l'},
b34976b6 5491 {"segments", no_argument, 0, 'l'},
595cf52e 5492 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5493 {"notes", no_argument, 0, 'n'},
ca0e11aa 5494 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5495 {"string-dump", required_argument, 0, 'p'},
5496 {"relocated-dump", required_argument, 0, 'R'},
5497 {"relocs", no_argument, 0, 'r'},
5498 {"section-headers", no_argument, 0, 'S'},
5499 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5500 {"symbols", no_argument, 0, 's'},
5501 {"syms", no_argument, 0, 's'},
79bc120c
NC
5502 {"silent-truncation",no_argument, 0, 'T'},
5503 {"section-details", no_argument, 0, 't'},
b3aa80b4 5504 {"unicode", required_argument, NULL, 'U'},
09c11c86 5505 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5506 {"version-info", no_argument, 0, 'V'},
5507 {"version", no_argument, 0, 'v'},
5508 {"wide", no_argument, 0, 'W'},
b34976b6 5509 {"hex-dump", required_argument, 0, 'x'},
0e602686 5510 {"decompress", no_argument, 0, 'z'},
252b5132 5511
79bc120c
NC
5512 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5513 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5514 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5515 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5516 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5517 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5518 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5519 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5520 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5521 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5522#ifdef ENABLE_LIBCTF
d344b407 5523 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5524 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5525 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5526 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5527#endif
42b6953b 5528 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
047c3dbf 5529 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5530
b34976b6 5531 {0, no_argument, 0, 0}
252b5132
RH
5532};
5533
5534static void
2cf0635d 5535usage (FILE * stream)
252b5132 5536{
92f01d61
JM
5537 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5538 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5539 fprintf (stream, _(" Options are:\n"));
5540 fprintf (stream, _("\
5541 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5542 fprintf (stream, _("\
5543 -h --file-header Display the ELF file header\n"));
5544 fprintf (stream, _("\
5545 -l --program-headers Display the program headers\n"));
5546 fprintf (stream, _("\
5547 --segments An alias for --program-headers\n"));
5548 fprintf (stream, _("\
5549 -S --section-headers Display the sections' header\n"));
5550 fprintf (stream, _("\
5551 --sections An alias for --section-headers\n"));
5552 fprintf (stream, _("\
5553 -g --section-groups Display the section groups\n"));
5554 fprintf (stream, _("\
5555 -t --section-details Display the section details\n"));
5556 fprintf (stream, _("\
5557 -e --headers Equivalent to: -h -l -S\n"));
5558 fprintf (stream, _("\
5559 -s --syms Display the symbol table\n"));
5560 fprintf (stream, _("\
5561 --symbols An alias for --syms\n"));
5562 fprintf (stream, _("\
5563 --dyn-syms Display the dynamic symbol table\n"));
5564 fprintf (stream, _("\
5565 --lto-syms Display LTO symbol tables\n"));
5566 fprintf (stream, _("\
047c3dbf
NL
5567 --sym-base=[0|8|10|16] \n\
5568 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5569 mixed (the default), octal, decimal, hexadecimal.\n"));
5570 fprintf (stream, _("\
0d646226
AM
5571 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5572 display_demangler_styles (stream, _("\
5573 STYLE can be "));
d6249f5f
AM
5574 fprintf (stream, _("\
5575 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5576 fprintf (stream, _("\
5577 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5578 fprintf (stream, _("\
5579 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5580 fprintf (stream, _("\
5581 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5582 Display unicode characters as determined by the current locale\n\
5583 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5584 escape sequences, or treat them as invalid and display as\n\
5585 \"{hex sequences}\"\n"));
d6249f5f
AM
5586 fprintf (stream, _("\
5587 -n --notes Display the core notes (if present)\n"));
5588 fprintf (stream, _("\
5589 -r --relocs Display the relocations (if present)\n"));
5590 fprintf (stream, _("\
5591 -u --unwind Display the unwind info (if present)\n"));
5592 fprintf (stream, _("\
5593 -d --dynamic Display the dynamic section (if present)\n"));
5594 fprintf (stream, _("\
5595 -V --version-info Display the version sections (if present)\n"));
5596 fprintf (stream, _("\
5597 -A --arch-specific Display architecture specific information (if any)\n"));
5598 fprintf (stream, _("\
5599 -c --archive-index Display the symbol/file index in an archive\n"));
5600 fprintf (stream, _("\
5601 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5602 fprintf (stream, _("\
5603 -L --lint|--enable-checks\n\
5604 Display warning messages for possible problems\n"));
5605 fprintf (stream, _("\
09c11c86 5606 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5607 Dump the contents of section <number|name> as bytes\n"));
5608 fprintf (stream, _("\
09c11c86 5609 -p --string-dump=<number|name>\n\
d6249f5f
AM
5610 Dump the contents of section <number|name> as strings\n"));
5611 fprintf (stream, _("\
cf13d699 5612 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5613 Dump the relocated contents of section <number|name>\n"));
5614 fprintf (stream, _("\
5615 -z --decompress Decompress section before dumping it\n"));
5616 fprintf (stream, _("\
5617 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5618 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5619 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5620 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5621 U/=trace_info]\n\
5622 Display the contents of DWARF debug sections\n"));
5623 fprintf (stream, _("\
5624 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5625 debuginfo files\n"));
5626 fprintf (stream, _("\
5627 -P --process-links Display the contents of non-debug sections in separate\n\
5628 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5629#if DEFAULT_FOR_FOLLOW_LINKS
5630 fprintf (stream, _("\
d6249f5f
AM
5631 -wK --debug-dump=follow-links\n\
5632 Follow links to separate debug info files (default)\n"));
5633 fprintf (stream, _("\
5634 -wN --debug-dump=no-follow-links\n\
5635 Do not follow links to separate debug info files\n"));
c46b7066
NC
5636#else
5637 fprintf (stream, _("\
d6249f5f
AM
5638 -wK --debug-dump=follow-links\n\
5639 Follow links to separate debug info files\n"));
5640 fprintf (stream, _("\
5641 -wN --debug-dump=no-follow-links\n\
5642 Do not follow links to separate debug info files\n\
5643 (default)\n"));
bed566bb
NC
5644#endif
5645#if HAVE_LIBDEBUGINFOD
5646 fprintf (stream, _("\
5647 -wD --debug-dump=use-debuginfod\n\
5648 When following links, also query debuginfod servers (default)\n"));
5649 fprintf (stream, _("\
5650 -wE --debug-dump=do-not-use-debuginfod\n\
5651 When following links, do not query debuginfod servers\n"));
c46b7066 5652#endif
fd2f0033 5653 fprintf (stream, _("\
d6249f5f
AM
5654 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5655 fprintf (stream, _("\
5656 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5657#ifdef ENABLE_LIBCTF
7d9813f1 5658 fprintf (stream, _("\
d6249f5f
AM
5659 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5660 fprintf (stream, _("\
80b56fad 5661 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5662 fprintf (stream, _("\
7d9813f1 5663 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5664 Use section <number|name> as the CTF external symtab\n"));
5665 fprintf (stream, _("\
7d9813f1 5666 --ctf-strings=<number|name>\n\
d6249f5f 5667 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5668#endif
42b6953b
IB
5669 fprintf (stream, _("\
5670 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
7d9813f1 5671
252b5132 5672#ifdef SUPPORT_DISASSEMBLY
92f01d61 5673 fprintf (stream, _("\
09c11c86
NC
5674 -i --instruction-dump=<number|name>\n\
5675 Disassemble the contents of section <number|name>\n"));
252b5132 5676#endif
92f01d61 5677 fprintf (stream, _("\
d6249f5f
AM
5678 -I --histogram Display histogram of bucket list lengths\n"));
5679 fprintf (stream, _("\
5680 -W --wide Allow output width to exceed 80 characters\n"));
5681 fprintf (stream, _("\
5682 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5683 fprintf (stream, _("\
5684 @<file> Read options from <file>\n"));
5685 fprintf (stream, _("\
5686 -H --help Display this information\n"));
5687 fprintf (stream, _("\
8b53311e 5688 -v --version Display the version number of readelf\n"));
1118d252 5689
92f01d61
JM
5690 if (REPORT_BUGS_TO[0] && stream == stdout)
5691 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5692
92f01d61 5693 exit (stream == stdout ? 0 : 1);
252b5132
RH
5694}
5695
18bd398b
NC
5696/* Record the fact that the user wants the contents of section number
5697 SECTION to be displayed using the method(s) encoded as flags bits
5698 in TYPE. Note, TYPE can be zero if we are creating the array for
5699 the first time. */
5700
252b5132 5701static void
6431e409
AM
5702request_dump_bynumber (struct dump_data *dumpdata,
5703 unsigned int section, dump_type type)
252b5132 5704{
6431e409 5705 if (section >= dumpdata->num_dump_sects)
252b5132 5706 {
2cf0635d 5707 dump_type * new_dump_sects;
252b5132 5708
3f5e193b 5709 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5710 sizeof (* new_dump_sects));
252b5132
RH
5711
5712 if (new_dump_sects == NULL)
591a748a 5713 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5714 else
5715 {
6431e409 5716 if (dumpdata->dump_sects)
21b65bac
NC
5717 {
5718 /* Copy current flag settings. */
6431e409
AM
5719 memcpy (new_dump_sects, dumpdata->dump_sects,
5720 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5721
6431e409 5722 free (dumpdata->dump_sects);
21b65bac 5723 }
252b5132 5724
6431e409
AM
5725 dumpdata->dump_sects = new_dump_sects;
5726 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5727 }
5728 }
5729
6431e409
AM
5730 if (dumpdata->dump_sects)
5731 dumpdata->dump_sects[section] |= type;
252b5132
RH
5732}
5733
aef1f6d0
DJ
5734/* Request a dump by section name. */
5735
5736static void
2cf0635d 5737request_dump_byname (const char * section, dump_type type)
aef1f6d0 5738{
2cf0635d 5739 struct dump_list_entry * new_request;
aef1f6d0 5740
3f5e193b
NC
5741 new_request = (struct dump_list_entry *)
5742 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5743 if (!new_request)
591a748a 5744 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5745
5746 new_request->name = strdup (section);
5747 if (!new_request->name)
591a748a 5748 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5749
5750 new_request->type = type;
5751
5752 new_request->next = dump_sects_byname;
5753 dump_sects_byname = new_request;
5754}
5755
cf13d699 5756static inline void
6431e409 5757request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5758{
5759 int section;
5760 char * cp;
5761
015dc7e1 5762 do_dump = true;
cf13d699
NC
5763 section = strtoul (optarg, & cp, 0);
5764
5765 if (! *cp && section >= 0)
6431e409 5766 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5767 else
5768 request_dump_byname (optarg, type);
5769}
5770
252b5132 5771static void
6431e409 5772parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5773{
5774 int c;
5775
5776 if (argc < 2)
92f01d61 5777 usage (stderr);
252b5132
RH
5778
5779 while ((c = getopt_long
b3aa80b4 5780 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5781 {
252b5132
RH
5782 switch (c)
5783 {
5784 case 0:
5785 /* Long options. */
5786 break;
5787 case 'H':
92f01d61 5788 usage (stdout);
252b5132
RH
5789 break;
5790
5791 case 'a':
015dc7e1
AM
5792 do_syms = true;
5793 do_reloc = true;
5794 do_unwind = true;
5795 do_dynamic = true;
5796 do_header = true;
5797 do_sections = true;
5798 do_section_groups = true;
5799 do_segments = true;
5800 do_version = true;
5801 do_histogram = true;
5802 do_arch = true;
5803 do_notes = true;
252b5132 5804 break;
79bc120c 5805
f5842774 5806 case 'g':
015dc7e1 5807 do_section_groups = true;
f5842774 5808 break;
5477e8a0 5809 case 't':
595cf52e 5810 case 'N':
015dc7e1
AM
5811 do_sections = true;
5812 do_section_details = true;
595cf52e 5813 break;
252b5132 5814 case 'e':
015dc7e1
AM
5815 do_header = true;
5816 do_sections = true;
5817 do_segments = true;
252b5132 5818 break;
a952a375 5819 case 'A':
015dc7e1 5820 do_arch = true;
a952a375 5821 break;
252b5132 5822 case 'D':
015dc7e1 5823 do_using_dynamic = true;
252b5132
RH
5824 break;
5825 case 'r':
015dc7e1 5826 do_reloc = true;
252b5132 5827 break;
4d6ed7c8 5828 case 'u':
015dc7e1 5829 do_unwind = true;
4d6ed7c8 5830 break;
252b5132 5831 case 'h':
015dc7e1 5832 do_header = true;
252b5132
RH
5833 break;
5834 case 'l':
015dc7e1 5835 do_segments = true;
252b5132
RH
5836 break;
5837 case 's':
015dc7e1 5838 do_syms = true;
252b5132
RH
5839 break;
5840 case 'S':
015dc7e1 5841 do_sections = true;
252b5132
RH
5842 break;
5843 case 'd':
015dc7e1 5844 do_dynamic = true;
252b5132 5845 break;
a952a375 5846 case 'I':
015dc7e1 5847 do_histogram = true;
a952a375 5848 break;
779fe533 5849 case 'n':
015dc7e1 5850 do_notes = true;
779fe533 5851 break;
4145f1d5 5852 case 'c':
015dc7e1 5853 do_archive_index = true;
4145f1d5 5854 break;
1b513401 5855 case 'L':
015dc7e1 5856 do_checks = true;
1b513401 5857 break;
ca0e11aa 5858 case 'P':
015dc7e1
AM
5859 process_links = true;
5860 do_follow_links = true;
e1dbfc17 5861 dump_any_debugging = true;
ca0e11aa 5862 break;
252b5132 5863 case 'x':
6431e409 5864 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5865 break;
09c11c86 5866 case 'p':
6431e409 5867 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5868 break;
5869 case 'R':
6431e409 5870 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5871 break;
0e602686 5872 case 'z':
015dc7e1 5873 decompress_dumps = true;
0e602686 5874 break;
252b5132 5875 case 'w':
0f03783c 5876 if (optarg == NULL)
613ff48b 5877 {
015dc7e1 5878 do_debugging = true;
94585d6d
NC
5879 do_dump = true;
5880 dump_any_debugging = true;
613ff48b
CC
5881 dwarf_select_sections_all ();
5882 }
252b5132
RH
5883 else
5884 {
015dc7e1 5885 do_debugging = false;
94585d6d
NC
5886 if (dwarf_select_sections_by_letters (optarg))
5887 {
5888 do_dump = true;
5889 dump_any_debugging = true;
5890 }
252b5132
RH
5891 }
5892 break;
2979dc34 5893 case OPTION_DEBUG_DUMP:
0f03783c 5894 if (optarg == NULL)
d6249f5f 5895 {
94585d6d 5896 do_dump = true;
d6249f5f 5897 do_debugging = true;
94585d6d 5898 dump_any_debugging = true;
d6249f5f
AM
5899 dwarf_select_sections_all ();
5900 }
2979dc34
JJ
5901 else
5902 {
015dc7e1 5903 do_debugging = false;
94585d6d
NC
5904 if (dwarf_select_sections_by_names (optarg))
5905 {
5906 do_dump = true;
5907 dump_any_debugging = true;
5908 }
2979dc34
JJ
5909 }
5910 break;
fd2f0033
TT
5911 case OPTION_DWARF_DEPTH:
5912 {
5913 char *cp;
5914
5915 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5916 }
5917 break;
5918 case OPTION_DWARF_START:
5919 {
5920 char *cp;
5921
5922 dwarf_start_die = strtoul (optarg, & cp, 0);
5923 }
5924 break;
4723351a 5925 case OPTION_DWARF_CHECK:
015dc7e1 5926 dwarf_check = true;
4723351a 5927 break;
7d9813f1 5928 case OPTION_CTF_DUMP:
015dc7e1 5929 do_ctf = true;
6431e409 5930 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5931 break;
5932 case OPTION_CTF_SYMBOLS:
df16e041 5933 free (dump_ctf_symtab_name);
7d9813f1
NA
5934 dump_ctf_symtab_name = strdup (optarg);
5935 break;
5936 case OPTION_CTF_STRINGS:
df16e041 5937 free (dump_ctf_strtab_name);
7d9813f1
NA
5938 dump_ctf_strtab_name = strdup (optarg);
5939 break;
5940 case OPTION_CTF_PARENT:
df16e041 5941 free (dump_ctf_parent_name);
7d9813f1
NA
5942 dump_ctf_parent_name = strdup (optarg);
5943 break;
42b6953b
IB
5944 case OPTION_SFRAME_DUMP:
5945 do_sframe = true;
5946 /* Providing section name is optional. request_dump (), however,
5947 thrives on non NULL optarg. Handle it explicitly here. */
5948 if (optarg != NULL)
5949 request_dump (dumpdata, SFRAME_DUMP);
5950 else
5951 {
5952 do_dump = true;
5953 const char *sframe_sec_name = strdup (".sframe");
5954 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
5955 }
5956 break;
2c610e4b 5957 case OPTION_DYN_SYMS:
015dc7e1 5958 do_dyn_syms = true;
2c610e4b 5959 break;
0f03783c 5960 case OPTION_LTO_SYMS:
015dc7e1 5961 do_lto_syms = true;
0f03783c 5962 break;
252b5132
RH
5963#ifdef SUPPORT_DISASSEMBLY
5964 case 'i':
6431e409 5965 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5966 break;
252b5132
RH
5967#endif
5968 case 'v':
5969 print_version (program_name);
5970 break;
5971 case 'V':
015dc7e1 5972 do_version = true;
252b5132 5973 break;
d974e256 5974 case 'W':
015dc7e1 5975 do_wide = true;
d974e256 5976 break;
0942c7ab 5977 case 'T':
015dc7e1 5978 do_not_show_symbol_truncation = true;
0942c7ab 5979 break;
79bc120c 5980 case 'C':
015dc7e1 5981 do_demangle = true;
79bc120c
NC
5982 if (optarg != NULL)
5983 {
5984 enum demangling_styles style;
5985
5986 style = cplus_demangle_name_to_style (optarg);
5987 if (style == unknown_demangling)
5988 error (_("unknown demangling style `%s'"), optarg);
5989
5990 cplus_demangle_set_style (style);
5991 }
5992 break;
5993 case OPTION_NO_DEMANGLING:
015dc7e1 5994 do_demangle = false;
79bc120c
NC
5995 break;
5996 case OPTION_RECURSE_LIMIT:
5997 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5998 break;
5999 case OPTION_NO_RECURSE_LIMIT:
6000 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
6001 break;
6002 case OPTION_WITH_SYMBOL_VERSIONS:
6003 /* Ignored for backward compatibility. */
6004 break;
b9e920ec 6005
b3aa80b4
NC
6006 case 'U':
6007 if (optarg == NULL)
6008 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
6009 else if (streq (optarg, "default") || streq (optarg, "d"))
6010 unicode_display = unicode_default;
6011 else if (streq (optarg, "locale") || streq (optarg, "l"))
6012 unicode_display = unicode_locale;
6013 else if (streq (optarg, "escape") || streq (optarg, "e"))
6014 unicode_display = unicode_escape;
6015 else if (streq (optarg, "invalid") || streq (optarg, "i"))
6016 unicode_display = unicode_invalid;
6017 else if (streq (optarg, "hex") || streq (optarg, "x"))
6018 unicode_display = unicode_hex;
6019 else if (streq (optarg, "highlight") || streq (optarg, "h"))
6020 unicode_display = unicode_highlight;
6021 else
6022 error (_("invalid argument to -U/--unicode: %s"), optarg);
6023 break;
6024
047c3dbf
NL
6025 case OPTION_SYM_BASE:
6026 sym_base = 0;
6027 if (optarg != NULL)
6028 {
6029 sym_base = strtoul (optarg, NULL, 0);
6030 switch (sym_base)
6031 {
6032 case 0:
6033 case 8:
6034 case 10:
6035 case 16:
6036 break;
6037
6038 default:
6039 sym_base = 0;
6040 break;
6041 }
6042 }
6043 break;
6044
252b5132 6045 default:
252b5132
RH
6046 /* xgettext:c-format */
6047 error (_("Invalid option '-%c'\n"), c);
1a0670f3 6048 /* Fall through. */
252b5132 6049 case '?':
92f01d61 6050 usage (stderr);
252b5132
RH
6051 }
6052 }
6053
4d6ed7c8 6054 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 6055 && !do_segments && !do_header && !do_dump && !do_version
f5842774 6056 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 6057 && !do_section_groups && !do_archive_index
0f03783c 6058 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
6059 {
6060 if (do_checks)
6061 {
015dc7e1
AM
6062 check_all = true;
6063 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
6064 do_segments = do_header = do_dump = do_version = true;
6065 do_histogram = do_debugging = do_arch = do_notes = true;
6066 do_section_groups = do_archive_index = do_dyn_syms = true;
6067 do_lto_syms = true;
1b513401
NC
6068 }
6069 else
6070 usage (stderr);
6071 }
252b5132
RH
6072}
6073
6074static const char *
d3ba0551 6075get_elf_class (unsigned int elf_class)
252b5132 6076{
b34976b6 6077 static char buff[32];
103f02d3 6078
252b5132
RH
6079 switch (elf_class)
6080 {
6081 case ELFCLASSNONE: return _("none");
e3c8793a
NC
6082 case ELFCLASS32: return "ELF32";
6083 case ELFCLASS64: return "ELF64";
ab5e7794 6084 default:
e9e44622 6085 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 6086 return buff;
252b5132
RH
6087 }
6088}
6089
6090static const char *
d3ba0551 6091get_data_encoding (unsigned int encoding)
252b5132 6092{
b34976b6 6093 static char buff[32];
103f02d3 6094
252b5132
RH
6095 switch (encoding)
6096 {
6097 case ELFDATANONE: return _("none");
33c63f9d
CM
6098 case ELFDATA2LSB: return _("2's complement, little endian");
6099 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 6100 default:
e9e44622 6101 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 6102 return buff;
252b5132
RH
6103 }
6104}
6105
521f7268
NC
6106static bool
6107check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
6108{
6109 if (header->e_ident[EI_MAG0] == ELFMAG0
6110 && header->e_ident[EI_MAG1] == ELFMAG1
6111 && header->e_ident[EI_MAG2] == ELFMAG2
6112 && header->e_ident[EI_MAG3] == ELFMAG3)
6113 return true;
6114
6115 /* Some compilers produce object files that are not in the ELF file format.
6116 As an aid to users of readelf, try to identify these cases and suggest
6117 alternative tools.
6118
6119 FIXME: It is not clear if all four bytes are used as constant magic
6120 valus by all compilers. It may be necessary to recode this function if
6121 different tools use different length sequences. */
6122
6123 static struct
6124 {
6125 unsigned char magic[4];
6126 const char * obj_message;
6127 const char * ar_message;
6128 }
6129 known_magic[] =
6130 {
6131 { { 'B', 'C', 0xc0, 0xde },
6132 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
6133 N_("This is a LLVM bitcode file - try extracing and then using llvm-bcanalyzer\n")
6134 },
6135 { { 'g', 'o', ' ', 'o' },
6136 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
6137 NULL
6138 }
6139 };
6140 int i;
6141
6142 for (i = ARRAY_SIZE (known_magic); i--;)
6143 {
6144 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
6145 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
6146 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
6147 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
6148 {
6149 /* Some compiler's analyzer tools do not handle archives,
6150 so we provide two different kinds of error message. */
6151 if (filedata->archive_file_size > 0
6152 && known_magic[i].ar_message != NULL)
b3ea2010 6153 error ("%s", known_magic[i].ar_message);
521f7268 6154 else
b3ea2010 6155 error ("%s", known_magic[i].obj_message);
521f7268
NC
6156 return false;
6157 }
6158 }
6159
6160 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
6161 return false;
6162}
6163
dda8d76d 6164/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 6165
015dc7e1 6166static bool
dda8d76d 6167process_file_header (Filedata * filedata)
252b5132 6168{
dda8d76d
NC
6169 Elf_Internal_Ehdr * header = & filedata->file_header;
6170
521f7268
NC
6171 if (! check_magic_number (filedata, header))
6172 return false;
252b5132 6173
ca0e11aa
NC
6174 if (! filedata->is_separate)
6175 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 6176
252b5132
RH
6177 if (do_header)
6178 {
32ec8896 6179 unsigned i;
252b5132 6180
ca0e11aa
NC
6181 if (filedata->is_separate)
6182 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
6183 else
6184 printf (_("ELF Header:\n"));
252b5132 6185 printf (_(" Magic: "));
b34976b6 6186 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 6187 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
6188 printf ("\n");
6189 printf (_(" Class: %s\n"),
dda8d76d 6190 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 6191 printf (_(" Data: %s\n"),
dda8d76d 6192 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 6193 printf (_(" Version: %d%s\n"),
dda8d76d
NC
6194 header->e_ident[EI_VERSION],
6195 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 6196 ? _(" (current)")
dda8d76d 6197 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 6198 ? _(" <unknown>")
789be9f7 6199 : "")));
252b5132 6200 printf (_(" OS/ABI: %s\n"),
dda8d76d 6201 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 6202 printf (_(" ABI Version: %d\n"),
dda8d76d 6203 header->e_ident[EI_ABIVERSION]);
252b5132 6204 printf (_(" Type: %s\n"),
93df3340 6205 get_file_type (filedata));
252b5132 6206 printf (_(" Machine: %s\n"),
dda8d76d 6207 get_machine_name (header->e_machine));
252b5132 6208 printf (_(" Version: 0x%lx\n"),
e8a64888 6209 header->e_version);
76da6bbe 6210
f7a99963 6211 printf (_(" Entry point address: "));
e8a64888 6212 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 6213 printf (_("\n Start of program headers: "));
e8a64888 6214 print_vma (header->e_phoff, DEC);
f7a99963 6215 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 6216 print_vma (header->e_shoff, DEC);
f7a99963 6217 printf (_(" (bytes into file)\n"));
76da6bbe 6218
252b5132 6219 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 6220 header->e_flags,
dda8d76d 6221 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
6222 printf (_(" Size of this header: %u (bytes)\n"),
6223 header->e_ehsize);
6224 printf (_(" Size of program headers: %u (bytes)\n"),
6225 header->e_phentsize);
6226 printf (_(" Number of program headers: %u"),
6227 header->e_phnum);
dda8d76d
NC
6228 if (filedata->section_headers != NULL
6229 && header->e_phnum == PN_XNUM
6230 && filedata->section_headers[0].sh_info != 0)
2969c3b3 6231 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 6232 putc ('\n', stdout);
e8a64888
AM
6233 printf (_(" Size of section headers: %u (bytes)\n"),
6234 header->e_shentsize);
6235 printf (_(" Number of section headers: %u"),
6236 header->e_shnum);
dda8d76d 6237 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
6238 {
6239 header->e_shnum = filedata->section_headers[0].sh_size;
6240 printf (" (%u)", header->e_shnum);
6241 }
560f3c1c 6242 putc ('\n', stdout);
e8a64888
AM
6243 printf (_(" Section header string table index: %u"),
6244 header->e_shstrndx);
dda8d76d
NC
6245 if (filedata->section_headers != NULL
6246 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
6247 {
6248 header->e_shstrndx = filedata->section_headers[0].sh_link;
6249 printf (" (%u)", header->e_shstrndx);
6250 }
6251 if (header->e_shstrndx != SHN_UNDEF
6252 && header->e_shstrndx >= header->e_shnum)
6253 {
6254 header->e_shstrndx = SHN_UNDEF;
6255 printf (_(" <corrupt: out of range>"));
6256 }
560f3c1c
AM
6257 putc ('\n', stdout);
6258 }
6259
dda8d76d 6260 if (filedata->section_headers != NULL)
560f3c1c 6261 {
dda8d76d
NC
6262 if (header->e_phnum == PN_XNUM
6263 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
6264 {
6265 /* Throw away any cached read of PN_XNUM headers. */
6266 free (filedata->program_headers);
6267 filedata->program_headers = NULL;
6268 header->e_phnum = filedata->section_headers[0].sh_info;
6269 }
dda8d76d
NC
6270 if (header->e_shnum == SHN_UNDEF)
6271 header->e_shnum = filedata->section_headers[0].sh_size;
6272 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
6273 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 6274 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 6275 header->e_shstrndx = SHN_UNDEF;
252b5132 6276 }
103f02d3 6277
015dc7e1 6278 return true;
9ea033b2
NC
6279}
6280
dda8d76d
NC
6281/* Read in the program headers from FILEDATA and store them in PHEADERS.
6282 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
6283
015dc7e1 6284static bool
dda8d76d 6285get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6286{
2cf0635d
NC
6287 Elf32_External_Phdr * phdrs;
6288 Elf32_External_Phdr * external;
6289 Elf_Internal_Phdr * internal;
b34976b6 6290 unsigned int i;
dda8d76d
NC
6291 unsigned int size = filedata->file_header.e_phentsize;
6292 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6293
6294 /* PR binutils/17531: Cope with unexpected section header sizes. */
6295 if (size == 0 || num == 0)
015dc7e1 6296 return false;
e0a31db1
NC
6297 if (size < sizeof * phdrs)
6298 {
6299 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6300 return false;
e0a31db1
NC
6301 }
6302 if (size > sizeof * phdrs)
6303 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6304
dda8d76d 6305 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
6306 size, num, _("program headers"));
6307 if (phdrs == NULL)
015dc7e1 6308 return false;
9ea033b2 6309
91d6fa6a 6310 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6311 i < filedata->file_header.e_phnum;
b34976b6 6312 i++, internal++, external++)
252b5132 6313 {
9ea033b2
NC
6314 internal->p_type = BYTE_GET (external->p_type);
6315 internal->p_offset = BYTE_GET (external->p_offset);
6316 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6317 internal->p_paddr = BYTE_GET (external->p_paddr);
6318 internal->p_filesz = BYTE_GET (external->p_filesz);
6319 internal->p_memsz = BYTE_GET (external->p_memsz);
6320 internal->p_flags = BYTE_GET (external->p_flags);
6321 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
6322 }
6323
9ea033b2 6324 free (phdrs);
015dc7e1 6325 return true;
252b5132
RH
6326}
6327
dda8d76d
NC
6328/* Read in the program headers from FILEDATA and store them in PHEADERS.
6329 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
6330
015dc7e1 6331static bool
dda8d76d 6332get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6333{
2cf0635d
NC
6334 Elf64_External_Phdr * phdrs;
6335 Elf64_External_Phdr * external;
6336 Elf_Internal_Phdr * internal;
b34976b6 6337 unsigned int i;
dda8d76d
NC
6338 unsigned int size = filedata->file_header.e_phentsize;
6339 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6340
6341 /* PR binutils/17531: Cope with unexpected section header sizes. */
6342 if (size == 0 || num == 0)
015dc7e1 6343 return false;
e0a31db1
NC
6344 if (size < sizeof * phdrs)
6345 {
6346 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6347 return false;
e0a31db1
NC
6348 }
6349 if (size > sizeof * phdrs)
6350 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6351
dda8d76d 6352 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 6353 size, num, _("program headers"));
a6e9f9df 6354 if (!phdrs)
015dc7e1 6355 return false;
9ea033b2 6356
91d6fa6a 6357 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6358 i < filedata->file_header.e_phnum;
b34976b6 6359 i++, internal++, external++)
9ea033b2
NC
6360 {
6361 internal->p_type = BYTE_GET (external->p_type);
6362 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
6363 internal->p_offset = BYTE_GET (external->p_offset);
6364 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6365 internal->p_paddr = BYTE_GET (external->p_paddr);
6366 internal->p_filesz = BYTE_GET (external->p_filesz);
6367 internal->p_memsz = BYTE_GET (external->p_memsz);
6368 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
6369 }
6370
6371 free (phdrs);
015dc7e1 6372 return true;
9ea033b2 6373}
252b5132 6374
32ec8896 6375/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 6376
015dc7e1 6377static bool
dda8d76d 6378get_program_headers (Filedata * filedata)
d93f0186 6379{
2cf0635d 6380 Elf_Internal_Phdr * phdrs;
d93f0186
NC
6381
6382 /* Check cache of prior read. */
dda8d76d 6383 if (filedata->program_headers != NULL)
015dc7e1 6384 return true;
d93f0186 6385
82156ab7
NC
6386 /* Be kind to memory checkers by looking for
6387 e_phnum values which we know must be invalid. */
dda8d76d 6388 if (filedata->file_header.e_phnum
82156ab7 6389 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 6390 >= filedata->file_size)
82156ab7
NC
6391 {
6392 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 6393 filedata->file_header.e_phnum);
015dc7e1 6394 return false;
82156ab7 6395 }
d93f0186 6396
dda8d76d 6397 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 6398 sizeof (Elf_Internal_Phdr));
d93f0186
NC
6399 if (phdrs == NULL)
6400 {
8b73c356 6401 error (_("Out of memory reading %u program headers\n"),
dda8d76d 6402 filedata->file_header.e_phnum);
015dc7e1 6403 return false;
d93f0186
NC
6404 }
6405
6406 if (is_32bit_elf
dda8d76d
NC
6407 ? get_32bit_program_headers (filedata, phdrs)
6408 : get_64bit_program_headers (filedata, phdrs))
d93f0186 6409 {
dda8d76d 6410 filedata->program_headers = phdrs;
015dc7e1 6411 return true;
d93f0186
NC
6412 }
6413
6414 free (phdrs);
015dc7e1 6415 return false;
d93f0186
NC
6416}
6417
93df3340 6418/* Print program header info and locate dynamic section. */
2f62977e 6419
93df3340 6420static void
dda8d76d 6421process_program_headers (Filedata * filedata)
252b5132 6422{
2cf0635d 6423 Elf_Internal_Phdr * segment;
b34976b6 6424 unsigned int i;
1a9ccd70 6425 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6426
dda8d76d 6427 if (filedata->file_header.e_phnum == 0)
252b5132 6428 {
82f2dbf7 6429 /* PR binutils/12467. */
dda8d76d 6430 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6431 warn (_("possibly corrupt ELF header - it has a non-zero program"
6432 " header offset, but no program headers\n"));
82f2dbf7 6433 else if (do_segments)
ca0e11aa
NC
6434 {
6435 if (filedata->is_separate)
6436 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6437 filedata->file_name);
6438 else
6439 printf (_("\nThere are no program headers in this file.\n"));
6440 }
93df3340 6441 goto no_headers;
252b5132
RH
6442 }
6443
6444 if (do_segments && !do_header)
6445 {
ca0e11aa
NC
6446 if (filedata->is_separate)
6447 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6448 filedata->file_name, get_file_type (filedata));
ca0e11aa 6449 else
93df3340 6450 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6451 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6452 filedata->file_header.e_entry);
b8281767
AM
6453 printf (ngettext ("There is %d program header,"
6454 " starting at offset %" PRIu64 "\n",
6455 "There are %d program headers,"
6456 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6457 filedata->file_header.e_phnum),
6458 filedata->file_header.e_phnum,
625d49fc 6459 filedata->file_header.e_phoff);
252b5132
RH
6460 }
6461
dda8d76d 6462 if (! get_program_headers (filedata))
93df3340 6463 goto no_headers;
103f02d3 6464
252b5132
RH
6465 if (do_segments)
6466 {
dda8d76d 6467 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6468 printf (_("\nProgram Headers:\n"));
6469 else
6470 printf (_("\nProgram Headers:\n"));
76da6bbe 6471
f7a99963
NC
6472 if (is_32bit_elf)
6473 printf
6474 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6475 else if (do_wide)
6476 printf
6477 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6478 else
6479 {
6480 printf
6481 (_(" Type Offset VirtAddr PhysAddr\n"));
6482 printf
6483 (_(" FileSiz MemSiz Flags Align\n"));
6484 }
252b5132
RH
6485 }
6486
26c527e6 6487 uint64_t dynamic_addr = 0;
be7d229a 6488 uint64_t dynamic_size = 0;
dda8d76d
NC
6489 for (i = 0, segment = filedata->program_headers;
6490 i < filedata->file_header.e_phnum;
b34976b6 6491 i++, segment++)
252b5132
RH
6492 {
6493 if (do_segments)
6494 {
dda8d76d 6495 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6496
6497 if (is_32bit_elf)
6498 {
6499 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6500 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6501 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6502 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6503 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6504 printf ("%c%c%c ",
6505 (segment->p_flags & PF_R ? 'R' : ' '),
6506 (segment->p_flags & PF_W ? 'W' : ' '),
6507 (segment->p_flags & PF_X ? 'E' : ' '));
6508 printf ("%#lx", (unsigned long) segment->p_align);
6509 }
d974e256
JJ
6510 else if (do_wide)
6511 {
6512 if ((unsigned long) segment->p_offset == segment->p_offset)
6513 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6514 else
6515 {
6516 print_vma (segment->p_offset, FULL_HEX);
6517 putchar (' ');
6518 }
6519
6520 print_vma (segment->p_vaddr, FULL_HEX);
6521 putchar (' ');
6522 print_vma (segment->p_paddr, FULL_HEX);
6523 putchar (' ');
6524
6525 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6526 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6527 else
6528 {
6529 print_vma (segment->p_filesz, FULL_HEX);
6530 putchar (' ');
6531 }
6532
6533 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6534 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6535 else
6536 {
f48e6c45 6537 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6538 }
6539
6540 printf (" %c%c%c ",
6541 (segment->p_flags & PF_R ? 'R' : ' '),
6542 (segment->p_flags & PF_W ? 'W' : ' '),
6543 (segment->p_flags & PF_X ? 'E' : ' '));
6544
6545 if ((unsigned long) segment->p_align == segment->p_align)
6546 printf ("%#lx", (unsigned long) segment->p_align);
6547 else
6548 {
6549 print_vma (segment->p_align, PREFIX_HEX);
6550 }
6551 }
f7a99963
NC
6552 else
6553 {
6554 print_vma (segment->p_offset, FULL_HEX);
6555 putchar (' ');
6556 print_vma (segment->p_vaddr, FULL_HEX);
6557 putchar (' ');
6558 print_vma (segment->p_paddr, FULL_HEX);
6559 printf ("\n ");
6560 print_vma (segment->p_filesz, FULL_HEX);
6561 putchar (' ');
6562 print_vma (segment->p_memsz, FULL_HEX);
6563 printf (" %c%c%c ",
6564 (segment->p_flags & PF_R ? 'R' : ' '),
6565 (segment->p_flags & PF_W ? 'W' : ' '),
6566 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6567 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6568 }
252b5132 6569
1a9ccd70
NC
6570 putc ('\n', stdout);
6571 }
f54498b4 6572
252b5132
RH
6573 switch (segment->p_type)
6574 {
1a9ccd70 6575 case PT_LOAD:
502d895c
NC
6576#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6577 required by the ELF standard, several programs, including the Linux
6578 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6579 if (previous_load
6580 && previous_load->p_vaddr > segment->p_vaddr)
6581 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6582#endif
1a9ccd70
NC
6583 if (segment->p_memsz < segment->p_filesz)
6584 error (_("the segment's file size is larger than its memory size\n"));
6585 previous_load = segment;
6586 break;
6587
6588 case PT_PHDR:
6589 /* PR 20815 - Verify that the program header is loaded into memory. */
6590 if (i > 0 && previous_load != NULL)
6591 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6592 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6593 {
6594 unsigned int j;
6595
dda8d76d 6596 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6597 {
6598 Elf_Internal_Phdr *load = filedata->program_headers + j;
6599 if (load->p_type == PT_LOAD
6600 && load->p_offset <= segment->p_offset
6601 && (load->p_offset + load->p_filesz
6602 >= segment->p_offset + segment->p_filesz)
6603 && load->p_vaddr <= segment->p_vaddr
6604 && (load->p_vaddr + load->p_filesz
6605 >= segment->p_vaddr + segment->p_filesz))
6606 break;
6607 }
dda8d76d 6608 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6609 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6610 }
6611 break;
6612
252b5132 6613 case PT_DYNAMIC:
93df3340 6614 if (dynamic_addr)
252b5132
RH
6615 error (_("more than one dynamic segment\n"));
6616
20737c13
AM
6617 /* By default, assume that the .dynamic section is the first
6618 section in the DYNAMIC segment. */
93df3340
AM
6619 dynamic_addr = segment->p_offset;
6620 dynamic_size = segment->p_filesz;
20737c13 6621
b2d38a17
NC
6622 /* Try to locate the .dynamic section. If there is
6623 a section header table, we can easily locate it. */
dda8d76d 6624 if (filedata->section_headers != NULL)
b2d38a17 6625 {
2cf0635d 6626 Elf_Internal_Shdr * sec;
b2d38a17 6627
dda8d76d 6628 sec = find_section (filedata, ".dynamic");
89fac5e3 6629 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6630 {
93df3340
AM
6631 /* A corresponding .dynamic section is expected, but on
6632 IA-64/OpenVMS it is OK for it to be missing. */
6633 if (!is_ia64_vms (filedata))
6634 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6635 break;
6636 }
6637
42bb2e33 6638 if (sec->sh_type == SHT_NOBITS)
20737c13 6639 {
93df3340
AM
6640 dynamic_addr = 0;
6641 dynamic_size = 0;
20737c13
AM
6642 break;
6643 }
42bb2e33 6644
93df3340
AM
6645 dynamic_addr = sec->sh_offset;
6646 dynamic_size = sec->sh_size;
b2d38a17 6647
8ac10c5b
L
6648 /* The PT_DYNAMIC segment, which is used by the run-time
6649 loader, should exactly match the .dynamic section. */
6650 if (do_checks
93df3340
AM
6651 && (dynamic_addr != segment->p_offset
6652 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6653 warn (_("\
6654the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6655 }
39e224f6
MW
6656
6657 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6658 segment. Check this after matching against the section headers
6659 so we don't warn on debuginfo file (which have NOBITS .dynamic
6660 sections). */
93df3340
AM
6661 if (dynamic_addr > filedata->file_size
6662 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6663 {
6664 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6665 dynamic_addr = 0;
6666 dynamic_size = 0;
39e224f6 6667 }
252b5132
RH
6668 break;
6669
6670 case PT_INTERP:
13acb58d
AM
6671 if (segment->p_offset >= filedata->file_size
6672 || segment->p_filesz > filedata->file_size - segment->p_offset
6673 || segment->p_filesz - 1 >= (size_t) -2
63cf857e
AM
6674 || fseek64 (filedata->handle,
6675 filedata->archive_file_offset + segment->p_offset,
6676 SEEK_SET))
252b5132
RH
6677 error (_("Unable to find program interpreter name\n"));
6678 else
6679 {
13acb58d
AM
6680 size_t len = segment->p_filesz;
6681 free (filedata->program_interpreter);
6682 filedata->program_interpreter = xmalloc (len + 1);
6683 len = fread (filedata->program_interpreter, 1, len,
6684 filedata->handle);
6685 filedata->program_interpreter[len] = 0;
252b5132
RH
6686
6687 if (do_segments)
f54498b4 6688 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6689 filedata->program_interpreter);
252b5132
RH
6690 }
6691 break;
6692 }
252b5132
RH
6693 }
6694
dda8d76d
NC
6695 if (do_segments
6696 && filedata->section_headers != NULL
6697 && filedata->string_table != NULL)
252b5132
RH
6698 {
6699 printf (_("\n Section to Segment mapping:\n"));
6700 printf (_(" Segment Sections...\n"));
6701
dda8d76d 6702 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6703 {
9ad5cbcf 6704 unsigned int j;
2cf0635d 6705 Elf_Internal_Shdr * section;
252b5132 6706
dda8d76d
NC
6707 segment = filedata->program_headers + i;
6708 section = filedata->section_headers + 1;
252b5132
RH
6709
6710 printf (" %2.2d ", i);
6711
dda8d76d 6712 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6713 {
f4638467
AM
6714 if (!ELF_TBSS_SPECIAL (section, segment)
6715 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6716 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6717 }
6718
6719 putc ('\n',stdout);
6720 }
6721 }
6722
93df3340
AM
6723 filedata->dynamic_addr = dynamic_addr;
6724 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6725 return;
6726
6727 no_headers:
6728 filedata->dynamic_addr = 0;
6729 filedata->dynamic_size = 1;
252b5132
RH
6730}
6731
6732
d93f0186
NC
6733/* Find the file offset corresponding to VMA by using the program headers. */
6734
26c527e6 6735static int64_t
625d49fc 6736offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 6737{
2cf0635d 6738 Elf_Internal_Phdr * seg;
d93f0186 6739
dda8d76d 6740 if (! get_program_headers (filedata))
d93f0186
NC
6741 {
6742 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6743 return (long) vma;
6744 }
6745
dda8d76d
NC
6746 for (seg = filedata->program_headers;
6747 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6748 ++seg)
6749 {
6750 if (seg->p_type != PT_LOAD)
6751 continue;
6752
6753 if (vma >= (seg->p_vaddr & -seg->p_align)
6754 && vma + size <= seg->p_vaddr + seg->p_filesz)
6755 return vma - seg->p_vaddr + seg->p_offset;
6756 }
6757
26c527e6
AM
6758 warn (_("Virtual address %#" PRIx64
6759 " not located in any PT_LOAD segment.\n"), vma);
6760 return vma;
d93f0186
NC
6761}
6762
6763
dda8d76d
NC
6764/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6765 If PROBE is true, this is just a probe and we do not generate any error
6766 messages if the load fails. */
049b0c3a 6767
015dc7e1
AM
6768static bool
6769get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6770{
2cf0635d
NC
6771 Elf32_External_Shdr * shdrs;
6772 Elf_Internal_Shdr * internal;
dda8d76d
NC
6773 unsigned int i;
6774 unsigned int size = filedata->file_header.e_shentsize;
6775 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6776
6777 /* PR binutils/17531: Cope with unexpected section header sizes. */
6778 if (size == 0 || num == 0)
015dc7e1 6779 return false;
907b52f4
NC
6780
6781 /* The section header cannot be at the start of the file - that is
6782 where the ELF file header is located. A file with absolutely no
6783 sections in it will use a shoff of 0. */
6784 if (filedata->file_header.e_shoff == 0)
6785 return false;
6786
049b0c3a
NC
6787 if (size < sizeof * shdrs)
6788 {
6789 if (! probe)
6790 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6791 return false;
049b0c3a
NC
6792 }
6793 if (!probe && size > sizeof * shdrs)
6794 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6795
dda8d76d 6796 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6797 size, num,
6798 probe ? NULL : _("section headers"));
6799 if (shdrs == NULL)
015dc7e1 6800 return false;
252b5132 6801
dda8d76d
NC
6802 filedata->section_headers = (Elf_Internal_Shdr *)
6803 cmalloc (num, sizeof (Elf_Internal_Shdr));
6804 if (filedata->section_headers == NULL)
252b5132 6805 {
049b0c3a 6806 if (!probe)
8b73c356 6807 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6808 free (shdrs);
015dc7e1 6809 return false;
252b5132
RH
6810 }
6811
dda8d76d 6812 for (i = 0, internal = filedata->section_headers;
560f3c1c 6813 i < num;
b34976b6 6814 i++, internal++)
252b5132
RH
6815 {
6816 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6817 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6818 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6819 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6820 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6821 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6822 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6823 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6824 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6825 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6826 if (!probe && internal->sh_link > num)
6827 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6828 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6829 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6830 }
6831
6832 free (shdrs);
015dc7e1 6833 return true;
252b5132
RH
6834}
6835
dda8d76d
NC
6836/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6837
015dc7e1
AM
6838static bool
6839get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6840{
dda8d76d
NC
6841 Elf64_External_Shdr * shdrs;
6842 Elf_Internal_Shdr * internal;
6843 unsigned int i;
6844 unsigned int size = filedata->file_header.e_shentsize;
6845 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6846
6847 /* PR binutils/17531: Cope with unexpected section header sizes. */
6848 if (size == 0 || num == 0)
015dc7e1 6849 return false;
dda8d76d 6850
907b52f4
NC
6851 /* The section header cannot be at the start of the file - that is
6852 where the ELF file header is located. A file with absolutely no
6853 sections in it will use a shoff of 0. */
6854 if (filedata->file_header.e_shoff == 0)
6855 return false;
6856
049b0c3a
NC
6857 if (size < sizeof * shdrs)
6858 {
6859 if (! probe)
6860 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6861 return false;
049b0c3a 6862 }
dda8d76d 6863
049b0c3a
NC
6864 if (! probe && size > sizeof * shdrs)
6865 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6866
dda8d76d
NC
6867 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6868 filedata->file_header.e_shoff,
049b0c3a
NC
6869 size, num,
6870 probe ? NULL : _("section headers"));
6871 if (shdrs == NULL)
015dc7e1 6872 return false;
9ea033b2 6873
dda8d76d
NC
6874 filedata->section_headers = (Elf_Internal_Shdr *)
6875 cmalloc (num, sizeof (Elf_Internal_Shdr));
6876 if (filedata->section_headers == NULL)
9ea033b2 6877 {
049b0c3a 6878 if (! probe)
8b73c356 6879 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6880 free (shdrs);
015dc7e1 6881 return false;
9ea033b2
NC
6882 }
6883
dda8d76d 6884 for (i = 0, internal = filedata->section_headers;
560f3c1c 6885 i < num;
b34976b6 6886 i++, internal++)
9ea033b2
NC
6887 {
6888 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6889 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6890 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6891 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6892 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6893 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6894 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6895 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6896 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6897 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6898 if (!probe && internal->sh_link > num)
6899 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6900 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6901 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6902 }
6903
6904 free (shdrs);
015dc7e1 6905 return true;
9ea033b2
NC
6906}
6907
4de91c10
AM
6908static bool
6909get_section_headers (Filedata *filedata, bool probe)
6910{
6911 if (filedata->section_headers != NULL)
6912 return true;
6913
4de91c10
AM
6914 if (is_32bit_elf)
6915 return get_32bit_section_headers (filedata, probe);
6916 else
6917 return get_64bit_section_headers (filedata, probe);
6918}
6919
252b5132 6920static Elf_Internal_Sym *
26c527e6
AM
6921get_32bit_elf_symbols (Filedata *filedata,
6922 Elf_Internal_Shdr *section,
6923 uint64_t *num_syms_return)
252b5132 6924{
26c527e6 6925 uint64_t number = 0;
dd24e3da 6926 Elf32_External_Sym * esyms = NULL;
ba5cdace 6927 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6928 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6929 Elf_Internal_Sym * psym;
b34976b6 6930 unsigned int j;
e3d39609 6931 elf_section_list * entry;
252b5132 6932
c9c1d674
EG
6933 if (section->sh_size == 0)
6934 {
6935 if (num_syms_return != NULL)
6936 * num_syms_return = 0;
6937 return NULL;
6938 }
6939
dd24e3da 6940 /* Run some sanity checks first. */
c9c1d674 6941 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6942 {
26c527e6 6943 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 6944 printable_section_name (filedata, section),
26c527e6 6945 section->sh_entsize);
ba5cdace 6946 goto exit_point;
dd24e3da
NC
6947 }
6948
dda8d76d 6949 if (section->sh_size > filedata->file_size)
f54498b4 6950 {
26c527e6 6951 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 6952 printable_section_name (filedata, section),
26c527e6 6953 section->sh_size);
f54498b4
NC
6954 goto exit_point;
6955 }
6956
dd24e3da
NC
6957 number = section->sh_size / section->sh_entsize;
6958
6959 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6960 {
26c527e6
AM
6961 error (_("Size (%#" PRIx64 ") of section %s "
6962 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
6963 section->sh_size,
dda8d76d 6964 printable_section_name (filedata, section),
26c527e6 6965 section->sh_entsize);
ba5cdace 6966 goto exit_point;
dd24e3da
NC
6967 }
6968
dda8d76d 6969 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6970 section->sh_size, _("symbols"));
dd24e3da 6971 if (esyms == NULL)
ba5cdace 6972 goto exit_point;
252b5132 6973
e3d39609 6974 shndx = NULL;
978c4450 6975 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 6976 {
26c527e6 6977 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
6978 continue;
6979
6980 if (shndx != NULL)
6981 {
6982 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6983 free (shndx);
6984 }
6985
6986 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6987 entry->hdr->sh_offset,
6988 1, entry->hdr->sh_size,
6989 _("symbol table section indices"));
6990 if (shndx == NULL)
6991 goto exit_point;
6992
6993 /* PR17531: file: heap-buffer-overflow */
6994 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6995 {
26c527e6 6996 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 6997 printable_section_name (filedata, entry->hdr),
26c527e6
AM
6998 entry->hdr->sh_size,
6999 section->sh_size);
e3d39609 7000 goto exit_point;
c9c1d674 7001 }
e3d39609 7002 }
9ad5cbcf 7003
3f5e193b 7004 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
7005
7006 if (isyms == NULL)
7007 {
26c527e6 7008 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
dd24e3da 7009 goto exit_point;
252b5132
RH
7010 }
7011
dd24e3da 7012 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
7013 {
7014 psym->st_name = BYTE_GET (esyms[j].st_name);
7015 psym->st_value = BYTE_GET (esyms[j].st_value);
7016 psym->st_size = BYTE_GET (esyms[j].st_size);
7017 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 7018 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7019 psym->st_shndx
7020 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7021 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7022 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
7023 psym->st_info = BYTE_GET (esyms[j].st_info);
7024 psym->st_other = BYTE_GET (esyms[j].st_other);
7025 }
7026
dd24e3da 7027 exit_point:
e3d39609
NC
7028 free (shndx);
7029 free (esyms);
252b5132 7030
ba5cdace
NC
7031 if (num_syms_return != NULL)
7032 * num_syms_return = isyms == NULL ? 0 : number;
7033
252b5132
RH
7034 return isyms;
7035}
7036
9ea033b2 7037static Elf_Internal_Sym *
26c527e6
AM
7038get_64bit_elf_symbols (Filedata *filedata,
7039 Elf_Internal_Shdr *section,
7040 uint64_t *num_syms_return)
9ea033b2 7041{
26c527e6 7042 uint64_t number = 0;
ba5cdace
NC
7043 Elf64_External_Sym * esyms = NULL;
7044 Elf_External_Sym_Shndx * shndx = NULL;
7045 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7046 Elf_Internal_Sym * psym;
b34976b6 7047 unsigned int j;
e3d39609 7048 elf_section_list * entry;
9ea033b2 7049
c9c1d674
EG
7050 if (section->sh_size == 0)
7051 {
7052 if (num_syms_return != NULL)
7053 * num_syms_return = 0;
7054 return NULL;
7055 }
7056
dd24e3da 7057 /* Run some sanity checks first. */
c9c1d674 7058 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7059 {
26c527e6 7060 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7061 printable_section_name (filedata, section),
26c527e6 7062 section->sh_entsize);
ba5cdace 7063 goto exit_point;
dd24e3da
NC
7064 }
7065
dda8d76d 7066 if (section->sh_size > filedata->file_size)
f54498b4 7067 {
26c527e6 7068 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7069 printable_section_name (filedata, section),
26c527e6 7070 section->sh_size);
f54498b4
NC
7071 goto exit_point;
7072 }
7073
dd24e3da
NC
7074 number = section->sh_size / section->sh_entsize;
7075
7076 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
7077 {
26c527e6
AM
7078 error (_("Size (%#" PRIx64 ") of section %s "
7079 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7080 section->sh_size,
dda8d76d 7081 printable_section_name (filedata, section),
26c527e6 7082 section->sh_entsize);
ba5cdace 7083 goto exit_point;
dd24e3da
NC
7084 }
7085
dda8d76d 7086 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7087 section->sh_size, _("symbols"));
a6e9f9df 7088 if (!esyms)
ba5cdace 7089 goto exit_point;
9ea033b2 7090
e3d39609 7091 shndx = NULL;
978c4450 7092 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7093 {
26c527e6 7094 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7095 continue;
7096
7097 if (shndx != NULL)
7098 {
7099 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7100 free (shndx);
c9c1d674 7101 }
e3d39609
NC
7102
7103 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7104 entry->hdr->sh_offset,
7105 1, entry->hdr->sh_size,
7106 _("symbol table section indices"));
7107 if (shndx == NULL)
7108 goto exit_point;
7109
7110 /* PR17531: file: heap-buffer-overflow */
7111 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7112 {
26c527e6 7113 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7114 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7115 entry->hdr->sh_size,
7116 section->sh_size);
e3d39609
NC
7117 goto exit_point;
7118 }
7119 }
9ad5cbcf 7120
3f5e193b 7121 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
7122
7123 if (isyms == NULL)
7124 {
26c527e6 7125 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
ba5cdace 7126 goto exit_point;
9ea033b2
NC
7127 }
7128
ba5cdace 7129 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
7130 {
7131 psym->st_name = BYTE_GET (esyms[j].st_name);
7132 psym->st_info = BYTE_GET (esyms[j].st_info);
7133 psym->st_other = BYTE_GET (esyms[j].st_other);
7134 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 7135
4fbb74a6 7136 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7137 psym->st_shndx
7138 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7139 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7140 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 7141
66543521
AM
7142 psym->st_value = BYTE_GET (esyms[j].st_value);
7143 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
7144 }
7145
ba5cdace 7146 exit_point:
e3d39609
NC
7147 free (shndx);
7148 free (esyms);
ba5cdace
NC
7149
7150 if (num_syms_return != NULL)
7151 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
7152
7153 return isyms;
7154}
7155
4de91c10
AM
7156static Elf_Internal_Sym *
7157get_elf_symbols (Filedata *filedata,
7158 Elf_Internal_Shdr *section,
26c527e6 7159 uint64_t *num_syms_return)
4de91c10
AM
7160{
7161 if (is_32bit_elf)
7162 return get_32bit_elf_symbols (filedata, section, num_syms_return);
7163 else
7164 return get_64bit_elf_symbols (filedata, section, num_syms_return);
7165}
7166
d1133906 7167static const char *
625d49fc 7168get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 7169{
5477e8a0 7170 static char buff[1024];
2cf0635d 7171 char * p = buff;
32ec8896
NC
7172 unsigned int field_size = is_32bit_elf ? 8 : 16;
7173 signed int sindex;
7174 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
7175 uint64_t os_flags = 0;
7176 uint64_t proc_flags = 0;
7177 uint64_t unknown_flags = 0;
148b93f2 7178 static const struct
5477e8a0 7179 {
2cf0635d 7180 const char * str;
32ec8896 7181 unsigned int len;
5477e8a0
L
7182 }
7183 flags [] =
7184 {
cfcac11d
NC
7185 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
7186 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
7187 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
7188 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
7189 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
7190 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
7191 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
7192 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
7193 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
7194 /* 9 */ { STRING_COMMA_LEN ("TLS") },
7195 /* IA-64 specific. */
7196 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
7197 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
7198 /* IA-64 OpenVMS specific. */
7199 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
7200 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
7201 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
7202 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
7203 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
7204 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 7205 /* Generic. */
cfcac11d 7206 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 7207 /* SPARC specific. */
77115a4a 7208 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
7209 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
7210 /* ARM specific. */
7211 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 7212 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
7213 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
7214 /* GNU specific. */
7215 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
7216 /* VLE specific. */
7217 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
7218 /* GNU specific. */
7219 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
7220 };
7221
7222 if (do_section_details)
f8c4789c
AM
7223 p += sprintf (p, "[%*.*lx]: ",
7224 field_size, field_size, (unsigned long) sh_flags);
76da6bbe 7225
d1133906
NC
7226 while (sh_flags)
7227 {
625d49fc 7228 uint64_t flag;
d1133906
NC
7229
7230 flag = sh_flags & - sh_flags;
7231 sh_flags &= ~ flag;
76da6bbe 7232
5477e8a0 7233 if (do_section_details)
d1133906 7234 {
5477e8a0
L
7235 switch (flag)
7236 {
91d6fa6a
NC
7237 case SHF_WRITE: sindex = 0; break;
7238 case SHF_ALLOC: sindex = 1; break;
7239 case SHF_EXECINSTR: sindex = 2; break;
7240 case SHF_MERGE: sindex = 3; break;
7241 case SHF_STRINGS: sindex = 4; break;
7242 case SHF_INFO_LINK: sindex = 5; break;
7243 case SHF_LINK_ORDER: sindex = 6; break;
7244 case SHF_OS_NONCONFORMING: sindex = 7; break;
7245 case SHF_GROUP: sindex = 8; break;
7246 case SHF_TLS: sindex = 9; break;
18ae9cc1 7247 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 7248 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 7249
5477e8a0 7250 default:
91d6fa6a 7251 sindex = -1;
dda8d76d 7252 switch (filedata->file_header.e_machine)
148b93f2 7253 {
cfcac11d 7254 case EM_IA_64:
148b93f2 7255 if (flag == SHF_IA_64_SHORT)
91d6fa6a 7256 sindex = 10;
148b93f2 7257 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 7258 sindex = 11;
dda8d76d 7259 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
7260 switch (flag)
7261 {
91d6fa6a
NC
7262 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
7263 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
7264 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
7265 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
7266 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
7267 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
7268 default: break;
7269 }
cfcac11d
NC
7270 break;
7271
caa83f8b 7272 case EM_386:
22abe556 7273 case EM_IAMCU:
caa83f8b 7274 case EM_X86_64:
7f502d6c 7275 case EM_L1OM:
7a9068fe 7276 case EM_K1OM:
cfcac11d
NC
7277 case EM_OLD_SPARCV9:
7278 case EM_SPARC32PLUS:
7279 case EM_SPARCV9:
7280 case EM_SPARC:
18ae9cc1 7281 if (flag == SHF_ORDERED)
91d6fa6a 7282 sindex = 19;
cfcac11d 7283 break;
ac4c9b04
MG
7284
7285 case EM_ARM:
7286 switch (flag)
7287 {
7288 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 7289 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
7290 case SHF_COMDEF: sindex = 23; break;
7291 default: break;
7292 }
7293 break;
83eef883
AFB
7294 case EM_PPC:
7295 if (flag == SHF_PPC_VLE)
7296 sindex = 25;
7297 break;
99fabbc9
JL
7298 default:
7299 break;
7300 }
ac4c9b04 7301
99fabbc9
JL
7302 switch (filedata->file_header.e_ident[EI_OSABI])
7303 {
7304 case ELFOSABI_GNU:
7305 case ELFOSABI_FREEBSD:
7306 if (flag == SHF_GNU_RETAIN)
7307 sindex = 26;
7308 /* Fall through */
7309 case ELFOSABI_NONE:
7310 if (flag == SHF_GNU_MBIND)
7311 /* We should not recognize SHF_GNU_MBIND for
7312 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7313 not set the EI_OSABI header byte. */
7314 sindex = 24;
7315 break;
cfcac11d
NC
7316 default:
7317 break;
148b93f2 7318 }
99fabbc9 7319 break;
5477e8a0
L
7320 }
7321
91d6fa6a 7322 if (sindex != -1)
5477e8a0 7323 {
8d5ff12c
L
7324 if (p != buff + field_size + 4)
7325 {
7326 if (size < (10 + 2))
bee0ee85
NC
7327 {
7328 warn (_("Internal error: not enough buffer room for section flag info"));
7329 return _("<unknown>");
7330 }
8d5ff12c
L
7331 size -= 2;
7332 *p++ = ',';
7333 *p++ = ' ';
7334 }
7335
91d6fa6a
NC
7336 size -= flags [sindex].len;
7337 p = stpcpy (p, flags [sindex].str);
5477e8a0 7338 }
3b22753a 7339 else if (flag & SHF_MASKOS)
8d5ff12c 7340 os_flags |= flag;
d1133906 7341 else if (flag & SHF_MASKPROC)
8d5ff12c 7342 proc_flags |= flag;
d1133906 7343 else
8d5ff12c 7344 unknown_flags |= flag;
5477e8a0
L
7345 }
7346 else
7347 {
7348 switch (flag)
7349 {
7350 case SHF_WRITE: *p = 'W'; break;
7351 case SHF_ALLOC: *p = 'A'; break;
7352 case SHF_EXECINSTR: *p = 'X'; break;
7353 case SHF_MERGE: *p = 'M'; break;
7354 case SHF_STRINGS: *p = 'S'; break;
7355 case SHF_INFO_LINK: *p = 'I'; break;
7356 case SHF_LINK_ORDER: *p = 'L'; break;
7357 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7358 case SHF_GROUP: *p = 'G'; break;
7359 case SHF_TLS: *p = 'T'; break;
18ae9cc1 7360 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 7361 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
7362
7363 default:
dda8d76d
NC
7364 if ((filedata->file_header.e_machine == EM_X86_64
7365 || filedata->file_header.e_machine == EM_L1OM
7366 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
7367 && flag == SHF_X86_64_LARGE)
7368 *p = 'l';
dda8d76d 7369 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 7370 && flag == SHF_ARM_PURECODE)
99fabbc9 7371 *p = 'y';
dda8d76d 7372 else if (filedata->file_header.e_machine == EM_PPC
83eef883 7373 && flag == SHF_PPC_VLE)
99fabbc9 7374 *p = 'v';
5477e8a0
L
7375 else if (flag & SHF_MASKOS)
7376 {
99fabbc9
JL
7377 switch (filedata->file_header.e_ident[EI_OSABI])
7378 {
7379 case ELFOSABI_GNU:
7380 case ELFOSABI_FREEBSD:
7381 if (flag == SHF_GNU_RETAIN)
7382 {
7383 *p = 'R';
7384 break;
7385 }
7386 /* Fall through */
7387 case ELFOSABI_NONE:
7388 if (flag == SHF_GNU_MBIND)
7389 {
7390 /* We should not recognize SHF_GNU_MBIND for
7391 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7392 not set the EI_OSABI header byte. */
7393 *p = 'D';
7394 break;
7395 }
7396 /* Fall through */
7397 default:
7398 *p = 'o';
7399 sh_flags &= ~SHF_MASKOS;
7400 break;
7401 }
5477e8a0
L
7402 }
7403 else if (flag & SHF_MASKPROC)
7404 {
7405 *p = 'p';
7406 sh_flags &= ~ SHF_MASKPROC;
7407 }
7408 else
7409 *p = 'x';
7410 break;
7411 }
7412 p++;
d1133906
NC
7413 }
7414 }
76da6bbe 7415
8d5ff12c
L
7416 if (do_section_details)
7417 {
7418 if (os_flags)
7419 {
8d5ff12c
L
7420 if (p != buff + field_size + 4)
7421 {
f8c4789c 7422 if (size < 2 + 5 + field_size + 1)
bee0ee85
NC
7423 {
7424 warn (_("Internal error: not enough buffer room for section flag info"));
7425 return _("<unknown>");
7426 }
8d5ff12c
L
7427 size -= 2;
7428 *p++ = ',';
7429 *p++ = ' ';
7430 }
f8c4789c
AM
7431 size -= 5 + field_size;
7432 p += sprintf (p, "OS (%*.*lx)", field_size, field_size,
7433 (unsigned long) os_flags);
8d5ff12c
L
7434 }
7435 if (proc_flags)
7436 {
8d5ff12c
L
7437 if (p != buff + field_size + 4)
7438 {
f8c4789c 7439 if (size < 2 + 7 + field_size + 1)
bee0ee85
NC
7440 {
7441 warn (_("Internal error: not enough buffer room for section flag info"));
7442 return _("<unknown>");
7443 }
8d5ff12c
L
7444 size -= 2;
7445 *p++ = ',';
7446 *p++ = ' ';
7447 }
f8c4789c
AM
7448 size -= 7 + field_size;
7449 p += sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7450 (unsigned long) proc_flags);
8d5ff12c
L
7451 }
7452 if (unknown_flags)
7453 {
8d5ff12c
L
7454 if (p != buff + field_size + 4)
7455 {
f8c4789c 7456 if (size < 2 + 10 + field_size + 1)
bee0ee85
NC
7457 {
7458 warn (_("Internal error: not enough buffer room for section flag info"));
7459 return _("<unknown>");
7460 }
8d5ff12c
L
7461 size -= 2;
7462 *p++ = ',';
7463 *p++ = ' ';
7464 }
f8c4789c
AM
7465 size -= 10 + field_size;
7466 p += sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
7467 (unsigned long) unknown_flags);
8d5ff12c
L
7468 }
7469 }
7470
e9e44622 7471 *p = '\0';
d1133906
NC
7472 return buff;
7473}
7474
5844b465 7475static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7476get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7477 uint64_t size)
77115a4a
L
7478{
7479 if (is_32bit_elf)
7480 {
7481 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7482
ebdf1ebf
NC
7483 if (size < sizeof (* echdr))
7484 {
7485 error (_("Compressed section is too small even for a compression header\n"));
7486 return 0;
7487 }
7488
77115a4a
L
7489 chdr->ch_type = BYTE_GET (echdr->ch_type);
7490 chdr->ch_size = BYTE_GET (echdr->ch_size);
7491 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7492 return sizeof (*echdr);
7493 }
7494 else
7495 {
7496 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7497
ebdf1ebf
NC
7498 if (size < sizeof (* echdr))
7499 {
7500 error (_("Compressed section is too small even for a compression header\n"));
7501 return 0;
7502 }
7503
77115a4a
L
7504 chdr->ch_type = BYTE_GET (echdr->ch_type);
7505 chdr->ch_size = BYTE_GET (echdr->ch_size);
7506 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7507 return sizeof (*echdr);
7508 }
7509}
7510
015dc7e1 7511static bool
dda8d76d 7512process_section_headers (Filedata * filedata)
252b5132 7513{
2cf0635d 7514 Elf_Internal_Shdr * section;
b34976b6 7515 unsigned int i;
252b5132 7516
dda8d76d 7517 if (filedata->file_header.e_shnum == 0)
252b5132 7518 {
82f2dbf7 7519 /* PR binutils/12467. */
dda8d76d 7520 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7521 {
7522 warn (_("possibly corrupt ELF file header - it has a non-zero"
7523 " section header offset, but no section headers\n"));
015dc7e1 7524 return false;
32ec8896 7525 }
82f2dbf7 7526 else if (do_sections)
252b5132
RH
7527 printf (_("\nThere are no sections in this file.\n"));
7528
015dc7e1 7529 return true;
252b5132
RH
7530 }
7531
7532 if (do_sections && !do_header)
ca0e11aa
NC
7533 {
7534 if (filedata->is_separate && process_links)
7535 printf (_("In linked file '%s': "), filedata->file_name);
7536 if (! filedata->is_separate || process_links)
7537 printf (ngettext ("There is %d section header, "
26c527e6 7538 "starting at offset %#" PRIx64 ":\n",
ca0e11aa 7539 "There are %d section headers, "
26c527e6 7540 "starting at offset %#" PRIx64 ":\n",
ca0e11aa
NC
7541 filedata->file_header.e_shnum),
7542 filedata->file_header.e_shnum,
26c527e6 7543 filedata->file_header.e_shoff);
ca0e11aa 7544 }
252b5132 7545
4de91c10
AM
7546 if (!get_section_headers (filedata, false))
7547 return false;
252b5132
RH
7548
7549 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7550 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7551 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7552 {
dda8d76d 7553 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7554
c256ffe7
JJ
7555 if (section->sh_size != 0)
7556 {
dda8d76d
NC
7557 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7558 1, section->sh_size,
7559 _("string table"));
0de14b54 7560
dda8d76d 7561 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7562 }
252b5132
RH
7563 }
7564
7565 /* Scan the sections for the dynamic symbol table
e3c8793a 7566 and dynamic string table and debug sections. */
89fac5e3 7567 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7568 switch (filedata->file_header.e_machine)
89fac5e3
RS
7569 {
7570 case EM_MIPS:
7571 case EM_MIPS_RS3_LE:
7572 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7573 FDE addresses. However, the ABI also has a semi-official ILP32
7574 variant for which the normal FDE address size rules apply.
7575
7576 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7577 section, where XX is the size of longs in bits. Unfortunately,
7578 earlier compilers provided no way of distinguishing ILP32 objects
7579 from LP64 objects, so if there's any doubt, we should assume that
7580 the official LP64 form is being used. */
dda8d76d
NC
7581 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7582 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7583 eh_addr_size = 8;
7584 break;
0f56a26a
DD
7585
7586 case EM_H8_300:
7587 case EM_H8_300H:
dda8d76d 7588 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7589 {
7590 case E_H8_MACH_H8300:
7591 case E_H8_MACH_H8300HN:
7592 case E_H8_MACH_H8300SN:
7593 case E_H8_MACH_H8300SXN:
7594 eh_addr_size = 2;
7595 break;
7596 case E_H8_MACH_H8300H:
7597 case E_H8_MACH_H8300S:
7598 case E_H8_MACH_H8300SX:
7599 eh_addr_size = 4;
7600 break;
7601 }
f4236fe4
DD
7602 break;
7603
ff7eeb89 7604 case EM_M32C_OLD:
f4236fe4 7605 case EM_M32C:
dda8d76d 7606 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7607 {
7608 case EF_M32C_CPU_M16C:
7609 eh_addr_size = 2;
7610 break;
7611 }
7612 break;
89fac5e3
RS
7613 }
7614
76ca31c0
NC
7615#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7616 do \
7617 { \
be7d229a 7618 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7619 if (section->sh_entsize != expected_entsize) \
9dd3a467 7620 { \
f493c217 7621 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7622 i, section->sh_entsize); \
f493c217 7623 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7624 expected_entsize); \
9dd3a467 7625 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7626 } \
7627 } \
08d8fa11 7628 while (0)
9dd3a467
NC
7629
7630#define CHECK_ENTSIZE(section, i, type) \
1b513401 7631 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7632 sizeof (Elf64_External_##type))
7633
dda8d76d
NC
7634 for (i = 0, section = filedata->section_headers;
7635 i < filedata->file_header.e_shnum;
b34976b6 7636 i++, section++)
252b5132 7637 {
84714f86 7638 const char *name = section_name_print (filedata, section);
252b5132 7639
1b513401
NC
7640 /* Run some sanity checks on the headers and
7641 possibly fill in some file data as well. */
7642 switch (section->sh_type)
252b5132 7643 {
1b513401 7644 case SHT_DYNSYM:
978c4450 7645 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7646 {
7647 error (_("File contains multiple dynamic symbol tables\n"));
7648 continue;
7649 }
7650
08d8fa11 7651 CHECK_ENTSIZE (section, i, Sym);
978c4450 7652 filedata->dynamic_symbols
4de91c10 7653 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7654 filedata->dynamic_symtab_section = section;
1b513401
NC
7655 break;
7656
7657 case SHT_STRTAB:
7658 if (streq (name, ".dynstr"))
252b5132 7659 {
1b513401
NC
7660 if (filedata->dynamic_strings != NULL)
7661 {
7662 error (_("File contains multiple dynamic string tables\n"));
7663 continue;
7664 }
7665
7666 filedata->dynamic_strings
7667 = (char *) get_data (NULL, filedata, section->sh_offset,
7668 1, section->sh_size, _("dynamic strings"));
7669 filedata->dynamic_strings_length
7670 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7671 filedata->dynamic_strtab_section = section;
252b5132 7672 }
1b513401
NC
7673 break;
7674
7675 case SHT_SYMTAB_SHNDX:
7676 {
7677 elf_section_list * entry = xmalloc (sizeof * entry);
7678
7679 entry->hdr = section;
7680 entry->next = filedata->symtab_shndx_list;
7681 filedata->symtab_shndx_list = entry;
7682 }
7683 break;
7684
7685 case SHT_SYMTAB:
7686 CHECK_ENTSIZE (section, i, Sym);
7687 break;
7688
7689 case SHT_GROUP:
7690 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7691 break;
252b5132 7692
1b513401
NC
7693 case SHT_REL:
7694 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7695 if (do_checks && section->sh_size == 0)
1b513401
NC
7696 warn (_("Section '%s': zero-sized relocation section\n"), name);
7697 break;
7698
7699 case SHT_RELA:
7700 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7701 if (do_checks && section->sh_size == 0)
1b513401
NC
7702 warn (_("Section '%s': zero-sized relocation section\n"), name);
7703 break;
7704
682351b9
AM
7705 case SHT_RELR:
7706 CHECK_ENTSIZE (section, i, Relr);
7707 break;
7708
1b513401
NC
7709 case SHT_NOTE:
7710 case SHT_PROGBITS:
546cb2d8
NC
7711 /* Having a zero sized section is not illegal according to the
7712 ELF standard, but it might be an indication that something
7713 is wrong. So issue a warning if we are running in lint mode. */
7714 if (do_checks && section->sh_size == 0)
1b513401
NC
7715 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7716 break;
7717
7718 default:
7719 break;
7720 }
7721
7722 if ((do_debugging || do_debug_info || do_debug_abbrevs
7723 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7724 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7725 || do_debug_str || do_debug_str_offsets || do_debug_loc
7726 || do_debug_ranges
1b513401 7727 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7728 && (startswith (name, ".debug_")
7729 || startswith (name, ".zdebug_")))
252b5132 7730 {
1b315056
CS
7731 if (name[1] == 'z')
7732 name += sizeof (".zdebug_") - 1;
7733 else
7734 name += sizeof (".debug_") - 1;
252b5132
RH
7735
7736 if (do_debugging
24d127aa
ML
7737 || (do_debug_info && startswith (name, "info"))
7738 || (do_debug_info && startswith (name, "types"))
7739 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7740 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7741 || (do_debug_lines && startswith (name, "line."))
7742 || (do_debug_pubnames && startswith (name, "pubnames"))
7743 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7744 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7745 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7746 || (do_debug_aranges && startswith (name, "aranges"))
7747 || (do_debug_ranges && startswith (name, "ranges"))
7748 || (do_debug_ranges && startswith (name, "rnglists"))
7749 || (do_debug_frames && startswith (name, "frame"))
7750 || (do_debug_macinfo && startswith (name, "macinfo"))
7751 || (do_debug_macinfo && startswith (name, "macro"))
7752 || (do_debug_str && startswith (name, "str"))
7753 || (do_debug_links && startswith (name, "sup"))
7754 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7755 || (do_debug_loc && startswith (name, "loc"))
7756 || (do_debug_loc && startswith (name, "loclists"))
7757 || (do_debug_addr && startswith (name, "addr"))
7758 || (do_debug_cu_index && startswith (name, "cu_index"))
7759 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7760 )
6431e409 7761 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7762 }
a262ae96 7763 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7764 else if ((do_debugging || do_debug_info)
24d127aa 7765 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7766 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7767 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7768 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7769 else if (do_gdb_index && (streq (name, ".gdb_index")
7770 || streq (name, ".debug_names")))
6431e409 7771 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7772 /* Trace sections for Itanium VMS. */
7773 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7774 || do_trace_aranges)
24d127aa 7775 && startswith (name, ".trace_"))
6f875884
TG
7776 {
7777 name += sizeof (".trace_") - 1;
7778
7779 if (do_debugging
7780 || (do_trace_info && streq (name, "info"))
7781 || (do_trace_abbrevs && streq (name, "abbrev"))
7782 || (do_trace_aranges && streq (name, "aranges"))
7783 )
6431e409 7784 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7785 }
dda8d76d 7786 else if ((do_debugging || do_debug_links)
24d127aa
ML
7787 && (startswith (name, ".gnu_debuglink")
7788 || startswith (name, ".gnu_debugaltlink")))
6431e409 7789 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7790 }
7791
7792 if (! do_sections)
015dc7e1 7793 return true;
252b5132 7794
ca0e11aa 7795 if (filedata->is_separate && ! process_links)
015dc7e1 7796 return true;
ca0e11aa
NC
7797
7798 if (filedata->is_separate)
7799 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7800 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7801 printf (_("\nSection Headers:\n"));
7802 else
7803 printf (_("\nSection Header:\n"));
76da6bbe 7804
f7a99963 7805 if (is_32bit_elf)
595cf52e 7806 {
5477e8a0 7807 if (do_section_details)
595cf52e
L
7808 {
7809 printf (_(" [Nr] Name\n"));
5477e8a0 7810 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7811 }
7812 else
7813 printf
7814 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7815 }
d974e256 7816 else if (do_wide)
595cf52e 7817 {
5477e8a0 7818 if (do_section_details)
595cf52e
L
7819 {
7820 printf (_(" [Nr] Name\n"));
5477e8a0 7821 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7822 }
7823 else
7824 printf
7825 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7826 }
f7a99963
NC
7827 else
7828 {
5477e8a0 7829 if (do_section_details)
595cf52e
L
7830 {
7831 printf (_(" [Nr] Name\n"));
5477e8a0
L
7832 printf (_(" Type Address Offset Link\n"));
7833 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7834 }
7835 else
7836 {
7837 printf (_(" [Nr] Name Type Address Offset\n"));
7838 printf (_(" Size EntSize Flags Link Info Align\n"));
7839 }
f7a99963 7840 }
252b5132 7841
5477e8a0
L
7842 if (do_section_details)
7843 printf (_(" Flags\n"));
7844
dda8d76d
NC
7845 for (i = 0, section = filedata->section_headers;
7846 i < filedata->file_header.e_shnum;
b34976b6 7847 i++, section++)
252b5132 7848 {
dd905818
NC
7849 /* Run some sanity checks on the section header. */
7850
7851 /* Check the sh_link field. */
7852 switch (section->sh_type)
7853 {
285e3f99
AM
7854 case SHT_REL:
7855 case SHT_RELA:
7856 if (section->sh_link == 0
7857 && (filedata->file_header.e_type == ET_EXEC
7858 || filedata->file_header.e_type == ET_DYN))
7859 /* A dynamic relocation section where all entries use a
7860 zero symbol index need not specify a symtab section. */
7861 break;
7862 /* Fall through. */
dd905818
NC
7863 case SHT_SYMTAB_SHNDX:
7864 case SHT_GROUP:
7865 case SHT_HASH:
7866 case SHT_GNU_HASH:
7867 case SHT_GNU_versym:
285e3f99 7868 if (section->sh_link == 0
dda8d76d
NC
7869 || section->sh_link >= filedata->file_header.e_shnum
7870 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7871 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7872 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7873 i, section->sh_link);
7874 break;
7875
7876 case SHT_DYNAMIC:
7877 case SHT_SYMTAB:
7878 case SHT_DYNSYM:
7879 case SHT_GNU_verneed:
7880 case SHT_GNU_verdef:
7881 case SHT_GNU_LIBLIST:
285e3f99 7882 if (section->sh_link == 0
dda8d76d
NC
7883 || section->sh_link >= filedata->file_header.e_shnum
7884 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7885 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7886 i, section->sh_link);
7887 break;
7888
7889 case SHT_INIT_ARRAY:
7890 case SHT_FINI_ARRAY:
7891 case SHT_PREINIT_ARRAY:
7892 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7893 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7894 i, section->sh_link);
7895 break;
7896
7897 default:
7898 /* FIXME: Add support for target specific section types. */
7899#if 0 /* Currently we do not check other section types as there are too
7900 many special cases. Stab sections for example have a type
7901 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7902 section. */
7903 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7904 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7905 i, section->sh_link);
7906#endif
7907 break;
7908 }
7909
7910 /* Check the sh_info field. */
7911 switch (section->sh_type)
7912 {
7913 case SHT_REL:
7914 case SHT_RELA:
285e3f99
AM
7915 if (section->sh_info == 0
7916 && (filedata->file_header.e_type == ET_EXEC
7917 || filedata->file_header.e_type == ET_DYN))
7918 /* Dynamic relocations apply to segments, so they do not
7919 need to specify the section they relocate. */
7920 break;
7921 if (section->sh_info == 0
dda8d76d
NC
7922 || section->sh_info >= filedata->file_header.e_shnum
7923 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7924 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7925 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7926 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7927 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7928 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7929 /* FIXME: Are other section types valid ? */
dda8d76d 7930 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7931 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7932 i, section->sh_info);
dd905818
NC
7933 break;
7934
7935 case SHT_DYNAMIC:
7936 case SHT_HASH:
7937 case SHT_SYMTAB_SHNDX:
7938 case SHT_INIT_ARRAY:
7939 case SHT_FINI_ARRAY:
7940 case SHT_PREINIT_ARRAY:
7941 if (section->sh_info != 0)
7942 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7943 i, section->sh_info);
7944 break;
7945
7946 case SHT_GROUP:
7947 case SHT_SYMTAB:
7948 case SHT_DYNSYM:
7949 /* A symbol index - we assume that it is valid. */
7950 break;
7951
7952 default:
7953 /* FIXME: Add support for target specific section types. */
7954 if (section->sh_type == SHT_NOBITS)
7955 /* NOBITS section headers with non-zero sh_info fields can be
7956 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7957 information. The stripped sections have their headers
7958 preserved but their types set to SHT_NOBITS. So do not check
7959 this type of section. */
dd905818
NC
7960 ;
7961 else if (section->sh_flags & SHF_INFO_LINK)
7962 {
dda8d76d 7963 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7964 warn (_("[%2u]: Expected link to another section in info field"), i);
7965 }
a91e1603
L
7966 else if (section->sh_type < SHT_LOOS
7967 && (section->sh_flags & SHF_GNU_MBIND) == 0
7968 && section->sh_info != 0)
dd905818
NC
7969 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7970 i, section->sh_info);
7971 break;
7972 }
7973
3e6b6445 7974 /* Check the sh_size field. */
dda8d76d 7975 if (section->sh_size > filedata->file_size
3e6b6445
NC
7976 && section->sh_type != SHT_NOBITS
7977 && section->sh_type != SHT_NULL
7978 && section->sh_type < SHT_LOOS)
7979 warn (_("Size of section %u is larger than the entire file!\n"), i);
7980
7bfd842d 7981 printf (" [%2u] ", i);
5477e8a0 7982 if (do_section_details)
dda8d76d 7983 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7984 else
84714f86 7985 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7986
ea52a088 7987 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7988 get_section_type_name (filedata, section->sh_type));
0b4362b0 7989
f7a99963
NC
7990 if (is_32bit_elf)
7991 {
cfcac11d
NC
7992 const char * link_too_big = NULL;
7993
f7a99963 7994 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7995
f7a99963
NC
7996 printf ( " %6.6lx %6.6lx %2.2lx",
7997 (unsigned long) section->sh_offset,
7998 (unsigned long) section->sh_size,
7999 (unsigned long) section->sh_entsize);
d1133906 8000
5477e8a0
L
8001 if (do_section_details)
8002 fputs (" ", stdout);
8003 else
dda8d76d 8004 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8005
dda8d76d 8006 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
8007 {
8008 link_too_big = "";
8009 /* The sh_link value is out of range. Normally this indicates
caa83f8b 8010 an error but it can have special values in Solaris binaries. */
dda8d76d 8011 switch (filedata->file_header.e_machine)
cfcac11d 8012 {
caa83f8b 8013 case EM_386:
22abe556 8014 case EM_IAMCU:
caa83f8b 8015 case EM_X86_64:
7f502d6c 8016 case EM_L1OM:
7a9068fe 8017 case EM_K1OM:
cfcac11d
NC
8018 case EM_OLD_SPARCV9:
8019 case EM_SPARC32PLUS:
8020 case EM_SPARCV9:
8021 case EM_SPARC:
8022 if (section->sh_link == (SHN_BEFORE & 0xffff))
8023 link_too_big = "BEFORE";
8024 else if (section->sh_link == (SHN_AFTER & 0xffff))
8025 link_too_big = "AFTER";
8026 break;
8027 default:
8028 break;
8029 }
8030 }
8031
8032 if (do_section_details)
8033 {
8034 if (link_too_big != NULL && * link_too_big)
8035 printf ("<%s> ", link_too_big);
8036 else
8037 printf ("%2u ", section->sh_link);
8038 printf ("%3u %2lu\n", section->sh_info,
8039 (unsigned long) section->sh_addralign);
8040 }
8041 else
8042 printf ("%2u %3u %2lu\n",
8043 section->sh_link,
8044 section->sh_info,
8045 (unsigned long) section->sh_addralign);
8046
8047 if (link_too_big && ! * link_too_big)
8048 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
8049 i, section->sh_link);
f7a99963 8050 }
d974e256
JJ
8051 else if (do_wide)
8052 {
8053 print_vma (section->sh_addr, LONG_HEX);
8054
8055 if ((long) section->sh_offset == section->sh_offset)
8056 printf (" %6.6lx", (unsigned long) section->sh_offset);
8057 else
8058 {
8059 putchar (' ');
8060 print_vma (section->sh_offset, LONG_HEX);
8061 }
8062
8063 if ((unsigned long) section->sh_size == section->sh_size)
8064 printf (" %6.6lx", (unsigned long) section->sh_size);
8065 else
8066 {
8067 putchar (' ');
8068 print_vma (section->sh_size, LONG_HEX);
8069 }
8070
8071 if ((unsigned long) section->sh_entsize == section->sh_entsize)
8072 printf (" %2.2lx", (unsigned long) section->sh_entsize);
8073 else
8074 {
8075 putchar (' ');
8076 print_vma (section->sh_entsize, LONG_HEX);
8077 }
8078
5477e8a0
L
8079 if (do_section_details)
8080 fputs (" ", stdout);
8081 else
dda8d76d 8082 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 8083
72de5009 8084 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
8085
8086 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 8087 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
8088 else
8089 {
8090 print_vma (section->sh_addralign, DEC);
8091 putchar ('\n');
8092 }
8093 }
5477e8a0 8094 else if (do_section_details)
595cf52e 8095 {
55cc53e9 8096 putchar (' ');
595cf52e
L
8097 print_vma (section->sh_addr, LONG_HEX);
8098 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 8099 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
8100 else
8101 {
8102 printf (" ");
8103 print_vma (section->sh_offset, LONG_HEX);
8104 }
72de5009 8105 printf (" %u\n ", section->sh_link);
595cf52e 8106 print_vma (section->sh_size, LONG_HEX);
5477e8a0 8107 putchar (' ');
595cf52e
L
8108 print_vma (section->sh_entsize, LONG_HEX);
8109
72de5009
AM
8110 printf (" %-16u %lu\n",
8111 section->sh_info,
595cf52e
L
8112 (unsigned long) section->sh_addralign);
8113 }
f7a99963
NC
8114 else
8115 {
8116 putchar (' ');
8117 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
8118 if ((long) section->sh_offset == section->sh_offset)
8119 printf (" %8.8lx", (unsigned long) section->sh_offset);
8120 else
8121 {
8122 printf (" ");
8123 print_vma (section->sh_offset, LONG_HEX);
8124 }
f7a99963
NC
8125 printf ("\n ");
8126 print_vma (section->sh_size, LONG_HEX);
8127 printf (" ");
8128 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 8129
dda8d76d 8130 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8131
72de5009
AM
8132 printf (" %2u %3u %lu\n",
8133 section->sh_link,
8134 section->sh_info,
f7a99963
NC
8135 (unsigned long) section->sh_addralign);
8136 }
5477e8a0
L
8137
8138 if (do_section_details)
77115a4a 8139 {
dda8d76d 8140 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
8141 if ((section->sh_flags & SHF_COMPRESSED) != 0)
8142 {
8143 /* Minimum section size is 12 bytes for 32-bit compression
8144 header + 12 bytes for compressed data header. */
8145 unsigned char buf[24];
d8024a91 8146
77115a4a 8147 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 8148 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
8149 sizeof (buf), _("compression header")))
8150 {
8151 Elf_Internal_Chdr chdr;
d8024a91 8152
5844b465
NC
8153 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
8154 printf (_(" [<corrupt>]\n"));
77115a4a 8155 else
5844b465 8156 {
89dbeac7 8157 if (chdr.ch_type == ch_compress_zlib)
5844b465 8158 printf (" ZLIB, ");
89dbeac7 8159 else if (chdr.ch_type == ch_compress_zstd)
1369522f 8160 printf (" ZSTD, ");
5844b465
NC
8161 else
8162 printf (_(" [<unknown>: 0x%x], "),
8163 chdr.ch_type);
8164 print_vma (chdr.ch_size, LONG_HEX);
8165 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
8166 }
77115a4a
L
8167 }
8168 }
8169 }
252b5132
RH
8170 }
8171
5477e8a0 8172 if (!do_section_details)
3dbcc61d 8173 {
9fb71ee4
NC
8174 /* The ordering of the letters shown here matches the ordering of the
8175 corresponding SHF_xxx values, and hence the order in which these
8176 letters will be displayed to the user. */
8177 printf (_("Key to Flags:\n\
8178 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
8179 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 8180 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
8181 switch (filedata->file_header.e_ident[EI_OSABI])
8182 {
8183 case ELFOSABI_GNU:
8184 case ELFOSABI_FREEBSD:
8185 printf (_("R (retain), "));
8186 /* Fall through */
8187 case ELFOSABI_NONE:
8188 printf (_("D (mbind), "));
8189 break;
8190 default:
8191 break;
8192 }
dda8d76d
NC
8193 if (filedata->file_header.e_machine == EM_X86_64
8194 || filedata->file_header.e_machine == EM_L1OM
8195 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 8196 printf (_("l (large), "));
dda8d76d 8197 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 8198 printf (_("y (purecode), "));
dda8d76d 8199 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 8200 printf (_("v (VLE), "));
9fb71ee4 8201 printf ("p (processor specific)\n");
0b4362b0 8202 }
d1133906 8203
015dc7e1 8204 return true;
252b5132
RH
8205}
8206
015dc7e1 8207static bool
28d13567 8208get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
26c527e6
AM
8209 Elf_Internal_Sym **symtab, uint64_t *nsyms,
8210 char **strtab, uint64_t *strtablen)
28d13567
AM
8211{
8212 *strtab = NULL;
8213 *strtablen = 0;
4de91c10 8214 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
8215
8216 if (*symtab == NULL)
015dc7e1 8217 return false;
28d13567
AM
8218
8219 if (symsec->sh_link != 0)
8220 {
8221 Elf_Internal_Shdr *strsec;
8222
8223 if (symsec->sh_link >= filedata->file_header.e_shnum)
8224 {
8225 error (_("Bad sh_link in symbol table section\n"));
8226 free (*symtab);
8227 *symtab = NULL;
8228 *nsyms = 0;
015dc7e1 8229 return false;
28d13567
AM
8230 }
8231
8232 strsec = filedata->section_headers + symsec->sh_link;
8233
8234 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
8235 1, strsec->sh_size, _("string table"));
8236 if (*strtab == NULL)
8237 {
8238 free (*symtab);
8239 *symtab = NULL;
8240 *nsyms = 0;
015dc7e1 8241 return false;
28d13567
AM
8242 }
8243 *strtablen = strsec->sh_size;
8244 }
015dc7e1 8245 return true;
28d13567
AM
8246}
8247
f5842774
L
8248static const char *
8249get_group_flags (unsigned int flags)
8250{
1449284b 8251 static char buff[128];
220453ec 8252
6d913794
NC
8253 if (flags == 0)
8254 return "";
8255 else if (flags == GRP_COMDAT)
8256 return "COMDAT ";
f5842774 8257
89246a0e
AM
8258 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
8259 flags,
8260 flags & GRP_MASKOS ? _("<OS specific>") : "",
8261 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
8262 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
8263 ? _("<unknown>") : ""));
6d913794 8264
f5842774
L
8265 return buff;
8266}
8267
015dc7e1 8268static bool
dda8d76d 8269process_section_groups (Filedata * filedata)
f5842774 8270{
2cf0635d 8271 Elf_Internal_Shdr * section;
f5842774 8272 unsigned int i;
2cf0635d
NC
8273 struct group * group;
8274 Elf_Internal_Shdr * symtab_sec;
8275 Elf_Internal_Shdr * strtab_sec;
8276 Elf_Internal_Sym * symtab;
26c527e6 8277 uint64_t num_syms;
2cf0635d 8278 char * strtab;
c256ffe7 8279 size_t strtab_size;
d1f5c6e3
L
8280
8281 /* Don't process section groups unless needed. */
8282 if (!do_unwind && !do_section_groups)
015dc7e1 8283 return true;
f5842774 8284
dda8d76d 8285 if (filedata->file_header.e_shnum == 0)
f5842774
L
8286 {
8287 if (do_section_groups)
ca0e11aa
NC
8288 {
8289 if (filedata->is_separate)
8290 printf (_("\nThere are no sections group in linked file '%s'.\n"),
8291 filedata->file_name);
8292 else
8293 printf (_("\nThere are no section groups in this file.\n"));
8294 }
015dc7e1 8295 return true;
f5842774
L
8296 }
8297
dda8d76d 8298 if (filedata->section_headers == NULL)
f5842774
L
8299 {
8300 error (_("Section headers are not available!\n"));
fa1908fd 8301 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 8302 return false;
f5842774
L
8303 }
8304
978c4450
AM
8305 filedata->section_headers_groups
8306 = (struct group **) calloc (filedata->file_header.e_shnum,
8307 sizeof (struct group *));
e4b17d5c 8308
978c4450 8309 if (filedata->section_headers_groups == NULL)
e4b17d5c 8310 {
8b73c356 8311 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 8312 filedata->file_header.e_shnum);
015dc7e1 8313 return false;
e4b17d5c
L
8314 }
8315
f5842774 8316 /* Scan the sections for the group section. */
978c4450 8317 filedata->group_count = 0;
dda8d76d
NC
8318 for (i = 0, section = filedata->section_headers;
8319 i < filedata->file_header.e_shnum;
f5842774 8320 i++, section++)
e4b17d5c 8321 if (section->sh_type == SHT_GROUP)
978c4450 8322 filedata->group_count++;
e4b17d5c 8323
978c4450 8324 if (filedata->group_count == 0)
d1f5c6e3
L
8325 {
8326 if (do_section_groups)
ca0e11aa
NC
8327 {
8328 if (filedata->is_separate)
8329 printf (_("\nThere are no section groups in linked file '%s'.\n"),
8330 filedata->file_name);
8331 else
8332 printf (_("\nThere are no section groups in this file.\n"));
8333 }
d1f5c6e3 8334
015dc7e1 8335 return true;
d1f5c6e3
L
8336 }
8337
978c4450
AM
8338 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8339 sizeof (struct group));
e4b17d5c 8340
978c4450 8341 if (filedata->section_groups == NULL)
e4b17d5c 8342 {
26c527e6 8343 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
015dc7e1 8344 return false;
e4b17d5c
L
8345 }
8346
d1f5c6e3
L
8347 symtab_sec = NULL;
8348 strtab_sec = NULL;
8349 symtab = NULL;
ba5cdace 8350 num_syms = 0;
d1f5c6e3 8351 strtab = NULL;
c256ffe7 8352 strtab_size = 0;
ca0e11aa
NC
8353
8354 if (filedata->is_separate)
8355 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 8356
978c4450 8357 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 8358 i < filedata->file_header.e_shnum;
e4b17d5c 8359 i++, section++)
f5842774
L
8360 {
8361 if (section->sh_type == SHT_GROUP)
8362 {
dda8d76d 8363 const char * name = printable_section_name (filedata, section);
74e1a04b 8364 const char * group_name;
2cf0635d
NC
8365 unsigned char * start;
8366 unsigned char * indices;
f5842774 8367 unsigned int entry, j, size;
2cf0635d
NC
8368 Elf_Internal_Shdr * sec;
8369 Elf_Internal_Sym * sym;
f5842774
L
8370
8371 /* Get the symbol table. */
dda8d76d
NC
8372 if (section->sh_link >= filedata->file_header.e_shnum
8373 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 8374 != SHT_SYMTAB))
f5842774
L
8375 {
8376 error (_("Bad sh_link in group section `%s'\n"), name);
8377 continue;
8378 }
d1f5c6e3
L
8379
8380 if (symtab_sec != sec)
8381 {
8382 symtab_sec = sec;
9db70fc3 8383 free (symtab);
4de91c10 8384 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 8385 }
f5842774 8386
dd24e3da
NC
8387 if (symtab == NULL)
8388 {
8389 error (_("Corrupt header in group section `%s'\n"), name);
8390 continue;
8391 }
8392
ba5cdace
NC
8393 if (section->sh_info >= num_syms)
8394 {
8395 error (_("Bad sh_info in group section `%s'\n"), name);
8396 continue;
8397 }
8398
f5842774
L
8399 sym = symtab + section->sh_info;
8400
8401 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8402 {
4fbb74a6 8403 if (sym->st_shndx == 0
dda8d76d 8404 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
8405 {
8406 error (_("Bad sh_info in group section `%s'\n"), name);
8407 continue;
8408 }
ba2685cc 8409
84714f86
AM
8410 group_name = section_name_print (filedata,
8411 filedata->section_headers
b9e920ec 8412 + sym->st_shndx);
c256ffe7 8413 strtab_sec = NULL;
9db70fc3 8414 free (strtab);
f5842774 8415 strtab = NULL;
c256ffe7 8416 strtab_size = 0;
f5842774
L
8417 }
8418 else
8419 {
8420 /* Get the string table. */
dda8d76d 8421 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8422 {
8423 strtab_sec = NULL;
9db70fc3 8424 free (strtab);
c256ffe7
JJ
8425 strtab = NULL;
8426 strtab_size = 0;
8427 }
8428 else if (strtab_sec
dda8d76d 8429 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8430 {
8431 strtab_sec = sec;
9db70fc3 8432 free (strtab);
071436c6 8433
dda8d76d 8434 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8435 1, strtab_sec->sh_size,
8436 _("string table"));
c256ffe7 8437 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8438 }
c256ffe7 8439 group_name = sym->st_name < strtab_size
2b692964 8440 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8441 }
8442
c9c1d674
EG
8443 /* PR 17531: file: loop. */
8444 if (section->sh_entsize > section->sh_size)
8445 {
26c527e6
AM
8446 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8447 " which is larger than its size (%#" PRIx64 ")\n"),
dda8d76d 8448 printable_section_name (filedata, section),
26c527e6
AM
8449 section->sh_entsize,
8450 section->sh_size);
61dd8e19 8451 continue;
c9c1d674
EG
8452 }
8453
dda8d76d 8454 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8455 1, section->sh_size,
8456 _("section data"));
59245841
NC
8457 if (start == NULL)
8458 continue;
f5842774
L
8459
8460 indices = start;
8461 size = (section->sh_size / section->sh_entsize) - 1;
8462 entry = byte_get (indices, 4);
8463 indices += 4;
e4b17d5c
L
8464
8465 if (do_section_groups)
8466 {
2b692964 8467 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8468 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8469
e4b17d5c
L
8470 printf (_(" [Index] Name\n"));
8471 }
8472
8473 group->group_index = i;
8474
f5842774
L
8475 for (j = 0; j < size; j++)
8476 {
2cf0635d 8477 struct group_list * g;
e4b17d5c 8478
f5842774
L
8479 entry = byte_get (indices, 4);
8480 indices += 4;
8481
dda8d76d 8482 if (entry >= filedata->file_header.e_shnum)
391cb864 8483 {
57028622
NC
8484 static unsigned num_group_errors = 0;
8485
8486 if (num_group_errors ++ < 10)
8487 {
8488 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8489 entry, i, filedata->file_header.e_shnum - 1);
57028622 8490 if (num_group_errors == 10)
67ce483b 8491 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8492 }
391cb864
L
8493 continue;
8494 }
391cb864 8495
978c4450 8496 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8497 {
d1f5c6e3
L
8498 if (entry)
8499 {
57028622
NC
8500 static unsigned num_errs = 0;
8501
8502 if (num_errs ++ < 10)
8503 {
8504 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8505 entry, i,
978c4450 8506 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8507 if (num_errs == 10)
8508 warn (_("Further error messages about already contained group sections suppressed\n"));
8509 }
d1f5c6e3
L
8510 continue;
8511 }
8512 else
8513 {
8514 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8515 section group. We just warn it the first time
d1f5c6e3 8516 and ignore it afterwards. */
015dc7e1 8517 static bool warned = false;
d1f5c6e3
L
8518 if (!warned)
8519 {
8520 error (_("section 0 in group section [%5u]\n"),
978c4450 8521 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8522 warned = true;
d1f5c6e3
L
8523 }
8524 }
e4b17d5c
L
8525 }
8526
978c4450 8527 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8528
8529 if (do_section_groups)
8530 {
dda8d76d
NC
8531 sec = filedata->section_headers + entry;
8532 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8533 }
8534
3f5e193b 8535 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8536 g->section_index = entry;
8537 g->next = group->root;
8538 group->root = g;
f5842774
L
8539 }
8540
9db70fc3 8541 free (start);
e4b17d5c
L
8542
8543 group++;
f5842774
L
8544 }
8545 }
8546
9db70fc3
AM
8547 free (symtab);
8548 free (strtab);
015dc7e1 8549 return true;
f5842774
L
8550}
8551
28f997cf
TG
8552/* Data used to display dynamic fixups. */
8553
8554struct ia64_vms_dynfixup
8555{
625d49fc
AM
8556 uint64_t needed_ident; /* Library ident number. */
8557 uint64_t needed; /* Index in the dstrtab of the library name. */
8558 uint64_t fixup_needed; /* Index of the library. */
8559 uint64_t fixup_rela_cnt; /* Number of fixups. */
8560 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8561};
8562
8563/* Data used to display dynamic relocations. */
8564
8565struct ia64_vms_dynimgrela
8566{
625d49fc
AM
8567 uint64_t img_rela_cnt; /* Number of relocations. */
8568 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8569};
8570
8571/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8572 library). */
8573
015dc7e1 8574static bool
dda8d76d
NC
8575dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8576 struct ia64_vms_dynfixup * fixup,
8577 const char * strtab,
8578 unsigned int strtab_sz)
28f997cf 8579{
32ec8896 8580 Elf64_External_VMS_IMAGE_FIXUP * imfs;
26c527e6 8581 size_t i;
32ec8896 8582 const char * lib_name;
28f997cf 8583
978c4450
AM
8584 imfs = get_data (NULL, filedata,
8585 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8586 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8587 _("dynamic section image fixups"));
8588 if (!imfs)
015dc7e1 8589 return false;
28f997cf
TG
8590
8591 if (fixup->needed < strtab_sz)
8592 lib_name = strtab + fixup->needed;
8593 else
8594 {
26c527e6
AM
8595 warn (_("corrupt library name index of %#" PRIx64
8596 " found in dynamic entry"), fixup->needed);
28f997cf
TG
8597 lib_name = "???";
8598 }
736990c4 8599
26c527e6
AM
8600 printf (_("\nImage fixups for needed library #%" PRId64
8601 ": %s - ident: %" PRIx64 "\n"),
8602 fixup->fixup_needed, lib_name, fixup->needed_ident);
28f997cf
TG
8603 printf
8604 (_("Seg Offset Type SymVec DataType\n"));
8605
26c527e6 8606 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
28f997cf
TG
8607 {
8608 unsigned int type;
8609 const char *rtype;
8610
8611 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8612 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8613 type = BYTE_GET (imfs [i].type);
8614 rtype = elf_ia64_reloc_type (type);
8615 if (rtype == NULL)
f493c217 8616 printf ("0x%08x ", type);
28f997cf 8617 else
f493c217 8618 printf ("%-32s ", rtype);
28f997cf
TG
8619 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8620 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8621 }
8622
8623 free (imfs);
015dc7e1 8624 return true;
28f997cf
TG
8625}
8626
8627/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8628
015dc7e1 8629static bool
dda8d76d 8630dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8631{
8632 Elf64_External_VMS_IMAGE_RELA *imrs;
26c527e6 8633 size_t i;
28f997cf 8634
978c4450
AM
8635 imrs = get_data (NULL, filedata,
8636 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8637 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8638 _("dynamic section image relocations"));
28f997cf 8639 if (!imrs)
015dc7e1 8640 return false;
28f997cf
TG
8641
8642 printf (_("\nImage relocs\n"));
8643 printf
8644 (_("Seg Offset Type Addend Seg Sym Off\n"));
8645
26c527e6 8646 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
28f997cf
TG
8647 {
8648 unsigned int type;
8649 const char *rtype;
8650
8651 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8652 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8653 type = BYTE_GET (imrs [i].type);
8654 rtype = elf_ia64_reloc_type (type);
8655 if (rtype == NULL)
8656 printf ("0x%08x ", type);
8657 else
8658 printf ("%-31s ", rtype);
8659 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8660 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8661 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8662 }
8663
8664 free (imrs);
015dc7e1 8665 return true;
28f997cf
TG
8666}
8667
8668/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8669
015dc7e1 8670static bool
dda8d76d 8671process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8672{
8673 struct ia64_vms_dynfixup fixup;
8674 struct ia64_vms_dynimgrela imgrela;
8675 Elf_Internal_Dyn *entry;
625d49fc
AM
8676 uint64_t strtab_off = 0;
8677 uint64_t strtab_sz = 0;
28f997cf 8678 char *strtab = NULL;
015dc7e1 8679 bool res = true;
28f997cf
TG
8680
8681 memset (&fixup, 0, sizeof (fixup));
8682 memset (&imgrela, 0, sizeof (imgrela));
8683
8684 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8685 for (entry = filedata->dynamic_section;
8686 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8687 entry++)
8688 {
8689 switch (entry->d_tag)
8690 {
8691 case DT_IA_64_VMS_STRTAB_OFFSET:
8692 strtab_off = entry->d_un.d_val;
8693 break;
8694 case DT_STRSZ:
8695 strtab_sz = entry->d_un.d_val;
8696 if (strtab == NULL)
978c4450
AM
8697 strtab = get_data (NULL, filedata,
8698 filedata->dynamic_addr + strtab_off,
28f997cf 8699 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8700 if (strtab == NULL)
8701 strtab_sz = 0;
28f997cf
TG
8702 break;
8703
8704 case DT_IA_64_VMS_NEEDED_IDENT:
8705 fixup.needed_ident = entry->d_un.d_val;
8706 break;
8707 case DT_NEEDED:
8708 fixup.needed = entry->d_un.d_val;
8709 break;
8710 case DT_IA_64_VMS_FIXUP_NEEDED:
8711 fixup.fixup_needed = entry->d_un.d_val;
8712 break;
8713 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8714 fixup.fixup_rela_cnt = entry->d_un.d_val;
8715 break;
8716 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8717 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8718 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8719 res = false;
28f997cf 8720 break;
28f997cf
TG
8721 case DT_IA_64_VMS_IMG_RELA_CNT:
8722 imgrela.img_rela_cnt = entry->d_un.d_val;
8723 break;
8724 case DT_IA_64_VMS_IMG_RELA_OFF:
8725 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8726 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8727 res = false;
28f997cf
TG
8728 break;
8729
8730 default:
8731 break;
8732 }
8733 }
8734
9db70fc3 8735 free (strtab);
28f997cf
TG
8736
8737 return res;
8738}
8739
85b1c36d 8740static struct
566b0d53 8741{
2cf0635d 8742 const char * name;
566b0d53
L
8743 int reloc;
8744 int size;
a7fd1186 8745 relocation_type rel_type;
32ec8896
NC
8746}
8747 dynamic_relocations [] =
566b0d53 8748{
a7fd1186
FS
8749 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8750 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8751 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8752 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8753};
8754
252b5132 8755/* Process the reloc section. */
18bd398b 8756
015dc7e1 8757static bool
dda8d76d 8758process_relocs (Filedata * filedata)
252b5132 8759{
26c527e6
AM
8760 uint64_t rel_size;
8761 uint64_t rel_offset;
252b5132 8762
252b5132 8763 if (!do_reloc)
015dc7e1 8764 return true;
252b5132
RH
8765
8766 if (do_using_dynamic)
8767 {
a7fd1186 8768 relocation_type rel_type;
2cf0635d 8769 const char * name;
015dc7e1 8770 bool has_dynamic_reloc;
566b0d53 8771 unsigned int i;
0de14b54 8772
015dc7e1 8773 has_dynamic_reloc = false;
252b5132 8774
566b0d53 8775 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8776 {
a7fd1186 8777 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8778 name = dynamic_relocations [i].name;
978c4450
AM
8779 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8780 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8781
32ec8896 8782 if (rel_size)
015dc7e1 8783 has_dynamic_reloc = true;
566b0d53 8784
a7fd1186 8785 if (rel_type == reltype_unknown)
aa903cfb 8786 {
566b0d53 8787 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8788 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8789 {
8790 case DT_REL:
a7fd1186 8791 rel_type = reltype_rel;
566b0d53
L
8792 break;
8793 case DT_RELA:
a7fd1186 8794 rel_type = reltype_rela;
566b0d53
L
8795 break;
8796 }
aa903cfb 8797 }
252b5132 8798
566b0d53
L
8799 if (rel_size)
8800 {
ca0e11aa
NC
8801 if (filedata->is_separate)
8802 printf
26c527e6
AM
8803 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
8804 " contains %" PRId64 " bytes:\n"),
ca0e11aa
NC
8805 filedata->file_name, name, rel_offset, rel_size);
8806 else
8807 printf
26c527e6
AM
8808 (_("\n'%s' relocation section at offset %#" PRIx64
8809 " contains %" PRId64 " bytes:\n"),
ca0e11aa 8810 name, rel_offset, rel_size);
252b5132 8811
dda8d76d
NC
8812 dump_relocations (filedata,
8813 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8814 rel_size,
978c4450
AM
8815 filedata->dynamic_symbols,
8816 filedata->num_dynamic_syms,
8817 filedata->dynamic_strings,
8818 filedata->dynamic_strings_length,
a7fd1186 8819 rel_type, true /* is_dynamic */);
566b0d53 8820 }
252b5132 8821 }
566b0d53 8822
dda8d76d
NC
8823 if (is_ia64_vms (filedata))
8824 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8825 has_dynamic_reloc = true;
28f997cf 8826
566b0d53 8827 if (! has_dynamic_reloc)
ca0e11aa
NC
8828 {
8829 if (filedata->is_separate)
8830 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8831 filedata->file_name);
8832 else
8833 printf (_("\nThere are no dynamic relocations in this file.\n"));
8834 }
252b5132
RH
8835 }
8836 else
8837 {
2cf0635d 8838 Elf_Internal_Shdr * section;
26c527e6 8839 size_t i;
015dc7e1 8840 bool found = false;
252b5132 8841
dda8d76d
NC
8842 for (i = 0, section = filedata->section_headers;
8843 i < filedata->file_header.e_shnum;
b34976b6 8844 i++, section++)
252b5132
RH
8845 {
8846 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8847 && section->sh_type != SHT_REL
8848 && section->sh_type != SHT_RELR)
252b5132
RH
8849 continue;
8850
8851 rel_offset = section->sh_offset;
8852 rel_size = section->sh_size;
8853
8854 if (rel_size)
8855 {
a7fd1186 8856 relocation_type rel_type;
26c527e6 8857 uint64_t num_rela;
103f02d3 8858
ca0e11aa
NC
8859 if (filedata->is_separate)
8860 printf (_("\nIn linked file '%s' relocation section "),
8861 filedata->file_name);
8862 else
8863 printf (_("\nRelocation section "));
252b5132 8864
dda8d76d 8865 if (filedata->string_table == NULL)
19936277 8866 printf ("%d", section->sh_name);
252b5132 8867 else
dda8d76d 8868 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8869
d3a49aa8 8870 num_rela = rel_size / section->sh_entsize;
26c527e6
AM
8871 printf (ngettext (" at offset %#" PRIx64
8872 " contains %" PRIu64 " entry:\n",
8873 " at offset %#" PRIx64
8874 " contains %" PRId64 " entries:\n",
d3a49aa8
AM
8875 num_rela),
8876 rel_offset, num_rela);
252b5132 8877
a7fd1186
FS
8878 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8879 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8880
4fbb74a6 8881 if (section->sh_link != 0
dda8d76d 8882 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8883 {
26c527e6
AM
8884 Elf_Internal_Shdr *symsec;
8885 Elf_Internal_Sym *symtab;
8886 uint64_t nsyms;
8887 uint64_t strtablen = 0;
8888 char *strtab = NULL;
57346661 8889
dda8d76d 8890 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8891 if (symsec->sh_type != SHT_SYMTAB
8892 && symsec->sh_type != SHT_DYNSYM)
8893 continue;
8894
28d13567
AM
8895 if (!get_symtab (filedata, symsec,
8896 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8897 continue;
252b5132 8898
dda8d76d 8899 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8900 symtab, nsyms, strtab, strtablen,
a7fd1186 8901 rel_type,
bb4d2ac2 8902 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8903 free (strtab);
d79b3d50
NC
8904 free (symtab);
8905 }
8906 else
dda8d76d 8907 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8908 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8909
015dc7e1 8910 found = true;
252b5132
RH
8911 }
8912 }
8913
8914 if (! found)
45ac8f4f
NC
8915 {
8916 /* Users sometimes forget the -D option, so try to be helpful. */
8917 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8918 {
978c4450 8919 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8920 {
ca0e11aa
NC
8921 if (filedata->is_separate)
8922 printf (_("\nThere are no static relocations in linked file '%s'."),
8923 filedata->file_name);
8924 else
8925 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8926 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8927
8928 break;
8929 }
8930 }
8931 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8932 {
8933 if (filedata->is_separate)
8934 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8935 filedata->file_name);
8936 else
8937 printf (_("\nThere are no relocations in this file.\n"));
8938 }
45ac8f4f 8939 }
252b5132
RH
8940 }
8941
015dc7e1 8942 return true;
252b5132
RH
8943}
8944
4d6ed7c8
NC
8945/* An absolute address consists of a section and an offset. If the
8946 section is NULL, the offset itself is the address, otherwise, the
8947 address equals to LOAD_ADDRESS(section) + offset. */
8948
8949struct absaddr
948f632f
DA
8950{
8951 unsigned short section;
625d49fc 8952 uint64_t offset;
948f632f 8953};
4d6ed7c8 8954
948f632f
DA
8955/* Find the nearest symbol at or below ADDR. Returns the symbol
8956 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8957
4d6ed7c8 8958static void
26c527e6
AM
8959find_symbol_for_address (Filedata *filedata,
8960 Elf_Internal_Sym *symtab,
8961 uint64_t nsyms,
8962 const char *strtab,
8963 uint64_t strtab_size,
8964 struct absaddr addr,
8965 const char **symname,
8966 uint64_t *offset)
4d6ed7c8 8967{
625d49fc 8968 uint64_t dist = 0x100000;
2cf0635d 8969 Elf_Internal_Sym * sym;
948f632f
DA
8970 Elf_Internal_Sym * beg;
8971 Elf_Internal_Sym * end;
2cf0635d 8972 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8973
0b6ae522 8974 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8975 beg = symtab;
8976 end = symtab + nsyms;
0b6ae522 8977
948f632f 8978 while (beg < end)
4d6ed7c8 8979 {
625d49fc 8980 uint64_t value;
948f632f
DA
8981
8982 sym = beg + (end - beg) / 2;
0b6ae522 8983
948f632f 8984 value = sym->st_value;
0b6ae522
DJ
8985 REMOVE_ARCH_BITS (value);
8986
948f632f 8987 if (sym->st_name != 0
4d6ed7c8 8988 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8989 && addr.offset >= value
8990 && addr.offset - value < dist)
4d6ed7c8
NC
8991 {
8992 best = sym;
0b6ae522 8993 dist = addr.offset - value;
4d6ed7c8
NC
8994 if (!dist)
8995 break;
8996 }
948f632f
DA
8997
8998 if (addr.offset < value)
8999 end = sym;
9000 else
9001 beg = sym + 1;
4d6ed7c8 9002 }
1b31d05e 9003
4d6ed7c8
NC
9004 if (best)
9005 {
57346661 9006 *symname = (best->st_name >= strtab_size
2b692964 9007 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
9008 *offset = dist;
9009 return;
9010 }
1b31d05e 9011
4d6ed7c8
NC
9012 *symname = NULL;
9013 *offset = addr.offset;
9014}
9015
32ec8896 9016static /* signed */ int
948f632f
DA
9017symcmp (const void *p, const void *q)
9018{
9019 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
9020 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
9021
9022 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
9023}
9024
9025/* Process the unwind section. */
9026
9027#include "unwind-ia64.h"
9028
9029struct ia64_unw_table_entry
9030{
9031 struct absaddr start;
9032 struct absaddr end;
9033 struct absaddr info;
9034};
9035
9036struct ia64_unw_aux_info
9037{
32ec8896 9038 struct ia64_unw_table_entry * table; /* Unwind table. */
26c527e6 9039 uint64_t table_len; /* Length of unwind table. */
32ec8896 9040 unsigned char * info; /* Unwind info. */
26c527e6 9041 uint64_t info_size; /* Size of unwind info. */
625d49fc
AM
9042 uint64_t info_addr; /* Starting address of unwind info. */
9043 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9044 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9045 uint64_t nsyms; /* Number of symbols. */
32ec8896 9046 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9047 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9048 char * strtab; /* The string table. */
26c527e6 9049 uint64_t strtab_size; /* Size of string table. */
948f632f
DA
9050};
9051
015dc7e1 9052static bool
dda8d76d 9053dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 9054{
2cf0635d 9055 struct ia64_unw_table_entry * tp;
26c527e6 9056 size_t j, nfuns;
4d6ed7c8 9057 int in_body;
015dc7e1 9058 bool res = true;
7036c0e1 9059
948f632f
DA
9060 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9061 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9062 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9063 aux->funtab[nfuns++] = aux->symtab[j];
9064 aux->nfuns = nfuns;
9065 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9066
4d6ed7c8
NC
9067 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9068 {
625d49fc
AM
9069 uint64_t stamp;
9070 uint64_t offset;
2cf0635d
NC
9071 const unsigned char * dp;
9072 const unsigned char * head;
53774b7e 9073 const unsigned char * end;
2cf0635d 9074 const char * procname;
4d6ed7c8 9075
dda8d76d 9076 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 9077 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
9078
9079 fputs ("\n<", stdout);
9080
9081 if (procname)
9082 {
9083 fputs (procname, stdout);
9084
9085 if (offset)
26c527e6 9086 printf ("+%" PRIx64, offset);
4d6ed7c8
NC
9087 }
9088
9089 fputs (">: [", stdout);
9090 print_vma (tp->start.offset, PREFIX_HEX);
9091 fputc ('-', stdout);
9092 print_vma (tp->end.offset, PREFIX_HEX);
26c527e6
AM
9093 printf ("], info at +0x%" PRIx64 "\n",
9094 tp->info.offset - aux->seg_base);
4d6ed7c8 9095
53774b7e
NC
9096 /* PR 17531: file: 86232b32. */
9097 if (aux->info == NULL)
9098 continue;
9099
97c0a079
AM
9100 offset = tp->info.offset;
9101 if (tp->info.section)
9102 {
9103 if (tp->info.section >= filedata->file_header.e_shnum)
9104 {
26c527e6
AM
9105 warn (_("Invalid section %u in table entry %td\n"),
9106 tp->info.section, tp - aux->table);
015dc7e1 9107 res = false;
97c0a079
AM
9108 continue;
9109 }
9110 offset += filedata->section_headers[tp->info.section].sh_addr;
9111 }
9112 offset -= aux->info_addr;
53774b7e 9113 /* PR 17531: file: 0997b4d1. */
90679903
AM
9114 if (offset >= aux->info_size
9115 || aux->info_size - offset < 8)
53774b7e 9116 {
26c527e6
AM
9117 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
9118 tp->info.offset, tp - aux->table);
015dc7e1 9119 res = false;
53774b7e
NC
9120 continue;
9121 }
9122
97c0a079 9123 head = aux->info + offset;
a4a00738 9124 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 9125
86f55779 9126 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
9127 (unsigned) UNW_VER (stamp),
9128 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
9129 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
9130 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 9131 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
9132
9133 if (UNW_VER (stamp) != 1)
9134 {
2b692964 9135 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
9136 continue;
9137 }
9138
9139 in_body = 0;
53774b7e
NC
9140 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
9141 /* PR 17531: file: 16ceda89. */
9142 if (end > aux->info + aux->info_size)
9143 end = aux->info + aux->info_size;
9144 for (dp = head + 8; dp < end;)
b4477bc8 9145 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 9146 }
948f632f
DA
9147
9148 free (aux->funtab);
32ec8896
NC
9149
9150 return res;
4d6ed7c8
NC
9151}
9152
015dc7e1 9153static bool
dda8d76d
NC
9154slurp_ia64_unwind_table (Filedata * filedata,
9155 struct ia64_unw_aux_info * aux,
9156 Elf_Internal_Shdr * sec)
4d6ed7c8 9157{
26c527e6 9158 uint64_t size, nrelas, i;
2cf0635d
NC
9159 Elf_Internal_Phdr * seg;
9160 struct ia64_unw_table_entry * tep;
9161 Elf_Internal_Shdr * relsec;
9162 Elf_Internal_Rela * rela;
9163 Elf_Internal_Rela * rp;
9164 unsigned char * table;
9165 unsigned char * tp;
9166 Elf_Internal_Sym * sym;
9167 const char * relname;
4d6ed7c8 9168
53774b7e
NC
9169 aux->table_len = 0;
9170
4d6ed7c8
NC
9171 /* First, find the starting address of the segment that includes
9172 this section: */
9173
dda8d76d 9174 if (filedata->file_header.e_phnum)
4d6ed7c8 9175 {
dda8d76d 9176 if (! get_program_headers (filedata))
015dc7e1 9177 return false;
4d6ed7c8 9178
dda8d76d
NC
9179 for (seg = filedata->program_headers;
9180 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 9181 ++seg)
4d6ed7c8
NC
9182 {
9183 if (seg->p_type != PT_LOAD)
9184 continue;
9185
9186 if (sec->sh_addr >= seg->p_vaddr
9187 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9188 {
9189 aux->seg_base = seg->p_vaddr;
9190 break;
9191 }
9192 }
4d6ed7c8
NC
9193 }
9194
9195 /* Second, build the unwind table from the contents of the unwind section: */
9196 size = sec->sh_size;
dda8d76d 9197 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9198 _("unwind table"));
a6e9f9df 9199 if (!table)
015dc7e1 9200 return false;
4d6ed7c8 9201
53774b7e 9202 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 9203 aux->table = (struct ia64_unw_table_entry *)
53774b7e 9204 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 9205 tep = aux->table;
53774b7e
NC
9206
9207 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
9208 {
9209 tep->start.section = SHN_UNDEF;
9210 tep->end.section = SHN_UNDEF;
9211 tep->info.section = SHN_UNDEF;
c6a0c689
AM
9212 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9213 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9214 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
9215 tep->start.offset += aux->seg_base;
9216 tep->end.offset += aux->seg_base;
9217 tep->info.offset += aux->seg_base;
9218 }
9219 free (table);
9220
41e92641 9221 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
9222 for (relsec = filedata->section_headers;
9223 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
9224 ++relsec)
9225 {
9226 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9227 || relsec->sh_info >= filedata->file_header.e_shnum
9228 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
9229 continue;
9230
dda8d76d 9231 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 9232 & rela, & nrelas))
53774b7e
NC
9233 {
9234 free (aux->table);
9235 aux->table = NULL;
9236 aux->table_len = 0;
015dc7e1 9237 return false;
53774b7e 9238 }
4d6ed7c8
NC
9239
9240 for (rp = rela; rp < rela + nrelas; ++rp)
9241 {
4770fb94 9242 unsigned int sym_ndx;
726bd37d
AM
9243 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9244 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 9245
82b1b41b
NC
9246 /* PR 17531: file: 9fa67536. */
9247 if (relname == NULL)
9248 {
726bd37d 9249 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
9250 continue;
9251 }
948f632f 9252
24d127aa 9253 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 9254 {
82b1b41b 9255 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
9256 continue;
9257 }
9258
89fac5e3 9259 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 9260
53774b7e
NC
9261 /* PR 17531: file: 5bc8d9bf. */
9262 if (i >= aux->table_len)
9263 {
26c527e6
AM
9264 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9265 i);
53774b7e
NC
9266 continue;
9267 }
9268
4770fb94
AM
9269 sym_ndx = get_reloc_symindex (rp->r_info);
9270 if (sym_ndx >= aux->nsyms)
9271 {
9272 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9273 sym_ndx);
9274 continue;
9275 }
9276 sym = aux->symtab + sym_ndx;
9277
53774b7e 9278 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
9279 {
9280 case 0:
9281 aux->table[i].start.section = sym->st_shndx;
e466bc6e 9282 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9283 break;
9284 case 1:
9285 aux->table[i].end.section = sym->st_shndx;
e466bc6e 9286 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9287 break;
9288 case 2:
9289 aux->table[i].info.section = sym->st_shndx;
e466bc6e 9290 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9291 break;
9292 default:
9293 break;
9294 }
9295 }
9296
9297 free (rela);
9298 }
9299
015dc7e1 9300 return true;
4d6ed7c8
NC
9301}
9302
015dc7e1 9303static bool
dda8d76d 9304ia64_process_unwind (Filedata * filedata)
4d6ed7c8 9305{
2cf0635d
NC
9306 Elf_Internal_Shdr * sec;
9307 Elf_Internal_Shdr * unwsec = NULL;
26c527e6 9308 uint64_t i, unwcount = 0, unwstart = 0;
57346661 9309 struct ia64_unw_aux_info aux;
015dc7e1 9310 bool res = true;
f1467e33 9311
4d6ed7c8
NC
9312 memset (& aux, 0, sizeof (aux));
9313
dda8d76d 9314 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 9315 {
28d13567 9316 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 9317 {
28d13567 9318 if (aux.symtab)
4082ef84 9319 {
28d13567
AM
9320 error (_("Multiple symbol tables encountered\n"));
9321 free (aux.symtab);
9322 aux.symtab = NULL;
4082ef84 9323 free (aux.strtab);
28d13567 9324 aux.strtab = NULL;
4082ef84 9325 }
28d13567
AM
9326 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9327 &aux.strtab, &aux.strtab_size))
015dc7e1 9328 return false;
4d6ed7c8
NC
9329 }
9330 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
9331 unwcount++;
9332 }
9333
9334 if (!unwcount)
9335 printf (_("\nThere are no unwind sections in this file.\n"));
9336
9337 while (unwcount-- > 0)
9338 {
84714f86 9339 const char *suffix;
579f31ac
JJ
9340 size_t len, len2;
9341
dda8d76d
NC
9342 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
9343 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
9344 if (sec->sh_type == SHT_IA_64_UNWIND)
9345 {
9346 unwsec = sec;
9347 break;
9348 }
4082ef84
NC
9349 /* We have already counted the number of SHT_IA64_UNWIND
9350 sections so the loop above should never fail. */
9351 assert (unwsec != NULL);
579f31ac
JJ
9352
9353 unwstart = i + 1;
9354 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9355
e4b17d5c
L
9356 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9357 {
9358 /* We need to find which section group it is in. */
4082ef84 9359 struct group_list * g;
e4b17d5c 9360
978c4450
AM
9361 if (filedata->section_headers_groups == NULL
9362 || filedata->section_headers_groups[i] == NULL)
dda8d76d 9363 i = filedata->file_header.e_shnum;
4082ef84 9364 else
e4b17d5c 9365 {
978c4450 9366 g = filedata->section_headers_groups[i]->root;
18bd398b 9367
4082ef84
NC
9368 for (; g != NULL; g = g->next)
9369 {
dda8d76d 9370 sec = filedata->section_headers + g->section_index;
e4b17d5c 9371
84714f86
AM
9372 if (section_name_valid (filedata, sec)
9373 && streq (section_name (filedata, sec),
9374 ELF_STRING_ia64_unwind_info))
4082ef84
NC
9375 break;
9376 }
9377
9378 if (g == NULL)
dda8d76d 9379 i = filedata->file_header.e_shnum;
4082ef84 9380 }
e4b17d5c 9381 }
84714f86
AM
9382 else if (section_name_valid (filedata, unwsec)
9383 && startswith (section_name (filedata, unwsec),
e9b095a5 9384 ELF_STRING_ia64_unwind_once))
579f31ac 9385 {
18bd398b 9386 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 9387 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 9388 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9389 for (i = 0, sec = filedata->section_headers;
9390 i < filedata->file_header.e_shnum;
579f31ac 9391 ++i, ++sec)
84714f86
AM
9392 if (section_name_valid (filedata, sec)
9393 && startswith (section_name (filedata, sec),
e9b095a5 9394 ELF_STRING_ia64_unwind_info_once)
84714f86 9395 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9396 break;
9397 }
9398 else
9399 {
9400 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 9401 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
9402 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9403 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9404 suffix = "";
84714f86
AM
9405 if (section_name_valid (filedata, unwsec)
9406 && startswith (section_name (filedata, unwsec),
9407 ELF_STRING_ia64_unwind))
9408 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9409 for (i = 0, sec = filedata->section_headers;
9410 i < filedata->file_header.e_shnum;
579f31ac 9411 ++i, ++sec)
84714f86
AM
9412 if (section_name_valid (filedata, sec)
9413 && startswith (section_name (filedata, sec),
9414 ELF_STRING_ia64_unwind_info)
9415 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9416 break;
9417 }
9418
dda8d76d 9419 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
9420 {
9421 printf (_("\nCould not find unwind info section for "));
9422
dda8d76d 9423 if (filedata->string_table == NULL)
579f31ac
JJ
9424 printf ("%d", unwsec->sh_name);
9425 else
dda8d76d 9426 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9427 }
9428 else
4d6ed7c8 9429 {
4d6ed7c8 9430 aux.info_addr = sec->sh_addr;
dda8d76d 9431 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9432 sec->sh_size,
9433 _("unwind info"));
59245841 9434 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9435
579f31ac 9436 printf (_("\nUnwind section "));
4d6ed7c8 9437
dda8d76d 9438 if (filedata->string_table == NULL)
579f31ac
JJ
9439 printf ("%d", unwsec->sh_name);
9440 else
dda8d76d 9441 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9442
26c527e6
AM
9443 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9444 unwsec->sh_offset,
9445 unwsec->sh_size / (3 * eh_addr_size));
4d6ed7c8 9446
dda8d76d 9447 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9448 && aux.table_len > 0)
dda8d76d 9449 dump_ia64_unwind (filedata, & aux);
579f31ac 9450
9db70fc3
AM
9451 free ((char *) aux.table);
9452 free ((char *) aux.info);
579f31ac
JJ
9453 aux.table = NULL;
9454 aux.info = NULL;
9455 }
4d6ed7c8 9456 }
4d6ed7c8 9457
9db70fc3
AM
9458 free (aux.symtab);
9459 free ((char *) aux.strtab);
32ec8896
NC
9460
9461 return res;
4d6ed7c8
NC
9462}
9463
3f5e193b 9464struct hppa_unw_table_entry
32ec8896
NC
9465{
9466 struct absaddr start;
9467 struct absaddr end;
9468 unsigned int Cannot_unwind:1; /* 0 */
9469 unsigned int Millicode:1; /* 1 */
9470 unsigned int Millicode_save_sr0:1; /* 2 */
9471 unsigned int Region_description:2; /* 3..4 */
9472 unsigned int reserved1:1; /* 5 */
9473 unsigned int Entry_SR:1; /* 6 */
9474 unsigned int Entry_FR:4; /* Number saved 7..10 */
9475 unsigned int Entry_GR:5; /* Number saved 11..15 */
9476 unsigned int Args_stored:1; /* 16 */
9477 unsigned int Variable_Frame:1; /* 17 */
9478 unsigned int Separate_Package_Body:1; /* 18 */
9479 unsigned int Frame_Extension_Millicode:1; /* 19 */
9480 unsigned int Stack_Overflow_Check:1; /* 20 */
9481 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9482 unsigned int Ada_Region:1; /* 22 */
9483 unsigned int cxx_info:1; /* 23 */
9484 unsigned int cxx_try_catch:1; /* 24 */
9485 unsigned int sched_entry_seq:1; /* 25 */
9486 unsigned int reserved2:1; /* 26 */
9487 unsigned int Save_SP:1; /* 27 */
9488 unsigned int Save_RP:1; /* 28 */
9489 unsigned int Save_MRP_in_frame:1; /* 29 */
9490 unsigned int extn_ptr_defined:1; /* 30 */
9491 unsigned int Cleanup_defined:1; /* 31 */
9492
9493 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9494 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9495 unsigned int Large_frame:1; /* 2 */
9496 unsigned int Pseudo_SP_Set:1; /* 3 */
9497 unsigned int reserved4:1; /* 4 */
9498 unsigned int Total_frame_size:27; /* 5..31 */
9499};
3f5e193b 9500
57346661 9501struct hppa_unw_aux_info
948f632f 9502{
32ec8896 9503 struct hppa_unw_table_entry * table; /* Unwind table. */
26c527e6 9504 uint64_t table_len; /* Length of unwind table. */
625d49fc 9505 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9506 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9507 uint64_t nsyms; /* Number of symbols. */
32ec8896 9508 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9509 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9510 char * strtab; /* The string table. */
26c527e6 9511 uint64_t strtab_size; /* Size of string table. */
948f632f 9512};
57346661 9513
015dc7e1 9514static bool
dda8d76d 9515dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9516{
2cf0635d 9517 struct hppa_unw_table_entry * tp;
26c527e6 9518 uint64_t j, nfuns;
015dc7e1 9519 bool res = true;
948f632f
DA
9520
9521 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9522 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9523 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9524 aux->funtab[nfuns++] = aux->symtab[j];
9525 aux->nfuns = nfuns;
9526 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9527
57346661
AM
9528 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9529 {
625d49fc 9530 uint64_t offset;
2cf0635d 9531 const char * procname;
57346661 9532
dda8d76d 9533 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9534 aux->strtab_size, tp->start, &procname,
9535 &offset);
9536
9537 fputs ("\n<", stdout);
9538
9539 if (procname)
9540 {
9541 fputs (procname, stdout);
9542
9543 if (offset)
26c527e6 9544 printf ("+%" PRIx64, offset);
57346661
AM
9545 }
9546
9547 fputs (">: [", stdout);
9548 print_vma (tp->start.offset, PREFIX_HEX);
9549 fputc ('-', stdout);
9550 print_vma (tp->end.offset, PREFIX_HEX);
9551 printf ("]\n\t");
9552
18bd398b
NC
9553#define PF(_m) if (tp->_m) printf (#_m " ");
9554#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9555 PF(Cannot_unwind);
9556 PF(Millicode);
9557 PF(Millicode_save_sr0);
18bd398b 9558 /* PV(Region_description); */
57346661
AM
9559 PF(Entry_SR);
9560 PV(Entry_FR);
9561 PV(Entry_GR);
9562 PF(Args_stored);
9563 PF(Variable_Frame);
9564 PF(Separate_Package_Body);
9565 PF(Frame_Extension_Millicode);
9566 PF(Stack_Overflow_Check);
9567 PF(Two_Instruction_SP_Increment);
9568 PF(Ada_Region);
9569 PF(cxx_info);
9570 PF(cxx_try_catch);
9571 PF(sched_entry_seq);
9572 PF(Save_SP);
9573 PF(Save_RP);
9574 PF(Save_MRP_in_frame);
9575 PF(extn_ptr_defined);
9576 PF(Cleanup_defined);
9577 PF(MPE_XL_interrupt_marker);
9578 PF(HP_UX_interrupt_marker);
9579 PF(Large_frame);
9580 PF(Pseudo_SP_Set);
9581 PV(Total_frame_size);
9582#undef PF
9583#undef PV
9584 }
9585
18bd398b 9586 printf ("\n");
948f632f
DA
9587
9588 free (aux->funtab);
32ec8896
NC
9589
9590 return res;
57346661
AM
9591}
9592
015dc7e1 9593static bool
dda8d76d
NC
9594slurp_hppa_unwind_table (Filedata * filedata,
9595 struct hppa_unw_aux_info * aux,
9596 Elf_Internal_Shdr * sec)
57346661 9597{
26c527e6 9598 uint64_t size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9599 Elf_Internal_Phdr * seg;
9600 struct hppa_unw_table_entry * tep;
9601 Elf_Internal_Shdr * relsec;
9602 Elf_Internal_Rela * rela;
9603 Elf_Internal_Rela * rp;
9604 unsigned char * table;
9605 unsigned char * tp;
9606 Elf_Internal_Sym * sym;
9607 const char * relname;
57346661 9608
57346661
AM
9609 /* First, find the starting address of the segment that includes
9610 this section. */
dda8d76d 9611 if (filedata->file_header.e_phnum)
57346661 9612 {
dda8d76d 9613 if (! get_program_headers (filedata))
015dc7e1 9614 return false;
57346661 9615
dda8d76d
NC
9616 for (seg = filedata->program_headers;
9617 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9618 ++seg)
9619 {
9620 if (seg->p_type != PT_LOAD)
9621 continue;
9622
9623 if (sec->sh_addr >= seg->p_vaddr
9624 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9625 {
9626 aux->seg_base = seg->p_vaddr;
9627 break;
9628 }
9629 }
9630 }
9631
9632 /* Second, build the unwind table from the contents of the unwind
9633 section. */
9634 size = sec->sh_size;
dda8d76d 9635 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9636 _("unwind table"));
57346661 9637 if (!table)
015dc7e1 9638 return false;
57346661 9639
1c0751b2
DA
9640 unw_ent_size = 16;
9641 nentries = size / unw_ent_size;
9642 size = unw_ent_size * nentries;
57346661 9643
e3fdc001 9644 aux->table_len = nentries;
3f5e193b
NC
9645 tep = aux->table = (struct hppa_unw_table_entry *)
9646 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9647
1c0751b2 9648 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9649 {
9650 unsigned int tmp1, tmp2;
9651
9652 tep->start.section = SHN_UNDEF;
9653 tep->end.section = SHN_UNDEF;
9654
1c0751b2
DA
9655 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9656 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9657 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9658 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9659
9660 tep->start.offset += aux->seg_base;
9661 tep->end.offset += aux->seg_base;
57346661
AM
9662
9663 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9664 tep->Millicode = (tmp1 >> 30) & 0x1;
9665 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9666 tep->Region_description = (tmp1 >> 27) & 0x3;
9667 tep->reserved1 = (tmp1 >> 26) & 0x1;
9668 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9669 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9670 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9671 tep->Args_stored = (tmp1 >> 15) & 0x1;
9672 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9673 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9674 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9675 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9676 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9677 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9678 tep->cxx_info = (tmp1 >> 8) & 0x1;
9679 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9680 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9681 tep->reserved2 = (tmp1 >> 5) & 0x1;
9682 tep->Save_SP = (tmp1 >> 4) & 0x1;
9683 tep->Save_RP = (tmp1 >> 3) & 0x1;
9684 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9685 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9686 tep->Cleanup_defined = tmp1 & 0x1;
9687
9688 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9689 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9690 tep->Large_frame = (tmp2 >> 29) & 0x1;
9691 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9692 tep->reserved4 = (tmp2 >> 27) & 0x1;
9693 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9694 }
9695 free (table);
9696
9697 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9698 for (relsec = filedata->section_headers;
9699 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9700 ++relsec)
9701 {
9702 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9703 || relsec->sh_info >= filedata->file_header.e_shnum
9704 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9705 continue;
9706
dda8d76d 9707 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9708 & rela, & nrelas))
015dc7e1 9709 return false;
57346661
AM
9710
9711 for (rp = rela; rp < rela + nrelas; ++rp)
9712 {
4770fb94 9713 unsigned int sym_ndx;
726bd37d
AM
9714 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9715 relname = elf_hppa_reloc_type (r_type);
57346661 9716
726bd37d
AM
9717 if (relname == NULL)
9718 {
9719 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9720 continue;
9721 }
9722
57346661 9723 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9724 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9725 {
726bd37d 9726 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9727 continue;
9728 }
9729
9730 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9731 if (i >= aux->table_len)
9732 {
26c527e6
AM
9733 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9734 i);
726bd37d
AM
9735 continue;
9736 }
57346661 9737
4770fb94
AM
9738 sym_ndx = get_reloc_symindex (rp->r_info);
9739 if (sym_ndx >= aux->nsyms)
9740 {
9741 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9742 sym_ndx);
9743 continue;
9744 }
9745 sym = aux->symtab + sym_ndx;
9746
43f6cd05 9747 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9748 {
9749 case 0:
9750 aux->table[i].start.section = sym->st_shndx;
1e456d54 9751 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9752 break;
9753 case 1:
9754 aux->table[i].end.section = sym->st_shndx;
1e456d54 9755 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9756 break;
9757 default:
9758 break;
9759 }
9760 }
9761
9762 free (rela);
9763 }
9764
015dc7e1 9765 return true;
57346661
AM
9766}
9767
015dc7e1 9768static bool
dda8d76d 9769hppa_process_unwind (Filedata * filedata)
57346661 9770{
57346661 9771 struct hppa_unw_aux_info aux;
2cf0635d 9772 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9773 Elf_Internal_Shdr * sec;
26c527e6 9774 size_t i;
015dc7e1 9775 bool res = true;
57346661 9776
dda8d76d 9777 if (filedata->string_table == NULL)
015dc7e1 9778 return false;
1b31d05e
NC
9779
9780 memset (& aux, 0, sizeof (aux));
57346661 9781
dda8d76d 9782 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9783 {
28d13567 9784 if (sec->sh_type == SHT_SYMTAB)
57346661 9785 {
28d13567 9786 if (aux.symtab)
4082ef84 9787 {
28d13567
AM
9788 error (_("Multiple symbol tables encountered\n"));
9789 free (aux.symtab);
9790 aux.symtab = NULL;
4082ef84 9791 free (aux.strtab);
28d13567 9792 aux.strtab = NULL;
4082ef84 9793 }
28d13567
AM
9794 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9795 &aux.strtab, &aux.strtab_size))
015dc7e1 9796 return false;
57346661 9797 }
84714f86
AM
9798 else if (section_name_valid (filedata, sec)
9799 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9800 unwsec = sec;
9801 }
9802
9803 if (!unwsec)
9804 printf (_("\nThere are no unwind sections in this file.\n"));
9805
dda8d76d 9806 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9807 {
84714f86
AM
9808 if (section_name_valid (filedata, sec)
9809 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9810 {
26c527e6 9811 uint64_t num_unwind = sec->sh_size / 16;
dda8d76d 9812
26c527e6
AM
9813 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
9814 "contains %" PRIu64 " entry:\n",
9815 "\nUnwind section '%s' at offset %#" PRIx64 " "
9816 "contains %" PRIu64 " entries:\n",
d3a49aa8 9817 num_unwind),
dda8d76d 9818 printable_section_name (filedata, sec),
26c527e6 9819 sec->sh_offset,
d3a49aa8 9820 num_unwind);
57346661 9821
dda8d76d 9822 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9823 res = false;
66b09c7e
S
9824
9825 if (res && aux.table_len > 0)
32ec8896 9826 {
dda8d76d 9827 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9828 res = false;
32ec8896 9829 }
57346661 9830
9db70fc3 9831 free ((char *) aux.table);
57346661
AM
9832 aux.table = NULL;
9833 }
9834 }
9835
9db70fc3
AM
9836 free (aux.symtab);
9837 free ((char *) aux.strtab);
32ec8896
NC
9838
9839 return res;
57346661
AM
9840}
9841
0b6ae522
DJ
9842struct arm_section
9843{
a734115a
NC
9844 unsigned char * data; /* The unwind data. */
9845 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9846 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
26c527e6 9847 uint64_t nrelas; /* The number of relocations. */
a734115a
NC
9848 unsigned int rel_type; /* REL or RELA ? */
9849 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9850};
9851
9852struct arm_unw_aux_info
9853{
dda8d76d 9854 Filedata * filedata; /* The file containing the unwind sections. */
a734115a 9855 Elf_Internal_Sym * symtab; /* The file's symbol table. */
26c527e6 9856 uint64_t nsyms; /* Number of symbols. */
948f632f 9857 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9858 uint64_t nfuns; /* Number of these symbols. */
a734115a 9859 char * strtab; /* The file's string table. */
26c527e6 9860 uint64_t strtab_size; /* Size of string table. */
0b6ae522
DJ
9861};
9862
9863static const char *
dda8d76d
NC
9864arm_print_vma_and_name (Filedata * filedata,
9865 struct arm_unw_aux_info * aux,
625d49fc 9866 uint64_t fn,
dda8d76d 9867 struct absaddr addr)
0b6ae522
DJ
9868{
9869 const char *procname;
625d49fc 9870 uint64_t sym_offset;
0b6ae522
DJ
9871
9872 if (addr.section == SHN_UNDEF)
9873 addr.offset = fn;
9874
dda8d76d 9875 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9876 aux->strtab_size, addr, &procname,
9877 &sym_offset);
9878
9879 print_vma (fn, PREFIX_HEX);
9880
9881 if (procname)
9882 {
9883 fputs (" <", stdout);
9884 fputs (procname, stdout);
9885
9886 if (sym_offset)
26c527e6 9887 printf ("+0x%" PRIx64, sym_offset);
0b6ae522
DJ
9888 fputc ('>', stdout);
9889 }
9890
9891 return procname;
9892}
9893
9894static void
9895arm_free_section (struct arm_section *arm_sec)
9896{
9db70fc3
AM
9897 free (arm_sec->data);
9898 free (arm_sec->rela);
0b6ae522
DJ
9899}
9900
a734115a
NC
9901/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9902 cached section and install SEC instead.
9903 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9904 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9905 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9906 relocation's offset in ADDR.
1b31d05e
NC
9907 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9908 into the string table of the symbol associated with the reloc. If no
9909 reloc was applied store -1 there.
9910 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9911
015dc7e1 9912static bool
dda8d76d
NC
9913get_unwind_section_word (Filedata * filedata,
9914 struct arm_unw_aux_info * aux,
1b31d05e
NC
9915 struct arm_section * arm_sec,
9916 Elf_Internal_Shdr * sec,
625d49fc 9917 uint64_t word_offset,
1b31d05e
NC
9918 unsigned int * wordp,
9919 struct absaddr * addr,
625d49fc 9920 uint64_t * sym_name)
0b6ae522
DJ
9921{
9922 Elf_Internal_Rela *rp;
9923 Elf_Internal_Sym *sym;
9924 const char * relname;
9925 unsigned int word;
015dc7e1 9926 bool wrapped;
0b6ae522 9927
e0a31db1 9928 if (sec == NULL || arm_sec == NULL)
015dc7e1 9929 return false;
e0a31db1 9930
0b6ae522
DJ
9931 addr->section = SHN_UNDEF;
9932 addr->offset = 0;
9933
1b31d05e 9934 if (sym_name != NULL)
625d49fc 9935 *sym_name = (uint64_t) -1;
1b31d05e 9936
a734115a 9937 /* If necessary, update the section cache. */
0b6ae522
DJ
9938 if (sec != arm_sec->sec)
9939 {
9940 Elf_Internal_Shdr *relsec;
9941
9942 arm_free_section (arm_sec);
9943
9944 arm_sec->sec = sec;
dda8d76d 9945 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9946 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9947 arm_sec->rela = NULL;
9948 arm_sec->nrelas = 0;
9949
dda8d76d
NC
9950 for (relsec = filedata->section_headers;
9951 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9952 ++relsec)
9953 {
dda8d76d
NC
9954 if (relsec->sh_info >= filedata->file_header.e_shnum
9955 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9956 /* PR 15745: Check the section type as well. */
9957 || (relsec->sh_type != SHT_REL
9958 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9959 continue;
9960
a734115a 9961 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9962 if (relsec->sh_type == SHT_REL)
9963 {
dda8d76d 9964 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9965 relsec->sh_size,
9966 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9967 return false;
0b6ae522 9968 }
1ae40aa4 9969 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9970 {
dda8d76d 9971 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9972 relsec->sh_size,
9973 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9974 return false;
0b6ae522 9975 }
1ae40aa4 9976 break;
0b6ae522
DJ
9977 }
9978
9979 arm_sec->next_rela = arm_sec->rela;
9980 }
9981
a734115a 9982 /* If there is no unwind data we can do nothing. */
0b6ae522 9983 if (arm_sec->data == NULL)
015dc7e1 9984 return false;
0b6ae522 9985
e0a31db1 9986 /* If the offset is invalid then fail. */
f32ba729
NC
9987 if (/* PR 21343 *//* PR 18879 */
9988 sec->sh_size < 4
625d49fc 9989 || word_offset > sec->sh_size - 4)
015dc7e1 9990 return false;
e0a31db1 9991
a734115a 9992 /* Get the word at the required offset. */
0b6ae522
DJ
9993 word = byte_get (arm_sec->data + word_offset, 4);
9994
0eff7165
NC
9995 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9996 if (arm_sec->rela == NULL)
9997 {
9998 * wordp = word;
015dc7e1 9999 return true;
0eff7165
NC
10000 }
10001
a734115a 10002 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 10003 wrapped = false;
0b6ae522
DJ
10004 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
10005 {
625d49fc 10006 uint64_t prelval, offset;
0b6ae522
DJ
10007
10008 if (rp->r_offset > word_offset && !wrapped)
10009 {
10010 rp = arm_sec->rela;
015dc7e1 10011 wrapped = true;
0b6ae522
DJ
10012 }
10013 if (rp->r_offset > word_offset)
10014 break;
10015
10016 if (rp->r_offset & 3)
10017 {
26c527e6
AM
10018 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
10019 rp->r_offset);
0b6ae522
DJ
10020 continue;
10021 }
10022
10023 if (rp->r_offset < word_offset)
10024 continue;
10025
74e1a04b
NC
10026 /* PR 17531: file: 027-161405-0.004 */
10027 if (aux->symtab == NULL)
10028 continue;
10029
0b6ae522
DJ
10030 if (arm_sec->rel_type == SHT_REL)
10031 {
10032 offset = word & 0x7fffffff;
10033 if (offset & 0x40000000)
625d49fc 10034 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 10035 }
a734115a 10036 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 10037 offset = rp->r_addend;
a734115a 10038 else
74e1a04b
NC
10039 {
10040 error (_("Unknown section relocation type %d encountered\n"),
10041 arm_sec->rel_type);
10042 break;
10043 }
0b6ae522 10044
071436c6
NC
10045 /* PR 17531 file: 027-1241568-0.004. */
10046 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
10047 {
26c527e6
AM
10048 error (_("Bad symbol index in unwind relocation "
10049 "(%" PRIu64 " > %" PRIu64 ")\n"),
10050 ELF32_R_SYM (rp->r_info), aux->nsyms);
071436c6
NC
10051 break;
10052 }
10053
10054 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
10055 offset += sym->st_value;
10056 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
10057
a734115a 10058 /* Check that we are processing the expected reloc type. */
dda8d76d 10059 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
10060 {
10061 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10062 if (relname == NULL)
10063 {
10064 warn (_("Skipping unknown ARM relocation type: %d\n"),
10065 (int) ELF32_R_TYPE (rp->r_info));
10066 continue;
10067 }
a734115a
NC
10068
10069 if (streq (relname, "R_ARM_NONE"))
10070 continue;
0b4362b0 10071
a734115a
NC
10072 if (! streq (relname, "R_ARM_PREL31"))
10073 {
071436c6 10074 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
10075 continue;
10076 }
10077 }
dda8d76d 10078 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
10079 {
10080 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10081 if (relname == NULL)
10082 {
10083 warn (_("Skipping unknown C6000 relocation type: %d\n"),
10084 (int) ELF32_R_TYPE (rp->r_info));
10085 continue;
10086 }
0b4362b0 10087
a734115a
NC
10088 if (streq (relname, "R_C6000_NONE"))
10089 continue;
10090
10091 if (! streq (relname, "R_C6000_PREL31"))
10092 {
071436c6 10093 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
10094 continue;
10095 }
10096
10097 prelval >>= 1;
10098 }
10099 else
74e1a04b
NC
10100 {
10101 /* This function currently only supports ARM and TI unwinders. */
10102 warn (_("Only TI and ARM unwinders are currently supported\n"));
10103 break;
10104 }
fa197c1c 10105
625d49fc 10106 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
10107 addr->section = sym->st_shndx;
10108 addr->offset = offset;
74e1a04b 10109
1b31d05e
NC
10110 if (sym_name)
10111 * sym_name = sym->st_name;
0b6ae522
DJ
10112 break;
10113 }
10114
10115 *wordp = word;
10116 arm_sec->next_rela = rp;
10117
015dc7e1 10118 return true;
0b6ae522
DJ
10119}
10120
a734115a
NC
10121static const char *tic6x_unwind_regnames[16] =
10122{
0b4362b0
RM
10123 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
10124 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
10125 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
10126};
fa197c1c 10127
0b6ae522 10128static void
fa197c1c 10129decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 10130{
fa197c1c
PB
10131 int i;
10132
10133 for (i = 12; mask; mask >>= 1, i--)
10134 {
10135 if (mask & 1)
10136 {
10137 fputs (tic6x_unwind_regnames[i], stdout);
10138 if (mask > 1)
10139 fputs (", ", stdout);
10140 }
10141 }
10142}
0b6ae522
DJ
10143
10144#define ADVANCE \
10145 if (remaining == 0 && more_words) \
10146 { \
10147 data_offset += 4; \
dda8d76d 10148 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 10149 data_offset, & word, & addr, NULL)) \
015dc7e1 10150 return false; \
0b6ae522
DJ
10151 remaining = 4; \
10152 more_words--; \
10153 } \
10154
10155#define GET_OP(OP) \
10156 ADVANCE; \
10157 if (remaining) \
10158 { \
10159 remaining--; \
10160 (OP) = word >> 24; \
10161 word <<= 8; \
10162 } \
10163 else \
10164 { \
2b692964 10165 printf (_("[Truncated opcode]\n")); \
015dc7e1 10166 return false; \
0b6ae522 10167 } \
cc5914eb 10168 printf ("0x%02x ", OP)
0b6ae522 10169
015dc7e1 10170static bool
dda8d76d
NC
10171decode_arm_unwind_bytecode (Filedata * filedata,
10172 struct arm_unw_aux_info * aux,
948f632f
DA
10173 unsigned int word,
10174 unsigned int remaining,
10175 unsigned int more_words,
625d49fc 10176 uint64_t data_offset,
948f632f
DA
10177 Elf_Internal_Shdr * data_sec,
10178 struct arm_section * data_arm_sec)
fa197c1c
PB
10179{
10180 struct absaddr addr;
015dc7e1 10181 bool res = true;
0b6ae522
DJ
10182
10183 /* Decode the unwinding instructions. */
10184 while (1)
10185 {
10186 unsigned int op, op2;
10187
10188 ADVANCE;
10189 if (remaining == 0)
10190 break;
10191 remaining--;
10192 op = word >> 24;
10193 word <<= 8;
10194
cc5914eb 10195 printf (" 0x%02x ", op);
0b6ae522
DJ
10196
10197 if ((op & 0xc0) == 0x00)
10198 {
10199 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10200
cc5914eb 10201 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
10202 }
10203 else if ((op & 0xc0) == 0x40)
10204 {
10205 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10206
cc5914eb 10207 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
10208 }
10209 else if ((op & 0xf0) == 0x80)
10210 {
10211 GET_OP (op2);
10212 if (op == 0x80 && op2 == 0)
10213 printf (_("Refuse to unwind"));
10214 else
10215 {
10216 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 10217 bool first = true;
0b6ae522 10218 int i;
2b692964 10219
0b6ae522
DJ
10220 printf ("pop {");
10221 for (i = 0; i < 12; i++)
10222 if (mask & (1 << i))
10223 {
10224 if (first)
015dc7e1 10225 first = false;
0b6ae522
DJ
10226 else
10227 printf (", ");
10228 printf ("r%d", 4 + i);
10229 }
10230 printf ("}");
10231 }
10232 }
10233 else if ((op & 0xf0) == 0x90)
10234 {
10235 if (op == 0x9d || op == 0x9f)
10236 printf (_(" [Reserved]"));
10237 else
cc5914eb 10238 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
10239 }
10240 else if ((op & 0xf0) == 0xa0)
10241 {
10242 int end = 4 + (op & 0x07);
015dc7e1 10243 bool first = true;
0b6ae522 10244 int i;
61865e30 10245
0b6ae522
DJ
10246 printf (" pop {");
10247 for (i = 4; i <= end; i++)
10248 {
10249 if (first)
015dc7e1 10250 first = false;
0b6ae522
DJ
10251 else
10252 printf (", ");
10253 printf ("r%d", i);
10254 }
10255 if (op & 0x08)
10256 {
1b31d05e 10257 if (!first)
0b6ae522
DJ
10258 printf (", ");
10259 printf ("r14");
10260 }
10261 printf ("}");
10262 }
10263 else if (op == 0xb0)
10264 printf (_(" finish"));
10265 else if (op == 0xb1)
10266 {
10267 GET_OP (op2);
10268 if (op2 == 0 || (op2 & 0xf0) != 0)
10269 printf (_("[Spare]"));
10270 else
10271 {
10272 unsigned int mask = op2 & 0x0f;
015dc7e1 10273 bool first = true;
0b6ae522 10274 int i;
61865e30 10275
0b6ae522
DJ
10276 printf ("pop {");
10277 for (i = 0; i < 12; i++)
10278 if (mask & (1 << i))
10279 {
10280 if (first)
015dc7e1 10281 first = false;
0b6ae522
DJ
10282 else
10283 printf (", ");
10284 printf ("r%d", i);
10285 }
10286 printf ("}");
10287 }
10288 }
10289 else if (op == 0xb2)
10290 {
b115cf96 10291 unsigned char buf[9];
0b6ae522 10292 unsigned int i, len;
26c527e6 10293 uint64_t offset;
61865e30 10294
b115cf96 10295 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
10296 {
10297 GET_OP (buf[i]);
10298 if ((buf[i] & 0x80) == 0)
10299 break;
10300 }
4082ef84 10301 if (i == sizeof (buf))
32ec8896 10302 {
27a45f42 10303 error (_("corrupt change to vsp\n"));
015dc7e1 10304 res = false;
32ec8896 10305 }
4082ef84
NC
10306 else
10307 {
015dc7e1 10308 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
10309 assert (len == i + 1);
10310 offset = offset * 4 + 0x204;
26c527e6 10311 printf ("vsp = vsp + %" PRId64, offset);
4082ef84 10312 }
0b6ae522 10313 }
61865e30 10314 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 10315 {
61865e30
NC
10316 unsigned int first, last;
10317
10318 GET_OP (op2);
10319 first = op2 >> 4;
10320 last = op2 & 0x0f;
10321 if (op == 0xc8)
10322 first = first + 16;
10323 printf ("pop {D%d", first);
10324 if (last)
10325 printf ("-D%d", first + last);
10326 printf ("}");
10327 }
09854a88
TB
10328 else if (op == 0xb4)
10329 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
10330 else if (op == 0xb5)
10331 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
10332 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
10333 {
10334 unsigned int count = op & 0x07;
10335
10336 printf ("pop {D8");
10337 if (count)
10338 printf ("-D%d", 8 + count);
10339 printf ("}");
10340 }
10341 else if (op >= 0xc0 && op <= 0xc5)
10342 {
10343 unsigned int count = op & 0x07;
10344
10345 printf (" pop {wR10");
10346 if (count)
10347 printf ("-wR%d", 10 + count);
10348 printf ("}");
10349 }
10350 else if (op == 0xc6)
10351 {
10352 unsigned int first, last;
10353
10354 GET_OP (op2);
10355 first = op2 >> 4;
10356 last = op2 & 0x0f;
10357 printf ("pop {wR%d", first);
10358 if (last)
10359 printf ("-wR%d", first + last);
10360 printf ("}");
10361 }
10362 else if (op == 0xc7)
10363 {
10364 GET_OP (op2);
10365 if (op2 == 0 || (op2 & 0xf0) != 0)
10366 printf (_("[Spare]"));
0b6ae522
DJ
10367 else
10368 {
61865e30 10369 unsigned int mask = op2 & 0x0f;
015dc7e1 10370 bool first = true;
61865e30
NC
10371 int i;
10372
10373 printf ("pop {");
10374 for (i = 0; i < 4; i++)
10375 if (mask & (1 << i))
10376 {
10377 if (first)
015dc7e1 10378 first = false;
61865e30
NC
10379 else
10380 printf (", ");
10381 printf ("wCGR%d", i);
10382 }
10383 printf ("}");
0b6ae522
DJ
10384 }
10385 }
61865e30 10386 else
32ec8896
NC
10387 {
10388 printf (_(" [unsupported opcode]"));
015dc7e1 10389 res = false;
32ec8896
NC
10390 }
10391
0b6ae522
DJ
10392 printf ("\n");
10393 }
32ec8896
NC
10394
10395 return res;
fa197c1c
PB
10396}
10397
015dc7e1 10398static bool
dda8d76d
NC
10399decode_tic6x_unwind_bytecode (Filedata * filedata,
10400 struct arm_unw_aux_info * aux,
948f632f
DA
10401 unsigned int word,
10402 unsigned int remaining,
10403 unsigned int more_words,
625d49fc 10404 uint64_t data_offset,
948f632f
DA
10405 Elf_Internal_Shdr * data_sec,
10406 struct arm_section * data_arm_sec)
fa197c1c
PB
10407{
10408 struct absaddr addr;
10409
10410 /* Decode the unwinding instructions. */
10411 while (1)
10412 {
10413 unsigned int op, op2;
10414
10415 ADVANCE;
10416 if (remaining == 0)
10417 break;
10418 remaining--;
10419 op = word >> 24;
10420 word <<= 8;
10421
9cf03b7e 10422 printf (" 0x%02x ", op);
fa197c1c
PB
10423
10424 if ((op & 0xc0) == 0x00)
10425 {
10426 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10427 printf (" sp = sp + %d", offset);
fa197c1c
PB
10428 }
10429 else if ((op & 0xc0) == 0x80)
10430 {
10431 GET_OP (op2);
10432 if (op == 0x80 && op2 == 0)
10433 printf (_("Refuse to unwind"));
10434 else
10435 {
10436 unsigned int mask = ((op & 0x1f) << 8) | op2;
10437 if (op & 0x20)
10438 printf ("pop compact {");
10439 else
10440 printf ("pop {");
10441
10442 decode_tic6x_unwind_regmask (mask);
10443 printf("}");
10444 }
10445 }
10446 else if ((op & 0xf0) == 0xc0)
10447 {
10448 unsigned int reg;
10449 unsigned int nregs;
10450 unsigned int i;
10451 const char *name;
a734115a
NC
10452 struct
10453 {
32ec8896
NC
10454 unsigned int offset;
10455 unsigned int reg;
fa197c1c
PB
10456 } regpos[16];
10457
10458 /* Scan entire instruction first so that GET_OP output is not
10459 interleaved with disassembly. */
10460 nregs = 0;
10461 for (i = 0; nregs < (op & 0xf); i++)
10462 {
10463 GET_OP (op2);
10464 reg = op2 >> 4;
10465 if (reg != 0xf)
10466 {
10467 regpos[nregs].offset = i * 2;
10468 regpos[nregs].reg = reg;
10469 nregs++;
10470 }
10471
10472 reg = op2 & 0xf;
10473 if (reg != 0xf)
10474 {
10475 regpos[nregs].offset = i * 2 + 1;
10476 regpos[nregs].reg = reg;
10477 nregs++;
10478 }
10479 }
10480
10481 printf (_("pop frame {"));
18344509 10482 if (nregs == 0)
fa197c1c 10483 {
18344509
NC
10484 printf (_("*corrupt* - no registers specified"));
10485 }
10486 else
10487 {
10488 reg = nregs - 1;
10489 for (i = i * 2; i > 0; i--)
fa197c1c 10490 {
18344509
NC
10491 if (regpos[reg].offset == i - 1)
10492 {
10493 name = tic6x_unwind_regnames[regpos[reg].reg];
10494 if (reg > 0)
10495 reg--;
10496 }
10497 else
10498 name = _("[pad]");
fa197c1c 10499
18344509
NC
10500 fputs (name, stdout);
10501 if (i > 1)
10502 printf (", ");
10503 }
fa197c1c
PB
10504 }
10505
10506 printf ("}");
10507 }
10508 else if (op == 0xd0)
10509 printf (" MOV FP, SP");
10510 else if (op == 0xd1)
10511 printf (" __c6xabi_pop_rts");
10512 else if (op == 0xd2)
10513 {
10514 unsigned char buf[9];
10515 unsigned int i, len;
26c527e6 10516 uint64_t offset;
a734115a 10517
fa197c1c
PB
10518 for (i = 0; i < sizeof (buf); i++)
10519 {
10520 GET_OP (buf[i]);
10521 if ((buf[i] & 0x80) == 0)
10522 break;
10523 }
0eff7165
NC
10524 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10525 if (i == sizeof (buf))
10526 {
0eff7165 10527 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10528 return false;
0eff7165 10529 }
948f632f 10530
015dc7e1 10531 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10532 assert (len == i + 1);
10533 offset = offset * 8 + 0x408;
26c527e6 10534 printf (_("sp = sp + %" PRId64), offset);
fa197c1c
PB
10535 }
10536 else if ((op & 0xf0) == 0xe0)
10537 {
10538 if ((op & 0x0f) == 7)
10539 printf (" RETURN");
10540 else
10541 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10542 }
10543 else
10544 {
10545 printf (_(" [unsupported opcode]"));
10546 }
10547 putchar ('\n');
10548 }
32ec8896 10549
015dc7e1 10550 return true;
fa197c1c
PB
10551}
10552
625d49fc
AM
10553static uint64_t
10554arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10555{
625d49fc 10556 uint64_t offset;
fa197c1c
PB
10557
10558 offset = word & 0x7fffffff;
10559 if (offset & 0x40000000)
625d49fc 10560 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10561
dda8d76d 10562 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10563 offset <<= 1;
10564
10565 return offset + where;
10566}
10567
015dc7e1 10568static bool
dda8d76d
NC
10569decode_arm_unwind (Filedata * filedata,
10570 struct arm_unw_aux_info * aux,
1b31d05e
NC
10571 unsigned int word,
10572 unsigned int remaining,
625d49fc 10573 uint64_t data_offset,
1b31d05e
NC
10574 Elf_Internal_Shdr * data_sec,
10575 struct arm_section * data_arm_sec)
fa197c1c
PB
10576{
10577 int per_index;
10578 unsigned int more_words = 0;
37e14bc3 10579 struct absaddr addr;
625d49fc 10580 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10581 bool res = true;
fa197c1c
PB
10582
10583 if (remaining == 0)
10584 {
1b31d05e
NC
10585 /* Fetch the first word.
10586 Note - when decoding an object file the address extracted
10587 here will always be 0. So we also pass in the sym_name
10588 parameter so that we can find the symbol associated with
10589 the personality routine. */
dda8d76d 10590 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10591 & word, & addr, & sym_name))
015dc7e1 10592 return false;
1b31d05e 10593
fa197c1c
PB
10594 remaining = 4;
10595 }
c93dbb25
CZ
10596 else
10597 {
10598 addr.section = SHN_UNDEF;
10599 addr.offset = 0;
10600 }
fa197c1c
PB
10601
10602 if ((word & 0x80000000) == 0)
10603 {
10604 /* Expand prel31 for personality routine. */
625d49fc 10605 uint64_t fn;
fa197c1c
PB
10606 const char *procname;
10607
dda8d76d 10608 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10609 printf (_(" Personality routine: "));
1b31d05e
NC
10610 if (fn == 0
10611 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10612 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10613 {
10614 procname = aux->strtab + sym_name;
10615 print_vma (fn, PREFIX_HEX);
10616 if (procname)
10617 {
10618 fputs (" <", stdout);
10619 fputs (procname, stdout);
10620 fputc ('>', stdout);
10621 }
10622 }
10623 else
dda8d76d 10624 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10625 fputc ('\n', stdout);
10626
10627 /* The GCC personality routines use the standard compact
10628 encoding, starting with one byte giving the number of
10629 words. */
10630 if (procname != NULL
24d127aa
ML
10631 && (startswith (procname, "__gcc_personality_v0")
10632 || startswith (procname, "__gxx_personality_v0")
10633 || startswith (procname, "__gcj_personality_v0")
10634 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10635 {
10636 remaining = 0;
10637 more_words = 1;
10638 ADVANCE;
10639 if (!remaining)
10640 {
10641 printf (_(" [Truncated data]\n"));
015dc7e1 10642 return false;
fa197c1c
PB
10643 }
10644 more_words = word >> 24;
10645 word <<= 8;
10646 remaining--;
10647 per_index = -1;
10648 }
10649 else
015dc7e1 10650 return true;
fa197c1c
PB
10651 }
10652 else
10653 {
1b31d05e 10654 /* ARM EHABI Section 6.3:
0b4362b0 10655
1b31d05e 10656 An exception-handling table entry for the compact model looks like:
0b4362b0 10657
1b31d05e
NC
10658 31 30-28 27-24 23-0
10659 -- ----- ----- ----
10660 1 0 index Data for personalityRoutine[index] */
10661
dda8d76d 10662 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10663 && (word & 0x70000000))
32ec8896
NC
10664 {
10665 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10666 res = false;
32ec8896 10667 }
1b31d05e 10668
fa197c1c 10669 per_index = (word >> 24) & 0x7f;
1b31d05e 10670 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10671 if (per_index == 0)
10672 {
10673 more_words = 0;
10674 word <<= 8;
10675 remaining--;
10676 }
10677 else if (per_index < 3)
10678 {
10679 more_words = (word >> 16) & 0xff;
10680 word <<= 16;
10681 remaining -= 2;
10682 }
10683 }
10684
dda8d76d 10685 switch (filedata->file_header.e_machine)
fa197c1c
PB
10686 {
10687 case EM_ARM:
10688 if (per_index < 3)
10689 {
dda8d76d 10690 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10691 data_offset, data_sec, data_arm_sec))
015dc7e1 10692 res = false;
fa197c1c
PB
10693 }
10694 else
1b31d05e
NC
10695 {
10696 warn (_("Unknown ARM compact model index encountered\n"));
10697 printf (_(" [reserved]\n"));
015dc7e1 10698 res = false;
1b31d05e 10699 }
fa197c1c
PB
10700 break;
10701
10702 case EM_TI_C6000:
10703 if (per_index < 3)
10704 {
dda8d76d 10705 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10706 data_offset, data_sec, data_arm_sec))
015dc7e1 10707 res = false;
fa197c1c
PB
10708 }
10709 else if (per_index < 5)
10710 {
10711 if (((word >> 17) & 0x7f) == 0x7f)
10712 printf (_(" Restore stack from frame pointer\n"));
10713 else
10714 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10715 printf (_(" Registers restored: "));
10716 if (per_index == 4)
10717 printf (" (compact) ");
10718 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10719 putchar ('\n');
10720 printf (_(" Return register: %s\n"),
10721 tic6x_unwind_regnames[word & 0xf]);
10722 }
10723 else
1b31d05e 10724 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10725 break;
10726
10727 default:
74e1a04b 10728 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10729 filedata->file_header.e_machine);
015dc7e1 10730 res = false;
fa197c1c 10731 }
0b6ae522
DJ
10732
10733 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10734
10735 return res;
0b6ae522
DJ
10736}
10737
015dc7e1 10738static bool
dda8d76d
NC
10739dump_arm_unwind (Filedata * filedata,
10740 struct arm_unw_aux_info * aux,
10741 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10742{
10743 struct arm_section exidx_arm_sec, extab_arm_sec;
10744 unsigned int i, exidx_len;
26c527e6 10745 uint64_t j, nfuns;
015dc7e1 10746 bool res = true;
0b6ae522
DJ
10747
10748 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10749 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10750 exidx_len = exidx_sec->sh_size / 8;
10751
948f632f
DA
10752 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10753 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10754 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10755 aux->funtab[nfuns++] = aux->symtab[j];
10756 aux->nfuns = nfuns;
10757 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10758
0b6ae522
DJ
10759 for (i = 0; i < exidx_len; i++)
10760 {
10761 unsigned int exidx_fn, exidx_entry;
10762 struct absaddr fn_addr, entry_addr;
625d49fc 10763 uint64_t fn;
0b6ae522
DJ
10764
10765 fputc ('\n', stdout);
10766
dda8d76d 10767 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10768 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10769 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10770 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10771 {
948f632f 10772 free (aux->funtab);
1b31d05e
NC
10773 arm_free_section (& exidx_arm_sec);
10774 arm_free_section (& extab_arm_sec);
015dc7e1 10775 return false;
0b6ae522
DJ
10776 }
10777
83c257ca
NC
10778 /* ARM EHABI, Section 5:
10779 An index table entry consists of 2 words.
10780 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10781 if (exidx_fn & 0x80000000)
32ec8896
NC
10782 {
10783 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10784 res = false;
32ec8896 10785 }
83c257ca 10786
dda8d76d 10787 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10788
dda8d76d 10789 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10790 fputs (": ", stdout);
10791
10792 if (exidx_entry == 1)
10793 {
10794 print_vma (exidx_entry, PREFIX_HEX);
10795 fputs (" [cantunwind]\n", stdout);
10796 }
10797 else if (exidx_entry & 0x80000000)
10798 {
10799 print_vma (exidx_entry, PREFIX_HEX);
10800 fputc ('\n', stdout);
dda8d76d 10801 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10802 }
10803 else
10804 {
625d49fc 10805 uint64_t table, table_offset = 0;
0b6ae522
DJ
10806 Elf_Internal_Shdr *table_sec;
10807
10808 fputs ("@", stdout);
dda8d76d 10809 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10810 print_vma (table, PREFIX_HEX);
10811 printf ("\n");
10812
10813 /* Locate the matching .ARM.extab. */
10814 if (entry_addr.section != SHN_UNDEF
dda8d76d 10815 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10816 {
dda8d76d 10817 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10818 table_offset = entry_addr.offset;
1a915552 10819 /* PR 18879 */
625d49fc 10820 if (table_offset > table_sec->sh_size)
1a915552 10821 {
26c527e6
AM
10822 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
10823 table_offset,
dda8d76d 10824 printable_section_name (filedata, table_sec));
015dc7e1 10825 res = false;
1a915552
NC
10826 continue;
10827 }
0b6ae522
DJ
10828 }
10829 else
10830 {
dda8d76d 10831 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10832 if (table_sec != NULL)
10833 table_offset = table - table_sec->sh_addr;
10834 }
32ec8896 10835
0b6ae522
DJ
10836 if (table_sec == NULL)
10837 {
26c527e6
AM
10838 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
10839 table);
015dc7e1 10840 res = false;
0b6ae522
DJ
10841 continue;
10842 }
32ec8896 10843
dda8d76d 10844 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10845 &extab_arm_sec))
015dc7e1 10846 res = false;
0b6ae522
DJ
10847 }
10848 }
10849
10850 printf ("\n");
10851
948f632f 10852 free (aux->funtab);
0b6ae522
DJ
10853 arm_free_section (&exidx_arm_sec);
10854 arm_free_section (&extab_arm_sec);
32ec8896
NC
10855
10856 return res;
0b6ae522
DJ
10857}
10858
fa197c1c 10859/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10860
015dc7e1 10861static bool
dda8d76d 10862arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10863{
10864 struct arm_unw_aux_info aux;
10865 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522 10866 Elf_Internal_Shdr *sec;
26c527e6 10867 size_t i;
fa197c1c 10868 unsigned int sec_type;
015dc7e1 10869 bool res = true;
0b6ae522 10870
dda8d76d 10871 switch (filedata->file_header.e_machine)
fa197c1c
PB
10872 {
10873 case EM_ARM:
10874 sec_type = SHT_ARM_EXIDX;
10875 break;
10876
10877 case EM_TI_C6000:
10878 sec_type = SHT_C6000_UNWIND;
10879 break;
10880
0b4362b0 10881 default:
74e1a04b 10882 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10883 filedata->file_header.e_machine);
015dc7e1 10884 return false;
fa197c1c
PB
10885 }
10886
dda8d76d 10887 if (filedata->string_table == NULL)
015dc7e1 10888 return false;
1b31d05e
NC
10889
10890 memset (& aux, 0, sizeof (aux));
dda8d76d 10891 aux.filedata = filedata;
0b6ae522 10892
dda8d76d 10893 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10894 {
28d13567 10895 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10896 {
28d13567 10897 if (aux.symtab)
74e1a04b 10898 {
28d13567
AM
10899 error (_("Multiple symbol tables encountered\n"));
10900 free (aux.symtab);
10901 aux.symtab = NULL;
74e1a04b 10902 free (aux.strtab);
28d13567 10903 aux.strtab = NULL;
74e1a04b 10904 }
28d13567
AM
10905 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10906 &aux.strtab, &aux.strtab_size))
015dc7e1 10907 return false;
0b6ae522 10908 }
fa197c1c 10909 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10910 unwsec = sec;
10911 }
10912
1b31d05e 10913 if (unwsec == NULL)
0b6ae522 10914 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10915 else
dda8d76d 10916 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10917 {
10918 if (sec->sh_type == sec_type)
10919 {
26c527e6
AM
10920 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
10921 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
10922 "contains %" PRIu64 " entry:\n",
10923 "\nUnwind section '%s' at offset %#" PRIx64 " "
10924 "contains %" PRIu64 " entries:\n",
d3a49aa8 10925 num_unwind),
dda8d76d 10926 printable_section_name (filedata, sec),
26c527e6 10927 sec->sh_offset,
d3a49aa8 10928 num_unwind);
0b6ae522 10929
dda8d76d 10930 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10931 res = false;
1b31d05e
NC
10932 }
10933 }
0b6ae522 10934
9db70fc3
AM
10935 free (aux.symtab);
10936 free ((char *) aux.strtab);
32ec8896
NC
10937
10938 return res;
0b6ae522
DJ
10939}
10940
3ecc00ec
NC
10941static bool
10942no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10943{
10944 printf (_("No processor specific unwind information to decode\n"));
10945 return true;
10946}
10947
015dc7e1 10948static bool
dda8d76d 10949process_unwind (Filedata * filedata)
57346661 10950{
2cf0635d
NC
10951 struct unwind_handler
10952 {
32ec8896 10953 unsigned int machtype;
015dc7e1 10954 bool (* handler)(Filedata *);
2cf0635d
NC
10955 } handlers[] =
10956 {
0b6ae522 10957 { EM_ARM, arm_process_unwind },
57346661
AM
10958 { EM_IA_64, ia64_process_unwind },
10959 { EM_PARISC, hppa_process_unwind },
fa197c1c 10960 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10961 { EM_386, no_processor_specific_unwind },
10962 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10963 { 0, NULL }
57346661
AM
10964 };
10965 int i;
10966
10967 if (!do_unwind)
015dc7e1 10968 return true;
57346661
AM
10969
10970 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10971 if (filedata->file_header.e_machine == handlers[i].machtype)
10972 return handlers[i].handler (filedata);
57346661 10973
1b31d05e 10974 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10975 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10976 return true;
57346661
AM
10977}
10978
37c18eed
SD
10979static void
10980dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10981{
10982 switch (entry->d_tag)
10983 {
10984 case DT_AARCH64_BTI_PLT:
1dbade74 10985 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10986 break;
10987 default:
10988 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10989 break;
10990 }
10991 putchar ('\n');
10992}
10993
252b5132 10994static void
978c4450 10995dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10996{
10997 switch (entry->d_tag)
10998 {
10999 case DT_MIPS_FLAGS:
11000 if (entry->d_un.d_val == 0)
4b68bca3 11001 printf (_("NONE"));
252b5132
RH
11002 else
11003 {
11004 static const char * opts[] =
11005 {
11006 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
11007 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
11008 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
11009 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
11010 "RLD_ORDER_SAFE"
11011 };
11012 unsigned int cnt;
015dc7e1 11013 bool first = true;
2b692964 11014
60bca95a 11015 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
11016 if (entry->d_un.d_val & (1 << cnt))
11017 {
11018 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 11019 first = false;
252b5132 11020 }
252b5132
RH
11021 }
11022 break;
103f02d3 11023
252b5132 11024 case DT_MIPS_IVERSION:
84714f86 11025 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11026 printf (_("Interface Version: %s"),
84714f86 11027 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11028 else
f493c217 11029 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 11030 entry->d_un.d_ptr);
252b5132 11031 break;
103f02d3 11032
252b5132
RH
11033 case DT_MIPS_TIME_STAMP:
11034 {
d5b07ef4 11035 char timebuf[128];
2cf0635d 11036 struct tm * tmp;
91d6fa6a 11037 time_t atime = entry->d_un.d_val;
82b1b41b 11038
91d6fa6a 11039 tmp = gmtime (&atime);
82b1b41b
NC
11040 /* PR 17531: file: 6accc532. */
11041 if (tmp == NULL)
11042 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
11043 else
11044 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
11045 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11046 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 11047 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
11048 }
11049 break;
103f02d3 11050
252b5132
RH
11051 case DT_MIPS_RLD_VERSION:
11052 case DT_MIPS_LOCAL_GOTNO:
11053 case DT_MIPS_CONFLICTNO:
11054 case DT_MIPS_LIBLISTNO:
11055 case DT_MIPS_SYMTABNO:
11056 case DT_MIPS_UNREFEXTNO:
11057 case DT_MIPS_HIPAGENO:
11058 case DT_MIPS_DELTA_CLASS_NO:
11059 case DT_MIPS_DELTA_INSTANCE_NO:
11060 case DT_MIPS_DELTA_RELOC_NO:
11061 case DT_MIPS_DELTA_SYM_NO:
11062 case DT_MIPS_DELTA_CLASSSYM_NO:
11063 case DT_MIPS_COMPACT_SIZE:
c69075ac 11064 print_vma (entry->d_un.d_val, DEC);
252b5132 11065 break;
103f02d3 11066
f16a9783 11067 case DT_MIPS_XHASH:
978c4450
AM
11068 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11069 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
11070 /* Falls through. */
11071
103f02d3 11072 default:
4b68bca3 11073 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 11074 }
4b68bca3 11075 putchar ('\n');
103f02d3
UD
11076}
11077
103f02d3 11078static void
2cf0635d 11079dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
11080{
11081 switch (entry->d_tag)
11082 {
11083 case DT_HP_DLD_FLAGS:
11084 {
11085 static struct
11086 {
26c527e6 11087 unsigned int bit;
2cf0635d 11088 const char * str;
5e220199
NC
11089 }
11090 flags[] =
11091 {
11092 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
11093 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
11094 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
11095 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
11096 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
11097 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
11098 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
11099 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
11100 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
11101 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
11102 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
11103 { DT_HP_GST, "HP_GST" },
11104 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
11105 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
11106 { DT_HP_NODELETE, "HP_NODELETE" },
11107 { DT_HP_GROUP, "HP_GROUP" },
11108 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 11109 };
015dc7e1 11110 bool first = true;
5e220199 11111 size_t cnt;
625d49fc 11112 uint64_t val = entry->d_un.d_val;
103f02d3 11113
60bca95a 11114 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 11115 if (val & flags[cnt].bit)
30800947
NC
11116 {
11117 if (! first)
11118 putchar (' ');
11119 fputs (flags[cnt].str, stdout);
015dc7e1 11120 first = false;
30800947
NC
11121 val ^= flags[cnt].bit;
11122 }
76da6bbe 11123
103f02d3 11124 if (val != 0 || first)
f7a99963
NC
11125 {
11126 if (! first)
11127 putchar (' ');
11128 print_vma (val, HEX);
11129 }
103f02d3
UD
11130 }
11131 break;
76da6bbe 11132
252b5132 11133 default:
f7a99963
NC
11134 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11135 break;
252b5132 11136 }
35b1837e 11137 putchar ('\n');
252b5132
RH
11138}
11139
28f997cf
TG
11140/* VMS vs Unix time offset and factor. */
11141
11142#define VMS_EPOCH_OFFSET 35067168000000000LL
11143#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
11144#ifndef INT64_MIN
11145#define INT64_MIN (-9223372036854775807LL - 1)
11146#endif
28f997cf
TG
11147
11148/* Display a VMS time in a human readable format. */
11149
11150static void
0e3c1eeb 11151print_vms_time (int64_t vmstime)
28f997cf 11152{
dccc31de 11153 struct tm *tm = NULL;
28f997cf
TG
11154 time_t unxtime;
11155
dccc31de
AM
11156 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
11157 {
11158 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
11159 unxtime = vmstime;
11160 if (unxtime == vmstime)
11161 tm = gmtime (&unxtime);
11162 }
11163 if (tm != NULL)
11164 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
11165 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
11166 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 11167}
28f997cf 11168
ecc51f48 11169static void
2cf0635d 11170dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
11171{
11172 switch (entry->d_tag)
11173 {
0de14b54 11174 case DT_IA_64_PLT_RESERVE:
bdf4d63a 11175 /* First 3 slots reserved. */
ecc51f48
NC
11176 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11177 printf (" -- ");
11178 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
11179 break;
11180
28f997cf 11181 case DT_IA_64_VMS_LINKTIME:
28f997cf 11182 print_vms_time (entry->d_un.d_val);
28f997cf
TG
11183 break;
11184
11185 case DT_IA_64_VMS_LNKFLAGS:
11186 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11187 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
11188 printf (" CALL_DEBUG");
11189 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
11190 printf (" NOP0BUFS");
11191 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
11192 printf (" P0IMAGE");
11193 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
11194 printf (" MKTHREADS");
11195 if (entry->d_un.d_val & VMS_LF_UPCALLS)
11196 printf (" UPCALLS");
11197 if (entry->d_un.d_val & VMS_LF_IMGSTA)
11198 printf (" IMGSTA");
11199 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
11200 printf (" INITIALIZE");
11201 if (entry->d_un.d_val & VMS_LF_MAIN)
11202 printf (" MAIN");
11203 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
11204 printf (" EXE_INIT");
11205 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
11206 printf (" TBK_IN_IMG");
11207 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
11208 printf (" DBG_IN_IMG");
11209 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
11210 printf (" TBK_IN_DSF");
11211 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
11212 printf (" DBG_IN_DSF");
11213 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
11214 printf (" SIGNATURES");
11215 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
11216 printf (" REL_SEG_OFF");
11217 break;
11218
bdf4d63a
JJ
11219 default:
11220 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11221 break;
ecc51f48 11222 }
bdf4d63a 11223 putchar ('\n');
ecc51f48
NC
11224}
11225
015dc7e1 11226static bool
dda8d76d 11227get_32bit_dynamic_section (Filedata * filedata)
252b5132 11228{
2cf0635d
NC
11229 Elf32_External_Dyn * edyn;
11230 Elf32_External_Dyn * ext;
11231 Elf_Internal_Dyn * entry;
103f02d3 11232
978c4450
AM
11233 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
11234 filedata->dynamic_addr, 1,
11235 filedata->dynamic_size,
11236 _("dynamic section"));
a6e9f9df 11237 if (!edyn)
015dc7e1 11238 return false;
103f02d3 11239
071436c6
NC
11240 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11241 might not have the luxury of section headers. Look for the DT_NULL
11242 terminator to determine the number of entries. */
978c4450
AM
11243 for (ext = edyn, filedata->dynamic_nent = 0;
11244 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11245 ext++)
11246 {
978c4450 11247 filedata->dynamic_nent++;
ba2685cc
AM
11248 if (BYTE_GET (ext->d_tag) == DT_NULL)
11249 break;
11250 }
252b5132 11251
978c4450
AM
11252 filedata->dynamic_section
11253 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11254 if (filedata->dynamic_section == NULL)
252b5132 11255 {
26c527e6
AM
11256 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11257 filedata->dynamic_nent);
9ea033b2 11258 free (edyn);
015dc7e1 11259 return false;
9ea033b2 11260 }
252b5132 11261
978c4450
AM
11262 for (ext = edyn, entry = filedata->dynamic_section;
11263 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11264 ext++, entry++)
9ea033b2 11265 {
fb514b26
AM
11266 entry->d_tag = BYTE_GET (ext->d_tag);
11267 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11268 }
11269
9ea033b2
NC
11270 free (edyn);
11271
015dc7e1 11272 return true;
9ea033b2
NC
11273}
11274
015dc7e1 11275static bool
dda8d76d 11276get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 11277{
2cf0635d
NC
11278 Elf64_External_Dyn * edyn;
11279 Elf64_External_Dyn * ext;
11280 Elf_Internal_Dyn * entry;
103f02d3 11281
071436c6 11282 /* Read in the data. */
978c4450
AM
11283 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
11284 filedata->dynamic_addr, 1,
11285 filedata->dynamic_size,
11286 _("dynamic section"));
a6e9f9df 11287 if (!edyn)
015dc7e1 11288 return false;
103f02d3 11289
071436c6
NC
11290 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11291 might not have the luxury of section headers. Look for the DT_NULL
11292 terminator to determine the number of entries. */
978c4450 11293 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 11294 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 11295 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11296 ext++)
11297 {
978c4450 11298 filedata->dynamic_nent++;
66543521 11299 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
11300 break;
11301 }
252b5132 11302
978c4450
AM
11303 filedata->dynamic_section
11304 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11305 if (filedata->dynamic_section == NULL)
252b5132 11306 {
26c527e6
AM
11307 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11308 filedata->dynamic_nent);
252b5132 11309 free (edyn);
015dc7e1 11310 return false;
252b5132
RH
11311 }
11312
071436c6 11313 /* Convert from external to internal formats. */
978c4450
AM
11314 for (ext = edyn, entry = filedata->dynamic_section;
11315 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11316 ext++, entry++)
252b5132 11317 {
66543521
AM
11318 entry->d_tag = BYTE_GET (ext->d_tag);
11319 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11320 }
11321
11322 free (edyn);
11323
015dc7e1 11324 return true;
9ea033b2
NC
11325}
11326
4de91c10
AM
11327static bool
11328get_dynamic_section (Filedata *filedata)
11329{
11330 if (filedata->dynamic_section)
11331 return true;
11332
11333 if (is_32bit_elf)
11334 return get_32bit_dynamic_section (filedata);
11335 else
11336 return get_64bit_dynamic_section (filedata);
11337}
11338
e9e44622 11339static void
625d49fc 11340print_dynamic_flags (uint64_t flags)
d1133906 11341{
015dc7e1 11342 bool first = true;
13ae64f3 11343
d1133906
NC
11344 while (flags)
11345 {
625d49fc 11346 uint64_t flag;
d1133906
NC
11347
11348 flag = flags & - flags;
11349 flags &= ~ flag;
11350
e9e44622 11351 if (first)
015dc7e1 11352 first = false;
e9e44622
JJ
11353 else
11354 putc (' ', stdout);
13ae64f3 11355
d1133906
NC
11356 switch (flag)
11357 {
e9e44622
JJ
11358 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11359 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11360 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11361 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11362 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 11363 default: fputs (_("unknown"), stdout); break;
d1133906
NC
11364 }
11365 }
e9e44622 11366 puts ("");
d1133906
NC
11367}
11368
625d49fc 11369static uint64_t *
be7d229a 11370get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
11371{
11372 unsigned char * e_data;
625d49fc 11373 uint64_t * i_data;
10ca4b04 11374
be7d229a
AM
11375 /* If size_t is smaller than uint64_t, eg because you are building
11376 on a 32-bit host, then make sure that when number is cast to
11377 size_t no information is lost. */
11378 if ((size_t) number != number
11379 || ent_size * number / ent_size != number)
10ca4b04 11380 {
be7d229a 11381 error (_("Size overflow prevents reading %" PRIu64
b8281767 11382 " elements of size %u\n"),
be7d229a 11383 number, ent_size);
10ca4b04
L
11384 return NULL;
11385 }
11386
11387 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11388 attempting to allocate memory when the read is bound to fail. */
11389 if (ent_size * number > filedata->file_size)
11390 {
b8281767 11391 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 11392 number);
10ca4b04
L
11393 return NULL;
11394 }
11395
11396 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11397 if (e_data == NULL)
11398 {
b8281767 11399 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 11400 number);
10ca4b04
L
11401 return NULL;
11402 }
11403
11404 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11405 {
b8281767 11406 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 11407 number * ent_size);
10ca4b04
L
11408 free (e_data);
11409 return NULL;
11410 }
11411
625d49fc 11412 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
11413 if (i_data == NULL)
11414 {
b8281767 11415 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 11416 number);
10ca4b04
L
11417 free (e_data);
11418 return NULL;
11419 }
11420
11421 while (number--)
11422 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11423
11424 free (e_data);
11425
11426 return i_data;
11427}
11428
26c527e6 11429static uint64_t
10ca4b04
L
11430get_num_dynamic_syms (Filedata * filedata)
11431{
26c527e6 11432 uint64_t num_of_syms = 0;
10ca4b04
L
11433
11434 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11435 return num_of_syms;
11436
978c4450 11437 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11438 {
11439 unsigned char nb[8];
11440 unsigned char nc[8];
11441 unsigned int hash_ent_size = 4;
11442
11443 if ((filedata->file_header.e_machine == EM_ALPHA
11444 || filedata->file_header.e_machine == EM_S390
11445 || filedata->file_header.e_machine == EM_S390_OLD)
11446 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11447 hash_ent_size = 8;
11448
63cf857e
AM
11449 if (fseek64 (filedata->handle,
11450 (filedata->archive_file_offset
11451 + offset_from_vma (filedata,
11452 filedata->dynamic_info[DT_HASH],
11453 sizeof nb + sizeof nc)),
11454 SEEK_SET))
10ca4b04
L
11455 {
11456 error (_("Unable to seek to start of dynamic information\n"));
11457 goto no_hash;
11458 }
11459
11460 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11461 {
11462 error (_("Failed to read in number of buckets\n"));
11463 goto no_hash;
11464 }
11465
11466 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11467 {
11468 error (_("Failed to read in number of chains\n"));
11469 goto no_hash;
11470 }
11471
978c4450
AM
11472 filedata->nbuckets = byte_get (nb, hash_ent_size);
11473 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11474
2482f306
AM
11475 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11476 {
11477 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11478 hash_ent_size);
11479 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11480 hash_ent_size);
001890e1 11481
2482f306
AM
11482 if (filedata->buckets != NULL && filedata->chains != NULL)
11483 num_of_syms = filedata->nchains;
11484 }
ceb9bf11 11485 no_hash:
10ca4b04
L
11486 if (num_of_syms == 0)
11487 {
9db70fc3
AM
11488 free (filedata->buckets);
11489 filedata->buckets = NULL;
11490 free (filedata->chains);
11491 filedata->chains = NULL;
978c4450 11492 filedata->nbuckets = 0;
10ca4b04
L
11493 }
11494 }
11495
978c4450 11496 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11497 {
11498 unsigned char nb[16];
625d49fc
AM
11499 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11500 uint64_t buckets_vma;
26c527e6 11501 uint64_t hn;
10ca4b04 11502
63cf857e
AM
11503 if (fseek64 (filedata->handle,
11504 (filedata->archive_file_offset
11505 + offset_from_vma (filedata,
11506 filedata->dynamic_info_DT_GNU_HASH,
11507 sizeof nb)),
11508 SEEK_SET))
10ca4b04
L
11509 {
11510 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11511 goto no_gnu_hash;
11512 }
11513
11514 if (fread (nb, 16, 1, filedata->handle) != 1)
11515 {
11516 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11517 goto no_gnu_hash;
11518 }
11519
978c4450
AM
11520 filedata->ngnubuckets = byte_get (nb, 4);
11521 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11522 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11523 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11524 if (is_32bit_elf)
11525 buckets_vma += bitmaskwords * 4;
11526 else
11527 buckets_vma += bitmaskwords * 8;
11528
63cf857e
AM
11529 if (fseek64 (filedata->handle,
11530 (filedata->archive_file_offset
11531 + offset_from_vma (filedata, buckets_vma, 4)),
11532 SEEK_SET))
10ca4b04
L
11533 {
11534 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11535 goto no_gnu_hash;
11536 }
11537
978c4450
AM
11538 filedata->gnubuckets
11539 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11540
978c4450 11541 if (filedata->gnubuckets == NULL)
90837ea7 11542 goto no_gnu_hash;
10ca4b04 11543
978c4450
AM
11544 for (i = 0; i < filedata->ngnubuckets; i++)
11545 if (filedata->gnubuckets[i] != 0)
10ca4b04 11546 {
978c4450 11547 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11548 goto no_gnu_hash;
10ca4b04 11549
978c4450
AM
11550 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11551 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11552 }
11553
11554 if (maxchain == 0xffffffff)
90837ea7 11555 goto no_gnu_hash;
10ca4b04 11556
978c4450 11557 maxchain -= filedata->gnusymidx;
10ca4b04 11558
63cf857e
AM
11559 if (fseek64 (filedata->handle,
11560 (filedata->archive_file_offset
11561 + offset_from_vma (filedata,
11562 buckets_vma + 4 * (filedata->ngnubuckets
11563 + maxchain),
11564 4)),
11565 SEEK_SET))
10ca4b04
L
11566 {
11567 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11568 goto no_gnu_hash;
11569 }
11570
11571 do
11572 {
11573 if (fread (nb, 4, 1, filedata->handle) != 1)
11574 {
11575 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11576 goto no_gnu_hash;
11577 }
11578
11579 if (maxchain + 1 == 0)
90837ea7 11580 goto no_gnu_hash;
10ca4b04
L
11581
11582 ++maxchain;
11583 }
11584 while ((byte_get (nb, 4) & 1) == 0);
11585
63cf857e
AM
11586 if (fseek64 (filedata->handle,
11587 (filedata->archive_file_offset
11588 + offset_from_vma (filedata, (buckets_vma
11589 + 4 * filedata->ngnubuckets),
11590 4)),
11591 SEEK_SET))
10ca4b04
L
11592 {
11593 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11594 goto no_gnu_hash;
11595 }
11596
978c4450
AM
11597 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11598 filedata->ngnuchains = maxchain;
10ca4b04 11599
978c4450 11600 if (filedata->gnuchains == NULL)
90837ea7 11601 goto no_gnu_hash;
10ca4b04 11602
978c4450 11603 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11604 {
63cf857e
AM
11605 if (fseek64 (filedata->handle,
11606 (filedata->archive_file_offset
11607 + offset_from_vma (filedata, (buckets_vma
11608 + 4 * (filedata->ngnubuckets
11609 + maxchain)), 4)),
11610 SEEK_SET))
10ca4b04
L
11611 {
11612 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11613 goto no_gnu_hash;
11614 }
11615
978c4450 11616 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11617 if (filedata->mipsxlat == NULL)
11618 goto no_gnu_hash;
10ca4b04
L
11619 }
11620
978c4450
AM
11621 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11622 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11623 {
625d49fc
AM
11624 uint64_t si = filedata->gnubuckets[hn];
11625 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11626
11627 do
11628 {
978c4450 11629 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11630 {
c31ab5a0
AM
11631 if (off < filedata->ngnuchains
11632 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11633 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11634 }
11635 else
11636 {
11637 if (si >= num_of_syms)
11638 num_of_syms = si + 1;
11639 }
11640 si++;
11641 }
978c4450
AM
11642 while (off < filedata->ngnuchains
11643 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11644 }
11645
90837ea7 11646 if (num_of_syms == 0)
10ca4b04 11647 {
90837ea7 11648 no_gnu_hash:
9db70fc3
AM
11649 free (filedata->mipsxlat);
11650 filedata->mipsxlat = NULL;
11651 free (filedata->gnuchains);
11652 filedata->gnuchains = NULL;
11653 free (filedata->gnubuckets);
11654 filedata->gnubuckets = NULL;
978c4450
AM
11655 filedata->ngnubuckets = 0;
11656 filedata->ngnuchains = 0;
10ca4b04
L
11657 }
11658 }
11659
11660 return num_of_syms;
11661}
11662
b2d38a17
NC
11663/* Parse and display the contents of the dynamic section. */
11664
015dc7e1 11665static bool
dda8d76d 11666process_dynamic_section (Filedata * filedata)
9ea033b2 11667{
2cf0635d 11668 Elf_Internal_Dyn * entry;
9ea033b2 11669
93df3340 11670 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11671 {
11672 if (do_dynamic)
ca0e11aa
NC
11673 {
11674 if (filedata->is_separate)
11675 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11676 filedata->file_name);
11677 else
11678 printf (_("\nThere is no dynamic section in this file.\n"));
11679 }
9ea033b2 11680
015dc7e1 11681 return true;
9ea033b2
NC
11682 }
11683
4de91c10
AM
11684 if (!get_dynamic_section (filedata))
11685 return false;
9ea033b2 11686
252b5132 11687 /* Find the appropriate symbol table. */
978c4450 11688 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11689 {
26c527e6 11690 uint64_t num_of_syms;
2482f306 11691
978c4450
AM
11692 for (entry = filedata->dynamic_section;
11693 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11694 ++entry)
10ca4b04 11695 if (entry->d_tag == DT_SYMTAB)
978c4450 11696 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11697 else if (entry->d_tag == DT_SYMENT)
978c4450 11698 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11699 else if (entry->d_tag == DT_HASH)
978c4450 11700 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11701 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11702 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11703 else if ((filedata->file_header.e_machine == EM_MIPS
11704 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11705 && entry->d_tag == DT_MIPS_XHASH)
11706 {
978c4450
AM
11707 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11708 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11709 }
252b5132 11710
2482f306
AM
11711 num_of_syms = get_num_dynamic_syms (filedata);
11712
11713 if (num_of_syms != 0
11714 && filedata->dynamic_symbols == NULL
11715 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11716 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11717 {
11718 Elf_Internal_Phdr *seg;
625d49fc 11719 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11720
2482f306
AM
11721 if (! get_program_headers (filedata))
11722 {
11723 error (_("Cannot interpret virtual addresses "
11724 "without program headers.\n"));
015dc7e1 11725 return false;
2482f306 11726 }
252b5132 11727
2482f306
AM
11728 for (seg = filedata->program_headers;
11729 seg < filedata->program_headers + filedata->file_header.e_phnum;
11730 ++seg)
11731 {
11732 if (seg->p_type != PT_LOAD)
11733 continue;
252b5132 11734
2482f306
AM
11735 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11736 {
11737 /* See PR 21379 for a reproducer. */
11738 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11739 return false;
2482f306 11740 }
252b5132 11741
2482f306
AM
11742 if (vma >= (seg->p_vaddr & -seg->p_align)
11743 && vma < seg->p_vaddr + seg->p_filesz)
11744 {
11745 /* Since we do not know how big the symbol table is,
11746 we default to reading in up to the end of PT_LOAD
11747 segment and processing that. This is overkill, I
11748 know, but it should work. */
11749 Elf_Internal_Shdr section;
11750 section.sh_offset = (vma - seg->p_vaddr
11751 + seg->p_offset);
11752 section.sh_size = (num_of_syms
11753 * filedata->dynamic_info[DT_SYMENT]);
11754 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11755
11756 if (do_checks
11757 && filedata->dynamic_symtab_section != NULL
11758 && ((filedata->dynamic_symtab_section->sh_offset
11759 != section.sh_offset)
11760 || (filedata->dynamic_symtab_section->sh_size
11761 != section.sh_size)
11762 || (filedata->dynamic_symtab_section->sh_entsize
11763 != section.sh_entsize)))
11764 warn (_("\
11765the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11766
2482f306
AM
11767 section.sh_name = filedata->string_table_length;
11768 filedata->dynamic_symbols
4de91c10 11769 = get_elf_symbols (filedata, &section,
2482f306
AM
11770 &filedata->num_dynamic_syms);
11771 if (filedata->dynamic_symbols == NULL
11772 || filedata->num_dynamic_syms != num_of_syms)
11773 {
11774 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11775 return false;
2482f306
AM
11776 }
11777 break;
11778 }
11779 }
11780 }
11781 }
252b5132
RH
11782
11783 /* Similarly find a string table. */
978c4450
AM
11784 if (filedata->dynamic_strings == NULL)
11785 for (entry = filedata->dynamic_section;
11786 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11787 ++entry)
11788 {
11789 if (entry->d_tag == DT_STRTAB)
978c4450 11790 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11791
10ca4b04 11792 if (entry->d_tag == DT_STRSZ)
978c4450 11793 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11794
978c4450
AM
11795 if (filedata->dynamic_info[DT_STRTAB]
11796 && filedata->dynamic_info[DT_STRSZ])
10ca4b04 11797 {
26c527e6 11798 uint64_t offset;
be7d229a 11799 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11800
11801 offset = offset_from_vma (filedata,
978c4450 11802 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11803 str_tab_len);
8ac10c5b
L
11804 if (do_checks
11805 && filedata->dynamic_strtab_section
11806 && ((filedata->dynamic_strtab_section->sh_offset
11807 != (file_ptr) offset)
11808 || (filedata->dynamic_strtab_section->sh_size
11809 != str_tab_len)))
11810 warn (_("\
11811the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11812
978c4450
AM
11813 filedata->dynamic_strings
11814 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11815 _("dynamic string table"));
11816 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11817 {
11818 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11819 break;
11820 }
e3d39609 11821
978c4450 11822 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11823 break;
11824 }
11825 }
252b5132
RH
11826
11827 /* And find the syminfo section if available. */
978c4450 11828 if (filedata->dynamic_syminfo == NULL)
252b5132 11829 {
26c527e6 11830 uint64_t syminsz = 0;
252b5132 11831
978c4450
AM
11832 for (entry = filedata->dynamic_section;
11833 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11834 ++entry)
252b5132
RH
11835 {
11836 if (entry->d_tag == DT_SYMINENT)
11837 {
11838 /* Note: these braces are necessary to avoid a syntax
11839 error from the SunOS4 C compiler. */
049b0c3a
NC
11840 /* PR binutils/17531: A corrupt file can trigger this test.
11841 So do not use an assert, instead generate an error message. */
11842 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11843 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11844 (int) entry->d_un.d_val);
252b5132
RH
11845 }
11846 else if (entry->d_tag == DT_SYMINSZ)
11847 syminsz = entry->d_un.d_val;
11848 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11849 filedata->dynamic_syminfo_offset
11850 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11851 }
11852
978c4450 11853 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11854 {
2cf0635d
NC
11855 Elf_External_Syminfo * extsyminfo;
11856 Elf_External_Syminfo * extsym;
11857 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11858
11859 /* There is a syminfo section. Read the data. */
3f5e193b 11860 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11861 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11862 1, syminsz, _("symbol information"));
a6e9f9df 11863 if (!extsyminfo)
015dc7e1 11864 return false;
252b5132 11865
978c4450 11866 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11867 {
11868 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11869 free (filedata->dynamic_syminfo);
e3d39609 11870 }
978c4450
AM
11871 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11872 if (filedata->dynamic_syminfo == NULL)
252b5132 11873 {
26c527e6
AM
11874 error (_("Out of memory allocating %" PRIu64
11875 " bytes for dynamic symbol info\n"),
11876 syminsz);
015dc7e1 11877 return false;
252b5132
RH
11878 }
11879
2482f306
AM
11880 filedata->dynamic_syminfo_nent
11881 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11882 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11883 syminfo < (filedata->dynamic_syminfo
11884 + filedata->dynamic_syminfo_nent);
86dba8ee 11885 ++syminfo, ++extsym)
252b5132 11886 {
86dba8ee
AM
11887 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11888 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11889 }
11890
11891 free (extsyminfo);
11892 }
11893 }
11894
978c4450 11895 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11896 {
f253158f 11897 if (filedata->is_separate)
26c527e6
AM
11898 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
11899 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
11900 filedata->dynamic_nent),
f253158f
NC
11901 filedata->file_name,
11902 filedata->dynamic_addr,
26c527e6 11903 filedata->dynamic_nent);
84a9f195 11904 else
02da71ee 11905 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
26c527e6
AM
11906 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
11907 filedata->dynamic_nent),
84a9f195 11908 filedata->dynamic_addr,
26c527e6 11909 filedata->dynamic_nent);
ca0e11aa 11910 }
252b5132
RH
11911 if (do_dynamic)
11912 printf (_(" Tag Type Name/Value\n"));
11913
978c4450
AM
11914 for (entry = filedata->dynamic_section;
11915 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11916 entry++)
252b5132
RH
11917 {
11918 if (do_dynamic)
f7a99963 11919 {
2cf0635d 11920 const char * dtype;
e699b9ff 11921
f7a99963
NC
11922 putchar (' ');
11923 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11924 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11925 printf (" (%s)%*s", dtype,
32ec8896 11926 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11927 }
252b5132
RH
11928
11929 switch (entry->d_tag)
11930 {
d1133906
NC
11931 case DT_FLAGS:
11932 if (do_dynamic)
e9e44622 11933 print_dynamic_flags (entry->d_un.d_val);
d1133906 11934 break;
76da6bbe 11935
252b5132
RH
11936 case DT_AUXILIARY:
11937 case DT_FILTER:
019148e4
L
11938 case DT_CONFIG:
11939 case DT_DEPAUDIT:
11940 case DT_AUDIT:
252b5132
RH
11941 if (do_dynamic)
11942 {
019148e4 11943 switch (entry->d_tag)
b34976b6 11944 {
019148e4
L
11945 case DT_AUXILIARY:
11946 printf (_("Auxiliary library"));
11947 break;
11948
11949 case DT_FILTER:
11950 printf (_("Filter library"));
11951 break;
11952
b34976b6 11953 case DT_CONFIG:
019148e4
L
11954 printf (_("Configuration file"));
11955 break;
11956
11957 case DT_DEPAUDIT:
11958 printf (_("Dependency audit library"));
11959 break;
11960
11961 case DT_AUDIT:
11962 printf (_("Audit library"));
11963 break;
11964 }
252b5132 11965
84714f86 11966 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11967 printf (": [%s]\n",
84714f86 11968 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11969 else
f7a99963
NC
11970 {
11971 printf (": ");
11972 print_vma (entry->d_un.d_val, PREFIX_HEX);
11973 putchar ('\n');
11974 }
252b5132
RH
11975 }
11976 break;
11977
dcefbbbd 11978 case DT_FEATURE:
252b5132
RH
11979 if (do_dynamic)
11980 {
11981 printf (_("Flags:"));
86f55779 11982
252b5132
RH
11983 if (entry->d_un.d_val == 0)
11984 printf (_(" None\n"));
11985 else
11986 {
26c527e6 11987 uint64_t val = entry->d_un.d_val;
86f55779 11988
252b5132
RH
11989 if (val & DTF_1_PARINIT)
11990 {
11991 printf (" PARINIT");
11992 val ^= DTF_1_PARINIT;
11993 }
dcefbbbd
L
11994 if (val & DTF_1_CONFEXP)
11995 {
11996 printf (" CONFEXP");
11997 val ^= DTF_1_CONFEXP;
11998 }
252b5132 11999 if (val != 0)
26c527e6 12000 printf (" %" PRIx64, val);
252b5132
RH
12001 puts ("");
12002 }
12003 }
12004 break;
12005
12006 case DT_POSFLAG_1:
12007 if (do_dynamic)
12008 {
12009 printf (_("Flags:"));
86f55779 12010
252b5132
RH
12011 if (entry->d_un.d_val == 0)
12012 printf (_(" None\n"));
12013 else
12014 {
26c527e6 12015 uint64_t val = entry->d_un.d_val;
86f55779 12016
252b5132
RH
12017 if (val & DF_P1_LAZYLOAD)
12018 {
12019 printf (" LAZYLOAD");
12020 val ^= DF_P1_LAZYLOAD;
12021 }
12022 if (val & DF_P1_GROUPPERM)
12023 {
12024 printf (" GROUPPERM");
12025 val ^= DF_P1_GROUPPERM;
12026 }
12027 if (val != 0)
26c527e6 12028 printf (" %" PRIx64, val);
252b5132
RH
12029 puts ("");
12030 }
12031 }
12032 break;
12033
12034 case DT_FLAGS_1:
12035 if (do_dynamic)
12036 {
12037 printf (_("Flags:"));
12038 if (entry->d_un.d_val == 0)
12039 printf (_(" None\n"));
12040 else
12041 {
26c527e6 12042 uint64_t val = entry->d_un.d_val;
86f55779 12043
252b5132
RH
12044 if (val & DF_1_NOW)
12045 {
12046 printf (" NOW");
12047 val ^= DF_1_NOW;
12048 }
12049 if (val & DF_1_GLOBAL)
12050 {
12051 printf (" GLOBAL");
12052 val ^= DF_1_GLOBAL;
12053 }
12054 if (val & DF_1_GROUP)
12055 {
12056 printf (" GROUP");
12057 val ^= DF_1_GROUP;
12058 }
12059 if (val & DF_1_NODELETE)
12060 {
12061 printf (" NODELETE");
12062 val ^= DF_1_NODELETE;
12063 }
12064 if (val & DF_1_LOADFLTR)
12065 {
12066 printf (" LOADFLTR");
12067 val ^= DF_1_LOADFLTR;
12068 }
12069 if (val & DF_1_INITFIRST)
12070 {
12071 printf (" INITFIRST");
12072 val ^= DF_1_INITFIRST;
12073 }
12074 if (val & DF_1_NOOPEN)
12075 {
12076 printf (" NOOPEN");
12077 val ^= DF_1_NOOPEN;
12078 }
12079 if (val & DF_1_ORIGIN)
12080 {
12081 printf (" ORIGIN");
12082 val ^= DF_1_ORIGIN;
12083 }
12084 if (val & DF_1_DIRECT)
12085 {
12086 printf (" DIRECT");
12087 val ^= DF_1_DIRECT;
12088 }
12089 if (val & DF_1_TRANS)
12090 {
12091 printf (" TRANS");
12092 val ^= DF_1_TRANS;
12093 }
12094 if (val & DF_1_INTERPOSE)
12095 {
12096 printf (" INTERPOSE");
12097 val ^= DF_1_INTERPOSE;
12098 }
f7db6139 12099 if (val & DF_1_NODEFLIB)
dcefbbbd 12100 {
f7db6139
L
12101 printf (" NODEFLIB");
12102 val ^= DF_1_NODEFLIB;
dcefbbbd
L
12103 }
12104 if (val & DF_1_NODUMP)
12105 {
12106 printf (" NODUMP");
12107 val ^= DF_1_NODUMP;
12108 }
34b60028 12109 if (val & DF_1_CONFALT)
dcefbbbd 12110 {
34b60028
L
12111 printf (" CONFALT");
12112 val ^= DF_1_CONFALT;
12113 }
12114 if (val & DF_1_ENDFILTEE)
12115 {
12116 printf (" ENDFILTEE");
12117 val ^= DF_1_ENDFILTEE;
12118 }
12119 if (val & DF_1_DISPRELDNE)
12120 {
12121 printf (" DISPRELDNE");
12122 val ^= DF_1_DISPRELDNE;
12123 }
12124 if (val & DF_1_DISPRELPND)
12125 {
12126 printf (" DISPRELPND");
12127 val ^= DF_1_DISPRELPND;
12128 }
12129 if (val & DF_1_NODIRECT)
12130 {
12131 printf (" NODIRECT");
12132 val ^= DF_1_NODIRECT;
12133 }
12134 if (val & DF_1_IGNMULDEF)
12135 {
12136 printf (" IGNMULDEF");
12137 val ^= DF_1_IGNMULDEF;
12138 }
12139 if (val & DF_1_NOKSYMS)
12140 {
12141 printf (" NOKSYMS");
12142 val ^= DF_1_NOKSYMS;
12143 }
12144 if (val & DF_1_NOHDR)
12145 {
12146 printf (" NOHDR");
12147 val ^= DF_1_NOHDR;
12148 }
12149 if (val & DF_1_EDITED)
12150 {
12151 printf (" EDITED");
12152 val ^= DF_1_EDITED;
12153 }
12154 if (val & DF_1_NORELOC)
12155 {
12156 printf (" NORELOC");
12157 val ^= DF_1_NORELOC;
12158 }
12159 if (val & DF_1_SYMINTPOSE)
12160 {
12161 printf (" SYMINTPOSE");
12162 val ^= DF_1_SYMINTPOSE;
12163 }
12164 if (val & DF_1_GLOBAUDIT)
12165 {
12166 printf (" GLOBAUDIT");
12167 val ^= DF_1_GLOBAUDIT;
12168 }
12169 if (val & DF_1_SINGLETON)
12170 {
12171 printf (" SINGLETON");
12172 val ^= DF_1_SINGLETON;
dcefbbbd 12173 }
5c383f02
RO
12174 if (val & DF_1_STUB)
12175 {
12176 printf (" STUB");
12177 val ^= DF_1_STUB;
12178 }
12179 if (val & DF_1_PIE)
12180 {
12181 printf (" PIE");
12182 val ^= DF_1_PIE;
12183 }
b1202ffa
L
12184 if (val & DF_1_KMOD)
12185 {
12186 printf (" KMOD");
12187 val ^= DF_1_KMOD;
12188 }
12189 if (val & DF_1_WEAKFILTER)
12190 {
12191 printf (" WEAKFILTER");
12192 val ^= DF_1_WEAKFILTER;
12193 }
12194 if (val & DF_1_NOCOMMON)
12195 {
12196 printf (" NOCOMMON");
12197 val ^= DF_1_NOCOMMON;
12198 }
252b5132 12199 if (val != 0)
26c527e6 12200 printf (" %" PRIx64, val);
252b5132
RH
12201 puts ("");
12202 }
12203 }
12204 break;
12205
12206 case DT_PLTREL:
978c4450 12207 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 12208 if (do_dynamic)
dda8d76d 12209 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
12210 break;
12211
12212 case DT_NULL :
12213 case DT_NEEDED :
12214 case DT_PLTGOT :
12215 case DT_HASH :
12216 case DT_STRTAB :
12217 case DT_SYMTAB :
12218 case DT_RELA :
12219 case DT_INIT :
12220 case DT_FINI :
12221 case DT_SONAME :
12222 case DT_RPATH :
12223 case DT_SYMBOLIC:
12224 case DT_REL :
a7fd1186 12225 case DT_RELR :
252b5132
RH
12226 case DT_DEBUG :
12227 case DT_TEXTREL :
12228 case DT_JMPREL :
019148e4 12229 case DT_RUNPATH :
978c4450 12230 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
12231
12232 if (do_dynamic)
12233 {
84714f86 12234 const char *name;
252b5132 12235
84714f86
AM
12236 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12237 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12238 else
d79b3d50 12239 name = NULL;
252b5132
RH
12240
12241 if (name)
12242 {
12243 switch (entry->d_tag)
12244 {
12245 case DT_NEEDED:
12246 printf (_("Shared library: [%s]"), name);
12247
13acb58d
AM
12248 if (filedata->program_interpreter
12249 && streq (name, filedata->program_interpreter))
f7a99963 12250 printf (_(" program interpreter"));
252b5132
RH
12251 break;
12252
12253 case DT_SONAME:
f7a99963 12254 printf (_("Library soname: [%s]"), name);
252b5132
RH
12255 break;
12256
12257 case DT_RPATH:
f7a99963 12258 printf (_("Library rpath: [%s]"), name);
252b5132
RH
12259 break;
12260
019148e4
L
12261 case DT_RUNPATH:
12262 printf (_("Library runpath: [%s]"), name);
12263 break;
12264
252b5132 12265 default:
f7a99963
NC
12266 print_vma (entry->d_un.d_val, PREFIX_HEX);
12267 break;
252b5132
RH
12268 }
12269 }
12270 else
f7a99963
NC
12271 print_vma (entry->d_un.d_val, PREFIX_HEX);
12272
12273 putchar ('\n');
252b5132
RH
12274 }
12275 break;
12276
12277 case DT_PLTRELSZ:
12278 case DT_RELASZ :
12279 case DT_STRSZ :
12280 case DT_RELSZ :
12281 case DT_RELAENT :
a7fd1186
FS
12282 case DT_RELRENT :
12283 case DT_RELRSZ :
252b5132
RH
12284 case DT_SYMENT :
12285 case DT_RELENT :
978c4450 12286 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 12287 /* Fall through. */
252b5132
RH
12288 case DT_PLTPADSZ:
12289 case DT_MOVEENT :
12290 case DT_MOVESZ :
04d8355a 12291 case DT_PREINIT_ARRAYSZ:
252b5132
RH
12292 case DT_INIT_ARRAYSZ:
12293 case DT_FINI_ARRAYSZ:
047b2264
JJ
12294 case DT_GNU_CONFLICTSZ:
12295 case DT_GNU_LIBLISTSZ:
252b5132 12296 if (do_dynamic)
f7a99963
NC
12297 {
12298 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 12299 printf (_(" (bytes)\n"));
f7a99963 12300 }
252b5132
RH
12301 break;
12302
12303 case DT_VERDEFNUM:
12304 case DT_VERNEEDNUM:
12305 case DT_RELACOUNT:
12306 case DT_RELCOUNT:
12307 if (do_dynamic)
f7a99963
NC
12308 {
12309 print_vma (entry->d_un.d_val, UNSIGNED);
12310 putchar ('\n');
12311 }
252b5132
RH
12312 break;
12313
12314 case DT_SYMINSZ:
12315 case DT_SYMINENT:
12316 case DT_SYMINFO:
12317 case DT_USED:
12318 case DT_INIT_ARRAY:
12319 case DT_FINI_ARRAY:
12320 if (do_dynamic)
12321 {
d79b3d50 12322 if (entry->d_tag == DT_USED
84714f86 12323 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 12324 {
84714f86
AM
12325 const char *name
12326 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12327
b34976b6 12328 if (*name)
252b5132
RH
12329 {
12330 printf (_("Not needed object: [%s]\n"), name);
12331 break;
12332 }
12333 }
103f02d3 12334
f7a99963
NC
12335 print_vma (entry->d_un.d_val, PREFIX_HEX);
12336 putchar ('\n');
252b5132
RH
12337 }
12338 break;
12339
12340 case DT_BIND_NOW:
12341 /* The value of this entry is ignored. */
35b1837e
AM
12342 if (do_dynamic)
12343 putchar ('\n');
252b5132 12344 break;
103f02d3 12345
047b2264
JJ
12346 case DT_GNU_PRELINKED:
12347 if (do_dynamic)
12348 {
2cf0635d 12349 struct tm * tmp;
91d6fa6a 12350 time_t atime = entry->d_un.d_val;
047b2264 12351
91d6fa6a 12352 tmp = gmtime (&atime);
071436c6
NC
12353 /* PR 17533 file: 041-1244816-0.004. */
12354 if (tmp == NULL)
26c527e6
AM
12355 printf (_("<corrupt time val: %" PRIx64),
12356 (uint64_t) atime);
071436c6
NC
12357 else
12358 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12359 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12360 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12361
12362 }
12363 break;
12364
fdc90cb4 12365 case DT_GNU_HASH:
978c4450 12366 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
12367 if (do_dynamic)
12368 {
12369 print_vma (entry->d_un.d_val, PREFIX_HEX);
12370 putchar ('\n');
12371 }
12372 break;
12373
a5da3dee
VDM
12374 case DT_GNU_FLAGS_1:
12375 if (do_dynamic)
12376 {
12377 printf (_("Flags:"));
12378 if (entry->d_un.d_val == 0)
12379 printf (_(" None\n"));
12380 else
12381 {
26c527e6 12382 uint64_t val = entry->d_un.d_val;
a5da3dee
VDM
12383
12384 if (val & DF_GNU_1_UNIQUE)
12385 {
12386 printf (" UNIQUE");
12387 val ^= DF_GNU_1_UNIQUE;
12388 }
12389 if (val != 0)
26c527e6 12390 printf (" %" PRIx64, val);
a5da3dee
VDM
12391 puts ("");
12392 }
12393 }
12394 break;
12395
252b5132
RH
12396 default:
12397 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
12398 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12399 = entry->d_un.d_val;
252b5132
RH
12400
12401 if (do_dynamic)
12402 {
dda8d76d 12403 switch (filedata->file_header.e_machine)
252b5132 12404 {
37c18eed
SD
12405 case EM_AARCH64:
12406 dynamic_section_aarch64_val (entry);
12407 break;
252b5132 12408 case EM_MIPS:
4fe85591 12409 case EM_MIPS_RS3_LE:
978c4450 12410 dynamic_section_mips_val (filedata, entry);
252b5132 12411 break;
103f02d3 12412 case EM_PARISC:
b2d38a17 12413 dynamic_section_parisc_val (entry);
103f02d3 12414 break;
ecc51f48 12415 case EM_IA_64:
b2d38a17 12416 dynamic_section_ia64_val (entry);
ecc51f48 12417 break;
252b5132 12418 default:
f7a99963
NC
12419 print_vma (entry->d_un.d_val, PREFIX_HEX);
12420 putchar ('\n');
252b5132
RH
12421 }
12422 }
12423 break;
12424 }
12425 }
12426
015dc7e1 12427 return true;
252b5132
RH
12428}
12429
12430static char *
d3ba0551 12431get_ver_flags (unsigned int flags)
252b5132 12432{
6d4f21f6 12433 static char buff[128];
252b5132
RH
12434
12435 buff[0] = 0;
12436
12437 if (flags == 0)
12438 return _("none");
12439
12440 if (flags & VER_FLG_BASE)
7bb1ad17 12441 strcat (buff, "BASE");
252b5132
RH
12442
12443 if (flags & VER_FLG_WEAK)
12444 {
12445 if (flags & VER_FLG_BASE)
7bb1ad17 12446 strcat (buff, " | ");
252b5132 12447
7bb1ad17 12448 strcat (buff, "WEAK");
252b5132
RH
12449 }
12450
44ec90b9
RO
12451 if (flags & VER_FLG_INFO)
12452 {
12453 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12454 strcat (buff, " | ");
44ec90b9 12455
7bb1ad17 12456 strcat (buff, "INFO");
44ec90b9
RO
12457 }
12458
12459 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12460 {
12461 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12462 strcat (buff, " | ");
12463
12464 strcat (buff, _("<unknown>"));
12465 }
252b5132
RH
12466
12467 return buff;
12468}
12469
12470/* Display the contents of the version sections. */
98fb390a 12471
015dc7e1 12472static bool
dda8d76d 12473process_version_sections (Filedata * filedata)
252b5132 12474{
2cf0635d 12475 Elf_Internal_Shdr * section;
b34976b6 12476 unsigned i;
015dc7e1 12477 bool found = false;
252b5132
RH
12478
12479 if (! do_version)
015dc7e1 12480 return true;
252b5132 12481
dda8d76d
NC
12482 for (i = 0, section = filedata->section_headers;
12483 i < filedata->file_header.e_shnum;
b34976b6 12484 i++, section++)
252b5132
RH
12485 {
12486 switch (section->sh_type)
12487 {
12488 case SHT_GNU_verdef:
12489 {
2cf0635d 12490 Elf_External_Verdef * edefs;
26c527e6
AM
12491 size_t idx;
12492 size_t cnt;
2cf0635d 12493 char * endbuf;
252b5132 12494
015dc7e1 12495 found = true;
252b5132 12496
ca0e11aa
NC
12497 if (filedata->is_separate)
12498 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12499 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12500 section->sh_info),
12501 filedata->file_name,
12502 printable_section_name (filedata, section),
12503 section->sh_info);
12504 else
12505 printf (ngettext ("\nVersion definition section '%s' "
12506 "contains %u entry:\n",
12507 "\nVersion definition section '%s' "
12508 "contains %u entries:\n",
12509 section->sh_info),
12510 printable_section_name (filedata, section),
12511 section->sh_info);
047c3dbf 12512
625d49fc 12513 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12514 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12515 section->sh_offset, section->sh_link,
dda8d76d 12516 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12517
3f5e193b 12518 edefs = (Elf_External_Verdef *)
dda8d76d 12519 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12520 _("version definition section"));
a6e9f9df
AM
12521 if (!edefs)
12522 break;
59245841 12523 endbuf = (char *) edefs + section->sh_size;
252b5132 12524
1445030f 12525 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12526 {
2cf0635d
NC
12527 char * vstart;
12528 Elf_External_Verdef * edef;
b34976b6 12529 Elf_Internal_Verdef ent;
2cf0635d 12530 Elf_External_Verdaux * eaux;
b34976b6 12531 Elf_Internal_Verdaux aux;
26c527e6 12532 size_t isum;
b34976b6 12533 int j;
103f02d3 12534
252b5132 12535 vstart = ((char *) edefs) + idx;
54806181
AM
12536 if (vstart + sizeof (*edef) > endbuf)
12537 break;
252b5132
RH
12538
12539 edef = (Elf_External_Verdef *) vstart;
12540
12541 ent.vd_version = BYTE_GET (edef->vd_version);
12542 ent.vd_flags = BYTE_GET (edef->vd_flags);
12543 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12544 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12545 ent.vd_hash = BYTE_GET (edef->vd_hash);
12546 ent.vd_aux = BYTE_GET (edef->vd_aux);
12547 ent.vd_next = BYTE_GET (edef->vd_next);
12548
26c527e6 12549 printf (_(" %#06zx: Rev: %d Flags: %s"),
252b5132
RH
12550 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12551
12552 printf (_(" Index: %d Cnt: %d "),
12553 ent.vd_ndx, ent.vd_cnt);
12554
452bf675 12555 /* Check for overflow. */
1445030f 12556 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12557 break;
12558
252b5132
RH
12559 vstart += ent.vd_aux;
12560
1445030f
AM
12561 if (vstart + sizeof (*eaux) > endbuf)
12562 break;
252b5132
RH
12563 eaux = (Elf_External_Verdaux *) vstart;
12564
12565 aux.vda_name = BYTE_GET (eaux->vda_name);
12566 aux.vda_next = BYTE_GET (eaux->vda_next);
12567
84714f86 12568 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12569 printf (_("Name: %s\n"),
84714f86 12570 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12571 else
12572 printf (_("Name index: %ld\n"), aux.vda_name);
12573
12574 isum = idx + ent.vd_aux;
12575
b34976b6 12576 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12577 {
1445030f
AM
12578 if (aux.vda_next < sizeof (*eaux)
12579 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12580 {
12581 warn (_("Invalid vda_next field of %lx\n"),
12582 aux.vda_next);
12583 j = ent.vd_cnt;
12584 break;
12585 }
dd24e3da 12586 /* Check for overflow. */
7e26601c 12587 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12588 break;
12589
252b5132
RH
12590 isum += aux.vda_next;
12591 vstart += aux.vda_next;
12592
54806181
AM
12593 if (vstart + sizeof (*eaux) > endbuf)
12594 break;
1445030f 12595 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12596
12597 aux.vda_name = BYTE_GET (eaux->vda_name);
12598 aux.vda_next = BYTE_GET (eaux->vda_next);
12599
84714f86 12600 if (valid_dynamic_name (filedata, aux.vda_name))
26c527e6 12601 printf (_(" %#06zx: Parent %d: %s\n"),
978c4450 12602 isum, j,
84714f86 12603 get_dynamic_name (filedata, aux.vda_name));
252b5132 12604 else
26c527e6 12605 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
252b5132
RH
12606 isum, j, aux.vda_name);
12607 }
dd24e3da 12608
54806181
AM
12609 if (j < ent.vd_cnt)
12610 printf (_(" Version def aux past end of section\n"));
252b5132 12611
c9f02c3e
MR
12612 /* PR 17531:
12613 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12614 if (ent.vd_next < sizeof (*edef)
12615 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12616 {
12617 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12618 cnt = section->sh_info;
12619 break;
12620 }
452bf675 12621 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12622 break;
12623
252b5132
RH
12624 idx += ent.vd_next;
12625 }
dd24e3da 12626
54806181
AM
12627 if (cnt < section->sh_info)
12628 printf (_(" Version definition past end of section\n"));
252b5132
RH
12629
12630 free (edefs);
12631 }
12632 break;
103f02d3 12633
252b5132
RH
12634 case SHT_GNU_verneed:
12635 {
2cf0635d 12636 Elf_External_Verneed * eneed;
26c527e6
AM
12637 size_t idx;
12638 size_t cnt;
2cf0635d 12639 char * endbuf;
252b5132 12640
015dc7e1 12641 found = true;
252b5132 12642
ca0e11aa
NC
12643 if (filedata->is_separate)
12644 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12645 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12646 section->sh_info),
12647 filedata->file_name,
12648 printable_section_name (filedata, section),
12649 section->sh_info);
12650 else
12651 printf (ngettext ("\nVersion needs section '%s' "
12652 "contains %u entry:\n",
12653 "\nVersion needs section '%s' "
12654 "contains %u entries:\n",
12655 section->sh_info),
12656 printable_section_name (filedata, section),
12657 section->sh_info);
047c3dbf 12658
625d49fc 12659 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12660 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12661 section->sh_offset, section->sh_link,
dda8d76d 12662 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12663
dda8d76d 12664 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12665 section->sh_offset, 1,
12666 section->sh_size,
9cf03b7e 12667 _("Version Needs section"));
a6e9f9df
AM
12668 if (!eneed)
12669 break;
59245841 12670 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12671
12672 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12673 {
2cf0635d 12674 Elf_External_Verneed * entry;
b34976b6 12675 Elf_Internal_Verneed ent;
26c527e6 12676 size_t isum;
b34976b6 12677 int j;
2cf0635d 12678 char * vstart;
252b5132
RH
12679
12680 vstart = ((char *) eneed) + idx;
54806181
AM
12681 if (vstart + sizeof (*entry) > endbuf)
12682 break;
252b5132
RH
12683
12684 entry = (Elf_External_Verneed *) vstart;
12685
12686 ent.vn_version = BYTE_GET (entry->vn_version);
12687 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12688 ent.vn_file = BYTE_GET (entry->vn_file);
12689 ent.vn_aux = BYTE_GET (entry->vn_aux);
12690 ent.vn_next = BYTE_GET (entry->vn_next);
12691
26c527e6 12692 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
252b5132 12693
84714f86 12694 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12695 printf (_(" File: %s"),
84714f86 12696 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12697 else
12698 printf (_(" File: %lx"), ent.vn_file);
12699
12700 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12701
dd24e3da 12702 /* Check for overflow. */
7e26601c 12703 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12704 break;
252b5132
RH
12705 vstart += ent.vn_aux;
12706
12707 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12708 {
2cf0635d 12709 Elf_External_Vernaux * eaux;
b34976b6 12710 Elf_Internal_Vernaux aux;
252b5132 12711
54806181
AM
12712 if (vstart + sizeof (*eaux) > endbuf)
12713 break;
252b5132
RH
12714 eaux = (Elf_External_Vernaux *) vstart;
12715
12716 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12717 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12718 aux.vna_other = BYTE_GET (eaux->vna_other);
12719 aux.vna_name = BYTE_GET (eaux->vna_name);
12720 aux.vna_next = BYTE_GET (eaux->vna_next);
12721
84714f86 12722 if (valid_dynamic_name (filedata, aux.vna_name))
26c527e6 12723 printf (_(" %#06zx: Name: %s"),
84714f86 12724 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12725 else
26c527e6 12726 printf (_(" %#06zx: Name index: %lx"),
252b5132
RH
12727 isum, aux.vna_name);
12728
12729 printf (_(" Flags: %s Version: %d\n"),
12730 get_ver_flags (aux.vna_flags), aux.vna_other);
12731
1445030f
AM
12732 if (aux.vna_next < sizeof (*eaux)
12733 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12734 {
12735 warn (_("Invalid vna_next field of %lx\n"),
12736 aux.vna_next);
12737 j = ent.vn_cnt;
12738 break;
12739 }
1445030f
AM
12740 /* Check for overflow. */
12741 if (aux.vna_next > (size_t) (endbuf - vstart))
12742 break;
252b5132
RH
12743 isum += aux.vna_next;
12744 vstart += aux.vna_next;
12745 }
9cf03b7e 12746
54806181 12747 if (j < ent.vn_cnt)
f9a6a8f0 12748 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12749
1445030f
AM
12750 if (ent.vn_next < sizeof (*entry)
12751 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12752 {
452bf675 12753 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12754 cnt = section->sh_info;
12755 break;
12756 }
1445030f
AM
12757 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12758 break;
252b5132
RH
12759 idx += ent.vn_next;
12760 }
9cf03b7e 12761
54806181 12762 if (cnt < section->sh_info)
9cf03b7e 12763 warn (_("Missing Version Needs information\n"));
103f02d3 12764
252b5132
RH
12765 free (eneed);
12766 }
12767 break;
12768
12769 case SHT_GNU_versym:
12770 {
2cf0635d 12771 Elf_Internal_Shdr * link_section;
26c527e6 12772 uint64_t total;
8b73c356 12773 unsigned int cnt;
2cf0635d
NC
12774 unsigned char * edata;
12775 unsigned short * data;
12776 char * strtab;
12777 Elf_Internal_Sym * symbols;
12778 Elf_Internal_Shdr * string_sec;
26c527e6
AM
12779 uint64_t num_syms;
12780 uint64_t off;
252b5132 12781
dda8d76d 12782 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12783 break;
12784
dda8d76d 12785 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12786 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12787
dda8d76d 12788 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12789 break;
12790
015dc7e1 12791 found = true;
252b5132 12792
4de91c10 12793 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12794 if (symbols == NULL)
12795 break;
252b5132 12796
dda8d76d 12797 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12798
dda8d76d 12799 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12800 string_sec->sh_size,
12801 _("version string table"));
a6e9f9df 12802 if (!strtab)
0429c154
MS
12803 {
12804 free (symbols);
12805 break;
12806 }
252b5132 12807
ca0e11aa 12808 if (filedata->is_separate)
26c527e6
AM
12809 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
12810 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12811 total),
12812 filedata->file_name,
12813 printable_section_name (filedata, section),
26c527e6 12814 total);
ca0e11aa
NC
12815 else
12816 printf (ngettext ("\nVersion symbols section '%s' "
26c527e6 12817 "contains %" PRIu64 " entry:\n",
ca0e11aa 12818 "\nVersion symbols section '%s' "
26c527e6 12819 "contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12820 total),
12821 printable_section_name (filedata, section),
26c527e6 12822 total);
252b5132 12823
625d49fc 12824 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12825 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12826 section->sh_offset, section->sh_link,
dda8d76d 12827 printable_section_name (filedata, link_section));
252b5132 12828
dda8d76d 12829 off = offset_from_vma (filedata,
978c4450 12830 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12831 total * sizeof (short));
95099889
AM
12832 edata = (unsigned char *) get_data (NULL, filedata, off,
12833 sizeof (short), total,
12834 _("version symbol data"));
a6e9f9df
AM
12835 if (!edata)
12836 {
12837 free (strtab);
0429c154 12838 free (symbols);
a6e9f9df
AM
12839 break;
12840 }
252b5132 12841
3f5e193b 12842 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12843
12844 for (cnt = total; cnt --;)
b34976b6
AM
12845 data[cnt] = byte_get (edata + cnt * sizeof (short),
12846 sizeof (short));
252b5132
RH
12847
12848 free (edata);
12849
12850 for (cnt = 0; cnt < total; cnt += 4)
12851 {
12852 int j, nn;
ab273396
AM
12853 char *name;
12854 char *invalid = _("*invalid*");
252b5132
RH
12855
12856 printf (" %03x:", cnt);
12857
12858 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12859 switch (data[cnt + j])
252b5132
RH
12860 {
12861 case 0:
12862 fputs (_(" 0 (*local*) "), stdout);
12863 break;
12864
12865 case 1:
12866 fputs (_(" 1 (*global*) "), stdout);
12867 break;
12868
12869 default:
c244d050
NC
12870 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12871 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12872
dd24e3da 12873 /* If this index value is greater than the size of the symbols
ba5cdace 12874 array, break to avoid an out-of-bounds read. */
26c527e6 12875 if (cnt + j >= num_syms)
dd24e3da
NC
12876 {
12877 warn (_("invalid index into symbol array\n"));
12878 break;
12879 }
12880
ab273396 12881 name = NULL;
978c4450 12882 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12883 {
b34976b6 12884 Elf_Internal_Verneed ivn;
26c527e6 12885 uint64_t offset;
252b5132 12886
d93f0186 12887 offset = offset_from_vma
978c4450
AM
12888 (filedata,
12889 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12890 sizeof (Elf_External_Verneed));
252b5132 12891
b34976b6 12892 do
252b5132 12893 {
b34976b6
AM
12894 Elf_Internal_Vernaux ivna;
12895 Elf_External_Verneed evn;
12896 Elf_External_Vernaux evna;
26c527e6 12897 uint64_t a_off;
252b5132 12898
dda8d76d 12899 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12900 _("version need")) == NULL)
12901 break;
0b4362b0 12902
252b5132
RH
12903 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12904 ivn.vn_next = BYTE_GET (evn.vn_next);
12905
12906 a_off = offset + ivn.vn_aux;
12907
12908 do
12909 {
dda8d76d 12910 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12911 1, _("version need aux (2)")) == NULL)
12912 {
12913 ivna.vna_next = 0;
12914 ivna.vna_other = 0;
12915 }
12916 else
12917 {
12918 ivna.vna_next = BYTE_GET (evna.vna_next);
12919 ivna.vna_other = BYTE_GET (evna.vna_other);
12920 }
252b5132
RH
12921
12922 a_off += ivna.vna_next;
12923 }
b34976b6 12924 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12925 && ivna.vna_next != 0);
12926
b34976b6 12927 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12928 {
12929 ivna.vna_name = BYTE_GET (evna.vna_name);
12930
54806181 12931 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12932 name = invalid;
54806181
AM
12933 else
12934 name = strtab + ivna.vna_name;
252b5132
RH
12935 break;
12936 }
12937
12938 offset += ivn.vn_next;
12939 }
12940 while (ivn.vn_next);
12941 }
00d93f34 12942
ab273396 12943 if (data[cnt + j] != 0x8001
978c4450 12944 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12945 {
b34976b6
AM
12946 Elf_Internal_Verdef ivd;
12947 Elf_External_Verdef evd;
26c527e6 12948 uint64_t offset;
252b5132 12949
d93f0186 12950 offset = offset_from_vma
978c4450
AM
12951 (filedata,
12952 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12953 sizeof evd);
252b5132
RH
12954
12955 do
12956 {
dda8d76d 12957 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12958 _("version def")) == NULL)
12959 {
12960 ivd.vd_next = 0;
948f632f 12961 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12962 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12963 break;
59245841
NC
12964 }
12965 else
12966 {
12967 ivd.vd_next = BYTE_GET (evd.vd_next);
12968 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12969 }
252b5132
RH
12970
12971 offset += ivd.vd_next;
12972 }
c244d050 12973 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12974 && ivd.vd_next != 0);
12975
c244d050 12976 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12977 {
b34976b6
AM
12978 Elf_External_Verdaux evda;
12979 Elf_Internal_Verdaux ivda;
252b5132
RH
12980
12981 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12982
dda8d76d 12983 if (get_data (&evda, filedata,
59245841
NC
12984 offset - ivd.vd_next + ivd.vd_aux,
12985 sizeof (evda), 1,
12986 _("version def aux")) == NULL)
12987 break;
252b5132
RH
12988
12989 ivda.vda_name = BYTE_GET (evda.vda_name);
12990
54806181 12991 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12992 name = invalid;
12993 else if (name != NULL && name != invalid)
12994 name = _("*both*");
54806181
AM
12995 else
12996 name = strtab + ivda.vda_name;
252b5132
RH
12997 }
12998 }
ab273396
AM
12999 if (name != NULL)
13000 nn += printf ("(%s%-*s",
13001 name,
13002 12 - (int) strlen (name),
13003 ")");
252b5132
RH
13004
13005 if (nn < 18)
13006 printf ("%*c", 18 - nn, ' ');
13007 }
13008
13009 putchar ('\n');
13010 }
13011
13012 free (data);
13013 free (strtab);
13014 free (symbols);
13015 }
13016 break;
103f02d3 13017
252b5132
RH
13018 default:
13019 break;
13020 }
13021 }
13022
13023 if (! found)
ca0e11aa
NC
13024 {
13025 if (filedata->is_separate)
13026 printf (_("\nNo version information found in linked file '%s'.\n"),
13027 filedata->file_name);
13028 else
13029 printf (_("\nNo version information found in this file.\n"));
13030 }
252b5132 13031
015dc7e1 13032 return true;
252b5132
RH
13033}
13034
d1133906 13035static const char *
dda8d76d 13036get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 13037{
89246a0e 13038 static char buff[64];
252b5132
RH
13039
13040 switch (binding)
13041 {
b34976b6
AM
13042 case STB_LOCAL: return "LOCAL";
13043 case STB_GLOBAL: return "GLOBAL";
13044 case STB_WEAK: return "WEAK";
252b5132
RH
13045 default:
13046 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
13047 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
13048 binding);
252b5132 13049 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
13050 {
13051 if (binding == STB_GNU_UNIQUE
df3a023b 13052 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
13053 return "UNIQUE";
13054 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
13055 }
252b5132 13056 else
e9e44622 13057 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
13058 return buff;
13059 }
13060}
13061
d1133906 13062static const char *
dda8d76d 13063get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 13064{
89246a0e 13065 static char buff[64];
252b5132
RH
13066
13067 switch (type)
13068 {
b34976b6
AM
13069 case STT_NOTYPE: return "NOTYPE";
13070 case STT_OBJECT: return "OBJECT";
13071 case STT_FUNC: return "FUNC";
13072 case STT_SECTION: return "SECTION";
13073 case STT_FILE: return "FILE";
13074 case STT_COMMON: return "COMMON";
13075 case STT_TLS: return "TLS";
15ab5209
DB
13076 case STT_RELC: return "RELC";
13077 case STT_SRELC: return "SRELC";
252b5132
RH
13078 default:
13079 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 13080 {
dda8d76d 13081 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 13082 return "THUMB_FUNC";
103f02d3 13083
dda8d76d 13084 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
13085 return "REGISTER";
13086
dda8d76d 13087 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
13088 return "PARISC_MILLI";
13089
e9e44622 13090 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 13091 }
252b5132 13092 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 13093 {
dda8d76d 13094 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
13095 {
13096 if (type == STT_HP_OPAQUE)
13097 return "HP_OPAQUE";
13098 if (type == STT_HP_STUB)
13099 return "HP_STUB";
13100 }
13101
8654c01f
ML
13102 if (type == STT_GNU_IFUNC
13103 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
13104 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
13105 return "IFUNC";
13106
e9e44622 13107 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 13108 }
252b5132 13109 else
e9e44622 13110 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
13111 return buff;
13112 }
13113}
13114
d1133906 13115static const char *
d3ba0551 13116get_symbol_visibility (unsigned int visibility)
d1133906
NC
13117{
13118 switch (visibility)
13119 {
b34976b6
AM
13120 case STV_DEFAULT: return "DEFAULT";
13121 case STV_INTERNAL: return "INTERNAL";
13122 case STV_HIDDEN: return "HIDDEN";
d1133906 13123 case STV_PROTECTED: return "PROTECTED";
bee0ee85 13124 default:
27a45f42 13125 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 13126 return _("<unknown>");
d1133906
NC
13127 }
13128}
13129
2057d69d
CZ
13130static const char *
13131get_alpha_symbol_other (unsigned int other)
9abca702 13132{
2057d69d
CZ
13133 switch (other)
13134 {
13135 case STO_ALPHA_NOPV: return "NOPV";
13136 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
13137 default:
27a45f42 13138 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 13139 return _("<unknown>");
9abca702 13140 }
2057d69d
CZ
13141}
13142
fd85a6a1
NC
13143static const char *
13144get_solaris_symbol_visibility (unsigned int visibility)
13145{
13146 switch (visibility)
13147 {
13148 case 4: return "EXPORTED";
13149 case 5: return "SINGLETON";
13150 case 6: return "ELIMINATE";
13151 default: return get_symbol_visibility (visibility);
13152 }
13153}
13154
2301ed1c
SN
13155static const char *
13156get_aarch64_symbol_other (unsigned int other)
13157{
13158 static char buf[32];
13159
13160 if (other & STO_AARCH64_VARIANT_PCS)
13161 {
13162 other &= ~STO_AARCH64_VARIANT_PCS;
13163 if (other == 0)
13164 return "VARIANT_PCS";
13165 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
13166 return buf;
13167 }
13168 return NULL;
13169}
13170
5e2b0d47
NC
13171static const char *
13172get_mips_symbol_other (unsigned int other)
13173{
13174 switch (other)
13175 {
32ec8896
NC
13176 case STO_OPTIONAL: return "OPTIONAL";
13177 case STO_MIPS_PLT: return "MIPS PLT";
13178 case STO_MIPS_PIC: return "MIPS PIC";
13179 case STO_MICROMIPS: return "MICROMIPS";
13180 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
13181 case STO_MIPS16: return "MIPS16";
13182 default: return NULL;
5e2b0d47
NC
13183 }
13184}
13185
28f997cf 13186static const char *
dda8d76d 13187get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 13188{
dda8d76d 13189 if (is_ia64_vms (filedata))
28f997cf
TG
13190 {
13191 static char res[32];
13192
13193 res[0] = 0;
13194
13195 /* Function types is for images and .STB files only. */
dda8d76d 13196 switch (filedata->file_header.e_type)
28f997cf
TG
13197 {
13198 case ET_DYN:
13199 case ET_EXEC:
13200 switch (VMS_ST_FUNC_TYPE (other))
13201 {
13202 case VMS_SFT_CODE_ADDR:
13203 strcat (res, " CA");
13204 break;
13205 case VMS_SFT_SYMV_IDX:
13206 strcat (res, " VEC");
13207 break;
13208 case VMS_SFT_FD:
13209 strcat (res, " FD");
13210 break;
13211 case VMS_SFT_RESERVE:
13212 strcat (res, " RSV");
13213 break;
13214 default:
bee0ee85
NC
13215 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
13216 VMS_ST_FUNC_TYPE (other));
13217 strcat (res, " <unknown>");
13218 break;
28f997cf
TG
13219 }
13220 break;
13221 default:
13222 break;
13223 }
13224 switch (VMS_ST_LINKAGE (other))
13225 {
13226 case VMS_STL_IGNORE:
13227 strcat (res, " IGN");
13228 break;
13229 case VMS_STL_RESERVE:
13230 strcat (res, " RSV");
13231 break;
13232 case VMS_STL_STD:
13233 strcat (res, " STD");
13234 break;
13235 case VMS_STL_LNK:
13236 strcat (res, " LNK");
13237 break;
13238 default:
bee0ee85
NC
13239 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
13240 VMS_ST_LINKAGE (other));
13241 strcat (res, " <unknown>");
13242 break;
28f997cf
TG
13243 }
13244
13245 if (res[0] != 0)
13246 return res + 1;
13247 else
13248 return res;
13249 }
13250 return NULL;
13251}
13252
6911b7dc
AM
13253static const char *
13254get_ppc64_symbol_other (unsigned int other)
13255{
14732552
AM
13256 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
13257 return NULL;
13258
13259 other >>= STO_PPC64_LOCAL_BIT;
13260 if (other <= 6)
6911b7dc 13261 {
89246a0e 13262 static char buf[64];
14732552
AM
13263 if (other >= 2)
13264 other = ppc64_decode_local_entry (other);
13265 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
13266 return buf;
13267 }
13268 return NULL;
13269}
13270
8155b853
NC
13271static const char *
13272get_riscv_symbol_other (unsigned int other)
13273{
13274 static char buf[32];
13275 buf[0] = 0;
13276
13277 if (other & STO_RISCV_VARIANT_CC)
13278 {
13279 strcat (buf, _(" VARIANT_CC"));
13280 other &= ~STO_RISCV_VARIANT_CC;
13281 }
13282
13283 if (other != 0)
13284 snprintf (buf, sizeof buf, " %x", other);
13285
13286
13287 if (buf[0] != 0)
13288 return buf + 1;
13289 else
13290 return buf;
13291}
13292
5e2b0d47 13293static const char *
dda8d76d 13294get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
13295{
13296 const char * result = NULL;
89246a0e 13297 static char buff [64];
5e2b0d47
NC
13298
13299 if (other == 0)
13300 return "";
13301
dda8d76d 13302 switch (filedata->file_header.e_machine)
5e2b0d47 13303 {
2057d69d
CZ
13304 case EM_ALPHA:
13305 result = get_alpha_symbol_other (other);
13306 break;
2301ed1c
SN
13307 case EM_AARCH64:
13308 result = get_aarch64_symbol_other (other);
13309 break;
5e2b0d47
NC
13310 case EM_MIPS:
13311 result = get_mips_symbol_other (other);
28f997cf
TG
13312 break;
13313 case EM_IA_64:
dda8d76d 13314 result = get_ia64_symbol_other (filedata, other);
28f997cf 13315 break;
6911b7dc
AM
13316 case EM_PPC64:
13317 result = get_ppc64_symbol_other (other);
13318 break;
8155b853
NC
13319 case EM_RISCV:
13320 result = get_riscv_symbol_other (other);
13321 break;
5e2b0d47 13322 default:
fd85a6a1 13323 result = NULL;
5e2b0d47
NC
13324 break;
13325 }
13326
13327 if (result)
13328 return result;
13329
13330 snprintf (buff, sizeof buff, _("<other>: %x"), other);
13331 return buff;
13332}
13333
d1133906 13334static const char *
dda8d76d 13335get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 13336{
b34976b6 13337 static char buff[32];
5cf1065c 13338
252b5132
RH
13339 switch (type)
13340 {
b34976b6
AM
13341 case SHN_UNDEF: return "UND";
13342 case SHN_ABS: return "ABS";
13343 case SHN_COMMON: return "COM";
252b5132 13344 default:
9ce701e2 13345 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
13346 && filedata->file_header.e_machine == EM_IA_64
13347 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
13348 return "ANSI_COM";
13349 else if ((filedata->file_header.e_machine == EM_X86_64
13350 || filedata->file_header.e_machine == EM_L1OM
13351 || filedata->file_header.e_machine == EM_K1OM)
13352 && type == SHN_X86_64_LCOMMON)
13353 return "LARGE_COM";
13354 else if ((type == SHN_MIPS_SCOMMON
13355 && filedata->file_header.e_machine == EM_MIPS)
13356 || (type == SHN_TIC6X_SCOMMON
13357 && filedata->file_header.e_machine == EM_TI_C6000))
13358 return "SCOM";
13359 else if (type == SHN_MIPS_SUNDEFINED
13360 && filedata->file_header.e_machine == EM_MIPS)
13361 return "SUND";
13362 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
13363 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
13364 else if (type >= SHN_LOOS && type <= SHN_HIOS)
13365 sprintf (buff, "OS [0x%04x]", type & 0xffff);
13366 else if (type >= SHN_LORESERVE)
13367 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
13368 else if (filedata->file_header.e_shnum != 0
13369 && type >= filedata->file_header.e_shnum)
13370 sprintf (buff, _("bad section index[%3d]"), type);
13371 else
13372 sprintf (buff, "%3d", type);
13373 break;
fd85a6a1
NC
13374 }
13375
10ca4b04 13376 return buff;
6bd1a22c
L
13377}
13378
bb4d2ac2 13379static const char *
26c527e6
AM
13380get_symbol_version_string (Filedata *filedata,
13381 bool is_dynsym,
13382 const char *strtab,
13383 size_t strtab_size,
13384 unsigned int si,
13385 Elf_Internal_Sym *psym,
13386 enum versioned_symbol_info *sym_info,
13387 unsigned short *vna_other)
bb4d2ac2 13388{
ab273396
AM
13389 unsigned char data[2];
13390 unsigned short vers_data;
26c527e6 13391 uint64_t offset;
7a815dd5 13392 unsigned short max_vd_ndx;
bb4d2ac2 13393
ab273396 13394 if (!is_dynsym
978c4450 13395 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 13396 return NULL;
bb4d2ac2 13397
978c4450
AM
13398 offset = offset_from_vma (filedata,
13399 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 13400 sizeof data + si * sizeof (vers_data));
bb4d2ac2 13401
dda8d76d 13402 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
13403 sizeof (data), 1, _("version data")) == NULL)
13404 return NULL;
13405
13406 vers_data = byte_get (data, 2);
bb4d2ac2 13407
1f6f5dba 13408 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 13409 return NULL;
bb4d2ac2 13410
0b8b7609 13411 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
13412 max_vd_ndx = 0;
13413
ab273396
AM
13414 /* Usually we'd only see verdef for defined symbols, and verneed for
13415 undefined symbols. However, symbols defined by the linker in
13416 .dynbss for variables copied from a shared library in order to
13417 avoid text relocations are defined yet have verneed. We could
13418 use a heuristic to detect the special case, for example, check
13419 for verneed first on symbols defined in SHT_NOBITS sections, but
13420 it is simpler and more reliable to just look for both verdef and
13421 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13422
ab273396
AM
13423 if (psym->st_shndx != SHN_UNDEF
13424 && vers_data != 0x8001
978c4450 13425 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13426 {
13427 Elf_Internal_Verdef ivd;
13428 Elf_Internal_Verdaux ivda;
13429 Elf_External_Verdaux evda;
26c527e6 13430 uint64_t off;
bb4d2ac2 13431
dda8d76d 13432 off = offset_from_vma (filedata,
978c4450 13433 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13434 sizeof (Elf_External_Verdef));
13435
13436 do
bb4d2ac2 13437 {
ab273396
AM
13438 Elf_External_Verdef evd;
13439
dda8d76d 13440 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13441 _("version def")) == NULL)
13442 {
13443 ivd.vd_ndx = 0;
13444 ivd.vd_aux = 0;
13445 ivd.vd_next = 0;
1f6f5dba 13446 ivd.vd_flags = 0;
ab273396
AM
13447 }
13448 else
bb4d2ac2 13449 {
ab273396
AM
13450 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13451 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13452 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13453 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13454 }
bb4d2ac2 13455
7a815dd5
L
13456 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13457 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13458
ab273396
AM
13459 off += ivd.vd_next;
13460 }
13461 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13462
ab273396
AM
13463 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13464 {
9abca702 13465 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13466 return NULL;
13467
ab273396
AM
13468 off -= ivd.vd_next;
13469 off += ivd.vd_aux;
bb4d2ac2 13470
dda8d76d 13471 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13472 _("version def aux")) != NULL)
13473 {
13474 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13475
ab273396 13476 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13477 return (ivda.vda_name < strtab_size
13478 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13479 }
13480 }
13481 }
bb4d2ac2 13482
978c4450 13483 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13484 {
13485 Elf_External_Verneed evn;
13486 Elf_Internal_Verneed ivn;
13487 Elf_Internal_Vernaux ivna;
bb4d2ac2 13488
dda8d76d 13489 offset = offset_from_vma (filedata,
978c4450 13490 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13491 sizeof evn);
13492 do
13493 {
26c527e6 13494 uint64_t vna_off;
bb4d2ac2 13495
dda8d76d 13496 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13497 _("version need")) == NULL)
13498 {
13499 ivna.vna_next = 0;
13500 ivna.vna_other = 0;
13501 ivna.vna_name = 0;
13502 break;
13503 }
bb4d2ac2 13504
ab273396
AM
13505 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13506 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13507
ab273396 13508 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13509
ab273396
AM
13510 do
13511 {
13512 Elf_External_Vernaux evna;
bb4d2ac2 13513
dda8d76d 13514 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13515 _("version need aux (3)")) == NULL)
bb4d2ac2 13516 {
ab273396
AM
13517 ivna.vna_next = 0;
13518 ivna.vna_other = 0;
13519 ivna.vna_name = 0;
bb4d2ac2 13520 }
bb4d2ac2 13521 else
bb4d2ac2 13522 {
ab273396
AM
13523 ivna.vna_other = BYTE_GET (evna.vna_other);
13524 ivna.vna_next = BYTE_GET (evna.vna_next);
13525 ivna.vna_name = BYTE_GET (evna.vna_name);
13526 }
bb4d2ac2 13527
ab273396
AM
13528 vna_off += ivna.vna_next;
13529 }
13530 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13531
ab273396
AM
13532 if (ivna.vna_other == vers_data)
13533 break;
bb4d2ac2 13534
ab273396
AM
13535 offset += ivn.vn_next;
13536 }
13537 while (ivn.vn_next != 0);
bb4d2ac2 13538
ab273396
AM
13539 if (ivna.vna_other == vers_data)
13540 {
13541 *sym_info = symbol_undefined;
13542 *vna_other = ivna.vna_other;
13543 return (ivna.vna_name < strtab_size
13544 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13545 }
7a815dd5
L
13546 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13547 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13548 return _("<corrupt>");
bb4d2ac2 13549 }
ab273396 13550 return NULL;
bb4d2ac2
L
13551}
13552
047c3dbf
NL
13553/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13554
13555static unsigned int
625d49fc 13556print_dynamic_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13557{
13558 switch (base)
13559 {
13560 case 8:
13561 return print_vma (vma, OCTAL_5);
13562
13563 case 10:
13564 return print_vma (vma, UNSIGNED_5);
13565
13566 case 16:
13567 return print_vma (vma, PREFIX_HEX_5);
13568
13569 case 0:
13570 default:
13571 return print_vma (vma, DEC_5);
13572 }
13573}
13574
10ca4b04 13575static void
26c527e6 13576print_dynamic_symbol (Filedata *filedata, uint64_t si,
10ca4b04
L
13577 Elf_Internal_Sym *symtab,
13578 Elf_Internal_Shdr *section,
13579 char *strtab, size_t strtab_size)
252b5132 13580{
10ca4b04
L
13581 const char *version_string;
13582 enum versioned_symbol_info sym_info;
13583 unsigned short vna_other;
23356397
NC
13584 bool is_valid;
13585 const char * sstr;
10ca4b04 13586 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13587
26c527e6 13588 printf ("%6" PRId64 ": ", si);
10ca4b04
L
13589 print_vma (psym->st_value, LONG_HEX);
13590 putchar (' ');
047c3dbf 13591 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13592 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13593 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13594 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13595 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13596 else
252b5132 13597 {
10ca4b04 13598 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13599
10ca4b04
L
13600 printf (" %-7s", get_symbol_visibility (vis));
13601 /* Check to see if any other bits in the st_other field are set.
13602 Note - displaying this information disrupts the layout of the
13603 table being generated, but for the moment this case is very rare. */
13604 if (psym->st_other ^ vis)
13605 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13606 }
10ca4b04 13607 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13608
23356397
NC
13609 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13610 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13611 && filedata->section_headers != NULL
23356397
NC
13612 && psym->st_name == 0)
13613 {
84714f86
AM
13614 is_valid
13615 = section_name_valid (filedata,
13616 filedata->section_headers + psym->st_shndx);
23356397 13617 sstr = is_valid ?
84714f86
AM
13618 section_name_print (filedata,
13619 filedata->section_headers + psym->st_shndx)
23356397
NC
13620 : _("<corrupt>");
13621 }
13622 else
13623 {
84714f86 13624 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13625 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13626 }
10ca4b04
L
13627
13628 version_string
13629 = get_symbol_version_string (filedata,
13630 (section == NULL
13631 || section->sh_type == SHT_DYNSYM),
13632 strtab, strtab_size, si,
13633 psym, &sym_info, &vna_other);
b9e920ec 13634
0942c7ab
NC
13635 int len_avail = 21;
13636 if (! do_wide && version_string != NULL)
13637 {
ddb43bab 13638 char buffer[16];
0942c7ab 13639
ddb43bab 13640 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13641
13642 if (sym_info == symbol_undefined)
13643 len_avail -= sprintf (buffer," (%d)", vna_other);
13644 else if (sym_info != symbol_hidden)
13645 len_avail -= 1;
13646 }
13647
13648 print_symbol (len_avail, sstr);
b9e920ec 13649
10ca4b04
L
13650 if (version_string)
13651 {
13652 if (sym_info == symbol_undefined)
13653 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13654 else
10ca4b04
L
13655 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13656 version_string);
13657 }
6bd1a22c 13658
10ca4b04 13659 putchar ('\n');
6bd1a22c 13660
10ca4b04
L
13661 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13662 && section != NULL
13663 && si >= section->sh_info
13664 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13665 && filedata->file_header.e_machine != EM_MIPS
13666 /* Solaris binaries have been found to violate this requirement as
13667 well. Not sure if this is a bug or an ABI requirement. */
13668 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
26c527e6 13669 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
10ca4b04
L
13670 si, printable_section_name (filedata, section), section->sh_info);
13671}
f16a9783 13672
0f03783c
NC
13673static const char *
13674get_lto_kind (unsigned int kind)
13675{
13676 switch (kind)
13677 {
13678 case 0: return "DEF";
13679 case 1: return "WEAKDEF";
13680 case 2: return "UNDEF";
13681 case 3: return "WEAKUNDEF";
13682 case 4: return "COMMON";
13683 default:
13684 break;
13685 }
13686
13687 static char buffer[30];
13688 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13689 sprintf (buffer, "<unknown: %u>", kind);
13690 return buffer;
13691}
13692
13693static const char *
13694get_lto_visibility (unsigned int visibility)
13695{
13696 switch (visibility)
13697 {
13698 case 0: return "DEFAULT";
13699 case 1: return "PROTECTED";
13700 case 2: return "INTERNAL";
13701 case 3: return "HIDDEN";
13702 default:
13703 break;
13704 }
13705
13706 static char buffer[30];
13707 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13708 sprintf (buffer, "<unknown: %u>", visibility);
13709 return buffer;
13710}
13711
13712static const char *
13713get_lto_sym_type (unsigned int sym_type)
13714{
13715 switch (sym_type)
13716 {
13717 case 0: return "UNKNOWN";
13718 case 1: return "FUNCTION";
13719 case 2: return "VARIABLE";
13720 default:
13721 break;
13722 }
13723
13724 static char buffer[30];
13725 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13726 sprintf (buffer, "<unknown: %u>", sym_type);
13727 return buffer;
13728}
13729
13730/* Display an LTO format symbol table.
13731 FIXME: The format of LTO symbol tables is not formalized.
13732 So this code could need changing in the future. */
13733
015dc7e1 13734static bool
0f03783c
NC
13735display_lto_symtab (Filedata * filedata,
13736 Elf_Internal_Shdr * section)
13737{
13738 if (section->sh_size == 0)
13739 {
ca0e11aa
NC
13740 if (filedata->is_separate)
13741 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13742 printable_section_name (filedata, section),
13743 filedata->file_name);
13744 else
13745 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13746 printable_section_name (filedata, section));
047c3dbf 13747
015dc7e1 13748 return true;
0f03783c
NC
13749 }
13750
13751 if (section->sh_size > filedata->file_size)
13752 {
26c527e6 13753 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
0f03783c 13754 printable_section_name (filedata, section),
26c527e6 13755 section->sh_size);
015dc7e1 13756 return false;
0f03783c
NC
13757 }
13758
13759 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13760 section->sh_size, 1, _("LTO symbols"));
13761 if (alloced_data == NULL)
015dc7e1 13762 return false;
0f03783c
NC
13763
13764 /* Look for extended data for the symbol table. */
13765 Elf_Internal_Shdr * ext;
13766 void * ext_data_orig = NULL;
13767 char * ext_data = NULL;
13768 char * ext_data_end = NULL;
13769 char * ext_name = NULL;
13770
13771 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13772 (section_name (filedata, section)
13773 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13774 && ext_name != NULL /* Paranoia. */
13775 && (ext = find_section (filedata, ext_name)) != NULL)
13776 {
13777 if (ext->sh_size < 3)
13778 error (_("LTO Symbol extension table '%s' is empty!\n"),
13779 printable_section_name (filedata, ext));
13780 else
13781 {
13782 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13783 ext->sh_size, 1,
13784 _("LTO ext symbol data"));
13785 if (ext_data != NULL)
13786 {
13787 ext_data_end = ext_data + ext->sh_size;
13788 if (* ext_data++ != 1)
13789 error (_("Unexpected version number in symbol extension table\n"));
13790 }
13791 }
13792 }
b9e920ec 13793
0f03783c
NC
13794 const unsigned char * data = (const unsigned char *) alloced_data;
13795 const unsigned char * end = data + section->sh_size;
13796
ca0e11aa
NC
13797 if (filedata->is_separate)
13798 printf (_("\nIn linked file '%s': "), filedata->file_name);
13799 else
13800 printf ("\n");
13801
0f03783c
NC
13802 if (ext_data_orig != NULL)
13803 {
13804 if (do_wide)
ca0e11aa 13805 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13806 printable_section_name (filedata, section),
13807 printable_section_name (filedata, ext));
13808 else
13809 {
ca0e11aa 13810 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13811 printable_section_name (filedata, section));
13812 printf (_(" and extension table '%s' contain:\n"),
13813 printable_section_name (filedata, ext));
13814 }
13815 }
13816 else
ca0e11aa 13817 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13818 printable_section_name (filedata, section));
b9e920ec 13819
0f03783c 13820 /* FIXME: Add a wide version. */
b9e920ec 13821 if (ext_data_orig != NULL)
0f03783c
NC
13822 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13823 else
13824 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13825
13826 /* FIXME: We do not handle style prefixes. */
13827
13828 while (data < end)
13829 {
13830 const unsigned char * sym_name = data;
13831 data += strnlen ((const char *) sym_name, end - data) + 1;
13832 if (data >= end)
13833 goto fail;
13834
13835 const unsigned char * comdat_key = data;
13836 data += strnlen ((const char *) comdat_key, end - data) + 1;
13837 if (data >= end)
13838 goto fail;
13839
13840 if (data + 2 + 8 + 4 > end)
13841 goto fail;
13842
13843 unsigned int kind = *data++;
13844 unsigned int visibility = *data++;
13845
928c411d 13846 uint64_t size = byte_get (data, 8);
0f03783c
NC
13847 data += 8;
13848
928c411d 13849 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13850 data += 4;
13851
13852 if (ext_data != NULL)
13853 {
13854 if (ext_data < (ext_data_end - 1))
13855 {
13856 unsigned int sym_type = * ext_data ++;
13857 unsigned int sec_kind = * ext_data ++;
13858
31e5a3a3 13859 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
13860 * comdat_key == 0 ? "-" : (char *) comdat_key,
13861 get_lto_kind (kind),
13862 get_lto_visibility (visibility),
31e5a3a3
AM
13863 size,
13864 slot,
0f03783c 13865 get_lto_sym_type (sym_type),
31e5a3a3 13866 sec_kind);
0f03783c
NC
13867 print_symbol (6, (const char *) sym_name);
13868 }
13869 else
13870 {
13871 error (_("Ran out of LTO symbol extension data\n"));
13872 ext_data = NULL;
13873 /* FIXME: return FAIL result ? */
13874 }
13875 }
13876 else
13877 {
31e5a3a3 13878 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
13879 * comdat_key == 0 ? "-" : (char *) comdat_key,
13880 get_lto_kind (kind),
13881 get_lto_visibility (visibility),
31e5a3a3
AM
13882 size,
13883 slot);
0f03783c
NC
13884 print_symbol (21, (const char *) sym_name);
13885 }
13886 putchar ('\n');
13887 }
13888
13889 if (ext_data != NULL && ext_data < ext_data_end)
13890 {
13891 error (_("Data remains in the LTO symbol extension table\n"));
13892 goto fail;
13893 }
13894
13895 free (alloced_data);
13896 free (ext_data_orig);
13897 free (ext_name);
015dc7e1 13898 return true;
b9e920ec 13899
0f03783c
NC
13900 fail:
13901 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13902 free (alloced_data);
13903 free (ext_data_orig);
13904 free (ext_name);
015dc7e1 13905 return false;
0f03783c
NC
13906}
13907
13908/* Display LTO symbol tables. */
13909
015dc7e1 13910static bool
0f03783c
NC
13911process_lto_symbol_tables (Filedata * filedata)
13912{
13913 Elf_Internal_Shdr * section;
13914 unsigned int i;
015dc7e1 13915 bool res = true;
0f03783c
NC
13916
13917 if (!do_lto_syms)
015dc7e1 13918 return true;
0f03783c
NC
13919
13920 if (filedata->section_headers == NULL)
015dc7e1 13921 return true;
0f03783c
NC
13922
13923 for (i = 0, section = filedata->section_headers;
13924 i < filedata->file_header.e_shnum;
13925 i++, section++)
84714f86
AM
13926 if (section_name_valid (filedata, section)
13927 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13928 res &= display_lto_symtab (filedata, section);
13929
b9e920ec 13930 return res;
0f03783c
NC
13931}
13932
10ca4b04 13933/* Dump the symbol table. */
0f03783c 13934
015dc7e1 13935static bool
10ca4b04
L
13936process_symbol_table (Filedata * filedata)
13937{
13938 Elf_Internal_Shdr * section;
f16a9783 13939
10ca4b04 13940 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13941 return true;
6bd1a22c 13942
978c4450 13943 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13944 && do_syms
13945 && do_using_dynamic
978c4450
AM
13946 && filedata->dynamic_strings != NULL
13947 && filedata->dynamic_symbols != NULL)
6bd1a22c 13948 {
26c527e6 13949 uint64_t si;
6bd1a22c 13950
ca0e11aa
NC
13951 if (filedata->is_separate)
13952 {
26c527e6
AM
13953 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
13954 " contains %" PRIu64 " entry:\n",
13955 "\nIn linked file '%s' the dynamic symbol table"
13956 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13957 filedata->num_dynamic_syms),
13958 filedata->file_name,
13959 filedata->num_dynamic_syms);
13960 }
13961 else
13962 {
26c527e6
AM
13963 printf (ngettext ("\nSymbol table for image contains %" PRIu64
13964 " entry:\n",
13965 "\nSymbol table for image contains %" PRIu64
13966 " entries:\n",
ca0e11aa
NC
13967 filedata->num_dynamic_syms),
13968 filedata->num_dynamic_syms);
13969 }
10ca4b04
L
13970 if (is_32bit_elf)
13971 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13972 else
13973 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13974
978c4450
AM
13975 for (si = 0; si < filedata->num_dynamic_syms; si++)
13976 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13977 filedata->dynamic_strings,
13978 filedata->dynamic_strings_length);
252b5132 13979 }
8b73c356 13980 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13981 && filedata->section_headers != NULL)
252b5132 13982 {
b34976b6 13983 unsigned int i;
252b5132 13984
dda8d76d
NC
13985 for (i = 0, section = filedata->section_headers;
13986 i < filedata->file_header.e_shnum;
252b5132
RH
13987 i++, section++)
13988 {
2cf0635d 13989 char * strtab = NULL;
26c527e6 13990 uint64_t strtab_size = 0;
2cf0635d 13991 Elf_Internal_Sym * symtab;
26c527e6 13992 uint64_t si, num_syms;
252b5132 13993
2c610e4b
L
13994 if ((section->sh_type != SHT_SYMTAB
13995 && section->sh_type != SHT_DYNSYM)
13996 || (!do_syms
13997 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13998 continue;
13999
dd24e3da
NC
14000 if (section->sh_entsize == 0)
14001 {
14002 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 14003 printable_section_name (filedata, section));
dd24e3da
NC
14004 continue;
14005 }
14006
d3a49aa8 14007 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
14008
14009 if (filedata->is_separate)
26c527e6
AM
14010 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
14011 " contains %" PRIu64 " entry:\n",
14012 "\nIn linked file '%s' symbol section '%s'"
14013 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
14014 num_syms),
14015 filedata->file_name,
14016 printable_section_name (filedata, section),
14017 num_syms);
14018 else
26c527e6
AM
14019 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
14020 " entry:\n",
14021 "\nSymbol table '%s' contains %" PRIu64
14022 " entries:\n",
ca0e11aa
NC
14023 num_syms),
14024 printable_section_name (filedata, section),
14025 num_syms);
dd24e3da 14026
f7a99963 14027 if (is_32bit_elf)
ca47b30c 14028 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 14029 else
ca47b30c 14030 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 14031
4de91c10 14032 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
14033 if (symtab == NULL)
14034 continue;
14035
dda8d76d 14036 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 14037 {
dda8d76d
NC
14038 strtab = filedata->string_table;
14039 strtab_size = filedata->string_table_length;
c256ffe7 14040 }
dda8d76d 14041 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 14042 {
2cf0635d 14043 Elf_Internal_Shdr * string_sec;
252b5132 14044
dda8d76d 14045 string_sec = filedata->section_headers + section->sh_link;
252b5132 14046
dda8d76d 14047 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
14048 1, string_sec->sh_size,
14049 _("string table"));
c256ffe7 14050 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
14051 }
14052
10ca4b04
L
14053 for (si = 0; si < num_syms; si++)
14054 print_dynamic_symbol (filedata, si, symtab, section,
14055 strtab, strtab_size);
252b5132
RH
14056
14057 free (symtab);
dda8d76d 14058 if (strtab != filedata->string_table)
252b5132
RH
14059 free (strtab);
14060 }
14061 }
14062 else if (do_syms)
14063 printf
14064 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
14065
978c4450 14066 if (do_histogram && filedata->buckets != NULL)
252b5132 14067 {
26c527e6
AM
14068 uint64_t *lengths;
14069 uint64_t *counts;
14070 uint64_t hn;
625d49fc 14071 uint64_t si;
26c527e6
AM
14072 uint64_t maxlength = 0;
14073 uint64_t nzero_counts = 0;
14074 uint64_t nsyms = 0;
6bd6a03d 14075 char *visited;
252b5132 14076
d3a49aa8 14077 printf (ngettext ("\nHistogram for bucket list length "
26c527e6 14078 "(total of %" PRIu64 " bucket):\n",
d3a49aa8 14079 "\nHistogram for bucket list length "
26c527e6
AM
14080 "(total of %" PRIu64 " buckets):\n",
14081 filedata->nbuckets),
14082 filedata->nbuckets);
252b5132 14083
26c527e6 14084 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
252b5132
RH
14085 if (lengths == NULL)
14086 {
8b73c356 14087 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 14088 goto err_out;
252b5132 14089 }
978c4450
AM
14090 visited = xcmalloc (filedata->nchains, 1);
14091 memset (visited, 0, filedata->nchains);
8b73c356
NC
14092
14093 printf (_(" Length Number %% of total Coverage\n"));
978c4450 14094 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 14095 {
978c4450 14096 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 14097 {
b34976b6 14098 ++nsyms;
252b5132 14099 if (maxlength < ++lengths[hn])
b34976b6 14100 ++maxlength;
978c4450 14101 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
14102 {
14103 error (_("histogram chain is corrupt\n"));
14104 break;
14105 }
14106 visited[si] = 1;
252b5132
RH
14107 }
14108 }
6bd6a03d 14109 free (visited);
252b5132 14110
26c527e6 14111 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
14112 if (counts == NULL)
14113 {
b2e951ec 14114 free (lengths);
8b73c356 14115 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 14116 goto err_out;
252b5132
RH
14117 }
14118
978c4450 14119 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 14120 ++counts[lengths[hn]];
252b5132 14121
978c4450 14122 if (filedata->nbuckets > 0)
252b5132 14123 {
26c527e6
AM
14124 uint64_t i;
14125 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14126 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 14127 for (i = 1; i <= maxlength; ++i)
103f02d3 14128 {
66543521 14129 nzero_counts += counts[i] * i;
26c527e6 14130 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14131 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
14132 (nzero_counts * 100.0) / nsyms);
14133 }
252b5132
RH
14134 }
14135
14136 free (counts);
14137 free (lengths);
14138 }
14139
978c4450
AM
14140 free (filedata->buckets);
14141 filedata->buckets = NULL;
14142 filedata->nbuckets = 0;
14143 free (filedata->chains);
14144 filedata->chains = NULL;
252b5132 14145
978c4450 14146 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 14147 {
26c527e6
AM
14148 uint64_t *lengths;
14149 uint64_t *counts;
14150 uint64_t hn;
14151 uint64_t maxlength = 0;
14152 uint64_t nzero_counts = 0;
14153 uint64_t nsyms = 0;
fdc90cb4 14154
f16a9783 14155 printf (ngettext ("\nHistogram for `%s' bucket list length "
26c527e6 14156 "(total of %" PRIu64 " bucket):\n",
f16a9783 14157 "\nHistogram for `%s' bucket list length "
26c527e6
AM
14158 "(total of %" PRIu64 " buckets):\n",
14159 filedata->ngnubuckets),
978c4450 14160 GNU_HASH_SECTION_NAME (filedata),
26c527e6 14161 filedata->ngnubuckets);
8b73c356 14162
26c527e6 14163 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
14164 if (lengths == NULL)
14165 {
8b73c356 14166 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 14167 goto err_out;
fdc90cb4
JJ
14168 }
14169
fdc90cb4
JJ
14170 printf (_(" Length Number %% of total Coverage\n"));
14171
978c4450
AM
14172 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14173 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 14174 {
625d49fc 14175 uint64_t off, length = 1;
fdc90cb4 14176
978c4450 14177 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 14178 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
14179 off < filedata->ngnuchains
14180 && (filedata->gnuchains[off] & 1) == 0;
071436c6 14181 ++off)
fdc90cb4
JJ
14182 ++length;
14183 lengths[hn] = length;
14184 if (length > maxlength)
14185 maxlength = length;
14186 nsyms += length;
14187 }
14188
26c527e6 14189 counts = calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
14190 if (counts == NULL)
14191 {
b2e951ec 14192 free (lengths);
8b73c356 14193 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 14194 goto err_out;
fdc90cb4
JJ
14195 }
14196
978c4450 14197 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
14198 ++counts[lengths[hn]];
14199
978c4450 14200 if (filedata->ngnubuckets > 0)
fdc90cb4 14201 {
26c527e6
AM
14202 uint64_t j;
14203 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14204 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
14205 for (j = 1; j <= maxlength; ++j)
14206 {
14207 nzero_counts += counts[j] * j;
26c527e6 14208 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14209 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
14210 (nzero_counts * 100.0) / nsyms);
14211 }
14212 }
14213
14214 free (counts);
14215 free (lengths);
fdc90cb4 14216 }
978c4450
AM
14217 free (filedata->gnubuckets);
14218 filedata->gnubuckets = NULL;
14219 filedata->ngnubuckets = 0;
14220 free (filedata->gnuchains);
14221 filedata->gnuchains = NULL;
14222 filedata->ngnuchains = 0;
14223 free (filedata->mipsxlat);
14224 filedata->mipsxlat = NULL;
015dc7e1 14225 return true;
fd486f32
AM
14226
14227 err_out:
978c4450
AM
14228 free (filedata->gnubuckets);
14229 filedata->gnubuckets = NULL;
14230 filedata->ngnubuckets = 0;
14231 free (filedata->gnuchains);
14232 filedata->gnuchains = NULL;
14233 filedata->ngnuchains = 0;
14234 free (filedata->mipsxlat);
14235 filedata->mipsxlat = NULL;
14236 free (filedata->buckets);
14237 filedata->buckets = NULL;
14238 filedata->nbuckets = 0;
14239 free (filedata->chains);
14240 filedata->chains = NULL;
015dc7e1 14241 return false;
252b5132
RH
14242}
14243
015dc7e1 14244static bool
ca0e11aa 14245process_syminfo (Filedata * filedata)
252b5132 14246{
b4c96d0d 14247 unsigned int i;
252b5132 14248
978c4450 14249 if (filedata->dynamic_syminfo == NULL
252b5132
RH
14250 || !do_dynamic)
14251 /* No syminfo, this is ok. */
015dc7e1 14252 return true;
252b5132
RH
14253
14254 /* There better should be a dynamic symbol section. */
978c4450 14255 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 14256 return false;
252b5132 14257
ca0e11aa 14258 if (filedata->is_separate)
26c527e6
AM
14259 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
14260 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
ca0e11aa
NC
14261 filedata->dynamic_syminfo_nent),
14262 filedata->file_name,
14263 filedata->dynamic_syminfo_offset,
14264 filedata->dynamic_syminfo_nent);
14265 else
26c527e6
AM
14266 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
14267 " contains %d entry:\n",
14268 "\nDynamic info segment at offset %#" PRIx64
14269 " contains %d entries:\n",
978c4450 14270 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
14271 filedata->dynamic_syminfo_offset,
14272 filedata->dynamic_syminfo_nent);
252b5132
RH
14273
14274 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 14275 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 14276 {
978c4450 14277 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 14278
31104126 14279 printf ("%4d: ", i);
978c4450 14280 if (i >= filedata->num_dynamic_syms)
4082ef84 14281 printf (_("<corrupt index>"));
84714f86
AM
14282 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
14283 print_symbol (30, get_dynamic_name (filedata,
978c4450 14284 filedata->dynamic_symbols[i].st_name));
d79b3d50 14285 else
978c4450 14286 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 14287 putchar (' ');
252b5132 14288
978c4450 14289 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
14290 {
14291 case SYMINFO_BT_SELF:
14292 fputs ("SELF ", stdout);
14293 break;
14294 case SYMINFO_BT_PARENT:
14295 fputs ("PARENT ", stdout);
14296 break;
14297 default:
978c4450
AM
14298 if (filedata->dynamic_syminfo[i].si_boundto > 0
14299 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 14300 && valid_dynamic_name (filedata,
978c4450 14301 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 14302 {
84714f86 14303 print_symbol (10, get_dynamic_name (filedata,
978c4450 14304 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
14305 putchar (' ' );
14306 }
252b5132 14307 else
978c4450 14308 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
14309 break;
14310 }
14311
14312 if (flags & SYMINFO_FLG_DIRECT)
14313 printf (" DIRECT");
14314 if (flags & SYMINFO_FLG_PASSTHRU)
14315 printf (" PASSTHRU");
14316 if (flags & SYMINFO_FLG_COPY)
14317 printf (" COPY");
14318 if (flags & SYMINFO_FLG_LAZYLOAD)
14319 printf (" LAZYLOAD");
14320
14321 puts ("");
14322 }
14323
015dc7e1 14324 return true;
252b5132
RH
14325}
14326
75802ccb
CE
14327/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
14328 is contained by the region START .. END. The types of ADDR, START
14329 and END should all be the same. Note both ADDR + NELEM and END
14330 point to just beyond the end of the regions that are being tested. */
14331#define IN_RANGE(START,END,ADDR,NELEM) \
14332 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 14333
cf13d699
NC
14334/* Check to see if the given reloc needs to be handled in a target specific
14335 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
14336 FALSE.
14337
14338 If called with reloc == NULL, then this is a signal that reloc processing
14339 for the current section has finished, and any saved state should be
14340 discarded. */
09c11c86 14341
015dc7e1 14342static bool
26c527e6
AM
14343target_specific_reloc_handling (Filedata *filedata,
14344 Elf_Internal_Rela *reloc,
14345 unsigned char *start,
14346 unsigned char *end,
14347 Elf_Internal_Sym *symtab,
14348 uint64_t num_syms)
252b5132 14349{
f84ce13b 14350 unsigned int reloc_type = 0;
26c527e6 14351 uint64_t sym_index = 0;
f84ce13b
NC
14352
14353 if (reloc)
14354 {
dda8d76d 14355 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
14356 sym_index = get_reloc_symindex (reloc->r_info);
14357 }
252b5132 14358
dda8d76d 14359 switch (filedata->file_header.e_machine)
252b5132 14360 {
76244462 14361 case EM_LOONGARCH:
14362 {
14363 switch (reloc_type)
14364 {
14365 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
14366 at assembly time. */
14367 case 107: /* R_LARCH_ADD_ULEB128. */
14368 case 108: /* R_LARCH_SUB_ULEB128. */
14369 {
d3f34076 14370 uint64_t value = 0;
76244462 14371 unsigned int reloc_size = 0;
14372 int leb_ret = 0;
14373
89c70cd3
AM
14374 if (reloc->r_offset < (size_t) (end - start))
14375 value = read_leb128 (start + reloc->r_offset, end, false,
14376 &reloc_size, &leb_ret);
76244462 14377 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14378 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
14379 "ULEB128 value\n"),
14380 (long) reloc->r_offset);
14381
74a965d8
AM
14382 else if (sym_index >= num_syms)
14383 error (_("%s reloc contains invalid symbol index "
14384 "%" PRIu64 "\n"),
14385 (reloc_type == 107
14386 ? "R_LARCH_ADD_ULEB128"
14387 : "R_LARCH_SUB_ULEB128"),
14388 sym_index);
14389 else
76244462 14390 {
74a965d8
AM
14391 if (reloc_type == 107)
14392 value += reloc->r_addend + symtab[sym_index].st_value;
14393 else
14394 value -= reloc->r_addend + symtab[sym_index].st_value;
14395
14396 /* Write uleb128 value to p. */
14397 bfd_byte *p = start + reloc->r_offset;
14398 do
14399 {
14400 bfd_byte c = value & 0x7f;
14401 value >>= 7;
14402 if (--reloc_size != 0)
14403 c |= 0x80;
14404 *p++ = c;
14405 }
14406 while (reloc_size);
76244462 14407 }
76244462 14408
14409 return true;
14410 }
14411 }
14412 break;
14413 }
14414
13761a11
NC
14415 case EM_MSP430:
14416 case EM_MSP430_OLD:
14417 {
14418 static Elf_Internal_Sym * saved_sym = NULL;
14419
f84ce13b
NC
14420 if (reloc == NULL)
14421 {
14422 saved_sym = NULL;
015dc7e1 14423 return true;
f84ce13b
NC
14424 }
14425
13761a11
NC
14426 switch (reloc_type)
14427 {
14428 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 14429 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 14430 if (uses_msp430x_relocs (filedata))
13761a11 14431 break;
1a0670f3 14432 /* Fall through. */
13761a11 14433 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 14434 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
14435 /* PR 21139. */
14436 if (sym_index >= num_syms)
74a965d8
AM
14437 error (_("%s reloc contains invalid symbol index "
14438 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
f84ce13b
NC
14439 else
14440 saved_sym = symtab + sym_index;
015dc7e1 14441 return true;
13761a11
NC
14442
14443 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14444 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14445 goto handle_sym_diff;
0b4362b0 14446
13761a11
NC
14447 case 5: /* R_MSP430_16_BYTE */
14448 case 9: /* R_MSP430_8 */
7d81bc93 14449 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 14450 if (uses_msp430x_relocs (filedata))
13761a11
NC
14451 break;
14452 goto handle_sym_diff;
14453
14454 case 2: /* R_MSP430_ABS16 */
14455 case 15: /* R_MSP430X_ABS16 */
7d81bc93 14456 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 14457 if (! uses_msp430x_relocs (filedata))
13761a11
NC
14458 break;
14459 goto handle_sym_diff;
0b4362b0 14460
13761a11
NC
14461 handle_sym_diff:
14462 if (saved_sym != NULL)
14463 {
625d49fc 14464 uint64_t value;
5a805384 14465 unsigned int reloc_size = 0;
7d81bc93
JL
14466 int leb_ret = 0;
14467 switch (reloc_type)
14468 {
14469 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14470 reloc_size = 4;
14471 break;
14472 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14473 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14474 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14475 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14476 &reloc_size, &leb_ret);
7d81bc93
JL
14477 break;
14478 default:
14479 reloc_size = 2;
14480 break;
14481 }
13761a11 14482
5a805384 14483 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
14484 error (_("MSP430 ULEB128 field at %#" PRIx64
14485 " contains invalid ULEB128 value\n"),
14486 reloc->r_offset);
7d81bc93 14487 else if (sym_index >= num_syms)
74a965d8
AM
14488 error (_("%s reloc contains invalid symbol index "
14489 "%" PRIu64 "\n"), "MSP430", sym_index);
03f7786e 14490 else
f84ce13b
NC
14491 {
14492 value = reloc->r_addend + (symtab[sym_index].st_value
14493 - saved_sym->st_value);
14494
b32e566b 14495 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14496 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14497 else
14498 /* PR 21137 */
26c527e6
AM
14499 error (_("MSP430 sym diff reloc contains invalid offset: "
14500 "%#" PRIx64 "\n"),
14501 reloc->r_offset);
f84ce13b 14502 }
13761a11
NC
14503
14504 saved_sym = NULL;
015dc7e1 14505 return true;
13761a11
NC
14506 }
14507 break;
14508
14509 default:
14510 if (saved_sym != NULL)
071436c6 14511 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14512 break;
14513 }
14514 break;
14515 }
14516
cf13d699
NC
14517 case EM_MN10300:
14518 case EM_CYGNUS_MN10300:
14519 {
14520 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14521
f84ce13b
NC
14522 if (reloc == NULL)
14523 {
14524 saved_sym = NULL;
015dc7e1 14525 return true;
f84ce13b
NC
14526 }
14527
cf13d699
NC
14528 switch (reloc_type)
14529 {
14530 case 34: /* R_MN10300_ALIGN */
015dc7e1 14531 return true;
cf13d699 14532 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 14533 if (sym_index >= num_syms)
74a965d8
AM
14534 error (_("%s reloc contains invalid symbol index "
14535 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
f84ce13b
NC
14536 else
14537 saved_sym = symtab + sym_index;
015dc7e1 14538 return true;
f84ce13b 14539
cf13d699
NC
14540 case 1: /* R_MN10300_32 */
14541 case 2: /* R_MN10300_16 */
14542 if (saved_sym != NULL)
14543 {
03f7786e 14544 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14545 uint64_t value;
252b5132 14546
f84ce13b 14547 if (sym_index >= num_syms)
74a965d8
AM
14548 error (_("%s reloc contains invalid symbol index "
14549 "%" PRIu64 "\n"), "MN10300", sym_index);
03f7786e 14550 else
f84ce13b
NC
14551 {
14552 value = reloc->r_addend + (symtab[sym_index].st_value
14553 - saved_sym->st_value);
14554
b32e566b 14555 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14556 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 14557 else
26c527e6
AM
14558 error (_("MN10300 sym diff reloc contains invalid offset:"
14559 " %#" PRIx64 "\n"),
14560 reloc->r_offset);
f84ce13b 14561 }
252b5132 14562
cf13d699 14563 saved_sym = NULL;
015dc7e1 14564 return true;
cf13d699
NC
14565 }
14566 break;
14567 default:
14568 if (saved_sym != NULL)
071436c6 14569 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14570 break;
14571 }
14572 break;
14573 }
6ff71e76
NC
14574
14575 case EM_RL78:
14576 {
625d49fc
AM
14577 static uint64_t saved_sym1 = 0;
14578 static uint64_t saved_sym2 = 0;
14579 static uint64_t value;
6ff71e76 14580
f84ce13b
NC
14581 if (reloc == NULL)
14582 {
14583 saved_sym1 = saved_sym2 = 0;
015dc7e1 14584 return true;
f84ce13b
NC
14585 }
14586
6ff71e76
NC
14587 switch (reloc_type)
14588 {
14589 case 0x80: /* R_RL78_SYM. */
14590 saved_sym1 = saved_sym2;
f84ce13b 14591 if (sym_index >= num_syms)
74a965d8
AM
14592 error (_("%s reloc contains invalid symbol index "
14593 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
f84ce13b
NC
14594 else
14595 {
14596 saved_sym2 = symtab[sym_index].st_value;
14597 saved_sym2 += reloc->r_addend;
14598 }
015dc7e1 14599 return true;
6ff71e76
NC
14600
14601 case 0x83: /* R_RL78_OPsub. */
14602 value = saved_sym1 - saved_sym2;
14603 saved_sym2 = saved_sym1 = 0;
015dc7e1 14604 return true;
6ff71e76
NC
14605 break;
14606
14607 case 0x41: /* R_RL78_ABS32. */
b32e566b 14608 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14609 byte_put (start + reloc->r_offset, value, 4);
b32e566b 14610 else
26c527e6
AM
14611 error (_("RL78 sym diff reloc contains invalid offset: "
14612 "%#" PRIx64 "\n"),
14613 reloc->r_offset);
6ff71e76 14614 value = 0;
015dc7e1 14615 return true;
6ff71e76
NC
14616
14617 case 0x43: /* R_RL78_ABS16. */
b32e566b 14618 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14619 byte_put (start + reloc->r_offset, value, 2);
b32e566b 14620 else
26c527e6
AM
14621 error (_("RL78 sym diff reloc contains invalid offset: "
14622 "%#" PRIx64 "\n"),
14623 reloc->r_offset);
6ff71e76 14624 value = 0;
015dc7e1 14625 return true;
6ff71e76
NC
14626
14627 default:
14628 break;
14629 }
14630 break;
14631 }
252b5132
RH
14632 }
14633
015dc7e1 14634 return false;
252b5132
RH
14635}
14636
aca88567
NC
14637/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14638 DWARF debug sections. This is a target specific test. Note - we do not
14639 go through the whole including-target-headers-multiple-times route, (as
14640 we have already done with <elf/h8.h>) because this would become very
14641 messy and even then this function would have to contain target specific
14642 information (the names of the relocs instead of their numeric values).
14643 FIXME: This is not the correct way to solve this problem. The proper way
14644 is to have target specific reloc sizing and typing functions created by
14645 the reloc-macros.h header, in the same way that it already creates the
14646 reloc naming functions. */
14647
015dc7e1 14648static bool
dda8d76d 14649is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14650{
d347c9df 14651 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14652 switch (filedata->file_header.e_machine)
aca88567 14653 {
41e92641 14654 case EM_386:
22abe556 14655 case EM_IAMCU:
41e92641 14656 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14657 case EM_68K:
14658 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14659 case EM_860:
14660 return reloc_type == 1; /* R_860_32. */
14661 case EM_960:
14662 return reloc_type == 2; /* R_960_32. */
a06ea964 14663 case EM_AARCH64:
9282b95a
JW
14664 return (reloc_type == 258
14665 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14666 case EM_BPF:
14667 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14668 case EM_ADAPTEVA_EPIPHANY:
14669 return reloc_type == 3;
aca88567 14670 case EM_ALPHA:
137b6b5f 14671 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14672 case EM_ARC:
14673 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14674 case EM_ARC_COMPACT:
14675 case EM_ARC_COMPACT2:
b5c37946
SJ
14676 case EM_ARC_COMPACT3:
14677 case EM_ARC_COMPACT3_64:
886a2506 14678 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14679 case EM_ARM:
14680 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14681 case EM_AVR_OLD:
aca88567
NC
14682 case EM_AVR:
14683 return reloc_type == 1;
14684 case EM_BLACKFIN:
14685 return reloc_type == 0x12; /* R_byte4_data. */
14686 case EM_CRIS:
14687 return reloc_type == 3; /* R_CRIS_32. */
14688 case EM_CR16:
14689 return reloc_type == 3; /* R_CR16_NUM32. */
14690 case EM_CRX:
14691 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14692 case EM_CSKY:
14693 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14694 case EM_CYGNUS_FRV:
14695 return reloc_type == 1;
41e92641
NC
14696 case EM_CYGNUS_D10V:
14697 case EM_D10V:
14698 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14699 case EM_CYGNUS_D30V:
14700 case EM_D30V:
14701 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14702 case EM_DLX:
14703 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14704 case EM_CYGNUS_FR30:
14705 case EM_FR30:
14706 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14707 case EM_FT32:
14708 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14709 case EM_H8S:
14710 case EM_H8_300:
14711 case EM_H8_300H:
14712 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14713 case EM_IA_64:
262cdac7
AM
14714 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14715 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14716 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14717 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14718 case EM_IP2K_OLD:
14719 case EM_IP2K:
14720 return reloc_type == 2; /* R_IP2K_32. */
14721 case EM_IQ2000:
14722 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14723 case EM_LATTICEMICO32:
14724 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14725 case EM_LOONGARCH:
14726 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14727 case EM_M32C_OLD:
aca88567
NC
14728 case EM_M32C:
14729 return reloc_type == 3; /* R_M32C_32. */
14730 case EM_M32R:
14731 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14732 case EM_68HC11:
14733 case EM_68HC12:
14734 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14735 case EM_S12Z:
2849d19f
JD
14736 return reloc_type == 7 || /* R_S12Z_EXT32 */
14737 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14738 case EM_MCORE:
14739 return reloc_type == 1; /* R_MCORE_ADDR32. */
14740 case EM_CYGNUS_MEP:
14741 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14742 case EM_METAG:
14743 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14744 case EM_MICROBLAZE:
14745 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14746 case EM_MIPS:
14747 return reloc_type == 2; /* R_MIPS_32. */
14748 case EM_MMIX:
14749 return reloc_type == 4; /* R_MMIX_32. */
14750 case EM_CYGNUS_MN10200:
14751 case EM_MN10200:
14752 return reloc_type == 1; /* R_MN10200_32. */
14753 case EM_CYGNUS_MN10300:
14754 case EM_MN10300:
14755 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14756 case EM_MOXIE:
14757 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14758 case EM_MSP430_OLD:
14759 case EM_MSP430:
13761a11 14760 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14761 case EM_MT:
14762 return reloc_type == 2; /* R_MT_32. */
35c08157 14763 case EM_NDS32:
81c5e376 14764 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14765 case EM_ALTERA_NIOS2:
36591ba1 14766 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14767 case EM_NIOS32:
14768 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14769 case EM_OR1K:
14770 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14771 case EM_PARISC:
9abca702 14772 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14773 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14774 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14775 case EM_PJ:
14776 case EM_PJ_OLD:
14777 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14778 case EM_PPC64:
14779 return reloc_type == 1; /* R_PPC64_ADDR32. */
14780 case EM_PPC:
14781 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14782 case EM_TI_PRU:
14783 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14784 case EM_RISCV:
14785 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14786 case EM_RL78:
14787 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14788 case EM_RX:
14789 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14790 case EM_S370:
14791 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14792 case EM_S390_OLD:
14793 case EM_S390:
14794 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14795 case EM_SCORE:
14796 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14797 case EM_SH:
14798 return reloc_type == 1; /* R_SH_DIR32. */
14799 case EM_SPARC32PLUS:
14800 case EM_SPARCV9:
14801 case EM_SPARC:
14802 return reloc_type == 3 /* R_SPARC_32. */
14803 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14804 case EM_SPU:
14805 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14806 case EM_TI_C6000:
14807 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14808 case EM_TILEGX:
14809 return reloc_type == 2; /* R_TILEGX_32. */
14810 case EM_TILEPRO:
14811 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14812 case EM_CYGNUS_V850:
14813 case EM_V850:
14814 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14815 case EM_V800:
14816 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14817 case EM_VAX:
14818 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14819 case EM_VISIUM:
14820 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14821 case EM_WEBASSEMBLY:
14822 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14823 case EM_X86_64:
8a9036a4 14824 case EM_L1OM:
7a9068fe 14825 case EM_K1OM:
aca88567 14826 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14827 case EM_XGATE:
14828 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14829 case EM_XSTORMY16:
14830 return reloc_type == 1; /* R_XSTROMY16_32. */
14831 case EM_XTENSA_OLD:
14832 case EM_XTENSA:
14833 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14834 case EM_Z80:
14835 return reloc_type == 6; /* R_Z80_32. */
aca88567 14836 default:
bee0ee85
NC
14837 {
14838 static unsigned int prev_warn = 0;
14839
14840 /* Avoid repeating the same warning multiple times. */
dda8d76d 14841 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14842 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14843 filedata->file_header.e_machine);
14844 prev_warn = filedata->file_header.e_machine;
015dc7e1 14845 return false;
bee0ee85 14846 }
aca88567
NC
14847 }
14848}
14849
14850/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14851 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14852
015dc7e1 14853static bool
dda8d76d 14854is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14855{
dda8d76d 14856 switch (filedata->file_header.e_machine)
d347c9df 14857 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14858 {
41e92641 14859 case EM_386:
22abe556 14860 case EM_IAMCU:
3e0873ac 14861 return reloc_type == 2; /* R_386_PC32. */
aca88567 14862 case EM_68K:
3e0873ac 14863 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14864 case EM_AARCH64:
14865 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14866 case EM_ADAPTEVA_EPIPHANY:
14867 return reloc_type == 6;
aca88567
NC
14868 case EM_ALPHA:
14869 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14870 case EM_ARC_COMPACT:
14871 case EM_ARC_COMPACT2:
b5c37946
SJ
14872 case EM_ARC_COMPACT3:
14873 case EM_ARC_COMPACT3_64:
726c18e1 14874 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14875 case EM_ARM:
3e0873ac 14876 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14877 case EM_AVR_OLD:
14878 case EM_AVR:
14879 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14880 case EM_LOONGARCH:
14881 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14882 case EM_MICROBLAZE:
14883 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14884 case EM_OR1K:
14885 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14886 case EM_PARISC:
85acf597 14887 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14888 case EM_PPC:
14889 return reloc_type == 26; /* R_PPC_REL32. */
14890 case EM_PPC64:
3e0873ac 14891 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14892 case EM_RISCV:
14893 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14894 case EM_S390_OLD:
14895 case EM_S390:
3e0873ac 14896 return reloc_type == 5; /* R_390_PC32. */
aca88567 14897 case EM_SH:
3e0873ac 14898 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14899 case EM_SPARC32PLUS:
14900 case EM_SPARCV9:
14901 case EM_SPARC:
3e0873ac 14902 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14903 case EM_SPU:
14904 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14905 case EM_TILEGX:
14906 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14907 case EM_TILEPRO:
14908 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14909 case EM_VISIUM:
14910 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14911 case EM_X86_64:
8a9036a4 14912 case EM_L1OM:
7a9068fe 14913 case EM_K1OM:
3e0873ac 14914 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14915 case EM_VAX:
14916 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14917 case EM_XTENSA_OLD:
14918 case EM_XTENSA:
14919 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14920 default:
14921 /* Do not abort or issue an error message here. Not all targets use
14922 pc-relative 32-bit relocs in their DWARF debug information and we
14923 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14924 more helpful warning message will be generated by apply_relocations
14925 anyway, so just return. */
015dc7e1 14926 return false;
aca88567
NC
14927 }
14928}
14929
14930/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14931 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14932
015dc7e1 14933static bool
dda8d76d 14934is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14935{
dda8d76d 14936 switch (filedata->file_header.e_machine)
aca88567 14937 {
a06ea964
NC
14938 case EM_AARCH64:
14939 return reloc_type == 257; /* R_AARCH64_ABS64. */
b5c37946
SJ
14940 case EM_ARC_COMPACT3_64:
14941 return reloc_type == 5; /* R_ARC_64. */
aca88567
NC
14942 case EM_ALPHA:
14943 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14944 case EM_IA_64:
262cdac7
AM
14945 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14946 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14947 case EM_LOONGARCH:
14948 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14949 case EM_PARISC:
14950 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14951 case EM_PPC64:
14952 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14953 case EM_RISCV:
14954 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14955 case EM_SPARC32PLUS:
14956 case EM_SPARCV9:
14957 case EM_SPARC:
714da62f
NC
14958 return reloc_type == 32 /* R_SPARC_64. */
14959 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14960 case EM_X86_64:
8a9036a4 14961 case EM_L1OM:
7a9068fe 14962 case EM_K1OM:
aca88567 14963 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14964 case EM_S390_OLD:
14965 case EM_S390:
aa137e4d
NC
14966 return reloc_type == 22; /* R_S390_64. */
14967 case EM_TILEGX:
14968 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14969 case EM_MIPS:
aa137e4d 14970 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14971 default:
015dc7e1 14972 return false;
aca88567
NC
14973 }
14974}
14975
85acf597
RH
14976/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14977 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14978
015dc7e1 14979static bool
dda8d76d 14980is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14981{
dda8d76d 14982 switch (filedata->file_header.e_machine)
85acf597 14983 {
a06ea964
NC
14984 case EM_AARCH64:
14985 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14986 case EM_ALPHA:
aa137e4d 14987 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14988 case EM_IA_64:
262cdac7
AM
14989 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14990 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14991 case EM_PARISC:
aa137e4d 14992 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14993 case EM_PPC64:
aa137e4d 14994 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14995 case EM_SPARC32PLUS:
14996 case EM_SPARCV9:
14997 case EM_SPARC:
aa137e4d 14998 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14999 case EM_X86_64:
8a9036a4 15000 case EM_L1OM:
7a9068fe 15001 case EM_K1OM:
aa137e4d 15002 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
15003 case EM_S390_OLD:
15004 case EM_S390:
aa137e4d
NC
15005 return reloc_type == 23; /* R_S390_PC64. */
15006 case EM_TILEGX:
15007 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 15008 default:
015dc7e1 15009 return false;
85acf597
RH
15010 }
15011}
15012
4dc3c23d
AM
15013/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15014 a 24-bit absolute RELA relocation used in DWARF debug sections. */
15015
015dc7e1 15016static bool
dda8d76d 15017is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 15018{
dda8d76d 15019 switch (filedata->file_header.e_machine)
4dc3c23d
AM
15020 {
15021 case EM_CYGNUS_MN10200:
15022 case EM_MN10200:
15023 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
15024 case EM_FT32:
15025 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
15026 case EM_Z80:
15027 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 15028 default:
015dc7e1 15029 return false;
4dc3c23d
AM
15030 }
15031}
15032
aca88567
NC
15033/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15034 a 16-bit absolute RELA relocation used in DWARF debug sections. */
15035
015dc7e1 15036static bool
dda8d76d 15037is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 15038{
d347c9df 15039 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 15040 switch (filedata->file_header.e_machine)
4b78141a 15041 {
886a2506
NC
15042 case EM_ARC:
15043 case EM_ARC_COMPACT:
15044 case EM_ARC_COMPACT2:
b5c37946
SJ
15045 case EM_ARC_COMPACT3:
15046 case EM_ARC_COMPACT3_64:
886a2506 15047 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
15048 case EM_ADAPTEVA_EPIPHANY:
15049 return reloc_type == 5;
aca88567
NC
15050 case EM_AVR_OLD:
15051 case EM_AVR:
15052 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
15053 case EM_CYGNUS_D10V:
15054 case EM_D10V:
15055 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
15056 case EM_FT32:
15057 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
15058 case EM_H8S:
15059 case EM_H8_300:
15060 case EM_H8_300H:
aca88567
NC
15061 return reloc_type == R_H8_DIR16;
15062 case EM_IP2K_OLD:
15063 case EM_IP2K:
15064 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 15065 case EM_M32C_OLD:
f4236fe4
DD
15066 case EM_M32C:
15067 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
15068 case EM_CYGNUS_MN10200:
15069 case EM_MN10200:
15070 return reloc_type == 2; /* R_MN10200_16. */
15071 case EM_CYGNUS_MN10300:
15072 case EM_MN10300:
15073 return reloc_type == 2; /* R_MN10300_16. */
aca88567 15074 case EM_MSP430:
dda8d76d 15075 if (uses_msp430x_relocs (filedata))
13761a11 15076 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 15077 /* Fall through. */
78c8d46c 15078 case EM_MSP430_OLD:
aca88567 15079 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 15080 case EM_NDS32:
81c5e376 15081 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 15082 case EM_ALTERA_NIOS2:
36591ba1 15083 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
15084 case EM_NIOS32:
15085 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
15086 case EM_OR1K:
15087 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
15088 case EM_RISCV:
15089 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
15090 case EM_TI_PRU:
15091 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
15092 case EM_TI_C6000:
15093 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
15094 case EM_VISIUM:
15095 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
15096 case EM_XGATE:
15097 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
15098 case EM_Z80:
15099 return reloc_type == 4; /* R_Z80_16. */
4b78141a 15100 default:
015dc7e1 15101 return false;
4b78141a
NC
15102 }
15103}
15104
39e07931
AS
15105/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15106 a 8-bit absolute RELA relocation used in DWARF debug sections. */
15107
015dc7e1 15108static bool
39e07931
AS
15109is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15110{
15111 switch (filedata->file_header.e_machine)
15112 {
15113 case EM_RISCV:
15114 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
15115 case EM_Z80:
15116 return reloc_type == 1; /* R_Z80_8. */
39e07931 15117 default:
015dc7e1 15118 return false;
39e07931
AS
15119 }
15120}
15121
15122/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15123 a 6-bit absolute RELA relocation used in DWARF debug sections. */
15124
015dc7e1 15125static bool
39e07931
AS
15126is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15127{
15128 switch (filedata->file_header.e_machine)
15129 {
15130 case EM_RISCV:
15131 return reloc_type == 53; /* R_RISCV_SET6. */
15132 default:
015dc7e1 15133 return false;
39e07931
AS
15134 }
15135}
15136
03336641
JW
15137/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15138 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
15139
015dc7e1 15140static bool
03336641
JW
15141is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15142{
15143 /* Please keep this table alpha-sorted for ease of visual lookup. */
15144 switch (filedata->file_header.e_machine)
15145 {
76244462 15146 case EM_LOONGARCH:
15147 return reloc_type == 50; /* R_LARCH_ADD32. */
03336641
JW
15148 case EM_RISCV:
15149 return reloc_type == 35; /* R_RISCV_ADD32. */
15150 default:
015dc7e1 15151 return false;
03336641
JW
15152 }
15153}
15154
15155/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15156 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
15157
015dc7e1 15158static bool
03336641
JW
15159is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15160{
15161 /* Please keep this table alpha-sorted for ease of visual lookup. */
15162 switch (filedata->file_header.e_machine)
15163 {
76244462 15164 case EM_LOONGARCH:
15165 return reloc_type == 55; /* R_LARCH_SUB32. */
03336641
JW
15166 case EM_RISCV:
15167 return reloc_type == 39; /* R_RISCV_SUB32. */
15168 default:
015dc7e1 15169 return false;
03336641
JW
15170 }
15171}
15172
15173/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15174 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
15175
015dc7e1 15176static bool
03336641
JW
15177is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15178{
15179 /* Please keep this table alpha-sorted for ease of visual lookup. */
15180 switch (filedata->file_header.e_machine)
15181 {
76244462 15182 case EM_LOONGARCH:
15183 return reloc_type == 51; /* R_LARCH_ADD64. */
03336641
JW
15184 case EM_RISCV:
15185 return reloc_type == 36; /* R_RISCV_ADD64. */
15186 default:
015dc7e1 15187 return false;
03336641
JW
15188 }
15189}
15190
15191/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15192 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
15193
015dc7e1 15194static bool
03336641
JW
15195is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15196{
15197 /* Please keep this table alpha-sorted for ease of visual lookup. */
15198 switch (filedata->file_header.e_machine)
15199 {
76244462 15200 case EM_LOONGARCH:
15201 return reloc_type == 56; /* R_LARCH_SUB64. */
03336641
JW
15202 case EM_RISCV:
15203 return reloc_type == 40; /* R_RISCV_SUB64. */
15204 default:
015dc7e1 15205 return false;
03336641
JW
15206 }
15207}
15208
15209/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15210 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
15211
015dc7e1 15212static bool
03336641
JW
15213is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15214{
15215 /* Please keep this table alpha-sorted for ease of visual lookup. */
15216 switch (filedata->file_header.e_machine)
15217 {
76244462 15218 case EM_LOONGARCH:
15219 return reloc_type == 48; /* R_LARCH_ADD16. */
03336641
JW
15220 case EM_RISCV:
15221 return reloc_type == 34; /* R_RISCV_ADD16. */
15222 default:
015dc7e1 15223 return false;
03336641
JW
15224 }
15225}
15226
15227/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15228 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
15229
015dc7e1 15230static bool
03336641
JW
15231is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15232{
15233 /* Please keep this table alpha-sorted for ease of visual lookup. */
15234 switch (filedata->file_header.e_machine)
15235 {
76244462 15236 case EM_LOONGARCH:
15237 return reloc_type == 53; /* R_LARCH_SUB16. */
03336641
JW
15238 case EM_RISCV:
15239 return reloc_type == 38; /* R_RISCV_SUB16. */
15240 default:
015dc7e1 15241 return false;
03336641
JW
15242 }
15243}
15244
15245/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15246 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
15247
015dc7e1 15248static bool
03336641
JW
15249is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15250{
15251 /* Please keep this table alpha-sorted for ease of visual lookup. */
15252 switch (filedata->file_header.e_machine)
15253 {
76244462 15254 case EM_LOONGARCH:
15255 return reloc_type == 47; /* R_LARCH_ADD8. */
03336641
JW
15256 case EM_RISCV:
15257 return reloc_type == 33; /* R_RISCV_ADD8. */
15258 default:
015dc7e1 15259 return false;
03336641
JW
15260 }
15261}
15262
15263/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15264 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
15265
015dc7e1 15266static bool
03336641
JW
15267is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15268{
15269 /* Please keep this table alpha-sorted for ease of visual lookup. */
15270 switch (filedata->file_header.e_machine)
15271 {
76244462 15272 case EM_LOONGARCH:
15273 return reloc_type == 52; /* R_LARCH_SUB8. */
03336641
JW
15274 case EM_RISCV:
15275 return reloc_type == 37; /* R_RISCV_SUB8. */
15276 default:
015dc7e1 15277 return false;
03336641
JW
15278 }
15279}
15280
76244462 15281/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15282 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
15283
15284static bool
15285is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15286{
15287 switch (filedata->file_header.e_machine)
15288 {
15289 case EM_LOONGARCH:
15290 return reloc_type == 105; /* R_LARCH_ADD6. */
15291 default:
15292 return false;
15293 }
15294}
15295
39e07931
AS
15296/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15297 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
15298
015dc7e1 15299static bool
39e07931
AS
15300is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15301{
15302 switch (filedata->file_header.e_machine)
15303 {
76244462 15304 case EM_LOONGARCH:
15305 return reloc_type == 106; /* R_LARCH_SUB6. */
39e07931
AS
15306 case EM_RISCV:
15307 return reloc_type == 52; /* R_RISCV_SUB6. */
15308 default:
015dc7e1 15309 return false;
39e07931
AS
15310 }
15311}
15312
2a7b2e88
JK
15313/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
15314 relocation entries (possibly formerly used for SHT_GROUP sections). */
15315
015dc7e1 15316static bool
dda8d76d 15317is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 15318{
dda8d76d 15319 switch (filedata->file_header.e_machine)
2a7b2e88 15320 {
cb8f3167 15321 case EM_386: /* R_386_NONE. */
d347c9df 15322 case EM_68K: /* R_68K_NONE. */
cfb8c092 15323 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
15324 case EM_ALPHA: /* R_ALPHA_NONE. */
15325 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 15326 case EM_ARC: /* R_ARC_NONE. */
886a2506 15327 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 15328 case EM_ARC_COMPACT: /* R_ARC_NONE. */
b5c37946
SJ
15329 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
15330 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
cb8f3167 15331 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 15332 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
15333 case EM_FT32: /* R_FT32_NONE. */
15334 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 15335 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
15336 case EM_L1OM: /* R_X86_64_NONE. */
15337 case EM_M32R: /* R_M32R_NONE. */
15338 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 15339 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 15340 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
15341 case EM_NIOS32: /* R_NIOS_NONE. */
15342 case EM_OR1K: /* R_OR1K_NONE. */
15343 case EM_PARISC: /* R_PARISC_NONE. */
15344 case EM_PPC64: /* R_PPC64_NONE. */
15345 case EM_PPC: /* R_PPC_NONE. */
e23eba97 15346 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
15347 case EM_S390: /* R_390_NONE. */
15348 case EM_S390_OLD:
15349 case EM_SH: /* R_SH_NONE. */
15350 case EM_SPARC32PLUS:
15351 case EM_SPARC: /* R_SPARC_NONE. */
15352 case EM_SPARCV9:
aa137e4d
NC
15353 case EM_TILEGX: /* R_TILEGX_NONE. */
15354 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
15355 case EM_TI_C6000:/* R_C6000_NONE. */
15356 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 15357 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 15358 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 15359 return reloc_type == 0;
d347c9df 15360
a06ea964
NC
15361 case EM_AARCH64:
15362 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
15363 case EM_AVR_OLD:
15364 case EM_AVR:
15365 return (reloc_type == 0 /* R_AVR_NONE. */
15366 || reloc_type == 30 /* R_AVR_DIFF8. */
15367 || reloc_type == 31 /* R_AVR_DIFF16. */
15368 || reloc_type == 32 /* R_AVR_DIFF32. */);
15369 case EM_METAG:
15370 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 15371 case EM_NDS32:
81c5e376
AM
15372 return (reloc_type == 0 /* R_NDS32_NONE. */
15373 || reloc_type == 205 /* R_NDS32_DIFF8. */
15374 || reloc_type == 206 /* R_NDS32_DIFF16. */
15375 || reloc_type == 207 /* R_NDS32_DIFF32. */
15376 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
15377 case EM_TI_PRU:
15378 return (reloc_type == 0 /* R_PRU_NONE. */
15379 || reloc_type == 65 /* R_PRU_DIFF8. */
15380 || reloc_type == 66 /* R_PRU_DIFF16. */
15381 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
15382 case EM_XTENSA_OLD:
15383 case EM_XTENSA:
4dc3c23d
AM
15384 return (reloc_type == 0 /* R_XTENSA_NONE. */
15385 || reloc_type == 17 /* R_XTENSA_DIFF8. */
15386 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
15387 || reloc_type == 19 /* R_XTENSA_DIFF32. */
15388 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
15389 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
15390 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
15391 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
15392 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
15393 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 15394 }
015dc7e1 15395 return false;
2a7b2e88
JK
15396}
15397
d1c4b12b
NC
15398/* Returns TRUE if there is a relocation against
15399 section NAME at OFFSET bytes. */
15400
015dc7e1 15401bool
31e5a3a3 15402reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
15403{
15404 Elf_Internal_Rela * relocs;
15405 Elf_Internal_Rela * rp;
15406
15407 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 15408 return false;
d1c4b12b
NC
15409
15410 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
15411
15412 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
15413 if (rp->r_offset == offset)
015dc7e1 15414 return true;
d1c4b12b 15415
015dc7e1 15416 return false;
d1c4b12b
NC
15417}
15418
cf13d699 15419/* Apply relocations to a section.
32ec8896
NC
15420 Returns TRUE upon success, FALSE otherwise.
15421 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
15422 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
15423 will be set to the number of relocs loaded.
15424
cf13d699 15425 Note: So far support has been added only for those relocations
32ec8896
NC
15426 which can be found in debug sections. FIXME: Add support for
15427 more relocations ? */
1b315056 15428
015dc7e1 15429static bool
be7d229a
AM
15430apply_relocations (Filedata *filedata,
15431 const Elf_Internal_Shdr *section,
15432 unsigned char *start,
15433 size_t size,
15434 void **relocs_return,
26c527e6 15435 uint64_t *num_relocs_return)
1b315056 15436{
cf13d699 15437 Elf_Internal_Shdr * relsec;
0d2a7a93 15438 unsigned char * end = start + size;
cb8f3167 15439
d1c4b12b
NC
15440 if (relocs_return != NULL)
15441 {
15442 * (Elf_Internal_Rela **) relocs_return = NULL;
15443 * num_relocs_return = 0;
15444 }
15445
dda8d76d 15446 if (filedata->file_header.e_type != ET_REL)
32ec8896 15447 /* No relocs to apply. */
015dc7e1 15448 return true;
1b315056 15449
cf13d699 15450 /* Find the reloc section associated with the section. */
dda8d76d
NC
15451 for (relsec = filedata->section_headers;
15452 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 15453 ++relsec)
252b5132 15454 {
015dc7e1 15455 bool is_rela;
26c527e6 15456 uint64_t num_relocs;
2cf0635d
NC
15457 Elf_Internal_Rela * relocs;
15458 Elf_Internal_Rela * rp;
15459 Elf_Internal_Shdr * symsec;
15460 Elf_Internal_Sym * symtab;
26c527e6 15461 uint64_t num_syms;
2cf0635d 15462 Elf_Internal_Sym * sym;
252b5132 15463
41e92641 15464 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15465 || relsec->sh_info >= filedata->file_header.e_shnum
15466 || filedata->section_headers + relsec->sh_info != section
c256ffe7 15467 || relsec->sh_size == 0
dda8d76d 15468 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 15469 continue;
428409d5 15470
a788aedd
AM
15471 symsec = filedata->section_headers + relsec->sh_link;
15472 if (symsec->sh_type != SHT_SYMTAB
15473 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 15474 return false;
a788aedd 15475
41e92641
NC
15476 is_rela = relsec->sh_type == SHT_RELA;
15477
15478 if (is_rela)
15479 {
dda8d76d 15480 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 15481 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15482 return false;
41e92641
NC
15483 }
15484 else
15485 {
dda8d76d 15486 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 15487 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15488 return false;
41e92641
NC
15489 }
15490
15491 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 15492 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 15493 is_rela = false;
428409d5 15494
4de91c10 15495 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 15496
41e92641 15497 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 15498 {
625d49fc 15499 uint64_t addend;
015dc7e1
AM
15500 unsigned int reloc_type;
15501 unsigned int reloc_size;
15502 bool reloc_inplace = false;
15503 bool reloc_subtract = false;
15504 unsigned char *rloc;
26c527e6 15505 uint64_t sym_index;
4b78141a 15506
dda8d76d 15507 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 15508
dda8d76d 15509 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 15510 continue;
dda8d76d 15511 else if (is_none_reloc (filedata, reloc_type))
98fb390a 15512 continue;
dda8d76d
NC
15513 else if (is_32bit_abs_reloc (filedata, reloc_type)
15514 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 15515 reloc_size = 4;
dda8d76d
NC
15516 else if (is_64bit_abs_reloc (filedata, reloc_type)
15517 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 15518 reloc_size = 8;
dda8d76d 15519 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15520 reloc_size = 3;
dda8d76d 15521 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15522 reloc_size = 2;
39e07931
AS
15523 else if (is_8bit_abs_reloc (filedata, reloc_type)
15524 || is_6bit_abs_reloc (filedata, reloc_type))
15525 reloc_size = 1;
03336641
JW
15526 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15527 reloc_type))
15528 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15529 {
15530 reloc_size = 4;
015dc7e1 15531 reloc_inplace = true;
03336641
JW
15532 }
15533 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15534 reloc_type))
15535 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15536 {
15537 reloc_size = 8;
015dc7e1 15538 reloc_inplace = true;
03336641
JW
15539 }
15540 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15541 reloc_type))
15542 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15543 {
15544 reloc_size = 2;
015dc7e1 15545 reloc_inplace = true;
03336641
JW
15546 }
15547 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15548 reloc_type))
15549 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15550 {
15551 reloc_size = 1;
015dc7e1 15552 reloc_inplace = true;
03336641 15553 }
39e07931 15554 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
76244462 15555 reloc_type))
15556 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15557 {
15558 reloc_size = 1;
015dc7e1 15559 reloc_inplace = true;
39e07931 15560 }
aca88567 15561 else
4b78141a 15562 {
bee0ee85 15563 static unsigned int prev_reloc = 0;
dda8d76d 15564
bee0ee85
NC
15565 if (reloc_type != prev_reloc)
15566 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15567 reloc_type, printable_section_name (filedata, section));
bee0ee85 15568 prev_reloc = reloc_type;
4b78141a
NC
15569 continue;
15570 }
103f02d3 15571
91d6fa6a 15572 rloc = start + rp->r_offset;
75802ccb 15573 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 15574 {
26c527e6
AM
15575 warn (_("skipping invalid relocation offset %#" PRIx64
15576 " in section %s\n"),
15577 rp->r_offset,
dda8d76d 15578 printable_section_name (filedata, section));
700dd8b7
L
15579 continue;
15580 }
103f02d3 15581
26c527e6 15582 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
15583 if (sym_index >= num_syms)
15584 {
26c527e6
AM
15585 warn (_("skipping invalid relocation symbol index %#" PRIx64
15586 " in section %s\n"),
dda8d76d 15587 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15588 continue;
15589 }
15590 sym = symtab + sym_index;
41e92641
NC
15591
15592 /* If the reloc has a symbol associated with it,
55f25fc3
L
15593 make sure that it is of an appropriate type.
15594
15595 Relocations against symbols without type can happen.
15596 Gcc -feliminate-dwarf2-dups may generate symbols
15597 without type for debug info.
15598
15599 Icc generates relocations against function symbols
15600 instead of local labels.
15601
15602 Relocations against object symbols can happen, eg when
15603 referencing a global array. For an example of this see
15604 the _clz.o binary in libgcc.a. */
aca88567 15605 if (sym != symtab
b8871f35 15606 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15607 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15608 {
26c527e6 15609 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
15610 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15611 printable_section_name (filedata, relsec),
26c527e6 15612 rp - relocs);
aca88567 15613 continue;
5b18a4bc 15614 }
252b5132 15615
4dc3c23d
AM
15616 addend = 0;
15617 if (is_rela)
15618 addend += rp->r_addend;
c47320c3
AM
15619 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15620 partial_inplace. */
4dc3c23d 15621 if (!is_rela
dda8d76d 15622 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15623 && reloc_type == 1)
dda8d76d
NC
15624 || ((filedata->file_header.e_machine == EM_PJ
15625 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15626 && reloc_type == 1)
dda8d76d
NC
15627 || ((filedata->file_header.e_machine == EM_D30V
15628 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15629 && reloc_type == 12)
15630 || reloc_inplace)
39e07931
AS
15631 {
15632 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15633 addend += byte_get (rloc, reloc_size) & 0x3f;
15634 else
15635 addend += byte_get (rloc, reloc_size);
15636 }
cb8f3167 15637
dda8d76d
NC
15638 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15639 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15640 {
15641 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15642 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15643 addend -= 8;
91d6fa6a 15644 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15645 reloc_size);
15646 }
39e07931 15647 else if (is_6bit_abs_reloc (filedata, reloc_type)
76244462 15648 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
15649 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15650 {
15651 if (reloc_subtract)
15652 addend -= sym->st_value;
15653 else
15654 addend += sym->st_value;
15655 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15656 byte_put (rloc, addend, reloc_size);
15657 }
03336641
JW
15658 else if (reloc_subtract)
15659 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15660 else
91d6fa6a 15661 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15662 }
252b5132 15663
5b18a4bc 15664 free (symtab);
f84ce13b
NC
15665 /* Let the target specific reloc processing code know that
15666 we have finished with these relocs. */
dda8d76d 15667 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15668
15669 if (relocs_return)
15670 {
15671 * (Elf_Internal_Rela **) relocs_return = relocs;
15672 * num_relocs_return = num_relocs;
15673 }
15674 else
15675 free (relocs);
15676
5b18a4bc
NC
15677 break;
15678 }
32ec8896 15679
015dc7e1 15680 return true;
5b18a4bc 15681}
103f02d3 15682
cf13d699 15683#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15684static bool
dda8d76d 15685disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15686{
dda8d76d 15687 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15688
74e1a04b 15689 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15690
015dc7e1 15691 return true;
cf13d699
NC
15692}
15693#endif
15694
15695/* Reads in the contents of SECTION from FILE, returning a pointer
15696 to a malloc'ed buffer or NULL if something went wrong. */
15697
15698static char *
dda8d76d 15699get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15700{
be7d229a 15701 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15702
15703 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15704 {
c6b78c96 15705 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15706 printable_section_name (filedata, section));
cf13d699
NC
15707 return NULL;
15708 }
15709
dda8d76d 15710 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15711 _("section contents"));
cf13d699
NC
15712}
15713
1f5a3546 15714/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 15715
015dc7e1 15716static bool
45f5fe46
NC
15717uncompress_section_contents (bool is_zstd,
15718 unsigned char ** buffer,
15719 uint64_t uncompressed_size,
15720 uint64_t * size,
15721 uint64_t file_size)
0e602686 15722{
31e5a3a3
AM
15723 uint64_t compressed_size = *size;
15724 unsigned char *compressed_buffer = *buffer;
45f5fe46 15725 unsigned char *uncompressed_buffer = NULL;
0e602686
NC
15726 z_stream strm;
15727 int rc;
15728
45f5fe46
NC
15729 /* Similar to _bfd_section_size_insane() in the BFD library we expect an
15730 upper limit of ~10x compression. Any compression larger than that is
15731 thought to be due to fuzzing of the compression header. */
15732 if (uncompressed_size > file_size * 10)
15733 {
15734 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
15735 uncompressed_size);
15736 goto fail;
15737 }
15738
15739 uncompressed_buffer = xmalloc (uncompressed_size);
15740
1f5a3546
FS
15741 if (is_zstd)
15742 {
15743#ifdef HAVE_ZSTD
15744 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15745 compressed_buffer, compressed_size);
15746 if (ZSTD_isError (ret))
15747 goto fail;
15748#endif
15749 }
15750 else
15751 {
15752 /* It is possible the section consists of several compressed
15753 buffers concatenated together, so we uncompress in a loop. */
15754 /* PR 18313: The state field in the z_stream structure is supposed
15755 to be invisible to the user (ie us), but some compilers will
15756 still complain about it being used without initialisation. So
15757 we first zero the entire z_stream structure and then set the fields
15758 that we need. */
15759 memset (&strm, 0, sizeof strm);
15760 strm.avail_in = compressed_size;
15761 strm.next_in = (Bytef *)compressed_buffer;
15762 strm.avail_out = uncompressed_size;
15763
15764 rc = inflateInit (&strm);
15765 while (strm.avail_in > 0)
15766 {
15767 if (rc != Z_OK)
15768 break;
15769 strm.next_out = ((Bytef *)uncompressed_buffer
15770 + (uncompressed_size - strm.avail_out));
15771 rc = inflate (&strm, Z_FINISH);
15772 if (rc != Z_STREAM_END)
15773 break;
15774 rc = inflateReset (&strm);
15775 }
15776 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15777 goto fail;
15778 }
0e602686
NC
15779
15780 *buffer = uncompressed_buffer;
15781 *size = uncompressed_size;
015dc7e1 15782 return true;
0e602686
NC
15783
15784 fail:
15785 free (uncompressed_buffer);
15786 /* Indicate decompression failure. */
15787 *buffer = NULL;
015dc7e1 15788 return false;
0e602686 15789}
dd24e3da 15790
015dc7e1 15791static bool
dda8d76d 15792dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15793{
015dc7e1 15794 Elf_Internal_Shdr *relsec;
be7d229a 15795 uint64_t num_bytes;
015dc7e1
AM
15796 unsigned char *data;
15797 unsigned char *end;
15798 unsigned char *real_start;
15799 unsigned char *start;
15800 bool some_strings_shown;
cf13d699 15801
dda8d76d 15802 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15803 if (start == NULL)
c6b78c96 15804 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15805 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15806
0e602686 15807 num_bytes = section->sh_size;
cf13d699 15808
835f2fae
NC
15809 if (filedata->is_separate)
15810 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15811 printable_section_name (filedata, section),
15812 filedata->file_name);
15813 else
15814 printf (_("\nString dump of section '%s':\n"),
15815 printable_section_name (filedata, section));
cf13d699 15816
0e602686
NC
15817 if (decompress_dumps)
15818 {
31e5a3a3
AM
15819 uint64_t new_size = num_bytes;
15820 uint64_t uncompressed_size = 0;
1f5a3546 15821 bool is_zstd = false;
0e602686
NC
15822
15823 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15824 {
15825 Elf_Internal_Chdr chdr;
15826 unsigned int compression_header_size
ebdf1ebf
NC
15827 = get_compression_header (& chdr, (unsigned char *) start,
15828 num_bytes);
5844b465
NC
15829 if (compression_header_size == 0)
15830 /* An error message will have already been generated
15831 by get_compression_header. */
15832 goto error_out;
0e602686 15833
89dbeac7 15834 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
15835 ;
15836#ifdef HAVE_ZSTD
89dbeac7 15837 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
15838 is_zstd = true;
15839#endif
15840 else
0e602686 15841 {
813dabb9 15842 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15843 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15844 goto error_out;
813dabb9 15845 }
813dabb9
L
15846 uncompressed_size = chdr.ch_size;
15847 start += compression_header_size;
15848 new_size -= compression_header_size;
0e602686
NC
15849 }
15850 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15851 {
15852 /* Read the zlib header. In this case, it should be "ZLIB"
15853 followed by the uncompressed section size, 8 bytes in
15854 big-endian order. */
15855 uncompressed_size = start[4]; uncompressed_size <<= 8;
15856 uncompressed_size += start[5]; uncompressed_size <<= 8;
15857 uncompressed_size += start[6]; uncompressed_size <<= 8;
15858 uncompressed_size += start[7]; uncompressed_size <<= 8;
15859 uncompressed_size += start[8]; uncompressed_size <<= 8;
15860 uncompressed_size += start[9]; uncompressed_size <<= 8;
15861 uncompressed_size += start[10]; uncompressed_size <<= 8;
15862 uncompressed_size += start[11];
15863 start += 12;
15864 new_size -= 12;
15865 }
15866
1835f746
NC
15867 if (uncompressed_size)
15868 {
1f5a3546 15869 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 15870 &new_size, filedata->file_size))
1835f746
NC
15871 num_bytes = new_size;
15872 else
15873 {
15874 error (_("Unable to decompress section %s\n"),
dda8d76d 15875 printable_section_name (filedata, section));
f761cb13 15876 goto error_out;
1835f746
NC
15877 }
15878 }
bc303e5d
NC
15879 else
15880 start = real_start;
0e602686 15881 }
fd8008d8 15882
cf13d699
NC
15883 /* If the section being dumped has relocations against it the user might
15884 be expecting these relocations to have been applied. Check for this
15885 case and issue a warning message in order to avoid confusion.
15886 FIXME: Maybe we ought to have an option that dumps a section with
15887 relocs applied ? */
dda8d76d
NC
15888 for (relsec = filedata->section_headers;
15889 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15890 ++relsec)
15891 {
15892 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15893 || relsec->sh_info >= filedata->file_header.e_shnum
15894 || filedata->section_headers + relsec->sh_info != section
cf13d699 15895 || relsec->sh_size == 0
dda8d76d 15896 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15897 continue;
15898
15899 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15900 break;
15901 }
15902
cf13d699
NC
15903 data = start;
15904 end = start + num_bytes;
015dc7e1 15905 some_strings_shown = false;
cf13d699 15906
ba3265d0
NC
15907#ifdef HAVE_MBSTATE_T
15908 mbstate_t state;
15909 /* Initialise the multibyte conversion state. */
15910 memset (& state, 0, sizeof (state));
15911#endif
15912
015dc7e1 15913 bool continuing = false;
ba3265d0 15914
cf13d699
NC
15915 while (data < end)
15916 {
15917 while (!ISPRINT (* data))
15918 if (++ data >= end)
15919 break;
15920
15921 if (data < end)
15922 {
071436c6
NC
15923 size_t maxlen = end - data;
15924
ba3265d0
NC
15925 if (continuing)
15926 {
15927 printf (" ");
015dc7e1 15928 continuing = false;
ba3265d0
NC
15929 }
15930 else
15931 {
26c527e6 15932 printf (" [%6tx] ", data - start);
ba3265d0
NC
15933 }
15934
4082ef84
NC
15935 if (maxlen > 0)
15936 {
f3da8a96 15937 char c = 0;
ba3265d0
NC
15938
15939 while (maxlen)
15940 {
15941 c = *data++;
15942
15943 if (c == 0)
15944 break;
15945
15946 /* PR 25543: Treat new-lines as string-ending characters. */
15947 if (c == '\n')
15948 {
15949 printf ("\\n\n");
15950 if (*data != 0)
015dc7e1 15951 continuing = true;
ba3265d0
NC
15952 break;
15953 }
15954
15955 /* Do not print control characters directly as they can affect terminal
15956 settings. Such characters usually appear in the names generated
15957 by the assembler for local labels. */
15958 if (ISCNTRL (c))
15959 {
15960 printf ("^%c", c + 0x40);
15961 }
15962 else if (ISPRINT (c))
15963 {
15964 putchar (c);
15965 }
15966 else
15967 {
15968 size_t n;
15969#ifdef HAVE_MBSTATE_T
15970 wchar_t w;
15971#endif
15972 /* Let printf do the hard work of displaying multibyte characters. */
15973 printf ("%.1s", data - 1);
15974#ifdef HAVE_MBSTATE_T
15975 /* Try to find out how many bytes made up the character that was
15976 just printed. Advance the symbol pointer past the bytes that
15977 were displayed. */
15978 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15979#else
15980 n = 1;
15981#endif
15982 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15983 data += (n - 1);
15984 }
15985 }
15986
15987 if (c != '\n')
15988 putchar ('\n');
4082ef84
NC
15989 }
15990 else
15991 {
15992 printf (_("<corrupt>\n"));
15993 data = end;
15994 }
015dc7e1 15995 some_strings_shown = true;
cf13d699
NC
15996 }
15997 }
15998
15999 if (! some_strings_shown)
16000 printf (_(" No strings found in this section."));
16001
0e602686 16002 free (real_start);
cf13d699
NC
16003
16004 putchar ('\n');
015dc7e1 16005 return true;
f761cb13
AM
16006
16007error_out:
16008 free (real_start);
015dc7e1 16009 return false;
cf13d699
NC
16010}
16011
015dc7e1
AM
16012static bool
16013dump_section_as_bytes (Elf_Internal_Shdr *section,
16014 Filedata *filedata,
16015 bool relocate)
cf13d699 16016{
be7d229a
AM
16017 Elf_Internal_Shdr *relsec;
16018 size_t bytes;
16019 uint64_t section_size;
625d49fc 16020 uint64_t addr;
be7d229a
AM
16021 unsigned char *data;
16022 unsigned char *real_start;
16023 unsigned char *start;
0e602686 16024
dda8d76d 16025 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 16026 if (start == NULL)
c6b78c96 16027 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 16028 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 16029
0e602686 16030 section_size = section->sh_size;
cf13d699 16031
835f2fae
NC
16032 if (filedata->is_separate)
16033 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
16034 printable_section_name (filedata, section),
16035 filedata->file_name);
16036 else
16037 printf (_("\nHex dump of section '%s':\n"),
16038 printable_section_name (filedata, section));
cf13d699 16039
0e602686
NC
16040 if (decompress_dumps)
16041 {
31e5a3a3
AM
16042 uint64_t new_size = section_size;
16043 uint64_t uncompressed_size = 0;
1f5a3546 16044 bool is_zstd = false;
0e602686
NC
16045
16046 if ((section->sh_flags & SHF_COMPRESSED) != 0)
16047 {
16048 Elf_Internal_Chdr chdr;
16049 unsigned int compression_header_size
ebdf1ebf 16050 = get_compression_header (& chdr, start, section_size);
0e602686 16051
5844b465
NC
16052 if (compression_header_size == 0)
16053 /* An error message will have already been generated
16054 by get_compression_header. */
16055 goto error_out;
16056
89dbeac7 16057 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16058 ;
16059#ifdef HAVE_ZSTD
89dbeac7 16060 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16061 is_zstd = true;
16062#endif
16063 else
0e602686 16064 {
813dabb9 16065 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 16066 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 16067 goto error_out;
0e602686 16068 }
813dabb9
L
16069 uncompressed_size = chdr.ch_size;
16070 start += compression_header_size;
16071 new_size -= compression_header_size;
0e602686
NC
16072 }
16073 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16074 {
16075 /* Read the zlib header. In this case, it should be "ZLIB"
16076 followed by the uncompressed section size, 8 bytes in
16077 big-endian order. */
16078 uncompressed_size = start[4]; uncompressed_size <<= 8;
16079 uncompressed_size += start[5]; uncompressed_size <<= 8;
16080 uncompressed_size += start[6]; uncompressed_size <<= 8;
16081 uncompressed_size += start[7]; uncompressed_size <<= 8;
16082 uncompressed_size += start[8]; uncompressed_size <<= 8;
16083 uncompressed_size += start[9]; uncompressed_size <<= 8;
16084 uncompressed_size += start[10]; uncompressed_size <<= 8;
16085 uncompressed_size += start[11];
16086 start += 12;
16087 new_size -= 12;
16088 }
16089
f055032e
NC
16090 if (uncompressed_size)
16091 {
1f5a3546 16092 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16093 &new_size, filedata->file_size))
bc303e5d
NC
16094 {
16095 section_size = new_size;
16096 }
f055032e
NC
16097 else
16098 {
16099 error (_("Unable to decompress section %s\n"),
dda8d76d 16100 printable_section_name (filedata, section));
bc303e5d 16101 /* FIXME: Print the section anyway ? */
f761cb13 16102 goto error_out;
f055032e
NC
16103 }
16104 }
bc303e5d
NC
16105 else
16106 start = real_start;
0e602686 16107 }
14ae95f2 16108
cf13d699
NC
16109 if (relocate)
16110 {
dda8d76d 16111 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 16112 goto error_out;
cf13d699
NC
16113 }
16114 else
16115 {
16116 /* If the section being dumped has relocations against it the user might
16117 be expecting these relocations to have been applied. Check for this
16118 case and issue a warning message in order to avoid confusion.
16119 FIXME: Maybe we ought to have an option that dumps a section with
16120 relocs applied ? */
dda8d76d
NC
16121 for (relsec = filedata->section_headers;
16122 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
16123 ++relsec)
16124 {
16125 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
16126 || relsec->sh_info >= filedata->file_header.e_shnum
16127 || filedata->section_headers + relsec->sh_info != section
cf13d699 16128 || relsec->sh_size == 0
dda8d76d 16129 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
16130 continue;
16131
16132 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16133 break;
16134 }
16135 }
16136
16137 addr = section->sh_addr;
0e602686 16138 bytes = section_size;
cf13d699
NC
16139 data = start;
16140
16141 while (bytes)
16142 {
16143 int j;
16144 int k;
16145 int lbytes;
16146
16147 lbytes = (bytes > 16 ? 16 : bytes);
16148
26c527e6 16149 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
16150
16151 for (j = 0; j < 16; j++)
16152 {
16153 if (j < lbytes)
16154 printf ("%2.2x", data[j]);
16155 else
16156 printf (" ");
16157
16158 if ((j & 3) == 3)
16159 printf (" ");
16160 }
16161
16162 for (j = 0; j < lbytes; j++)
16163 {
16164 k = data[j];
16165 if (k >= ' ' && k < 0x7f)
16166 printf ("%c", k);
16167 else
16168 printf (".");
16169 }
16170
16171 putchar ('\n');
16172
16173 data += lbytes;
16174 addr += lbytes;
16175 bytes -= lbytes;
16176 }
16177
0e602686 16178 free (real_start);
cf13d699
NC
16179
16180 putchar ('\n');
015dc7e1 16181 return true;
f761cb13
AM
16182
16183 error_out:
16184 free (real_start);
015dc7e1 16185 return false;
cf13d699
NC
16186}
16187
094e34f2 16188#ifdef ENABLE_LIBCTF
7d9813f1
NA
16189static ctf_sect_t *
16190shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
16191{
84714f86 16192 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
16193 buf->cts_size = shdr->sh_size;
16194 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
16195
16196 return buf;
16197}
16198
16199/* Formatting callback function passed to ctf_dump. Returns either the pointer
16200 it is passed, or a pointer to newly-allocated storage, in which case
16201 dump_ctf() will free it when it no longer needs it. */
16202
2f6ecaed
NA
16203static char *
16204dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
16205 char *s, void *arg)
7d9813f1 16206{
3e50a591 16207 const char *blanks = arg;
7d9813f1
NA
16208 char *new_s;
16209
3e50a591 16210 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
16211 return s;
16212 return new_s;
16213}
16214
926c9e76
NA
16215/* Dump CTF errors/warnings. */
16216static void
139633c3 16217dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
16218{
16219 ctf_next_t *it = NULL;
16220 char *errtext;
16221 int is_warning;
16222 int err;
16223
16224 /* Dump accumulated errors and warnings. */
16225 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
16226 {
5e9b84f7 16227 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
16228 errtext);
16229 free (errtext);
16230 }
16231 if (err != ECTF_NEXT_END)
16232 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
16233}
16234
2f6ecaed
NA
16235/* Dump one CTF archive member. */
16236
80b56fad
NA
16237static void
16238dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
16239 size_t member)
2f6ecaed 16240{
2f6ecaed
NA
16241 const char *things[] = {"Header", "Labels", "Data objects",
16242 "Function objects", "Variables", "Types", "Strings",
16243 ""};
16244 const char **thing;
16245 size_t i;
16246
80b56fad
NA
16247 /* Don't print out the name of the default-named archive member if it appears
16248 first in the list. The name .ctf appears everywhere, even for things that
16249 aren't really archives, so printing it out is liable to be confusing; also,
16250 the common case by far is for only one archive member to exist, and hiding
16251 it in that case seems worthwhile. */
2f6ecaed 16252
80b56fad
NA
16253 if (strcmp (name, ".ctf") != 0 || member != 0)
16254 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 16255
80b56fad
NA
16256 if (ctf_parent_name (ctf) != NULL)
16257 ctf_import (ctf, parent);
2f6ecaed
NA
16258
16259 for (i = 0, thing = things; *thing[0]; thing++, i++)
16260 {
16261 ctf_dump_state_t *s = NULL;
16262 char *item;
16263
16264 printf ("\n %s:\n", *thing);
16265 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
16266 (void *) " ")) != NULL)
16267 {
16268 printf ("%s\n", item);
16269 free (item);
16270 }
16271
16272 if (ctf_errno (ctf))
16273 {
16274 error (_("Iteration failed: %s, %s\n"), *thing,
16275 ctf_errmsg (ctf_errno (ctf)));
80b56fad 16276 break;
2f6ecaed
NA
16277 }
16278 }
8b37e7b6 16279
926c9e76 16280 dump_ctf_errs (ctf);
2f6ecaed
NA
16281}
16282
015dc7e1 16283static bool
7d9813f1
NA
16284dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
16285{
7d9813f1
NA
16286 Elf_Internal_Shdr * symtab_sec = NULL;
16287 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
16288 void * data = NULL;
16289 void * symdata = NULL;
16290 void * strdata = NULL;
80b56fad 16291 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
16292 ctf_sect_t * symsectp = NULL;
16293 ctf_sect_t * strsectp = NULL;
2f6ecaed 16294 ctf_archive_t * ctfa = NULL;
139633c3 16295 ctf_dict_t * parent = NULL;
80b56fad 16296 ctf_dict_t * fp;
7d9813f1 16297
80b56fad
NA
16298 ctf_next_t *i = NULL;
16299 const char *name;
16300 size_t member = 0;
7d9813f1 16301 int err;
015dc7e1 16302 bool ret = false;
7d9813f1
NA
16303
16304 shdr_to_ctf_sect (&ctfsect, section, filedata);
16305 data = get_section_contents (section, filedata);
16306 ctfsect.cts_data = data;
16307
616febde 16308 if (!dump_ctf_symtab_name)
3d16b64e 16309 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
16310
16311 if (!dump_ctf_strtab_name)
3d16b64e 16312 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
16313
16314 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
16315 {
16316 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
16317 {
16318 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
16319 goto fail;
16320 }
16321 if ((symdata = (void *) get_data (NULL, filedata,
16322 symtab_sec->sh_offset, 1,
16323 symtab_sec->sh_size,
16324 _("symbols"))) == NULL)
16325 goto fail;
16326 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
16327 symsect.cts_data = symdata;
16328 }
835f2fae 16329
df16e041 16330 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
16331 {
16332 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
16333 {
16334 error (_("No string table section named %s\n"),
16335 dump_ctf_strtab_name);
16336 goto fail;
16337 }
16338 if ((strdata = (void *) get_data (NULL, filedata,
16339 strtab_sec->sh_offset, 1,
16340 strtab_sec->sh_size,
16341 _("strings"))) == NULL)
16342 goto fail;
16343 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
16344 strsect.cts_data = strdata;
16345 }
835f2fae 16346
2f6ecaed
NA
16347 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
16348 libctf papers over the difference, so we can pretend it is always an
80b56fad 16349 archive. */
7d9813f1 16350
2f6ecaed 16351 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 16352 {
926c9e76 16353 dump_ctf_errs (NULL);
7d9813f1
NA
16354 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16355 goto fail;
16356 }
16357
96c61be5
NA
16358 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
16359 != ELFDATA2MSB);
16360
80b56fad
NA
16361 /* Preload the parent dict, since it will need to be imported into every
16362 child in turn. */
16363 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 16364 {
926c9e76 16365 dump_ctf_errs (NULL);
2f6ecaed
NA
16366 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16367 goto fail;
7d9813f1
NA
16368 }
16369
015dc7e1 16370 ret = true;
7d9813f1 16371
835f2fae
NC
16372 if (filedata->is_separate)
16373 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
16374 printable_section_name (filedata, section),
16375 filedata->file_name);
16376 else
16377 printf (_("\nDump of CTF section '%s':\n"),
16378 printable_section_name (filedata, section));
7d9813f1 16379
80b56fad
NA
16380 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
16381 dump_ctf_archive_member (fp, name, parent, member++);
16382 if (err != ECTF_NEXT_END)
16383 {
16384 dump_ctf_errs (NULL);
16385 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
16386 ret = false;
16387 }
7d9813f1
NA
16388
16389 fail:
139633c3 16390 ctf_dict_close (parent);
2f6ecaed 16391 ctf_close (ctfa);
7d9813f1
NA
16392 free (data);
16393 free (symdata);
16394 free (strdata);
16395 return ret;
16396}
094e34f2 16397#endif
7d9813f1 16398
42b6953b
IB
16399static bool
16400dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
16401{
16402 void * data = NULL;
16403 sframe_decoder_ctx *sfd_ctx = NULL;
16404 const char *print_name = printable_section_name (filedata, section);
16405
16406 bool ret = true;
16407 size_t sf_size;
16408 int err = 0;
16409
16410 if (strcmp (print_name, "") == 0)
16411 {
16412 error (_("Section name must be provided \n"));
16413 ret = false;
16414 return ret;
16415 }
16416
16417 data = get_section_contents (section, filedata);
16418 sf_size = section->sh_size;
16419 /* Decode the contents of the section. */
16420 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
16421 if (!sfd_ctx)
16422 {
16423 ret = false;
16424 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
16425 goto fail;
16426 }
16427
16428 printf (_("Contents of the SFrame section %s:"), print_name);
16429 /* Dump the contents as text. */
16430 dump_sframe (sfd_ctx, section->sh_addr);
16431
16432 fail:
16433 free (data);
16434 return ret;
16435}
16436
015dc7e1 16437static bool
dda8d76d
NC
16438load_specific_debug_section (enum dwarf_section_display_enum debug,
16439 const Elf_Internal_Shdr * sec,
16440 void * data)
1007acb3 16441{
2cf0635d 16442 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 16443 char buf [64];
dda8d76d 16444 Filedata * filedata = (Filedata *) data;
9abca702 16445
19e6b90e 16446 if (section->start != NULL)
dda8d76d
NC
16447 {
16448 /* If it is already loaded, do nothing. */
16449 if (streq (section->filename, filedata->file_name))
015dc7e1 16450 return true;
dda8d76d
NC
16451 free (section->start);
16452 }
1007acb3 16453
19e6b90e
L
16454 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16455 section->address = sec->sh_addr;
dda8d76d
NC
16456 section->filename = filedata->file_name;
16457 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
16458 sec->sh_offset, 1,
16459 sec->sh_size, buf);
59245841
NC
16460 if (section->start == NULL)
16461 section->size = 0;
16462 else
16463 {
77115a4a 16464 unsigned char *start = section->start;
31e5a3a3
AM
16465 uint64_t size = sec->sh_size;
16466 uint64_t uncompressed_size = 0;
1f5a3546 16467 bool is_zstd = false;
77115a4a
L
16468
16469 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16470 {
16471 Elf_Internal_Chdr chdr;
d8024a91
NC
16472 unsigned int compression_header_size;
16473
f53be977
L
16474 if (size < (is_32bit_elf
16475 ? sizeof (Elf32_External_Chdr)
16476 : sizeof (Elf64_External_Chdr)))
d8024a91 16477 {
55be8fd0 16478 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 16479 section->name);
015dc7e1 16480 return false;
d8024a91
NC
16481 }
16482
ebdf1ebf 16483 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
16484 if (compression_header_size == 0)
16485 /* An error message will have already been generated
16486 by get_compression_header. */
015dc7e1 16487 return false;
d8024a91 16488
89dbeac7 16489 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16490 ;
16491#ifdef HAVE_ZSTD
89dbeac7 16492 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16493 is_zstd = true;
16494#endif
16495 else
813dabb9
L
16496 {
16497 warn (_("section '%s' has unsupported compress type: %d\n"),
16498 section->name, chdr.ch_type);
015dc7e1 16499 return false;
813dabb9 16500 }
dab394de 16501 uncompressed_size = chdr.ch_size;
77115a4a
L
16502 start += compression_header_size;
16503 size -= compression_header_size;
16504 }
dab394de
L
16505 else if (size > 12 && streq ((char *) start, "ZLIB"))
16506 {
16507 /* Read the zlib header. In this case, it should be "ZLIB"
16508 followed by the uncompressed section size, 8 bytes in
16509 big-endian order. */
16510 uncompressed_size = start[4]; uncompressed_size <<= 8;
16511 uncompressed_size += start[5]; uncompressed_size <<= 8;
16512 uncompressed_size += start[6]; uncompressed_size <<= 8;
16513 uncompressed_size += start[7]; uncompressed_size <<= 8;
16514 uncompressed_size += start[8]; uncompressed_size <<= 8;
16515 uncompressed_size += start[9]; uncompressed_size <<= 8;
16516 uncompressed_size += start[10]; uncompressed_size <<= 8;
16517 uncompressed_size += start[11];
16518 start += 12;
16519 size -= 12;
16520 }
16521
1835f746 16522 if (uncompressed_size)
77115a4a 16523 {
1f5a3546 16524 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16525 &size, filedata->file_size))
1835f746
NC
16526 {
16527 /* Free the compressed buffer, update the section buffer
16528 and the section size if uncompress is successful. */
16529 free (section->start);
16530 section->start = start;
16531 }
16532 else
16533 {
16534 error (_("Unable to decompress section %s\n"),
dda8d76d 16535 printable_section_name (filedata, sec));
015dc7e1 16536 return false;
1835f746 16537 }
77115a4a 16538 }
bc303e5d 16539
77115a4a 16540 section->size = size;
59245841 16541 }
4a114e3e 16542
1b315056 16543 if (section->start == NULL)
015dc7e1 16544 return false;
1b315056 16545
19e6b90e 16546 if (debug_displays [debug].relocate)
32ec8896 16547 {
dda8d76d 16548 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 16549 & section->reloc_info, & section->num_relocs))
015dc7e1 16550 return false;
32ec8896 16551 }
d1c4b12b
NC
16552 else
16553 {
16554 section->reloc_info = NULL;
16555 section->num_relocs = 0;
16556 }
1007acb3 16557
015dc7e1 16558 return true;
1007acb3
L
16559}
16560
301a9420
AM
16561#if HAVE_LIBDEBUGINFOD
16562/* Return a hex string representation of the build-id. */
16563unsigned char *
16564get_build_id (void * data)
16565{
ca0e11aa 16566 Filedata * filedata = (Filedata *) data;
301a9420 16567 Elf_Internal_Shdr * shdr;
26c527e6 16568 size_t i;
301a9420 16569
55be8fd0
NC
16570 /* Iterate through notes to find note.gnu.build-id.
16571 FIXME: Only the first note in any note section is examined. */
301a9420
AM
16572 for (i = 0, shdr = filedata->section_headers;
16573 i < filedata->file_header.e_shnum && shdr != NULL;
16574 i++, shdr++)
16575 {
16576 if (shdr->sh_type != SHT_NOTE)
16577 continue;
16578
16579 char * next;
16580 char * end;
16581 size_t data_remaining;
16582 size_t min_notesz;
16583 Elf_External_Note * enote;
16584 Elf_Internal_Note inote;
16585
625d49fc
AM
16586 uint64_t offset = shdr->sh_offset;
16587 uint64_t align = shdr->sh_addralign;
16588 uint64_t length = shdr->sh_size;
301a9420
AM
16589
16590 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16591 if (enote == NULL)
16592 continue;
16593
16594 if (align < 4)
16595 align = 4;
16596 else if (align != 4 && align != 8)
f761cb13
AM
16597 {
16598 free (enote);
16599 continue;
16600 }
301a9420
AM
16601
16602 end = (char *) enote + length;
16603 data_remaining = end - (char *) enote;
16604
16605 if (!is_ia64_vms (filedata))
16606 {
16607 min_notesz = offsetof (Elf_External_Note, name);
16608 if (data_remaining < min_notesz)
16609 {
55be8fd0
NC
16610 warn (_("\
16611malformed note encountered in section %s whilst scanning for build-id note\n"),
16612 printable_section_name (filedata, shdr));
f761cb13 16613 free (enote);
55be8fd0 16614 continue;
301a9420
AM
16615 }
16616 data_remaining -= min_notesz;
16617
16618 inote.type = BYTE_GET (enote->type);
16619 inote.namesz = BYTE_GET (enote->namesz);
16620 inote.namedata = enote->name;
16621 inote.descsz = BYTE_GET (enote->descsz);
16622 inote.descdata = ((char *) enote
16623 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16624 inote.descpos = offset + (inote.descdata - (char *) enote);
16625 next = ((char *) enote
16626 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16627 }
16628 else
16629 {
16630 Elf64_External_VMS_Note *vms_enote;
16631
16632 /* PR binutils/15191
16633 Make sure that there is enough data to read. */
16634 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16635 if (data_remaining < min_notesz)
16636 {
55be8fd0
NC
16637 warn (_("\
16638malformed note encountered in section %s whilst scanning for build-id note\n"),
16639 printable_section_name (filedata, shdr));
f761cb13 16640 free (enote);
55be8fd0 16641 continue;
301a9420
AM
16642 }
16643 data_remaining -= min_notesz;
16644
16645 vms_enote = (Elf64_External_VMS_Note *) enote;
16646 inote.type = BYTE_GET (vms_enote->type);
16647 inote.namesz = BYTE_GET (vms_enote->namesz);
16648 inote.namedata = vms_enote->name;
16649 inote.descsz = BYTE_GET (vms_enote->descsz);
16650 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16651 inote.descpos = offset + (inote.descdata - (char *) enote);
16652 next = inote.descdata + align_power (inote.descsz, 3);
16653 }
16654
16655 /* Skip malformed notes. */
16656 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16657 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16658 || (size_t) (next - inote.descdata) < inote.descsz
16659 || ((size_t) (next - inote.descdata)
16660 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16661 {
55be8fd0
NC
16662 warn (_("\
16663malformed note encountered in section %s whilst scanning for build-id note\n"),
16664 printable_section_name (filedata, shdr));
f761cb13 16665 free (enote);
301a9420
AM
16666 continue;
16667 }
16668
16669 /* Check if this is the build-id note. If so then convert the build-id
16670 bytes to a hex string. */
16671 if (inote.namesz > 0
24d127aa 16672 && startswith (inote.namedata, "GNU")
301a9420
AM
16673 && inote.type == NT_GNU_BUILD_ID)
16674 {
26c527e6 16675 size_t j;
301a9420
AM
16676 char * build_id;
16677
16678 build_id = malloc (inote.descsz * 2 + 1);
16679 if (build_id == NULL)
f761cb13
AM
16680 {
16681 free (enote);
16682 return NULL;
16683 }
301a9420
AM
16684
16685 for (j = 0; j < inote.descsz; ++j)
16686 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16687 build_id[inote.descsz * 2] = '\0';
f761cb13 16688 free (enote);
301a9420 16689
55be8fd0 16690 return (unsigned char *) build_id;
301a9420 16691 }
f761cb13 16692 free (enote);
301a9420
AM
16693 }
16694
16695 return NULL;
16696}
16697#endif /* HAVE_LIBDEBUGINFOD */
16698
657d0d47
CC
16699/* If this is not NULL, load_debug_section will only look for sections
16700 within the list of sections given here. */
32ec8896 16701static unsigned int * section_subset = NULL;
657d0d47 16702
015dc7e1 16703bool
dda8d76d 16704load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16705{
2cf0635d
NC
16706 struct dwarf_section * section = &debug_displays [debug].section;
16707 Elf_Internal_Shdr * sec;
dda8d76d
NC
16708 Filedata * filedata = (Filedata *) data;
16709
e1dbfc17
L
16710 if (!dump_any_debugging)
16711 return false;
16712
f425ec66
NC
16713 /* Without section headers we cannot find any sections. */
16714 if (filedata->section_headers == NULL)
015dc7e1 16715 return false;
f425ec66 16716
9c1ce108
AM
16717 if (filedata->string_table == NULL
16718 && filedata->file_header.e_shstrndx != SHN_UNDEF
16719 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16720 {
16721 Elf_Internal_Shdr * strs;
16722
16723 /* Read in the string table, so that we have section names to scan. */
16724 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16725
4dff97b2 16726 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16727 {
9c1ce108
AM
16728 filedata->string_table
16729 = (char *) get_data (NULL, filedata, strs->sh_offset,
16730 1, strs->sh_size, _("string table"));
dda8d76d 16731
9c1ce108
AM
16732 filedata->string_table_length
16733 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16734 }
16735 }
d966045b
DJ
16736
16737 /* Locate the debug section. */
dda8d76d 16738 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16739 if (sec != NULL)
16740 section->name = section->uncompressed_name;
16741 else
16742 {
dda8d76d 16743 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16744 if (sec != NULL)
16745 section->name = section->compressed_name;
16746 }
16747 if (sec == NULL)
015dc7e1 16748 return false;
d966045b 16749
657d0d47
CC
16750 /* If we're loading from a subset of sections, and we've loaded
16751 a section matching this name before, it's likely that it's a
16752 different one. */
16753 if (section_subset != NULL)
16754 free_debug_section (debug);
16755
dda8d76d 16756 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16757}
16758
19e6b90e
L
16759void
16760free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16761{
2cf0635d 16762 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16763
19e6b90e
L
16764 if (section->start == NULL)
16765 return;
1007acb3 16766
19e6b90e
L
16767 free ((char *) section->start);
16768 section->start = NULL;
16769 section->address = 0;
16770 section->size = 0;
a788aedd 16771
9db70fc3
AM
16772 free (section->reloc_info);
16773 section->reloc_info = NULL;
16774 section->num_relocs = 0;
1007acb3
L
16775}
16776
015dc7e1 16777static bool
dda8d76d 16778display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16779{
84714f86
AM
16780 const char *name = (section_name_valid (filedata, section)
16781 ? section_name (filedata, section) : "");
16782 const char *print_name = printable_section_name (filedata, section);
be7d229a 16783 uint64_t length;
015dc7e1 16784 bool result = true;
3f5e193b 16785 int i;
1007acb3 16786
19e6b90e
L
16787 length = section->sh_size;
16788 if (length == 0)
1007acb3 16789 {
74e1a04b 16790 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16791 return true;
1007acb3 16792 }
5dff79d8
NC
16793 if (section->sh_type == SHT_NOBITS)
16794 {
16795 /* There is no point in dumping the contents of a debugging section
16796 which has the NOBITS type - the bits in the file will be random.
16797 This can happen when a file containing a .eh_frame section is
16798 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16799 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16800 print_name);
015dc7e1 16801 return false;
5dff79d8 16802 }
1007acb3 16803
24d127aa 16804 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16805 name = ".debug_info";
1007acb3 16806
19e6b90e
L
16807 /* See if we know how to display the contents of this section. */
16808 for (i = 0; i < max; i++)
d85bf2ba
NC
16809 {
16810 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16811 struct dwarf_section_display * display = debug_displays + i;
16812 struct dwarf_section * sec = & display->section;
d966045b 16813
d85bf2ba 16814 if (streq (sec->uncompressed_name, name)
24d127aa 16815 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16816 || streq (sec->compressed_name, name))
16817 {
015dc7e1 16818 bool secondary = (section != find_section (filedata, name));
1007acb3 16819
d85bf2ba
NC
16820 if (secondary)
16821 free_debug_section (id);
dda8d76d 16822
24d127aa 16823 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16824 sec->name = name;
16825 else if (streq (sec->uncompressed_name, name))
16826 sec->name = sec->uncompressed_name;
16827 else
16828 sec->name = sec->compressed_name;
657d0d47 16829
d85bf2ba
NC
16830 if (load_specific_debug_section (id, section, filedata))
16831 {
16832 /* If this debug section is part of a CU/TU set in a .dwp file,
16833 restrict load_debug_section to the sections in that set. */
16834 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16835
d85bf2ba 16836 result &= display->display (sec, filedata);
657d0d47 16837
d85bf2ba 16838 section_subset = NULL;
1007acb3 16839
44266f36 16840 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16841 free_debug_section (id);
16842 }
16843 break;
16844 }
16845 }
1007acb3 16846
19e6b90e 16847 if (i == max)
1007acb3 16848 {
74e1a04b 16849 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16850 result = false;
1007acb3
L
16851 }
16852
19e6b90e 16853 return result;
5b18a4bc 16854}
103f02d3 16855
aef1f6d0
DJ
16856/* Set DUMP_SECTS for all sections where dumps were requested
16857 based on section name. */
16858
16859static void
dda8d76d 16860initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16861{
2cf0635d 16862 struct dump_list_entry * cur;
aef1f6d0
DJ
16863
16864 for (cur = dump_sects_byname; cur; cur = cur->next)
16865 {
16866 unsigned int i;
015dc7e1 16867 bool any = false;
aef1f6d0 16868
dda8d76d 16869 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16870 if (section_name_valid (filedata, filedata->section_headers + i)
16871 && streq (section_name (filedata, filedata->section_headers + i),
16872 cur->name))
aef1f6d0 16873 {
6431e409 16874 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16875 any = true;
aef1f6d0
DJ
16876 }
16877
835f2fae
NC
16878 if (!any && !filedata->is_separate)
16879 warn (_("Section '%s' was not dumped because it does not exist\n"),
16880 cur->name);
aef1f6d0
DJ
16881 }
16882}
16883
015dc7e1 16884static bool
dda8d76d 16885process_section_contents (Filedata * filedata)
5b18a4bc 16886{
2cf0635d 16887 Elf_Internal_Shdr * section;
19e6b90e 16888 unsigned int i;
015dc7e1 16889 bool res = true;
103f02d3 16890
19e6b90e 16891 if (! do_dump)
015dc7e1 16892 return true;
103f02d3 16893
dda8d76d 16894 initialise_dumps_byname (filedata);
aef1f6d0 16895
dda8d76d 16896 for (i = 0, section = filedata->section_headers;
6431e409 16897 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16898 i++, section++)
16899 {
6431e409 16900 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16901
d6bfbc39
NC
16902 if (filedata->is_separate && ! process_links)
16903 dump &= DEBUG_DUMP;
047c3dbf 16904
19e6b90e 16905#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16906 if (dump & DISASS_DUMP)
16907 {
16908 if (! disassemble_section (section, filedata))
015dc7e1 16909 res = false;
dda8d76d 16910 }
19e6b90e 16911#endif
dda8d76d 16912 if (dump & HEX_DUMP)
32ec8896 16913 {
015dc7e1
AM
16914 if (! dump_section_as_bytes (section, filedata, false))
16915 res = false;
32ec8896 16916 }
103f02d3 16917
dda8d76d 16918 if (dump & RELOC_DUMP)
32ec8896 16919 {
015dc7e1
AM
16920 if (! dump_section_as_bytes (section, filedata, true))
16921 res = false;
32ec8896 16922 }
09c11c86 16923
dda8d76d 16924 if (dump & STRING_DUMP)
32ec8896 16925 {
dda8d76d 16926 if (! dump_section_as_strings (section, filedata))
015dc7e1 16927 res = false;
32ec8896 16928 }
cf13d699 16929
dda8d76d 16930 if (dump & DEBUG_DUMP)
32ec8896 16931 {
dda8d76d 16932 if (! display_debug_section (i, section, filedata))
015dc7e1 16933 res = false;
32ec8896 16934 }
7d9813f1 16935
094e34f2 16936#ifdef ENABLE_LIBCTF
7d9813f1
NA
16937 if (dump & CTF_DUMP)
16938 {
16939 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16940 res = false;
7d9813f1 16941 }
094e34f2 16942#endif
42b6953b
IB
16943 if (dump & SFRAME_DUMP)
16944 {
16945 if (! dump_section_as_sframe (section, filedata))
16946 res = false;
16947 }
5b18a4bc 16948 }
103f02d3 16949
835f2fae 16950 if (! filedata->is_separate)
0ee3043f 16951 {
835f2fae
NC
16952 /* Check to see if the user requested a
16953 dump of a section that does not exist. */
16954 for (; i < filedata->dump.num_dump_sects; i++)
16955 if (filedata->dump.dump_sects[i])
16956 {
ca0e11aa 16957 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16958 res = false;
835f2fae 16959 }
0ee3043f 16960 }
32ec8896
NC
16961
16962 return res;
5b18a4bc 16963}
103f02d3 16964
5b18a4bc 16965static void
19e6b90e 16966process_mips_fpe_exception (int mask)
5b18a4bc 16967{
19e6b90e
L
16968 if (mask)
16969 {
015dc7e1 16970 bool first = true;
32ec8896 16971
19e6b90e 16972 if (mask & OEX_FPU_INEX)
015dc7e1 16973 fputs ("INEX", stdout), first = false;
19e6b90e 16974 if (mask & OEX_FPU_UFLO)
015dc7e1 16975 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16976 if (mask & OEX_FPU_OFLO)
015dc7e1 16977 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16978 if (mask & OEX_FPU_DIV0)
015dc7e1 16979 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16980 if (mask & OEX_FPU_INVAL)
16981 printf ("%sINVAL", first ? "" : "|");
16982 }
5b18a4bc 16983 else
19e6b90e 16984 fputs ("0", stdout);
5b18a4bc 16985}
103f02d3 16986
f6f0e17b
NC
16987/* Display's the value of TAG at location P. If TAG is
16988 greater than 0 it is assumed to be an unknown tag, and
16989 a message is printed to this effect. Otherwise it is
16990 assumed that a message has already been printed.
16991
16992 If the bottom bit of TAG is set it assumed to have a
16993 string value, otherwise it is assumed to have an integer
16994 value.
16995
16996 Returns an updated P pointing to the first unread byte
16997 beyond the end of TAG's value.
16998
16999 Reads at or beyond END will not be made. */
17000
17001static unsigned char *
60abdbed 17002display_tag_value (signed int tag,
f6f0e17b
NC
17003 unsigned char * p,
17004 const unsigned char * const end)
17005{
26c527e6 17006 uint64_t val;
f6f0e17b
NC
17007
17008 if (tag > 0)
17009 printf (" Tag_unknown_%d: ", tag);
17010
17011 if (p >= end)
17012 {
4082ef84 17013 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
17014 }
17015 else if (tag & 1)
17016 {
071436c6
NC
17017 /* PR 17531 file: 027-19978-0.004. */
17018 size_t maxlen = (end - p) - 1;
17019
17020 putchar ('"');
4082ef84
NC
17021 if (maxlen > 0)
17022 {
17023 print_symbol ((int) maxlen, (const char *) p);
17024 p += strnlen ((char *) p, maxlen) + 1;
17025 }
17026 else
17027 {
17028 printf (_("<corrupt string tag>"));
17029 p = (unsigned char *) end;
17030 }
071436c6 17031 printf ("\"\n");
f6f0e17b
NC
17032 }
17033 else
17034 {
cd30bcef 17035 READ_ULEB (val, p, end);
26c527e6 17036 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
17037 }
17038
4082ef84 17039 assert (p <= end);
f6f0e17b
NC
17040 return p;
17041}
17042
53a346d8
CZ
17043/* ARC ABI attributes section. */
17044
17045static unsigned char *
17046display_arc_attribute (unsigned char * p,
17047 const unsigned char * const end)
17048{
17049 unsigned int tag;
53a346d8
CZ
17050 unsigned int val;
17051
cd30bcef 17052 READ_ULEB (tag, p, end);
53a346d8
CZ
17053
17054 switch (tag)
17055 {
17056 case Tag_ARC_PCS_config:
cd30bcef 17057 READ_ULEB (val, p, end);
53a346d8
CZ
17058 printf (" Tag_ARC_PCS_config: ");
17059 switch (val)
17060 {
17061 case 0:
17062 printf (_("Absent/Non standard\n"));
17063 break;
17064 case 1:
17065 printf (_("Bare metal/mwdt\n"));
17066 break;
17067 case 2:
17068 printf (_("Bare metal/newlib\n"));
17069 break;
17070 case 3:
17071 printf (_("Linux/uclibc\n"));
17072 break;
17073 case 4:
17074 printf (_("Linux/glibc\n"));
17075 break;
17076 default:
17077 printf (_("Unknown\n"));
17078 break;
17079 }
17080 break;
17081
17082 case Tag_ARC_CPU_base:
cd30bcef 17083 READ_ULEB (val, p, end);
53a346d8
CZ
17084 printf (" Tag_ARC_CPU_base: ");
17085 switch (val)
17086 {
17087 default:
17088 case TAG_CPU_NONE:
17089 printf (_("Absent\n"));
17090 break;
17091 case TAG_CPU_ARC6xx:
17092 printf ("ARC6xx\n");
17093 break;
17094 case TAG_CPU_ARC7xx:
17095 printf ("ARC7xx\n");
17096 break;
17097 case TAG_CPU_ARCEM:
17098 printf ("ARCEM\n");
17099 break;
17100 case TAG_CPU_ARCHS:
17101 printf ("ARCHS\n");
17102 break;
17103 }
17104 break;
17105
17106 case Tag_ARC_CPU_variation:
cd30bcef 17107 READ_ULEB (val, p, end);
53a346d8
CZ
17108 printf (" Tag_ARC_CPU_variation: ");
17109 switch (val)
17110 {
17111 default:
17112 if (val > 0 && val < 16)
53a346d8 17113 printf ("Core%d\n", val);
d8cbc93b
JL
17114 else
17115 printf ("Unknown\n");
17116 break;
17117
53a346d8
CZ
17118 case 0:
17119 printf (_("Absent\n"));
17120 break;
17121 }
17122 break;
17123
17124 case Tag_ARC_CPU_name:
17125 printf (" Tag_ARC_CPU_name: ");
17126 p = display_tag_value (-1, p, end);
17127 break;
17128
17129 case Tag_ARC_ABI_rf16:
cd30bcef 17130 READ_ULEB (val, p, end);
53a346d8
CZ
17131 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
17132 break;
17133
17134 case Tag_ARC_ABI_osver:
cd30bcef 17135 READ_ULEB (val, p, end);
53a346d8
CZ
17136 printf (" Tag_ARC_ABI_osver: v%d\n", val);
17137 break;
17138
17139 case Tag_ARC_ABI_pic:
17140 case Tag_ARC_ABI_sda:
cd30bcef 17141 READ_ULEB (val, p, end);
53a346d8
CZ
17142 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
17143 : " Tag_ARC_ABI_pic: ");
17144 switch (val)
17145 {
17146 case 0:
17147 printf (_("Absent\n"));
17148 break;
17149 case 1:
17150 printf ("MWDT\n");
17151 break;
17152 case 2:
17153 printf ("GNU\n");
17154 break;
17155 default:
17156 printf (_("Unknown\n"));
17157 break;
17158 }
17159 break;
17160
17161 case Tag_ARC_ABI_tls:
cd30bcef 17162 READ_ULEB (val, p, end);
53a346d8
CZ
17163 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
17164 break;
17165
17166 case Tag_ARC_ABI_enumsize:
cd30bcef 17167 READ_ULEB (val, p, end);
53a346d8
CZ
17168 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
17169 _("smallest"));
17170 break;
17171
17172 case Tag_ARC_ABI_exceptions:
cd30bcef 17173 READ_ULEB (val, p, end);
53a346d8
CZ
17174 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
17175 : _("default"));
17176 break;
17177
17178 case Tag_ARC_ABI_double_size:
cd30bcef 17179 READ_ULEB (val, p, end);
53a346d8
CZ
17180 printf (" Tag_ARC_ABI_double_size: %d\n", val);
17181 break;
17182
17183 case Tag_ARC_ISA_config:
17184 printf (" Tag_ARC_ISA_config: ");
17185 p = display_tag_value (-1, p, end);
17186 break;
17187
17188 case Tag_ARC_ISA_apex:
17189 printf (" Tag_ARC_ISA_apex: ");
17190 p = display_tag_value (-1, p, end);
17191 break;
17192
17193 case Tag_ARC_ISA_mpy_option:
cd30bcef 17194 READ_ULEB (val, p, end);
53a346d8
CZ
17195 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
17196 break;
17197
db1e1b45 17198 case Tag_ARC_ATR_version:
cd30bcef 17199 READ_ULEB (val, p, end);
db1e1b45 17200 printf (" Tag_ARC_ATR_version: %d\n", val);
17201 break;
17202
53a346d8
CZ
17203 default:
17204 return display_tag_value (tag & 1, p, end);
17205 }
17206
17207 return p;
17208}
17209
11c1ff18
PB
17210/* ARM EABI attributes section. */
17211typedef struct
17212{
70e99720 17213 unsigned int tag;
2cf0635d 17214 const char * name;
11c1ff18 17215 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 17216 unsigned int type;
288f0ba2 17217 const char *const *table;
11c1ff18
PB
17218} arm_attr_public_tag;
17219
288f0ba2 17220static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 17221 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 17222 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
17223 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
17224 "v8.1-M.mainline", "v9"};
288f0ba2
AM
17225static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
17226static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 17227 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 17228static const char *const arm_attr_tag_FP_arch[] =
bca38921 17229 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 17230 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
17231static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
17232static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
17233 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
17234 "NEON for ARMv8.1"};
288f0ba2 17235static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
17236 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
17237 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 17238static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 17239 {"V6", "SB", "TLS", "Unused"};
288f0ba2 17240static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 17241 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 17242static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 17243 {"Absolute", "PC-relative", "None"};
288f0ba2 17244static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 17245 {"None", "direct", "GOT-indirect"};
288f0ba2 17246static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 17247 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
17248static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
17249static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 17250 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
17251static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
17252static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
17253static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 17254 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 17255static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 17256 {"Unused", "small", "int", "forced to int"};
288f0ba2 17257static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 17258 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 17259static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 17260 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 17261static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 17262 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 17263static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
17264 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17265 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 17266static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
17267 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17268 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
17269static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
17270static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 17271 {"Not Allowed", "Allowed"};
288f0ba2 17272static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 17273 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 17274static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 17275 {"Follow architecture", "Allowed"};
288f0ba2 17276static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 17277 {"Not Allowed", "Allowed"};
288f0ba2 17278static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 17279 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 17280 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
17281static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
17282static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 17283 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 17284 "TrustZone and Virtualization Extensions"};
288f0ba2 17285static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 17286 {"Not Allowed", "Allowed"};
11c1ff18 17287
288f0ba2 17288static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
17289 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
17290
99db83d0
AC
17291static const char * arm_attr_tag_PAC_extension[] =
17292 {"No PAC/AUT instructions",
17293 "PAC/AUT instructions permitted in the NOP space",
17294 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
17295
4b535030
AC
17296static const char * arm_attr_tag_BTI_extension[] =
17297 {"BTI instructions not permitted",
17298 "BTI instructions permitted in the NOP space",
17299 "BTI instructions permitted in the NOP and in the non-NOP space"};
17300
b81ee92f
AC
17301static const char * arm_attr_tag_BTI_use[] =
17302 {"Compiled without branch target enforcement",
17303 "Compiled with branch target enforcement"};
17304
c9fed665
AC
17305static const char * arm_attr_tag_PACRET_use[] =
17306 {"Compiled without return address signing and authentication",
17307 "Compiled with return address signing and authentication"};
17308
11c1ff18
PB
17309#define LOOKUP(id, name) \
17310 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 17311static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
17312{
17313 {4, "CPU_raw_name", 1, NULL},
17314 {5, "CPU_name", 1, NULL},
17315 LOOKUP(6, CPU_arch),
17316 {7, "CPU_arch_profile", 0, NULL},
17317 LOOKUP(8, ARM_ISA_use),
17318 LOOKUP(9, THUMB_ISA_use),
75375b3e 17319 LOOKUP(10, FP_arch),
11c1ff18 17320 LOOKUP(11, WMMX_arch),
f5f53991
AS
17321 LOOKUP(12, Advanced_SIMD_arch),
17322 LOOKUP(13, PCS_config),
11c1ff18
PB
17323 LOOKUP(14, ABI_PCS_R9_use),
17324 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 17325 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
17326 LOOKUP(17, ABI_PCS_GOT_use),
17327 LOOKUP(18, ABI_PCS_wchar_t),
17328 LOOKUP(19, ABI_FP_rounding),
17329 LOOKUP(20, ABI_FP_denormal),
17330 LOOKUP(21, ABI_FP_exceptions),
17331 LOOKUP(22, ABI_FP_user_exceptions),
17332 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
17333 {24, "ABI_align_needed", 0, NULL},
17334 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
17335 LOOKUP(26, ABI_enum_size),
17336 LOOKUP(27, ABI_HardFP_use),
17337 LOOKUP(28, ABI_VFP_args),
17338 LOOKUP(29, ABI_WMMX_args),
17339 LOOKUP(30, ABI_optimization_goals),
17340 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 17341 {32, "compatibility", 0, NULL},
f5f53991 17342 LOOKUP(34, CPU_unaligned_access),
75375b3e 17343 LOOKUP(36, FP_HP_extension),
8e79c3df 17344 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
17345 LOOKUP(42, MPextension_use),
17346 LOOKUP(44, DIV_use),
15afaa63 17347 LOOKUP(46, DSP_extension),
a7ad558c 17348 LOOKUP(48, MVE_arch),
99db83d0 17349 LOOKUP(50, PAC_extension),
4b535030 17350 LOOKUP(52, BTI_extension),
b81ee92f 17351 LOOKUP(74, BTI_use),
c9fed665 17352 LOOKUP(76, PACRET_use),
f5f53991
AS
17353 {64, "nodefaults", 0, NULL},
17354 {65, "also_compatible_with", 0, NULL},
17355 LOOKUP(66, T2EE_use),
17356 {67, "conformance", 1, NULL},
17357 LOOKUP(68, Virtualization_use),
cd21e546 17358 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
17359};
17360#undef LOOKUP
17361
11c1ff18 17362static unsigned char *
f6f0e17b
NC
17363display_arm_attribute (unsigned char * p,
17364 const unsigned char * const end)
11c1ff18 17365{
70e99720 17366 unsigned int tag;
70e99720 17367 unsigned int val;
2cf0635d 17368 arm_attr_public_tag * attr;
11c1ff18 17369 unsigned i;
70e99720 17370 unsigned int type;
11c1ff18 17371
cd30bcef 17372 READ_ULEB (tag, p, end);
11c1ff18 17373 attr = NULL;
2cf0635d 17374 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
17375 {
17376 if (arm_attr_public_tags[i].tag == tag)
17377 {
17378 attr = &arm_attr_public_tags[i];
17379 break;
17380 }
17381 }
17382
17383 if (attr)
17384 {
17385 printf (" Tag_%s: ", attr->name);
17386 switch (attr->type)
17387 {
17388 case 0:
17389 switch (tag)
17390 {
17391 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 17392 READ_ULEB (val, p, end);
11c1ff18
PB
17393 switch (val)
17394 {
2b692964
NC
17395 case 0: printf (_("None\n")); break;
17396 case 'A': printf (_("Application\n")); break;
17397 case 'R': printf (_("Realtime\n")); break;
17398 case 'M': printf (_("Microcontroller\n")); break;
17399 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
17400 default: printf ("??? (%d)\n", val); break;
17401 }
17402 break;
17403
75375b3e 17404 case 24: /* Tag_align_needed. */
cd30bcef 17405 READ_ULEB (val, p, end);
75375b3e
MGD
17406 switch (val)
17407 {
2b692964
NC
17408 case 0: printf (_("None\n")); break;
17409 case 1: printf (_("8-byte\n")); break;
17410 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
17411 case 3: printf ("??? 3\n"); break;
17412 default:
17413 if (val <= 12)
dd24e3da 17414 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17415 1 << val);
17416 else
17417 printf ("??? (%d)\n", val);
17418 break;
17419 }
17420 break;
17421
17422 case 25: /* Tag_align_preserved. */
cd30bcef 17423 READ_ULEB (val, p, end);
75375b3e
MGD
17424 switch (val)
17425 {
2b692964
NC
17426 case 0: printf (_("None\n")); break;
17427 case 1: printf (_("8-byte, except leaf SP\n")); break;
17428 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
17429 case 3: printf ("??? 3\n"); break;
17430 default:
17431 if (val <= 12)
dd24e3da 17432 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17433 1 << val);
17434 else
17435 printf ("??? (%d)\n", val);
17436 break;
17437 }
17438 break;
17439
11c1ff18 17440 case 32: /* Tag_compatibility. */
071436c6 17441 {
cd30bcef 17442 READ_ULEB (val, p, end);
071436c6 17443 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17444 if (p < end - 1)
17445 {
17446 size_t maxlen = (end - p) - 1;
17447
17448 print_symbol ((int) maxlen, (const char *) p);
17449 p += strnlen ((char *) p, maxlen) + 1;
17450 }
17451 else
17452 {
17453 printf (_("<corrupt>"));
17454 p = (unsigned char *) end;
17455 }
071436c6 17456 putchar ('\n');
071436c6 17457 }
11c1ff18
PB
17458 break;
17459
f5f53991 17460 case 64: /* Tag_nodefaults. */
541a3cbd
NC
17461 /* PR 17531: file: 001-505008-0.01. */
17462 if (p < end)
17463 p++;
2b692964 17464 printf (_("True\n"));
f5f53991
AS
17465 break;
17466
17467 case 65: /* Tag_also_compatible_with. */
cd30bcef 17468 READ_ULEB (val, p, end);
f5f53991
AS
17469 if (val == 6 /* Tag_CPU_arch. */)
17470 {
cd30bcef 17471 READ_ULEB (val, p, end);
071436c6 17472 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
17473 printf ("??? (%d)\n", val);
17474 else
17475 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17476 }
17477 else
17478 printf ("???\n");
071436c6
NC
17479 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17480 ;
f5f53991
AS
17481 break;
17482
11c1ff18 17483 default:
bee0ee85
NC
17484 printf (_("<unknown: %d>\n"), tag);
17485 break;
11c1ff18
PB
17486 }
17487 return p;
17488
17489 case 1:
f6f0e17b 17490 return display_tag_value (-1, p, end);
11c1ff18 17491 case 2:
f6f0e17b 17492 return display_tag_value (0, p, end);
11c1ff18
PB
17493
17494 default:
17495 assert (attr->type & 0x80);
cd30bcef 17496 READ_ULEB (val, p, end);
11c1ff18
PB
17497 type = attr->type & 0x7f;
17498 if (val >= type)
17499 printf ("??? (%d)\n", val);
17500 else
17501 printf ("%s\n", attr->table[val]);
17502 return p;
17503 }
17504 }
11c1ff18 17505
f6f0e17b 17506 return display_tag_value (tag, p, end);
11c1ff18
PB
17507}
17508
104d59d1 17509static unsigned char *
60bca95a 17510display_gnu_attribute (unsigned char * p,
60abdbed 17511 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 17512 const unsigned char * const end)
104d59d1 17513{
cd30bcef 17514 unsigned int tag;
60abdbed 17515 unsigned int val;
104d59d1 17516
cd30bcef 17517 READ_ULEB (tag, p, end);
104d59d1
JM
17518
17519 /* Tag_compatibility is the only generic GNU attribute defined at
17520 present. */
17521 if (tag == 32)
17522 {
cd30bcef 17523 READ_ULEB (val, p, end);
071436c6
NC
17524
17525 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
17526 if (p == end)
17527 {
071436c6 17528 printf (_("<corrupt>\n"));
f6f0e17b
NC
17529 warn (_("corrupt vendor attribute\n"));
17530 }
17531 else
17532 {
4082ef84
NC
17533 if (p < end - 1)
17534 {
17535 size_t maxlen = (end - p) - 1;
071436c6 17536
4082ef84
NC
17537 print_symbol ((int) maxlen, (const char *) p);
17538 p += strnlen ((char *) p, maxlen) + 1;
17539 }
17540 else
17541 {
17542 printf (_("<corrupt>"));
17543 p = (unsigned char *) end;
17544 }
071436c6 17545 putchar ('\n');
f6f0e17b 17546 }
104d59d1
JM
17547 return p;
17548 }
17549
17550 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 17551 return display_proc_gnu_attribute (p, tag, end);
104d59d1 17552
f6f0e17b 17553 return display_tag_value (tag, p, end);
104d59d1
JM
17554}
17555
85f7484a
PB
17556static unsigned char *
17557display_m68k_gnu_attribute (unsigned char * p,
17558 unsigned int tag,
17559 const unsigned char * const end)
17560{
17561 unsigned int val;
17562
17563 if (tag == Tag_GNU_M68K_ABI_FP)
17564 {
17565 printf (" Tag_GNU_M68K_ABI_FP: ");
17566 if (p == end)
17567 {
17568 printf (_("<corrupt>\n"));
17569 return p;
17570 }
17571 READ_ULEB (val, p, end);
17572
17573 if (val > 3)
17574 printf ("(%#x), ", val);
17575
17576 switch (val & 3)
17577 {
17578 case 0:
17579 printf (_("unspecified hard/soft float\n"));
17580 break;
17581 case 1:
17582 printf (_("hard float\n"));
17583 break;
17584 case 2:
17585 printf (_("soft float\n"));
17586 break;
17587 }
17588 return p;
17589 }
17590
17591 return display_tag_value (tag & 1, p, end);
17592}
17593
34c8bcba 17594static unsigned char *
f6f0e17b 17595display_power_gnu_attribute (unsigned char * p,
60abdbed 17596 unsigned int tag,
f6f0e17b 17597 const unsigned char * const end)
34c8bcba 17598{
005d79fd 17599 unsigned int val;
34c8bcba
JM
17600
17601 if (tag == Tag_GNU_Power_ABI_FP)
17602 {
34c8bcba 17603 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 17604 if (p == end)
005d79fd
AM
17605 {
17606 printf (_("<corrupt>\n"));
17607 return p;
17608 }
cd30bcef 17609 READ_ULEB (val, p, end);
60bca95a 17610
005d79fd
AM
17611 if (val > 15)
17612 printf ("(%#x), ", val);
17613
17614 switch (val & 3)
34c8bcba
JM
17615 {
17616 case 0:
005d79fd 17617 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17618 break;
17619 case 1:
005d79fd 17620 printf (_("hard float, "));
34c8bcba
JM
17621 break;
17622 case 2:
005d79fd 17623 printf (_("soft float, "));
34c8bcba 17624 break;
3c7b9897 17625 case 3:
005d79fd 17626 printf (_("single-precision hard float, "));
3c7b9897 17627 break;
005d79fd
AM
17628 }
17629
17630 switch (val & 0xC)
17631 {
17632 case 0:
17633 printf (_("unspecified long double\n"));
17634 break;
17635 case 4:
17636 printf (_("128-bit IBM long double\n"));
17637 break;
17638 case 8:
17639 printf (_("64-bit long double\n"));
17640 break;
17641 case 12:
17642 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17643 break;
17644 }
17645 return p;
005d79fd 17646 }
34c8bcba 17647
c6e65352
DJ
17648 if (tag == Tag_GNU_Power_ABI_Vector)
17649 {
c6e65352 17650 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17651 if (p == end)
005d79fd
AM
17652 {
17653 printf (_("<corrupt>\n"));
17654 return p;
17655 }
cd30bcef 17656 READ_ULEB (val, p, end);
005d79fd
AM
17657
17658 if (val > 3)
17659 printf ("(%#x), ", val);
17660
17661 switch (val & 3)
c6e65352
DJ
17662 {
17663 case 0:
005d79fd 17664 printf (_("unspecified\n"));
c6e65352
DJ
17665 break;
17666 case 1:
005d79fd 17667 printf (_("generic\n"));
c6e65352
DJ
17668 break;
17669 case 2:
17670 printf ("AltiVec\n");
17671 break;
17672 case 3:
17673 printf ("SPE\n");
17674 break;
c6e65352
DJ
17675 }
17676 return p;
005d79fd 17677 }
c6e65352 17678
f82e0623
NF
17679 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17680 {
005d79fd 17681 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17682 if (p == end)
f6f0e17b 17683 {
005d79fd 17684 printf (_("<corrupt>\n"));
f6f0e17b
NC
17685 return p;
17686 }
cd30bcef 17687 READ_ULEB (val, p, end);
0b4362b0 17688
005d79fd
AM
17689 if (val > 2)
17690 printf ("(%#x), ", val);
17691
17692 switch (val & 3)
17693 {
17694 case 0:
17695 printf (_("unspecified\n"));
17696 break;
17697 case 1:
17698 printf ("r3/r4\n");
17699 break;
17700 case 2:
17701 printf (_("memory\n"));
17702 break;
17703 case 3:
17704 printf ("???\n");
17705 break;
17706 }
f82e0623
NF
17707 return p;
17708 }
17709
f6f0e17b 17710 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17711}
17712
643f7afb
AK
17713static unsigned char *
17714display_s390_gnu_attribute (unsigned char * p,
60abdbed 17715 unsigned int tag,
643f7afb
AK
17716 const unsigned char * const end)
17717{
cd30bcef 17718 unsigned int val;
643f7afb
AK
17719
17720 if (tag == Tag_GNU_S390_ABI_Vector)
17721 {
643f7afb 17722 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17723 READ_ULEB (val, p, end);
643f7afb
AK
17724
17725 switch (val)
17726 {
17727 case 0:
17728 printf (_("any\n"));
17729 break;
17730 case 1:
17731 printf (_("software\n"));
17732 break;
17733 case 2:
17734 printf (_("hardware\n"));
17735 break;
17736 default:
17737 printf ("??? (%d)\n", val);
17738 break;
17739 }
17740 return p;
17741 }
17742
17743 return display_tag_value (tag & 1, p, end);
17744}
17745
9e8c70f9 17746static void
60abdbed 17747display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17748{
17749 if (mask)
17750 {
015dc7e1 17751 bool first = true;
071436c6 17752
9e8c70f9 17753 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17754 fputs ("mul32", stdout), first = false;
9e8c70f9 17755 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17756 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17757 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17758 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17759 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17760 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17761 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17762 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17763 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17764 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17765 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17766 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17767 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17768 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17769 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17770 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17771 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17772 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17773 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17774 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17775 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17776 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17777 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17778 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17779 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17780 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17781 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17782 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17783 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17784 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17785 }
17786 else
071436c6
NC
17787 fputc ('0', stdout);
17788 fputc ('\n', stdout);
9e8c70f9
DM
17789}
17790
3d68f91c 17791static void
60abdbed 17792display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17793{
17794 if (mask)
17795 {
015dc7e1 17796 bool first = true;
071436c6 17797
3d68f91c 17798 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17799 fputs ("fjathplus", stdout), first = false;
3d68f91c 17800 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17801 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17802 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17803 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17804 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17805 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17806 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17807 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17808 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17809 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17810 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17811 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17812 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17813 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17814 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17815 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17816 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17817 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17818 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17819 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17820 }
17821 else
071436c6
NC
17822 fputc ('0', stdout);
17823 fputc ('\n', stdout);
3d68f91c
JM
17824}
17825
9e8c70f9 17826static unsigned char *
f6f0e17b 17827display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17828 unsigned int tag,
f6f0e17b 17829 const unsigned char * const end)
9e8c70f9 17830{
cd30bcef 17831 unsigned int val;
3d68f91c 17832
9e8c70f9
DM
17833 if (tag == Tag_GNU_Sparc_HWCAPS)
17834 {
cd30bcef 17835 READ_ULEB (val, p, end);
9e8c70f9 17836 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17837 display_sparc_hwcaps (val);
17838 return p;
3d68f91c
JM
17839 }
17840 if (tag == Tag_GNU_Sparc_HWCAPS2)
17841 {
cd30bcef 17842 READ_ULEB (val, p, end);
3d68f91c
JM
17843 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17844 display_sparc_hwcaps2 (val);
17845 return p;
17846 }
9e8c70f9 17847
f6f0e17b 17848 return display_tag_value (tag, p, end);
9e8c70f9
DM
17849}
17850
351cdf24 17851static void
32ec8896 17852print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17853{
17854 switch (val)
17855 {
17856 case Val_GNU_MIPS_ABI_FP_ANY:
17857 printf (_("Hard or soft float\n"));
17858 break;
17859 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17860 printf (_("Hard float (double precision)\n"));
17861 break;
17862 case Val_GNU_MIPS_ABI_FP_SINGLE:
17863 printf (_("Hard float (single precision)\n"));
17864 break;
17865 case Val_GNU_MIPS_ABI_FP_SOFT:
17866 printf (_("Soft float\n"));
17867 break;
17868 case Val_GNU_MIPS_ABI_FP_OLD_64:
17869 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17870 break;
17871 case Val_GNU_MIPS_ABI_FP_XX:
17872 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17873 break;
17874 case Val_GNU_MIPS_ABI_FP_64:
17875 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17876 break;
17877 case Val_GNU_MIPS_ABI_FP_64A:
17878 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17879 break;
3350cc01
CM
17880 case Val_GNU_MIPS_ABI_FP_NAN2008:
17881 printf (_("NaN 2008 compatibility\n"));
17882 break;
351cdf24
MF
17883 default:
17884 printf ("??? (%d)\n", val);
17885 break;
17886 }
17887}
17888
2cf19d5c 17889static unsigned char *
f6f0e17b 17890display_mips_gnu_attribute (unsigned char * p,
60abdbed 17891 unsigned int tag,
f6f0e17b 17892 const unsigned char * const end)
2cf19d5c 17893{
2cf19d5c
JM
17894 if (tag == Tag_GNU_MIPS_ABI_FP)
17895 {
32ec8896 17896 unsigned int val;
f6f0e17b 17897
2cf19d5c 17898 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17899 READ_ULEB (val, p, end);
351cdf24 17900 print_mips_fp_abi_value (val);
2cf19d5c
JM
17901 return p;
17902 }
17903
a9f58168
CF
17904 if (tag == Tag_GNU_MIPS_ABI_MSA)
17905 {
32ec8896 17906 unsigned int val;
a9f58168 17907
a9f58168 17908 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17909 READ_ULEB (val, p, end);
a9f58168
CF
17910
17911 switch (val)
17912 {
17913 case Val_GNU_MIPS_ABI_MSA_ANY:
17914 printf (_("Any MSA or not\n"));
17915 break;
17916 case Val_GNU_MIPS_ABI_MSA_128:
17917 printf (_("128-bit MSA\n"));
17918 break;
17919 default:
17920 printf ("??? (%d)\n", val);
17921 break;
17922 }
17923 return p;
17924 }
17925
f6f0e17b 17926 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17927}
17928
59e6276b 17929static unsigned char *
f6f0e17b
NC
17930display_tic6x_attribute (unsigned char * p,
17931 const unsigned char * const end)
59e6276b 17932{
60abdbed 17933 unsigned int tag;
cd30bcef 17934 unsigned int val;
59e6276b 17935
cd30bcef 17936 READ_ULEB (tag, p, end);
59e6276b
JM
17937
17938 switch (tag)
17939 {
75fa6dc1 17940 case Tag_ISA:
75fa6dc1 17941 printf (" Tag_ISA: ");
cd30bcef 17942 READ_ULEB (val, p, end);
59e6276b
JM
17943
17944 switch (val)
17945 {
75fa6dc1 17946 case C6XABI_Tag_ISA_none:
59e6276b
JM
17947 printf (_("None\n"));
17948 break;
75fa6dc1 17949 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17950 printf ("C62x\n");
17951 break;
75fa6dc1 17952 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17953 printf ("C67x\n");
17954 break;
75fa6dc1 17955 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17956 printf ("C67x+\n");
17957 break;
75fa6dc1 17958 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17959 printf ("C64x\n");
17960 break;
75fa6dc1 17961 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17962 printf ("C64x+\n");
17963 break;
75fa6dc1 17964 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17965 printf ("C674x\n");
17966 break;
17967 default:
17968 printf ("??? (%d)\n", val);
17969 break;
17970 }
17971 return p;
17972
87779176 17973 case Tag_ABI_wchar_t:
87779176 17974 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17975 READ_ULEB (val, p, end);
87779176
JM
17976 switch (val)
17977 {
17978 case 0:
17979 printf (_("Not used\n"));
17980 break;
17981 case 1:
17982 printf (_("2 bytes\n"));
17983 break;
17984 case 2:
17985 printf (_("4 bytes\n"));
17986 break;
17987 default:
17988 printf ("??? (%d)\n", val);
17989 break;
17990 }
17991 return p;
17992
17993 case Tag_ABI_stack_align_needed:
87779176 17994 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17995 READ_ULEB (val, p, end);
87779176
JM
17996 switch (val)
17997 {
17998 case 0:
17999 printf (_("8-byte\n"));
18000 break;
18001 case 1:
18002 printf (_("16-byte\n"));
18003 break;
18004 default:
18005 printf ("??? (%d)\n", val);
18006 break;
18007 }
18008 return p;
18009
18010 case Tag_ABI_stack_align_preserved:
cd30bcef 18011 READ_ULEB (val, p, end);
87779176
JM
18012 printf (" Tag_ABI_stack_align_preserved: ");
18013 switch (val)
18014 {
18015 case 0:
18016 printf (_("8-byte\n"));
18017 break;
18018 case 1:
18019 printf (_("16-byte\n"));
18020 break;
18021 default:
18022 printf ("??? (%d)\n", val);
18023 break;
18024 }
18025 return p;
18026
b5593623 18027 case Tag_ABI_DSBT:
cd30bcef 18028 READ_ULEB (val, p, end);
b5593623
JM
18029 printf (" Tag_ABI_DSBT: ");
18030 switch (val)
18031 {
18032 case 0:
18033 printf (_("DSBT addressing not used\n"));
18034 break;
18035 case 1:
18036 printf (_("DSBT addressing used\n"));
18037 break;
18038 default:
18039 printf ("??? (%d)\n", val);
18040 break;
18041 }
18042 return p;
18043
87779176 18044 case Tag_ABI_PID:
cd30bcef 18045 READ_ULEB (val, p, end);
87779176
JM
18046 printf (" Tag_ABI_PID: ");
18047 switch (val)
18048 {
18049 case 0:
18050 printf (_("Data addressing position-dependent\n"));
18051 break;
18052 case 1:
18053 printf (_("Data addressing position-independent, GOT near DP\n"));
18054 break;
18055 case 2:
18056 printf (_("Data addressing position-independent, GOT far from DP\n"));
18057 break;
18058 default:
18059 printf ("??? (%d)\n", val);
18060 break;
18061 }
18062 return p;
18063
18064 case Tag_ABI_PIC:
cd30bcef 18065 READ_ULEB (val, p, end);
87779176
JM
18066 printf (" Tag_ABI_PIC: ");
18067 switch (val)
18068 {
18069 case 0:
18070 printf (_("Code addressing position-dependent\n"));
18071 break;
18072 case 1:
18073 printf (_("Code addressing position-independent\n"));
18074 break;
18075 default:
18076 printf ("??? (%d)\n", val);
18077 break;
18078 }
18079 return p;
18080
18081 case Tag_ABI_array_object_alignment:
cd30bcef 18082 READ_ULEB (val, p, end);
87779176
JM
18083 printf (" Tag_ABI_array_object_alignment: ");
18084 switch (val)
18085 {
18086 case 0:
18087 printf (_("8-byte\n"));
18088 break;
18089 case 1:
18090 printf (_("4-byte\n"));
18091 break;
18092 case 2:
18093 printf (_("16-byte\n"));
18094 break;
18095 default:
18096 printf ("??? (%d)\n", val);
18097 break;
18098 }
18099 return p;
18100
18101 case Tag_ABI_array_object_align_expected:
cd30bcef 18102 READ_ULEB (val, p, end);
87779176
JM
18103 printf (" Tag_ABI_array_object_align_expected: ");
18104 switch (val)
18105 {
18106 case 0:
18107 printf (_("8-byte\n"));
18108 break;
18109 case 1:
18110 printf (_("4-byte\n"));
18111 break;
18112 case 2:
18113 printf (_("16-byte\n"));
18114 break;
18115 default:
18116 printf ("??? (%d)\n", val);
18117 break;
18118 }
18119 return p;
18120
3cbd1c06 18121 case Tag_ABI_compatibility:
071436c6 18122 {
cd30bcef 18123 READ_ULEB (val, p, end);
071436c6 18124 printf (" Tag_ABI_compatibility: ");
071436c6 18125 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
18126 if (p < end - 1)
18127 {
18128 size_t maxlen = (end - p) - 1;
18129
18130 print_symbol ((int) maxlen, (const char *) p);
18131 p += strnlen ((char *) p, maxlen) + 1;
18132 }
18133 else
18134 {
18135 printf (_("<corrupt>"));
18136 p = (unsigned char *) end;
18137 }
071436c6 18138 putchar ('\n');
071436c6
NC
18139 return p;
18140 }
87779176
JM
18141
18142 case Tag_ABI_conformance:
071436c6 18143 {
4082ef84
NC
18144 printf (" Tag_ABI_conformance: \"");
18145 if (p < end - 1)
18146 {
18147 size_t maxlen = (end - p) - 1;
071436c6 18148
4082ef84
NC
18149 print_symbol ((int) maxlen, (const char *) p);
18150 p += strnlen ((char *) p, maxlen) + 1;
18151 }
18152 else
18153 {
18154 printf (_("<corrupt>"));
18155 p = (unsigned char *) end;
18156 }
071436c6 18157 printf ("\"\n");
071436c6
NC
18158 return p;
18159 }
59e6276b
JM
18160 }
18161
f6f0e17b
NC
18162 return display_tag_value (tag, p, end);
18163}
59e6276b 18164
f6f0e17b 18165static void
60abdbed 18166display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 18167{
26c527e6 18168 uint64_t addr = 0;
f6f0e17b
NC
18169 size_t bytes = end - p;
18170
feceaa59 18171 assert (end >= p);
f6f0e17b 18172 while (bytes)
87779176 18173 {
f6f0e17b
NC
18174 int j;
18175 int k;
18176 int lbytes = (bytes > 16 ? 16 : bytes);
18177
26c527e6 18178 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
18179
18180 for (j = 0; j < 16; j++)
18181 {
18182 if (j < lbytes)
18183 printf ("%2.2x", p[j]);
18184 else
18185 printf (" ");
18186
18187 if ((j & 3) == 3)
18188 printf (" ");
18189 }
18190
18191 for (j = 0; j < lbytes; j++)
18192 {
18193 k = p[j];
18194 if (k >= ' ' && k < 0x7f)
18195 printf ("%c", k);
18196 else
18197 printf (".");
18198 }
18199
18200 putchar ('\n');
18201
18202 p += lbytes;
18203 bytes -= lbytes;
18204 addr += lbytes;
87779176 18205 }
59e6276b 18206
f6f0e17b 18207 putchar ('\n');
59e6276b
JM
18208}
18209
13761a11 18210static unsigned char *
b0191216 18211display_msp430_attribute (unsigned char * p,
26c527e6 18212 const unsigned char * const end)
13761a11 18213{
26c527e6
AM
18214 uint64_t val;
18215 uint64_t tag;
13761a11 18216
cd30bcef 18217 READ_ULEB (tag, p, end);
0b4362b0 18218
13761a11
NC
18219 switch (tag)
18220 {
18221 case OFBA_MSPABI_Tag_ISA:
13761a11 18222 printf (" Tag_ISA: ");
cd30bcef 18223 READ_ULEB (val, p, end);
13761a11
NC
18224 switch (val)
18225 {
18226 case 0: printf (_("None\n")); break;
18227 case 1: printf (_("MSP430\n")); break;
18228 case 2: printf (_("MSP430X\n")); break;
26c527e6 18229 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18230 }
18231 break;
18232
18233 case OFBA_MSPABI_Tag_Code_Model:
13761a11 18234 printf (" Tag_Code_Model: ");
cd30bcef 18235 READ_ULEB (val, p, end);
13761a11
NC
18236 switch (val)
18237 {
18238 case 0: printf (_("None\n")); break;
18239 case 1: printf (_("Small\n")); break;
18240 case 2: printf (_("Large\n")); break;
26c527e6 18241 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18242 }
18243 break;
18244
18245 case OFBA_MSPABI_Tag_Data_Model:
13761a11 18246 printf (" Tag_Data_Model: ");
cd30bcef 18247 READ_ULEB (val, p, end);
13761a11
NC
18248 switch (val)
18249 {
18250 case 0: printf (_("None\n")); break;
18251 case 1: printf (_("Small\n")); break;
18252 case 2: printf (_("Large\n")); break;
18253 case 3: printf (_("Restricted Large\n")); break;
26c527e6 18254 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18255 }
18256 break;
18257
18258 default:
26c527e6 18259 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
18260
18261 if (tag & 1)
18262 {
071436c6 18263 putchar ('"');
4082ef84
NC
18264 if (p < end - 1)
18265 {
18266 size_t maxlen = (end - p) - 1;
18267
18268 print_symbol ((int) maxlen, (const char *) p);
18269 p += strnlen ((char *) p, maxlen) + 1;
18270 }
18271 else
18272 {
18273 printf (_("<corrupt>"));
18274 p = (unsigned char *) end;
18275 }
071436c6 18276 printf ("\"\n");
13761a11
NC
18277 }
18278 else
18279 {
cd30bcef 18280 READ_ULEB (val, p, end);
26c527e6 18281 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
18282 }
18283 break;
18284 }
18285
4082ef84 18286 assert (p <= end);
13761a11
NC
18287 return p;
18288}
18289
c0ea7c52
JL
18290static unsigned char *
18291display_msp430_gnu_attribute (unsigned char * p,
18292 unsigned int tag,
18293 const unsigned char * const end)
18294{
18295 if (tag == Tag_GNU_MSP430_Data_Region)
18296 {
26c527e6 18297 uint64_t val;
c0ea7c52 18298
c0ea7c52 18299 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 18300 READ_ULEB (val, p, end);
c0ea7c52
JL
18301
18302 switch (val)
18303 {
18304 case Val_GNU_MSP430_Data_Region_Any:
18305 printf (_("Any Region\n"));
18306 break;
18307 case Val_GNU_MSP430_Data_Region_Lower:
18308 printf (_("Lower Region Only\n"));
18309 break;
18310 default:
26c527e6 18311 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
18312 }
18313 return p;
18314 }
18315 return display_tag_value (tag & 1, p, end);
18316}
18317
2dc8dd17
JW
18318struct riscv_attr_tag_t {
18319 const char *name;
cd30bcef 18320 unsigned int tag;
2dc8dd17
JW
18321};
18322
18323static struct riscv_attr_tag_t riscv_attr_tag[] =
18324{
18325#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
18326 T(arch),
18327 T(priv_spec),
18328 T(priv_spec_minor),
18329 T(priv_spec_revision),
18330 T(unaligned_access),
18331 T(stack_align),
18332#undef T
18333};
18334
18335static unsigned char *
18336display_riscv_attribute (unsigned char *p,
18337 const unsigned char * const end)
18338{
26c527e6
AM
18339 uint64_t val;
18340 uint64_t tag;
2dc8dd17
JW
18341 struct riscv_attr_tag_t *attr = NULL;
18342 unsigned i;
18343
cd30bcef 18344 READ_ULEB (tag, p, end);
2dc8dd17
JW
18345
18346 /* Find the name of attribute. */
18347 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
18348 {
18349 if (riscv_attr_tag[i].tag == tag)
18350 {
18351 attr = &riscv_attr_tag[i];
18352 break;
18353 }
18354 }
18355
18356 if (attr)
18357 printf (" %s: ", attr->name);
18358 else
18359 return display_tag_value (tag, p, end);
18360
18361 switch (tag)
18362 {
18363 case Tag_RISCV_priv_spec:
18364 case Tag_RISCV_priv_spec_minor:
18365 case Tag_RISCV_priv_spec_revision:
cd30bcef 18366 READ_ULEB (val, p, end);
26c527e6 18367 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
18368 break;
18369 case Tag_RISCV_unaligned_access:
cd30bcef 18370 READ_ULEB (val, p, end);
2dc8dd17
JW
18371 switch (val)
18372 {
18373 case 0:
18374 printf (_("No unaligned access\n"));
18375 break;
18376 case 1:
18377 printf (_("Unaligned access\n"));
18378 break;
18379 }
18380 break;
18381 case Tag_RISCV_stack_align:
cd30bcef 18382 READ_ULEB (val, p, end);
26c527e6 18383 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
18384 break;
18385 case Tag_RISCV_arch:
18386 p = display_tag_value (-1, p, end);
18387 break;
18388 default:
18389 return display_tag_value (tag, p, end);
18390 }
18391
18392 return p;
18393}
18394
0861f561
CQ
18395static unsigned char *
18396display_csky_attribute (unsigned char * p,
18397 const unsigned char * const end)
18398{
26c527e6
AM
18399 uint64_t tag;
18400 uint64_t val;
0861f561
CQ
18401 READ_ULEB (tag, p, end);
18402
18403 if (tag >= Tag_CSKY_MAX)
18404 {
18405 return display_tag_value (-1, p, end);
18406 }
18407
18408 switch (tag)
18409 {
18410 case Tag_CSKY_ARCH_NAME:
18411 printf (" Tag_CSKY_ARCH_NAME:\t\t");
18412 return display_tag_value (-1, p, end);
18413 case Tag_CSKY_CPU_NAME:
18414 printf (" Tag_CSKY_CPU_NAME:\t\t");
18415 return display_tag_value (-1, p, end);
18416
18417 case Tag_CSKY_ISA_FLAGS:
18418 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
18419 return display_tag_value (0, p, end);
18420 case Tag_CSKY_ISA_EXT_FLAGS:
18421 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
18422 return display_tag_value (0, p, end);
18423
18424 case Tag_CSKY_DSP_VERSION:
18425 printf (" Tag_CSKY_DSP_VERSION:\t\t");
18426 READ_ULEB (val, p, end);
18427 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
18428 printf ("DSP Extension\n");
18429 else if (val == VAL_CSKY_DSP_VERSION_2)
18430 printf ("DSP 2.0\n");
18431 break;
18432
18433 case Tag_CSKY_VDSP_VERSION:
18434 printf (" Tag_CSKY_VDSP_VERSION:\t");
18435 READ_ULEB (val, p, end);
26c527e6 18436 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
18437 break;
18438
18439 case Tag_CSKY_FPU_VERSION:
18440 printf (" Tag_CSKY_FPU_VERSION:\t\t");
18441 READ_ULEB (val, p, end);
18442 if (val == VAL_CSKY_FPU_VERSION_1)
18443 printf ("ABIV1 FPU Version 1\n");
18444 else if (val == VAL_CSKY_FPU_VERSION_2)
18445 printf ("FPU Version 2\n");
18446 break;
18447
18448 case Tag_CSKY_FPU_ABI:
18449 printf (" Tag_CSKY_FPU_ABI:\t\t");
18450 READ_ULEB (val, p, end);
18451 if (val == VAL_CSKY_FPU_ABI_HARD)
18452 printf ("Hard\n");
18453 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18454 printf ("SoftFP\n");
18455 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18456 printf ("Soft\n");
18457 break;
18458 case Tag_CSKY_FPU_ROUNDING:
18459 READ_ULEB (val, p, end);
f253158f
NC
18460 if (val == 1)
18461 {
18462 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18463 printf ("Needed\n");
18464 }
0861f561
CQ
18465 break;
18466 case Tag_CSKY_FPU_DENORMAL:
18467 READ_ULEB (val, p, end);
f253158f
NC
18468 if (val == 1)
18469 {
18470 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18471 printf ("Needed\n");
18472 }
0861f561
CQ
18473 break;
18474 case Tag_CSKY_FPU_Exception:
18475 READ_ULEB (val, p, end);
f253158f
NC
18476 if (val == 1)
18477 {
18478 printf (" Tag_CSKY_FPU_Exception:\t");
18479 printf ("Needed\n");
18480 }
0861f561
CQ
18481 break;
18482 case Tag_CSKY_FPU_NUMBER_MODULE:
18483 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18484 return display_tag_value (-1, p, end);
18485 case Tag_CSKY_FPU_HARDFP:
18486 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18487 READ_ULEB (val, p, end);
18488 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18489 printf (" Half");
18490 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18491 printf (" Single");
18492 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18493 printf (" Double");
18494 printf ("\n");
18495 break;
18496 default:
18497 return display_tag_value (tag, p, end);
18498 }
18499 return p;
18500}
18501
015dc7e1 18502static bool
dda8d76d 18503process_attributes (Filedata * filedata,
60bca95a 18504 const char * public_name,
104d59d1 18505 unsigned int proc_type,
f6f0e17b 18506 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 18507 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 18508{
2cf0635d 18509 Elf_Internal_Shdr * sect;
11c1ff18 18510 unsigned i;
015dc7e1 18511 bool res = true;
11c1ff18
PB
18512
18513 /* Find the section header so that we get the size. */
dda8d76d
NC
18514 for (i = 0, sect = filedata->section_headers;
18515 i < filedata->file_header.e_shnum;
11c1ff18
PB
18516 i++, sect++)
18517 {
071436c6
NC
18518 unsigned char * contents;
18519 unsigned char * p;
18520
104d59d1 18521 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
18522 continue;
18523
dda8d76d 18524 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 18525 sect->sh_size, _("attributes"));
60bca95a 18526 if (contents == NULL)
32ec8896 18527 {
015dc7e1 18528 res = false;
32ec8896
NC
18529 continue;
18530 }
60bca95a 18531
11c1ff18 18532 p = contents;
60abdbed
NC
18533 /* The first character is the version of the attributes.
18534 Currently only version 1, (aka 'A') is recognised here. */
18535 if (*p != 'A')
32ec8896
NC
18536 {
18537 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 18538 res = false;
32ec8896 18539 }
60abdbed 18540 else
11c1ff18 18541 {
625d49fc 18542 uint64_t section_len;
071436c6
NC
18543
18544 section_len = sect->sh_size - 1;
11c1ff18 18545 p++;
60bca95a 18546
071436c6 18547 while (section_len > 0)
11c1ff18 18548 {
625d49fc 18549 uint64_t attr_len;
e9847026 18550 unsigned int namelen;
015dc7e1
AM
18551 bool public_section;
18552 bool gnu_section;
11c1ff18 18553
071436c6 18554 if (section_len <= 4)
e0a31db1
NC
18555 {
18556 error (_("Tag section ends prematurely\n"));
015dc7e1 18557 res = false;
e0a31db1
NC
18558 break;
18559 }
071436c6 18560 attr_len = byte_get (p, 4);
11c1ff18 18561 p += 4;
60bca95a 18562
071436c6 18563 if (attr_len > section_len)
11c1ff18 18564 {
071436c6
NC
18565 error (_("Bad attribute length (%u > %u)\n"),
18566 (unsigned) attr_len, (unsigned) section_len);
18567 attr_len = section_len;
015dc7e1 18568 res = false;
11c1ff18 18569 }
74e1a04b 18570 /* PR 17531: file: 001-101425-0.004 */
071436c6 18571 else if (attr_len < 5)
74e1a04b 18572 {
071436c6 18573 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 18574 res = false;
74e1a04b
NC
18575 break;
18576 }
e9847026 18577
071436c6
NC
18578 section_len -= attr_len;
18579 attr_len -= 4;
18580
18581 namelen = strnlen ((char *) p, attr_len) + 1;
18582 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
18583 {
18584 error (_("Corrupt attribute section name\n"));
015dc7e1 18585 res = false;
e9847026
NC
18586 break;
18587 }
18588
071436c6
NC
18589 printf (_("Attribute Section: "));
18590 print_symbol (INT_MAX, (const char *) p);
18591 putchar ('\n');
60bca95a
NC
18592
18593 if (public_name && streq ((char *) p, public_name))
015dc7e1 18594 public_section = true;
11c1ff18 18595 else
015dc7e1 18596 public_section = false;
60bca95a
NC
18597
18598 if (streq ((char *) p, "gnu"))
015dc7e1 18599 gnu_section = true;
104d59d1 18600 else
015dc7e1 18601 gnu_section = false;
60bca95a 18602
11c1ff18 18603 p += namelen;
071436c6 18604 attr_len -= namelen;
e0a31db1 18605
071436c6 18606 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18607 {
e0a31db1 18608 int tag;
cd30bcef 18609 unsigned int val;
625d49fc 18610 uint64_t size;
071436c6 18611 unsigned char * end;
60bca95a 18612
e0a31db1 18613 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18614 if (attr_len < 6)
e0a31db1
NC
18615 {
18616 error (_("Unused bytes at end of section\n"));
015dc7e1 18617 res = false;
e0a31db1
NC
18618 section_len = 0;
18619 break;
18620 }
18621
18622 tag = *(p++);
11c1ff18 18623 size = byte_get (p, 4);
071436c6 18624 if (size > attr_len)
11c1ff18 18625 {
e9847026 18626 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18627 (unsigned) size, (unsigned) attr_len);
015dc7e1 18628 res = false;
071436c6 18629 size = attr_len;
11c1ff18 18630 }
e0a31db1
NC
18631 /* PR binutils/17531: Safe handling of corrupt files. */
18632 if (size < 6)
18633 {
18634 error (_("Bad subsection length (%u < 6)\n"),
18635 (unsigned) size);
015dc7e1 18636 res = false;
e0a31db1
NC
18637 section_len = 0;
18638 break;
18639 }
60bca95a 18640
071436c6 18641 attr_len -= size;
11c1ff18 18642 end = p + size - 1;
071436c6 18643 assert (end <= contents + sect->sh_size);
11c1ff18 18644 p += 4;
60bca95a 18645
11c1ff18
PB
18646 switch (tag)
18647 {
18648 case 1:
2b692964 18649 printf (_("File Attributes\n"));
11c1ff18
PB
18650 break;
18651 case 2:
2b692964 18652 printf (_("Section Attributes:"));
11c1ff18
PB
18653 goto do_numlist;
18654 case 3:
2b692964 18655 printf (_("Symbol Attributes:"));
1a0670f3 18656 /* Fall through. */
11c1ff18
PB
18657 do_numlist:
18658 for (;;)
18659 {
cd30bcef 18660 READ_ULEB (val, p, end);
11c1ff18
PB
18661 if (val == 0)
18662 break;
18663 printf (" %d", val);
18664 }
18665 printf ("\n");
18666 break;
18667 default:
2b692964 18668 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18669 public_section = false;
11c1ff18
PB
18670 break;
18671 }
60bca95a 18672
071436c6 18673 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18674 {
18675 while (p < end)
f6f0e17b 18676 p = display_pub_attribute (p, end);
60abdbed 18677 assert (p == end);
104d59d1 18678 }
071436c6 18679 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18680 {
18681 while (p < end)
18682 p = display_gnu_attribute (p,
f6f0e17b
NC
18683 display_proc_gnu_attribute,
18684 end);
60abdbed 18685 assert (p == end);
11c1ff18 18686 }
071436c6 18687 else if (p < end)
11c1ff18 18688 {
071436c6 18689 printf (_(" Unknown attribute:\n"));
f6f0e17b 18690 display_raw_attribute (p, end);
11c1ff18
PB
18691 p = end;
18692 }
071436c6
NC
18693 else
18694 attr_len = 0;
11c1ff18
PB
18695 }
18696 }
18697 }
d70c5fc7 18698
60bca95a 18699 free (contents);
11c1ff18 18700 }
32ec8896
NC
18701
18702 return res;
11c1ff18
PB
18703}
18704
ccb4c951
RS
18705/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18706 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18707 and return the VMA of the next entry, or -1 if there was a problem.
18708 Does not read from DATA_END or beyond. */
ccb4c951 18709
625d49fc
AM
18710static uint64_t
18711print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18712 unsigned char * data_end)
ccb4c951
RS
18713{
18714 printf (" ");
18715 print_vma (addr, LONG_HEX);
18716 printf (" ");
18717 if (addr < pltgot + 0xfff0)
18718 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18719 else
18720 printf ("%10s", "");
18721 printf (" ");
18722 if (data == NULL)
2b692964 18723 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18724 else
18725 {
625d49fc 18726 uint64_t entry;
82b1b41b 18727 unsigned char * from = data + addr - pltgot;
ccb4c951 18728
82b1b41b
NC
18729 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18730 {
18731 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18732 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18733 return (uint64_t) -1;
82b1b41b
NC
18734 }
18735 else
18736 {
18737 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18738 print_vma (entry, LONG_HEX);
18739 }
ccb4c951
RS
18740 }
18741 return addr + (is_32bit_elf ? 4 : 8);
18742}
18743
861fb55a
DJ
18744/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18745 PLTGOT. Print the Address and Initial fields of an entry at VMA
18746 ADDR and return the VMA of the next entry. */
18747
625d49fc
AM
18748static uint64_t
18749print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18750{
18751 printf (" ");
18752 print_vma (addr, LONG_HEX);
18753 printf (" ");
18754 if (data == NULL)
2b692964 18755 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18756 else
18757 {
625d49fc 18758 uint64_t entry;
861fb55a
DJ
18759
18760 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18761 print_vma (entry, LONG_HEX);
18762 }
18763 return addr + (is_32bit_elf ? 4 : 8);
18764}
18765
351cdf24
MF
18766static void
18767print_mips_ases (unsigned int mask)
18768{
18769 if (mask & AFL_ASE_DSP)
18770 fputs ("\n\tDSP ASE", stdout);
18771 if (mask & AFL_ASE_DSPR2)
18772 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18773 if (mask & AFL_ASE_DSPR3)
18774 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18775 if (mask & AFL_ASE_EVA)
18776 fputs ("\n\tEnhanced VA Scheme", stdout);
18777 if (mask & AFL_ASE_MCU)
18778 fputs ("\n\tMCU (MicroController) ASE", stdout);
18779 if (mask & AFL_ASE_MDMX)
18780 fputs ("\n\tMDMX ASE", stdout);
18781 if (mask & AFL_ASE_MIPS3D)
18782 fputs ("\n\tMIPS-3D ASE", stdout);
18783 if (mask & AFL_ASE_MT)
18784 fputs ("\n\tMT ASE", stdout);
18785 if (mask & AFL_ASE_SMARTMIPS)
18786 fputs ("\n\tSmartMIPS ASE", stdout);
18787 if (mask & AFL_ASE_VIRT)
18788 fputs ("\n\tVZ ASE", stdout);
18789 if (mask & AFL_ASE_MSA)
18790 fputs ("\n\tMSA ASE", stdout);
18791 if (mask & AFL_ASE_MIPS16)
18792 fputs ("\n\tMIPS16 ASE", stdout);
18793 if (mask & AFL_ASE_MICROMIPS)
18794 fputs ("\n\tMICROMIPS ASE", stdout);
18795 if (mask & AFL_ASE_XPA)
18796 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18797 if (mask & AFL_ASE_MIPS16E2)
18798 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18799 if (mask & AFL_ASE_CRC)
18800 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18801 if (mask & AFL_ASE_GINV)
18802 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18803 if (mask & AFL_ASE_LOONGSON_MMI)
18804 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18805 if (mask & AFL_ASE_LOONGSON_CAM)
18806 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18807 if (mask & AFL_ASE_LOONGSON_EXT)
18808 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18809 if (mask & AFL_ASE_LOONGSON_EXT2)
18810 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18811 if (mask == 0)
18812 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18813 else if ((mask & ~AFL_ASE_MASK) != 0)
18814 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18815}
18816
18817static void
18818print_mips_isa_ext (unsigned int isa_ext)
18819{
18820 switch (isa_ext)
18821 {
18822 case 0:
18823 fputs (_("None"), stdout);
18824 break;
18825 case AFL_EXT_XLR:
18826 fputs ("RMI XLR", stdout);
18827 break;
2c629856
N
18828 case AFL_EXT_OCTEON3:
18829 fputs ("Cavium Networks Octeon3", stdout);
18830 break;
351cdf24
MF
18831 case AFL_EXT_OCTEON2:
18832 fputs ("Cavium Networks Octeon2", stdout);
18833 break;
18834 case AFL_EXT_OCTEONP:
18835 fputs ("Cavium Networks OcteonP", stdout);
18836 break;
351cdf24
MF
18837 case AFL_EXT_OCTEON:
18838 fputs ("Cavium Networks Octeon", stdout);
18839 break;
18840 case AFL_EXT_5900:
18841 fputs ("Toshiba R5900", stdout);
18842 break;
18843 case AFL_EXT_4650:
18844 fputs ("MIPS R4650", stdout);
18845 break;
18846 case AFL_EXT_4010:
18847 fputs ("LSI R4010", stdout);
18848 break;
18849 case AFL_EXT_4100:
18850 fputs ("NEC VR4100", stdout);
18851 break;
18852 case AFL_EXT_3900:
18853 fputs ("Toshiba R3900", stdout);
18854 break;
18855 case AFL_EXT_10000:
18856 fputs ("MIPS R10000", stdout);
18857 break;
18858 case AFL_EXT_SB1:
18859 fputs ("Broadcom SB-1", stdout);
18860 break;
18861 case AFL_EXT_4111:
18862 fputs ("NEC VR4111/VR4181", stdout);
18863 break;
18864 case AFL_EXT_4120:
18865 fputs ("NEC VR4120", stdout);
18866 break;
18867 case AFL_EXT_5400:
18868 fputs ("NEC VR5400", stdout);
18869 break;
18870 case AFL_EXT_5500:
18871 fputs ("NEC VR5500", stdout);
18872 break;
18873 case AFL_EXT_LOONGSON_2E:
18874 fputs ("ST Microelectronics Loongson 2E", stdout);
18875 break;
18876 case AFL_EXT_LOONGSON_2F:
18877 fputs ("ST Microelectronics Loongson 2F", stdout);
18878 break;
38bf472a
MR
18879 case AFL_EXT_INTERAPTIV_MR2:
18880 fputs ("Imagination interAptiv MR2", stdout);
18881 break;
351cdf24 18882 default:
00ac7aa0 18883 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18884 }
18885}
18886
32ec8896 18887static signed int
351cdf24
MF
18888get_mips_reg_size (int reg_size)
18889{
18890 return (reg_size == AFL_REG_NONE) ? 0
18891 : (reg_size == AFL_REG_32) ? 32
18892 : (reg_size == AFL_REG_64) ? 64
18893 : (reg_size == AFL_REG_128) ? 128
18894 : -1;
18895}
18896
015dc7e1 18897static bool
dda8d76d 18898process_mips_specific (Filedata * filedata)
5b18a4bc 18899{
2cf0635d 18900 Elf_Internal_Dyn * entry;
351cdf24 18901 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18902 size_t liblist_offset = 0;
18903 size_t liblistno = 0;
18904 size_t conflictsno = 0;
18905 size_t options_offset = 0;
18906 size_t conflicts_offset = 0;
861fb55a
DJ
18907 size_t pltrelsz = 0;
18908 size_t pltrel = 0;
625d49fc
AM
18909 uint64_t pltgot = 0;
18910 uint64_t mips_pltgot = 0;
18911 uint64_t jmprel = 0;
18912 uint64_t local_gotno = 0;
18913 uint64_t gotsym = 0;
18914 uint64_t symtabno = 0;
015dc7e1 18915 bool res = true;
103f02d3 18916
dda8d76d 18917 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18918 display_mips_gnu_attribute))
015dc7e1 18919 res = false;
2cf19d5c 18920
dda8d76d 18921 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18922
18923 if (sect != NULL)
18924 {
18925 Elf_External_ABIFlags_v0 *abiflags_ext;
18926 Elf_Internal_ABIFlags_v0 abiflags_in;
18927
18928 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18929 {
18930 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18931 res = false;
32ec8896 18932 }
351cdf24
MF
18933 else
18934 {
dda8d76d 18935 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18936 sect->sh_size, _("MIPS ABI Flags section"));
18937 if (abiflags_ext)
18938 {
18939 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18940 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18941 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18942 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18943 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18944 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18945 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18946 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18947 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18948 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18949 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18950
18951 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18952 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18953 if (abiflags_in.isa_rev > 1)
18954 printf ("r%d", abiflags_in.isa_rev);
18955 printf ("\nGPR size: %d",
18956 get_mips_reg_size (abiflags_in.gpr_size));
18957 printf ("\nCPR1 size: %d",
18958 get_mips_reg_size (abiflags_in.cpr1_size));
18959 printf ("\nCPR2 size: %d",
18960 get_mips_reg_size (abiflags_in.cpr2_size));
18961 fputs ("\nFP ABI: ", stdout);
18962 print_mips_fp_abi_value (abiflags_in.fp_abi);
18963 fputs ("ISA Extension: ", stdout);
18964 print_mips_isa_ext (abiflags_in.isa_ext);
18965 fputs ("\nASEs:", stdout);
18966 print_mips_ases (abiflags_in.ases);
18967 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18968 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18969 fputc ('\n', stdout);
18970 free (abiflags_ext);
18971 }
18972 }
18973 }
18974
19e6b90e 18975 /* We have a lot of special sections. Thanks SGI! */
978c4450 18976 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18977 {
18978 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18979 sect = find_section (filedata, ".got");
bbdd9a68
MR
18980 if (sect != NULL)
18981 {
18982 unsigned char *data_end;
18983 unsigned char *data;
625d49fc 18984 uint64_t ent, end;
bbdd9a68
MR
18985 int addr_size;
18986
18987 pltgot = sect->sh_addr;
18988
18989 ent = pltgot;
18990 addr_size = (is_32bit_elf ? 4 : 8);
18991 end = pltgot + sect->sh_size;
18992
dda8d76d 18993 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18994 end - pltgot, 1,
18995 _("Global Offset Table data"));
18996 /* PR 12855: Null data is handled gracefully throughout. */
18997 data_end = data + (end - pltgot);
18998
18999 printf (_("\nStatic GOT:\n"));
19000 printf (_(" Canonical gp value: "));
19001 print_vma (ent + 0x7ff0, LONG_HEX);
19002 printf ("\n\n");
19003
19004 /* In a dynamic binary GOT[0] is reserved for the dynamic
19005 loader to store the lazy resolver pointer, however in
19006 a static binary it may well have been omitted and GOT
19007 reduced to a table of addresses.
19008 PR 21344: Check for the entry being fully available
19009 before fetching it. */
19010 if (data
19011 && data + ent - pltgot + addr_size <= data_end
19012 && byte_get (data + ent - pltgot, addr_size) == 0)
19013 {
19014 printf (_(" Reserved entries:\n"));
19015 printf (_(" %*s %10s %*s\n"),
19016 addr_size * 2, _("Address"), _("Access"),
19017 addr_size * 2, _("Value"));
19018 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19019 printf ("\n");
625d49fc 19020 if (ent == (uint64_t) -1)
bbdd9a68
MR
19021 goto sgot_print_fail;
19022
19023 /* Check for the MSB of GOT[1] being set, identifying a
19024 GNU object. This entry will be used by some runtime
19025 loaders, to store the module pointer. Otherwise this
19026 is an ordinary local entry.
19027 PR 21344: Check for the entry being fully available
19028 before fetching it. */
19029 if (data
19030 && data + ent - pltgot + addr_size <= data_end
19031 && (byte_get (data + ent - pltgot, addr_size)
19032 >> (addr_size * 8 - 1)) != 0)
19033 {
19034 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19035 printf ("\n");
625d49fc 19036 if (ent == (uint64_t) -1)
bbdd9a68
MR
19037 goto sgot_print_fail;
19038 }
19039 printf ("\n");
19040 }
19041
f17e9d8a 19042 if (data != NULL && ent < end)
bbdd9a68
MR
19043 {
19044 printf (_(" Local entries:\n"));
19045 printf (" %*s %10s %*s\n",
19046 addr_size * 2, _("Address"), _("Access"),
19047 addr_size * 2, _("Value"));
19048 while (ent < end)
19049 {
19050 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19051 printf ("\n");
625d49fc 19052 if (ent == (uint64_t) -1)
bbdd9a68
MR
19053 goto sgot_print_fail;
19054 }
19055 printf ("\n");
19056 }
19057
19058 sgot_print_fail:
9db70fc3 19059 free (data);
bbdd9a68
MR
19060 }
19061 return res;
19062 }
252b5132 19063
978c4450 19064 for (entry = filedata->dynamic_section;
071436c6 19065 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
19066 (entry < filedata->dynamic_section + filedata->dynamic_nent
19067 && entry->d_tag != DT_NULL);
071436c6 19068 ++entry)
252b5132
RH
19069 switch (entry->d_tag)
19070 {
19071 case DT_MIPS_LIBLIST:
d93f0186 19072 liblist_offset
dda8d76d 19073 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19074 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
19075 break;
19076 case DT_MIPS_LIBLISTNO:
19077 liblistno = entry->d_un.d_val;
19078 break;
19079 case DT_MIPS_OPTIONS:
dda8d76d 19080 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
19081 break;
19082 case DT_MIPS_CONFLICT:
d93f0186 19083 conflicts_offset
dda8d76d 19084 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19085 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
19086 break;
19087 case DT_MIPS_CONFLICTNO:
19088 conflictsno = entry->d_un.d_val;
19089 break;
ccb4c951 19090 case DT_PLTGOT:
861fb55a
DJ
19091 pltgot = entry->d_un.d_ptr;
19092 break;
ccb4c951
RS
19093 case DT_MIPS_LOCAL_GOTNO:
19094 local_gotno = entry->d_un.d_val;
19095 break;
19096 case DT_MIPS_GOTSYM:
19097 gotsym = entry->d_un.d_val;
19098 break;
19099 case DT_MIPS_SYMTABNO:
19100 symtabno = entry->d_un.d_val;
19101 break;
861fb55a
DJ
19102 case DT_MIPS_PLTGOT:
19103 mips_pltgot = entry->d_un.d_ptr;
19104 break;
19105 case DT_PLTREL:
19106 pltrel = entry->d_un.d_val;
19107 break;
19108 case DT_PLTRELSZ:
19109 pltrelsz = entry->d_un.d_val;
19110 break;
19111 case DT_JMPREL:
19112 jmprel = entry->d_un.d_ptr;
19113 break;
252b5132
RH
19114 default:
19115 break;
19116 }
19117
19118 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
19119 {
2cf0635d 19120 Elf32_External_Lib * elib;
252b5132
RH
19121 size_t cnt;
19122
dda8d76d 19123 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
19124 sizeof (Elf32_External_Lib),
19125 liblistno,
19126 _("liblist section data"));
a6e9f9df 19127 if (elib)
252b5132 19128 {
26c527e6
AM
19129 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
19130 "\nSection '.liblist' contains %zu entries:\n",
19131 liblistno),
19132 liblistno);
2b692964 19133 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
19134 stdout);
19135
19136 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 19137 {
a6e9f9df 19138 Elf32_Lib liblist;
91d6fa6a 19139 time_t atime;
d5b07ef4 19140 char timebuf[128];
2cf0635d 19141 struct tm * tmp;
a6e9f9df
AM
19142
19143 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19144 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
19145 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19146 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19147 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19148
91d6fa6a 19149 tmp = gmtime (&atime);
e9e44622
JJ
19150 snprintf (timebuf, sizeof (timebuf),
19151 "%04u-%02u-%02uT%02u:%02u:%02u",
19152 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19153 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 19154
26c527e6 19155 printf ("%3zu: ", cnt);
84714f86
AM
19156 if (valid_dynamic_name (filedata, liblist.l_name))
19157 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 19158 else
2b692964 19159 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
19160 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
19161 liblist.l_version);
a6e9f9df
AM
19162
19163 if (liblist.l_flags == 0)
2b692964 19164 puts (_(" NONE"));
a6e9f9df
AM
19165 else
19166 {
19167 static const struct
252b5132 19168 {
2cf0635d 19169 const char * name;
a6e9f9df 19170 int bit;
252b5132 19171 }
a6e9f9df
AM
19172 l_flags_vals[] =
19173 {
19174 { " EXACT_MATCH", LL_EXACT_MATCH },
19175 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
19176 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
19177 { " EXPORTS", LL_EXPORTS },
19178 { " DELAY_LOAD", LL_DELAY_LOAD },
19179 { " DELTA", LL_DELTA }
19180 };
19181 int flags = liblist.l_flags;
19182 size_t fcnt;
19183
60bca95a 19184 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
19185 if ((flags & l_flags_vals[fcnt].bit) != 0)
19186 {
19187 fputs (l_flags_vals[fcnt].name, stdout);
19188 flags ^= l_flags_vals[fcnt].bit;
19189 }
19190 if (flags != 0)
19191 printf (" %#x", (unsigned int) flags);
252b5132 19192
a6e9f9df
AM
19193 puts ("");
19194 }
252b5132 19195 }
252b5132 19196
a6e9f9df
AM
19197 free (elib);
19198 }
32ec8896 19199 else
015dc7e1 19200 res = false;
252b5132
RH
19201 }
19202
19203 if (options_offset != 0)
19204 {
2cf0635d 19205 Elf_External_Options * eopt;
252b5132
RH
19206 size_t offset;
19207 int cnt;
19208
19209 /* Find the section header so that we get the size. */
dda8d76d 19210 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 19211 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
19212 if (sect == NULL)
19213 {
19214 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 19215 return false;
071436c6 19216 }
7fc0c668
NC
19217 /* PR 24243 */
19218 if (sect->sh_size < sizeof (* eopt))
19219 {
19220 error (_("The MIPS options section is too small.\n"));
015dc7e1 19221 return false;
7fc0c668 19222 }
252b5132 19223
dda8d76d 19224 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 19225 sect->sh_size, _("options"));
a6e9f9df 19226 if (eopt)
252b5132 19227 {
fd17d1e6 19228 Elf_Internal_Options option;
76da6bbe 19229
a6e9f9df 19230 offset = cnt = 0;
82b1b41b 19231 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 19232 {
2cf0635d 19233 Elf_External_Options * eoption;
fd17d1e6 19234 unsigned int optsize;
252b5132 19235
a6e9f9df 19236 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 19237
fd17d1e6 19238 optsize = BYTE_GET (eoption->size);
76da6bbe 19239
82b1b41b 19240 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
19241 if (optsize < sizeof (* eopt)
19242 || optsize > sect->sh_size - offset)
82b1b41b 19243 {
645f43a8 19244 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 19245 optsize);
645f43a8 19246 free (eopt);
015dc7e1 19247 return false;
82b1b41b 19248 }
fd17d1e6 19249 offset += optsize;
a6e9f9df
AM
19250 ++cnt;
19251 }
252b5132 19252
d3a49aa8
AM
19253 printf (ngettext ("\nSection '%s' contains %d entry:\n",
19254 "\nSection '%s' contains %d entries:\n",
19255 cnt),
dda8d76d 19256 printable_section_name (filedata, sect), cnt);
76da6bbe 19257
82b1b41b 19258 offset = 0;
a6e9f9df 19259 while (cnt-- > 0)
252b5132 19260 {
a6e9f9df 19261 size_t len;
fd17d1e6
AM
19262 Elf_External_Options * eoption;
19263
19264 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19265
19266 option.kind = BYTE_GET (eoption->kind);
19267 option.size = BYTE_GET (eoption->size);
19268 option.section = BYTE_GET (eoption->section);
19269 option.info = BYTE_GET (eoption->info);
a6e9f9df 19270
fd17d1e6 19271 switch (option.kind)
252b5132 19272 {
a6e9f9df
AM
19273 case ODK_NULL:
19274 /* This shouldn't happen. */
d0c4e780 19275 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 19276 option.section, option.info);
a6e9f9df 19277 break;
2e6be59c 19278
a6e9f9df
AM
19279 case ODK_REGINFO:
19280 printf (" REGINFO ");
dda8d76d 19281 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 19282 {
2cf0635d 19283 Elf32_External_RegInfo * ereg;
b34976b6 19284 Elf32_RegInfo reginfo;
a6e9f9df 19285
2e6be59c 19286 /* 32bit form. */
fd17d1e6
AM
19287 if (option.size < (sizeof (Elf_External_Options)
19288 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
19289 {
19290 printf (_("<corrupt>\n"));
19291 error (_("Truncated MIPS REGINFO option\n"));
19292 cnt = 0;
19293 break;
19294 }
19295
fd17d1e6 19296 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 19297
a6e9f9df
AM
19298 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19299 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19300 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19301 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19302 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
19303 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
19304
d0c4e780
AM
19305 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
19306 reginfo.ri_gprmask, reginfo.ri_gp_value);
19307 printf (" "
19308 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19309 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19310 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19311 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19312 }
19313 else
19314 {
19315 /* 64 bit form. */
2cf0635d 19316 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
19317 Elf64_Internal_RegInfo reginfo;
19318
fd17d1e6
AM
19319 if (option.size < (sizeof (Elf_External_Options)
19320 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
19321 {
19322 printf (_("<corrupt>\n"));
19323 error (_("Truncated MIPS REGINFO option\n"));
19324 cnt = 0;
19325 break;
19326 }
19327
fd17d1e6 19328 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
19329 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19330 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19331 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19332 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19333 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 19334 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 19335
d0c4e780
AM
19336 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
19337 reginfo.ri_gprmask, reginfo.ri_gp_value);
19338 printf (" "
19339 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19340 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19341 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19342 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19343 }
fd17d1e6 19344 offset += option.size;
a6e9f9df 19345 continue;
2e6be59c 19346
a6e9f9df
AM
19347 case ODK_EXCEPTIONS:
19348 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 19349 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 19350 fputs (") fpe_max(", stdout);
fd17d1e6 19351 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
19352 fputs (")", stdout);
19353
fd17d1e6 19354 if (option.info & OEX_PAGE0)
a6e9f9df 19355 fputs (" PAGE0", stdout);
fd17d1e6 19356 if (option.info & OEX_SMM)
a6e9f9df 19357 fputs (" SMM", stdout);
fd17d1e6 19358 if (option.info & OEX_FPDBUG)
a6e9f9df 19359 fputs (" FPDBUG", stdout);
fd17d1e6 19360 if (option.info & OEX_DISMISS)
a6e9f9df
AM
19361 fputs (" DISMISS", stdout);
19362 break;
2e6be59c 19363
a6e9f9df
AM
19364 case ODK_PAD:
19365 fputs (" PAD ", stdout);
fd17d1e6 19366 if (option.info & OPAD_PREFIX)
a6e9f9df 19367 fputs (" PREFIX", stdout);
fd17d1e6 19368 if (option.info & OPAD_POSTFIX)
a6e9f9df 19369 fputs (" POSTFIX", stdout);
fd17d1e6 19370 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
19371 fputs (" SYMBOL", stdout);
19372 break;
2e6be59c 19373
a6e9f9df
AM
19374 case ODK_HWPATCH:
19375 fputs (" HWPATCH ", stdout);
fd17d1e6 19376 if (option.info & OHW_R4KEOP)
a6e9f9df 19377 fputs (" R4KEOP", stdout);
fd17d1e6 19378 if (option.info & OHW_R8KPFETCH)
a6e9f9df 19379 fputs (" R8KPFETCH", stdout);
fd17d1e6 19380 if (option.info & OHW_R5KEOP)
a6e9f9df 19381 fputs (" R5KEOP", stdout);
fd17d1e6 19382 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
19383 fputs (" R5KCVTL", stdout);
19384 break;
2e6be59c 19385
a6e9f9df
AM
19386 case ODK_FILL:
19387 fputs (" FILL ", stdout);
19388 /* XXX Print content of info word? */
19389 break;
2e6be59c 19390
a6e9f9df
AM
19391 case ODK_TAGS:
19392 fputs (" TAGS ", stdout);
19393 /* XXX Print content of info word? */
19394 break;
2e6be59c 19395
a6e9f9df
AM
19396 case ODK_HWAND:
19397 fputs (" HWAND ", stdout);
fd17d1e6 19398 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19399 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19400 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19401 fputs (" R4KEOP_CLEAN", stdout);
19402 break;
2e6be59c 19403
a6e9f9df
AM
19404 case ODK_HWOR:
19405 fputs (" HWOR ", stdout);
fd17d1e6 19406 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19407 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19408 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19409 fputs (" R4KEOP_CLEAN", stdout);
19410 break;
2e6be59c 19411
a6e9f9df 19412 case ODK_GP_GROUP:
d0c4e780 19413 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
19414 option.info & OGP_GROUP,
19415 (option.info & OGP_SELF) >> 16);
a6e9f9df 19416 break;
2e6be59c 19417
a6e9f9df 19418 case ODK_IDENT:
d0c4e780 19419 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
19420 option.info & OGP_GROUP,
19421 (option.info & OGP_SELF) >> 16);
a6e9f9df 19422 break;
2e6be59c 19423
a6e9f9df
AM
19424 default:
19425 /* This shouldn't happen. */
d0c4e780 19426 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 19427 option.kind, option.section, option.info);
a6e9f9df 19428 break;
252b5132 19429 }
a6e9f9df 19430
2cf0635d 19431 len = sizeof (* eopt);
fd17d1e6 19432 while (len < option.size)
82b1b41b 19433 {
fd17d1e6 19434 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 19435
82b1b41b
NC
19436 if (ISPRINT (datum))
19437 printf ("%c", datum);
19438 else
19439 printf ("\\%03o", datum);
19440 len ++;
19441 }
a6e9f9df 19442 fputs ("\n", stdout);
82b1b41b 19443
fd17d1e6 19444 offset += option.size;
252b5132 19445 }
a6e9f9df 19446 free (eopt);
252b5132 19447 }
32ec8896 19448 else
015dc7e1 19449 res = false;
252b5132
RH
19450 }
19451
19452 if (conflicts_offset != 0 && conflictsno != 0)
19453 {
2cf0635d 19454 Elf32_Conflict * iconf;
252b5132
RH
19455 size_t cnt;
19456
978c4450 19457 if (filedata->dynamic_symbols == NULL)
252b5132 19458 {
591a748a 19459 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 19460 return false;
252b5132
RH
19461 }
19462
7296a62a
NC
19463 /* PR 21345 - print a slightly more helpful error message
19464 if we are sure that the cmalloc will fail. */
645f43a8 19465 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 19466 {
26c527e6
AM
19467 error (_("Overlarge number of conflicts detected: %zx\n"),
19468 conflictsno);
015dc7e1 19469 return false;
7296a62a
NC
19470 }
19471
3f5e193b 19472 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
19473 if (iconf == NULL)
19474 {
8b73c356 19475 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 19476 return false;
252b5132
RH
19477 }
19478
9ea033b2 19479 if (is_32bit_elf)
252b5132 19480 {
2cf0635d 19481 Elf32_External_Conflict * econf32;
a6e9f9df 19482
3f5e193b 19483 econf32 = (Elf32_External_Conflict *)
95099889
AM
19484 get_data (NULL, filedata, conflicts_offset,
19485 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 19486 if (!econf32)
5a814d6d
AM
19487 {
19488 free (iconf);
015dc7e1 19489 return false;
5a814d6d 19490 }
252b5132
RH
19491
19492 for (cnt = 0; cnt < conflictsno; ++cnt)
19493 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
19494
19495 free (econf32);
252b5132
RH
19496 }
19497 else
19498 {
2cf0635d 19499 Elf64_External_Conflict * econf64;
a6e9f9df 19500
3f5e193b 19501 econf64 = (Elf64_External_Conflict *)
95099889
AM
19502 get_data (NULL, filedata, conflicts_offset,
19503 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 19504 if (!econf64)
5a814d6d
AM
19505 {
19506 free (iconf);
015dc7e1 19507 return false;
5a814d6d 19508 }
252b5132
RH
19509
19510 for (cnt = 0; cnt < conflictsno; ++cnt)
19511 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
19512
19513 free (econf64);
252b5132
RH
19514 }
19515
26c527e6
AM
19516 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19517 "\nSection '.conflict' contains %zu entries:\n",
19518 conflictsno),
19519 conflictsno);
252b5132
RH
19520 puts (_(" Num: Index Value Name"));
19521
19522 for (cnt = 0; cnt < conflictsno; ++cnt)
19523 {
26c527e6 19524 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 19525
978c4450 19526 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 19527 printf (_("<corrupt symbol index>"));
d79b3d50 19528 else
e0a31db1
NC
19529 {
19530 Elf_Internal_Sym * psym;
19531
978c4450 19532 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
19533 print_vma (psym->st_value, FULL_HEX);
19534 putchar (' ');
84714f86
AM
19535 if (valid_dynamic_name (filedata, psym->st_name))
19536 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19537 else
19538 printf (_("<corrupt: %14ld>"), psym->st_name);
19539 }
31104126 19540 putchar ('\n');
252b5132
RH
19541 }
19542
252b5132
RH
19543 free (iconf);
19544 }
19545
ccb4c951
RS
19546 if (pltgot != 0 && local_gotno != 0)
19547 {
625d49fc 19548 uint64_t ent, local_end, global_end;
bbeee7ea 19549 size_t i, offset;
2cf0635d 19550 unsigned char * data;
82b1b41b 19551 unsigned char * data_end;
bbeee7ea 19552 int addr_size;
ccb4c951 19553
91d6fa6a 19554 ent = pltgot;
ccb4c951
RS
19555 addr_size = (is_32bit_elf ? 4 : 8);
19556 local_end = pltgot + local_gotno * addr_size;
ccb4c951 19557
74e1a04b
NC
19558 /* PR binutils/17533 file: 012-111227-0.004 */
19559 if (symtabno < gotsym)
19560 {
26c527e6
AM
19561 error (_("The GOT symbol offset (%" PRIu64
19562 ") is greater than the symbol table size (%" PRIu64 ")\n"),
19563 gotsym, symtabno);
015dc7e1 19564 return false;
74e1a04b 19565 }
82b1b41b 19566
74e1a04b 19567 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
19568 /* PR 17531: file: 54c91a34. */
19569 if (global_end < local_end)
19570 {
26c527e6 19571 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 19572 return false;
82b1b41b 19573 }
948f632f 19574
dda8d76d
NC
19575 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
19576 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
19577 global_end - pltgot, 1,
19578 _("Global Offset Table data"));
919383ac 19579 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 19580 data_end = data + (global_end - pltgot);
59245841 19581
ccb4c951
RS
19582 printf (_("\nPrimary GOT:\n"));
19583 printf (_(" Canonical gp value: "));
19584 print_vma (pltgot + 0x7ff0, LONG_HEX);
19585 printf ("\n\n");
19586
19587 printf (_(" Reserved entries:\n"));
19588 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
19589 addr_size * 2, _("Address"), _("Access"),
19590 addr_size * 2, _("Initial"));
82b1b41b 19591 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 19592 printf (_(" Lazy resolver\n"));
625d49fc 19593 if (ent == (uint64_t) -1)
82b1b41b 19594 goto got_print_fail;
75ec1fdb 19595
c4ab9505
MR
19596 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19597 This entry will be used by some runtime loaders, to store the
19598 module pointer. Otherwise this is an ordinary local entry.
19599 PR 21344: Check for the entry being fully available before
19600 fetching it. */
19601 if (data
19602 && data + ent - pltgot + addr_size <= data_end
19603 && (byte_get (data + ent - pltgot, addr_size)
19604 >> (addr_size * 8 - 1)) != 0)
19605 {
19606 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19607 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 19608 if (ent == (uint64_t) -1)
c4ab9505 19609 goto got_print_fail;
ccb4c951
RS
19610 }
19611 printf ("\n");
19612
f17e9d8a 19613 if (data != NULL && ent < local_end)
ccb4c951
RS
19614 {
19615 printf (_(" Local entries:\n"));
cc5914eb 19616 printf (" %*s %10s %*s\n",
2b692964
NC
19617 addr_size * 2, _("Address"), _("Access"),
19618 addr_size * 2, _("Initial"));
91d6fa6a 19619 while (ent < local_end)
ccb4c951 19620 {
82b1b41b 19621 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19622 printf ("\n");
625d49fc 19623 if (ent == (uint64_t) -1)
82b1b41b 19624 goto got_print_fail;
ccb4c951
RS
19625 }
19626 printf ("\n");
19627 }
19628
f17e9d8a 19629 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19630 {
19631 int sym_width;
19632
19633 printf (_(" Global entries:\n"));
cc5914eb 19634 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19635 addr_size * 2, _("Address"),
19636 _("Access"),
2b692964 19637 addr_size * 2, _("Initial"),
9cf03b7e
NC
19638 addr_size * 2, _("Sym.Val."),
19639 _("Type"),
19640 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19641 _("Ndx"), _("Name"));
0b4362b0 19642
ccb4c951 19643 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19644
ccb4c951
RS
19645 for (i = gotsym; i < symtabno; i++)
19646 {
82b1b41b 19647 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19648 printf (" ");
e0a31db1 19649
978c4450 19650 if (filedata->dynamic_symbols == NULL)
e0a31db1 19651 printf (_("<no dynamic symbols>"));
978c4450 19652 else if (i < filedata->num_dynamic_syms)
e0a31db1 19653 {
978c4450 19654 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19655
19656 print_vma (psym->st_value, LONG_HEX);
19657 printf (" %-7s %3s ",
dda8d76d
NC
19658 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19659 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19660
84714f86 19661 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19662 print_symbol (sym_width,
84714f86 19663 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19664 else
19665 printf (_("<corrupt: %14ld>"), psym->st_name);
19666 }
ccb4c951 19667 else
26c527e6
AM
19668 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
19669 i);
e0a31db1 19670
ccb4c951 19671 printf ("\n");
625d49fc 19672 if (ent == (uint64_t) -1)
82b1b41b 19673 break;
ccb4c951
RS
19674 }
19675 printf ("\n");
19676 }
19677
82b1b41b 19678 got_print_fail:
9db70fc3 19679 free (data);
ccb4c951
RS
19680 }
19681
861fb55a
DJ
19682 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19683 {
625d49fc 19684 uint64_t ent, end;
26c527e6
AM
19685 uint64_t offset, rel_offset;
19686 uint64_t count, i;
2cf0635d 19687 unsigned char * data;
861fb55a 19688 int addr_size, sym_width;
2cf0635d 19689 Elf_Internal_Rela * rels;
861fb55a 19690
dda8d76d 19691 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19692 if (pltrel == DT_RELA)
19693 {
dda8d76d 19694 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19695 return false;
861fb55a
DJ
19696 }
19697 else
19698 {
dda8d76d 19699 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19700 return false;
861fb55a
DJ
19701 }
19702
91d6fa6a 19703 ent = mips_pltgot;
861fb55a
DJ
19704 addr_size = (is_32bit_elf ? 4 : 8);
19705 end = mips_pltgot + (2 + count) * addr_size;
19706
dda8d76d
NC
19707 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19708 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19709 1, _("Procedure Linkage Table data"));
59245841 19710 if (data == NULL)
288f0ba2
AM
19711 {
19712 free (rels);
015dc7e1 19713 return false;
288f0ba2 19714 }
59245841 19715
9cf03b7e 19716 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19717 printf (_(" Reserved entries:\n"));
19718 printf (_(" %*s %*s Purpose\n"),
2b692964 19719 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19720 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19721 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19722 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19723 printf (_(" Module pointer\n"));
861fb55a
DJ
19724 printf ("\n");
19725
19726 printf (_(" Entries:\n"));
cc5914eb 19727 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19728 addr_size * 2, _("Address"),
19729 addr_size * 2, _("Initial"),
19730 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19731 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19732 for (i = 0; i < count; i++)
19733 {
26c527e6 19734 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19735
91d6fa6a 19736 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19737 printf (" ");
e0a31db1 19738
978c4450 19739 if (idx >= filedata->num_dynamic_syms)
26c527e6 19740 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 19741 else
e0a31db1 19742 {
978c4450 19743 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19744
19745 print_vma (psym->st_value, LONG_HEX);
19746 printf (" %-7s %3s ",
dda8d76d
NC
19747 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19748 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19749 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19750 print_symbol (sym_width,
84714f86 19751 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19752 else
19753 printf (_("<corrupt: %14ld>"), psym->st_name);
19754 }
861fb55a
DJ
19755 printf ("\n");
19756 }
19757 printf ("\n");
19758
9db70fc3 19759 free (data);
861fb55a
DJ
19760 free (rels);
19761 }
19762
32ec8896 19763 return res;
252b5132
RH
19764}
19765
015dc7e1 19766static bool
dda8d76d 19767process_nds32_specific (Filedata * filedata)
35c08157
KLC
19768{
19769 Elf_Internal_Shdr *sect = NULL;
19770
dda8d76d 19771 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19772 if (sect != NULL && sect->sh_size >= 4)
35c08157 19773 {
9c7b8e9b
AM
19774 unsigned char *buf;
19775 unsigned int flag;
35c08157
KLC
19776
19777 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19778 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19779 _("NDS32 elf flags section"));
35c08157 19780
9c7b8e9b 19781 if (buf == NULL)
015dc7e1 19782 return false;
32ec8896 19783
9c7b8e9b
AM
19784 flag = byte_get (buf, 4);
19785 free (buf);
19786 switch (flag & 0x3)
35c08157
KLC
19787 {
19788 case 0:
19789 printf ("(VEC_SIZE):\tNo entry.\n");
19790 break;
19791 case 1:
19792 printf ("(VEC_SIZE):\t4 bytes\n");
19793 break;
19794 case 2:
19795 printf ("(VEC_SIZE):\t16 bytes\n");
19796 break;
19797 case 3:
19798 printf ("(VEC_SIZE):\treserved\n");
19799 break;
19800 }
19801 }
19802
015dc7e1 19803 return true;
35c08157
KLC
19804}
19805
015dc7e1 19806static bool
dda8d76d 19807process_gnu_liblist (Filedata * filedata)
047b2264 19808{
2cf0635d
NC
19809 Elf_Internal_Shdr * section;
19810 Elf_Internal_Shdr * string_sec;
19811 Elf32_External_Lib * elib;
19812 char * strtab;
c256ffe7 19813 size_t strtab_size;
047b2264 19814 size_t cnt;
26c527e6 19815 uint64_t num_liblist;
047b2264 19816 unsigned i;
015dc7e1 19817 bool res = true;
047b2264
JJ
19818
19819 if (! do_arch)
015dc7e1 19820 return true;
047b2264 19821
dda8d76d
NC
19822 for (i = 0, section = filedata->section_headers;
19823 i < filedata->file_header.e_shnum;
b34976b6 19824 i++, section++)
047b2264
JJ
19825 {
19826 switch (section->sh_type)
19827 {
19828 case SHT_GNU_LIBLIST:
dda8d76d 19829 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19830 break;
19831
3f5e193b 19832 elib = (Elf32_External_Lib *)
dda8d76d 19833 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19834 _("liblist section data"));
047b2264
JJ
19835
19836 if (elib == NULL)
32ec8896 19837 {
015dc7e1 19838 res = false;
32ec8896
NC
19839 break;
19840 }
047b2264 19841
dda8d76d
NC
19842 string_sec = filedata->section_headers + section->sh_link;
19843 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19844 string_sec->sh_size,
19845 _("liblist string table"));
047b2264
JJ
19846 if (strtab == NULL
19847 || section->sh_entsize != sizeof (Elf32_External_Lib))
19848 {
19849 free (elib);
2842702f 19850 free (strtab);
015dc7e1 19851 res = false;
047b2264
JJ
19852 break;
19853 }
59245841 19854 strtab_size = string_sec->sh_size;
047b2264 19855
d3a49aa8 19856 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
19857 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
19858 " entries:\n",
19859 "\nLibrary list section '%s' contains %" PRIu64
19860 " entries:\n",
d3a49aa8 19861 num_liblist),
dda8d76d 19862 printable_section_name (filedata, section),
d3a49aa8 19863 num_liblist);
047b2264 19864
2b692964 19865 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19866
19867 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19868 ++cnt)
19869 {
19870 Elf32_Lib liblist;
91d6fa6a 19871 time_t atime;
d5b07ef4 19872 char timebuf[128];
2cf0635d 19873 struct tm * tmp;
047b2264
JJ
19874
19875 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19876 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19877 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19878 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19879 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19880
91d6fa6a 19881 tmp = gmtime (&atime);
e9e44622
JJ
19882 snprintf (timebuf, sizeof (timebuf),
19883 "%04u-%02u-%02uT%02u:%02u:%02u",
19884 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19885 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 19886
26c527e6 19887 printf ("%3zu: ", cnt);
047b2264 19888 if (do_wide)
c256ffe7 19889 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19890 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19891 else
c256ffe7 19892 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19893 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19894 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19895 liblist.l_version, liblist.l_flags);
19896 }
19897
19898 free (elib);
2842702f 19899 free (strtab);
047b2264
JJ
19900 }
19901 }
19902
32ec8896 19903 return res;
047b2264
JJ
19904}
19905
9437c45b 19906static const char *
dda8d76d 19907get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19908{
19909 static char buff[64];
103f02d3 19910
dda8d76d 19911 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19912 switch (e_type)
19913 {
57346661 19914 case NT_AUXV:
1ec5cd37 19915 return _("NT_AUXV (auxiliary vector)");
57346661 19916 case NT_PRSTATUS:
1ec5cd37 19917 return _("NT_PRSTATUS (prstatus structure)");
57346661 19918 case NT_FPREGSET:
1ec5cd37 19919 return _("NT_FPREGSET (floating point registers)");
57346661 19920 case NT_PRPSINFO:
1ec5cd37 19921 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19922 case NT_TASKSTRUCT:
1ec5cd37 19923 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19924 case NT_GDB_TDESC:
19925 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19926 case NT_PRXFPREG:
1ec5cd37 19927 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19928 case NT_PPC_VMX:
19929 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19930 case NT_PPC_VSX:
19931 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19932 case NT_PPC_TAR:
19933 return _("NT_PPC_TAR (ppc TAR register)");
19934 case NT_PPC_PPR:
19935 return _("NT_PPC_PPR (ppc PPR register)");
19936 case NT_PPC_DSCR:
19937 return _("NT_PPC_DSCR (ppc DSCR register)");
19938 case NT_PPC_EBB:
19939 return _("NT_PPC_EBB (ppc EBB registers)");
19940 case NT_PPC_PMU:
19941 return _("NT_PPC_PMU (ppc PMU registers)");
19942 case NT_PPC_TM_CGPR:
19943 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19944 case NT_PPC_TM_CFPR:
19945 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19946 case NT_PPC_TM_CVMX:
19947 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19948 case NT_PPC_TM_CVSX:
3fd21718 19949 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19950 case NT_PPC_TM_SPR:
19951 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19952 case NT_PPC_TM_CTAR:
19953 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19954 case NT_PPC_TM_CPPR:
19955 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19956 case NT_PPC_TM_CDSCR:
19957 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19958 case NT_386_TLS:
19959 return _("NT_386_TLS (x86 TLS information)");
19960 case NT_386_IOPERM:
19961 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19962 case NT_X86_XSTATE:
19963 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19964 case NT_X86_CET:
19965 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19966 case NT_S390_HIGH_GPRS:
19967 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19968 case NT_S390_TIMER:
19969 return _("NT_S390_TIMER (s390 timer register)");
19970 case NT_S390_TODCMP:
19971 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19972 case NT_S390_TODPREG:
19973 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19974 case NT_S390_CTRS:
19975 return _("NT_S390_CTRS (s390 control registers)");
19976 case NT_S390_PREFIX:
19977 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19978 case NT_S390_LAST_BREAK:
19979 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19980 case NT_S390_SYSTEM_CALL:
19981 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19982 case NT_S390_TDB:
19983 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19984 case NT_S390_VXRS_LOW:
19985 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19986 case NT_S390_VXRS_HIGH:
19987 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19988 case NT_S390_GS_CB:
19989 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19990 case NT_S390_GS_BC:
19991 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19992 case NT_ARM_VFP:
19993 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19994 case NT_ARM_TLS:
19995 return _("NT_ARM_TLS (AArch TLS registers)");
19996 case NT_ARM_HW_BREAK:
19997 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19998 case NT_ARM_HW_WATCH:
19999 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
20000 case NT_ARM_SYSTEM_CALL:
20001 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
20002 case NT_ARM_SVE:
20003 return _("NT_ARM_SVE (AArch SVE registers)");
20004 case NT_ARM_PAC_MASK:
20005 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
20006 case NT_ARM_PACA_KEYS:
20007 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
20008 case NT_ARM_PACG_KEYS:
20009 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
20010 case NT_ARM_TAGGED_ADDR_CTRL:
20011 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
a8f175d9
LM
20012 case NT_ARM_SSVE:
20013 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
20014 case NT_ARM_ZA:
20015 return _("NT_ARM_ZA (AArch64 SME ZA register)");
3af2785c
LM
20016 case NT_ARM_PAC_ENABLED_KEYS:
20017 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
20018 case NT_ARC_V2:
20019 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
20020 case NT_RISCV_CSR:
20021 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 20022 case NT_PSTATUS:
1ec5cd37 20023 return _("NT_PSTATUS (pstatus structure)");
57346661 20024 case NT_FPREGS:
1ec5cd37 20025 return _("NT_FPREGS (floating point registers)");
57346661 20026 case NT_PSINFO:
1ec5cd37 20027 return _("NT_PSINFO (psinfo structure)");
57346661 20028 case NT_LWPSTATUS:
1ec5cd37 20029 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 20030 case NT_LWPSINFO:
1ec5cd37 20031 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 20032 case NT_WIN32PSTATUS:
1ec5cd37 20033 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
20034 case NT_SIGINFO:
20035 return _("NT_SIGINFO (siginfo_t data)");
20036 case NT_FILE:
20037 return _("NT_FILE (mapped files)");
1ec5cd37
NC
20038 default:
20039 break;
20040 }
20041 else
20042 switch (e_type)
20043 {
20044 case NT_VERSION:
20045 return _("NT_VERSION (version)");
20046 case NT_ARCH:
20047 return _("NT_ARCH (architecture)");
9ef920e9 20048 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 20049 return _("OPEN");
9ef920e9 20050 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 20051 return _("func");
c8795e1f
NC
20052 case NT_GO_BUILDID:
20053 return _("GO BUILDID");
3ac925fc
LB
20054 case FDO_PACKAGING_METADATA:
20055 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
20056 default:
20057 break;
20058 }
20059
e9e44622 20060 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 20061 return buff;
779fe533
NC
20062}
20063
015dc7e1 20064static bool
9ece1fa9
TT
20065print_core_note (Elf_Internal_Note *pnote)
20066{
20067 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 20068 uint64_t count, page_size;
9ece1fa9
TT
20069 unsigned char *descdata, *filenames, *descend;
20070
20071 if (pnote->type != NT_FILE)
04ac15ab
AS
20072 {
20073 if (do_wide)
20074 printf ("\n");
015dc7e1 20075 return true;
04ac15ab 20076 }
9ece1fa9 20077
9ece1fa9
TT
20078 if (!is_32bit_elf)
20079 {
20080 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
20081 /* Still "successful". */
015dc7e1 20082 return true;
9ece1fa9 20083 }
9ece1fa9
TT
20084
20085 if (pnote->descsz < 2 * addr_size)
20086 {
32ec8896 20087 error (_(" Malformed note - too short for header\n"));
015dc7e1 20088 return false;
9ece1fa9
TT
20089 }
20090
20091 descdata = (unsigned char *) pnote->descdata;
20092 descend = descdata + pnote->descsz;
20093
20094 if (descdata[pnote->descsz - 1] != '\0')
20095 {
32ec8896 20096 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 20097 return false;
9ece1fa9
TT
20098 }
20099
20100 count = byte_get (descdata, addr_size);
20101 descdata += addr_size;
20102
20103 page_size = byte_get (descdata, addr_size);
20104 descdata += addr_size;
20105
625d49fc 20106 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 20107 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 20108 {
32ec8896 20109 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 20110 return false;
9ece1fa9
TT
20111 }
20112
20113 printf (_(" Page size: "));
20114 print_vma (page_size, DEC);
20115 printf ("\n");
20116
20117 printf (_(" %*s%*s%*s\n"),
20118 (int) (2 + 2 * addr_size), _("Start"),
20119 (int) (4 + 2 * addr_size), _("End"),
20120 (int) (4 + 2 * addr_size), _("Page Offset"));
20121 filenames = descdata + count * 3 * addr_size;
595712bb 20122 while (count-- > 0)
9ece1fa9 20123 {
625d49fc 20124 uint64_t start, end, file_ofs;
9ece1fa9
TT
20125
20126 if (filenames == descend)
20127 {
32ec8896 20128 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 20129 return false;
9ece1fa9
TT
20130 }
20131
20132 start = byte_get (descdata, addr_size);
20133 descdata += addr_size;
20134 end = byte_get (descdata, addr_size);
20135 descdata += addr_size;
20136 file_ofs = byte_get (descdata, addr_size);
20137 descdata += addr_size;
20138
20139 printf (" ");
20140 print_vma (start, FULL_HEX);
20141 printf (" ");
20142 print_vma (end, FULL_HEX);
20143 printf (" ");
20144 print_vma (file_ofs, FULL_HEX);
20145 printf ("\n %s\n", filenames);
20146
20147 filenames += 1 + strlen ((char *) filenames);
20148 }
20149
015dc7e1 20150 return true;
9ece1fa9
TT
20151}
20152
1118d252
RM
20153static const char *
20154get_gnu_elf_note_type (unsigned e_type)
20155{
1449284b 20156 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
20157 switch (e_type)
20158 {
20159 case NT_GNU_ABI_TAG:
20160 return _("NT_GNU_ABI_TAG (ABI version tag)");
20161 case NT_GNU_HWCAP:
20162 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
20163 case NT_GNU_BUILD_ID:
20164 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
20165 case NT_GNU_GOLD_VERSION:
20166 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
20167 case NT_GNU_PROPERTY_TYPE_0:
20168 return _("NT_GNU_PROPERTY_TYPE_0");
20169 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20170 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
20171 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20172 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 20173 default:
1449284b
NC
20174 {
20175 static char buff[64];
1118d252 20176
1449284b
NC
20177 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20178 return buff;
20179 }
20180 }
1118d252
RM
20181}
20182
a9eafb08
L
20183static void
20184decode_x86_compat_isa (unsigned int bitmask)
20185{
20186 while (bitmask)
20187 {
20188 unsigned int bit = bitmask & (- bitmask);
20189
20190 bitmask &= ~ bit;
20191 switch (bit)
20192 {
20193 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
20194 printf ("i486");
20195 break;
20196 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
20197 printf ("586");
20198 break;
20199 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
20200 printf ("686");
20201 break;
20202 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
20203 printf ("SSE");
20204 break;
20205 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
20206 printf ("SSE2");
20207 break;
20208 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
20209 printf ("SSE3");
20210 break;
20211 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
20212 printf ("SSSE3");
20213 break;
20214 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
20215 printf ("SSE4_1");
20216 break;
20217 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
20218 printf ("SSE4_2");
20219 break;
20220 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
20221 printf ("AVX");
20222 break;
20223 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
20224 printf ("AVX2");
20225 break;
20226 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
20227 printf ("AVX512F");
20228 break;
20229 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
20230 printf ("AVX512CD");
20231 break;
20232 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
20233 printf ("AVX512ER");
20234 break;
20235 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
20236 printf ("AVX512PF");
20237 break;
20238 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
20239 printf ("AVX512VL");
20240 break;
20241 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
20242 printf ("AVX512DQ");
20243 break;
20244 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
20245 printf ("AVX512BW");
20246 break;
65b3d26e
L
20247 default:
20248 printf (_("<unknown: %x>"), bit);
20249 break;
a9eafb08
L
20250 }
20251 if (bitmask)
20252 printf (", ");
20253 }
20254}
20255
9ef920e9 20256static void
32930e4e 20257decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 20258{
0a59decb 20259 if (!bitmask)
90c745dc
L
20260 {
20261 printf (_("<None>"));
20262 return;
20263 }
90c745dc 20264
9ef920e9
NC
20265 while (bitmask)
20266 {
1fc87489 20267 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
20268
20269 bitmask &= ~ bit;
20270 switch (bit)
20271 {
32930e4e 20272 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
20273 printf ("CMOV");
20274 break;
32930e4e 20275 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
20276 printf ("SSE");
20277 break;
32930e4e 20278 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
20279 printf ("SSE2");
20280 break;
32930e4e 20281 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
20282 printf ("SSE3");
20283 break;
32930e4e 20284 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
20285 printf ("SSSE3");
20286 break;
32930e4e 20287 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
20288 printf ("SSE4_1");
20289 break;
32930e4e 20290 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
20291 printf ("SSE4_2");
20292 break;
32930e4e 20293 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
20294 printf ("AVX");
20295 break;
32930e4e 20296 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
20297 printf ("AVX2");
20298 break;
32930e4e 20299 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
20300 printf ("FMA");
20301 break;
32930e4e 20302 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
20303 printf ("AVX512F");
20304 break;
32930e4e 20305 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
20306 printf ("AVX512CD");
20307 break;
32930e4e 20308 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
20309 printf ("AVX512ER");
20310 break;
32930e4e 20311 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
20312 printf ("AVX512PF");
20313 break;
32930e4e 20314 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
20315 printf ("AVX512VL");
20316 break;
32930e4e 20317 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
20318 printf ("AVX512DQ");
20319 break;
32930e4e 20320 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
20321 printf ("AVX512BW");
20322 break;
32930e4e 20323 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
20324 printf ("AVX512_4FMAPS");
20325 break;
32930e4e 20326 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
20327 printf ("AVX512_4VNNIW");
20328 break;
32930e4e 20329 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
20330 printf ("AVX512_BITALG");
20331 break;
32930e4e 20332 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
20333 printf ("AVX512_IFMA");
20334 break;
32930e4e 20335 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
20336 printf ("AVX512_VBMI");
20337 break;
32930e4e 20338 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
20339 printf ("AVX512_VBMI2");
20340 break;
32930e4e 20341 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
20342 printf ("AVX512_VNNI");
20343 break;
32930e4e 20344 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
20345 printf ("AVX512_BF16");
20346 break;
65b3d26e
L
20347 default:
20348 printf (_("<unknown: %x>"), bit);
20349 break;
9ef920e9
NC
20350 }
20351 if (bitmask)
20352 printf (", ");
20353 }
20354}
20355
28cdbb18
SM
20356static const char *
20357get_amdgpu_elf_note_type (unsigned int e_type)
20358{
20359 switch (e_type)
20360 {
20361 case NT_AMDGPU_METADATA:
20362 return _("NT_AMDGPU_METADATA (code object metadata)");
20363 default:
20364 {
20365 static char buf[64];
20366 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
20367 return buf;
20368 }
20369 }
20370}
20371
32930e4e
L
20372static void
20373decode_x86_isa (unsigned int bitmask)
20374{
32930e4e
L
20375 while (bitmask)
20376 {
20377 unsigned int bit = bitmask & (- bitmask);
20378
20379 bitmask &= ~ bit;
20380 switch (bit)
20381 {
b0ab0693
L
20382 case GNU_PROPERTY_X86_ISA_1_BASELINE:
20383 printf ("x86-64-baseline");
20384 break;
32930e4e
L
20385 case GNU_PROPERTY_X86_ISA_1_V2:
20386 printf ("x86-64-v2");
20387 break;
20388 case GNU_PROPERTY_X86_ISA_1_V3:
20389 printf ("x86-64-v3");
20390 break;
20391 case GNU_PROPERTY_X86_ISA_1_V4:
20392 printf ("x86-64-v4");
20393 break;
20394 default:
20395 printf (_("<unknown: %x>"), bit);
20396 break;
20397 }
20398 if (bitmask)
20399 printf (", ");
20400 }
20401}
20402
ee2fdd6f 20403static void
a9eafb08 20404decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 20405{
0a59decb 20406 if (!bitmask)
90c745dc
L
20407 {
20408 printf (_("<None>"));
20409 return;
20410 }
90c745dc 20411
ee2fdd6f
L
20412 while (bitmask)
20413 {
20414 unsigned int bit = bitmask & (- bitmask);
20415
20416 bitmask &= ~ bit;
20417 switch (bit)
20418 {
20419 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 20420 printf ("IBT");
ee2fdd6f 20421 break;
48580982 20422 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 20423 printf ("SHSTK");
48580982 20424 break;
279d901e
L
20425 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
20426 printf ("LAM_U48");
20427 break;
20428 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
20429 printf ("LAM_U57");
20430 break;
ee2fdd6f
L
20431 default:
20432 printf (_("<unknown: %x>"), bit);
20433 break;
20434 }
20435 if (bitmask)
20436 printf (", ");
20437 }
20438}
20439
a9eafb08
L
20440static void
20441decode_x86_feature_2 (unsigned int bitmask)
20442{
0a59decb 20443 if (!bitmask)
90c745dc
L
20444 {
20445 printf (_("<None>"));
20446 return;
20447 }
90c745dc 20448
a9eafb08
L
20449 while (bitmask)
20450 {
20451 unsigned int bit = bitmask & (- bitmask);
20452
20453 bitmask &= ~ bit;
20454 switch (bit)
20455 {
20456 case GNU_PROPERTY_X86_FEATURE_2_X86:
20457 printf ("x86");
20458 break;
20459 case GNU_PROPERTY_X86_FEATURE_2_X87:
20460 printf ("x87");
20461 break;
20462 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20463 printf ("MMX");
20464 break;
20465 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20466 printf ("XMM");
20467 break;
20468 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20469 printf ("YMM");
20470 break;
20471 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20472 printf ("ZMM");
20473 break;
a308b89d
L
20474 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20475 printf ("TMM");
20476 break;
32930e4e
L
20477 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20478 printf ("MASK");
20479 break;
a9eafb08
L
20480 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20481 printf ("FXSR");
20482 break;
20483 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20484 printf ("XSAVE");
20485 break;
20486 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20487 printf ("XSAVEOPT");
20488 break;
20489 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20490 printf ("XSAVEC");
20491 break;
65b3d26e
L
20492 default:
20493 printf (_("<unknown: %x>"), bit);
20494 break;
a9eafb08
L
20495 }
20496 if (bitmask)
20497 printf (", ");
20498 }
20499}
20500
cd702818
SD
20501static void
20502decode_aarch64_feature_1_and (unsigned int bitmask)
20503{
20504 while (bitmask)
20505 {
20506 unsigned int bit = bitmask & (- bitmask);
20507
20508 bitmask &= ~ bit;
20509 switch (bit)
20510 {
20511 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20512 printf ("BTI");
20513 break;
20514
20515 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20516 printf ("PAC");
20517 break;
20518
20519 default:
20520 printf (_("<unknown: %x>"), bit);
20521 break;
20522 }
20523 if (bitmask)
20524 printf (", ");
20525 }
20526}
20527
6320fd00
L
20528static void
20529decode_1_needed (unsigned int bitmask)
20530{
20531 while (bitmask)
20532 {
20533 unsigned int bit = bitmask & (- bitmask);
20534
20535 bitmask &= ~ bit;
20536 switch (bit)
20537 {
20538 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20539 printf ("indirect external access");
20540 break;
20541 default:
20542 printf (_("<unknown: %x>"), bit);
20543 break;
20544 }
20545 if (bitmask)
20546 printf (", ");
20547 }
20548}
20549
9ef920e9 20550static void
dda8d76d 20551print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
20552{
20553 unsigned char * ptr = (unsigned char *) pnote->descdata;
20554 unsigned char * ptr_end = ptr + pnote->descsz;
20555 unsigned int size = is_32bit_elf ? 4 : 8;
20556
20557 printf (_(" Properties: "));
20558
1fc87489 20559 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
20560 {
20561 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
20562 return;
20563 }
20564
6ab2c4ed 20565 while (ptr < ptr_end)
9ef920e9 20566 {
1fc87489 20567 unsigned int j;
6ab2c4ed
MC
20568 unsigned int type;
20569 unsigned int datasz;
20570
20571 if ((size_t) (ptr_end - ptr) < 8)
20572 {
20573 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
20574 break;
20575 }
20576
20577 type = byte_get (ptr, 4);
20578 datasz = byte_get (ptr + 4, 4);
9ef920e9 20579
1fc87489 20580 ptr += 8;
9ef920e9 20581
6ab2c4ed 20582 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 20583 {
1fc87489
L
20584 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
20585 type, datasz);
9ef920e9 20586 break;
1fc87489 20587 }
9ef920e9 20588
1fc87489
L
20589 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20590 {
dda8d76d
NC
20591 if (filedata->file_header.e_machine == EM_X86_64
20592 || filedata->file_header.e_machine == EM_IAMCU
20593 || filedata->file_header.e_machine == EM_386)
1fc87489 20594 {
aa7bca9b
L
20595 unsigned int bitmask;
20596
20597 if (datasz == 4)
0a59decb 20598 bitmask = byte_get (ptr, 4);
aa7bca9b
L
20599 else
20600 bitmask = 0;
20601
1fc87489
L
20602 switch (type)
20603 {
20604 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 20605 if (datasz != 4)
aa7bca9b
L
20606 printf (_("x86 ISA used: <corrupt length: %#x> "),
20607 datasz);
1fc87489 20608 else
aa7bca9b
L
20609 {
20610 printf ("x86 ISA used: ");
20611 decode_x86_isa (bitmask);
20612 }
1fc87489 20613 goto next;
9ef920e9 20614
1fc87489 20615 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20616 if (datasz != 4)
aa7bca9b
L
20617 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20618 datasz);
1fc87489 20619 else
aa7bca9b
L
20620 {
20621 printf ("x86 ISA needed: ");
20622 decode_x86_isa (bitmask);
20623 }
1fc87489 20624 goto next;
9ef920e9 20625
ee2fdd6f 20626 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20627 if (datasz != 4)
aa7bca9b
L
20628 printf (_("x86 feature: <corrupt length: %#x> "),
20629 datasz);
ee2fdd6f 20630 else
aa7bca9b
L
20631 {
20632 printf ("x86 feature: ");
a9eafb08
L
20633 decode_x86_feature_1 (bitmask);
20634 }
20635 goto next;
20636
20637 case GNU_PROPERTY_X86_FEATURE_2_USED:
20638 if (datasz != 4)
20639 printf (_("x86 feature used: <corrupt length: %#x> "),
20640 datasz);
20641 else
20642 {
20643 printf ("x86 feature used: ");
20644 decode_x86_feature_2 (bitmask);
20645 }
20646 goto next;
20647
20648 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20649 if (datasz != 4)
20650 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20651 else
20652 {
20653 printf ("x86 feature needed: ");
20654 decode_x86_feature_2 (bitmask);
20655 }
20656 goto next;
20657
20658 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20659 if (datasz != 4)
20660 printf (_("x86 ISA used: <corrupt length: %#x> "),
20661 datasz);
20662 else
20663 {
20664 printf ("x86 ISA used: ");
20665 decode_x86_compat_isa (bitmask);
20666 }
20667 goto next;
20668
20669 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20670 if (datasz != 4)
20671 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20672 datasz);
20673 else
20674 {
20675 printf ("x86 ISA needed: ");
20676 decode_x86_compat_isa (bitmask);
aa7bca9b 20677 }
ee2fdd6f
L
20678 goto next;
20679
32930e4e
L
20680 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20681 if (datasz != 4)
20682 printf (_("x86 ISA used: <corrupt length: %#x> "),
20683 datasz);
20684 else
20685 {
20686 printf ("x86 ISA used: ");
20687 decode_x86_compat_2_isa (bitmask);
20688 }
20689 goto next;
20690
20691 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20692 if (datasz != 4)
20693 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20694 datasz);
20695 else
20696 {
20697 printf ("x86 ISA needed: ");
20698 decode_x86_compat_2_isa (bitmask);
20699 }
20700 goto next;
20701
1fc87489
L
20702 default:
20703 break;
20704 }
20705 }
cd702818
SD
20706 else if (filedata->file_header.e_machine == EM_AARCH64)
20707 {
20708 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20709 {
20710 printf ("AArch64 feature: ");
20711 if (datasz != 4)
20712 printf (_("<corrupt length: %#x> "), datasz);
20713 else
20714 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20715 goto next;
20716 }
20717 }
1fc87489
L
20718 }
20719 else
20720 {
20721 switch (type)
9ef920e9 20722 {
1fc87489
L
20723 case GNU_PROPERTY_STACK_SIZE:
20724 printf (_("stack size: "));
20725 if (datasz != size)
20726 printf (_("<corrupt length: %#x> "), datasz);
20727 else
26c527e6 20728 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
20729 goto next;
20730
20731 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20732 printf ("no copy on protected ");
20733 if (datasz)
20734 printf (_("<corrupt length: %#x> "), datasz);
20735 goto next;
20736
20737 default:
5a767724
L
20738 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20739 && type <= GNU_PROPERTY_UINT32_AND_HI)
20740 || (type >= GNU_PROPERTY_UINT32_OR_LO
20741 && type <= GNU_PROPERTY_UINT32_OR_HI))
20742 {
6320fd00
L
20743 switch (type)
20744 {
20745 case GNU_PROPERTY_1_NEEDED:
20746 if (datasz != 4)
20747 printf (_("1_needed: <corrupt length: %#x> "),
20748 datasz);
20749 else
20750 {
20751 unsigned int bitmask = byte_get (ptr, 4);
20752 printf ("1_needed: ");
20753 decode_1_needed (bitmask);
20754 }
20755 goto next;
20756
20757 default:
20758 break;
20759 }
5a767724
L
20760 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20761 printf (_("UINT32_AND (%#x): "), type);
20762 else
20763 printf (_("UINT32_OR (%#x): "), type);
20764 if (datasz != 4)
20765 printf (_("<corrupt length: %#x> "), datasz);
20766 else
20767 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20768 goto next;
20769 }
9ef920e9
NC
20770 break;
20771 }
9ef920e9
NC
20772 }
20773
1fc87489
L
20774 if (type < GNU_PROPERTY_LOPROC)
20775 printf (_("<unknown type %#x data: "), type);
20776 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20777 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20778 else
20779 printf (_("<application-specific type %#x data: "), type);
20780 for (j = 0; j < datasz; ++j)
20781 printf ("%02x ", ptr[j] & 0xff);
20782 printf (">");
20783
dc1e8a47 20784 next:
9ef920e9 20785 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20786 if (ptr == ptr_end)
20787 break;
1fc87489 20788
6ab2c4ed
MC
20789 if (do_wide)
20790 printf (", ");
20791 else
20792 printf ("\n\t");
9ef920e9
NC
20793 }
20794
20795 printf ("\n");
20796}
20797
015dc7e1 20798static bool
dda8d76d 20799print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20800{
1449284b 20801 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20802 switch (pnote->type)
20803 {
20804 case NT_GNU_BUILD_ID:
20805 {
26c527e6 20806 size_t i;
664f90a3
TT
20807
20808 printf (_(" Build ID: "));
20809 for (i = 0; i < pnote->descsz; ++i)
20810 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20811 printf ("\n");
664f90a3
TT
20812 }
20813 break;
20814
20815 case NT_GNU_ABI_TAG:
20816 {
26c527e6 20817 unsigned int os, major, minor, subminor;
664f90a3
TT
20818 const char *osname;
20819
3102e897
NC
20820 /* PR 17531: file: 030-599401-0.004. */
20821 if (pnote->descsz < 16)
20822 {
20823 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20824 break;
20825 }
20826
664f90a3
TT
20827 os = byte_get ((unsigned char *) pnote->descdata, 4);
20828 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20829 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20830 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20831
20832 switch (os)
20833 {
20834 case GNU_ABI_TAG_LINUX:
20835 osname = "Linux";
20836 break;
20837 case GNU_ABI_TAG_HURD:
20838 osname = "Hurd";
20839 break;
20840 case GNU_ABI_TAG_SOLARIS:
20841 osname = "Solaris";
20842 break;
20843 case GNU_ABI_TAG_FREEBSD:
20844 osname = "FreeBSD";
20845 break;
20846 case GNU_ABI_TAG_NETBSD:
20847 osname = "NetBSD";
20848 break;
14ae95f2
RM
20849 case GNU_ABI_TAG_SYLLABLE:
20850 osname = "Syllable";
20851 break;
20852 case GNU_ABI_TAG_NACL:
20853 osname = "NaCl";
20854 break;
664f90a3
TT
20855 default:
20856 osname = "Unknown";
20857 break;
20858 }
20859
26c527e6 20860 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
20861 major, minor, subminor);
20862 }
20863 break;
926c5385
CC
20864
20865 case NT_GNU_GOLD_VERSION:
20866 {
26c527e6 20867 size_t i;
926c5385
CC
20868
20869 printf (_(" Version: "));
20870 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20871 printf ("%c", pnote->descdata[i]);
20872 printf ("\n");
20873 }
20874 break;
1449284b
NC
20875
20876 case NT_GNU_HWCAP:
20877 {
26c527e6 20878 unsigned int num_entries, mask;
1449284b
NC
20879
20880 /* Hardware capabilities information. Word 0 is the number of entries.
20881 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20882 is a series of entries, where each entry is a single byte followed
20883 by a nul terminated string. The byte gives the bit number to test
20884 if enabled in the bitmask. */
20885 printf (_(" Hardware Capabilities: "));
20886 if (pnote->descsz < 8)
20887 {
32ec8896 20888 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20889 return false;
1449284b
NC
20890 }
20891 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20892 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 20893 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
20894 /* FIXME: Add code to display the entries... */
20895 }
20896 break;
20897
9ef920e9 20898 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20899 print_gnu_property_note (filedata, pnote);
9ef920e9 20900 break;
9abca702 20901
1449284b
NC
20902 default:
20903 /* Handle unrecognised types. An error message should have already been
20904 created by get_gnu_elf_note_type(), so all that we need to do is to
20905 display the data. */
20906 {
26c527e6 20907 size_t i;
1449284b
NC
20908
20909 printf (_(" Description data: "));
20910 for (i = 0; i < pnote->descsz; ++i)
20911 printf ("%02x ", pnote->descdata[i] & 0xff);
20912 printf ("\n");
20913 }
20914 break;
664f90a3
TT
20915 }
20916
015dc7e1 20917 return true;
664f90a3
TT
20918}
20919
685080f2
NC
20920static const char *
20921get_v850_elf_note_type (enum v850_notes n_type)
20922{
20923 static char buff[64];
20924
20925 switch (n_type)
20926 {
20927 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20928 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20929 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20930 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20931 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20932 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20933 default:
20934 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20935 return buff;
20936 }
20937}
20938
015dc7e1 20939static bool
685080f2
NC
20940print_v850_note (Elf_Internal_Note * pnote)
20941{
20942 unsigned int val;
20943
20944 if (pnote->descsz != 4)
015dc7e1 20945 return false;
32ec8896 20946
685080f2
NC
20947 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20948
20949 if (val == 0)
20950 {
20951 printf (_("not set\n"));
015dc7e1 20952 return true;
685080f2
NC
20953 }
20954
20955 switch (pnote->type)
20956 {
20957 case V850_NOTE_ALIGNMENT:
20958 switch (val)
20959 {
015dc7e1
AM
20960 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20961 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20962 }
20963 break;
14ae95f2 20964
685080f2
NC
20965 case V850_NOTE_DATA_SIZE:
20966 switch (val)
20967 {
015dc7e1
AM
20968 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20969 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20970 }
20971 break;
14ae95f2 20972
685080f2
NC
20973 case V850_NOTE_FPU_INFO:
20974 switch (val)
20975 {
015dc7e1
AM
20976 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20977 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20978 }
20979 break;
14ae95f2 20980
685080f2
NC
20981 case V850_NOTE_MMU_INFO:
20982 case V850_NOTE_CACHE_INFO:
20983 case V850_NOTE_SIMD_INFO:
20984 if (val == EF_RH850_SIMD)
20985 {
20986 printf (_("yes\n"));
015dc7e1 20987 return true;
685080f2
NC
20988 }
20989 break;
20990
20991 default:
20992 /* An 'unknown note type' message will already have been displayed. */
20993 break;
20994 }
20995
20996 printf (_("unknown value: %x\n"), val);
015dc7e1 20997 return false;
685080f2
NC
20998}
20999
015dc7e1 21000static bool
c6056a74
SF
21001process_netbsd_elf_note (Elf_Internal_Note * pnote)
21002{
21003 unsigned int version;
21004
21005 switch (pnote->type)
21006 {
21007 case NT_NETBSD_IDENT:
b966f55f
AM
21008 if (pnote->descsz < 1)
21009 break;
c6056a74
SF
21010 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21011 if ((version / 10000) % 100)
b966f55f 21012 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
21013 version, version / 100000000, (version / 1000000) % 100,
21014 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 21015 'A' + (version / 10000) % 26);
c6056a74
SF
21016 else
21017 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 21018 version, version / 100000000, (version / 1000000) % 100,
15f205b1 21019 (version / 100) % 100);
015dc7e1 21020 return true;
c6056a74
SF
21021
21022 case NT_NETBSD_MARCH:
9abca702 21023 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 21024 pnote->descdata);
015dc7e1 21025 return true;
c6056a74 21026
9abca702 21027 case NT_NETBSD_PAX:
b966f55f
AM
21028 if (pnote->descsz < 1)
21029 break;
9abca702
CZ
21030 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21031 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
21032 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
21033 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
21034 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
21035 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
21036 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
21037 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 21038 return true;
c6056a74 21039 }
b966f55f
AM
21040
21041 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
21042 pnote->descsz, pnote->type);
015dc7e1 21043 return false;
c6056a74
SF
21044}
21045
f4ddf30f 21046static const char *
dda8d76d 21047get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 21048{
f4ddf30f
JB
21049 switch (e_type)
21050 {
21051 case NT_FREEBSD_THRMISC:
21052 return _("NT_THRMISC (thrmisc structure)");
21053 case NT_FREEBSD_PROCSTAT_PROC:
21054 return _("NT_PROCSTAT_PROC (proc data)");
21055 case NT_FREEBSD_PROCSTAT_FILES:
21056 return _("NT_PROCSTAT_FILES (files data)");
21057 case NT_FREEBSD_PROCSTAT_VMMAP:
21058 return _("NT_PROCSTAT_VMMAP (vmmap data)");
21059 case NT_FREEBSD_PROCSTAT_GROUPS:
21060 return _("NT_PROCSTAT_GROUPS (groups data)");
21061 case NT_FREEBSD_PROCSTAT_UMASK:
21062 return _("NT_PROCSTAT_UMASK (umask data)");
21063 case NT_FREEBSD_PROCSTAT_RLIMIT:
21064 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
21065 case NT_FREEBSD_PROCSTAT_OSREL:
21066 return _("NT_PROCSTAT_OSREL (osreldate data)");
21067 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
21068 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
21069 case NT_FREEBSD_PROCSTAT_AUXV:
21070 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
21071 case NT_FREEBSD_PTLWPINFO:
21072 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
21073 case NT_FREEBSD_X86_SEGBASES:
21074 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 21075 }
dda8d76d 21076 return get_note_type (filedata, e_type);
f4ddf30f
JB
21077}
21078
9437c45b 21079static const char *
dda8d76d 21080get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
21081{
21082 static char buff[64];
21083
540e6170
CZ
21084 switch (e_type)
21085 {
21086 case NT_NETBSDCORE_PROCINFO:
21087 /* NetBSD core "procinfo" structure. */
21088 return _("NetBSD procinfo structure");
9437c45b 21089
540e6170
CZ
21090 case NT_NETBSDCORE_AUXV:
21091 return _("NetBSD ELF auxiliary vector data");
9437c45b 21092
06d949ec
KR
21093 case NT_NETBSDCORE_LWPSTATUS:
21094 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 21095
540e6170 21096 default:
06d949ec 21097 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
21098 defined for NetBSD core files. If the note type is less
21099 than the start of the machine-dependent note types, we don't
21100 understand it. */
21101
21102 if (e_type < NT_NETBSDCORE_FIRSTMACH)
21103 {
21104 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21105 return buff;
21106 }
21107 break;
9437c45b
JT
21108 }
21109
dda8d76d 21110 switch (filedata->file_header.e_machine)
9437c45b
JT
21111 {
21112 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
21113 and PT_GETFPREGS == mach+2. */
21114
21115 case EM_OLD_ALPHA:
21116 case EM_ALPHA:
21117 case EM_SPARC:
21118 case EM_SPARC32PLUS:
21119 case EM_SPARCV9:
21120 switch (e_type)
21121 {
2b692964 21122 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 21123 return _("PT_GETREGS (reg structure)");
2b692964 21124 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 21125 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21126 default:
21127 break;
21128 }
21129 break;
21130
c0d38b0e
CZ
21131 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
21132 There's also old PT___GETREGS40 == mach + 1 for old reg
21133 structure which lacks GBR. */
21134 case EM_SH:
21135 switch (e_type)
21136 {
21137 case NT_NETBSDCORE_FIRSTMACH + 1:
21138 return _("PT___GETREGS40 (old reg structure)");
21139 case NT_NETBSDCORE_FIRSTMACH + 3:
21140 return _("PT_GETREGS (reg structure)");
21141 case NT_NETBSDCORE_FIRSTMACH + 5:
21142 return _("PT_GETFPREGS (fpreg structure)");
21143 default:
21144 break;
21145 }
21146 break;
21147
9437c45b
JT
21148 /* On all other arch's, PT_GETREGS == mach+1 and
21149 PT_GETFPREGS == mach+3. */
21150 default:
21151 switch (e_type)
21152 {
2b692964 21153 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 21154 return _("PT_GETREGS (reg structure)");
2b692964 21155 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 21156 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21157 default:
21158 break;
21159 }
21160 }
21161
9cf03b7e 21162 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 21163 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
21164 return buff;
21165}
21166
98ca73af
FC
21167static const char *
21168get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21169{
21170 switch (e_type)
21171 {
21172 case NT_OPENBSD_PROCINFO:
21173 return _("OpenBSD procinfo structure");
21174 case NT_OPENBSD_AUXV:
21175 return _("OpenBSD ELF auxiliary vector data");
21176 case NT_OPENBSD_REGS:
21177 return _("OpenBSD regular registers");
21178 case NT_OPENBSD_FPREGS:
21179 return _("OpenBSD floating point registers");
21180 case NT_OPENBSD_WCOOKIE:
21181 return _("OpenBSD window cookie");
21182 }
21183
21184 return get_note_type (filedata, e_type);
21185}
21186
e263a66b
CC
21187static const char *
21188get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
21189{
21190 switch (e_type)
21191 {
21192 case QNT_DEBUG_FULLPATH:
21193 return _("QNX debug fullpath");
21194 case QNT_DEBUG_RELOC:
21195 return _("QNX debug relocation");
21196 case QNT_STACK:
21197 return _("QNX stack");
21198 case QNT_GENERATOR:
21199 return _("QNX generator");
21200 case QNT_DEFAULT_LIB:
21201 return _("QNX default library");
21202 case QNT_CORE_SYSINFO:
21203 return _("QNX core sysinfo");
21204 case QNT_CORE_INFO:
21205 return _("QNX core info");
21206 case QNT_CORE_STATUS:
21207 return _("QNX core status");
21208 case QNT_CORE_GREG:
21209 return _("QNX general registers");
21210 case QNT_CORE_FPREG:
21211 return _("QNX floating point registers");
21212 case QNT_LINK_MAP:
21213 return _("QNX link map");
21214 }
21215
21216 return get_note_type (filedata, e_type);
21217}
21218
70616151
TT
21219static const char *
21220get_stapsdt_note_type (unsigned e_type)
21221{
21222 static char buff[64];
21223
21224 switch (e_type)
21225 {
21226 case NT_STAPSDT:
21227 return _("NT_STAPSDT (SystemTap probe descriptors)");
21228
21229 default:
21230 break;
21231 }
21232
21233 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21234 return buff;
21235}
21236
015dc7e1 21237static bool
c6a9fc58
TT
21238print_stapsdt_note (Elf_Internal_Note *pnote)
21239{
3ca60c57 21240 size_t len, maxlen;
26c527e6 21241 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
21242 char *data = pnote->descdata;
21243 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 21244 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
21245 char *provider, *probe, *arg_fmt;
21246
3ca60c57
NC
21247 if (pnote->descsz < (addr_size * 3))
21248 goto stapdt_note_too_small;
21249
c6a9fc58
TT
21250 pc = byte_get ((unsigned char *) data, addr_size);
21251 data += addr_size;
3ca60c57 21252
c6a9fc58
TT
21253 base_addr = byte_get ((unsigned char *) data, addr_size);
21254 data += addr_size;
3ca60c57 21255
c6a9fc58
TT
21256 semaphore = byte_get ((unsigned char *) data, addr_size);
21257 data += addr_size;
21258
3ca60c57
NC
21259 if (data >= data_end)
21260 goto stapdt_note_too_small;
21261 maxlen = data_end - data;
21262 len = strnlen (data, maxlen);
21263 if (len < maxlen)
21264 {
21265 provider = data;
21266 data += len + 1;
21267 }
21268 else
21269 goto stapdt_note_too_small;
21270
21271 if (data >= data_end)
21272 goto stapdt_note_too_small;
21273 maxlen = data_end - data;
21274 len = strnlen (data, maxlen);
21275 if (len < maxlen)
21276 {
21277 probe = data;
21278 data += len + 1;
21279 }
21280 else
21281 goto stapdt_note_too_small;
9abca702 21282
3ca60c57
NC
21283 if (data >= data_end)
21284 goto stapdt_note_too_small;
21285 maxlen = data_end - data;
21286 len = strnlen (data, maxlen);
21287 if (len < maxlen)
21288 {
21289 arg_fmt = data;
21290 data += len + 1;
21291 }
21292 else
21293 goto stapdt_note_too_small;
c6a9fc58
TT
21294
21295 printf (_(" Provider: %s\n"), provider);
21296 printf (_(" Name: %s\n"), probe);
21297 printf (_(" Location: "));
21298 print_vma (pc, FULL_HEX);
21299 printf (_(", Base: "));
21300 print_vma (base_addr, FULL_HEX);
21301 printf (_(", Semaphore: "));
21302 print_vma (semaphore, FULL_HEX);
9cf03b7e 21303 printf ("\n");
c6a9fc58
TT
21304 printf (_(" Arguments: %s\n"), arg_fmt);
21305
21306 return data == data_end;
3ca60c57
NC
21307
21308 stapdt_note_too_small:
21309 printf (_(" <corrupt - note is too small>\n"));
21310 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 21311 return false;
c6a9fc58
TT
21312}
21313
e5382207
LB
21314static bool
21315print_fdo_note (Elf_Internal_Note * pnote)
21316{
21317 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
21318 {
21319 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
21320 return true;
21321 }
21322 return false;
21323}
21324
00e98fc7
TG
21325static const char *
21326get_ia64_vms_note_type (unsigned e_type)
21327{
21328 static char buff[64];
21329
21330 switch (e_type)
21331 {
21332 case NT_VMS_MHD:
21333 return _("NT_VMS_MHD (module header)");
21334 case NT_VMS_LNM:
21335 return _("NT_VMS_LNM (language name)");
21336 case NT_VMS_SRC:
21337 return _("NT_VMS_SRC (source files)");
21338 case NT_VMS_TITLE:
9cf03b7e 21339 return "NT_VMS_TITLE";
00e98fc7
TG
21340 case NT_VMS_EIDC:
21341 return _("NT_VMS_EIDC (consistency check)");
21342 case NT_VMS_FPMODE:
21343 return _("NT_VMS_FPMODE (FP mode)");
21344 case NT_VMS_LINKTIME:
9cf03b7e 21345 return "NT_VMS_LINKTIME";
00e98fc7
TG
21346 case NT_VMS_IMGNAM:
21347 return _("NT_VMS_IMGNAM (image name)");
21348 case NT_VMS_IMGID:
21349 return _("NT_VMS_IMGID (image id)");
21350 case NT_VMS_LINKID:
21351 return _("NT_VMS_LINKID (link id)");
21352 case NT_VMS_IMGBID:
21353 return _("NT_VMS_IMGBID (build id)");
21354 case NT_VMS_GSTNAM:
21355 return _("NT_VMS_GSTNAM (sym table name)");
21356 case NT_VMS_ORIG_DYN:
9cf03b7e 21357 return "NT_VMS_ORIG_DYN";
00e98fc7 21358 case NT_VMS_PATCHTIME:
9cf03b7e 21359 return "NT_VMS_PATCHTIME";
00e98fc7
TG
21360 default:
21361 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21362 return buff;
21363 }
21364}
21365
015dc7e1 21366static bool
00e98fc7
TG
21367print_ia64_vms_note (Elf_Internal_Note * pnote)
21368{
26c527e6 21369 unsigned int maxlen = pnote->descsz;
8d18bf79 21370
26c527e6 21371 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
21372 goto desc_size_fail;
21373
00e98fc7
TG
21374 switch (pnote->type)
21375 {
21376 case NT_VMS_MHD:
8d18bf79
NC
21377 if (maxlen <= 36)
21378 goto desc_size_fail;
21379
26c527e6 21380 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
21381
21382 printf (_(" Creation date : %.17s\n"), pnote->descdata);
21383 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
21384 if (l + 34 < maxlen)
21385 {
21386 printf (_(" Module name : %s\n"), pnote->descdata + 34);
21387 if (l + 35 < maxlen)
21388 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
21389 else
21390 printf (_(" Module version : <missing>\n"));
21391 }
00e98fc7 21392 else
8d18bf79
NC
21393 {
21394 printf (_(" Module name : <missing>\n"));
21395 printf (_(" Module version : <missing>\n"));
21396 }
00e98fc7 21397 break;
8d18bf79 21398
00e98fc7 21399 case NT_VMS_LNM:
8d18bf79 21400 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21401 break;
8d18bf79 21402
00e98fc7 21403 case NT_VMS_FPMODE:
9cf03b7e 21404 printf (_(" Floating Point mode: "));
8d18bf79
NC
21405 if (maxlen < 8)
21406 goto desc_size_fail;
21407 /* FIXME: Generate an error if descsz > 8 ? */
21408
b8281767 21409 printf ("0x%016" PRIx64 "\n",
625d49fc 21410 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 21411 break;
8d18bf79 21412
00e98fc7
TG
21413 case NT_VMS_LINKTIME:
21414 printf (_(" Link time: "));
8d18bf79
NC
21415 if (maxlen < 8)
21416 goto desc_size_fail;
21417 /* FIXME: Generate an error if descsz > 8 ? */
21418
0e3c1eeb 21419 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21420 printf ("\n");
21421 break;
8d18bf79 21422
00e98fc7
TG
21423 case NT_VMS_PATCHTIME:
21424 printf (_(" Patch time: "));
8d18bf79
NC
21425 if (maxlen < 8)
21426 goto desc_size_fail;
21427 /* FIXME: Generate an error if descsz > 8 ? */
21428
0e3c1eeb 21429 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21430 printf ("\n");
21431 break;
8d18bf79 21432
00e98fc7 21433 case NT_VMS_ORIG_DYN:
8d18bf79
NC
21434 if (maxlen < 34)
21435 goto desc_size_fail;
21436
00e98fc7 21437 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
21438 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
21439 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 21440 printf (_(" Last modified : "));
0e3c1eeb 21441 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 21442 printf (_("\n Link flags : "));
b8281767 21443 printf ("0x%016" PRIx64 "\n",
625d49fc 21444 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 21445 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 21446 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 21447 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 21448 break;
8d18bf79 21449
00e98fc7 21450 case NT_VMS_IMGNAM:
8d18bf79 21451 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21452 break;
8d18bf79 21453
00e98fc7 21454 case NT_VMS_GSTNAM:
8d18bf79 21455 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21456 break;
8d18bf79 21457
00e98fc7 21458 case NT_VMS_IMGID:
8d18bf79 21459 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21460 break;
8d18bf79 21461
00e98fc7 21462 case NT_VMS_LINKID:
8d18bf79 21463 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21464 break;
8d18bf79 21465
00e98fc7 21466 default:
015dc7e1 21467 return false;
00e98fc7 21468 }
8d18bf79 21469
015dc7e1 21470 return true;
8d18bf79
NC
21471
21472 desc_size_fail:
21473 printf (_(" <corrupt - data size is too small>\n"));
21474 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 21475 return false;
00e98fc7
TG
21476}
21477
fd486f32
AM
21478struct build_attr_cache {
21479 Filedata *filedata;
21480 char *strtab;
26c527e6 21481 uint64_t strtablen;
fd486f32 21482 Elf_Internal_Sym *symtab;
26c527e6 21483 uint64_t nsyms;
fd486f32
AM
21484} ba_cache;
21485
6f156d7a
NC
21486/* Find the symbol associated with a build attribute that is attached
21487 to address OFFSET. If PNAME is non-NULL then store the name of
21488 the symbol (if found) in the provided pointer, Returns NULL if a
21489 symbol could not be found. */
c799a79d 21490
6f156d7a 21491static Elf_Internal_Sym *
015dc7e1 21492get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 21493 uint64_t offset,
015dc7e1
AM
21494 bool is_open_attr,
21495 const char **pname)
9ef920e9 21496{
fd486f32
AM
21497 Elf_Internal_Sym *saved_sym = NULL;
21498 Elf_Internal_Sym *sym;
9ef920e9 21499
dda8d76d 21500 if (filedata->section_headers != NULL
fd486f32 21501 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 21502 {
c799a79d 21503 Elf_Internal_Shdr * symsec;
9ef920e9 21504
fd486f32
AM
21505 free (ba_cache.strtab);
21506 ba_cache.strtab = NULL;
21507 free (ba_cache.symtab);
21508 ba_cache.symtab = NULL;
21509
c799a79d 21510 /* Load the symbol and string sections. */
dda8d76d
NC
21511 for (symsec = filedata->section_headers;
21512 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 21513 symsec ++)
9ef920e9 21514 {
28d13567
AM
21515 if (symsec->sh_type == SHT_SYMTAB
21516 && get_symtab (filedata, symsec,
21517 &ba_cache.symtab, &ba_cache.nsyms,
21518 &ba_cache.strtab, &ba_cache.strtablen))
21519 break;
9ef920e9 21520 }
fd486f32 21521 ba_cache.filedata = filedata;
9ef920e9
NC
21522 }
21523
fd486f32 21524 if (ba_cache.symtab == NULL)
6f156d7a 21525 return NULL;
9ef920e9 21526
c799a79d 21527 /* Find a symbol whose value matches offset. */
fd486f32 21528 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
21529 if (sym->st_value == offset)
21530 {
fd486f32 21531 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
21532 /* Huh ? This should not happen. */
21533 continue;
9ef920e9 21534
fd486f32 21535 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 21536 continue;
9ef920e9 21537
9b9b1092 21538 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 21539 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
21540 if (ba_cache.strtab[sym->st_name] == '$'
21541 && ba_cache.strtab[sym->st_name + 1] != 0
21542 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
21543 continue;
21544
c799a79d
NC
21545 if (is_open_attr)
21546 {
21547 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
21548 and FILE or OBJECT symbols over NOTYPE symbols. We skip
21549 FUNC symbols entirely. */
21550 switch (ELF_ST_TYPE (sym->st_info))
21551 {
c799a79d 21552 case STT_OBJECT:
6f156d7a 21553 case STT_FILE:
c799a79d 21554 saved_sym = sym;
6f156d7a
NC
21555 if (sym->st_size)
21556 {
21557 /* If the symbol has a size associated
21558 with it then we can stop searching. */
fd486f32 21559 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 21560 }
c799a79d 21561 continue;
9ef920e9 21562
c799a79d
NC
21563 case STT_FUNC:
21564 /* Ignore function symbols. */
21565 continue;
21566
21567 default:
21568 break;
21569 }
21570
21571 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 21572 {
c799a79d
NC
21573 case STB_GLOBAL:
21574 if (saved_sym == NULL
21575 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
21576 saved_sym = sym;
21577 break;
c871dade 21578
c799a79d
NC
21579 case STB_LOCAL:
21580 if (saved_sym == NULL)
21581 saved_sym = sym;
21582 break;
21583
21584 default:
9ef920e9
NC
21585 break;
21586 }
21587 }
c799a79d
NC
21588 else
21589 {
21590 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
21591 continue;
21592
21593 saved_sym = sym;
21594 break;
21595 }
21596 }
21597
6f156d7a 21598 if (saved_sym && pname)
fd486f32 21599 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
21600
21601 return saved_sym;
c799a79d
NC
21602}
21603
d20e98ab
NC
21604/* Returns true iff addr1 and addr2 are in the same section. */
21605
015dc7e1 21606static bool
26c527e6 21607same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
21608{
21609 Elf_Internal_Shdr * a1;
21610 Elf_Internal_Shdr * a2;
21611
21612 a1 = find_section_by_address (filedata, addr1);
21613 a2 = find_section_by_address (filedata, addr2);
9abca702 21614
d20e98ab
NC
21615 return a1 == a2 && a1 != NULL;
21616}
21617
015dc7e1 21618static bool
dda8d76d
NC
21619print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21620 Filedata * filedata)
c799a79d 21621{
26c527e6
AM
21622 static uint64_t global_offset = 0;
21623 static uint64_t global_end = 0;
21624 static uint64_t func_offset = 0;
21625 static uint64_t func_end = 0;
c871dade 21626
015dc7e1
AM
21627 Elf_Internal_Sym *sym;
21628 const char *name;
26c527e6
AM
21629 uint64_t start;
21630 uint64_t end;
015dc7e1 21631 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
21632
21633 switch (pnote->descsz)
c799a79d 21634 {
6f156d7a
NC
21635 case 0:
21636 /* A zero-length description means that the range of
21637 the previous note of the same type should be used. */
c799a79d 21638 if (is_open_attr)
c871dade 21639 {
6f156d7a 21640 if (global_end > global_offset)
26c527e6
AM
21641 printf (_(" Applies to region from %#" PRIx64
21642 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 21643 else
26c527e6
AM
21644 printf (_(" Applies to region from %#" PRIx64
21645 "\n"), global_offset);
c799a79d
NC
21646 }
21647 else
21648 {
6f156d7a 21649 if (func_end > func_offset)
26c527e6
AM
21650 printf (_(" Applies to region from %#" PRIx64
21651 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 21652 else
26c527e6
AM
21653 printf (_(" Applies to region from %#" PRIx64
21654 "\n"), func_offset);
c871dade 21655 }
015dc7e1 21656 return true;
9ef920e9 21657
6f156d7a
NC
21658 case 4:
21659 start = byte_get ((unsigned char *) pnote->descdata, 4);
21660 end = 0;
21661 break;
21662
21663 case 8:
c74147bb
NC
21664 start = byte_get ((unsigned char *) pnote->descdata, 4);
21665 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21666 break;
21667
21668 case 16:
21669 start = byte_get ((unsigned char *) pnote->descdata, 8);
21670 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21671 break;
9abca702 21672
6f156d7a 21673 default:
c799a79d
NC
21674 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21675 printf (_(" <invalid descsz>"));
015dc7e1 21676 return false;
c799a79d
NC
21677 }
21678
6f156d7a
NC
21679 name = NULL;
21680 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21681 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21682 in order to avoid them being confused with the start address of the
21683 first function in the file... */
21684 if (sym == NULL && is_open_attr)
21685 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21686 & name);
6f156d7a
NC
21687
21688 if (end == 0 && sym != NULL && sym->st_size > 0)
21689 end = start + sym->st_size;
c799a79d
NC
21690
21691 if (is_open_attr)
21692 {
d20e98ab
NC
21693 /* FIXME: Need to properly allow for section alignment.
21694 16 is just the alignment used on x86_64. */
21695 if (global_end > 0
21696 && start > BFD_ALIGN (global_end, 16)
21697 /* Build notes are not guaranteed to be organised in order of
21698 increasing address, but we should find the all of the notes
21699 for one section in the same place. */
21700 && same_section (filedata, start, global_end))
26c527e6
AM
21701 warn (_("Gap in build notes detected from %#" PRIx64
21702 " to %#" PRIx64 "\n"),
6f156d7a
NC
21703 global_end + 1, start - 1);
21704
26c527e6 21705 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21706 global_offset = start;
21707
21708 if (end)
21709 {
26c527e6 21710 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21711 global_end = end;
21712 }
c799a79d
NC
21713 }
21714 else
21715 {
26c527e6 21716 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21717 func_offset = start;
21718
21719 if (end)
21720 {
26c527e6 21721 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21722 func_end = end;
21723 }
c799a79d
NC
21724 }
21725
6f156d7a
NC
21726 if (sym && name)
21727 printf (_(" (%s)"), name);
21728
21729 printf ("\n");
015dc7e1 21730 return true;
9ef920e9
NC
21731}
21732
015dc7e1 21733static bool
9ef920e9
NC
21734print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21735{
1d15e434
NC
21736 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21737 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21738 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21739 char name_type;
21740 char name_attribute;
1d15e434 21741 const char * expected_types;
9ef920e9
NC
21742 const char * name = pnote->namedata;
21743 const char * text;
88305e1b 21744 signed int left;
9ef920e9
NC
21745
21746 if (name == NULL || pnote->namesz < 2)
21747 {
21748 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21749 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21750 return false;
9ef920e9
NC
21751 }
21752
6f156d7a
NC
21753 if (do_wide)
21754 left = 28;
21755 else
21756 left = 20;
88305e1b
NC
21757
21758 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21759 if (name[0] == 'G' && name[1] == 'A')
21760 {
6f156d7a
NC
21761 if (pnote->namesz < 4)
21762 {
21763 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21764 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21765 return false;
6f156d7a
NC
21766 }
21767
88305e1b
NC
21768 printf ("GA");
21769 name += 2;
21770 left -= 2;
21771 }
21772
9ef920e9
NC
21773 switch ((name_type = * name))
21774 {
21775 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21776 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21777 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21778 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21779 printf ("%c", * name);
88305e1b 21780 left --;
9ef920e9
NC
21781 break;
21782 default:
21783 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21784 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21785 return false;
9ef920e9
NC
21786 }
21787
9ef920e9
NC
21788 ++ name;
21789 text = NULL;
21790
21791 switch ((name_attribute = * name))
21792 {
21793 case GNU_BUILD_ATTRIBUTE_VERSION:
21794 text = _("<version>");
1d15e434 21795 expected_types = string_expected;
9ef920e9
NC
21796 ++ name;
21797 break;
21798 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21799 text = _("<stack prot>");
75d7d298 21800 expected_types = "!+*";
9ef920e9
NC
21801 ++ name;
21802 break;
21803 case GNU_BUILD_ATTRIBUTE_RELRO:
21804 text = _("<relro>");
1d15e434 21805 expected_types = bool_expected;
9ef920e9
NC
21806 ++ name;
21807 break;
21808 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21809 text = _("<stack size>");
1d15e434 21810 expected_types = number_expected;
9ef920e9
NC
21811 ++ name;
21812 break;
21813 case GNU_BUILD_ATTRIBUTE_TOOL:
21814 text = _("<tool>");
1d15e434 21815 expected_types = string_expected;
9ef920e9
NC
21816 ++ name;
21817 break;
21818 case GNU_BUILD_ATTRIBUTE_ABI:
21819 text = _("<ABI>");
21820 expected_types = "$*";
21821 ++ name;
21822 break;
21823 case GNU_BUILD_ATTRIBUTE_PIC:
21824 text = _("<PIC>");
1d15e434 21825 expected_types = number_expected;
9ef920e9
NC
21826 ++ name;
21827 break;
a8be5506
NC
21828 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21829 text = _("<short enum>");
1d15e434 21830 expected_types = bool_expected;
a8be5506
NC
21831 ++ name;
21832 break;
9ef920e9
NC
21833 default:
21834 if (ISPRINT (* name))
21835 {
21836 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21837
21838 if (len > left && ! do_wide)
21839 len = left;
75d7d298 21840 printf ("%.*s:", len, name);
9ef920e9 21841 left -= len;
0dd6ae21 21842 name += len;
9ef920e9
NC
21843 }
21844 else
21845 {
3e6b6445 21846 static char tmpbuf [128];
88305e1b 21847
3e6b6445
NC
21848 error (_("unrecognised byte in name field: %d\n"), * name);
21849 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21850 text = tmpbuf;
21851 name ++;
9ef920e9
NC
21852 }
21853 expected_types = "*$!+";
21854 break;
21855 }
21856
21857 if (text)
88305e1b 21858 left -= printf ("%s", text);
9ef920e9
NC
21859
21860 if (strchr (expected_types, name_type) == NULL)
75d7d298 21861 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 21862
26c527e6 21863 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 21864 {
26c527e6
AM
21865 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
21866 pnote->namesz,
21867 name - pnote->namedata);
015dc7e1 21868 return false;
9ef920e9
NC
21869 }
21870
21871 if (left < 1 && ! do_wide)
015dc7e1 21872 return true;
9ef920e9
NC
21873
21874 switch (name_type)
21875 {
21876 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21877 {
26c527e6
AM
21878 unsigned int bytes;
21879 uint64_t val = 0;
21880 unsigned int shift = 0;
21881 char *decoded = NULL;
ddef72cd 21882
b06b2c92
NC
21883 bytes = pnote->namesz - (name - pnote->namedata);
21884 if (bytes > 0)
21885 /* The -1 is because the name field is always 0 terminated, and we
21886 want to be able to ensure that the shift in the while loop below
21887 will not overflow. */
21888 -- bytes;
21889
ddef72cd
NC
21890 if (bytes > sizeof (val))
21891 {
3e6b6445
NC
21892 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21893 bytes);
21894 bytes = sizeof (val);
ddef72cd 21895 }
3e6b6445
NC
21896 /* We do not bother to warn if bytes == 0 as this can
21897 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21898
21899 while (bytes --)
21900 {
26c527e6 21901 uint64_t byte = *name++ & 0xff;
79a964dc
NC
21902
21903 val |= byte << shift;
9ef920e9
NC
21904 shift += 8;
21905 }
21906
75d7d298 21907 switch (name_attribute)
9ef920e9 21908 {
75d7d298 21909 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21910 switch (val)
21911 {
75d7d298
NC
21912 case 0: decoded = "static"; break;
21913 case 1: decoded = "pic"; break;
21914 case 2: decoded = "PIC"; break;
21915 case 3: decoded = "pie"; break;
21916 case 4: decoded = "PIE"; break;
21917 default: break;
9ef920e9 21918 }
75d7d298
NC
21919 break;
21920 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21921 switch (val)
9ef920e9 21922 {
75d7d298
NC
21923 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21924 case 0: decoded = "off"; break;
21925 case 1: decoded = "on"; break;
21926 case 2: decoded = "all"; break;
21927 case 3: decoded = "strong"; break;
21928 case 4: decoded = "explicit"; break;
21929 default: break;
9ef920e9 21930 }
75d7d298
NC
21931 break;
21932 default:
21933 break;
9ef920e9
NC
21934 }
21935
75d7d298 21936 if (decoded != NULL)
3e6b6445
NC
21937 {
21938 print_symbol (-left, decoded);
21939 left = 0;
21940 }
21941 else if (val == 0)
21942 {
21943 printf ("0x0");
21944 left -= 3;
21945 }
9ef920e9 21946 else
75d7d298
NC
21947 {
21948 if (do_wide)
26c527e6 21949 left -= printf ("0x%" PRIx64, val);
75d7d298 21950 else
26c527e6 21951 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 21952 }
9ef920e9
NC
21953 }
21954 break;
21955 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21956 left -= print_symbol (- left, name);
21957 break;
21958 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21959 left -= print_symbol (- left, "true");
21960 break;
21961 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21962 left -= print_symbol (- left, "false");
21963 break;
21964 }
21965
21966 if (do_wide && left > 0)
21967 printf ("%-*s", left, " ");
9abca702 21968
015dc7e1 21969 return true;
9ef920e9
NC
21970}
21971
2952f10c
SM
21972/* Print the contents of PNOTE as hex. */
21973
21974static void
21975print_note_contents_hex (Elf_Internal_Note *pnote)
21976{
21977 if (pnote->descsz)
21978 {
26c527e6 21979 size_t i;
2952f10c
SM
21980
21981 printf (_(" description data: "));
21982 for (i = 0; i < pnote->descsz; i++)
21983 printf ("%02x ", pnote->descdata[i] & 0xff);
21984 if (!do_wide)
21985 printf ("\n");
21986 }
21987
21988 if (do_wide)
21989 printf ("\n");
21990}
21991
21992#if defined HAVE_MSGPACK
21993
21994static void
21995print_indents (int n)
21996{
21997 printf (" ");
21998
21999 for (int i = 0; i < n; i++)
22000 printf (" ");
22001}
22002
22003/* Print OBJ in human-readable form. */
22004
22005static void
22006dump_msgpack_obj (const msgpack_object *obj, int indent)
22007{
22008 switch (obj->type)
22009 {
22010 case MSGPACK_OBJECT_NIL:
22011 printf ("(nil)");
22012 break;
22013
22014 case MSGPACK_OBJECT_BOOLEAN:
22015 printf ("%s", obj->via.boolean ? "true" : "false");
22016 break;
22017
22018 case MSGPACK_OBJECT_POSITIVE_INTEGER:
22019 printf ("%" PRIu64, obj->via.u64);
22020 break;
22021
22022 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
22023 printf ("%" PRIi64, obj->via.i64);
22024 break;
22025
22026 case MSGPACK_OBJECT_FLOAT32:
22027 case MSGPACK_OBJECT_FLOAT64:
22028 printf ("%f", obj->via.f64);
22029 break;
22030
22031 case MSGPACK_OBJECT_STR:
22032 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
22033 break;
22034
22035 case MSGPACK_OBJECT_ARRAY:
22036 {
22037 const msgpack_object_array *array = &obj->via.array;
22038
22039 printf ("[\n");
22040 ++indent;
22041
22042 for (uint32_t i = 0; i < array->size; ++i)
22043 {
22044 const msgpack_object *item = &array->ptr[i];
22045
22046 print_indents (indent);
22047 dump_msgpack_obj (item, indent);
22048 printf (",\n");
22049 }
22050
22051 --indent;
22052 print_indents (indent);
22053 printf ("]");
22054 break;
22055 }
22056 break;
22057
22058 case MSGPACK_OBJECT_MAP:
22059 {
22060 const msgpack_object_map *map = &obj->via.map;
22061
22062 printf ("{\n");
22063 ++indent;
22064
22065 for (uint32_t i = 0; i < map->size; ++i)
22066 {
22067 const msgpack_object_kv *kv = &map->ptr[i];
22068 const msgpack_object *key = &kv->key;
22069 const msgpack_object *val = &kv->val;
22070
22071 print_indents (indent);
22072 dump_msgpack_obj (key, indent);
22073 printf (": ");
22074 dump_msgpack_obj (val, indent);
22075
22076 printf (",\n");
22077 }
22078
22079 --indent;
22080 print_indents (indent);
22081 printf ("}");
22082
22083 break;
22084 }
22085
22086 case MSGPACK_OBJECT_BIN:
22087 printf ("(bin)");
22088 break;
22089
22090 case MSGPACK_OBJECT_EXT:
22091 printf ("(ext)");
22092 break;
22093 }
22094}
22095
22096static void
22097dump_msgpack (const msgpack_unpacked *msg)
22098{
22099 print_indents (0);
22100 dump_msgpack_obj (&msg->data, 0);
22101 printf ("\n");
22102}
22103
22104#endif /* defined HAVE_MSGPACK */
22105
22106static bool
22107print_amdgpu_note (Elf_Internal_Note *pnote)
22108{
22109#if defined HAVE_MSGPACK
22110 /* If msgpack is available, decode and dump the note's content. */
22111 bool ret;
22112 msgpack_unpacked msg;
22113 msgpack_unpack_return msgpack_ret;
22114
22115 assert (pnote->type == NT_AMDGPU_METADATA);
22116
22117 msgpack_unpacked_init (&msg);
22118 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
22119 NULL);
22120
22121 switch (msgpack_ret)
22122 {
22123 case MSGPACK_UNPACK_SUCCESS:
22124 dump_msgpack (&msg);
22125 ret = true;
22126 break;
22127
22128 default:
22129 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
22130 ret = false;
22131 break;
22132 }
22133
22134 msgpack_unpacked_destroy (&msg);
22135 return ret;
22136#else
22137 /* msgpack is not available, dump contents as hex. */
22138 print_note_contents_hex (pnote);
22139 return true;
22140#endif
22141}
22142
e263a66b
CC
22143static bool
22144print_qnx_note (Elf_Internal_Note *pnote)
22145{
22146 switch (pnote->type)
22147 {
22148 case QNT_STACK:
22149 if (pnote->descsz != 12)
22150 goto desc_size_fail;
22151
22152 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
22153 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
22154 printf (_(" Stack allocated: %" PRIx32 "\n"),
22155 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22156 printf (_(" Executable: %s\n"),
22157 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
22158 break;
22159
22160 default:
22161 print_note_contents_hex(pnote);
22162 }
22163 return true;
22164
22165desc_size_fail:
22166 printf (_(" <corrupt - data size is too small>\n"));
22167 error (_("corrupt QNX note: data size is too small\n"));
22168 return false;
22169}
22170
22171
6d118b09
NC
22172/* Note that by the ELF standard, the name field is already null byte
22173 terminated, and namesz includes the terminating null byte.
22174 I.E. the value of namesz for the name "FSF" is 4.
22175
e3c8793a 22176 If the value of namesz is zero, there is no name present. */
9ef920e9 22177
015dc7e1 22178static bool
9ef920e9 22179process_note (Elf_Internal_Note * pnote,
dda8d76d 22180 Filedata * filedata)
779fe533 22181{
2cf0635d
NC
22182 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
22183 const char * nt;
9437c45b
JT
22184
22185 if (pnote->namesz == 0)
1ec5cd37
NC
22186 /* If there is no note name, then use the default set of
22187 note type strings. */
dda8d76d 22188 nt = get_note_type (filedata, pnote->type);
1ec5cd37 22189
24d127aa 22190 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
22191 /* GNU-specific object file notes. */
22192 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 22193
28cdbb18
SM
22194 else if (startswith (pnote->namedata, "AMDGPU"))
22195 /* AMDGPU-specific object file notes. */
22196 nt = get_amdgpu_elf_note_type (pnote->type);
22197
24d127aa 22198 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 22199 /* FreeBSD-specific core file notes. */
dda8d76d 22200 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 22201
24d127aa 22202 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 22203 /* NetBSD-specific core file notes. */
dda8d76d 22204 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 22205
24d127aa 22206 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
22207 /* NetBSD-specific core file notes. */
22208 return process_netbsd_elf_note (pnote);
22209
24d127aa 22210 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
22211 /* NetBSD-specific core file notes. */
22212 return process_netbsd_elf_note (pnote);
22213
98ca73af
FC
22214 else if (startswith (pnote->namedata, "OpenBSD"))
22215 /* OpenBSD-specific core file notes. */
22216 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
22217
e263a66b
CC
22218 else if (startswith (pnote->namedata, "QNX"))
22219 /* QNX-specific core file notes. */
22220 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
22221
e9b095a5 22222 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
22223 {
22224 /* SPU-specific core file notes. */
22225 nt = pnote->namedata + 4;
22226 name = "SPU";
22227 }
22228
24d127aa 22229 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
22230 /* VMS/ia64-specific file notes. */
22231 nt = get_ia64_vms_note_type (pnote->type);
22232
24d127aa 22233 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
22234 nt = get_stapsdt_note_type (pnote->type);
22235
9437c45b 22236 else
1ec5cd37
NC
22237 /* Don't recognize this note name; just use the default set of
22238 note type strings. */
dda8d76d 22239 nt = get_note_type (filedata, pnote->type);
9437c45b 22240
1449284b 22241 printf (" ");
9ef920e9 22242
24d127aa 22243 if (((startswith (pnote->namedata, "GA")
483767a3
AM
22244 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22245 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22246 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22247 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
22248 print_gnu_build_attribute_name (pnote);
22249 else
22250 print_symbol (-20, name);
22251
22252 if (do_wide)
22253 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
22254 else
22255 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 22256
24d127aa 22257 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 22258 return print_ia64_vms_note (pnote);
24d127aa 22259 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 22260 return print_gnu_note (filedata, pnote);
24d127aa 22261 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 22262 return print_stapsdt_note (pnote);
24d127aa 22263 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 22264 return print_core_note (pnote);
e5382207
LB
22265 else if (startswith (pnote->namedata, "FDO"))
22266 return print_fdo_note (pnote);
24d127aa 22267 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
22268 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22269 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22270 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22271 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 22272 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
22273 else if (startswith (pnote->namedata, "AMDGPU")
22274 && pnote->type == NT_AMDGPU_METADATA)
22275 return print_amdgpu_note (pnote);
e263a66b
CC
22276 else if (startswith (pnote->namedata, "QNX"))
22277 return print_qnx_note (pnote);
779fe533 22278
2952f10c 22279 print_note_contents_hex (pnote);
015dc7e1 22280 return true;
1449284b 22281}
6d118b09 22282
015dc7e1 22283static bool
dda8d76d
NC
22284process_notes_at (Filedata * filedata,
22285 Elf_Internal_Shdr * section,
625d49fc
AM
22286 uint64_t offset,
22287 uint64_t length,
22288 uint64_t align)
779fe533 22289{
015dc7e1
AM
22290 Elf_External_Note *pnotes;
22291 Elf_External_Note *external;
22292 char *end;
22293 bool res = true;
103f02d3 22294
779fe533 22295 if (length <= 0)
015dc7e1 22296 return false;
103f02d3 22297
1449284b
NC
22298 if (section)
22299 {
dda8d76d 22300 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 22301 if (pnotes)
32ec8896 22302 {
dda8d76d 22303 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
22304 {
22305 free (pnotes);
015dc7e1 22306 return false;
f761cb13 22307 }
32ec8896 22308 }
1449284b
NC
22309 }
22310 else
82ed9683 22311 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 22312 _("notes"));
4dff97b2 22313
dd24e3da 22314 if (pnotes == NULL)
015dc7e1 22315 return false;
779fe533 22316
103f02d3 22317 external = pnotes;
103f02d3 22318
ca0e11aa
NC
22319 if (filedata->is_separate)
22320 printf (_("In linked file '%s': "), filedata->file_name);
22321 else
22322 printf ("\n");
1449284b 22323 if (section)
ca0e11aa 22324 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 22325 else
26c527e6
AM
22326 printf (_("Displaying notes found at file offset 0x%08" PRIx64
22327 " with length 0x%08" PRIx64 ":\n"),
22328 offset, length);
1449284b 22329
82ed9683
L
22330 /* NB: Some note sections may have alignment value of 0 or 1. gABI
22331 specifies that notes should be aligned to 4 bytes in 32-bit
22332 objects and to 8 bytes in 64-bit objects. As a Linux extension,
22333 we also support 4 byte alignment in 64-bit objects. If section
22334 alignment is less than 4, we treate alignment as 4 bytes. */
22335 if (align < 4)
22336 align = 4;
22337 else if (align != 4 && align != 8)
22338 {
26c527e6
AM
22339 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
22340 align);
a788aedd 22341 free (pnotes);
015dc7e1 22342 return false;
82ed9683
L
22343 }
22344
dbe15e4e 22345 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 22346
c8071705
NC
22347 end = (char *) pnotes + length;
22348 while ((char *) external < end)
779fe533 22349 {
b34976b6 22350 Elf_Internal_Note inote;
15b42fb0 22351 size_t min_notesz;
4dff97b2 22352 char * next;
2cf0635d 22353 char * temp = NULL;
c8071705 22354 size_t data_remaining = end - (char *) external;
6d118b09 22355
dda8d76d 22356 if (!is_ia64_vms (filedata))
15b42fb0 22357 {
9dd3a467
NC
22358 /* PR binutils/15191
22359 Make sure that there is enough data to read. */
15b42fb0
AM
22360 min_notesz = offsetof (Elf_External_Note, name);
22361 if (data_remaining < min_notesz)
9dd3a467 22362 {
26c527e6 22363 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22364 "not enough for a full note\n",
26c527e6 22365 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22366 "not enough for a full note\n",
22367 data_remaining),
26c527e6 22368 data_remaining);
9dd3a467
NC
22369 break;
22370 }
5396a86e
AM
22371 data_remaining -= min_notesz;
22372
15b42fb0
AM
22373 inote.type = BYTE_GET (external->type);
22374 inote.namesz = BYTE_GET (external->namesz);
22375 inote.namedata = external->name;
22376 inote.descsz = BYTE_GET (external->descsz);
276da9b3 22377 inote.descdata = ((char *) external
4dff97b2 22378 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 22379 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 22380 next = ((char *) external
4dff97b2 22381 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 22382 }
00e98fc7 22383 else
15b42fb0
AM
22384 {
22385 Elf64_External_VMS_Note *vms_external;
00e98fc7 22386
9dd3a467
NC
22387 /* PR binutils/15191
22388 Make sure that there is enough data to read. */
15b42fb0
AM
22389 min_notesz = offsetof (Elf64_External_VMS_Note, name);
22390 if (data_remaining < min_notesz)
9dd3a467 22391 {
26c527e6 22392 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22393 "not enough for a full note\n",
26c527e6 22394 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22395 "not enough for a full note\n",
22396 data_remaining),
26c527e6 22397 data_remaining);
9dd3a467
NC
22398 break;
22399 }
5396a86e 22400 data_remaining -= min_notesz;
3e55a963 22401
15b42fb0
AM
22402 vms_external = (Elf64_External_VMS_Note *) external;
22403 inote.type = BYTE_GET (vms_external->type);
22404 inote.namesz = BYTE_GET (vms_external->namesz);
22405 inote.namedata = vms_external->name;
22406 inote.descsz = BYTE_GET (vms_external->descsz);
22407 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
22408 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22409 next = inote.descdata + align_power (inote.descsz, 3);
22410 }
22411
5396a86e
AM
22412 /* PR 17531: file: 3443835e. */
22413 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
22414 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
22415 || (size_t) (inote.descdata - inote.namedata) > data_remaining
22416 || (size_t) (next - inote.descdata) < inote.descsz
22417 || ((size_t) (next - inote.descdata)
22418 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 22419 {
26c527e6
AM
22420 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
22421 (char *) external - (char *) pnotes);
22422 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 22423 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
22424 break;
22425 }
22426
15b42fb0 22427 external = (Elf_External_Note *) next;
dd24e3da 22428
6d118b09
NC
22429 /* Verify that name is null terminated. It appears that at least
22430 one version of Linux (RedHat 6.0) generates corefiles that don't
22431 comply with the ELF spec by failing to include the null byte in
22432 namesz. */
18344509 22433 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 22434 {
5396a86e 22435 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 22436 {
5396a86e
AM
22437 temp = (char *) malloc (inote.namesz + 1);
22438 if (temp == NULL)
22439 {
22440 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 22441 res = false;
5396a86e
AM
22442 break;
22443 }
76da6bbe 22444
5396a86e
AM
22445 memcpy (temp, inote.namedata, inote.namesz);
22446 inote.namedata = temp;
22447 }
22448 inote.namedata[inote.namesz] = 0;
6d118b09
NC
22449 }
22450
dda8d76d 22451 if (! process_note (& inote, filedata))
015dc7e1 22452 res = false;
103f02d3 22453
9db70fc3
AM
22454 free (temp);
22455 temp = NULL;
779fe533
NC
22456 }
22457
22458 free (pnotes);
103f02d3 22459
779fe533
NC
22460 return res;
22461}
22462
015dc7e1 22463static bool
dda8d76d 22464process_corefile_note_segments (Filedata * filedata)
779fe533 22465{
015dc7e1 22466 Elf_Internal_Phdr *segment;
b34976b6 22467 unsigned int i;
015dc7e1 22468 bool res = true;
103f02d3 22469
dda8d76d 22470 if (! get_program_headers (filedata))
015dc7e1 22471 return true;
103f02d3 22472
dda8d76d
NC
22473 for (i = 0, segment = filedata->program_headers;
22474 i < filedata->file_header.e_phnum;
b34976b6 22475 i++, segment++)
779fe533
NC
22476 {
22477 if (segment->p_type == PT_NOTE)
625d49fc
AM
22478 if (! process_notes_at (filedata, NULL, segment->p_offset,
22479 segment->p_filesz, segment->p_align))
015dc7e1 22480 res = false;
779fe533 22481 }
103f02d3 22482
779fe533
NC
22483 return res;
22484}
22485
015dc7e1 22486static bool
625d49fc 22487process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
22488{
22489 Elf_External_Note * pnotes;
22490 Elf_External_Note * external;
c8071705 22491 char * end;
015dc7e1 22492 bool res = true;
685080f2
NC
22493
22494 if (length <= 0)
015dc7e1 22495 return false;
685080f2 22496
dda8d76d 22497 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
22498 _("v850 notes"));
22499 if (pnotes == NULL)
015dc7e1 22500 return false;
685080f2
NC
22501
22502 external = pnotes;
c8071705 22503 end = (char*) pnotes + length;
685080f2 22504
26c527e6
AM
22505 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22506 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22507 offset, length);
685080f2 22508
c8071705 22509 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
22510 {
22511 Elf_External_Note * next;
22512 Elf_Internal_Note inote;
22513
22514 inote.type = BYTE_GET (external->type);
22515 inote.namesz = BYTE_GET (external->namesz);
22516 inote.namedata = external->name;
22517 inote.descsz = BYTE_GET (external->descsz);
22518 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22519 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22520
c8071705
NC
22521 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22522 {
22523 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22524 inote.descdata = inote.namedata;
22525 inote.namesz = 0;
22526 }
22527
685080f2
NC
22528 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22529
c8071705 22530 if ( ((char *) next > end)
685080f2
NC
22531 || ((char *) next < (char *) pnotes))
22532 {
26c527e6
AM
22533 warn (_("corrupt descsz found in note at offset %#tx\n"),
22534 (char *) external - (char *) pnotes);
22535 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22536 inote.type, inote.namesz, inote.descsz);
22537 break;
22538 }
22539
22540 external = next;
22541
22542 /* Prevent out-of-bounds indexing. */
c8071705 22543 if ( inote.namedata + inote.namesz > end
685080f2
NC
22544 || inote.namedata + inote.namesz < inote.namedata)
22545 {
26c527e6
AM
22546 warn (_("corrupt namesz found in note at offset %#zx\n"),
22547 (char *) external - (char *) pnotes);
22548 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22549 inote.type, inote.namesz, inote.descsz);
22550 break;
22551 }
22552
22553 printf (" %s: ", get_v850_elf_note_type (inote.type));
22554
22555 if (! print_v850_note (& inote))
22556 {
015dc7e1 22557 res = false;
26c527e6 22558 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
22559 inote.namesz, inote.descsz);
22560 }
22561 }
22562
22563 free (pnotes);
22564
22565 return res;
22566}
22567
015dc7e1 22568static bool
dda8d76d 22569process_note_sections (Filedata * filedata)
1ec5cd37 22570{
015dc7e1 22571 Elf_Internal_Shdr *section;
26c527e6 22572 size_t i;
32ec8896 22573 unsigned int n = 0;
015dc7e1 22574 bool res = true;
1ec5cd37 22575
dda8d76d
NC
22576 for (i = 0, section = filedata->section_headers;
22577 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 22578 i++, section++)
685080f2
NC
22579 {
22580 if (section->sh_type == SHT_NOTE)
22581 {
625d49fc
AM
22582 if (! process_notes_at (filedata, section, section->sh_offset,
22583 section->sh_size, section->sh_addralign))
015dc7e1 22584 res = false;
685080f2
NC
22585 n++;
22586 }
22587
dda8d76d
NC
22588 if (( filedata->file_header.e_machine == EM_V800
22589 || filedata->file_header.e_machine == EM_V850
22590 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
22591 && section->sh_type == SHT_RENESAS_INFO)
22592 {
625d49fc
AM
22593 if (! process_v850_notes (filedata, section->sh_offset,
22594 section->sh_size))
015dc7e1 22595 res = false;
685080f2
NC
22596 n++;
22597 }
22598 }
df565f32
NC
22599
22600 if (n == 0)
22601 /* Try processing NOTE segments instead. */
dda8d76d 22602 return process_corefile_note_segments (filedata);
1ec5cd37
NC
22603
22604 return res;
22605}
22606
015dc7e1 22607static bool
dda8d76d 22608process_notes (Filedata * filedata)
779fe533
NC
22609{
22610 /* If we have not been asked to display the notes then do nothing. */
22611 if (! do_notes)
015dc7e1 22612 return true;
103f02d3 22613
dda8d76d
NC
22614 if (filedata->file_header.e_type != ET_CORE)
22615 return process_note_sections (filedata);
103f02d3 22616
779fe533 22617 /* No program headers means no NOTE segment. */
dda8d76d
NC
22618 if (filedata->file_header.e_phnum > 0)
22619 return process_corefile_note_segments (filedata);
779fe533 22620
ca0e11aa
NC
22621 if (filedata->is_separate)
22622 printf (_("No notes found in linked file '%s'.\n"),
22623 filedata->file_name);
22624 else
22625 printf (_("No notes found file.\n"));
22626
015dc7e1 22627 return true;
779fe533
NC
22628}
22629
60abdbed
NC
22630static unsigned char *
22631display_public_gnu_attributes (unsigned char * start,
22632 const unsigned char * const end)
22633{
22634 printf (_(" Unknown GNU attribute: %s\n"), start);
22635
22636 start += strnlen ((char *) start, end - start);
22637 display_raw_attribute (start, end);
22638
22639 return (unsigned char *) end;
22640}
22641
22642static unsigned char *
22643display_generic_attribute (unsigned char * start,
22644 unsigned int tag,
22645 const unsigned char * const end)
22646{
22647 if (tag == 0)
22648 return (unsigned char *) end;
22649
22650 return display_tag_value (tag, start, end);
22651}
22652
015dc7e1 22653static bool
dda8d76d 22654process_arch_specific (Filedata * filedata)
252b5132 22655{
a952a375 22656 if (! do_arch)
015dc7e1 22657 return true;
a952a375 22658
dda8d76d 22659 switch (filedata->file_header.e_machine)
252b5132 22660 {
53a346d8
CZ
22661 case EM_ARC:
22662 case EM_ARC_COMPACT:
22663 case EM_ARC_COMPACT2:
b5c37946
SJ
22664 case EM_ARC_COMPACT3:
22665 case EM_ARC_COMPACT3_64:
dda8d76d 22666 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
22667 display_arc_attribute,
22668 display_generic_attribute);
11c1ff18 22669 case EM_ARM:
dda8d76d 22670 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
22671 display_arm_attribute,
22672 display_generic_attribute);
22673
252b5132 22674 case EM_MIPS:
4fe85591 22675 case EM_MIPS_RS3_LE:
dda8d76d 22676 return process_mips_specific (filedata);
60abdbed
NC
22677
22678 case EM_MSP430:
dda8d76d 22679 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 22680 display_msp430_attribute,
c0ea7c52 22681 display_msp430_gnu_attribute);
60abdbed 22682
2dc8dd17
JW
22683 case EM_RISCV:
22684 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22685 display_riscv_attribute,
22686 display_generic_attribute);
22687
35c08157 22688 case EM_NDS32:
dda8d76d 22689 return process_nds32_specific (filedata);
60abdbed 22690
85f7484a
PB
22691 case EM_68K:
22692 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22693 display_m68k_gnu_attribute);
22694
34c8bcba 22695 case EM_PPC:
b82317dd 22696 case EM_PPC64:
dda8d76d 22697 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22698 display_power_gnu_attribute);
22699
643f7afb
AK
22700 case EM_S390:
22701 case EM_S390_OLD:
dda8d76d 22702 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22703 display_s390_gnu_attribute);
22704
9e8c70f9
DM
22705 case EM_SPARC:
22706 case EM_SPARC32PLUS:
22707 case EM_SPARCV9:
dda8d76d 22708 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22709 display_sparc_gnu_attribute);
22710
59e6276b 22711 case EM_TI_C6000:
dda8d76d 22712 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22713 display_tic6x_attribute,
22714 display_generic_attribute);
22715
0861f561
CQ
22716 case EM_CSKY:
22717 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22718 display_csky_attribute, NULL);
22719
252b5132 22720 default:
dda8d76d 22721 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22722 display_public_gnu_attributes,
22723 display_generic_attribute);
252b5132 22724 }
252b5132
RH
22725}
22726
015dc7e1 22727static bool
dda8d76d 22728get_file_header (Filedata * filedata)
252b5132 22729{
9ea033b2 22730 /* Read in the identity array. */
dda8d76d 22731 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22732 return false;
252b5132 22733
9ea033b2 22734 /* Determine how to read the rest of the header. */
dda8d76d 22735 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22736 {
1a0670f3
AM
22737 default:
22738 case ELFDATANONE:
adab8cdc
AO
22739 case ELFDATA2LSB:
22740 byte_get = byte_get_little_endian;
22741 byte_put = byte_put_little_endian;
22742 break;
22743 case ELFDATA2MSB:
22744 byte_get = byte_get_big_endian;
22745 byte_put = byte_put_big_endian;
22746 break;
9ea033b2
NC
22747 }
22748
22749 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22750 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22751
22752 /* Read in the rest of the header. */
22753 if (is_32bit_elf)
22754 {
22755 Elf32_External_Ehdr ehdr32;
252b5132 22756
dda8d76d 22757 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22758 return false;
103f02d3 22759
dda8d76d
NC
22760 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22761 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22762 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22763 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22764 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22765 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22766 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22767 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22768 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22769 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22770 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22771 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22772 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22773 }
252b5132 22774 else
9ea033b2
NC
22775 {
22776 Elf64_External_Ehdr ehdr64;
a952a375 22777
dda8d76d 22778 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22779 return false;
103f02d3 22780
dda8d76d
NC
22781 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22782 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22783 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22784 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22785 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22786 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22787 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22788 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22789 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22790 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22791 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22792 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22793 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22794 }
252b5132 22795
015dc7e1 22796 return true;
252b5132
RH
22797}
22798
13acb58d
AM
22799static void
22800free_filedata (Filedata *filedata)
22801{
22802 free (filedata->program_interpreter);
13acb58d 22803 free (filedata->program_headers);
13acb58d 22804 free (filedata->section_headers);
13acb58d 22805 free (filedata->string_table);
13acb58d 22806 free (filedata->dump.dump_sects);
13acb58d 22807 free (filedata->dynamic_strings);
13acb58d 22808 free (filedata->dynamic_symbols);
13acb58d 22809 free (filedata->dynamic_syminfo);
13acb58d 22810 free (filedata->dynamic_section);
13acb58d
AM
22811
22812 while (filedata->symtab_shndx_list != NULL)
22813 {
22814 elf_section_list *next = filedata->symtab_shndx_list->next;
22815 free (filedata->symtab_shndx_list);
22816 filedata->symtab_shndx_list = next;
22817 }
22818
22819 free (filedata->section_headers_groups);
13acb58d
AM
22820
22821 if (filedata->section_groups)
22822 {
22823 size_t i;
22824 struct group_list * g;
22825 struct group_list * next;
22826
22827 for (i = 0; i < filedata->group_count; i++)
22828 {
22829 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22830 {
22831 next = g->next;
22832 free (g);
22833 }
22834 }
22835
22836 free (filedata->section_groups);
13acb58d 22837 }
066f8fbe
AM
22838 memset (&filedata->section_headers, 0,
22839 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22840}
22841
dda8d76d
NC
22842static void
22843close_file (Filedata * filedata)
22844{
22845 if (filedata)
22846 {
22847 if (filedata->handle)
22848 fclose (filedata->handle);
22849 free (filedata);
22850 }
22851}
22852
22853void
22854close_debug_file (void * data)
22855{
13acb58d 22856 free_filedata ((Filedata *) data);
dda8d76d
NC
22857 close_file ((Filedata *) data);
22858}
22859
22860static Filedata *
015dc7e1 22861open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22862{
22863 struct stat statbuf;
22864 Filedata * filedata = NULL;
22865
22866 if (stat (pathname, & statbuf) < 0
22867 || ! S_ISREG (statbuf.st_mode))
22868 goto fail;
22869
22870 filedata = calloc (1, sizeof * filedata);
22871 if (filedata == NULL)
22872 goto fail;
22873
22874 filedata->handle = fopen (pathname, "rb");
22875 if (filedata->handle == NULL)
22876 goto fail;
22877
be7d229a 22878 filedata->file_size = statbuf.st_size;
dda8d76d 22879 filedata->file_name = pathname;
ca0e11aa 22880 filedata->is_separate = is_separate;
dda8d76d
NC
22881
22882 if (! get_file_header (filedata))
22883 goto fail;
22884
4de91c10
AM
22885 if (!get_section_headers (filedata, false))
22886 goto fail;
dda8d76d
NC
22887
22888 return filedata;
22889
22890 fail:
22891 if (filedata)
22892 {
22893 if (filedata->handle)
22894 fclose (filedata->handle);
22895 free (filedata);
22896 }
22897 return NULL;
22898}
22899
22900void *
22901open_debug_file (const char * pathname)
22902{
015dc7e1 22903 return open_file (pathname, true);
dda8d76d
NC
22904}
22905
835f2fae
NC
22906static void
22907initialise_dump_sects (Filedata * filedata)
22908{
22909 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22910 Note we do this even if cmdline_dump_sects is empty because we
22911 must make sure that the dump_sets array is zeroed out before each
22912 object file is processed. */
22913 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22914 memset (filedata->dump.dump_sects, 0,
22915 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22916
22917 if (cmdline.num_dump_sects > 0)
22918 {
22919 if (filedata->dump.num_dump_sects == 0)
22920 /* A sneaky way of allocating the dump_sects array. */
22921 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22922
22923 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22924 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22925 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22926 }
22927}
22928
94585d6d
NC
22929static bool
22930might_need_separate_debug_info (Filedata * filedata)
22931{
22932 /* Debuginfo files do not need further separate file loading. */
22933 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22934 return false;
22935
22936 /* Since do_follow_links might be enabled by default, only treat it as an
22937 indication that separate files should be loaded if setting it was a
22938 deliberate user action. */
22939 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22940 return true;
22941
22942 if (process_links || do_syms || do_unwind
22943 || dump_any_debugging || do_dump || do_debugging)
22944 return true;
22945
22946 return false;
22947}
22948
fb52b2f4
NC
22949/* Process one ELF object file according to the command line options.
22950 This file may actually be stored in an archive. The file is
32ec8896
NC
22951 positioned at the start of the ELF object. Returns TRUE if no
22952 problems were encountered, FALSE otherwise. */
fb52b2f4 22953
015dc7e1 22954static bool
dda8d76d 22955process_object (Filedata * filedata)
252b5132 22956{
015dc7e1 22957 bool have_separate_files;
252b5132 22958 unsigned int i;
015dc7e1 22959 bool res;
252b5132 22960
dda8d76d 22961 if (! get_file_header (filedata))
252b5132 22962 {
dda8d76d 22963 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22964 return false;
252b5132
RH
22965 }
22966
22967 /* Initialise per file variables. */
978c4450
AM
22968 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22969 filedata->version_info[i] = 0;
252b5132 22970
978c4450
AM
22971 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22972 filedata->dynamic_info[i] = 0;
22973 filedata->dynamic_info_DT_GNU_HASH = 0;
22974 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22975
22976 /* Process the file. */
22977 if (show_name)
dda8d76d 22978 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22979
835f2fae 22980 initialise_dump_sects (filedata);
d70c5fc7 22981
4de91c10
AM
22982 /* There may be some extensions in the first section header. Don't
22983 bomb if we can't read it. */
22984 get_section_headers (filedata, true);
22985
dda8d76d 22986 if (! process_file_header (filedata))
4de91c10
AM
22987 {
22988 res = false;
22989 goto out;
22990 }
252b5132 22991
e331b18d
AM
22992 /* Throw away the single section header read above, so that we
22993 re-read the entire set. */
22994 free (filedata->section_headers);
22995 filedata->section_headers = NULL;
22996
dda8d76d 22997 if (! process_section_headers (filedata))
2f62977e 22998 {
32ec8896 22999 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 23000 do_unwind = do_version = do_dump = do_arch = false;
252b5132 23001
2f62977e 23002 if (! do_using_dynamic)
015dc7e1 23003 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 23004 }
252b5132 23005
dda8d76d 23006 if (! process_section_groups (filedata))
32ec8896 23007 /* Without loaded section groups we cannot process unwind. */
015dc7e1 23008 do_unwind = false;
d1f5c6e3 23009
93df3340
AM
23010 process_program_headers (filedata);
23011
23012 res = process_dynamic_section (filedata);
252b5132 23013
dda8d76d 23014 if (! process_relocs (filedata))
015dc7e1 23015 res = false;
252b5132 23016
dda8d76d 23017 if (! process_unwind (filedata))
015dc7e1 23018 res = false;
4d6ed7c8 23019
dda8d76d 23020 if (! process_symbol_table (filedata))
015dc7e1 23021 res = false;
252b5132 23022
0f03783c 23023 if (! process_lto_symbol_tables (filedata))
015dc7e1 23024 res = false;
b9e920ec 23025
dda8d76d 23026 if (! process_syminfo (filedata))
015dc7e1 23027 res = false;
252b5132 23028
dda8d76d 23029 if (! process_version_sections (filedata))
015dc7e1 23030 res = false;
252b5132 23031
94585d6d 23032 if (might_need_separate_debug_info (filedata))
24841daa 23033 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 23034 else
015dc7e1 23035 have_separate_files = false;
dda8d76d
NC
23036
23037 if (! process_section_contents (filedata))
015dc7e1 23038 res = false;
f5842774 23039
24841daa 23040 if (have_separate_files)
dda8d76d 23041 {
24841daa
NC
23042 separate_info * d;
23043
23044 for (d = first_separate_info; d != NULL; d = d->next)
23045 {
835f2fae
NC
23046 initialise_dump_sects (d->handle);
23047
ca0e11aa 23048 if (process_links && ! process_file_header (d->handle))
015dc7e1 23049 res = false;
ca0e11aa 23050 else if (! process_section_headers (d->handle))
015dc7e1 23051 res = false;
d6bfbc39 23052 else if (! process_section_contents (d->handle))
015dc7e1 23053 res = false;
ca0e11aa
NC
23054 else if (process_links)
23055 {
ca0e11aa 23056 if (! process_section_groups (d->handle))
015dc7e1 23057 res = false;
93df3340 23058 process_program_headers (d->handle);
ca0e11aa 23059 if (! process_dynamic_section (d->handle))
015dc7e1 23060 res = false;
ca0e11aa 23061 if (! process_relocs (d->handle))
015dc7e1 23062 res = false;
ca0e11aa 23063 if (! process_unwind (d->handle))
015dc7e1 23064 res = false;
ca0e11aa 23065 if (! process_symbol_table (d->handle))
015dc7e1 23066 res = false;
ca0e11aa 23067 if (! process_lto_symbol_tables (d->handle))
015dc7e1 23068 res = false;
ca0e11aa 23069 if (! process_syminfo (d->handle))
015dc7e1 23070 res = false;
ca0e11aa 23071 if (! process_version_sections (d->handle))
015dc7e1 23072 res = false;
ca0e11aa 23073 if (! process_notes (d->handle))
015dc7e1 23074 res = false;
ca0e11aa 23075 }
24841daa
NC
23076 }
23077
23078 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
23079 }
23080
23081 if (! process_notes (filedata))
015dc7e1 23082 res = false;
103f02d3 23083
dda8d76d 23084 if (! process_gnu_liblist (filedata))
015dc7e1 23085 res = false;
047b2264 23086
dda8d76d 23087 if (! process_arch_specific (filedata))
015dc7e1 23088 res = false;
252b5132 23089
4de91c10 23090 out:
13acb58d 23091 free_filedata (filedata);
e4b17d5c 23092
19e6b90e 23093 free_debug_memory ();
18bd398b 23094
32ec8896 23095 return res;
252b5132
RH
23096}
23097
2cf0635d 23098/* Process an ELF archive.
32ec8896
NC
23099 On entry the file is positioned just after the ARMAG string.
23100 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 23101
015dc7e1
AM
23102static bool
23103process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
23104{
23105 struct archive_info arch;
23106 struct archive_info nested_arch;
23107 size_t got;
015dc7e1 23108 bool ret = true;
2cf0635d 23109
015dc7e1 23110 show_name = true;
2cf0635d
NC
23111
23112 /* The ARCH structure is used to hold information about this archive. */
23113 arch.file_name = NULL;
23114 arch.file = NULL;
23115 arch.index_array = NULL;
23116 arch.sym_table = NULL;
23117 arch.longnames = NULL;
23118
23119 /* The NESTED_ARCH structure is used as a single-item cache of information
23120 about a nested archive (when members of a thin archive reside within
23121 another regular archive file). */
23122 nested_arch.file_name = NULL;
23123 nested_arch.file = NULL;
23124 nested_arch.index_array = NULL;
23125 nested_arch.sym_table = NULL;
23126 nested_arch.longnames = NULL;
23127
dda8d76d 23128 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
23129 filedata->file_size, is_thin_archive,
23130 do_archive_index) != 0)
2cf0635d 23131 {
015dc7e1 23132 ret = false;
2cf0635d 23133 goto out;
4145f1d5 23134 }
fb52b2f4 23135
4145f1d5
NC
23136 if (do_archive_index)
23137 {
2cf0635d 23138 if (arch.sym_table == NULL)
1cb7d8b1
AM
23139 error (_("%s: unable to dump the index as none was found\n"),
23140 filedata->file_name);
4145f1d5
NC
23141 else
23142 {
26c527e6
AM
23143 uint64_t i, l;
23144 uint64_t current_pos;
4145f1d5 23145
26c527e6
AM
23146 printf (_("Index of archive %s: (%" PRIu64 " entries,"
23147 " %#" PRIx64 " bytes in the symbol table)\n"),
23148 filedata->file_name, arch.index_num,
1cb7d8b1 23149 arch.sym_size);
dda8d76d
NC
23150
23151 current_pos = ftell (filedata->handle);
4145f1d5 23152
2cf0635d 23153 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 23154 {
1cb7d8b1
AM
23155 if (i == 0
23156 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
23157 {
23158 char * member_name
23159 = get_archive_member_name_at (&arch, arch.index_array[i],
23160 &nested_arch);
2cf0635d 23161
1cb7d8b1
AM
23162 if (member_name != NULL)
23163 {
23164 char * qualified_name
23165 = make_qualified_name (&arch, &nested_arch,
23166 member_name);
2cf0635d 23167
1cb7d8b1
AM
23168 if (qualified_name != NULL)
23169 {
23170 printf (_("Contents of binary %s at offset "),
23171 qualified_name);
c2a7d3f5
NC
23172 (void) print_vma (arch.index_array[i], PREFIX_HEX);
23173 putchar ('\n');
1cb7d8b1
AM
23174 free (qualified_name);
23175 }
fd486f32 23176 free (member_name);
4145f1d5
NC
23177 }
23178 }
2cf0635d
NC
23179
23180 if (l >= arch.sym_size)
4145f1d5 23181 {
1cb7d8b1
AM
23182 error (_("%s: end of the symbol table reached "
23183 "before the end of the index\n"),
dda8d76d 23184 filedata->file_name);
015dc7e1 23185 ret = false;
cb8f3167 23186 break;
4145f1d5 23187 }
591f7597 23188 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
23189 printf ("\t%.*s\n",
23190 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 23191 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
23192 }
23193
67ce483b 23194 if (arch.uses_64bit_indices)
c2a7d3f5
NC
23195 l = (l + 7) & ~ 7;
23196 else
23197 l += l & 1;
23198
2cf0635d 23199 if (l < arch.sym_size)
32ec8896 23200 {
26c527e6 23201 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
23202 "but without corresponding entries in "
23203 "the index table\n",
26c527e6 23204 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
23205 "but without corresponding entries in "
23206 "the index table\n",
23207 arch.sym_size - l),
dda8d76d 23208 filedata->file_name, arch.sym_size - l);
015dc7e1 23209 ret = false;
32ec8896 23210 }
4145f1d5 23211
63cf857e 23212 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 23213 {
1cb7d8b1
AM
23214 error (_("%s: failed to seek back to start of object files "
23215 "in the archive\n"),
dda8d76d 23216 filedata->file_name);
015dc7e1 23217 ret = false;
2cf0635d 23218 goto out;
4145f1d5 23219 }
fb52b2f4 23220 }
4145f1d5
NC
23221
23222 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
23223 && !do_segments && !do_header && !do_dump && !do_version
23224 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 23225 && !do_section_groups && !do_dyn_syms)
2cf0635d 23226 {
015dc7e1 23227 ret = true; /* Archive index only. */
2cf0635d
NC
23228 goto out;
23229 }
fb52b2f4
NC
23230 }
23231
fb52b2f4
NC
23232 while (1)
23233 {
2cf0635d
NC
23234 char * name;
23235 size_t namelen;
23236 char * qualified_name;
23237
23238 /* Read the next archive header. */
63cf857e 23239 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
23240 {
23241 error (_("%s: failed to seek to next archive header\n"),
23242 arch.file_name);
015dc7e1 23243 ret = false;
1cb7d8b1
AM
23244 break;
23245 }
dda8d76d 23246 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 23247 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
23248 {
23249 if (got == 0)
2cf0635d 23250 break;
28e817cc
NC
23251 /* PR 24049 - we cannot use filedata->file_name as this will
23252 have already been freed. */
23253 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 23254
015dc7e1 23255 ret = false;
1cb7d8b1
AM
23256 break;
23257 }
2cf0635d 23258 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
23259 {
23260 error (_("%s: did not find a valid archive header\n"),
23261 arch.file_name);
015dc7e1 23262 ret = false;
1cb7d8b1
AM
23263 break;
23264 }
2cf0635d
NC
23265
23266 arch.next_arhdr_offset += sizeof arch.arhdr;
23267
978c4450 23268 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
23269
23270 name = get_archive_member_name (&arch, &nested_arch);
23271 if (name == NULL)
fb52b2f4 23272 {
28e817cc 23273 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 23274 ret = false;
d989285c 23275 break;
fb52b2f4 23276 }
2cf0635d 23277 namelen = strlen (name);
fb52b2f4 23278
2cf0635d
NC
23279 qualified_name = make_qualified_name (&arch, &nested_arch, name);
23280 if (qualified_name == NULL)
fb52b2f4 23281 {
28e817cc 23282 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 23283 free (name);
015dc7e1 23284 ret = false;
d989285c 23285 break;
fb52b2f4
NC
23286 }
23287
2cf0635d 23288 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
23289 {
23290 /* This is a proxy for an external member of a thin archive. */
23291 Filedata * member_filedata;
23292 char * member_file_name = adjust_relative_path
dda8d76d 23293 (filedata->file_name, name, namelen);
32ec8896 23294
fd486f32 23295 free (name);
1cb7d8b1
AM
23296 if (member_file_name == NULL)
23297 {
fd486f32 23298 free (qualified_name);
015dc7e1 23299 ret = false;
1cb7d8b1
AM
23300 break;
23301 }
2cf0635d 23302
015dc7e1 23303 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
23304 if (member_filedata == NULL)
23305 {
23306 error (_("Input file '%s' is not readable.\n"), member_file_name);
23307 free (member_file_name);
fd486f32 23308 free (qualified_name);
015dc7e1 23309 ret = false;
1cb7d8b1
AM
23310 break;
23311 }
2cf0635d 23312
978c4450 23313 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 23314 member_filedata->file_name = qualified_name;
2cf0635d 23315
75a2da57
AH
23316 /* The call to process_object() expects the file to be at the beginning. */
23317 rewind (member_filedata->handle);
23318
1cb7d8b1 23319 if (! process_object (member_filedata))
015dc7e1 23320 ret = false;
2cf0635d 23321
1cb7d8b1
AM
23322 close_file (member_filedata);
23323 free (member_file_name);
1cb7d8b1 23324 }
2cf0635d 23325 else if (is_thin_archive)
1cb7d8b1
AM
23326 {
23327 Filedata thin_filedata;
eb02c04d 23328
1cb7d8b1 23329 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 23330
a043396b
NC
23331 /* PR 15140: Allow for corrupt thin archives. */
23332 if (nested_arch.file == NULL)
23333 {
23334 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 23335 qualified_name, name);
fd486f32
AM
23336 free (qualified_name);
23337 free (name);
015dc7e1 23338 ret = false;
a043396b
NC
23339 break;
23340 }
fd486f32 23341 free (name);
a043396b 23342
1cb7d8b1 23343 /* This is a proxy for a member of a nested archive. */
978c4450
AM
23344 filedata->archive_file_offset
23345 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 23346
1cb7d8b1
AM
23347 /* The nested archive file will have been opened and setup by
23348 get_archive_member_name. */
63cf857e
AM
23349 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
23350 SEEK_SET) != 0)
1cb7d8b1
AM
23351 {
23352 error (_("%s: failed to seek to archive member.\n"),
23353 nested_arch.file_name);
fd486f32 23354 free (qualified_name);
015dc7e1 23355 ret = false;
1cb7d8b1
AM
23356 break;
23357 }
2cf0635d 23358
dda8d76d
NC
23359 thin_filedata.handle = nested_arch.file;
23360 thin_filedata.file_name = qualified_name;
9abca702 23361
1cb7d8b1 23362 if (! process_object (& thin_filedata))
015dc7e1 23363 ret = false;
1cb7d8b1 23364 }
2cf0635d 23365 else
1cb7d8b1 23366 {
fd486f32 23367 free (name);
978c4450 23368 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 23369 filedata->file_name = qualified_name;
1cb7d8b1 23370 if (! process_object (filedata))
015dc7e1 23371 ret = false;
237877b8 23372 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 23373 /* Stop looping with "negative" archive_file_size. */
978c4450 23374 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 23375 arch.next_arhdr_offset = -1ul;
1cb7d8b1 23376 }
fb52b2f4 23377
2cf0635d 23378 free (qualified_name);
fb52b2f4
NC
23379 }
23380
4145f1d5 23381 out:
2cf0635d
NC
23382 if (nested_arch.file != NULL)
23383 fclose (nested_arch.file);
23384 release_archive (&nested_arch);
23385 release_archive (&arch);
fb52b2f4 23386
d989285c 23387 return ret;
fb52b2f4
NC
23388}
23389
015dc7e1 23390static bool
2cf0635d 23391process_file (char * file_name)
fb52b2f4 23392{
dda8d76d 23393 Filedata * filedata = NULL;
fb52b2f4
NC
23394 struct stat statbuf;
23395 char armag[SARMAG];
015dc7e1 23396 bool ret = true;
fb52b2f4
NC
23397
23398 if (stat (file_name, &statbuf) < 0)
23399 {
f24ddbdd
NC
23400 if (errno == ENOENT)
23401 error (_("'%s': No such file\n"), file_name);
23402 else
23403 error (_("Could not locate '%s'. System error message: %s\n"),
23404 file_name, strerror (errno));
015dc7e1 23405 return false;
f24ddbdd
NC
23406 }
23407
23408 if (! S_ISREG (statbuf.st_mode))
23409 {
23410 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 23411 return false;
fb52b2f4
NC
23412 }
23413
dda8d76d
NC
23414 filedata = calloc (1, sizeof * filedata);
23415 if (filedata == NULL)
23416 {
23417 error (_("Out of memory allocating file data structure\n"));
015dc7e1 23418 return false;
dda8d76d
NC
23419 }
23420
23421 filedata->file_name = file_name;
23422 filedata->handle = fopen (file_name, "rb");
23423 if (filedata->handle == NULL)
fb52b2f4 23424 {
f24ddbdd 23425 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 23426 free (filedata);
015dc7e1 23427 return false;
fb52b2f4
NC
23428 }
23429
dda8d76d 23430 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 23431 {
4145f1d5 23432 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
23433 fclose (filedata->handle);
23434 free (filedata);
015dc7e1 23435 return false;
fb52b2f4
NC
23436 }
23437
be7d229a 23438 filedata->file_size = statbuf.st_size;
015dc7e1 23439 filedata->is_separate = false;
f54498b4 23440
fb52b2f4 23441 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 23442 {
015dc7e1
AM
23443 if (! process_archive (filedata, false))
23444 ret = false;
32ec8896 23445 }
2cf0635d 23446 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 23447 {
015dc7e1
AM
23448 if ( ! process_archive (filedata, true))
23449 ret = false;
32ec8896 23450 }
fb52b2f4
NC
23451 else
23452 {
1b513401 23453 if (do_archive_index && !check_all)
4145f1d5
NC
23454 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23455 file_name);
23456
dda8d76d 23457 rewind (filedata->handle);
978c4450 23458 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 23459
dda8d76d 23460 if (! process_object (filedata))
015dc7e1 23461 ret = false;
fb52b2f4
NC
23462 }
23463
dda8d76d 23464 fclose (filedata->handle);
8fb879cd
AM
23465 free (filedata->section_headers);
23466 free (filedata->program_headers);
23467 free (filedata->string_table);
6431e409 23468 free (filedata->dump.dump_sects);
dda8d76d 23469 free (filedata);
32ec8896 23470
fd486f32 23471 free (ba_cache.strtab);
1bd6175a 23472 ba_cache.strtab = NULL;
fd486f32 23473 free (ba_cache.symtab);
1bd6175a 23474 ba_cache.symtab = NULL;
fd486f32
AM
23475 ba_cache.filedata = NULL;
23476
fb52b2f4
NC
23477 return ret;
23478}
23479
252b5132
RH
23480#ifdef SUPPORT_DISASSEMBLY
23481/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 23482 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 23483 symbols. */
252b5132
RH
23484
23485void
2cf0635d 23486print_address (unsigned int addr, FILE * outfile)
252b5132
RH
23487{
23488 fprintf (outfile,"0x%8.8x", addr);
23489}
23490
e3c8793a 23491/* Needed by the i386 disassembler. */
dda8d76d 23492
252b5132
RH
23493void
23494db_task_printsym (unsigned int addr)
23495{
23496 print_address (addr, stderr);
23497}
23498#endif
23499
23500int
2cf0635d 23501main (int argc, char ** argv)
252b5132 23502{
ff78d6d6
L
23503 int err;
23504
87b9f255 23505#ifdef HAVE_LC_MESSAGES
252b5132 23506 setlocale (LC_MESSAGES, "");
3882b010 23507#endif
3882b010 23508 setlocale (LC_CTYPE, "");
252b5132
RH
23509 bindtextdomain (PACKAGE, LOCALEDIR);
23510 textdomain (PACKAGE);
23511
869b9d07
MM
23512 expandargv (&argc, &argv);
23513
dda8d76d 23514 parse_args (& cmdline, argc, argv);
59f14fc0 23515
18bd398b 23516 if (optind < (argc - 1))
1b513401
NC
23517 /* When displaying information for more than one file,
23518 prefix the information with the file name. */
015dc7e1 23519 show_name = true;
5656ba2c
L
23520 else if (optind >= argc)
23521 {
1b513401 23522 /* Ensure that the warning is always displayed. */
015dc7e1 23523 do_checks = true;
1b513401 23524
5656ba2c
L
23525 warn (_("Nothing to do.\n"));
23526 usage (stderr);
23527 }
18bd398b 23528
015dc7e1 23529 err = false;
252b5132 23530 while (optind < argc)
32ec8896 23531 if (! process_file (argv[optind++]))
015dc7e1 23532 err = true;
252b5132 23533
9db70fc3 23534 free (cmdline.dump_sects);
252b5132 23535
7d9813f1
NA
23536 free (dump_ctf_symtab_name);
23537 free (dump_ctf_strtab_name);
23538 free (dump_ctf_parent_name);
23539
32ec8896 23540 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 23541}