]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
bpf: gas: add field overflow checking to the BPF assembler
[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"
252b5132 171
252b5132 172#include "getopt.h"
566b0d53 173#include "libiberty.h"
09c11c86 174#include "safe-ctype.h"
2cf0635d 175#include "filenames.h"
252b5132 176
15b42fb0
AM
177#ifndef offsetof
178#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
179#endif
180
6a40cf0c
NC
181typedef struct elf_section_list
182{
dda8d76d
NC
183 Elf_Internal_Shdr * hdr;
184 struct elf_section_list * next;
6a40cf0c
NC
185} elf_section_list;
186
dda8d76d
NC
187/* Flag bits indicating particular types of dump. */
188#define HEX_DUMP (1 << 0) /* The -x command line switch. */
189#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
190#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
191#define STRING_DUMP (1 << 3) /* The -p command line switch. */
192#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 193#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
42b6953b 194#define SFRAME_DUMP (1 << 6) /* The --sframe command line switch. */
dda8d76d
NC
195
196typedef unsigned char dump_type;
197
198/* A linked list of the section names for which dumps were requested. */
199struct dump_list_entry
200{
201 char * name;
202 dump_type type;
203 struct dump_list_entry * next;
204};
205
6431e409
AM
206/* A dynamic array of flags indicating for which sections a dump
207 has been requested via command line switches. */
1b513401
NC
208struct dump_data
209{
6431e409
AM
210 dump_type * dump_sects;
211 unsigned int num_dump_sects;
212};
213
214static struct dump_data cmdline;
215
216static struct dump_list_entry * dump_sects_byname;
217
2cf0635d 218char * program_name = "readelf";
dda8d76d 219
015dc7e1
AM
220static bool show_name = false;
221static bool do_dynamic = false;
222static bool do_syms = false;
223static bool do_dyn_syms = false;
224static bool do_lto_syms = false;
225static bool do_reloc = false;
226static bool do_sections = false;
227static bool do_section_groups = false;
228static bool do_section_details = false;
229static bool do_segments = false;
230static bool do_unwind = false;
231static bool do_using_dynamic = false;
232static bool do_header = false;
233static bool do_dump = false;
234static bool do_version = false;
235static bool do_histogram = false;
236static bool do_debugging = false;
237static bool do_ctf = false;
42b6953b 238static bool do_sframe = false;
015dc7e1
AM
239static bool do_arch = false;
240static bool do_notes = false;
241static bool do_archive_index = false;
242static bool check_all = false;
243static bool is_32bit_elf = false;
244static bool decompress_dumps = false;
245static bool do_not_show_symbol_truncation = false;
246static bool do_demangle = false; /* Pretty print C++ symbol names. */
247static bool process_links = false;
e1dbfc17 248static bool dump_any_debugging = false;
79bc120c 249static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 250static int sym_base = 0;
252b5132 251
7d9813f1
NA
252static char *dump_ctf_parent_name;
253static char *dump_ctf_symtab_name;
254static char *dump_ctf_strtab_name;
255
e4b17d5c
L
256struct group_list
257{
dda8d76d
NC
258 struct group_list * next;
259 unsigned int section_index;
e4b17d5c
L
260};
261
262struct group
263{
dda8d76d
NC
264 struct group_list * root;
265 unsigned int group_index;
e4b17d5c
L
266};
267
978c4450
AM
268typedef struct filedata
269{
270 const char * file_name;
015dc7e1 271 bool is_separate;
978c4450 272 FILE * handle;
be7d229a 273 uint64_t file_size;
978c4450 274 Elf_Internal_Ehdr file_header;
26c527e6
AM
275 uint64_t archive_file_offset;
276 uint64_t archive_file_size;
066f8fbe 277 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
278 Elf_Internal_Shdr * section_headers;
279 Elf_Internal_Phdr * program_headers;
280 char * string_table;
26c527e6
AM
281 uint64_t string_table_length;
282 uint64_t dynamic_addr;
be7d229a 283 uint64_t dynamic_size;
26c527e6 284 uint64_t dynamic_nent;
978c4450 285 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 286 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450 287 char * dynamic_strings;
26c527e6 288 uint64_t dynamic_strings_length;
8ac10c5b 289 Elf_Internal_Shdr * dynamic_symtab_section;
26c527e6 290 uint64_t num_dynamic_syms;
978c4450 291 Elf_Internal_Sym * dynamic_symbols;
26c527e6 292 uint64_t version_info[16];
978c4450
AM
293 unsigned int dynamic_syminfo_nent;
294 Elf_Internal_Syminfo * dynamic_syminfo;
26c527e6 295 uint64_t dynamic_syminfo_offset;
be7d229a
AM
296 uint64_t nbuckets;
297 uint64_t nchains;
625d49fc
AM
298 uint64_t * buckets;
299 uint64_t * chains;
be7d229a
AM
300 uint64_t ngnubuckets;
301 uint64_t ngnuchains;
625d49fc
AM
302 uint64_t * gnubuckets;
303 uint64_t * gnuchains;
304 uint64_t * mipsxlat;
305 uint64_t gnusymidx;
13acb58d 306 char * program_interpreter;
bc227f4c 307 uint64_t dynamic_info[DT_RELRENT + 1];
625d49fc
AM
308 uint64_t dynamic_info_DT_GNU_HASH;
309 uint64_t dynamic_info_DT_MIPS_XHASH;
978c4450
AM
310 elf_section_list * symtab_shndx_list;
311 size_t group_count;
312 struct group * section_groups;
313 struct group ** section_headers_groups;
314 /* A dynamic array of flags indicating for which sections a dump of
315 some kind has been requested. It is reset on a per-object file
316 basis and then initialised from the cmdline_dump_sects array,
317 the results of interpreting the -w switch, and the
318 dump_sects_byname list. */
319 struct dump_data dump;
320} Filedata;
aef1f6d0 321
c256ffe7 322/* How to print a vma value. */
843dd992
NC
323typedef enum print_mode
324{
325 HEX,
047c3dbf 326 HEX_5,
843dd992
NC
327 DEC,
328 DEC_5,
329 UNSIGNED,
047c3dbf 330 UNSIGNED_5,
843dd992 331 PREFIX_HEX,
047c3dbf 332 PREFIX_HEX_5,
843dd992 333 FULL_HEX,
047c3dbf
NL
334 LONG_HEX,
335 OCTAL,
336 OCTAL_5
843dd992
NC
337}
338print_mode;
339
b3aa80b4
NC
340typedef enum unicode_display_type
341{
342 unicode_default = 0,
343 unicode_locale,
344 unicode_escape,
345 unicode_hex,
346 unicode_highlight,
347 unicode_invalid
348} unicode_display_type;
349
350static unicode_display_type unicode_display = unicode_default;
351
a7fd1186
FS
352typedef enum
353{
354 reltype_unknown,
355 reltype_rel,
356 reltype_rela,
357 reltype_relr
358} relocation_type;
359
bb4d2ac2
L
360/* Versioned symbol info. */
361enum versioned_symbol_info
362{
363 symbol_undefined,
364 symbol_hidden,
365 symbol_public
366};
367
63cf857e
AM
368static int
369fseek64 (FILE *stream, int64_t offset, int whence)
370{
371#if defined (HAVE_FSEEKO64)
372 off64_t o = offset;
373 if (o != offset)
374 {
375 errno = EINVAL;
376 return -1;
377 }
378 return fseeko64 (stream, o, whence);
379#elif defined (HAVE_FSEEKO)
380 off_t o = offset;
381 if (o != offset)
382 {
383 errno = EINVAL;
384 return -1;
385 }
386 return fseeko (stream, o, whence);
387#else
388 long o = offset;
389 if (o != offset)
390 {
391 errno = EINVAL;
392 return -1;
393 }
394 return fseek (stream, o, whence);
395#endif
396}
397
32ec8896 398static const char * get_symbol_version_string
26c527e6 399 (Filedata *, bool, const char *, size_t, unsigned,
32ec8896 400 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 401
9c19a809
NC
402#define UNKNOWN -1
403
84714f86
AM
404static inline const char *
405section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
406{
407 return filedata->string_table + hdr->sh_name;
408}
b9e920ec 409
84714f86
AM
410static inline bool
411section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
412{
413 return (hdr != NULL
414 && filedata->string_table != NULL
415 && hdr->sh_name < filedata->string_table_length);
416}
b9e920ec 417
84714f86
AM
418static inline const char *
419section_name_print (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
420{
421 if (hdr == NULL)
422 return _("<none>");
423 if (filedata->string_table == NULL)
424 return _("<no-strings>");
425 if (hdr->sh_name >= filedata->string_table_length)
426 return _("<corrupt>");
427 return section_name (filedata, hdr);
428}
252b5132 429
ee42cf8c 430#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 431
84714f86
AM
432static inline bool
433valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
434{
435 return strtab != NULL && offset < strtab_size;
436}
437
438static inline bool
439valid_dynamic_name (const Filedata *filedata, uint64_t offset)
440{
441 return valid_symbol_name (filedata->dynamic_strings,
442 filedata->dynamic_strings_length, offset);
443}
444
d79b3d50
NC
445/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
446 already been called and verified that the string exists. */
84714f86
AM
447static inline const char *
448get_dynamic_name (const Filedata *filedata, size_t offset)
449{
450 return filedata->dynamic_strings + offset;
451}
18bd398b 452
61865e30
NC
453#define REMOVE_ARCH_BITS(ADDR) \
454 do \
455 { \
dda8d76d 456 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
457 (ADDR) &= ~1; \
458 } \
459 while (0)
f16a9783
MS
460
461/* Get the correct GNU hash section name. */
978c4450
AM
462#define GNU_HASH_SECTION_NAME(filedata) \
463 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 464\f
dda8d76d
NC
465/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
466 OFFSET + the offset of the current archive member, if we are examining an
467 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
468 allocate a buffer using malloc and fill that. In either case return the
469 pointer to the start of the retrieved data or NULL if something went wrong.
470 If something does go wrong and REASON is not NULL then emit an error
471 message using REASON as part of the context. */
59245841 472
c256ffe7 473static void *
be7d229a
AM
474get_data (void *var,
475 Filedata *filedata,
26c527e6 476 uint64_t offset,
be7d229a
AM
477 uint64_t size,
478 uint64_t nmemb,
479 const char *reason)
a6e9f9df 480{
2cf0635d 481 void * mvar;
be7d229a 482 uint64_t amt = size * nmemb;
a6e9f9df 483
c256ffe7 484 if (size == 0 || nmemb == 0)
a6e9f9df
AM
485 return NULL;
486
be7d229a
AM
487 /* If size_t is smaller than uint64_t, eg because you are building
488 on a 32-bit host, then make sure that when the sizes are cast to
489 size_t no information is lost. */
7c1c1904
AM
490 if ((size_t) size != size
491 || (size_t) nmemb != nmemb
be7d229a
AM
492 || (size_t) amt != amt
493 || amt / size != nmemb
494 || (size_t) amt + 1 == 0)
57028622
NC
495 {
496 if (reason)
b8281767
AM
497 error (_("Size overflow prevents reading %" PRIu64
498 " elements of size %" PRIu64 " for %s\n"),
be7d229a 499 nmemb, size, reason);
57028622
NC
500 return NULL;
501 }
502
c22b42ce 503 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 504 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
505 if (filedata->archive_file_offset > filedata->file_size
506 || offset > filedata->file_size - filedata->archive_file_offset
507 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 508 {
049b0c3a 509 if (reason)
b8281767 510 error (_("Reading %" PRIu64 " bytes extends past end of file for %s\n"),
be7d229a 511 amt, reason);
a6e9f9df
AM
512 return NULL;
513 }
514
63cf857e
AM
515 if (fseek64 (filedata->handle, filedata->archive_file_offset + offset,
516 SEEK_SET))
071436c6
NC
517 {
518 if (reason)
26c527e6 519 error (_("Unable to seek to %#" PRIx64 " for %s\n"),
978c4450 520 filedata->archive_file_offset + offset, reason);
071436c6
NC
521 return NULL;
522 }
523
a6e9f9df
AM
524 mvar = var;
525 if (mvar == NULL)
526 {
7c1c1904
AM
527 /* + 1 so that we can '\0' terminate invalid string table sections. */
528 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
529
530 if (mvar == NULL)
531 {
049b0c3a 532 if (reason)
b8281767 533 error (_("Out of memory allocating %" PRIu64 " bytes for %s\n"),
be7d229a 534 amt, reason);
a6e9f9df
AM
535 return NULL;
536 }
c256ffe7 537
c9c1d674 538 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
539 }
540
dda8d76d 541 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 542 {
049b0c3a 543 if (reason)
b8281767 544 error (_("Unable to read in %" PRIu64 " bytes of %s\n"),
be7d229a 545 amt, reason);
a6e9f9df
AM
546 if (mvar != var)
547 free (mvar);
548 return NULL;
549 }
550
551 return mvar;
552}
553
32ec8896
NC
554/* Print a VMA value in the MODE specified.
555 Returns the number of characters displayed. */
cb8f3167 556
32ec8896 557static unsigned int
625d49fc 558print_vma (uint64_t vma, print_mode mode)
66543521 559{
32ec8896 560 unsigned int nc = 0;
66543521 561
14a91970 562 switch (mode)
66543521 563 {
14a91970
AM
564 case FULL_HEX:
565 nc = printf ("0x");
1a0670f3 566 /* Fall through. */
14a91970 567 case LONG_HEX:
f493c217 568 if (!is_32bit_elf)
625d49fc
AM
569 return nc + printf ("%16.16" PRIx64, vma);
570 return nc + printf ("%8.8" PRIx64, vma);
b19aac67 571
14a91970
AM
572 case DEC_5:
573 if (vma <= 99999)
625d49fc 574 return printf ("%5" PRId64, vma);
1a0670f3 575 /* Fall through. */
14a91970
AM
576 case PREFIX_HEX:
577 nc = printf ("0x");
1a0670f3 578 /* Fall through. */
14a91970 579 case HEX:
625d49fc 580 return nc + printf ("%" PRIx64, vma);
b19aac67 581
047c3dbf
NL
582 case PREFIX_HEX_5:
583 nc = printf ("0x");
584 /* Fall through. */
585 case HEX_5:
625d49fc 586 return nc + printf ("%05" PRIx64, vma);
047c3dbf 587
14a91970 588 case DEC:
625d49fc 589 return printf ("%" PRId64, vma);
b19aac67 590
14a91970 591 case UNSIGNED:
625d49fc 592 return printf ("%" PRIu64, vma);
32ec8896 593
047c3dbf 594 case UNSIGNED_5:
625d49fc 595 return printf ("%5" PRIu64, vma);
047c3dbf
NL
596
597 case OCTAL:
625d49fc 598 return printf ("%" PRIo64, vma);
047c3dbf
NL
599
600 case OCTAL_5:
625d49fc 601 return printf ("%5" PRIo64, vma);
047c3dbf 602
32ec8896
NC
603 default:
604 /* FIXME: Report unrecognised mode ? */
605 return 0;
f7a99963 606 }
f7a99963
NC
607}
608
047c3dbf 609
7bfd842d 610/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 611 multibye characters (assuming the host environment supports them).
31104126 612
7bfd842d
NC
613 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
614
0942c7ab
NC
615 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
616 abs(WIDTH) - 5 characters followed by "[...]".
617
7bfd842d
NC
618 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
619 padding as necessary.
171191ba
NC
620
621 Returns the number of emitted characters. */
622
623static unsigned int
0942c7ab 624print_symbol (signed int width, const char * symbol)
31104126 625{
015dc7e1
AM
626 bool extra_padding = false;
627 bool do_dots = false;
32ec8896 628 signed int num_printed = 0;
3bfcb652 629#ifdef HAVE_MBSTATE_T
7bfd842d 630 mbstate_t state;
3bfcb652 631#endif
32ec8896 632 unsigned int width_remaining;
79bc120c 633 const void * alloced_symbol = NULL;
961c521f 634
7bfd842d 635 if (width < 0)
961c521f 636 {
88305e1b 637 /* Keep the width positive. This helps the code below. */
961c521f 638 width = - width;
015dc7e1 639 extra_padding = true;
0b4362b0 640 }
56d8f8a9
NC
641 else if (width == 0)
642 return 0;
961c521f 643
7bfd842d
NC
644 if (do_wide)
645 /* Set the remaining width to a very large value.
646 This simplifies the code below. */
647 width_remaining = INT_MAX;
648 else
0942c7ab
NC
649 {
650 width_remaining = width;
651 if (! do_not_show_symbol_truncation
652 && (int) strlen (symbol) > width)
653 {
654 width_remaining -= 5;
655 if ((int) width_remaining < 0)
656 width_remaining = 0;
015dc7e1 657 do_dots = true;
0942c7ab
NC
658 }
659 }
cb8f3167 660
3bfcb652 661#ifdef HAVE_MBSTATE_T
7bfd842d
NC
662 /* Initialise the multibyte conversion state. */
663 memset (& state, 0, sizeof (state));
3bfcb652 664#endif
961c521f 665
79bc120c
NC
666 if (do_demangle && *symbol)
667 {
668 const char * res = cplus_demangle (symbol, demangle_flags);
669
670 if (res != NULL)
671 alloced_symbol = symbol = res;
672 }
673
7bfd842d
NC
674 while (width_remaining)
675 {
676 size_t n;
7bfd842d 677 const char c = *symbol++;
961c521f 678
7bfd842d 679 if (c == 0)
961c521f
NC
680 break;
681
b3aa80b4
NC
682 if (ISPRINT (c))
683 {
684 putchar (c);
685 width_remaining --;
686 num_printed ++;
687 }
688 else if (ISCNTRL (c))
961c521f 689 {
b3aa80b4
NC
690 /* Do not print control characters directly as they can affect terminal
691 settings. Such characters usually appear in the names generated
692 by the assembler for local labels. */
693
7bfd842d 694 if (width_remaining < 2)
961c521f
NC
695 break;
696
7bfd842d
NC
697 printf ("^%c", c + 0x40);
698 width_remaining -= 2;
171191ba 699 num_printed += 2;
961c521f 700 }
b3aa80b4 701 else if (c == 0x7f)
7bfd842d 702 {
b3aa80b4
NC
703 if (width_remaining < 5)
704 break;
705 printf ("<DEL>");
706 width_remaining -= 5;
707 num_printed += 5;
708 }
709 else if (unicode_display != unicode_locale
710 && unicode_display != unicode_default)
711 {
712 /* Display unicode characters as something else. */
713 unsigned char bytes[4];
714 bool is_utf8;
795588ae 715 unsigned int nbytes;
b3aa80b4
NC
716
717 bytes[0] = c;
718
719 if (bytes[0] < 0xc0)
720 {
721 nbytes = 1;
722 is_utf8 = false;
723 }
724 else
725 {
726 bytes[1] = *symbol++;
727
728 if ((bytes[1] & 0xc0) != 0x80)
729 {
730 is_utf8 = false;
731 /* Do not consume this character. It may only
732 be the first byte in the sequence that was
733 corrupt. */
734 --symbol;
735 nbytes = 1;
736 }
737 else if ((bytes[0] & 0x20) == 0)
738 {
739 is_utf8 = true;
740 nbytes = 2;
741 }
742 else
743 {
744 bytes[2] = *symbol++;
745
746 if ((bytes[2] & 0xc0) != 0x80)
747 {
748 is_utf8 = false;
749 symbol -= 2;
750 nbytes = 1;
751 }
752 else if ((bytes[0] & 0x10) == 0)
753 {
754 is_utf8 = true;
755 nbytes = 3;
756 }
757 else
758 {
759 bytes[3] = *symbol++;
760
761 nbytes = 4;
762
763 if ((bytes[3] & 0xc0) != 0x80)
764 {
765 is_utf8 = false;
766 symbol -= 3;
767 nbytes = 1;
768 }
769 else
770 is_utf8 = true;
771 }
772 }
773 }
774
775 if (unicode_display == unicode_invalid)
776 is_utf8 = false;
777
778 if (unicode_display == unicode_hex || ! is_utf8)
779 {
795588ae 780 unsigned int i;
b3aa80b4
NC
781
782 if (width_remaining < (nbytes * 2) + 2)
783 break;
784
785 putchar (is_utf8 ? '<' : '{');
786 printf ("0x");
787 for (i = 0; i < nbytes; i++)
788 printf ("%02x", bytes[i]);
789 putchar (is_utf8 ? '>' : '}');
790 }
791 else
792 {
793 if (unicode_display == unicode_highlight && isatty (1))
794 printf ("\x1B[31;47m"); /* Red. */
795
796 switch (nbytes)
797 {
798 case 2:
799 if (width_remaining < 6)
800 break;
801 printf ("\\u%02x%02x",
802 (bytes[0] & 0x1c) >> 2,
803 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
804 break;
805 case 3:
806 if (width_remaining < 6)
807 break;
808 printf ("\\u%02x%02x",
809 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
810 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
811 break;
812 case 4:
813 if (width_remaining < 8)
814 break;
815 printf ("\\u%02x%02x%02x",
816 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
817 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
818 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
819
820 break;
821 default:
822 /* URG. */
823 break;
824 }
825
826 if (unicode_display == unicode_highlight && isatty (1))
827 printf ("\033[0m"); /* Default colour. */
828 }
829
830 if (bytes[nbytes - 1] == 0)
831 break;
7bfd842d 832 }
961c521f
NC
833 else
834 {
3bfcb652
NC
835#ifdef HAVE_MBSTATE_T
836 wchar_t w;
837#endif
7bfd842d
NC
838 /* Let printf do the hard work of displaying multibyte characters. */
839 printf ("%.1s", symbol - 1);
840 width_remaining --;
841 num_printed ++;
842
3bfcb652 843#ifdef HAVE_MBSTATE_T
7bfd842d
NC
844 /* Try to find out how many bytes made up the character that was
845 just printed. Advance the symbol pointer past the bytes that
846 were displayed. */
847 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
848#else
849 n = 1;
850#endif
7bfd842d
NC
851 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
852 symbol += (n - 1);
961c521f 853 }
961c521f 854 }
171191ba 855
0942c7ab
NC
856 if (do_dots)
857 num_printed += printf ("[...]");
858
7bfd842d 859 if (extra_padding && num_printed < width)
171191ba
NC
860 {
861 /* Fill in the remaining spaces. */
7bfd842d
NC
862 printf ("%-*s", width - num_printed, " ");
863 num_printed = width;
171191ba
NC
864 }
865
79bc120c 866 free ((void *) alloced_symbol);
171191ba 867 return num_printed;
31104126
NC
868}
869
1449284b 870/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
871 the given section's name. Like print_symbol, except that it does not try
872 to print multibyte characters, it just interprets them as hex values. */
873
874static const char *
dda8d76d 875printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 876{
ca0e11aa 877#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 878 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
84714f86 879 const char * name = section_name_print (filedata, sec);
74e1a04b
NC
880 char * buf = sec_name_buf;
881 char c;
882 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
883
884 while ((c = * name ++) != 0)
885 {
886 if (ISCNTRL (c))
887 {
888 if (remaining < 2)
889 break;
948f632f 890
74e1a04b
NC
891 * buf ++ = '^';
892 * buf ++ = c + 0x40;
893 remaining -= 2;
894 }
895 else if (ISPRINT (c))
896 {
897 * buf ++ = c;
898 remaining -= 1;
899 }
900 else
901 {
902 static char hex[17] = "0123456789ABCDEF";
903
904 if (remaining < 4)
905 break;
906 * buf ++ = '<';
907 * buf ++ = hex[(c & 0xf0) >> 4];
908 * buf ++ = hex[c & 0x0f];
909 * buf ++ = '>';
910 remaining -= 4;
911 }
912
913 if (remaining == 0)
914 break;
915 }
916
917 * buf = 0;
918 return sec_name_buf;
919}
920
921static const char *
26c527e6 922printable_section_name_from_index (Filedata *filedata, size_t ndx)
74e1a04b 923{
dda8d76d 924 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
925 return _("<corrupt>");
926
dda8d76d 927 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
928}
929
89fac5e3
RS
930/* Return a pointer to section NAME, or NULL if no such section exists. */
931
932static Elf_Internal_Shdr *
dda8d76d 933find_section (Filedata * filedata, const char * name)
89fac5e3
RS
934{
935 unsigned int i;
936
68807c3c
NC
937 if (filedata->section_headers == NULL)
938 return NULL;
dda8d76d
NC
939
940 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
941 if (section_name_valid (filedata, filedata->section_headers + i)
942 && streq (section_name (filedata, filedata->section_headers + i),
943 name))
dda8d76d 944 return filedata->section_headers + i;
89fac5e3
RS
945
946 return NULL;
947}
948
0b6ae522
DJ
949/* Return a pointer to a section containing ADDR, or NULL if no such
950 section exists. */
951
952static Elf_Internal_Shdr *
625d49fc 953find_section_by_address (Filedata * filedata, uint64_t addr)
0b6ae522
DJ
954{
955 unsigned int i;
956
68807c3c
NC
957 if (filedata->section_headers == NULL)
958 return NULL;
959
dda8d76d 960 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 961 {
dda8d76d
NC
962 Elf_Internal_Shdr *sec = filedata->section_headers + i;
963
0b6ae522
DJ
964 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
965 return sec;
966 }
967
968 return NULL;
969}
970
071436c6 971static Elf_Internal_Shdr *
dda8d76d 972find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
973{
974 unsigned int i;
975
68807c3c
NC
976 if (filedata->section_headers == NULL)
977 return NULL;
978
dda8d76d 979 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 980 {
dda8d76d
NC
981 Elf_Internal_Shdr *sec = filedata->section_headers + i;
982
071436c6
NC
983 if (sec->sh_type == type)
984 return sec;
985 }
986
987 return NULL;
988}
989
657d0d47
CC
990/* Return a pointer to section NAME, or NULL if no such section exists,
991 restricted to the list of sections given in SET. */
992
993static Elf_Internal_Shdr *
dda8d76d 994find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
995{
996 unsigned int i;
997
68807c3c
NC
998 if (filedata->section_headers == NULL)
999 return NULL;
1000
657d0d47
CC
1001 if (set != NULL)
1002 {
1003 while ((i = *set++) > 0)
b814a36d
NC
1004 {
1005 /* See PR 21156 for a reproducer. */
dda8d76d 1006 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
1007 continue; /* FIXME: Should we issue an error message ? */
1008
84714f86
AM
1009 if (section_name_valid (filedata, filedata->section_headers + i)
1010 && streq (section_name (filedata, filedata->section_headers + i),
1011 name))
dda8d76d 1012 return filedata->section_headers + i;
b814a36d 1013 }
657d0d47
CC
1014 }
1015
dda8d76d 1016 return find_section (filedata, name);
657d0d47
CC
1017}
1018
32ec8896 1019/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
1020 This OS has so many departures from the ELF standard that we test it at
1021 many places. */
1022
015dc7e1 1023static inline bool
dda8d76d 1024is_ia64_vms (Filedata * filedata)
28f997cf 1025{
dda8d76d
NC
1026 return filedata->file_header.e_machine == EM_IA_64
1027 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
1028}
1029
bcedfee6 1030/* Guess the relocation size commonly used by the specific machines. */
252b5132 1031
015dc7e1 1032static bool
2dc4cec1 1033guess_is_rela (unsigned int e_machine)
252b5132 1034{
9c19a809 1035 switch (e_machine)
252b5132
RH
1036 {
1037 /* Targets that use REL relocations. */
252b5132 1038 case EM_386:
22abe556 1039 case EM_IAMCU:
f954747f 1040 case EM_960:
e9f53129 1041 case EM_ARM:
2b0337b0 1042 case EM_D10V:
252b5132 1043 case EM_CYGNUS_D10V:
e9f53129 1044 case EM_DLX:
252b5132 1045 case EM_MIPS:
4fe85591 1046 case EM_MIPS_RS3_LE:
e9f53129 1047 case EM_CYGNUS_M32R:
1c0d3aa6 1048 case EM_SCORE:
f6c1a2d5 1049 case EM_XGATE:
fe944acf 1050 case EM_NFP:
aca4efc7 1051 case EM_BPF:
015dc7e1 1052 return false;
103f02d3 1053
252b5132
RH
1054 /* Targets that use RELA relocations. */
1055 case EM_68K:
f954747f 1056 case EM_860:
a06ea964 1057 case EM_AARCH64:
cfb8c092 1058 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1059 case EM_ALPHA:
1060 case EM_ALTERA_NIOS2:
886a2506
NC
1061 case EM_ARC:
1062 case EM_ARC_COMPACT:
1063 case EM_ARC_COMPACT2:
13aa307c
CZ
1064 case EM_ARC_COMPACT3:
1065 case EM_ARC_COMPACT3_64:
e9f53129
AM
1066 case EM_AVR:
1067 case EM_AVR_OLD:
1068 case EM_BLACKFIN:
60bca95a 1069 case EM_CR16:
e9f53129
AM
1070 case EM_CRIS:
1071 case EM_CRX:
b8891f8d 1072 case EM_CSKY:
2b0337b0 1073 case EM_D30V:
252b5132 1074 case EM_CYGNUS_D30V:
2b0337b0 1075 case EM_FR30:
3f8107ab 1076 case EM_FT32:
252b5132 1077 case EM_CYGNUS_FR30:
5c70f934 1078 case EM_CYGNUS_FRV:
e9f53129
AM
1079 case EM_H8S:
1080 case EM_H8_300:
1081 case EM_H8_300H:
800eeca4 1082 case EM_IA_64:
1e4cf259
NC
1083 case EM_IP2K:
1084 case EM_IP2K_OLD:
3b36097d 1085 case EM_IQ2000:
84e94c90 1086 case EM_LATTICEMICO32:
ff7eeb89 1087 case EM_M32C_OLD:
49f58d10 1088 case EM_M32C:
e9f53129
AM
1089 case EM_M32R:
1090 case EM_MCORE:
15ab5209 1091 case EM_CYGNUS_MEP:
a3c62988 1092 case EM_METAG:
e9f53129
AM
1093 case EM_MMIX:
1094 case EM_MN10200:
1095 case EM_CYGNUS_MN10200:
1096 case EM_MN10300:
1097 case EM_CYGNUS_MN10300:
5506d11a 1098 case EM_MOXIE:
e9f53129
AM
1099 case EM_MSP430:
1100 case EM_MSP430_OLD:
d031aafb 1101 case EM_MT:
35c08157 1102 case EM_NDS32:
64fd6348 1103 case EM_NIOS32:
73589c9d 1104 case EM_OR1K:
e9f53129
AM
1105 case EM_PPC64:
1106 case EM_PPC:
2b100bb5 1107 case EM_TI_PRU:
e23eba97 1108 case EM_RISCV:
99c513f6 1109 case EM_RL78:
c7927a3c 1110 case EM_RX:
e9f53129
AM
1111 case EM_S390:
1112 case EM_S390_OLD:
1113 case EM_SH:
1114 case EM_SPARC:
1115 case EM_SPARC32PLUS:
1116 case EM_SPARCV9:
1117 case EM_SPU:
40b36596 1118 case EM_TI_C6000:
aa137e4d
NC
1119 case EM_TILEGX:
1120 case EM_TILEPRO:
708e2187 1121 case EM_V800:
e9f53129
AM
1122 case EM_V850:
1123 case EM_CYGNUS_V850:
1124 case EM_VAX:
619ed720 1125 case EM_VISIUM:
e9f53129 1126 case EM_X86_64:
8a9036a4 1127 case EM_L1OM:
7a9068fe 1128 case EM_K1OM:
e9f53129
AM
1129 case EM_XSTORMY16:
1130 case EM_XTENSA:
1131 case EM_XTENSA_OLD:
7ba29e2a
NC
1132 case EM_MICROBLAZE:
1133 case EM_MICROBLAZE_OLD:
f96bd6c2 1134 case EM_WEBASSEMBLY:
015dc7e1 1135 return true;
103f02d3 1136
e9f53129
AM
1137 case EM_68HC05:
1138 case EM_68HC08:
1139 case EM_68HC11:
1140 case EM_68HC16:
1141 case EM_FX66:
1142 case EM_ME16:
d1133906 1143 case EM_MMA:
d1133906
NC
1144 case EM_NCPU:
1145 case EM_NDR1:
e9f53129 1146 case EM_PCP:
d1133906 1147 case EM_ST100:
e9f53129 1148 case EM_ST19:
d1133906 1149 case EM_ST7:
e9f53129
AM
1150 case EM_ST9PLUS:
1151 case EM_STARCORE:
d1133906 1152 case EM_SVX:
e9f53129 1153 case EM_TINYJ:
9c19a809
NC
1154 default:
1155 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1156 return false;
9c19a809
NC
1157 }
1158}
252b5132 1159
dda8d76d 1160/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1161 Returns TRUE upon success, FALSE otherwise. If successful then a
1162 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1163 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1164 responsibility to free the allocated buffer. */
1165
015dc7e1 1166static bool
26c527e6
AM
1167slurp_rela_relocs (Filedata *filedata,
1168 uint64_t rel_offset,
1169 uint64_t rel_size,
1170 Elf_Internal_Rela **relasp,
1171 uint64_t *nrelasp)
9c19a809 1172{
2cf0635d 1173 Elf_Internal_Rela * relas;
26c527e6 1174 uint64_t nrelas;
4d6ed7c8 1175 unsigned int i;
252b5132 1176
4d6ed7c8
NC
1177 if (is_32bit_elf)
1178 {
2cf0635d 1179 Elf32_External_Rela * erelas;
103f02d3 1180
dda8d76d 1181 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1182 rel_size, _("32-bit relocation data"));
a6e9f9df 1183 if (!erelas)
015dc7e1 1184 return false;
252b5132 1185
4d6ed7c8 1186 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1187
3f5e193b
NC
1188 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1189 sizeof (Elf_Internal_Rela));
103f02d3 1190
4d6ed7c8
NC
1191 if (relas == NULL)
1192 {
c256ffe7 1193 free (erelas);
591a748a 1194 error (_("out of memory parsing relocs\n"));
015dc7e1 1195 return false;
4d6ed7c8 1196 }
103f02d3 1197
4d6ed7c8
NC
1198 for (i = 0; i < nrelas; i++)
1199 {
1200 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1201 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1202 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1203 }
103f02d3 1204
4d6ed7c8
NC
1205 free (erelas);
1206 }
1207 else
1208 {
2cf0635d 1209 Elf64_External_Rela * erelas;
103f02d3 1210
dda8d76d 1211 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1212 rel_size, _("64-bit relocation data"));
a6e9f9df 1213 if (!erelas)
015dc7e1 1214 return false;
4d6ed7c8
NC
1215
1216 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1217
3f5e193b
NC
1218 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1219 sizeof (Elf_Internal_Rela));
103f02d3 1220
4d6ed7c8
NC
1221 if (relas == NULL)
1222 {
c256ffe7 1223 free (erelas);
591a748a 1224 error (_("out of memory parsing relocs\n"));
015dc7e1 1225 return false;
9c19a809 1226 }
4d6ed7c8
NC
1227
1228 for (i = 0; i < nrelas; i++)
9c19a809 1229 {
66543521
AM
1230 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1231 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1232 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a 1233
dda8d76d
NC
1234 if (filedata->file_header.e_machine == EM_MIPS
1235 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1236 {
1237 /* In little-endian objects, r_info isn't really a
1238 64-bit little-endian value: it has a 32-bit
1239 little-endian symbol index followed by four
1240 individual byte fields. Reorder INFO
1241 accordingly. */
625d49fc 1242 uint64_t inf = relas[i].r_info;
91d6fa6a
NC
1243 inf = (((inf & 0xffffffff) << 32)
1244 | ((inf >> 56) & 0xff)
1245 | ((inf >> 40) & 0xff00)
1246 | ((inf >> 24) & 0xff0000)
1247 | ((inf >> 8) & 0xff000000));
1248 relas[i].r_info = inf;
861fb55a 1249 }
4d6ed7c8 1250 }
103f02d3 1251
4d6ed7c8
NC
1252 free (erelas);
1253 }
32ec8896 1254
4d6ed7c8
NC
1255 *relasp = relas;
1256 *nrelasp = nrelas;
015dc7e1 1257 return true;
4d6ed7c8 1258}
103f02d3 1259
dda8d76d 1260/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1261 Returns TRUE upon success, FALSE otherwise. If successful then a
1262 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1263 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1264 responsibility to free the allocated buffer. */
1265
015dc7e1 1266static bool
26c527e6
AM
1267slurp_rel_relocs (Filedata *filedata,
1268 uint64_t rel_offset,
1269 uint64_t rel_size,
1270 Elf_Internal_Rela **relsp,
1271 uint64_t *nrelsp)
4d6ed7c8 1272{
2cf0635d 1273 Elf_Internal_Rela * rels;
26c527e6 1274 uint64_t nrels;
4d6ed7c8 1275 unsigned int i;
103f02d3 1276
4d6ed7c8
NC
1277 if (is_32bit_elf)
1278 {
2cf0635d 1279 Elf32_External_Rel * erels;
103f02d3 1280
dda8d76d 1281 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1282 rel_size, _("32-bit relocation data"));
a6e9f9df 1283 if (!erels)
015dc7e1 1284 return false;
103f02d3 1285
4d6ed7c8 1286 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1287
3f5e193b 1288 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1289
4d6ed7c8
NC
1290 if (rels == NULL)
1291 {
c256ffe7 1292 free (erels);
591a748a 1293 error (_("out of memory parsing relocs\n"));
015dc7e1 1294 return false;
4d6ed7c8
NC
1295 }
1296
1297 for (i = 0; i < nrels; i++)
1298 {
1299 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1300 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1301 rels[i].r_addend = 0;
9ea033b2 1302 }
4d6ed7c8
NC
1303
1304 free (erels);
9c19a809
NC
1305 }
1306 else
1307 {
2cf0635d 1308 Elf64_External_Rel * erels;
9ea033b2 1309
dda8d76d 1310 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1311 rel_size, _("64-bit relocation data"));
a6e9f9df 1312 if (!erels)
015dc7e1 1313 return false;
103f02d3 1314
4d6ed7c8 1315 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1316
3f5e193b 1317 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1318
4d6ed7c8 1319 if (rels == NULL)
9c19a809 1320 {
c256ffe7 1321 free (erels);
591a748a 1322 error (_("out of memory parsing relocs\n"));
015dc7e1 1323 return false;
4d6ed7c8 1324 }
103f02d3 1325
4d6ed7c8
NC
1326 for (i = 0; i < nrels; i++)
1327 {
66543521
AM
1328 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1329 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1330 rels[i].r_addend = 0;
861fb55a 1331
dda8d76d
NC
1332 if (filedata->file_header.e_machine == EM_MIPS
1333 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1334 {
1335 /* In little-endian objects, r_info isn't really a
1336 64-bit little-endian value: it has a 32-bit
1337 little-endian symbol index followed by four
1338 individual byte fields. Reorder INFO
1339 accordingly. */
625d49fc 1340 uint64_t inf = rels[i].r_info;
91d6fa6a
NC
1341 inf = (((inf & 0xffffffff) << 32)
1342 | ((inf >> 56) & 0xff)
1343 | ((inf >> 40) & 0xff00)
1344 | ((inf >> 24) & 0xff0000)
1345 | ((inf >> 8) & 0xff000000));
1346 rels[i].r_info = inf;
861fb55a 1347 }
4d6ed7c8 1348 }
103f02d3 1349
4d6ed7c8
NC
1350 free (erels);
1351 }
32ec8896 1352
4d6ed7c8
NC
1353 *relsp = rels;
1354 *nrelsp = nrels;
015dc7e1 1355 return true;
4d6ed7c8 1356}
103f02d3 1357
a7fd1186 1358static bool
26c527e6
AM
1359slurp_relr_relocs (Filedata *filedata,
1360 uint64_t relr_offset,
1361 uint64_t relr_size,
1362 uint64_t **relrsp,
1363 uint64_t *nrelrsp)
a7fd1186
FS
1364{
1365 void *relrs;
1366 size_t size = 0, nentries, i;
625d49fc 1367 uint64_t base = 0, addr, entry;
a7fd1186
FS
1368
1369 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1370 _("RELR relocation data"));
1371 if (!relrs)
1372 return false;
1373
1374 if (is_32bit_elf)
1375 nentries = relr_size / sizeof (Elf32_External_Relr);
1376 else
1377 nentries = relr_size / sizeof (Elf64_External_Relr);
1378 for (i = 0; i < nentries; i++)
1379 {
1380 if (is_32bit_elf)
1381 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1382 else
1383 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1384 if ((entry & 1) == 0)
1385 size++;
1386 else
1387 while ((entry >>= 1) != 0)
1388 if ((entry & 1) == 1)
1389 size++;
1390 }
1391
625d49fc 1392 *relrsp = malloc (size * sizeof (**relrsp));
a7fd1186
FS
1393 if (*relrsp == NULL)
1394 {
1395 free (relrs);
1396 error (_("out of memory parsing relocs\n"));
1397 return false;
1398 }
1399
1400 size = 0;
1401 for (i = 0; i < nentries; i++)
1402 {
625d49fc 1403 const uint64_t entry_bytes = is_32bit_elf ? 4 : 8;
a7fd1186
FS
1404
1405 if (is_32bit_elf)
1406 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1407 else
1408 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1409 if ((entry & 1) == 0)
1410 {
1411 (*relrsp)[size++] = entry;
1412 base = entry + entry_bytes;
1413 }
1414 else
1415 {
1416 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1417 if ((entry & 1) != 0)
1418 (*relrsp)[size++] = addr;
1419 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1420 }
1421 }
1422
1423 *nrelrsp = size;
1424 free (relrs);
1425 return true;
1426}
1427
aca88567
NC
1428/* Returns the reloc type extracted from the reloc info field. */
1429
1430static unsigned int
625d49fc 1431get_reloc_type (Filedata * filedata, uint64_t reloc_info)
aca88567
NC
1432{
1433 if (is_32bit_elf)
1434 return ELF32_R_TYPE (reloc_info);
1435
dda8d76d 1436 switch (filedata->file_header.e_machine)
aca88567
NC
1437 {
1438 case EM_MIPS:
1439 /* Note: We assume that reloc_info has already been adjusted for us. */
1440 return ELF64_MIPS_R_TYPE (reloc_info);
1441
1442 case EM_SPARCV9:
1443 return ELF64_R_TYPE_ID (reloc_info);
1444
1445 default:
1446 return ELF64_R_TYPE (reloc_info);
1447 }
1448}
1449
1450/* Return the symbol index extracted from the reloc info field. */
1451
625d49fc
AM
1452static uint64_t
1453get_reloc_symindex (uint64_t reloc_info)
aca88567
NC
1454{
1455 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1456}
1457
015dc7e1 1458static inline bool
dda8d76d 1459uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1460{
1461 return
dda8d76d 1462 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1463 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1464 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1465 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1466 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1467}
1468
d3ba0551
AM
1469/* Display the contents of the relocation data found at the specified
1470 offset. */
ee42cf8c 1471
015dc7e1 1472static bool
26c527e6
AM
1473dump_relocations (Filedata *filedata,
1474 uint64_t rel_offset,
1475 uint64_t rel_size,
1476 Elf_Internal_Sym *symtab,
1477 uint64_t nsyms,
1478 char *strtab,
1479 uint64_t strtablen,
1480 relocation_type rel_type,
1481 bool is_dynsym)
1482{
1483 size_t i;
2cf0635d 1484 Elf_Internal_Rela * rels;
015dc7e1 1485 bool res = true;
103f02d3 1486
a7fd1186
FS
1487 if (rel_type == reltype_unknown)
1488 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1489
a7fd1186 1490 if (rel_type == reltype_rela)
4d6ed7c8 1491 {
dda8d76d 1492 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1493 return false;
4d6ed7c8 1494 }
a7fd1186 1495 else if (rel_type == reltype_rel)
4d6ed7c8 1496 {
dda8d76d 1497 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1498 return false;
252b5132 1499 }
a7fd1186
FS
1500 else if (rel_type == reltype_relr)
1501 {
625d49fc 1502 uint64_t * relrs;
a7fd1186 1503 const char *format
b8281767 1504 = is_32bit_elf ? "%08" PRIx64 "\n" : "%016" PRIx64 "\n";
a7fd1186
FS
1505
1506 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1507 &rel_size))
1508 return false;
1509
26c527e6
AM
1510 printf (ngettext (" %" PRIu64 " offset\n",
1511 " %" PRIu64 " offsets\n", rel_size),
b8281767 1512 rel_size);
a7fd1186 1513 for (i = 0; i < rel_size; i++)
625d49fc 1514 printf (format, relrs[i]);
a7fd1186
FS
1515 free (relrs);
1516 return true;
1517 }
252b5132 1518
410f7a12
L
1519 if (is_32bit_elf)
1520 {
a7fd1186 1521 if (rel_type == reltype_rela)
2c71103e
NC
1522 {
1523 if (do_wide)
1524 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1525 else
1526 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1527 }
410f7a12 1528 else
2c71103e
NC
1529 {
1530 if (do_wide)
1531 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1532 else
1533 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1534 }
410f7a12 1535 }
252b5132 1536 else
410f7a12 1537 {
a7fd1186 1538 if (rel_type == reltype_rela)
2c71103e
NC
1539 {
1540 if (do_wide)
8beeaeb7 1541 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1542 else
1543 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1544 }
410f7a12 1545 else
2c71103e
NC
1546 {
1547 if (do_wide)
8beeaeb7 1548 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1549 else
1550 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1551 }
410f7a12 1552 }
252b5132
RH
1553
1554 for (i = 0; i < rel_size; i++)
1555 {
2cf0635d 1556 const char * rtype;
625d49fc
AM
1557 uint64_t offset;
1558 uint64_t inf;
1559 uint64_t symtab_index;
1560 uint64_t type;
103f02d3 1561
b34976b6 1562 offset = rels[i].r_offset;
91d6fa6a 1563 inf = rels[i].r_info;
103f02d3 1564
dda8d76d 1565 type = get_reloc_type (filedata, inf);
91d6fa6a 1566 symtab_index = get_reloc_symindex (inf);
252b5132 1567
410f7a12
L
1568 if (is_32bit_elf)
1569 {
39dbeff8
AM
1570 printf ("%8.8lx %8.8lx ",
1571 (unsigned long) offset & 0xffffffff,
91d6fa6a 1572 (unsigned long) inf & 0xffffffff);
410f7a12
L
1573 }
1574 else
1575 {
39dbeff8 1576 printf (do_wide
b8281767
AM
1577 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
1578 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
625d49fc 1579 offset, inf);
410f7a12 1580 }
103f02d3 1581
dda8d76d 1582 switch (filedata->file_header.e_machine)
252b5132
RH
1583 {
1584 default:
1585 rtype = NULL;
1586 break;
1587
a06ea964
NC
1588 case EM_AARCH64:
1589 rtype = elf_aarch64_reloc_type (type);
1590 break;
1591
2b0337b0 1592 case EM_M32R:
252b5132 1593 case EM_CYGNUS_M32R:
9ea033b2 1594 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1595 break;
1596
1597 case EM_386:
22abe556 1598 case EM_IAMCU:
9ea033b2 1599 rtype = elf_i386_reloc_type (type);
252b5132
RH
1600 break;
1601
ba2685cc
AM
1602 case EM_68HC11:
1603 case EM_68HC12:
1604 rtype = elf_m68hc11_reloc_type (type);
1605 break;
75751cd9 1606
7b4ae824
JD
1607 case EM_S12Z:
1608 rtype = elf_s12z_reloc_type (type);
1609 break;
1610
252b5132 1611 case EM_68K:
9ea033b2 1612 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1613 break;
1614
f954747f
AM
1615 case EM_960:
1616 rtype = elf_i960_reloc_type (type);
1617 break;
1618
adde6300 1619 case EM_AVR:
2b0337b0 1620 case EM_AVR_OLD:
adde6300
AM
1621 rtype = elf_avr_reloc_type (type);
1622 break;
1623
9ea033b2
NC
1624 case EM_OLD_SPARCV9:
1625 case EM_SPARC32PLUS:
1626 case EM_SPARCV9:
252b5132 1627 case EM_SPARC:
9ea033b2 1628 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1629 break;
1630
e9f53129
AM
1631 case EM_SPU:
1632 rtype = elf_spu_reloc_type (type);
1633 break;
1634
708e2187
NC
1635 case EM_V800:
1636 rtype = v800_reloc_type (type);
1637 break;
2b0337b0 1638 case EM_V850:
252b5132 1639 case EM_CYGNUS_V850:
9ea033b2 1640 rtype = v850_reloc_type (type);
252b5132
RH
1641 break;
1642
2b0337b0 1643 case EM_D10V:
252b5132 1644 case EM_CYGNUS_D10V:
9ea033b2 1645 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1646 break;
1647
2b0337b0 1648 case EM_D30V:
252b5132 1649 case EM_CYGNUS_D30V:
9ea033b2 1650 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1651 break;
1652
d172d4ba
NC
1653 case EM_DLX:
1654 rtype = elf_dlx_reloc_type (type);
1655 break;
1656
252b5132 1657 case EM_SH:
9ea033b2 1658 rtype = elf_sh_reloc_type (type);
252b5132
RH
1659 break;
1660
2b0337b0 1661 case EM_MN10300:
252b5132 1662 case EM_CYGNUS_MN10300:
9ea033b2 1663 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1664 break;
1665
2b0337b0 1666 case EM_MN10200:
252b5132 1667 case EM_CYGNUS_MN10200:
9ea033b2 1668 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1669 break;
1670
2b0337b0 1671 case EM_FR30:
252b5132 1672 case EM_CYGNUS_FR30:
9ea033b2 1673 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1674 break;
1675
ba2685cc
AM
1676 case EM_CYGNUS_FRV:
1677 rtype = elf_frv_reloc_type (type);
1678 break;
5c70f934 1679
b8891f8d
AJ
1680 case EM_CSKY:
1681 rtype = elf_csky_reloc_type (type);
1682 break;
1683
3f8107ab
AM
1684 case EM_FT32:
1685 rtype = elf_ft32_reloc_type (type);
1686 break;
1687
252b5132 1688 case EM_MCORE:
9ea033b2 1689 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1690 break;
1691
3c3bdf30
NC
1692 case EM_MMIX:
1693 rtype = elf_mmix_reloc_type (type);
1694 break;
1695
5506d11a
AM
1696 case EM_MOXIE:
1697 rtype = elf_moxie_reloc_type (type);
1698 break;
1699
2469cfa2 1700 case EM_MSP430:
dda8d76d 1701 if (uses_msp430x_relocs (filedata))
13761a11
NC
1702 {
1703 rtype = elf_msp430x_reloc_type (type);
1704 break;
1705 }
1a0670f3 1706 /* Fall through. */
2469cfa2
NC
1707 case EM_MSP430_OLD:
1708 rtype = elf_msp430_reloc_type (type);
1709 break;
1710
35c08157
KLC
1711 case EM_NDS32:
1712 rtype = elf_nds32_reloc_type (type);
1713 break;
1714
252b5132 1715 case EM_PPC:
9ea033b2 1716 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1717 break;
1718
c833c019
AM
1719 case EM_PPC64:
1720 rtype = elf_ppc64_reloc_type (type);
1721 break;
1722
252b5132 1723 case EM_MIPS:
4fe85591 1724 case EM_MIPS_RS3_LE:
9ea033b2 1725 rtype = elf_mips_reloc_type (type);
252b5132
RH
1726 break;
1727
e23eba97
NC
1728 case EM_RISCV:
1729 rtype = elf_riscv_reloc_type (type);
1730 break;
1731
252b5132 1732 case EM_ALPHA:
9ea033b2 1733 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1734 break;
1735
1736 case EM_ARM:
9ea033b2 1737 rtype = elf_arm_reloc_type (type);
252b5132
RH
1738 break;
1739
584da044 1740 case EM_ARC:
886a2506
NC
1741 case EM_ARC_COMPACT:
1742 case EM_ARC_COMPACT2:
13aa307c
CZ
1743 case EM_ARC_COMPACT3:
1744 case EM_ARC_COMPACT3_64:
9ea033b2 1745 rtype = elf_arc_reloc_type (type);
252b5132
RH
1746 break;
1747
1748 case EM_PARISC:
69e617ca 1749 rtype = elf_hppa_reloc_type (type);
252b5132 1750 break;
7d466069 1751
b8720f9d
JL
1752 case EM_H8_300:
1753 case EM_H8_300H:
1754 case EM_H8S:
1755 rtype = elf_h8_reloc_type (type);
1756 break;
1757
73589c9d
CS
1758 case EM_OR1K:
1759 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1760 break;
1761
7d466069 1762 case EM_PJ:
2b0337b0 1763 case EM_PJ_OLD:
7d466069
ILT
1764 rtype = elf_pj_reloc_type (type);
1765 break;
800eeca4
JW
1766 case EM_IA_64:
1767 rtype = elf_ia64_reloc_type (type);
1768 break;
1b61cf92
HPN
1769
1770 case EM_CRIS:
1771 rtype = elf_cris_reloc_type (type);
1772 break;
535c37ff 1773
f954747f
AM
1774 case EM_860:
1775 rtype = elf_i860_reloc_type (type);
1776 break;
1777
bcedfee6 1778 case EM_X86_64:
8a9036a4 1779 case EM_L1OM:
7a9068fe 1780 case EM_K1OM:
bcedfee6
NC
1781 rtype = elf_x86_64_reloc_type (type);
1782 break;
a85d7ed0 1783
f954747f
AM
1784 case EM_S370:
1785 rtype = i370_reloc_type (type);
1786 break;
1787
53c7db4b
KH
1788 case EM_S390_OLD:
1789 case EM_S390:
1790 rtype = elf_s390_reloc_type (type);
1791 break;
93fbbb04 1792
1c0d3aa6
NC
1793 case EM_SCORE:
1794 rtype = elf_score_reloc_type (type);
1795 break;
1796
93fbbb04
GK
1797 case EM_XSTORMY16:
1798 rtype = elf_xstormy16_reloc_type (type);
1799 break;
179d3252 1800
1fe1f39c
NC
1801 case EM_CRX:
1802 rtype = elf_crx_reloc_type (type);
1803 break;
1804
179d3252
JT
1805 case EM_VAX:
1806 rtype = elf_vax_reloc_type (type);
1807 break;
1e4cf259 1808
619ed720
EB
1809 case EM_VISIUM:
1810 rtype = elf_visium_reloc_type (type);
1811 break;
1812
aca4efc7
JM
1813 case EM_BPF:
1814 rtype = elf_bpf_reloc_type (type);
1815 break;
1816
cfb8c092
NC
1817 case EM_ADAPTEVA_EPIPHANY:
1818 rtype = elf_epiphany_reloc_type (type);
1819 break;
1820
1e4cf259
NC
1821 case EM_IP2K:
1822 case EM_IP2K_OLD:
1823 rtype = elf_ip2k_reloc_type (type);
1824 break;
3b36097d
SC
1825
1826 case EM_IQ2000:
1827 rtype = elf_iq2000_reloc_type (type);
1828 break;
88da6820
NC
1829
1830 case EM_XTENSA_OLD:
1831 case EM_XTENSA:
1832 rtype = elf_xtensa_reloc_type (type);
1833 break;
a34e3ecb 1834
84e94c90
NC
1835 case EM_LATTICEMICO32:
1836 rtype = elf_lm32_reloc_type (type);
1837 break;
1838
ff7eeb89 1839 case EM_M32C_OLD:
49f58d10
JB
1840 case EM_M32C:
1841 rtype = elf_m32c_reloc_type (type);
1842 break;
1843
d031aafb
NS
1844 case EM_MT:
1845 rtype = elf_mt_reloc_type (type);
a34e3ecb 1846 break;
1d65ded4
CM
1847
1848 case EM_BLACKFIN:
1849 rtype = elf_bfin_reloc_type (type);
1850 break;
15ab5209
DB
1851
1852 case EM_CYGNUS_MEP:
1853 rtype = elf_mep_reloc_type (type);
1854 break;
60bca95a
NC
1855
1856 case EM_CR16:
1857 rtype = elf_cr16_reloc_type (type);
1858 break;
dd24e3da 1859
7ba29e2a
NC
1860 case EM_MICROBLAZE:
1861 case EM_MICROBLAZE_OLD:
1862 rtype = elf_microblaze_reloc_type (type);
1863 break;
c7927a3c 1864
99c513f6
DD
1865 case EM_RL78:
1866 rtype = elf_rl78_reloc_type (type);
1867 break;
1868
c7927a3c
NC
1869 case EM_RX:
1870 rtype = elf_rx_reloc_type (type);
1871 break;
c29aca4a 1872
a3c62988
NC
1873 case EM_METAG:
1874 rtype = elf_metag_reloc_type (type);
1875 break;
1876
40b36596
JM
1877 case EM_TI_C6000:
1878 rtype = elf_tic6x_reloc_type (type);
1879 break;
aa137e4d
NC
1880
1881 case EM_TILEGX:
1882 rtype = elf_tilegx_reloc_type (type);
1883 break;
1884
1885 case EM_TILEPRO:
1886 rtype = elf_tilepro_reloc_type (type);
1887 break;
f6c1a2d5 1888
f96bd6c2
PC
1889 case EM_WEBASSEMBLY:
1890 rtype = elf_wasm32_reloc_type (type);
1891 break;
1892
f6c1a2d5
NC
1893 case EM_XGATE:
1894 rtype = elf_xgate_reloc_type (type);
1895 break;
36591ba1
SL
1896
1897 case EM_ALTERA_NIOS2:
1898 rtype = elf_nios2_reloc_type (type);
1899 break;
2b100bb5
DD
1900
1901 case EM_TI_PRU:
1902 rtype = elf_pru_reloc_type (type);
1903 break;
fe944acf
FT
1904
1905 case EM_NFP:
1906 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1907 rtype = elf_nfp3200_reloc_type (type);
1908 else
1909 rtype = elf_nfp_reloc_type (type);
1910 break;
6655dba2
SB
1911
1912 case EM_Z80:
1913 rtype = elf_z80_reloc_type (type);
1914 break;
e9a0721f 1915
1916 case EM_LOONGARCH:
1917 rtype = elf_loongarch_reloc_type (type);
1918 break;
1919
0c857ef4
SM
1920 case EM_AMDGPU:
1921 rtype = elf_amdgpu_reloc_type (type);
1922 break;
252b5132
RH
1923 }
1924
1925 if (rtype == NULL)
39dbeff8 1926 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1927 else
5c144731 1928 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1929
dda8d76d 1930 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1931 && rtype != NULL
7ace3541 1932 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 1933 && rel_type == reltype_rela)
7ace3541
RH
1934 {
1935 switch (rels[i].r_addend)
1936 {
1937 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1938 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1939 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1940 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1941 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1942 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1943 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1944 default: rtype = NULL;
1945 }
32ec8896 1946
7ace3541
RH
1947 if (rtype)
1948 printf (" (%s)", rtype);
1949 else
1950 {
1951 putchar (' ');
26c527e6
AM
1952 printf (_("<unknown addend: %" PRIx64 ">"),
1953 rels[i].r_addend);
015dc7e1 1954 res = false;
7ace3541
RH
1955 }
1956 }
1957 else if (symtab_index)
252b5132 1958 {
af3fc3bc 1959 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1960 {
27a45f42
AS
1961 error (_(" bad symbol index: %08lx in reloc\n"),
1962 (unsigned long) symtab_index);
015dc7e1 1963 res = false;
32ec8896 1964 }
af3fc3bc 1965 else
19936277 1966 {
2cf0635d 1967 Elf_Internal_Sym * psym;
bb4d2ac2
L
1968 const char * version_string;
1969 enum versioned_symbol_info sym_info;
1970 unsigned short vna_other;
19936277 1971
af3fc3bc 1972 psym = symtab + symtab_index;
103f02d3 1973
bb4d2ac2 1974 version_string
dda8d76d 1975 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1976 strtab, strtablen,
1977 symtab_index,
1978 psym,
1979 &sym_info,
1980 &vna_other);
1981
af3fc3bc 1982 printf (" ");
171191ba 1983
d8045f23
NC
1984 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1985 {
1986 const char * name;
1987 unsigned int len;
1988 unsigned int width = is_32bit_elf ? 8 : 14;
1989
1990 /* Relocations against GNU_IFUNC symbols do not use the value
1991 of the symbol as the address to relocate against. Instead
1992 they invoke the function named by the symbol and use its
1993 result as the address for relocation.
1994
1995 To indicate this to the user, do not display the value of
1996 the symbol in the "Symbols's Value" field. Instead show
1997 its name followed by () as a hint that the symbol is
1998 invoked. */
1999
2000 if (strtab == NULL
2001 || psym->st_name == 0
2002 || psym->st_name >= strtablen)
2003 name = "??";
2004 else
2005 name = strtab + psym->st_name;
2006
2007 len = print_symbol (width, name);
bb4d2ac2
L
2008 if (version_string)
2009 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2010 version_string);
d8045f23
NC
2011 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2012 }
2013 else
2014 {
2015 print_vma (psym->st_value, LONG_HEX);
171191ba 2016
d8045f23
NC
2017 printf (is_32bit_elf ? " " : " ");
2018 }
103f02d3 2019
af3fc3bc 2020 if (psym->st_name == 0)
f1ef08cb 2021 {
2cf0635d 2022 const char * sec_name = "<null>";
f1ef08cb
AM
2023 char name_buf[40];
2024
2025 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
2026 {
b9af6379
AM
2027 if (psym->st_shndx < filedata->file_header.e_shnum
2028 && filedata->section_headers != NULL)
84714f86
AM
2029 sec_name = section_name_print (filedata,
2030 filedata->section_headers
b9e920ec 2031 + psym->st_shndx);
f1ef08cb
AM
2032 else if (psym->st_shndx == SHN_ABS)
2033 sec_name = "ABS";
2034 else if (psym->st_shndx == SHN_COMMON)
2035 sec_name = "COMMON";
dda8d76d 2036 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 2037 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 2038 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 2039 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 2040 sec_name = "SCOMMON";
dda8d76d 2041 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
2042 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
2043 sec_name = "SUNDEF";
dda8d76d
NC
2044 else if ((filedata->file_header.e_machine == EM_X86_64
2045 || filedata->file_header.e_machine == EM_L1OM
2046 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
2047 && psym->st_shndx == SHN_X86_64_LCOMMON)
2048 sec_name = "LARGE_COMMON";
dda8d76d
NC
2049 else if (filedata->file_header.e_machine == EM_IA_64
2050 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
2051 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
2052 sec_name = "ANSI_COM";
dda8d76d 2053 else if (is_ia64_vms (filedata)
148b93f2
NC
2054 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
2055 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
2056 else
2057 {
2058 sprintf (name_buf, "<section 0x%x>",
2059 (unsigned int) psym->st_shndx);
2060 sec_name = name_buf;
2061 }
2062 }
2063 print_symbol (22, sec_name);
2064 }
af3fc3bc 2065 else if (strtab == NULL)
d79b3d50 2066 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2067 else if (psym->st_name >= strtablen)
32ec8896 2068 {
27a45f42
AS
2069 error (_("<corrupt string table index: %3ld>\n"),
2070 psym->st_name);
015dc7e1 2071 res = false;
32ec8896 2072 }
af3fc3bc 2073 else
bb4d2ac2
L
2074 {
2075 print_symbol (22, strtab + psym->st_name);
2076 if (version_string)
2077 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2078 version_string);
2079 }
103f02d3 2080
a7fd1186 2081 if (rel_type == reltype_rela)
171191ba 2082 {
625d49fc 2083 uint64_t off = rels[i].r_addend;
171191ba 2084
625d49fc
AM
2085 if ((int64_t) off < 0)
2086 printf (" - %" PRIx64, -off);
171191ba 2087 else
625d49fc 2088 printf (" + %" PRIx64, off);
171191ba 2089 }
19936277 2090 }
252b5132 2091 }
a7fd1186 2092 else if (rel_type == reltype_rela)
f7a99963 2093 {
625d49fc 2094 uint64_t off = rels[i].r_addend;
e04d7088
L
2095
2096 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
625d49fc
AM
2097 if ((int64_t) off < 0)
2098 printf ("-%" PRIx64, -off);
e04d7088 2099 else
625d49fc 2100 printf ("%" PRIx64, off);
f7a99963 2101 }
252b5132 2102
dda8d76d 2103 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2104 && rtype != NULL
2105 && streq (rtype, "R_SPARC_OLO10"))
26c527e6 2106 printf (" + %" PRIx64, ELF64_R_TYPE_DATA (inf));
351b4b40 2107
252b5132 2108 putchar ('\n');
2c71103e 2109
dda8d76d 2110 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2111 {
625d49fc
AM
2112 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2113 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2114 const char * rtype2 = elf_mips_reloc_type (type2);
2115 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2116
2c71103e
NC
2117 printf (" Type2: ");
2118
2119 if (rtype2 == NULL)
39dbeff8
AM
2120 printf (_("unrecognized: %-7lx"),
2121 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2122 else
2123 printf ("%-17.17s", rtype2);
2124
18bd398b 2125 printf ("\n Type3: ");
2c71103e
NC
2126
2127 if (rtype3 == NULL)
39dbeff8
AM
2128 printf (_("unrecognized: %-7lx"),
2129 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2130 else
2131 printf ("%-17.17s", rtype3);
2132
53c7db4b 2133 putchar ('\n');
2c71103e 2134 }
252b5132
RH
2135 }
2136
c8286bd1 2137 free (rels);
32ec8896
NC
2138
2139 return res;
252b5132
RH
2140}
2141
37c18eed
SD
2142static const char *
2143get_aarch64_dynamic_type (unsigned long type)
2144{
2145 switch (type)
2146 {
2147 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2148 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2149 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2150 default:
2151 return NULL;
2152 }
2153}
2154
252b5132 2155static const char *
d3ba0551 2156get_mips_dynamic_type (unsigned long type)
252b5132
RH
2157{
2158 switch (type)
2159 {
2160 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2161 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2162 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2163 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2164 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2165 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2166 case DT_MIPS_MSYM: return "MIPS_MSYM";
2167 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2168 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2169 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2170 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2171 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2172 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2173 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2174 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2175 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2176 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2177 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2178 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2179 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2180 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2181 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2182 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2183 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2184 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2185 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2186 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2187 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2188 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2189 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2190 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2191 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2192 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2193 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2194 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2195 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2196 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2197 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2198 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2199 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2200 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2201 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2202 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2203 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2204 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2205 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2206 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2207 default:
2208 return NULL;
2209 }
2210}
2211
9a097730 2212static const char *
d3ba0551 2213get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2214{
2215 switch (type)
2216 {
2217 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2218 default:
2219 return NULL;
2220 }
103f02d3
UD
2221}
2222
7490d522
AM
2223static const char *
2224get_ppc_dynamic_type (unsigned long type)
2225{
2226 switch (type)
2227 {
a7f2871e 2228 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2229 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2230 default:
2231 return NULL;
2232 }
2233}
2234
f1cb7e17 2235static const char *
d3ba0551 2236get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2237{
2238 switch (type)
2239 {
a7f2871e
AM
2240 case DT_PPC64_GLINK: return "PPC64_GLINK";
2241 case DT_PPC64_OPD: return "PPC64_OPD";
2242 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2243 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2244 default:
2245 return NULL;
2246 }
2247}
2248
103f02d3 2249static const char *
d3ba0551 2250get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2251{
2252 switch (type)
2253 {
2254 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2255 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2256 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2257 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2258 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2259 case DT_HP_PREINIT: return "HP_PREINIT";
2260 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2261 case DT_HP_NEEDED: return "HP_NEEDED";
2262 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2263 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2264 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2265 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2266 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2267 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2268 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2269 case DT_HP_FILTERED: return "HP_FILTERED";
2270 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2271 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2272 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2273 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2274 case DT_PLT: return "PLT";
2275 case DT_PLT_SIZE: return "PLT_SIZE";
2276 case DT_DLT: return "DLT";
2277 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2278 default:
2279 return NULL;
2280 }
2281}
9a097730 2282
ecc51f48 2283static const char *
d3ba0551 2284get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2285{
2286 switch (type)
2287 {
148b93f2
NC
2288 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2289 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2290 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2291 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2292 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2293 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2294 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2295 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2296 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2297 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2298 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2299 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2300 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2301 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2302 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2303 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2304 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2305 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2306 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2307 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2308 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2309 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2310 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2311 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2312 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2313 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2314 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2315 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2316 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2317 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2318 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2319 default:
2320 return NULL;
2321 }
2322}
2323
fd85a6a1
NC
2324static const char *
2325get_solaris_section_type (unsigned long type)
2326{
2327 switch (type)
2328 {
2329 case 0x6fffffee: return "SUNW_ancillary";
2330 case 0x6fffffef: return "SUNW_capchain";
2331 case 0x6ffffff0: return "SUNW_capinfo";
2332 case 0x6ffffff1: return "SUNW_symsort";
2333 case 0x6ffffff2: return "SUNW_tlssort";
2334 case 0x6ffffff3: return "SUNW_LDYNSYM";
2335 case 0x6ffffff4: return "SUNW_dof";
2336 case 0x6ffffff5: return "SUNW_cap";
2337 case 0x6ffffff6: return "SUNW_SIGNATURE";
2338 case 0x6ffffff7: return "SUNW_ANNOTATE";
2339 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2340 case 0x6ffffff9: return "SUNW_DEBUG";
2341 case 0x6ffffffa: return "SUNW_move";
2342 case 0x6ffffffb: return "SUNW_COMDAT";
2343 case 0x6ffffffc: return "SUNW_syminfo";
2344 case 0x6ffffffd: return "SUNW_verdef";
2345 case 0x6ffffffe: return "SUNW_verneed";
2346 case 0x6fffffff: return "SUNW_versym";
2347 case 0x70000000: return "SPARC_GOTDATA";
2348 default: return NULL;
2349 }
2350}
2351
fabcb361
RH
2352static const char *
2353get_alpha_dynamic_type (unsigned long type)
2354{
2355 switch (type)
2356 {
2357 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2358 default: return NULL;
fabcb361
RH
2359 }
2360}
2361
1c0d3aa6
NC
2362static const char *
2363get_score_dynamic_type (unsigned long type)
2364{
2365 switch (type)
2366 {
2367 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2368 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2369 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2370 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2371 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2372 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2373 default: return NULL;
1c0d3aa6
NC
2374 }
2375}
2376
40b36596
JM
2377static const char *
2378get_tic6x_dynamic_type (unsigned long type)
2379{
2380 switch (type)
2381 {
2382 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2383 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2384 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2385 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2386 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2387 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2388 default: return NULL;
40b36596
JM
2389 }
2390}
1c0d3aa6 2391
36591ba1
SL
2392static const char *
2393get_nios2_dynamic_type (unsigned long type)
2394{
2395 switch (type)
2396 {
2397 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2398 default: return NULL;
36591ba1
SL
2399 }
2400}
2401
fd85a6a1
NC
2402static const char *
2403get_solaris_dynamic_type (unsigned long type)
2404{
2405 switch (type)
2406 {
2407 case 0x6000000d: return "SUNW_AUXILIARY";
2408 case 0x6000000e: return "SUNW_RTLDINF";
2409 case 0x6000000f: return "SUNW_FILTER";
2410 case 0x60000010: return "SUNW_CAP";
2411 case 0x60000011: return "SUNW_SYMTAB";
2412 case 0x60000012: return "SUNW_SYMSZ";
2413 case 0x60000013: return "SUNW_SORTENT";
2414 case 0x60000014: return "SUNW_SYMSORT";
2415 case 0x60000015: return "SUNW_SYMSORTSZ";
2416 case 0x60000016: return "SUNW_TLSSORT";
2417 case 0x60000017: return "SUNW_TLSSORTSZ";
2418 case 0x60000018: return "SUNW_CAPINFO";
2419 case 0x60000019: return "SUNW_STRPAD";
2420 case 0x6000001a: return "SUNW_CAPCHAIN";
2421 case 0x6000001b: return "SUNW_LDMACH";
2422 case 0x6000001d: return "SUNW_CAPCHAINENT";
2423 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2424 case 0x60000021: return "SUNW_PARENT";
2425 case 0x60000023: return "SUNW_ASLR";
2426 case 0x60000025: return "SUNW_RELAX";
2427 case 0x60000029: return "SUNW_NXHEAP";
2428 case 0x6000002b: return "SUNW_NXSTACK";
2429
2430 case 0x70000001: return "SPARC_REGISTER";
2431 case 0x7ffffffd: return "AUXILIARY";
2432 case 0x7ffffffe: return "USED";
2433 case 0x7fffffff: return "FILTER";
2434
15f205b1 2435 default: return NULL;
fd85a6a1
NC
2436 }
2437}
2438
8155b853
NC
2439static const char *
2440get_riscv_dynamic_type (unsigned long type)
2441{
2442 switch (type)
2443 {
2444 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2445 default:
2446 return NULL;
2447 }
2448}
2449
252b5132 2450static const char *
dda8d76d 2451get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2452{
e9e44622 2453 static char buff[64];
252b5132
RH
2454
2455 switch (type)
2456 {
2457 case DT_NULL: return "NULL";
2458 case DT_NEEDED: return "NEEDED";
2459 case DT_PLTRELSZ: return "PLTRELSZ";
2460 case DT_PLTGOT: return "PLTGOT";
2461 case DT_HASH: return "HASH";
2462 case DT_STRTAB: return "STRTAB";
2463 case DT_SYMTAB: return "SYMTAB";
2464 case DT_RELA: return "RELA";
2465 case DT_RELASZ: return "RELASZ";
2466 case DT_RELAENT: return "RELAENT";
2467 case DT_STRSZ: return "STRSZ";
2468 case DT_SYMENT: return "SYMENT";
2469 case DT_INIT: return "INIT";
2470 case DT_FINI: return "FINI";
2471 case DT_SONAME: return "SONAME";
2472 case DT_RPATH: return "RPATH";
2473 case DT_SYMBOLIC: return "SYMBOLIC";
2474 case DT_REL: return "REL";
2475 case DT_RELSZ: return "RELSZ";
2476 case DT_RELENT: return "RELENT";
dd207c13
FS
2477 case DT_RELR: return "RELR";
2478 case DT_RELRSZ: return "RELRSZ";
2479 case DT_RELRENT: return "RELRENT";
252b5132
RH
2480 case DT_PLTREL: return "PLTREL";
2481 case DT_DEBUG: return "DEBUG";
2482 case DT_TEXTREL: return "TEXTREL";
2483 case DT_JMPREL: return "JMPREL";
2484 case DT_BIND_NOW: return "BIND_NOW";
2485 case DT_INIT_ARRAY: return "INIT_ARRAY";
2486 case DT_FINI_ARRAY: return "FINI_ARRAY";
2487 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2488 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2489 case DT_RUNPATH: return "RUNPATH";
2490 case DT_FLAGS: return "FLAGS";
2d0e6f43 2491
d1133906
NC
2492 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2493 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2494 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2495
05107a46 2496 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2497 case DT_PLTPADSZ: return "PLTPADSZ";
2498 case DT_MOVEENT: return "MOVEENT";
2499 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2500 case DT_FEATURE: return "FEATURE";
252b5132
RH
2501 case DT_POSFLAG_1: return "POSFLAG_1";
2502 case DT_SYMINSZ: return "SYMINSZ";
2503 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2504
252b5132 2505 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2506 case DT_CONFIG: return "CONFIG";
2507 case DT_DEPAUDIT: return "DEPAUDIT";
2508 case DT_AUDIT: return "AUDIT";
2509 case DT_PLTPAD: return "PLTPAD";
2510 case DT_MOVETAB: return "MOVETAB";
252b5132 2511 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2512
252b5132 2513 case DT_VERSYM: return "VERSYM";
103f02d3 2514
67a4f2b7
AO
2515 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2516 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2517 case DT_RELACOUNT: return "RELACOUNT";
2518 case DT_RELCOUNT: return "RELCOUNT";
2519 case DT_FLAGS_1: return "FLAGS_1";
2520 case DT_VERDEF: return "VERDEF";
2521 case DT_VERDEFNUM: return "VERDEFNUM";
2522 case DT_VERNEED: return "VERNEED";
2523 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2524
019148e4 2525 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2526 case DT_USED: return "USED";
2527 case DT_FILTER: return "FILTER";
103f02d3 2528
047b2264
JJ
2529 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2530 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2531 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2532 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2533 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2534 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2535 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2536
252b5132
RH
2537 default:
2538 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2539 {
2cf0635d 2540 const char * result;
103f02d3 2541
dda8d76d 2542 switch (filedata->file_header.e_machine)
252b5132 2543 {
37c18eed
SD
2544 case EM_AARCH64:
2545 result = get_aarch64_dynamic_type (type);
2546 break;
252b5132 2547 case EM_MIPS:
4fe85591 2548 case EM_MIPS_RS3_LE:
252b5132
RH
2549 result = get_mips_dynamic_type (type);
2550 break;
9a097730
RH
2551 case EM_SPARCV9:
2552 result = get_sparc64_dynamic_type (type);
2553 break;
7490d522
AM
2554 case EM_PPC:
2555 result = get_ppc_dynamic_type (type);
2556 break;
f1cb7e17
AM
2557 case EM_PPC64:
2558 result = get_ppc64_dynamic_type (type);
2559 break;
ecc51f48
NC
2560 case EM_IA_64:
2561 result = get_ia64_dynamic_type (type);
2562 break;
fabcb361
RH
2563 case EM_ALPHA:
2564 result = get_alpha_dynamic_type (type);
2565 break;
1c0d3aa6
NC
2566 case EM_SCORE:
2567 result = get_score_dynamic_type (type);
2568 break;
40b36596
JM
2569 case EM_TI_C6000:
2570 result = get_tic6x_dynamic_type (type);
2571 break;
36591ba1
SL
2572 case EM_ALTERA_NIOS2:
2573 result = get_nios2_dynamic_type (type);
2574 break;
8155b853
NC
2575 case EM_RISCV:
2576 result = get_riscv_dynamic_type (type);
2577 break;
252b5132 2578 default:
dda8d76d 2579 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2580 result = get_solaris_dynamic_type (type);
2581 else
2582 result = NULL;
252b5132
RH
2583 break;
2584 }
2585
2586 if (result != NULL)
2587 return result;
2588
e9e44622 2589 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2590 }
eec8f817 2591 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2592 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2593 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2594 {
2cf0635d 2595 const char * result;
103f02d3 2596
dda8d76d 2597 switch (filedata->file_header.e_machine)
103f02d3
UD
2598 {
2599 case EM_PARISC:
2600 result = get_parisc_dynamic_type (type);
2601 break;
148b93f2
NC
2602 case EM_IA_64:
2603 result = get_ia64_dynamic_type (type);
2604 break;
103f02d3 2605 default:
dda8d76d 2606 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2607 result = get_solaris_dynamic_type (type);
2608 else
2609 result = NULL;
103f02d3
UD
2610 break;
2611 }
2612
2613 if (result != NULL)
2614 return result;
2615
e9e44622
JJ
2616 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2617 type);
103f02d3 2618 }
252b5132 2619 else
e9e44622 2620 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2621
252b5132
RH
2622 return buff;
2623 }
2624}
2625
93df3340
AM
2626static bool get_program_headers (Filedata *);
2627static bool get_dynamic_section (Filedata *);
2628
2629static void
2630locate_dynamic_section (Filedata *filedata)
2631{
26c527e6 2632 uint64_t dynamic_addr = 0;
be7d229a 2633 uint64_t dynamic_size = 0;
93df3340
AM
2634
2635 if (filedata->file_header.e_phnum != 0
2636 && get_program_headers (filedata))
2637 {
2638 Elf_Internal_Phdr *segment;
2639 unsigned int i;
2640
2641 for (i = 0, segment = filedata->program_headers;
2642 i < filedata->file_header.e_phnum;
2643 i++, segment++)
2644 {
2645 if (segment->p_type == PT_DYNAMIC)
2646 {
2647 dynamic_addr = segment->p_offset;
2648 dynamic_size = segment->p_filesz;
2649
2650 if (filedata->section_headers != NULL)
2651 {
2652 Elf_Internal_Shdr *sec;
2653
2654 sec = find_section (filedata, ".dynamic");
2655 if (sec != NULL)
2656 {
2657 if (sec->sh_size == 0
2658 || sec->sh_type == SHT_NOBITS)
2659 {
2660 dynamic_addr = 0;
2661 dynamic_size = 0;
2662 }
2663 else
2664 {
2665 dynamic_addr = sec->sh_offset;
2666 dynamic_size = sec->sh_size;
2667 }
2668 }
2669 }
2670
2671 if (dynamic_addr > filedata->file_size
2672 || (dynamic_size > filedata->file_size - dynamic_addr))
2673 {
2674 dynamic_addr = 0;
2675 dynamic_size = 0;
2676 }
2677 break;
2678 }
2679 }
2680 }
2681 filedata->dynamic_addr = dynamic_addr;
2682 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2683}
2684
2685static bool
2686is_pie (Filedata *filedata)
2687{
2688 Elf_Internal_Dyn *entry;
2689
2690 if (filedata->dynamic_size == 0)
2691 locate_dynamic_section (filedata);
2692 if (filedata->dynamic_size <= 1)
2693 return false;
2694
2695 if (!get_dynamic_section (filedata))
2696 return false;
2697
2698 for (entry = filedata->dynamic_section;
2699 entry < filedata->dynamic_section + filedata->dynamic_nent;
2700 entry++)
2701 {
2702 if (entry->d_tag == DT_FLAGS_1)
2703 {
2704 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2705 return true;
2706 break;
2707 }
2708 }
2709 return false;
2710}
2711
252b5132 2712static char *
93df3340 2713get_file_type (Filedata *filedata)
252b5132 2714{
93df3340 2715 unsigned e_type = filedata->file_header.e_type;
89246a0e 2716 static char buff[64];
252b5132
RH
2717
2718 switch (e_type)
2719 {
32ec8896
NC
2720 case ET_NONE: return _("NONE (None)");
2721 case ET_REL: return _("REL (Relocatable file)");
2722 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2723 case ET_DYN:
2724 if (is_pie (filedata))
2725 return _("DYN (Position-Independent Executable file)");
2726 else
2727 return _("DYN (Shared object file)");
32ec8896 2728 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2729
2730 default:
2731 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2732 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2733 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2734 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2735 else
e9e44622 2736 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2737 return buff;
2738 }
2739}
2740
2741static char *
d3ba0551 2742get_machine_name (unsigned e_machine)
252b5132 2743{
b34976b6 2744 static char buff[64]; /* XXX */
252b5132
RH
2745
2746 switch (e_machine)
2747 {
55e22ca8
NC
2748 /* Please keep this switch table sorted by increasing EM_ value. */
2749 /* 0 */
c45021f2
NC
2750 case EM_NONE: return _("None");
2751 case EM_M32: return "WE32100";
2752 case EM_SPARC: return "Sparc";
2753 case EM_386: return "Intel 80386";
2754 case EM_68K: return "MC68000";
2755 case EM_88K: return "MC88000";
22abe556 2756 case EM_IAMCU: return "Intel MCU";
fb70ec17 2757 case EM_860: return "Intel 80860";
c45021f2
NC
2758 case EM_MIPS: return "MIPS R3000";
2759 case EM_S370: return "IBM System/370";
55e22ca8 2760 /* 10 */
7036c0e1 2761 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2762 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2763 case EM_PARISC: return "HPPA";
55e22ca8 2764 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2765 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2766 case EM_960: return "Intel 80960";
c45021f2 2767 case EM_PPC: return "PowerPC";
55e22ca8 2768 /* 20 */
285d1771 2769 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2770 case EM_S390_OLD:
2771 case EM_S390: return "IBM S/390";
2772 case EM_SPU: return "SPU";
2773 /* 30 */
2774 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2775 case EM_FR20: return "Fujitsu FR20";
2776 case EM_RH32: return "TRW RH32";
b34976b6 2777 case EM_MCORE: return "MCORE";
55e22ca8 2778 /* 40 */
7036c0e1
AJ
2779 case EM_ARM: return "ARM";
2780 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2781 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2782 case EM_SPARCV9: return "Sparc v9";
2783 case EM_TRICORE: return "Siemens Tricore";
584da044 2784 case EM_ARC: return "ARC";
c2dcd04e
NC
2785 case EM_H8_300: return "Renesas H8/300";
2786 case EM_H8_300H: return "Renesas H8/300H";
2787 case EM_H8S: return "Renesas H8S";
2788 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2789 /* 50 */
30800947 2790 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2791 case EM_MIPS_X: return "Stanford MIPS-X";
2792 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2793 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2794 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2795 case EM_PCP: return "Siemens PCP";
2796 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2797 case EM_NDR1: return "Denso NDR1 microprocesspr";
2798 case EM_STARCORE: return "Motorola Star*Core processor";
2799 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2800 /* 60 */
7036c0e1
AJ
2801 case EM_ST100: return "STMicroelectronics ST100 processor";
2802 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2803 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2804 case EM_PDSP: return "Sony DSP processor";
2805 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2806 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2807 case EM_FX66: return "Siemens FX66 microcontroller";
2808 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2809 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2810 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2811 /* 70 */
7036c0e1
AJ
2812 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2813 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2814 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2815 case EM_SVX: return "Silicon Graphics SVx";
2816 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2817 case EM_VAX: return "Digital VAX";
1b61cf92 2818 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2819 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2820 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2821 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2822 /* 80 */
b34976b6 2823 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2824 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2825 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2826 case EM_AVR_OLD:
2827 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2828 case EM_CYGNUS_FR30:
2829 case EM_FR30: return "Fujitsu FR30";
2830 case EM_CYGNUS_D10V:
2831 case EM_D10V: return "d10v";
2832 case EM_CYGNUS_D30V:
2833 case EM_D30V: return "d30v";
2834 case EM_CYGNUS_V850:
2835 case EM_V850: return "Renesas V850";
2836 case EM_CYGNUS_M32R:
2837 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2838 case EM_CYGNUS_MN10300:
2839 case EM_MN10300: return "mn10300";
2840 /* 90 */
2841 case EM_CYGNUS_MN10200:
2842 case EM_MN10200: return "mn10200";
2843 case EM_PJ: return "picoJava";
73589c9d 2844 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2845 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2846 case EM_XTENSA_OLD:
2847 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2848 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2849 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2850 case EM_NS32K: return "National Semiconductor 32000 series";
2851 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2852 case EM_SNP1K: return "Trebia SNP 1000 processor";
2853 /* 100 */
9abca702 2854 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2855 case EM_IP2K_OLD:
2856 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2857 case EM_MAX: return "MAX Processor";
2858 case EM_CR: return "National Semiconductor CompactRISC";
2859 case EM_F2MC16: return "Fujitsu F2MC16";
2860 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2861 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2862 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2863 case EM_SEP: return "Sharp embedded microprocessor";
2864 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2865 /* 110 */
11636f9e
JM
2866 case EM_UNICORE: return "Unicore";
2867 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2868 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2869 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2870 case EM_CRX: return "National Semiconductor CRX microprocessor";
2871 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2872 case EM_C166:
d70c5fc7 2873 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2874 case EM_M16C: return "Renesas M16C series microprocessors";
2875 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2876 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2877 /* 120 */
2878 case EM_M32C: return "Renesas M32c";
2879 /* 130 */
11636f9e
JM
2880 case EM_TSK3000: return "Altium TSK3000 core";
2881 case EM_RS08: return "Freescale RS08 embedded processor";
2882 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2883 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2884 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2885 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2886 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2887 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2888 /* 140 */
11636f9e
JM
2889 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2890 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2891 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2892 case EM_TI_PRU: return "TI PRU I/O processor";
2893 /* 160 */
11636f9e
JM
2894 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2895 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2896 case EM_R32C: return "Renesas R32C series microprocessors";
2897 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2898 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2899 case EM_8051: return "Intel 8051 and variants";
2900 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2901 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2902 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2903 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2904 /* 170 */
11636f9e
JM
2905 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2906 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2907 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2908 case EM_RX: return "Renesas RX";
a3c62988 2909 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2910 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2911 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2912 case EM_CR16:
2913 case EM_MICROBLAZE:
2914 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2915 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2916 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2917 /* 180 */
2918 case EM_L1OM: return "Intel L1OM";
2919 case EM_K1OM: return "Intel K1OM";
2920 case EM_INTEL182: return "Intel (reserved)";
2921 case EM_AARCH64: return "AArch64";
2922 case EM_ARM184: return "ARM (reserved)";
2923 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2924 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2925 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2926 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2927 /* 190 */
11636f9e 2928 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2929 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2930 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2931 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2932 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2933 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2934 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2935 case EM_RL78: return "Renesas RL78";
6d913794 2936 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2937 case EM_78K0R: return "Renesas 78K0R";
2938 /* 200 */
6d913794 2939 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2940 case EM_BA1: return "Beyond BA1 CPU architecture";
2941 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2942 case EM_XCORE: return "XMOS xCORE processor family";
2943 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2944 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2945 /* 210 */
6d913794
NC
2946 case EM_KM32: return "KM211 KM32 32-bit processor";
2947 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2948 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2949 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2950 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2951 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2952 case EM_COGE: return "Cognitive Smart Memory Processor";
2953 case EM_COOL: return "Bluechip Systems CoolEngine";
2954 case EM_NORC: return "Nanoradio Optimized RISC";
2955 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2956 /* 220 */
15f205b1 2957 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2958 case EM_VISIUM: return "CDS VISIUMcore processor";
2959 case EM_FT32: return "FTDI Chip FT32";
2960 case EM_MOXIE: return "Moxie";
2961 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2962 /* 230 (all reserved) */
2963 /* 240 */
55e22ca8
NC
2964 case EM_RISCV: return "RISC-V";
2965 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2966 case EM_CEVA: return "CEVA Processor Architecture Family";
2967 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2968 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2969 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2970 case EM_IMG1: return "Imagination Technologies";
2971 /* 250 */
fe944acf 2972 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2973 case EM_VE: return "NEC Vector Engine";
2974 case EM_CSKY: return "C-SKY";
13aa307c 2975 case EM_ARC_COMPACT3_64: return "Synopsys ARCv3 64-bit processor";
4cf2ad72 2976 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
13aa307c 2977 case EM_ARC_COMPACT3: return "Synopsys ARCv3 32-bit processor";
4cf2ad72
CC
2978 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2979 case EM_65816: return "WDC 65816/65C816";
01a8c731 2980 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2981 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2982
2983 /* Large numbers... */
2984 case EM_MT: return "Morpho Techologies MT processor";
2985 case EM_ALPHA: return "Alpha";
2986 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2987 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2988 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2989 case EM_IQ2000: return "Vitesse IQ2000";
2990 case EM_M32C_OLD:
2991 case EM_NIOS32: return "Altera Nios";
2992 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2993 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2994 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2995 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2996
252b5132 2997 default:
35d9dd2f 2998 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2999 return buff;
3000 }
3001}
3002
a9522a21
AB
3003static void
3004decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
3005{
3006 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3007 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3008 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3009 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3010 architectures.
3011
3012 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3013 but also sets a specific architecture type in the e_flags field.
3014
3015 However, when decoding the flags we don't worry if we see an
3016 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3017 ARCEM architecture type. */
3018
3019 switch (e_flags & EF_ARC_MACH_MSK)
3020 {
3021 /* We only expect these to occur for EM_ARC_COMPACT2. */
3022 case EF_ARC_CPU_ARCV2EM:
3023 strcat (buf, ", ARC EM");
3024 break;
3025 case EF_ARC_CPU_ARCV2HS:
3026 strcat (buf, ", ARC HS");
3027 break;
3028
3029 /* We only expect these to occur for EM_ARC_COMPACT. */
3030 case E_ARC_MACH_ARC600:
3031 strcat (buf, ", ARC600");
3032 break;
3033 case E_ARC_MACH_ARC601:
3034 strcat (buf, ", ARC601");
3035 break;
3036 case E_ARC_MACH_ARC700:
3037 strcat (buf, ", ARC700");
3038 break;
3039
3040 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3041 new ELF with new architecture being read by an old version of
3042 readelf, or (c) An ELF built with non-GNU compiler that does not
3043 set the architecture in the e_flags. */
3044 default:
3045 if (e_machine == EM_ARC_COMPACT)
3046 strcat (buf, ", Unknown ARCompact");
3047 else
3048 strcat (buf, ", Unknown ARC");
3049 break;
3050 }
3051
3052 switch (e_flags & EF_ARC_OSABI_MSK)
3053 {
3054 case E_ARC_OSABI_ORIG:
3055 strcat (buf, ", (ABI:legacy)");
3056 break;
3057 case E_ARC_OSABI_V2:
3058 strcat (buf, ", (ABI:v2)");
3059 break;
3060 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3061 case E_ARC_OSABI_V3:
3062 strcat (buf, ", v3 no-legacy-syscalls ABI");
3063 break;
53a346d8
CZ
3064 case E_ARC_OSABI_V4:
3065 strcat (buf, ", v4 ABI");
3066 break;
a9522a21
AB
3067 default:
3068 strcat (buf, ", unrecognised ARC OSABI flag");
3069 break;
3070 }
3071}
3072
f3485b74 3073static void
d3ba0551 3074decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
3075{
3076 unsigned eabi;
015dc7e1 3077 bool unknown = false;
f3485b74
NC
3078
3079 eabi = EF_ARM_EABI_VERSION (e_flags);
3080 e_flags &= ~ EF_ARM_EABIMASK;
3081
3082 /* Handle "generic" ARM flags. */
3083 if (e_flags & EF_ARM_RELEXEC)
3084 {
3085 strcat (buf, ", relocatable executable");
3086 e_flags &= ~ EF_ARM_RELEXEC;
3087 }
76da6bbe 3088
18a20338
CL
3089 if (e_flags & EF_ARM_PIC)
3090 {
3091 strcat (buf, ", position independent");
3092 e_flags &= ~ EF_ARM_PIC;
3093 }
3094
f3485b74
NC
3095 /* Now handle EABI specific flags. */
3096 switch (eabi)
3097 {
3098 default:
2c71103e 3099 strcat (buf, ", <unrecognized EABI>");
f3485b74 3100 if (e_flags)
015dc7e1 3101 unknown = true;
f3485b74
NC
3102 break;
3103
3104 case EF_ARM_EABI_VER1:
a5bcd848 3105 strcat (buf, ", Version1 EABI");
f3485b74
NC
3106 while (e_flags)
3107 {
3108 unsigned flag;
76da6bbe 3109
f3485b74
NC
3110 /* Process flags one bit at a time. */
3111 flag = e_flags & - e_flags;
3112 e_flags &= ~ flag;
76da6bbe 3113
f3485b74
NC
3114 switch (flag)
3115 {
a5bcd848 3116 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
3117 strcat (buf, ", sorted symbol tables");
3118 break;
76da6bbe 3119
f3485b74 3120 default:
015dc7e1 3121 unknown = true;
f3485b74
NC
3122 break;
3123 }
3124 }
3125 break;
76da6bbe 3126
a5bcd848
PB
3127 case EF_ARM_EABI_VER2:
3128 strcat (buf, ", Version2 EABI");
3129 while (e_flags)
3130 {
3131 unsigned flag;
3132
3133 /* Process flags one bit at a time. */
3134 flag = e_flags & - e_flags;
3135 e_flags &= ~ flag;
3136
3137 switch (flag)
3138 {
3139 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3140 strcat (buf, ", sorted symbol tables");
3141 break;
3142
3143 case EF_ARM_DYNSYMSUSESEGIDX:
3144 strcat (buf, ", dynamic symbols use segment index");
3145 break;
3146
3147 case EF_ARM_MAPSYMSFIRST:
3148 strcat (buf, ", mapping symbols precede others");
3149 break;
3150
3151 default:
015dc7e1 3152 unknown = true;
a5bcd848
PB
3153 break;
3154 }
3155 }
3156 break;
3157
d507cf36
PB
3158 case EF_ARM_EABI_VER3:
3159 strcat (buf, ", Version3 EABI");
8cb51566
PB
3160 break;
3161
3162 case EF_ARM_EABI_VER4:
3163 strcat (buf, ", Version4 EABI");
3bfcb652
NC
3164 while (e_flags)
3165 {
3166 unsigned flag;
3167
3168 /* Process flags one bit at a time. */
3169 flag = e_flags & - e_flags;
3170 e_flags &= ~ flag;
3171
3172 switch (flag)
3173 {
3174 case EF_ARM_BE8:
3175 strcat (buf, ", BE8");
3176 break;
3177
3178 case EF_ARM_LE8:
3179 strcat (buf, ", LE8");
3180 break;
3181
3182 default:
015dc7e1 3183 unknown = true;
3bfcb652
NC
3184 break;
3185 }
3bfcb652
NC
3186 }
3187 break;
3a4a14e9
PB
3188
3189 case EF_ARM_EABI_VER5:
3190 strcat (buf, ", Version5 EABI");
d507cf36
PB
3191 while (e_flags)
3192 {
3193 unsigned flag;
3194
3195 /* Process flags one bit at a time. */
3196 flag = e_flags & - e_flags;
3197 e_flags &= ~ flag;
3198
3199 switch (flag)
3200 {
3201 case EF_ARM_BE8:
3202 strcat (buf, ", BE8");
3203 break;
3204
3205 case EF_ARM_LE8:
3206 strcat (buf, ", LE8");
3207 break;
3208
3bfcb652
NC
3209 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3210 strcat (buf, ", soft-float ABI");
3211 break;
3212
3213 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3214 strcat (buf, ", hard-float ABI");
3215 break;
3216
d507cf36 3217 default:
015dc7e1 3218 unknown = true;
d507cf36
PB
3219 break;
3220 }
3221 }
3222 break;
3223
f3485b74 3224 case EF_ARM_EABI_UNKNOWN:
a5bcd848 3225 strcat (buf, ", GNU EABI");
f3485b74
NC
3226 while (e_flags)
3227 {
3228 unsigned flag;
76da6bbe 3229
f3485b74
NC
3230 /* Process flags one bit at a time. */
3231 flag = e_flags & - e_flags;
3232 e_flags &= ~ flag;
76da6bbe 3233
f3485b74
NC
3234 switch (flag)
3235 {
a5bcd848 3236 case EF_ARM_INTERWORK:
f3485b74
NC
3237 strcat (buf, ", interworking enabled");
3238 break;
76da6bbe 3239
a5bcd848 3240 case EF_ARM_APCS_26:
f3485b74
NC
3241 strcat (buf, ", uses APCS/26");
3242 break;
76da6bbe 3243
a5bcd848 3244 case EF_ARM_APCS_FLOAT:
f3485b74
NC
3245 strcat (buf, ", uses APCS/float");
3246 break;
76da6bbe 3247
a5bcd848 3248 case EF_ARM_PIC:
f3485b74
NC
3249 strcat (buf, ", position independent");
3250 break;
76da6bbe 3251
a5bcd848 3252 case EF_ARM_ALIGN8:
f3485b74
NC
3253 strcat (buf, ", 8 bit structure alignment");
3254 break;
76da6bbe 3255
a5bcd848 3256 case EF_ARM_NEW_ABI:
f3485b74
NC
3257 strcat (buf, ", uses new ABI");
3258 break;
76da6bbe 3259
a5bcd848 3260 case EF_ARM_OLD_ABI:
f3485b74
NC
3261 strcat (buf, ", uses old ABI");
3262 break;
76da6bbe 3263
a5bcd848 3264 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
3265 strcat (buf, ", software FP");
3266 break;
76da6bbe 3267
90e01f86
ILT
3268 case EF_ARM_VFP_FLOAT:
3269 strcat (buf, ", VFP");
3270 break;
3271
fde78edd
NC
3272 case EF_ARM_MAVERICK_FLOAT:
3273 strcat (buf, ", Maverick FP");
3274 break;
3275
f3485b74 3276 default:
015dc7e1 3277 unknown = true;
f3485b74
NC
3278 break;
3279 }
3280 }
3281 }
f3485b74
NC
3282
3283 if (unknown)
2b692964 3284 strcat (buf,_(", <unknown>"));
f3485b74
NC
3285}
3286
343433df
AB
3287static void
3288decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
3289{
3290 --size; /* Leave space for null terminator. */
3291
3292 switch (e_flags & EF_AVR_MACH)
3293 {
3294 case E_AVR_MACH_AVR1:
3295 strncat (buf, ", avr:1", size);
3296 break;
3297 case E_AVR_MACH_AVR2:
3298 strncat (buf, ", avr:2", size);
3299 break;
3300 case E_AVR_MACH_AVR25:
3301 strncat (buf, ", avr:25", size);
3302 break;
3303 case E_AVR_MACH_AVR3:
3304 strncat (buf, ", avr:3", size);
3305 break;
3306 case E_AVR_MACH_AVR31:
3307 strncat (buf, ", avr:31", size);
3308 break;
3309 case E_AVR_MACH_AVR35:
3310 strncat (buf, ", avr:35", size);
3311 break;
3312 case E_AVR_MACH_AVR4:
3313 strncat (buf, ", avr:4", size);
3314 break;
3315 case E_AVR_MACH_AVR5:
3316 strncat (buf, ", avr:5", size);
3317 break;
3318 case E_AVR_MACH_AVR51:
3319 strncat (buf, ", avr:51", size);
3320 break;
3321 case E_AVR_MACH_AVR6:
3322 strncat (buf, ", avr:6", size);
3323 break;
3324 case E_AVR_MACH_AVRTINY:
3325 strncat (buf, ", avr:100", size);
3326 break;
3327 case E_AVR_MACH_XMEGA1:
3328 strncat (buf, ", avr:101", size);
3329 break;
3330 case E_AVR_MACH_XMEGA2:
3331 strncat (buf, ", avr:102", size);
3332 break;
3333 case E_AVR_MACH_XMEGA3:
3334 strncat (buf, ", avr:103", size);
3335 break;
3336 case E_AVR_MACH_XMEGA4:
3337 strncat (buf, ", avr:104", size);
3338 break;
3339 case E_AVR_MACH_XMEGA5:
3340 strncat (buf, ", avr:105", size);
3341 break;
3342 case E_AVR_MACH_XMEGA6:
3343 strncat (buf, ", avr:106", size);
3344 break;
3345 case E_AVR_MACH_XMEGA7:
3346 strncat (buf, ", avr:107", size);
3347 break;
3348 default:
3349 strncat (buf, ", avr:<unknown>", size);
3350 break;
3351 }
3352
3353 size -= strlen (buf);
3354 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3355 strncat (buf, ", link-relax", size);
3356}
3357
35c08157
KLC
3358static void
3359decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
3360{
3361 unsigned abi;
3362 unsigned arch;
3363 unsigned config;
3364 unsigned version;
015dc7e1 3365 bool has_fpu = false;
32ec8896 3366 unsigned int r = 0;
35c08157
KLC
3367
3368 static const char *ABI_STRINGS[] =
3369 {
3370 "ABI v0", /* use r5 as return register; only used in N1213HC */
3371 "ABI v1", /* use r0 as return register */
3372 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3373 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3374 "AABI",
3375 "ABI2 FP+"
35c08157
KLC
3376 };
3377 static const char *VER_STRINGS[] =
3378 {
3379 "Andes ELF V1.3 or older",
3380 "Andes ELF V1.3.1",
3381 "Andes ELF V1.4"
3382 };
3383 static const char *ARCH_STRINGS[] =
3384 {
3385 "",
3386 "Andes Star v1.0",
3387 "Andes Star v2.0",
3388 "Andes Star v3.0",
3389 "Andes Star v3.0m"
3390 };
3391
3392 abi = EF_NDS_ABI & e_flags;
3393 arch = EF_NDS_ARCH & e_flags;
3394 config = EF_NDS_INST & e_flags;
3395 version = EF_NDS32_ELF_VERSION & e_flags;
3396
3397 memset (buf, 0, size);
3398
3399 switch (abi)
3400 {
3401 case E_NDS_ABI_V0:
3402 case E_NDS_ABI_V1:
3403 case E_NDS_ABI_V2:
3404 case E_NDS_ABI_V2FP:
3405 case E_NDS_ABI_AABI:
40c7a7cb 3406 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3407 /* In case there are holes in the array. */
3408 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3409 break;
3410
3411 default:
3412 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3413 break;
3414 }
3415
3416 switch (version)
3417 {
3418 case E_NDS32_ELF_VER_1_2:
3419 case E_NDS32_ELF_VER_1_3:
3420 case E_NDS32_ELF_VER_1_4:
3421 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3422 break;
3423
3424 default:
3425 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3426 break;
3427 }
3428
3429 if (E_NDS_ABI_V0 == abi)
3430 {
3431 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3432 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3433 if (arch == E_NDS_ARCH_STAR_V1_0)
3434 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3435 return;
3436 }
3437
3438 switch (arch)
3439 {
3440 case E_NDS_ARCH_STAR_V1_0:
3441 case E_NDS_ARCH_STAR_V2_0:
3442 case E_NDS_ARCH_STAR_V3_0:
3443 case E_NDS_ARCH_STAR_V3_M:
3444 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3445 break;
3446
3447 default:
3448 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3449 /* ARCH version determines how the e_flags are interpreted.
3450 If it is unknown, we cannot proceed. */
3451 return;
3452 }
3453
3454 /* Newer ABI; Now handle architecture specific flags. */
3455 if (arch == E_NDS_ARCH_STAR_V1_0)
3456 {
3457 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3458 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3459
3460 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3461 r += snprintf (buf + r, size -r, ", MAC");
3462
3463 if (config & E_NDS32_HAS_DIV_INST)
3464 r += snprintf (buf + r, size -r, ", DIV");
3465
3466 if (config & E_NDS32_HAS_16BIT_INST)
3467 r += snprintf (buf + r, size -r, ", 16b");
3468 }
3469 else
3470 {
3471 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3472 {
3473 if (version <= E_NDS32_ELF_VER_1_3)
3474 r += snprintf (buf + r, size -r, ", [B8]");
3475 else
3476 r += snprintf (buf + r, size -r, ", EX9");
3477 }
3478
3479 if (config & E_NDS32_HAS_MAC_DX_INST)
3480 r += snprintf (buf + r, size -r, ", MAC_DX");
3481
3482 if (config & E_NDS32_HAS_DIV_DX_INST)
3483 r += snprintf (buf + r, size -r, ", DIV_DX");
3484
3485 if (config & E_NDS32_HAS_16BIT_INST)
3486 {
3487 if (version <= E_NDS32_ELF_VER_1_3)
3488 r += snprintf (buf + r, size -r, ", 16b");
3489 else
3490 r += snprintf (buf + r, size -r, ", IFC");
3491 }
3492 }
3493
3494 if (config & E_NDS32_HAS_EXT_INST)
3495 r += snprintf (buf + r, size -r, ", PERF1");
3496
3497 if (config & E_NDS32_HAS_EXT2_INST)
3498 r += snprintf (buf + r, size -r, ", PERF2");
3499
3500 if (config & E_NDS32_HAS_FPU_INST)
3501 {
015dc7e1 3502 has_fpu = true;
35c08157
KLC
3503 r += snprintf (buf + r, size -r, ", FPU_SP");
3504 }
3505
3506 if (config & E_NDS32_HAS_FPU_DP_INST)
3507 {
015dc7e1 3508 has_fpu = true;
35c08157
KLC
3509 r += snprintf (buf + r, size -r, ", FPU_DP");
3510 }
3511
3512 if (config & E_NDS32_HAS_FPU_MAC_INST)
3513 {
015dc7e1 3514 has_fpu = true;
35c08157
KLC
3515 r += snprintf (buf + r, size -r, ", FPU_MAC");
3516 }
3517
3518 if (has_fpu)
3519 {
3520 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3521 {
3522 case E_NDS32_FPU_REG_8SP_4DP:
3523 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3524 break;
3525 case E_NDS32_FPU_REG_16SP_8DP:
3526 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3527 break;
3528 case E_NDS32_FPU_REG_32SP_16DP:
3529 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3530 break;
3531 case E_NDS32_FPU_REG_32SP_32DP:
3532 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3533 break;
3534 }
3535 }
3536
3537 if (config & E_NDS32_HAS_AUDIO_INST)
3538 r += snprintf (buf + r, size -r, ", AUDIO");
3539
3540 if (config & E_NDS32_HAS_STRING_INST)
3541 r += snprintf (buf + r, size -r, ", STR");
3542
3543 if (config & E_NDS32_HAS_REDUCED_REGS)
3544 r += snprintf (buf + r, size -r, ", 16REG");
3545
3546 if (config & E_NDS32_HAS_VIDEO_INST)
3547 {
3548 if (version <= E_NDS32_ELF_VER_1_3)
3549 r += snprintf (buf + r, size -r, ", VIDEO");
3550 else
3551 r += snprintf (buf + r, size -r, ", SATURATION");
3552 }
3553
3554 if (config & E_NDS32_HAS_ENCRIPT_INST)
3555 r += snprintf (buf + r, size -r, ", ENCRP");
3556
3557 if (config & E_NDS32_HAS_L2C_INST)
3558 r += snprintf (buf + r, size -r, ", L2C");
3559}
3560
c077c580
SM
3561static void
3562decode_AMDGPU_machine_flags (Filedata *filedata, unsigned int e_flags,
3563 char *buf)
3564{
3565 unsigned char *e_ident = filedata->file_header.e_ident;
3566 unsigned char osabi = e_ident[EI_OSABI];
3567 unsigned char abiversion = e_ident[EI_ABIVERSION];
3568 unsigned int mach;
3569
3570 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
3571 it has been deprecated for a while.
3572
3573 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
3574 of writing, they use the same flags as HSA v3, so the code below uses that
3575 assumption. */
3576 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
3577 return;
3578
3579 mach = e_flags & EF_AMDGPU_MACH;
3580 switch (mach)
3581 {
3582#define AMDGPU_CASE(code, string) \
3583 case code: strcat (buf, ", " string); break;
3584 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
3585 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
3586 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
3587 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
3588 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
3589 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
3590 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
3591 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
3592 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
3593 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
3594 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
3595 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
3596 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
3597 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
3598 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
3599 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
3600 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
3601 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
3602 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
3603 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
3604 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
3605 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
3606 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
3607 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
3608 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
3609 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
3610 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
3611 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
3612 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
3613 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
3614 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
3615 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
3616 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
3617 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
3618 default:
3619 sprintf (buf, _(", <unknown AMDGPU GPU type: %#x>"), mach);
3620 break;
3621#undef AMDGPU_CASE
3622 }
3623
3624 buf += strlen (buf);
3625 e_flags &= ~EF_AMDGPU_MACH;
3626
3627 if ((osabi == ELFOSABI_AMDGPU_HSA
3628 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
3629 || osabi != ELFOSABI_AMDGPU_HSA)
3630 {
3631 /* For HSA v3 and other OS ABIs. */
3632 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
3633 {
3634 strcat (buf, ", xnack on");
3635 buf += strlen (buf);
3636 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
3637 }
3638
3639 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
3640 {
3641 strcat (buf, ", sramecc on");
3642 buf += strlen (buf);
3643 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
3644 }
3645 }
3646 else
3647 {
3648 /* For HSA v4+. */
3649 int xnack, sramecc;
3650
3651 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
3652 switch (xnack)
3653 {
3654 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
3655 break;
3656
3657 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
3658 strcat (buf, ", xnack any");
3659 break;
3660
3661 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
3662 strcat (buf, ", xnack off");
3663 break;
3664
3665 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
3666 strcat (buf, ", xnack on");
3667 break;
3668
3669 default:
3670 sprintf (buf, _(", <unknown xnack value: %#x>"), xnack);
3671 break;
3672 }
3673
3674 buf += strlen (buf);
3675 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
3676
3677 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
3678 switch (sramecc)
3679 {
3680 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
3681 break;
3682
3683 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
3684 strcat (buf, ", sramecc any");
3685 break;
3686
3687 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
3688 strcat (buf, ", sramecc off");
3689 break;
3690
3691 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
3692 strcat (buf, ", sramecc on");
3693 break;
3694
3695 default:
3696 sprintf (buf, _(", <unknown sramecc value: %#x>"), sramecc);
3697 break;
3698 }
3699
3700 buf += strlen (buf);
3701 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
3702 }
3703
3704 if (e_flags != 0)
3705 sprintf (buf, _(", unknown flags bits: %#x"), e_flags);
3706}
3707
252b5132 3708static char *
dda8d76d 3709get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3710{
b34976b6 3711 static char buf[1024];
252b5132
RH
3712
3713 buf[0] = '\0';
76da6bbe 3714
252b5132
RH
3715 if (e_flags)
3716 {
3717 switch (e_machine)
3718 {
3719 default:
3720 break;
3721
13aa307c
CZ
3722 case EM_ARC_COMPACT3:
3723 strcat (buf, ", HS5x");
3724 break;
3725
3726 case EM_ARC_COMPACT3_64:
3727 strcat (buf, ", HS6x");
3728 break;
3729
886a2506 3730 case EM_ARC_COMPACT2:
886a2506 3731 case EM_ARC_COMPACT:
a9522a21
AB
3732 decode_ARC_machine_flags (e_flags, e_machine, buf);
3733 break;
886a2506 3734
f3485b74
NC
3735 case EM_ARM:
3736 decode_ARM_machine_flags (e_flags, buf);
3737 break;
76da6bbe 3738
343433df
AB
3739 case EM_AVR:
3740 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3741 break;
3742
781303ce
MF
3743 case EM_BLACKFIN:
3744 if (e_flags & EF_BFIN_PIC)
3745 strcat (buf, ", PIC");
3746
3747 if (e_flags & EF_BFIN_FDPIC)
3748 strcat (buf, ", FDPIC");
3749
3750 if (e_flags & EF_BFIN_CODE_IN_L1)
3751 strcat (buf, ", code in L1");
3752
3753 if (e_flags & EF_BFIN_DATA_IN_L1)
3754 strcat (buf, ", data in L1");
3755
3756 break;
3757
ec2dfb42
AO
3758 case EM_CYGNUS_FRV:
3759 switch (e_flags & EF_FRV_CPU_MASK)
3760 {
3761 case EF_FRV_CPU_GENERIC:
3762 break;
3763
3764 default:
3765 strcat (buf, ", fr???");
3766 break;
57346661 3767
ec2dfb42
AO
3768 case EF_FRV_CPU_FR300:
3769 strcat (buf, ", fr300");
3770 break;
3771
3772 case EF_FRV_CPU_FR400:
3773 strcat (buf, ", fr400");
3774 break;
3775 case EF_FRV_CPU_FR405:
3776 strcat (buf, ", fr405");
3777 break;
3778
3779 case EF_FRV_CPU_FR450:
3780 strcat (buf, ", fr450");
3781 break;
3782
3783 case EF_FRV_CPU_FR500:
3784 strcat (buf, ", fr500");
3785 break;
3786 case EF_FRV_CPU_FR550:
3787 strcat (buf, ", fr550");
3788 break;
3789
3790 case EF_FRV_CPU_SIMPLE:
3791 strcat (buf, ", simple");
3792 break;
3793 case EF_FRV_CPU_TOMCAT:
3794 strcat (buf, ", tomcat");
3795 break;
3796 }
1c877e87 3797 break;
ec2dfb42 3798
53c7db4b 3799 case EM_68K:
425c6cb0 3800 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3801 strcat (buf, ", m68000");
425c6cb0 3802 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3803 strcat (buf, ", cpu32");
3804 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3805 strcat (buf, ", fido_a");
425c6cb0 3806 else
266abb8f 3807 {
2cf0635d
NC
3808 char const * isa = _("unknown");
3809 char const * mac = _("unknown mac");
3810 char const * additional = NULL;
0112cd26 3811
c694fd50 3812 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3813 {
c694fd50 3814 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3815 isa = "A";
3816 additional = ", nodiv";
3817 break;
c694fd50 3818 case EF_M68K_CF_ISA_A:
266abb8f
NS
3819 isa = "A";
3820 break;
c694fd50 3821 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3822 isa = "A+";
3823 break;
c694fd50 3824 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3825 isa = "B";
3826 additional = ", nousp";
3827 break;
c694fd50 3828 case EF_M68K_CF_ISA_B:
266abb8f
NS
3829 isa = "B";
3830 break;
f608cd77
NS
3831 case EF_M68K_CF_ISA_C:
3832 isa = "C";
3833 break;
3834 case EF_M68K_CF_ISA_C_NODIV:
3835 isa = "C";
3836 additional = ", nodiv";
3837 break;
266abb8f
NS
3838 }
3839 strcat (buf, ", cf, isa ");
3840 strcat (buf, isa);
0b2e31dc
NS
3841 if (additional)
3842 strcat (buf, additional);
c694fd50 3843 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3844 strcat (buf, ", float");
c694fd50 3845 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3846 {
3847 case 0:
3848 mac = NULL;
3849 break;
c694fd50 3850 case EF_M68K_CF_MAC:
266abb8f
NS
3851 mac = "mac";
3852 break;
c694fd50 3853 case EF_M68K_CF_EMAC:
266abb8f
NS
3854 mac = "emac";
3855 break;
f608cd77
NS
3856 case EF_M68K_CF_EMAC_B:
3857 mac = "emac_b";
3858 break;
266abb8f
NS
3859 }
3860 if (mac)
3861 {
3862 strcat (buf, ", ");
3863 strcat (buf, mac);
3864 }
266abb8f 3865 }
53c7db4b 3866 break;
33c63f9d 3867
c077c580
SM
3868 case EM_AMDGPU:
3869 decode_AMDGPU_machine_flags (filedata, e_flags, buf);
3870 break;
3871
153a2776
NC
3872 case EM_CYGNUS_MEP:
3873 switch (e_flags & EF_MEP_CPU_MASK)
3874 {
3875 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3876 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3877 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3878 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3879 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3880 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3881 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3882 }
3883
3884 switch (e_flags & EF_MEP_COP_MASK)
3885 {
3886 case EF_MEP_COP_NONE: break;
3887 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3888 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3889 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3890 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3891 default: strcat (buf, _("<unknown MeP copro type>")); break;
3892 }
3893
3894 if (e_flags & EF_MEP_LIBRARY)
3895 strcat (buf, ", Built for Library");
3896
3897 if (e_flags & EF_MEP_INDEX_MASK)
3898 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3899 e_flags & EF_MEP_INDEX_MASK);
3900
3901 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3902 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3903 e_flags & ~ EF_MEP_ALL_FLAGS);
3904 break;
3905
252b5132
RH
3906 case EM_PPC:
3907 if (e_flags & EF_PPC_EMB)
3908 strcat (buf, ", emb");
3909
3910 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3911 strcat (buf, _(", relocatable"));
252b5132
RH
3912
3913 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3914 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3915 break;
3916
ee67d69a
AM
3917 case EM_PPC64:
3918 if (e_flags & EF_PPC64_ABI)
3919 {
3920 char abi[] = ", abiv0";
3921
3922 abi[6] += e_flags & EF_PPC64_ABI;
3923 strcat (buf, abi);
3924 }
3925 break;
3926
708e2187
NC
3927 case EM_V800:
3928 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3929 strcat (buf, ", RH850 ABI");
0b4362b0 3930
708e2187
NC
3931 if (e_flags & EF_V800_850E3)
3932 strcat (buf, ", V3 architecture");
3933
3934 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3935 strcat (buf, ", FPU not used");
3936
3937 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3938 strcat (buf, ", regmode: COMMON");
3939
3940 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3941 strcat (buf, ", r4 not used");
3942
3943 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3944 strcat (buf, ", r30 not used");
3945
3946 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3947 strcat (buf, ", r5 not used");
3948
3949 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3950 strcat (buf, ", r2 not used");
3951
3952 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3953 {
3954 switch (e_flags & - e_flags)
3955 {
3956 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3957 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3958 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3959 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3960 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3961 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3962 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3963 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3964 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3965 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3966 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3967 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3968 default: break;
3969 }
3970 }
3971 break;
3972
2b0337b0 3973 case EM_V850:
252b5132
RH
3974 case EM_CYGNUS_V850:
3975 switch (e_flags & EF_V850_ARCH)
3976 {
78c8d46c
NC
3977 case E_V850E3V5_ARCH:
3978 strcat (buf, ", v850e3v5");
3979 break;
1cd986c5
NC
3980 case E_V850E2V3_ARCH:
3981 strcat (buf, ", v850e2v3");
3982 break;
3983 case E_V850E2_ARCH:
3984 strcat (buf, ", v850e2");
3985 break;
3986 case E_V850E1_ARCH:
3987 strcat (buf, ", v850e1");
8ad30312 3988 break;
252b5132
RH
3989 case E_V850E_ARCH:
3990 strcat (buf, ", v850e");
3991 break;
252b5132
RH
3992 case E_V850_ARCH:
3993 strcat (buf, ", v850");
3994 break;
3995 default:
2b692964 3996 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3997 break;
3998 }
3999 break;
4000
2b0337b0 4001 case EM_M32R:
252b5132
RH
4002 case EM_CYGNUS_M32R:
4003 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
4004 strcat (buf, ", m32r");
252b5132
RH
4005 break;
4006
4007 case EM_MIPS:
4fe85591 4008 case EM_MIPS_RS3_LE:
252b5132
RH
4009 if (e_flags & EF_MIPS_NOREORDER)
4010 strcat (buf, ", noreorder");
4011
4012 if (e_flags & EF_MIPS_PIC)
4013 strcat (buf, ", pic");
4014
4015 if (e_flags & EF_MIPS_CPIC)
4016 strcat (buf, ", cpic");
4017
d1bdd336
TS
4018 if (e_flags & EF_MIPS_UCODE)
4019 strcat (buf, ", ugen_reserved");
4020
252b5132
RH
4021 if (e_flags & EF_MIPS_ABI2)
4022 strcat (buf, ", abi2");
4023
43521d43
TS
4024 if (e_flags & EF_MIPS_OPTIONS_FIRST)
4025 strcat (buf, ", odk first");
4026
a5d22d2a
TS
4027 if (e_flags & EF_MIPS_32BITMODE)
4028 strcat (buf, ", 32bitmode");
4029
ba92f887
MR
4030 if (e_flags & EF_MIPS_NAN2008)
4031 strcat (buf, ", nan2008");
4032
fef1b0b3
SE
4033 if (e_flags & EF_MIPS_FP64)
4034 strcat (buf, ", fp64");
4035
156c2f8b
NC
4036 switch ((e_flags & EF_MIPS_MACH))
4037 {
4038 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
4039 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
4040 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 4041 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
4042 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
4043 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
4044 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
4045 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 4046 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 4047 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 4048 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
4049 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
4050 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 4051 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 4052 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 4053 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 4054 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 4055 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 4056 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 4057 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 4058 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
df18f71b 4059 case E_MIPS_MACH_ALLEGREX: strcat(buf, ", allegrex"); break;
43521d43
TS
4060 case 0:
4061 /* We simply ignore the field in this case to avoid confusion:
4062 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4063 extension. */
4064 break;
2b692964 4065 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 4066 }
43521d43
TS
4067
4068 switch ((e_flags & EF_MIPS_ABI))
4069 {
4070 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
4071 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
4072 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
4073 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
4074 case 0:
4075 /* We simply ignore the field in this case to avoid confusion:
4076 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4077 This means it is likely to be an o32 file, but not for
4078 sure. */
4079 break;
2b692964 4080 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
4081 }
4082
4083 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4084 strcat (buf, ", mdmx");
4085
4086 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4087 strcat (buf, ", mips16");
4088
df58fc94
RS
4089 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4090 strcat (buf, ", micromips");
4091
43521d43
TS
4092 switch ((e_flags & EF_MIPS_ARCH))
4093 {
4094 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
4095 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
4096 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
4097 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
4098 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
4099 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 4100 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 4101 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 4102 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 4103 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 4104 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 4105 default: strcat (buf, _(", unknown ISA")); break;
43521d43 4106 }
252b5132 4107 break;
351b4b40 4108
35c08157
KLC
4109 case EM_NDS32:
4110 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
4111 break;
4112
fe944acf
FT
4113 case EM_NFP:
4114 switch (EF_NFP_MACH (e_flags))
4115 {
4116 case E_NFP_MACH_3200:
4117 strcat (buf, ", NFP-32xx");
4118 break;
4119 case E_NFP_MACH_6000:
4120 strcat (buf, ", NFP-6xxx");
4121 break;
4122 }
4123 break;
4124
e23eba97
NC
4125 case EM_RISCV:
4126 if (e_flags & EF_RISCV_RVC)
4127 strcat (buf, ", RVC");
2922d21d 4128
7f999549
JW
4129 if (e_flags & EF_RISCV_RVE)
4130 strcat (buf, ", RVE");
4131
96462b01
S
4132 if (e_flags & EF_RISCV_TSO)
4133 strcat (buf, ", TSO");
4134
2922d21d
AW
4135 switch (e_flags & EF_RISCV_FLOAT_ABI)
4136 {
4137 case EF_RISCV_FLOAT_ABI_SOFT:
4138 strcat (buf, ", soft-float ABI");
4139 break;
4140
4141 case EF_RISCV_FLOAT_ABI_SINGLE:
4142 strcat (buf, ", single-float ABI");
4143 break;
4144
4145 case EF_RISCV_FLOAT_ABI_DOUBLE:
4146 strcat (buf, ", double-float ABI");
4147 break;
4148
4149 case EF_RISCV_FLOAT_ABI_QUAD:
4150 strcat (buf, ", quad-float ABI");
4151 break;
4152 }
e23eba97
NC
4153 break;
4154
ccde1100
AO
4155 case EM_SH:
4156 switch ((e_flags & EF_SH_MACH_MASK))
4157 {
4158 case EF_SH1: strcat (buf, ", sh1"); break;
4159 case EF_SH2: strcat (buf, ", sh2"); break;
4160 case EF_SH3: strcat (buf, ", sh3"); break;
4161 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
4162 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
4163 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
4164 case EF_SH3E: strcat (buf, ", sh3e"); break;
4165 case EF_SH4: strcat (buf, ", sh4"); break;
4166 case EF_SH5: strcat (buf, ", sh5"); break;
4167 case EF_SH2E: strcat (buf, ", sh2e"); break;
4168 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 4169 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
4170 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
4171 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 4172 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
4173 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
4174 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
4175 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
4176 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
4177 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
4178 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 4179 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
4180 }
4181
cec6a5b8
MR
4182 if (e_flags & EF_SH_PIC)
4183 strcat (buf, ", pic");
4184
4185 if (e_flags & EF_SH_FDPIC)
4186 strcat (buf, ", fdpic");
ccde1100 4187 break;
948f632f 4188
73589c9d
CS
4189 case EM_OR1K:
4190 if (e_flags & EF_OR1K_NODELAY)
4191 strcat (buf, ", no delay");
4192 break;
57346661 4193
351b4b40
RH
4194 case EM_SPARCV9:
4195 if (e_flags & EF_SPARC_32PLUS)
4196 strcat (buf, ", v8+");
4197
4198 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
4199 strcat (buf, ", ultrasparcI");
4200
4201 if (e_flags & EF_SPARC_SUN_US3)
4202 strcat (buf, ", ultrasparcIII");
351b4b40
RH
4203
4204 if (e_flags & EF_SPARC_HAL_R1)
4205 strcat (buf, ", halr1");
4206
4207 if (e_flags & EF_SPARC_LEDATA)
4208 strcat (buf, ", ledata");
4209
4210 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4211 strcat (buf, ", tso");
4212
4213 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4214 strcat (buf, ", pso");
4215
4216 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4217 strcat (buf, ", rmo");
4218 break;
7d466069 4219
103f02d3
UD
4220 case EM_PARISC:
4221 switch (e_flags & EF_PARISC_ARCH)
4222 {
4223 case EFA_PARISC_1_0:
4224 strcpy (buf, ", PA-RISC 1.0");
4225 break;
4226 case EFA_PARISC_1_1:
4227 strcpy (buf, ", PA-RISC 1.1");
4228 break;
4229 case EFA_PARISC_2_0:
4230 strcpy (buf, ", PA-RISC 2.0");
4231 break;
4232 default:
4233 break;
4234 }
4235 if (e_flags & EF_PARISC_TRAPNIL)
4236 strcat (buf, ", trapnil");
4237 if (e_flags & EF_PARISC_EXT)
4238 strcat (buf, ", ext");
4239 if (e_flags & EF_PARISC_LSB)
4240 strcat (buf, ", lsb");
4241 if (e_flags & EF_PARISC_WIDE)
4242 strcat (buf, ", wide");
4243 if (e_flags & EF_PARISC_NO_KABP)
4244 strcat (buf, ", no kabp");
4245 if (e_flags & EF_PARISC_LAZYSWAP)
4246 strcat (buf, ", lazyswap");
30800947 4247 break;
76da6bbe 4248
7d466069 4249 case EM_PJ:
2b0337b0 4250 case EM_PJ_OLD:
7d466069
ILT
4251 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4252 strcat (buf, ", new calling convention");
4253
4254 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4255 strcat (buf, ", gnu calling convention");
4256 break;
4d6ed7c8
NC
4257
4258 case EM_IA_64:
4259 if ((e_flags & EF_IA_64_ABI64))
4260 strcat (buf, ", 64-bit");
4261 else
4262 strcat (buf, ", 32-bit");
4263 if ((e_flags & EF_IA_64_REDUCEDFP))
4264 strcat (buf, ", reduced fp model");
4265 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4266 strcat (buf, ", no function descriptors, constant gp");
4267 else if ((e_flags & EF_IA_64_CONS_GP))
4268 strcat (buf, ", constant gp");
4269 if ((e_flags & EF_IA_64_ABSOLUTE))
4270 strcat (buf, ", absolute");
dda8d76d 4271 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
4272 {
4273 if ((e_flags & EF_IA_64_VMS_LINKAGES))
4274 strcat (buf, ", vms_linkages");
4275 switch ((e_flags & EF_IA_64_VMS_COMCOD))
4276 {
4277 case EF_IA_64_VMS_COMCOD_SUCCESS:
4278 break;
4279 case EF_IA_64_VMS_COMCOD_WARNING:
4280 strcat (buf, ", warning");
4281 break;
4282 case EF_IA_64_VMS_COMCOD_ERROR:
4283 strcat (buf, ", error");
4284 break;
4285 case EF_IA_64_VMS_COMCOD_ABORT:
4286 strcat (buf, ", abort");
4287 break;
4288 default:
bee0ee85
NC
4289 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
4290 e_flags & EF_IA_64_VMS_COMCOD);
4291 strcat (buf, ", <unknown>");
28f997cf
TG
4292 }
4293 }
4d6ed7c8 4294 break;
179d3252
JT
4295
4296 case EM_VAX:
4297 if ((e_flags & EF_VAX_NONPIC))
4298 strcat (buf, ", non-PIC");
4299 if ((e_flags & EF_VAX_DFLOAT))
4300 strcat (buf, ", D-Float");
4301 if ((e_flags & EF_VAX_GFLOAT))
4302 strcat (buf, ", G-Float");
4303 break;
c7927a3c 4304
619ed720
EB
4305 case EM_VISIUM:
4306 if (e_flags & EF_VISIUM_ARCH_MCM)
4307 strcat (buf, ", mcm");
4308 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4309 strcat (buf, ", mcm24");
4310 if (e_flags & EF_VISIUM_ARCH_GR6)
4311 strcat (buf, ", gr6");
4312 break;
4313
4046d87a 4314 case EM_RL78:
1740ba0c
NC
4315 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4316 {
4317 case E_FLAG_RL78_ANY_CPU: break;
4318 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
4319 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
4320 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
4321 }
856ea05c
KP
4322 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4323 strcat (buf, ", 64-bit doubles");
4046d87a 4324 break;
0b4362b0 4325
c7927a3c
NC
4326 case EM_RX:
4327 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4328 strcat (buf, ", 64-bit doubles");
4329 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 4330 strcat (buf, ", dsp");
d4cb0ea0 4331 if (e_flags & E_FLAG_RX_PID)
0b4362b0 4332 strcat (buf, ", pid");
708e2187
NC
4333 if (e_flags & E_FLAG_RX_ABI)
4334 strcat (buf, ", RX ABI");
3525236c
NC
4335 if (e_flags & E_FLAG_RX_SINSNS_SET)
4336 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
4337 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
4338 if (e_flags & E_FLAG_RX_V2)
4339 strcat (buf, ", V2");
f87673e0
YS
4340 if (e_flags & E_FLAG_RX_V3)
4341 strcat (buf, ", V3");
d4cb0ea0 4342 break;
55786da2
AK
4343
4344 case EM_S390:
4345 if (e_flags & EF_S390_HIGH_GPRS)
4346 strcat (buf, ", highgprs");
d4cb0ea0 4347 break;
40b36596
JM
4348
4349 case EM_TI_C6000:
4350 if ((e_flags & EF_C6000_REL))
4351 strcat (buf, ", relocatable module");
d4cb0ea0 4352 break;
13761a11
NC
4353
4354 case EM_MSP430:
4355 strcat (buf, _(": architecture variant: "));
4356 switch (e_flags & EF_MSP430_MACH)
4357 {
4358 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
4359 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
4360 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
4361 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
4362 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
4363 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
4364 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
4365 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
4366 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
4367 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
4368 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
4369 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
4370 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
4371 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
4372 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
4373 default:
4374 strcat (buf, _(": unknown")); break;
4375 }
4376
4377 if (e_flags & ~ EF_MSP430_MACH)
4378 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
4379 break;
4380
4381 case EM_Z80:
4382 switch (e_flags & EF_Z80_MACH_MSK)
4383 {
4384 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
4385 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
4386 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
4387 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
4388 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
4389 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 4390 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
4391 default:
4392 strcat (buf, _(", unknown")); break;
4393 }
4394 break;
e9a0721f 4395 case EM_LOONGARCH:
e9a0721f 4396 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
4397 strcat (buf, ", SOFT-FLOAT");
4398 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
4399 strcat (buf, ", SINGLE-FLOAT");
4400 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
4401 strcat (buf, ", DOUBLE-FLOAT");
4402
c4a7e6b5 4403 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
4404 strcat (buf, ", OBJ-v0");
4405 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
4406 strcat (buf, ", OBJ-v1");
4407
e9a0721f 4408 break;
252b5132
RH
4409 }
4410 }
4411
4412 return buf;
4413}
4414
252b5132 4415static const char *
dda8d76d 4416get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4417{
4418 static char buff[32];
4419
4420 switch (osabi)
4421 {
4422 case ELFOSABI_NONE: return "UNIX - System V";
4423 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4424 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4425 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4426 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4427 case ELFOSABI_AIX: return "UNIX - AIX";
4428 case ELFOSABI_IRIX: return "UNIX - IRIX";
4429 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4430 case ELFOSABI_TRU64: return "UNIX - TRU64";
4431 case ELFOSABI_MODESTO: return "Novell - Modesto";
4432 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4433 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4434 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4435 case ELFOSABI_AROS: return "AROS";
11636f9e 4436 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4437 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4438 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4439 default:
40b36596 4440 if (osabi >= 64)
dda8d76d 4441 switch (filedata->file_header.e_machine)
40b36596 4442 {
37870be8
SM
4443 case EM_AMDGPU:
4444 switch (osabi)
4445 {
4446 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4447 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4448 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4449 default:
4450 break;
4451 }
4452 break;
4453
40b36596
JM
4454 case EM_ARM:
4455 switch (osabi)
4456 {
4457 case ELFOSABI_ARM: return "ARM";
18a20338 4458 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4459 default:
4460 break;
4461 }
4462 break;
4463
4464 case EM_MSP430:
4465 case EM_MSP430_OLD:
619ed720 4466 case EM_VISIUM:
40b36596
JM
4467 switch (osabi)
4468 {
4469 case ELFOSABI_STANDALONE: return _("Standalone App");
4470 default:
4471 break;
4472 }
4473 break;
4474
4475 case EM_TI_C6000:
4476 switch (osabi)
4477 {
4478 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4479 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4480 default:
4481 break;
4482 }
4483 break;
4484
4485 default:
4486 break;
4487 }
e9e44622 4488 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4489 return buff;
4490 }
4491}
4492
a06ea964
NC
4493static const char *
4494get_aarch64_segment_type (unsigned long type)
4495{
4496 switch (type)
4497 {
32ec8896 4498 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4499 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4500 default: return NULL;
a06ea964 4501 }
a06ea964
NC
4502}
4503
b294bdf8
MM
4504static const char *
4505get_arm_segment_type (unsigned long type)
4506{
4507 switch (type)
4508 {
32ec8896
NC
4509 case PT_ARM_EXIDX: return "EXIDX";
4510 default: return NULL;
b294bdf8 4511 }
b294bdf8
MM
4512}
4513
b4cbbe8f
AK
4514static const char *
4515get_s390_segment_type (unsigned long type)
4516{
4517 switch (type)
4518 {
4519 case PT_S390_PGSTE: return "S390_PGSTE";
4520 default: return NULL;
4521 }
4522}
4523
d3ba0551
AM
4524static const char *
4525get_mips_segment_type (unsigned long type)
252b5132
RH
4526{
4527 switch (type)
4528 {
32ec8896
NC
4529 case PT_MIPS_REGINFO: return "REGINFO";
4530 case PT_MIPS_RTPROC: return "RTPROC";
4531 case PT_MIPS_OPTIONS: return "OPTIONS";
4532 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4533 default: return NULL;
252b5132 4534 }
252b5132
RH
4535}
4536
103f02d3 4537static const char *
d3ba0551 4538get_parisc_segment_type (unsigned long type)
103f02d3
UD
4539{
4540 switch (type)
4541 {
103f02d3
UD
4542 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4543 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4544 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4545 default: return NULL;
103f02d3 4546 }
103f02d3
UD
4547}
4548
4d6ed7c8 4549static const char *
d3ba0551 4550get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4551{
4552 switch (type)
4553 {
4554 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4555 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4556 default: return NULL;
4d6ed7c8 4557 }
4d6ed7c8
NC
4558}
4559
40b36596
JM
4560static const char *
4561get_tic6x_segment_type (unsigned long type)
4562{
4563 switch (type)
4564 {
32ec8896
NC
4565 case PT_C6000_PHATTR: return "C6000_PHATTR";
4566 default: return NULL;
40b36596 4567 }
40b36596
JM
4568}
4569
fbc95f1e
KC
4570static const char *
4571get_riscv_segment_type (unsigned long type)
4572{
4573 switch (type)
4574 {
4575 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4576 default: return NULL;
4577 }
4578}
4579
df3a023b
AM
4580static const char *
4581get_hpux_segment_type (unsigned long type, unsigned e_machine)
4582{
4583 if (e_machine == EM_PARISC)
4584 switch (type)
4585 {
4586 case PT_HP_TLS: return "HP_TLS";
4587 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4588 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4589 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4590 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4591 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4592 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4593 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4594 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4595 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4596 case PT_HP_PARALLEL: return "HP_PARALLEL";
4597 case PT_HP_FASTBIND: return "HP_FASTBIND";
4598 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4599 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4600 case PT_HP_STACK: return "HP_STACK";
4601 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4602 default: return NULL;
4603 }
4604
4605 if (e_machine == EM_IA_64)
4606 switch (type)
4607 {
4608 case PT_HP_TLS: return "HP_TLS";
4609 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4610 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4611 case PT_IA_64_HP_STACK: return "HP_STACK";
4612 default: return NULL;
4613 }
4614
4615 return NULL;
4616}
4617
5522f910
NC
4618static const char *
4619get_solaris_segment_type (unsigned long type)
4620{
4621 switch (type)
4622 {
4623 case 0x6464e550: return "PT_SUNW_UNWIND";
4624 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4625 case 0x6ffffff7: return "PT_LOSUNW";
4626 case 0x6ffffffa: return "PT_SUNWBSS";
4627 case 0x6ffffffb: return "PT_SUNWSTACK";
4628 case 0x6ffffffc: return "PT_SUNWDTRACE";
4629 case 0x6ffffffd: return "PT_SUNWCAP";
4630 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4631 default: return NULL;
5522f910
NC
4632 }
4633}
4634
252b5132 4635static const char *
dda8d76d 4636get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4637{
b34976b6 4638 static char buff[32];
252b5132
RH
4639
4640 switch (p_type)
4641 {
b34976b6
AM
4642 case PT_NULL: return "NULL";
4643 case PT_LOAD: return "LOAD";
252b5132 4644 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4645 case PT_INTERP: return "INTERP";
4646 case PT_NOTE: return "NOTE";
4647 case PT_SHLIB: return "SHLIB";
4648 case PT_PHDR: return "PHDR";
13ae64f3 4649 case PT_TLS: return "TLS";
32ec8896 4650 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4651 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4652 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4653 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
cf0e0a0b 4654 case PT_GNU_SFRAME: return "GNU_SFRAME";
65765700 4655
80251d41 4656 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
3eba3ef3
NC
4657 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4658 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4659 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4660
252b5132 4661 default:
df3a023b 4662 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4663 {
2cf0635d 4664 const char * result;
103f02d3 4665
dda8d76d 4666 switch (filedata->file_header.e_machine)
252b5132 4667 {
a06ea964
NC
4668 case EM_AARCH64:
4669 result = get_aarch64_segment_type (p_type);
4670 break;
b294bdf8
MM
4671 case EM_ARM:
4672 result = get_arm_segment_type (p_type);
4673 break;
252b5132 4674 case EM_MIPS:
4fe85591 4675 case EM_MIPS_RS3_LE:
252b5132
RH
4676 result = get_mips_segment_type (p_type);
4677 break;
103f02d3
UD
4678 case EM_PARISC:
4679 result = get_parisc_segment_type (p_type);
4680 break;
4d6ed7c8
NC
4681 case EM_IA_64:
4682 result = get_ia64_segment_type (p_type);
4683 break;
40b36596
JM
4684 case EM_TI_C6000:
4685 result = get_tic6x_segment_type (p_type);
4686 break;
b4cbbe8f
AK
4687 case EM_S390:
4688 case EM_S390_OLD:
4689 result = get_s390_segment_type (p_type);
4690 break;
fbc95f1e
KC
4691 case EM_RISCV:
4692 result = get_riscv_segment_type (p_type);
4693 break;
252b5132
RH
4694 default:
4695 result = NULL;
4696 break;
4697 }
103f02d3 4698
252b5132
RH
4699 if (result != NULL)
4700 return result;
103f02d3 4701
1a9ccd70 4702 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4703 }
4704 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4705 {
df3a023b 4706 const char * result = NULL;
103f02d3 4707
df3a023b 4708 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4709 {
df3a023b
AM
4710 case ELFOSABI_GNU:
4711 case ELFOSABI_FREEBSD:
4712 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4713 {
4714 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4715 result = buff;
4716 }
103f02d3 4717 break;
df3a023b
AM
4718 case ELFOSABI_HPUX:
4719 result = get_hpux_segment_type (p_type,
4720 filedata->file_header.e_machine);
4721 break;
4722 case ELFOSABI_SOLARIS:
4723 result = get_solaris_segment_type (p_type);
00428cca 4724 break;
103f02d3 4725 default:
103f02d3
UD
4726 break;
4727 }
103f02d3
UD
4728 if (result != NULL)
4729 return result;
4730
1a9ccd70 4731 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4732 }
252b5132 4733 else
e9e44622 4734 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4735
4736 return buff;
4737 }
4738}
4739
53a346d8
CZ
4740static const char *
4741get_arc_section_type_name (unsigned int sh_type)
4742{
4743 switch (sh_type)
4744 {
4745 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4746 default:
4747 break;
4748 }
4749 return NULL;
4750}
4751
252b5132 4752static const char *
d3ba0551 4753get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4754{
4755 switch (sh_type)
4756 {
b34976b6
AM
4757 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4758 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4759 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4760 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4761 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4762 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4763 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4764 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4765 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4766 case SHT_MIPS_RELD: return "MIPS_RELD";
4767 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4768 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4769 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4770 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4771 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4772 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4773 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4774 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4775 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4776 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4777 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4778 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4779 case SHT_MIPS_LINE: return "MIPS_LINE";
4780 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4781 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4782 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4783 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4784 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4785 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4786 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4787 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4788 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4789 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4790 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4791 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4792 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4793 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4794 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4795 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4796 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4797 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4798 default:
4799 break;
4800 }
4801 return NULL;
4802}
4803
103f02d3 4804static const char *
d3ba0551 4805get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4806{
4807 switch (sh_type)
4808 {
4809 case SHT_PARISC_EXT: return "PARISC_EXT";
4810 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4811 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4812 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4813 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4814 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4815 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4816 default: return NULL;
103f02d3 4817 }
103f02d3
UD
4818}
4819
4d6ed7c8 4820static const char *
dda8d76d 4821get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4822{
18bd398b 4823 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4824 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4825 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4826
4d6ed7c8
NC
4827 switch (sh_type)
4828 {
148b93f2
NC
4829 case SHT_IA_64_EXT: return "IA_64_EXT";
4830 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4831 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4832 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4833 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4834 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4835 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4836 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4837 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4838 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4839 default:
4840 break;
4841 }
4842 return NULL;
4843}
4844
d2b2c203
DJ
4845static const char *
4846get_x86_64_section_type_name (unsigned int sh_type)
4847{
4848 switch (sh_type)
4849 {
4850 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4851 default: return NULL;
d2b2c203 4852 }
d2b2c203
DJ
4853}
4854
a06ea964
NC
4855static const char *
4856get_aarch64_section_type_name (unsigned int sh_type)
4857{
4858 switch (sh_type)
4859 {
32ec8896
NC
4860 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4861 default: return NULL;
a06ea964 4862 }
a06ea964
NC
4863}
4864
40a18ebd
NC
4865static const char *
4866get_arm_section_type_name (unsigned int sh_type)
4867{
4868 switch (sh_type)
4869 {
7f6fed87
NC
4870 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4871 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4872 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4873 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4874 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4875 default: return NULL;
40a18ebd 4876 }
40a18ebd
NC
4877}
4878
40b36596
JM
4879static const char *
4880get_tic6x_section_type_name (unsigned int sh_type)
4881{
4882 switch (sh_type)
4883 {
32ec8896
NC
4884 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4885 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4886 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4887 case SHT_TI_ICODE: return "TI_ICODE";
4888 case SHT_TI_XREF: return "TI_XREF";
4889 case SHT_TI_HANDLER: return "TI_HANDLER";
4890 case SHT_TI_INITINFO: return "TI_INITINFO";
4891 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4892 default: return NULL;
40b36596 4893 }
40b36596
JM
4894}
4895
13761a11 4896static const char *
b0191216 4897get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4898{
4899 switch (sh_type)
4900 {
32ec8896
NC
4901 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4902 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4903 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4904 default: return NULL;
13761a11
NC
4905 }
4906}
4907
fe944acf
FT
4908static const char *
4909get_nfp_section_type_name (unsigned int sh_type)
4910{
4911 switch (sh_type)
4912 {
4913 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4914 case SHT_NFP_INITREG: return "NFP_INITREG";
4915 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4916 default: return NULL;
4917 }
4918}
4919
685080f2
NC
4920static const char *
4921get_v850_section_type_name (unsigned int sh_type)
4922{
4923 switch (sh_type)
4924 {
32ec8896
NC
4925 case SHT_V850_SCOMMON: return "V850 Small Common";
4926 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4927 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4928 case SHT_RENESAS_IOP: return "RENESAS IOP";
4929 case SHT_RENESAS_INFO: return "RENESAS INFO";
4930 default: return NULL;
685080f2
NC
4931 }
4932}
4933
2dc8dd17
JW
4934static const char *
4935get_riscv_section_type_name (unsigned int sh_type)
4936{
4937 switch (sh_type)
4938 {
4939 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4940 default: return NULL;
4941 }
4942}
4943
0861f561
CQ
4944static const char *
4945get_csky_section_type_name (unsigned int sh_type)
4946{
4947 switch (sh_type)
4948 {
4949 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4950 default: return NULL;
4951 }
4952}
4953
252b5132 4954static const char *
dda8d76d 4955get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4956{
b34976b6 4957 static char buff[32];
9fb71ee4 4958 const char * result;
252b5132
RH
4959
4960 switch (sh_type)
4961 {
4962 case SHT_NULL: return "NULL";
4963 case SHT_PROGBITS: return "PROGBITS";
4964 case SHT_SYMTAB: return "SYMTAB";
4965 case SHT_STRTAB: return "STRTAB";
4966 case SHT_RELA: return "RELA";
dd207c13 4967 case SHT_RELR: return "RELR";
252b5132
RH
4968 case SHT_HASH: return "HASH";
4969 case SHT_DYNAMIC: return "DYNAMIC";
4970 case SHT_NOTE: return "NOTE";
4971 case SHT_NOBITS: return "NOBITS";
4972 case SHT_REL: return "REL";
4973 case SHT_SHLIB: return "SHLIB";
4974 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4975 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4976 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4977 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4978 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4979 case SHT_GROUP: return "GROUP";
67ce483b 4980 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4981 case SHT_GNU_verdef: return "VERDEF";
4982 case SHT_GNU_verneed: return "VERNEED";
4983 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4984 case 0x6ffffff0: return "VERSYM";
4985 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4986 case 0x7ffffffd: return "AUXILIARY";
4987 case 0x7fffffff: return "FILTER";
047b2264 4988 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4989
4990 default:
4991 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4992 {
dda8d76d 4993 switch (filedata->file_header.e_machine)
252b5132 4994 {
53a346d8
CZ
4995 case EM_ARC:
4996 case EM_ARC_COMPACT:
4997 case EM_ARC_COMPACT2:
13aa307c
CZ
4998 case EM_ARC_COMPACT3:
4999 case EM_ARC_COMPACT3_64:
53a346d8
CZ
5000 result = get_arc_section_type_name (sh_type);
5001 break;
252b5132 5002 case EM_MIPS:
4fe85591 5003 case EM_MIPS_RS3_LE:
252b5132
RH
5004 result = get_mips_section_type_name (sh_type);
5005 break;
103f02d3
UD
5006 case EM_PARISC:
5007 result = get_parisc_section_type_name (sh_type);
5008 break;
4d6ed7c8 5009 case EM_IA_64:
dda8d76d 5010 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 5011 break;
d2b2c203 5012 case EM_X86_64:
8a9036a4 5013 case EM_L1OM:
7a9068fe 5014 case EM_K1OM:
d2b2c203
DJ
5015 result = get_x86_64_section_type_name (sh_type);
5016 break;
a06ea964
NC
5017 case EM_AARCH64:
5018 result = get_aarch64_section_type_name (sh_type);
5019 break;
40a18ebd
NC
5020 case EM_ARM:
5021 result = get_arm_section_type_name (sh_type);
5022 break;
40b36596
JM
5023 case EM_TI_C6000:
5024 result = get_tic6x_section_type_name (sh_type);
5025 break;
13761a11 5026 case EM_MSP430:
b0191216 5027 result = get_msp430_section_type_name (sh_type);
13761a11 5028 break;
fe944acf
FT
5029 case EM_NFP:
5030 result = get_nfp_section_type_name (sh_type);
5031 break;
685080f2
NC
5032 case EM_V800:
5033 case EM_V850:
5034 case EM_CYGNUS_V850:
5035 result = get_v850_section_type_name (sh_type);
5036 break;
2dc8dd17
JW
5037 case EM_RISCV:
5038 result = get_riscv_section_type_name (sh_type);
5039 break;
0861f561
CQ
5040 case EM_CSKY:
5041 result = get_csky_section_type_name (sh_type);
5042 break;
252b5132
RH
5043 default:
5044 result = NULL;
5045 break;
5046 }
5047
5048 if (result != NULL)
5049 return result;
5050
9fb71ee4 5051 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5052 }
5053 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5054 {
dda8d76d 5055 switch (filedata->file_header.e_machine)
148b93f2
NC
5056 {
5057 case EM_IA_64:
dda8d76d 5058 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5059 break;
5060 default:
dda8d76d 5061 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5062 result = get_solaris_section_type (sh_type);
5063 else
1b4b80bf
NC
5064 {
5065 switch (sh_type)
5066 {
5067 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5068 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5069 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5070 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5071 default:
5072 result = NULL;
5073 break;
5074 }
5075 }
148b93f2
NC
5076 break;
5077 }
5078
5079 if (result != NULL)
5080 return result;
5081
9fb71ee4 5082 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5083 }
252b5132 5084 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5085 {
dda8d76d 5086 switch (filedata->file_header.e_machine)
685080f2
NC
5087 {
5088 case EM_V800:
5089 case EM_V850:
5090 case EM_CYGNUS_V850:
9fb71ee4 5091 result = get_v850_section_type_name (sh_type);
a9fb83be 5092 break;
685080f2 5093 default:
9fb71ee4 5094 result = NULL;
685080f2
NC
5095 break;
5096 }
5097
9fb71ee4
NC
5098 if (result != NULL)
5099 return result;
5100
5101 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5102 }
252b5132 5103 else
a7dbfd1c
NC
5104 /* This message is probably going to be displayed in a 15
5105 character wide field, so put the hex value first. */
5106 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5107
252b5132
RH
5108 return buff;
5109 }
5110}
5111
79bc120c
NC
5112enum long_option_values
5113{
5114 OPTION_DEBUG_DUMP = 512,
5115 OPTION_DYN_SYMS,
0f03783c 5116 OPTION_LTO_SYMS,
79bc120c
NC
5117 OPTION_DWARF_DEPTH,
5118 OPTION_DWARF_START,
5119 OPTION_DWARF_CHECK,
5120 OPTION_CTF_DUMP,
5121 OPTION_CTF_PARENT,
5122 OPTION_CTF_SYMBOLS,
5123 OPTION_CTF_STRINGS,
42b6953b 5124 OPTION_SFRAME_DUMP,
79bc120c
NC
5125 OPTION_WITH_SYMBOL_VERSIONS,
5126 OPTION_RECURSE_LIMIT,
5127 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
5128 OPTION_NO_DEMANGLING,
5129 OPTION_SYM_BASE
79bc120c 5130};
2979dc34 5131
85b1c36d 5132static struct option options[] =
252b5132 5133{
79bc120c
NC
5134 /* Note - This table is alpha-sorted on the 'val'
5135 field in order to make adding new options easier. */
5136 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5137 {"all", no_argument, 0, 'a'},
79bc120c
NC
5138 {"demangle", optional_argument, 0, 'C'},
5139 {"archive-index", no_argument, 0, 'c'},
5140 {"use-dynamic", no_argument, 0, 'D'},
5141 {"dynamic", no_argument, 0, 'd'},
b34976b6 5142 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5143 {"section-groups", no_argument, 0, 'g'},
5144 {"help", no_argument, 0, 'H'},
5145 {"file-header", no_argument, 0, 'h'},
b34976b6 5146 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5147 {"lint", no_argument, 0, 'L'},
5148 {"enable-checks", no_argument, 0, 'L'},
5149 {"program-headers", no_argument, 0, 'l'},
b34976b6 5150 {"segments", no_argument, 0, 'l'},
595cf52e 5151 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5152 {"notes", no_argument, 0, 'n'},
ca0e11aa 5153 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5154 {"string-dump", required_argument, 0, 'p'},
5155 {"relocated-dump", required_argument, 0, 'R'},
5156 {"relocs", no_argument, 0, 'r'},
5157 {"section-headers", no_argument, 0, 'S'},
5158 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5159 {"symbols", no_argument, 0, 's'},
5160 {"syms", no_argument, 0, 's'},
79bc120c
NC
5161 {"silent-truncation",no_argument, 0, 'T'},
5162 {"section-details", no_argument, 0, 't'},
b3aa80b4 5163 {"unicode", required_argument, NULL, 'U'},
09c11c86 5164 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5165 {"version-info", no_argument, 0, 'V'},
5166 {"version", no_argument, 0, 'v'},
5167 {"wide", no_argument, 0, 'W'},
b34976b6 5168 {"hex-dump", required_argument, 0, 'x'},
0e602686 5169 {"decompress", no_argument, 0, 'z'},
252b5132 5170
79bc120c
NC
5171 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5172 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5173 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5174 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5175 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5176 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5177 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5178 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5179 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5180 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5181#ifdef ENABLE_LIBCTF
d344b407 5182 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5183 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5184 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5185 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5186#endif
42b6953b 5187 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
047c3dbf 5188 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5189
b34976b6 5190 {0, no_argument, 0, 0}
252b5132
RH
5191};
5192
5193static void
2cf0635d 5194usage (FILE * stream)
252b5132 5195{
92f01d61
JM
5196 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5197 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5198 fprintf (stream, _(" Options are:\n"));
5199 fprintf (stream, _("\
5200 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5201 fprintf (stream, _("\
5202 -h --file-header Display the ELF file header\n"));
5203 fprintf (stream, _("\
5204 -l --program-headers Display the program headers\n"));
5205 fprintf (stream, _("\
5206 --segments An alias for --program-headers\n"));
5207 fprintf (stream, _("\
5208 -S --section-headers Display the sections' header\n"));
5209 fprintf (stream, _("\
5210 --sections An alias for --section-headers\n"));
5211 fprintf (stream, _("\
5212 -g --section-groups Display the section groups\n"));
5213 fprintf (stream, _("\
5214 -t --section-details Display the section details\n"));
5215 fprintf (stream, _("\
5216 -e --headers Equivalent to: -h -l -S\n"));
5217 fprintf (stream, _("\
5218 -s --syms Display the symbol table\n"));
5219 fprintf (stream, _("\
5220 --symbols An alias for --syms\n"));
5221 fprintf (stream, _("\
5222 --dyn-syms Display the dynamic symbol table\n"));
5223 fprintf (stream, _("\
5224 --lto-syms Display LTO symbol tables\n"));
5225 fprintf (stream, _("\
047c3dbf
NL
5226 --sym-base=[0|8|10|16] \n\
5227 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5228 mixed (the default), octal, decimal, hexadecimal.\n"));
5229 fprintf (stream, _("\
0d646226
AM
5230 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5231 display_demangler_styles (stream, _("\
5232 STYLE can be "));
d6249f5f
AM
5233 fprintf (stream, _("\
5234 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5235 fprintf (stream, _("\
5236 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5237 fprintf (stream, _("\
5238 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5239 fprintf (stream, _("\
5240 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5241 Display unicode characters as determined by the current locale\n\
5242 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5243 escape sequences, or treat them as invalid and display as\n\
5244 \"{hex sequences}\"\n"));
d6249f5f
AM
5245 fprintf (stream, _("\
5246 -n --notes Display the core notes (if present)\n"));
5247 fprintf (stream, _("\
5248 -r --relocs Display the relocations (if present)\n"));
5249 fprintf (stream, _("\
5250 -u --unwind Display the unwind info (if present)\n"));
5251 fprintf (stream, _("\
5252 -d --dynamic Display the dynamic section (if present)\n"));
5253 fprintf (stream, _("\
5254 -V --version-info Display the version sections (if present)\n"));
5255 fprintf (stream, _("\
5256 -A --arch-specific Display architecture specific information (if any)\n"));
5257 fprintf (stream, _("\
5258 -c --archive-index Display the symbol/file index in an archive\n"));
5259 fprintf (stream, _("\
5260 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5261 fprintf (stream, _("\
5262 -L --lint|--enable-checks\n\
5263 Display warning messages for possible problems\n"));
5264 fprintf (stream, _("\
09c11c86 5265 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5266 Dump the contents of section <number|name> as bytes\n"));
5267 fprintf (stream, _("\
09c11c86 5268 -p --string-dump=<number|name>\n\
d6249f5f
AM
5269 Dump the contents of section <number|name> as strings\n"));
5270 fprintf (stream, _("\
cf13d699 5271 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5272 Dump the relocated contents of section <number|name>\n"));
5273 fprintf (stream, _("\
5274 -z --decompress Decompress section before dumping it\n"));
5275 fprintf (stream, _("\
5276 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5277 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5278 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5279 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5280 U/=trace_info]\n\
5281 Display the contents of DWARF debug sections\n"));
5282 fprintf (stream, _("\
5283 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5284 debuginfo files\n"));
5285 fprintf (stream, _("\
5286 -P --process-links Display the contents of non-debug sections in separate\n\
5287 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5288#if DEFAULT_FOR_FOLLOW_LINKS
5289 fprintf (stream, _("\
d6249f5f
AM
5290 -wK --debug-dump=follow-links\n\
5291 Follow links to separate debug info files (default)\n"));
5292 fprintf (stream, _("\
5293 -wN --debug-dump=no-follow-links\n\
5294 Do not follow links to separate debug info files\n"));
c46b7066
NC
5295#else
5296 fprintf (stream, _("\
d6249f5f
AM
5297 -wK --debug-dump=follow-links\n\
5298 Follow links to separate debug info files\n"));
5299 fprintf (stream, _("\
5300 -wN --debug-dump=no-follow-links\n\
5301 Do not follow links to separate debug info files\n\
5302 (default)\n"));
bed566bb
NC
5303#endif
5304#if HAVE_LIBDEBUGINFOD
5305 fprintf (stream, _("\
5306 -wD --debug-dump=use-debuginfod\n\
5307 When following links, also query debuginfod servers (default)\n"));
5308 fprintf (stream, _("\
5309 -wE --debug-dump=do-not-use-debuginfod\n\
5310 When following links, do not query debuginfod servers\n"));
c46b7066 5311#endif
fd2f0033 5312 fprintf (stream, _("\
d6249f5f
AM
5313 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5314 fprintf (stream, _("\
5315 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5316#ifdef ENABLE_LIBCTF
7d9813f1 5317 fprintf (stream, _("\
d6249f5f
AM
5318 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5319 fprintf (stream, _("\
80b56fad 5320 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5321 fprintf (stream, _("\
7d9813f1 5322 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5323 Use section <number|name> as the CTF external symtab\n"));
5324 fprintf (stream, _("\
7d9813f1 5325 --ctf-strings=<number|name>\n\
d6249f5f 5326 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5327#endif
42b6953b
IB
5328 fprintf (stream, _("\
5329 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
7d9813f1 5330
252b5132 5331#ifdef SUPPORT_DISASSEMBLY
92f01d61 5332 fprintf (stream, _("\
09c11c86
NC
5333 -i --instruction-dump=<number|name>\n\
5334 Disassemble the contents of section <number|name>\n"));
252b5132 5335#endif
92f01d61 5336 fprintf (stream, _("\
d6249f5f
AM
5337 -I --histogram Display histogram of bucket list lengths\n"));
5338 fprintf (stream, _("\
5339 -W --wide Allow output width to exceed 80 characters\n"));
5340 fprintf (stream, _("\
5341 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5342 fprintf (stream, _("\
5343 @<file> Read options from <file>\n"));
5344 fprintf (stream, _("\
5345 -H --help Display this information\n"));
5346 fprintf (stream, _("\
8b53311e 5347 -v --version Display the version number of readelf\n"));
1118d252 5348
92f01d61
JM
5349 if (REPORT_BUGS_TO[0] && stream == stdout)
5350 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5351
92f01d61 5352 exit (stream == stdout ? 0 : 1);
252b5132
RH
5353}
5354
18bd398b
NC
5355/* Record the fact that the user wants the contents of section number
5356 SECTION to be displayed using the method(s) encoded as flags bits
5357 in TYPE. Note, TYPE can be zero if we are creating the array for
5358 the first time. */
5359
252b5132 5360static void
6431e409
AM
5361request_dump_bynumber (struct dump_data *dumpdata,
5362 unsigned int section, dump_type type)
252b5132 5363{
6431e409 5364 if (section >= dumpdata->num_dump_sects)
252b5132 5365 {
2cf0635d 5366 dump_type * new_dump_sects;
252b5132 5367
3f5e193b 5368 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5369 sizeof (* new_dump_sects));
252b5132
RH
5370
5371 if (new_dump_sects == NULL)
591a748a 5372 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5373 else
5374 {
6431e409 5375 if (dumpdata->dump_sects)
21b65bac
NC
5376 {
5377 /* Copy current flag settings. */
6431e409
AM
5378 memcpy (new_dump_sects, dumpdata->dump_sects,
5379 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5380
6431e409 5381 free (dumpdata->dump_sects);
21b65bac 5382 }
252b5132 5383
6431e409
AM
5384 dumpdata->dump_sects = new_dump_sects;
5385 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5386 }
5387 }
5388
6431e409
AM
5389 if (dumpdata->dump_sects)
5390 dumpdata->dump_sects[section] |= type;
252b5132
RH
5391}
5392
aef1f6d0
DJ
5393/* Request a dump by section name. */
5394
5395static void
2cf0635d 5396request_dump_byname (const char * section, dump_type type)
aef1f6d0 5397{
2cf0635d 5398 struct dump_list_entry * new_request;
aef1f6d0 5399
3f5e193b
NC
5400 new_request = (struct dump_list_entry *)
5401 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5402 if (!new_request)
591a748a 5403 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5404
5405 new_request->name = strdup (section);
5406 if (!new_request->name)
591a748a 5407 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5408
5409 new_request->type = type;
5410
5411 new_request->next = dump_sects_byname;
5412 dump_sects_byname = new_request;
5413}
5414
cf13d699 5415static inline void
6431e409 5416request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5417{
5418 int section;
5419 char * cp;
5420
015dc7e1 5421 do_dump = true;
cf13d699
NC
5422 section = strtoul (optarg, & cp, 0);
5423
5424 if (! *cp && section >= 0)
6431e409 5425 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5426 else
5427 request_dump_byname (optarg, type);
5428}
5429
252b5132 5430static void
6431e409 5431parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5432{
5433 int c;
5434
5435 if (argc < 2)
92f01d61 5436 usage (stderr);
252b5132
RH
5437
5438 while ((c = getopt_long
b3aa80b4 5439 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5440 {
252b5132
RH
5441 switch (c)
5442 {
5443 case 0:
5444 /* Long options. */
5445 break;
5446 case 'H':
92f01d61 5447 usage (stdout);
252b5132
RH
5448 break;
5449
5450 case 'a':
015dc7e1
AM
5451 do_syms = true;
5452 do_reloc = true;
5453 do_unwind = true;
5454 do_dynamic = true;
5455 do_header = true;
5456 do_sections = true;
5457 do_section_groups = true;
5458 do_segments = true;
5459 do_version = true;
5460 do_histogram = true;
5461 do_arch = true;
5462 do_notes = true;
252b5132 5463 break;
79bc120c 5464
f5842774 5465 case 'g':
015dc7e1 5466 do_section_groups = true;
f5842774 5467 break;
5477e8a0 5468 case 't':
595cf52e 5469 case 'N':
015dc7e1
AM
5470 do_sections = true;
5471 do_section_details = true;
595cf52e 5472 break;
252b5132 5473 case 'e':
015dc7e1
AM
5474 do_header = true;
5475 do_sections = true;
5476 do_segments = true;
252b5132 5477 break;
a952a375 5478 case 'A':
015dc7e1 5479 do_arch = true;
a952a375 5480 break;
252b5132 5481 case 'D':
015dc7e1 5482 do_using_dynamic = true;
252b5132
RH
5483 break;
5484 case 'r':
015dc7e1 5485 do_reloc = true;
252b5132 5486 break;
4d6ed7c8 5487 case 'u':
015dc7e1 5488 do_unwind = true;
4d6ed7c8 5489 break;
252b5132 5490 case 'h':
015dc7e1 5491 do_header = true;
252b5132
RH
5492 break;
5493 case 'l':
015dc7e1 5494 do_segments = true;
252b5132
RH
5495 break;
5496 case 's':
015dc7e1 5497 do_syms = true;
252b5132
RH
5498 break;
5499 case 'S':
015dc7e1 5500 do_sections = true;
252b5132
RH
5501 break;
5502 case 'd':
015dc7e1 5503 do_dynamic = true;
252b5132 5504 break;
a952a375 5505 case 'I':
015dc7e1 5506 do_histogram = true;
a952a375 5507 break;
779fe533 5508 case 'n':
015dc7e1 5509 do_notes = true;
779fe533 5510 break;
4145f1d5 5511 case 'c':
015dc7e1 5512 do_archive_index = true;
4145f1d5 5513 break;
1b513401 5514 case 'L':
015dc7e1 5515 do_checks = true;
1b513401 5516 break;
ca0e11aa 5517 case 'P':
015dc7e1
AM
5518 process_links = true;
5519 do_follow_links = true;
e1dbfc17 5520 dump_any_debugging = true;
ca0e11aa 5521 break;
252b5132 5522 case 'x':
6431e409 5523 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5524 break;
09c11c86 5525 case 'p':
6431e409 5526 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5527 break;
5528 case 'R':
6431e409 5529 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5530 break;
0e602686 5531 case 'z':
015dc7e1 5532 decompress_dumps = true;
0e602686 5533 break;
252b5132 5534 case 'w':
0f03783c 5535 if (optarg == NULL)
613ff48b 5536 {
015dc7e1 5537 do_debugging = true;
94585d6d
NC
5538 do_dump = true;
5539 dump_any_debugging = true;
613ff48b
CC
5540 dwarf_select_sections_all ();
5541 }
252b5132
RH
5542 else
5543 {
015dc7e1 5544 do_debugging = false;
94585d6d
NC
5545 if (dwarf_select_sections_by_letters (optarg))
5546 {
5547 do_dump = true;
5548 dump_any_debugging = true;
5549 }
252b5132
RH
5550 }
5551 break;
2979dc34 5552 case OPTION_DEBUG_DUMP:
0f03783c 5553 if (optarg == NULL)
d6249f5f 5554 {
94585d6d 5555 do_dump = true;
d6249f5f 5556 do_debugging = true;
94585d6d 5557 dump_any_debugging = true;
d6249f5f
AM
5558 dwarf_select_sections_all ();
5559 }
2979dc34
JJ
5560 else
5561 {
015dc7e1 5562 do_debugging = false;
94585d6d
NC
5563 if (dwarf_select_sections_by_names (optarg))
5564 {
5565 do_dump = true;
5566 dump_any_debugging = true;
5567 }
2979dc34
JJ
5568 }
5569 break;
fd2f0033
TT
5570 case OPTION_DWARF_DEPTH:
5571 {
5572 char *cp;
5573
5574 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5575 }
5576 break;
5577 case OPTION_DWARF_START:
5578 {
5579 char *cp;
5580
5581 dwarf_start_die = strtoul (optarg, & cp, 0);
5582 }
5583 break;
4723351a 5584 case OPTION_DWARF_CHECK:
015dc7e1 5585 dwarf_check = true;
4723351a 5586 break;
7d9813f1 5587 case OPTION_CTF_DUMP:
015dc7e1 5588 do_ctf = true;
6431e409 5589 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5590 break;
5591 case OPTION_CTF_SYMBOLS:
df16e041 5592 free (dump_ctf_symtab_name);
7d9813f1
NA
5593 dump_ctf_symtab_name = strdup (optarg);
5594 break;
5595 case OPTION_CTF_STRINGS:
df16e041 5596 free (dump_ctf_strtab_name);
7d9813f1
NA
5597 dump_ctf_strtab_name = strdup (optarg);
5598 break;
5599 case OPTION_CTF_PARENT:
df16e041 5600 free (dump_ctf_parent_name);
7d9813f1
NA
5601 dump_ctf_parent_name = strdup (optarg);
5602 break;
42b6953b
IB
5603 case OPTION_SFRAME_DUMP:
5604 do_sframe = true;
5605 /* Providing section name is optional. request_dump (), however,
5606 thrives on non NULL optarg. Handle it explicitly here. */
5607 if (optarg != NULL)
5608 request_dump (dumpdata, SFRAME_DUMP);
5609 else
5610 {
5611 do_dump = true;
5612 const char *sframe_sec_name = strdup (".sframe");
5613 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
5614 }
5615 break;
2c610e4b 5616 case OPTION_DYN_SYMS:
015dc7e1 5617 do_dyn_syms = true;
2c610e4b 5618 break;
0f03783c 5619 case OPTION_LTO_SYMS:
015dc7e1 5620 do_lto_syms = true;
0f03783c 5621 break;
252b5132
RH
5622#ifdef SUPPORT_DISASSEMBLY
5623 case 'i':
6431e409 5624 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5625 break;
252b5132
RH
5626#endif
5627 case 'v':
5628 print_version (program_name);
5629 break;
5630 case 'V':
015dc7e1 5631 do_version = true;
252b5132 5632 break;
d974e256 5633 case 'W':
015dc7e1 5634 do_wide = true;
d974e256 5635 break;
0942c7ab 5636 case 'T':
015dc7e1 5637 do_not_show_symbol_truncation = true;
0942c7ab 5638 break;
79bc120c 5639 case 'C':
015dc7e1 5640 do_demangle = true;
79bc120c
NC
5641 if (optarg != NULL)
5642 {
5643 enum demangling_styles style;
5644
5645 style = cplus_demangle_name_to_style (optarg);
5646 if (style == unknown_demangling)
5647 error (_("unknown demangling style `%s'"), optarg);
5648
5649 cplus_demangle_set_style (style);
5650 }
5651 break;
5652 case OPTION_NO_DEMANGLING:
015dc7e1 5653 do_demangle = false;
79bc120c
NC
5654 break;
5655 case OPTION_RECURSE_LIMIT:
5656 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5657 break;
5658 case OPTION_NO_RECURSE_LIMIT:
5659 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5660 break;
5661 case OPTION_WITH_SYMBOL_VERSIONS:
5662 /* Ignored for backward compatibility. */
5663 break;
b9e920ec 5664
b3aa80b4
NC
5665 case 'U':
5666 if (optarg == NULL)
5667 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5668 else if (streq (optarg, "default") || streq (optarg, "d"))
5669 unicode_display = unicode_default;
5670 else if (streq (optarg, "locale") || streq (optarg, "l"))
5671 unicode_display = unicode_locale;
5672 else if (streq (optarg, "escape") || streq (optarg, "e"))
5673 unicode_display = unicode_escape;
5674 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5675 unicode_display = unicode_invalid;
5676 else if (streq (optarg, "hex") || streq (optarg, "x"))
5677 unicode_display = unicode_hex;
5678 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5679 unicode_display = unicode_highlight;
5680 else
5681 error (_("invalid argument to -U/--unicode: %s"), optarg);
5682 break;
5683
047c3dbf
NL
5684 case OPTION_SYM_BASE:
5685 sym_base = 0;
5686 if (optarg != NULL)
5687 {
5688 sym_base = strtoul (optarg, NULL, 0);
5689 switch (sym_base)
5690 {
5691 case 0:
5692 case 8:
5693 case 10:
5694 case 16:
5695 break;
5696
5697 default:
5698 sym_base = 0;
5699 break;
5700 }
5701 }
5702 break;
5703
252b5132 5704 default:
252b5132
RH
5705 /* xgettext:c-format */
5706 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5707 /* Fall through. */
252b5132 5708 case '?':
92f01d61 5709 usage (stderr);
252b5132
RH
5710 }
5711 }
5712
4d6ed7c8 5713 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5714 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5715 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5716 && !do_section_groups && !do_archive_index
0f03783c 5717 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5718 {
5719 if (do_checks)
5720 {
015dc7e1
AM
5721 check_all = true;
5722 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5723 do_segments = do_header = do_dump = do_version = true;
5724 do_histogram = do_debugging = do_arch = do_notes = true;
5725 do_section_groups = do_archive_index = do_dyn_syms = true;
5726 do_lto_syms = true;
1b513401
NC
5727 }
5728 else
5729 usage (stderr);
5730 }
252b5132
RH
5731}
5732
5733static const char *
d3ba0551 5734get_elf_class (unsigned int elf_class)
252b5132 5735{
b34976b6 5736 static char buff[32];
103f02d3 5737
252b5132
RH
5738 switch (elf_class)
5739 {
5740 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5741 case ELFCLASS32: return "ELF32";
5742 case ELFCLASS64: return "ELF64";
ab5e7794 5743 default:
e9e44622 5744 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5745 return buff;
252b5132
RH
5746 }
5747}
5748
5749static const char *
d3ba0551 5750get_data_encoding (unsigned int encoding)
252b5132 5751{
b34976b6 5752 static char buff[32];
103f02d3 5753
252b5132
RH
5754 switch (encoding)
5755 {
5756 case ELFDATANONE: return _("none");
33c63f9d
CM
5757 case ELFDATA2LSB: return _("2's complement, little endian");
5758 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5759 default:
e9e44622 5760 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5761 return buff;
252b5132
RH
5762 }
5763}
5764
521f7268
NC
5765static bool
5766check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
5767{
5768 if (header->e_ident[EI_MAG0] == ELFMAG0
5769 && header->e_ident[EI_MAG1] == ELFMAG1
5770 && header->e_ident[EI_MAG2] == ELFMAG2
5771 && header->e_ident[EI_MAG3] == ELFMAG3)
5772 return true;
5773
5774 /* Some compilers produce object files that are not in the ELF file format.
5775 As an aid to users of readelf, try to identify these cases and suggest
5776 alternative tools.
5777
5778 FIXME: It is not clear if all four bytes are used as constant magic
5779 valus by all compilers. It may be necessary to recode this function if
5780 different tools use different length sequences. */
5781
5782 static struct
5783 {
5784 unsigned char magic[4];
5785 const char * obj_message;
5786 const char * ar_message;
5787 }
5788 known_magic[] =
5789 {
5790 { { 'B', 'C', 0xc0, 0xde },
5791 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
5792 N_("This is a LLVM bitcode file - try extracing and then using llvm-bcanalyzer\n")
5793 },
5794 { { 'g', 'o', ' ', 'o' },
5795 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
5796 NULL
5797 }
5798 };
5799 int i;
5800
5801 for (i = ARRAY_SIZE (known_magic); i--;)
5802 {
5803 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
5804 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
5805 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
5806 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
5807 {
5808 /* Some compiler's analyzer tools do not handle archives,
5809 so we provide two different kinds of error message. */
5810 if (filedata->archive_file_size > 0
5811 && known_magic[i].ar_message != NULL)
b3ea2010 5812 error ("%s", known_magic[i].ar_message);
521f7268 5813 else
b3ea2010 5814 error ("%s", known_magic[i].obj_message);
521f7268
NC
5815 return false;
5816 }
5817 }
5818
5819 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
5820 return false;
5821}
5822
dda8d76d 5823/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5824
015dc7e1 5825static bool
dda8d76d 5826process_file_header (Filedata * filedata)
252b5132 5827{
dda8d76d
NC
5828 Elf_Internal_Ehdr * header = & filedata->file_header;
5829
521f7268
NC
5830 if (! check_magic_number (filedata, header))
5831 return false;
252b5132 5832
ca0e11aa
NC
5833 if (! filedata->is_separate)
5834 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5835
252b5132
RH
5836 if (do_header)
5837 {
32ec8896 5838 unsigned i;
252b5132 5839
ca0e11aa
NC
5840 if (filedata->is_separate)
5841 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5842 else
5843 printf (_("ELF Header:\n"));
252b5132 5844 printf (_(" Magic: "));
b34976b6 5845 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5846 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5847 printf ("\n");
5848 printf (_(" Class: %s\n"),
dda8d76d 5849 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5850 printf (_(" Data: %s\n"),
dda8d76d 5851 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5852 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5853 header->e_ident[EI_VERSION],
5854 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5855 ? _(" (current)")
dda8d76d 5856 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5857 ? _(" <unknown>")
789be9f7 5858 : "")));
252b5132 5859 printf (_(" OS/ABI: %s\n"),
dda8d76d 5860 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5861 printf (_(" ABI Version: %d\n"),
dda8d76d 5862 header->e_ident[EI_ABIVERSION]);
252b5132 5863 printf (_(" Type: %s\n"),
93df3340 5864 get_file_type (filedata));
252b5132 5865 printf (_(" Machine: %s\n"),
dda8d76d 5866 get_machine_name (header->e_machine));
252b5132 5867 printf (_(" Version: 0x%lx\n"),
e8a64888 5868 header->e_version);
76da6bbe 5869
f7a99963 5870 printf (_(" Entry point address: "));
e8a64888 5871 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5872 printf (_("\n Start of program headers: "));
e8a64888 5873 print_vma (header->e_phoff, DEC);
f7a99963 5874 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5875 print_vma (header->e_shoff, DEC);
f7a99963 5876 printf (_(" (bytes into file)\n"));
76da6bbe 5877
252b5132 5878 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5879 header->e_flags,
dda8d76d 5880 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5881 printf (_(" Size of this header: %u (bytes)\n"),
5882 header->e_ehsize);
5883 printf (_(" Size of program headers: %u (bytes)\n"),
5884 header->e_phentsize);
5885 printf (_(" Number of program headers: %u"),
5886 header->e_phnum);
dda8d76d
NC
5887 if (filedata->section_headers != NULL
5888 && header->e_phnum == PN_XNUM
5889 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5890 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5891 putc ('\n', stdout);
e8a64888
AM
5892 printf (_(" Size of section headers: %u (bytes)\n"),
5893 header->e_shentsize);
5894 printf (_(" Number of section headers: %u"),
5895 header->e_shnum);
dda8d76d 5896 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5897 {
5898 header->e_shnum = filedata->section_headers[0].sh_size;
5899 printf (" (%u)", header->e_shnum);
5900 }
560f3c1c 5901 putc ('\n', stdout);
e8a64888
AM
5902 printf (_(" Section header string table index: %u"),
5903 header->e_shstrndx);
dda8d76d
NC
5904 if (filedata->section_headers != NULL
5905 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5906 {
5907 header->e_shstrndx = filedata->section_headers[0].sh_link;
5908 printf (" (%u)", header->e_shstrndx);
5909 }
5910 if (header->e_shstrndx != SHN_UNDEF
5911 && header->e_shstrndx >= header->e_shnum)
5912 {
5913 header->e_shstrndx = SHN_UNDEF;
5914 printf (_(" <corrupt: out of range>"));
5915 }
560f3c1c
AM
5916 putc ('\n', stdout);
5917 }
5918
dda8d76d 5919 if (filedata->section_headers != NULL)
560f3c1c 5920 {
dda8d76d
NC
5921 if (header->e_phnum == PN_XNUM
5922 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5923 {
5924 /* Throw away any cached read of PN_XNUM headers. */
5925 free (filedata->program_headers);
5926 filedata->program_headers = NULL;
5927 header->e_phnum = filedata->section_headers[0].sh_info;
5928 }
dda8d76d
NC
5929 if (header->e_shnum == SHN_UNDEF)
5930 header->e_shnum = filedata->section_headers[0].sh_size;
5931 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5932 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5933 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5934 header->e_shstrndx = SHN_UNDEF;
252b5132 5935 }
103f02d3 5936
015dc7e1 5937 return true;
9ea033b2
NC
5938}
5939
dda8d76d
NC
5940/* Read in the program headers from FILEDATA and store them in PHEADERS.
5941 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5942
015dc7e1 5943static bool
dda8d76d 5944get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5945{
2cf0635d
NC
5946 Elf32_External_Phdr * phdrs;
5947 Elf32_External_Phdr * external;
5948 Elf_Internal_Phdr * internal;
b34976b6 5949 unsigned int i;
dda8d76d
NC
5950 unsigned int size = filedata->file_header.e_phentsize;
5951 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5952
5953 /* PR binutils/17531: Cope with unexpected section header sizes. */
5954 if (size == 0 || num == 0)
015dc7e1 5955 return false;
e0a31db1
NC
5956 if (size < sizeof * phdrs)
5957 {
5958 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5959 return false;
e0a31db1
NC
5960 }
5961 if (size > sizeof * phdrs)
5962 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5963
dda8d76d 5964 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5965 size, num, _("program headers"));
5966 if (phdrs == NULL)
015dc7e1 5967 return false;
9ea033b2 5968
91d6fa6a 5969 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5970 i < filedata->file_header.e_phnum;
b34976b6 5971 i++, internal++, external++)
252b5132 5972 {
9ea033b2
NC
5973 internal->p_type = BYTE_GET (external->p_type);
5974 internal->p_offset = BYTE_GET (external->p_offset);
5975 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5976 internal->p_paddr = BYTE_GET (external->p_paddr);
5977 internal->p_filesz = BYTE_GET (external->p_filesz);
5978 internal->p_memsz = BYTE_GET (external->p_memsz);
5979 internal->p_flags = BYTE_GET (external->p_flags);
5980 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5981 }
5982
9ea033b2 5983 free (phdrs);
015dc7e1 5984 return true;
252b5132
RH
5985}
5986
dda8d76d
NC
5987/* Read in the program headers from FILEDATA and store them in PHEADERS.
5988 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5989
015dc7e1 5990static bool
dda8d76d 5991get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5992{
2cf0635d
NC
5993 Elf64_External_Phdr * phdrs;
5994 Elf64_External_Phdr * external;
5995 Elf_Internal_Phdr * internal;
b34976b6 5996 unsigned int i;
dda8d76d
NC
5997 unsigned int size = filedata->file_header.e_phentsize;
5998 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5999
6000 /* PR binutils/17531: Cope with unexpected section header sizes. */
6001 if (size == 0 || num == 0)
015dc7e1 6002 return false;
e0a31db1
NC
6003 if (size < sizeof * phdrs)
6004 {
6005 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6006 return false;
e0a31db1
NC
6007 }
6008 if (size > sizeof * phdrs)
6009 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6010
dda8d76d 6011 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 6012 size, num, _("program headers"));
a6e9f9df 6013 if (!phdrs)
015dc7e1 6014 return false;
9ea033b2 6015
91d6fa6a 6016 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6017 i < filedata->file_header.e_phnum;
b34976b6 6018 i++, internal++, external++)
9ea033b2
NC
6019 {
6020 internal->p_type = BYTE_GET (external->p_type);
6021 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
6022 internal->p_offset = BYTE_GET (external->p_offset);
6023 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6024 internal->p_paddr = BYTE_GET (external->p_paddr);
6025 internal->p_filesz = BYTE_GET (external->p_filesz);
6026 internal->p_memsz = BYTE_GET (external->p_memsz);
6027 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
6028 }
6029
6030 free (phdrs);
015dc7e1 6031 return true;
9ea033b2 6032}
252b5132 6033
32ec8896 6034/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 6035
015dc7e1 6036static bool
dda8d76d 6037get_program_headers (Filedata * filedata)
d93f0186 6038{
2cf0635d 6039 Elf_Internal_Phdr * phdrs;
d93f0186
NC
6040
6041 /* Check cache of prior read. */
dda8d76d 6042 if (filedata->program_headers != NULL)
015dc7e1 6043 return true;
d93f0186 6044
82156ab7
NC
6045 /* Be kind to memory checkers by looking for
6046 e_phnum values which we know must be invalid. */
dda8d76d 6047 if (filedata->file_header.e_phnum
82156ab7 6048 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 6049 >= filedata->file_size)
82156ab7
NC
6050 {
6051 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 6052 filedata->file_header.e_phnum);
015dc7e1 6053 return false;
82156ab7 6054 }
d93f0186 6055
dda8d76d 6056 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 6057 sizeof (Elf_Internal_Phdr));
d93f0186
NC
6058 if (phdrs == NULL)
6059 {
8b73c356 6060 error (_("Out of memory reading %u program headers\n"),
dda8d76d 6061 filedata->file_header.e_phnum);
015dc7e1 6062 return false;
d93f0186
NC
6063 }
6064
6065 if (is_32bit_elf
dda8d76d
NC
6066 ? get_32bit_program_headers (filedata, phdrs)
6067 : get_64bit_program_headers (filedata, phdrs))
d93f0186 6068 {
dda8d76d 6069 filedata->program_headers = phdrs;
015dc7e1 6070 return true;
d93f0186
NC
6071 }
6072
6073 free (phdrs);
015dc7e1 6074 return false;
d93f0186
NC
6075}
6076
93df3340 6077/* Print program header info and locate dynamic section. */
2f62977e 6078
93df3340 6079static void
dda8d76d 6080process_program_headers (Filedata * filedata)
252b5132 6081{
2cf0635d 6082 Elf_Internal_Phdr * segment;
b34976b6 6083 unsigned int i;
1a9ccd70 6084 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6085
dda8d76d 6086 if (filedata->file_header.e_phnum == 0)
252b5132 6087 {
82f2dbf7 6088 /* PR binutils/12467. */
dda8d76d 6089 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6090 warn (_("possibly corrupt ELF header - it has a non-zero program"
6091 " header offset, but no program headers\n"));
82f2dbf7 6092 else if (do_segments)
ca0e11aa
NC
6093 {
6094 if (filedata->is_separate)
6095 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6096 filedata->file_name);
6097 else
6098 printf (_("\nThere are no program headers in this file.\n"));
6099 }
93df3340 6100 goto no_headers;
252b5132
RH
6101 }
6102
6103 if (do_segments && !do_header)
6104 {
ca0e11aa
NC
6105 if (filedata->is_separate)
6106 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6107 filedata->file_name, get_file_type (filedata));
ca0e11aa 6108 else
93df3340 6109 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6110 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6111 filedata->file_header.e_entry);
b8281767
AM
6112 printf (ngettext ("There is %d program header,"
6113 " starting at offset %" PRIu64 "\n",
6114 "There are %d program headers,"
6115 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6116 filedata->file_header.e_phnum),
6117 filedata->file_header.e_phnum,
625d49fc 6118 filedata->file_header.e_phoff);
252b5132
RH
6119 }
6120
dda8d76d 6121 if (! get_program_headers (filedata))
93df3340 6122 goto no_headers;
103f02d3 6123
252b5132
RH
6124 if (do_segments)
6125 {
dda8d76d 6126 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6127 printf (_("\nProgram Headers:\n"));
6128 else
6129 printf (_("\nProgram Headers:\n"));
76da6bbe 6130
f7a99963
NC
6131 if (is_32bit_elf)
6132 printf
6133 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6134 else if (do_wide)
6135 printf
6136 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6137 else
6138 {
6139 printf
6140 (_(" Type Offset VirtAddr PhysAddr\n"));
6141 printf
6142 (_(" FileSiz MemSiz Flags Align\n"));
6143 }
252b5132
RH
6144 }
6145
26c527e6 6146 uint64_t dynamic_addr = 0;
be7d229a 6147 uint64_t dynamic_size = 0;
dda8d76d
NC
6148 for (i = 0, segment = filedata->program_headers;
6149 i < filedata->file_header.e_phnum;
b34976b6 6150 i++, segment++)
252b5132
RH
6151 {
6152 if (do_segments)
6153 {
dda8d76d 6154 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6155
6156 if (is_32bit_elf)
6157 {
6158 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6159 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6160 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6161 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6162 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6163 printf ("%c%c%c ",
6164 (segment->p_flags & PF_R ? 'R' : ' '),
6165 (segment->p_flags & PF_W ? 'W' : ' '),
6166 (segment->p_flags & PF_X ? 'E' : ' '));
6167 printf ("%#lx", (unsigned long) segment->p_align);
6168 }
d974e256
JJ
6169 else if (do_wide)
6170 {
6171 if ((unsigned long) segment->p_offset == segment->p_offset)
6172 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6173 else
6174 {
6175 print_vma (segment->p_offset, FULL_HEX);
6176 putchar (' ');
6177 }
6178
6179 print_vma (segment->p_vaddr, FULL_HEX);
6180 putchar (' ');
6181 print_vma (segment->p_paddr, FULL_HEX);
6182 putchar (' ');
6183
6184 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6185 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6186 else
6187 {
6188 print_vma (segment->p_filesz, FULL_HEX);
6189 putchar (' ');
6190 }
6191
6192 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6193 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6194 else
6195 {
f48e6c45 6196 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6197 }
6198
6199 printf (" %c%c%c ",
6200 (segment->p_flags & PF_R ? 'R' : ' '),
6201 (segment->p_flags & PF_W ? 'W' : ' '),
6202 (segment->p_flags & PF_X ? 'E' : ' '));
6203
6204 if ((unsigned long) segment->p_align == segment->p_align)
6205 printf ("%#lx", (unsigned long) segment->p_align);
6206 else
6207 {
6208 print_vma (segment->p_align, PREFIX_HEX);
6209 }
6210 }
f7a99963
NC
6211 else
6212 {
6213 print_vma (segment->p_offset, FULL_HEX);
6214 putchar (' ');
6215 print_vma (segment->p_vaddr, FULL_HEX);
6216 putchar (' ');
6217 print_vma (segment->p_paddr, FULL_HEX);
6218 printf ("\n ");
6219 print_vma (segment->p_filesz, FULL_HEX);
6220 putchar (' ');
6221 print_vma (segment->p_memsz, FULL_HEX);
6222 printf (" %c%c%c ",
6223 (segment->p_flags & PF_R ? 'R' : ' '),
6224 (segment->p_flags & PF_W ? 'W' : ' '),
6225 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6226 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6227 }
252b5132 6228
1a9ccd70
NC
6229 putc ('\n', stdout);
6230 }
f54498b4 6231
252b5132
RH
6232 switch (segment->p_type)
6233 {
1a9ccd70 6234 case PT_LOAD:
502d895c
NC
6235#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6236 required by the ELF standard, several programs, including the Linux
6237 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6238 if (previous_load
6239 && previous_load->p_vaddr > segment->p_vaddr)
6240 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6241#endif
1a9ccd70
NC
6242 if (segment->p_memsz < segment->p_filesz)
6243 error (_("the segment's file size is larger than its memory size\n"));
6244 previous_load = segment;
6245 break;
6246
6247 case PT_PHDR:
6248 /* PR 20815 - Verify that the program header is loaded into memory. */
6249 if (i > 0 && previous_load != NULL)
6250 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6251 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6252 {
6253 unsigned int j;
6254
dda8d76d 6255 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6256 {
6257 Elf_Internal_Phdr *load = filedata->program_headers + j;
6258 if (load->p_type == PT_LOAD
6259 && load->p_offset <= segment->p_offset
6260 && (load->p_offset + load->p_filesz
6261 >= segment->p_offset + segment->p_filesz)
6262 && load->p_vaddr <= segment->p_vaddr
6263 && (load->p_vaddr + load->p_filesz
6264 >= segment->p_vaddr + segment->p_filesz))
6265 break;
6266 }
dda8d76d 6267 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6268 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6269 }
6270 break;
6271
252b5132 6272 case PT_DYNAMIC:
93df3340 6273 if (dynamic_addr)
252b5132
RH
6274 error (_("more than one dynamic segment\n"));
6275
20737c13
AM
6276 /* By default, assume that the .dynamic section is the first
6277 section in the DYNAMIC segment. */
93df3340
AM
6278 dynamic_addr = segment->p_offset;
6279 dynamic_size = segment->p_filesz;
20737c13 6280
b2d38a17
NC
6281 /* Try to locate the .dynamic section. If there is
6282 a section header table, we can easily locate it. */
dda8d76d 6283 if (filedata->section_headers != NULL)
b2d38a17 6284 {
2cf0635d 6285 Elf_Internal_Shdr * sec;
b2d38a17 6286
dda8d76d 6287 sec = find_section (filedata, ".dynamic");
89fac5e3 6288 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6289 {
93df3340
AM
6290 /* A corresponding .dynamic section is expected, but on
6291 IA-64/OpenVMS it is OK for it to be missing. */
6292 if (!is_ia64_vms (filedata))
6293 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6294 break;
6295 }
6296
42bb2e33 6297 if (sec->sh_type == SHT_NOBITS)
20737c13 6298 {
93df3340
AM
6299 dynamic_addr = 0;
6300 dynamic_size = 0;
20737c13
AM
6301 break;
6302 }
42bb2e33 6303
93df3340
AM
6304 dynamic_addr = sec->sh_offset;
6305 dynamic_size = sec->sh_size;
b2d38a17 6306
8ac10c5b
L
6307 /* The PT_DYNAMIC segment, which is used by the run-time
6308 loader, should exactly match the .dynamic section. */
6309 if (do_checks
93df3340
AM
6310 && (dynamic_addr != segment->p_offset
6311 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6312 warn (_("\
6313the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6314 }
39e224f6
MW
6315
6316 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6317 segment. Check this after matching against the section headers
6318 so we don't warn on debuginfo file (which have NOBITS .dynamic
6319 sections). */
93df3340
AM
6320 if (dynamic_addr > filedata->file_size
6321 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6322 {
6323 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6324 dynamic_addr = 0;
6325 dynamic_size = 0;
39e224f6 6326 }
252b5132
RH
6327 break;
6328
6329 case PT_INTERP:
13acb58d
AM
6330 if (segment->p_offset >= filedata->file_size
6331 || segment->p_filesz > filedata->file_size - segment->p_offset
6332 || segment->p_filesz - 1 >= (size_t) -2
63cf857e
AM
6333 || fseek64 (filedata->handle,
6334 filedata->archive_file_offset + segment->p_offset,
6335 SEEK_SET))
252b5132
RH
6336 error (_("Unable to find program interpreter name\n"));
6337 else
6338 {
13acb58d
AM
6339 size_t len = segment->p_filesz;
6340 free (filedata->program_interpreter);
6341 filedata->program_interpreter = xmalloc (len + 1);
6342 len = fread (filedata->program_interpreter, 1, len,
6343 filedata->handle);
6344 filedata->program_interpreter[len] = 0;
252b5132
RH
6345
6346 if (do_segments)
f54498b4 6347 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6348 filedata->program_interpreter);
252b5132
RH
6349 }
6350 break;
6351 }
252b5132
RH
6352 }
6353
dda8d76d
NC
6354 if (do_segments
6355 && filedata->section_headers != NULL
6356 && filedata->string_table != NULL)
252b5132
RH
6357 {
6358 printf (_("\n Section to Segment mapping:\n"));
6359 printf (_(" Segment Sections...\n"));
6360
dda8d76d 6361 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6362 {
9ad5cbcf 6363 unsigned int j;
2cf0635d 6364 Elf_Internal_Shdr * section;
252b5132 6365
dda8d76d
NC
6366 segment = filedata->program_headers + i;
6367 section = filedata->section_headers + 1;
252b5132
RH
6368
6369 printf (" %2.2d ", i);
6370
dda8d76d 6371 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6372 {
f4638467
AM
6373 if (!ELF_TBSS_SPECIAL (section, segment)
6374 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6375 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6376 }
6377
6378 putc ('\n',stdout);
6379 }
6380 }
6381
93df3340
AM
6382 filedata->dynamic_addr = dynamic_addr;
6383 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6384 return;
6385
6386 no_headers:
6387 filedata->dynamic_addr = 0;
6388 filedata->dynamic_size = 1;
252b5132
RH
6389}
6390
6391
d93f0186
NC
6392/* Find the file offset corresponding to VMA by using the program headers. */
6393
26c527e6 6394static int64_t
625d49fc 6395offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 6396{
2cf0635d 6397 Elf_Internal_Phdr * seg;
d93f0186 6398
dda8d76d 6399 if (! get_program_headers (filedata))
d93f0186
NC
6400 {
6401 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6402 return (long) vma;
6403 }
6404
dda8d76d
NC
6405 for (seg = filedata->program_headers;
6406 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6407 ++seg)
6408 {
6409 if (seg->p_type != PT_LOAD)
6410 continue;
6411
6412 if (vma >= (seg->p_vaddr & -seg->p_align)
6413 && vma + size <= seg->p_vaddr + seg->p_filesz)
6414 return vma - seg->p_vaddr + seg->p_offset;
6415 }
6416
26c527e6
AM
6417 warn (_("Virtual address %#" PRIx64
6418 " not located in any PT_LOAD segment.\n"), vma);
6419 return vma;
d93f0186
NC
6420}
6421
6422
dda8d76d
NC
6423/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6424 If PROBE is true, this is just a probe and we do not generate any error
6425 messages if the load fails. */
049b0c3a 6426
015dc7e1
AM
6427static bool
6428get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6429{
2cf0635d
NC
6430 Elf32_External_Shdr * shdrs;
6431 Elf_Internal_Shdr * internal;
dda8d76d
NC
6432 unsigned int i;
6433 unsigned int size = filedata->file_header.e_shentsize;
6434 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6435
6436 /* PR binutils/17531: Cope with unexpected section header sizes. */
6437 if (size == 0 || num == 0)
015dc7e1 6438 return false;
907b52f4
NC
6439
6440 /* The section header cannot be at the start of the file - that is
6441 where the ELF file header is located. A file with absolutely no
6442 sections in it will use a shoff of 0. */
6443 if (filedata->file_header.e_shoff == 0)
6444 return false;
6445
049b0c3a
NC
6446 if (size < sizeof * shdrs)
6447 {
6448 if (! probe)
6449 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6450 return false;
049b0c3a
NC
6451 }
6452 if (!probe && size > sizeof * shdrs)
6453 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6454
dda8d76d 6455 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6456 size, num,
6457 probe ? NULL : _("section headers"));
6458 if (shdrs == NULL)
015dc7e1 6459 return false;
252b5132 6460
dda8d76d
NC
6461 filedata->section_headers = (Elf_Internal_Shdr *)
6462 cmalloc (num, sizeof (Elf_Internal_Shdr));
6463 if (filedata->section_headers == NULL)
252b5132 6464 {
049b0c3a 6465 if (!probe)
8b73c356 6466 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6467 free (shdrs);
015dc7e1 6468 return false;
252b5132
RH
6469 }
6470
dda8d76d 6471 for (i = 0, internal = filedata->section_headers;
560f3c1c 6472 i < num;
b34976b6 6473 i++, internal++)
252b5132
RH
6474 {
6475 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6476 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6477 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6478 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6479 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6480 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6481 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6482 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6483 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6484 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6485 if (!probe && internal->sh_link > num)
6486 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6487 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6488 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6489 }
6490
6491 free (shdrs);
015dc7e1 6492 return true;
252b5132
RH
6493}
6494
dda8d76d
NC
6495/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6496
015dc7e1
AM
6497static bool
6498get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6499{
dda8d76d
NC
6500 Elf64_External_Shdr * shdrs;
6501 Elf_Internal_Shdr * internal;
6502 unsigned int i;
6503 unsigned int size = filedata->file_header.e_shentsize;
6504 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6505
6506 /* PR binutils/17531: Cope with unexpected section header sizes. */
6507 if (size == 0 || num == 0)
015dc7e1 6508 return false;
dda8d76d 6509
907b52f4
NC
6510 /* The section header cannot be at the start of the file - that is
6511 where the ELF file header is located. A file with absolutely no
6512 sections in it will use a shoff of 0. */
6513 if (filedata->file_header.e_shoff == 0)
6514 return false;
6515
049b0c3a
NC
6516 if (size < sizeof * shdrs)
6517 {
6518 if (! probe)
6519 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6520 return false;
049b0c3a 6521 }
dda8d76d 6522
049b0c3a
NC
6523 if (! probe && size > sizeof * shdrs)
6524 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6525
dda8d76d
NC
6526 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6527 filedata->file_header.e_shoff,
049b0c3a
NC
6528 size, num,
6529 probe ? NULL : _("section headers"));
6530 if (shdrs == NULL)
015dc7e1 6531 return false;
9ea033b2 6532
dda8d76d
NC
6533 filedata->section_headers = (Elf_Internal_Shdr *)
6534 cmalloc (num, sizeof (Elf_Internal_Shdr));
6535 if (filedata->section_headers == NULL)
9ea033b2 6536 {
049b0c3a 6537 if (! probe)
8b73c356 6538 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6539 free (shdrs);
015dc7e1 6540 return false;
9ea033b2
NC
6541 }
6542
dda8d76d 6543 for (i = 0, internal = filedata->section_headers;
560f3c1c 6544 i < num;
b34976b6 6545 i++, internal++)
9ea033b2
NC
6546 {
6547 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6548 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6549 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6550 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6551 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6552 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6553 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6554 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6555 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6556 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6557 if (!probe && internal->sh_link > num)
6558 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6559 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6560 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6561 }
6562
6563 free (shdrs);
015dc7e1 6564 return true;
9ea033b2
NC
6565}
6566
4de91c10
AM
6567static bool
6568get_section_headers (Filedata *filedata, bool probe)
6569{
6570 if (filedata->section_headers != NULL)
6571 return true;
6572
4de91c10
AM
6573 if (is_32bit_elf)
6574 return get_32bit_section_headers (filedata, probe);
6575 else
6576 return get_64bit_section_headers (filedata, probe);
6577}
6578
252b5132 6579static Elf_Internal_Sym *
26c527e6
AM
6580get_32bit_elf_symbols (Filedata *filedata,
6581 Elf_Internal_Shdr *section,
6582 uint64_t *num_syms_return)
252b5132 6583{
26c527e6 6584 uint64_t number = 0;
dd24e3da 6585 Elf32_External_Sym * esyms = NULL;
ba5cdace 6586 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6587 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6588 Elf_Internal_Sym * psym;
b34976b6 6589 unsigned int j;
e3d39609 6590 elf_section_list * entry;
252b5132 6591
c9c1d674
EG
6592 if (section->sh_size == 0)
6593 {
6594 if (num_syms_return != NULL)
6595 * num_syms_return = 0;
6596 return NULL;
6597 }
6598
dd24e3da 6599 /* Run some sanity checks first. */
c9c1d674 6600 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6601 {
26c527e6 6602 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 6603 printable_section_name (filedata, section),
26c527e6 6604 section->sh_entsize);
ba5cdace 6605 goto exit_point;
dd24e3da
NC
6606 }
6607
dda8d76d 6608 if (section->sh_size > filedata->file_size)
f54498b4 6609 {
26c527e6 6610 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 6611 printable_section_name (filedata, section),
26c527e6 6612 section->sh_size);
f54498b4
NC
6613 goto exit_point;
6614 }
6615
dd24e3da
NC
6616 number = section->sh_size / section->sh_entsize;
6617
6618 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6619 {
26c527e6
AM
6620 error (_("Size (%#" PRIx64 ") of section %s "
6621 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
6622 section->sh_size,
dda8d76d 6623 printable_section_name (filedata, section),
26c527e6 6624 section->sh_entsize);
ba5cdace 6625 goto exit_point;
dd24e3da
NC
6626 }
6627
dda8d76d 6628 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6629 section->sh_size, _("symbols"));
dd24e3da 6630 if (esyms == NULL)
ba5cdace 6631 goto exit_point;
252b5132 6632
e3d39609 6633 shndx = NULL;
978c4450 6634 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 6635 {
26c527e6 6636 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
6637 continue;
6638
6639 if (shndx != NULL)
6640 {
6641 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6642 free (shndx);
6643 }
6644
6645 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6646 entry->hdr->sh_offset,
6647 1, entry->hdr->sh_size,
6648 _("symbol table section indices"));
6649 if (shndx == NULL)
6650 goto exit_point;
6651
6652 /* PR17531: file: heap-buffer-overflow */
6653 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6654 {
26c527e6 6655 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 6656 printable_section_name (filedata, entry->hdr),
26c527e6
AM
6657 entry->hdr->sh_size,
6658 section->sh_size);
e3d39609 6659 goto exit_point;
c9c1d674 6660 }
e3d39609 6661 }
9ad5cbcf 6662
3f5e193b 6663 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6664
6665 if (isyms == NULL)
6666 {
26c527e6 6667 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
dd24e3da 6668 goto exit_point;
252b5132
RH
6669 }
6670
dd24e3da 6671 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6672 {
6673 psym->st_name = BYTE_GET (esyms[j].st_name);
6674 psym->st_value = BYTE_GET (esyms[j].st_value);
6675 psym->st_size = BYTE_GET (esyms[j].st_size);
6676 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6677 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6678 psym->st_shndx
6679 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6680 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6681 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6682 psym->st_info = BYTE_GET (esyms[j].st_info);
6683 psym->st_other = BYTE_GET (esyms[j].st_other);
6684 }
6685
dd24e3da 6686 exit_point:
e3d39609
NC
6687 free (shndx);
6688 free (esyms);
252b5132 6689
ba5cdace
NC
6690 if (num_syms_return != NULL)
6691 * num_syms_return = isyms == NULL ? 0 : number;
6692
252b5132
RH
6693 return isyms;
6694}
6695
9ea033b2 6696static Elf_Internal_Sym *
26c527e6
AM
6697get_64bit_elf_symbols (Filedata *filedata,
6698 Elf_Internal_Shdr *section,
6699 uint64_t *num_syms_return)
9ea033b2 6700{
26c527e6 6701 uint64_t number = 0;
ba5cdace
NC
6702 Elf64_External_Sym * esyms = NULL;
6703 Elf_External_Sym_Shndx * shndx = NULL;
6704 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6705 Elf_Internal_Sym * psym;
b34976b6 6706 unsigned int j;
e3d39609 6707 elf_section_list * entry;
9ea033b2 6708
c9c1d674
EG
6709 if (section->sh_size == 0)
6710 {
6711 if (num_syms_return != NULL)
6712 * num_syms_return = 0;
6713 return NULL;
6714 }
6715
dd24e3da 6716 /* Run some sanity checks first. */
c9c1d674 6717 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6718 {
26c527e6 6719 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 6720 printable_section_name (filedata, section),
26c527e6 6721 section->sh_entsize);
ba5cdace 6722 goto exit_point;
dd24e3da
NC
6723 }
6724
dda8d76d 6725 if (section->sh_size > filedata->file_size)
f54498b4 6726 {
26c527e6 6727 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 6728 printable_section_name (filedata, section),
26c527e6 6729 section->sh_size);
f54498b4
NC
6730 goto exit_point;
6731 }
6732
dd24e3da
NC
6733 number = section->sh_size / section->sh_entsize;
6734
6735 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6736 {
26c527e6
AM
6737 error (_("Size (%#" PRIx64 ") of section %s "
6738 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
6739 section->sh_size,
dda8d76d 6740 printable_section_name (filedata, section),
26c527e6 6741 section->sh_entsize);
ba5cdace 6742 goto exit_point;
dd24e3da
NC
6743 }
6744
dda8d76d 6745 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6746 section->sh_size, _("symbols"));
a6e9f9df 6747 if (!esyms)
ba5cdace 6748 goto exit_point;
9ea033b2 6749
e3d39609 6750 shndx = NULL;
978c4450 6751 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 6752 {
26c527e6 6753 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
6754 continue;
6755
6756 if (shndx != NULL)
6757 {
6758 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6759 free (shndx);
c9c1d674 6760 }
e3d39609
NC
6761
6762 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6763 entry->hdr->sh_offset,
6764 1, entry->hdr->sh_size,
6765 _("symbol table section indices"));
6766 if (shndx == NULL)
6767 goto exit_point;
6768
6769 /* PR17531: file: heap-buffer-overflow */
6770 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6771 {
26c527e6 6772 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 6773 printable_section_name (filedata, entry->hdr),
26c527e6
AM
6774 entry->hdr->sh_size,
6775 section->sh_size);
e3d39609
NC
6776 goto exit_point;
6777 }
6778 }
9ad5cbcf 6779
3f5e193b 6780 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6781
6782 if (isyms == NULL)
6783 {
26c527e6 6784 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
ba5cdace 6785 goto exit_point;
9ea033b2
NC
6786 }
6787
ba5cdace 6788 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6789 {
6790 psym->st_name = BYTE_GET (esyms[j].st_name);
6791 psym->st_info = BYTE_GET (esyms[j].st_info);
6792 psym->st_other = BYTE_GET (esyms[j].st_other);
6793 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6794
4fbb74a6 6795 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6796 psym->st_shndx
6797 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6798 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6799 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6800
66543521
AM
6801 psym->st_value = BYTE_GET (esyms[j].st_value);
6802 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6803 }
6804
ba5cdace 6805 exit_point:
e3d39609
NC
6806 free (shndx);
6807 free (esyms);
ba5cdace
NC
6808
6809 if (num_syms_return != NULL)
6810 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6811
6812 return isyms;
6813}
6814
4de91c10
AM
6815static Elf_Internal_Sym *
6816get_elf_symbols (Filedata *filedata,
6817 Elf_Internal_Shdr *section,
26c527e6 6818 uint64_t *num_syms_return)
4de91c10
AM
6819{
6820 if (is_32bit_elf)
6821 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6822 else
6823 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6824}
6825
d1133906 6826static const char *
625d49fc 6827get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 6828{
5477e8a0 6829 static char buff[1024];
2cf0635d 6830 char * p = buff;
32ec8896
NC
6831 unsigned int field_size = is_32bit_elf ? 8 : 16;
6832 signed int sindex;
6833 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
6834 uint64_t os_flags = 0;
6835 uint64_t proc_flags = 0;
6836 uint64_t unknown_flags = 0;
148b93f2 6837 static const struct
5477e8a0 6838 {
2cf0635d 6839 const char * str;
32ec8896 6840 unsigned int len;
5477e8a0
L
6841 }
6842 flags [] =
6843 {
cfcac11d
NC
6844 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6845 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6846 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6847 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6848 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6849 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6850 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6851 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6852 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6853 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6854 /* IA-64 specific. */
6855 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6856 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6857 /* IA-64 OpenVMS specific. */
6858 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6859 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6860 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6861 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6862 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6863 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6864 /* Generic. */
cfcac11d 6865 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6866 /* SPARC specific. */
77115a4a 6867 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6868 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6869 /* ARM specific. */
6870 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6871 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6872 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6873 /* GNU specific. */
6874 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6875 /* VLE specific. */
6876 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6877 /* GNU specific. */
6878 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6879 };
6880
6881 if (do_section_details)
6882 {
8d5ff12c
L
6883 sprintf (buff, "[%*.*lx]: ",
6884 field_size, field_size, (unsigned long) sh_flags);
6885 p += field_size + 4;
5477e8a0 6886 }
76da6bbe 6887
d1133906
NC
6888 while (sh_flags)
6889 {
625d49fc 6890 uint64_t flag;
d1133906
NC
6891
6892 flag = sh_flags & - sh_flags;
6893 sh_flags &= ~ flag;
76da6bbe 6894
5477e8a0 6895 if (do_section_details)
d1133906 6896 {
5477e8a0
L
6897 switch (flag)
6898 {
91d6fa6a
NC
6899 case SHF_WRITE: sindex = 0; break;
6900 case SHF_ALLOC: sindex = 1; break;
6901 case SHF_EXECINSTR: sindex = 2; break;
6902 case SHF_MERGE: sindex = 3; break;
6903 case SHF_STRINGS: sindex = 4; break;
6904 case SHF_INFO_LINK: sindex = 5; break;
6905 case SHF_LINK_ORDER: sindex = 6; break;
6906 case SHF_OS_NONCONFORMING: sindex = 7; break;
6907 case SHF_GROUP: sindex = 8; break;
6908 case SHF_TLS: sindex = 9; break;
18ae9cc1 6909 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6910 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6911
5477e8a0 6912 default:
91d6fa6a 6913 sindex = -1;
dda8d76d 6914 switch (filedata->file_header.e_machine)
148b93f2 6915 {
cfcac11d 6916 case EM_IA_64:
148b93f2 6917 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6918 sindex = 10;
148b93f2 6919 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6920 sindex = 11;
dda8d76d 6921 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6922 switch (flag)
6923 {
91d6fa6a
NC
6924 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6925 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6926 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6927 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6928 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6929 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6930 default: break;
6931 }
cfcac11d
NC
6932 break;
6933
caa83f8b 6934 case EM_386:
22abe556 6935 case EM_IAMCU:
caa83f8b 6936 case EM_X86_64:
7f502d6c 6937 case EM_L1OM:
7a9068fe 6938 case EM_K1OM:
cfcac11d
NC
6939 case EM_OLD_SPARCV9:
6940 case EM_SPARC32PLUS:
6941 case EM_SPARCV9:
6942 case EM_SPARC:
18ae9cc1 6943 if (flag == SHF_ORDERED)
91d6fa6a 6944 sindex = 19;
cfcac11d 6945 break;
ac4c9b04
MG
6946
6947 case EM_ARM:
6948 switch (flag)
6949 {
6950 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6951 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6952 case SHF_COMDEF: sindex = 23; break;
6953 default: break;
6954 }
6955 break;
83eef883
AFB
6956 case EM_PPC:
6957 if (flag == SHF_PPC_VLE)
6958 sindex = 25;
6959 break;
99fabbc9
JL
6960 default:
6961 break;
6962 }
ac4c9b04 6963
99fabbc9
JL
6964 switch (filedata->file_header.e_ident[EI_OSABI])
6965 {
6966 case ELFOSABI_GNU:
6967 case ELFOSABI_FREEBSD:
6968 if (flag == SHF_GNU_RETAIN)
6969 sindex = 26;
6970 /* Fall through */
6971 case ELFOSABI_NONE:
6972 if (flag == SHF_GNU_MBIND)
6973 /* We should not recognize SHF_GNU_MBIND for
6974 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6975 not set the EI_OSABI header byte. */
6976 sindex = 24;
6977 break;
cfcac11d
NC
6978 default:
6979 break;
148b93f2 6980 }
99fabbc9 6981 break;
5477e8a0
L
6982 }
6983
91d6fa6a 6984 if (sindex != -1)
5477e8a0 6985 {
8d5ff12c
L
6986 if (p != buff + field_size + 4)
6987 {
6988 if (size < (10 + 2))
bee0ee85
NC
6989 {
6990 warn (_("Internal error: not enough buffer room for section flag info"));
6991 return _("<unknown>");
6992 }
8d5ff12c
L
6993 size -= 2;
6994 *p++ = ',';
6995 *p++ = ' ';
6996 }
6997
91d6fa6a
NC
6998 size -= flags [sindex].len;
6999 p = stpcpy (p, flags [sindex].str);
5477e8a0 7000 }
3b22753a 7001 else if (flag & SHF_MASKOS)
8d5ff12c 7002 os_flags |= flag;
d1133906 7003 else if (flag & SHF_MASKPROC)
8d5ff12c 7004 proc_flags |= flag;
d1133906 7005 else
8d5ff12c 7006 unknown_flags |= flag;
5477e8a0
L
7007 }
7008 else
7009 {
7010 switch (flag)
7011 {
7012 case SHF_WRITE: *p = 'W'; break;
7013 case SHF_ALLOC: *p = 'A'; break;
7014 case SHF_EXECINSTR: *p = 'X'; break;
7015 case SHF_MERGE: *p = 'M'; break;
7016 case SHF_STRINGS: *p = 'S'; break;
7017 case SHF_INFO_LINK: *p = 'I'; break;
7018 case SHF_LINK_ORDER: *p = 'L'; break;
7019 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7020 case SHF_GROUP: *p = 'G'; break;
7021 case SHF_TLS: *p = 'T'; break;
18ae9cc1 7022 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 7023 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
7024
7025 default:
dda8d76d
NC
7026 if ((filedata->file_header.e_machine == EM_X86_64
7027 || filedata->file_header.e_machine == EM_L1OM
7028 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
7029 && flag == SHF_X86_64_LARGE)
7030 *p = 'l';
dda8d76d 7031 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 7032 && flag == SHF_ARM_PURECODE)
99fabbc9 7033 *p = 'y';
dda8d76d 7034 else if (filedata->file_header.e_machine == EM_PPC
83eef883 7035 && flag == SHF_PPC_VLE)
99fabbc9 7036 *p = 'v';
5477e8a0
L
7037 else if (flag & SHF_MASKOS)
7038 {
99fabbc9
JL
7039 switch (filedata->file_header.e_ident[EI_OSABI])
7040 {
7041 case ELFOSABI_GNU:
7042 case ELFOSABI_FREEBSD:
7043 if (flag == SHF_GNU_RETAIN)
7044 {
7045 *p = 'R';
7046 break;
7047 }
7048 /* Fall through */
7049 case ELFOSABI_NONE:
7050 if (flag == SHF_GNU_MBIND)
7051 {
7052 /* We should not recognize SHF_GNU_MBIND for
7053 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7054 not set the EI_OSABI header byte. */
7055 *p = 'D';
7056 break;
7057 }
7058 /* Fall through */
7059 default:
7060 *p = 'o';
7061 sh_flags &= ~SHF_MASKOS;
7062 break;
7063 }
5477e8a0
L
7064 }
7065 else if (flag & SHF_MASKPROC)
7066 {
7067 *p = 'p';
7068 sh_flags &= ~ SHF_MASKPROC;
7069 }
7070 else
7071 *p = 'x';
7072 break;
7073 }
7074 p++;
d1133906
NC
7075 }
7076 }
76da6bbe 7077
8d5ff12c
L
7078 if (do_section_details)
7079 {
7080 if (os_flags)
7081 {
7082 size -= 5 + field_size;
7083 if (p != buff + field_size + 4)
7084 {
7085 if (size < (2 + 1))
bee0ee85
NC
7086 {
7087 warn (_("Internal error: not enough buffer room for section flag info"));
7088 return _("<unknown>");
7089 }
8d5ff12c
L
7090 size -= 2;
7091 *p++ = ',';
7092 *p++ = ' ';
7093 }
7094 sprintf (p, "OS (%*.*lx)", field_size, field_size,
7095 (unsigned long) os_flags);
7096 p += 5 + field_size;
7097 }
7098 if (proc_flags)
7099 {
7100 size -= 7 + field_size;
7101 if (p != buff + field_size + 4)
7102 {
7103 if (size < (2 + 1))
bee0ee85
NC
7104 {
7105 warn (_("Internal error: not enough buffer room for section flag info"));
7106 return _("<unknown>");
7107 }
8d5ff12c
L
7108 size -= 2;
7109 *p++ = ',';
7110 *p++ = ' ';
7111 }
7112 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7113 (unsigned long) proc_flags);
7114 p += 7 + field_size;
7115 }
7116 if (unknown_flags)
7117 {
7118 size -= 10 + field_size;
7119 if (p != buff + field_size + 4)
7120 {
7121 if (size < (2 + 1))
bee0ee85
NC
7122 {
7123 warn (_("Internal error: not enough buffer room for section flag info"));
7124 return _("<unknown>");
7125 }
8d5ff12c
L
7126 size -= 2;
7127 *p++ = ',';
7128 *p++ = ' ';
7129 }
2b692964 7130 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
7131 (unsigned long) unknown_flags);
7132 p += 10 + field_size;
7133 }
7134 }
7135
e9e44622 7136 *p = '\0';
d1133906
NC
7137 return buff;
7138}
7139
5844b465 7140static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7141get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7142 uint64_t size)
77115a4a
L
7143{
7144 if (is_32bit_elf)
7145 {
7146 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7147
ebdf1ebf
NC
7148 if (size < sizeof (* echdr))
7149 {
7150 error (_("Compressed section is too small even for a compression header\n"));
7151 return 0;
7152 }
7153
77115a4a
L
7154 chdr->ch_type = BYTE_GET (echdr->ch_type);
7155 chdr->ch_size = BYTE_GET (echdr->ch_size);
7156 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7157 return sizeof (*echdr);
7158 }
7159 else
7160 {
7161 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7162
ebdf1ebf
NC
7163 if (size < sizeof (* echdr))
7164 {
7165 error (_("Compressed section is too small even for a compression header\n"));
7166 return 0;
7167 }
7168
77115a4a
L
7169 chdr->ch_type = BYTE_GET (echdr->ch_type);
7170 chdr->ch_size = BYTE_GET (echdr->ch_size);
7171 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7172 return sizeof (*echdr);
7173 }
7174}
7175
015dc7e1 7176static bool
dda8d76d 7177process_section_headers (Filedata * filedata)
252b5132 7178{
2cf0635d 7179 Elf_Internal_Shdr * section;
b34976b6 7180 unsigned int i;
252b5132 7181
dda8d76d 7182 if (filedata->file_header.e_shnum == 0)
252b5132 7183 {
82f2dbf7 7184 /* PR binutils/12467. */
dda8d76d 7185 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7186 {
7187 warn (_("possibly corrupt ELF file header - it has a non-zero"
7188 " section header offset, but no section headers\n"));
015dc7e1 7189 return false;
32ec8896 7190 }
82f2dbf7 7191 else if (do_sections)
252b5132
RH
7192 printf (_("\nThere are no sections in this file.\n"));
7193
015dc7e1 7194 return true;
252b5132
RH
7195 }
7196
7197 if (do_sections && !do_header)
ca0e11aa
NC
7198 {
7199 if (filedata->is_separate && process_links)
7200 printf (_("In linked file '%s': "), filedata->file_name);
7201 if (! filedata->is_separate || process_links)
7202 printf (ngettext ("There is %d section header, "
26c527e6 7203 "starting at offset %#" PRIx64 ":\n",
ca0e11aa 7204 "There are %d section headers, "
26c527e6 7205 "starting at offset %#" PRIx64 ":\n",
ca0e11aa
NC
7206 filedata->file_header.e_shnum),
7207 filedata->file_header.e_shnum,
26c527e6 7208 filedata->file_header.e_shoff);
ca0e11aa 7209 }
252b5132 7210
4de91c10
AM
7211 if (!get_section_headers (filedata, false))
7212 return false;
252b5132
RH
7213
7214 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7215 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7216 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7217 {
dda8d76d 7218 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7219
c256ffe7
JJ
7220 if (section->sh_size != 0)
7221 {
dda8d76d
NC
7222 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7223 1, section->sh_size,
7224 _("string table"));
0de14b54 7225
dda8d76d 7226 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7227 }
252b5132
RH
7228 }
7229
7230 /* Scan the sections for the dynamic symbol table
e3c8793a 7231 and dynamic string table and debug sections. */
89fac5e3 7232 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7233 switch (filedata->file_header.e_machine)
89fac5e3
RS
7234 {
7235 case EM_MIPS:
7236 case EM_MIPS_RS3_LE:
7237 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7238 FDE addresses. However, the ABI also has a semi-official ILP32
7239 variant for which the normal FDE address size rules apply.
7240
7241 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7242 section, where XX is the size of longs in bits. Unfortunately,
7243 earlier compilers provided no way of distinguishing ILP32 objects
7244 from LP64 objects, so if there's any doubt, we should assume that
7245 the official LP64 form is being used. */
dda8d76d
NC
7246 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7247 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7248 eh_addr_size = 8;
7249 break;
0f56a26a
DD
7250
7251 case EM_H8_300:
7252 case EM_H8_300H:
dda8d76d 7253 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7254 {
7255 case E_H8_MACH_H8300:
7256 case E_H8_MACH_H8300HN:
7257 case E_H8_MACH_H8300SN:
7258 case E_H8_MACH_H8300SXN:
7259 eh_addr_size = 2;
7260 break;
7261 case E_H8_MACH_H8300H:
7262 case E_H8_MACH_H8300S:
7263 case E_H8_MACH_H8300SX:
7264 eh_addr_size = 4;
7265 break;
7266 }
f4236fe4
DD
7267 break;
7268
ff7eeb89 7269 case EM_M32C_OLD:
f4236fe4 7270 case EM_M32C:
dda8d76d 7271 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7272 {
7273 case EF_M32C_CPU_M16C:
7274 eh_addr_size = 2;
7275 break;
7276 }
7277 break;
89fac5e3
RS
7278 }
7279
76ca31c0
NC
7280#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7281 do \
7282 { \
be7d229a 7283 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7284 if (section->sh_entsize != expected_entsize) \
9dd3a467 7285 { \
f493c217 7286 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7287 i, section->sh_entsize); \
f493c217 7288 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7289 expected_entsize); \
9dd3a467 7290 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7291 } \
7292 } \
08d8fa11 7293 while (0)
9dd3a467
NC
7294
7295#define CHECK_ENTSIZE(section, i, type) \
1b513401 7296 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7297 sizeof (Elf64_External_##type))
7298
dda8d76d
NC
7299 for (i = 0, section = filedata->section_headers;
7300 i < filedata->file_header.e_shnum;
b34976b6 7301 i++, section++)
252b5132 7302 {
84714f86 7303 const char *name = section_name_print (filedata, section);
252b5132 7304
1b513401
NC
7305 /* Run some sanity checks on the headers and
7306 possibly fill in some file data as well. */
7307 switch (section->sh_type)
252b5132 7308 {
1b513401 7309 case SHT_DYNSYM:
978c4450 7310 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7311 {
7312 error (_("File contains multiple dynamic symbol tables\n"));
7313 continue;
7314 }
7315
08d8fa11 7316 CHECK_ENTSIZE (section, i, Sym);
978c4450 7317 filedata->dynamic_symbols
4de91c10 7318 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7319 filedata->dynamic_symtab_section = section;
1b513401
NC
7320 break;
7321
7322 case SHT_STRTAB:
7323 if (streq (name, ".dynstr"))
252b5132 7324 {
1b513401
NC
7325 if (filedata->dynamic_strings != NULL)
7326 {
7327 error (_("File contains multiple dynamic string tables\n"));
7328 continue;
7329 }
7330
7331 filedata->dynamic_strings
7332 = (char *) get_data (NULL, filedata, section->sh_offset,
7333 1, section->sh_size, _("dynamic strings"));
7334 filedata->dynamic_strings_length
7335 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7336 filedata->dynamic_strtab_section = section;
252b5132 7337 }
1b513401
NC
7338 break;
7339
7340 case SHT_SYMTAB_SHNDX:
7341 {
7342 elf_section_list * entry = xmalloc (sizeof * entry);
7343
7344 entry->hdr = section;
7345 entry->next = filedata->symtab_shndx_list;
7346 filedata->symtab_shndx_list = entry;
7347 }
7348 break;
7349
7350 case SHT_SYMTAB:
7351 CHECK_ENTSIZE (section, i, Sym);
7352 break;
7353
7354 case SHT_GROUP:
7355 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7356 break;
252b5132 7357
1b513401
NC
7358 case SHT_REL:
7359 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7360 if (do_checks && section->sh_size == 0)
1b513401
NC
7361 warn (_("Section '%s': zero-sized relocation section\n"), name);
7362 break;
7363
7364 case SHT_RELA:
7365 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7366 if (do_checks && section->sh_size == 0)
1b513401
NC
7367 warn (_("Section '%s': zero-sized relocation section\n"), name);
7368 break;
7369
682351b9
AM
7370 case SHT_RELR:
7371 CHECK_ENTSIZE (section, i, Relr);
7372 break;
7373
1b513401
NC
7374 case SHT_NOTE:
7375 case SHT_PROGBITS:
546cb2d8
NC
7376 /* Having a zero sized section is not illegal according to the
7377 ELF standard, but it might be an indication that something
7378 is wrong. So issue a warning if we are running in lint mode. */
7379 if (do_checks && section->sh_size == 0)
1b513401
NC
7380 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7381 break;
7382
7383 default:
7384 break;
7385 }
7386
7387 if ((do_debugging || do_debug_info || do_debug_abbrevs
7388 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7389 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7390 || do_debug_str || do_debug_str_offsets || do_debug_loc
7391 || do_debug_ranges
1b513401 7392 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7393 && (startswith (name, ".debug_")
7394 || startswith (name, ".zdebug_")))
252b5132 7395 {
1b315056
CS
7396 if (name[1] == 'z')
7397 name += sizeof (".zdebug_") - 1;
7398 else
7399 name += sizeof (".debug_") - 1;
252b5132
RH
7400
7401 if (do_debugging
24d127aa
ML
7402 || (do_debug_info && startswith (name, "info"))
7403 || (do_debug_info && startswith (name, "types"))
7404 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7405 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7406 || (do_debug_lines && startswith (name, "line."))
7407 || (do_debug_pubnames && startswith (name, "pubnames"))
7408 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7409 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7410 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7411 || (do_debug_aranges && startswith (name, "aranges"))
7412 || (do_debug_ranges && startswith (name, "ranges"))
7413 || (do_debug_ranges && startswith (name, "rnglists"))
7414 || (do_debug_frames && startswith (name, "frame"))
7415 || (do_debug_macinfo && startswith (name, "macinfo"))
7416 || (do_debug_macinfo && startswith (name, "macro"))
7417 || (do_debug_str && startswith (name, "str"))
7418 || (do_debug_links && startswith (name, "sup"))
7419 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7420 || (do_debug_loc && startswith (name, "loc"))
7421 || (do_debug_loc && startswith (name, "loclists"))
7422 || (do_debug_addr && startswith (name, "addr"))
7423 || (do_debug_cu_index && startswith (name, "cu_index"))
7424 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7425 )
6431e409 7426 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7427 }
a262ae96 7428 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7429 else if ((do_debugging || do_debug_info)
24d127aa 7430 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7431 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7432 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7433 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7434 else if (do_gdb_index && (streq (name, ".gdb_index")
7435 || streq (name, ".debug_names")))
6431e409 7436 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7437 /* Trace sections for Itanium VMS. */
7438 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7439 || do_trace_aranges)
24d127aa 7440 && startswith (name, ".trace_"))
6f875884
TG
7441 {
7442 name += sizeof (".trace_") - 1;
7443
7444 if (do_debugging
7445 || (do_trace_info && streq (name, "info"))
7446 || (do_trace_abbrevs && streq (name, "abbrev"))
7447 || (do_trace_aranges && streq (name, "aranges"))
7448 )
6431e409 7449 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7450 }
dda8d76d 7451 else if ((do_debugging || do_debug_links)
24d127aa
ML
7452 && (startswith (name, ".gnu_debuglink")
7453 || startswith (name, ".gnu_debugaltlink")))
6431e409 7454 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7455 }
7456
7457 if (! do_sections)
015dc7e1 7458 return true;
252b5132 7459
ca0e11aa 7460 if (filedata->is_separate && ! process_links)
015dc7e1 7461 return true;
ca0e11aa
NC
7462
7463 if (filedata->is_separate)
7464 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7465 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7466 printf (_("\nSection Headers:\n"));
7467 else
7468 printf (_("\nSection Header:\n"));
76da6bbe 7469
f7a99963 7470 if (is_32bit_elf)
595cf52e 7471 {
5477e8a0 7472 if (do_section_details)
595cf52e
L
7473 {
7474 printf (_(" [Nr] Name\n"));
5477e8a0 7475 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7476 }
7477 else
7478 printf
7479 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7480 }
d974e256 7481 else if (do_wide)
595cf52e 7482 {
5477e8a0 7483 if (do_section_details)
595cf52e
L
7484 {
7485 printf (_(" [Nr] Name\n"));
5477e8a0 7486 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7487 }
7488 else
7489 printf
7490 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7491 }
f7a99963
NC
7492 else
7493 {
5477e8a0 7494 if (do_section_details)
595cf52e
L
7495 {
7496 printf (_(" [Nr] Name\n"));
5477e8a0
L
7497 printf (_(" Type Address Offset Link\n"));
7498 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7499 }
7500 else
7501 {
7502 printf (_(" [Nr] Name Type Address Offset\n"));
7503 printf (_(" Size EntSize Flags Link Info Align\n"));
7504 }
f7a99963 7505 }
252b5132 7506
5477e8a0
L
7507 if (do_section_details)
7508 printf (_(" Flags\n"));
7509
dda8d76d
NC
7510 for (i = 0, section = filedata->section_headers;
7511 i < filedata->file_header.e_shnum;
b34976b6 7512 i++, section++)
252b5132 7513 {
dd905818
NC
7514 /* Run some sanity checks on the section header. */
7515
7516 /* Check the sh_link field. */
7517 switch (section->sh_type)
7518 {
285e3f99
AM
7519 case SHT_REL:
7520 case SHT_RELA:
7521 if (section->sh_link == 0
7522 && (filedata->file_header.e_type == ET_EXEC
7523 || filedata->file_header.e_type == ET_DYN))
7524 /* A dynamic relocation section where all entries use a
7525 zero symbol index need not specify a symtab section. */
7526 break;
7527 /* Fall through. */
dd905818
NC
7528 case SHT_SYMTAB_SHNDX:
7529 case SHT_GROUP:
7530 case SHT_HASH:
7531 case SHT_GNU_HASH:
7532 case SHT_GNU_versym:
285e3f99 7533 if (section->sh_link == 0
dda8d76d
NC
7534 || section->sh_link >= filedata->file_header.e_shnum
7535 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7536 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7537 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7538 i, section->sh_link);
7539 break;
7540
7541 case SHT_DYNAMIC:
7542 case SHT_SYMTAB:
7543 case SHT_DYNSYM:
7544 case SHT_GNU_verneed:
7545 case SHT_GNU_verdef:
7546 case SHT_GNU_LIBLIST:
285e3f99 7547 if (section->sh_link == 0
dda8d76d
NC
7548 || section->sh_link >= filedata->file_header.e_shnum
7549 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7550 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7551 i, section->sh_link);
7552 break;
7553
7554 case SHT_INIT_ARRAY:
7555 case SHT_FINI_ARRAY:
7556 case SHT_PREINIT_ARRAY:
7557 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7558 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7559 i, section->sh_link);
7560 break;
7561
7562 default:
7563 /* FIXME: Add support for target specific section types. */
7564#if 0 /* Currently we do not check other section types as there are too
7565 many special cases. Stab sections for example have a type
7566 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7567 section. */
7568 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7569 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7570 i, section->sh_link);
7571#endif
7572 break;
7573 }
7574
7575 /* Check the sh_info field. */
7576 switch (section->sh_type)
7577 {
7578 case SHT_REL:
7579 case SHT_RELA:
285e3f99
AM
7580 if (section->sh_info == 0
7581 && (filedata->file_header.e_type == ET_EXEC
7582 || filedata->file_header.e_type == ET_DYN))
7583 /* Dynamic relocations apply to segments, so they do not
7584 need to specify the section they relocate. */
7585 break;
7586 if (section->sh_info == 0
dda8d76d
NC
7587 || section->sh_info >= filedata->file_header.e_shnum
7588 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7589 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7590 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7591 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7592 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7593 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7594 /* FIXME: Are other section types valid ? */
dda8d76d 7595 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7596 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7597 i, section->sh_info);
dd905818
NC
7598 break;
7599
7600 case SHT_DYNAMIC:
7601 case SHT_HASH:
7602 case SHT_SYMTAB_SHNDX:
7603 case SHT_INIT_ARRAY:
7604 case SHT_FINI_ARRAY:
7605 case SHT_PREINIT_ARRAY:
7606 if (section->sh_info != 0)
7607 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7608 i, section->sh_info);
7609 break;
7610
7611 case SHT_GROUP:
7612 case SHT_SYMTAB:
7613 case SHT_DYNSYM:
7614 /* A symbol index - we assume that it is valid. */
7615 break;
7616
7617 default:
7618 /* FIXME: Add support for target specific section types. */
7619 if (section->sh_type == SHT_NOBITS)
7620 /* NOBITS section headers with non-zero sh_info fields can be
7621 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7622 information. The stripped sections have their headers
7623 preserved but their types set to SHT_NOBITS. So do not check
7624 this type of section. */
dd905818
NC
7625 ;
7626 else if (section->sh_flags & SHF_INFO_LINK)
7627 {
dda8d76d 7628 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7629 warn (_("[%2u]: Expected link to another section in info field"), i);
7630 }
a91e1603
L
7631 else if (section->sh_type < SHT_LOOS
7632 && (section->sh_flags & SHF_GNU_MBIND) == 0
7633 && section->sh_info != 0)
dd905818
NC
7634 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7635 i, section->sh_info);
7636 break;
7637 }
7638
3e6b6445 7639 /* Check the sh_size field. */
dda8d76d 7640 if (section->sh_size > filedata->file_size
3e6b6445
NC
7641 && section->sh_type != SHT_NOBITS
7642 && section->sh_type != SHT_NULL
7643 && section->sh_type < SHT_LOOS)
7644 warn (_("Size of section %u is larger than the entire file!\n"), i);
7645
7bfd842d 7646 printf (" [%2u] ", i);
5477e8a0 7647 if (do_section_details)
dda8d76d 7648 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7649 else
84714f86 7650 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7651
ea52a088 7652 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7653 get_section_type_name (filedata, section->sh_type));
0b4362b0 7654
f7a99963
NC
7655 if (is_32bit_elf)
7656 {
cfcac11d
NC
7657 const char * link_too_big = NULL;
7658
f7a99963 7659 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7660
f7a99963
NC
7661 printf ( " %6.6lx %6.6lx %2.2lx",
7662 (unsigned long) section->sh_offset,
7663 (unsigned long) section->sh_size,
7664 (unsigned long) section->sh_entsize);
d1133906 7665
5477e8a0
L
7666 if (do_section_details)
7667 fputs (" ", stdout);
7668 else
dda8d76d 7669 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7670
dda8d76d 7671 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7672 {
7673 link_too_big = "";
7674 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7675 an error but it can have special values in Solaris binaries. */
dda8d76d 7676 switch (filedata->file_header.e_machine)
cfcac11d 7677 {
caa83f8b 7678 case EM_386:
22abe556 7679 case EM_IAMCU:
caa83f8b 7680 case EM_X86_64:
7f502d6c 7681 case EM_L1OM:
7a9068fe 7682 case EM_K1OM:
cfcac11d
NC
7683 case EM_OLD_SPARCV9:
7684 case EM_SPARC32PLUS:
7685 case EM_SPARCV9:
7686 case EM_SPARC:
7687 if (section->sh_link == (SHN_BEFORE & 0xffff))
7688 link_too_big = "BEFORE";
7689 else if (section->sh_link == (SHN_AFTER & 0xffff))
7690 link_too_big = "AFTER";
7691 break;
7692 default:
7693 break;
7694 }
7695 }
7696
7697 if (do_section_details)
7698 {
7699 if (link_too_big != NULL && * link_too_big)
7700 printf ("<%s> ", link_too_big);
7701 else
7702 printf ("%2u ", section->sh_link);
7703 printf ("%3u %2lu\n", section->sh_info,
7704 (unsigned long) section->sh_addralign);
7705 }
7706 else
7707 printf ("%2u %3u %2lu\n",
7708 section->sh_link,
7709 section->sh_info,
7710 (unsigned long) section->sh_addralign);
7711
7712 if (link_too_big && ! * link_too_big)
7713 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7714 i, section->sh_link);
f7a99963 7715 }
d974e256
JJ
7716 else if (do_wide)
7717 {
7718 print_vma (section->sh_addr, LONG_HEX);
7719
7720 if ((long) section->sh_offset == section->sh_offset)
7721 printf (" %6.6lx", (unsigned long) section->sh_offset);
7722 else
7723 {
7724 putchar (' ');
7725 print_vma (section->sh_offset, LONG_HEX);
7726 }
7727
7728 if ((unsigned long) section->sh_size == section->sh_size)
7729 printf (" %6.6lx", (unsigned long) section->sh_size);
7730 else
7731 {
7732 putchar (' ');
7733 print_vma (section->sh_size, LONG_HEX);
7734 }
7735
7736 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7737 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7738 else
7739 {
7740 putchar (' ');
7741 print_vma (section->sh_entsize, LONG_HEX);
7742 }
7743
5477e8a0
L
7744 if (do_section_details)
7745 fputs (" ", stdout);
7746 else
dda8d76d 7747 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7748
72de5009 7749 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7750
7751 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7752 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7753 else
7754 {
7755 print_vma (section->sh_addralign, DEC);
7756 putchar ('\n');
7757 }
7758 }
5477e8a0 7759 else if (do_section_details)
595cf52e 7760 {
55cc53e9 7761 putchar (' ');
595cf52e
L
7762 print_vma (section->sh_addr, LONG_HEX);
7763 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7764 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7765 else
7766 {
7767 printf (" ");
7768 print_vma (section->sh_offset, LONG_HEX);
7769 }
72de5009 7770 printf (" %u\n ", section->sh_link);
595cf52e 7771 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7772 putchar (' ');
595cf52e
L
7773 print_vma (section->sh_entsize, LONG_HEX);
7774
72de5009
AM
7775 printf (" %-16u %lu\n",
7776 section->sh_info,
595cf52e
L
7777 (unsigned long) section->sh_addralign);
7778 }
f7a99963
NC
7779 else
7780 {
7781 putchar (' ');
7782 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7783 if ((long) section->sh_offset == section->sh_offset)
7784 printf (" %8.8lx", (unsigned long) section->sh_offset);
7785 else
7786 {
7787 printf (" ");
7788 print_vma (section->sh_offset, LONG_HEX);
7789 }
f7a99963
NC
7790 printf ("\n ");
7791 print_vma (section->sh_size, LONG_HEX);
7792 printf (" ");
7793 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7794
dda8d76d 7795 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7796
72de5009
AM
7797 printf (" %2u %3u %lu\n",
7798 section->sh_link,
7799 section->sh_info,
f7a99963
NC
7800 (unsigned long) section->sh_addralign);
7801 }
5477e8a0
L
7802
7803 if (do_section_details)
77115a4a 7804 {
dda8d76d 7805 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7806 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7807 {
7808 /* Minimum section size is 12 bytes for 32-bit compression
7809 header + 12 bytes for compressed data header. */
7810 unsigned char buf[24];
d8024a91 7811
77115a4a 7812 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7813 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7814 sizeof (buf), _("compression header")))
7815 {
7816 Elf_Internal_Chdr chdr;
d8024a91 7817
5844b465
NC
7818 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7819 printf (_(" [<corrupt>]\n"));
77115a4a 7820 else
5844b465 7821 {
89dbeac7 7822 if (chdr.ch_type == ch_compress_zlib)
5844b465 7823 printf (" ZLIB, ");
89dbeac7 7824 else if (chdr.ch_type == ch_compress_zstd)
1369522f 7825 printf (" ZSTD, ");
5844b465
NC
7826 else
7827 printf (_(" [<unknown>: 0x%x], "),
7828 chdr.ch_type);
7829 print_vma (chdr.ch_size, LONG_HEX);
7830 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7831 }
77115a4a
L
7832 }
7833 }
7834 }
252b5132
RH
7835 }
7836
5477e8a0 7837 if (!do_section_details)
3dbcc61d 7838 {
9fb71ee4
NC
7839 /* The ordering of the letters shown here matches the ordering of the
7840 corresponding SHF_xxx values, and hence the order in which these
7841 letters will be displayed to the user. */
7842 printf (_("Key to Flags:\n\
7843 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7844 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7845 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7846 switch (filedata->file_header.e_ident[EI_OSABI])
7847 {
7848 case ELFOSABI_GNU:
7849 case ELFOSABI_FREEBSD:
7850 printf (_("R (retain), "));
7851 /* Fall through */
7852 case ELFOSABI_NONE:
7853 printf (_("D (mbind), "));
7854 break;
7855 default:
7856 break;
7857 }
dda8d76d
NC
7858 if (filedata->file_header.e_machine == EM_X86_64
7859 || filedata->file_header.e_machine == EM_L1OM
7860 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7861 printf (_("l (large), "));
dda8d76d 7862 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7863 printf (_("y (purecode), "));
dda8d76d 7864 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7865 printf (_("v (VLE), "));
9fb71ee4 7866 printf ("p (processor specific)\n");
0b4362b0 7867 }
d1133906 7868
015dc7e1 7869 return true;
252b5132
RH
7870}
7871
015dc7e1 7872static bool
28d13567 7873get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
26c527e6
AM
7874 Elf_Internal_Sym **symtab, uint64_t *nsyms,
7875 char **strtab, uint64_t *strtablen)
28d13567
AM
7876{
7877 *strtab = NULL;
7878 *strtablen = 0;
4de91c10 7879 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7880
7881 if (*symtab == NULL)
015dc7e1 7882 return false;
28d13567
AM
7883
7884 if (symsec->sh_link != 0)
7885 {
7886 Elf_Internal_Shdr *strsec;
7887
7888 if (symsec->sh_link >= filedata->file_header.e_shnum)
7889 {
7890 error (_("Bad sh_link in symbol table section\n"));
7891 free (*symtab);
7892 *symtab = NULL;
7893 *nsyms = 0;
015dc7e1 7894 return false;
28d13567
AM
7895 }
7896
7897 strsec = filedata->section_headers + symsec->sh_link;
7898
7899 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7900 1, strsec->sh_size, _("string table"));
7901 if (*strtab == NULL)
7902 {
7903 free (*symtab);
7904 *symtab = NULL;
7905 *nsyms = 0;
015dc7e1 7906 return false;
28d13567
AM
7907 }
7908 *strtablen = strsec->sh_size;
7909 }
015dc7e1 7910 return true;
28d13567
AM
7911}
7912
f5842774
L
7913static const char *
7914get_group_flags (unsigned int flags)
7915{
1449284b 7916 static char buff[128];
220453ec 7917
6d913794
NC
7918 if (flags == 0)
7919 return "";
7920 else if (flags == GRP_COMDAT)
7921 return "COMDAT ";
f5842774 7922
89246a0e
AM
7923 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7924 flags,
7925 flags & GRP_MASKOS ? _("<OS specific>") : "",
7926 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7927 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7928 ? _("<unknown>") : ""));
6d913794 7929
f5842774
L
7930 return buff;
7931}
7932
015dc7e1 7933static bool
dda8d76d 7934process_section_groups (Filedata * filedata)
f5842774 7935{
2cf0635d 7936 Elf_Internal_Shdr * section;
f5842774 7937 unsigned int i;
2cf0635d
NC
7938 struct group * group;
7939 Elf_Internal_Shdr * symtab_sec;
7940 Elf_Internal_Shdr * strtab_sec;
7941 Elf_Internal_Sym * symtab;
26c527e6 7942 uint64_t num_syms;
2cf0635d 7943 char * strtab;
c256ffe7 7944 size_t strtab_size;
d1f5c6e3
L
7945
7946 /* Don't process section groups unless needed. */
7947 if (!do_unwind && !do_section_groups)
015dc7e1 7948 return true;
f5842774 7949
dda8d76d 7950 if (filedata->file_header.e_shnum == 0)
f5842774
L
7951 {
7952 if (do_section_groups)
ca0e11aa
NC
7953 {
7954 if (filedata->is_separate)
7955 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7956 filedata->file_name);
7957 else
7958 printf (_("\nThere are no section groups in this file.\n"));
7959 }
015dc7e1 7960 return true;
f5842774
L
7961 }
7962
dda8d76d 7963 if (filedata->section_headers == NULL)
f5842774
L
7964 {
7965 error (_("Section headers are not available!\n"));
fa1908fd 7966 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7967 return false;
f5842774
L
7968 }
7969
978c4450
AM
7970 filedata->section_headers_groups
7971 = (struct group **) calloc (filedata->file_header.e_shnum,
7972 sizeof (struct group *));
e4b17d5c 7973
978c4450 7974 if (filedata->section_headers_groups == NULL)
e4b17d5c 7975 {
8b73c356 7976 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7977 filedata->file_header.e_shnum);
015dc7e1 7978 return false;
e4b17d5c
L
7979 }
7980
f5842774 7981 /* Scan the sections for the group section. */
978c4450 7982 filedata->group_count = 0;
dda8d76d
NC
7983 for (i = 0, section = filedata->section_headers;
7984 i < filedata->file_header.e_shnum;
f5842774 7985 i++, section++)
e4b17d5c 7986 if (section->sh_type == SHT_GROUP)
978c4450 7987 filedata->group_count++;
e4b17d5c 7988
978c4450 7989 if (filedata->group_count == 0)
d1f5c6e3
L
7990 {
7991 if (do_section_groups)
ca0e11aa
NC
7992 {
7993 if (filedata->is_separate)
7994 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7995 filedata->file_name);
7996 else
7997 printf (_("\nThere are no section groups in this file.\n"));
7998 }
d1f5c6e3 7999
015dc7e1 8000 return true;
d1f5c6e3
L
8001 }
8002
978c4450
AM
8003 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8004 sizeof (struct group));
e4b17d5c 8005
978c4450 8006 if (filedata->section_groups == NULL)
e4b17d5c 8007 {
26c527e6 8008 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
015dc7e1 8009 return false;
e4b17d5c
L
8010 }
8011
d1f5c6e3
L
8012 symtab_sec = NULL;
8013 strtab_sec = NULL;
8014 symtab = NULL;
ba5cdace 8015 num_syms = 0;
d1f5c6e3 8016 strtab = NULL;
c256ffe7 8017 strtab_size = 0;
ca0e11aa
NC
8018
8019 if (filedata->is_separate)
8020 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 8021
978c4450 8022 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 8023 i < filedata->file_header.e_shnum;
e4b17d5c 8024 i++, section++)
f5842774
L
8025 {
8026 if (section->sh_type == SHT_GROUP)
8027 {
dda8d76d 8028 const char * name = printable_section_name (filedata, section);
74e1a04b 8029 const char * group_name;
2cf0635d
NC
8030 unsigned char * start;
8031 unsigned char * indices;
f5842774 8032 unsigned int entry, j, size;
2cf0635d
NC
8033 Elf_Internal_Shdr * sec;
8034 Elf_Internal_Sym * sym;
f5842774
L
8035
8036 /* Get the symbol table. */
dda8d76d
NC
8037 if (section->sh_link >= filedata->file_header.e_shnum
8038 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 8039 != SHT_SYMTAB))
f5842774
L
8040 {
8041 error (_("Bad sh_link in group section `%s'\n"), name);
8042 continue;
8043 }
d1f5c6e3
L
8044
8045 if (symtab_sec != sec)
8046 {
8047 symtab_sec = sec;
9db70fc3 8048 free (symtab);
4de91c10 8049 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 8050 }
f5842774 8051
dd24e3da
NC
8052 if (symtab == NULL)
8053 {
8054 error (_("Corrupt header in group section `%s'\n"), name);
8055 continue;
8056 }
8057
ba5cdace
NC
8058 if (section->sh_info >= num_syms)
8059 {
8060 error (_("Bad sh_info in group section `%s'\n"), name);
8061 continue;
8062 }
8063
f5842774
L
8064 sym = symtab + section->sh_info;
8065
8066 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8067 {
4fbb74a6 8068 if (sym->st_shndx == 0
dda8d76d 8069 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
8070 {
8071 error (_("Bad sh_info in group section `%s'\n"), name);
8072 continue;
8073 }
ba2685cc 8074
84714f86
AM
8075 group_name = section_name_print (filedata,
8076 filedata->section_headers
b9e920ec 8077 + sym->st_shndx);
c256ffe7 8078 strtab_sec = NULL;
9db70fc3 8079 free (strtab);
f5842774 8080 strtab = NULL;
c256ffe7 8081 strtab_size = 0;
f5842774
L
8082 }
8083 else
8084 {
8085 /* Get the string table. */
dda8d76d 8086 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8087 {
8088 strtab_sec = NULL;
9db70fc3 8089 free (strtab);
c256ffe7
JJ
8090 strtab = NULL;
8091 strtab_size = 0;
8092 }
8093 else if (strtab_sec
dda8d76d 8094 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8095 {
8096 strtab_sec = sec;
9db70fc3 8097 free (strtab);
071436c6 8098
dda8d76d 8099 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8100 1, strtab_sec->sh_size,
8101 _("string table"));
c256ffe7 8102 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8103 }
c256ffe7 8104 group_name = sym->st_name < strtab_size
2b692964 8105 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8106 }
8107
c9c1d674
EG
8108 /* PR 17531: file: loop. */
8109 if (section->sh_entsize > section->sh_size)
8110 {
26c527e6
AM
8111 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8112 " which is larger than its size (%#" PRIx64 ")\n"),
dda8d76d 8113 printable_section_name (filedata, section),
26c527e6
AM
8114 section->sh_entsize,
8115 section->sh_size);
61dd8e19 8116 continue;
c9c1d674
EG
8117 }
8118
dda8d76d 8119 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8120 1, section->sh_size,
8121 _("section data"));
59245841
NC
8122 if (start == NULL)
8123 continue;
f5842774
L
8124
8125 indices = start;
8126 size = (section->sh_size / section->sh_entsize) - 1;
8127 entry = byte_get (indices, 4);
8128 indices += 4;
e4b17d5c
L
8129
8130 if (do_section_groups)
8131 {
2b692964 8132 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8133 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8134
e4b17d5c
L
8135 printf (_(" [Index] Name\n"));
8136 }
8137
8138 group->group_index = i;
8139
f5842774
L
8140 for (j = 0; j < size; j++)
8141 {
2cf0635d 8142 struct group_list * g;
e4b17d5c 8143
f5842774
L
8144 entry = byte_get (indices, 4);
8145 indices += 4;
8146
dda8d76d 8147 if (entry >= filedata->file_header.e_shnum)
391cb864 8148 {
57028622
NC
8149 static unsigned num_group_errors = 0;
8150
8151 if (num_group_errors ++ < 10)
8152 {
8153 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8154 entry, i, filedata->file_header.e_shnum - 1);
57028622 8155 if (num_group_errors == 10)
67ce483b 8156 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8157 }
391cb864
L
8158 continue;
8159 }
391cb864 8160
978c4450 8161 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8162 {
d1f5c6e3
L
8163 if (entry)
8164 {
57028622
NC
8165 static unsigned num_errs = 0;
8166
8167 if (num_errs ++ < 10)
8168 {
8169 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8170 entry, i,
978c4450 8171 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8172 if (num_errs == 10)
8173 warn (_("Further error messages about already contained group sections suppressed\n"));
8174 }
d1f5c6e3
L
8175 continue;
8176 }
8177 else
8178 {
8179 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8180 section group. We just warn it the first time
d1f5c6e3 8181 and ignore it afterwards. */
015dc7e1 8182 static bool warned = false;
d1f5c6e3
L
8183 if (!warned)
8184 {
8185 error (_("section 0 in group section [%5u]\n"),
978c4450 8186 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8187 warned = true;
d1f5c6e3
L
8188 }
8189 }
e4b17d5c
L
8190 }
8191
978c4450 8192 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8193
8194 if (do_section_groups)
8195 {
dda8d76d
NC
8196 sec = filedata->section_headers + entry;
8197 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8198 }
8199
3f5e193b 8200 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8201 g->section_index = entry;
8202 g->next = group->root;
8203 group->root = g;
f5842774
L
8204 }
8205
9db70fc3 8206 free (start);
e4b17d5c
L
8207
8208 group++;
f5842774
L
8209 }
8210 }
8211
9db70fc3
AM
8212 free (symtab);
8213 free (strtab);
015dc7e1 8214 return true;
f5842774
L
8215}
8216
28f997cf
TG
8217/* Data used to display dynamic fixups. */
8218
8219struct ia64_vms_dynfixup
8220{
625d49fc
AM
8221 uint64_t needed_ident; /* Library ident number. */
8222 uint64_t needed; /* Index in the dstrtab of the library name. */
8223 uint64_t fixup_needed; /* Index of the library. */
8224 uint64_t fixup_rela_cnt; /* Number of fixups. */
8225 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8226};
8227
8228/* Data used to display dynamic relocations. */
8229
8230struct ia64_vms_dynimgrela
8231{
625d49fc
AM
8232 uint64_t img_rela_cnt; /* Number of relocations. */
8233 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8234};
8235
8236/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8237 library). */
8238
015dc7e1 8239static bool
dda8d76d
NC
8240dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8241 struct ia64_vms_dynfixup * fixup,
8242 const char * strtab,
8243 unsigned int strtab_sz)
28f997cf 8244{
32ec8896 8245 Elf64_External_VMS_IMAGE_FIXUP * imfs;
26c527e6 8246 size_t i;
32ec8896 8247 const char * lib_name;
28f997cf 8248
978c4450
AM
8249 imfs = get_data (NULL, filedata,
8250 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8251 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8252 _("dynamic section image fixups"));
8253 if (!imfs)
015dc7e1 8254 return false;
28f997cf
TG
8255
8256 if (fixup->needed < strtab_sz)
8257 lib_name = strtab + fixup->needed;
8258 else
8259 {
26c527e6
AM
8260 warn (_("corrupt library name index of %#" PRIx64
8261 " found in dynamic entry"), fixup->needed);
28f997cf
TG
8262 lib_name = "???";
8263 }
736990c4 8264
26c527e6
AM
8265 printf (_("\nImage fixups for needed library #%" PRId64
8266 ": %s - ident: %" PRIx64 "\n"),
8267 fixup->fixup_needed, lib_name, fixup->needed_ident);
28f997cf
TG
8268 printf
8269 (_("Seg Offset Type SymVec DataType\n"));
8270
26c527e6 8271 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
28f997cf
TG
8272 {
8273 unsigned int type;
8274 const char *rtype;
8275
8276 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8277 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8278 type = BYTE_GET (imfs [i].type);
8279 rtype = elf_ia64_reloc_type (type);
8280 if (rtype == NULL)
f493c217 8281 printf ("0x%08x ", type);
28f997cf 8282 else
f493c217 8283 printf ("%-32s ", rtype);
28f997cf
TG
8284 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8285 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8286 }
8287
8288 free (imfs);
015dc7e1 8289 return true;
28f997cf
TG
8290}
8291
8292/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8293
015dc7e1 8294static bool
dda8d76d 8295dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8296{
8297 Elf64_External_VMS_IMAGE_RELA *imrs;
26c527e6 8298 size_t i;
28f997cf 8299
978c4450
AM
8300 imrs = get_data (NULL, filedata,
8301 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8302 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8303 _("dynamic section image relocations"));
28f997cf 8304 if (!imrs)
015dc7e1 8305 return false;
28f997cf
TG
8306
8307 printf (_("\nImage relocs\n"));
8308 printf
8309 (_("Seg Offset Type Addend Seg Sym Off\n"));
8310
26c527e6 8311 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
28f997cf
TG
8312 {
8313 unsigned int type;
8314 const char *rtype;
8315
8316 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8317 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8318 type = BYTE_GET (imrs [i].type);
8319 rtype = elf_ia64_reloc_type (type);
8320 if (rtype == NULL)
8321 printf ("0x%08x ", type);
8322 else
8323 printf ("%-31s ", rtype);
8324 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8325 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8326 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8327 }
8328
8329 free (imrs);
015dc7e1 8330 return true;
28f997cf
TG
8331}
8332
8333/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8334
015dc7e1 8335static bool
dda8d76d 8336process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8337{
8338 struct ia64_vms_dynfixup fixup;
8339 struct ia64_vms_dynimgrela imgrela;
8340 Elf_Internal_Dyn *entry;
625d49fc
AM
8341 uint64_t strtab_off = 0;
8342 uint64_t strtab_sz = 0;
28f997cf 8343 char *strtab = NULL;
015dc7e1 8344 bool res = true;
28f997cf
TG
8345
8346 memset (&fixup, 0, sizeof (fixup));
8347 memset (&imgrela, 0, sizeof (imgrela));
8348
8349 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8350 for (entry = filedata->dynamic_section;
8351 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8352 entry++)
8353 {
8354 switch (entry->d_tag)
8355 {
8356 case DT_IA_64_VMS_STRTAB_OFFSET:
8357 strtab_off = entry->d_un.d_val;
8358 break;
8359 case DT_STRSZ:
8360 strtab_sz = entry->d_un.d_val;
8361 if (strtab == NULL)
978c4450
AM
8362 strtab = get_data (NULL, filedata,
8363 filedata->dynamic_addr + strtab_off,
28f997cf 8364 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8365 if (strtab == NULL)
8366 strtab_sz = 0;
28f997cf
TG
8367 break;
8368
8369 case DT_IA_64_VMS_NEEDED_IDENT:
8370 fixup.needed_ident = entry->d_un.d_val;
8371 break;
8372 case DT_NEEDED:
8373 fixup.needed = entry->d_un.d_val;
8374 break;
8375 case DT_IA_64_VMS_FIXUP_NEEDED:
8376 fixup.fixup_needed = entry->d_un.d_val;
8377 break;
8378 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8379 fixup.fixup_rela_cnt = entry->d_un.d_val;
8380 break;
8381 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8382 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8383 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8384 res = false;
28f997cf 8385 break;
28f997cf
TG
8386 case DT_IA_64_VMS_IMG_RELA_CNT:
8387 imgrela.img_rela_cnt = entry->d_un.d_val;
8388 break;
8389 case DT_IA_64_VMS_IMG_RELA_OFF:
8390 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8391 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8392 res = false;
28f997cf
TG
8393 break;
8394
8395 default:
8396 break;
8397 }
8398 }
8399
9db70fc3 8400 free (strtab);
28f997cf
TG
8401
8402 return res;
8403}
8404
85b1c36d 8405static struct
566b0d53 8406{
2cf0635d 8407 const char * name;
566b0d53
L
8408 int reloc;
8409 int size;
a7fd1186 8410 relocation_type rel_type;
32ec8896
NC
8411}
8412 dynamic_relocations [] =
566b0d53 8413{
a7fd1186
FS
8414 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8415 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8416 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8417 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8418};
8419
252b5132 8420/* Process the reloc section. */
18bd398b 8421
015dc7e1 8422static bool
dda8d76d 8423process_relocs (Filedata * filedata)
252b5132 8424{
26c527e6
AM
8425 uint64_t rel_size;
8426 uint64_t rel_offset;
252b5132 8427
252b5132 8428 if (!do_reloc)
015dc7e1 8429 return true;
252b5132
RH
8430
8431 if (do_using_dynamic)
8432 {
a7fd1186 8433 relocation_type rel_type;
2cf0635d 8434 const char * name;
015dc7e1 8435 bool has_dynamic_reloc;
566b0d53 8436 unsigned int i;
0de14b54 8437
015dc7e1 8438 has_dynamic_reloc = false;
252b5132 8439
566b0d53 8440 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8441 {
a7fd1186 8442 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8443 name = dynamic_relocations [i].name;
978c4450
AM
8444 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8445 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8446
32ec8896 8447 if (rel_size)
015dc7e1 8448 has_dynamic_reloc = true;
566b0d53 8449
a7fd1186 8450 if (rel_type == reltype_unknown)
aa903cfb 8451 {
566b0d53 8452 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8453 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8454 {
8455 case DT_REL:
a7fd1186 8456 rel_type = reltype_rel;
566b0d53
L
8457 break;
8458 case DT_RELA:
a7fd1186 8459 rel_type = reltype_rela;
566b0d53
L
8460 break;
8461 }
aa903cfb 8462 }
252b5132 8463
566b0d53
L
8464 if (rel_size)
8465 {
ca0e11aa
NC
8466 if (filedata->is_separate)
8467 printf
26c527e6
AM
8468 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
8469 " contains %" PRId64 " bytes:\n"),
ca0e11aa
NC
8470 filedata->file_name, name, rel_offset, rel_size);
8471 else
8472 printf
26c527e6
AM
8473 (_("\n'%s' relocation section at offset %#" PRIx64
8474 " contains %" PRId64 " bytes:\n"),
ca0e11aa 8475 name, rel_offset, rel_size);
252b5132 8476
dda8d76d
NC
8477 dump_relocations (filedata,
8478 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8479 rel_size,
978c4450
AM
8480 filedata->dynamic_symbols,
8481 filedata->num_dynamic_syms,
8482 filedata->dynamic_strings,
8483 filedata->dynamic_strings_length,
a7fd1186 8484 rel_type, true /* is_dynamic */);
566b0d53 8485 }
252b5132 8486 }
566b0d53 8487
dda8d76d
NC
8488 if (is_ia64_vms (filedata))
8489 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8490 has_dynamic_reloc = true;
28f997cf 8491
566b0d53 8492 if (! has_dynamic_reloc)
ca0e11aa
NC
8493 {
8494 if (filedata->is_separate)
8495 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8496 filedata->file_name);
8497 else
8498 printf (_("\nThere are no dynamic relocations in this file.\n"));
8499 }
252b5132
RH
8500 }
8501 else
8502 {
2cf0635d 8503 Elf_Internal_Shdr * section;
26c527e6 8504 size_t i;
015dc7e1 8505 bool found = false;
252b5132 8506
dda8d76d
NC
8507 for (i = 0, section = filedata->section_headers;
8508 i < filedata->file_header.e_shnum;
b34976b6 8509 i++, section++)
252b5132
RH
8510 {
8511 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8512 && section->sh_type != SHT_REL
8513 && section->sh_type != SHT_RELR)
252b5132
RH
8514 continue;
8515
8516 rel_offset = section->sh_offset;
8517 rel_size = section->sh_size;
8518
8519 if (rel_size)
8520 {
a7fd1186 8521 relocation_type rel_type;
26c527e6 8522 uint64_t num_rela;
103f02d3 8523
ca0e11aa
NC
8524 if (filedata->is_separate)
8525 printf (_("\nIn linked file '%s' relocation section "),
8526 filedata->file_name);
8527 else
8528 printf (_("\nRelocation section "));
252b5132 8529
dda8d76d 8530 if (filedata->string_table == NULL)
19936277 8531 printf ("%d", section->sh_name);
252b5132 8532 else
dda8d76d 8533 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8534
d3a49aa8 8535 num_rela = rel_size / section->sh_entsize;
26c527e6
AM
8536 printf (ngettext (" at offset %#" PRIx64
8537 " contains %" PRIu64 " entry:\n",
8538 " at offset %#" PRIx64
8539 " contains %" PRId64 " entries:\n",
d3a49aa8
AM
8540 num_rela),
8541 rel_offset, num_rela);
252b5132 8542
a7fd1186
FS
8543 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8544 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8545
4fbb74a6 8546 if (section->sh_link != 0
dda8d76d 8547 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8548 {
26c527e6
AM
8549 Elf_Internal_Shdr *symsec;
8550 Elf_Internal_Sym *symtab;
8551 uint64_t nsyms;
8552 uint64_t strtablen = 0;
8553 char *strtab = NULL;
57346661 8554
dda8d76d 8555 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8556 if (symsec->sh_type != SHT_SYMTAB
8557 && symsec->sh_type != SHT_DYNSYM)
8558 continue;
8559
28d13567
AM
8560 if (!get_symtab (filedata, symsec,
8561 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8562 continue;
252b5132 8563
dda8d76d 8564 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8565 symtab, nsyms, strtab, strtablen,
a7fd1186 8566 rel_type,
bb4d2ac2 8567 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8568 free (strtab);
d79b3d50
NC
8569 free (symtab);
8570 }
8571 else
dda8d76d 8572 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8573 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8574
015dc7e1 8575 found = true;
252b5132
RH
8576 }
8577 }
8578
8579 if (! found)
45ac8f4f
NC
8580 {
8581 /* Users sometimes forget the -D option, so try to be helpful. */
8582 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8583 {
978c4450 8584 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8585 {
ca0e11aa
NC
8586 if (filedata->is_separate)
8587 printf (_("\nThere are no static relocations in linked file '%s'."),
8588 filedata->file_name);
8589 else
8590 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8591 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8592
8593 break;
8594 }
8595 }
8596 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8597 {
8598 if (filedata->is_separate)
8599 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8600 filedata->file_name);
8601 else
8602 printf (_("\nThere are no relocations in this file.\n"));
8603 }
45ac8f4f 8604 }
252b5132
RH
8605 }
8606
015dc7e1 8607 return true;
252b5132
RH
8608}
8609
4d6ed7c8
NC
8610/* An absolute address consists of a section and an offset. If the
8611 section is NULL, the offset itself is the address, otherwise, the
8612 address equals to LOAD_ADDRESS(section) + offset. */
8613
8614struct absaddr
948f632f
DA
8615{
8616 unsigned short section;
625d49fc 8617 uint64_t offset;
948f632f 8618};
4d6ed7c8 8619
948f632f
DA
8620/* Find the nearest symbol at or below ADDR. Returns the symbol
8621 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8622
4d6ed7c8 8623static void
26c527e6
AM
8624find_symbol_for_address (Filedata *filedata,
8625 Elf_Internal_Sym *symtab,
8626 uint64_t nsyms,
8627 const char *strtab,
8628 uint64_t strtab_size,
8629 struct absaddr addr,
8630 const char **symname,
8631 uint64_t *offset)
4d6ed7c8 8632{
625d49fc 8633 uint64_t dist = 0x100000;
2cf0635d 8634 Elf_Internal_Sym * sym;
948f632f
DA
8635 Elf_Internal_Sym * beg;
8636 Elf_Internal_Sym * end;
2cf0635d 8637 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8638
0b6ae522 8639 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8640 beg = symtab;
8641 end = symtab + nsyms;
0b6ae522 8642
948f632f 8643 while (beg < end)
4d6ed7c8 8644 {
625d49fc 8645 uint64_t value;
948f632f
DA
8646
8647 sym = beg + (end - beg) / 2;
0b6ae522 8648
948f632f 8649 value = sym->st_value;
0b6ae522
DJ
8650 REMOVE_ARCH_BITS (value);
8651
948f632f 8652 if (sym->st_name != 0
4d6ed7c8 8653 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8654 && addr.offset >= value
8655 && addr.offset - value < dist)
4d6ed7c8
NC
8656 {
8657 best = sym;
0b6ae522 8658 dist = addr.offset - value;
4d6ed7c8
NC
8659 if (!dist)
8660 break;
8661 }
948f632f
DA
8662
8663 if (addr.offset < value)
8664 end = sym;
8665 else
8666 beg = sym + 1;
4d6ed7c8 8667 }
1b31d05e 8668
4d6ed7c8
NC
8669 if (best)
8670 {
57346661 8671 *symname = (best->st_name >= strtab_size
2b692964 8672 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8673 *offset = dist;
8674 return;
8675 }
1b31d05e 8676
4d6ed7c8
NC
8677 *symname = NULL;
8678 *offset = addr.offset;
8679}
8680
32ec8896 8681static /* signed */ int
948f632f
DA
8682symcmp (const void *p, const void *q)
8683{
8684 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8685 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8686
8687 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8688}
8689
8690/* Process the unwind section. */
8691
8692#include "unwind-ia64.h"
8693
8694struct ia64_unw_table_entry
8695{
8696 struct absaddr start;
8697 struct absaddr end;
8698 struct absaddr info;
8699};
8700
8701struct ia64_unw_aux_info
8702{
32ec8896 8703 struct ia64_unw_table_entry * table; /* Unwind table. */
26c527e6 8704 uint64_t table_len; /* Length of unwind table. */
32ec8896 8705 unsigned char * info; /* Unwind info. */
26c527e6 8706 uint64_t info_size; /* Size of unwind info. */
625d49fc
AM
8707 uint64_t info_addr; /* Starting address of unwind info. */
8708 uint64_t seg_base; /* Starting address of segment. */
32ec8896 8709 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 8710 uint64_t nsyms; /* Number of symbols. */
32ec8896 8711 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 8712 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 8713 char * strtab; /* The string table. */
26c527e6 8714 uint64_t strtab_size; /* Size of string table. */
948f632f
DA
8715};
8716
015dc7e1 8717static bool
dda8d76d 8718dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8719{
2cf0635d 8720 struct ia64_unw_table_entry * tp;
26c527e6 8721 size_t j, nfuns;
4d6ed7c8 8722 int in_body;
015dc7e1 8723 bool res = true;
7036c0e1 8724
948f632f
DA
8725 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8726 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8727 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8728 aux->funtab[nfuns++] = aux->symtab[j];
8729 aux->nfuns = nfuns;
8730 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8731
4d6ed7c8
NC
8732 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8733 {
625d49fc
AM
8734 uint64_t stamp;
8735 uint64_t offset;
2cf0635d
NC
8736 const unsigned char * dp;
8737 const unsigned char * head;
53774b7e 8738 const unsigned char * end;
2cf0635d 8739 const char * procname;
4d6ed7c8 8740
dda8d76d 8741 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8742 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8743
8744 fputs ("\n<", stdout);
8745
8746 if (procname)
8747 {
8748 fputs (procname, stdout);
8749
8750 if (offset)
26c527e6 8751 printf ("+%" PRIx64, offset);
4d6ed7c8
NC
8752 }
8753
8754 fputs (">: [", stdout);
8755 print_vma (tp->start.offset, PREFIX_HEX);
8756 fputc ('-', stdout);
8757 print_vma (tp->end.offset, PREFIX_HEX);
26c527e6
AM
8758 printf ("], info at +0x%" PRIx64 "\n",
8759 tp->info.offset - aux->seg_base);
4d6ed7c8 8760
53774b7e
NC
8761 /* PR 17531: file: 86232b32. */
8762 if (aux->info == NULL)
8763 continue;
8764
97c0a079
AM
8765 offset = tp->info.offset;
8766 if (tp->info.section)
8767 {
8768 if (tp->info.section >= filedata->file_header.e_shnum)
8769 {
26c527e6
AM
8770 warn (_("Invalid section %u in table entry %td\n"),
8771 tp->info.section, tp - aux->table);
015dc7e1 8772 res = false;
97c0a079
AM
8773 continue;
8774 }
8775 offset += filedata->section_headers[tp->info.section].sh_addr;
8776 }
8777 offset -= aux->info_addr;
53774b7e 8778 /* PR 17531: file: 0997b4d1. */
90679903
AM
8779 if (offset >= aux->info_size
8780 || aux->info_size - offset < 8)
53774b7e 8781 {
26c527e6
AM
8782 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
8783 tp->info.offset, tp - aux->table);
015dc7e1 8784 res = false;
53774b7e
NC
8785 continue;
8786 }
8787
97c0a079 8788 head = aux->info + offset;
a4a00738 8789 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8790
86f55779 8791 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8792 (unsigned) UNW_VER (stamp),
8793 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8794 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8795 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8796 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8797
8798 if (UNW_VER (stamp) != 1)
8799 {
2b692964 8800 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8801 continue;
8802 }
8803
8804 in_body = 0;
53774b7e
NC
8805 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8806 /* PR 17531: file: 16ceda89. */
8807 if (end > aux->info + aux->info_size)
8808 end = aux->info + aux->info_size;
8809 for (dp = head + 8; dp < end;)
b4477bc8 8810 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8811 }
948f632f
DA
8812
8813 free (aux->funtab);
32ec8896
NC
8814
8815 return res;
4d6ed7c8
NC
8816}
8817
015dc7e1 8818static bool
dda8d76d
NC
8819slurp_ia64_unwind_table (Filedata * filedata,
8820 struct ia64_unw_aux_info * aux,
8821 Elf_Internal_Shdr * sec)
4d6ed7c8 8822{
26c527e6 8823 uint64_t size, nrelas, i;
2cf0635d
NC
8824 Elf_Internal_Phdr * seg;
8825 struct ia64_unw_table_entry * tep;
8826 Elf_Internal_Shdr * relsec;
8827 Elf_Internal_Rela * rela;
8828 Elf_Internal_Rela * rp;
8829 unsigned char * table;
8830 unsigned char * tp;
8831 Elf_Internal_Sym * sym;
8832 const char * relname;
4d6ed7c8 8833
53774b7e
NC
8834 aux->table_len = 0;
8835
4d6ed7c8
NC
8836 /* First, find the starting address of the segment that includes
8837 this section: */
8838
dda8d76d 8839 if (filedata->file_header.e_phnum)
4d6ed7c8 8840 {
dda8d76d 8841 if (! get_program_headers (filedata))
015dc7e1 8842 return false;
4d6ed7c8 8843
dda8d76d
NC
8844 for (seg = filedata->program_headers;
8845 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8846 ++seg)
4d6ed7c8
NC
8847 {
8848 if (seg->p_type != PT_LOAD)
8849 continue;
8850
8851 if (sec->sh_addr >= seg->p_vaddr
8852 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8853 {
8854 aux->seg_base = seg->p_vaddr;
8855 break;
8856 }
8857 }
4d6ed7c8
NC
8858 }
8859
8860 /* Second, build the unwind table from the contents of the unwind section: */
8861 size = sec->sh_size;
dda8d76d 8862 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8863 _("unwind table"));
a6e9f9df 8864 if (!table)
015dc7e1 8865 return false;
4d6ed7c8 8866
53774b7e 8867 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8868 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8869 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8870 tep = aux->table;
53774b7e
NC
8871
8872 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8873 {
8874 tep->start.section = SHN_UNDEF;
8875 tep->end.section = SHN_UNDEF;
8876 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8877 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8878 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8879 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8880 tep->start.offset += aux->seg_base;
8881 tep->end.offset += aux->seg_base;
8882 tep->info.offset += aux->seg_base;
8883 }
8884 free (table);
8885
41e92641 8886 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8887 for (relsec = filedata->section_headers;
8888 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8889 ++relsec)
8890 {
8891 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8892 || relsec->sh_info >= filedata->file_header.e_shnum
8893 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8894 continue;
8895
dda8d76d 8896 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8897 & rela, & nrelas))
53774b7e
NC
8898 {
8899 free (aux->table);
8900 aux->table = NULL;
8901 aux->table_len = 0;
015dc7e1 8902 return false;
53774b7e 8903 }
4d6ed7c8
NC
8904
8905 for (rp = rela; rp < rela + nrelas; ++rp)
8906 {
4770fb94 8907 unsigned int sym_ndx;
726bd37d
AM
8908 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8909 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8910
82b1b41b
NC
8911 /* PR 17531: file: 9fa67536. */
8912 if (relname == NULL)
8913 {
726bd37d 8914 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8915 continue;
8916 }
948f632f 8917
24d127aa 8918 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8919 {
82b1b41b 8920 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8921 continue;
8922 }
8923
89fac5e3 8924 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8925
53774b7e
NC
8926 /* PR 17531: file: 5bc8d9bf. */
8927 if (i >= aux->table_len)
8928 {
26c527e6
AM
8929 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
8930 i);
53774b7e
NC
8931 continue;
8932 }
8933
4770fb94
AM
8934 sym_ndx = get_reloc_symindex (rp->r_info);
8935 if (sym_ndx >= aux->nsyms)
8936 {
8937 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8938 sym_ndx);
8939 continue;
8940 }
8941 sym = aux->symtab + sym_ndx;
8942
53774b7e 8943 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8944 {
8945 case 0:
8946 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8947 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8948 break;
8949 case 1:
8950 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8951 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8952 break;
8953 case 2:
8954 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8955 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8956 break;
8957 default:
8958 break;
8959 }
8960 }
8961
8962 free (rela);
8963 }
8964
015dc7e1 8965 return true;
4d6ed7c8
NC
8966}
8967
015dc7e1 8968static bool
dda8d76d 8969ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8970{
2cf0635d
NC
8971 Elf_Internal_Shdr * sec;
8972 Elf_Internal_Shdr * unwsec = NULL;
26c527e6 8973 uint64_t i, unwcount = 0, unwstart = 0;
57346661 8974 struct ia64_unw_aux_info aux;
015dc7e1 8975 bool res = true;
f1467e33 8976
4d6ed7c8
NC
8977 memset (& aux, 0, sizeof (aux));
8978
dda8d76d 8979 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8980 {
28d13567 8981 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8982 {
28d13567 8983 if (aux.symtab)
4082ef84 8984 {
28d13567
AM
8985 error (_("Multiple symbol tables encountered\n"));
8986 free (aux.symtab);
8987 aux.symtab = NULL;
4082ef84 8988 free (aux.strtab);
28d13567 8989 aux.strtab = NULL;
4082ef84 8990 }
28d13567
AM
8991 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8992 &aux.strtab, &aux.strtab_size))
015dc7e1 8993 return false;
4d6ed7c8
NC
8994 }
8995 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8996 unwcount++;
8997 }
8998
8999 if (!unwcount)
9000 printf (_("\nThere are no unwind sections in this file.\n"));
9001
9002 while (unwcount-- > 0)
9003 {
84714f86 9004 const char *suffix;
579f31ac
JJ
9005 size_t len, len2;
9006
dda8d76d
NC
9007 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
9008 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
9009 if (sec->sh_type == SHT_IA_64_UNWIND)
9010 {
9011 unwsec = sec;
9012 break;
9013 }
4082ef84
NC
9014 /* We have already counted the number of SHT_IA64_UNWIND
9015 sections so the loop above should never fail. */
9016 assert (unwsec != NULL);
579f31ac
JJ
9017
9018 unwstart = i + 1;
9019 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9020
e4b17d5c
L
9021 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9022 {
9023 /* We need to find which section group it is in. */
4082ef84 9024 struct group_list * g;
e4b17d5c 9025
978c4450
AM
9026 if (filedata->section_headers_groups == NULL
9027 || filedata->section_headers_groups[i] == NULL)
dda8d76d 9028 i = filedata->file_header.e_shnum;
4082ef84 9029 else
e4b17d5c 9030 {
978c4450 9031 g = filedata->section_headers_groups[i]->root;
18bd398b 9032
4082ef84
NC
9033 for (; g != NULL; g = g->next)
9034 {
dda8d76d 9035 sec = filedata->section_headers + g->section_index;
e4b17d5c 9036
84714f86
AM
9037 if (section_name_valid (filedata, sec)
9038 && streq (section_name (filedata, sec),
9039 ELF_STRING_ia64_unwind_info))
4082ef84
NC
9040 break;
9041 }
9042
9043 if (g == NULL)
dda8d76d 9044 i = filedata->file_header.e_shnum;
4082ef84 9045 }
e4b17d5c 9046 }
84714f86
AM
9047 else if (section_name_valid (filedata, unwsec)
9048 && startswith (section_name (filedata, unwsec),
e9b095a5 9049 ELF_STRING_ia64_unwind_once))
579f31ac 9050 {
18bd398b 9051 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 9052 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 9053 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9054 for (i = 0, sec = filedata->section_headers;
9055 i < filedata->file_header.e_shnum;
579f31ac 9056 ++i, ++sec)
84714f86
AM
9057 if (section_name_valid (filedata, sec)
9058 && startswith (section_name (filedata, sec),
e9b095a5 9059 ELF_STRING_ia64_unwind_info_once)
84714f86 9060 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9061 break;
9062 }
9063 else
9064 {
9065 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 9066 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
9067 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9068 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9069 suffix = "";
84714f86
AM
9070 if (section_name_valid (filedata, unwsec)
9071 && startswith (section_name (filedata, unwsec),
9072 ELF_STRING_ia64_unwind))
9073 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9074 for (i = 0, sec = filedata->section_headers;
9075 i < filedata->file_header.e_shnum;
579f31ac 9076 ++i, ++sec)
84714f86
AM
9077 if (section_name_valid (filedata, sec)
9078 && startswith (section_name (filedata, sec),
9079 ELF_STRING_ia64_unwind_info)
9080 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9081 break;
9082 }
9083
dda8d76d 9084 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
9085 {
9086 printf (_("\nCould not find unwind info section for "));
9087
dda8d76d 9088 if (filedata->string_table == NULL)
579f31ac
JJ
9089 printf ("%d", unwsec->sh_name);
9090 else
dda8d76d 9091 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9092 }
9093 else
4d6ed7c8 9094 {
4d6ed7c8 9095 aux.info_addr = sec->sh_addr;
dda8d76d 9096 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9097 sec->sh_size,
9098 _("unwind info"));
59245841 9099 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9100
579f31ac 9101 printf (_("\nUnwind section "));
4d6ed7c8 9102
dda8d76d 9103 if (filedata->string_table == NULL)
579f31ac
JJ
9104 printf ("%d", unwsec->sh_name);
9105 else
dda8d76d 9106 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9107
26c527e6
AM
9108 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9109 unwsec->sh_offset,
9110 unwsec->sh_size / (3 * eh_addr_size));
4d6ed7c8 9111
dda8d76d 9112 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9113 && aux.table_len > 0)
dda8d76d 9114 dump_ia64_unwind (filedata, & aux);
579f31ac 9115
9db70fc3
AM
9116 free ((char *) aux.table);
9117 free ((char *) aux.info);
579f31ac
JJ
9118 aux.table = NULL;
9119 aux.info = NULL;
9120 }
4d6ed7c8 9121 }
4d6ed7c8 9122
9db70fc3
AM
9123 free (aux.symtab);
9124 free ((char *) aux.strtab);
32ec8896
NC
9125
9126 return res;
4d6ed7c8
NC
9127}
9128
3f5e193b 9129struct hppa_unw_table_entry
32ec8896
NC
9130{
9131 struct absaddr start;
9132 struct absaddr end;
9133 unsigned int Cannot_unwind:1; /* 0 */
9134 unsigned int Millicode:1; /* 1 */
9135 unsigned int Millicode_save_sr0:1; /* 2 */
9136 unsigned int Region_description:2; /* 3..4 */
9137 unsigned int reserved1:1; /* 5 */
9138 unsigned int Entry_SR:1; /* 6 */
9139 unsigned int Entry_FR:4; /* Number saved 7..10 */
9140 unsigned int Entry_GR:5; /* Number saved 11..15 */
9141 unsigned int Args_stored:1; /* 16 */
9142 unsigned int Variable_Frame:1; /* 17 */
9143 unsigned int Separate_Package_Body:1; /* 18 */
9144 unsigned int Frame_Extension_Millicode:1; /* 19 */
9145 unsigned int Stack_Overflow_Check:1; /* 20 */
9146 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9147 unsigned int Ada_Region:1; /* 22 */
9148 unsigned int cxx_info:1; /* 23 */
9149 unsigned int cxx_try_catch:1; /* 24 */
9150 unsigned int sched_entry_seq:1; /* 25 */
9151 unsigned int reserved2:1; /* 26 */
9152 unsigned int Save_SP:1; /* 27 */
9153 unsigned int Save_RP:1; /* 28 */
9154 unsigned int Save_MRP_in_frame:1; /* 29 */
9155 unsigned int extn_ptr_defined:1; /* 30 */
9156 unsigned int Cleanup_defined:1; /* 31 */
9157
9158 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9159 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9160 unsigned int Large_frame:1; /* 2 */
9161 unsigned int Pseudo_SP_Set:1; /* 3 */
9162 unsigned int reserved4:1; /* 4 */
9163 unsigned int Total_frame_size:27; /* 5..31 */
9164};
3f5e193b 9165
57346661 9166struct hppa_unw_aux_info
948f632f 9167{
32ec8896 9168 struct hppa_unw_table_entry * table; /* Unwind table. */
26c527e6 9169 uint64_t table_len; /* Length of unwind table. */
625d49fc 9170 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9171 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9172 uint64_t nsyms; /* Number of symbols. */
32ec8896 9173 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9174 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9175 char * strtab; /* The string table. */
26c527e6 9176 uint64_t strtab_size; /* Size of string table. */
948f632f 9177};
57346661 9178
015dc7e1 9179static bool
dda8d76d 9180dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9181{
2cf0635d 9182 struct hppa_unw_table_entry * tp;
26c527e6 9183 uint64_t j, nfuns;
015dc7e1 9184 bool res = true;
948f632f
DA
9185
9186 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9187 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9188 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9189 aux->funtab[nfuns++] = aux->symtab[j];
9190 aux->nfuns = nfuns;
9191 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9192
57346661
AM
9193 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9194 {
625d49fc 9195 uint64_t offset;
2cf0635d 9196 const char * procname;
57346661 9197
dda8d76d 9198 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9199 aux->strtab_size, tp->start, &procname,
9200 &offset);
9201
9202 fputs ("\n<", stdout);
9203
9204 if (procname)
9205 {
9206 fputs (procname, stdout);
9207
9208 if (offset)
26c527e6 9209 printf ("+%" PRIx64, offset);
57346661
AM
9210 }
9211
9212 fputs (">: [", stdout);
9213 print_vma (tp->start.offset, PREFIX_HEX);
9214 fputc ('-', stdout);
9215 print_vma (tp->end.offset, PREFIX_HEX);
9216 printf ("]\n\t");
9217
18bd398b
NC
9218#define PF(_m) if (tp->_m) printf (#_m " ");
9219#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9220 PF(Cannot_unwind);
9221 PF(Millicode);
9222 PF(Millicode_save_sr0);
18bd398b 9223 /* PV(Region_description); */
57346661
AM
9224 PF(Entry_SR);
9225 PV(Entry_FR);
9226 PV(Entry_GR);
9227 PF(Args_stored);
9228 PF(Variable_Frame);
9229 PF(Separate_Package_Body);
9230 PF(Frame_Extension_Millicode);
9231 PF(Stack_Overflow_Check);
9232 PF(Two_Instruction_SP_Increment);
9233 PF(Ada_Region);
9234 PF(cxx_info);
9235 PF(cxx_try_catch);
9236 PF(sched_entry_seq);
9237 PF(Save_SP);
9238 PF(Save_RP);
9239 PF(Save_MRP_in_frame);
9240 PF(extn_ptr_defined);
9241 PF(Cleanup_defined);
9242 PF(MPE_XL_interrupt_marker);
9243 PF(HP_UX_interrupt_marker);
9244 PF(Large_frame);
9245 PF(Pseudo_SP_Set);
9246 PV(Total_frame_size);
9247#undef PF
9248#undef PV
9249 }
9250
18bd398b 9251 printf ("\n");
948f632f
DA
9252
9253 free (aux->funtab);
32ec8896
NC
9254
9255 return res;
57346661
AM
9256}
9257
015dc7e1 9258static bool
dda8d76d
NC
9259slurp_hppa_unwind_table (Filedata * filedata,
9260 struct hppa_unw_aux_info * aux,
9261 Elf_Internal_Shdr * sec)
57346661 9262{
26c527e6 9263 uint64_t size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9264 Elf_Internal_Phdr * seg;
9265 struct hppa_unw_table_entry * tep;
9266 Elf_Internal_Shdr * relsec;
9267 Elf_Internal_Rela * rela;
9268 Elf_Internal_Rela * rp;
9269 unsigned char * table;
9270 unsigned char * tp;
9271 Elf_Internal_Sym * sym;
9272 const char * relname;
57346661 9273
57346661
AM
9274 /* First, find the starting address of the segment that includes
9275 this section. */
dda8d76d 9276 if (filedata->file_header.e_phnum)
57346661 9277 {
dda8d76d 9278 if (! get_program_headers (filedata))
015dc7e1 9279 return false;
57346661 9280
dda8d76d
NC
9281 for (seg = filedata->program_headers;
9282 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9283 ++seg)
9284 {
9285 if (seg->p_type != PT_LOAD)
9286 continue;
9287
9288 if (sec->sh_addr >= seg->p_vaddr
9289 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9290 {
9291 aux->seg_base = seg->p_vaddr;
9292 break;
9293 }
9294 }
9295 }
9296
9297 /* Second, build the unwind table from the contents of the unwind
9298 section. */
9299 size = sec->sh_size;
dda8d76d 9300 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9301 _("unwind table"));
57346661 9302 if (!table)
015dc7e1 9303 return false;
57346661 9304
1c0751b2
DA
9305 unw_ent_size = 16;
9306 nentries = size / unw_ent_size;
9307 size = unw_ent_size * nentries;
57346661 9308
e3fdc001 9309 aux->table_len = nentries;
3f5e193b
NC
9310 tep = aux->table = (struct hppa_unw_table_entry *)
9311 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9312
1c0751b2 9313 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9314 {
9315 unsigned int tmp1, tmp2;
9316
9317 tep->start.section = SHN_UNDEF;
9318 tep->end.section = SHN_UNDEF;
9319
1c0751b2
DA
9320 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9321 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9322 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9323 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9324
9325 tep->start.offset += aux->seg_base;
9326 tep->end.offset += aux->seg_base;
57346661
AM
9327
9328 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9329 tep->Millicode = (tmp1 >> 30) & 0x1;
9330 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9331 tep->Region_description = (tmp1 >> 27) & 0x3;
9332 tep->reserved1 = (tmp1 >> 26) & 0x1;
9333 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9334 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9335 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9336 tep->Args_stored = (tmp1 >> 15) & 0x1;
9337 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9338 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9339 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9340 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9341 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9342 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9343 tep->cxx_info = (tmp1 >> 8) & 0x1;
9344 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9345 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9346 tep->reserved2 = (tmp1 >> 5) & 0x1;
9347 tep->Save_SP = (tmp1 >> 4) & 0x1;
9348 tep->Save_RP = (tmp1 >> 3) & 0x1;
9349 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9350 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9351 tep->Cleanup_defined = tmp1 & 0x1;
9352
9353 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9354 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9355 tep->Large_frame = (tmp2 >> 29) & 0x1;
9356 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9357 tep->reserved4 = (tmp2 >> 27) & 0x1;
9358 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9359 }
9360 free (table);
9361
9362 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9363 for (relsec = filedata->section_headers;
9364 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9365 ++relsec)
9366 {
9367 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9368 || relsec->sh_info >= filedata->file_header.e_shnum
9369 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9370 continue;
9371
dda8d76d 9372 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9373 & rela, & nrelas))
015dc7e1 9374 return false;
57346661
AM
9375
9376 for (rp = rela; rp < rela + nrelas; ++rp)
9377 {
4770fb94 9378 unsigned int sym_ndx;
726bd37d
AM
9379 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9380 relname = elf_hppa_reloc_type (r_type);
57346661 9381
726bd37d
AM
9382 if (relname == NULL)
9383 {
9384 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9385 continue;
9386 }
9387
57346661 9388 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9389 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9390 {
726bd37d 9391 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9392 continue;
9393 }
9394
9395 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9396 if (i >= aux->table_len)
9397 {
26c527e6
AM
9398 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9399 i);
726bd37d
AM
9400 continue;
9401 }
57346661 9402
4770fb94
AM
9403 sym_ndx = get_reloc_symindex (rp->r_info);
9404 if (sym_ndx >= aux->nsyms)
9405 {
9406 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9407 sym_ndx);
9408 continue;
9409 }
9410 sym = aux->symtab + sym_ndx;
9411
43f6cd05 9412 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9413 {
9414 case 0:
9415 aux->table[i].start.section = sym->st_shndx;
1e456d54 9416 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9417 break;
9418 case 1:
9419 aux->table[i].end.section = sym->st_shndx;
1e456d54 9420 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9421 break;
9422 default:
9423 break;
9424 }
9425 }
9426
9427 free (rela);
9428 }
9429
015dc7e1 9430 return true;
57346661
AM
9431}
9432
015dc7e1 9433static bool
dda8d76d 9434hppa_process_unwind (Filedata * filedata)
57346661 9435{
57346661 9436 struct hppa_unw_aux_info aux;
2cf0635d 9437 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9438 Elf_Internal_Shdr * sec;
26c527e6 9439 size_t i;
015dc7e1 9440 bool res = true;
57346661 9441
dda8d76d 9442 if (filedata->string_table == NULL)
015dc7e1 9443 return false;
1b31d05e
NC
9444
9445 memset (& aux, 0, sizeof (aux));
57346661 9446
dda8d76d 9447 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9448 {
28d13567 9449 if (sec->sh_type == SHT_SYMTAB)
57346661 9450 {
28d13567 9451 if (aux.symtab)
4082ef84 9452 {
28d13567
AM
9453 error (_("Multiple symbol tables encountered\n"));
9454 free (aux.symtab);
9455 aux.symtab = NULL;
4082ef84 9456 free (aux.strtab);
28d13567 9457 aux.strtab = NULL;
4082ef84 9458 }
28d13567
AM
9459 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9460 &aux.strtab, &aux.strtab_size))
015dc7e1 9461 return false;
57346661 9462 }
84714f86
AM
9463 else if (section_name_valid (filedata, sec)
9464 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9465 unwsec = sec;
9466 }
9467
9468 if (!unwsec)
9469 printf (_("\nThere are no unwind sections in this file.\n"));
9470
dda8d76d 9471 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9472 {
84714f86
AM
9473 if (section_name_valid (filedata, sec)
9474 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9475 {
26c527e6 9476 uint64_t num_unwind = sec->sh_size / 16;
dda8d76d 9477
26c527e6
AM
9478 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
9479 "contains %" PRIu64 " entry:\n",
9480 "\nUnwind section '%s' at offset %#" PRIx64 " "
9481 "contains %" PRIu64 " entries:\n",
d3a49aa8 9482 num_unwind),
dda8d76d 9483 printable_section_name (filedata, sec),
26c527e6 9484 sec->sh_offset,
d3a49aa8 9485 num_unwind);
57346661 9486
dda8d76d 9487 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9488 res = false;
66b09c7e
S
9489
9490 if (res && aux.table_len > 0)
32ec8896 9491 {
dda8d76d 9492 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9493 res = false;
32ec8896 9494 }
57346661 9495
9db70fc3 9496 free ((char *) aux.table);
57346661
AM
9497 aux.table = NULL;
9498 }
9499 }
9500
9db70fc3
AM
9501 free (aux.symtab);
9502 free ((char *) aux.strtab);
32ec8896
NC
9503
9504 return res;
57346661
AM
9505}
9506
0b6ae522
DJ
9507struct arm_section
9508{
a734115a
NC
9509 unsigned char * data; /* The unwind data. */
9510 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9511 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
26c527e6 9512 uint64_t nrelas; /* The number of relocations. */
a734115a
NC
9513 unsigned int rel_type; /* REL or RELA ? */
9514 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9515};
9516
9517struct arm_unw_aux_info
9518{
dda8d76d 9519 Filedata * filedata; /* The file containing the unwind sections. */
a734115a 9520 Elf_Internal_Sym * symtab; /* The file's symbol table. */
26c527e6 9521 uint64_t nsyms; /* Number of symbols. */
948f632f 9522 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9523 uint64_t nfuns; /* Number of these symbols. */
a734115a 9524 char * strtab; /* The file's string table. */
26c527e6 9525 uint64_t strtab_size; /* Size of string table. */
0b6ae522
DJ
9526};
9527
9528static const char *
dda8d76d
NC
9529arm_print_vma_and_name (Filedata * filedata,
9530 struct arm_unw_aux_info * aux,
625d49fc 9531 uint64_t fn,
dda8d76d 9532 struct absaddr addr)
0b6ae522
DJ
9533{
9534 const char *procname;
625d49fc 9535 uint64_t sym_offset;
0b6ae522
DJ
9536
9537 if (addr.section == SHN_UNDEF)
9538 addr.offset = fn;
9539
dda8d76d 9540 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9541 aux->strtab_size, addr, &procname,
9542 &sym_offset);
9543
9544 print_vma (fn, PREFIX_HEX);
9545
9546 if (procname)
9547 {
9548 fputs (" <", stdout);
9549 fputs (procname, stdout);
9550
9551 if (sym_offset)
26c527e6 9552 printf ("+0x%" PRIx64, sym_offset);
0b6ae522
DJ
9553 fputc ('>', stdout);
9554 }
9555
9556 return procname;
9557}
9558
9559static void
9560arm_free_section (struct arm_section *arm_sec)
9561{
9db70fc3
AM
9562 free (arm_sec->data);
9563 free (arm_sec->rela);
0b6ae522
DJ
9564}
9565
a734115a
NC
9566/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9567 cached section and install SEC instead.
9568 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9569 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9570 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9571 relocation's offset in ADDR.
1b31d05e
NC
9572 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9573 into the string table of the symbol associated with the reloc. If no
9574 reloc was applied store -1 there.
9575 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9576
015dc7e1 9577static bool
dda8d76d
NC
9578get_unwind_section_word (Filedata * filedata,
9579 struct arm_unw_aux_info * aux,
1b31d05e
NC
9580 struct arm_section * arm_sec,
9581 Elf_Internal_Shdr * sec,
625d49fc 9582 uint64_t word_offset,
1b31d05e
NC
9583 unsigned int * wordp,
9584 struct absaddr * addr,
625d49fc 9585 uint64_t * sym_name)
0b6ae522
DJ
9586{
9587 Elf_Internal_Rela *rp;
9588 Elf_Internal_Sym *sym;
9589 const char * relname;
9590 unsigned int word;
015dc7e1 9591 bool wrapped;
0b6ae522 9592
e0a31db1 9593 if (sec == NULL || arm_sec == NULL)
015dc7e1 9594 return false;
e0a31db1 9595
0b6ae522
DJ
9596 addr->section = SHN_UNDEF;
9597 addr->offset = 0;
9598
1b31d05e 9599 if (sym_name != NULL)
625d49fc 9600 *sym_name = (uint64_t) -1;
1b31d05e 9601
a734115a 9602 /* If necessary, update the section cache. */
0b6ae522
DJ
9603 if (sec != arm_sec->sec)
9604 {
9605 Elf_Internal_Shdr *relsec;
9606
9607 arm_free_section (arm_sec);
9608
9609 arm_sec->sec = sec;
dda8d76d 9610 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9611 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9612 arm_sec->rela = NULL;
9613 arm_sec->nrelas = 0;
9614
dda8d76d
NC
9615 for (relsec = filedata->section_headers;
9616 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9617 ++relsec)
9618 {
dda8d76d
NC
9619 if (relsec->sh_info >= filedata->file_header.e_shnum
9620 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9621 /* PR 15745: Check the section type as well. */
9622 || (relsec->sh_type != SHT_REL
9623 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9624 continue;
9625
a734115a 9626 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9627 if (relsec->sh_type == SHT_REL)
9628 {
dda8d76d 9629 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9630 relsec->sh_size,
9631 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9632 return false;
0b6ae522 9633 }
1ae40aa4 9634 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9635 {
dda8d76d 9636 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9637 relsec->sh_size,
9638 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9639 return false;
0b6ae522 9640 }
1ae40aa4 9641 break;
0b6ae522
DJ
9642 }
9643
9644 arm_sec->next_rela = arm_sec->rela;
9645 }
9646
a734115a 9647 /* If there is no unwind data we can do nothing. */
0b6ae522 9648 if (arm_sec->data == NULL)
015dc7e1 9649 return false;
0b6ae522 9650
e0a31db1 9651 /* If the offset is invalid then fail. */
f32ba729
NC
9652 if (/* PR 21343 *//* PR 18879 */
9653 sec->sh_size < 4
625d49fc 9654 || word_offset > sec->sh_size - 4)
015dc7e1 9655 return false;
e0a31db1 9656
a734115a 9657 /* Get the word at the required offset. */
0b6ae522
DJ
9658 word = byte_get (arm_sec->data + word_offset, 4);
9659
0eff7165
NC
9660 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9661 if (arm_sec->rela == NULL)
9662 {
9663 * wordp = word;
015dc7e1 9664 return true;
0eff7165
NC
9665 }
9666
a734115a 9667 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9668 wrapped = false;
0b6ae522
DJ
9669 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9670 {
625d49fc 9671 uint64_t prelval, offset;
0b6ae522
DJ
9672
9673 if (rp->r_offset > word_offset && !wrapped)
9674 {
9675 rp = arm_sec->rela;
015dc7e1 9676 wrapped = true;
0b6ae522
DJ
9677 }
9678 if (rp->r_offset > word_offset)
9679 break;
9680
9681 if (rp->r_offset & 3)
9682 {
26c527e6
AM
9683 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
9684 rp->r_offset);
0b6ae522
DJ
9685 continue;
9686 }
9687
9688 if (rp->r_offset < word_offset)
9689 continue;
9690
74e1a04b
NC
9691 /* PR 17531: file: 027-161405-0.004 */
9692 if (aux->symtab == NULL)
9693 continue;
9694
0b6ae522
DJ
9695 if (arm_sec->rel_type == SHT_REL)
9696 {
9697 offset = word & 0x7fffffff;
9698 if (offset & 0x40000000)
625d49fc 9699 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 9700 }
a734115a 9701 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9702 offset = rp->r_addend;
a734115a 9703 else
74e1a04b
NC
9704 {
9705 error (_("Unknown section relocation type %d encountered\n"),
9706 arm_sec->rel_type);
9707 break;
9708 }
0b6ae522 9709
071436c6
NC
9710 /* PR 17531 file: 027-1241568-0.004. */
9711 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9712 {
26c527e6
AM
9713 error (_("Bad symbol index in unwind relocation "
9714 "(%" PRIu64 " > %" PRIu64 ")\n"),
9715 ELF32_R_SYM (rp->r_info), aux->nsyms);
071436c6
NC
9716 break;
9717 }
9718
9719 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9720 offset += sym->st_value;
9721 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9722
a734115a 9723 /* Check that we are processing the expected reloc type. */
dda8d76d 9724 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9725 {
9726 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9727 if (relname == NULL)
9728 {
9729 warn (_("Skipping unknown ARM relocation type: %d\n"),
9730 (int) ELF32_R_TYPE (rp->r_info));
9731 continue;
9732 }
a734115a
NC
9733
9734 if (streq (relname, "R_ARM_NONE"))
9735 continue;
0b4362b0 9736
a734115a
NC
9737 if (! streq (relname, "R_ARM_PREL31"))
9738 {
071436c6 9739 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9740 continue;
9741 }
9742 }
dda8d76d 9743 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9744 {
9745 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9746 if (relname == NULL)
9747 {
9748 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9749 (int) ELF32_R_TYPE (rp->r_info));
9750 continue;
9751 }
0b4362b0 9752
a734115a
NC
9753 if (streq (relname, "R_C6000_NONE"))
9754 continue;
9755
9756 if (! streq (relname, "R_C6000_PREL31"))
9757 {
071436c6 9758 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9759 continue;
9760 }
9761
9762 prelval >>= 1;
9763 }
9764 else
74e1a04b
NC
9765 {
9766 /* This function currently only supports ARM and TI unwinders. */
9767 warn (_("Only TI and ARM unwinders are currently supported\n"));
9768 break;
9769 }
fa197c1c 9770
625d49fc 9771 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
9772 addr->section = sym->st_shndx;
9773 addr->offset = offset;
74e1a04b 9774
1b31d05e
NC
9775 if (sym_name)
9776 * sym_name = sym->st_name;
0b6ae522
DJ
9777 break;
9778 }
9779
9780 *wordp = word;
9781 arm_sec->next_rela = rp;
9782
015dc7e1 9783 return true;
0b6ae522
DJ
9784}
9785
a734115a
NC
9786static const char *tic6x_unwind_regnames[16] =
9787{
0b4362b0
RM
9788 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9789 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9790 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9791};
fa197c1c 9792
0b6ae522 9793static void
fa197c1c 9794decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9795{
fa197c1c
PB
9796 int i;
9797
9798 for (i = 12; mask; mask >>= 1, i--)
9799 {
9800 if (mask & 1)
9801 {
9802 fputs (tic6x_unwind_regnames[i], stdout);
9803 if (mask > 1)
9804 fputs (", ", stdout);
9805 }
9806 }
9807}
0b6ae522
DJ
9808
9809#define ADVANCE \
9810 if (remaining == 0 && more_words) \
9811 { \
9812 data_offset += 4; \
dda8d76d 9813 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9814 data_offset, & word, & addr, NULL)) \
015dc7e1 9815 return false; \
0b6ae522
DJ
9816 remaining = 4; \
9817 more_words--; \
9818 } \
9819
9820#define GET_OP(OP) \
9821 ADVANCE; \
9822 if (remaining) \
9823 { \
9824 remaining--; \
9825 (OP) = word >> 24; \
9826 word <<= 8; \
9827 } \
9828 else \
9829 { \
2b692964 9830 printf (_("[Truncated opcode]\n")); \
015dc7e1 9831 return false; \
0b6ae522 9832 } \
cc5914eb 9833 printf ("0x%02x ", OP)
0b6ae522 9834
015dc7e1 9835static bool
dda8d76d
NC
9836decode_arm_unwind_bytecode (Filedata * filedata,
9837 struct arm_unw_aux_info * aux,
948f632f
DA
9838 unsigned int word,
9839 unsigned int remaining,
9840 unsigned int more_words,
625d49fc 9841 uint64_t data_offset,
948f632f
DA
9842 Elf_Internal_Shdr * data_sec,
9843 struct arm_section * data_arm_sec)
fa197c1c
PB
9844{
9845 struct absaddr addr;
015dc7e1 9846 bool res = true;
0b6ae522
DJ
9847
9848 /* Decode the unwinding instructions. */
9849 while (1)
9850 {
9851 unsigned int op, op2;
9852
9853 ADVANCE;
9854 if (remaining == 0)
9855 break;
9856 remaining--;
9857 op = word >> 24;
9858 word <<= 8;
9859
cc5914eb 9860 printf (" 0x%02x ", op);
0b6ae522
DJ
9861
9862 if ((op & 0xc0) == 0x00)
9863 {
9864 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9865
cc5914eb 9866 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9867 }
9868 else if ((op & 0xc0) == 0x40)
9869 {
9870 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9871
cc5914eb 9872 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9873 }
9874 else if ((op & 0xf0) == 0x80)
9875 {
9876 GET_OP (op2);
9877 if (op == 0x80 && op2 == 0)
9878 printf (_("Refuse to unwind"));
9879 else
9880 {
9881 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9882 bool first = true;
0b6ae522 9883 int i;
2b692964 9884
0b6ae522
DJ
9885 printf ("pop {");
9886 for (i = 0; i < 12; i++)
9887 if (mask & (1 << i))
9888 {
9889 if (first)
015dc7e1 9890 first = false;
0b6ae522
DJ
9891 else
9892 printf (", ");
9893 printf ("r%d", 4 + i);
9894 }
9895 printf ("}");
9896 }
9897 }
9898 else if ((op & 0xf0) == 0x90)
9899 {
9900 if (op == 0x9d || op == 0x9f)
9901 printf (_(" [Reserved]"));
9902 else
cc5914eb 9903 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9904 }
9905 else if ((op & 0xf0) == 0xa0)
9906 {
9907 int end = 4 + (op & 0x07);
015dc7e1 9908 bool first = true;
0b6ae522 9909 int i;
61865e30 9910
0b6ae522
DJ
9911 printf (" pop {");
9912 for (i = 4; i <= end; i++)
9913 {
9914 if (first)
015dc7e1 9915 first = false;
0b6ae522
DJ
9916 else
9917 printf (", ");
9918 printf ("r%d", i);
9919 }
9920 if (op & 0x08)
9921 {
1b31d05e 9922 if (!first)
0b6ae522
DJ
9923 printf (", ");
9924 printf ("r14");
9925 }
9926 printf ("}");
9927 }
9928 else if (op == 0xb0)
9929 printf (_(" finish"));
9930 else if (op == 0xb1)
9931 {
9932 GET_OP (op2);
9933 if (op2 == 0 || (op2 & 0xf0) != 0)
9934 printf (_("[Spare]"));
9935 else
9936 {
9937 unsigned int mask = op2 & 0x0f;
015dc7e1 9938 bool first = true;
0b6ae522 9939 int i;
61865e30 9940
0b6ae522
DJ
9941 printf ("pop {");
9942 for (i = 0; i < 12; i++)
9943 if (mask & (1 << i))
9944 {
9945 if (first)
015dc7e1 9946 first = false;
0b6ae522
DJ
9947 else
9948 printf (", ");
9949 printf ("r%d", i);
9950 }
9951 printf ("}");
9952 }
9953 }
9954 else if (op == 0xb2)
9955 {
b115cf96 9956 unsigned char buf[9];
0b6ae522 9957 unsigned int i, len;
26c527e6 9958 uint64_t offset;
61865e30 9959
b115cf96 9960 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9961 {
9962 GET_OP (buf[i]);
9963 if ((buf[i] & 0x80) == 0)
9964 break;
9965 }
4082ef84 9966 if (i == sizeof (buf))
32ec8896 9967 {
27a45f42 9968 error (_("corrupt change to vsp\n"));
015dc7e1 9969 res = false;
32ec8896 9970 }
4082ef84
NC
9971 else
9972 {
015dc7e1 9973 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9974 assert (len == i + 1);
9975 offset = offset * 4 + 0x204;
26c527e6 9976 printf ("vsp = vsp + %" PRId64, offset);
4082ef84 9977 }
0b6ae522 9978 }
61865e30 9979 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9980 {
61865e30
NC
9981 unsigned int first, last;
9982
9983 GET_OP (op2);
9984 first = op2 >> 4;
9985 last = op2 & 0x0f;
9986 if (op == 0xc8)
9987 first = first + 16;
9988 printf ("pop {D%d", first);
9989 if (last)
9990 printf ("-D%d", first + last);
9991 printf ("}");
9992 }
09854a88
TB
9993 else if (op == 0xb4)
9994 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
9995 else if (op == 0xb5)
9996 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
9997 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9998 {
9999 unsigned int count = op & 0x07;
10000
10001 printf ("pop {D8");
10002 if (count)
10003 printf ("-D%d", 8 + count);
10004 printf ("}");
10005 }
10006 else if (op >= 0xc0 && op <= 0xc5)
10007 {
10008 unsigned int count = op & 0x07;
10009
10010 printf (" pop {wR10");
10011 if (count)
10012 printf ("-wR%d", 10 + count);
10013 printf ("}");
10014 }
10015 else if (op == 0xc6)
10016 {
10017 unsigned int first, last;
10018
10019 GET_OP (op2);
10020 first = op2 >> 4;
10021 last = op2 & 0x0f;
10022 printf ("pop {wR%d", first);
10023 if (last)
10024 printf ("-wR%d", first + last);
10025 printf ("}");
10026 }
10027 else if (op == 0xc7)
10028 {
10029 GET_OP (op2);
10030 if (op2 == 0 || (op2 & 0xf0) != 0)
10031 printf (_("[Spare]"));
0b6ae522
DJ
10032 else
10033 {
61865e30 10034 unsigned int mask = op2 & 0x0f;
015dc7e1 10035 bool first = true;
61865e30
NC
10036 int i;
10037
10038 printf ("pop {");
10039 for (i = 0; i < 4; i++)
10040 if (mask & (1 << i))
10041 {
10042 if (first)
015dc7e1 10043 first = false;
61865e30
NC
10044 else
10045 printf (", ");
10046 printf ("wCGR%d", i);
10047 }
10048 printf ("}");
0b6ae522
DJ
10049 }
10050 }
61865e30 10051 else
32ec8896
NC
10052 {
10053 printf (_(" [unsupported opcode]"));
015dc7e1 10054 res = false;
32ec8896
NC
10055 }
10056
0b6ae522
DJ
10057 printf ("\n");
10058 }
32ec8896
NC
10059
10060 return res;
fa197c1c
PB
10061}
10062
015dc7e1 10063static bool
dda8d76d
NC
10064decode_tic6x_unwind_bytecode (Filedata * filedata,
10065 struct arm_unw_aux_info * aux,
948f632f
DA
10066 unsigned int word,
10067 unsigned int remaining,
10068 unsigned int more_words,
625d49fc 10069 uint64_t data_offset,
948f632f
DA
10070 Elf_Internal_Shdr * data_sec,
10071 struct arm_section * data_arm_sec)
fa197c1c
PB
10072{
10073 struct absaddr addr;
10074
10075 /* Decode the unwinding instructions. */
10076 while (1)
10077 {
10078 unsigned int op, op2;
10079
10080 ADVANCE;
10081 if (remaining == 0)
10082 break;
10083 remaining--;
10084 op = word >> 24;
10085 word <<= 8;
10086
9cf03b7e 10087 printf (" 0x%02x ", op);
fa197c1c
PB
10088
10089 if ((op & 0xc0) == 0x00)
10090 {
10091 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10092 printf (" sp = sp + %d", offset);
fa197c1c
PB
10093 }
10094 else if ((op & 0xc0) == 0x80)
10095 {
10096 GET_OP (op2);
10097 if (op == 0x80 && op2 == 0)
10098 printf (_("Refuse to unwind"));
10099 else
10100 {
10101 unsigned int mask = ((op & 0x1f) << 8) | op2;
10102 if (op & 0x20)
10103 printf ("pop compact {");
10104 else
10105 printf ("pop {");
10106
10107 decode_tic6x_unwind_regmask (mask);
10108 printf("}");
10109 }
10110 }
10111 else if ((op & 0xf0) == 0xc0)
10112 {
10113 unsigned int reg;
10114 unsigned int nregs;
10115 unsigned int i;
10116 const char *name;
a734115a
NC
10117 struct
10118 {
32ec8896
NC
10119 unsigned int offset;
10120 unsigned int reg;
fa197c1c
PB
10121 } regpos[16];
10122
10123 /* Scan entire instruction first so that GET_OP output is not
10124 interleaved with disassembly. */
10125 nregs = 0;
10126 for (i = 0; nregs < (op & 0xf); i++)
10127 {
10128 GET_OP (op2);
10129 reg = op2 >> 4;
10130 if (reg != 0xf)
10131 {
10132 regpos[nregs].offset = i * 2;
10133 regpos[nregs].reg = reg;
10134 nregs++;
10135 }
10136
10137 reg = op2 & 0xf;
10138 if (reg != 0xf)
10139 {
10140 regpos[nregs].offset = i * 2 + 1;
10141 regpos[nregs].reg = reg;
10142 nregs++;
10143 }
10144 }
10145
10146 printf (_("pop frame {"));
18344509 10147 if (nregs == 0)
fa197c1c 10148 {
18344509
NC
10149 printf (_("*corrupt* - no registers specified"));
10150 }
10151 else
10152 {
10153 reg = nregs - 1;
10154 for (i = i * 2; i > 0; i--)
fa197c1c 10155 {
18344509
NC
10156 if (regpos[reg].offset == i - 1)
10157 {
10158 name = tic6x_unwind_regnames[regpos[reg].reg];
10159 if (reg > 0)
10160 reg--;
10161 }
10162 else
10163 name = _("[pad]");
fa197c1c 10164
18344509
NC
10165 fputs (name, stdout);
10166 if (i > 1)
10167 printf (", ");
10168 }
fa197c1c
PB
10169 }
10170
10171 printf ("}");
10172 }
10173 else if (op == 0xd0)
10174 printf (" MOV FP, SP");
10175 else if (op == 0xd1)
10176 printf (" __c6xabi_pop_rts");
10177 else if (op == 0xd2)
10178 {
10179 unsigned char buf[9];
10180 unsigned int i, len;
26c527e6 10181 uint64_t offset;
a734115a 10182
fa197c1c
PB
10183 for (i = 0; i < sizeof (buf); i++)
10184 {
10185 GET_OP (buf[i]);
10186 if ((buf[i] & 0x80) == 0)
10187 break;
10188 }
0eff7165
NC
10189 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10190 if (i == sizeof (buf))
10191 {
0eff7165 10192 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10193 return false;
0eff7165 10194 }
948f632f 10195
015dc7e1 10196 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10197 assert (len == i + 1);
10198 offset = offset * 8 + 0x408;
26c527e6 10199 printf (_("sp = sp + %" PRId64), offset);
fa197c1c
PB
10200 }
10201 else if ((op & 0xf0) == 0xe0)
10202 {
10203 if ((op & 0x0f) == 7)
10204 printf (" RETURN");
10205 else
10206 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10207 }
10208 else
10209 {
10210 printf (_(" [unsupported opcode]"));
10211 }
10212 putchar ('\n');
10213 }
32ec8896 10214
015dc7e1 10215 return true;
fa197c1c
PB
10216}
10217
625d49fc
AM
10218static uint64_t
10219arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10220{
625d49fc 10221 uint64_t offset;
fa197c1c
PB
10222
10223 offset = word & 0x7fffffff;
10224 if (offset & 0x40000000)
625d49fc 10225 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10226
dda8d76d 10227 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10228 offset <<= 1;
10229
10230 return offset + where;
10231}
10232
015dc7e1 10233static bool
dda8d76d
NC
10234decode_arm_unwind (Filedata * filedata,
10235 struct arm_unw_aux_info * aux,
1b31d05e
NC
10236 unsigned int word,
10237 unsigned int remaining,
625d49fc 10238 uint64_t data_offset,
1b31d05e
NC
10239 Elf_Internal_Shdr * data_sec,
10240 struct arm_section * data_arm_sec)
fa197c1c
PB
10241{
10242 int per_index;
10243 unsigned int more_words = 0;
37e14bc3 10244 struct absaddr addr;
625d49fc 10245 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10246 bool res = true;
fa197c1c
PB
10247
10248 if (remaining == 0)
10249 {
1b31d05e
NC
10250 /* Fetch the first word.
10251 Note - when decoding an object file the address extracted
10252 here will always be 0. So we also pass in the sym_name
10253 parameter so that we can find the symbol associated with
10254 the personality routine. */
dda8d76d 10255 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10256 & word, & addr, & sym_name))
015dc7e1 10257 return false;
1b31d05e 10258
fa197c1c
PB
10259 remaining = 4;
10260 }
c93dbb25
CZ
10261 else
10262 {
10263 addr.section = SHN_UNDEF;
10264 addr.offset = 0;
10265 }
fa197c1c
PB
10266
10267 if ((word & 0x80000000) == 0)
10268 {
10269 /* Expand prel31 for personality routine. */
625d49fc 10270 uint64_t fn;
fa197c1c
PB
10271 const char *procname;
10272
dda8d76d 10273 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10274 printf (_(" Personality routine: "));
1b31d05e
NC
10275 if (fn == 0
10276 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10277 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10278 {
10279 procname = aux->strtab + sym_name;
10280 print_vma (fn, PREFIX_HEX);
10281 if (procname)
10282 {
10283 fputs (" <", stdout);
10284 fputs (procname, stdout);
10285 fputc ('>', stdout);
10286 }
10287 }
10288 else
dda8d76d 10289 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10290 fputc ('\n', stdout);
10291
10292 /* The GCC personality routines use the standard compact
10293 encoding, starting with one byte giving the number of
10294 words. */
10295 if (procname != NULL
24d127aa
ML
10296 && (startswith (procname, "__gcc_personality_v0")
10297 || startswith (procname, "__gxx_personality_v0")
10298 || startswith (procname, "__gcj_personality_v0")
10299 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10300 {
10301 remaining = 0;
10302 more_words = 1;
10303 ADVANCE;
10304 if (!remaining)
10305 {
10306 printf (_(" [Truncated data]\n"));
015dc7e1 10307 return false;
fa197c1c
PB
10308 }
10309 more_words = word >> 24;
10310 word <<= 8;
10311 remaining--;
10312 per_index = -1;
10313 }
10314 else
015dc7e1 10315 return true;
fa197c1c
PB
10316 }
10317 else
10318 {
1b31d05e 10319 /* ARM EHABI Section 6.3:
0b4362b0 10320
1b31d05e 10321 An exception-handling table entry for the compact model looks like:
0b4362b0 10322
1b31d05e
NC
10323 31 30-28 27-24 23-0
10324 -- ----- ----- ----
10325 1 0 index Data for personalityRoutine[index] */
10326
dda8d76d 10327 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10328 && (word & 0x70000000))
32ec8896
NC
10329 {
10330 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10331 res = false;
32ec8896 10332 }
1b31d05e 10333
fa197c1c 10334 per_index = (word >> 24) & 0x7f;
1b31d05e 10335 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10336 if (per_index == 0)
10337 {
10338 more_words = 0;
10339 word <<= 8;
10340 remaining--;
10341 }
10342 else if (per_index < 3)
10343 {
10344 more_words = (word >> 16) & 0xff;
10345 word <<= 16;
10346 remaining -= 2;
10347 }
10348 }
10349
dda8d76d 10350 switch (filedata->file_header.e_machine)
fa197c1c
PB
10351 {
10352 case EM_ARM:
10353 if (per_index < 3)
10354 {
dda8d76d 10355 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10356 data_offset, data_sec, data_arm_sec))
015dc7e1 10357 res = false;
fa197c1c
PB
10358 }
10359 else
1b31d05e
NC
10360 {
10361 warn (_("Unknown ARM compact model index encountered\n"));
10362 printf (_(" [reserved]\n"));
015dc7e1 10363 res = false;
1b31d05e 10364 }
fa197c1c
PB
10365 break;
10366
10367 case EM_TI_C6000:
10368 if (per_index < 3)
10369 {
dda8d76d 10370 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10371 data_offset, data_sec, data_arm_sec))
015dc7e1 10372 res = false;
fa197c1c
PB
10373 }
10374 else if (per_index < 5)
10375 {
10376 if (((word >> 17) & 0x7f) == 0x7f)
10377 printf (_(" Restore stack from frame pointer\n"));
10378 else
10379 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10380 printf (_(" Registers restored: "));
10381 if (per_index == 4)
10382 printf (" (compact) ");
10383 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10384 putchar ('\n');
10385 printf (_(" Return register: %s\n"),
10386 tic6x_unwind_regnames[word & 0xf]);
10387 }
10388 else
1b31d05e 10389 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10390 break;
10391
10392 default:
74e1a04b 10393 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10394 filedata->file_header.e_machine);
015dc7e1 10395 res = false;
fa197c1c 10396 }
0b6ae522
DJ
10397
10398 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10399
10400 return res;
0b6ae522
DJ
10401}
10402
015dc7e1 10403static bool
dda8d76d
NC
10404dump_arm_unwind (Filedata * filedata,
10405 struct arm_unw_aux_info * aux,
10406 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10407{
10408 struct arm_section exidx_arm_sec, extab_arm_sec;
10409 unsigned int i, exidx_len;
26c527e6 10410 uint64_t j, nfuns;
015dc7e1 10411 bool res = true;
0b6ae522
DJ
10412
10413 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10414 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10415 exidx_len = exidx_sec->sh_size / 8;
10416
948f632f
DA
10417 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10418 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10419 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10420 aux->funtab[nfuns++] = aux->symtab[j];
10421 aux->nfuns = nfuns;
10422 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10423
0b6ae522
DJ
10424 for (i = 0; i < exidx_len; i++)
10425 {
10426 unsigned int exidx_fn, exidx_entry;
10427 struct absaddr fn_addr, entry_addr;
625d49fc 10428 uint64_t fn;
0b6ae522
DJ
10429
10430 fputc ('\n', stdout);
10431
dda8d76d 10432 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10433 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10434 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10435 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10436 {
948f632f 10437 free (aux->funtab);
1b31d05e
NC
10438 arm_free_section (& exidx_arm_sec);
10439 arm_free_section (& extab_arm_sec);
015dc7e1 10440 return false;
0b6ae522
DJ
10441 }
10442
83c257ca
NC
10443 /* ARM EHABI, Section 5:
10444 An index table entry consists of 2 words.
10445 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10446 if (exidx_fn & 0x80000000)
32ec8896
NC
10447 {
10448 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10449 res = false;
32ec8896 10450 }
83c257ca 10451
dda8d76d 10452 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10453
dda8d76d 10454 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10455 fputs (": ", stdout);
10456
10457 if (exidx_entry == 1)
10458 {
10459 print_vma (exidx_entry, PREFIX_HEX);
10460 fputs (" [cantunwind]\n", stdout);
10461 }
10462 else if (exidx_entry & 0x80000000)
10463 {
10464 print_vma (exidx_entry, PREFIX_HEX);
10465 fputc ('\n', stdout);
dda8d76d 10466 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10467 }
10468 else
10469 {
625d49fc 10470 uint64_t table, table_offset = 0;
0b6ae522
DJ
10471 Elf_Internal_Shdr *table_sec;
10472
10473 fputs ("@", stdout);
dda8d76d 10474 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10475 print_vma (table, PREFIX_HEX);
10476 printf ("\n");
10477
10478 /* Locate the matching .ARM.extab. */
10479 if (entry_addr.section != SHN_UNDEF
dda8d76d 10480 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10481 {
dda8d76d 10482 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10483 table_offset = entry_addr.offset;
1a915552 10484 /* PR 18879 */
625d49fc 10485 if (table_offset > table_sec->sh_size)
1a915552 10486 {
26c527e6
AM
10487 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
10488 table_offset,
dda8d76d 10489 printable_section_name (filedata, table_sec));
015dc7e1 10490 res = false;
1a915552
NC
10491 continue;
10492 }
0b6ae522
DJ
10493 }
10494 else
10495 {
dda8d76d 10496 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10497 if (table_sec != NULL)
10498 table_offset = table - table_sec->sh_addr;
10499 }
32ec8896 10500
0b6ae522
DJ
10501 if (table_sec == NULL)
10502 {
26c527e6
AM
10503 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
10504 table);
015dc7e1 10505 res = false;
0b6ae522
DJ
10506 continue;
10507 }
32ec8896 10508
dda8d76d 10509 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10510 &extab_arm_sec))
015dc7e1 10511 res = false;
0b6ae522
DJ
10512 }
10513 }
10514
10515 printf ("\n");
10516
948f632f 10517 free (aux->funtab);
0b6ae522
DJ
10518 arm_free_section (&exidx_arm_sec);
10519 arm_free_section (&extab_arm_sec);
32ec8896
NC
10520
10521 return res;
0b6ae522
DJ
10522}
10523
fa197c1c 10524/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10525
015dc7e1 10526static bool
dda8d76d 10527arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10528{
10529 struct arm_unw_aux_info aux;
10530 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522 10531 Elf_Internal_Shdr *sec;
26c527e6 10532 size_t i;
fa197c1c 10533 unsigned int sec_type;
015dc7e1 10534 bool res = true;
0b6ae522 10535
dda8d76d 10536 switch (filedata->file_header.e_machine)
fa197c1c
PB
10537 {
10538 case EM_ARM:
10539 sec_type = SHT_ARM_EXIDX;
10540 break;
10541
10542 case EM_TI_C6000:
10543 sec_type = SHT_C6000_UNWIND;
10544 break;
10545
0b4362b0 10546 default:
74e1a04b 10547 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10548 filedata->file_header.e_machine);
015dc7e1 10549 return false;
fa197c1c
PB
10550 }
10551
dda8d76d 10552 if (filedata->string_table == NULL)
015dc7e1 10553 return false;
1b31d05e
NC
10554
10555 memset (& aux, 0, sizeof (aux));
dda8d76d 10556 aux.filedata = filedata;
0b6ae522 10557
dda8d76d 10558 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10559 {
28d13567 10560 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10561 {
28d13567 10562 if (aux.symtab)
74e1a04b 10563 {
28d13567
AM
10564 error (_("Multiple symbol tables encountered\n"));
10565 free (aux.symtab);
10566 aux.symtab = NULL;
74e1a04b 10567 free (aux.strtab);
28d13567 10568 aux.strtab = NULL;
74e1a04b 10569 }
28d13567
AM
10570 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10571 &aux.strtab, &aux.strtab_size))
015dc7e1 10572 return false;
0b6ae522 10573 }
fa197c1c 10574 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10575 unwsec = sec;
10576 }
10577
1b31d05e 10578 if (unwsec == NULL)
0b6ae522 10579 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10580 else
dda8d76d 10581 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10582 {
10583 if (sec->sh_type == sec_type)
10584 {
26c527e6
AM
10585 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
10586 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
10587 "contains %" PRIu64 " entry:\n",
10588 "\nUnwind section '%s' at offset %#" PRIx64 " "
10589 "contains %" PRIu64 " entries:\n",
d3a49aa8 10590 num_unwind),
dda8d76d 10591 printable_section_name (filedata, sec),
26c527e6 10592 sec->sh_offset,
d3a49aa8 10593 num_unwind);
0b6ae522 10594
dda8d76d 10595 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10596 res = false;
1b31d05e
NC
10597 }
10598 }
0b6ae522 10599
9db70fc3
AM
10600 free (aux.symtab);
10601 free ((char *) aux.strtab);
32ec8896
NC
10602
10603 return res;
0b6ae522
DJ
10604}
10605
3ecc00ec
NC
10606static bool
10607no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10608{
10609 printf (_("No processor specific unwind information to decode\n"));
10610 return true;
10611}
10612
015dc7e1 10613static bool
dda8d76d 10614process_unwind (Filedata * filedata)
57346661 10615{
2cf0635d
NC
10616 struct unwind_handler
10617 {
32ec8896 10618 unsigned int machtype;
015dc7e1 10619 bool (* handler)(Filedata *);
2cf0635d
NC
10620 } handlers[] =
10621 {
0b6ae522 10622 { EM_ARM, arm_process_unwind },
57346661
AM
10623 { EM_IA_64, ia64_process_unwind },
10624 { EM_PARISC, hppa_process_unwind },
fa197c1c 10625 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10626 { EM_386, no_processor_specific_unwind },
10627 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10628 { 0, NULL }
57346661
AM
10629 };
10630 int i;
10631
10632 if (!do_unwind)
015dc7e1 10633 return true;
57346661
AM
10634
10635 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10636 if (filedata->file_header.e_machine == handlers[i].machtype)
10637 return handlers[i].handler (filedata);
57346661 10638
1b31d05e 10639 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10640 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10641 return true;
57346661
AM
10642}
10643
37c18eed
SD
10644static void
10645dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10646{
10647 switch (entry->d_tag)
10648 {
10649 case DT_AARCH64_BTI_PLT:
1dbade74 10650 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10651 break;
10652 default:
10653 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10654 break;
10655 }
10656 putchar ('\n');
10657}
10658
252b5132 10659static void
978c4450 10660dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10661{
10662 switch (entry->d_tag)
10663 {
10664 case DT_MIPS_FLAGS:
10665 if (entry->d_un.d_val == 0)
4b68bca3 10666 printf (_("NONE"));
252b5132
RH
10667 else
10668 {
10669 static const char * opts[] =
10670 {
10671 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10672 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10673 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10674 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10675 "RLD_ORDER_SAFE"
10676 };
10677 unsigned int cnt;
015dc7e1 10678 bool first = true;
2b692964 10679
60bca95a 10680 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10681 if (entry->d_un.d_val & (1 << cnt))
10682 {
10683 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10684 first = false;
252b5132 10685 }
252b5132
RH
10686 }
10687 break;
103f02d3 10688
252b5132 10689 case DT_MIPS_IVERSION:
84714f86 10690 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10691 printf (_("Interface Version: %s"),
84714f86 10692 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10693 else
f493c217 10694 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 10695 entry->d_un.d_ptr);
252b5132 10696 break;
103f02d3 10697
252b5132
RH
10698 case DT_MIPS_TIME_STAMP:
10699 {
d5b07ef4 10700 char timebuf[128];
2cf0635d 10701 struct tm * tmp;
91d6fa6a 10702 time_t atime = entry->d_un.d_val;
82b1b41b 10703
91d6fa6a 10704 tmp = gmtime (&atime);
82b1b41b
NC
10705 /* PR 17531: file: 6accc532. */
10706 if (tmp == NULL)
10707 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10708 else
10709 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10710 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10711 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10712 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10713 }
10714 break;
103f02d3 10715
252b5132
RH
10716 case DT_MIPS_RLD_VERSION:
10717 case DT_MIPS_LOCAL_GOTNO:
10718 case DT_MIPS_CONFLICTNO:
10719 case DT_MIPS_LIBLISTNO:
10720 case DT_MIPS_SYMTABNO:
10721 case DT_MIPS_UNREFEXTNO:
10722 case DT_MIPS_HIPAGENO:
10723 case DT_MIPS_DELTA_CLASS_NO:
10724 case DT_MIPS_DELTA_INSTANCE_NO:
10725 case DT_MIPS_DELTA_RELOC_NO:
10726 case DT_MIPS_DELTA_SYM_NO:
10727 case DT_MIPS_DELTA_CLASSSYM_NO:
10728 case DT_MIPS_COMPACT_SIZE:
c69075ac 10729 print_vma (entry->d_un.d_val, DEC);
252b5132 10730 break;
103f02d3 10731
f16a9783 10732 case DT_MIPS_XHASH:
978c4450
AM
10733 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10734 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10735 /* Falls through. */
10736
103f02d3 10737 default:
4b68bca3 10738 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10739 }
4b68bca3 10740 putchar ('\n');
103f02d3
UD
10741}
10742
103f02d3 10743static void
2cf0635d 10744dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10745{
10746 switch (entry->d_tag)
10747 {
10748 case DT_HP_DLD_FLAGS:
10749 {
10750 static struct
10751 {
26c527e6 10752 unsigned int bit;
2cf0635d 10753 const char * str;
5e220199
NC
10754 }
10755 flags[] =
10756 {
10757 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10758 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10759 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10760 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10761 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10762 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10763 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10764 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10765 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10766 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10767 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10768 { DT_HP_GST, "HP_GST" },
10769 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10770 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10771 { DT_HP_NODELETE, "HP_NODELETE" },
10772 { DT_HP_GROUP, "HP_GROUP" },
10773 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10774 };
015dc7e1 10775 bool first = true;
5e220199 10776 size_t cnt;
625d49fc 10777 uint64_t val = entry->d_un.d_val;
103f02d3 10778
60bca95a 10779 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10780 if (val & flags[cnt].bit)
30800947
NC
10781 {
10782 if (! first)
10783 putchar (' ');
10784 fputs (flags[cnt].str, stdout);
015dc7e1 10785 first = false;
30800947
NC
10786 val ^= flags[cnt].bit;
10787 }
76da6bbe 10788
103f02d3 10789 if (val != 0 || first)
f7a99963
NC
10790 {
10791 if (! first)
10792 putchar (' ');
10793 print_vma (val, HEX);
10794 }
103f02d3
UD
10795 }
10796 break;
76da6bbe 10797
252b5132 10798 default:
f7a99963
NC
10799 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10800 break;
252b5132 10801 }
35b1837e 10802 putchar ('\n');
252b5132
RH
10803}
10804
28f997cf
TG
10805/* VMS vs Unix time offset and factor. */
10806
10807#define VMS_EPOCH_OFFSET 35067168000000000LL
10808#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10809#ifndef INT64_MIN
10810#define INT64_MIN (-9223372036854775807LL - 1)
10811#endif
28f997cf
TG
10812
10813/* Display a VMS time in a human readable format. */
10814
10815static void
0e3c1eeb 10816print_vms_time (int64_t vmstime)
28f997cf 10817{
dccc31de 10818 struct tm *tm = NULL;
28f997cf
TG
10819 time_t unxtime;
10820
dccc31de
AM
10821 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10822 {
10823 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10824 unxtime = vmstime;
10825 if (unxtime == vmstime)
10826 tm = gmtime (&unxtime);
10827 }
10828 if (tm != NULL)
10829 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10830 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10831 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 10832}
28f997cf 10833
ecc51f48 10834static void
2cf0635d 10835dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10836{
10837 switch (entry->d_tag)
10838 {
0de14b54 10839 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10840 /* First 3 slots reserved. */
ecc51f48
NC
10841 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10842 printf (" -- ");
10843 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10844 break;
10845
28f997cf 10846 case DT_IA_64_VMS_LINKTIME:
28f997cf 10847 print_vms_time (entry->d_un.d_val);
28f997cf
TG
10848 break;
10849
10850 case DT_IA_64_VMS_LNKFLAGS:
10851 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10852 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10853 printf (" CALL_DEBUG");
10854 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10855 printf (" NOP0BUFS");
10856 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10857 printf (" P0IMAGE");
10858 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10859 printf (" MKTHREADS");
10860 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10861 printf (" UPCALLS");
10862 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10863 printf (" IMGSTA");
10864 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10865 printf (" INITIALIZE");
10866 if (entry->d_un.d_val & VMS_LF_MAIN)
10867 printf (" MAIN");
10868 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10869 printf (" EXE_INIT");
10870 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10871 printf (" TBK_IN_IMG");
10872 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10873 printf (" DBG_IN_IMG");
10874 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10875 printf (" TBK_IN_DSF");
10876 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10877 printf (" DBG_IN_DSF");
10878 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10879 printf (" SIGNATURES");
10880 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10881 printf (" REL_SEG_OFF");
10882 break;
10883
bdf4d63a
JJ
10884 default:
10885 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10886 break;
ecc51f48 10887 }
bdf4d63a 10888 putchar ('\n');
ecc51f48
NC
10889}
10890
015dc7e1 10891static bool
dda8d76d 10892get_32bit_dynamic_section (Filedata * filedata)
252b5132 10893{
2cf0635d
NC
10894 Elf32_External_Dyn * edyn;
10895 Elf32_External_Dyn * ext;
10896 Elf_Internal_Dyn * entry;
103f02d3 10897
978c4450
AM
10898 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10899 filedata->dynamic_addr, 1,
10900 filedata->dynamic_size,
10901 _("dynamic section"));
a6e9f9df 10902 if (!edyn)
015dc7e1 10903 return false;
103f02d3 10904
071436c6
NC
10905 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10906 might not have the luxury of section headers. Look for the DT_NULL
10907 terminator to determine the number of entries. */
978c4450
AM
10908 for (ext = edyn, filedata->dynamic_nent = 0;
10909 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10910 ext++)
10911 {
978c4450 10912 filedata->dynamic_nent++;
ba2685cc
AM
10913 if (BYTE_GET (ext->d_tag) == DT_NULL)
10914 break;
10915 }
252b5132 10916
978c4450
AM
10917 filedata->dynamic_section
10918 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10919 if (filedata->dynamic_section == NULL)
252b5132 10920 {
26c527e6
AM
10921 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
10922 filedata->dynamic_nent);
9ea033b2 10923 free (edyn);
015dc7e1 10924 return false;
9ea033b2 10925 }
252b5132 10926
978c4450
AM
10927 for (ext = edyn, entry = filedata->dynamic_section;
10928 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10929 ext++, entry++)
9ea033b2 10930 {
fb514b26
AM
10931 entry->d_tag = BYTE_GET (ext->d_tag);
10932 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10933 }
10934
9ea033b2
NC
10935 free (edyn);
10936
015dc7e1 10937 return true;
9ea033b2
NC
10938}
10939
015dc7e1 10940static bool
dda8d76d 10941get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10942{
2cf0635d
NC
10943 Elf64_External_Dyn * edyn;
10944 Elf64_External_Dyn * ext;
10945 Elf_Internal_Dyn * entry;
103f02d3 10946
071436c6 10947 /* Read in the data. */
978c4450
AM
10948 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10949 filedata->dynamic_addr, 1,
10950 filedata->dynamic_size,
10951 _("dynamic section"));
a6e9f9df 10952 if (!edyn)
015dc7e1 10953 return false;
103f02d3 10954
071436c6
NC
10955 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10956 might not have the luxury of section headers. Look for the DT_NULL
10957 terminator to determine the number of entries. */
978c4450 10958 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10959 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10960 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10961 ext++)
10962 {
978c4450 10963 filedata->dynamic_nent++;
66543521 10964 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10965 break;
10966 }
252b5132 10967
978c4450
AM
10968 filedata->dynamic_section
10969 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10970 if (filedata->dynamic_section == NULL)
252b5132 10971 {
26c527e6
AM
10972 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
10973 filedata->dynamic_nent);
252b5132 10974 free (edyn);
015dc7e1 10975 return false;
252b5132
RH
10976 }
10977
071436c6 10978 /* Convert from external to internal formats. */
978c4450
AM
10979 for (ext = edyn, entry = filedata->dynamic_section;
10980 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10981 ext++, entry++)
252b5132 10982 {
66543521
AM
10983 entry->d_tag = BYTE_GET (ext->d_tag);
10984 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10985 }
10986
10987 free (edyn);
10988
015dc7e1 10989 return true;
9ea033b2
NC
10990}
10991
4de91c10
AM
10992static bool
10993get_dynamic_section (Filedata *filedata)
10994{
10995 if (filedata->dynamic_section)
10996 return true;
10997
10998 if (is_32bit_elf)
10999 return get_32bit_dynamic_section (filedata);
11000 else
11001 return get_64bit_dynamic_section (filedata);
11002}
11003
e9e44622 11004static void
625d49fc 11005print_dynamic_flags (uint64_t flags)
d1133906 11006{
015dc7e1 11007 bool first = true;
13ae64f3 11008
d1133906
NC
11009 while (flags)
11010 {
625d49fc 11011 uint64_t flag;
d1133906
NC
11012
11013 flag = flags & - flags;
11014 flags &= ~ flag;
11015
e9e44622 11016 if (first)
015dc7e1 11017 first = false;
e9e44622
JJ
11018 else
11019 putc (' ', stdout);
13ae64f3 11020
d1133906
NC
11021 switch (flag)
11022 {
e9e44622
JJ
11023 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11024 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11025 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11026 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11027 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 11028 default: fputs (_("unknown"), stdout); break;
d1133906
NC
11029 }
11030 }
e9e44622 11031 puts ("");
d1133906
NC
11032}
11033
625d49fc 11034static uint64_t *
be7d229a 11035get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
11036{
11037 unsigned char * e_data;
625d49fc 11038 uint64_t * i_data;
10ca4b04 11039
be7d229a
AM
11040 /* If size_t is smaller than uint64_t, eg because you are building
11041 on a 32-bit host, then make sure that when number is cast to
11042 size_t no information is lost. */
11043 if ((size_t) number != number
11044 || ent_size * number / ent_size != number)
10ca4b04 11045 {
be7d229a 11046 error (_("Size overflow prevents reading %" PRIu64
b8281767 11047 " elements of size %u\n"),
be7d229a 11048 number, ent_size);
10ca4b04
L
11049 return NULL;
11050 }
11051
11052 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11053 attempting to allocate memory when the read is bound to fail. */
11054 if (ent_size * number > filedata->file_size)
11055 {
b8281767 11056 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 11057 number);
10ca4b04
L
11058 return NULL;
11059 }
11060
11061 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11062 if (e_data == NULL)
11063 {
b8281767 11064 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 11065 number);
10ca4b04
L
11066 return NULL;
11067 }
11068
11069 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11070 {
b8281767 11071 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 11072 number * ent_size);
10ca4b04
L
11073 free (e_data);
11074 return NULL;
11075 }
11076
625d49fc 11077 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
11078 if (i_data == NULL)
11079 {
b8281767 11080 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 11081 number);
10ca4b04
L
11082 free (e_data);
11083 return NULL;
11084 }
11085
11086 while (number--)
11087 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11088
11089 free (e_data);
11090
11091 return i_data;
11092}
11093
26c527e6 11094static uint64_t
10ca4b04
L
11095get_num_dynamic_syms (Filedata * filedata)
11096{
26c527e6 11097 uint64_t num_of_syms = 0;
10ca4b04
L
11098
11099 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11100 return num_of_syms;
11101
978c4450 11102 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11103 {
11104 unsigned char nb[8];
11105 unsigned char nc[8];
11106 unsigned int hash_ent_size = 4;
11107
11108 if ((filedata->file_header.e_machine == EM_ALPHA
11109 || filedata->file_header.e_machine == EM_S390
11110 || filedata->file_header.e_machine == EM_S390_OLD)
11111 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11112 hash_ent_size = 8;
11113
63cf857e
AM
11114 if (fseek64 (filedata->handle,
11115 (filedata->archive_file_offset
11116 + offset_from_vma (filedata,
11117 filedata->dynamic_info[DT_HASH],
11118 sizeof nb + sizeof nc)),
11119 SEEK_SET))
10ca4b04
L
11120 {
11121 error (_("Unable to seek to start of dynamic information\n"));
11122 goto no_hash;
11123 }
11124
11125 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11126 {
11127 error (_("Failed to read in number of buckets\n"));
11128 goto no_hash;
11129 }
11130
11131 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11132 {
11133 error (_("Failed to read in number of chains\n"));
11134 goto no_hash;
11135 }
11136
978c4450
AM
11137 filedata->nbuckets = byte_get (nb, hash_ent_size);
11138 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11139
2482f306
AM
11140 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11141 {
11142 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11143 hash_ent_size);
11144 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11145 hash_ent_size);
001890e1 11146
2482f306
AM
11147 if (filedata->buckets != NULL && filedata->chains != NULL)
11148 num_of_syms = filedata->nchains;
11149 }
ceb9bf11 11150 no_hash:
10ca4b04
L
11151 if (num_of_syms == 0)
11152 {
9db70fc3
AM
11153 free (filedata->buckets);
11154 filedata->buckets = NULL;
11155 free (filedata->chains);
11156 filedata->chains = NULL;
978c4450 11157 filedata->nbuckets = 0;
10ca4b04
L
11158 }
11159 }
11160
978c4450 11161 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11162 {
11163 unsigned char nb[16];
625d49fc
AM
11164 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11165 uint64_t buckets_vma;
26c527e6 11166 uint64_t hn;
10ca4b04 11167
63cf857e
AM
11168 if (fseek64 (filedata->handle,
11169 (filedata->archive_file_offset
11170 + offset_from_vma (filedata,
11171 filedata->dynamic_info_DT_GNU_HASH,
11172 sizeof nb)),
11173 SEEK_SET))
10ca4b04
L
11174 {
11175 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11176 goto no_gnu_hash;
11177 }
11178
11179 if (fread (nb, 16, 1, filedata->handle) != 1)
11180 {
11181 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11182 goto no_gnu_hash;
11183 }
11184
978c4450
AM
11185 filedata->ngnubuckets = byte_get (nb, 4);
11186 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11187 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11188 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11189 if (is_32bit_elf)
11190 buckets_vma += bitmaskwords * 4;
11191 else
11192 buckets_vma += bitmaskwords * 8;
11193
63cf857e
AM
11194 if (fseek64 (filedata->handle,
11195 (filedata->archive_file_offset
11196 + offset_from_vma (filedata, buckets_vma, 4)),
11197 SEEK_SET))
10ca4b04
L
11198 {
11199 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11200 goto no_gnu_hash;
11201 }
11202
978c4450
AM
11203 filedata->gnubuckets
11204 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11205
978c4450 11206 if (filedata->gnubuckets == NULL)
90837ea7 11207 goto no_gnu_hash;
10ca4b04 11208
978c4450
AM
11209 for (i = 0; i < filedata->ngnubuckets; i++)
11210 if (filedata->gnubuckets[i] != 0)
10ca4b04 11211 {
978c4450 11212 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11213 goto no_gnu_hash;
10ca4b04 11214
978c4450
AM
11215 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11216 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11217 }
11218
11219 if (maxchain == 0xffffffff)
90837ea7 11220 goto no_gnu_hash;
10ca4b04 11221
978c4450 11222 maxchain -= filedata->gnusymidx;
10ca4b04 11223
63cf857e
AM
11224 if (fseek64 (filedata->handle,
11225 (filedata->archive_file_offset
11226 + offset_from_vma (filedata,
11227 buckets_vma + 4 * (filedata->ngnubuckets
11228 + maxchain),
11229 4)),
11230 SEEK_SET))
10ca4b04
L
11231 {
11232 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11233 goto no_gnu_hash;
11234 }
11235
11236 do
11237 {
11238 if (fread (nb, 4, 1, filedata->handle) != 1)
11239 {
11240 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11241 goto no_gnu_hash;
11242 }
11243
11244 if (maxchain + 1 == 0)
90837ea7 11245 goto no_gnu_hash;
10ca4b04
L
11246
11247 ++maxchain;
11248 }
11249 while ((byte_get (nb, 4) & 1) == 0);
11250
63cf857e
AM
11251 if (fseek64 (filedata->handle,
11252 (filedata->archive_file_offset
11253 + offset_from_vma (filedata, (buckets_vma
11254 + 4 * filedata->ngnubuckets),
11255 4)),
11256 SEEK_SET))
10ca4b04
L
11257 {
11258 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11259 goto no_gnu_hash;
11260 }
11261
978c4450
AM
11262 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11263 filedata->ngnuchains = maxchain;
10ca4b04 11264
978c4450 11265 if (filedata->gnuchains == NULL)
90837ea7 11266 goto no_gnu_hash;
10ca4b04 11267
978c4450 11268 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11269 {
63cf857e
AM
11270 if (fseek64 (filedata->handle,
11271 (filedata->archive_file_offset
11272 + offset_from_vma (filedata, (buckets_vma
11273 + 4 * (filedata->ngnubuckets
11274 + maxchain)), 4)),
11275 SEEK_SET))
10ca4b04
L
11276 {
11277 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11278 goto no_gnu_hash;
11279 }
11280
978c4450 11281 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11282 if (filedata->mipsxlat == NULL)
11283 goto no_gnu_hash;
10ca4b04
L
11284 }
11285
978c4450
AM
11286 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11287 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11288 {
625d49fc
AM
11289 uint64_t si = filedata->gnubuckets[hn];
11290 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11291
11292 do
11293 {
978c4450 11294 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11295 {
c31ab5a0
AM
11296 if (off < filedata->ngnuchains
11297 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11298 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11299 }
11300 else
11301 {
11302 if (si >= num_of_syms)
11303 num_of_syms = si + 1;
11304 }
11305 si++;
11306 }
978c4450
AM
11307 while (off < filedata->ngnuchains
11308 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11309 }
11310
90837ea7 11311 if (num_of_syms == 0)
10ca4b04 11312 {
90837ea7 11313 no_gnu_hash:
9db70fc3
AM
11314 free (filedata->mipsxlat);
11315 filedata->mipsxlat = NULL;
11316 free (filedata->gnuchains);
11317 filedata->gnuchains = NULL;
11318 free (filedata->gnubuckets);
11319 filedata->gnubuckets = NULL;
978c4450
AM
11320 filedata->ngnubuckets = 0;
11321 filedata->ngnuchains = 0;
10ca4b04
L
11322 }
11323 }
11324
11325 return num_of_syms;
11326}
11327
b2d38a17
NC
11328/* Parse and display the contents of the dynamic section. */
11329
015dc7e1 11330static bool
dda8d76d 11331process_dynamic_section (Filedata * filedata)
9ea033b2 11332{
2cf0635d 11333 Elf_Internal_Dyn * entry;
9ea033b2 11334
93df3340 11335 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11336 {
11337 if (do_dynamic)
ca0e11aa
NC
11338 {
11339 if (filedata->is_separate)
11340 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11341 filedata->file_name);
11342 else
11343 printf (_("\nThere is no dynamic section in this file.\n"));
11344 }
9ea033b2 11345
015dc7e1 11346 return true;
9ea033b2
NC
11347 }
11348
4de91c10
AM
11349 if (!get_dynamic_section (filedata))
11350 return false;
9ea033b2 11351
252b5132 11352 /* Find the appropriate symbol table. */
978c4450 11353 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11354 {
26c527e6 11355 uint64_t num_of_syms;
2482f306 11356
978c4450
AM
11357 for (entry = filedata->dynamic_section;
11358 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11359 ++entry)
10ca4b04 11360 if (entry->d_tag == DT_SYMTAB)
978c4450 11361 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11362 else if (entry->d_tag == DT_SYMENT)
978c4450 11363 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11364 else if (entry->d_tag == DT_HASH)
978c4450 11365 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11366 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11367 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11368 else if ((filedata->file_header.e_machine == EM_MIPS
11369 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11370 && entry->d_tag == DT_MIPS_XHASH)
11371 {
978c4450
AM
11372 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11373 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11374 }
252b5132 11375
2482f306
AM
11376 num_of_syms = get_num_dynamic_syms (filedata);
11377
11378 if (num_of_syms != 0
11379 && filedata->dynamic_symbols == NULL
11380 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11381 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11382 {
11383 Elf_Internal_Phdr *seg;
625d49fc 11384 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11385
2482f306
AM
11386 if (! get_program_headers (filedata))
11387 {
11388 error (_("Cannot interpret virtual addresses "
11389 "without program headers.\n"));
015dc7e1 11390 return false;
2482f306 11391 }
252b5132 11392
2482f306
AM
11393 for (seg = filedata->program_headers;
11394 seg < filedata->program_headers + filedata->file_header.e_phnum;
11395 ++seg)
11396 {
11397 if (seg->p_type != PT_LOAD)
11398 continue;
252b5132 11399
2482f306
AM
11400 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11401 {
11402 /* See PR 21379 for a reproducer. */
11403 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11404 return false;
2482f306 11405 }
252b5132 11406
2482f306
AM
11407 if (vma >= (seg->p_vaddr & -seg->p_align)
11408 && vma < seg->p_vaddr + seg->p_filesz)
11409 {
11410 /* Since we do not know how big the symbol table is,
11411 we default to reading in up to the end of PT_LOAD
11412 segment and processing that. This is overkill, I
11413 know, but it should work. */
11414 Elf_Internal_Shdr section;
11415 section.sh_offset = (vma - seg->p_vaddr
11416 + seg->p_offset);
11417 section.sh_size = (num_of_syms
11418 * filedata->dynamic_info[DT_SYMENT]);
11419 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11420
11421 if (do_checks
11422 && filedata->dynamic_symtab_section != NULL
11423 && ((filedata->dynamic_symtab_section->sh_offset
11424 != section.sh_offset)
11425 || (filedata->dynamic_symtab_section->sh_size
11426 != section.sh_size)
11427 || (filedata->dynamic_symtab_section->sh_entsize
11428 != section.sh_entsize)))
11429 warn (_("\
11430the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11431
2482f306
AM
11432 section.sh_name = filedata->string_table_length;
11433 filedata->dynamic_symbols
4de91c10 11434 = get_elf_symbols (filedata, &section,
2482f306
AM
11435 &filedata->num_dynamic_syms);
11436 if (filedata->dynamic_symbols == NULL
11437 || filedata->num_dynamic_syms != num_of_syms)
11438 {
11439 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11440 return false;
2482f306
AM
11441 }
11442 break;
11443 }
11444 }
11445 }
11446 }
252b5132
RH
11447
11448 /* Similarly find a string table. */
978c4450
AM
11449 if (filedata->dynamic_strings == NULL)
11450 for (entry = filedata->dynamic_section;
11451 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11452 ++entry)
11453 {
11454 if (entry->d_tag == DT_STRTAB)
978c4450 11455 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11456
10ca4b04 11457 if (entry->d_tag == DT_STRSZ)
978c4450 11458 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11459
978c4450
AM
11460 if (filedata->dynamic_info[DT_STRTAB]
11461 && filedata->dynamic_info[DT_STRSZ])
10ca4b04 11462 {
26c527e6 11463 uint64_t offset;
be7d229a 11464 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11465
11466 offset = offset_from_vma (filedata,
978c4450 11467 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11468 str_tab_len);
8ac10c5b
L
11469 if (do_checks
11470 && filedata->dynamic_strtab_section
11471 && ((filedata->dynamic_strtab_section->sh_offset
11472 != (file_ptr) offset)
11473 || (filedata->dynamic_strtab_section->sh_size
11474 != str_tab_len)))
11475 warn (_("\
11476the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11477
978c4450
AM
11478 filedata->dynamic_strings
11479 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11480 _("dynamic string table"));
11481 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11482 {
11483 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11484 break;
11485 }
e3d39609 11486
978c4450 11487 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11488 break;
11489 }
11490 }
252b5132
RH
11491
11492 /* And find the syminfo section if available. */
978c4450 11493 if (filedata->dynamic_syminfo == NULL)
252b5132 11494 {
26c527e6 11495 uint64_t syminsz = 0;
252b5132 11496
978c4450
AM
11497 for (entry = filedata->dynamic_section;
11498 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11499 ++entry)
252b5132
RH
11500 {
11501 if (entry->d_tag == DT_SYMINENT)
11502 {
11503 /* Note: these braces are necessary to avoid a syntax
11504 error from the SunOS4 C compiler. */
049b0c3a
NC
11505 /* PR binutils/17531: A corrupt file can trigger this test.
11506 So do not use an assert, instead generate an error message. */
11507 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11508 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11509 (int) entry->d_un.d_val);
252b5132
RH
11510 }
11511 else if (entry->d_tag == DT_SYMINSZ)
11512 syminsz = entry->d_un.d_val;
11513 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11514 filedata->dynamic_syminfo_offset
11515 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11516 }
11517
978c4450 11518 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11519 {
2cf0635d
NC
11520 Elf_External_Syminfo * extsyminfo;
11521 Elf_External_Syminfo * extsym;
11522 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11523
11524 /* There is a syminfo section. Read the data. */
3f5e193b 11525 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11526 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11527 1, syminsz, _("symbol information"));
a6e9f9df 11528 if (!extsyminfo)
015dc7e1 11529 return false;
252b5132 11530
978c4450 11531 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11532 {
11533 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11534 free (filedata->dynamic_syminfo);
e3d39609 11535 }
978c4450
AM
11536 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11537 if (filedata->dynamic_syminfo == NULL)
252b5132 11538 {
26c527e6
AM
11539 error (_("Out of memory allocating %" PRIu64
11540 " bytes for dynamic symbol info\n"),
11541 syminsz);
015dc7e1 11542 return false;
252b5132
RH
11543 }
11544
2482f306
AM
11545 filedata->dynamic_syminfo_nent
11546 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11547 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11548 syminfo < (filedata->dynamic_syminfo
11549 + filedata->dynamic_syminfo_nent);
86dba8ee 11550 ++syminfo, ++extsym)
252b5132 11551 {
86dba8ee
AM
11552 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11553 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11554 }
11555
11556 free (extsyminfo);
11557 }
11558 }
11559
978c4450 11560 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11561 {
f253158f 11562 if (filedata->is_separate)
26c527e6
AM
11563 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
11564 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
11565 filedata->dynamic_nent),
f253158f
NC
11566 filedata->file_name,
11567 filedata->dynamic_addr,
26c527e6 11568 filedata->dynamic_nent);
84a9f195 11569 else
02da71ee 11570 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
26c527e6
AM
11571 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
11572 filedata->dynamic_nent),
84a9f195 11573 filedata->dynamic_addr,
26c527e6 11574 filedata->dynamic_nent);
ca0e11aa 11575 }
252b5132
RH
11576 if (do_dynamic)
11577 printf (_(" Tag Type Name/Value\n"));
11578
978c4450
AM
11579 for (entry = filedata->dynamic_section;
11580 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11581 entry++)
252b5132
RH
11582 {
11583 if (do_dynamic)
f7a99963 11584 {
2cf0635d 11585 const char * dtype;
e699b9ff 11586
f7a99963
NC
11587 putchar (' ');
11588 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11589 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11590 printf (" (%s)%*s", dtype,
32ec8896 11591 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11592 }
252b5132
RH
11593
11594 switch (entry->d_tag)
11595 {
d1133906
NC
11596 case DT_FLAGS:
11597 if (do_dynamic)
e9e44622 11598 print_dynamic_flags (entry->d_un.d_val);
d1133906 11599 break;
76da6bbe 11600
252b5132
RH
11601 case DT_AUXILIARY:
11602 case DT_FILTER:
019148e4
L
11603 case DT_CONFIG:
11604 case DT_DEPAUDIT:
11605 case DT_AUDIT:
252b5132
RH
11606 if (do_dynamic)
11607 {
019148e4 11608 switch (entry->d_tag)
b34976b6 11609 {
019148e4
L
11610 case DT_AUXILIARY:
11611 printf (_("Auxiliary library"));
11612 break;
11613
11614 case DT_FILTER:
11615 printf (_("Filter library"));
11616 break;
11617
b34976b6 11618 case DT_CONFIG:
019148e4
L
11619 printf (_("Configuration file"));
11620 break;
11621
11622 case DT_DEPAUDIT:
11623 printf (_("Dependency audit library"));
11624 break;
11625
11626 case DT_AUDIT:
11627 printf (_("Audit library"));
11628 break;
11629 }
252b5132 11630
84714f86 11631 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11632 printf (": [%s]\n",
84714f86 11633 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11634 else
f7a99963
NC
11635 {
11636 printf (": ");
11637 print_vma (entry->d_un.d_val, PREFIX_HEX);
11638 putchar ('\n');
11639 }
252b5132
RH
11640 }
11641 break;
11642
dcefbbbd 11643 case DT_FEATURE:
252b5132
RH
11644 if (do_dynamic)
11645 {
11646 printf (_("Flags:"));
86f55779 11647
252b5132
RH
11648 if (entry->d_un.d_val == 0)
11649 printf (_(" None\n"));
11650 else
11651 {
26c527e6 11652 uint64_t val = entry->d_un.d_val;
86f55779 11653
252b5132
RH
11654 if (val & DTF_1_PARINIT)
11655 {
11656 printf (" PARINIT");
11657 val ^= DTF_1_PARINIT;
11658 }
dcefbbbd
L
11659 if (val & DTF_1_CONFEXP)
11660 {
11661 printf (" CONFEXP");
11662 val ^= DTF_1_CONFEXP;
11663 }
252b5132 11664 if (val != 0)
26c527e6 11665 printf (" %" PRIx64, val);
252b5132
RH
11666 puts ("");
11667 }
11668 }
11669 break;
11670
11671 case DT_POSFLAG_1:
11672 if (do_dynamic)
11673 {
11674 printf (_("Flags:"));
86f55779 11675
252b5132
RH
11676 if (entry->d_un.d_val == 0)
11677 printf (_(" None\n"));
11678 else
11679 {
26c527e6 11680 uint64_t val = entry->d_un.d_val;
86f55779 11681
252b5132
RH
11682 if (val & DF_P1_LAZYLOAD)
11683 {
11684 printf (" LAZYLOAD");
11685 val ^= DF_P1_LAZYLOAD;
11686 }
11687 if (val & DF_P1_GROUPPERM)
11688 {
11689 printf (" GROUPPERM");
11690 val ^= DF_P1_GROUPPERM;
11691 }
11692 if (val != 0)
26c527e6 11693 printf (" %" PRIx64, val);
252b5132
RH
11694 puts ("");
11695 }
11696 }
11697 break;
11698
11699 case DT_FLAGS_1:
11700 if (do_dynamic)
11701 {
11702 printf (_("Flags:"));
11703 if (entry->d_un.d_val == 0)
11704 printf (_(" None\n"));
11705 else
11706 {
26c527e6 11707 uint64_t val = entry->d_un.d_val;
86f55779 11708
252b5132
RH
11709 if (val & DF_1_NOW)
11710 {
11711 printf (" NOW");
11712 val ^= DF_1_NOW;
11713 }
11714 if (val & DF_1_GLOBAL)
11715 {
11716 printf (" GLOBAL");
11717 val ^= DF_1_GLOBAL;
11718 }
11719 if (val & DF_1_GROUP)
11720 {
11721 printf (" GROUP");
11722 val ^= DF_1_GROUP;
11723 }
11724 if (val & DF_1_NODELETE)
11725 {
11726 printf (" NODELETE");
11727 val ^= DF_1_NODELETE;
11728 }
11729 if (val & DF_1_LOADFLTR)
11730 {
11731 printf (" LOADFLTR");
11732 val ^= DF_1_LOADFLTR;
11733 }
11734 if (val & DF_1_INITFIRST)
11735 {
11736 printf (" INITFIRST");
11737 val ^= DF_1_INITFIRST;
11738 }
11739 if (val & DF_1_NOOPEN)
11740 {
11741 printf (" NOOPEN");
11742 val ^= DF_1_NOOPEN;
11743 }
11744 if (val & DF_1_ORIGIN)
11745 {
11746 printf (" ORIGIN");
11747 val ^= DF_1_ORIGIN;
11748 }
11749 if (val & DF_1_DIRECT)
11750 {
11751 printf (" DIRECT");
11752 val ^= DF_1_DIRECT;
11753 }
11754 if (val & DF_1_TRANS)
11755 {
11756 printf (" TRANS");
11757 val ^= DF_1_TRANS;
11758 }
11759 if (val & DF_1_INTERPOSE)
11760 {
11761 printf (" INTERPOSE");
11762 val ^= DF_1_INTERPOSE;
11763 }
f7db6139 11764 if (val & DF_1_NODEFLIB)
dcefbbbd 11765 {
f7db6139
L
11766 printf (" NODEFLIB");
11767 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11768 }
11769 if (val & DF_1_NODUMP)
11770 {
11771 printf (" NODUMP");
11772 val ^= DF_1_NODUMP;
11773 }
34b60028 11774 if (val & DF_1_CONFALT)
dcefbbbd 11775 {
34b60028
L
11776 printf (" CONFALT");
11777 val ^= DF_1_CONFALT;
11778 }
11779 if (val & DF_1_ENDFILTEE)
11780 {
11781 printf (" ENDFILTEE");
11782 val ^= DF_1_ENDFILTEE;
11783 }
11784 if (val & DF_1_DISPRELDNE)
11785 {
11786 printf (" DISPRELDNE");
11787 val ^= DF_1_DISPRELDNE;
11788 }
11789 if (val & DF_1_DISPRELPND)
11790 {
11791 printf (" DISPRELPND");
11792 val ^= DF_1_DISPRELPND;
11793 }
11794 if (val & DF_1_NODIRECT)
11795 {
11796 printf (" NODIRECT");
11797 val ^= DF_1_NODIRECT;
11798 }
11799 if (val & DF_1_IGNMULDEF)
11800 {
11801 printf (" IGNMULDEF");
11802 val ^= DF_1_IGNMULDEF;
11803 }
11804 if (val & DF_1_NOKSYMS)
11805 {
11806 printf (" NOKSYMS");
11807 val ^= DF_1_NOKSYMS;
11808 }
11809 if (val & DF_1_NOHDR)
11810 {
11811 printf (" NOHDR");
11812 val ^= DF_1_NOHDR;
11813 }
11814 if (val & DF_1_EDITED)
11815 {
11816 printf (" EDITED");
11817 val ^= DF_1_EDITED;
11818 }
11819 if (val & DF_1_NORELOC)
11820 {
11821 printf (" NORELOC");
11822 val ^= DF_1_NORELOC;
11823 }
11824 if (val & DF_1_SYMINTPOSE)
11825 {
11826 printf (" SYMINTPOSE");
11827 val ^= DF_1_SYMINTPOSE;
11828 }
11829 if (val & DF_1_GLOBAUDIT)
11830 {
11831 printf (" GLOBAUDIT");
11832 val ^= DF_1_GLOBAUDIT;
11833 }
11834 if (val & DF_1_SINGLETON)
11835 {
11836 printf (" SINGLETON");
11837 val ^= DF_1_SINGLETON;
dcefbbbd 11838 }
5c383f02
RO
11839 if (val & DF_1_STUB)
11840 {
11841 printf (" STUB");
11842 val ^= DF_1_STUB;
11843 }
11844 if (val & DF_1_PIE)
11845 {
11846 printf (" PIE");
11847 val ^= DF_1_PIE;
11848 }
b1202ffa
L
11849 if (val & DF_1_KMOD)
11850 {
11851 printf (" KMOD");
11852 val ^= DF_1_KMOD;
11853 }
11854 if (val & DF_1_WEAKFILTER)
11855 {
11856 printf (" WEAKFILTER");
11857 val ^= DF_1_WEAKFILTER;
11858 }
11859 if (val & DF_1_NOCOMMON)
11860 {
11861 printf (" NOCOMMON");
11862 val ^= DF_1_NOCOMMON;
11863 }
252b5132 11864 if (val != 0)
26c527e6 11865 printf (" %" PRIx64, val);
252b5132
RH
11866 puts ("");
11867 }
11868 }
11869 break;
11870
11871 case DT_PLTREL:
978c4450 11872 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11873 if (do_dynamic)
dda8d76d 11874 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11875 break;
11876
11877 case DT_NULL :
11878 case DT_NEEDED :
11879 case DT_PLTGOT :
11880 case DT_HASH :
11881 case DT_STRTAB :
11882 case DT_SYMTAB :
11883 case DT_RELA :
11884 case DT_INIT :
11885 case DT_FINI :
11886 case DT_SONAME :
11887 case DT_RPATH :
11888 case DT_SYMBOLIC:
11889 case DT_REL :
a7fd1186 11890 case DT_RELR :
252b5132
RH
11891 case DT_DEBUG :
11892 case DT_TEXTREL :
11893 case DT_JMPREL :
019148e4 11894 case DT_RUNPATH :
978c4450 11895 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11896
11897 if (do_dynamic)
11898 {
84714f86 11899 const char *name;
252b5132 11900
84714f86
AM
11901 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11902 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11903 else
d79b3d50 11904 name = NULL;
252b5132
RH
11905
11906 if (name)
11907 {
11908 switch (entry->d_tag)
11909 {
11910 case DT_NEEDED:
11911 printf (_("Shared library: [%s]"), name);
11912
13acb58d
AM
11913 if (filedata->program_interpreter
11914 && streq (name, filedata->program_interpreter))
f7a99963 11915 printf (_(" program interpreter"));
252b5132
RH
11916 break;
11917
11918 case DT_SONAME:
f7a99963 11919 printf (_("Library soname: [%s]"), name);
252b5132
RH
11920 break;
11921
11922 case DT_RPATH:
f7a99963 11923 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11924 break;
11925
019148e4
L
11926 case DT_RUNPATH:
11927 printf (_("Library runpath: [%s]"), name);
11928 break;
11929
252b5132 11930 default:
f7a99963
NC
11931 print_vma (entry->d_un.d_val, PREFIX_HEX);
11932 break;
252b5132
RH
11933 }
11934 }
11935 else
f7a99963
NC
11936 print_vma (entry->d_un.d_val, PREFIX_HEX);
11937
11938 putchar ('\n');
252b5132
RH
11939 }
11940 break;
11941
11942 case DT_PLTRELSZ:
11943 case DT_RELASZ :
11944 case DT_STRSZ :
11945 case DT_RELSZ :
11946 case DT_RELAENT :
a7fd1186
FS
11947 case DT_RELRENT :
11948 case DT_RELRSZ :
252b5132
RH
11949 case DT_SYMENT :
11950 case DT_RELENT :
978c4450 11951 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11952 /* Fall through. */
252b5132
RH
11953 case DT_PLTPADSZ:
11954 case DT_MOVEENT :
11955 case DT_MOVESZ :
04d8355a 11956 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11957 case DT_INIT_ARRAYSZ:
11958 case DT_FINI_ARRAYSZ:
047b2264
JJ
11959 case DT_GNU_CONFLICTSZ:
11960 case DT_GNU_LIBLISTSZ:
252b5132 11961 if (do_dynamic)
f7a99963
NC
11962 {
11963 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11964 printf (_(" (bytes)\n"));
f7a99963 11965 }
252b5132
RH
11966 break;
11967
11968 case DT_VERDEFNUM:
11969 case DT_VERNEEDNUM:
11970 case DT_RELACOUNT:
11971 case DT_RELCOUNT:
11972 if (do_dynamic)
f7a99963
NC
11973 {
11974 print_vma (entry->d_un.d_val, UNSIGNED);
11975 putchar ('\n');
11976 }
252b5132
RH
11977 break;
11978
11979 case DT_SYMINSZ:
11980 case DT_SYMINENT:
11981 case DT_SYMINFO:
11982 case DT_USED:
11983 case DT_INIT_ARRAY:
11984 case DT_FINI_ARRAY:
11985 if (do_dynamic)
11986 {
d79b3d50 11987 if (entry->d_tag == DT_USED
84714f86 11988 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11989 {
84714f86
AM
11990 const char *name
11991 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11992
b34976b6 11993 if (*name)
252b5132
RH
11994 {
11995 printf (_("Not needed object: [%s]\n"), name);
11996 break;
11997 }
11998 }
103f02d3 11999
f7a99963
NC
12000 print_vma (entry->d_un.d_val, PREFIX_HEX);
12001 putchar ('\n');
252b5132
RH
12002 }
12003 break;
12004
12005 case DT_BIND_NOW:
12006 /* The value of this entry is ignored. */
35b1837e
AM
12007 if (do_dynamic)
12008 putchar ('\n');
252b5132 12009 break;
103f02d3 12010
047b2264
JJ
12011 case DT_GNU_PRELINKED:
12012 if (do_dynamic)
12013 {
2cf0635d 12014 struct tm * tmp;
91d6fa6a 12015 time_t atime = entry->d_un.d_val;
047b2264 12016
91d6fa6a 12017 tmp = gmtime (&atime);
071436c6
NC
12018 /* PR 17533 file: 041-1244816-0.004. */
12019 if (tmp == NULL)
26c527e6
AM
12020 printf (_("<corrupt time val: %" PRIx64),
12021 (uint64_t) atime);
071436c6
NC
12022 else
12023 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12024 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12025 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12026
12027 }
12028 break;
12029
fdc90cb4 12030 case DT_GNU_HASH:
978c4450 12031 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
12032 if (do_dynamic)
12033 {
12034 print_vma (entry->d_un.d_val, PREFIX_HEX);
12035 putchar ('\n');
12036 }
12037 break;
12038
a5da3dee
VDM
12039 case DT_GNU_FLAGS_1:
12040 if (do_dynamic)
12041 {
12042 printf (_("Flags:"));
12043 if (entry->d_un.d_val == 0)
12044 printf (_(" None\n"));
12045 else
12046 {
26c527e6 12047 uint64_t val = entry->d_un.d_val;
a5da3dee
VDM
12048
12049 if (val & DF_GNU_1_UNIQUE)
12050 {
12051 printf (" UNIQUE");
12052 val ^= DF_GNU_1_UNIQUE;
12053 }
12054 if (val != 0)
26c527e6 12055 printf (" %" PRIx64, val);
a5da3dee
VDM
12056 puts ("");
12057 }
12058 }
12059 break;
12060
252b5132
RH
12061 default:
12062 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
12063 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12064 = entry->d_un.d_val;
252b5132
RH
12065
12066 if (do_dynamic)
12067 {
dda8d76d 12068 switch (filedata->file_header.e_machine)
252b5132 12069 {
37c18eed
SD
12070 case EM_AARCH64:
12071 dynamic_section_aarch64_val (entry);
12072 break;
252b5132 12073 case EM_MIPS:
4fe85591 12074 case EM_MIPS_RS3_LE:
978c4450 12075 dynamic_section_mips_val (filedata, entry);
252b5132 12076 break;
103f02d3 12077 case EM_PARISC:
b2d38a17 12078 dynamic_section_parisc_val (entry);
103f02d3 12079 break;
ecc51f48 12080 case EM_IA_64:
b2d38a17 12081 dynamic_section_ia64_val (entry);
ecc51f48 12082 break;
252b5132 12083 default:
f7a99963
NC
12084 print_vma (entry->d_un.d_val, PREFIX_HEX);
12085 putchar ('\n');
252b5132
RH
12086 }
12087 }
12088 break;
12089 }
12090 }
12091
015dc7e1 12092 return true;
252b5132
RH
12093}
12094
12095static char *
d3ba0551 12096get_ver_flags (unsigned int flags)
252b5132 12097{
6d4f21f6 12098 static char buff[128];
252b5132
RH
12099
12100 buff[0] = 0;
12101
12102 if (flags == 0)
12103 return _("none");
12104
12105 if (flags & VER_FLG_BASE)
7bb1ad17 12106 strcat (buff, "BASE");
252b5132
RH
12107
12108 if (flags & VER_FLG_WEAK)
12109 {
12110 if (flags & VER_FLG_BASE)
7bb1ad17 12111 strcat (buff, " | ");
252b5132 12112
7bb1ad17 12113 strcat (buff, "WEAK");
252b5132
RH
12114 }
12115
44ec90b9
RO
12116 if (flags & VER_FLG_INFO)
12117 {
12118 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12119 strcat (buff, " | ");
44ec90b9 12120
7bb1ad17 12121 strcat (buff, "INFO");
44ec90b9
RO
12122 }
12123
12124 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12125 {
12126 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12127 strcat (buff, " | ");
12128
12129 strcat (buff, _("<unknown>"));
12130 }
252b5132
RH
12131
12132 return buff;
12133}
12134
12135/* Display the contents of the version sections. */
98fb390a 12136
015dc7e1 12137static bool
dda8d76d 12138process_version_sections (Filedata * filedata)
252b5132 12139{
2cf0635d 12140 Elf_Internal_Shdr * section;
b34976b6 12141 unsigned i;
015dc7e1 12142 bool found = false;
252b5132
RH
12143
12144 if (! do_version)
015dc7e1 12145 return true;
252b5132 12146
dda8d76d
NC
12147 for (i = 0, section = filedata->section_headers;
12148 i < filedata->file_header.e_shnum;
b34976b6 12149 i++, section++)
252b5132
RH
12150 {
12151 switch (section->sh_type)
12152 {
12153 case SHT_GNU_verdef:
12154 {
2cf0635d 12155 Elf_External_Verdef * edefs;
26c527e6
AM
12156 size_t idx;
12157 size_t cnt;
2cf0635d 12158 char * endbuf;
252b5132 12159
015dc7e1 12160 found = true;
252b5132 12161
ca0e11aa
NC
12162 if (filedata->is_separate)
12163 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12164 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12165 section->sh_info),
12166 filedata->file_name,
12167 printable_section_name (filedata, section),
12168 section->sh_info);
12169 else
12170 printf (ngettext ("\nVersion definition section '%s' "
12171 "contains %u entry:\n",
12172 "\nVersion definition section '%s' "
12173 "contains %u entries:\n",
12174 section->sh_info),
12175 printable_section_name (filedata, section),
12176 section->sh_info);
047c3dbf 12177
625d49fc 12178 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12179 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12180 section->sh_offset, section->sh_link,
dda8d76d 12181 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12182
3f5e193b 12183 edefs = (Elf_External_Verdef *)
dda8d76d 12184 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12185 _("version definition section"));
a6e9f9df
AM
12186 if (!edefs)
12187 break;
59245841 12188 endbuf = (char *) edefs + section->sh_size;
252b5132 12189
1445030f 12190 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12191 {
2cf0635d
NC
12192 char * vstart;
12193 Elf_External_Verdef * edef;
b34976b6 12194 Elf_Internal_Verdef ent;
2cf0635d 12195 Elf_External_Verdaux * eaux;
b34976b6 12196 Elf_Internal_Verdaux aux;
26c527e6 12197 size_t isum;
b34976b6 12198 int j;
103f02d3 12199
252b5132 12200 vstart = ((char *) edefs) + idx;
54806181
AM
12201 if (vstart + sizeof (*edef) > endbuf)
12202 break;
252b5132
RH
12203
12204 edef = (Elf_External_Verdef *) vstart;
12205
12206 ent.vd_version = BYTE_GET (edef->vd_version);
12207 ent.vd_flags = BYTE_GET (edef->vd_flags);
12208 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12209 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12210 ent.vd_hash = BYTE_GET (edef->vd_hash);
12211 ent.vd_aux = BYTE_GET (edef->vd_aux);
12212 ent.vd_next = BYTE_GET (edef->vd_next);
12213
26c527e6 12214 printf (_(" %#06zx: Rev: %d Flags: %s"),
252b5132
RH
12215 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12216
12217 printf (_(" Index: %d Cnt: %d "),
12218 ent.vd_ndx, ent.vd_cnt);
12219
452bf675 12220 /* Check for overflow. */
1445030f 12221 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12222 break;
12223
252b5132
RH
12224 vstart += ent.vd_aux;
12225
1445030f
AM
12226 if (vstart + sizeof (*eaux) > endbuf)
12227 break;
252b5132
RH
12228 eaux = (Elf_External_Verdaux *) vstart;
12229
12230 aux.vda_name = BYTE_GET (eaux->vda_name);
12231 aux.vda_next = BYTE_GET (eaux->vda_next);
12232
84714f86 12233 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12234 printf (_("Name: %s\n"),
84714f86 12235 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12236 else
12237 printf (_("Name index: %ld\n"), aux.vda_name);
12238
12239 isum = idx + ent.vd_aux;
12240
b34976b6 12241 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12242 {
1445030f
AM
12243 if (aux.vda_next < sizeof (*eaux)
12244 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12245 {
12246 warn (_("Invalid vda_next field of %lx\n"),
12247 aux.vda_next);
12248 j = ent.vd_cnt;
12249 break;
12250 }
dd24e3da 12251 /* Check for overflow. */
7e26601c 12252 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12253 break;
12254
252b5132
RH
12255 isum += aux.vda_next;
12256 vstart += aux.vda_next;
12257
54806181
AM
12258 if (vstart + sizeof (*eaux) > endbuf)
12259 break;
1445030f 12260 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12261
12262 aux.vda_name = BYTE_GET (eaux->vda_name);
12263 aux.vda_next = BYTE_GET (eaux->vda_next);
12264
84714f86 12265 if (valid_dynamic_name (filedata, aux.vda_name))
26c527e6 12266 printf (_(" %#06zx: Parent %d: %s\n"),
978c4450 12267 isum, j,
84714f86 12268 get_dynamic_name (filedata, aux.vda_name));
252b5132 12269 else
26c527e6 12270 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
252b5132
RH
12271 isum, j, aux.vda_name);
12272 }
dd24e3da 12273
54806181
AM
12274 if (j < ent.vd_cnt)
12275 printf (_(" Version def aux past end of section\n"));
252b5132 12276
c9f02c3e
MR
12277 /* PR 17531:
12278 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12279 if (ent.vd_next < sizeof (*edef)
12280 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12281 {
12282 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12283 cnt = section->sh_info;
12284 break;
12285 }
452bf675 12286 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12287 break;
12288
252b5132
RH
12289 idx += ent.vd_next;
12290 }
dd24e3da 12291
54806181
AM
12292 if (cnt < section->sh_info)
12293 printf (_(" Version definition past end of section\n"));
252b5132
RH
12294
12295 free (edefs);
12296 }
12297 break;
103f02d3 12298
252b5132
RH
12299 case SHT_GNU_verneed:
12300 {
2cf0635d 12301 Elf_External_Verneed * eneed;
26c527e6
AM
12302 size_t idx;
12303 size_t cnt;
2cf0635d 12304 char * endbuf;
252b5132 12305
015dc7e1 12306 found = true;
252b5132 12307
ca0e11aa
NC
12308 if (filedata->is_separate)
12309 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12310 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12311 section->sh_info),
12312 filedata->file_name,
12313 printable_section_name (filedata, section),
12314 section->sh_info);
12315 else
12316 printf (ngettext ("\nVersion needs section '%s' "
12317 "contains %u entry:\n",
12318 "\nVersion needs section '%s' "
12319 "contains %u entries:\n",
12320 section->sh_info),
12321 printable_section_name (filedata, section),
12322 section->sh_info);
047c3dbf 12323
625d49fc 12324 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12325 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12326 section->sh_offset, section->sh_link,
dda8d76d 12327 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12328
dda8d76d 12329 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12330 section->sh_offset, 1,
12331 section->sh_size,
9cf03b7e 12332 _("Version Needs section"));
a6e9f9df
AM
12333 if (!eneed)
12334 break;
59245841 12335 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12336
12337 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12338 {
2cf0635d 12339 Elf_External_Verneed * entry;
b34976b6 12340 Elf_Internal_Verneed ent;
26c527e6 12341 size_t isum;
b34976b6 12342 int j;
2cf0635d 12343 char * vstart;
252b5132
RH
12344
12345 vstart = ((char *) eneed) + idx;
54806181
AM
12346 if (vstart + sizeof (*entry) > endbuf)
12347 break;
252b5132
RH
12348
12349 entry = (Elf_External_Verneed *) vstart;
12350
12351 ent.vn_version = BYTE_GET (entry->vn_version);
12352 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12353 ent.vn_file = BYTE_GET (entry->vn_file);
12354 ent.vn_aux = BYTE_GET (entry->vn_aux);
12355 ent.vn_next = BYTE_GET (entry->vn_next);
12356
26c527e6 12357 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
252b5132 12358
84714f86 12359 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12360 printf (_(" File: %s"),
84714f86 12361 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12362 else
12363 printf (_(" File: %lx"), ent.vn_file);
12364
12365 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12366
dd24e3da 12367 /* Check for overflow. */
7e26601c 12368 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12369 break;
252b5132
RH
12370 vstart += ent.vn_aux;
12371
12372 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12373 {
2cf0635d 12374 Elf_External_Vernaux * eaux;
b34976b6 12375 Elf_Internal_Vernaux aux;
252b5132 12376
54806181
AM
12377 if (vstart + sizeof (*eaux) > endbuf)
12378 break;
252b5132
RH
12379 eaux = (Elf_External_Vernaux *) vstart;
12380
12381 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12382 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12383 aux.vna_other = BYTE_GET (eaux->vna_other);
12384 aux.vna_name = BYTE_GET (eaux->vna_name);
12385 aux.vna_next = BYTE_GET (eaux->vna_next);
12386
84714f86 12387 if (valid_dynamic_name (filedata, aux.vna_name))
26c527e6 12388 printf (_(" %#06zx: Name: %s"),
84714f86 12389 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12390 else
26c527e6 12391 printf (_(" %#06zx: Name index: %lx"),
252b5132
RH
12392 isum, aux.vna_name);
12393
12394 printf (_(" Flags: %s Version: %d\n"),
12395 get_ver_flags (aux.vna_flags), aux.vna_other);
12396
1445030f
AM
12397 if (aux.vna_next < sizeof (*eaux)
12398 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12399 {
12400 warn (_("Invalid vna_next field of %lx\n"),
12401 aux.vna_next);
12402 j = ent.vn_cnt;
12403 break;
12404 }
1445030f
AM
12405 /* Check for overflow. */
12406 if (aux.vna_next > (size_t) (endbuf - vstart))
12407 break;
252b5132
RH
12408 isum += aux.vna_next;
12409 vstart += aux.vna_next;
12410 }
9cf03b7e 12411
54806181 12412 if (j < ent.vn_cnt)
f9a6a8f0 12413 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12414
1445030f
AM
12415 if (ent.vn_next < sizeof (*entry)
12416 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12417 {
452bf675 12418 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12419 cnt = section->sh_info;
12420 break;
12421 }
1445030f
AM
12422 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12423 break;
252b5132
RH
12424 idx += ent.vn_next;
12425 }
9cf03b7e 12426
54806181 12427 if (cnt < section->sh_info)
9cf03b7e 12428 warn (_("Missing Version Needs information\n"));
103f02d3 12429
252b5132
RH
12430 free (eneed);
12431 }
12432 break;
12433
12434 case SHT_GNU_versym:
12435 {
2cf0635d 12436 Elf_Internal_Shdr * link_section;
26c527e6 12437 uint64_t total;
8b73c356 12438 unsigned int cnt;
2cf0635d
NC
12439 unsigned char * edata;
12440 unsigned short * data;
12441 char * strtab;
12442 Elf_Internal_Sym * symbols;
12443 Elf_Internal_Shdr * string_sec;
26c527e6
AM
12444 uint64_t num_syms;
12445 uint64_t off;
252b5132 12446
dda8d76d 12447 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12448 break;
12449
dda8d76d 12450 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12451 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12452
dda8d76d 12453 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12454 break;
12455
015dc7e1 12456 found = true;
252b5132 12457
4de91c10 12458 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12459 if (symbols == NULL)
12460 break;
252b5132 12461
dda8d76d 12462 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12463
dda8d76d 12464 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12465 string_sec->sh_size,
12466 _("version string table"));
a6e9f9df 12467 if (!strtab)
0429c154
MS
12468 {
12469 free (symbols);
12470 break;
12471 }
252b5132 12472
ca0e11aa 12473 if (filedata->is_separate)
26c527e6
AM
12474 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
12475 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12476 total),
12477 filedata->file_name,
12478 printable_section_name (filedata, section),
26c527e6 12479 total);
ca0e11aa
NC
12480 else
12481 printf (ngettext ("\nVersion symbols section '%s' "
26c527e6 12482 "contains %" PRIu64 " entry:\n",
ca0e11aa 12483 "\nVersion symbols section '%s' "
26c527e6 12484 "contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12485 total),
12486 printable_section_name (filedata, section),
26c527e6 12487 total);
252b5132 12488
625d49fc 12489 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12490 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12491 section->sh_offset, section->sh_link,
dda8d76d 12492 printable_section_name (filedata, link_section));
252b5132 12493
dda8d76d 12494 off = offset_from_vma (filedata,
978c4450 12495 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12496 total * sizeof (short));
95099889
AM
12497 edata = (unsigned char *) get_data (NULL, filedata, off,
12498 sizeof (short), total,
12499 _("version symbol data"));
a6e9f9df
AM
12500 if (!edata)
12501 {
12502 free (strtab);
0429c154 12503 free (symbols);
a6e9f9df
AM
12504 break;
12505 }
252b5132 12506
3f5e193b 12507 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12508
12509 for (cnt = total; cnt --;)
b34976b6
AM
12510 data[cnt] = byte_get (edata + cnt * sizeof (short),
12511 sizeof (short));
252b5132
RH
12512
12513 free (edata);
12514
12515 for (cnt = 0; cnt < total; cnt += 4)
12516 {
12517 int j, nn;
ab273396
AM
12518 char *name;
12519 char *invalid = _("*invalid*");
252b5132
RH
12520
12521 printf (" %03x:", cnt);
12522
12523 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12524 switch (data[cnt + j])
252b5132
RH
12525 {
12526 case 0:
12527 fputs (_(" 0 (*local*) "), stdout);
12528 break;
12529
12530 case 1:
12531 fputs (_(" 1 (*global*) "), stdout);
12532 break;
12533
12534 default:
c244d050
NC
12535 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12536 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12537
dd24e3da 12538 /* If this index value is greater than the size of the symbols
ba5cdace 12539 array, break to avoid an out-of-bounds read. */
26c527e6 12540 if (cnt + j >= num_syms)
dd24e3da
NC
12541 {
12542 warn (_("invalid index into symbol array\n"));
12543 break;
12544 }
12545
ab273396 12546 name = NULL;
978c4450 12547 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12548 {
b34976b6 12549 Elf_Internal_Verneed ivn;
26c527e6 12550 uint64_t offset;
252b5132 12551
d93f0186 12552 offset = offset_from_vma
978c4450
AM
12553 (filedata,
12554 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12555 sizeof (Elf_External_Verneed));
252b5132 12556
b34976b6 12557 do
252b5132 12558 {
b34976b6
AM
12559 Elf_Internal_Vernaux ivna;
12560 Elf_External_Verneed evn;
12561 Elf_External_Vernaux evna;
26c527e6 12562 uint64_t a_off;
252b5132 12563
dda8d76d 12564 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12565 _("version need")) == NULL)
12566 break;
0b4362b0 12567
252b5132
RH
12568 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12569 ivn.vn_next = BYTE_GET (evn.vn_next);
12570
12571 a_off = offset + ivn.vn_aux;
12572
12573 do
12574 {
dda8d76d 12575 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12576 1, _("version need aux (2)")) == NULL)
12577 {
12578 ivna.vna_next = 0;
12579 ivna.vna_other = 0;
12580 }
12581 else
12582 {
12583 ivna.vna_next = BYTE_GET (evna.vna_next);
12584 ivna.vna_other = BYTE_GET (evna.vna_other);
12585 }
252b5132
RH
12586
12587 a_off += ivna.vna_next;
12588 }
b34976b6 12589 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12590 && ivna.vna_next != 0);
12591
b34976b6 12592 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12593 {
12594 ivna.vna_name = BYTE_GET (evna.vna_name);
12595
54806181 12596 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12597 name = invalid;
54806181
AM
12598 else
12599 name = strtab + ivna.vna_name;
252b5132
RH
12600 break;
12601 }
12602
12603 offset += ivn.vn_next;
12604 }
12605 while (ivn.vn_next);
12606 }
00d93f34 12607
ab273396 12608 if (data[cnt + j] != 0x8001
978c4450 12609 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12610 {
b34976b6
AM
12611 Elf_Internal_Verdef ivd;
12612 Elf_External_Verdef evd;
26c527e6 12613 uint64_t offset;
252b5132 12614
d93f0186 12615 offset = offset_from_vma
978c4450
AM
12616 (filedata,
12617 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12618 sizeof evd);
252b5132
RH
12619
12620 do
12621 {
dda8d76d 12622 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12623 _("version def")) == NULL)
12624 {
12625 ivd.vd_next = 0;
948f632f 12626 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12627 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12628 break;
59245841
NC
12629 }
12630 else
12631 {
12632 ivd.vd_next = BYTE_GET (evd.vd_next);
12633 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12634 }
252b5132
RH
12635
12636 offset += ivd.vd_next;
12637 }
c244d050 12638 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12639 && ivd.vd_next != 0);
12640
c244d050 12641 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12642 {
b34976b6
AM
12643 Elf_External_Verdaux evda;
12644 Elf_Internal_Verdaux ivda;
252b5132
RH
12645
12646 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12647
dda8d76d 12648 if (get_data (&evda, filedata,
59245841
NC
12649 offset - ivd.vd_next + ivd.vd_aux,
12650 sizeof (evda), 1,
12651 _("version def aux")) == NULL)
12652 break;
252b5132
RH
12653
12654 ivda.vda_name = BYTE_GET (evda.vda_name);
12655
54806181 12656 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12657 name = invalid;
12658 else if (name != NULL && name != invalid)
12659 name = _("*both*");
54806181
AM
12660 else
12661 name = strtab + ivda.vda_name;
252b5132
RH
12662 }
12663 }
ab273396
AM
12664 if (name != NULL)
12665 nn += printf ("(%s%-*s",
12666 name,
12667 12 - (int) strlen (name),
12668 ")");
252b5132
RH
12669
12670 if (nn < 18)
12671 printf ("%*c", 18 - nn, ' ');
12672 }
12673
12674 putchar ('\n');
12675 }
12676
12677 free (data);
12678 free (strtab);
12679 free (symbols);
12680 }
12681 break;
103f02d3 12682
252b5132
RH
12683 default:
12684 break;
12685 }
12686 }
12687
12688 if (! found)
ca0e11aa
NC
12689 {
12690 if (filedata->is_separate)
12691 printf (_("\nNo version information found in linked file '%s'.\n"),
12692 filedata->file_name);
12693 else
12694 printf (_("\nNo version information found in this file.\n"));
12695 }
252b5132 12696
015dc7e1 12697 return true;
252b5132
RH
12698}
12699
d1133906 12700static const char *
dda8d76d 12701get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12702{
89246a0e 12703 static char buff[64];
252b5132
RH
12704
12705 switch (binding)
12706 {
b34976b6
AM
12707 case STB_LOCAL: return "LOCAL";
12708 case STB_GLOBAL: return "GLOBAL";
12709 case STB_WEAK: return "WEAK";
252b5132
RH
12710 default:
12711 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12712 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12713 binding);
252b5132 12714 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12715 {
12716 if (binding == STB_GNU_UNIQUE
df3a023b 12717 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12718 return "UNIQUE";
12719 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12720 }
252b5132 12721 else
e9e44622 12722 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12723 return buff;
12724 }
12725}
12726
d1133906 12727static const char *
dda8d76d 12728get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12729{
89246a0e 12730 static char buff[64];
252b5132
RH
12731
12732 switch (type)
12733 {
b34976b6
AM
12734 case STT_NOTYPE: return "NOTYPE";
12735 case STT_OBJECT: return "OBJECT";
12736 case STT_FUNC: return "FUNC";
12737 case STT_SECTION: return "SECTION";
12738 case STT_FILE: return "FILE";
12739 case STT_COMMON: return "COMMON";
12740 case STT_TLS: return "TLS";
15ab5209
DB
12741 case STT_RELC: return "RELC";
12742 case STT_SRELC: return "SRELC";
252b5132
RH
12743 default:
12744 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12745 {
dda8d76d 12746 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12747 return "THUMB_FUNC";
103f02d3 12748
dda8d76d 12749 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12750 return "REGISTER";
12751
dda8d76d 12752 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12753 return "PARISC_MILLI";
12754
e9e44622 12755 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12756 }
252b5132 12757 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12758 {
dda8d76d 12759 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12760 {
12761 if (type == STT_HP_OPAQUE)
12762 return "HP_OPAQUE";
12763 if (type == STT_HP_STUB)
12764 return "HP_STUB";
12765 }
12766
8654c01f
ML
12767 if (type == STT_GNU_IFUNC
12768 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
12769 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
12770 return "IFUNC";
12771
e9e44622 12772 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12773 }
252b5132 12774 else
e9e44622 12775 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12776 return buff;
12777 }
12778}
12779
d1133906 12780static const char *
d3ba0551 12781get_symbol_visibility (unsigned int visibility)
d1133906
NC
12782{
12783 switch (visibility)
12784 {
b34976b6
AM
12785 case STV_DEFAULT: return "DEFAULT";
12786 case STV_INTERNAL: return "INTERNAL";
12787 case STV_HIDDEN: return "HIDDEN";
d1133906 12788 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12789 default:
27a45f42 12790 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12791 return _("<unknown>");
d1133906
NC
12792 }
12793}
12794
2057d69d
CZ
12795static const char *
12796get_alpha_symbol_other (unsigned int other)
9abca702 12797{
2057d69d
CZ
12798 switch (other)
12799 {
12800 case STO_ALPHA_NOPV: return "NOPV";
12801 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12802 default:
27a45f42 12803 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12804 return _("<unknown>");
9abca702 12805 }
2057d69d
CZ
12806}
12807
fd85a6a1
NC
12808static const char *
12809get_solaris_symbol_visibility (unsigned int visibility)
12810{
12811 switch (visibility)
12812 {
12813 case 4: return "EXPORTED";
12814 case 5: return "SINGLETON";
12815 case 6: return "ELIMINATE";
12816 default: return get_symbol_visibility (visibility);
12817 }
12818}
12819
2301ed1c
SN
12820static const char *
12821get_aarch64_symbol_other (unsigned int other)
12822{
12823 static char buf[32];
12824
12825 if (other & STO_AARCH64_VARIANT_PCS)
12826 {
12827 other &= ~STO_AARCH64_VARIANT_PCS;
12828 if (other == 0)
12829 return "VARIANT_PCS";
12830 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12831 return buf;
12832 }
12833 return NULL;
12834}
12835
5e2b0d47
NC
12836static const char *
12837get_mips_symbol_other (unsigned int other)
12838{
12839 switch (other)
12840 {
32ec8896
NC
12841 case STO_OPTIONAL: return "OPTIONAL";
12842 case STO_MIPS_PLT: return "MIPS PLT";
12843 case STO_MIPS_PIC: return "MIPS PIC";
12844 case STO_MICROMIPS: return "MICROMIPS";
12845 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12846 case STO_MIPS16: return "MIPS16";
12847 default: return NULL;
5e2b0d47
NC
12848 }
12849}
12850
28f997cf 12851static const char *
dda8d76d 12852get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12853{
dda8d76d 12854 if (is_ia64_vms (filedata))
28f997cf
TG
12855 {
12856 static char res[32];
12857
12858 res[0] = 0;
12859
12860 /* Function types is for images and .STB files only. */
dda8d76d 12861 switch (filedata->file_header.e_type)
28f997cf
TG
12862 {
12863 case ET_DYN:
12864 case ET_EXEC:
12865 switch (VMS_ST_FUNC_TYPE (other))
12866 {
12867 case VMS_SFT_CODE_ADDR:
12868 strcat (res, " CA");
12869 break;
12870 case VMS_SFT_SYMV_IDX:
12871 strcat (res, " VEC");
12872 break;
12873 case VMS_SFT_FD:
12874 strcat (res, " FD");
12875 break;
12876 case VMS_SFT_RESERVE:
12877 strcat (res, " RSV");
12878 break;
12879 default:
bee0ee85
NC
12880 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12881 VMS_ST_FUNC_TYPE (other));
12882 strcat (res, " <unknown>");
12883 break;
28f997cf
TG
12884 }
12885 break;
12886 default:
12887 break;
12888 }
12889 switch (VMS_ST_LINKAGE (other))
12890 {
12891 case VMS_STL_IGNORE:
12892 strcat (res, " IGN");
12893 break;
12894 case VMS_STL_RESERVE:
12895 strcat (res, " RSV");
12896 break;
12897 case VMS_STL_STD:
12898 strcat (res, " STD");
12899 break;
12900 case VMS_STL_LNK:
12901 strcat (res, " LNK");
12902 break;
12903 default:
bee0ee85
NC
12904 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12905 VMS_ST_LINKAGE (other));
12906 strcat (res, " <unknown>");
12907 break;
28f997cf
TG
12908 }
12909
12910 if (res[0] != 0)
12911 return res + 1;
12912 else
12913 return res;
12914 }
12915 return NULL;
12916}
12917
6911b7dc
AM
12918static const char *
12919get_ppc64_symbol_other (unsigned int other)
12920{
14732552
AM
12921 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12922 return NULL;
12923
12924 other >>= STO_PPC64_LOCAL_BIT;
12925 if (other <= 6)
6911b7dc 12926 {
89246a0e 12927 static char buf[64];
14732552
AM
12928 if (other >= 2)
12929 other = ppc64_decode_local_entry (other);
12930 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12931 return buf;
12932 }
12933 return NULL;
12934}
12935
8155b853
NC
12936static const char *
12937get_riscv_symbol_other (unsigned int other)
12938{
12939 static char buf[32];
12940 buf[0] = 0;
12941
12942 if (other & STO_RISCV_VARIANT_CC)
12943 {
12944 strcat (buf, _(" VARIANT_CC"));
12945 other &= ~STO_RISCV_VARIANT_CC;
12946 }
12947
12948 if (other != 0)
12949 snprintf (buf, sizeof buf, " %x", other);
12950
12951
12952 if (buf[0] != 0)
12953 return buf + 1;
12954 else
12955 return buf;
12956}
12957
5e2b0d47 12958static const char *
dda8d76d 12959get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12960{
12961 const char * result = NULL;
89246a0e 12962 static char buff [64];
5e2b0d47
NC
12963
12964 if (other == 0)
12965 return "";
12966
dda8d76d 12967 switch (filedata->file_header.e_machine)
5e2b0d47 12968 {
2057d69d
CZ
12969 case EM_ALPHA:
12970 result = get_alpha_symbol_other (other);
12971 break;
2301ed1c
SN
12972 case EM_AARCH64:
12973 result = get_aarch64_symbol_other (other);
12974 break;
5e2b0d47
NC
12975 case EM_MIPS:
12976 result = get_mips_symbol_other (other);
28f997cf
TG
12977 break;
12978 case EM_IA_64:
dda8d76d 12979 result = get_ia64_symbol_other (filedata, other);
28f997cf 12980 break;
6911b7dc
AM
12981 case EM_PPC64:
12982 result = get_ppc64_symbol_other (other);
12983 break;
8155b853
NC
12984 case EM_RISCV:
12985 result = get_riscv_symbol_other (other);
12986 break;
5e2b0d47 12987 default:
fd85a6a1 12988 result = NULL;
5e2b0d47
NC
12989 break;
12990 }
12991
12992 if (result)
12993 return result;
12994
12995 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12996 return buff;
12997}
12998
d1133906 12999static const char *
dda8d76d 13000get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 13001{
b34976b6 13002 static char buff[32];
5cf1065c 13003
252b5132
RH
13004 switch (type)
13005 {
b34976b6
AM
13006 case SHN_UNDEF: return "UND";
13007 case SHN_ABS: return "ABS";
13008 case SHN_COMMON: return "COM";
252b5132 13009 default:
9ce701e2 13010 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
13011 && filedata->file_header.e_machine == EM_IA_64
13012 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
13013 return "ANSI_COM";
13014 else if ((filedata->file_header.e_machine == EM_X86_64
13015 || filedata->file_header.e_machine == EM_L1OM
13016 || filedata->file_header.e_machine == EM_K1OM)
13017 && type == SHN_X86_64_LCOMMON)
13018 return "LARGE_COM";
13019 else if ((type == SHN_MIPS_SCOMMON
13020 && filedata->file_header.e_machine == EM_MIPS)
13021 || (type == SHN_TIC6X_SCOMMON
13022 && filedata->file_header.e_machine == EM_TI_C6000))
13023 return "SCOM";
13024 else if (type == SHN_MIPS_SUNDEFINED
13025 && filedata->file_header.e_machine == EM_MIPS)
13026 return "SUND";
13027 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
13028 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
13029 else if (type >= SHN_LOOS && type <= SHN_HIOS)
13030 sprintf (buff, "OS [0x%04x]", type & 0xffff);
13031 else if (type >= SHN_LORESERVE)
13032 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
13033 else if (filedata->file_header.e_shnum != 0
13034 && type >= filedata->file_header.e_shnum)
13035 sprintf (buff, _("bad section index[%3d]"), type);
13036 else
13037 sprintf (buff, "%3d", type);
13038 break;
fd85a6a1
NC
13039 }
13040
10ca4b04 13041 return buff;
6bd1a22c
L
13042}
13043
bb4d2ac2 13044static const char *
26c527e6
AM
13045get_symbol_version_string (Filedata *filedata,
13046 bool is_dynsym,
13047 const char *strtab,
13048 size_t strtab_size,
13049 unsigned int si,
13050 Elf_Internal_Sym *psym,
13051 enum versioned_symbol_info *sym_info,
13052 unsigned short *vna_other)
bb4d2ac2 13053{
ab273396
AM
13054 unsigned char data[2];
13055 unsigned short vers_data;
26c527e6 13056 uint64_t offset;
7a815dd5 13057 unsigned short max_vd_ndx;
bb4d2ac2 13058
ab273396 13059 if (!is_dynsym
978c4450 13060 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 13061 return NULL;
bb4d2ac2 13062
978c4450
AM
13063 offset = offset_from_vma (filedata,
13064 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 13065 sizeof data + si * sizeof (vers_data));
bb4d2ac2 13066
dda8d76d 13067 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
13068 sizeof (data), 1, _("version data")) == NULL)
13069 return NULL;
13070
13071 vers_data = byte_get (data, 2);
bb4d2ac2 13072
1f6f5dba 13073 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 13074 return NULL;
bb4d2ac2 13075
0b8b7609 13076 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
13077 max_vd_ndx = 0;
13078
ab273396
AM
13079 /* Usually we'd only see verdef for defined symbols, and verneed for
13080 undefined symbols. However, symbols defined by the linker in
13081 .dynbss for variables copied from a shared library in order to
13082 avoid text relocations are defined yet have verneed. We could
13083 use a heuristic to detect the special case, for example, check
13084 for verneed first on symbols defined in SHT_NOBITS sections, but
13085 it is simpler and more reliable to just look for both verdef and
13086 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13087
ab273396
AM
13088 if (psym->st_shndx != SHN_UNDEF
13089 && vers_data != 0x8001
978c4450 13090 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13091 {
13092 Elf_Internal_Verdef ivd;
13093 Elf_Internal_Verdaux ivda;
13094 Elf_External_Verdaux evda;
26c527e6 13095 uint64_t off;
bb4d2ac2 13096
dda8d76d 13097 off = offset_from_vma (filedata,
978c4450 13098 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13099 sizeof (Elf_External_Verdef));
13100
13101 do
bb4d2ac2 13102 {
ab273396
AM
13103 Elf_External_Verdef evd;
13104
dda8d76d 13105 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13106 _("version def")) == NULL)
13107 {
13108 ivd.vd_ndx = 0;
13109 ivd.vd_aux = 0;
13110 ivd.vd_next = 0;
1f6f5dba 13111 ivd.vd_flags = 0;
ab273396
AM
13112 }
13113 else
bb4d2ac2 13114 {
ab273396
AM
13115 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13116 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13117 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13118 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13119 }
bb4d2ac2 13120
7a815dd5
L
13121 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13122 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13123
ab273396
AM
13124 off += ivd.vd_next;
13125 }
13126 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13127
ab273396
AM
13128 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13129 {
9abca702 13130 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13131 return NULL;
13132
ab273396
AM
13133 off -= ivd.vd_next;
13134 off += ivd.vd_aux;
bb4d2ac2 13135
dda8d76d 13136 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13137 _("version def aux")) != NULL)
13138 {
13139 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13140
ab273396 13141 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13142 return (ivda.vda_name < strtab_size
13143 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13144 }
13145 }
13146 }
bb4d2ac2 13147
978c4450 13148 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13149 {
13150 Elf_External_Verneed evn;
13151 Elf_Internal_Verneed ivn;
13152 Elf_Internal_Vernaux ivna;
bb4d2ac2 13153
dda8d76d 13154 offset = offset_from_vma (filedata,
978c4450 13155 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13156 sizeof evn);
13157 do
13158 {
26c527e6 13159 uint64_t vna_off;
bb4d2ac2 13160
dda8d76d 13161 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13162 _("version need")) == NULL)
13163 {
13164 ivna.vna_next = 0;
13165 ivna.vna_other = 0;
13166 ivna.vna_name = 0;
13167 break;
13168 }
bb4d2ac2 13169
ab273396
AM
13170 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13171 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13172
ab273396 13173 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13174
ab273396
AM
13175 do
13176 {
13177 Elf_External_Vernaux evna;
bb4d2ac2 13178
dda8d76d 13179 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13180 _("version need aux (3)")) == NULL)
bb4d2ac2 13181 {
ab273396
AM
13182 ivna.vna_next = 0;
13183 ivna.vna_other = 0;
13184 ivna.vna_name = 0;
bb4d2ac2 13185 }
bb4d2ac2 13186 else
bb4d2ac2 13187 {
ab273396
AM
13188 ivna.vna_other = BYTE_GET (evna.vna_other);
13189 ivna.vna_next = BYTE_GET (evna.vna_next);
13190 ivna.vna_name = BYTE_GET (evna.vna_name);
13191 }
bb4d2ac2 13192
ab273396
AM
13193 vna_off += ivna.vna_next;
13194 }
13195 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13196
ab273396
AM
13197 if (ivna.vna_other == vers_data)
13198 break;
bb4d2ac2 13199
ab273396
AM
13200 offset += ivn.vn_next;
13201 }
13202 while (ivn.vn_next != 0);
bb4d2ac2 13203
ab273396
AM
13204 if (ivna.vna_other == vers_data)
13205 {
13206 *sym_info = symbol_undefined;
13207 *vna_other = ivna.vna_other;
13208 return (ivna.vna_name < strtab_size
13209 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13210 }
7a815dd5
L
13211 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13212 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13213 return _("<corrupt>");
bb4d2ac2 13214 }
ab273396 13215 return NULL;
bb4d2ac2
L
13216}
13217
047c3dbf
NL
13218/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13219
13220static unsigned int
625d49fc 13221print_dynamic_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13222{
13223 switch (base)
13224 {
13225 case 8:
13226 return print_vma (vma, OCTAL_5);
13227
13228 case 10:
13229 return print_vma (vma, UNSIGNED_5);
13230
13231 case 16:
13232 return print_vma (vma, PREFIX_HEX_5);
13233
13234 case 0:
13235 default:
13236 return print_vma (vma, DEC_5);
13237 }
13238}
13239
10ca4b04 13240static void
26c527e6 13241print_dynamic_symbol (Filedata *filedata, uint64_t si,
10ca4b04
L
13242 Elf_Internal_Sym *symtab,
13243 Elf_Internal_Shdr *section,
13244 char *strtab, size_t strtab_size)
252b5132 13245{
10ca4b04
L
13246 const char *version_string;
13247 enum versioned_symbol_info sym_info;
13248 unsigned short vna_other;
23356397
NC
13249 bool is_valid;
13250 const char * sstr;
10ca4b04 13251 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13252
26c527e6 13253 printf ("%6" PRId64 ": ", si);
10ca4b04
L
13254 print_vma (psym->st_value, LONG_HEX);
13255 putchar (' ');
047c3dbf 13256 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13257 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13258 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13259 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13260 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13261 else
252b5132 13262 {
10ca4b04 13263 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13264
10ca4b04
L
13265 printf (" %-7s", get_symbol_visibility (vis));
13266 /* Check to see if any other bits in the st_other field are set.
13267 Note - displaying this information disrupts the layout of the
13268 table being generated, but for the moment this case is very rare. */
13269 if (psym->st_other ^ vis)
13270 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13271 }
10ca4b04 13272 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13273
23356397
NC
13274 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13275 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13276 && filedata->section_headers != NULL
23356397
NC
13277 && psym->st_name == 0)
13278 {
84714f86
AM
13279 is_valid
13280 = section_name_valid (filedata,
13281 filedata->section_headers + psym->st_shndx);
23356397 13282 sstr = is_valid ?
84714f86
AM
13283 section_name_print (filedata,
13284 filedata->section_headers + psym->st_shndx)
23356397
NC
13285 : _("<corrupt>");
13286 }
13287 else
13288 {
84714f86 13289 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13290 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13291 }
10ca4b04
L
13292
13293 version_string
13294 = get_symbol_version_string (filedata,
13295 (section == NULL
13296 || section->sh_type == SHT_DYNSYM),
13297 strtab, strtab_size, si,
13298 psym, &sym_info, &vna_other);
b9e920ec 13299
0942c7ab
NC
13300 int len_avail = 21;
13301 if (! do_wide && version_string != NULL)
13302 {
ddb43bab 13303 char buffer[16];
0942c7ab 13304
ddb43bab 13305 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13306
13307 if (sym_info == symbol_undefined)
13308 len_avail -= sprintf (buffer," (%d)", vna_other);
13309 else if (sym_info != symbol_hidden)
13310 len_avail -= 1;
13311 }
13312
13313 print_symbol (len_avail, sstr);
b9e920ec 13314
10ca4b04
L
13315 if (version_string)
13316 {
13317 if (sym_info == symbol_undefined)
13318 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13319 else
10ca4b04
L
13320 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13321 version_string);
13322 }
6bd1a22c 13323
10ca4b04 13324 putchar ('\n');
6bd1a22c 13325
10ca4b04
L
13326 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13327 && section != NULL
13328 && si >= section->sh_info
13329 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13330 && filedata->file_header.e_machine != EM_MIPS
13331 /* Solaris binaries have been found to violate this requirement as
13332 well. Not sure if this is a bug or an ABI requirement. */
13333 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
26c527e6 13334 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
10ca4b04
L
13335 si, printable_section_name (filedata, section), section->sh_info);
13336}
f16a9783 13337
0f03783c
NC
13338static const char *
13339get_lto_kind (unsigned int kind)
13340{
13341 switch (kind)
13342 {
13343 case 0: return "DEF";
13344 case 1: return "WEAKDEF";
13345 case 2: return "UNDEF";
13346 case 3: return "WEAKUNDEF";
13347 case 4: return "COMMON";
13348 default:
13349 break;
13350 }
13351
13352 static char buffer[30];
13353 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13354 sprintf (buffer, "<unknown: %u>", kind);
13355 return buffer;
13356}
13357
13358static const char *
13359get_lto_visibility (unsigned int visibility)
13360{
13361 switch (visibility)
13362 {
13363 case 0: return "DEFAULT";
13364 case 1: return "PROTECTED";
13365 case 2: return "INTERNAL";
13366 case 3: return "HIDDEN";
13367 default:
13368 break;
13369 }
13370
13371 static char buffer[30];
13372 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13373 sprintf (buffer, "<unknown: %u>", visibility);
13374 return buffer;
13375}
13376
13377static const char *
13378get_lto_sym_type (unsigned int sym_type)
13379{
13380 switch (sym_type)
13381 {
13382 case 0: return "UNKNOWN";
13383 case 1: return "FUNCTION";
13384 case 2: return "VARIABLE";
13385 default:
13386 break;
13387 }
13388
13389 static char buffer[30];
13390 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13391 sprintf (buffer, "<unknown: %u>", sym_type);
13392 return buffer;
13393}
13394
13395/* Display an LTO format symbol table.
13396 FIXME: The format of LTO symbol tables is not formalized.
13397 So this code could need changing in the future. */
13398
015dc7e1 13399static bool
0f03783c
NC
13400display_lto_symtab (Filedata * filedata,
13401 Elf_Internal_Shdr * section)
13402{
13403 if (section->sh_size == 0)
13404 {
ca0e11aa
NC
13405 if (filedata->is_separate)
13406 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13407 printable_section_name (filedata, section),
13408 filedata->file_name);
13409 else
13410 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13411 printable_section_name (filedata, section));
047c3dbf 13412
015dc7e1 13413 return true;
0f03783c
NC
13414 }
13415
13416 if (section->sh_size > filedata->file_size)
13417 {
26c527e6 13418 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
0f03783c 13419 printable_section_name (filedata, section),
26c527e6 13420 section->sh_size);
015dc7e1 13421 return false;
0f03783c
NC
13422 }
13423
13424 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13425 section->sh_size, 1, _("LTO symbols"));
13426 if (alloced_data == NULL)
015dc7e1 13427 return false;
0f03783c
NC
13428
13429 /* Look for extended data for the symbol table. */
13430 Elf_Internal_Shdr * ext;
13431 void * ext_data_orig = NULL;
13432 char * ext_data = NULL;
13433 char * ext_data_end = NULL;
13434 char * ext_name = NULL;
13435
13436 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13437 (section_name (filedata, section)
13438 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13439 && ext_name != NULL /* Paranoia. */
13440 && (ext = find_section (filedata, ext_name)) != NULL)
13441 {
13442 if (ext->sh_size < 3)
13443 error (_("LTO Symbol extension table '%s' is empty!\n"),
13444 printable_section_name (filedata, ext));
13445 else
13446 {
13447 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13448 ext->sh_size, 1,
13449 _("LTO ext symbol data"));
13450 if (ext_data != NULL)
13451 {
13452 ext_data_end = ext_data + ext->sh_size;
13453 if (* ext_data++ != 1)
13454 error (_("Unexpected version number in symbol extension table\n"));
13455 }
13456 }
13457 }
b9e920ec 13458
0f03783c
NC
13459 const unsigned char * data = (const unsigned char *) alloced_data;
13460 const unsigned char * end = data + section->sh_size;
13461
ca0e11aa
NC
13462 if (filedata->is_separate)
13463 printf (_("\nIn linked file '%s': "), filedata->file_name);
13464 else
13465 printf ("\n");
13466
0f03783c
NC
13467 if (ext_data_orig != NULL)
13468 {
13469 if (do_wide)
ca0e11aa 13470 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13471 printable_section_name (filedata, section),
13472 printable_section_name (filedata, ext));
13473 else
13474 {
ca0e11aa 13475 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13476 printable_section_name (filedata, section));
13477 printf (_(" and extension table '%s' contain:\n"),
13478 printable_section_name (filedata, ext));
13479 }
13480 }
13481 else
ca0e11aa 13482 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13483 printable_section_name (filedata, section));
b9e920ec 13484
0f03783c 13485 /* FIXME: Add a wide version. */
b9e920ec 13486 if (ext_data_orig != NULL)
0f03783c
NC
13487 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13488 else
13489 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13490
13491 /* FIXME: We do not handle style prefixes. */
13492
13493 while (data < end)
13494 {
13495 const unsigned char * sym_name = data;
13496 data += strnlen ((const char *) sym_name, end - data) + 1;
13497 if (data >= end)
13498 goto fail;
13499
13500 const unsigned char * comdat_key = data;
13501 data += strnlen ((const char *) comdat_key, end - data) + 1;
13502 if (data >= end)
13503 goto fail;
13504
13505 if (data + 2 + 8 + 4 > end)
13506 goto fail;
13507
13508 unsigned int kind = *data++;
13509 unsigned int visibility = *data++;
13510
928c411d 13511 uint64_t size = byte_get (data, 8);
0f03783c
NC
13512 data += 8;
13513
928c411d 13514 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13515 data += 4;
13516
13517 if (ext_data != NULL)
13518 {
13519 if (ext_data < (ext_data_end - 1))
13520 {
13521 unsigned int sym_type = * ext_data ++;
13522 unsigned int sec_kind = * ext_data ++;
13523
31e5a3a3 13524 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
13525 * comdat_key == 0 ? "-" : (char *) comdat_key,
13526 get_lto_kind (kind),
13527 get_lto_visibility (visibility),
31e5a3a3
AM
13528 size,
13529 slot,
0f03783c 13530 get_lto_sym_type (sym_type),
31e5a3a3 13531 sec_kind);
0f03783c
NC
13532 print_symbol (6, (const char *) sym_name);
13533 }
13534 else
13535 {
13536 error (_("Ran out of LTO symbol extension data\n"));
13537 ext_data = NULL;
13538 /* FIXME: return FAIL result ? */
13539 }
13540 }
13541 else
13542 {
31e5a3a3 13543 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
13544 * comdat_key == 0 ? "-" : (char *) comdat_key,
13545 get_lto_kind (kind),
13546 get_lto_visibility (visibility),
31e5a3a3
AM
13547 size,
13548 slot);
0f03783c
NC
13549 print_symbol (21, (const char *) sym_name);
13550 }
13551 putchar ('\n');
13552 }
13553
13554 if (ext_data != NULL && ext_data < ext_data_end)
13555 {
13556 error (_("Data remains in the LTO symbol extension table\n"));
13557 goto fail;
13558 }
13559
13560 free (alloced_data);
13561 free (ext_data_orig);
13562 free (ext_name);
015dc7e1 13563 return true;
b9e920ec 13564
0f03783c
NC
13565 fail:
13566 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13567 free (alloced_data);
13568 free (ext_data_orig);
13569 free (ext_name);
015dc7e1 13570 return false;
0f03783c
NC
13571}
13572
13573/* Display LTO symbol tables. */
13574
015dc7e1 13575static bool
0f03783c
NC
13576process_lto_symbol_tables (Filedata * filedata)
13577{
13578 Elf_Internal_Shdr * section;
13579 unsigned int i;
015dc7e1 13580 bool res = true;
0f03783c
NC
13581
13582 if (!do_lto_syms)
015dc7e1 13583 return true;
0f03783c
NC
13584
13585 if (filedata->section_headers == NULL)
015dc7e1 13586 return true;
0f03783c
NC
13587
13588 for (i = 0, section = filedata->section_headers;
13589 i < filedata->file_header.e_shnum;
13590 i++, section++)
84714f86
AM
13591 if (section_name_valid (filedata, section)
13592 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13593 res &= display_lto_symtab (filedata, section);
13594
b9e920ec 13595 return res;
0f03783c
NC
13596}
13597
10ca4b04 13598/* Dump the symbol table. */
0f03783c 13599
015dc7e1 13600static bool
10ca4b04
L
13601process_symbol_table (Filedata * filedata)
13602{
13603 Elf_Internal_Shdr * section;
f16a9783 13604
10ca4b04 13605 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13606 return true;
6bd1a22c 13607
978c4450 13608 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13609 && do_syms
13610 && do_using_dynamic
978c4450
AM
13611 && filedata->dynamic_strings != NULL
13612 && filedata->dynamic_symbols != NULL)
6bd1a22c 13613 {
26c527e6 13614 uint64_t si;
6bd1a22c 13615
ca0e11aa
NC
13616 if (filedata->is_separate)
13617 {
26c527e6
AM
13618 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
13619 " contains %" PRIu64 " entry:\n",
13620 "\nIn linked file '%s' the dynamic symbol table"
13621 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13622 filedata->num_dynamic_syms),
13623 filedata->file_name,
13624 filedata->num_dynamic_syms);
13625 }
13626 else
13627 {
26c527e6
AM
13628 printf (ngettext ("\nSymbol table for image contains %" PRIu64
13629 " entry:\n",
13630 "\nSymbol table for image contains %" PRIu64
13631 " entries:\n",
ca0e11aa
NC
13632 filedata->num_dynamic_syms),
13633 filedata->num_dynamic_syms);
13634 }
10ca4b04
L
13635 if (is_32bit_elf)
13636 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13637 else
13638 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13639
978c4450
AM
13640 for (si = 0; si < filedata->num_dynamic_syms; si++)
13641 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13642 filedata->dynamic_strings,
13643 filedata->dynamic_strings_length);
252b5132 13644 }
8b73c356 13645 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13646 && filedata->section_headers != NULL)
252b5132 13647 {
b34976b6 13648 unsigned int i;
252b5132 13649
dda8d76d
NC
13650 for (i = 0, section = filedata->section_headers;
13651 i < filedata->file_header.e_shnum;
252b5132
RH
13652 i++, section++)
13653 {
2cf0635d 13654 char * strtab = NULL;
26c527e6 13655 uint64_t strtab_size = 0;
2cf0635d 13656 Elf_Internal_Sym * symtab;
26c527e6 13657 uint64_t si, num_syms;
252b5132 13658
2c610e4b
L
13659 if ((section->sh_type != SHT_SYMTAB
13660 && section->sh_type != SHT_DYNSYM)
13661 || (!do_syms
13662 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13663 continue;
13664
dd24e3da
NC
13665 if (section->sh_entsize == 0)
13666 {
13667 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13668 printable_section_name (filedata, section));
dd24e3da
NC
13669 continue;
13670 }
13671
d3a49aa8 13672 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13673
13674 if (filedata->is_separate)
26c527e6
AM
13675 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
13676 " contains %" PRIu64 " entry:\n",
13677 "\nIn linked file '%s' symbol section '%s'"
13678 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13679 num_syms),
13680 filedata->file_name,
13681 printable_section_name (filedata, section),
13682 num_syms);
13683 else
26c527e6
AM
13684 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
13685 " entry:\n",
13686 "\nSymbol table '%s' contains %" PRIu64
13687 " entries:\n",
ca0e11aa
NC
13688 num_syms),
13689 printable_section_name (filedata, section),
13690 num_syms);
dd24e3da 13691
f7a99963 13692 if (is_32bit_elf)
ca47b30c 13693 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13694 else
ca47b30c 13695 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13696
4de91c10 13697 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13698 if (symtab == NULL)
13699 continue;
13700
dda8d76d 13701 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13702 {
dda8d76d
NC
13703 strtab = filedata->string_table;
13704 strtab_size = filedata->string_table_length;
c256ffe7 13705 }
dda8d76d 13706 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13707 {
2cf0635d 13708 Elf_Internal_Shdr * string_sec;
252b5132 13709
dda8d76d 13710 string_sec = filedata->section_headers + section->sh_link;
252b5132 13711
dda8d76d 13712 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13713 1, string_sec->sh_size,
13714 _("string table"));
c256ffe7 13715 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13716 }
13717
10ca4b04
L
13718 for (si = 0; si < num_syms; si++)
13719 print_dynamic_symbol (filedata, si, symtab, section,
13720 strtab, strtab_size);
252b5132
RH
13721
13722 free (symtab);
dda8d76d 13723 if (strtab != filedata->string_table)
252b5132
RH
13724 free (strtab);
13725 }
13726 }
13727 else if (do_syms)
13728 printf
13729 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13730
978c4450 13731 if (do_histogram && filedata->buckets != NULL)
252b5132 13732 {
26c527e6
AM
13733 uint64_t *lengths;
13734 uint64_t *counts;
13735 uint64_t hn;
625d49fc 13736 uint64_t si;
26c527e6
AM
13737 uint64_t maxlength = 0;
13738 uint64_t nzero_counts = 0;
13739 uint64_t nsyms = 0;
6bd6a03d 13740 char *visited;
252b5132 13741
d3a49aa8 13742 printf (ngettext ("\nHistogram for bucket list length "
26c527e6 13743 "(total of %" PRIu64 " bucket):\n",
d3a49aa8 13744 "\nHistogram for bucket list length "
26c527e6
AM
13745 "(total of %" PRIu64 " buckets):\n",
13746 filedata->nbuckets),
13747 filedata->nbuckets);
252b5132 13748
26c527e6 13749 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
252b5132
RH
13750 if (lengths == NULL)
13751 {
8b73c356 13752 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13753 goto err_out;
252b5132 13754 }
978c4450
AM
13755 visited = xcmalloc (filedata->nchains, 1);
13756 memset (visited, 0, filedata->nchains);
8b73c356
NC
13757
13758 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13759 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13760 {
978c4450 13761 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13762 {
b34976b6 13763 ++nsyms;
252b5132 13764 if (maxlength < ++lengths[hn])
b34976b6 13765 ++maxlength;
978c4450 13766 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13767 {
13768 error (_("histogram chain is corrupt\n"));
13769 break;
13770 }
13771 visited[si] = 1;
252b5132
RH
13772 }
13773 }
6bd6a03d 13774 free (visited);
252b5132 13775
26c527e6 13776 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13777 if (counts == NULL)
13778 {
b2e951ec 13779 free (lengths);
8b73c356 13780 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13781 goto err_out;
252b5132
RH
13782 }
13783
978c4450 13784 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13785 ++counts[lengths[hn]];
252b5132 13786
978c4450 13787 if (filedata->nbuckets > 0)
252b5132 13788 {
26c527e6
AM
13789 uint64_t i;
13790 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 13791 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13792 for (i = 1; i <= maxlength; ++i)
103f02d3 13793 {
66543521 13794 nzero_counts += counts[i] * i;
26c527e6 13795 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 13796 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13797 (nzero_counts * 100.0) / nsyms);
13798 }
252b5132
RH
13799 }
13800
13801 free (counts);
13802 free (lengths);
13803 }
13804
978c4450
AM
13805 free (filedata->buckets);
13806 filedata->buckets = NULL;
13807 filedata->nbuckets = 0;
13808 free (filedata->chains);
13809 filedata->chains = NULL;
252b5132 13810
978c4450 13811 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13812 {
26c527e6
AM
13813 uint64_t *lengths;
13814 uint64_t *counts;
13815 uint64_t hn;
13816 uint64_t maxlength = 0;
13817 uint64_t nzero_counts = 0;
13818 uint64_t nsyms = 0;
fdc90cb4 13819
f16a9783 13820 printf (ngettext ("\nHistogram for `%s' bucket list length "
26c527e6 13821 "(total of %" PRIu64 " bucket):\n",
f16a9783 13822 "\nHistogram for `%s' bucket list length "
26c527e6
AM
13823 "(total of %" PRIu64 " buckets):\n",
13824 filedata->ngnubuckets),
978c4450 13825 GNU_HASH_SECTION_NAME (filedata),
26c527e6 13826 filedata->ngnubuckets);
8b73c356 13827
26c527e6 13828 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
13829 if (lengths == NULL)
13830 {
8b73c356 13831 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13832 goto err_out;
fdc90cb4
JJ
13833 }
13834
fdc90cb4
JJ
13835 printf (_(" Length Number %% of total Coverage\n"));
13836
978c4450
AM
13837 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13838 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 13839 {
625d49fc 13840 uint64_t off, length = 1;
fdc90cb4 13841
978c4450 13842 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13843 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13844 off < filedata->ngnuchains
13845 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13846 ++off)
fdc90cb4
JJ
13847 ++length;
13848 lengths[hn] = length;
13849 if (length > maxlength)
13850 maxlength = length;
13851 nsyms += length;
13852 }
13853
26c527e6 13854 counts = calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13855 if (counts == NULL)
13856 {
b2e951ec 13857 free (lengths);
8b73c356 13858 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13859 goto err_out;
fdc90cb4
JJ
13860 }
13861
978c4450 13862 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13863 ++counts[lengths[hn]];
13864
978c4450 13865 if (filedata->ngnubuckets > 0)
fdc90cb4 13866 {
26c527e6
AM
13867 uint64_t j;
13868 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 13869 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13870 for (j = 1; j <= maxlength; ++j)
13871 {
13872 nzero_counts += counts[j] * j;
26c527e6 13873 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 13874 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13875 (nzero_counts * 100.0) / nsyms);
13876 }
13877 }
13878
13879 free (counts);
13880 free (lengths);
fdc90cb4 13881 }
978c4450
AM
13882 free (filedata->gnubuckets);
13883 filedata->gnubuckets = NULL;
13884 filedata->ngnubuckets = 0;
13885 free (filedata->gnuchains);
13886 filedata->gnuchains = NULL;
13887 filedata->ngnuchains = 0;
13888 free (filedata->mipsxlat);
13889 filedata->mipsxlat = NULL;
015dc7e1 13890 return true;
fd486f32
AM
13891
13892 err_out:
978c4450
AM
13893 free (filedata->gnubuckets);
13894 filedata->gnubuckets = NULL;
13895 filedata->ngnubuckets = 0;
13896 free (filedata->gnuchains);
13897 filedata->gnuchains = NULL;
13898 filedata->ngnuchains = 0;
13899 free (filedata->mipsxlat);
13900 filedata->mipsxlat = NULL;
13901 free (filedata->buckets);
13902 filedata->buckets = NULL;
13903 filedata->nbuckets = 0;
13904 free (filedata->chains);
13905 filedata->chains = NULL;
015dc7e1 13906 return false;
252b5132
RH
13907}
13908
015dc7e1 13909static bool
ca0e11aa 13910process_syminfo (Filedata * filedata)
252b5132 13911{
b4c96d0d 13912 unsigned int i;
252b5132 13913
978c4450 13914 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13915 || !do_dynamic)
13916 /* No syminfo, this is ok. */
015dc7e1 13917 return true;
252b5132
RH
13918
13919 /* There better should be a dynamic symbol section. */
978c4450 13920 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13921 return false;
252b5132 13922
ca0e11aa 13923 if (filedata->is_separate)
26c527e6
AM
13924 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
13925 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
ca0e11aa
NC
13926 filedata->dynamic_syminfo_nent),
13927 filedata->file_name,
13928 filedata->dynamic_syminfo_offset,
13929 filedata->dynamic_syminfo_nent);
13930 else
26c527e6
AM
13931 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
13932 " contains %d entry:\n",
13933 "\nDynamic info segment at offset %#" PRIx64
13934 " contains %d entries:\n",
978c4450 13935 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13936 filedata->dynamic_syminfo_offset,
13937 filedata->dynamic_syminfo_nent);
252b5132
RH
13938
13939 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13940 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13941 {
978c4450 13942 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13943
31104126 13944 printf ("%4d: ", i);
978c4450 13945 if (i >= filedata->num_dynamic_syms)
4082ef84 13946 printf (_("<corrupt index>"));
84714f86
AM
13947 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13948 print_symbol (30, get_dynamic_name (filedata,
978c4450 13949 filedata->dynamic_symbols[i].st_name));
d79b3d50 13950 else
978c4450 13951 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13952 putchar (' ');
252b5132 13953
978c4450 13954 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13955 {
13956 case SYMINFO_BT_SELF:
13957 fputs ("SELF ", stdout);
13958 break;
13959 case SYMINFO_BT_PARENT:
13960 fputs ("PARENT ", stdout);
13961 break;
13962 default:
978c4450
AM
13963 if (filedata->dynamic_syminfo[i].si_boundto > 0
13964 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13965 && valid_dynamic_name (filedata,
978c4450 13966 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13967 {
84714f86 13968 print_symbol (10, get_dynamic_name (filedata,
978c4450 13969 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13970 putchar (' ' );
13971 }
252b5132 13972 else
978c4450 13973 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13974 break;
13975 }
13976
13977 if (flags & SYMINFO_FLG_DIRECT)
13978 printf (" DIRECT");
13979 if (flags & SYMINFO_FLG_PASSTHRU)
13980 printf (" PASSTHRU");
13981 if (flags & SYMINFO_FLG_COPY)
13982 printf (" COPY");
13983 if (flags & SYMINFO_FLG_LAZYLOAD)
13984 printf (" LAZYLOAD");
13985
13986 puts ("");
13987 }
13988
015dc7e1 13989 return true;
252b5132
RH
13990}
13991
75802ccb
CE
13992/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13993 is contained by the region START .. END. The types of ADDR, START
13994 and END should all be the same. Note both ADDR + NELEM and END
13995 point to just beyond the end of the regions that are being tested. */
13996#define IN_RANGE(START,END,ADDR,NELEM) \
13997 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13998
cf13d699
NC
13999/* Check to see if the given reloc needs to be handled in a target specific
14000 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
14001 FALSE.
14002
14003 If called with reloc == NULL, then this is a signal that reloc processing
14004 for the current section has finished, and any saved state should be
14005 discarded. */
09c11c86 14006
015dc7e1 14007static bool
26c527e6
AM
14008target_specific_reloc_handling (Filedata *filedata,
14009 Elf_Internal_Rela *reloc,
14010 unsigned char *start,
14011 unsigned char *end,
14012 Elf_Internal_Sym *symtab,
14013 uint64_t num_syms)
252b5132 14014{
f84ce13b 14015 unsigned int reloc_type = 0;
26c527e6 14016 uint64_t sym_index = 0;
f84ce13b
NC
14017
14018 if (reloc)
14019 {
dda8d76d 14020 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
14021 sym_index = get_reloc_symindex (reloc->r_info);
14022 }
252b5132 14023
dda8d76d 14024 switch (filedata->file_header.e_machine)
252b5132 14025 {
76244462 14026 case EM_LOONGARCH:
14027 {
14028 switch (reloc_type)
14029 {
14030 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
14031 at assembly time. */
14032 case 107: /* R_LARCH_ADD_ULEB128. */
14033 case 108: /* R_LARCH_SUB_ULEB128. */
14034 {
d3f34076 14035 uint64_t value = 0;
76244462 14036 unsigned int reloc_size = 0;
14037 int leb_ret = 0;
14038
89c70cd3
AM
14039 if (reloc->r_offset < (size_t) (end - start))
14040 value = read_leb128 (start + reloc->r_offset, end, false,
14041 &reloc_size, &leb_ret);
76244462 14042 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14043 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
14044 "ULEB128 value\n"),
14045 (long) reloc->r_offset);
14046
74a965d8
AM
14047 else if (sym_index >= num_syms)
14048 error (_("%s reloc contains invalid symbol index "
14049 "%" PRIu64 "\n"),
14050 (reloc_type == 107
14051 ? "R_LARCH_ADD_ULEB128"
14052 : "R_LARCH_SUB_ULEB128"),
14053 sym_index);
14054 else
76244462 14055 {
74a965d8
AM
14056 if (reloc_type == 107)
14057 value += reloc->r_addend + symtab[sym_index].st_value;
14058 else
14059 value -= reloc->r_addend + symtab[sym_index].st_value;
14060
14061 /* Write uleb128 value to p. */
14062 bfd_byte *p = start + reloc->r_offset;
14063 do
14064 {
14065 bfd_byte c = value & 0x7f;
14066 value >>= 7;
14067 if (--reloc_size != 0)
14068 c |= 0x80;
14069 *p++ = c;
14070 }
14071 while (reloc_size);
76244462 14072 }
76244462 14073
14074 return true;
14075 }
14076 }
14077 break;
14078 }
14079
13761a11
NC
14080 case EM_MSP430:
14081 case EM_MSP430_OLD:
14082 {
14083 static Elf_Internal_Sym * saved_sym = NULL;
14084
f84ce13b
NC
14085 if (reloc == NULL)
14086 {
14087 saved_sym = NULL;
015dc7e1 14088 return true;
f84ce13b
NC
14089 }
14090
13761a11
NC
14091 switch (reloc_type)
14092 {
14093 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 14094 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 14095 if (uses_msp430x_relocs (filedata))
13761a11 14096 break;
1a0670f3 14097 /* Fall through. */
13761a11 14098 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 14099 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
14100 /* PR 21139. */
14101 if (sym_index >= num_syms)
74a965d8
AM
14102 error (_("%s reloc contains invalid symbol index "
14103 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
f84ce13b
NC
14104 else
14105 saved_sym = symtab + sym_index;
015dc7e1 14106 return true;
13761a11
NC
14107
14108 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14109 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14110 goto handle_sym_diff;
0b4362b0 14111
13761a11
NC
14112 case 5: /* R_MSP430_16_BYTE */
14113 case 9: /* R_MSP430_8 */
7d81bc93 14114 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 14115 if (uses_msp430x_relocs (filedata))
13761a11
NC
14116 break;
14117 goto handle_sym_diff;
14118
14119 case 2: /* R_MSP430_ABS16 */
14120 case 15: /* R_MSP430X_ABS16 */
7d81bc93 14121 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 14122 if (! uses_msp430x_relocs (filedata))
13761a11
NC
14123 break;
14124 goto handle_sym_diff;
0b4362b0 14125
13761a11
NC
14126 handle_sym_diff:
14127 if (saved_sym != NULL)
14128 {
625d49fc 14129 uint64_t value;
5a805384 14130 unsigned int reloc_size = 0;
7d81bc93
JL
14131 int leb_ret = 0;
14132 switch (reloc_type)
14133 {
14134 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14135 reloc_size = 4;
14136 break;
14137 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14138 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14139 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14140 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14141 &reloc_size, &leb_ret);
7d81bc93
JL
14142 break;
14143 default:
14144 reloc_size = 2;
14145 break;
14146 }
13761a11 14147
5a805384 14148 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
14149 error (_("MSP430 ULEB128 field at %#" PRIx64
14150 " contains invalid ULEB128 value\n"),
14151 reloc->r_offset);
7d81bc93 14152 else if (sym_index >= num_syms)
74a965d8
AM
14153 error (_("%s reloc contains invalid symbol index "
14154 "%" PRIu64 "\n"), "MSP430", sym_index);
03f7786e 14155 else
f84ce13b
NC
14156 {
14157 value = reloc->r_addend + (symtab[sym_index].st_value
14158 - saved_sym->st_value);
14159
b32e566b 14160 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14161 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14162 else
14163 /* PR 21137 */
26c527e6
AM
14164 error (_("MSP430 sym diff reloc contains invalid offset: "
14165 "%#" PRIx64 "\n"),
14166 reloc->r_offset);
f84ce13b 14167 }
13761a11
NC
14168
14169 saved_sym = NULL;
015dc7e1 14170 return true;
13761a11
NC
14171 }
14172 break;
14173
14174 default:
14175 if (saved_sym != NULL)
071436c6 14176 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14177 break;
14178 }
14179 break;
14180 }
14181
cf13d699
NC
14182 case EM_MN10300:
14183 case EM_CYGNUS_MN10300:
14184 {
14185 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14186
f84ce13b
NC
14187 if (reloc == NULL)
14188 {
14189 saved_sym = NULL;
015dc7e1 14190 return true;
f84ce13b
NC
14191 }
14192
cf13d699
NC
14193 switch (reloc_type)
14194 {
14195 case 34: /* R_MN10300_ALIGN */
015dc7e1 14196 return true;
cf13d699 14197 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 14198 if (sym_index >= num_syms)
74a965d8
AM
14199 error (_("%s reloc contains invalid symbol index "
14200 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
f84ce13b
NC
14201 else
14202 saved_sym = symtab + sym_index;
015dc7e1 14203 return true;
f84ce13b 14204
cf13d699
NC
14205 case 1: /* R_MN10300_32 */
14206 case 2: /* R_MN10300_16 */
14207 if (saved_sym != NULL)
14208 {
03f7786e 14209 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14210 uint64_t value;
252b5132 14211
f84ce13b 14212 if (sym_index >= num_syms)
74a965d8
AM
14213 error (_("%s reloc contains invalid symbol index "
14214 "%" PRIu64 "\n"), "MN10300", sym_index);
03f7786e 14215 else
f84ce13b
NC
14216 {
14217 value = reloc->r_addend + (symtab[sym_index].st_value
14218 - saved_sym->st_value);
14219
b32e566b 14220 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14221 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 14222 else
26c527e6
AM
14223 error (_("MN10300 sym diff reloc contains invalid offset:"
14224 " %#" PRIx64 "\n"),
14225 reloc->r_offset);
f84ce13b 14226 }
252b5132 14227
cf13d699 14228 saved_sym = NULL;
015dc7e1 14229 return true;
cf13d699
NC
14230 }
14231 break;
14232 default:
14233 if (saved_sym != NULL)
071436c6 14234 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14235 break;
14236 }
14237 break;
14238 }
6ff71e76
NC
14239
14240 case EM_RL78:
14241 {
625d49fc
AM
14242 static uint64_t saved_sym1 = 0;
14243 static uint64_t saved_sym2 = 0;
14244 static uint64_t value;
6ff71e76 14245
f84ce13b
NC
14246 if (reloc == NULL)
14247 {
14248 saved_sym1 = saved_sym2 = 0;
015dc7e1 14249 return true;
f84ce13b
NC
14250 }
14251
6ff71e76
NC
14252 switch (reloc_type)
14253 {
14254 case 0x80: /* R_RL78_SYM. */
14255 saved_sym1 = saved_sym2;
f84ce13b 14256 if (sym_index >= num_syms)
74a965d8
AM
14257 error (_("%s reloc contains invalid symbol index "
14258 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
f84ce13b
NC
14259 else
14260 {
14261 saved_sym2 = symtab[sym_index].st_value;
14262 saved_sym2 += reloc->r_addend;
14263 }
015dc7e1 14264 return true;
6ff71e76
NC
14265
14266 case 0x83: /* R_RL78_OPsub. */
14267 value = saved_sym1 - saved_sym2;
14268 saved_sym2 = saved_sym1 = 0;
015dc7e1 14269 return true;
6ff71e76
NC
14270 break;
14271
14272 case 0x41: /* R_RL78_ABS32. */
b32e566b 14273 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14274 byte_put (start + reloc->r_offset, value, 4);
b32e566b 14275 else
26c527e6
AM
14276 error (_("RL78 sym diff reloc contains invalid offset: "
14277 "%#" PRIx64 "\n"),
14278 reloc->r_offset);
6ff71e76 14279 value = 0;
015dc7e1 14280 return true;
6ff71e76
NC
14281
14282 case 0x43: /* R_RL78_ABS16. */
b32e566b 14283 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14284 byte_put (start + reloc->r_offset, value, 2);
b32e566b 14285 else
26c527e6
AM
14286 error (_("RL78 sym diff reloc contains invalid offset: "
14287 "%#" PRIx64 "\n"),
14288 reloc->r_offset);
6ff71e76 14289 value = 0;
015dc7e1 14290 return true;
6ff71e76
NC
14291
14292 default:
14293 break;
14294 }
14295 break;
14296 }
252b5132
RH
14297 }
14298
015dc7e1 14299 return false;
252b5132
RH
14300}
14301
aca88567
NC
14302/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14303 DWARF debug sections. This is a target specific test. Note - we do not
14304 go through the whole including-target-headers-multiple-times route, (as
14305 we have already done with <elf/h8.h>) because this would become very
14306 messy and even then this function would have to contain target specific
14307 information (the names of the relocs instead of their numeric values).
14308 FIXME: This is not the correct way to solve this problem. The proper way
14309 is to have target specific reloc sizing and typing functions created by
14310 the reloc-macros.h header, in the same way that it already creates the
14311 reloc naming functions. */
14312
015dc7e1 14313static bool
dda8d76d 14314is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14315{
d347c9df 14316 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14317 switch (filedata->file_header.e_machine)
aca88567 14318 {
41e92641 14319 case EM_386:
22abe556 14320 case EM_IAMCU:
41e92641 14321 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14322 case EM_68K:
14323 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14324 case EM_860:
14325 return reloc_type == 1; /* R_860_32. */
14326 case EM_960:
14327 return reloc_type == 2; /* R_960_32. */
a06ea964 14328 case EM_AARCH64:
9282b95a
JW
14329 return (reloc_type == 258
14330 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14331 case EM_BPF:
14332 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14333 case EM_ADAPTEVA_EPIPHANY:
14334 return reloc_type == 3;
aca88567 14335 case EM_ALPHA:
137b6b5f 14336 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14337 case EM_ARC:
14338 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14339 case EM_ARC_COMPACT:
14340 case EM_ARC_COMPACT2:
13aa307c
CZ
14341 case EM_ARC_COMPACT3:
14342 case EM_ARC_COMPACT3_64:
886a2506 14343 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14344 case EM_ARM:
14345 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14346 case EM_AVR_OLD:
aca88567
NC
14347 case EM_AVR:
14348 return reloc_type == 1;
14349 case EM_BLACKFIN:
14350 return reloc_type == 0x12; /* R_byte4_data. */
14351 case EM_CRIS:
14352 return reloc_type == 3; /* R_CRIS_32. */
14353 case EM_CR16:
14354 return reloc_type == 3; /* R_CR16_NUM32. */
14355 case EM_CRX:
14356 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14357 case EM_CSKY:
14358 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14359 case EM_CYGNUS_FRV:
14360 return reloc_type == 1;
41e92641
NC
14361 case EM_CYGNUS_D10V:
14362 case EM_D10V:
14363 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14364 case EM_CYGNUS_D30V:
14365 case EM_D30V:
14366 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14367 case EM_DLX:
14368 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14369 case EM_CYGNUS_FR30:
14370 case EM_FR30:
14371 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14372 case EM_FT32:
14373 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14374 case EM_H8S:
14375 case EM_H8_300:
14376 case EM_H8_300H:
14377 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14378 case EM_IA_64:
262cdac7
AM
14379 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14380 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14381 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14382 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14383 case EM_IP2K_OLD:
14384 case EM_IP2K:
14385 return reloc_type == 2; /* R_IP2K_32. */
14386 case EM_IQ2000:
14387 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14388 case EM_LATTICEMICO32:
14389 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14390 case EM_LOONGARCH:
14391 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14392 case EM_M32C_OLD:
aca88567
NC
14393 case EM_M32C:
14394 return reloc_type == 3; /* R_M32C_32. */
14395 case EM_M32R:
14396 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14397 case EM_68HC11:
14398 case EM_68HC12:
14399 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14400 case EM_S12Z:
2849d19f
JD
14401 return reloc_type == 7 || /* R_S12Z_EXT32 */
14402 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14403 case EM_MCORE:
14404 return reloc_type == 1; /* R_MCORE_ADDR32. */
14405 case EM_CYGNUS_MEP:
14406 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14407 case EM_METAG:
14408 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14409 case EM_MICROBLAZE:
14410 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14411 case EM_MIPS:
14412 return reloc_type == 2; /* R_MIPS_32. */
14413 case EM_MMIX:
14414 return reloc_type == 4; /* R_MMIX_32. */
14415 case EM_CYGNUS_MN10200:
14416 case EM_MN10200:
14417 return reloc_type == 1; /* R_MN10200_32. */
14418 case EM_CYGNUS_MN10300:
14419 case EM_MN10300:
14420 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14421 case EM_MOXIE:
14422 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14423 case EM_MSP430_OLD:
14424 case EM_MSP430:
13761a11 14425 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14426 case EM_MT:
14427 return reloc_type == 2; /* R_MT_32. */
35c08157 14428 case EM_NDS32:
81c5e376 14429 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14430 case EM_ALTERA_NIOS2:
36591ba1 14431 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14432 case EM_NIOS32:
14433 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14434 case EM_OR1K:
14435 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14436 case EM_PARISC:
9abca702 14437 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14438 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14439 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14440 case EM_PJ:
14441 case EM_PJ_OLD:
14442 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14443 case EM_PPC64:
14444 return reloc_type == 1; /* R_PPC64_ADDR32. */
14445 case EM_PPC:
14446 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14447 case EM_TI_PRU:
14448 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14449 case EM_RISCV:
14450 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14451 case EM_RL78:
14452 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14453 case EM_RX:
14454 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14455 case EM_S370:
14456 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14457 case EM_S390_OLD:
14458 case EM_S390:
14459 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14460 case EM_SCORE:
14461 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14462 case EM_SH:
14463 return reloc_type == 1; /* R_SH_DIR32. */
14464 case EM_SPARC32PLUS:
14465 case EM_SPARCV9:
14466 case EM_SPARC:
14467 return reloc_type == 3 /* R_SPARC_32. */
14468 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14469 case EM_SPU:
14470 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14471 case EM_TI_C6000:
14472 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14473 case EM_TILEGX:
14474 return reloc_type == 2; /* R_TILEGX_32. */
14475 case EM_TILEPRO:
14476 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14477 case EM_CYGNUS_V850:
14478 case EM_V850:
14479 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14480 case EM_V800:
14481 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14482 case EM_VAX:
14483 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14484 case EM_VISIUM:
14485 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14486 case EM_WEBASSEMBLY:
14487 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14488 case EM_X86_64:
8a9036a4 14489 case EM_L1OM:
7a9068fe 14490 case EM_K1OM:
aca88567 14491 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14492 case EM_XGATE:
14493 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14494 case EM_XSTORMY16:
14495 return reloc_type == 1; /* R_XSTROMY16_32. */
14496 case EM_XTENSA_OLD:
14497 case EM_XTENSA:
14498 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14499 case EM_Z80:
14500 return reloc_type == 6; /* R_Z80_32. */
aca88567 14501 default:
bee0ee85
NC
14502 {
14503 static unsigned int prev_warn = 0;
14504
14505 /* Avoid repeating the same warning multiple times. */
dda8d76d 14506 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14507 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14508 filedata->file_header.e_machine);
14509 prev_warn = filedata->file_header.e_machine;
015dc7e1 14510 return false;
bee0ee85 14511 }
aca88567
NC
14512 }
14513}
14514
14515/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14516 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14517
015dc7e1 14518static bool
dda8d76d 14519is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14520{
dda8d76d 14521 switch (filedata->file_header.e_machine)
d347c9df 14522 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14523 {
41e92641 14524 case EM_386:
22abe556 14525 case EM_IAMCU:
3e0873ac 14526 return reloc_type == 2; /* R_386_PC32. */
aca88567 14527 case EM_68K:
3e0873ac 14528 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14529 case EM_AARCH64:
14530 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14531 case EM_ADAPTEVA_EPIPHANY:
14532 return reloc_type == 6;
aca88567
NC
14533 case EM_ALPHA:
14534 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14535 case EM_ARC_COMPACT:
14536 case EM_ARC_COMPACT2:
13aa307c
CZ
14537 case EM_ARC_COMPACT3:
14538 case EM_ARC_COMPACT3_64:
726c18e1 14539 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14540 case EM_ARM:
3e0873ac 14541 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14542 case EM_AVR_OLD:
14543 case EM_AVR:
14544 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14545 case EM_LOONGARCH:
14546 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14547 case EM_MICROBLAZE:
14548 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14549 case EM_OR1K:
14550 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14551 case EM_PARISC:
85acf597 14552 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14553 case EM_PPC:
14554 return reloc_type == 26; /* R_PPC_REL32. */
14555 case EM_PPC64:
3e0873ac 14556 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14557 case EM_RISCV:
14558 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14559 case EM_S390_OLD:
14560 case EM_S390:
3e0873ac 14561 return reloc_type == 5; /* R_390_PC32. */
aca88567 14562 case EM_SH:
3e0873ac 14563 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14564 case EM_SPARC32PLUS:
14565 case EM_SPARCV9:
14566 case EM_SPARC:
3e0873ac 14567 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14568 case EM_SPU:
14569 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14570 case EM_TILEGX:
14571 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14572 case EM_TILEPRO:
14573 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14574 case EM_VISIUM:
14575 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14576 case EM_X86_64:
8a9036a4 14577 case EM_L1OM:
7a9068fe 14578 case EM_K1OM:
3e0873ac 14579 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14580 case EM_VAX:
14581 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14582 case EM_XTENSA_OLD:
14583 case EM_XTENSA:
14584 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14585 default:
14586 /* Do not abort or issue an error message here. Not all targets use
14587 pc-relative 32-bit relocs in their DWARF debug information and we
14588 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14589 more helpful warning message will be generated by apply_relocations
14590 anyway, so just return. */
015dc7e1 14591 return false;
aca88567
NC
14592 }
14593}
14594
14595/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14596 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14597
015dc7e1 14598static bool
dda8d76d 14599is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14600{
dda8d76d 14601 switch (filedata->file_header.e_machine)
aca88567 14602 {
a06ea964
NC
14603 case EM_AARCH64:
14604 return reloc_type == 257; /* R_AARCH64_ABS64. */
13aa307c
CZ
14605 case EM_ARC_COMPACT3_64:
14606 return reloc_type == 5; /* R_ARC_64. */
aca88567
NC
14607 case EM_ALPHA:
14608 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14609 case EM_IA_64:
262cdac7
AM
14610 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14611 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14612 case EM_LOONGARCH:
14613 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14614 case EM_PARISC:
14615 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14616 case EM_PPC64:
14617 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14618 case EM_RISCV:
14619 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14620 case EM_SPARC32PLUS:
14621 case EM_SPARCV9:
14622 case EM_SPARC:
714da62f
NC
14623 return reloc_type == 32 /* R_SPARC_64. */
14624 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14625 case EM_X86_64:
8a9036a4 14626 case EM_L1OM:
7a9068fe 14627 case EM_K1OM:
aca88567 14628 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14629 case EM_S390_OLD:
14630 case EM_S390:
aa137e4d
NC
14631 return reloc_type == 22; /* R_S390_64. */
14632 case EM_TILEGX:
14633 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14634 case EM_MIPS:
aa137e4d 14635 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14636 default:
015dc7e1 14637 return false;
aca88567
NC
14638 }
14639}
14640
85acf597
RH
14641/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14642 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14643
015dc7e1 14644static bool
dda8d76d 14645is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14646{
dda8d76d 14647 switch (filedata->file_header.e_machine)
85acf597 14648 {
a06ea964
NC
14649 case EM_AARCH64:
14650 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14651 case EM_ALPHA:
aa137e4d 14652 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14653 case EM_IA_64:
262cdac7
AM
14654 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14655 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14656 case EM_PARISC:
aa137e4d 14657 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14658 case EM_PPC64:
aa137e4d 14659 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14660 case EM_SPARC32PLUS:
14661 case EM_SPARCV9:
14662 case EM_SPARC:
aa137e4d 14663 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14664 case EM_X86_64:
8a9036a4 14665 case EM_L1OM:
7a9068fe 14666 case EM_K1OM:
aa137e4d 14667 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14668 case EM_S390_OLD:
14669 case EM_S390:
aa137e4d
NC
14670 return reloc_type == 23; /* R_S390_PC64. */
14671 case EM_TILEGX:
14672 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14673 default:
015dc7e1 14674 return false;
85acf597
RH
14675 }
14676}
14677
4dc3c23d
AM
14678/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14679 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14680
015dc7e1 14681static bool
dda8d76d 14682is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14683{
dda8d76d 14684 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14685 {
14686 case EM_CYGNUS_MN10200:
14687 case EM_MN10200:
14688 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14689 case EM_FT32:
14690 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14691 case EM_Z80:
14692 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14693 default:
015dc7e1 14694 return false;
4dc3c23d
AM
14695 }
14696}
14697
aca88567
NC
14698/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14699 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14700
015dc7e1 14701static bool
dda8d76d 14702is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14703{
d347c9df 14704 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14705 switch (filedata->file_header.e_machine)
4b78141a 14706 {
886a2506
NC
14707 case EM_ARC:
14708 case EM_ARC_COMPACT:
14709 case EM_ARC_COMPACT2:
13aa307c
CZ
14710 case EM_ARC_COMPACT3:
14711 case EM_ARC_COMPACT3_64:
886a2506 14712 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14713 case EM_ADAPTEVA_EPIPHANY:
14714 return reloc_type == 5;
aca88567
NC
14715 case EM_AVR_OLD:
14716 case EM_AVR:
14717 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14718 case EM_CYGNUS_D10V:
14719 case EM_D10V:
14720 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14721 case EM_FT32:
14722 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14723 case EM_H8S:
14724 case EM_H8_300:
14725 case EM_H8_300H:
aca88567
NC
14726 return reloc_type == R_H8_DIR16;
14727 case EM_IP2K_OLD:
14728 case EM_IP2K:
14729 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14730 case EM_M32C_OLD:
f4236fe4
DD
14731 case EM_M32C:
14732 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14733 case EM_CYGNUS_MN10200:
14734 case EM_MN10200:
14735 return reloc_type == 2; /* R_MN10200_16. */
14736 case EM_CYGNUS_MN10300:
14737 case EM_MN10300:
14738 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14739 case EM_MSP430:
dda8d76d 14740 if (uses_msp430x_relocs (filedata))
13761a11 14741 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14742 /* Fall through. */
78c8d46c 14743 case EM_MSP430_OLD:
aca88567 14744 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 14745 case EM_NDS32:
81c5e376 14746 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 14747 case EM_ALTERA_NIOS2:
36591ba1 14748 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14749 case EM_NIOS32:
14750 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14751 case EM_OR1K:
14752 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14753 case EM_RISCV:
14754 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14755 case EM_TI_PRU:
14756 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14757 case EM_TI_C6000:
14758 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14759 case EM_VISIUM:
14760 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
14761 case EM_XGATE:
14762 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14763 case EM_Z80:
14764 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14765 default:
015dc7e1 14766 return false;
4b78141a
NC
14767 }
14768}
14769
39e07931
AS
14770/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14771 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14772
015dc7e1 14773static bool
39e07931
AS
14774is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14775{
14776 switch (filedata->file_header.e_machine)
14777 {
14778 case EM_RISCV:
14779 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14780 case EM_Z80:
14781 return reloc_type == 1; /* R_Z80_8. */
39e07931 14782 default:
015dc7e1 14783 return false;
39e07931
AS
14784 }
14785}
14786
14787/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14788 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14789
015dc7e1 14790static bool
39e07931
AS
14791is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14792{
14793 switch (filedata->file_header.e_machine)
14794 {
14795 case EM_RISCV:
14796 return reloc_type == 53; /* R_RISCV_SET6. */
14797 default:
015dc7e1 14798 return false;
39e07931
AS
14799 }
14800}
14801
03336641
JW
14802/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14803 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14804
015dc7e1 14805static bool
03336641
JW
14806is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14807{
14808 /* Please keep this table alpha-sorted for ease of visual lookup. */
14809 switch (filedata->file_header.e_machine)
14810 {
76244462 14811 case EM_LOONGARCH:
14812 return reloc_type == 50; /* R_LARCH_ADD32. */
03336641
JW
14813 case EM_RISCV:
14814 return reloc_type == 35; /* R_RISCV_ADD32. */
14815 default:
015dc7e1 14816 return false;
03336641
JW
14817 }
14818}
14819
14820/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14821 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14822
015dc7e1 14823static bool
03336641
JW
14824is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14825{
14826 /* Please keep this table alpha-sorted for ease of visual lookup. */
14827 switch (filedata->file_header.e_machine)
14828 {
76244462 14829 case EM_LOONGARCH:
14830 return reloc_type == 55; /* R_LARCH_SUB32. */
03336641
JW
14831 case EM_RISCV:
14832 return reloc_type == 39; /* R_RISCV_SUB32. */
14833 default:
015dc7e1 14834 return false;
03336641
JW
14835 }
14836}
14837
14838/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14839 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14840
015dc7e1 14841static bool
03336641
JW
14842is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14843{
14844 /* Please keep this table alpha-sorted for ease of visual lookup. */
14845 switch (filedata->file_header.e_machine)
14846 {
76244462 14847 case EM_LOONGARCH:
14848 return reloc_type == 51; /* R_LARCH_ADD64. */
03336641
JW
14849 case EM_RISCV:
14850 return reloc_type == 36; /* R_RISCV_ADD64. */
14851 default:
015dc7e1 14852 return false;
03336641
JW
14853 }
14854}
14855
14856/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14857 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14858
015dc7e1 14859static bool
03336641
JW
14860is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14861{
14862 /* Please keep this table alpha-sorted for ease of visual lookup. */
14863 switch (filedata->file_header.e_machine)
14864 {
76244462 14865 case EM_LOONGARCH:
14866 return reloc_type == 56; /* R_LARCH_SUB64. */
03336641
JW
14867 case EM_RISCV:
14868 return reloc_type == 40; /* R_RISCV_SUB64. */
14869 default:
015dc7e1 14870 return false;
03336641
JW
14871 }
14872}
14873
14874/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14875 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14876
015dc7e1 14877static bool
03336641
JW
14878is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14879{
14880 /* Please keep this table alpha-sorted for ease of visual lookup. */
14881 switch (filedata->file_header.e_machine)
14882 {
76244462 14883 case EM_LOONGARCH:
14884 return reloc_type == 48; /* R_LARCH_ADD16. */
03336641
JW
14885 case EM_RISCV:
14886 return reloc_type == 34; /* R_RISCV_ADD16. */
14887 default:
015dc7e1 14888 return false;
03336641
JW
14889 }
14890}
14891
14892/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14893 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14894
015dc7e1 14895static bool
03336641
JW
14896is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14897{
14898 /* Please keep this table alpha-sorted for ease of visual lookup. */
14899 switch (filedata->file_header.e_machine)
14900 {
76244462 14901 case EM_LOONGARCH:
14902 return reloc_type == 53; /* R_LARCH_SUB16. */
03336641
JW
14903 case EM_RISCV:
14904 return reloc_type == 38; /* R_RISCV_SUB16. */
14905 default:
015dc7e1 14906 return false;
03336641
JW
14907 }
14908}
14909
14910/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14911 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14912
015dc7e1 14913static bool
03336641
JW
14914is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14915{
14916 /* Please keep this table alpha-sorted for ease of visual lookup. */
14917 switch (filedata->file_header.e_machine)
14918 {
76244462 14919 case EM_LOONGARCH:
14920 return reloc_type == 47; /* R_LARCH_ADD8. */
03336641
JW
14921 case EM_RISCV:
14922 return reloc_type == 33; /* R_RISCV_ADD8. */
14923 default:
015dc7e1 14924 return false;
03336641
JW
14925 }
14926}
14927
14928/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14929 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14930
015dc7e1 14931static bool
03336641
JW
14932is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14933{
14934 /* Please keep this table alpha-sorted for ease of visual lookup. */
14935 switch (filedata->file_header.e_machine)
14936 {
76244462 14937 case EM_LOONGARCH:
14938 return reloc_type == 52; /* R_LARCH_SUB8. */
03336641
JW
14939 case EM_RISCV:
14940 return reloc_type == 37; /* R_RISCV_SUB8. */
14941 default:
015dc7e1 14942 return false;
03336641
JW
14943 }
14944}
14945
76244462 14946/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14947 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
14948
14949static bool
14950is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14951{
14952 switch (filedata->file_header.e_machine)
14953 {
14954 case EM_LOONGARCH:
14955 return reloc_type == 105; /* R_LARCH_ADD6. */
14956 default:
14957 return false;
14958 }
14959}
14960
39e07931
AS
14961/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14962 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14963
015dc7e1 14964static bool
39e07931
AS
14965is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14966{
14967 switch (filedata->file_header.e_machine)
14968 {
76244462 14969 case EM_LOONGARCH:
14970 return reloc_type == 106; /* R_LARCH_SUB6. */
39e07931
AS
14971 case EM_RISCV:
14972 return reloc_type == 52; /* R_RISCV_SUB6. */
14973 default:
015dc7e1 14974 return false;
39e07931
AS
14975 }
14976}
14977
2a7b2e88
JK
14978/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14979 relocation entries (possibly formerly used for SHT_GROUP sections). */
14980
015dc7e1 14981static bool
dda8d76d 14982is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14983{
dda8d76d 14984 switch (filedata->file_header.e_machine)
2a7b2e88 14985 {
cb8f3167 14986 case EM_386: /* R_386_NONE. */
d347c9df 14987 case EM_68K: /* R_68K_NONE. */
cfb8c092 14988 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14989 case EM_ALPHA: /* R_ALPHA_NONE. */
14990 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14991 case EM_ARC: /* R_ARC_NONE. */
886a2506 14992 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14993 case EM_ARC_COMPACT: /* R_ARC_NONE. */
13aa307c
CZ
14994 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
14995 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
cb8f3167 14996 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 14997 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14998 case EM_FT32: /* R_FT32_NONE. */
14999 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 15000 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
15001 case EM_L1OM: /* R_X86_64_NONE. */
15002 case EM_M32R: /* R_M32R_NONE. */
15003 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 15004 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 15005 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
15006 case EM_NIOS32: /* R_NIOS_NONE. */
15007 case EM_OR1K: /* R_OR1K_NONE. */
15008 case EM_PARISC: /* R_PARISC_NONE. */
15009 case EM_PPC64: /* R_PPC64_NONE. */
15010 case EM_PPC: /* R_PPC_NONE. */
e23eba97 15011 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
15012 case EM_S390: /* R_390_NONE. */
15013 case EM_S390_OLD:
15014 case EM_SH: /* R_SH_NONE. */
15015 case EM_SPARC32PLUS:
15016 case EM_SPARC: /* R_SPARC_NONE. */
15017 case EM_SPARCV9:
aa137e4d
NC
15018 case EM_TILEGX: /* R_TILEGX_NONE. */
15019 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
15020 case EM_TI_C6000:/* R_C6000_NONE. */
15021 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 15022 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 15023 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 15024 return reloc_type == 0;
d347c9df 15025
a06ea964
NC
15026 case EM_AARCH64:
15027 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
15028 case EM_AVR_OLD:
15029 case EM_AVR:
15030 return (reloc_type == 0 /* R_AVR_NONE. */
15031 || reloc_type == 30 /* R_AVR_DIFF8. */
15032 || reloc_type == 31 /* R_AVR_DIFF16. */
15033 || reloc_type == 32 /* R_AVR_DIFF32. */);
15034 case EM_METAG:
15035 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 15036 case EM_NDS32:
81c5e376
AM
15037 return (reloc_type == 0 /* R_NDS32_NONE. */
15038 || reloc_type == 205 /* R_NDS32_DIFF8. */
15039 || reloc_type == 206 /* R_NDS32_DIFF16. */
15040 || reloc_type == 207 /* R_NDS32_DIFF32. */
15041 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
15042 case EM_TI_PRU:
15043 return (reloc_type == 0 /* R_PRU_NONE. */
15044 || reloc_type == 65 /* R_PRU_DIFF8. */
15045 || reloc_type == 66 /* R_PRU_DIFF16. */
15046 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
15047 case EM_XTENSA_OLD:
15048 case EM_XTENSA:
4dc3c23d
AM
15049 return (reloc_type == 0 /* R_XTENSA_NONE. */
15050 || reloc_type == 17 /* R_XTENSA_DIFF8. */
15051 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
15052 || reloc_type == 19 /* R_XTENSA_DIFF32. */
15053 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
15054 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
15055 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
15056 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
15057 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
15058 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 15059 }
015dc7e1 15060 return false;
2a7b2e88
JK
15061}
15062
d1c4b12b
NC
15063/* Returns TRUE if there is a relocation against
15064 section NAME at OFFSET bytes. */
15065
015dc7e1 15066bool
31e5a3a3 15067reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
15068{
15069 Elf_Internal_Rela * relocs;
15070 Elf_Internal_Rela * rp;
15071
15072 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 15073 return false;
d1c4b12b
NC
15074
15075 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
15076
15077 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
15078 if (rp->r_offset == offset)
015dc7e1 15079 return true;
d1c4b12b 15080
015dc7e1 15081 return false;
d1c4b12b
NC
15082}
15083
cf13d699 15084/* Apply relocations to a section.
32ec8896
NC
15085 Returns TRUE upon success, FALSE otherwise.
15086 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
15087 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
15088 will be set to the number of relocs loaded.
15089
cf13d699 15090 Note: So far support has been added only for those relocations
32ec8896
NC
15091 which can be found in debug sections. FIXME: Add support for
15092 more relocations ? */
1b315056 15093
015dc7e1 15094static bool
be7d229a
AM
15095apply_relocations (Filedata *filedata,
15096 const Elf_Internal_Shdr *section,
15097 unsigned char *start,
15098 size_t size,
15099 void **relocs_return,
26c527e6 15100 uint64_t *num_relocs_return)
1b315056 15101{
cf13d699 15102 Elf_Internal_Shdr * relsec;
0d2a7a93 15103 unsigned char * end = start + size;
cb8f3167 15104
d1c4b12b
NC
15105 if (relocs_return != NULL)
15106 {
15107 * (Elf_Internal_Rela **) relocs_return = NULL;
15108 * num_relocs_return = 0;
15109 }
15110
dda8d76d 15111 if (filedata->file_header.e_type != ET_REL)
32ec8896 15112 /* No relocs to apply. */
015dc7e1 15113 return true;
1b315056 15114
cf13d699 15115 /* Find the reloc section associated with the section. */
dda8d76d
NC
15116 for (relsec = filedata->section_headers;
15117 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 15118 ++relsec)
252b5132 15119 {
015dc7e1 15120 bool is_rela;
26c527e6 15121 uint64_t num_relocs;
2cf0635d
NC
15122 Elf_Internal_Rela * relocs;
15123 Elf_Internal_Rela * rp;
15124 Elf_Internal_Shdr * symsec;
15125 Elf_Internal_Sym * symtab;
26c527e6 15126 uint64_t num_syms;
2cf0635d 15127 Elf_Internal_Sym * sym;
252b5132 15128
41e92641 15129 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15130 || relsec->sh_info >= filedata->file_header.e_shnum
15131 || filedata->section_headers + relsec->sh_info != section
c256ffe7 15132 || relsec->sh_size == 0
dda8d76d 15133 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 15134 continue;
428409d5 15135
a788aedd
AM
15136 symsec = filedata->section_headers + relsec->sh_link;
15137 if (symsec->sh_type != SHT_SYMTAB
15138 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 15139 return false;
a788aedd 15140
41e92641
NC
15141 is_rela = relsec->sh_type == SHT_RELA;
15142
15143 if (is_rela)
15144 {
dda8d76d 15145 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 15146 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15147 return false;
41e92641
NC
15148 }
15149 else
15150 {
dda8d76d 15151 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 15152 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15153 return false;
41e92641
NC
15154 }
15155
15156 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 15157 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 15158 is_rela = false;
428409d5 15159
4de91c10 15160 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 15161
41e92641 15162 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 15163 {
625d49fc 15164 uint64_t addend;
015dc7e1
AM
15165 unsigned int reloc_type;
15166 unsigned int reloc_size;
15167 bool reloc_inplace = false;
15168 bool reloc_subtract = false;
15169 unsigned char *rloc;
26c527e6 15170 uint64_t sym_index;
4b78141a 15171
dda8d76d 15172 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 15173
dda8d76d 15174 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 15175 continue;
dda8d76d 15176 else if (is_none_reloc (filedata, reloc_type))
98fb390a 15177 continue;
dda8d76d
NC
15178 else if (is_32bit_abs_reloc (filedata, reloc_type)
15179 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 15180 reloc_size = 4;
dda8d76d
NC
15181 else if (is_64bit_abs_reloc (filedata, reloc_type)
15182 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 15183 reloc_size = 8;
dda8d76d 15184 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15185 reloc_size = 3;
dda8d76d 15186 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15187 reloc_size = 2;
39e07931
AS
15188 else if (is_8bit_abs_reloc (filedata, reloc_type)
15189 || is_6bit_abs_reloc (filedata, reloc_type))
15190 reloc_size = 1;
03336641
JW
15191 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15192 reloc_type))
15193 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15194 {
15195 reloc_size = 4;
015dc7e1 15196 reloc_inplace = true;
03336641
JW
15197 }
15198 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15199 reloc_type))
15200 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15201 {
15202 reloc_size = 8;
015dc7e1 15203 reloc_inplace = true;
03336641
JW
15204 }
15205 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15206 reloc_type))
15207 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15208 {
15209 reloc_size = 2;
015dc7e1 15210 reloc_inplace = true;
03336641
JW
15211 }
15212 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15213 reloc_type))
15214 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15215 {
15216 reloc_size = 1;
015dc7e1 15217 reloc_inplace = true;
03336641 15218 }
39e07931 15219 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
76244462 15220 reloc_type))
15221 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15222 {
15223 reloc_size = 1;
015dc7e1 15224 reloc_inplace = true;
39e07931 15225 }
aca88567 15226 else
4b78141a 15227 {
bee0ee85 15228 static unsigned int prev_reloc = 0;
dda8d76d 15229
bee0ee85
NC
15230 if (reloc_type != prev_reloc)
15231 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15232 reloc_type, printable_section_name (filedata, section));
bee0ee85 15233 prev_reloc = reloc_type;
4b78141a
NC
15234 continue;
15235 }
103f02d3 15236
91d6fa6a 15237 rloc = start + rp->r_offset;
75802ccb 15238 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 15239 {
26c527e6
AM
15240 warn (_("skipping invalid relocation offset %#" PRIx64
15241 " in section %s\n"),
15242 rp->r_offset,
dda8d76d 15243 printable_section_name (filedata, section));
700dd8b7
L
15244 continue;
15245 }
103f02d3 15246
26c527e6 15247 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
15248 if (sym_index >= num_syms)
15249 {
26c527e6
AM
15250 warn (_("skipping invalid relocation symbol index %#" PRIx64
15251 " in section %s\n"),
dda8d76d 15252 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15253 continue;
15254 }
15255 sym = symtab + sym_index;
41e92641
NC
15256
15257 /* If the reloc has a symbol associated with it,
55f25fc3
L
15258 make sure that it is of an appropriate type.
15259
15260 Relocations against symbols without type can happen.
15261 Gcc -feliminate-dwarf2-dups may generate symbols
15262 without type for debug info.
15263
15264 Icc generates relocations against function symbols
15265 instead of local labels.
15266
15267 Relocations against object symbols can happen, eg when
15268 referencing a global array. For an example of this see
15269 the _clz.o binary in libgcc.a. */
aca88567 15270 if (sym != symtab
b8871f35 15271 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15272 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15273 {
26c527e6 15274 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
15275 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15276 printable_section_name (filedata, relsec),
26c527e6 15277 rp - relocs);
aca88567 15278 continue;
5b18a4bc 15279 }
252b5132 15280
4dc3c23d
AM
15281 addend = 0;
15282 if (is_rela)
15283 addend += rp->r_addend;
c47320c3
AM
15284 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15285 partial_inplace. */
4dc3c23d 15286 if (!is_rela
dda8d76d 15287 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15288 && reloc_type == 1)
dda8d76d
NC
15289 || ((filedata->file_header.e_machine == EM_PJ
15290 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15291 && reloc_type == 1)
dda8d76d
NC
15292 || ((filedata->file_header.e_machine == EM_D30V
15293 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15294 && reloc_type == 12)
15295 || reloc_inplace)
39e07931
AS
15296 {
15297 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15298 addend += byte_get (rloc, reloc_size) & 0x3f;
15299 else
15300 addend += byte_get (rloc, reloc_size);
15301 }
cb8f3167 15302
dda8d76d
NC
15303 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15304 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15305 {
15306 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15307 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15308 addend -= 8;
91d6fa6a 15309 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15310 reloc_size);
15311 }
39e07931 15312 else if (is_6bit_abs_reloc (filedata, reloc_type)
76244462 15313 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
15314 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15315 {
15316 if (reloc_subtract)
15317 addend -= sym->st_value;
15318 else
15319 addend += sym->st_value;
15320 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15321 byte_put (rloc, addend, reloc_size);
15322 }
03336641
JW
15323 else if (reloc_subtract)
15324 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15325 else
91d6fa6a 15326 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15327 }
252b5132 15328
5b18a4bc 15329 free (symtab);
f84ce13b
NC
15330 /* Let the target specific reloc processing code know that
15331 we have finished with these relocs. */
dda8d76d 15332 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15333
15334 if (relocs_return)
15335 {
15336 * (Elf_Internal_Rela **) relocs_return = relocs;
15337 * num_relocs_return = num_relocs;
15338 }
15339 else
15340 free (relocs);
15341
5b18a4bc
NC
15342 break;
15343 }
32ec8896 15344
015dc7e1 15345 return true;
5b18a4bc 15346}
103f02d3 15347
cf13d699 15348#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15349static bool
dda8d76d 15350disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15351{
dda8d76d 15352 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15353
74e1a04b 15354 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15355
015dc7e1 15356 return true;
cf13d699
NC
15357}
15358#endif
15359
15360/* Reads in the contents of SECTION from FILE, returning a pointer
15361 to a malloc'ed buffer or NULL if something went wrong. */
15362
15363static char *
dda8d76d 15364get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15365{
be7d229a 15366 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15367
15368 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15369 {
c6b78c96 15370 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15371 printable_section_name (filedata, section));
cf13d699
NC
15372 return NULL;
15373 }
15374
dda8d76d 15375 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15376 _("section contents"));
cf13d699
NC
15377}
15378
1f5a3546 15379/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 15380
015dc7e1 15381static bool
45f5fe46
NC
15382uncompress_section_contents (bool is_zstd,
15383 unsigned char ** buffer,
15384 uint64_t uncompressed_size,
15385 uint64_t * size,
15386 uint64_t file_size)
0e602686 15387{
31e5a3a3
AM
15388 uint64_t compressed_size = *size;
15389 unsigned char *compressed_buffer = *buffer;
45f5fe46 15390 unsigned char *uncompressed_buffer = NULL;
0e602686
NC
15391 z_stream strm;
15392 int rc;
15393
45f5fe46
NC
15394 /* Similar to _bfd_section_size_insane() in the BFD library we expect an
15395 upper limit of ~10x compression. Any compression larger than that is
15396 thought to be due to fuzzing of the compression header. */
15397 if (uncompressed_size > file_size * 10)
15398 {
15399 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
15400 uncompressed_size);
15401 goto fail;
15402 }
15403
15404 uncompressed_buffer = xmalloc (uncompressed_size);
15405
1f5a3546
FS
15406 if (is_zstd)
15407 {
15408#ifdef HAVE_ZSTD
15409 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15410 compressed_buffer, compressed_size);
15411 if (ZSTD_isError (ret))
15412 goto fail;
15413#endif
15414 }
15415 else
15416 {
15417 /* It is possible the section consists of several compressed
15418 buffers concatenated together, so we uncompress in a loop. */
15419 /* PR 18313: The state field in the z_stream structure is supposed
15420 to be invisible to the user (ie us), but some compilers will
15421 still complain about it being used without initialisation. So
15422 we first zero the entire z_stream structure and then set the fields
15423 that we need. */
15424 memset (&strm, 0, sizeof strm);
15425 strm.avail_in = compressed_size;
15426 strm.next_in = (Bytef *)compressed_buffer;
15427 strm.avail_out = uncompressed_size;
15428
15429 rc = inflateInit (&strm);
15430 while (strm.avail_in > 0)
15431 {
15432 if (rc != Z_OK)
15433 break;
15434 strm.next_out = ((Bytef *)uncompressed_buffer
15435 + (uncompressed_size - strm.avail_out));
15436 rc = inflate (&strm, Z_FINISH);
15437 if (rc != Z_STREAM_END)
15438 break;
15439 rc = inflateReset (&strm);
15440 }
15441 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15442 goto fail;
15443 }
0e602686
NC
15444
15445 *buffer = uncompressed_buffer;
15446 *size = uncompressed_size;
015dc7e1 15447 return true;
0e602686
NC
15448
15449 fail:
15450 free (uncompressed_buffer);
15451 /* Indicate decompression failure. */
15452 *buffer = NULL;
015dc7e1 15453 return false;
0e602686 15454}
dd24e3da 15455
015dc7e1 15456static bool
dda8d76d 15457dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15458{
015dc7e1 15459 Elf_Internal_Shdr *relsec;
be7d229a 15460 uint64_t num_bytes;
015dc7e1
AM
15461 unsigned char *data;
15462 unsigned char *end;
15463 unsigned char *real_start;
15464 unsigned char *start;
15465 bool some_strings_shown;
cf13d699 15466
dda8d76d 15467 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15468 if (start == NULL)
c6b78c96 15469 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15470 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15471
0e602686 15472 num_bytes = section->sh_size;
cf13d699 15473
835f2fae
NC
15474 if (filedata->is_separate)
15475 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15476 printable_section_name (filedata, section),
15477 filedata->file_name);
15478 else
15479 printf (_("\nString dump of section '%s':\n"),
15480 printable_section_name (filedata, section));
cf13d699 15481
0e602686
NC
15482 if (decompress_dumps)
15483 {
31e5a3a3
AM
15484 uint64_t new_size = num_bytes;
15485 uint64_t uncompressed_size = 0;
1f5a3546 15486 bool is_zstd = false;
0e602686
NC
15487
15488 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15489 {
15490 Elf_Internal_Chdr chdr;
15491 unsigned int compression_header_size
ebdf1ebf
NC
15492 = get_compression_header (& chdr, (unsigned char *) start,
15493 num_bytes);
5844b465
NC
15494 if (compression_header_size == 0)
15495 /* An error message will have already been generated
15496 by get_compression_header. */
15497 goto error_out;
0e602686 15498
89dbeac7 15499 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
15500 ;
15501#ifdef HAVE_ZSTD
89dbeac7 15502 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
15503 is_zstd = true;
15504#endif
15505 else
0e602686 15506 {
813dabb9 15507 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15508 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15509 goto error_out;
813dabb9 15510 }
813dabb9
L
15511 uncompressed_size = chdr.ch_size;
15512 start += compression_header_size;
15513 new_size -= compression_header_size;
0e602686
NC
15514 }
15515 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15516 {
15517 /* Read the zlib header. In this case, it should be "ZLIB"
15518 followed by the uncompressed section size, 8 bytes in
15519 big-endian order. */
15520 uncompressed_size = start[4]; uncompressed_size <<= 8;
15521 uncompressed_size += start[5]; uncompressed_size <<= 8;
15522 uncompressed_size += start[6]; uncompressed_size <<= 8;
15523 uncompressed_size += start[7]; uncompressed_size <<= 8;
15524 uncompressed_size += start[8]; uncompressed_size <<= 8;
15525 uncompressed_size += start[9]; uncompressed_size <<= 8;
15526 uncompressed_size += start[10]; uncompressed_size <<= 8;
15527 uncompressed_size += start[11];
15528 start += 12;
15529 new_size -= 12;
15530 }
15531
1835f746
NC
15532 if (uncompressed_size)
15533 {
1f5a3546 15534 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 15535 &new_size, filedata->file_size))
1835f746
NC
15536 num_bytes = new_size;
15537 else
15538 {
15539 error (_("Unable to decompress section %s\n"),
dda8d76d 15540 printable_section_name (filedata, section));
f761cb13 15541 goto error_out;
1835f746
NC
15542 }
15543 }
bc303e5d
NC
15544 else
15545 start = real_start;
0e602686 15546 }
fd8008d8 15547
cf13d699
NC
15548 /* If the section being dumped has relocations against it the user might
15549 be expecting these relocations to have been applied. Check for this
15550 case and issue a warning message in order to avoid confusion.
15551 FIXME: Maybe we ought to have an option that dumps a section with
15552 relocs applied ? */
dda8d76d
NC
15553 for (relsec = filedata->section_headers;
15554 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15555 ++relsec)
15556 {
15557 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15558 || relsec->sh_info >= filedata->file_header.e_shnum
15559 || filedata->section_headers + relsec->sh_info != section
cf13d699 15560 || relsec->sh_size == 0
dda8d76d 15561 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15562 continue;
15563
15564 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15565 break;
15566 }
15567
cf13d699
NC
15568 data = start;
15569 end = start + num_bytes;
015dc7e1 15570 some_strings_shown = false;
cf13d699 15571
ba3265d0
NC
15572#ifdef HAVE_MBSTATE_T
15573 mbstate_t state;
15574 /* Initialise the multibyte conversion state. */
15575 memset (& state, 0, sizeof (state));
15576#endif
15577
015dc7e1 15578 bool continuing = false;
ba3265d0 15579
cf13d699
NC
15580 while (data < end)
15581 {
15582 while (!ISPRINT (* data))
15583 if (++ data >= end)
15584 break;
15585
15586 if (data < end)
15587 {
071436c6
NC
15588 size_t maxlen = end - data;
15589
ba3265d0
NC
15590 if (continuing)
15591 {
15592 printf (" ");
015dc7e1 15593 continuing = false;
ba3265d0
NC
15594 }
15595 else
15596 {
26c527e6 15597 printf (" [%6tx] ", data - start);
ba3265d0
NC
15598 }
15599
4082ef84
NC
15600 if (maxlen > 0)
15601 {
f3da8a96 15602 char c = 0;
ba3265d0
NC
15603
15604 while (maxlen)
15605 {
15606 c = *data++;
15607
15608 if (c == 0)
15609 break;
15610
15611 /* PR 25543: Treat new-lines as string-ending characters. */
15612 if (c == '\n')
15613 {
15614 printf ("\\n\n");
15615 if (*data != 0)
015dc7e1 15616 continuing = true;
ba3265d0
NC
15617 break;
15618 }
15619
15620 /* Do not print control characters directly as they can affect terminal
15621 settings. Such characters usually appear in the names generated
15622 by the assembler for local labels. */
15623 if (ISCNTRL (c))
15624 {
15625 printf ("^%c", c + 0x40);
15626 }
15627 else if (ISPRINT (c))
15628 {
15629 putchar (c);
15630 }
15631 else
15632 {
15633 size_t n;
15634#ifdef HAVE_MBSTATE_T
15635 wchar_t w;
15636#endif
15637 /* Let printf do the hard work of displaying multibyte characters. */
15638 printf ("%.1s", data - 1);
15639#ifdef HAVE_MBSTATE_T
15640 /* Try to find out how many bytes made up the character that was
15641 just printed. Advance the symbol pointer past the bytes that
15642 were displayed. */
15643 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15644#else
15645 n = 1;
15646#endif
15647 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15648 data += (n - 1);
15649 }
15650 }
15651
15652 if (c != '\n')
15653 putchar ('\n');
4082ef84
NC
15654 }
15655 else
15656 {
15657 printf (_("<corrupt>\n"));
15658 data = end;
15659 }
015dc7e1 15660 some_strings_shown = true;
cf13d699
NC
15661 }
15662 }
15663
15664 if (! some_strings_shown)
15665 printf (_(" No strings found in this section."));
15666
0e602686 15667 free (real_start);
cf13d699
NC
15668
15669 putchar ('\n');
015dc7e1 15670 return true;
f761cb13
AM
15671
15672error_out:
15673 free (real_start);
015dc7e1 15674 return false;
cf13d699
NC
15675}
15676
015dc7e1
AM
15677static bool
15678dump_section_as_bytes (Elf_Internal_Shdr *section,
15679 Filedata *filedata,
15680 bool relocate)
cf13d699 15681{
be7d229a
AM
15682 Elf_Internal_Shdr *relsec;
15683 size_t bytes;
15684 uint64_t section_size;
625d49fc 15685 uint64_t addr;
be7d229a
AM
15686 unsigned char *data;
15687 unsigned char *real_start;
15688 unsigned char *start;
0e602686 15689
dda8d76d 15690 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15691 if (start == NULL)
c6b78c96 15692 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15693 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15694
0e602686 15695 section_size = section->sh_size;
cf13d699 15696
835f2fae
NC
15697 if (filedata->is_separate)
15698 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15699 printable_section_name (filedata, section),
15700 filedata->file_name);
15701 else
15702 printf (_("\nHex dump of section '%s':\n"),
15703 printable_section_name (filedata, section));
cf13d699 15704
0e602686
NC
15705 if (decompress_dumps)
15706 {
31e5a3a3
AM
15707 uint64_t new_size = section_size;
15708 uint64_t uncompressed_size = 0;
1f5a3546 15709 bool is_zstd = false;
0e602686
NC
15710
15711 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15712 {
15713 Elf_Internal_Chdr chdr;
15714 unsigned int compression_header_size
ebdf1ebf 15715 = get_compression_header (& chdr, start, section_size);
0e602686 15716
5844b465
NC
15717 if (compression_header_size == 0)
15718 /* An error message will have already been generated
15719 by get_compression_header. */
15720 goto error_out;
15721
89dbeac7 15722 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
15723 ;
15724#ifdef HAVE_ZSTD
89dbeac7 15725 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
15726 is_zstd = true;
15727#endif
15728 else
0e602686 15729 {
813dabb9 15730 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15731 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15732 goto error_out;
0e602686 15733 }
813dabb9
L
15734 uncompressed_size = chdr.ch_size;
15735 start += compression_header_size;
15736 new_size -= compression_header_size;
0e602686
NC
15737 }
15738 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15739 {
15740 /* Read the zlib header. In this case, it should be "ZLIB"
15741 followed by the uncompressed section size, 8 bytes in
15742 big-endian order. */
15743 uncompressed_size = start[4]; uncompressed_size <<= 8;
15744 uncompressed_size += start[5]; uncompressed_size <<= 8;
15745 uncompressed_size += start[6]; uncompressed_size <<= 8;
15746 uncompressed_size += start[7]; uncompressed_size <<= 8;
15747 uncompressed_size += start[8]; uncompressed_size <<= 8;
15748 uncompressed_size += start[9]; uncompressed_size <<= 8;
15749 uncompressed_size += start[10]; uncompressed_size <<= 8;
15750 uncompressed_size += start[11];
15751 start += 12;
15752 new_size -= 12;
15753 }
15754
f055032e
NC
15755 if (uncompressed_size)
15756 {
1f5a3546 15757 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 15758 &new_size, filedata->file_size))
bc303e5d
NC
15759 {
15760 section_size = new_size;
15761 }
f055032e
NC
15762 else
15763 {
15764 error (_("Unable to decompress section %s\n"),
dda8d76d 15765 printable_section_name (filedata, section));
bc303e5d 15766 /* FIXME: Print the section anyway ? */
f761cb13 15767 goto error_out;
f055032e
NC
15768 }
15769 }
bc303e5d
NC
15770 else
15771 start = real_start;
0e602686 15772 }
14ae95f2 15773
cf13d699
NC
15774 if (relocate)
15775 {
dda8d76d 15776 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15777 goto error_out;
cf13d699
NC
15778 }
15779 else
15780 {
15781 /* If the section being dumped has relocations against it the user might
15782 be expecting these relocations to have been applied. Check for this
15783 case and issue a warning message in order to avoid confusion.
15784 FIXME: Maybe we ought to have an option that dumps a section with
15785 relocs applied ? */
dda8d76d
NC
15786 for (relsec = filedata->section_headers;
15787 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15788 ++relsec)
15789 {
15790 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15791 || relsec->sh_info >= filedata->file_header.e_shnum
15792 || filedata->section_headers + relsec->sh_info != section
cf13d699 15793 || relsec->sh_size == 0
dda8d76d 15794 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15795 continue;
15796
15797 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15798 break;
15799 }
15800 }
15801
15802 addr = section->sh_addr;
0e602686 15803 bytes = section_size;
cf13d699
NC
15804 data = start;
15805
15806 while (bytes)
15807 {
15808 int j;
15809 int k;
15810 int lbytes;
15811
15812 lbytes = (bytes > 16 ? 16 : bytes);
15813
26c527e6 15814 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
15815
15816 for (j = 0; j < 16; j++)
15817 {
15818 if (j < lbytes)
15819 printf ("%2.2x", data[j]);
15820 else
15821 printf (" ");
15822
15823 if ((j & 3) == 3)
15824 printf (" ");
15825 }
15826
15827 for (j = 0; j < lbytes; j++)
15828 {
15829 k = data[j];
15830 if (k >= ' ' && k < 0x7f)
15831 printf ("%c", k);
15832 else
15833 printf (".");
15834 }
15835
15836 putchar ('\n');
15837
15838 data += lbytes;
15839 addr += lbytes;
15840 bytes -= lbytes;
15841 }
15842
0e602686 15843 free (real_start);
cf13d699
NC
15844
15845 putchar ('\n');
015dc7e1 15846 return true;
f761cb13
AM
15847
15848 error_out:
15849 free (real_start);
015dc7e1 15850 return false;
cf13d699
NC
15851}
15852
094e34f2 15853#ifdef ENABLE_LIBCTF
7d9813f1
NA
15854static ctf_sect_t *
15855shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15856{
84714f86 15857 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15858 buf->cts_size = shdr->sh_size;
15859 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15860
15861 return buf;
15862}
15863
15864/* Formatting callback function passed to ctf_dump. Returns either the pointer
15865 it is passed, or a pointer to newly-allocated storage, in which case
15866 dump_ctf() will free it when it no longer needs it. */
15867
2f6ecaed
NA
15868static char *
15869dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15870 char *s, void *arg)
7d9813f1 15871{
3e50a591 15872 const char *blanks = arg;
7d9813f1
NA
15873 char *new_s;
15874
3e50a591 15875 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15876 return s;
15877 return new_s;
15878}
15879
926c9e76
NA
15880/* Dump CTF errors/warnings. */
15881static void
139633c3 15882dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15883{
15884 ctf_next_t *it = NULL;
15885 char *errtext;
15886 int is_warning;
15887 int err;
15888
15889 /* Dump accumulated errors and warnings. */
15890 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15891 {
5e9b84f7 15892 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15893 errtext);
15894 free (errtext);
15895 }
15896 if (err != ECTF_NEXT_END)
15897 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15898}
15899
2f6ecaed
NA
15900/* Dump one CTF archive member. */
15901
80b56fad
NA
15902static void
15903dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15904 size_t member)
2f6ecaed 15905{
2f6ecaed
NA
15906 const char *things[] = {"Header", "Labels", "Data objects",
15907 "Function objects", "Variables", "Types", "Strings",
15908 ""};
15909 const char **thing;
15910 size_t i;
15911
80b56fad
NA
15912 /* Don't print out the name of the default-named archive member if it appears
15913 first in the list. The name .ctf appears everywhere, even for things that
15914 aren't really archives, so printing it out is liable to be confusing; also,
15915 the common case by far is for only one archive member to exist, and hiding
15916 it in that case seems worthwhile. */
2f6ecaed 15917
80b56fad
NA
15918 if (strcmp (name, ".ctf") != 0 || member != 0)
15919 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15920
80b56fad
NA
15921 if (ctf_parent_name (ctf) != NULL)
15922 ctf_import (ctf, parent);
2f6ecaed
NA
15923
15924 for (i = 0, thing = things; *thing[0]; thing++, i++)
15925 {
15926 ctf_dump_state_t *s = NULL;
15927 char *item;
15928
15929 printf ("\n %s:\n", *thing);
15930 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15931 (void *) " ")) != NULL)
15932 {
15933 printf ("%s\n", item);
15934 free (item);
15935 }
15936
15937 if (ctf_errno (ctf))
15938 {
15939 error (_("Iteration failed: %s, %s\n"), *thing,
15940 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15941 break;
2f6ecaed
NA
15942 }
15943 }
8b37e7b6 15944
926c9e76 15945 dump_ctf_errs (ctf);
2f6ecaed
NA
15946}
15947
015dc7e1 15948static bool
7d9813f1
NA
15949dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15950{
7d9813f1
NA
15951 Elf_Internal_Shdr * symtab_sec = NULL;
15952 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15953 void * data = NULL;
15954 void * symdata = NULL;
15955 void * strdata = NULL;
80b56fad 15956 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15957 ctf_sect_t * symsectp = NULL;
15958 ctf_sect_t * strsectp = NULL;
2f6ecaed 15959 ctf_archive_t * ctfa = NULL;
139633c3 15960 ctf_dict_t * parent = NULL;
80b56fad 15961 ctf_dict_t * fp;
7d9813f1 15962
80b56fad
NA
15963 ctf_next_t *i = NULL;
15964 const char *name;
15965 size_t member = 0;
7d9813f1 15966 int err;
015dc7e1 15967 bool ret = false;
7d9813f1
NA
15968
15969 shdr_to_ctf_sect (&ctfsect, section, filedata);
15970 data = get_section_contents (section, filedata);
15971 ctfsect.cts_data = data;
15972
616febde 15973 if (!dump_ctf_symtab_name)
3d16b64e 15974 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15975
15976 if (!dump_ctf_strtab_name)
3d16b64e 15977 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15978
15979 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15980 {
15981 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15982 {
15983 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15984 goto fail;
15985 }
15986 if ((symdata = (void *) get_data (NULL, filedata,
15987 symtab_sec->sh_offset, 1,
15988 symtab_sec->sh_size,
15989 _("symbols"))) == NULL)
15990 goto fail;
15991 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15992 symsect.cts_data = symdata;
15993 }
835f2fae 15994
df16e041 15995 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15996 {
15997 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15998 {
15999 error (_("No string table section named %s\n"),
16000 dump_ctf_strtab_name);
16001 goto fail;
16002 }
16003 if ((strdata = (void *) get_data (NULL, filedata,
16004 strtab_sec->sh_offset, 1,
16005 strtab_sec->sh_size,
16006 _("strings"))) == NULL)
16007 goto fail;
16008 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
16009 strsect.cts_data = strdata;
16010 }
835f2fae 16011
2f6ecaed
NA
16012 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
16013 libctf papers over the difference, so we can pretend it is always an
80b56fad 16014 archive. */
7d9813f1 16015
2f6ecaed 16016 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 16017 {
926c9e76 16018 dump_ctf_errs (NULL);
7d9813f1
NA
16019 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16020 goto fail;
16021 }
16022
96c61be5
NA
16023 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
16024 != ELFDATA2MSB);
16025
80b56fad
NA
16026 /* Preload the parent dict, since it will need to be imported into every
16027 child in turn. */
16028 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 16029 {
926c9e76 16030 dump_ctf_errs (NULL);
2f6ecaed
NA
16031 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16032 goto fail;
7d9813f1
NA
16033 }
16034
015dc7e1 16035 ret = true;
7d9813f1 16036
835f2fae
NC
16037 if (filedata->is_separate)
16038 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
16039 printable_section_name (filedata, section),
16040 filedata->file_name);
16041 else
16042 printf (_("\nDump of CTF section '%s':\n"),
16043 printable_section_name (filedata, section));
7d9813f1 16044
80b56fad
NA
16045 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
16046 dump_ctf_archive_member (fp, name, parent, member++);
16047 if (err != ECTF_NEXT_END)
16048 {
16049 dump_ctf_errs (NULL);
16050 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
16051 ret = false;
16052 }
7d9813f1
NA
16053
16054 fail:
139633c3 16055 ctf_dict_close (parent);
2f6ecaed 16056 ctf_close (ctfa);
7d9813f1
NA
16057 free (data);
16058 free (symdata);
16059 free (strdata);
16060 return ret;
16061}
094e34f2 16062#endif
7d9813f1 16063
42b6953b
IB
16064static bool
16065dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
16066{
16067 void * data = NULL;
16068 sframe_decoder_ctx *sfd_ctx = NULL;
16069 const char *print_name = printable_section_name (filedata, section);
16070
16071 bool ret = true;
16072 size_t sf_size;
16073 int err = 0;
16074
16075 if (strcmp (print_name, "") == 0)
16076 {
16077 error (_("Section name must be provided \n"));
16078 ret = false;
16079 return ret;
16080 }
16081
16082 data = get_section_contents (section, filedata);
16083 sf_size = section->sh_size;
16084 /* Decode the contents of the section. */
16085 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
16086 if (!sfd_ctx)
16087 {
16088 ret = false;
16089 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
16090 goto fail;
16091 }
16092
16093 printf (_("Contents of the SFrame section %s:"), print_name);
16094 /* Dump the contents as text. */
16095 dump_sframe (sfd_ctx, section->sh_addr);
16096
16097 fail:
16098 free (data);
16099 return ret;
16100}
16101
015dc7e1 16102static bool
dda8d76d
NC
16103load_specific_debug_section (enum dwarf_section_display_enum debug,
16104 const Elf_Internal_Shdr * sec,
16105 void * data)
1007acb3 16106{
2cf0635d 16107 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 16108 char buf [64];
dda8d76d 16109 Filedata * filedata = (Filedata *) data;
9abca702 16110
19e6b90e 16111 if (section->start != NULL)
dda8d76d
NC
16112 {
16113 /* If it is already loaded, do nothing. */
16114 if (streq (section->filename, filedata->file_name))
015dc7e1 16115 return true;
dda8d76d
NC
16116 free (section->start);
16117 }
1007acb3 16118
19e6b90e
L
16119 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16120 section->address = sec->sh_addr;
dda8d76d
NC
16121 section->filename = filedata->file_name;
16122 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
16123 sec->sh_offset, 1,
16124 sec->sh_size, buf);
59245841
NC
16125 if (section->start == NULL)
16126 section->size = 0;
16127 else
16128 {
77115a4a 16129 unsigned char *start = section->start;
31e5a3a3
AM
16130 uint64_t size = sec->sh_size;
16131 uint64_t uncompressed_size = 0;
1f5a3546 16132 bool is_zstd = false;
77115a4a
L
16133
16134 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16135 {
16136 Elf_Internal_Chdr chdr;
d8024a91
NC
16137 unsigned int compression_header_size;
16138
f53be977
L
16139 if (size < (is_32bit_elf
16140 ? sizeof (Elf32_External_Chdr)
16141 : sizeof (Elf64_External_Chdr)))
d8024a91 16142 {
55be8fd0 16143 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 16144 section->name);
015dc7e1 16145 return false;
d8024a91
NC
16146 }
16147
ebdf1ebf 16148 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
16149 if (compression_header_size == 0)
16150 /* An error message will have already been generated
16151 by get_compression_header. */
015dc7e1 16152 return false;
d8024a91 16153
89dbeac7 16154 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16155 ;
16156#ifdef HAVE_ZSTD
89dbeac7 16157 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16158 is_zstd = true;
16159#endif
16160 else
813dabb9
L
16161 {
16162 warn (_("section '%s' has unsupported compress type: %d\n"),
16163 section->name, chdr.ch_type);
015dc7e1 16164 return false;
813dabb9 16165 }
dab394de 16166 uncompressed_size = chdr.ch_size;
77115a4a
L
16167 start += compression_header_size;
16168 size -= compression_header_size;
16169 }
dab394de
L
16170 else if (size > 12 && streq ((char *) start, "ZLIB"))
16171 {
16172 /* Read the zlib header. In this case, it should be "ZLIB"
16173 followed by the uncompressed section size, 8 bytes in
16174 big-endian order. */
16175 uncompressed_size = start[4]; uncompressed_size <<= 8;
16176 uncompressed_size += start[5]; uncompressed_size <<= 8;
16177 uncompressed_size += start[6]; uncompressed_size <<= 8;
16178 uncompressed_size += start[7]; uncompressed_size <<= 8;
16179 uncompressed_size += start[8]; uncompressed_size <<= 8;
16180 uncompressed_size += start[9]; uncompressed_size <<= 8;
16181 uncompressed_size += start[10]; uncompressed_size <<= 8;
16182 uncompressed_size += start[11];
16183 start += 12;
16184 size -= 12;
16185 }
16186
1835f746 16187 if (uncompressed_size)
77115a4a 16188 {
1f5a3546 16189 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16190 &size, filedata->file_size))
1835f746
NC
16191 {
16192 /* Free the compressed buffer, update the section buffer
16193 and the section size if uncompress is successful. */
16194 free (section->start);
16195 section->start = start;
16196 }
16197 else
16198 {
16199 error (_("Unable to decompress section %s\n"),
dda8d76d 16200 printable_section_name (filedata, sec));
015dc7e1 16201 return false;
1835f746 16202 }
77115a4a 16203 }
bc303e5d 16204
77115a4a 16205 section->size = size;
59245841 16206 }
4a114e3e 16207
1b315056 16208 if (section->start == NULL)
015dc7e1 16209 return false;
1b315056 16210
19e6b90e 16211 if (debug_displays [debug].relocate)
32ec8896 16212 {
dda8d76d 16213 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 16214 & section->reloc_info, & section->num_relocs))
015dc7e1 16215 return false;
32ec8896 16216 }
d1c4b12b
NC
16217 else
16218 {
16219 section->reloc_info = NULL;
16220 section->num_relocs = 0;
16221 }
1007acb3 16222
015dc7e1 16223 return true;
1007acb3
L
16224}
16225
301a9420
AM
16226#if HAVE_LIBDEBUGINFOD
16227/* Return a hex string representation of the build-id. */
16228unsigned char *
16229get_build_id (void * data)
16230{
ca0e11aa 16231 Filedata * filedata = (Filedata *) data;
301a9420 16232 Elf_Internal_Shdr * shdr;
26c527e6 16233 size_t i;
301a9420 16234
55be8fd0
NC
16235 /* Iterate through notes to find note.gnu.build-id.
16236 FIXME: Only the first note in any note section is examined. */
301a9420
AM
16237 for (i = 0, shdr = filedata->section_headers;
16238 i < filedata->file_header.e_shnum && shdr != NULL;
16239 i++, shdr++)
16240 {
16241 if (shdr->sh_type != SHT_NOTE)
16242 continue;
16243
16244 char * next;
16245 char * end;
16246 size_t data_remaining;
16247 size_t min_notesz;
16248 Elf_External_Note * enote;
16249 Elf_Internal_Note inote;
16250
625d49fc
AM
16251 uint64_t offset = shdr->sh_offset;
16252 uint64_t align = shdr->sh_addralign;
16253 uint64_t length = shdr->sh_size;
301a9420
AM
16254
16255 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16256 if (enote == NULL)
16257 continue;
16258
16259 if (align < 4)
16260 align = 4;
16261 else if (align != 4 && align != 8)
f761cb13
AM
16262 {
16263 free (enote);
16264 continue;
16265 }
301a9420
AM
16266
16267 end = (char *) enote + length;
16268 data_remaining = end - (char *) enote;
16269
16270 if (!is_ia64_vms (filedata))
16271 {
16272 min_notesz = offsetof (Elf_External_Note, name);
16273 if (data_remaining < min_notesz)
16274 {
55be8fd0
NC
16275 warn (_("\
16276malformed note encountered in section %s whilst scanning for build-id note\n"),
16277 printable_section_name (filedata, shdr));
f761cb13 16278 free (enote);
55be8fd0 16279 continue;
301a9420
AM
16280 }
16281 data_remaining -= min_notesz;
16282
16283 inote.type = BYTE_GET (enote->type);
16284 inote.namesz = BYTE_GET (enote->namesz);
16285 inote.namedata = enote->name;
16286 inote.descsz = BYTE_GET (enote->descsz);
16287 inote.descdata = ((char *) enote
16288 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16289 inote.descpos = offset + (inote.descdata - (char *) enote);
16290 next = ((char *) enote
16291 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16292 }
16293 else
16294 {
16295 Elf64_External_VMS_Note *vms_enote;
16296
16297 /* PR binutils/15191
16298 Make sure that there is enough data to read. */
16299 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16300 if (data_remaining < min_notesz)
16301 {
55be8fd0
NC
16302 warn (_("\
16303malformed note encountered in section %s whilst scanning for build-id note\n"),
16304 printable_section_name (filedata, shdr));
f761cb13 16305 free (enote);
55be8fd0 16306 continue;
301a9420
AM
16307 }
16308 data_remaining -= min_notesz;
16309
16310 vms_enote = (Elf64_External_VMS_Note *) enote;
16311 inote.type = BYTE_GET (vms_enote->type);
16312 inote.namesz = BYTE_GET (vms_enote->namesz);
16313 inote.namedata = vms_enote->name;
16314 inote.descsz = BYTE_GET (vms_enote->descsz);
16315 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16316 inote.descpos = offset + (inote.descdata - (char *) enote);
16317 next = inote.descdata + align_power (inote.descsz, 3);
16318 }
16319
16320 /* Skip malformed notes. */
16321 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16322 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16323 || (size_t) (next - inote.descdata) < inote.descsz
16324 || ((size_t) (next - inote.descdata)
16325 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16326 {
55be8fd0
NC
16327 warn (_("\
16328malformed note encountered in section %s whilst scanning for build-id note\n"),
16329 printable_section_name (filedata, shdr));
f761cb13 16330 free (enote);
301a9420
AM
16331 continue;
16332 }
16333
16334 /* Check if this is the build-id note. If so then convert the build-id
16335 bytes to a hex string. */
16336 if (inote.namesz > 0
24d127aa 16337 && startswith (inote.namedata, "GNU")
301a9420
AM
16338 && inote.type == NT_GNU_BUILD_ID)
16339 {
26c527e6 16340 size_t j;
301a9420
AM
16341 char * build_id;
16342
16343 build_id = malloc (inote.descsz * 2 + 1);
16344 if (build_id == NULL)
f761cb13
AM
16345 {
16346 free (enote);
16347 return NULL;
16348 }
301a9420
AM
16349
16350 for (j = 0; j < inote.descsz; ++j)
16351 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16352 build_id[inote.descsz * 2] = '\0';
f761cb13 16353 free (enote);
301a9420 16354
55be8fd0 16355 return (unsigned char *) build_id;
301a9420 16356 }
f761cb13 16357 free (enote);
301a9420
AM
16358 }
16359
16360 return NULL;
16361}
16362#endif /* HAVE_LIBDEBUGINFOD */
16363
657d0d47
CC
16364/* If this is not NULL, load_debug_section will only look for sections
16365 within the list of sections given here. */
32ec8896 16366static unsigned int * section_subset = NULL;
657d0d47 16367
015dc7e1 16368bool
dda8d76d 16369load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16370{
2cf0635d
NC
16371 struct dwarf_section * section = &debug_displays [debug].section;
16372 Elf_Internal_Shdr * sec;
dda8d76d
NC
16373 Filedata * filedata = (Filedata *) data;
16374
e1dbfc17
L
16375 if (!dump_any_debugging)
16376 return false;
16377
f425ec66
NC
16378 /* Without section headers we cannot find any sections. */
16379 if (filedata->section_headers == NULL)
015dc7e1 16380 return false;
f425ec66 16381
9c1ce108
AM
16382 if (filedata->string_table == NULL
16383 && filedata->file_header.e_shstrndx != SHN_UNDEF
16384 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16385 {
16386 Elf_Internal_Shdr * strs;
16387
16388 /* Read in the string table, so that we have section names to scan. */
16389 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16390
4dff97b2 16391 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16392 {
9c1ce108
AM
16393 filedata->string_table
16394 = (char *) get_data (NULL, filedata, strs->sh_offset,
16395 1, strs->sh_size, _("string table"));
dda8d76d 16396
9c1ce108
AM
16397 filedata->string_table_length
16398 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16399 }
16400 }
d966045b
DJ
16401
16402 /* Locate the debug section. */
dda8d76d 16403 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16404 if (sec != NULL)
16405 section->name = section->uncompressed_name;
16406 else
16407 {
dda8d76d 16408 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16409 if (sec != NULL)
16410 section->name = section->compressed_name;
16411 }
16412 if (sec == NULL)
015dc7e1 16413 return false;
d966045b 16414
657d0d47
CC
16415 /* If we're loading from a subset of sections, and we've loaded
16416 a section matching this name before, it's likely that it's a
16417 different one. */
16418 if (section_subset != NULL)
16419 free_debug_section (debug);
16420
dda8d76d 16421 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16422}
16423
19e6b90e
L
16424void
16425free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16426{
2cf0635d 16427 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16428
19e6b90e
L
16429 if (section->start == NULL)
16430 return;
1007acb3 16431
19e6b90e
L
16432 free ((char *) section->start);
16433 section->start = NULL;
16434 section->address = 0;
16435 section->size = 0;
a788aedd 16436
9db70fc3
AM
16437 free (section->reloc_info);
16438 section->reloc_info = NULL;
16439 section->num_relocs = 0;
1007acb3
L
16440}
16441
015dc7e1 16442static bool
dda8d76d 16443display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16444{
84714f86
AM
16445 const char *name = (section_name_valid (filedata, section)
16446 ? section_name (filedata, section) : "");
16447 const char *print_name = printable_section_name (filedata, section);
be7d229a 16448 uint64_t length;
015dc7e1 16449 bool result = true;
3f5e193b 16450 int i;
1007acb3 16451
19e6b90e
L
16452 length = section->sh_size;
16453 if (length == 0)
1007acb3 16454 {
74e1a04b 16455 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16456 return true;
1007acb3 16457 }
5dff79d8
NC
16458 if (section->sh_type == SHT_NOBITS)
16459 {
16460 /* There is no point in dumping the contents of a debugging section
16461 which has the NOBITS type - the bits in the file will be random.
16462 This can happen when a file containing a .eh_frame section is
16463 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16464 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16465 print_name);
015dc7e1 16466 return false;
5dff79d8 16467 }
1007acb3 16468
24d127aa 16469 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16470 name = ".debug_info";
1007acb3 16471
19e6b90e
L
16472 /* See if we know how to display the contents of this section. */
16473 for (i = 0; i < max; i++)
d85bf2ba
NC
16474 {
16475 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16476 struct dwarf_section_display * display = debug_displays + i;
16477 struct dwarf_section * sec = & display->section;
d966045b 16478
d85bf2ba 16479 if (streq (sec->uncompressed_name, name)
24d127aa 16480 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16481 || streq (sec->compressed_name, name))
16482 {
015dc7e1 16483 bool secondary = (section != find_section (filedata, name));
1007acb3 16484
d85bf2ba
NC
16485 if (secondary)
16486 free_debug_section (id);
dda8d76d 16487
24d127aa 16488 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16489 sec->name = name;
16490 else if (streq (sec->uncompressed_name, name))
16491 sec->name = sec->uncompressed_name;
16492 else
16493 sec->name = sec->compressed_name;
657d0d47 16494
d85bf2ba
NC
16495 if (load_specific_debug_section (id, section, filedata))
16496 {
16497 /* If this debug section is part of a CU/TU set in a .dwp file,
16498 restrict load_debug_section to the sections in that set. */
16499 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16500
d85bf2ba 16501 result &= display->display (sec, filedata);
657d0d47 16502
d85bf2ba 16503 section_subset = NULL;
1007acb3 16504
44266f36 16505 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16506 free_debug_section (id);
16507 }
16508 break;
16509 }
16510 }
1007acb3 16511
19e6b90e 16512 if (i == max)
1007acb3 16513 {
74e1a04b 16514 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16515 result = false;
1007acb3
L
16516 }
16517
19e6b90e 16518 return result;
5b18a4bc 16519}
103f02d3 16520
aef1f6d0
DJ
16521/* Set DUMP_SECTS for all sections where dumps were requested
16522 based on section name. */
16523
16524static void
dda8d76d 16525initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16526{
2cf0635d 16527 struct dump_list_entry * cur;
aef1f6d0
DJ
16528
16529 for (cur = dump_sects_byname; cur; cur = cur->next)
16530 {
16531 unsigned int i;
015dc7e1 16532 bool any = false;
aef1f6d0 16533
dda8d76d 16534 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16535 if (section_name_valid (filedata, filedata->section_headers + i)
16536 && streq (section_name (filedata, filedata->section_headers + i),
16537 cur->name))
aef1f6d0 16538 {
6431e409 16539 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16540 any = true;
aef1f6d0
DJ
16541 }
16542
835f2fae
NC
16543 if (!any && !filedata->is_separate)
16544 warn (_("Section '%s' was not dumped because it does not exist\n"),
16545 cur->name);
aef1f6d0
DJ
16546 }
16547}
16548
015dc7e1 16549static bool
dda8d76d 16550process_section_contents (Filedata * filedata)
5b18a4bc 16551{
2cf0635d 16552 Elf_Internal_Shdr * section;
19e6b90e 16553 unsigned int i;
015dc7e1 16554 bool res = true;
103f02d3 16555
19e6b90e 16556 if (! do_dump)
015dc7e1 16557 return true;
103f02d3 16558
dda8d76d 16559 initialise_dumps_byname (filedata);
aef1f6d0 16560
dda8d76d 16561 for (i = 0, section = filedata->section_headers;
6431e409 16562 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16563 i++, section++)
16564 {
6431e409 16565 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16566
d6bfbc39
NC
16567 if (filedata->is_separate && ! process_links)
16568 dump &= DEBUG_DUMP;
047c3dbf 16569
19e6b90e 16570#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16571 if (dump & DISASS_DUMP)
16572 {
16573 if (! disassemble_section (section, filedata))
015dc7e1 16574 res = false;
dda8d76d 16575 }
19e6b90e 16576#endif
dda8d76d 16577 if (dump & HEX_DUMP)
32ec8896 16578 {
015dc7e1
AM
16579 if (! dump_section_as_bytes (section, filedata, false))
16580 res = false;
32ec8896 16581 }
103f02d3 16582
dda8d76d 16583 if (dump & RELOC_DUMP)
32ec8896 16584 {
015dc7e1
AM
16585 if (! dump_section_as_bytes (section, filedata, true))
16586 res = false;
32ec8896 16587 }
09c11c86 16588
dda8d76d 16589 if (dump & STRING_DUMP)
32ec8896 16590 {
dda8d76d 16591 if (! dump_section_as_strings (section, filedata))
015dc7e1 16592 res = false;
32ec8896 16593 }
cf13d699 16594
dda8d76d 16595 if (dump & DEBUG_DUMP)
32ec8896 16596 {
dda8d76d 16597 if (! display_debug_section (i, section, filedata))
015dc7e1 16598 res = false;
32ec8896 16599 }
7d9813f1 16600
094e34f2 16601#ifdef ENABLE_LIBCTF
7d9813f1
NA
16602 if (dump & CTF_DUMP)
16603 {
16604 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16605 res = false;
7d9813f1 16606 }
094e34f2 16607#endif
42b6953b
IB
16608 if (dump & SFRAME_DUMP)
16609 {
16610 if (! dump_section_as_sframe (section, filedata))
16611 res = false;
16612 }
5b18a4bc 16613 }
103f02d3 16614
835f2fae 16615 if (! filedata->is_separate)
0ee3043f 16616 {
835f2fae
NC
16617 /* Check to see if the user requested a
16618 dump of a section that does not exist. */
16619 for (; i < filedata->dump.num_dump_sects; i++)
16620 if (filedata->dump.dump_sects[i])
16621 {
ca0e11aa 16622 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16623 res = false;
835f2fae 16624 }
0ee3043f 16625 }
32ec8896
NC
16626
16627 return res;
5b18a4bc 16628}
103f02d3 16629
5b18a4bc 16630static void
19e6b90e 16631process_mips_fpe_exception (int mask)
5b18a4bc 16632{
19e6b90e
L
16633 if (mask)
16634 {
015dc7e1 16635 bool first = true;
32ec8896 16636
19e6b90e 16637 if (mask & OEX_FPU_INEX)
015dc7e1 16638 fputs ("INEX", stdout), first = false;
19e6b90e 16639 if (mask & OEX_FPU_UFLO)
015dc7e1 16640 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16641 if (mask & OEX_FPU_OFLO)
015dc7e1 16642 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16643 if (mask & OEX_FPU_DIV0)
015dc7e1 16644 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16645 if (mask & OEX_FPU_INVAL)
16646 printf ("%sINVAL", first ? "" : "|");
16647 }
5b18a4bc 16648 else
19e6b90e 16649 fputs ("0", stdout);
5b18a4bc 16650}
103f02d3 16651
f6f0e17b
NC
16652/* Display's the value of TAG at location P. If TAG is
16653 greater than 0 it is assumed to be an unknown tag, and
16654 a message is printed to this effect. Otherwise it is
16655 assumed that a message has already been printed.
16656
16657 If the bottom bit of TAG is set it assumed to have a
16658 string value, otherwise it is assumed to have an integer
16659 value.
16660
16661 Returns an updated P pointing to the first unread byte
16662 beyond the end of TAG's value.
16663
16664 Reads at or beyond END will not be made. */
16665
16666static unsigned char *
60abdbed 16667display_tag_value (signed int tag,
f6f0e17b
NC
16668 unsigned char * p,
16669 const unsigned char * const end)
16670{
26c527e6 16671 uint64_t val;
f6f0e17b
NC
16672
16673 if (tag > 0)
16674 printf (" Tag_unknown_%d: ", tag);
16675
16676 if (p >= end)
16677 {
4082ef84 16678 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16679 }
16680 else if (tag & 1)
16681 {
071436c6
NC
16682 /* PR 17531 file: 027-19978-0.004. */
16683 size_t maxlen = (end - p) - 1;
16684
16685 putchar ('"');
4082ef84
NC
16686 if (maxlen > 0)
16687 {
16688 print_symbol ((int) maxlen, (const char *) p);
16689 p += strnlen ((char *) p, maxlen) + 1;
16690 }
16691 else
16692 {
16693 printf (_("<corrupt string tag>"));
16694 p = (unsigned char *) end;
16695 }
071436c6 16696 printf ("\"\n");
f6f0e17b
NC
16697 }
16698 else
16699 {
cd30bcef 16700 READ_ULEB (val, p, end);
26c527e6 16701 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
16702 }
16703
4082ef84 16704 assert (p <= end);
f6f0e17b
NC
16705 return p;
16706}
16707
53a346d8
CZ
16708/* ARC ABI attributes section. */
16709
16710static unsigned char *
16711display_arc_attribute (unsigned char * p,
16712 const unsigned char * const end)
16713{
16714 unsigned int tag;
53a346d8
CZ
16715 unsigned int val;
16716
cd30bcef 16717 READ_ULEB (tag, p, end);
53a346d8
CZ
16718
16719 switch (tag)
16720 {
16721 case Tag_ARC_PCS_config:
cd30bcef 16722 READ_ULEB (val, p, end);
53a346d8
CZ
16723 printf (" Tag_ARC_PCS_config: ");
16724 switch (val)
16725 {
16726 case 0:
16727 printf (_("Absent/Non standard\n"));
16728 break;
16729 case 1:
16730 printf (_("Bare metal/mwdt\n"));
16731 break;
16732 case 2:
16733 printf (_("Bare metal/newlib\n"));
16734 break;
16735 case 3:
16736 printf (_("Linux/uclibc\n"));
16737 break;
16738 case 4:
16739 printf (_("Linux/glibc\n"));
16740 break;
16741 default:
16742 printf (_("Unknown\n"));
16743 break;
16744 }
16745 break;
16746
16747 case Tag_ARC_CPU_base:
cd30bcef 16748 READ_ULEB (val, p, end);
53a346d8
CZ
16749 printf (" Tag_ARC_CPU_base: ");
16750 switch (val)
16751 {
16752 default:
16753 case TAG_CPU_NONE:
16754 printf (_("Absent\n"));
16755 break;
16756 case TAG_CPU_ARC6xx:
16757 printf ("ARC6xx\n");
16758 break;
16759 case TAG_CPU_ARC7xx:
16760 printf ("ARC7xx\n");
16761 break;
16762 case TAG_CPU_ARCEM:
16763 printf ("ARCEM\n");
16764 break;
16765 case TAG_CPU_ARCHS:
16766 printf ("ARCHS\n");
16767 break;
16768 }
16769 break;
16770
16771 case Tag_ARC_CPU_variation:
cd30bcef 16772 READ_ULEB (val, p, end);
53a346d8
CZ
16773 printf (" Tag_ARC_CPU_variation: ");
16774 switch (val)
16775 {
16776 default:
16777 if (val > 0 && val < 16)
53a346d8 16778 printf ("Core%d\n", val);
d8cbc93b
JL
16779 else
16780 printf ("Unknown\n");
16781 break;
16782
53a346d8
CZ
16783 case 0:
16784 printf (_("Absent\n"));
16785 break;
16786 }
16787 break;
16788
16789 case Tag_ARC_CPU_name:
16790 printf (" Tag_ARC_CPU_name: ");
16791 p = display_tag_value (-1, p, end);
16792 break;
16793
16794 case Tag_ARC_ABI_rf16:
cd30bcef 16795 READ_ULEB (val, p, end);
53a346d8
CZ
16796 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16797 break;
16798
16799 case Tag_ARC_ABI_osver:
cd30bcef 16800 READ_ULEB (val, p, end);
53a346d8
CZ
16801 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16802 break;
16803
16804 case Tag_ARC_ABI_pic:
16805 case Tag_ARC_ABI_sda:
cd30bcef 16806 READ_ULEB (val, p, end);
53a346d8
CZ
16807 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16808 : " Tag_ARC_ABI_pic: ");
16809 switch (val)
16810 {
16811 case 0:
16812 printf (_("Absent\n"));
16813 break;
16814 case 1:
16815 printf ("MWDT\n");
16816 break;
16817 case 2:
16818 printf ("GNU\n");
16819 break;
16820 default:
16821 printf (_("Unknown\n"));
16822 break;
16823 }
16824 break;
16825
16826 case Tag_ARC_ABI_tls:
cd30bcef 16827 READ_ULEB (val, p, end);
53a346d8
CZ
16828 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16829 break;
16830
16831 case Tag_ARC_ABI_enumsize:
cd30bcef 16832 READ_ULEB (val, p, end);
53a346d8
CZ
16833 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16834 _("smallest"));
16835 break;
16836
16837 case Tag_ARC_ABI_exceptions:
cd30bcef 16838 READ_ULEB (val, p, end);
53a346d8
CZ
16839 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16840 : _("default"));
16841 break;
16842
16843 case Tag_ARC_ABI_double_size:
cd30bcef 16844 READ_ULEB (val, p, end);
53a346d8
CZ
16845 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16846 break;
16847
16848 case Tag_ARC_ISA_config:
16849 printf (" Tag_ARC_ISA_config: ");
16850 p = display_tag_value (-1, p, end);
16851 break;
16852
16853 case Tag_ARC_ISA_apex:
16854 printf (" Tag_ARC_ISA_apex: ");
16855 p = display_tag_value (-1, p, end);
16856 break;
16857
16858 case Tag_ARC_ISA_mpy_option:
cd30bcef 16859 READ_ULEB (val, p, end);
53a346d8
CZ
16860 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16861 break;
16862
db1e1b45 16863 case Tag_ARC_ATR_version:
cd30bcef 16864 READ_ULEB (val, p, end);
db1e1b45 16865 printf (" Tag_ARC_ATR_version: %d\n", val);
16866 break;
16867
53a346d8
CZ
16868 default:
16869 return display_tag_value (tag & 1, p, end);
16870 }
16871
16872 return p;
16873}
16874
11c1ff18
PB
16875/* ARM EABI attributes section. */
16876typedef struct
16877{
70e99720 16878 unsigned int tag;
2cf0635d 16879 const char * name;
11c1ff18 16880 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16881 unsigned int type;
288f0ba2 16882 const char *const *table;
11c1ff18
PB
16883} arm_attr_public_tag;
16884
288f0ba2 16885static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16886 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16887 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16888 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16889 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16890static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16891static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16892 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16893static const char *const arm_attr_tag_FP_arch[] =
bca38921 16894 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16895 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16896static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16897static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16898 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16899 "NEON for ARMv8.1"};
288f0ba2 16900static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16901 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16902 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16903static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16904 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16905static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16906 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16907static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16908 {"Absolute", "PC-relative", "None"};
288f0ba2 16909static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16910 {"None", "direct", "GOT-indirect"};
288f0ba2 16911static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16912 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16913static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16914static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16915 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16916static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16917static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16918static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16919 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16920static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16921 {"Unused", "small", "int", "forced to int"};
288f0ba2 16922static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16923 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16924static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16925 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16926static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16927 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16928static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16929 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16930 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16931static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16932 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16933 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16934static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16935static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16936 {"Not Allowed", "Allowed"};
288f0ba2 16937static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16938 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16939static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16940 {"Follow architecture", "Allowed"};
288f0ba2 16941static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16942 {"Not Allowed", "Allowed"};
288f0ba2 16943static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16944 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16945 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16946static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16947static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16948 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16949 "TrustZone and Virtualization Extensions"};
288f0ba2 16950static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16951 {"Not Allowed", "Allowed"};
11c1ff18 16952
288f0ba2 16953static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16954 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16955
99db83d0
AC
16956static const char * arm_attr_tag_PAC_extension[] =
16957 {"No PAC/AUT instructions",
16958 "PAC/AUT instructions permitted in the NOP space",
16959 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16960
4b535030
AC
16961static const char * arm_attr_tag_BTI_extension[] =
16962 {"BTI instructions not permitted",
16963 "BTI instructions permitted in the NOP space",
16964 "BTI instructions permitted in the NOP and in the non-NOP space"};
16965
b81ee92f
AC
16966static const char * arm_attr_tag_BTI_use[] =
16967 {"Compiled without branch target enforcement",
16968 "Compiled with branch target enforcement"};
16969
c9fed665
AC
16970static const char * arm_attr_tag_PACRET_use[] =
16971 {"Compiled without return address signing and authentication",
16972 "Compiled with return address signing and authentication"};
16973
11c1ff18
PB
16974#define LOOKUP(id, name) \
16975 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16976static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16977{
16978 {4, "CPU_raw_name", 1, NULL},
16979 {5, "CPU_name", 1, NULL},
16980 LOOKUP(6, CPU_arch),
16981 {7, "CPU_arch_profile", 0, NULL},
16982 LOOKUP(8, ARM_ISA_use),
16983 LOOKUP(9, THUMB_ISA_use),
75375b3e 16984 LOOKUP(10, FP_arch),
11c1ff18 16985 LOOKUP(11, WMMX_arch),
f5f53991
AS
16986 LOOKUP(12, Advanced_SIMD_arch),
16987 LOOKUP(13, PCS_config),
11c1ff18
PB
16988 LOOKUP(14, ABI_PCS_R9_use),
16989 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16990 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16991 LOOKUP(17, ABI_PCS_GOT_use),
16992 LOOKUP(18, ABI_PCS_wchar_t),
16993 LOOKUP(19, ABI_FP_rounding),
16994 LOOKUP(20, ABI_FP_denormal),
16995 LOOKUP(21, ABI_FP_exceptions),
16996 LOOKUP(22, ABI_FP_user_exceptions),
16997 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16998 {24, "ABI_align_needed", 0, NULL},
16999 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
17000 LOOKUP(26, ABI_enum_size),
17001 LOOKUP(27, ABI_HardFP_use),
17002 LOOKUP(28, ABI_VFP_args),
17003 LOOKUP(29, ABI_WMMX_args),
17004 LOOKUP(30, ABI_optimization_goals),
17005 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 17006 {32, "compatibility", 0, NULL},
f5f53991 17007 LOOKUP(34, CPU_unaligned_access),
75375b3e 17008 LOOKUP(36, FP_HP_extension),
8e79c3df 17009 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
17010 LOOKUP(42, MPextension_use),
17011 LOOKUP(44, DIV_use),
15afaa63 17012 LOOKUP(46, DSP_extension),
a7ad558c 17013 LOOKUP(48, MVE_arch),
99db83d0 17014 LOOKUP(50, PAC_extension),
4b535030 17015 LOOKUP(52, BTI_extension),
b81ee92f 17016 LOOKUP(74, BTI_use),
c9fed665 17017 LOOKUP(76, PACRET_use),
f5f53991
AS
17018 {64, "nodefaults", 0, NULL},
17019 {65, "also_compatible_with", 0, NULL},
17020 LOOKUP(66, T2EE_use),
17021 {67, "conformance", 1, NULL},
17022 LOOKUP(68, Virtualization_use),
cd21e546 17023 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
17024};
17025#undef LOOKUP
17026
11c1ff18 17027static unsigned char *
f6f0e17b
NC
17028display_arm_attribute (unsigned char * p,
17029 const unsigned char * const end)
11c1ff18 17030{
70e99720 17031 unsigned int tag;
70e99720 17032 unsigned int val;
2cf0635d 17033 arm_attr_public_tag * attr;
11c1ff18 17034 unsigned i;
70e99720 17035 unsigned int type;
11c1ff18 17036
cd30bcef 17037 READ_ULEB (tag, p, end);
11c1ff18 17038 attr = NULL;
2cf0635d 17039 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
17040 {
17041 if (arm_attr_public_tags[i].tag == tag)
17042 {
17043 attr = &arm_attr_public_tags[i];
17044 break;
17045 }
17046 }
17047
17048 if (attr)
17049 {
17050 printf (" Tag_%s: ", attr->name);
17051 switch (attr->type)
17052 {
17053 case 0:
17054 switch (tag)
17055 {
17056 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 17057 READ_ULEB (val, p, end);
11c1ff18
PB
17058 switch (val)
17059 {
2b692964
NC
17060 case 0: printf (_("None\n")); break;
17061 case 'A': printf (_("Application\n")); break;
17062 case 'R': printf (_("Realtime\n")); break;
17063 case 'M': printf (_("Microcontroller\n")); break;
17064 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
17065 default: printf ("??? (%d)\n", val); break;
17066 }
17067 break;
17068
75375b3e 17069 case 24: /* Tag_align_needed. */
cd30bcef 17070 READ_ULEB (val, p, end);
75375b3e
MGD
17071 switch (val)
17072 {
2b692964
NC
17073 case 0: printf (_("None\n")); break;
17074 case 1: printf (_("8-byte\n")); break;
17075 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
17076 case 3: printf ("??? 3\n"); break;
17077 default:
17078 if (val <= 12)
dd24e3da 17079 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17080 1 << val);
17081 else
17082 printf ("??? (%d)\n", val);
17083 break;
17084 }
17085 break;
17086
17087 case 25: /* Tag_align_preserved. */
cd30bcef 17088 READ_ULEB (val, p, end);
75375b3e
MGD
17089 switch (val)
17090 {
2b692964
NC
17091 case 0: printf (_("None\n")); break;
17092 case 1: printf (_("8-byte, except leaf SP\n")); break;
17093 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
17094 case 3: printf ("??? 3\n"); break;
17095 default:
17096 if (val <= 12)
dd24e3da 17097 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17098 1 << val);
17099 else
17100 printf ("??? (%d)\n", val);
17101 break;
17102 }
17103 break;
17104
11c1ff18 17105 case 32: /* Tag_compatibility. */
071436c6 17106 {
cd30bcef 17107 READ_ULEB (val, p, end);
071436c6 17108 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17109 if (p < end - 1)
17110 {
17111 size_t maxlen = (end - p) - 1;
17112
17113 print_symbol ((int) maxlen, (const char *) p);
17114 p += strnlen ((char *) p, maxlen) + 1;
17115 }
17116 else
17117 {
17118 printf (_("<corrupt>"));
17119 p = (unsigned char *) end;
17120 }
071436c6 17121 putchar ('\n');
071436c6 17122 }
11c1ff18
PB
17123 break;
17124
f5f53991 17125 case 64: /* Tag_nodefaults. */
541a3cbd
NC
17126 /* PR 17531: file: 001-505008-0.01. */
17127 if (p < end)
17128 p++;
2b692964 17129 printf (_("True\n"));
f5f53991
AS
17130 break;
17131
17132 case 65: /* Tag_also_compatible_with. */
cd30bcef 17133 READ_ULEB (val, p, end);
f5f53991
AS
17134 if (val == 6 /* Tag_CPU_arch. */)
17135 {
cd30bcef 17136 READ_ULEB (val, p, end);
071436c6 17137 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
17138 printf ("??? (%d)\n", val);
17139 else
17140 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17141 }
17142 else
17143 printf ("???\n");
071436c6
NC
17144 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17145 ;
f5f53991
AS
17146 break;
17147
11c1ff18 17148 default:
bee0ee85
NC
17149 printf (_("<unknown: %d>\n"), tag);
17150 break;
11c1ff18
PB
17151 }
17152 return p;
17153
17154 case 1:
f6f0e17b 17155 return display_tag_value (-1, p, end);
11c1ff18 17156 case 2:
f6f0e17b 17157 return display_tag_value (0, p, end);
11c1ff18
PB
17158
17159 default:
17160 assert (attr->type & 0x80);
cd30bcef 17161 READ_ULEB (val, p, end);
11c1ff18
PB
17162 type = attr->type & 0x7f;
17163 if (val >= type)
17164 printf ("??? (%d)\n", val);
17165 else
17166 printf ("%s\n", attr->table[val]);
17167 return p;
17168 }
17169 }
11c1ff18 17170
f6f0e17b 17171 return display_tag_value (tag, p, end);
11c1ff18
PB
17172}
17173
104d59d1 17174static unsigned char *
60bca95a 17175display_gnu_attribute (unsigned char * p,
60abdbed 17176 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 17177 const unsigned char * const end)
104d59d1 17178{
cd30bcef 17179 unsigned int tag;
60abdbed 17180 unsigned int val;
104d59d1 17181
cd30bcef 17182 READ_ULEB (tag, p, end);
104d59d1
JM
17183
17184 /* Tag_compatibility is the only generic GNU attribute defined at
17185 present. */
17186 if (tag == 32)
17187 {
cd30bcef 17188 READ_ULEB (val, p, end);
071436c6
NC
17189
17190 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
17191 if (p == end)
17192 {
071436c6 17193 printf (_("<corrupt>\n"));
f6f0e17b
NC
17194 warn (_("corrupt vendor attribute\n"));
17195 }
17196 else
17197 {
4082ef84
NC
17198 if (p < end - 1)
17199 {
17200 size_t maxlen = (end - p) - 1;
071436c6 17201
4082ef84
NC
17202 print_symbol ((int) maxlen, (const char *) p);
17203 p += strnlen ((char *) p, maxlen) + 1;
17204 }
17205 else
17206 {
17207 printf (_("<corrupt>"));
17208 p = (unsigned char *) end;
17209 }
071436c6 17210 putchar ('\n');
f6f0e17b 17211 }
104d59d1
JM
17212 return p;
17213 }
17214
17215 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 17216 return display_proc_gnu_attribute (p, tag, end);
104d59d1 17217
f6f0e17b 17218 return display_tag_value (tag, p, end);
104d59d1
JM
17219}
17220
85f7484a
PB
17221static unsigned char *
17222display_m68k_gnu_attribute (unsigned char * p,
17223 unsigned int tag,
17224 const unsigned char * const end)
17225{
17226 unsigned int val;
17227
17228 if (tag == Tag_GNU_M68K_ABI_FP)
17229 {
17230 printf (" Tag_GNU_M68K_ABI_FP: ");
17231 if (p == end)
17232 {
17233 printf (_("<corrupt>\n"));
17234 return p;
17235 }
17236 READ_ULEB (val, p, end);
17237
17238 if (val > 3)
17239 printf ("(%#x), ", val);
17240
17241 switch (val & 3)
17242 {
17243 case 0:
17244 printf (_("unspecified hard/soft float\n"));
17245 break;
17246 case 1:
17247 printf (_("hard float\n"));
17248 break;
17249 case 2:
17250 printf (_("soft float\n"));
17251 break;
17252 }
17253 return p;
17254 }
17255
17256 return display_tag_value (tag & 1, p, end);
17257}
17258
34c8bcba 17259static unsigned char *
f6f0e17b 17260display_power_gnu_attribute (unsigned char * p,
60abdbed 17261 unsigned int tag,
f6f0e17b 17262 const unsigned char * const end)
34c8bcba 17263{
005d79fd 17264 unsigned int val;
34c8bcba
JM
17265
17266 if (tag == Tag_GNU_Power_ABI_FP)
17267 {
34c8bcba 17268 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 17269 if (p == end)
005d79fd
AM
17270 {
17271 printf (_("<corrupt>\n"));
17272 return p;
17273 }
cd30bcef 17274 READ_ULEB (val, p, end);
60bca95a 17275
005d79fd
AM
17276 if (val > 15)
17277 printf ("(%#x), ", val);
17278
17279 switch (val & 3)
34c8bcba
JM
17280 {
17281 case 0:
005d79fd 17282 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17283 break;
17284 case 1:
005d79fd 17285 printf (_("hard float, "));
34c8bcba
JM
17286 break;
17287 case 2:
005d79fd 17288 printf (_("soft float, "));
34c8bcba 17289 break;
3c7b9897 17290 case 3:
005d79fd 17291 printf (_("single-precision hard float, "));
3c7b9897 17292 break;
005d79fd
AM
17293 }
17294
17295 switch (val & 0xC)
17296 {
17297 case 0:
17298 printf (_("unspecified long double\n"));
17299 break;
17300 case 4:
17301 printf (_("128-bit IBM long double\n"));
17302 break;
17303 case 8:
17304 printf (_("64-bit long double\n"));
17305 break;
17306 case 12:
17307 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17308 break;
17309 }
17310 return p;
005d79fd 17311 }
34c8bcba 17312
c6e65352
DJ
17313 if (tag == Tag_GNU_Power_ABI_Vector)
17314 {
c6e65352 17315 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17316 if (p == end)
005d79fd
AM
17317 {
17318 printf (_("<corrupt>\n"));
17319 return p;
17320 }
cd30bcef 17321 READ_ULEB (val, p, end);
005d79fd
AM
17322
17323 if (val > 3)
17324 printf ("(%#x), ", val);
17325
17326 switch (val & 3)
c6e65352
DJ
17327 {
17328 case 0:
005d79fd 17329 printf (_("unspecified\n"));
c6e65352
DJ
17330 break;
17331 case 1:
005d79fd 17332 printf (_("generic\n"));
c6e65352
DJ
17333 break;
17334 case 2:
17335 printf ("AltiVec\n");
17336 break;
17337 case 3:
17338 printf ("SPE\n");
17339 break;
c6e65352
DJ
17340 }
17341 return p;
005d79fd 17342 }
c6e65352 17343
f82e0623
NF
17344 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17345 {
005d79fd 17346 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17347 if (p == end)
f6f0e17b 17348 {
005d79fd 17349 printf (_("<corrupt>\n"));
f6f0e17b
NC
17350 return p;
17351 }
cd30bcef 17352 READ_ULEB (val, p, end);
0b4362b0 17353
005d79fd
AM
17354 if (val > 2)
17355 printf ("(%#x), ", val);
17356
17357 switch (val & 3)
17358 {
17359 case 0:
17360 printf (_("unspecified\n"));
17361 break;
17362 case 1:
17363 printf ("r3/r4\n");
17364 break;
17365 case 2:
17366 printf (_("memory\n"));
17367 break;
17368 case 3:
17369 printf ("???\n");
17370 break;
17371 }
f82e0623
NF
17372 return p;
17373 }
17374
f6f0e17b 17375 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17376}
17377
643f7afb
AK
17378static unsigned char *
17379display_s390_gnu_attribute (unsigned char * p,
60abdbed 17380 unsigned int tag,
643f7afb
AK
17381 const unsigned char * const end)
17382{
cd30bcef 17383 unsigned int val;
643f7afb
AK
17384
17385 if (tag == Tag_GNU_S390_ABI_Vector)
17386 {
643f7afb 17387 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17388 READ_ULEB (val, p, end);
643f7afb
AK
17389
17390 switch (val)
17391 {
17392 case 0:
17393 printf (_("any\n"));
17394 break;
17395 case 1:
17396 printf (_("software\n"));
17397 break;
17398 case 2:
17399 printf (_("hardware\n"));
17400 break;
17401 default:
17402 printf ("??? (%d)\n", val);
17403 break;
17404 }
17405 return p;
17406 }
17407
17408 return display_tag_value (tag & 1, p, end);
17409}
17410
9e8c70f9 17411static void
60abdbed 17412display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17413{
17414 if (mask)
17415 {
015dc7e1 17416 bool first = true;
071436c6 17417
9e8c70f9 17418 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17419 fputs ("mul32", stdout), first = false;
9e8c70f9 17420 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17421 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17422 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17423 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17424 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17425 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17426 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17427 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17428 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17429 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17430 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17431 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17432 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17433 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17434 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17435 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17436 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17437 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17438 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17439 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17440 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17441 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17442 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17443 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17444 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17445 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17446 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17447 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17448 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17449 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17450 }
17451 else
071436c6
NC
17452 fputc ('0', stdout);
17453 fputc ('\n', stdout);
9e8c70f9
DM
17454}
17455
3d68f91c 17456static void
60abdbed 17457display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17458{
17459 if (mask)
17460 {
015dc7e1 17461 bool first = true;
071436c6 17462
3d68f91c 17463 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17464 fputs ("fjathplus", stdout), first = false;
3d68f91c 17465 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17466 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17467 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17468 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17469 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17470 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17471 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17472 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17473 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17474 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17475 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17476 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17477 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17478 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17479 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17480 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17481 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17482 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17483 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17484 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17485 }
17486 else
071436c6
NC
17487 fputc ('0', stdout);
17488 fputc ('\n', stdout);
3d68f91c
JM
17489}
17490
9e8c70f9 17491static unsigned char *
f6f0e17b 17492display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17493 unsigned int tag,
f6f0e17b 17494 const unsigned char * const end)
9e8c70f9 17495{
cd30bcef 17496 unsigned int val;
3d68f91c 17497
9e8c70f9
DM
17498 if (tag == Tag_GNU_Sparc_HWCAPS)
17499 {
cd30bcef 17500 READ_ULEB (val, p, end);
9e8c70f9 17501 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17502 display_sparc_hwcaps (val);
17503 return p;
3d68f91c
JM
17504 }
17505 if (tag == Tag_GNU_Sparc_HWCAPS2)
17506 {
cd30bcef 17507 READ_ULEB (val, p, end);
3d68f91c
JM
17508 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17509 display_sparc_hwcaps2 (val);
17510 return p;
17511 }
9e8c70f9 17512
f6f0e17b 17513 return display_tag_value (tag, p, end);
9e8c70f9
DM
17514}
17515
351cdf24 17516static void
32ec8896 17517print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17518{
17519 switch (val)
17520 {
17521 case Val_GNU_MIPS_ABI_FP_ANY:
17522 printf (_("Hard or soft float\n"));
17523 break;
17524 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17525 printf (_("Hard float (double precision)\n"));
17526 break;
17527 case Val_GNU_MIPS_ABI_FP_SINGLE:
17528 printf (_("Hard float (single precision)\n"));
17529 break;
17530 case Val_GNU_MIPS_ABI_FP_SOFT:
17531 printf (_("Soft float\n"));
17532 break;
17533 case Val_GNU_MIPS_ABI_FP_OLD_64:
17534 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17535 break;
17536 case Val_GNU_MIPS_ABI_FP_XX:
17537 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17538 break;
17539 case Val_GNU_MIPS_ABI_FP_64:
17540 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17541 break;
17542 case Val_GNU_MIPS_ABI_FP_64A:
17543 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17544 break;
3350cc01
CM
17545 case Val_GNU_MIPS_ABI_FP_NAN2008:
17546 printf (_("NaN 2008 compatibility\n"));
17547 break;
351cdf24
MF
17548 default:
17549 printf ("??? (%d)\n", val);
17550 break;
17551 }
17552}
17553
2cf19d5c 17554static unsigned char *
f6f0e17b 17555display_mips_gnu_attribute (unsigned char * p,
60abdbed 17556 unsigned int tag,
f6f0e17b 17557 const unsigned char * const end)
2cf19d5c 17558{
2cf19d5c
JM
17559 if (tag == Tag_GNU_MIPS_ABI_FP)
17560 {
32ec8896 17561 unsigned int val;
f6f0e17b 17562
2cf19d5c 17563 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17564 READ_ULEB (val, p, end);
351cdf24 17565 print_mips_fp_abi_value (val);
2cf19d5c
JM
17566 return p;
17567 }
17568
a9f58168
CF
17569 if (tag == Tag_GNU_MIPS_ABI_MSA)
17570 {
32ec8896 17571 unsigned int val;
a9f58168 17572
a9f58168 17573 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17574 READ_ULEB (val, p, end);
a9f58168
CF
17575
17576 switch (val)
17577 {
17578 case Val_GNU_MIPS_ABI_MSA_ANY:
17579 printf (_("Any MSA or not\n"));
17580 break;
17581 case Val_GNU_MIPS_ABI_MSA_128:
17582 printf (_("128-bit MSA\n"));
17583 break;
17584 default:
17585 printf ("??? (%d)\n", val);
17586 break;
17587 }
17588 return p;
17589 }
17590
f6f0e17b 17591 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17592}
17593
59e6276b 17594static unsigned char *
f6f0e17b
NC
17595display_tic6x_attribute (unsigned char * p,
17596 const unsigned char * const end)
59e6276b 17597{
60abdbed 17598 unsigned int tag;
cd30bcef 17599 unsigned int val;
59e6276b 17600
cd30bcef 17601 READ_ULEB (tag, p, end);
59e6276b
JM
17602
17603 switch (tag)
17604 {
75fa6dc1 17605 case Tag_ISA:
75fa6dc1 17606 printf (" Tag_ISA: ");
cd30bcef 17607 READ_ULEB (val, p, end);
59e6276b
JM
17608
17609 switch (val)
17610 {
75fa6dc1 17611 case C6XABI_Tag_ISA_none:
59e6276b
JM
17612 printf (_("None\n"));
17613 break;
75fa6dc1 17614 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17615 printf ("C62x\n");
17616 break;
75fa6dc1 17617 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17618 printf ("C67x\n");
17619 break;
75fa6dc1 17620 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17621 printf ("C67x+\n");
17622 break;
75fa6dc1 17623 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17624 printf ("C64x\n");
17625 break;
75fa6dc1 17626 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17627 printf ("C64x+\n");
17628 break;
75fa6dc1 17629 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17630 printf ("C674x\n");
17631 break;
17632 default:
17633 printf ("??? (%d)\n", val);
17634 break;
17635 }
17636 return p;
17637
87779176 17638 case Tag_ABI_wchar_t:
87779176 17639 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17640 READ_ULEB (val, p, end);
87779176
JM
17641 switch (val)
17642 {
17643 case 0:
17644 printf (_("Not used\n"));
17645 break;
17646 case 1:
17647 printf (_("2 bytes\n"));
17648 break;
17649 case 2:
17650 printf (_("4 bytes\n"));
17651 break;
17652 default:
17653 printf ("??? (%d)\n", val);
17654 break;
17655 }
17656 return p;
17657
17658 case Tag_ABI_stack_align_needed:
87779176 17659 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17660 READ_ULEB (val, p, end);
87779176
JM
17661 switch (val)
17662 {
17663 case 0:
17664 printf (_("8-byte\n"));
17665 break;
17666 case 1:
17667 printf (_("16-byte\n"));
17668 break;
17669 default:
17670 printf ("??? (%d)\n", val);
17671 break;
17672 }
17673 return p;
17674
17675 case Tag_ABI_stack_align_preserved:
cd30bcef 17676 READ_ULEB (val, p, end);
87779176
JM
17677 printf (" Tag_ABI_stack_align_preserved: ");
17678 switch (val)
17679 {
17680 case 0:
17681 printf (_("8-byte\n"));
17682 break;
17683 case 1:
17684 printf (_("16-byte\n"));
17685 break;
17686 default:
17687 printf ("??? (%d)\n", val);
17688 break;
17689 }
17690 return p;
17691
b5593623 17692 case Tag_ABI_DSBT:
cd30bcef 17693 READ_ULEB (val, p, end);
b5593623
JM
17694 printf (" Tag_ABI_DSBT: ");
17695 switch (val)
17696 {
17697 case 0:
17698 printf (_("DSBT addressing not used\n"));
17699 break;
17700 case 1:
17701 printf (_("DSBT addressing used\n"));
17702 break;
17703 default:
17704 printf ("??? (%d)\n", val);
17705 break;
17706 }
17707 return p;
17708
87779176 17709 case Tag_ABI_PID:
cd30bcef 17710 READ_ULEB (val, p, end);
87779176
JM
17711 printf (" Tag_ABI_PID: ");
17712 switch (val)
17713 {
17714 case 0:
17715 printf (_("Data addressing position-dependent\n"));
17716 break;
17717 case 1:
17718 printf (_("Data addressing position-independent, GOT near DP\n"));
17719 break;
17720 case 2:
17721 printf (_("Data addressing position-independent, GOT far from DP\n"));
17722 break;
17723 default:
17724 printf ("??? (%d)\n", val);
17725 break;
17726 }
17727 return p;
17728
17729 case Tag_ABI_PIC:
cd30bcef 17730 READ_ULEB (val, p, end);
87779176
JM
17731 printf (" Tag_ABI_PIC: ");
17732 switch (val)
17733 {
17734 case 0:
17735 printf (_("Code addressing position-dependent\n"));
17736 break;
17737 case 1:
17738 printf (_("Code addressing position-independent\n"));
17739 break;
17740 default:
17741 printf ("??? (%d)\n", val);
17742 break;
17743 }
17744 return p;
17745
17746 case Tag_ABI_array_object_alignment:
cd30bcef 17747 READ_ULEB (val, p, end);
87779176
JM
17748 printf (" Tag_ABI_array_object_alignment: ");
17749 switch (val)
17750 {
17751 case 0:
17752 printf (_("8-byte\n"));
17753 break;
17754 case 1:
17755 printf (_("4-byte\n"));
17756 break;
17757 case 2:
17758 printf (_("16-byte\n"));
17759 break;
17760 default:
17761 printf ("??? (%d)\n", val);
17762 break;
17763 }
17764 return p;
17765
17766 case Tag_ABI_array_object_align_expected:
cd30bcef 17767 READ_ULEB (val, p, end);
87779176
JM
17768 printf (" Tag_ABI_array_object_align_expected: ");
17769 switch (val)
17770 {
17771 case 0:
17772 printf (_("8-byte\n"));
17773 break;
17774 case 1:
17775 printf (_("4-byte\n"));
17776 break;
17777 case 2:
17778 printf (_("16-byte\n"));
17779 break;
17780 default:
17781 printf ("??? (%d)\n", val);
17782 break;
17783 }
17784 return p;
17785
3cbd1c06 17786 case Tag_ABI_compatibility:
071436c6 17787 {
cd30bcef 17788 READ_ULEB (val, p, end);
071436c6 17789 printf (" Tag_ABI_compatibility: ");
071436c6 17790 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17791 if (p < end - 1)
17792 {
17793 size_t maxlen = (end - p) - 1;
17794
17795 print_symbol ((int) maxlen, (const char *) p);
17796 p += strnlen ((char *) p, maxlen) + 1;
17797 }
17798 else
17799 {
17800 printf (_("<corrupt>"));
17801 p = (unsigned char *) end;
17802 }
071436c6 17803 putchar ('\n');
071436c6
NC
17804 return p;
17805 }
87779176
JM
17806
17807 case Tag_ABI_conformance:
071436c6 17808 {
4082ef84
NC
17809 printf (" Tag_ABI_conformance: \"");
17810 if (p < end - 1)
17811 {
17812 size_t maxlen = (end - p) - 1;
071436c6 17813
4082ef84
NC
17814 print_symbol ((int) maxlen, (const char *) p);
17815 p += strnlen ((char *) p, maxlen) + 1;
17816 }
17817 else
17818 {
17819 printf (_("<corrupt>"));
17820 p = (unsigned char *) end;
17821 }
071436c6 17822 printf ("\"\n");
071436c6
NC
17823 return p;
17824 }
59e6276b
JM
17825 }
17826
f6f0e17b
NC
17827 return display_tag_value (tag, p, end);
17828}
59e6276b 17829
f6f0e17b 17830static void
60abdbed 17831display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 17832{
26c527e6 17833 uint64_t addr = 0;
f6f0e17b
NC
17834 size_t bytes = end - p;
17835
feceaa59 17836 assert (end >= p);
f6f0e17b 17837 while (bytes)
87779176 17838 {
f6f0e17b
NC
17839 int j;
17840 int k;
17841 int lbytes = (bytes > 16 ? 16 : bytes);
17842
26c527e6 17843 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
17844
17845 for (j = 0; j < 16; j++)
17846 {
17847 if (j < lbytes)
17848 printf ("%2.2x", p[j]);
17849 else
17850 printf (" ");
17851
17852 if ((j & 3) == 3)
17853 printf (" ");
17854 }
17855
17856 for (j = 0; j < lbytes; j++)
17857 {
17858 k = p[j];
17859 if (k >= ' ' && k < 0x7f)
17860 printf ("%c", k);
17861 else
17862 printf (".");
17863 }
17864
17865 putchar ('\n');
17866
17867 p += lbytes;
17868 bytes -= lbytes;
17869 addr += lbytes;
87779176 17870 }
59e6276b 17871
f6f0e17b 17872 putchar ('\n');
59e6276b
JM
17873}
17874
13761a11 17875static unsigned char *
b0191216 17876display_msp430_attribute (unsigned char * p,
26c527e6 17877 const unsigned char * const end)
13761a11 17878{
26c527e6
AM
17879 uint64_t val;
17880 uint64_t tag;
13761a11 17881
cd30bcef 17882 READ_ULEB (tag, p, end);
0b4362b0 17883
13761a11
NC
17884 switch (tag)
17885 {
17886 case OFBA_MSPABI_Tag_ISA:
13761a11 17887 printf (" Tag_ISA: ");
cd30bcef 17888 READ_ULEB (val, p, end);
13761a11
NC
17889 switch (val)
17890 {
17891 case 0: printf (_("None\n")); break;
17892 case 1: printf (_("MSP430\n")); break;
17893 case 2: printf (_("MSP430X\n")); break;
26c527e6 17894 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17895 }
17896 break;
17897
17898 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17899 printf (" Tag_Code_Model: ");
cd30bcef 17900 READ_ULEB (val, p, end);
13761a11
NC
17901 switch (val)
17902 {
17903 case 0: printf (_("None\n")); break;
17904 case 1: printf (_("Small\n")); break;
17905 case 2: printf (_("Large\n")); break;
26c527e6 17906 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17907 }
17908 break;
17909
17910 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17911 printf (" Tag_Data_Model: ");
cd30bcef 17912 READ_ULEB (val, p, end);
13761a11
NC
17913 switch (val)
17914 {
17915 case 0: printf (_("None\n")); break;
17916 case 1: printf (_("Small\n")); break;
17917 case 2: printf (_("Large\n")); break;
17918 case 3: printf (_("Restricted Large\n")); break;
26c527e6 17919 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17920 }
17921 break;
17922
17923 default:
26c527e6 17924 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
17925
17926 if (tag & 1)
17927 {
071436c6 17928 putchar ('"');
4082ef84
NC
17929 if (p < end - 1)
17930 {
17931 size_t maxlen = (end - p) - 1;
17932
17933 print_symbol ((int) maxlen, (const char *) p);
17934 p += strnlen ((char *) p, maxlen) + 1;
17935 }
17936 else
17937 {
17938 printf (_("<corrupt>"));
17939 p = (unsigned char *) end;
17940 }
071436c6 17941 printf ("\"\n");
13761a11
NC
17942 }
17943 else
17944 {
cd30bcef 17945 READ_ULEB (val, p, end);
26c527e6 17946 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
17947 }
17948 break;
17949 }
17950
4082ef84 17951 assert (p <= end);
13761a11
NC
17952 return p;
17953}
17954
c0ea7c52
JL
17955static unsigned char *
17956display_msp430_gnu_attribute (unsigned char * p,
17957 unsigned int tag,
17958 const unsigned char * const end)
17959{
17960 if (tag == Tag_GNU_MSP430_Data_Region)
17961 {
26c527e6 17962 uint64_t val;
c0ea7c52 17963
c0ea7c52 17964 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17965 READ_ULEB (val, p, end);
c0ea7c52
JL
17966
17967 switch (val)
17968 {
17969 case Val_GNU_MSP430_Data_Region_Any:
17970 printf (_("Any Region\n"));
17971 break;
17972 case Val_GNU_MSP430_Data_Region_Lower:
17973 printf (_("Lower Region Only\n"));
17974 break;
17975 default:
26c527e6 17976 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
17977 }
17978 return p;
17979 }
17980 return display_tag_value (tag & 1, p, end);
17981}
17982
2dc8dd17
JW
17983struct riscv_attr_tag_t {
17984 const char *name;
cd30bcef 17985 unsigned int tag;
2dc8dd17
JW
17986};
17987
17988static struct riscv_attr_tag_t riscv_attr_tag[] =
17989{
17990#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17991 T(arch),
17992 T(priv_spec),
17993 T(priv_spec_minor),
17994 T(priv_spec_revision),
17995 T(unaligned_access),
17996 T(stack_align),
17997#undef T
17998};
17999
18000static unsigned char *
18001display_riscv_attribute (unsigned char *p,
18002 const unsigned char * const end)
18003{
26c527e6
AM
18004 uint64_t val;
18005 uint64_t tag;
2dc8dd17
JW
18006 struct riscv_attr_tag_t *attr = NULL;
18007 unsigned i;
18008
cd30bcef 18009 READ_ULEB (tag, p, end);
2dc8dd17
JW
18010
18011 /* Find the name of attribute. */
18012 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
18013 {
18014 if (riscv_attr_tag[i].tag == tag)
18015 {
18016 attr = &riscv_attr_tag[i];
18017 break;
18018 }
18019 }
18020
18021 if (attr)
18022 printf (" %s: ", attr->name);
18023 else
18024 return display_tag_value (tag, p, end);
18025
18026 switch (tag)
18027 {
18028 case Tag_RISCV_priv_spec:
18029 case Tag_RISCV_priv_spec_minor:
18030 case Tag_RISCV_priv_spec_revision:
cd30bcef 18031 READ_ULEB (val, p, end);
26c527e6 18032 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
18033 break;
18034 case Tag_RISCV_unaligned_access:
cd30bcef 18035 READ_ULEB (val, p, end);
2dc8dd17
JW
18036 switch (val)
18037 {
18038 case 0:
18039 printf (_("No unaligned access\n"));
18040 break;
18041 case 1:
18042 printf (_("Unaligned access\n"));
18043 break;
18044 }
18045 break;
18046 case Tag_RISCV_stack_align:
cd30bcef 18047 READ_ULEB (val, p, end);
26c527e6 18048 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
18049 break;
18050 case Tag_RISCV_arch:
18051 p = display_tag_value (-1, p, end);
18052 break;
18053 default:
18054 return display_tag_value (tag, p, end);
18055 }
18056
18057 return p;
18058}
18059
0861f561
CQ
18060static unsigned char *
18061display_csky_attribute (unsigned char * p,
18062 const unsigned char * const end)
18063{
26c527e6
AM
18064 uint64_t tag;
18065 uint64_t val;
0861f561
CQ
18066 READ_ULEB (tag, p, end);
18067
18068 if (tag >= Tag_CSKY_MAX)
18069 {
18070 return display_tag_value (-1, p, end);
18071 }
18072
18073 switch (tag)
18074 {
18075 case Tag_CSKY_ARCH_NAME:
18076 printf (" Tag_CSKY_ARCH_NAME:\t\t");
18077 return display_tag_value (-1, p, end);
18078 case Tag_CSKY_CPU_NAME:
18079 printf (" Tag_CSKY_CPU_NAME:\t\t");
18080 return display_tag_value (-1, p, end);
18081
18082 case Tag_CSKY_ISA_FLAGS:
18083 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
18084 return display_tag_value (0, p, end);
18085 case Tag_CSKY_ISA_EXT_FLAGS:
18086 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
18087 return display_tag_value (0, p, end);
18088
18089 case Tag_CSKY_DSP_VERSION:
18090 printf (" Tag_CSKY_DSP_VERSION:\t\t");
18091 READ_ULEB (val, p, end);
18092 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
18093 printf ("DSP Extension\n");
18094 else if (val == VAL_CSKY_DSP_VERSION_2)
18095 printf ("DSP 2.0\n");
18096 break;
18097
18098 case Tag_CSKY_VDSP_VERSION:
18099 printf (" Tag_CSKY_VDSP_VERSION:\t");
18100 READ_ULEB (val, p, end);
26c527e6 18101 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
18102 break;
18103
18104 case Tag_CSKY_FPU_VERSION:
18105 printf (" Tag_CSKY_FPU_VERSION:\t\t");
18106 READ_ULEB (val, p, end);
18107 if (val == VAL_CSKY_FPU_VERSION_1)
18108 printf ("ABIV1 FPU Version 1\n");
18109 else if (val == VAL_CSKY_FPU_VERSION_2)
18110 printf ("FPU Version 2\n");
18111 break;
18112
18113 case Tag_CSKY_FPU_ABI:
18114 printf (" Tag_CSKY_FPU_ABI:\t\t");
18115 READ_ULEB (val, p, end);
18116 if (val == VAL_CSKY_FPU_ABI_HARD)
18117 printf ("Hard\n");
18118 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18119 printf ("SoftFP\n");
18120 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18121 printf ("Soft\n");
18122 break;
18123 case Tag_CSKY_FPU_ROUNDING:
18124 READ_ULEB (val, p, end);
f253158f
NC
18125 if (val == 1)
18126 {
18127 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18128 printf ("Needed\n");
18129 }
0861f561
CQ
18130 break;
18131 case Tag_CSKY_FPU_DENORMAL:
18132 READ_ULEB (val, p, end);
f253158f
NC
18133 if (val == 1)
18134 {
18135 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18136 printf ("Needed\n");
18137 }
0861f561
CQ
18138 break;
18139 case Tag_CSKY_FPU_Exception:
18140 READ_ULEB (val, p, end);
f253158f
NC
18141 if (val == 1)
18142 {
18143 printf (" Tag_CSKY_FPU_Exception:\t");
18144 printf ("Needed\n");
18145 }
0861f561
CQ
18146 break;
18147 case Tag_CSKY_FPU_NUMBER_MODULE:
18148 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18149 return display_tag_value (-1, p, end);
18150 case Tag_CSKY_FPU_HARDFP:
18151 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18152 READ_ULEB (val, p, end);
18153 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18154 printf (" Half");
18155 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18156 printf (" Single");
18157 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18158 printf (" Double");
18159 printf ("\n");
18160 break;
18161 default:
18162 return display_tag_value (tag, p, end);
18163 }
18164 return p;
18165}
18166
015dc7e1 18167static bool
dda8d76d 18168process_attributes (Filedata * filedata,
60bca95a 18169 const char * public_name,
104d59d1 18170 unsigned int proc_type,
f6f0e17b 18171 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 18172 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 18173{
2cf0635d 18174 Elf_Internal_Shdr * sect;
11c1ff18 18175 unsigned i;
015dc7e1 18176 bool res = true;
11c1ff18
PB
18177
18178 /* Find the section header so that we get the size. */
dda8d76d
NC
18179 for (i = 0, sect = filedata->section_headers;
18180 i < filedata->file_header.e_shnum;
11c1ff18
PB
18181 i++, sect++)
18182 {
071436c6
NC
18183 unsigned char * contents;
18184 unsigned char * p;
18185
104d59d1 18186 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
18187 continue;
18188
dda8d76d 18189 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 18190 sect->sh_size, _("attributes"));
60bca95a 18191 if (contents == NULL)
32ec8896 18192 {
015dc7e1 18193 res = false;
32ec8896
NC
18194 continue;
18195 }
60bca95a 18196
11c1ff18 18197 p = contents;
60abdbed
NC
18198 /* The first character is the version of the attributes.
18199 Currently only version 1, (aka 'A') is recognised here. */
18200 if (*p != 'A')
32ec8896
NC
18201 {
18202 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 18203 res = false;
32ec8896 18204 }
60abdbed 18205 else
11c1ff18 18206 {
625d49fc 18207 uint64_t section_len;
071436c6
NC
18208
18209 section_len = sect->sh_size - 1;
11c1ff18 18210 p++;
60bca95a 18211
071436c6 18212 while (section_len > 0)
11c1ff18 18213 {
625d49fc 18214 uint64_t attr_len;
e9847026 18215 unsigned int namelen;
015dc7e1
AM
18216 bool public_section;
18217 bool gnu_section;
11c1ff18 18218
071436c6 18219 if (section_len <= 4)
e0a31db1
NC
18220 {
18221 error (_("Tag section ends prematurely\n"));
015dc7e1 18222 res = false;
e0a31db1
NC
18223 break;
18224 }
071436c6 18225 attr_len = byte_get (p, 4);
11c1ff18 18226 p += 4;
60bca95a 18227
071436c6 18228 if (attr_len > section_len)
11c1ff18 18229 {
071436c6
NC
18230 error (_("Bad attribute length (%u > %u)\n"),
18231 (unsigned) attr_len, (unsigned) section_len);
18232 attr_len = section_len;
015dc7e1 18233 res = false;
11c1ff18 18234 }
74e1a04b 18235 /* PR 17531: file: 001-101425-0.004 */
071436c6 18236 else if (attr_len < 5)
74e1a04b 18237 {
071436c6 18238 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 18239 res = false;
74e1a04b
NC
18240 break;
18241 }
e9847026 18242
071436c6
NC
18243 section_len -= attr_len;
18244 attr_len -= 4;
18245
18246 namelen = strnlen ((char *) p, attr_len) + 1;
18247 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
18248 {
18249 error (_("Corrupt attribute section name\n"));
015dc7e1 18250 res = false;
e9847026
NC
18251 break;
18252 }
18253
071436c6
NC
18254 printf (_("Attribute Section: "));
18255 print_symbol (INT_MAX, (const char *) p);
18256 putchar ('\n');
60bca95a
NC
18257
18258 if (public_name && streq ((char *) p, public_name))
015dc7e1 18259 public_section = true;
11c1ff18 18260 else
015dc7e1 18261 public_section = false;
60bca95a
NC
18262
18263 if (streq ((char *) p, "gnu"))
015dc7e1 18264 gnu_section = true;
104d59d1 18265 else
015dc7e1 18266 gnu_section = false;
60bca95a 18267
11c1ff18 18268 p += namelen;
071436c6 18269 attr_len -= namelen;
e0a31db1 18270
071436c6 18271 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18272 {
e0a31db1 18273 int tag;
cd30bcef 18274 unsigned int val;
625d49fc 18275 uint64_t size;
071436c6 18276 unsigned char * end;
60bca95a 18277
e0a31db1 18278 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18279 if (attr_len < 6)
e0a31db1
NC
18280 {
18281 error (_("Unused bytes at end of section\n"));
015dc7e1 18282 res = false;
e0a31db1
NC
18283 section_len = 0;
18284 break;
18285 }
18286
18287 tag = *(p++);
11c1ff18 18288 size = byte_get (p, 4);
071436c6 18289 if (size > attr_len)
11c1ff18 18290 {
e9847026 18291 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18292 (unsigned) size, (unsigned) attr_len);
015dc7e1 18293 res = false;
071436c6 18294 size = attr_len;
11c1ff18 18295 }
e0a31db1
NC
18296 /* PR binutils/17531: Safe handling of corrupt files. */
18297 if (size < 6)
18298 {
18299 error (_("Bad subsection length (%u < 6)\n"),
18300 (unsigned) size);
015dc7e1 18301 res = false;
e0a31db1
NC
18302 section_len = 0;
18303 break;
18304 }
60bca95a 18305
071436c6 18306 attr_len -= size;
11c1ff18 18307 end = p + size - 1;
071436c6 18308 assert (end <= contents + sect->sh_size);
11c1ff18 18309 p += 4;
60bca95a 18310
11c1ff18
PB
18311 switch (tag)
18312 {
18313 case 1:
2b692964 18314 printf (_("File Attributes\n"));
11c1ff18
PB
18315 break;
18316 case 2:
2b692964 18317 printf (_("Section Attributes:"));
11c1ff18
PB
18318 goto do_numlist;
18319 case 3:
2b692964 18320 printf (_("Symbol Attributes:"));
1a0670f3 18321 /* Fall through. */
11c1ff18
PB
18322 do_numlist:
18323 for (;;)
18324 {
cd30bcef 18325 READ_ULEB (val, p, end);
11c1ff18
PB
18326 if (val == 0)
18327 break;
18328 printf (" %d", val);
18329 }
18330 printf ("\n");
18331 break;
18332 default:
2b692964 18333 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18334 public_section = false;
11c1ff18
PB
18335 break;
18336 }
60bca95a 18337
071436c6 18338 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18339 {
18340 while (p < end)
f6f0e17b 18341 p = display_pub_attribute (p, end);
60abdbed 18342 assert (p == end);
104d59d1 18343 }
071436c6 18344 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18345 {
18346 while (p < end)
18347 p = display_gnu_attribute (p,
f6f0e17b
NC
18348 display_proc_gnu_attribute,
18349 end);
60abdbed 18350 assert (p == end);
11c1ff18 18351 }
071436c6 18352 else if (p < end)
11c1ff18 18353 {
071436c6 18354 printf (_(" Unknown attribute:\n"));
f6f0e17b 18355 display_raw_attribute (p, end);
11c1ff18
PB
18356 p = end;
18357 }
071436c6
NC
18358 else
18359 attr_len = 0;
11c1ff18
PB
18360 }
18361 }
18362 }
d70c5fc7 18363
60bca95a 18364 free (contents);
11c1ff18 18365 }
32ec8896
NC
18366
18367 return res;
11c1ff18
PB
18368}
18369
ccb4c951
RS
18370/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18371 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18372 and return the VMA of the next entry, or -1 if there was a problem.
18373 Does not read from DATA_END or beyond. */
ccb4c951 18374
625d49fc
AM
18375static uint64_t
18376print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18377 unsigned char * data_end)
ccb4c951
RS
18378{
18379 printf (" ");
18380 print_vma (addr, LONG_HEX);
18381 printf (" ");
18382 if (addr < pltgot + 0xfff0)
18383 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18384 else
18385 printf ("%10s", "");
18386 printf (" ");
18387 if (data == NULL)
2b692964 18388 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18389 else
18390 {
625d49fc 18391 uint64_t entry;
82b1b41b 18392 unsigned char * from = data + addr - pltgot;
ccb4c951 18393
82b1b41b
NC
18394 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18395 {
18396 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18397 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18398 return (uint64_t) -1;
82b1b41b
NC
18399 }
18400 else
18401 {
18402 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18403 print_vma (entry, LONG_HEX);
18404 }
ccb4c951
RS
18405 }
18406 return addr + (is_32bit_elf ? 4 : 8);
18407}
18408
861fb55a
DJ
18409/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18410 PLTGOT. Print the Address and Initial fields of an entry at VMA
18411 ADDR and return the VMA of the next entry. */
18412
625d49fc
AM
18413static uint64_t
18414print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18415{
18416 printf (" ");
18417 print_vma (addr, LONG_HEX);
18418 printf (" ");
18419 if (data == NULL)
2b692964 18420 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18421 else
18422 {
625d49fc 18423 uint64_t entry;
861fb55a
DJ
18424
18425 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18426 print_vma (entry, LONG_HEX);
18427 }
18428 return addr + (is_32bit_elf ? 4 : 8);
18429}
18430
351cdf24
MF
18431static void
18432print_mips_ases (unsigned int mask)
18433{
18434 if (mask & AFL_ASE_DSP)
18435 fputs ("\n\tDSP ASE", stdout);
18436 if (mask & AFL_ASE_DSPR2)
18437 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18438 if (mask & AFL_ASE_DSPR3)
18439 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18440 if (mask & AFL_ASE_EVA)
18441 fputs ("\n\tEnhanced VA Scheme", stdout);
18442 if (mask & AFL_ASE_MCU)
18443 fputs ("\n\tMCU (MicroController) ASE", stdout);
18444 if (mask & AFL_ASE_MDMX)
18445 fputs ("\n\tMDMX ASE", stdout);
18446 if (mask & AFL_ASE_MIPS3D)
18447 fputs ("\n\tMIPS-3D ASE", stdout);
18448 if (mask & AFL_ASE_MT)
18449 fputs ("\n\tMT ASE", stdout);
18450 if (mask & AFL_ASE_SMARTMIPS)
18451 fputs ("\n\tSmartMIPS ASE", stdout);
18452 if (mask & AFL_ASE_VIRT)
18453 fputs ("\n\tVZ ASE", stdout);
18454 if (mask & AFL_ASE_MSA)
18455 fputs ("\n\tMSA ASE", stdout);
18456 if (mask & AFL_ASE_MIPS16)
18457 fputs ("\n\tMIPS16 ASE", stdout);
18458 if (mask & AFL_ASE_MICROMIPS)
18459 fputs ("\n\tMICROMIPS ASE", stdout);
18460 if (mask & AFL_ASE_XPA)
18461 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18462 if (mask & AFL_ASE_MIPS16E2)
18463 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18464 if (mask & AFL_ASE_CRC)
18465 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18466 if (mask & AFL_ASE_GINV)
18467 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18468 if (mask & AFL_ASE_LOONGSON_MMI)
18469 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18470 if (mask & AFL_ASE_LOONGSON_CAM)
18471 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18472 if (mask & AFL_ASE_LOONGSON_EXT)
18473 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18474 if (mask & AFL_ASE_LOONGSON_EXT2)
18475 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18476 if (mask == 0)
18477 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18478 else if ((mask & ~AFL_ASE_MASK) != 0)
18479 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18480}
18481
18482static void
18483print_mips_isa_ext (unsigned int isa_ext)
18484{
18485 switch (isa_ext)
18486 {
18487 case 0:
18488 fputs (_("None"), stdout);
18489 break;
18490 case AFL_EXT_XLR:
18491 fputs ("RMI XLR", stdout);
18492 break;
2c629856
N
18493 case AFL_EXT_OCTEON3:
18494 fputs ("Cavium Networks Octeon3", stdout);
18495 break;
351cdf24
MF
18496 case AFL_EXT_OCTEON2:
18497 fputs ("Cavium Networks Octeon2", stdout);
18498 break;
18499 case AFL_EXT_OCTEONP:
18500 fputs ("Cavium Networks OcteonP", stdout);
18501 break;
351cdf24
MF
18502 case AFL_EXT_OCTEON:
18503 fputs ("Cavium Networks Octeon", stdout);
18504 break;
18505 case AFL_EXT_5900:
18506 fputs ("Toshiba R5900", stdout);
18507 break;
18508 case AFL_EXT_4650:
18509 fputs ("MIPS R4650", stdout);
18510 break;
18511 case AFL_EXT_4010:
18512 fputs ("LSI R4010", stdout);
18513 break;
18514 case AFL_EXT_4100:
18515 fputs ("NEC VR4100", stdout);
18516 break;
18517 case AFL_EXT_3900:
18518 fputs ("Toshiba R3900", stdout);
18519 break;
18520 case AFL_EXT_10000:
18521 fputs ("MIPS R10000", stdout);
18522 break;
18523 case AFL_EXT_SB1:
18524 fputs ("Broadcom SB-1", stdout);
18525 break;
18526 case AFL_EXT_4111:
18527 fputs ("NEC VR4111/VR4181", stdout);
18528 break;
18529 case AFL_EXT_4120:
18530 fputs ("NEC VR4120", stdout);
18531 break;
18532 case AFL_EXT_5400:
18533 fputs ("NEC VR5400", stdout);
18534 break;
18535 case AFL_EXT_5500:
18536 fputs ("NEC VR5500", stdout);
18537 break;
18538 case AFL_EXT_LOONGSON_2E:
18539 fputs ("ST Microelectronics Loongson 2E", stdout);
18540 break;
18541 case AFL_EXT_LOONGSON_2F:
18542 fputs ("ST Microelectronics Loongson 2F", stdout);
18543 break;
38bf472a
MR
18544 case AFL_EXT_INTERAPTIV_MR2:
18545 fputs ("Imagination interAptiv MR2", stdout);
18546 break;
351cdf24 18547 default:
00ac7aa0 18548 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18549 }
18550}
18551
32ec8896 18552static signed int
351cdf24
MF
18553get_mips_reg_size (int reg_size)
18554{
18555 return (reg_size == AFL_REG_NONE) ? 0
18556 : (reg_size == AFL_REG_32) ? 32
18557 : (reg_size == AFL_REG_64) ? 64
18558 : (reg_size == AFL_REG_128) ? 128
18559 : -1;
18560}
18561
015dc7e1 18562static bool
dda8d76d 18563process_mips_specific (Filedata * filedata)
5b18a4bc 18564{
2cf0635d 18565 Elf_Internal_Dyn * entry;
351cdf24 18566 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18567 size_t liblist_offset = 0;
18568 size_t liblistno = 0;
18569 size_t conflictsno = 0;
18570 size_t options_offset = 0;
18571 size_t conflicts_offset = 0;
861fb55a
DJ
18572 size_t pltrelsz = 0;
18573 size_t pltrel = 0;
625d49fc
AM
18574 uint64_t pltgot = 0;
18575 uint64_t mips_pltgot = 0;
18576 uint64_t jmprel = 0;
18577 uint64_t local_gotno = 0;
18578 uint64_t gotsym = 0;
18579 uint64_t symtabno = 0;
015dc7e1 18580 bool res = true;
103f02d3 18581
dda8d76d 18582 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18583 display_mips_gnu_attribute))
015dc7e1 18584 res = false;
2cf19d5c 18585
dda8d76d 18586 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18587
18588 if (sect != NULL)
18589 {
18590 Elf_External_ABIFlags_v0 *abiflags_ext;
18591 Elf_Internal_ABIFlags_v0 abiflags_in;
18592
18593 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18594 {
18595 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18596 res = false;
32ec8896 18597 }
351cdf24
MF
18598 else
18599 {
dda8d76d 18600 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18601 sect->sh_size, _("MIPS ABI Flags section"));
18602 if (abiflags_ext)
18603 {
18604 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18605 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18606 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18607 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18608 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18609 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18610 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18611 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18612 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18613 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18614 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18615
18616 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18617 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18618 if (abiflags_in.isa_rev > 1)
18619 printf ("r%d", abiflags_in.isa_rev);
18620 printf ("\nGPR size: %d",
18621 get_mips_reg_size (abiflags_in.gpr_size));
18622 printf ("\nCPR1 size: %d",
18623 get_mips_reg_size (abiflags_in.cpr1_size));
18624 printf ("\nCPR2 size: %d",
18625 get_mips_reg_size (abiflags_in.cpr2_size));
18626 fputs ("\nFP ABI: ", stdout);
18627 print_mips_fp_abi_value (abiflags_in.fp_abi);
18628 fputs ("ISA Extension: ", stdout);
18629 print_mips_isa_ext (abiflags_in.isa_ext);
18630 fputs ("\nASEs:", stdout);
18631 print_mips_ases (abiflags_in.ases);
18632 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18633 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18634 fputc ('\n', stdout);
18635 free (abiflags_ext);
18636 }
18637 }
18638 }
18639
19e6b90e 18640 /* We have a lot of special sections. Thanks SGI! */
978c4450 18641 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18642 {
18643 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18644 sect = find_section (filedata, ".got");
bbdd9a68
MR
18645 if (sect != NULL)
18646 {
18647 unsigned char *data_end;
18648 unsigned char *data;
625d49fc 18649 uint64_t ent, end;
bbdd9a68
MR
18650 int addr_size;
18651
18652 pltgot = sect->sh_addr;
18653
18654 ent = pltgot;
18655 addr_size = (is_32bit_elf ? 4 : 8);
18656 end = pltgot + sect->sh_size;
18657
dda8d76d 18658 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18659 end - pltgot, 1,
18660 _("Global Offset Table data"));
18661 /* PR 12855: Null data is handled gracefully throughout. */
18662 data_end = data + (end - pltgot);
18663
18664 printf (_("\nStatic GOT:\n"));
18665 printf (_(" Canonical gp value: "));
18666 print_vma (ent + 0x7ff0, LONG_HEX);
18667 printf ("\n\n");
18668
18669 /* In a dynamic binary GOT[0] is reserved for the dynamic
18670 loader to store the lazy resolver pointer, however in
18671 a static binary it may well have been omitted and GOT
18672 reduced to a table of addresses.
18673 PR 21344: Check for the entry being fully available
18674 before fetching it. */
18675 if (data
18676 && data + ent - pltgot + addr_size <= data_end
18677 && byte_get (data + ent - pltgot, addr_size) == 0)
18678 {
18679 printf (_(" Reserved entries:\n"));
18680 printf (_(" %*s %10s %*s\n"),
18681 addr_size * 2, _("Address"), _("Access"),
18682 addr_size * 2, _("Value"));
18683 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18684 printf ("\n");
625d49fc 18685 if (ent == (uint64_t) -1)
bbdd9a68
MR
18686 goto sgot_print_fail;
18687
18688 /* Check for the MSB of GOT[1] being set, identifying a
18689 GNU object. This entry will be used by some runtime
18690 loaders, to store the module pointer. Otherwise this
18691 is an ordinary local entry.
18692 PR 21344: Check for the entry being fully available
18693 before fetching it. */
18694 if (data
18695 && data + ent - pltgot + addr_size <= data_end
18696 && (byte_get (data + ent - pltgot, addr_size)
18697 >> (addr_size * 8 - 1)) != 0)
18698 {
18699 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18700 printf ("\n");
625d49fc 18701 if (ent == (uint64_t) -1)
bbdd9a68
MR
18702 goto sgot_print_fail;
18703 }
18704 printf ("\n");
18705 }
18706
f17e9d8a 18707 if (data != NULL && ent < end)
bbdd9a68
MR
18708 {
18709 printf (_(" Local entries:\n"));
18710 printf (" %*s %10s %*s\n",
18711 addr_size * 2, _("Address"), _("Access"),
18712 addr_size * 2, _("Value"));
18713 while (ent < end)
18714 {
18715 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18716 printf ("\n");
625d49fc 18717 if (ent == (uint64_t) -1)
bbdd9a68
MR
18718 goto sgot_print_fail;
18719 }
18720 printf ("\n");
18721 }
18722
18723 sgot_print_fail:
9db70fc3 18724 free (data);
bbdd9a68
MR
18725 }
18726 return res;
18727 }
252b5132 18728
978c4450 18729 for (entry = filedata->dynamic_section;
071436c6 18730 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18731 (entry < filedata->dynamic_section + filedata->dynamic_nent
18732 && entry->d_tag != DT_NULL);
071436c6 18733 ++entry)
252b5132
RH
18734 switch (entry->d_tag)
18735 {
18736 case DT_MIPS_LIBLIST:
d93f0186 18737 liblist_offset
dda8d76d 18738 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18739 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18740 break;
18741 case DT_MIPS_LIBLISTNO:
18742 liblistno = entry->d_un.d_val;
18743 break;
18744 case DT_MIPS_OPTIONS:
dda8d76d 18745 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18746 break;
18747 case DT_MIPS_CONFLICT:
d93f0186 18748 conflicts_offset
dda8d76d 18749 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18750 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18751 break;
18752 case DT_MIPS_CONFLICTNO:
18753 conflictsno = entry->d_un.d_val;
18754 break;
ccb4c951 18755 case DT_PLTGOT:
861fb55a
DJ
18756 pltgot = entry->d_un.d_ptr;
18757 break;
ccb4c951
RS
18758 case DT_MIPS_LOCAL_GOTNO:
18759 local_gotno = entry->d_un.d_val;
18760 break;
18761 case DT_MIPS_GOTSYM:
18762 gotsym = entry->d_un.d_val;
18763 break;
18764 case DT_MIPS_SYMTABNO:
18765 symtabno = entry->d_un.d_val;
18766 break;
861fb55a
DJ
18767 case DT_MIPS_PLTGOT:
18768 mips_pltgot = entry->d_un.d_ptr;
18769 break;
18770 case DT_PLTREL:
18771 pltrel = entry->d_un.d_val;
18772 break;
18773 case DT_PLTRELSZ:
18774 pltrelsz = entry->d_un.d_val;
18775 break;
18776 case DT_JMPREL:
18777 jmprel = entry->d_un.d_ptr;
18778 break;
252b5132
RH
18779 default:
18780 break;
18781 }
18782
18783 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18784 {
2cf0635d 18785 Elf32_External_Lib * elib;
252b5132
RH
18786 size_t cnt;
18787
dda8d76d 18788 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18789 sizeof (Elf32_External_Lib),
18790 liblistno,
18791 _("liblist section data"));
a6e9f9df 18792 if (elib)
252b5132 18793 {
26c527e6
AM
18794 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
18795 "\nSection '.liblist' contains %zu entries:\n",
18796 liblistno),
18797 liblistno);
2b692964 18798 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18799 stdout);
18800
18801 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18802 {
a6e9f9df 18803 Elf32_Lib liblist;
91d6fa6a 18804 time_t atime;
d5b07ef4 18805 char timebuf[128];
2cf0635d 18806 struct tm * tmp;
a6e9f9df
AM
18807
18808 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18809 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18810 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18811 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18812 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18813
91d6fa6a 18814 tmp = gmtime (&atime);
e9e44622
JJ
18815 snprintf (timebuf, sizeof (timebuf),
18816 "%04u-%02u-%02uT%02u:%02u:%02u",
18817 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18818 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18819
26c527e6 18820 printf ("%3zu: ", cnt);
84714f86
AM
18821 if (valid_dynamic_name (filedata, liblist.l_name))
18822 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18823 else
2b692964 18824 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18825 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18826 liblist.l_version);
a6e9f9df
AM
18827
18828 if (liblist.l_flags == 0)
2b692964 18829 puts (_(" NONE"));
a6e9f9df
AM
18830 else
18831 {
18832 static const struct
252b5132 18833 {
2cf0635d 18834 const char * name;
a6e9f9df 18835 int bit;
252b5132 18836 }
a6e9f9df
AM
18837 l_flags_vals[] =
18838 {
18839 { " EXACT_MATCH", LL_EXACT_MATCH },
18840 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18841 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18842 { " EXPORTS", LL_EXPORTS },
18843 { " DELAY_LOAD", LL_DELAY_LOAD },
18844 { " DELTA", LL_DELTA }
18845 };
18846 int flags = liblist.l_flags;
18847 size_t fcnt;
18848
60bca95a 18849 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18850 if ((flags & l_flags_vals[fcnt].bit) != 0)
18851 {
18852 fputs (l_flags_vals[fcnt].name, stdout);
18853 flags ^= l_flags_vals[fcnt].bit;
18854 }
18855 if (flags != 0)
18856 printf (" %#x", (unsigned int) flags);
252b5132 18857
a6e9f9df
AM
18858 puts ("");
18859 }
252b5132 18860 }
252b5132 18861
a6e9f9df
AM
18862 free (elib);
18863 }
32ec8896 18864 else
015dc7e1 18865 res = false;
252b5132
RH
18866 }
18867
18868 if (options_offset != 0)
18869 {
2cf0635d 18870 Elf_External_Options * eopt;
252b5132
RH
18871 size_t offset;
18872 int cnt;
18873
18874 /* Find the section header so that we get the size. */
dda8d76d 18875 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18876 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18877 if (sect == NULL)
18878 {
18879 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18880 return false;
071436c6 18881 }
7fc0c668
NC
18882 /* PR 24243 */
18883 if (sect->sh_size < sizeof (* eopt))
18884 {
18885 error (_("The MIPS options section is too small.\n"));
015dc7e1 18886 return false;
7fc0c668 18887 }
252b5132 18888
dda8d76d 18889 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18890 sect->sh_size, _("options"));
a6e9f9df 18891 if (eopt)
252b5132 18892 {
fd17d1e6 18893 Elf_Internal_Options option;
76da6bbe 18894
a6e9f9df 18895 offset = cnt = 0;
82b1b41b 18896 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18897 {
2cf0635d 18898 Elf_External_Options * eoption;
fd17d1e6 18899 unsigned int optsize;
252b5132 18900
a6e9f9df 18901 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18902
fd17d1e6 18903 optsize = BYTE_GET (eoption->size);
76da6bbe 18904
82b1b41b 18905 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18906 if (optsize < sizeof (* eopt)
18907 || optsize > sect->sh_size - offset)
82b1b41b 18908 {
645f43a8 18909 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18910 optsize);
645f43a8 18911 free (eopt);
015dc7e1 18912 return false;
82b1b41b 18913 }
fd17d1e6 18914 offset += optsize;
a6e9f9df
AM
18915 ++cnt;
18916 }
252b5132 18917
d3a49aa8
AM
18918 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18919 "\nSection '%s' contains %d entries:\n",
18920 cnt),
dda8d76d 18921 printable_section_name (filedata, sect), cnt);
76da6bbe 18922
82b1b41b 18923 offset = 0;
a6e9f9df 18924 while (cnt-- > 0)
252b5132 18925 {
a6e9f9df 18926 size_t len;
fd17d1e6
AM
18927 Elf_External_Options * eoption;
18928
18929 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18930
18931 option.kind = BYTE_GET (eoption->kind);
18932 option.size = BYTE_GET (eoption->size);
18933 option.section = BYTE_GET (eoption->section);
18934 option.info = BYTE_GET (eoption->info);
a6e9f9df 18935
fd17d1e6 18936 switch (option.kind)
252b5132 18937 {
a6e9f9df
AM
18938 case ODK_NULL:
18939 /* This shouldn't happen. */
d0c4e780 18940 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18941 option.section, option.info);
a6e9f9df 18942 break;
2e6be59c 18943
a6e9f9df
AM
18944 case ODK_REGINFO:
18945 printf (" REGINFO ");
dda8d76d 18946 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18947 {
2cf0635d 18948 Elf32_External_RegInfo * ereg;
b34976b6 18949 Elf32_RegInfo reginfo;
a6e9f9df 18950
2e6be59c 18951 /* 32bit form. */
fd17d1e6
AM
18952 if (option.size < (sizeof (Elf_External_Options)
18953 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18954 {
18955 printf (_("<corrupt>\n"));
18956 error (_("Truncated MIPS REGINFO option\n"));
18957 cnt = 0;
18958 break;
18959 }
18960
fd17d1e6 18961 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18962
a6e9f9df
AM
18963 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18964 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18965 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18966 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18967 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18968 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18969
d0c4e780
AM
18970 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18971 reginfo.ri_gprmask, reginfo.ri_gp_value);
18972 printf (" "
18973 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18974 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18975 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18976 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18977 }
18978 else
18979 {
18980 /* 64 bit form. */
2cf0635d 18981 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18982 Elf64_Internal_RegInfo reginfo;
18983
fd17d1e6
AM
18984 if (option.size < (sizeof (Elf_External_Options)
18985 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18986 {
18987 printf (_("<corrupt>\n"));
18988 error (_("Truncated MIPS REGINFO option\n"));
18989 cnt = 0;
18990 break;
18991 }
18992
fd17d1e6 18993 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18994 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18995 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18996 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18997 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18998 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18999 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 19000
d0c4e780
AM
19001 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
19002 reginfo.ri_gprmask, reginfo.ri_gp_value);
19003 printf (" "
19004 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19005 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19006 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19007 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19008 }
fd17d1e6 19009 offset += option.size;
a6e9f9df 19010 continue;
2e6be59c 19011
a6e9f9df
AM
19012 case ODK_EXCEPTIONS:
19013 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 19014 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 19015 fputs (") fpe_max(", stdout);
fd17d1e6 19016 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
19017 fputs (")", stdout);
19018
fd17d1e6 19019 if (option.info & OEX_PAGE0)
a6e9f9df 19020 fputs (" PAGE0", stdout);
fd17d1e6 19021 if (option.info & OEX_SMM)
a6e9f9df 19022 fputs (" SMM", stdout);
fd17d1e6 19023 if (option.info & OEX_FPDBUG)
a6e9f9df 19024 fputs (" FPDBUG", stdout);
fd17d1e6 19025 if (option.info & OEX_DISMISS)
a6e9f9df
AM
19026 fputs (" DISMISS", stdout);
19027 break;
2e6be59c 19028
a6e9f9df
AM
19029 case ODK_PAD:
19030 fputs (" PAD ", stdout);
fd17d1e6 19031 if (option.info & OPAD_PREFIX)
a6e9f9df 19032 fputs (" PREFIX", stdout);
fd17d1e6 19033 if (option.info & OPAD_POSTFIX)
a6e9f9df 19034 fputs (" POSTFIX", stdout);
fd17d1e6 19035 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
19036 fputs (" SYMBOL", stdout);
19037 break;
2e6be59c 19038
a6e9f9df
AM
19039 case ODK_HWPATCH:
19040 fputs (" HWPATCH ", stdout);
fd17d1e6 19041 if (option.info & OHW_R4KEOP)
a6e9f9df 19042 fputs (" R4KEOP", stdout);
fd17d1e6 19043 if (option.info & OHW_R8KPFETCH)
a6e9f9df 19044 fputs (" R8KPFETCH", stdout);
fd17d1e6 19045 if (option.info & OHW_R5KEOP)
a6e9f9df 19046 fputs (" R5KEOP", stdout);
fd17d1e6 19047 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
19048 fputs (" R5KCVTL", stdout);
19049 break;
2e6be59c 19050
a6e9f9df
AM
19051 case ODK_FILL:
19052 fputs (" FILL ", stdout);
19053 /* XXX Print content of info word? */
19054 break;
2e6be59c 19055
a6e9f9df
AM
19056 case ODK_TAGS:
19057 fputs (" TAGS ", stdout);
19058 /* XXX Print content of info word? */
19059 break;
2e6be59c 19060
a6e9f9df
AM
19061 case ODK_HWAND:
19062 fputs (" HWAND ", stdout);
fd17d1e6 19063 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19064 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19065 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19066 fputs (" R4KEOP_CLEAN", stdout);
19067 break;
2e6be59c 19068
a6e9f9df
AM
19069 case ODK_HWOR:
19070 fputs (" HWOR ", stdout);
fd17d1e6 19071 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19072 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19073 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19074 fputs (" R4KEOP_CLEAN", stdout);
19075 break;
2e6be59c 19076
a6e9f9df 19077 case ODK_GP_GROUP:
d0c4e780 19078 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
19079 option.info & OGP_GROUP,
19080 (option.info & OGP_SELF) >> 16);
a6e9f9df 19081 break;
2e6be59c 19082
a6e9f9df 19083 case ODK_IDENT:
d0c4e780 19084 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
19085 option.info & OGP_GROUP,
19086 (option.info & OGP_SELF) >> 16);
a6e9f9df 19087 break;
2e6be59c 19088
a6e9f9df
AM
19089 default:
19090 /* This shouldn't happen. */
d0c4e780 19091 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 19092 option.kind, option.section, option.info);
a6e9f9df 19093 break;
252b5132 19094 }
a6e9f9df 19095
2cf0635d 19096 len = sizeof (* eopt);
fd17d1e6 19097 while (len < option.size)
82b1b41b 19098 {
fd17d1e6 19099 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 19100
82b1b41b
NC
19101 if (ISPRINT (datum))
19102 printf ("%c", datum);
19103 else
19104 printf ("\\%03o", datum);
19105 len ++;
19106 }
a6e9f9df 19107 fputs ("\n", stdout);
82b1b41b 19108
fd17d1e6 19109 offset += option.size;
252b5132 19110 }
a6e9f9df 19111 free (eopt);
252b5132 19112 }
32ec8896 19113 else
015dc7e1 19114 res = false;
252b5132
RH
19115 }
19116
19117 if (conflicts_offset != 0 && conflictsno != 0)
19118 {
2cf0635d 19119 Elf32_Conflict * iconf;
252b5132
RH
19120 size_t cnt;
19121
978c4450 19122 if (filedata->dynamic_symbols == NULL)
252b5132 19123 {
591a748a 19124 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 19125 return false;
252b5132
RH
19126 }
19127
7296a62a
NC
19128 /* PR 21345 - print a slightly more helpful error message
19129 if we are sure that the cmalloc will fail. */
645f43a8 19130 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 19131 {
26c527e6
AM
19132 error (_("Overlarge number of conflicts detected: %zx\n"),
19133 conflictsno);
015dc7e1 19134 return false;
7296a62a
NC
19135 }
19136
3f5e193b 19137 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
19138 if (iconf == NULL)
19139 {
8b73c356 19140 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 19141 return false;
252b5132
RH
19142 }
19143
9ea033b2 19144 if (is_32bit_elf)
252b5132 19145 {
2cf0635d 19146 Elf32_External_Conflict * econf32;
a6e9f9df 19147
3f5e193b 19148 econf32 = (Elf32_External_Conflict *)
95099889
AM
19149 get_data (NULL, filedata, conflicts_offset,
19150 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 19151 if (!econf32)
5a814d6d
AM
19152 {
19153 free (iconf);
015dc7e1 19154 return false;
5a814d6d 19155 }
252b5132
RH
19156
19157 for (cnt = 0; cnt < conflictsno; ++cnt)
19158 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
19159
19160 free (econf32);
252b5132
RH
19161 }
19162 else
19163 {
2cf0635d 19164 Elf64_External_Conflict * econf64;
a6e9f9df 19165
3f5e193b 19166 econf64 = (Elf64_External_Conflict *)
95099889
AM
19167 get_data (NULL, filedata, conflicts_offset,
19168 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 19169 if (!econf64)
5a814d6d
AM
19170 {
19171 free (iconf);
015dc7e1 19172 return false;
5a814d6d 19173 }
252b5132
RH
19174
19175 for (cnt = 0; cnt < conflictsno; ++cnt)
19176 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
19177
19178 free (econf64);
252b5132
RH
19179 }
19180
26c527e6
AM
19181 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19182 "\nSection '.conflict' contains %zu entries:\n",
19183 conflictsno),
19184 conflictsno);
252b5132
RH
19185 puts (_(" Num: Index Value Name"));
19186
19187 for (cnt = 0; cnt < conflictsno; ++cnt)
19188 {
26c527e6 19189 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 19190
978c4450 19191 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 19192 printf (_("<corrupt symbol index>"));
d79b3d50 19193 else
e0a31db1
NC
19194 {
19195 Elf_Internal_Sym * psym;
19196
978c4450 19197 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
19198 print_vma (psym->st_value, FULL_HEX);
19199 putchar (' ');
84714f86
AM
19200 if (valid_dynamic_name (filedata, psym->st_name))
19201 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19202 else
19203 printf (_("<corrupt: %14ld>"), psym->st_name);
19204 }
31104126 19205 putchar ('\n');
252b5132
RH
19206 }
19207
252b5132
RH
19208 free (iconf);
19209 }
19210
ccb4c951
RS
19211 if (pltgot != 0 && local_gotno != 0)
19212 {
625d49fc 19213 uint64_t ent, local_end, global_end;
bbeee7ea 19214 size_t i, offset;
2cf0635d 19215 unsigned char * data;
82b1b41b 19216 unsigned char * data_end;
bbeee7ea 19217 int addr_size;
ccb4c951 19218
91d6fa6a 19219 ent = pltgot;
ccb4c951
RS
19220 addr_size = (is_32bit_elf ? 4 : 8);
19221 local_end = pltgot + local_gotno * addr_size;
ccb4c951 19222
74e1a04b
NC
19223 /* PR binutils/17533 file: 012-111227-0.004 */
19224 if (symtabno < gotsym)
19225 {
26c527e6
AM
19226 error (_("The GOT symbol offset (%" PRIu64
19227 ") is greater than the symbol table size (%" PRIu64 ")\n"),
19228 gotsym, symtabno);
015dc7e1 19229 return false;
74e1a04b 19230 }
82b1b41b 19231
74e1a04b 19232 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
19233 /* PR 17531: file: 54c91a34. */
19234 if (global_end < local_end)
19235 {
26c527e6 19236 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 19237 return false;
82b1b41b 19238 }
948f632f 19239
dda8d76d
NC
19240 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
19241 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
19242 global_end - pltgot, 1,
19243 _("Global Offset Table data"));
919383ac 19244 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 19245 data_end = data + (global_end - pltgot);
59245841 19246
ccb4c951
RS
19247 printf (_("\nPrimary GOT:\n"));
19248 printf (_(" Canonical gp value: "));
19249 print_vma (pltgot + 0x7ff0, LONG_HEX);
19250 printf ("\n\n");
19251
19252 printf (_(" Reserved entries:\n"));
19253 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
19254 addr_size * 2, _("Address"), _("Access"),
19255 addr_size * 2, _("Initial"));
82b1b41b 19256 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 19257 printf (_(" Lazy resolver\n"));
625d49fc 19258 if (ent == (uint64_t) -1)
82b1b41b 19259 goto got_print_fail;
75ec1fdb 19260
c4ab9505
MR
19261 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19262 This entry will be used by some runtime loaders, to store the
19263 module pointer. Otherwise this is an ordinary local entry.
19264 PR 21344: Check for the entry being fully available before
19265 fetching it. */
19266 if (data
19267 && data + ent - pltgot + addr_size <= data_end
19268 && (byte_get (data + ent - pltgot, addr_size)
19269 >> (addr_size * 8 - 1)) != 0)
19270 {
19271 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19272 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 19273 if (ent == (uint64_t) -1)
c4ab9505 19274 goto got_print_fail;
ccb4c951
RS
19275 }
19276 printf ("\n");
19277
f17e9d8a 19278 if (data != NULL && ent < local_end)
ccb4c951
RS
19279 {
19280 printf (_(" Local entries:\n"));
cc5914eb 19281 printf (" %*s %10s %*s\n",
2b692964
NC
19282 addr_size * 2, _("Address"), _("Access"),
19283 addr_size * 2, _("Initial"));
91d6fa6a 19284 while (ent < local_end)
ccb4c951 19285 {
82b1b41b 19286 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19287 printf ("\n");
625d49fc 19288 if (ent == (uint64_t) -1)
82b1b41b 19289 goto got_print_fail;
ccb4c951
RS
19290 }
19291 printf ("\n");
19292 }
19293
f17e9d8a 19294 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19295 {
19296 int sym_width;
19297
19298 printf (_(" Global entries:\n"));
cc5914eb 19299 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19300 addr_size * 2, _("Address"),
19301 _("Access"),
2b692964 19302 addr_size * 2, _("Initial"),
9cf03b7e
NC
19303 addr_size * 2, _("Sym.Val."),
19304 _("Type"),
19305 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19306 _("Ndx"), _("Name"));
0b4362b0 19307
ccb4c951 19308 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19309
ccb4c951
RS
19310 for (i = gotsym; i < symtabno; i++)
19311 {
82b1b41b 19312 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19313 printf (" ");
e0a31db1 19314
978c4450 19315 if (filedata->dynamic_symbols == NULL)
e0a31db1 19316 printf (_("<no dynamic symbols>"));
978c4450 19317 else if (i < filedata->num_dynamic_syms)
e0a31db1 19318 {
978c4450 19319 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19320
19321 print_vma (psym->st_value, LONG_HEX);
19322 printf (" %-7s %3s ",
dda8d76d
NC
19323 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19324 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19325
84714f86 19326 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19327 print_symbol (sym_width,
84714f86 19328 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19329 else
19330 printf (_("<corrupt: %14ld>"), psym->st_name);
19331 }
ccb4c951 19332 else
26c527e6
AM
19333 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
19334 i);
e0a31db1 19335
ccb4c951 19336 printf ("\n");
625d49fc 19337 if (ent == (uint64_t) -1)
82b1b41b 19338 break;
ccb4c951
RS
19339 }
19340 printf ("\n");
19341 }
19342
82b1b41b 19343 got_print_fail:
9db70fc3 19344 free (data);
ccb4c951
RS
19345 }
19346
861fb55a
DJ
19347 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19348 {
625d49fc 19349 uint64_t ent, end;
26c527e6
AM
19350 uint64_t offset, rel_offset;
19351 uint64_t count, i;
2cf0635d 19352 unsigned char * data;
861fb55a 19353 int addr_size, sym_width;
2cf0635d 19354 Elf_Internal_Rela * rels;
861fb55a 19355
dda8d76d 19356 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19357 if (pltrel == DT_RELA)
19358 {
dda8d76d 19359 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19360 return false;
861fb55a
DJ
19361 }
19362 else
19363 {
dda8d76d 19364 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19365 return false;
861fb55a
DJ
19366 }
19367
91d6fa6a 19368 ent = mips_pltgot;
861fb55a
DJ
19369 addr_size = (is_32bit_elf ? 4 : 8);
19370 end = mips_pltgot + (2 + count) * addr_size;
19371
dda8d76d
NC
19372 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19373 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19374 1, _("Procedure Linkage Table data"));
59245841 19375 if (data == NULL)
288f0ba2
AM
19376 {
19377 free (rels);
015dc7e1 19378 return false;
288f0ba2 19379 }
59245841 19380
9cf03b7e 19381 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19382 printf (_(" Reserved entries:\n"));
19383 printf (_(" %*s %*s Purpose\n"),
2b692964 19384 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19385 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19386 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19387 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19388 printf (_(" Module pointer\n"));
861fb55a
DJ
19389 printf ("\n");
19390
19391 printf (_(" Entries:\n"));
cc5914eb 19392 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19393 addr_size * 2, _("Address"),
19394 addr_size * 2, _("Initial"),
19395 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19396 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19397 for (i = 0; i < count; i++)
19398 {
26c527e6 19399 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19400
91d6fa6a 19401 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19402 printf (" ");
e0a31db1 19403
978c4450 19404 if (idx >= filedata->num_dynamic_syms)
26c527e6 19405 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 19406 else
e0a31db1 19407 {
978c4450 19408 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19409
19410 print_vma (psym->st_value, LONG_HEX);
19411 printf (" %-7s %3s ",
dda8d76d
NC
19412 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19413 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19414 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19415 print_symbol (sym_width,
84714f86 19416 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19417 else
19418 printf (_("<corrupt: %14ld>"), psym->st_name);
19419 }
861fb55a
DJ
19420 printf ("\n");
19421 }
19422 printf ("\n");
19423
9db70fc3 19424 free (data);
861fb55a
DJ
19425 free (rels);
19426 }
19427
32ec8896 19428 return res;
252b5132
RH
19429}
19430
015dc7e1 19431static bool
dda8d76d 19432process_nds32_specific (Filedata * filedata)
35c08157
KLC
19433{
19434 Elf_Internal_Shdr *sect = NULL;
19435
dda8d76d 19436 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19437 if (sect != NULL && sect->sh_size >= 4)
35c08157 19438 {
9c7b8e9b
AM
19439 unsigned char *buf;
19440 unsigned int flag;
35c08157
KLC
19441
19442 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19443 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19444 _("NDS32 elf flags section"));
35c08157 19445
9c7b8e9b 19446 if (buf == NULL)
015dc7e1 19447 return false;
32ec8896 19448
9c7b8e9b
AM
19449 flag = byte_get (buf, 4);
19450 free (buf);
19451 switch (flag & 0x3)
35c08157
KLC
19452 {
19453 case 0:
19454 printf ("(VEC_SIZE):\tNo entry.\n");
19455 break;
19456 case 1:
19457 printf ("(VEC_SIZE):\t4 bytes\n");
19458 break;
19459 case 2:
19460 printf ("(VEC_SIZE):\t16 bytes\n");
19461 break;
19462 case 3:
19463 printf ("(VEC_SIZE):\treserved\n");
19464 break;
19465 }
19466 }
19467
015dc7e1 19468 return true;
35c08157
KLC
19469}
19470
015dc7e1 19471static bool
dda8d76d 19472process_gnu_liblist (Filedata * filedata)
047b2264 19473{
2cf0635d
NC
19474 Elf_Internal_Shdr * section;
19475 Elf_Internal_Shdr * string_sec;
19476 Elf32_External_Lib * elib;
19477 char * strtab;
c256ffe7 19478 size_t strtab_size;
047b2264 19479 size_t cnt;
26c527e6 19480 uint64_t num_liblist;
047b2264 19481 unsigned i;
015dc7e1 19482 bool res = true;
047b2264
JJ
19483
19484 if (! do_arch)
015dc7e1 19485 return true;
047b2264 19486
dda8d76d
NC
19487 for (i = 0, section = filedata->section_headers;
19488 i < filedata->file_header.e_shnum;
b34976b6 19489 i++, section++)
047b2264
JJ
19490 {
19491 switch (section->sh_type)
19492 {
19493 case SHT_GNU_LIBLIST:
dda8d76d 19494 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19495 break;
19496
3f5e193b 19497 elib = (Elf32_External_Lib *)
dda8d76d 19498 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19499 _("liblist section data"));
047b2264
JJ
19500
19501 if (elib == NULL)
32ec8896 19502 {
015dc7e1 19503 res = false;
32ec8896
NC
19504 break;
19505 }
047b2264 19506
dda8d76d
NC
19507 string_sec = filedata->section_headers + section->sh_link;
19508 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19509 string_sec->sh_size,
19510 _("liblist string table"));
047b2264
JJ
19511 if (strtab == NULL
19512 || section->sh_entsize != sizeof (Elf32_External_Lib))
19513 {
19514 free (elib);
2842702f 19515 free (strtab);
015dc7e1 19516 res = false;
047b2264
JJ
19517 break;
19518 }
59245841 19519 strtab_size = string_sec->sh_size;
047b2264 19520
d3a49aa8 19521 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
19522 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
19523 " entries:\n",
19524 "\nLibrary list section '%s' contains %" PRIu64
19525 " entries:\n",
d3a49aa8 19526 num_liblist),
dda8d76d 19527 printable_section_name (filedata, section),
d3a49aa8 19528 num_liblist);
047b2264 19529
2b692964 19530 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19531
19532 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19533 ++cnt)
19534 {
19535 Elf32_Lib liblist;
91d6fa6a 19536 time_t atime;
d5b07ef4 19537 char timebuf[128];
2cf0635d 19538 struct tm * tmp;
047b2264
JJ
19539
19540 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19541 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19542 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19543 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19544 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19545
91d6fa6a 19546 tmp = gmtime (&atime);
e9e44622
JJ
19547 snprintf (timebuf, sizeof (timebuf),
19548 "%04u-%02u-%02uT%02u:%02u:%02u",
19549 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19550 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 19551
26c527e6 19552 printf ("%3zu: ", cnt);
047b2264 19553 if (do_wide)
c256ffe7 19554 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19555 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19556 else
c256ffe7 19557 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19558 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19559 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19560 liblist.l_version, liblist.l_flags);
19561 }
19562
19563 free (elib);
2842702f 19564 free (strtab);
047b2264
JJ
19565 }
19566 }
19567
32ec8896 19568 return res;
047b2264
JJ
19569}
19570
9437c45b 19571static const char *
dda8d76d 19572get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19573{
19574 static char buff[64];
103f02d3 19575
dda8d76d 19576 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19577 switch (e_type)
19578 {
57346661 19579 case NT_AUXV:
1ec5cd37 19580 return _("NT_AUXV (auxiliary vector)");
57346661 19581 case NT_PRSTATUS:
1ec5cd37 19582 return _("NT_PRSTATUS (prstatus structure)");
57346661 19583 case NT_FPREGSET:
1ec5cd37 19584 return _("NT_FPREGSET (floating point registers)");
57346661 19585 case NT_PRPSINFO:
1ec5cd37 19586 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19587 case NT_TASKSTRUCT:
1ec5cd37 19588 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19589 case NT_GDB_TDESC:
19590 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19591 case NT_PRXFPREG:
1ec5cd37 19592 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19593 case NT_PPC_VMX:
19594 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19595 case NT_PPC_VSX:
19596 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19597 case NT_PPC_TAR:
19598 return _("NT_PPC_TAR (ppc TAR register)");
19599 case NT_PPC_PPR:
19600 return _("NT_PPC_PPR (ppc PPR register)");
19601 case NT_PPC_DSCR:
19602 return _("NT_PPC_DSCR (ppc DSCR register)");
19603 case NT_PPC_EBB:
19604 return _("NT_PPC_EBB (ppc EBB registers)");
19605 case NT_PPC_PMU:
19606 return _("NT_PPC_PMU (ppc PMU registers)");
19607 case NT_PPC_TM_CGPR:
19608 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19609 case NT_PPC_TM_CFPR:
19610 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19611 case NT_PPC_TM_CVMX:
19612 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19613 case NT_PPC_TM_CVSX:
3fd21718 19614 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19615 case NT_PPC_TM_SPR:
19616 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19617 case NT_PPC_TM_CTAR:
19618 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19619 case NT_PPC_TM_CPPR:
19620 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19621 case NT_PPC_TM_CDSCR:
19622 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19623 case NT_386_TLS:
19624 return _("NT_386_TLS (x86 TLS information)");
19625 case NT_386_IOPERM:
19626 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19627 case NT_X86_XSTATE:
19628 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19629 case NT_X86_CET:
19630 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19631 case NT_S390_HIGH_GPRS:
19632 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19633 case NT_S390_TIMER:
19634 return _("NT_S390_TIMER (s390 timer register)");
19635 case NT_S390_TODCMP:
19636 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19637 case NT_S390_TODPREG:
19638 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19639 case NT_S390_CTRS:
19640 return _("NT_S390_CTRS (s390 control registers)");
19641 case NT_S390_PREFIX:
19642 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19643 case NT_S390_LAST_BREAK:
19644 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19645 case NT_S390_SYSTEM_CALL:
19646 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19647 case NT_S390_TDB:
19648 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19649 case NT_S390_VXRS_LOW:
19650 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19651 case NT_S390_VXRS_HIGH:
19652 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19653 case NT_S390_GS_CB:
19654 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19655 case NT_S390_GS_BC:
19656 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19657 case NT_ARM_VFP:
19658 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19659 case NT_ARM_TLS:
19660 return _("NT_ARM_TLS (AArch TLS registers)");
19661 case NT_ARM_HW_BREAK:
19662 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19663 case NT_ARM_HW_WATCH:
19664 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
19665 case NT_ARM_SYSTEM_CALL:
19666 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
19667 case NT_ARM_SVE:
19668 return _("NT_ARM_SVE (AArch SVE registers)");
19669 case NT_ARM_PAC_MASK:
19670 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19671 case NT_ARM_PACA_KEYS:
19672 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19673 case NT_ARM_PACG_KEYS:
19674 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19675 case NT_ARM_TAGGED_ADDR_CTRL:
19676 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
a8f175d9
LM
19677 case NT_ARM_SSVE:
19678 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
19679 case NT_ARM_ZA:
19680 return _("NT_ARM_ZA (AArch64 SME ZA register)");
3af2785c
LM
19681 case NT_ARM_PAC_ENABLED_KEYS:
19682 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19683 case NT_ARC_V2:
19684 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19685 case NT_RISCV_CSR:
19686 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19687 case NT_PSTATUS:
1ec5cd37 19688 return _("NT_PSTATUS (pstatus structure)");
57346661 19689 case NT_FPREGS:
1ec5cd37 19690 return _("NT_FPREGS (floating point registers)");
57346661 19691 case NT_PSINFO:
1ec5cd37 19692 return _("NT_PSINFO (psinfo structure)");
57346661 19693 case NT_LWPSTATUS:
1ec5cd37 19694 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19695 case NT_LWPSINFO:
1ec5cd37 19696 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19697 case NT_WIN32PSTATUS:
1ec5cd37 19698 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19699 case NT_SIGINFO:
19700 return _("NT_SIGINFO (siginfo_t data)");
19701 case NT_FILE:
19702 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19703 default:
19704 break;
19705 }
19706 else
19707 switch (e_type)
19708 {
19709 case NT_VERSION:
19710 return _("NT_VERSION (version)");
19711 case NT_ARCH:
19712 return _("NT_ARCH (architecture)");
9ef920e9 19713 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19714 return _("OPEN");
9ef920e9 19715 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19716 return _("func");
c8795e1f
NC
19717 case NT_GO_BUILDID:
19718 return _("GO BUILDID");
3ac925fc
LB
19719 case FDO_PACKAGING_METADATA:
19720 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19721 default:
19722 break;
19723 }
19724
e9e44622 19725 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19726 return buff;
779fe533
NC
19727}
19728
015dc7e1 19729static bool
9ece1fa9
TT
19730print_core_note (Elf_Internal_Note *pnote)
19731{
19732 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 19733 uint64_t count, page_size;
9ece1fa9
TT
19734 unsigned char *descdata, *filenames, *descend;
19735
19736 if (pnote->type != NT_FILE)
04ac15ab
AS
19737 {
19738 if (do_wide)
19739 printf ("\n");
015dc7e1 19740 return true;
04ac15ab 19741 }
9ece1fa9 19742
9ece1fa9
TT
19743 if (!is_32bit_elf)
19744 {
19745 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19746 /* Still "successful". */
015dc7e1 19747 return true;
9ece1fa9 19748 }
9ece1fa9
TT
19749
19750 if (pnote->descsz < 2 * addr_size)
19751 {
32ec8896 19752 error (_(" Malformed note - too short for header\n"));
015dc7e1 19753 return false;
9ece1fa9
TT
19754 }
19755
19756 descdata = (unsigned char *) pnote->descdata;
19757 descend = descdata + pnote->descsz;
19758
19759 if (descdata[pnote->descsz - 1] != '\0')
19760 {
32ec8896 19761 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19762 return false;
9ece1fa9
TT
19763 }
19764
19765 count = byte_get (descdata, addr_size);
19766 descdata += addr_size;
19767
19768 page_size = byte_get (descdata, addr_size);
19769 descdata += addr_size;
19770
625d49fc 19771 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 19772 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19773 {
32ec8896 19774 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19775 return false;
9ece1fa9
TT
19776 }
19777
19778 printf (_(" Page size: "));
19779 print_vma (page_size, DEC);
19780 printf ("\n");
19781
19782 printf (_(" %*s%*s%*s\n"),
19783 (int) (2 + 2 * addr_size), _("Start"),
19784 (int) (4 + 2 * addr_size), _("End"),
19785 (int) (4 + 2 * addr_size), _("Page Offset"));
19786 filenames = descdata + count * 3 * addr_size;
595712bb 19787 while (count-- > 0)
9ece1fa9 19788 {
625d49fc 19789 uint64_t start, end, file_ofs;
9ece1fa9
TT
19790
19791 if (filenames == descend)
19792 {
32ec8896 19793 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19794 return false;
9ece1fa9
TT
19795 }
19796
19797 start = byte_get (descdata, addr_size);
19798 descdata += addr_size;
19799 end = byte_get (descdata, addr_size);
19800 descdata += addr_size;
19801 file_ofs = byte_get (descdata, addr_size);
19802 descdata += addr_size;
19803
19804 printf (" ");
19805 print_vma (start, FULL_HEX);
19806 printf (" ");
19807 print_vma (end, FULL_HEX);
19808 printf (" ");
19809 print_vma (file_ofs, FULL_HEX);
19810 printf ("\n %s\n", filenames);
19811
19812 filenames += 1 + strlen ((char *) filenames);
19813 }
19814
015dc7e1 19815 return true;
9ece1fa9
TT
19816}
19817
1118d252
RM
19818static const char *
19819get_gnu_elf_note_type (unsigned e_type)
19820{
1449284b 19821 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19822 switch (e_type)
19823 {
19824 case NT_GNU_ABI_TAG:
19825 return _("NT_GNU_ABI_TAG (ABI version tag)");
19826 case NT_GNU_HWCAP:
19827 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19828 case NT_GNU_BUILD_ID:
19829 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19830 case NT_GNU_GOLD_VERSION:
19831 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19832 case NT_GNU_PROPERTY_TYPE_0:
19833 return _("NT_GNU_PROPERTY_TYPE_0");
19834 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19835 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19836 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19837 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19838 default:
1449284b
NC
19839 {
19840 static char buff[64];
1118d252 19841
1449284b
NC
19842 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19843 return buff;
19844 }
19845 }
1118d252
RM
19846}
19847
a9eafb08
L
19848static void
19849decode_x86_compat_isa (unsigned int bitmask)
19850{
19851 while (bitmask)
19852 {
19853 unsigned int bit = bitmask & (- bitmask);
19854
19855 bitmask &= ~ bit;
19856 switch (bit)
19857 {
19858 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19859 printf ("i486");
19860 break;
19861 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19862 printf ("586");
19863 break;
19864 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19865 printf ("686");
19866 break;
19867 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19868 printf ("SSE");
19869 break;
19870 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19871 printf ("SSE2");
19872 break;
19873 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19874 printf ("SSE3");
19875 break;
19876 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19877 printf ("SSSE3");
19878 break;
19879 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19880 printf ("SSE4_1");
19881 break;
19882 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19883 printf ("SSE4_2");
19884 break;
19885 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19886 printf ("AVX");
19887 break;
19888 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19889 printf ("AVX2");
19890 break;
19891 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19892 printf ("AVX512F");
19893 break;
19894 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19895 printf ("AVX512CD");
19896 break;
19897 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19898 printf ("AVX512ER");
19899 break;
19900 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19901 printf ("AVX512PF");
19902 break;
19903 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19904 printf ("AVX512VL");
19905 break;
19906 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19907 printf ("AVX512DQ");
19908 break;
19909 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19910 printf ("AVX512BW");
19911 break;
65b3d26e
L
19912 default:
19913 printf (_("<unknown: %x>"), bit);
19914 break;
a9eafb08
L
19915 }
19916 if (bitmask)
19917 printf (", ");
19918 }
19919}
19920
9ef920e9 19921static void
32930e4e 19922decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19923{
0a59decb 19924 if (!bitmask)
90c745dc
L
19925 {
19926 printf (_("<None>"));
19927 return;
19928 }
90c745dc 19929
9ef920e9
NC
19930 while (bitmask)
19931 {
1fc87489 19932 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19933
19934 bitmask &= ~ bit;
19935 switch (bit)
19936 {
32930e4e 19937 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19938 printf ("CMOV");
19939 break;
32930e4e 19940 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19941 printf ("SSE");
19942 break;
32930e4e 19943 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19944 printf ("SSE2");
19945 break;
32930e4e 19946 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19947 printf ("SSE3");
19948 break;
32930e4e 19949 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19950 printf ("SSSE3");
19951 break;
32930e4e 19952 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19953 printf ("SSE4_1");
19954 break;
32930e4e 19955 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19956 printf ("SSE4_2");
19957 break;
32930e4e 19958 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19959 printf ("AVX");
19960 break;
32930e4e 19961 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19962 printf ("AVX2");
19963 break;
32930e4e 19964 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19965 printf ("FMA");
19966 break;
32930e4e 19967 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19968 printf ("AVX512F");
19969 break;
32930e4e 19970 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19971 printf ("AVX512CD");
19972 break;
32930e4e 19973 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19974 printf ("AVX512ER");
19975 break;
32930e4e 19976 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19977 printf ("AVX512PF");
19978 break;
32930e4e 19979 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19980 printf ("AVX512VL");
19981 break;
32930e4e 19982 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19983 printf ("AVX512DQ");
19984 break;
32930e4e 19985 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19986 printf ("AVX512BW");
19987 break;
32930e4e 19988 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19989 printf ("AVX512_4FMAPS");
19990 break;
32930e4e 19991 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19992 printf ("AVX512_4VNNIW");
19993 break;
32930e4e 19994 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19995 printf ("AVX512_BITALG");
19996 break;
32930e4e 19997 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19998 printf ("AVX512_IFMA");
19999 break;
32930e4e 20000 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
20001 printf ("AVX512_VBMI");
20002 break;
32930e4e 20003 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
20004 printf ("AVX512_VBMI2");
20005 break;
32930e4e 20006 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
20007 printf ("AVX512_VNNI");
20008 break;
32930e4e 20009 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
20010 printf ("AVX512_BF16");
20011 break;
65b3d26e
L
20012 default:
20013 printf (_("<unknown: %x>"), bit);
20014 break;
9ef920e9
NC
20015 }
20016 if (bitmask)
20017 printf (", ");
20018 }
20019}
20020
28cdbb18
SM
20021static const char *
20022get_amdgpu_elf_note_type (unsigned int e_type)
20023{
20024 switch (e_type)
20025 {
20026 case NT_AMDGPU_METADATA:
20027 return _("NT_AMDGPU_METADATA (code object metadata)");
20028 default:
20029 {
20030 static char buf[64];
20031 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
20032 return buf;
20033 }
20034 }
20035}
20036
32930e4e
L
20037static void
20038decode_x86_isa (unsigned int bitmask)
20039{
32930e4e
L
20040 while (bitmask)
20041 {
20042 unsigned int bit = bitmask & (- bitmask);
20043
20044 bitmask &= ~ bit;
20045 switch (bit)
20046 {
b0ab0693
L
20047 case GNU_PROPERTY_X86_ISA_1_BASELINE:
20048 printf ("x86-64-baseline");
20049 break;
32930e4e
L
20050 case GNU_PROPERTY_X86_ISA_1_V2:
20051 printf ("x86-64-v2");
20052 break;
20053 case GNU_PROPERTY_X86_ISA_1_V3:
20054 printf ("x86-64-v3");
20055 break;
20056 case GNU_PROPERTY_X86_ISA_1_V4:
20057 printf ("x86-64-v4");
20058 break;
20059 default:
20060 printf (_("<unknown: %x>"), bit);
20061 break;
20062 }
20063 if (bitmask)
20064 printf (", ");
20065 }
20066}
20067
ee2fdd6f 20068static void
a9eafb08 20069decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 20070{
0a59decb 20071 if (!bitmask)
90c745dc
L
20072 {
20073 printf (_("<None>"));
20074 return;
20075 }
90c745dc 20076
ee2fdd6f
L
20077 while (bitmask)
20078 {
20079 unsigned int bit = bitmask & (- bitmask);
20080
20081 bitmask &= ~ bit;
20082 switch (bit)
20083 {
20084 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 20085 printf ("IBT");
ee2fdd6f 20086 break;
48580982 20087 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 20088 printf ("SHSTK");
48580982 20089 break;
279d901e
L
20090 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
20091 printf ("LAM_U48");
20092 break;
20093 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
20094 printf ("LAM_U57");
20095 break;
ee2fdd6f
L
20096 default:
20097 printf (_("<unknown: %x>"), bit);
20098 break;
20099 }
20100 if (bitmask)
20101 printf (", ");
20102 }
20103}
20104
a9eafb08
L
20105static void
20106decode_x86_feature_2 (unsigned int bitmask)
20107{
0a59decb 20108 if (!bitmask)
90c745dc
L
20109 {
20110 printf (_("<None>"));
20111 return;
20112 }
90c745dc 20113
a9eafb08
L
20114 while (bitmask)
20115 {
20116 unsigned int bit = bitmask & (- bitmask);
20117
20118 bitmask &= ~ bit;
20119 switch (bit)
20120 {
20121 case GNU_PROPERTY_X86_FEATURE_2_X86:
20122 printf ("x86");
20123 break;
20124 case GNU_PROPERTY_X86_FEATURE_2_X87:
20125 printf ("x87");
20126 break;
20127 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20128 printf ("MMX");
20129 break;
20130 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20131 printf ("XMM");
20132 break;
20133 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20134 printf ("YMM");
20135 break;
20136 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20137 printf ("ZMM");
20138 break;
a308b89d
L
20139 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20140 printf ("TMM");
20141 break;
32930e4e
L
20142 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20143 printf ("MASK");
20144 break;
a9eafb08
L
20145 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20146 printf ("FXSR");
20147 break;
20148 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20149 printf ("XSAVE");
20150 break;
20151 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20152 printf ("XSAVEOPT");
20153 break;
20154 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20155 printf ("XSAVEC");
20156 break;
65b3d26e
L
20157 default:
20158 printf (_("<unknown: %x>"), bit);
20159 break;
a9eafb08
L
20160 }
20161 if (bitmask)
20162 printf (", ");
20163 }
20164}
20165
cd702818
SD
20166static void
20167decode_aarch64_feature_1_and (unsigned int bitmask)
20168{
20169 while (bitmask)
20170 {
20171 unsigned int bit = bitmask & (- bitmask);
20172
20173 bitmask &= ~ bit;
20174 switch (bit)
20175 {
20176 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20177 printf ("BTI");
20178 break;
20179
20180 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20181 printf ("PAC");
20182 break;
20183
20184 default:
20185 printf (_("<unknown: %x>"), bit);
20186 break;
20187 }
20188 if (bitmask)
20189 printf (", ");
20190 }
20191}
20192
6320fd00
L
20193static void
20194decode_1_needed (unsigned int bitmask)
20195{
20196 while (bitmask)
20197 {
20198 unsigned int bit = bitmask & (- bitmask);
20199
20200 bitmask &= ~ bit;
20201 switch (bit)
20202 {
20203 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20204 printf ("indirect external access");
20205 break;
20206 default:
20207 printf (_("<unknown: %x>"), bit);
20208 break;
20209 }
20210 if (bitmask)
20211 printf (", ");
20212 }
20213}
20214
9ef920e9 20215static void
dda8d76d 20216print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
20217{
20218 unsigned char * ptr = (unsigned char *) pnote->descdata;
20219 unsigned char * ptr_end = ptr + pnote->descsz;
20220 unsigned int size = is_32bit_elf ? 4 : 8;
20221
20222 printf (_(" Properties: "));
20223
1fc87489 20224 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
20225 {
20226 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
20227 return;
20228 }
20229
6ab2c4ed 20230 while (ptr < ptr_end)
9ef920e9 20231 {
1fc87489 20232 unsigned int j;
6ab2c4ed
MC
20233 unsigned int type;
20234 unsigned int datasz;
20235
20236 if ((size_t) (ptr_end - ptr) < 8)
20237 {
20238 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
20239 break;
20240 }
20241
20242 type = byte_get (ptr, 4);
20243 datasz = byte_get (ptr + 4, 4);
9ef920e9 20244
1fc87489 20245 ptr += 8;
9ef920e9 20246
6ab2c4ed 20247 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 20248 {
1fc87489
L
20249 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
20250 type, datasz);
9ef920e9 20251 break;
1fc87489 20252 }
9ef920e9 20253
1fc87489
L
20254 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20255 {
dda8d76d
NC
20256 if (filedata->file_header.e_machine == EM_X86_64
20257 || filedata->file_header.e_machine == EM_IAMCU
20258 || filedata->file_header.e_machine == EM_386)
1fc87489 20259 {
aa7bca9b
L
20260 unsigned int bitmask;
20261
20262 if (datasz == 4)
0a59decb 20263 bitmask = byte_get (ptr, 4);
aa7bca9b
L
20264 else
20265 bitmask = 0;
20266
1fc87489
L
20267 switch (type)
20268 {
20269 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 20270 if (datasz != 4)
aa7bca9b
L
20271 printf (_("x86 ISA used: <corrupt length: %#x> "),
20272 datasz);
1fc87489 20273 else
aa7bca9b
L
20274 {
20275 printf ("x86 ISA used: ");
20276 decode_x86_isa (bitmask);
20277 }
1fc87489 20278 goto next;
9ef920e9 20279
1fc87489 20280 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20281 if (datasz != 4)
aa7bca9b
L
20282 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20283 datasz);
1fc87489 20284 else
aa7bca9b
L
20285 {
20286 printf ("x86 ISA needed: ");
20287 decode_x86_isa (bitmask);
20288 }
1fc87489 20289 goto next;
9ef920e9 20290
ee2fdd6f 20291 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20292 if (datasz != 4)
aa7bca9b
L
20293 printf (_("x86 feature: <corrupt length: %#x> "),
20294 datasz);
ee2fdd6f 20295 else
aa7bca9b
L
20296 {
20297 printf ("x86 feature: ");
a9eafb08
L
20298 decode_x86_feature_1 (bitmask);
20299 }
20300 goto next;
20301
20302 case GNU_PROPERTY_X86_FEATURE_2_USED:
20303 if (datasz != 4)
20304 printf (_("x86 feature used: <corrupt length: %#x> "),
20305 datasz);
20306 else
20307 {
20308 printf ("x86 feature used: ");
20309 decode_x86_feature_2 (bitmask);
20310 }
20311 goto next;
20312
20313 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20314 if (datasz != 4)
20315 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20316 else
20317 {
20318 printf ("x86 feature needed: ");
20319 decode_x86_feature_2 (bitmask);
20320 }
20321 goto next;
20322
20323 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20324 if (datasz != 4)
20325 printf (_("x86 ISA used: <corrupt length: %#x> "),
20326 datasz);
20327 else
20328 {
20329 printf ("x86 ISA used: ");
20330 decode_x86_compat_isa (bitmask);
20331 }
20332 goto next;
20333
20334 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20335 if (datasz != 4)
20336 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20337 datasz);
20338 else
20339 {
20340 printf ("x86 ISA needed: ");
20341 decode_x86_compat_isa (bitmask);
aa7bca9b 20342 }
ee2fdd6f
L
20343 goto next;
20344
32930e4e
L
20345 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20346 if (datasz != 4)
20347 printf (_("x86 ISA used: <corrupt length: %#x> "),
20348 datasz);
20349 else
20350 {
20351 printf ("x86 ISA used: ");
20352 decode_x86_compat_2_isa (bitmask);
20353 }
20354 goto next;
20355
20356 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20357 if (datasz != 4)
20358 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20359 datasz);
20360 else
20361 {
20362 printf ("x86 ISA needed: ");
20363 decode_x86_compat_2_isa (bitmask);
20364 }
20365 goto next;
20366
1fc87489
L
20367 default:
20368 break;
20369 }
20370 }
cd702818
SD
20371 else if (filedata->file_header.e_machine == EM_AARCH64)
20372 {
20373 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20374 {
20375 printf ("AArch64 feature: ");
20376 if (datasz != 4)
20377 printf (_("<corrupt length: %#x> "), datasz);
20378 else
20379 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20380 goto next;
20381 }
20382 }
1fc87489
L
20383 }
20384 else
20385 {
20386 switch (type)
9ef920e9 20387 {
1fc87489
L
20388 case GNU_PROPERTY_STACK_SIZE:
20389 printf (_("stack size: "));
20390 if (datasz != size)
20391 printf (_("<corrupt length: %#x> "), datasz);
20392 else
26c527e6 20393 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
20394 goto next;
20395
20396 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20397 printf ("no copy on protected ");
20398 if (datasz)
20399 printf (_("<corrupt length: %#x> "), datasz);
20400 goto next;
20401
20402 default:
5a767724
L
20403 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20404 && type <= GNU_PROPERTY_UINT32_AND_HI)
20405 || (type >= GNU_PROPERTY_UINT32_OR_LO
20406 && type <= GNU_PROPERTY_UINT32_OR_HI))
20407 {
6320fd00
L
20408 switch (type)
20409 {
20410 case GNU_PROPERTY_1_NEEDED:
20411 if (datasz != 4)
20412 printf (_("1_needed: <corrupt length: %#x> "),
20413 datasz);
20414 else
20415 {
20416 unsigned int bitmask = byte_get (ptr, 4);
20417 printf ("1_needed: ");
20418 decode_1_needed (bitmask);
20419 }
20420 goto next;
20421
20422 default:
20423 break;
20424 }
5a767724
L
20425 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20426 printf (_("UINT32_AND (%#x): "), type);
20427 else
20428 printf (_("UINT32_OR (%#x): "), type);
20429 if (datasz != 4)
20430 printf (_("<corrupt length: %#x> "), datasz);
20431 else
20432 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20433 goto next;
20434 }
9ef920e9
NC
20435 break;
20436 }
9ef920e9
NC
20437 }
20438
1fc87489
L
20439 if (type < GNU_PROPERTY_LOPROC)
20440 printf (_("<unknown type %#x data: "), type);
20441 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20442 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20443 else
20444 printf (_("<application-specific type %#x data: "), type);
20445 for (j = 0; j < datasz; ++j)
20446 printf ("%02x ", ptr[j] & 0xff);
20447 printf (">");
20448
dc1e8a47 20449 next:
9ef920e9 20450 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20451 if (ptr == ptr_end)
20452 break;
1fc87489 20453
6ab2c4ed
MC
20454 if (do_wide)
20455 printf (", ");
20456 else
20457 printf ("\n\t");
9ef920e9
NC
20458 }
20459
20460 printf ("\n");
20461}
20462
015dc7e1 20463static bool
dda8d76d 20464print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20465{
1449284b 20466 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20467 switch (pnote->type)
20468 {
20469 case NT_GNU_BUILD_ID:
20470 {
26c527e6 20471 size_t i;
664f90a3
TT
20472
20473 printf (_(" Build ID: "));
20474 for (i = 0; i < pnote->descsz; ++i)
20475 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20476 printf ("\n");
664f90a3
TT
20477 }
20478 break;
20479
20480 case NT_GNU_ABI_TAG:
20481 {
26c527e6 20482 unsigned int os, major, minor, subminor;
664f90a3
TT
20483 const char *osname;
20484
3102e897
NC
20485 /* PR 17531: file: 030-599401-0.004. */
20486 if (pnote->descsz < 16)
20487 {
20488 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20489 break;
20490 }
20491
664f90a3
TT
20492 os = byte_get ((unsigned char *) pnote->descdata, 4);
20493 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20494 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20495 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20496
20497 switch (os)
20498 {
20499 case GNU_ABI_TAG_LINUX:
20500 osname = "Linux";
20501 break;
20502 case GNU_ABI_TAG_HURD:
20503 osname = "Hurd";
20504 break;
20505 case GNU_ABI_TAG_SOLARIS:
20506 osname = "Solaris";
20507 break;
20508 case GNU_ABI_TAG_FREEBSD:
20509 osname = "FreeBSD";
20510 break;
20511 case GNU_ABI_TAG_NETBSD:
20512 osname = "NetBSD";
20513 break;
14ae95f2
RM
20514 case GNU_ABI_TAG_SYLLABLE:
20515 osname = "Syllable";
20516 break;
20517 case GNU_ABI_TAG_NACL:
20518 osname = "NaCl";
20519 break;
664f90a3
TT
20520 default:
20521 osname = "Unknown";
20522 break;
20523 }
20524
26c527e6 20525 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
20526 major, minor, subminor);
20527 }
20528 break;
926c5385
CC
20529
20530 case NT_GNU_GOLD_VERSION:
20531 {
26c527e6 20532 size_t i;
926c5385
CC
20533
20534 printf (_(" Version: "));
20535 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20536 printf ("%c", pnote->descdata[i]);
20537 printf ("\n");
20538 }
20539 break;
1449284b
NC
20540
20541 case NT_GNU_HWCAP:
20542 {
26c527e6 20543 unsigned int num_entries, mask;
1449284b
NC
20544
20545 /* Hardware capabilities information. Word 0 is the number of entries.
20546 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20547 is a series of entries, where each entry is a single byte followed
20548 by a nul terminated string. The byte gives the bit number to test
20549 if enabled in the bitmask. */
20550 printf (_(" Hardware Capabilities: "));
20551 if (pnote->descsz < 8)
20552 {
32ec8896 20553 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20554 return false;
1449284b
NC
20555 }
20556 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20557 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 20558 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
20559 /* FIXME: Add code to display the entries... */
20560 }
20561 break;
20562
9ef920e9 20563 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20564 print_gnu_property_note (filedata, pnote);
9ef920e9 20565 break;
9abca702 20566
1449284b
NC
20567 default:
20568 /* Handle unrecognised types. An error message should have already been
20569 created by get_gnu_elf_note_type(), so all that we need to do is to
20570 display the data. */
20571 {
26c527e6 20572 size_t i;
1449284b
NC
20573
20574 printf (_(" Description data: "));
20575 for (i = 0; i < pnote->descsz; ++i)
20576 printf ("%02x ", pnote->descdata[i] & 0xff);
20577 printf ("\n");
20578 }
20579 break;
664f90a3
TT
20580 }
20581
015dc7e1 20582 return true;
664f90a3
TT
20583}
20584
685080f2
NC
20585static const char *
20586get_v850_elf_note_type (enum v850_notes n_type)
20587{
20588 static char buff[64];
20589
20590 switch (n_type)
20591 {
20592 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20593 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20594 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20595 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20596 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20597 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20598 default:
20599 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20600 return buff;
20601 }
20602}
20603
015dc7e1 20604static bool
685080f2
NC
20605print_v850_note (Elf_Internal_Note * pnote)
20606{
20607 unsigned int val;
20608
20609 if (pnote->descsz != 4)
015dc7e1 20610 return false;
32ec8896 20611
685080f2
NC
20612 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20613
20614 if (val == 0)
20615 {
20616 printf (_("not set\n"));
015dc7e1 20617 return true;
685080f2
NC
20618 }
20619
20620 switch (pnote->type)
20621 {
20622 case V850_NOTE_ALIGNMENT:
20623 switch (val)
20624 {
015dc7e1
AM
20625 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20626 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20627 }
20628 break;
14ae95f2 20629
685080f2
NC
20630 case V850_NOTE_DATA_SIZE:
20631 switch (val)
20632 {
015dc7e1
AM
20633 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20634 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20635 }
20636 break;
14ae95f2 20637
685080f2
NC
20638 case V850_NOTE_FPU_INFO:
20639 switch (val)
20640 {
015dc7e1
AM
20641 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20642 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20643 }
20644 break;
14ae95f2 20645
685080f2
NC
20646 case V850_NOTE_MMU_INFO:
20647 case V850_NOTE_CACHE_INFO:
20648 case V850_NOTE_SIMD_INFO:
20649 if (val == EF_RH850_SIMD)
20650 {
20651 printf (_("yes\n"));
015dc7e1 20652 return true;
685080f2
NC
20653 }
20654 break;
20655
20656 default:
20657 /* An 'unknown note type' message will already have been displayed. */
20658 break;
20659 }
20660
20661 printf (_("unknown value: %x\n"), val);
015dc7e1 20662 return false;
685080f2
NC
20663}
20664
015dc7e1 20665static bool
c6056a74
SF
20666process_netbsd_elf_note (Elf_Internal_Note * pnote)
20667{
20668 unsigned int version;
20669
20670 switch (pnote->type)
20671 {
20672 case NT_NETBSD_IDENT:
b966f55f
AM
20673 if (pnote->descsz < 1)
20674 break;
c6056a74
SF
20675 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20676 if ((version / 10000) % 100)
b966f55f 20677 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20678 version, version / 100000000, (version / 1000000) % 100,
20679 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20680 'A' + (version / 10000) % 26);
c6056a74
SF
20681 else
20682 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20683 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20684 (version / 100) % 100);
015dc7e1 20685 return true;
c6056a74
SF
20686
20687 case NT_NETBSD_MARCH:
9abca702 20688 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20689 pnote->descdata);
015dc7e1 20690 return true;
c6056a74 20691
9abca702 20692 case NT_NETBSD_PAX:
b966f55f
AM
20693 if (pnote->descsz < 1)
20694 break;
9abca702
CZ
20695 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20696 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20697 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20698 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20699 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20700 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20701 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20702 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20703 return true;
c6056a74 20704 }
b966f55f
AM
20705
20706 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20707 pnote->descsz, pnote->type);
015dc7e1 20708 return false;
c6056a74
SF
20709}
20710
f4ddf30f 20711static const char *
dda8d76d 20712get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20713{
f4ddf30f
JB
20714 switch (e_type)
20715 {
20716 case NT_FREEBSD_THRMISC:
20717 return _("NT_THRMISC (thrmisc structure)");
20718 case NT_FREEBSD_PROCSTAT_PROC:
20719 return _("NT_PROCSTAT_PROC (proc data)");
20720 case NT_FREEBSD_PROCSTAT_FILES:
20721 return _("NT_PROCSTAT_FILES (files data)");
20722 case NT_FREEBSD_PROCSTAT_VMMAP:
20723 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20724 case NT_FREEBSD_PROCSTAT_GROUPS:
20725 return _("NT_PROCSTAT_GROUPS (groups data)");
20726 case NT_FREEBSD_PROCSTAT_UMASK:
20727 return _("NT_PROCSTAT_UMASK (umask data)");
20728 case NT_FREEBSD_PROCSTAT_RLIMIT:
20729 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20730 case NT_FREEBSD_PROCSTAT_OSREL:
20731 return _("NT_PROCSTAT_OSREL (osreldate data)");
20732 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20733 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20734 case NT_FREEBSD_PROCSTAT_AUXV:
20735 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20736 case NT_FREEBSD_PTLWPINFO:
20737 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
20738 case NT_FREEBSD_X86_SEGBASES:
20739 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 20740 }
dda8d76d 20741 return get_note_type (filedata, e_type);
f4ddf30f
JB
20742}
20743
9437c45b 20744static const char *
dda8d76d 20745get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20746{
20747 static char buff[64];
20748
540e6170
CZ
20749 switch (e_type)
20750 {
20751 case NT_NETBSDCORE_PROCINFO:
20752 /* NetBSD core "procinfo" structure. */
20753 return _("NetBSD procinfo structure");
9437c45b 20754
540e6170
CZ
20755 case NT_NETBSDCORE_AUXV:
20756 return _("NetBSD ELF auxiliary vector data");
9437c45b 20757
06d949ec
KR
20758 case NT_NETBSDCORE_LWPSTATUS:
20759 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20760
540e6170 20761 default:
06d949ec 20762 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20763 defined for NetBSD core files. If the note type is less
20764 than the start of the machine-dependent note types, we don't
20765 understand it. */
20766
20767 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20768 {
20769 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20770 return buff;
20771 }
20772 break;
9437c45b
JT
20773 }
20774
dda8d76d 20775 switch (filedata->file_header.e_machine)
9437c45b
JT
20776 {
20777 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20778 and PT_GETFPREGS == mach+2. */
20779
20780 case EM_OLD_ALPHA:
20781 case EM_ALPHA:
20782 case EM_SPARC:
20783 case EM_SPARC32PLUS:
20784 case EM_SPARCV9:
20785 switch (e_type)
20786 {
2b692964 20787 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20788 return _("PT_GETREGS (reg structure)");
2b692964 20789 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20790 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20791 default:
20792 break;
20793 }
20794 break;
20795
c0d38b0e
CZ
20796 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20797 There's also old PT___GETREGS40 == mach + 1 for old reg
20798 structure which lacks GBR. */
20799 case EM_SH:
20800 switch (e_type)
20801 {
20802 case NT_NETBSDCORE_FIRSTMACH + 1:
20803 return _("PT___GETREGS40 (old reg structure)");
20804 case NT_NETBSDCORE_FIRSTMACH + 3:
20805 return _("PT_GETREGS (reg structure)");
20806 case NT_NETBSDCORE_FIRSTMACH + 5:
20807 return _("PT_GETFPREGS (fpreg structure)");
20808 default:
20809 break;
20810 }
20811 break;
20812
9437c45b
JT
20813 /* On all other arch's, PT_GETREGS == mach+1 and
20814 PT_GETFPREGS == mach+3. */
20815 default:
20816 switch (e_type)
20817 {
2b692964 20818 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20819 return _("PT_GETREGS (reg structure)");
2b692964 20820 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20821 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20822 default:
20823 break;
20824 }
20825 }
20826
9cf03b7e 20827 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20828 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20829 return buff;
20830}
20831
98ca73af
FC
20832static const char *
20833get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20834{
20835 switch (e_type)
20836 {
20837 case NT_OPENBSD_PROCINFO:
20838 return _("OpenBSD procinfo structure");
20839 case NT_OPENBSD_AUXV:
20840 return _("OpenBSD ELF auxiliary vector data");
20841 case NT_OPENBSD_REGS:
20842 return _("OpenBSD regular registers");
20843 case NT_OPENBSD_FPREGS:
20844 return _("OpenBSD floating point registers");
20845 case NT_OPENBSD_WCOOKIE:
20846 return _("OpenBSD window cookie");
20847 }
20848
20849 return get_note_type (filedata, e_type);
20850}
20851
e263a66b
CC
20852static const char *
20853get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
20854{
20855 switch (e_type)
20856 {
20857 case QNT_DEBUG_FULLPATH:
20858 return _("QNX debug fullpath");
20859 case QNT_DEBUG_RELOC:
20860 return _("QNX debug relocation");
20861 case QNT_STACK:
20862 return _("QNX stack");
20863 case QNT_GENERATOR:
20864 return _("QNX generator");
20865 case QNT_DEFAULT_LIB:
20866 return _("QNX default library");
20867 case QNT_CORE_SYSINFO:
20868 return _("QNX core sysinfo");
20869 case QNT_CORE_INFO:
20870 return _("QNX core info");
20871 case QNT_CORE_STATUS:
20872 return _("QNX core status");
20873 case QNT_CORE_GREG:
20874 return _("QNX general registers");
20875 case QNT_CORE_FPREG:
20876 return _("QNX floating point registers");
20877 case QNT_LINK_MAP:
20878 return _("QNX link map");
20879 }
20880
20881 return get_note_type (filedata, e_type);
20882}
20883
70616151
TT
20884static const char *
20885get_stapsdt_note_type (unsigned e_type)
20886{
20887 static char buff[64];
20888
20889 switch (e_type)
20890 {
20891 case NT_STAPSDT:
20892 return _("NT_STAPSDT (SystemTap probe descriptors)");
20893
20894 default:
20895 break;
20896 }
20897
20898 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20899 return buff;
20900}
20901
015dc7e1 20902static bool
c6a9fc58
TT
20903print_stapsdt_note (Elf_Internal_Note *pnote)
20904{
3ca60c57 20905 size_t len, maxlen;
26c527e6 20906 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20907 char *data = pnote->descdata;
20908 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 20909 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
20910 char *provider, *probe, *arg_fmt;
20911
3ca60c57
NC
20912 if (pnote->descsz < (addr_size * 3))
20913 goto stapdt_note_too_small;
20914
c6a9fc58
TT
20915 pc = byte_get ((unsigned char *) data, addr_size);
20916 data += addr_size;
3ca60c57 20917
c6a9fc58
TT
20918 base_addr = byte_get ((unsigned char *) data, addr_size);
20919 data += addr_size;
3ca60c57 20920
c6a9fc58
TT
20921 semaphore = byte_get ((unsigned char *) data, addr_size);
20922 data += addr_size;
20923
3ca60c57
NC
20924 if (data >= data_end)
20925 goto stapdt_note_too_small;
20926 maxlen = data_end - data;
20927 len = strnlen (data, maxlen);
20928 if (len < maxlen)
20929 {
20930 provider = data;
20931 data += len + 1;
20932 }
20933 else
20934 goto stapdt_note_too_small;
20935
20936 if (data >= data_end)
20937 goto stapdt_note_too_small;
20938 maxlen = data_end - data;
20939 len = strnlen (data, maxlen);
20940 if (len < maxlen)
20941 {
20942 probe = data;
20943 data += len + 1;
20944 }
20945 else
20946 goto stapdt_note_too_small;
9abca702 20947
3ca60c57
NC
20948 if (data >= data_end)
20949 goto stapdt_note_too_small;
20950 maxlen = data_end - data;
20951 len = strnlen (data, maxlen);
20952 if (len < maxlen)
20953 {
20954 arg_fmt = data;
20955 data += len + 1;
20956 }
20957 else
20958 goto stapdt_note_too_small;
c6a9fc58
TT
20959
20960 printf (_(" Provider: %s\n"), provider);
20961 printf (_(" Name: %s\n"), probe);
20962 printf (_(" Location: "));
20963 print_vma (pc, FULL_HEX);
20964 printf (_(", Base: "));
20965 print_vma (base_addr, FULL_HEX);
20966 printf (_(", Semaphore: "));
20967 print_vma (semaphore, FULL_HEX);
9cf03b7e 20968 printf ("\n");
c6a9fc58
TT
20969 printf (_(" Arguments: %s\n"), arg_fmt);
20970
20971 return data == data_end;
3ca60c57
NC
20972
20973 stapdt_note_too_small:
20974 printf (_(" <corrupt - note is too small>\n"));
20975 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20976 return false;
c6a9fc58
TT
20977}
20978
e5382207
LB
20979static bool
20980print_fdo_note (Elf_Internal_Note * pnote)
20981{
20982 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20983 {
20984 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20985 return true;
20986 }
20987 return false;
20988}
20989
00e98fc7
TG
20990static const char *
20991get_ia64_vms_note_type (unsigned e_type)
20992{
20993 static char buff[64];
20994
20995 switch (e_type)
20996 {
20997 case NT_VMS_MHD:
20998 return _("NT_VMS_MHD (module header)");
20999 case NT_VMS_LNM:
21000 return _("NT_VMS_LNM (language name)");
21001 case NT_VMS_SRC:
21002 return _("NT_VMS_SRC (source files)");
21003 case NT_VMS_TITLE:
9cf03b7e 21004 return "NT_VMS_TITLE";
00e98fc7
TG
21005 case NT_VMS_EIDC:
21006 return _("NT_VMS_EIDC (consistency check)");
21007 case NT_VMS_FPMODE:
21008 return _("NT_VMS_FPMODE (FP mode)");
21009 case NT_VMS_LINKTIME:
9cf03b7e 21010 return "NT_VMS_LINKTIME";
00e98fc7
TG
21011 case NT_VMS_IMGNAM:
21012 return _("NT_VMS_IMGNAM (image name)");
21013 case NT_VMS_IMGID:
21014 return _("NT_VMS_IMGID (image id)");
21015 case NT_VMS_LINKID:
21016 return _("NT_VMS_LINKID (link id)");
21017 case NT_VMS_IMGBID:
21018 return _("NT_VMS_IMGBID (build id)");
21019 case NT_VMS_GSTNAM:
21020 return _("NT_VMS_GSTNAM (sym table name)");
21021 case NT_VMS_ORIG_DYN:
9cf03b7e 21022 return "NT_VMS_ORIG_DYN";
00e98fc7 21023 case NT_VMS_PATCHTIME:
9cf03b7e 21024 return "NT_VMS_PATCHTIME";
00e98fc7
TG
21025 default:
21026 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21027 return buff;
21028 }
21029}
21030
015dc7e1 21031static bool
00e98fc7
TG
21032print_ia64_vms_note (Elf_Internal_Note * pnote)
21033{
26c527e6 21034 unsigned int maxlen = pnote->descsz;
8d18bf79 21035
26c527e6 21036 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
21037 goto desc_size_fail;
21038
00e98fc7
TG
21039 switch (pnote->type)
21040 {
21041 case NT_VMS_MHD:
8d18bf79
NC
21042 if (maxlen <= 36)
21043 goto desc_size_fail;
21044
26c527e6 21045 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
21046
21047 printf (_(" Creation date : %.17s\n"), pnote->descdata);
21048 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
21049 if (l + 34 < maxlen)
21050 {
21051 printf (_(" Module name : %s\n"), pnote->descdata + 34);
21052 if (l + 35 < maxlen)
21053 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
21054 else
21055 printf (_(" Module version : <missing>\n"));
21056 }
00e98fc7 21057 else
8d18bf79
NC
21058 {
21059 printf (_(" Module name : <missing>\n"));
21060 printf (_(" Module version : <missing>\n"));
21061 }
00e98fc7 21062 break;
8d18bf79 21063
00e98fc7 21064 case NT_VMS_LNM:
8d18bf79 21065 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21066 break;
8d18bf79 21067
00e98fc7 21068 case NT_VMS_FPMODE:
9cf03b7e 21069 printf (_(" Floating Point mode: "));
8d18bf79
NC
21070 if (maxlen < 8)
21071 goto desc_size_fail;
21072 /* FIXME: Generate an error if descsz > 8 ? */
21073
b8281767 21074 printf ("0x%016" PRIx64 "\n",
625d49fc 21075 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 21076 break;
8d18bf79 21077
00e98fc7
TG
21078 case NT_VMS_LINKTIME:
21079 printf (_(" Link time: "));
8d18bf79
NC
21080 if (maxlen < 8)
21081 goto desc_size_fail;
21082 /* FIXME: Generate an error if descsz > 8 ? */
21083
0e3c1eeb 21084 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21085 printf ("\n");
21086 break;
8d18bf79 21087
00e98fc7
TG
21088 case NT_VMS_PATCHTIME:
21089 printf (_(" Patch time: "));
8d18bf79
NC
21090 if (maxlen < 8)
21091 goto desc_size_fail;
21092 /* FIXME: Generate an error if descsz > 8 ? */
21093
0e3c1eeb 21094 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21095 printf ("\n");
21096 break;
8d18bf79 21097
00e98fc7 21098 case NT_VMS_ORIG_DYN:
8d18bf79
NC
21099 if (maxlen < 34)
21100 goto desc_size_fail;
21101
00e98fc7 21102 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
21103 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
21104 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 21105 printf (_(" Last modified : "));
0e3c1eeb 21106 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 21107 printf (_("\n Link flags : "));
b8281767 21108 printf ("0x%016" PRIx64 "\n",
625d49fc 21109 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 21110 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 21111 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 21112 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 21113 break;
8d18bf79 21114
00e98fc7 21115 case NT_VMS_IMGNAM:
8d18bf79 21116 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21117 break;
8d18bf79 21118
00e98fc7 21119 case NT_VMS_GSTNAM:
8d18bf79 21120 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21121 break;
8d18bf79 21122
00e98fc7 21123 case NT_VMS_IMGID:
8d18bf79 21124 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21125 break;
8d18bf79 21126
00e98fc7 21127 case NT_VMS_LINKID:
8d18bf79 21128 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21129 break;
8d18bf79 21130
00e98fc7 21131 default:
015dc7e1 21132 return false;
00e98fc7 21133 }
8d18bf79 21134
015dc7e1 21135 return true;
8d18bf79
NC
21136
21137 desc_size_fail:
21138 printf (_(" <corrupt - data size is too small>\n"));
21139 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 21140 return false;
00e98fc7
TG
21141}
21142
fd486f32
AM
21143struct build_attr_cache {
21144 Filedata *filedata;
21145 char *strtab;
26c527e6 21146 uint64_t strtablen;
fd486f32 21147 Elf_Internal_Sym *symtab;
26c527e6 21148 uint64_t nsyms;
fd486f32
AM
21149} ba_cache;
21150
6f156d7a
NC
21151/* Find the symbol associated with a build attribute that is attached
21152 to address OFFSET. If PNAME is non-NULL then store the name of
21153 the symbol (if found) in the provided pointer, Returns NULL if a
21154 symbol could not be found. */
c799a79d 21155
6f156d7a 21156static Elf_Internal_Sym *
015dc7e1 21157get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 21158 uint64_t offset,
015dc7e1
AM
21159 bool is_open_attr,
21160 const char **pname)
9ef920e9 21161{
fd486f32
AM
21162 Elf_Internal_Sym *saved_sym = NULL;
21163 Elf_Internal_Sym *sym;
9ef920e9 21164
dda8d76d 21165 if (filedata->section_headers != NULL
fd486f32 21166 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 21167 {
c799a79d 21168 Elf_Internal_Shdr * symsec;
9ef920e9 21169
fd486f32
AM
21170 free (ba_cache.strtab);
21171 ba_cache.strtab = NULL;
21172 free (ba_cache.symtab);
21173 ba_cache.symtab = NULL;
21174
c799a79d 21175 /* Load the symbol and string sections. */
dda8d76d
NC
21176 for (symsec = filedata->section_headers;
21177 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 21178 symsec ++)
9ef920e9 21179 {
28d13567
AM
21180 if (symsec->sh_type == SHT_SYMTAB
21181 && get_symtab (filedata, symsec,
21182 &ba_cache.symtab, &ba_cache.nsyms,
21183 &ba_cache.strtab, &ba_cache.strtablen))
21184 break;
9ef920e9 21185 }
fd486f32 21186 ba_cache.filedata = filedata;
9ef920e9
NC
21187 }
21188
fd486f32 21189 if (ba_cache.symtab == NULL)
6f156d7a 21190 return NULL;
9ef920e9 21191
c799a79d 21192 /* Find a symbol whose value matches offset. */
fd486f32 21193 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
21194 if (sym->st_value == offset)
21195 {
fd486f32 21196 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
21197 /* Huh ? This should not happen. */
21198 continue;
9ef920e9 21199
fd486f32 21200 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 21201 continue;
9ef920e9 21202
9b9b1092 21203 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 21204 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
21205 if (ba_cache.strtab[sym->st_name] == '$'
21206 && ba_cache.strtab[sym->st_name + 1] != 0
21207 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
21208 continue;
21209
c799a79d
NC
21210 if (is_open_attr)
21211 {
21212 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
21213 and FILE or OBJECT symbols over NOTYPE symbols. We skip
21214 FUNC symbols entirely. */
21215 switch (ELF_ST_TYPE (sym->st_info))
21216 {
c799a79d 21217 case STT_OBJECT:
6f156d7a 21218 case STT_FILE:
c799a79d 21219 saved_sym = sym;
6f156d7a
NC
21220 if (sym->st_size)
21221 {
21222 /* If the symbol has a size associated
21223 with it then we can stop searching. */
fd486f32 21224 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 21225 }
c799a79d 21226 continue;
9ef920e9 21227
c799a79d
NC
21228 case STT_FUNC:
21229 /* Ignore function symbols. */
21230 continue;
21231
21232 default:
21233 break;
21234 }
21235
21236 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 21237 {
c799a79d
NC
21238 case STB_GLOBAL:
21239 if (saved_sym == NULL
21240 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
21241 saved_sym = sym;
21242 break;
c871dade 21243
c799a79d
NC
21244 case STB_LOCAL:
21245 if (saved_sym == NULL)
21246 saved_sym = sym;
21247 break;
21248
21249 default:
9ef920e9
NC
21250 break;
21251 }
21252 }
c799a79d
NC
21253 else
21254 {
21255 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
21256 continue;
21257
21258 saved_sym = sym;
21259 break;
21260 }
21261 }
21262
6f156d7a 21263 if (saved_sym && pname)
fd486f32 21264 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
21265
21266 return saved_sym;
c799a79d
NC
21267}
21268
d20e98ab
NC
21269/* Returns true iff addr1 and addr2 are in the same section. */
21270
015dc7e1 21271static bool
26c527e6 21272same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
21273{
21274 Elf_Internal_Shdr * a1;
21275 Elf_Internal_Shdr * a2;
21276
21277 a1 = find_section_by_address (filedata, addr1);
21278 a2 = find_section_by_address (filedata, addr2);
9abca702 21279
d20e98ab
NC
21280 return a1 == a2 && a1 != NULL;
21281}
21282
015dc7e1 21283static bool
dda8d76d
NC
21284print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21285 Filedata * filedata)
c799a79d 21286{
26c527e6
AM
21287 static uint64_t global_offset = 0;
21288 static uint64_t global_end = 0;
21289 static uint64_t func_offset = 0;
21290 static uint64_t func_end = 0;
c871dade 21291
015dc7e1
AM
21292 Elf_Internal_Sym *sym;
21293 const char *name;
26c527e6
AM
21294 uint64_t start;
21295 uint64_t end;
015dc7e1 21296 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
21297
21298 switch (pnote->descsz)
c799a79d 21299 {
6f156d7a
NC
21300 case 0:
21301 /* A zero-length description means that the range of
21302 the previous note of the same type should be used. */
c799a79d 21303 if (is_open_attr)
c871dade 21304 {
6f156d7a 21305 if (global_end > global_offset)
26c527e6
AM
21306 printf (_(" Applies to region from %#" PRIx64
21307 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 21308 else
26c527e6
AM
21309 printf (_(" Applies to region from %#" PRIx64
21310 "\n"), global_offset);
c799a79d
NC
21311 }
21312 else
21313 {
6f156d7a 21314 if (func_end > func_offset)
26c527e6
AM
21315 printf (_(" Applies to region from %#" PRIx64
21316 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 21317 else
26c527e6
AM
21318 printf (_(" Applies to region from %#" PRIx64
21319 "\n"), func_offset);
c871dade 21320 }
015dc7e1 21321 return true;
9ef920e9 21322
6f156d7a
NC
21323 case 4:
21324 start = byte_get ((unsigned char *) pnote->descdata, 4);
21325 end = 0;
21326 break;
21327
21328 case 8:
c74147bb
NC
21329 start = byte_get ((unsigned char *) pnote->descdata, 4);
21330 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21331 break;
21332
21333 case 16:
21334 start = byte_get ((unsigned char *) pnote->descdata, 8);
21335 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21336 break;
9abca702 21337
6f156d7a 21338 default:
c799a79d
NC
21339 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21340 printf (_(" <invalid descsz>"));
015dc7e1 21341 return false;
c799a79d
NC
21342 }
21343
6f156d7a
NC
21344 name = NULL;
21345 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21346 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21347 in order to avoid them being confused with the start address of the
21348 first function in the file... */
21349 if (sym == NULL && is_open_attr)
21350 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21351 & name);
6f156d7a
NC
21352
21353 if (end == 0 && sym != NULL && sym->st_size > 0)
21354 end = start + sym->st_size;
c799a79d
NC
21355
21356 if (is_open_attr)
21357 {
d20e98ab
NC
21358 /* FIXME: Need to properly allow for section alignment.
21359 16 is just the alignment used on x86_64. */
21360 if (global_end > 0
21361 && start > BFD_ALIGN (global_end, 16)
21362 /* Build notes are not guaranteed to be organised in order of
21363 increasing address, but we should find the all of the notes
21364 for one section in the same place. */
21365 && same_section (filedata, start, global_end))
26c527e6
AM
21366 warn (_("Gap in build notes detected from %#" PRIx64
21367 " to %#" PRIx64 "\n"),
6f156d7a
NC
21368 global_end + 1, start - 1);
21369
26c527e6 21370 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21371 global_offset = start;
21372
21373 if (end)
21374 {
26c527e6 21375 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21376 global_end = end;
21377 }
c799a79d
NC
21378 }
21379 else
21380 {
26c527e6 21381 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21382 func_offset = start;
21383
21384 if (end)
21385 {
26c527e6 21386 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21387 func_end = end;
21388 }
c799a79d
NC
21389 }
21390
6f156d7a
NC
21391 if (sym && name)
21392 printf (_(" (%s)"), name);
21393
21394 printf ("\n");
015dc7e1 21395 return true;
9ef920e9
NC
21396}
21397
015dc7e1 21398static bool
9ef920e9
NC
21399print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21400{
1d15e434
NC
21401 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21402 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21403 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21404 char name_type;
21405 char name_attribute;
1d15e434 21406 const char * expected_types;
9ef920e9
NC
21407 const char * name = pnote->namedata;
21408 const char * text;
88305e1b 21409 signed int left;
9ef920e9
NC
21410
21411 if (name == NULL || pnote->namesz < 2)
21412 {
21413 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21414 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21415 return false;
9ef920e9
NC
21416 }
21417
6f156d7a
NC
21418 if (do_wide)
21419 left = 28;
21420 else
21421 left = 20;
88305e1b
NC
21422
21423 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21424 if (name[0] == 'G' && name[1] == 'A')
21425 {
6f156d7a
NC
21426 if (pnote->namesz < 4)
21427 {
21428 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21429 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21430 return false;
6f156d7a
NC
21431 }
21432
88305e1b
NC
21433 printf ("GA");
21434 name += 2;
21435 left -= 2;
21436 }
21437
9ef920e9
NC
21438 switch ((name_type = * name))
21439 {
21440 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21441 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21442 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21443 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21444 printf ("%c", * name);
88305e1b 21445 left --;
9ef920e9
NC
21446 break;
21447 default:
21448 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21449 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21450 return false;
9ef920e9
NC
21451 }
21452
9ef920e9
NC
21453 ++ name;
21454 text = NULL;
21455
21456 switch ((name_attribute = * name))
21457 {
21458 case GNU_BUILD_ATTRIBUTE_VERSION:
21459 text = _("<version>");
1d15e434 21460 expected_types = string_expected;
9ef920e9
NC
21461 ++ name;
21462 break;
21463 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21464 text = _("<stack prot>");
75d7d298 21465 expected_types = "!+*";
9ef920e9
NC
21466 ++ name;
21467 break;
21468 case GNU_BUILD_ATTRIBUTE_RELRO:
21469 text = _("<relro>");
1d15e434 21470 expected_types = bool_expected;
9ef920e9
NC
21471 ++ name;
21472 break;
21473 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21474 text = _("<stack size>");
1d15e434 21475 expected_types = number_expected;
9ef920e9
NC
21476 ++ name;
21477 break;
21478 case GNU_BUILD_ATTRIBUTE_TOOL:
21479 text = _("<tool>");
1d15e434 21480 expected_types = string_expected;
9ef920e9
NC
21481 ++ name;
21482 break;
21483 case GNU_BUILD_ATTRIBUTE_ABI:
21484 text = _("<ABI>");
21485 expected_types = "$*";
21486 ++ name;
21487 break;
21488 case GNU_BUILD_ATTRIBUTE_PIC:
21489 text = _("<PIC>");
1d15e434 21490 expected_types = number_expected;
9ef920e9
NC
21491 ++ name;
21492 break;
a8be5506
NC
21493 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21494 text = _("<short enum>");
1d15e434 21495 expected_types = bool_expected;
a8be5506
NC
21496 ++ name;
21497 break;
9ef920e9
NC
21498 default:
21499 if (ISPRINT (* name))
21500 {
21501 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21502
21503 if (len > left && ! do_wide)
21504 len = left;
75d7d298 21505 printf ("%.*s:", len, name);
9ef920e9 21506 left -= len;
0dd6ae21 21507 name += len;
9ef920e9
NC
21508 }
21509 else
21510 {
3e6b6445 21511 static char tmpbuf [128];
88305e1b 21512
3e6b6445
NC
21513 error (_("unrecognised byte in name field: %d\n"), * name);
21514 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21515 text = tmpbuf;
21516 name ++;
9ef920e9
NC
21517 }
21518 expected_types = "*$!+";
21519 break;
21520 }
21521
21522 if (text)
88305e1b 21523 left -= printf ("%s", text);
9ef920e9
NC
21524
21525 if (strchr (expected_types, name_type) == NULL)
75d7d298 21526 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 21527
26c527e6 21528 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 21529 {
26c527e6
AM
21530 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
21531 pnote->namesz,
21532 name - pnote->namedata);
015dc7e1 21533 return false;
9ef920e9
NC
21534 }
21535
21536 if (left < 1 && ! do_wide)
015dc7e1 21537 return true;
9ef920e9
NC
21538
21539 switch (name_type)
21540 {
21541 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21542 {
26c527e6
AM
21543 unsigned int bytes;
21544 uint64_t val = 0;
21545 unsigned int shift = 0;
21546 char *decoded = NULL;
ddef72cd 21547
b06b2c92
NC
21548 bytes = pnote->namesz - (name - pnote->namedata);
21549 if (bytes > 0)
21550 /* The -1 is because the name field is always 0 terminated, and we
21551 want to be able to ensure that the shift in the while loop below
21552 will not overflow. */
21553 -- bytes;
21554
ddef72cd
NC
21555 if (bytes > sizeof (val))
21556 {
3e6b6445
NC
21557 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21558 bytes);
21559 bytes = sizeof (val);
ddef72cd 21560 }
3e6b6445
NC
21561 /* We do not bother to warn if bytes == 0 as this can
21562 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21563
21564 while (bytes --)
21565 {
26c527e6 21566 uint64_t byte = *name++ & 0xff;
79a964dc
NC
21567
21568 val |= byte << shift;
9ef920e9
NC
21569 shift += 8;
21570 }
21571
75d7d298 21572 switch (name_attribute)
9ef920e9 21573 {
75d7d298 21574 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21575 switch (val)
21576 {
75d7d298
NC
21577 case 0: decoded = "static"; break;
21578 case 1: decoded = "pic"; break;
21579 case 2: decoded = "PIC"; break;
21580 case 3: decoded = "pie"; break;
21581 case 4: decoded = "PIE"; break;
21582 default: break;
9ef920e9 21583 }
75d7d298
NC
21584 break;
21585 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21586 switch (val)
9ef920e9 21587 {
75d7d298
NC
21588 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21589 case 0: decoded = "off"; break;
21590 case 1: decoded = "on"; break;
21591 case 2: decoded = "all"; break;
21592 case 3: decoded = "strong"; break;
21593 case 4: decoded = "explicit"; break;
21594 default: break;
9ef920e9 21595 }
75d7d298
NC
21596 break;
21597 default:
21598 break;
9ef920e9
NC
21599 }
21600
75d7d298 21601 if (decoded != NULL)
3e6b6445
NC
21602 {
21603 print_symbol (-left, decoded);
21604 left = 0;
21605 }
21606 else if (val == 0)
21607 {
21608 printf ("0x0");
21609 left -= 3;
21610 }
9ef920e9 21611 else
75d7d298
NC
21612 {
21613 if (do_wide)
26c527e6 21614 left -= printf ("0x%" PRIx64, val);
75d7d298 21615 else
26c527e6 21616 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 21617 }
9ef920e9
NC
21618 }
21619 break;
21620 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21621 left -= print_symbol (- left, name);
21622 break;
21623 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21624 left -= print_symbol (- left, "true");
21625 break;
21626 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21627 left -= print_symbol (- left, "false");
21628 break;
21629 }
21630
21631 if (do_wide && left > 0)
21632 printf ("%-*s", left, " ");
9abca702 21633
015dc7e1 21634 return true;
9ef920e9
NC
21635}
21636
2952f10c
SM
21637/* Print the contents of PNOTE as hex. */
21638
21639static void
21640print_note_contents_hex (Elf_Internal_Note *pnote)
21641{
21642 if (pnote->descsz)
21643 {
26c527e6 21644 size_t i;
2952f10c
SM
21645
21646 printf (_(" description data: "));
21647 for (i = 0; i < pnote->descsz; i++)
21648 printf ("%02x ", pnote->descdata[i] & 0xff);
21649 if (!do_wide)
21650 printf ("\n");
21651 }
21652
21653 if (do_wide)
21654 printf ("\n");
21655}
21656
21657#if defined HAVE_MSGPACK
21658
21659static void
21660print_indents (int n)
21661{
21662 printf (" ");
21663
21664 for (int i = 0; i < n; i++)
21665 printf (" ");
21666}
21667
21668/* Print OBJ in human-readable form. */
21669
21670static void
21671dump_msgpack_obj (const msgpack_object *obj, int indent)
21672{
21673 switch (obj->type)
21674 {
21675 case MSGPACK_OBJECT_NIL:
21676 printf ("(nil)");
21677 break;
21678
21679 case MSGPACK_OBJECT_BOOLEAN:
21680 printf ("%s", obj->via.boolean ? "true" : "false");
21681 break;
21682
21683 case MSGPACK_OBJECT_POSITIVE_INTEGER:
21684 printf ("%" PRIu64, obj->via.u64);
21685 break;
21686
21687 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
21688 printf ("%" PRIi64, obj->via.i64);
21689 break;
21690
21691 case MSGPACK_OBJECT_FLOAT32:
21692 case MSGPACK_OBJECT_FLOAT64:
21693 printf ("%f", obj->via.f64);
21694 break;
21695
21696 case MSGPACK_OBJECT_STR:
21697 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
21698 break;
21699
21700 case MSGPACK_OBJECT_ARRAY:
21701 {
21702 const msgpack_object_array *array = &obj->via.array;
21703
21704 printf ("[\n");
21705 ++indent;
21706
21707 for (uint32_t i = 0; i < array->size; ++i)
21708 {
21709 const msgpack_object *item = &array->ptr[i];
21710
21711 print_indents (indent);
21712 dump_msgpack_obj (item, indent);
21713 printf (",\n");
21714 }
21715
21716 --indent;
21717 print_indents (indent);
21718 printf ("]");
21719 break;
21720 }
21721 break;
21722
21723 case MSGPACK_OBJECT_MAP:
21724 {
21725 const msgpack_object_map *map = &obj->via.map;
21726
21727 printf ("{\n");
21728 ++indent;
21729
21730 for (uint32_t i = 0; i < map->size; ++i)
21731 {
21732 const msgpack_object_kv *kv = &map->ptr[i];
21733 const msgpack_object *key = &kv->key;
21734 const msgpack_object *val = &kv->val;
21735
21736 print_indents (indent);
21737 dump_msgpack_obj (key, indent);
21738 printf (": ");
21739 dump_msgpack_obj (val, indent);
21740
21741 printf (",\n");
21742 }
21743
21744 --indent;
21745 print_indents (indent);
21746 printf ("}");
21747
21748 break;
21749 }
21750
21751 case MSGPACK_OBJECT_BIN:
21752 printf ("(bin)");
21753 break;
21754
21755 case MSGPACK_OBJECT_EXT:
21756 printf ("(ext)");
21757 break;
21758 }
21759}
21760
21761static void
21762dump_msgpack (const msgpack_unpacked *msg)
21763{
21764 print_indents (0);
21765 dump_msgpack_obj (&msg->data, 0);
21766 printf ("\n");
21767}
21768
21769#endif /* defined HAVE_MSGPACK */
21770
21771static bool
21772print_amdgpu_note (Elf_Internal_Note *pnote)
21773{
21774#if defined HAVE_MSGPACK
21775 /* If msgpack is available, decode and dump the note's content. */
21776 bool ret;
21777 msgpack_unpacked msg;
21778 msgpack_unpack_return msgpack_ret;
21779
21780 assert (pnote->type == NT_AMDGPU_METADATA);
21781
21782 msgpack_unpacked_init (&msg);
21783 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
21784 NULL);
21785
21786 switch (msgpack_ret)
21787 {
21788 case MSGPACK_UNPACK_SUCCESS:
21789 dump_msgpack (&msg);
21790 ret = true;
21791 break;
21792
21793 default:
21794 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
21795 ret = false;
21796 break;
21797 }
21798
21799 msgpack_unpacked_destroy (&msg);
21800 return ret;
21801#else
21802 /* msgpack is not available, dump contents as hex. */
21803 print_note_contents_hex (pnote);
21804 return true;
21805#endif
21806}
21807
e263a66b
CC
21808static bool
21809print_qnx_note (Elf_Internal_Note *pnote)
21810{
21811 switch (pnote->type)
21812 {
21813 case QNT_STACK:
21814 if (pnote->descsz != 12)
21815 goto desc_size_fail;
21816
21817 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
21818 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
21819 printf (_(" Stack allocated: %" PRIx32 "\n"),
21820 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
21821 printf (_(" Executable: %s\n"),
21822 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
21823 break;
21824
21825 default:
21826 print_note_contents_hex(pnote);
21827 }
21828 return true;
21829
21830desc_size_fail:
21831 printf (_(" <corrupt - data size is too small>\n"));
21832 error (_("corrupt QNX note: data size is too small\n"));
21833 return false;
21834}
21835
21836
6d118b09
NC
21837/* Note that by the ELF standard, the name field is already null byte
21838 terminated, and namesz includes the terminating null byte.
21839 I.E. the value of namesz for the name "FSF" is 4.
21840
e3c8793a 21841 If the value of namesz is zero, there is no name present. */
9ef920e9 21842
015dc7e1 21843static bool
9ef920e9 21844process_note (Elf_Internal_Note * pnote,
dda8d76d 21845 Filedata * filedata)
779fe533 21846{
2cf0635d
NC
21847 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21848 const char * nt;
9437c45b
JT
21849
21850 if (pnote->namesz == 0)
1ec5cd37
NC
21851 /* If there is no note name, then use the default set of
21852 note type strings. */
dda8d76d 21853 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21854
24d127aa 21855 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21856 /* GNU-specific object file notes. */
21857 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21858
28cdbb18
SM
21859 else if (startswith (pnote->namedata, "AMDGPU"))
21860 /* AMDGPU-specific object file notes. */
21861 nt = get_amdgpu_elf_note_type (pnote->type);
21862
24d127aa 21863 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21864 /* FreeBSD-specific core file notes. */
dda8d76d 21865 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21866
24d127aa 21867 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21868 /* NetBSD-specific core file notes. */
dda8d76d 21869 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21870
24d127aa 21871 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21872 /* NetBSD-specific core file notes. */
21873 return process_netbsd_elf_note (pnote);
21874
24d127aa 21875 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21876 /* NetBSD-specific core file notes. */
21877 return process_netbsd_elf_note (pnote);
21878
98ca73af
FC
21879 else if (startswith (pnote->namedata, "OpenBSD"))
21880 /* OpenBSD-specific core file notes. */
21881 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21882
e263a66b
CC
21883 else if (startswith (pnote->namedata, "QNX"))
21884 /* QNX-specific core file notes. */
21885 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
21886
e9b095a5 21887 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21888 {
21889 /* SPU-specific core file notes. */
21890 nt = pnote->namedata + 4;
21891 name = "SPU";
21892 }
21893
24d127aa 21894 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21895 /* VMS/ia64-specific file notes. */
21896 nt = get_ia64_vms_note_type (pnote->type);
21897
24d127aa 21898 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21899 nt = get_stapsdt_note_type (pnote->type);
21900
9437c45b 21901 else
1ec5cd37
NC
21902 /* Don't recognize this note name; just use the default set of
21903 note type strings. */
dda8d76d 21904 nt = get_note_type (filedata, pnote->type);
9437c45b 21905
1449284b 21906 printf (" ");
9ef920e9 21907
24d127aa 21908 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21909 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21910 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21911 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21912 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21913 print_gnu_build_attribute_name (pnote);
21914 else
21915 print_symbol (-20, name);
21916
21917 if (do_wide)
21918 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21919 else
21920 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21921
24d127aa 21922 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21923 return print_ia64_vms_note (pnote);
24d127aa 21924 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21925 return print_gnu_note (filedata, pnote);
24d127aa 21926 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21927 return print_stapsdt_note (pnote);
24d127aa 21928 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21929 return print_core_note (pnote);
e5382207
LB
21930 else if (startswith (pnote->namedata, "FDO"))
21931 return print_fdo_note (pnote);
24d127aa 21932 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21933 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21934 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21935 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21936 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21937 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
21938 else if (startswith (pnote->namedata, "AMDGPU")
21939 && pnote->type == NT_AMDGPU_METADATA)
21940 return print_amdgpu_note (pnote);
e263a66b
CC
21941 else if (startswith (pnote->namedata, "QNX"))
21942 return print_qnx_note (pnote);
779fe533 21943
2952f10c 21944 print_note_contents_hex (pnote);
015dc7e1 21945 return true;
1449284b 21946}
6d118b09 21947
015dc7e1 21948static bool
dda8d76d
NC
21949process_notes_at (Filedata * filedata,
21950 Elf_Internal_Shdr * section,
625d49fc
AM
21951 uint64_t offset,
21952 uint64_t length,
21953 uint64_t align)
779fe533 21954{
015dc7e1
AM
21955 Elf_External_Note *pnotes;
21956 Elf_External_Note *external;
21957 char *end;
21958 bool res = true;
103f02d3 21959
779fe533 21960 if (length <= 0)
015dc7e1 21961 return false;
103f02d3 21962
1449284b
NC
21963 if (section)
21964 {
dda8d76d 21965 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21966 if (pnotes)
32ec8896 21967 {
dda8d76d 21968 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21969 {
21970 free (pnotes);
015dc7e1 21971 return false;
f761cb13 21972 }
32ec8896 21973 }
1449284b
NC
21974 }
21975 else
82ed9683 21976 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21977 _("notes"));
4dff97b2 21978
dd24e3da 21979 if (pnotes == NULL)
015dc7e1 21980 return false;
779fe533 21981
103f02d3 21982 external = pnotes;
103f02d3 21983
ca0e11aa
NC
21984 if (filedata->is_separate)
21985 printf (_("In linked file '%s': "), filedata->file_name);
21986 else
21987 printf ("\n");
1449284b 21988 if (section)
ca0e11aa 21989 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21990 else
26c527e6
AM
21991 printf (_("Displaying notes found at file offset 0x%08" PRIx64
21992 " with length 0x%08" PRIx64 ":\n"),
21993 offset, length);
1449284b 21994
82ed9683
L
21995 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21996 specifies that notes should be aligned to 4 bytes in 32-bit
21997 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21998 we also support 4 byte alignment in 64-bit objects. If section
21999 alignment is less than 4, we treate alignment as 4 bytes. */
22000 if (align < 4)
22001 align = 4;
22002 else if (align != 4 && align != 8)
22003 {
26c527e6
AM
22004 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
22005 align);
a788aedd 22006 free (pnotes);
015dc7e1 22007 return false;
82ed9683
L
22008 }
22009
dbe15e4e 22010 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 22011
c8071705
NC
22012 end = (char *) pnotes + length;
22013 while ((char *) external < end)
779fe533 22014 {
b34976b6 22015 Elf_Internal_Note inote;
15b42fb0 22016 size_t min_notesz;
4dff97b2 22017 char * next;
2cf0635d 22018 char * temp = NULL;
c8071705 22019 size_t data_remaining = end - (char *) external;
6d118b09 22020
dda8d76d 22021 if (!is_ia64_vms (filedata))
15b42fb0 22022 {
9dd3a467
NC
22023 /* PR binutils/15191
22024 Make sure that there is enough data to read. */
15b42fb0
AM
22025 min_notesz = offsetof (Elf_External_Note, name);
22026 if (data_remaining < min_notesz)
9dd3a467 22027 {
26c527e6 22028 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22029 "not enough for a full note\n",
26c527e6 22030 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22031 "not enough for a full note\n",
22032 data_remaining),
26c527e6 22033 data_remaining);
9dd3a467
NC
22034 break;
22035 }
5396a86e
AM
22036 data_remaining -= min_notesz;
22037
15b42fb0
AM
22038 inote.type = BYTE_GET (external->type);
22039 inote.namesz = BYTE_GET (external->namesz);
22040 inote.namedata = external->name;
22041 inote.descsz = BYTE_GET (external->descsz);
276da9b3 22042 inote.descdata = ((char *) external
4dff97b2 22043 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 22044 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 22045 next = ((char *) external
4dff97b2 22046 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 22047 }
00e98fc7 22048 else
15b42fb0
AM
22049 {
22050 Elf64_External_VMS_Note *vms_external;
00e98fc7 22051
9dd3a467
NC
22052 /* PR binutils/15191
22053 Make sure that there is enough data to read. */
15b42fb0
AM
22054 min_notesz = offsetof (Elf64_External_VMS_Note, name);
22055 if (data_remaining < min_notesz)
9dd3a467 22056 {
26c527e6 22057 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22058 "not enough for a full note\n",
26c527e6 22059 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22060 "not enough for a full note\n",
22061 data_remaining),
26c527e6 22062 data_remaining);
9dd3a467
NC
22063 break;
22064 }
5396a86e 22065 data_remaining -= min_notesz;
3e55a963 22066
15b42fb0
AM
22067 vms_external = (Elf64_External_VMS_Note *) external;
22068 inote.type = BYTE_GET (vms_external->type);
22069 inote.namesz = BYTE_GET (vms_external->namesz);
22070 inote.namedata = vms_external->name;
22071 inote.descsz = BYTE_GET (vms_external->descsz);
22072 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
22073 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22074 next = inote.descdata + align_power (inote.descsz, 3);
22075 }
22076
5396a86e
AM
22077 /* PR 17531: file: 3443835e. */
22078 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
22079 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
22080 || (size_t) (inote.descdata - inote.namedata) > data_remaining
22081 || (size_t) (next - inote.descdata) < inote.descsz
22082 || ((size_t) (next - inote.descdata)
22083 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 22084 {
26c527e6
AM
22085 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
22086 (char *) external - (char *) pnotes);
22087 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 22088 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
22089 break;
22090 }
22091
15b42fb0 22092 external = (Elf_External_Note *) next;
dd24e3da 22093
6d118b09
NC
22094 /* Verify that name is null terminated. It appears that at least
22095 one version of Linux (RedHat 6.0) generates corefiles that don't
22096 comply with the ELF spec by failing to include the null byte in
22097 namesz. */
18344509 22098 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 22099 {
5396a86e 22100 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 22101 {
5396a86e
AM
22102 temp = (char *) malloc (inote.namesz + 1);
22103 if (temp == NULL)
22104 {
22105 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 22106 res = false;
5396a86e
AM
22107 break;
22108 }
76da6bbe 22109
5396a86e
AM
22110 memcpy (temp, inote.namedata, inote.namesz);
22111 inote.namedata = temp;
22112 }
22113 inote.namedata[inote.namesz] = 0;
6d118b09
NC
22114 }
22115
dda8d76d 22116 if (! process_note (& inote, filedata))
015dc7e1 22117 res = false;
103f02d3 22118
9db70fc3
AM
22119 free (temp);
22120 temp = NULL;
779fe533
NC
22121 }
22122
22123 free (pnotes);
103f02d3 22124
779fe533
NC
22125 return res;
22126}
22127
015dc7e1 22128static bool
dda8d76d 22129process_corefile_note_segments (Filedata * filedata)
779fe533 22130{
015dc7e1 22131 Elf_Internal_Phdr *segment;
b34976b6 22132 unsigned int i;
015dc7e1 22133 bool res = true;
103f02d3 22134
dda8d76d 22135 if (! get_program_headers (filedata))
015dc7e1 22136 return true;
103f02d3 22137
dda8d76d
NC
22138 for (i = 0, segment = filedata->program_headers;
22139 i < filedata->file_header.e_phnum;
b34976b6 22140 i++, segment++)
779fe533
NC
22141 {
22142 if (segment->p_type == PT_NOTE)
625d49fc
AM
22143 if (! process_notes_at (filedata, NULL, segment->p_offset,
22144 segment->p_filesz, segment->p_align))
015dc7e1 22145 res = false;
779fe533 22146 }
103f02d3 22147
779fe533
NC
22148 return res;
22149}
22150
015dc7e1 22151static bool
625d49fc 22152process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
22153{
22154 Elf_External_Note * pnotes;
22155 Elf_External_Note * external;
c8071705 22156 char * end;
015dc7e1 22157 bool res = true;
685080f2
NC
22158
22159 if (length <= 0)
015dc7e1 22160 return false;
685080f2 22161
dda8d76d 22162 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
22163 _("v850 notes"));
22164 if (pnotes == NULL)
015dc7e1 22165 return false;
685080f2
NC
22166
22167 external = pnotes;
c8071705 22168 end = (char*) pnotes + length;
685080f2 22169
26c527e6
AM
22170 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22171 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22172 offset, length);
685080f2 22173
c8071705 22174 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
22175 {
22176 Elf_External_Note * next;
22177 Elf_Internal_Note inote;
22178
22179 inote.type = BYTE_GET (external->type);
22180 inote.namesz = BYTE_GET (external->namesz);
22181 inote.namedata = external->name;
22182 inote.descsz = BYTE_GET (external->descsz);
22183 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22184 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22185
c8071705
NC
22186 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22187 {
22188 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22189 inote.descdata = inote.namedata;
22190 inote.namesz = 0;
22191 }
22192
685080f2
NC
22193 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22194
c8071705 22195 if ( ((char *) next > end)
685080f2
NC
22196 || ((char *) next < (char *) pnotes))
22197 {
26c527e6
AM
22198 warn (_("corrupt descsz found in note at offset %#tx\n"),
22199 (char *) external - (char *) pnotes);
22200 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22201 inote.type, inote.namesz, inote.descsz);
22202 break;
22203 }
22204
22205 external = next;
22206
22207 /* Prevent out-of-bounds indexing. */
c8071705 22208 if ( inote.namedata + inote.namesz > end
685080f2
NC
22209 || inote.namedata + inote.namesz < inote.namedata)
22210 {
26c527e6
AM
22211 warn (_("corrupt namesz found in note at offset %#zx\n"),
22212 (char *) external - (char *) pnotes);
22213 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22214 inote.type, inote.namesz, inote.descsz);
22215 break;
22216 }
22217
22218 printf (" %s: ", get_v850_elf_note_type (inote.type));
22219
22220 if (! print_v850_note (& inote))
22221 {
015dc7e1 22222 res = false;
26c527e6 22223 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
22224 inote.namesz, inote.descsz);
22225 }
22226 }
22227
22228 free (pnotes);
22229
22230 return res;
22231}
22232
015dc7e1 22233static bool
dda8d76d 22234process_note_sections (Filedata * filedata)
1ec5cd37 22235{
015dc7e1 22236 Elf_Internal_Shdr *section;
26c527e6 22237 size_t i;
32ec8896 22238 unsigned int n = 0;
015dc7e1 22239 bool res = true;
1ec5cd37 22240
dda8d76d
NC
22241 for (i = 0, section = filedata->section_headers;
22242 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 22243 i++, section++)
685080f2
NC
22244 {
22245 if (section->sh_type == SHT_NOTE)
22246 {
625d49fc
AM
22247 if (! process_notes_at (filedata, section, section->sh_offset,
22248 section->sh_size, section->sh_addralign))
015dc7e1 22249 res = false;
685080f2
NC
22250 n++;
22251 }
22252
dda8d76d
NC
22253 if (( filedata->file_header.e_machine == EM_V800
22254 || filedata->file_header.e_machine == EM_V850
22255 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
22256 && section->sh_type == SHT_RENESAS_INFO)
22257 {
625d49fc
AM
22258 if (! process_v850_notes (filedata, section->sh_offset,
22259 section->sh_size))
015dc7e1 22260 res = false;
685080f2
NC
22261 n++;
22262 }
22263 }
df565f32
NC
22264
22265 if (n == 0)
22266 /* Try processing NOTE segments instead. */
dda8d76d 22267 return process_corefile_note_segments (filedata);
1ec5cd37
NC
22268
22269 return res;
22270}
22271
015dc7e1 22272static bool
dda8d76d 22273process_notes (Filedata * filedata)
779fe533
NC
22274{
22275 /* If we have not been asked to display the notes then do nothing. */
22276 if (! do_notes)
015dc7e1 22277 return true;
103f02d3 22278
dda8d76d
NC
22279 if (filedata->file_header.e_type != ET_CORE)
22280 return process_note_sections (filedata);
103f02d3 22281
779fe533 22282 /* No program headers means no NOTE segment. */
dda8d76d
NC
22283 if (filedata->file_header.e_phnum > 0)
22284 return process_corefile_note_segments (filedata);
779fe533 22285
ca0e11aa
NC
22286 if (filedata->is_separate)
22287 printf (_("No notes found in linked file '%s'.\n"),
22288 filedata->file_name);
22289 else
22290 printf (_("No notes found file.\n"));
22291
015dc7e1 22292 return true;
779fe533
NC
22293}
22294
60abdbed
NC
22295static unsigned char *
22296display_public_gnu_attributes (unsigned char * start,
22297 const unsigned char * const end)
22298{
22299 printf (_(" Unknown GNU attribute: %s\n"), start);
22300
22301 start += strnlen ((char *) start, end - start);
22302 display_raw_attribute (start, end);
22303
22304 return (unsigned char *) end;
22305}
22306
22307static unsigned char *
22308display_generic_attribute (unsigned char * start,
22309 unsigned int tag,
22310 const unsigned char * const end)
22311{
22312 if (tag == 0)
22313 return (unsigned char *) end;
22314
22315 return display_tag_value (tag, start, end);
22316}
22317
015dc7e1 22318static bool
dda8d76d 22319process_arch_specific (Filedata * filedata)
252b5132 22320{
a952a375 22321 if (! do_arch)
015dc7e1 22322 return true;
a952a375 22323
dda8d76d 22324 switch (filedata->file_header.e_machine)
252b5132 22325 {
53a346d8
CZ
22326 case EM_ARC:
22327 case EM_ARC_COMPACT:
22328 case EM_ARC_COMPACT2:
13aa307c
CZ
22329 case EM_ARC_COMPACT3:
22330 case EM_ARC_COMPACT3_64:
dda8d76d 22331 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
22332 display_arc_attribute,
22333 display_generic_attribute);
11c1ff18 22334 case EM_ARM:
dda8d76d 22335 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
22336 display_arm_attribute,
22337 display_generic_attribute);
22338
252b5132 22339 case EM_MIPS:
4fe85591 22340 case EM_MIPS_RS3_LE:
dda8d76d 22341 return process_mips_specific (filedata);
60abdbed
NC
22342
22343 case EM_MSP430:
dda8d76d 22344 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 22345 display_msp430_attribute,
c0ea7c52 22346 display_msp430_gnu_attribute);
60abdbed 22347
2dc8dd17
JW
22348 case EM_RISCV:
22349 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22350 display_riscv_attribute,
22351 display_generic_attribute);
22352
35c08157 22353 case EM_NDS32:
dda8d76d 22354 return process_nds32_specific (filedata);
60abdbed 22355
85f7484a
PB
22356 case EM_68K:
22357 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22358 display_m68k_gnu_attribute);
22359
34c8bcba 22360 case EM_PPC:
b82317dd 22361 case EM_PPC64:
dda8d76d 22362 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22363 display_power_gnu_attribute);
22364
643f7afb
AK
22365 case EM_S390:
22366 case EM_S390_OLD:
dda8d76d 22367 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22368 display_s390_gnu_attribute);
22369
9e8c70f9
DM
22370 case EM_SPARC:
22371 case EM_SPARC32PLUS:
22372 case EM_SPARCV9:
dda8d76d 22373 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22374 display_sparc_gnu_attribute);
22375
59e6276b 22376 case EM_TI_C6000:
dda8d76d 22377 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22378 display_tic6x_attribute,
22379 display_generic_attribute);
22380
0861f561
CQ
22381 case EM_CSKY:
22382 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22383 display_csky_attribute, NULL);
22384
252b5132 22385 default:
dda8d76d 22386 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22387 display_public_gnu_attributes,
22388 display_generic_attribute);
252b5132 22389 }
252b5132
RH
22390}
22391
015dc7e1 22392static bool
dda8d76d 22393get_file_header (Filedata * filedata)
252b5132 22394{
9ea033b2 22395 /* Read in the identity array. */
dda8d76d 22396 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22397 return false;
252b5132 22398
9ea033b2 22399 /* Determine how to read the rest of the header. */
dda8d76d 22400 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22401 {
1a0670f3
AM
22402 default:
22403 case ELFDATANONE:
adab8cdc
AO
22404 case ELFDATA2LSB:
22405 byte_get = byte_get_little_endian;
22406 byte_put = byte_put_little_endian;
22407 break;
22408 case ELFDATA2MSB:
22409 byte_get = byte_get_big_endian;
22410 byte_put = byte_put_big_endian;
22411 break;
9ea033b2
NC
22412 }
22413
22414 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22415 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22416
22417 /* Read in the rest of the header. */
22418 if (is_32bit_elf)
22419 {
22420 Elf32_External_Ehdr ehdr32;
252b5132 22421
dda8d76d 22422 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22423 return false;
103f02d3 22424
dda8d76d
NC
22425 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22426 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22427 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22428 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22429 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22430 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22431 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22432 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22433 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22434 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22435 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22436 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22437 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22438 }
252b5132 22439 else
9ea033b2
NC
22440 {
22441 Elf64_External_Ehdr ehdr64;
a952a375 22442
dda8d76d 22443 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22444 return false;
103f02d3 22445
dda8d76d
NC
22446 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22447 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22448 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22449 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22450 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22451 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22452 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22453 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22454 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22455 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22456 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22457 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22458 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22459 }
252b5132 22460
015dc7e1 22461 return true;
252b5132
RH
22462}
22463
13acb58d
AM
22464static void
22465free_filedata (Filedata *filedata)
22466{
22467 free (filedata->program_interpreter);
13acb58d 22468 free (filedata->program_headers);
13acb58d 22469 free (filedata->section_headers);
13acb58d 22470 free (filedata->string_table);
13acb58d 22471 free (filedata->dump.dump_sects);
13acb58d 22472 free (filedata->dynamic_strings);
13acb58d 22473 free (filedata->dynamic_symbols);
13acb58d 22474 free (filedata->dynamic_syminfo);
13acb58d 22475 free (filedata->dynamic_section);
13acb58d
AM
22476
22477 while (filedata->symtab_shndx_list != NULL)
22478 {
22479 elf_section_list *next = filedata->symtab_shndx_list->next;
22480 free (filedata->symtab_shndx_list);
22481 filedata->symtab_shndx_list = next;
22482 }
22483
22484 free (filedata->section_headers_groups);
13acb58d
AM
22485
22486 if (filedata->section_groups)
22487 {
22488 size_t i;
22489 struct group_list * g;
22490 struct group_list * next;
22491
22492 for (i = 0; i < filedata->group_count; i++)
22493 {
22494 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22495 {
22496 next = g->next;
22497 free (g);
22498 }
22499 }
22500
22501 free (filedata->section_groups);
13acb58d 22502 }
066f8fbe
AM
22503 memset (&filedata->section_headers, 0,
22504 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22505}
22506
dda8d76d
NC
22507static void
22508close_file (Filedata * filedata)
22509{
22510 if (filedata)
22511 {
22512 if (filedata->handle)
22513 fclose (filedata->handle);
22514 free (filedata);
22515 }
22516}
22517
22518void
22519close_debug_file (void * data)
22520{
13acb58d 22521 free_filedata ((Filedata *) data);
dda8d76d
NC
22522 close_file ((Filedata *) data);
22523}
22524
22525static Filedata *
015dc7e1 22526open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22527{
22528 struct stat statbuf;
22529 Filedata * filedata = NULL;
22530
22531 if (stat (pathname, & statbuf) < 0
22532 || ! S_ISREG (statbuf.st_mode))
22533 goto fail;
22534
22535 filedata = calloc (1, sizeof * filedata);
22536 if (filedata == NULL)
22537 goto fail;
22538
22539 filedata->handle = fopen (pathname, "rb");
22540 if (filedata->handle == NULL)
22541 goto fail;
22542
be7d229a 22543 filedata->file_size = statbuf.st_size;
dda8d76d 22544 filedata->file_name = pathname;
ca0e11aa 22545 filedata->is_separate = is_separate;
dda8d76d
NC
22546
22547 if (! get_file_header (filedata))
22548 goto fail;
22549
4de91c10
AM
22550 if (!get_section_headers (filedata, false))
22551 goto fail;
dda8d76d
NC
22552
22553 return filedata;
22554
22555 fail:
22556 if (filedata)
22557 {
22558 if (filedata->handle)
22559 fclose (filedata->handle);
22560 free (filedata);
22561 }
22562 return NULL;
22563}
22564
22565void *
22566open_debug_file (const char * pathname)
22567{
015dc7e1 22568 return open_file (pathname, true);
dda8d76d
NC
22569}
22570
835f2fae
NC
22571static void
22572initialise_dump_sects (Filedata * filedata)
22573{
22574 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22575 Note we do this even if cmdline_dump_sects is empty because we
22576 must make sure that the dump_sets array is zeroed out before each
22577 object file is processed. */
22578 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22579 memset (filedata->dump.dump_sects, 0,
22580 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22581
22582 if (cmdline.num_dump_sects > 0)
22583 {
22584 if (filedata->dump.num_dump_sects == 0)
22585 /* A sneaky way of allocating the dump_sects array. */
22586 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22587
22588 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22589 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22590 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22591 }
22592}
22593
94585d6d
NC
22594static bool
22595might_need_separate_debug_info (Filedata * filedata)
22596{
22597 /* Debuginfo files do not need further separate file loading. */
22598 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22599 return false;
22600
22601 /* Since do_follow_links might be enabled by default, only treat it as an
22602 indication that separate files should be loaded if setting it was a
22603 deliberate user action. */
22604 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22605 return true;
22606
22607 if (process_links || do_syms || do_unwind
22608 || dump_any_debugging || do_dump || do_debugging)
22609 return true;
22610
22611 return false;
22612}
22613
fb52b2f4
NC
22614/* Process one ELF object file according to the command line options.
22615 This file may actually be stored in an archive. The file is
32ec8896
NC
22616 positioned at the start of the ELF object. Returns TRUE if no
22617 problems were encountered, FALSE otherwise. */
fb52b2f4 22618
015dc7e1 22619static bool
dda8d76d 22620process_object (Filedata * filedata)
252b5132 22621{
015dc7e1 22622 bool have_separate_files;
252b5132 22623 unsigned int i;
015dc7e1 22624 bool res;
252b5132 22625
dda8d76d 22626 if (! get_file_header (filedata))
252b5132 22627 {
dda8d76d 22628 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22629 return false;
252b5132
RH
22630 }
22631
22632 /* Initialise per file variables. */
978c4450
AM
22633 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22634 filedata->version_info[i] = 0;
252b5132 22635
978c4450
AM
22636 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22637 filedata->dynamic_info[i] = 0;
22638 filedata->dynamic_info_DT_GNU_HASH = 0;
22639 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22640
22641 /* Process the file. */
22642 if (show_name)
dda8d76d 22643 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22644
835f2fae 22645 initialise_dump_sects (filedata);
d70c5fc7 22646
4de91c10
AM
22647 /* There may be some extensions in the first section header. Don't
22648 bomb if we can't read it. */
22649 get_section_headers (filedata, true);
22650
dda8d76d 22651 if (! process_file_header (filedata))
4de91c10
AM
22652 {
22653 res = false;
22654 goto out;
22655 }
252b5132 22656
e331b18d
AM
22657 /* Throw away the single section header read above, so that we
22658 re-read the entire set. */
22659 free (filedata->section_headers);
22660 filedata->section_headers = NULL;
22661
dda8d76d 22662 if (! process_section_headers (filedata))
2f62977e 22663 {
32ec8896 22664 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22665 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22666
2f62977e 22667 if (! do_using_dynamic)
015dc7e1 22668 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22669 }
252b5132 22670
dda8d76d 22671 if (! process_section_groups (filedata))
32ec8896 22672 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22673 do_unwind = false;
d1f5c6e3 22674
93df3340
AM
22675 process_program_headers (filedata);
22676
22677 res = process_dynamic_section (filedata);
252b5132 22678
dda8d76d 22679 if (! process_relocs (filedata))
015dc7e1 22680 res = false;
252b5132 22681
dda8d76d 22682 if (! process_unwind (filedata))
015dc7e1 22683 res = false;
4d6ed7c8 22684
dda8d76d 22685 if (! process_symbol_table (filedata))
015dc7e1 22686 res = false;
252b5132 22687
0f03783c 22688 if (! process_lto_symbol_tables (filedata))
015dc7e1 22689 res = false;
b9e920ec 22690
dda8d76d 22691 if (! process_syminfo (filedata))
015dc7e1 22692 res = false;
252b5132 22693
dda8d76d 22694 if (! process_version_sections (filedata))
015dc7e1 22695 res = false;
252b5132 22696
94585d6d 22697 if (might_need_separate_debug_info (filedata))
24841daa 22698 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22699 else
015dc7e1 22700 have_separate_files = false;
dda8d76d
NC
22701
22702 if (! process_section_contents (filedata))
015dc7e1 22703 res = false;
f5842774 22704
24841daa 22705 if (have_separate_files)
dda8d76d 22706 {
24841daa
NC
22707 separate_info * d;
22708
22709 for (d = first_separate_info; d != NULL; d = d->next)
22710 {
835f2fae
NC
22711 initialise_dump_sects (d->handle);
22712
ca0e11aa 22713 if (process_links && ! process_file_header (d->handle))
015dc7e1 22714 res = false;
ca0e11aa 22715 else if (! process_section_headers (d->handle))
015dc7e1 22716 res = false;
d6bfbc39 22717 else if (! process_section_contents (d->handle))
015dc7e1 22718 res = false;
ca0e11aa
NC
22719 else if (process_links)
22720 {
ca0e11aa 22721 if (! process_section_groups (d->handle))
015dc7e1 22722 res = false;
93df3340 22723 process_program_headers (d->handle);
ca0e11aa 22724 if (! process_dynamic_section (d->handle))
015dc7e1 22725 res = false;
ca0e11aa 22726 if (! process_relocs (d->handle))
015dc7e1 22727 res = false;
ca0e11aa 22728 if (! process_unwind (d->handle))
015dc7e1 22729 res = false;
ca0e11aa 22730 if (! process_symbol_table (d->handle))
015dc7e1 22731 res = false;
ca0e11aa 22732 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22733 res = false;
ca0e11aa 22734 if (! process_syminfo (d->handle))
015dc7e1 22735 res = false;
ca0e11aa 22736 if (! process_version_sections (d->handle))
015dc7e1 22737 res = false;
ca0e11aa 22738 if (! process_notes (d->handle))
015dc7e1 22739 res = false;
ca0e11aa 22740 }
24841daa
NC
22741 }
22742
22743 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22744 }
22745
22746 if (! process_notes (filedata))
015dc7e1 22747 res = false;
103f02d3 22748
dda8d76d 22749 if (! process_gnu_liblist (filedata))
015dc7e1 22750 res = false;
047b2264 22751
dda8d76d 22752 if (! process_arch_specific (filedata))
015dc7e1 22753 res = false;
252b5132 22754
4de91c10 22755 out:
13acb58d 22756 free_filedata (filedata);
e4b17d5c 22757
19e6b90e 22758 free_debug_memory ();
18bd398b 22759
32ec8896 22760 return res;
252b5132
RH
22761}
22762
2cf0635d 22763/* Process an ELF archive.
32ec8896
NC
22764 On entry the file is positioned just after the ARMAG string.
22765 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22766
015dc7e1
AM
22767static bool
22768process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22769{
22770 struct archive_info arch;
22771 struct archive_info nested_arch;
22772 size_t got;
015dc7e1 22773 bool ret = true;
2cf0635d 22774
015dc7e1 22775 show_name = true;
2cf0635d
NC
22776
22777 /* The ARCH structure is used to hold information about this archive. */
22778 arch.file_name = NULL;
22779 arch.file = NULL;
22780 arch.index_array = NULL;
22781 arch.sym_table = NULL;
22782 arch.longnames = NULL;
22783
22784 /* The NESTED_ARCH structure is used as a single-item cache of information
22785 about a nested archive (when members of a thin archive reside within
22786 another regular archive file). */
22787 nested_arch.file_name = NULL;
22788 nested_arch.file = NULL;
22789 nested_arch.index_array = NULL;
22790 nested_arch.sym_table = NULL;
22791 nested_arch.longnames = NULL;
22792
dda8d76d 22793 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22794 filedata->file_size, is_thin_archive,
22795 do_archive_index) != 0)
2cf0635d 22796 {
015dc7e1 22797 ret = false;
2cf0635d 22798 goto out;
4145f1d5 22799 }
fb52b2f4 22800
4145f1d5
NC
22801 if (do_archive_index)
22802 {
2cf0635d 22803 if (arch.sym_table == NULL)
1cb7d8b1
AM
22804 error (_("%s: unable to dump the index as none was found\n"),
22805 filedata->file_name);
4145f1d5
NC
22806 else
22807 {
26c527e6
AM
22808 uint64_t i, l;
22809 uint64_t current_pos;
4145f1d5 22810
26c527e6
AM
22811 printf (_("Index of archive %s: (%" PRIu64 " entries,"
22812 " %#" PRIx64 " bytes in the symbol table)\n"),
22813 filedata->file_name, arch.index_num,
1cb7d8b1 22814 arch.sym_size);
dda8d76d
NC
22815
22816 current_pos = ftell (filedata->handle);
4145f1d5 22817
2cf0635d 22818 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22819 {
1cb7d8b1
AM
22820 if (i == 0
22821 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22822 {
22823 char * member_name
22824 = get_archive_member_name_at (&arch, arch.index_array[i],
22825 &nested_arch);
2cf0635d 22826
1cb7d8b1
AM
22827 if (member_name != NULL)
22828 {
22829 char * qualified_name
22830 = make_qualified_name (&arch, &nested_arch,
22831 member_name);
2cf0635d 22832
1cb7d8b1
AM
22833 if (qualified_name != NULL)
22834 {
22835 printf (_("Contents of binary %s at offset "),
22836 qualified_name);
c2a7d3f5
NC
22837 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22838 putchar ('\n');
1cb7d8b1
AM
22839 free (qualified_name);
22840 }
fd486f32 22841 free (member_name);
4145f1d5
NC
22842 }
22843 }
2cf0635d
NC
22844
22845 if (l >= arch.sym_size)
4145f1d5 22846 {
1cb7d8b1
AM
22847 error (_("%s: end of the symbol table reached "
22848 "before the end of the index\n"),
dda8d76d 22849 filedata->file_name);
015dc7e1 22850 ret = false;
cb8f3167 22851 break;
4145f1d5 22852 }
591f7597 22853 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22854 printf ("\t%.*s\n",
22855 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22856 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22857 }
22858
67ce483b 22859 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22860 l = (l + 7) & ~ 7;
22861 else
22862 l += l & 1;
22863
2cf0635d 22864 if (l < arch.sym_size)
32ec8896 22865 {
26c527e6 22866 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
22867 "but without corresponding entries in "
22868 "the index table\n",
26c527e6 22869 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
22870 "but without corresponding entries in "
22871 "the index table\n",
22872 arch.sym_size - l),
dda8d76d 22873 filedata->file_name, arch.sym_size - l);
015dc7e1 22874 ret = false;
32ec8896 22875 }
4145f1d5 22876
63cf857e 22877 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22878 {
1cb7d8b1
AM
22879 error (_("%s: failed to seek back to start of object files "
22880 "in the archive\n"),
dda8d76d 22881 filedata->file_name);
015dc7e1 22882 ret = false;
2cf0635d 22883 goto out;
4145f1d5 22884 }
fb52b2f4 22885 }
4145f1d5
NC
22886
22887 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22888 && !do_segments && !do_header && !do_dump && !do_version
22889 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22890 && !do_section_groups && !do_dyn_syms)
2cf0635d 22891 {
015dc7e1 22892 ret = true; /* Archive index only. */
2cf0635d
NC
22893 goto out;
22894 }
fb52b2f4
NC
22895 }
22896
fb52b2f4
NC
22897 while (1)
22898 {
2cf0635d
NC
22899 char * name;
22900 size_t namelen;
22901 char * qualified_name;
22902
22903 /* Read the next archive header. */
63cf857e 22904 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22905 {
22906 error (_("%s: failed to seek to next archive header\n"),
22907 arch.file_name);
015dc7e1 22908 ret = false;
1cb7d8b1
AM
22909 break;
22910 }
dda8d76d 22911 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22912 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22913 {
22914 if (got == 0)
2cf0635d 22915 break;
28e817cc
NC
22916 /* PR 24049 - we cannot use filedata->file_name as this will
22917 have already been freed. */
22918 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22919
015dc7e1 22920 ret = false;
1cb7d8b1
AM
22921 break;
22922 }
2cf0635d 22923 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22924 {
22925 error (_("%s: did not find a valid archive header\n"),
22926 arch.file_name);
015dc7e1 22927 ret = false;
1cb7d8b1
AM
22928 break;
22929 }
2cf0635d
NC
22930
22931 arch.next_arhdr_offset += sizeof arch.arhdr;
22932
978c4450 22933 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22934
22935 name = get_archive_member_name (&arch, &nested_arch);
22936 if (name == NULL)
fb52b2f4 22937 {
28e817cc 22938 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22939 ret = false;
d989285c 22940 break;
fb52b2f4 22941 }
2cf0635d 22942 namelen = strlen (name);
fb52b2f4 22943
2cf0635d
NC
22944 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22945 if (qualified_name == NULL)
fb52b2f4 22946 {
28e817cc 22947 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22948 free (name);
015dc7e1 22949 ret = false;
d989285c 22950 break;
fb52b2f4
NC
22951 }
22952
2cf0635d 22953 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22954 {
22955 /* This is a proxy for an external member of a thin archive. */
22956 Filedata * member_filedata;
22957 char * member_file_name = adjust_relative_path
dda8d76d 22958 (filedata->file_name, name, namelen);
32ec8896 22959
fd486f32 22960 free (name);
1cb7d8b1
AM
22961 if (member_file_name == NULL)
22962 {
fd486f32 22963 free (qualified_name);
015dc7e1 22964 ret = false;
1cb7d8b1
AM
22965 break;
22966 }
2cf0635d 22967
015dc7e1 22968 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22969 if (member_filedata == NULL)
22970 {
22971 error (_("Input file '%s' is not readable.\n"), member_file_name);
22972 free (member_file_name);
fd486f32 22973 free (qualified_name);
015dc7e1 22974 ret = false;
1cb7d8b1
AM
22975 break;
22976 }
2cf0635d 22977
978c4450 22978 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22979 member_filedata->file_name = qualified_name;
2cf0635d 22980
75a2da57
AH
22981 /* The call to process_object() expects the file to be at the beginning. */
22982 rewind (member_filedata->handle);
22983
1cb7d8b1 22984 if (! process_object (member_filedata))
015dc7e1 22985 ret = false;
2cf0635d 22986
1cb7d8b1
AM
22987 close_file (member_filedata);
22988 free (member_file_name);
1cb7d8b1 22989 }
2cf0635d 22990 else if (is_thin_archive)
1cb7d8b1
AM
22991 {
22992 Filedata thin_filedata;
eb02c04d 22993
1cb7d8b1 22994 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22995
a043396b
NC
22996 /* PR 15140: Allow for corrupt thin archives. */
22997 if (nested_arch.file == NULL)
22998 {
22999 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 23000 qualified_name, name);
fd486f32
AM
23001 free (qualified_name);
23002 free (name);
015dc7e1 23003 ret = false;
a043396b
NC
23004 break;
23005 }
fd486f32 23006 free (name);
a043396b 23007
1cb7d8b1 23008 /* This is a proxy for a member of a nested archive. */
978c4450
AM
23009 filedata->archive_file_offset
23010 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 23011
1cb7d8b1
AM
23012 /* The nested archive file will have been opened and setup by
23013 get_archive_member_name. */
63cf857e
AM
23014 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
23015 SEEK_SET) != 0)
1cb7d8b1
AM
23016 {
23017 error (_("%s: failed to seek to archive member.\n"),
23018 nested_arch.file_name);
fd486f32 23019 free (qualified_name);
015dc7e1 23020 ret = false;
1cb7d8b1
AM
23021 break;
23022 }
2cf0635d 23023
dda8d76d
NC
23024 thin_filedata.handle = nested_arch.file;
23025 thin_filedata.file_name = qualified_name;
9abca702 23026
1cb7d8b1 23027 if (! process_object (& thin_filedata))
015dc7e1 23028 ret = false;
1cb7d8b1 23029 }
2cf0635d 23030 else
1cb7d8b1 23031 {
fd486f32 23032 free (name);
978c4450 23033 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 23034 filedata->file_name = qualified_name;
1cb7d8b1 23035 if (! process_object (filedata))
015dc7e1 23036 ret = false;
237877b8 23037 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 23038 /* Stop looping with "negative" archive_file_size. */
978c4450 23039 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 23040 arch.next_arhdr_offset = -1ul;
1cb7d8b1 23041 }
fb52b2f4 23042
2cf0635d 23043 free (qualified_name);
fb52b2f4
NC
23044 }
23045
4145f1d5 23046 out:
2cf0635d
NC
23047 if (nested_arch.file != NULL)
23048 fclose (nested_arch.file);
23049 release_archive (&nested_arch);
23050 release_archive (&arch);
fb52b2f4 23051
d989285c 23052 return ret;
fb52b2f4
NC
23053}
23054
015dc7e1 23055static bool
2cf0635d 23056process_file (char * file_name)
fb52b2f4 23057{
dda8d76d 23058 Filedata * filedata = NULL;
fb52b2f4
NC
23059 struct stat statbuf;
23060 char armag[SARMAG];
015dc7e1 23061 bool ret = true;
fb52b2f4
NC
23062
23063 if (stat (file_name, &statbuf) < 0)
23064 {
f24ddbdd
NC
23065 if (errno == ENOENT)
23066 error (_("'%s': No such file\n"), file_name);
23067 else
23068 error (_("Could not locate '%s'. System error message: %s\n"),
23069 file_name, strerror (errno));
015dc7e1 23070 return false;
f24ddbdd
NC
23071 }
23072
23073 if (! S_ISREG (statbuf.st_mode))
23074 {
23075 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 23076 return false;
fb52b2f4
NC
23077 }
23078
dda8d76d
NC
23079 filedata = calloc (1, sizeof * filedata);
23080 if (filedata == NULL)
23081 {
23082 error (_("Out of memory allocating file data structure\n"));
015dc7e1 23083 return false;
dda8d76d
NC
23084 }
23085
23086 filedata->file_name = file_name;
23087 filedata->handle = fopen (file_name, "rb");
23088 if (filedata->handle == NULL)
fb52b2f4 23089 {
f24ddbdd 23090 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 23091 free (filedata);
015dc7e1 23092 return false;
fb52b2f4
NC
23093 }
23094
dda8d76d 23095 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 23096 {
4145f1d5 23097 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
23098 fclose (filedata->handle);
23099 free (filedata);
015dc7e1 23100 return false;
fb52b2f4
NC
23101 }
23102
be7d229a 23103 filedata->file_size = statbuf.st_size;
015dc7e1 23104 filedata->is_separate = false;
f54498b4 23105
fb52b2f4 23106 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 23107 {
015dc7e1
AM
23108 if (! process_archive (filedata, false))
23109 ret = false;
32ec8896 23110 }
2cf0635d 23111 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 23112 {
015dc7e1
AM
23113 if ( ! process_archive (filedata, true))
23114 ret = false;
32ec8896 23115 }
fb52b2f4
NC
23116 else
23117 {
1b513401 23118 if (do_archive_index && !check_all)
4145f1d5
NC
23119 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23120 file_name);
23121
dda8d76d 23122 rewind (filedata->handle);
978c4450 23123 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 23124
dda8d76d 23125 if (! process_object (filedata))
015dc7e1 23126 ret = false;
fb52b2f4
NC
23127 }
23128
dda8d76d 23129 fclose (filedata->handle);
8fb879cd
AM
23130 free (filedata->section_headers);
23131 free (filedata->program_headers);
23132 free (filedata->string_table);
6431e409 23133 free (filedata->dump.dump_sects);
dda8d76d 23134 free (filedata);
32ec8896 23135
fd486f32 23136 free (ba_cache.strtab);
1bd6175a 23137 ba_cache.strtab = NULL;
fd486f32 23138 free (ba_cache.symtab);
1bd6175a 23139 ba_cache.symtab = NULL;
fd486f32
AM
23140 ba_cache.filedata = NULL;
23141
fb52b2f4
NC
23142 return ret;
23143}
23144
252b5132
RH
23145#ifdef SUPPORT_DISASSEMBLY
23146/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 23147 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 23148 symbols. */
252b5132
RH
23149
23150void
2cf0635d 23151print_address (unsigned int addr, FILE * outfile)
252b5132
RH
23152{
23153 fprintf (outfile,"0x%8.8x", addr);
23154}
23155
e3c8793a 23156/* Needed by the i386 disassembler. */
dda8d76d 23157
252b5132
RH
23158void
23159db_task_printsym (unsigned int addr)
23160{
23161 print_address (addr, stderr);
23162}
23163#endif
23164
23165int
2cf0635d 23166main (int argc, char ** argv)
252b5132 23167{
ff78d6d6
L
23168 int err;
23169
87b9f255 23170#ifdef HAVE_LC_MESSAGES
252b5132 23171 setlocale (LC_MESSAGES, "");
3882b010 23172#endif
3882b010 23173 setlocale (LC_CTYPE, "");
252b5132
RH
23174 bindtextdomain (PACKAGE, LOCALEDIR);
23175 textdomain (PACKAGE);
23176
869b9d07
MM
23177 expandargv (&argc, &argv);
23178
dda8d76d 23179 parse_args (& cmdline, argc, argv);
59f14fc0 23180
18bd398b 23181 if (optind < (argc - 1))
1b513401
NC
23182 /* When displaying information for more than one file,
23183 prefix the information with the file name. */
015dc7e1 23184 show_name = true;
5656ba2c
L
23185 else if (optind >= argc)
23186 {
1b513401 23187 /* Ensure that the warning is always displayed. */
015dc7e1 23188 do_checks = true;
1b513401 23189
5656ba2c
L
23190 warn (_("Nothing to do.\n"));
23191 usage (stderr);
23192 }
18bd398b 23193
015dc7e1 23194 err = false;
252b5132 23195 while (optind < argc)
32ec8896 23196 if (! process_file (argv[optind++]))
015dc7e1 23197 err = true;
252b5132 23198
9db70fc3 23199 free (cmdline.dump_sects);
252b5132 23200
7d9813f1
NA
23201 free (dump_ctf_symtab_name);
23202 free (dump_ctf_strtab_name);
23203 free (dump_ctf_parent_name);
23204
32ec8896 23205 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 23206}