]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Automatic date update in version.in
[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:
e9f53129
AM
1064 case EM_AVR:
1065 case EM_AVR_OLD:
1066 case EM_BLACKFIN:
60bca95a 1067 case EM_CR16:
e9f53129
AM
1068 case EM_CRIS:
1069 case EM_CRX:
b8891f8d 1070 case EM_CSKY:
2b0337b0 1071 case EM_D30V:
252b5132 1072 case EM_CYGNUS_D30V:
2b0337b0 1073 case EM_FR30:
3f8107ab 1074 case EM_FT32:
252b5132 1075 case EM_CYGNUS_FR30:
5c70f934 1076 case EM_CYGNUS_FRV:
e9f53129
AM
1077 case EM_H8S:
1078 case EM_H8_300:
1079 case EM_H8_300H:
800eeca4 1080 case EM_IA_64:
1e4cf259
NC
1081 case EM_IP2K:
1082 case EM_IP2K_OLD:
3b36097d 1083 case EM_IQ2000:
84e94c90 1084 case EM_LATTICEMICO32:
ff7eeb89 1085 case EM_M32C_OLD:
49f58d10 1086 case EM_M32C:
e9f53129
AM
1087 case EM_M32R:
1088 case EM_MCORE:
15ab5209 1089 case EM_CYGNUS_MEP:
a3c62988 1090 case EM_METAG:
e9f53129
AM
1091 case EM_MMIX:
1092 case EM_MN10200:
1093 case EM_CYGNUS_MN10200:
1094 case EM_MN10300:
1095 case EM_CYGNUS_MN10300:
5506d11a 1096 case EM_MOXIE:
e9f53129
AM
1097 case EM_MSP430:
1098 case EM_MSP430_OLD:
d031aafb 1099 case EM_MT:
35c08157 1100 case EM_NDS32:
64fd6348 1101 case EM_NIOS32:
73589c9d 1102 case EM_OR1K:
e9f53129
AM
1103 case EM_PPC64:
1104 case EM_PPC:
2b100bb5 1105 case EM_TI_PRU:
e23eba97 1106 case EM_RISCV:
99c513f6 1107 case EM_RL78:
c7927a3c 1108 case EM_RX:
e9f53129
AM
1109 case EM_S390:
1110 case EM_S390_OLD:
1111 case EM_SH:
1112 case EM_SPARC:
1113 case EM_SPARC32PLUS:
1114 case EM_SPARCV9:
1115 case EM_SPU:
40b36596 1116 case EM_TI_C6000:
aa137e4d
NC
1117 case EM_TILEGX:
1118 case EM_TILEPRO:
708e2187 1119 case EM_V800:
e9f53129
AM
1120 case EM_V850:
1121 case EM_CYGNUS_V850:
1122 case EM_VAX:
619ed720 1123 case EM_VISIUM:
e9f53129 1124 case EM_X86_64:
8a9036a4 1125 case EM_L1OM:
7a9068fe 1126 case EM_K1OM:
e9f53129
AM
1127 case EM_XSTORMY16:
1128 case EM_XTENSA:
1129 case EM_XTENSA_OLD:
7ba29e2a
NC
1130 case EM_MICROBLAZE:
1131 case EM_MICROBLAZE_OLD:
f96bd6c2 1132 case EM_WEBASSEMBLY:
015dc7e1 1133 return true;
103f02d3 1134
e9f53129
AM
1135 case EM_68HC05:
1136 case EM_68HC08:
1137 case EM_68HC11:
1138 case EM_68HC16:
1139 case EM_FX66:
1140 case EM_ME16:
d1133906 1141 case EM_MMA:
d1133906
NC
1142 case EM_NCPU:
1143 case EM_NDR1:
e9f53129 1144 case EM_PCP:
d1133906 1145 case EM_ST100:
e9f53129 1146 case EM_ST19:
d1133906 1147 case EM_ST7:
e9f53129
AM
1148 case EM_ST9PLUS:
1149 case EM_STARCORE:
d1133906 1150 case EM_SVX:
e9f53129 1151 case EM_TINYJ:
9c19a809
NC
1152 default:
1153 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1154 return false;
9c19a809
NC
1155 }
1156}
252b5132 1157
dda8d76d 1158/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1159 Returns TRUE upon success, FALSE otherwise. If successful then a
1160 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1161 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1162 responsibility to free the allocated buffer. */
1163
015dc7e1 1164static bool
26c527e6
AM
1165slurp_rela_relocs (Filedata *filedata,
1166 uint64_t rel_offset,
1167 uint64_t rel_size,
1168 Elf_Internal_Rela **relasp,
1169 uint64_t *nrelasp)
9c19a809 1170{
2cf0635d 1171 Elf_Internal_Rela * relas;
26c527e6 1172 uint64_t nrelas;
4d6ed7c8 1173 unsigned int i;
252b5132 1174
4d6ed7c8
NC
1175 if (is_32bit_elf)
1176 {
2cf0635d 1177 Elf32_External_Rela * erelas;
103f02d3 1178
dda8d76d 1179 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1180 rel_size, _("32-bit relocation data"));
a6e9f9df 1181 if (!erelas)
015dc7e1 1182 return false;
252b5132 1183
4d6ed7c8 1184 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1185
3f5e193b
NC
1186 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1187 sizeof (Elf_Internal_Rela));
103f02d3 1188
4d6ed7c8
NC
1189 if (relas == NULL)
1190 {
c256ffe7 1191 free (erelas);
591a748a 1192 error (_("out of memory parsing relocs\n"));
015dc7e1 1193 return false;
4d6ed7c8 1194 }
103f02d3 1195
4d6ed7c8
NC
1196 for (i = 0; i < nrelas; i++)
1197 {
1198 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1199 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1200 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1201 }
103f02d3 1202
4d6ed7c8
NC
1203 free (erelas);
1204 }
1205 else
1206 {
2cf0635d 1207 Elf64_External_Rela * erelas;
103f02d3 1208
dda8d76d 1209 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1210 rel_size, _("64-bit relocation data"));
a6e9f9df 1211 if (!erelas)
015dc7e1 1212 return false;
4d6ed7c8
NC
1213
1214 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1215
3f5e193b
NC
1216 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1217 sizeof (Elf_Internal_Rela));
103f02d3 1218
4d6ed7c8
NC
1219 if (relas == NULL)
1220 {
c256ffe7 1221 free (erelas);
591a748a 1222 error (_("out of memory parsing relocs\n"));
015dc7e1 1223 return false;
9c19a809 1224 }
4d6ed7c8
NC
1225
1226 for (i = 0; i < nrelas; i++)
9c19a809 1227 {
66543521
AM
1228 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1229 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1230 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a 1231
dda8d76d
NC
1232 if (filedata->file_header.e_machine == EM_MIPS
1233 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1234 {
1235 /* In little-endian objects, r_info isn't really a
1236 64-bit little-endian value: it has a 32-bit
1237 little-endian symbol index followed by four
1238 individual byte fields. Reorder INFO
1239 accordingly. */
625d49fc 1240 uint64_t inf = relas[i].r_info;
91d6fa6a
NC
1241 inf = (((inf & 0xffffffff) << 32)
1242 | ((inf >> 56) & 0xff)
1243 | ((inf >> 40) & 0xff00)
1244 | ((inf >> 24) & 0xff0000)
1245 | ((inf >> 8) & 0xff000000));
1246 relas[i].r_info = inf;
861fb55a 1247 }
4d6ed7c8 1248 }
103f02d3 1249
4d6ed7c8
NC
1250 free (erelas);
1251 }
32ec8896 1252
4d6ed7c8
NC
1253 *relasp = relas;
1254 *nrelasp = nrelas;
015dc7e1 1255 return true;
4d6ed7c8 1256}
103f02d3 1257
dda8d76d 1258/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1259 Returns TRUE upon success, FALSE otherwise. If successful then a
1260 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1261 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1262 responsibility to free the allocated buffer. */
1263
015dc7e1 1264static bool
26c527e6
AM
1265slurp_rel_relocs (Filedata *filedata,
1266 uint64_t rel_offset,
1267 uint64_t rel_size,
1268 Elf_Internal_Rela **relsp,
1269 uint64_t *nrelsp)
4d6ed7c8 1270{
2cf0635d 1271 Elf_Internal_Rela * rels;
26c527e6 1272 uint64_t nrels;
4d6ed7c8 1273 unsigned int i;
103f02d3 1274
4d6ed7c8
NC
1275 if (is_32bit_elf)
1276 {
2cf0635d 1277 Elf32_External_Rel * erels;
103f02d3 1278
dda8d76d 1279 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1280 rel_size, _("32-bit relocation data"));
a6e9f9df 1281 if (!erels)
015dc7e1 1282 return false;
103f02d3 1283
4d6ed7c8 1284 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1285
3f5e193b 1286 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1287
4d6ed7c8
NC
1288 if (rels == NULL)
1289 {
c256ffe7 1290 free (erels);
591a748a 1291 error (_("out of memory parsing relocs\n"));
015dc7e1 1292 return false;
4d6ed7c8
NC
1293 }
1294
1295 for (i = 0; i < nrels; i++)
1296 {
1297 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1298 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1299 rels[i].r_addend = 0;
9ea033b2 1300 }
4d6ed7c8
NC
1301
1302 free (erels);
9c19a809
NC
1303 }
1304 else
1305 {
2cf0635d 1306 Elf64_External_Rel * erels;
9ea033b2 1307
dda8d76d 1308 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1309 rel_size, _("64-bit relocation data"));
a6e9f9df 1310 if (!erels)
015dc7e1 1311 return false;
103f02d3 1312
4d6ed7c8 1313 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1314
3f5e193b 1315 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1316
4d6ed7c8 1317 if (rels == NULL)
9c19a809 1318 {
c256ffe7 1319 free (erels);
591a748a 1320 error (_("out of memory parsing relocs\n"));
015dc7e1 1321 return false;
4d6ed7c8 1322 }
103f02d3 1323
4d6ed7c8
NC
1324 for (i = 0; i < nrels; i++)
1325 {
66543521
AM
1326 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1327 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1328 rels[i].r_addend = 0;
861fb55a 1329
dda8d76d
NC
1330 if (filedata->file_header.e_machine == EM_MIPS
1331 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1332 {
1333 /* In little-endian objects, r_info isn't really a
1334 64-bit little-endian value: it has a 32-bit
1335 little-endian symbol index followed by four
1336 individual byte fields. Reorder INFO
1337 accordingly. */
625d49fc 1338 uint64_t inf = rels[i].r_info;
91d6fa6a
NC
1339 inf = (((inf & 0xffffffff) << 32)
1340 | ((inf >> 56) & 0xff)
1341 | ((inf >> 40) & 0xff00)
1342 | ((inf >> 24) & 0xff0000)
1343 | ((inf >> 8) & 0xff000000));
1344 rels[i].r_info = inf;
861fb55a 1345 }
4d6ed7c8 1346 }
103f02d3 1347
4d6ed7c8
NC
1348 free (erels);
1349 }
32ec8896 1350
4d6ed7c8
NC
1351 *relsp = rels;
1352 *nrelsp = nrels;
015dc7e1 1353 return true;
4d6ed7c8 1354}
103f02d3 1355
a7fd1186 1356static bool
26c527e6
AM
1357slurp_relr_relocs (Filedata *filedata,
1358 uint64_t relr_offset,
1359 uint64_t relr_size,
1360 uint64_t **relrsp,
1361 uint64_t *nrelrsp)
a7fd1186
FS
1362{
1363 void *relrs;
1364 size_t size = 0, nentries, i;
625d49fc 1365 uint64_t base = 0, addr, entry;
a7fd1186
FS
1366
1367 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1368 _("RELR relocation data"));
1369 if (!relrs)
1370 return false;
1371
1372 if (is_32bit_elf)
1373 nentries = relr_size / sizeof (Elf32_External_Relr);
1374 else
1375 nentries = relr_size / sizeof (Elf64_External_Relr);
1376 for (i = 0; i < nentries; i++)
1377 {
1378 if (is_32bit_elf)
1379 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1380 else
1381 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1382 if ((entry & 1) == 0)
1383 size++;
1384 else
1385 while ((entry >>= 1) != 0)
1386 if ((entry & 1) == 1)
1387 size++;
1388 }
1389
625d49fc 1390 *relrsp = malloc (size * sizeof (**relrsp));
a7fd1186
FS
1391 if (*relrsp == NULL)
1392 {
1393 free (relrs);
1394 error (_("out of memory parsing relocs\n"));
1395 return false;
1396 }
1397
1398 size = 0;
1399 for (i = 0; i < nentries; i++)
1400 {
625d49fc 1401 const uint64_t entry_bytes = is_32bit_elf ? 4 : 8;
a7fd1186
FS
1402
1403 if (is_32bit_elf)
1404 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1405 else
1406 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1407 if ((entry & 1) == 0)
1408 {
1409 (*relrsp)[size++] = entry;
1410 base = entry + entry_bytes;
1411 }
1412 else
1413 {
1414 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1415 if ((entry & 1) != 0)
1416 (*relrsp)[size++] = addr;
1417 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1418 }
1419 }
1420
1421 *nrelrsp = size;
1422 free (relrs);
1423 return true;
1424}
1425
aca88567
NC
1426/* Returns the reloc type extracted from the reloc info field. */
1427
1428static unsigned int
625d49fc 1429get_reloc_type (Filedata * filedata, uint64_t reloc_info)
aca88567
NC
1430{
1431 if (is_32bit_elf)
1432 return ELF32_R_TYPE (reloc_info);
1433
dda8d76d 1434 switch (filedata->file_header.e_machine)
aca88567
NC
1435 {
1436 case EM_MIPS:
1437 /* Note: We assume that reloc_info has already been adjusted for us. */
1438 return ELF64_MIPS_R_TYPE (reloc_info);
1439
1440 case EM_SPARCV9:
1441 return ELF64_R_TYPE_ID (reloc_info);
1442
1443 default:
1444 return ELF64_R_TYPE (reloc_info);
1445 }
1446}
1447
1448/* Return the symbol index extracted from the reloc info field. */
1449
625d49fc
AM
1450static uint64_t
1451get_reloc_symindex (uint64_t reloc_info)
aca88567
NC
1452{
1453 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1454}
1455
015dc7e1 1456static inline bool
dda8d76d 1457uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1458{
1459 return
dda8d76d 1460 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1461 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1462 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1463 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1464 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1465}
1466
d3ba0551
AM
1467/* Display the contents of the relocation data found at the specified
1468 offset. */
ee42cf8c 1469
015dc7e1 1470static bool
26c527e6
AM
1471dump_relocations (Filedata *filedata,
1472 uint64_t rel_offset,
1473 uint64_t rel_size,
1474 Elf_Internal_Sym *symtab,
1475 uint64_t nsyms,
1476 char *strtab,
1477 uint64_t strtablen,
1478 relocation_type rel_type,
1479 bool is_dynsym)
1480{
1481 size_t i;
2cf0635d 1482 Elf_Internal_Rela * rels;
015dc7e1 1483 bool res = true;
103f02d3 1484
a7fd1186
FS
1485 if (rel_type == reltype_unknown)
1486 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1487
a7fd1186 1488 if (rel_type == reltype_rela)
4d6ed7c8 1489 {
dda8d76d 1490 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1491 return false;
4d6ed7c8 1492 }
a7fd1186 1493 else if (rel_type == reltype_rel)
4d6ed7c8 1494 {
dda8d76d 1495 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1496 return false;
252b5132 1497 }
a7fd1186
FS
1498 else if (rel_type == reltype_relr)
1499 {
625d49fc 1500 uint64_t * relrs;
a7fd1186 1501 const char *format
b8281767 1502 = is_32bit_elf ? "%08" PRIx64 "\n" : "%016" PRIx64 "\n";
a7fd1186
FS
1503
1504 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1505 &rel_size))
1506 return false;
1507
26c527e6
AM
1508 printf (ngettext (" %" PRIu64 " offset\n",
1509 " %" PRIu64 " offsets\n", rel_size),
b8281767 1510 rel_size);
a7fd1186 1511 for (i = 0; i < rel_size; i++)
625d49fc 1512 printf (format, relrs[i]);
a7fd1186
FS
1513 free (relrs);
1514 return true;
1515 }
252b5132 1516
410f7a12
L
1517 if (is_32bit_elf)
1518 {
a7fd1186 1519 if (rel_type == reltype_rela)
2c71103e
NC
1520 {
1521 if (do_wide)
1522 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1523 else
1524 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1525 }
410f7a12 1526 else
2c71103e
NC
1527 {
1528 if (do_wide)
1529 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1530 else
1531 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1532 }
410f7a12 1533 }
252b5132 1534 else
410f7a12 1535 {
a7fd1186 1536 if (rel_type == reltype_rela)
2c71103e
NC
1537 {
1538 if (do_wide)
8beeaeb7 1539 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1540 else
1541 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1542 }
410f7a12 1543 else
2c71103e
NC
1544 {
1545 if (do_wide)
8beeaeb7 1546 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1547 else
1548 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1549 }
410f7a12 1550 }
252b5132
RH
1551
1552 for (i = 0; i < rel_size; i++)
1553 {
2cf0635d 1554 const char * rtype;
625d49fc
AM
1555 uint64_t offset;
1556 uint64_t inf;
1557 uint64_t symtab_index;
1558 uint64_t type;
103f02d3 1559
b34976b6 1560 offset = rels[i].r_offset;
91d6fa6a 1561 inf = rels[i].r_info;
103f02d3 1562
dda8d76d 1563 type = get_reloc_type (filedata, inf);
91d6fa6a 1564 symtab_index = get_reloc_symindex (inf);
252b5132 1565
410f7a12
L
1566 if (is_32bit_elf)
1567 {
39dbeff8
AM
1568 printf ("%8.8lx %8.8lx ",
1569 (unsigned long) offset & 0xffffffff,
91d6fa6a 1570 (unsigned long) inf & 0xffffffff);
410f7a12
L
1571 }
1572 else
1573 {
39dbeff8 1574 printf (do_wide
b8281767
AM
1575 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
1576 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
625d49fc 1577 offset, inf);
410f7a12 1578 }
103f02d3 1579
dda8d76d 1580 switch (filedata->file_header.e_machine)
252b5132
RH
1581 {
1582 default:
1583 rtype = NULL;
1584 break;
1585
a06ea964
NC
1586 case EM_AARCH64:
1587 rtype = elf_aarch64_reloc_type (type);
1588 break;
1589
2b0337b0 1590 case EM_M32R:
252b5132 1591 case EM_CYGNUS_M32R:
9ea033b2 1592 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1593 break;
1594
1595 case EM_386:
22abe556 1596 case EM_IAMCU:
9ea033b2 1597 rtype = elf_i386_reloc_type (type);
252b5132
RH
1598 break;
1599
ba2685cc
AM
1600 case EM_68HC11:
1601 case EM_68HC12:
1602 rtype = elf_m68hc11_reloc_type (type);
1603 break;
75751cd9 1604
7b4ae824
JD
1605 case EM_S12Z:
1606 rtype = elf_s12z_reloc_type (type);
1607 break;
1608
252b5132 1609 case EM_68K:
9ea033b2 1610 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1611 break;
1612
f954747f
AM
1613 case EM_960:
1614 rtype = elf_i960_reloc_type (type);
1615 break;
1616
adde6300 1617 case EM_AVR:
2b0337b0 1618 case EM_AVR_OLD:
adde6300
AM
1619 rtype = elf_avr_reloc_type (type);
1620 break;
1621
9ea033b2
NC
1622 case EM_OLD_SPARCV9:
1623 case EM_SPARC32PLUS:
1624 case EM_SPARCV9:
252b5132 1625 case EM_SPARC:
9ea033b2 1626 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1627 break;
1628
e9f53129
AM
1629 case EM_SPU:
1630 rtype = elf_spu_reloc_type (type);
1631 break;
1632
708e2187
NC
1633 case EM_V800:
1634 rtype = v800_reloc_type (type);
1635 break;
2b0337b0 1636 case EM_V850:
252b5132 1637 case EM_CYGNUS_V850:
9ea033b2 1638 rtype = v850_reloc_type (type);
252b5132
RH
1639 break;
1640
2b0337b0 1641 case EM_D10V:
252b5132 1642 case EM_CYGNUS_D10V:
9ea033b2 1643 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1644 break;
1645
2b0337b0 1646 case EM_D30V:
252b5132 1647 case EM_CYGNUS_D30V:
9ea033b2 1648 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1649 break;
1650
d172d4ba
NC
1651 case EM_DLX:
1652 rtype = elf_dlx_reloc_type (type);
1653 break;
1654
252b5132 1655 case EM_SH:
9ea033b2 1656 rtype = elf_sh_reloc_type (type);
252b5132
RH
1657 break;
1658
2b0337b0 1659 case EM_MN10300:
252b5132 1660 case EM_CYGNUS_MN10300:
9ea033b2 1661 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1662 break;
1663
2b0337b0 1664 case EM_MN10200:
252b5132 1665 case EM_CYGNUS_MN10200:
9ea033b2 1666 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1667 break;
1668
2b0337b0 1669 case EM_FR30:
252b5132 1670 case EM_CYGNUS_FR30:
9ea033b2 1671 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1672 break;
1673
ba2685cc
AM
1674 case EM_CYGNUS_FRV:
1675 rtype = elf_frv_reloc_type (type);
1676 break;
5c70f934 1677
b8891f8d
AJ
1678 case EM_CSKY:
1679 rtype = elf_csky_reloc_type (type);
1680 break;
1681
3f8107ab
AM
1682 case EM_FT32:
1683 rtype = elf_ft32_reloc_type (type);
1684 break;
1685
252b5132 1686 case EM_MCORE:
9ea033b2 1687 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1688 break;
1689
3c3bdf30
NC
1690 case EM_MMIX:
1691 rtype = elf_mmix_reloc_type (type);
1692 break;
1693
5506d11a
AM
1694 case EM_MOXIE:
1695 rtype = elf_moxie_reloc_type (type);
1696 break;
1697
2469cfa2 1698 case EM_MSP430:
dda8d76d 1699 if (uses_msp430x_relocs (filedata))
13761a11
NC
1700 {
1701 rtype = elf_msp430x_reloc_type (type);
1702 break;
1703 }
1a0670f3 1704 /* Fall through. */
2469cfa2
NC
1705 case EM_MSP430_OLD:
1706 rtype = elf_msp430_reloc_type (type);
1707 break;
1708
35c08157
KLC
1709 case EM_NDS32:
1710 rtype = elf_nds32_reloc_type (type);
1711 break;
1712
252b5132 1713 case EM_PPC:
9ea033b2 1714 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1715 break;
1716
c833c019
AM
1717 case EM_PPC64:
1718 rtype = elf_ppc64_reloc_type (type);
1719 break;
1720
252b5132 1721 case EM_MIPS:
4fe85591 1722 case EM_MIPS_RS3_LE:
9ea033b2 1723 rtype = elf_mips_reloc_type (type);
252b5132
RH
1724 break;
1725
e23eba97
NC
1726 case EM_RISCV:
1727 rtype = elf_riscv_reloc_type (type);
1728 break;
1729
252b5132 1730 case EM_ALPHA:
9ea033b2 1731 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1732 break;
1733
1734 case EM_ARM:
9ea033b2 1735 rtype = elf_arm_reloc_type (type);
252b5132
RH
1736 break;
1737
584da044 1738 case EM_ARC:
886a2506
NC
1739 case EM_ARC_COMPACT:
1740 case EM_ARC_COMPACT2:
9ea033b2 1741 rtype = elf_arc_reloc_type (type);
252b5132
RH
1742 break;
1743
1744 case EM_PARISC:
69e617ca 1745 rtype = elf_hppa_reloc_type (type);
252b5132 1746 break;
7d466069 1747
b8720f9d
JL
1748 case EM_H8_300:
1749 case EM_H8_300H:
1750 case EM_H8S:
1751 rtype = elf_h8_reloc_type (type);
1752 break;
1753
73589c9d
CS
1754 case EM_OR1K:
1755 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1756 break;
1757
7d466069 1758 case EM_PJ:
2b0337b0 1759 case EM_PJ_OLD:
7d466069
ILT
1760 rtype = elf_pj_reloc_type (type);
1761 break;
800eeca4
JW
1762 case EM_IA_64:
1763 rtype = elf_ia64_reloc_type (type);
1764 break;
1b61cf92
HPN
1765
1766 case EM_CRIS:
1767 rtype = elf_cris_reloc_type (type);
1768 break;
535c37ff 1769
f954747f
AM
1770 case EM_860:
1771 rtype = elf_i860_reloc_type (type);
1772 break;
1773
bcedfee6 1774 case EM_X86_64:
8a9036a4 1775 case EM_L1OM:
7a9068fe 1776 case EM_K1OM:
bcedfee6
NC
1777 rtype = elf_x86_64_reloc_type (type);
1778 break;
a85d7ed0 1779
f954747f
AM
1780 case EM_S370:
1781 rtype = i370_reloc_type (type);
1782 break;
1783
53c7db4b
KH
1784 case EM_S390_OLD:
1785 case EM_S390:
1786 rtype = elf_s390_reloc_type (type);
1787 break;
93fbbb04 1788
1c0d3aa6
NC
1789 case EM_SCORE:
1790 rtype = elf_score_reloc_type (type);
1791 break;
1792
93fbbb04
GK
1793 case EM_XSTORMY16:
1794 rtype = elf_xstormy16_reloc_type (type);
1795 break;
179d3252 1796
1fe1f39c
NC
1797 case EM_CRX:
1798 rtype = elf_crx_reloc_type (type);
1799 break;
1800
179d3252
JT
1801 case EM_VAX:
1802 rtype = elf_vax_reloc_type (type);
1803 break;
1e4cf259 1804
619ed720
EB
1805 case EM_VISIUM:
1806 rtype = elf_visium_reloc_type (type);
1807 break;
1808
aca4efc7
JM
1809 case EM_BPF:
1810 rtype = elf_bpf_reloc_type (type);
1811 break;
1812
cfb8c092
NC
1813 case EM_ADAPTEVA_EPIPHANY:
1814 rtype = elf_epiphany_reloc_type (type);
1815 break;
1816
1e4cf259
NC
1817 case EM_IP2K:
1818 case EM_IP2K_OLD:
1819 rtype = elf_ip2k_reloc_type (type);
1820 break;
3b36097d
SC
1821
1822 case EM_IQ2000:
1823 rtype = elf_iq2000_reloc_type (type);
1824 break;
88da6820
NC
1825
1826 case EM_XTENSA_OLD:
1827 case EM_XTENSA:
1828 rtype = elf_xtensa_reloc_type (type);
1829 break;
a34e3ecb 1830
84e94c90
NC
1831 case EM_LATTICEMICO32:
1832 rtype = elf_lm32_reloc_type (type);
1833 break;
1834
ff7eeb89 1835 case EM_M32C_OLD:
49f58d10
JB
1836 case EM_M32C:
1837 rtype = elf_m32c_reloc_type (type);
1838 break;
1839
d031aafb
NS
1840 case EM_MT:
1841 rtype = elf_mt_reloc_type (type);
a34e3ecb 1842 break;
1d65ded4
CM
1843
1844 case EM_BLACKFIN:
1845 rtype = elf_bfin_reloc_type (type);
1846 break;
15ab5209
DB
1847
1848 case EM_CYGNUS_MEP:
1849 rtype = elf_mep_reloc_type (type);
1850 break;
60bca95a
NC
1851
1852 case EM_CR16:
1853 rtype = elf_cr16_reloc_type (type);
1854 break;
dd24e3da 1855
7ba29e2a
NC
1856 case EM_MICROBLAZE:
1857 case EM_MICROBLAZE_OLD:
1858 rtype = elf_microblaze_reloc_type (type);
1859 break;
c7927a3c 1860
99c513f6
DD
1861 case EM_RL78:
1862 rtype = elf_rl78_reloc_type (type);
1863 break;
1864
c7927a3c
NC
1865 case EM_RX:
1866 rtype = elf_rx_reloc_type (type);
1867 break;
c29aca4a 1868
a3c62988
NC
1869 case EM_METAG:
1870 rtype = elf_metag_reloc_type (type);
1871 break;
1872
40b36596
JM
1873 case EM_TI_C6000:
1874 rtype = elf_tic6x_reloc_type (type);
1875 break;
aa137e4d
NC
1876
1877 case EM_TILEGX:
1878 rtype = elf_tilegx_reloc_type (type);
1879 break;
1880
1881 case EM_TILEPRO:
1882 rtype = elf_tilepro_reloc_type (type);
1883 break;
f6c1a2d5 1884
f96bd6c2
PC
1885 case EM_WEBASSEMBLY:
1886 rtype = elf_wasm32_reloc_type (type);
1887 break;
1888
f6c1a2d5
NC
1889 case EM_XGATE:
1890 rtype = elf_xgate_reloc_type (type);
1891 break;
36591ba1
SL
1892
1893 case EM_ALTERA_NIOS2:
1894 rtype = elf_nios2_reloc_type (type);
1895 break;
2b100bb5
DD
1896
1897 case EM_TI_PRU:
1898 rtype = elf_pru_reloc_type (type);
1899 break;
fe944acf
FT
1900
1901 case EM_NFP:
1902 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1903 rtype = elf_nfp3200_reloc_type (type);
1904 else
1905 rtype = elf_nfp_reloc_type (type);
1906 break;
6655dba2
SB
1907
1908 case EM_Z80:
1909 rtype = elf_z80_reloc_type (type);
1910 break;
e9a0721f 1911
1912 case EM_LOONGARCH:
1913 rtype = elf_loongarch_reloc_type (type);
1914 break;
1915
0c857ef4
SM
1916 case EM_AMDGPU:
1917 rtype = elf_amdgpu_reloc_type (type);
1918 break;
252b5132
RH
1919 }
1920
1921 if (rtype == NULL)
39dbeff8 1922 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1923 else
5c144731 1924 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1925
dda8d76d 1926 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1927 && rtype != NULL
7ace3541 1928 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 1929 && rel_type == reltype_rela)
7ace3541
RH
1930 {
1931 switch (rels[i].r_addend)
1932 {
1933 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1934 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1935 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1936 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1937 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1938 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1939 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1940 default: rtype = NULL;
1941 }
32ec8896 1942
7ace3541
RH
1943 if (rtype)
1944 printf (" (%s)", rtype);
1945 else
1946 {
1947 putchar (' ');
26c527e6
AM
1948 printf (_("<unknown addend: %" PRIx64 ">"),
1949 rels[i].r_addend);
015dc7e1 1950 res = false;
7ace3541
RH
1951 }
1952 }
1953 else if (symtab_index)
252b5132 1954 {
af3fc3bc 1955 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1956 {
27a45f42
AS
1957 error (_(" bad symbol index: %08lx in reloc\n"),
1958 (unsigned long) symtab_index);
015dc7e1 1959 res = false;
32ec8896 1960 }
af3fc3bc 1961 else
19936277 1962 {
2cf0635d 1963 Elf_Internal_Sym * psym;
bb4d2ac2
L
1964 const char * version_string;
1965 enum versioned_symbol_info sym_info;
1966 unsigned short vna_other;
19936277 1967
af3fc3bc 1968 psym = symtab + symtab_index;
103f02d3 1969
bb4d2ac2 1970 version_string
dda8d76d 1971 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1972 strtab, strtablen,
1973 symtab_index,
1974 psym,
1975 &sym_info,
1976 &vna_other);
1977
af3fc3bc 1978 printf (" ");
171191ba 1979
d8045f23
NC
1980 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1981 {
1982 const char * name;
1983 unsigned int len;
1984 unsigned int width = is_32bit_elf ? 8 : 14;
1985
1986 /* Relocations against GNU_IFUNC symbols do not use the value
1987 of the symbol as the address to relocate against. Instead
1988 they invoke the function named by the symbol and use its
1989 result as the address for relocation.
1990
1991 To indicate this to the user, do not display the value of
1992 the symbol in the "Symbols's Value" field. Instead show
1993 its name followed by () as a hint that the symbol is
1994 invoked. */
1995
1996 if (strtab == NULL
1997 || psym->st_name == 0
1998 || psym->st_name >= strtablen)
1999 name = "??";
2000 else
2001 name = strtab + psym->st_name;
2002
2003 len = print_symbol (width, name);
bb4d2ac2
L
2004 if (version_string)
2005 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2006 version_string);
d8045f23
NC
2007 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2008 }
2009 else
2010 {
2011 print_vma (psym->st_value, LONG_HEX);
171191ba 2012
d8045f23
NC
2013 printf (is_32bit_elf ? " " : " ");
2014 }
103f02d3 2015
af3fc3bc 2016 if (psym->st_name == 0)
f1ef08cb 2017 {
2cf0635d 2018 const char * sec_name = "<null>";
f1ef08cb
AM
2019 char name_buf[40];
2020
2021 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
2022 {
b9af6379
AM
2023 if (psym->st_shndx < filedata->file_header.e_shnum
2024 && filedata->section_headers != NULL)
84714f86
AM
2025 sec_name = section_name_print (filedata,
2026 filedata->section_headers
b9e920ec 2027 + psym->st_shndx);
f1ef08cb
AM
2028 else if (psym->st_shndx == SHN_ABS)
2029 sec_name = "ABS";
2030 else if (psym->st_shndx == SHN_COMMON)
2031 sec_name = "COMMON";
dda8d76d 2032 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 2033 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 2034 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 2035 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 2036 sec_name = "SCOMMON";
dda8d76d 2037 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
2038 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
2039 sec_name = "SUNDEF";
dda8d76d
NC
2040 else if ((filedata->file_header.e_machine == EM_X86_64
2041 || filedata->file_header.e_machine == EM_L1OM
2042 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
2043 && psym->st_shndx == SHN_X86_64_LCOMMON)
2044 sec_name = "LARGE_COMMON";
dda8d76d
NC
2045 else if (filedata->file_header.e_machine == EM_IA_64
2046 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
2047 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
2048 sec_name = "ANSI_COM";
dda8d76d 2049 else if (is_ia64_vms (filedata)
148b93f2
NC
2050 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
2051 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
2052 else
2053 {
2054 sprintf (name_buf, "<section 0x%x>",
2055 (unsigned int) psym->st_shndx);
2056 sec_name = name_buf;
2057 }
2058 }
2059 print_symbol (22, sec_name);
2060 }
af3fc3bc 2061 else if (strtab == NULL)
d79b3d50 2062 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2063 else if (psym->st_name >= strtablen)
32ec8896 2064 {
27a45f42
AS
2065 error (_("<corrupt string table index: %3ld>\n"),
2066 psym->st_name);
015dc7e1 2067 res = false;
32ec8896 2068 }
af3fc3bc 2069 else
bb4d2ac2
L
2070 {
2071 print_symbol (22, strtab + psym->st_name);
2072 if (version_string)
2073 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2074 version_string);
2075 }
103f02d3 2076
a7fd1186 2077 if (rel_type == reltype_rela)
171191ba 2078 {
625d49fc 2079 uint64_t off = rels[i].r_addend;
171191ba 2080
625d49fc
AM
2081 if ((int64_t) off < 0)
2082 printf (" - %" PRIx64, -off);
171191ba 2083 else
625d49fc 2084 printf (" + %" PRIx64, off);
171191ba 2085 }
19936277 2086 }
252b5132 2087 }
a7fd1186 2088 else if (rel_type == reltype_rela)
f7a99963 2089 {
625d49fc 2090 uint64_t off = rels[i].r_addend;
e04d7088
L
2091
2092 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
625d49fc
AM
2093 if ((int64_t) off < 0)
2094 printf ("-%" PRIx64, -off);
e04d7088 2095 else
625d49fc 2096 printf ("%" PRIx64, off);
f7a99963 2097 }
252b5132 2098
dda8d76d 2099 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2100 && rtype != NULL
2101 && streq (rtype, "R_SPARC_OLO10"))
26c527e6 2102 printf (" + %" PRIx64, ELF64_R_TYPE_DATA (inf));
351b4b40 2103
252b5132 2104 putchar ('\n');
2c71103e 2105
dda8d76d 2106 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2107 {
625d49fc
AM
2108 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2109 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2110 const char * rtype2 = elf_mips_reloc_type (type2);
2111 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2112
2c71103e
NC
2113 printf (" Type2: ");
2114
2115 if (rtype2 == NULL)
39dbeff8
AM
2116 printf (_("unrecognized: %-7lx"),
2117 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2118 else
2119 printf ("%-17.17s", rtype2);
2120
18bd398b 2121 printf ("\n Type3: ");
2c71103e
NC
2122
2123 if (rtype3 == NULL)
39dbeff8
AM
2124 printf (_("unrecognized: %-7lx"),
2125 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2126 else
2127 printf ("%-17.17s", rtype3);
2128
53c7db4b 2129 putchar ('\n');
2c71103e 2130 }
252b5132
RH
2131 }
2132
c8286bd1 2133 free (rels);
32ec8896
NC
2134
2135 return res;
252b5132
RH
2136}
2137
37c18eed
SD
2138static const char *
2139get_aarch64_dynamic_type (unsigned long type)
2140{
2141 switch (type)
2142 {
2143 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2144 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2145 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2146 default:
2147 return NULL;
2148 }
2149}
2150
252b5132 2151static const char *
d3ba0551 2152get_mips_dynamic_type (unsigned long type)
252b5132
RH
2153{
2154 switch (type)
2155 {
2156 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2157 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2158 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2159 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2160 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2161 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2162 case DT_MIPS_MSYM: return "MIPS_MSYM";
2163 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2164 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2165 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2166 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2167 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2168 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2169 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2170 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2171 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2172 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2173 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2174 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2175 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2176 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2177 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2178 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2179 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2180 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2181 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2182 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2183 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2184 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2185 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2186 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2187 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2188 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2189 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2190 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2191 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2192 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2193 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2194 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2195 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2196 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2197 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2198 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2199 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2200 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2201 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2202 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2203 default:
2204 return NULL;
2205 }
2206}
2207
9a097730 2208static const char *
d3ba0551 2209get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2210{
2211 switch (type)
2212 {
2213 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2214 default:
2215 return NULL;
2216 }
103f02d3
UD
2217}
2218
7490d522
AM
2219static const char *
2220get_ppc_dynamic_type (unsigned long type)
2221{
2222 switch (type)
2223 {
a7f2871e 2224 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2225 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2226 default:
2227 return NULL;
2228 }
2229}
2230
f1cb7e17 2231static const char *
d3ba0551 2232get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2233{
2234 switch (type)
2235 {
a7f2871e
AM
2236 case DT_PPC64_GLINK: return "PPC64_GLINK";
2237 case DT_PPC64_OPD: return "PPC64_OPD";
2238 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2239 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2240 default:
2241 return NULL;
2242 }
2243}
2244
103f02d3 2245static const char *
d3ba0551 2246get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2247{
2248 switch (type)
2249 {
2250 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2251 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2252 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2253 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2254 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2255 case DT_HP_PREINIT: return "HP_PREINIT";
2256 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2257 case DT_HP_NEEDED: return "HP_NEEDED";
2258 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2259 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2260 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2261 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2262 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2263 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2264 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2265 case DT_HP_FILTERED: return "HP_FILTERED";
2266 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2267 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2268 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2269 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2270 case DT_PLT: return "PLT";
2271 case DT_PLT_SIZE: return "PLT_SIZE";
2272 case DT_DLT: return "DLT";
2273 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2274 default:
2275 return NULL;
2276 }
2277}
9a097730 2278
ecc51f48 2279static const char *
d3ba0551 2280get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2281{
2282 switch (type)
2283 {
148b93f2
NC
2284 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2285 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2286 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2287 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2288 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2289 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2290 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2291 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2292 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2293 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2294 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2295 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2296 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2297 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2298 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2299 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2300 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2301 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2302 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2303 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2304 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2305 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2306 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2307 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2308 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2309 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2310 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2311 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2312 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2313 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2314 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2315 default:
2316 return NULL;
2317 }
2318}
2319
fd85a6a1
NC
2320static const char *
2321get_solaris_section_type (unsigned long type)
2322{
2323 switch (type)
2324 {
2325 case 0x6fffffee: return "SUNW_ancillary";
2326 case 0x6fffffef: return "SUNW_capchain";
2327 case 0x6ffffff0: return "SUNW_capinfo";
2328 case 0x6ffffff1: return "SUNW_symsort";
2329 case 0x6ffffff2: return "SUNW_tlssort";
2330 case 0x6ffffff3: return "SUNW_LDYNSYM";
2331 case 0x6ffffff4: return "SUNW_dof";
2332 case 0x6ffffff5: return "SUNW_cap";
2333 case 0x6ffffff6: return "SUNW_SIGNATURE";
2334 case 0x6ffffff7: return "SUNW_ANNOTATE";
2335 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2336 case 0x6ffffff9: return "SUNW_DEBUG";
2337 case 0x6ffffffa: return "SUNW_move";
2338 case 0x6ffffffb: return "SUNW_COMDAT";
2339 case 0x6ffffffc: return "SUNW_syminfo";
2340 case 0x6ffffffd: return "SUNW_verdef";
2341 case 0x6ffffffe: return "SUNW_verneed";
2342 case 0x6fffffff: return "SUNW_versym";
2343 case 0x70000000: return "SPARC_GOTDATA";
2344 default: return NULL;
2345 }
2346}
2347
fabcb361
RH
2348static const char *
2349get_alpha_dynamic_type (unsigned long type)
2350{
2351 switch (type)
2352 {
2353 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2354 default: return NULL;
fabcb361
RH
2355 }
2356}
2357
1c0d3aa6
NC
2358static const char *
2359get_score_dynamic_type (unsigned long type)
2360{
2361 switch (type)
2362 {
2363 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2364 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2365 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2366 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2367 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2368 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2369 default: return NULL;
1c0d3aa6
NC
2370 }
2371}
2372
40b36596
JM
2373static const char *
2374get_tic6x_dynamic_type (unsigned long type)
2375{
2376 switch (type)
2377 {
2378 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2379 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2380 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2381 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2382 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2383 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2384 default: return NULL;
40b36596
JM
2385 }
2386}
1c0d3aa6 2387
36591ba1
SL
2388static const char *
2389get_nios2_dynamic_type (unsigned long type)
2390{
2391 switch (type)
2392 {
2393 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2394 default: return NULL;
36591ba1
SL
2395 }
2396}
2397
fd85a6a1
NC
2398static const char *
2399get_solaris_dynamic_type (unsigned long type)
2400{
2401 switch (type)
2402 {
2403 case 0x6000000d: return "SUNW_AUXILIARY";
2404 case 0x6000000e: return "SUNW_RTLDINF";
2405 case 0x6000000f: return "SUNW_FILTER";
2406 case 0x60000010: return "SUNW_CAP";
2407 case 0x60000011: return "SUNW_SYMTAB";
2408 case 0x60000012: return "SUNW_SYMSZ";
2409 case 0x60000013: return "SUNW_SORTENT";
2410 case 0x60000014: return "SUNW_SYMSORT";
2411 case 0x60000015: return "SUNW_SYMSORTSZ";
2412 case 0x60000016: return "SUNW_TLSSORT";
2413 case 0x60000017: return "SUNW_TLSSORTSZ";
2414 case 0x60000018: return "SUNW_CAPINFO";
2415 case 0x60000019: return "SUNW_STRPAD";
2416 case 0x6000001a: return "SUNW_CAPCHAIN";
2417 case 0x6000001b: return "SUNW_LDMACH";
2418 case 0x6000001d: return "SUNW_CAPCHAINENT";
2419 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2420 case 0x60000021: return "SUNW_PARENT";
2421 case 0x60000023: return "SUNW_ASLR";
2422 case 0x60000025: return "SUNW_RELAX";
2423 case 0x60000029: return "SUNW_NXHEAP";
2424 case 0x6000002b: return "SUNW_NXSTACK";
2425
2426 case 0x70000001: return "SPARC_REGISTER";
2427 case 0x7ffffffd: return "AUXILIARY";
2428 case 0x7ffffffe: return "USED";
2429 case 0x7fffffff: return "FILTER";
2430
15f205b1 2431 default: return NULL;
fd85a6a1
NC
2432 }
2433}
2434
8155b853
NC
2435static const char *
2436get_riscv_dynamic_type (unsigned long type)
2437{
2438 switch (type)
2439 {
2440 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2441 default:
2442 return NULL;
2443 }
2444}
2445
252b5132 2446static const char *
dda8d76d 2447get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2448{
e9e44622 2449 static char buff[64];
252b5132
RH
2450
2451 switch (type)
2452 {
2453 case DT_NULL: return "NULL";
2454 case DT_NEEDED: return "NEEDED";
2455 case DT_PLTRELSZ: return "PLTRELSZ";
2456 case DT_PLTGOT: return "PLTGOT";
2457 case DT_HASH: return "HASH";
2458 case DT_STRTAB: return "STRTAB";
2459 case DT_SYMTAB: return "SYMTAB";
2460 case DT_RELA: return "RELA";
2461 case DT_RELASZ: return "RELASZ";
2462 case DT_RELAENT: return "RELAENT";
2463 case DT_STRSZ: return "STRSZ";
2464 case DT_SYMENT: return "SYMENT";
2465 case DT_INIT: return "INIT";
2466 case DT_FINI: return "FINI";
2467 case DT_SONAME: return "SONAME";
2468 case DT_RPATH: return "RPATH";
2469 case DT_SYMBOLIC: return "SYMBOLIC";
2470 case DT_REL: return "REL";
2471 case DT_RELSZ: return "RELSZ";
2472 case DT_RELENT: return "RELENT";
dd207c13
FS
2473 case DT_RELR: return "RELR";
2474 case DT_RELRSZ: return "RELRSZ";
2475 case DT_RELRENT: return "RELRENT";
252b5132
RH
2476 case DT_PLTREL: return "PLTREL";
2477 case DT_DEBUG: return "DEBUG";
2478 case DT_TEXTREL: return "TEXTREL";
2479 case DT_JMPREL: return "JMPREL";
2480 case DT_BIND_NOW: return "BIND_NOW";
2481 case DT_INIT_ARRAY: return "INIT_ARRAY";
2482 case DT_FINI_ARRAY: return "FINI_ARRAY";
2483 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2484 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2485 case DT_RUNPATH: return "RUNPATH";
2486 case DT_FLAGS: return "FLAGS";
2d0e6f43 2487
d1133906
NC
2488 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2489 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2490 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2491
05107a46 2492 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2493 case DT_PLTPADSZ: return "PLTPADSZ";
2494 case DT_MOVEENT: return "MOVEENT";
2495 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2496 case DT_FEATURE: return "FEATURE";
252b5132
RH
2497 case DT_POSFLAG_1: return "POSFLAG_1";
2498 case DT_SYMINSZ: return "SYMINSZ";
2499 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2500
252b5132 2501 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2502 case DT_CONFIG: return "CONFIG";
2503 case DT_DEPAUDIT: return "DEPAUDIT";
2504 case DT_AUDIT: return "AUDIT";
2505 case DT_PLTPAD: return "PLTPAD";
2506 case DT_MOVETAB: return "MOVETAB";
252b5132 2507 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2508
252b5132 2509 case DT_VERSYM: return "VERSYM";
103f02d3 2510
67a4f2b7
AO
2511 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2512 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2513 case DT_RELACOUNT: return "RELACOUNT";
2514 case DT_RELCOUNT: return "RELCOUNT";
2515 case DT_FLAGS_1: return "FLAGS_1";
2516 case DT_VERDEF: return "VERDEF";
2517 case DT_VERDEFNUM: return "VERDEFNUM";
2518 case DT_VERNEED: return "VERNEED";
2519 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2520
019148e4 2521 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2522 case DT_USED: return "USED";
2523 case DT_FILTER: return "FILTER";
103f02d3 2524
047b2264
JJ
2525 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2526 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2527 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2528 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2529 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2530 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2531 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2532
252b5132
RH
2533 default:
2534 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2535 {
2cf0635d 2536 const char * result;
103f02d3 2537
dda8d76d 2538 switch (filedata->file_header.e_machine)
252b5132 2539 {
37c18eed
SD
2540 case EM_AARCH64:
2541 result = get_aarch64_dynamic_type (type);
2542 break;
252b5132 2543 case EM_MIPS:
4fe85591 2544 case EM_MIPS_RS3_LE:
252b5132
RH
2545 result = get_mips_dynamic_type (type);
2546 break;
9a097730
RH
2547 case EM_SPARCV9:
2548 result = get_sparc64_dynamic_type (type);
2549 break;
7490d522
AM
2550 case EM_PPC:
2551 result = get_ppc_dynamic_type (type);
2552 break;
f1cb7e17
AM
2553 case EM_PPC64:
2554 result = get_ppc64_dynamic_type (type);
2555 break;
ecc51f48
NC
2556 case EM_IA_64:
2557 result = get_ia64_dynamic_type (type);
2558 break;
fabcb361
RH
2559 case EM_ALPHA:
2560 result = get_alpha_dynamic_type (type);
2561 break;
1c0d3aa6
NC
2562 case EM_SCORE:
2563 result = get_score_dynamic_type (type);
2564 break;
40b36596
JM
2565 case EM_TI_C6000:
2566 result = get_tic6x_dynamic_type (type);
2567 break;
36591ba1
SL
2568 case EM_ALTERA_NIOS2:
2569 result = get_nios2_dynamic_type (type);
2570 break;
8155b853
NC
2571 case EM_RISCV:
2572 result = get_riscv_dynamic_type (type);
2573 break;
252b5132 2574 default:
dda8d76d 2575 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2576 result = get_solaris_dynamic_type (type);
2577 else
2578 result = NULL;
252b5132
RH
2579 break;
2580 }
2581
2582 if (result != NULL)
2583 return result;
2584
e9e44622 2585 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2586 }
eec8f817 2587 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2588 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2589 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2590 {
2cf0635d 2591 const char * result;
103f02d3 2592
dda8d76d 2593 switch (filedata->file_header.e_machine)
103f02d3
UD
2594 {
2595 case EM_PARISC:
2596 result = get_parisc_dynamic_type (type);
2597 break;
148b93f2
NC
2598 case EM_IA_64:
2599 result = get_ia64_dynamic_type (type);
2600 break;
103f02d3 2601 default:
dda8d76d 2602 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2603 result = get_solaris_dynamic_type (type);
2604 else
2605 result = NULL;
103f02d3
UD
2606 break;
2607 }
2608
2609 if (result != NULL)
2610 return result;
2611
e9e44622
JJ
2612 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2613 type);
103f02d3 2614 }
252b5132 2615 else
e9e44622 2616 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2617
252b5132
RH
2618 return buff;
2619 }
2620}
2621
93df3340
AM
2622static bool get_program_headers (Filedata *);
2623static bool get_dynamic_section (Filedata *);
2624
2625static void
2626locate_dynamic_section (Filedata *filedata)
2627{
26c527e6 2628 uint64_t dynamic_addr = 0;
be7d229a 2629 uint64_t dynamic_size = 0;
93df3340
AM
2630
2631 if (filedata->file_header.e_phnum != 0
2632 && get_program_headers (filedata))
2633 {
2634 Elf_Internal_Phdr *segment;
2635 unsigned int i;
2636
2637 for (i = 0, segment = filedata->program_headers;
2638 i < filedata->file_header.e_phnum;
2639 i++, segment++)
2640 {
2641 if (segment->p_type == PT_DYNAMIC)
2642 {
2643 dynamic_addr = segment->p_offset;
2644 dynamic_size = segment->p_filesz;
2645
2646 if (filedata->section_headers != NULL)
2647 {
2648 Elf_Internal_Shdr *sec;
2649
2650 sec = find_section (filedata, ".dynamic");
2651 if (sec != NULL)
2652 {
2653 if (sec->sh_size == 0
2654 || sec->sh_type == SHT_NOBITS)
2655 {
2656 dynamic_addr = 0;
2657 dynamic_size = 0;
2658 }
2659 else
2660 {
2661 dynamic_addr = sec->sh_offset;
2662 dynamic_size = sec->sh_size;
2663 }
2664 }
2665 }
2666
2667 if (dynamic_addr > filedata->file_size
2668 || (dynamic_size > filedata->file_size - dynamic_addr))
2669 {
2670 dynamic_addr = 0;
2671 dynamic_size = 0;
2672 }
2673 break;
2674 }
2675 }
2676 }
2677 filedata->dynamic_addr = dynamic_addr;
2678 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2679}
2680
2681static bool
2682is_pie (Filedata *filedata)
2683{
2684 Elf_Internal_Dyn *entry;
2685
2686 if (filedata->dynamic_size == 0)
2687 locate_dynamic_section (filedata);
2688 if (filedata->dynamic_size <= 1)
2689 return false;
2690
2691 if (!get_dynamic_section (filedata))
2692 return false;
2693
2694 for (entry = filedata->dynamic_section;
2695 entry < filedata->dynamic_section + filedata->dynamic_nent;
2696 entry++)
2697 {
2698 if (entry->d_tag == DT_FLAGS_1)
2699 {
2700 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2701 return true;
2702 break;
2703 }
2704 }
2705 return false;
2706}
2707
252b5132 2708static char *
93df3340 2709get_file_type (Filedata *filedata)
252b5132 2710{
93df3340 2711 unsigned e_type = filedata->file_header.e_type;
89246a0e 2712 static char buff[64];
252b5132
RH
2713
2714 switch (e_type)
2715 {
32ec8896
NC
2716 case ET_NONE: return _("NONE (None)");
2717 case ET_REL: return _("REL (Relocatable file)");
2718 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2719 case ET_DYN:
2720 if (is_pie (filedata))
2721 return _("DYN (Position-Independent Executable file)");
2722 else
2723 return _("DYN (Shared object file)");
32ec8896 2724 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2725
2726 default:
2727 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2728 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2729 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2730 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2731 else
e9e44622 2732 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2733 return buff;
2734 }
2735}
2736
2737static char *
d3ba0551 2738get_machine_name (unsigned e_machine)
252b5132 2739{
b34976b6 2740 static char buff[64]; /* XXX */
252b5132
RH
2741
2742 switch (e_machine)
2743 {
55e22ca8
NC
2744 /* Please keep this switch table sorted by increasing EM_ value. */
2745 /* 0 */
c45021f2
NC
2746 case EM_NONE: return _("None");
2747 case EM_M32: return "WE32100";
2748 case EM_SPARC: return "Sparc";
2749 case EM_386: return "Intel 80386";
2750 case EM_68K: return "MC68000";
2751 case EM_88K: return "MC88000";
22abe556 2752 case EM_IAMCU: return "Intel MCU";
fb70ec17 2753 case EM_860: return "Intel 80860";
c45021f2
NC
2754 case EM_MIPS: return "MIPS R3000";
2755 case EM_S370: return "IBM System/370";
55e22ca8 2756 /* 10 */
7036c0e1 2757 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2758 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2759 case EM_PARISC: return "HPPA";
55e22ca8 2760 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2761 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2762 case EM_960: return "Intel 80960";
c45021f2 2763 case EM_PPC: return "PowerPC";
55e22ca8 2764 /* 20 */
285d1771 2765 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2766 case EM_S390_OLD:
2767 case EM_S390: return "IBM S/390";
2768 case EM_SPU: return "SPU";
2769 /* 30 */
2770 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2771 case EM_FR20: return "Fujitsu FR20";
2772 case EM_RH32: return "TRW RH32";
b34976b6 2773 case EM_MCORE: return "MCORE";
55e22ca8 2774 /* 40 */
7036c0e1
AJ
2775 case EM_ARM: return "ARM";
2776 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2777 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2778 case EM_SPARCV9: return "Sparc v9";
2779 case EM_TRICORE: return "Siemens Tricore";
584da044 2780 case EM_ARC: return "ARC";
c2dcd04e
NC
2781 case EM_H8_300: return "Renesas H8/300";
2782 case EM_H8_300H: return "Renesas H8/300H";
2783 case EM_H8S: return "Renesas H8S";
2784 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2785 /* 50 */
30800947 2786 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2787 case EM_MIPS_X: return "Stanford MIPS-X";
2788 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2789 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2790 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2791 case EM_PCP: return "Siemens PCP";
2792 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2793 case EM_NDR1: return "Denso NDR1 microprocesspr";
2794 case EM_STARCORE: return "Motorola Star*Core processor";
2795 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2796 /* 60 */
7036c0e1
AJ
2797 case EM_ST100: return "STMicroelectronics ST100 processor";
2798 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2799 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2800 case EM_PDSP: return "Sony DSP processor";
2801 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2802 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2803 case EM_FX66: return "Siemens FX66 microcontroller";
2804 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2805 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2806 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2807 /* 70 */
7036c0e1
AJ
2808 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2809 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2810 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2811 case EM_SVX: return "Silicon Graphics SVx";
2812 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2813 case EM_VAX: return "Digital VAX";
1b61cf92 2814 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2815 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2816 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2817 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2818 /* 80 */
b34976b6 2819 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2820 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2821 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2822 case EM_AVR_OLD:
2823 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2824 case EM_CYGNUS_FR30:
2825 case EM_FR30: return "Fujitsu FR30";
2826 case EM_CYGNUS_D10V:
2827 case EM_D10V: return "d10v";
2828 case EM_CYGNUS_D30V:
2829 case EM_D30V: return "d30v";
2830 case EM_CYGNUS_V850:
2831 case EM_V850: return "Renesas V850";
2832 case EM_CYGNUS_M32R:
2833 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2834 case EM_CYGNUS_MN10300:
2835 case EM_MN10300: return "mn10300";
2836 /* 90 */
2837 case EM_CYGNUS_MN10200:
2838 case EM_MN10200: return "mn10200";
2839 case EM_PJ: return "picoJava";
73589c9d 2840 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2841 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2842 case EM_XTENSA_OLD:
2843 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2844 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2845 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2846 case EM_NS32K: return "National Semiconductor 32000 series";
2847 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2848 case EM_SNP1K: return "Trebia SNP 1000 processor";
2849 /* 100 */
9abca702 2850 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2851 case EM_IP2K_OLD:
2852 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2853 case EM_MAX: return "MAX Processor";
2854 case EM_CR: return "National Semiconductor CompactRISC";
2855 case EM_F2MC16: return "Fujitsu F2MC16";
2856 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2857 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2858 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2859 case EM_SEP: return "Sharp embedded microprocessor";
2860 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2861 /* 110 */
11636f9e
JM
2862 case EM_UNICORE: return "Unicore";
2863 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2864 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2865 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2866 case EM_CRX: return "National Semiconductor CRX microprocessor";
2867 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2868 case EM_C166:
d70c5fc7 2869 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2870 case EM_M16C: return "Renesas M16C series microprocessors";
2871 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2872 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2873 /* 120 */
2874 case EM_M32C: return "Renesas M32c";
2875 /* 130 */
11636f9e
JM
2876 case EM_TSK3000: return "Altium TSK3000 core";
2877 case EM_RS08: return "Freescale RS08 embedded processor";
2878 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2879 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2880 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2881 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2882 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2883 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2884 /* 140 */
11636f9e
JM
2885 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2886 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2887 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2888 case EM_TI_PRU: return "TI PRU I/O processor";
2889 /* 160 */
11636f9e
JM
2890 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2891 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2892 case EM_R32C: return "Renesas R32C series microprocessors";
2893 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2894 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2895 case EM_8051: return "Intel 8051 and variants";
2896 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2897 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2898 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2899 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2900 /* 170 */
11636f9e
JM
2901 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2902 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2903 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2904 case EM_RX: return "Renesas RX";
a3c62988 2905 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2906 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2907 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2908 case EM_CR16:
2909 case EM_MICROBLAZE:
2910 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2911 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2912 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2913 /* 180 */
2914 case EM_L1OM: return "Intel L1OM";
2915 case EM_K1OM: return "Intel K1OM";
2916 case EM_INTEL182: return "Intel (reserved)";
2917 case EM_AARCH64: return "AArch64";
2918 case EM_ARM184: return "ARM (reserved)";
2919 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2920 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2921 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2922 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2923 /* 190 */
11636f9e 2924 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2925 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2926 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2927 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2928 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2929 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2930 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2931 case EM_RL78: return "Renesas RL78";
6d913794 2932 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2933 case EM_78K0R: return "Renesas 78K0R";
2934 /* 200 */
6d913794 2935 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2936 case EM_BA1: return "Beyond BA1 CPU architecture";
2937 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2938 case EM_XCORE: return "XMOS xCORE processor family";
2939 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2940 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2941 /* 210 */
6d913794
NC
2942 case EM_KM32: return "KM211 KM32 32-bit processor";
2943 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2944 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2945 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2946 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2947 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2948 case EM_COGE: return "Cognitive Smart Memory Processor";
2949 case EM_COOL: return "Bluechip Systems CoolEngine";
2950 case EM_NORC: return "Nanoradio Optimized RISC";
2951 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2952 /* 220 */
15f205b1 2953 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2954 case EM_VISIUM: return "CDS VISIUMcore processor";
2955 case EM_FT32: return "FTDI Chip FT32";
2956 case EM_MOXIE: return "Moxie";
2957 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2958 /* 230 (all reserved) */
2959 /* 240 */
55e22ca8
NC
2960 case EM_RISCV: return "RISC-V";
2961 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2962 case EM_CEVA: return "CEVA Processor Architecture Family";
2963 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2964 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2965 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2966 case EM_IMG1: return "Imagination Technologies";
2967 /* 250 */
fe944acf 2968 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2969 case EM_VE: return "NEC Vector Engine";
2970 case EM_CSKY: return "C-SKY";
2971 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2972 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2973 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2974 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2975 case EM_65816: return "WDC 65816/65C816";
01a8c731 2976 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2977 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2978
2979 /* Large numbers... */
2980 case EM_MT: return "Morpho Techologies MT processor";
2981 case EM_ALPHA: return "Alpha";
2982 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2983 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2984 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2985 case EM_IQ2000: return "Vitesse IQ2000";
2986 case EM_M32C_OLD:
2987 case EM_NIOS32: return "Altera Nios";
2988 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2989 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2990 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2991 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2992
252b5132 2993 default:
35d9dd2f 2994 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2995 return buff;
2996 }
2997}
2998
a9522a21
AB
2999static void
3000decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
3001{
3002 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3003 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3004 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3005 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3006 architectures.
3007
3008 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3009 but also sets a specific architecture type in the e_flags field.
3010
3011 However, when decoding the flags we don't worry if we see an
3012 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3013 ARCEM architecture type. */
3014
3015 switch (e_flags & EF_ARC_MACH_MSK)
3016 {
3017 /* We only expect these to occur for EM_ARC_COMPACT2. */
3018 case EF_ARC_CPU_ARCV2EM:
3019 strcat (buf, ", ARC EM");
3020 break;
3021 case EF_ARC_CPU_ARCV2HS:
3022 strcat (buf, ", ARC HS");
3023 break;
3024
3025 /* We only expect these to occur for EM_ARC_COMPACT. */
3026 case E_ARC_MACH_ARC600:
3027 strcat (buf, ", ARC600");
3028 break;
3029 case E_ARC_MACH_ARC601:
3030 strcat (buf, ", ARC601");
3031 break;
3032 case E_ARC_MACH_ARC700:
3033 strcat (buf, ", ARC700");
3034 break;
3035
3036 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3037 new ELF with new architecture being read by an old version of
3038 readelf, or (c) An ELF built with non-GNU compiler that does not
3039 set the architecture in the e_flags. */
3040 default:
3041 if (e_machine == EM_ARC_COMPACT)
3042 strcat (buf, ", Unknown ARCompact");
3043 else
3044 strcat (buf, ", Unknown ARC");
3045 break;
3046 }
3047
3048 switch (e_flags & EF_ARC_OSABI_MSK)
3049 {
3050 case E_ARC_OSABI_ORIG:
3051 strcat (buf, ", (ABI:legacy)");
3052 break;
3053 case E_ARC_OSABI_V2:
3054 strcat (buf, ", (ABI:v2)");
3055 break;
3056 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3057 case E_ARC_OSABI_V3:
3058 strcat (buf, ", v3 no-legacy-syscalls ABI");
3059 break;
53a346d8
CZ
3060 case E_ARC_OSABI_V4:
3061 strcat (buf, ", v4 ABI");
3062 break;
a9522a21
AB
3063 default:
3064 strcat (buf, ", unrecognised ARC OSABI flag");
3065 break;
3066 }
3067}
3068
f3485b74 3069static void
d3ba0551 3070decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
3071{
3072 unsigned eabi;
015dc7e1 3073 bool unknown = false;
f3485b74
NC
3074
3075 eabi = EF_ARM_EABI_VERSION (e_flags);
3076 e_flags &= ~ EF_ARM_EABIMASK;
3077
3078 /* Handle "generic" ARM flags. */
3079 if (e_flags & EF_ARM_RELEXEC)
3080 {
3081 strcat (buf, ", relocatable executable");
3082 e_flags &= ~ EF_ARM_RELEXEC;
3083 }
76da6bbe 3084
18a20338
CL
3085 if (e_flags & EF_ARM_PIC)
3086 {
3087 strcat (buf, ", position independent");
3088 e_flags &= ~ EF_ARM_PIC;
3089 }
3090
f3485b74
NC
3091 /* Now handle EABI specific flags. */
3092 switch (eabi)
3093 {
3094 default:
2c71103e 3095 strcat (buf, ", <unrecognized EABI>");
f3485b74 3096 if (e_flags)
015dc7e1 3097 unknown = true;
f3485b74
NC
3098 break;
3099
3100 case EF_ARM_EABI_VER1:
a5bcd848 3101 strcat (buf, ", Version1 EABI");
f3485b74
NC
3102 while (e_flags)
3103 {
3104 unsigned flag;
76da6bbe 3105
f3485b74
NC
3106 /* Process flags one bit at a time. */
3107 flag = e_flags & - e_flags;
3108 e_flags &= ~ flag;
76da6bbe 3109
f3485b74
NC
3110 switch (flag)
3111 {
a5bcd848 3112 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
3113 strcat (buf, ", sorted symbol tables");
3114 break;
76da6bbe 3115
f3485b74 3116 default:
015dc7e1 3117 unknown = true;
f3485b74
NC
3118 break;
3119 }
3120 }
3121 break;
76da6bbe 3122
a5bcd848
PB
3123 case EF_ARM_EABI_VER2:
3124 strcat (buf, ", Version2 EABI");
3125 while (e_flags)
3126 {
3127 unsigned flag;
3128
3129 /* Process flags one bit at a time. */
3130 flag = e_flags & - e_flags;
3131 e_flags &= ~ flag;
3132
3133 switch (flag)
3134 {
3135 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3136 strcat (buf, ", sorted symbol tables");
3137 break;
3138
3139 case EF_ARM_DYNSYMSUSESEGIDX:
3140 strcat (buf, ", dynamic symbols use segment index");
3141 break;
3142
3143 case EF_ARM_MAPSYMSFIRST:
3144 strcat (buf, ", mapping symbols precede others");
3145 break;
3146
3147 default:
015dc7e1 3148 unknown = true;
a5bcd848
PB
3149 break;
3150 }
3151 }
3152 break;
3153
d507cf36
PB
3154 case EF_ARM_EABI_VER3:
3155 strcat (buf, ", Version3 EABI");
8cb51566
PB
3156 break;
3157
3158 case EF_ARM_EABI_VER4:
3159 strcat (buf, ", Version4 EABI");
3bfcb652
NC
3160 while (e_flags)
3161 {
3162 unsigned flag;
3163
3164 /* Process flags one bit at a time. */
3165 flag = e_flags & - e_flags;
3166 e_flags &= ~ flag;
3167
3168 switch (flag)
3169 {
3170 case EF_ARM_BE8:
3171 strcat (buf, ", BE8");
3172 break;
3173
3174 case EF_ARM_LE8:
3175 strcat (buf, ", LE8");
3176 break;
3177
3178 default:
015dc7e1 3179 unknown = true;
3bfcb652
NC
3180 break;
3181 }
3bfcb652
NC
3182 }
3183 break;
3a4a14e9
PB
3184
3185 case EF_ARM_EABI_VER5:
3186 strcat (buf, ", Version5 EABI");
d507cf36
PB
3187 while (e_flags)
3188 {
3189 unsigned flag;
3190
3191 /* Process flags one bit at a time. */
3192 flag = e_flags & - e_flags;
3193 e_flags &= ~ flag;
3194
3195 switch (flag)
3196 {
3197 case EF_ARM_BE8:
3198 strcat (buf, ", BE8");
3199 break;
3200
3201 case EF_ARM_LE8:
3202 strcat (buf, ", LE8");
3203 break;
3204
3bfcb652
NC
3205 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3206 strcat (buf, ", soft-float ABI");
3207 break;
3208
3209 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3210 strcat (buf, ", hard-float ABI");
3211 break;
3212
d507cf36 3213 default:
015dc7e1 3214 unknown = true;
d507cf36
PB
3215 break;
3216 }
3217 }
3218 break;
3219
f3485b74 3220 case EF_ARM_EABI_UNKNOWN:
a5bcd848 3221 strcat (buf, ", GNU EABI");
f3485b74
NC
3222 while (e_flags)
3223 {
3224 unsigned flag;
76da6bbe 3225
f3485b74
NC
3226 /* Process flags one bit at a time. */
3227 flag = e_flags & - e_flags;
3228 e_flags &= ~ flag;
76da6bbe 3229
f3485b74
NC
3230 switch (flag)
3231 {
a5bcd848 3232 case EF_ARM_INTERWORK:
f3485b74
NC
3233 strcat (buf, ", interworking enabled");
3234 break;
76da6bbe 3235
a5bcd848 3236 case EF_ARM_APCS_26:
f3485b74
NC
3237 strcat (buf, ", uses APCS/26");
3238 break;
76da6bbe 3239
a5bcd848 3240 case EF_ARM_APCS_FLOAT:
f3485b74
NC
3241 strcat (buf, ", uses APCS/float");
3242 break;
76da6bbe 3243
a5bcd848 3244 case EF_ARM_PIC:
f3485b74
NC
3245 strcat (buf, ", position independent");
3246 break;
76da6bbe 3247
a5bcd848 3248 case EF_ARM_ALIGN8:
f3485b74
NC
3249 strcat (buf, ", 8 bit structure alignment");
3250 break;
76da6bbe 3251
a5bcd848 3252 case EF_ARM_NEW_ABI:
f3485b74
NC
3253 strcat (buf, ", uses new ABI");
3254 break;
76da6bbe 3255
a5bcd848 3256 case EF_ARM_OLD_ABI:
f3485b74
NC
3257 strcat (buf, ", uses old ABI");
3258 break;
76da6bbe 3259
a5bcd848 3260 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
3261 strcat (buf, ", software FP");
3262 break;
76da6bbe 3263
90e01f86
ILT
3264 case EF_ARM_VFP_FLOAT:
3265 strcat (buf, ", VFP");
3266 break;
3267
fde78edd
NC
3268 case EF_ARM_MAVERICK_FLOAT:
3269 strcat (buf, ", Maverick FP");
3270 break;
3271
f3485b74 3272 default:
015dc7e1 3273 unknown = true;
f3485b74
NC
3274 break;
3275 }
3276 }
3277 }
f3485b74
NC
3278
3279 if (unknown)
2b692964 3280 strcat (buf,_(", <unknown>"));
f3485b74
NC
3281}
3282
343433df
AB
3283static void
3284decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
3285{
3286 --size; /* Leave space for null terminator. */
3287
3288 switch (e_flags & EF_AVR_MACH)
3289 {
3290 case E_AVR_MACH_AVR1:
3291 strncat (buf, ", avr:1", size);
3292 break;
3293 case E_AVR_MACH_AVR2:
3294 strncat (buf, ", avr:2", size);
3295 break;
3296 case E_AVR_MACH_AVR25:
3297 strncat (buf, ", avr:25", size);
3298 break;
3299 case E_AVR_MACH_AVR3:
3300 strncat (buf, ", avr:3", size);
3301 break;
3302 case E_AVR_MACH_AVR31:
3303 strncat (buf, ", avr:31", size);
3304 break;
3305 case E_AVR_MACH_AVR35:
3306 strncat (buf, ", avr:35", size);
3307 break;
3308 case E_AVR_MACH_AVR4:
3309 strncat (buf, ", avr:4", size);
3310 break;
3311 case E_AVR_MACH_AVR5:
3312 strncat (buf, ", avr:5", size);
3313 break;
3314 case E_AVR_MACH_AVR51:
3315 strncat (buf, ", avr:51", size);
3316 break;
3317 case E_AVR_MACH_AVR6:
3318 strncat (buf, ", avr:6", size);
3319 break;
3320 case E_AVR_MACH_AVRTINY:
3321 strncat (buf, ", avr:100", size);
3322 break;
3323 case E_AVR_MACH_XMEGA1:
3324 strncat (buf, ", avr:101", size);
3325 break;
3326 case E_AVR_MACH_XMEGA2:
3327 strncat (buf, ", avr:102", size);
3328 break;
3329 case E_AVR_MACH_XMEGA3:
3330 strncat (buf, ", avr:103", size);
3331 break;
3332 case E_AVR_MACH_XMEGA4:
3333 strncat (buf, ", avr:104", size);
3334 break;
3335 case E_AVR_MACH_XMEGA5:
3336 strncat (buf, ", avr:105", size);
3337 break;
3338 case E_AVR_MACH_XMEGA6:
3339 strncat (buf, ", avr:106", size);
3340 break;
3341 case E_AVR_MACH_XMEGA7:
3342 strncat (buf, ", avr:107", size);
3343 break;
3344 default:
3345 strncat (buf, ", avr:<unknown>", size);
3346 break;
3347 }
3348
3349 size -= strlen (buf);
3350 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3351 strncat (buf, ", link-relax", size);
3352}
3353
35c08157
KLC
3354static void
3355decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
3356{
3357 unsigned abi;
3358 unsigned arch;
3359 unsigned config;
3360 unsigned version;
015dc7e1 3361 bool has_fpu = false;
32ec8896 3362 unsigned int r = 0;
35c08157
KLC
3363
3364 static const char *ABI_STRINGS[] =
3365 {
3366 "ABI v0", /* use r5 as return register; only used in N1213HC */
3367 "ABI v1", /* use r0 as return register */
3368 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3369 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3370 "AABI",
3371 "ABI2 FP+"
35c08157
KLC
3372 };
3373 static const char *VER_STRINGS[] =
3374 {
3375 "Andes ELF V1.3 or older",
3376 "Andes ELF V1.3.1",
3377 "Andes ELF V1.4"
3378 };
3379 static const char *ARCH_STRINGS[] =
3380 {
3381 "",
3382 "Andes Star v1.0",
3383 "Andes Star v2.0",
3384 "Andes Star v3.0",
3385 "Andes Star v3.0m"
3386 };
3387
3388 abi = EF_NDS_ABI & e_flags;
3389 arch = EF_NDS_ARCH & e_flags;
3390 config = EF_NDS_INST & e_flags;
3391 version = EF_NDS32_ELF_VERSION & e_flags;
3392
3393 memset (buf, 0, size);
3394
3395 switch (abi)
3396 {
3397 case E_NDS_ABI_V0:
3398 case E_NDS_ABI_V1:
3399 case E_NDS_ABI_V2:
3400 case E_NDS_ABI_V2FP:
3401 case E_NDS_ABI_AABI:
40c7a7cb 3402 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3403 /* In case there are holes in the array. */
3404 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3405 break;
3406
3407 default:
3408 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3409 break;
3410 }
3411
3412 switch (version)
3413 {
3414 case E_NDS32_ELF_VER_1_2:
3415 case E_NDS32_ELF_VER_1_3:
3416 case E_NDS32_ELF_VER_1_4:
3417 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3418 break;
3419
3420 default:
3421 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3422 break;
3423 }
3424
3425 if (E_NDS_ABI_V0 == abi)
3426 {
3427 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3428 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3429 if (arch == E_NDS_ARCH_STAR_V1_0)
3430 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3431 return;
3432 }
3433
3434 switch (arch)
3435 {
3436 case E_NDS_ARCH_STAR_V1_0:
3437 case E_NDS_ARCH_STAR_V2_0:
3438 case E_NDS_ARCH_STAR_V3_0:
3439 case E_NDS_ARCH_STAR_V3_M:
3440 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3441 break;
3442
3443 default:
3444 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3445 /* ARCH version determines how the e_flags are interpreted.
3446 If it is unknown, we cannot proceed. */
3447 return;
3448 }
3449
3450 /* Newer ABI; Now handle architecture specific flags. */
3451 if (arch == E_NDS_ARCH_STAR_V1_0)
3452 {
3453 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3454 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3455
3456 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3457 r += snprintf (buf + r, size -r, ", MAC");
3458
3459 if (config & E_NDS32_HAS_DIV_INST)
3460 r += snprintf (buf + r, size -r, ", DIV");
3461
3462 if (config & E_NDS32_HAS_16BIT_INST)
3463 r += snprintf (buf + r, size -r, ", 16b");
3464 }
3465 else
3466 {
3467 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3468 {
3469 if (version <= E_NDS32_ELF_VER_1_3)
3470 r += snprintf (buf + r, size -r, ", [B8]");
3471 else
3472 r += snprintf (buf + r, size -r, ", EX9");
3473 }
3474
3475 if (config & E_NDS32_HAS_MAC_DX_INST)
3476 r += snprintf (buf + r, size -r, ", MAC_DX");
3477
3478 if (config & E_NDS32_HAS_DIV_DX_INST)
3479 r += snprintf (buf + r, size -r, ", DIV_DX");
3480
3481 if (config & E_NDS32_HAS_16BIT_INST)
3482 {
3483 if (version <= E_NDS32_ELF_VER_1_3)
3484 r += snprintf (buf + r, size -r, ", 16b");
3485 else
3486 r += snprintf (buf + r, size -r, ", IFC");
3487 }
3488 }
3489
3490 if (config & E_NDS32_HAS_EXT_INST)
3491 r += snprintf (buf + r, size -r, ", PERF1");
3492
3493 if (config & E_NDS32_HAS_EXT2_INST)
3494 r += snprintf (buf + r, size -r, ", PERF2");
3495
3496 if (config & E_NDS32_HAS_FPU_INST)
3497 {
015dc7e1 3498 has_fpu = true;
35c08157
KLC
3499 r += snprintf (buf + r, size -r, ", FPU_SP");
3500 }
3501
3502 if (config & E_NDS32_HAS_FPU_DP_INST)
3503 {
015dc7e1 3504 has_fpu = true;
35c08157
KLC
3505 r += snprintf (buf + r, size -r, ", FPU_DP");
3506 }
3507
3508 if (config & E_NDS32_HAS_FPU_MAC_INST)
3509 {
015dc7e1 3510 has_fpu = true;
35c08157
KLC
3511 r += snprintf (buf + r, size -r, ", FPU_MAC");
3512 }
3513
3514 if (has_fpu)
3515 {
3516 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3517 {
3518 case E_NDS32_FPU_REG_8SP_4DP:
3519 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3520 break;
3521 case E_NDS32_FPU_REG_16SP_8DP:
3522 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3523 break;
3524 case E_NDS32_FPU_REG_32SP_16DP:
3525 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3526 break;
3527 case E_NDS32_FPU_REG_32SP_32DP:
3528 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3529 break;
3530 }
3531 }
3532
3533 if (config & E_NDS32_HAS_AUDIO_INST)
3534 r += snprintf (buf + r, size -r, ", AUDIO");
3535
3536 if (config & E_NDS32_HAS_STRING_INST)
3537 r += snprintf (buf + r, size -r, ", STR");
3538
3539 if (config & E_NDS32_HAS_REDUCED_REGS)
3540 r += snprintf (buf + r, size -r, ", 16REG");
3541
3542 if (config & E_NDS32_HAS_VIDEO_INST)
3543 {
3544 if (version <= E_NDS32_ELF_VER_1_3)
3545 r += snprintf (buf + r, size -r, ", VIDEO");
3546 else
3547 r += snprintf (buf + r, size -r, ", SATURATION");
3548 }
3549
3550 if (config & E_NDS32_HAS_ENCRIPT_INST)
3551 r += snprintf (buf + r, size -r, ", ENCRP");
3552
3553 if (config & E_NDS32_HAS_L2C_INST)
3554 r += snprintf (buf + r, size -r, ", L2C");
3555}
3556
c077c580
SM
3557static void
3558decode_AMDGPU_machine_flags (Filedata *filedata, unsigned int e_flags,
3559 char *buf)
3560{
3561 unsigned char *e_ident = filedata->file_header.e_ident;
3562 unsigned char osabi = e_ident[EI_OSABI];
3563 unsigned char abiversion = e_ident[EI_ABIVERSION];
3564 unsigned int mach;
3565
3566 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
3567 it has been deprecated for a while.
3568
3569 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
3570 of writing, they use the same flags as HSA v3, so the code below uses that
3571 assumption. */
3572 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
3573 return;
3574
3575 mach = e_flags & EF_AMDGPU_MACH;
3576 switch (mach)
3577 {
3578#define AMDGPU_CASE(code, string) \
3579 case code: strcat (buf, ", " string); break;
3580 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
3581 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
3582 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
3583 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
3584 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
3585 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
3586 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
3587 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
3588 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
3589 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
3590 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
3591 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
3592 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
3593 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
3594 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
3595 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
3596 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
3597 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
3598 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
3599 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
3600 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
3601 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
3602 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
3603 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
3604 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
3605 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
3606 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
3607 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
3608 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
3609 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
3610 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
3611 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
3612 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
3613 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
3614 default:
3615 sprintf (buf, _(", <unknown AMDGPU GPU type: %#x>"), mach);
3616 break;
3617#undef AMDGPU_CASE
3618 }
3619
3620 buf += strlen (buf);
3621 e_flags &= ~EF_AMDGPU_MACH;
3622
3623 if ((osabi == ELFOSABI_AMDGPU_HSA
3624 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
3625 || osabi != ELFOSABI_AMDGPU_HSA)
3626 {
3627 /* For HSA v3 and other OS ABIs. */
3628 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
3629 {
3630 strcat (buf, ", xnack on");
3631 buf += strlen (buf);
3632 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
3633 }
3634
3635 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
3636 {
3637 strcat (buf, ", sramecc on");
3638 buf += strlen (buf);
3639 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
3640 }
3641 }
3642 else
3643 {
3644 /* For HSA v4+. */
3645 int xnack, sramecc;
3646
3647 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
3648 switch (xnack)
3649 {
3650 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
3651 break;
3652
3653 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
3654 strcat (buf, ", xnack any");
3655 break;
3656
3657 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
3658 strcat (buf, ", xnack off");
3659 break;
3660
3661 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
3662 strcat (buf, ", xnack on");
3663 break;
3664
3665 default:
3666 sprintf (buf, _(", <unknown xnack value: %#x>"), xnack);
3667 break;
3668 }
3669
3670 buf += strlen (buf);
3671 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
3672
3673 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
3674 switch (sramecc)
3675 {
3676 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
3677 break;
3678
3679 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
3680 strcat (buf, ", sramecc any");
3681 break;
3682
3683 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
3684 strcat (buf, ", sramecc off");
3685 break;
3686
3687 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
3688 strcat (buf, ", sramecc on");
3689 break;
3690
3691 default:
3692 sprintf (buf, _(", <unknown sramecc value: %#x>"), sramecc);
3693 break;
3694 }
3695
3696 buf += strlen (buf);
3697 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
3698 }
3699
3700 if (e_flags != 0)
3701 sprintf (buf, _(", unknown flags bits: %#x"), e_flags);
3702}
3703
252b5132 3704static char *
dda8d76d 3705get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3706{
b34976b6 3707 static char buf[1024];
252b5132
RH
3708
3709 buf[0] = '\0';
76da6bbe 3710
252b5132
RH
3711 if (e_flags)
3712 {
3713 switch (e_machine)
3714 {
3715 default:
3716 break;
3717
886a2506 3718 case EM_ARC_COMPACT2:
886a2506 3719 case EM_ARC_COMPACT:
a9522a21
AB
3720 decode_ARC_machine_flags (e_flags, e_machine, buf);
3721 break;
886a2506 3722
f3485b74
NC
3723 case EM_ARM:
3724 decode_ARM_machine_flags (e_flags, buf);
3725 break;
76da6bbe 3726
343433df
AB
3727 case EM_AVR:
3728 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3729 break;
3730
781303ce
MF
3731 case EM_BLACKFIN:
3732 if (e_flags & EF_BFIN_PIC)
3733 strcat (buf, ", PIC");
3734
3735 if (e_flags & EF_BFIN_FDPIC)
3736 strcat (buf, ", FDPIC");
3737
3738 if (e_flags & EF_BFIN_CODE_IN_L1)
3739 strcat (buf, ", code in L1");
3740
3741 if (e_flags & EF_BFIN_DATA_IN_L1)
3742 strcat (buf, ", data in L1");
3743
3744 break;
3745
ec2dfb42
AO
3746 case EM_CYGNUS_FRV:
3747 switch (e_flags & EF_FRV_CPU_MASK)
3748 {
3749 case EF_FRV_CPU_GENERIC:
3750 break;
3751
3752 default:
3753 strcat (buf, ", fr???");
3754 break;
57346661 3755
ec2dfb42
AO
3756 case EF_FRV_CPU_FR300:
3757 strcat (buf, ", fr300");
3758 break;
3759
3760 case EF_FRV_CPU_FR400:
3761 strcat (buf, ", fr400");
3762 break;
3763 case EF_FRV_CPU_FR405:
3764 strcat (buf, ", fr405");
3765 break;
3766
3767 case EF_FRV_CPU_FR450:
3768 strcat (buf, ", fr450");
3769 break;
3770
3771 case EF_FRV_CPU_FR500:
3772 strcat (buf, ", fr500");
3773 break;
3774 case EF_FRV_CPU_FR550:
3775 strcat (buf, ", fr550");
3776 break;
3777
3778 case EF_FRV_CPU_SIMPLE:
3779 strcat (buf, ", simple");
3780 break;
3781 case EF_FRV_CPU_TOMCAT:
3782 strcat (buf, ", tomcat");
3783 break;
3784 }
1c877e87 3785 break;
ec2dfb42 3786
53c7db4b 3787 case EM_68K:
425c6cb0 3788 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3789 strcat (buf, ", m68000");
425c6cb0 3790 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3791 strcat (buf, ", cpu32");
3792 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3793 strcat (buf, ", fido_a");
425c6cb0 3794 else
266abb8f 3795 {
2cf0635d
NC
3796 char const * isa = _("unknown");
3797 char const * mac = _("unknown mac");
3798 char const * additional = NULL;
0112cd26 3799
c694fd50 3800 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3801 {
c694fd50 3802 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3803 isa = "A";
3804 additional = ", nodiv";
3805 break;
c694fd50 3806 case EF_M68K_CF_ISA_A:
266abb8f
NS
3807 isa = "A";
3808 break;
c694fd50 3809 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3810 isa = "A+";
3811 break;
c694fd50 3812 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3813 isa = "B";
3814 additional = ", nousp";
3815 break;
c694fd50 3816 case EF_M68K_CF_ISA_B:
266abb8f
NS
3817 isa = "B";
3818 break;
f608cd77
NS
3819 case EF_M68K_CF_ISA_C:
3820 isa = "C";
3821 break;
3822 case EF_M68K_CF_ISA_C_NODIV:
3823 isa = "C";
3824 additional = ", nodiv";
3825 break;
266abb8f
NS
3826 }
3827 strcat (buf, ", cf, isa ");
3828 strcat (buf, isa);
0b2e31dc
NS
3829 if (additional)
3830 strcat (buf, additional);
c694fd50 3831 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3832 strcat (buf, ", float");
c694fd50 3833 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3834 {
3835 case 0:
3836 mac = NULL;
3837 break;
c694fd50 3838 case EF_M68K_CF_MAC:
266abb8f
NS
3839 mac = "mac";
3840 break;
c694fd50 3841 case EF_M68K_CF_EMAC:
266abb8f
NS
3842 mac = "emac";
3843 break;
f608cd77
NS
3844 case EF_M68K_CF_EMAC_B:
3845 mac = "emac_b";
3846 break;
266abb8f
NS
3847 }
3848 if (mac)
3849 {
3850 strcat (buf, ", ");
3851 strcat (buf, mac);
3852 }
266abb8f 3853 }
53c7db4b 3854 break;
33c63f9d 3855
c077c580
SM
3856 case EM_AMDGPU:
3857 decode_AMDGPU_machine_flags (filedata, e_flags, buf);
3858 break;
3859
153a2776
NC
3860 case EM_CYGNUS_MEP:
3861 switch (e_flags & EF_MEP_CPU_MASK)
3862 {
3863 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3864 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3865 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3866 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3867 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3868 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3869 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3870 }
3871
3872 switch (e_flags & EF_MEP_COP_MASK)
3873 {
3874 case EF_MEP_COP_NONE: break;
3875 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3876 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3877 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3878 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3879 default: strcat (buf, _("<unknown MeP copro type>")); break;
3880 }
3881
3882 if (e_flags & EF_MEP_LIBRARY)
3883 strcat (buf, ", Built for Library");
3884
3885 if (e_flags & EF_MEP_INDEX_MASK)
3886 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3887 e_flags & EF_MEP_INDEX_MASK);
3888
3889 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3890 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3891 e_flags & ~ EF_MEP_ALL_FLAGS);
3892 break;
3893
252b5132
RH
3894 case EM_PPC:
3895 if (e_flags & EF_PPC_EMB)
3896 strcat (buf, ", emb");
3897
3898 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3899 strcat (buf, _(", relocatable"));
252b5132
RH
3900
3901 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3902 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3903 break;
3904
ee67d69a
AM
3905 case EM_PPC64:
3906 if (e_flags & EF_PPC64_ABI)
3907 {
3908 char abi[] = ", abiv0";
3909
3910 abi[6] += e_flags & EF_PPC64_ABI;
3911 strcat (buf, abi);
3912 }
3913 break;
3914
708e2187
NC
3915 case EM_V800:
3916 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3917 strcat (buf, ", RH850 ABI");
0b4362b0 3918
708e2187
NC
3919 if (e_flags & EF_V800_850E3)
3920 strcat (buf, ", V3 architecture");
3921
3922 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3923 strcat (buf, ", FPU not used");
3924
3925 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3926 strcat (buf, ", regmode: COMMON");
3927
3928 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3929 strcat (buf, ", r4 not used");
3930
3931 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3932 strcat (buf, ", r30 not used");
3933
3934 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3935 strcat (buf, ", r5 not used");
3936
3937 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3938 strcat (buf, ", r2 not used");
3939
3940 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3941 {
3942 switch (e_flags & - e_flags)
3943 {
3944 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3945 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3946 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3947 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3948 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3949 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3950 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3951 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3952 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3953 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3954 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3955 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3956 default: break;
3957 }
3958 }
3959 break;
3960
2b0337b0 3961 case EM_V850:
252b5132
RH
3962 case EM_CYGNUS_V850:
3963 switch (e_flags & EF_V850_ARCH)
3964 {
78c8d46c
NC
3965 case E_V850E3V5_ARCH:
3966 strcat (buf, ", v850e3v5");
3967 break;
1cd986c5
NC
3968 case E_V850E2V3_ARCH:
3969 strcat (buf, ", v850e2v3");
3970 break;
3971 case E_V850E2_ARCH:
3972 strcat (buf, ", v850e2");
3973 break;
3974 case E_V850E1_ARCH:
3975 strcat (buf, ", v850e1");
8ad30312 3976 break;
252b5132
RH
3977 case E_V850E_ARCH:
3978 strcat (buf, ", v850e");
3979 break;
252b5132
RH
3980 case E_V850_ARCH:
3981 strcat (buf, ", v850");
3982 break;
3983 default:
2b692964 3984 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3985 break;
3986 }
3987 break;
3988
2b0337b0 3989 case EM_M32R:
252b5132
RH
3990 case EM_CYGNUS_M32R:
3991 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3992 strcat (buf, ", m32r");
252b5132
RH
3993 break;
3994
3995 case EM_MIPS:
4fe85591 3996 case EM_MIPS_RS3_LE:
252b5132
RH
3997 if (e_flags & EF_MIPS_NOREORDER)
3998 strcat (buf, ", noreorder");
3999
4000 if (e_flags & EF_MIPS_PIC)
4001 strcat (buf, ", pic");
4002
4003 if (e_flags & EF_MIPS_CPIC)
4004 strcat (buf, ", cpic");
4005
d1bdd336
TS
4006 if (e_flags & EF_MIPS_UCODE)
4007 strcat (buf, ", ugen_reserved");
4008
252b5132
RH
4009 if (e_flags & EF_MIPS_ABI2)
4010 strcat (buf, ", abi2");
4011
43521d43
TS
4012 if (e_flags & EF_MIPS_OPTIONS_FIRST)
4013 strcat (buf, ", odk first");
4014
a5d22d2a
TS
4015 if (e_flags & EF_MIPS_32BITMODE)
4016 strcat (buf, ", 32bitmode");
4017
ba92f887
MR
4018 if (e_flags & EF_MIPS_NAN2008)
4019 strcat (buf, ", nan2008");
4020
fef1b0b3
SE
4021 if (e_flags & EF_MIPS_FP64)
4022 strcat (buf, ", fp64");
4023
156c2f8b
NC
4024 switch ((e_flags & EF_MIPS_MACH))
4025 {
4026 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
4027 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
4028 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 4029 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
4030 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
4031 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
4032 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
4033 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 4034 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 4035 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 4036 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
4037 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
4038 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 4039 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 4040 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 4041 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 4042 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 4043 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 4044 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 4045 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 4046 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
4047 case 0:
4048 /* We simply ignore the field in this case to avoid confusion:
4049 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4050 extension. */
4051 break;
2b692964 4052 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 4053 }
43521d43
TS
4054
4055 switch ((e_flags & EF_MIPS_ABI))
4056 {
4057 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
4058 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
4059 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
4060 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
4061 case 0:
4062 /* We simply ignore the field in this case to avoid confusion:
4063 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4064 This means it is likely to be an o32 file, but not for
4065 sure. */
4066 break;
2b692964 4067 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
4068 }
4069
4070 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4071 strcat (buf, ", mdmx");
4072
4073 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4074 strcat (buf, ", mips16");
4075
df58fc94
RS
4076 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4077 strcat (buf, ", micromips");
4078
43521d43
TS
4079 switch ((e_flags & EF_MIPS_ARCH))
4080 {
4081 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
4082 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
4083 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
4084 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
4085 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
4086 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 4087 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 4088 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 4089 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 4090 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 4091 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 4092 default: strcat (buf, _(", unknown ISA")); break;
43521d43 4093 }
252b5132 4094 break;
351b4b40 4095
35c08157
KLC
4096 case EM_NDS32:
4097 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
4098 break;
4099
fe944acf
FT
4100 case EM_NFP:
4101 switch (EF_NFP_MACH (e_flags))
4102 {
4103 case E_NFP_MACH_3200:
4104 strcat (buf, ", NFP-32xx");
4105 break;
4106 case E_NFP_MACH_6000:
4107 strcat (buf, ", NFP-6xxx");
4108 break;
4109 }
4110 break;
4111
e23eba97
NC
4112 case EM_RISCV:
4113 if (e_flags & EF_RISCV_RVC)
4114 strcat (buf, ", RVC");
2922d21d 4115
7f999549
JW
4116 if (e_flags & EF_RISCV_RVE)
4117 strcat (buf, ", RVE");
4118
96462b01
S
4119 if (e_flags & EF_RISCV_TSO)
4120 strcat (buf, ", TSO");
4121
2922d21d
AW
4122 switch (e_flags & EF_RISCV_FLOAT_ABI)
4123 {
4124 case EF_RISCV_FLOAT_ABI_SOFT:
4125 strcat (buf, ", soft-float ABI");
4126 break;
4127
4128 case EF_RISCV_FLOAT_ABI_SINGLE:
4129 strcat (buf, ", single-float ABI");
4130 break;
4131
4132 case EF_RISCV_FLOAT_ABI_DOUBLE:
4133 strcat (buf, ", double-float ABI");
4134 break;
4135
4136 case EF_RISCV_FLOAT_ABI_QUAD:
4137 strcat (buf, ", quad-float ABI");
4138 break;
4139 }
e23eba97
NC
4140 break;
4141
ccde1100
AO
4142 case EM_SH:
4143 switch ((e_flags & EF_SH_MACH_MASK))
4144 {
4145 case EF_SH1: strcat (buf, ", sh1"); break;
4146 case EF_SH2: strcat (buf, ", sh2"); break;
4147 case EF_SH3: strcat (buf, ", sh3"); break;
4148 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
4149 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
4150 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
4151 case EF_SH3E: strcat (buf, ", sh3e"); break;
4152 case EF_SH4: strcat (buf, ", sh4"); break;
4153 case EF_SH5: strcat (buf, ", sh5"); break;
4154 case EF_SH2E: strcat (buf, ", sh2e"); break;
4155 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 4156 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
4157 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
4158 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 4159 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
4160 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
4161 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
4162 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
4163 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
4164 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
4165 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 4166 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
4167 }
4168
cec6a5b8
MR
4169 if (e_flags & EF_SH_PIC)
4170 strcat (buf, ", pic");
4171
4172 if (e_flags & EF_SH_FDPIC)
4173 strcat (buf, ", fdpic");
ccde1100 4174 break;
948f632f 4175
73589c9d
CS
4176 case EM_OR1K:
4177 if (e_flags & EF_OR1K_NODELAY)
4178 strcat (buf, ", no delay");
4179 break;
57346661 4180
351b4b40
RH
4181 case EM_SPARCV9:
4182 if (e_flags & EF_SPARC_32PLUS)
4183 strcat (buf, ", v8+");
4184
4185 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
4186 strcat (buf, ", ultrasparcI");
4187
4188 if (e_flags & EF_SPARC_SUN_US3)
4189 strcat (buf, ", ultrasparcIII");
351b4b40
RH
4190
4191 if (e_flags & EF_SPARC_HAL_R1)
4192 strcat (buf, ", halr1");
4193
4194 if (e_flags & EF_SPARC_LEDATA)
4195 strcat (buf, ", ledata");
4196
4197 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4198 strcat (buf, ", tso");
4199
4200 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4201 strcat (buf, ", pso");
4202
4203 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4204 strcat (buf, ", rmo");
4205 break;
7d466069 4206
103f02d3
UD
4207 case EM_PARISC:
4208 switch (e_flags & EF_PARISC_ARCH)
4209 {
4210 case EFA_PARISC_1_0:
4211 strcpy (buf, ", PA-RISC 1.0");
4212 break;
4213 case EFA_PARISC_1_1:
4214 strcpy (buf, ", PA-RISC 1.1");
4215 break;
4216 case EFA_PARISC_2_0:
4217 strcpy (buf, ", PA-RISC 2.0");
4218 break;
4219 default:
4220 break;
4221 }
4222 if (e_flags & EF_PARISC_TRAPNIL)
4223 strcat (buf, ", trapnil");
4224 if (e_flags & EF_PARISC_EXT)
4225 strcat (buf, ", ext");
4226 if (e_flags & EF_PARISC_LSB)
4227 strcat (buf, ", lsb");
4228 if (e_flags & EF_PARISC_WIDE)
4229 strcat (buf, ", wide");
4230 if (e_flags & EF_PARISC_NO_KABP)
4231 strcat (buf, ", no kabp");
4232 if (e_flags & EF_PARISC_LAZYSWAP)
4233 strcat (buf, ", lazyswap");
30800947 4234 break;
76da6bbe 4235
7d466069 4236 case EM_PJ:
2b0337b0 4237 case EM_PJ_OLD:
7d466069
ILT
4238 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4239 strcat (buf, ", new calling convention");
4240
4241 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4242 strcat (buf, ", gnu calling convention");
4243 break;
4d6ed7c8
NC
4244
4245 case EM_IA_64:
4246 if ((e_flags & EF_IA_64_ABI64))
4247 strcat (buf, ", 64-bit");
4248 else
4249 strcat (buf, ", 32-bit");
4250 if ((e_flags & EF_IA_64_REDUCEDFP))
4251 strcat (buf, ", reduced fp model");
4252 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4253 strcat (buf, ", no function descriptors, constant gp");
4254 else if ((e_flags & EF_IA_64_CONS_GP))
4255 strcat (buf, ", constant gp");
4256 if ((e_flags & EF_IA_64_ABSOLUTE))
4257 strcat (buf, ", absolute");
dda8d76d 4258 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
4259 {
4260 if ((e_flags & EF_IA_64_VMS_LINKAGES))
4261 strcat (buf, ", vms_linkages");
4262 switch ((e_flags & EF_IA_64_VMS_COMCOD))
4263 {
4264 case EF_IA_64_VMS_COMCOD_SUCCESS:
4265 break;
4266 case EF_IA_64_VMS_COMCOD_WARNING:
4267 strcat (buf, ", warning");
4268 break;
4269 case EF_IA_64_VMS_COMCOD_ERROR:
4270 strcat (buf, ", error");
4271 break;
4272 case EF_IA_64_VMS_COMCOD_ABORT:
4273 strcat (buf, ", abort");
4274 break;
4275 default:
bee0ee85
NC
4276 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
4277 e_flags & EF_IA_64_VMS_COMCOD);
4278 strcat (buf, ", <unknown>");
28f997cf
TG
4279 }
4280 }
4d6ed7c8 4281 break;
179d3252
JT
4282
4283 case EM_VAX:
4284 if ((e_flags & EF_VAX_NONPIC))
4285 strcat (buf, ", non-PIC");
4286 if ((e_flags & EF_VAX_DFLOAT))
4287 strcat (buf, ", D-Float");
4288 if ((e_flags & EF_VAX_GFLOAT))
4289 strcat (buf, ", G-Float");
4290 break;
c7927a3c 4291
619ed720
EB
4292 case EM_VISIUM:
4293 if (e_flags & EF_VISIUM_ARCH_MCM)
4294 strcat (buf, ", mcm");
4295 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4296 strcat (buf, ", mcm24");
4297 if (e_flags & EF_VISIUM_ARCH_GR6)
4298 strcat (buf, ", gr6");
4299 break;
4300
4046d87a 4301 case EM_RL78:
1740ba0c
NC
4302 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4303 {
4304 case E_FLAG_RL78_ANY_CPU: break;
4305 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
4306 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
4307 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
4308 }
856ea05c
KP
4309 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4310 strcat (buf, ", 64-bit doubles");
4046d87a 4311 break;
0b4362b0 4312
c7927a3c
NC
4313 case EM_RX:
4314 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4315 strcat (buf, ", 64-bit doubles");
4316 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 4317 strcat (buf, ", dsp");
d4cb0ea0 4318 if (e_flags & E_FLAG_RX_PID)
0b4362b0 4319 strcat (buf, ", pid");
708e2187
NC
4320 if (e_flags & E_FLAG_RX_ABI)
4321 strcat (buf, ", RX ABI");
3525236c
NC
4322 if (e_flags & E_FLAG_RX_SINSNS_SET)
4323 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
4324 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
4325 if (e_flags & E_FLAG_RX_V2)
4326 strcat (buf, ", V2");
f87673e0
YS
4327 if (e_flags & E_FLAG_RX_V3)
4328 strcat (buf, ", V3");
d4cb0ea0 4329 break;
55786da2
AK
4330
4331 case EM_S390:
4332 if (e_flags & EF_S390_HIGH_GPRS)
4333 strcat (buf, ", highgprs");
d4cb0ea0 4334 break;
40b36596
JM
4335
4336 case EM_TI_C6000:
4337 if ((e_flags & EF_C6000_REL))
4338 strcat (buf, ", relocatable module");
d4cb0ea0 4339 break;
13761a11
NC
4340
4341 case EM_MSP430:
4342 strcat (buf, _(": architecture variant: "));
4343 switch (e_flags & EF_MSP430_MACH)
4344 {
4345 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
4346 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
4347 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
4348 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
4349 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
4350 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
4351 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
4352 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
4353 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
4354 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
4355 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
4356 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
4357 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
4358 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
4359 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
4360 default:
4361 strcat (buf, _(": unknown")); break;
4362 }
4363
4364 if (e_flags & ~ EF_MSP430_MACH)
4365 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
4366 break;
4367
4368 case EM_Z80:
4369 switch (e_flags & EF_Z80_MACH_MSK)
4370 {
4371 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
4372 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
4373 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
4374 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
4375 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
4376 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 4377 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
4378 default:
4379 strcat (buf, _(", unknown")); break;
4380 }
4381 break;
e9a0721f 4382 case EM_LOONGARCH:
e9a0721f 4383 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
4384 strcat (buf, ", SOFT-FLOAT");
4385 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
4386 strcat (buf, ", SINGLE-FLOAT");
4387 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
4388 strcat (buf, ", DOUBLE-FLOAT");
4389
c4a7e6b5 4390 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
4391 strcat (buf, ", OBJ-v0");
4392 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
4393 strcat (buf, ", OBJ-v1");
4394
e9a0721f 4395 break;
252b5132
RH
4396 }
4397 }
4398
4399 return buf;
4400}
4401
252b5132 4402static const char *
dda8d76d 4403get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4404{
4405 static char buff[32];
4406
4407 switch (osabi)
4408 {
4409 case ELFOSABI_NONE: return "UNIX - System V";
4410 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4411 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4412 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4413 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4414 case ELFOSABI_AIX: return "UNIX - AIX";
4415 case ELFOSABI_IRIX: return "UNIX - IRIX";
4416 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4417 case ELFOSABI_TRU64: return "UNIX - TRU64";
4418 case ELFOSABI_MODESTO: return "Novell - Modesto";
4419 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4420 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4421 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4422 case ELFOSABI_AROS: return "AROS";
11636f9e 4423 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4424 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4425 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4426 default:
40b36596 4427 if (osabi >= 64)
dda8d76d 4428 switch (filedata->file_header.e_machine)
40b36596 4429 {
37870be8
SM
4430 case EM_AMDGPU:
4431 switch (osabi)
4432 {
4433 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4434 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4435 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4436 default:
4437 break;
4438 }
4439 break;
4440
40b36596
JM
4441 case EM_ARM:
4442 switch (osabi)
4443 {
4444 case ELFOSABI_ARM: return "ARM";
18a20338 4445 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4446 default:
4447 break;
4448 }
4449 break;
4450
4451 case EM_MSP430:
4452 case EM_MSP430_OLD:
619ed720 4453 case EM_VISIUM:
40b36596
JM
4454 switch (osabi)
4455 {
4456 case ELFOSABI_STANDALONE: return _("Standalone App");
4457 default:
4458 break;
4459 }
4460 break;
4461
4462 case EM_TI_C6000:
4463 switch (osabi)
4464 {
4465 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4466 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4467 default:
4468 break;
4469 }
4470 break;
4471
4472 default:
4473 break;
4474 }
e9e44622 4475 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4476 return buff;
4477 }
4478}
4479
a06ea964
NC
4480static const char *
4481get_aarch64_segment_type (unsigned long type)
4482{
4483 switch (type)
4484 {
32ec8896 4485 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4486 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4487 default: return NULL;
a06ea964 4488 }
a06ea964
NC
4489}
4490
b294bdf8
MM
4491static const char *
4492get_arm_segment_type (unsigned long type)
4493{
4494 switch (type)
4495 {
32ec8896
NC
4496 case PT_ARM_EXIDX: return "EXIDX";
4497 default: return NULL;
b294bdf8 4498 }
b294bdf8
MM
4499}
4500
b4cbbe8f
AK
4501static const char *
4502get_s390_segment_type (unsigned long type)
4503{
4504 switch (type)
4505 {
4506 case PT_S390_PGSTE: return "S390_PGSTE";
4507 default: return NULL;
4508 }
4509}
4510
d3ba0551
AM
4511static const char *
4512get_mips_segment_type (unsigned long type)
252b5132
RH
4513{
4514 switch (type)
4515 {
32ec8896
NC
4516 case PT_MIPS_REGINFO: return "REGINFO";
4517 case PT_MIPS_RTPROC: return "RTPROC";
4518 case PT_MIPS_OPTIONS: return "OPTIONS";
4519 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4520 default: return NULL;
252b5132 4521 }
252b5132
RH
4522}
4523
103f02d3 4524static const char *
d3ba0551 4525get_parisc_segment_type (unsigned long type)
103f02d3
UD
4526{
4527 switch (type)
4528 {
103f02d3
UD
4529 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4530 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4531 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4532 default: return NULL;
103f02d3 4533 }
103f02d3
UD
4534}
4535
4d6ed7c8 4536static const char *
d3ba0551 4537get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4538{
4539 switch (type)
4540 {
4541 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4542 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4543 default: return NULL;
4d6ed7c8 4544 }
4d6ed7c8
NC
4545}
4546
40b36596
JM
4547static const char *
4548get_tic6x_segment_type (unsigned long type)
4549{
4550 switch (type)
4551 {
32ec8896
NC
4552 case PT_C6000_PHATTR: return "C6000_PHATTR";
4553 default: return NULL;
40b36596 4554 }
40b36596
JM
4555}
4556
fbc95f1e
KC
4557static const char *
4558get_riscv_segment_type (unsigned long type)
4559{
4560 switch (type)
4561 {
4562 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4563 default: return NULL;
4564 }
4565}
4566
df3a023b
AM
4567static const char *
4568get_hpux_segment_type (unsigned long type, unsigned e_machine)
4569{
4570 if (e_machine == EM_PARISC)
4571 switch (type)
4572 {
4573 case PT_HP_TLS: return "HP_TLS";
4574 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4575 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4576 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4577 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4578 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4579 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4580 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4581 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4582 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4583 case PT_HP_PARALLEL: return "HP_PARALLEL";
4584 case PT_HP_FASTBIND: return "HP_FASTBIND";
4585 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4586 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4587 case PT_HP_STACK: return "HP_STACK";
4588 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4589 default: return NULL;
4590 }
4591
4592 if (e_machine == EM_IA_64)
4593 switch (type)
4594 {
4595 case PT_HP_TLS: return "HP_TLS";
4596 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4597 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4598 case PT_IA_64_HP_STACK: return "HP_STACK";
4599 default: return NULL;
4600 }
4601
4602 return NULL;
4603}
4604
5522f910
NC
4605static const char *
4606get_solaris_segment_type (unsigned long type)
4607{
4608 switch (type)
4609 {
4610 case 0x6464e550: return "PT_SUNW_UNWIND";
4611 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4612 case 0x6ffffff7: return "PT_LOSUNW";
4613 case 0x6ffffffa: return "PT_SUNWBSS";
4614 case 0x6ffffffb: return "PT_SUNWSTACK";
4615 case 0x6ffffffc: return "PT_SUNWDTRACE";
4616 case 0x6ffffffd: return "PT_SUNWCAP";
4617 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4618 default: return NULL;
5522f910
NC
4619 }
4620}
4621
252b5132 4622static const char *
dda8d76d 4623get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4624{
b34976b6 4625 static char buff[32];
252b5132
RH
4626
4627 switch (p_type)
4628 {
b34976b6
AM
4629 case PT_NULL: return "NULL";
4630 case PT_LOAD: return "LOAD";
252b5132 4631 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4632 case PT_INTERP: return "INTERP";
4633 case PT_NOTE: return "NOTE";
4634 case PT_SHLIB: return "SHLIB";
4635 case PT_PHDR: return "PHDR";
13ae64f3 4636 case PT_TLS: return "TLS";
32ec8896 4637 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4638 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4639 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4640 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
cf0e0a0b 4641 case PT_GNU_SFRAME: return "GNU_SFRAME";
65765700 4642
80251d41 4643 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
3eba3ef3
NC
4644 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4645 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4646 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4647
252b5132 4648 default:
df3a023b 4649 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4650 {
2cf0635d 4651 const char * result;
103f02d3 4652
dda8d76d 4653 switch (filedata->file_header.e_machine)
252b5132 4654 {
a06ea964
NC
4655 case EM_AARCH64:
4656 result = get_aarch64_segment_type (p_type);
4657 break;
b294bdf8
MM
4658 case EM_ARM:
4659 result = get_arm_segment_type (p_type);
4660 break;
252b5132 4661 case EM_MIPS:
4fe85591 4662 case EM_MIPS_RS3_LE:
252b5132
RH
4663 result = get_mips_segment_type (p_type);
4664 break;
103f02d3
UD
4665 case EM_PARISC:
4666 result = get_parisc_segment_type (p_type);
4667 break;
4d6ed7c8
NC
4668 case EM_IA_64:
4669 result = get_ia64_segment_type (p_type);
4670 break;
40b36596
JM
4671 case EM_TI_C6000:
4672 result = get_tic6x_segment_type (p_type);
4673 break;
b4cbbe8f
AK
4674 case EM_S390:
4675 case EM_S390_OLD:
4676 result = get_s390_segment_type (p_type);
4677 break;
fbc95f1e
KC
4678 case EM_RISCV:
4679 result = get_riscv_segment_type (p_type);
4680 break;
252b5132
RH
4681 default:
4682 result = NULL;
4683 break;
4684 }
103f02d3 4685
252b5132
RH
4686 if (result != NULL)
4687 return result;
103f02d3 4688
1a9ccd70 4689 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4690 }
4691 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4692 {
df3a023b 4693 const char * result = NULL;
103f02d3 4694
df3a023b 4695 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4696 {
df3a023b
AM
4697 case ELFOSABI_GNU:
4698 case ELFOSABI_FREEBSD:
4699 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4700 {
4701 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4702 result = buff;
4703 }
103f02d3 4704 break;
df3a023b
AM
4705 case ELFOSABI_HPUX:
4706 result = get_hpux_segment_type (p_type,
4707 filedata->file_header.e_machine);
4708 break;
4709 case ELFOSABI_SOLARIS:
4710 result = get_solaris_segment_type (p_type);
00428cca 4711 break;
103f02d3 4712 default:
103f02d3
UD
4713 break;
4714 }
103f02d3
UD
4715 if (result != NULL)
4716 return result;
4717
1a9ccd70 4718 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4719 }
252b5132 4720 else
e9e44622 4721 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4722
4723 return buff;
4724 }
4725}
4726
53a346d8
CZ
4727static const char *
4728get_arc_section_type_name (unsigned int sh_type)
4729{
4730 switch (sh_type)
4731 {
4732 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4733 default:
4734 break;
4735 }
4736 return NULL;
4737}
4738
252b5132 4739static const char *
d3ba0551 4740get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4741{
4742 switch (sh_type)
4743 {
b34976b6
AM
4744 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4745 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4746 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4747 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4748 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4749 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4750 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4751 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4752 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4753 case SHT_MIPS_RELD: return "MIPS_RELD";
4754 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4755 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4756 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4757 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4758 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4759 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4760 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4761 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4762 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4763 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4764 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4765 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4766 case SHT_MIPS_LINE: return "MIPS_LINE";
4767 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4768 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4769 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4770 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4771 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4772 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4773 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4774 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4775 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4776 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4777 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4778 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4779 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4780 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4781 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4782 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4783 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4784 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4785 default:
4786 break;
4787 }
4788 return NULL;
4789}
4790
103f02d3 4791static const char *
d3ba0551 4792get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4793{
4794 switch (sh_type)
4795 {
4796 case SHT_PARISC_EXT: return "PARISC_EXT";
4797 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4798 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4799 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4800 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4801 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4802 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4803 default: return NULL;
103f02d3 4804 }
103f02d3
UD
4805}
4806
4d6ed7c8 4807static const char *
dda8d76d 4808get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4809{
18bd398b 4810 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4811 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4812 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4813
4d6ed7c8
NC
4814 switch (sh_type)
4815 {
148b93f2
NC
4816 case SHT_IA_64_EXT: return "IA_64_EXT";
4817 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4818 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4819 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4820 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4821 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4822 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4823 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4824 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4825 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4826 default:
4827 break;
4828 }
4829 return NULL;
4830}
4831
d2b2c203
DJ
4832static const char *
4833get_x86_64_section_type_name (unsigned int sh_type)
4834{
4835 switch (sh_type)
4836 {
4837 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4838 default: return NULL;
d2b2c203 4839 }
d2b2c203
DJ
4840}
4841
a06ea964
NC
4842static const char *
4843get_aarch64_section_type_name (unsigned int sh_type)
4844{
4845 switch (sh_type)
4846 {
32ec8896
NC
4847 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4848 default: return NULL;
a06ea964 4849 }
a06ea964
NC
4850}
4851
40a18ebd
NC
4852static const char *
4853get_arm_section_type_name (unsigned int sh_type)
4854{
4855 switch (sh_type)
4856 {
7f6fed87
NC
4857 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4858 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4859 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4860 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4861 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4862 default: return NULL;
40a18ebd 4863 }
40a18ebd
NC
4864}
4865
40b36596
JM
4866static const char *
4867get_tic6x_section_type_name (unsigned int sh_type)
4868{
4869 switch (sh_type)
4870 {
32ec8896
NC
4871 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4872 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4873 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4874 case SHT_TI_ICODE: return "TI_ICODE";
4875 case SHT_TI_XREF: return "TI_XREF";
4876 case SHT_TI_HANDLER: return "TI_HANDLER";
4877 case SHT_TI_INITINFO: return "TI_INITINFO";
4878 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4879 default: return NULL;
40b36596 4880 }
40b36596
JM
4881}
4882
13761a11 4883static const char *
b0191216 4884get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4885{
4886 switch (sh_type)
4887 {
32ec8896
NC
4888 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4889 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4890 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4891 default: return NULL;
13761a11
NC
4892 }
4893}
4894
fe944acf
FT
4895static const char *
4896get_nfp_section_type_name (unsigned int sh_type)
4897{
4898 switch (sh_type)
4899 {
4900 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4901 case SHT_NFP_INITREG: return "NFP_INITREG";
4902 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4903 default: return NULL;
4904 }
4905}
4906
685080f2
NC
4907static const char *
4908get_v850_section_type_name (unsigned int sh_type)
4909{
4910 switch (sh_type)
4911 {
32ec8896
NC
4912 case SHT_V850_SCOMMON: return "V850 Small Common";
4913 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4914 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4915 case SHT_RENESAS_IOP: return "RENESAS IOP";
4916 case SHT_RENESAS_INFO: return "RENESAS INFO";
4917 default: return NULL;
685080f2
NC
4918 }
4919}
4920
2dc8dd17
JW
4921static const char *
4922get_riscv_section_type_name (unsigned int sh_type)
4923{
4924 switch (sh_type)
4925 {
4926 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4927 default: return NULL;
4928 }
4929}
4930
0861f561
CQ
4931static const char *
4932get_csky_section_type_name (unsigned int sh_type)
4933{
4934 switch (sh_type)
4935 {
4936 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4937 default: return NULL;
4938 }
4939}
4940
252b5132 4941static const char *
dda8d76d 4942get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4943{
b34976b6 4944 static char buff[32];
9fb71ee4 4945 const char * result;
252b5132
RH
4946
4947 switch (sh_type)
4948 {
4949 case SHT_NULL: return "NULL";
4950 case SHT_PROGBITS: return "PROGBITS";
4951 case SHT_SYMTAB: return "SYMTAB";
4952 case SHT_STRTAB: return "STRTAB";
4953 case SHT_RELA: return "RELA";
dd207c13 4954 case SHT_RELR: return "RELR";
252b5132
RH
4955 case SHT_HASH: return "HASH";
4956 case SHT_DYNAMIC: return "DYNAMIC";
4957 case SHT_NOTE: return "NOTE";
4958 case SHT_NOBITS: return "NOBITS";
4959 case SHT_REL: return "REL";
4960 case SHT_SHLIB: return "SHLIB";
4961 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4962 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4963 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4964 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4965 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4966 case SHT_GROUP: return "GROUP";
67ce483b 4967 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4968 case SHT_GNU_verdef: return "VERDEF";
4969 case SHT_GNU_verneed: return "VERNEED";
4970 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4971 case 0x6ffffff0: return "VERSYM";
4972 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4973 case 0x7ffffffd: return "AUXILIARY";
4974 case 0x7fffffff: return "FILTER";
047b2264 4975 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4976
4977 default:
4978 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4979 {
dda8d76d 4980 switch (filedata->file_header.e_machine)
252b5132 4981 {
53a346d8
CZ
4982 case EM_ARC:
4983 case EM_ARC_COMPACT:
4984 case EM_ARC_COMPACT2:
4985 result = get_arc_section_type_name (sh_type);
4986 break;
252b5132 4987 case EM_MIPS:
4fe85591 4988 case EM_MIPS_RS3_LE:
252b5132
RH
4989 result = get_mips_section_type_name (sh_type);
4990 break;
103f02d3
UD
4991 case EM_PARISC:
4992 result = get_parisc_section_type_name (sh_type);
4993 break;
4d6ed7c8 4994 case EM_IA_64:
dda8d76d 4995 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4996 break;
d2b2c203 4997 case EM_X86_64:
8a9036a4 4998 case EM_L1OM:
7a9068fe 4999 case EM_K1OM:
d2b2c203
DJ
5000 result = get_x86_64_section_type_name (sh_type);
5001 break;
a06ea964
NC
5002 case EM_AARCH64:
5003 result = get_aarch64_section_type_name (sh_type);
5004 break;
40a18ebd
NC
5005 case EM_ARM:
5006 result = get_arm_section_type_name (sh_type);
5007 break;
40b36596
JM
5008 case EM_TI_C6000:
5009 result = get_tic6x_section_type_name (sh_type);
5010 break;
13761a11 5011 case EM_MSP430:
b0191216 5012 result = get_msp430_section_type_name (sh_type);
13761a11 5013 break;
fe944acf
FT
5014 case EM_NFP:
5015 result = get_nfp_section_type_name (sh_type);
5016 break;
685080f2
NC
5017 case EM_V800:
5018 case EM_V850:
5019 case EM_CYGNUS_V850:
5020 result = get_v850_section_type_name (sh_type);
5021 break;
2dc8dd17
JW
5022 case EM_RISCV:
5023 result = get_riscv_section_type_name (sh_type);
5024 break;
0861f561
CQ
5025 case EM_CSKY:
5026 result = get_csky_section_type_name (sh_type);
5027 break;
252b5132
RH
5028 default:
5029 result = NULL;
5030 break;
5031 }
5032
5033 if (result != NULL)
5034 return result;
5035
9fb71ee4 5036 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5037 }
5038 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5039 {
dda8d76d 5040 switch (filedata->file_header.e_machine)
148b93f2
NC
5041 {
5042 case EM_IA_64:
dda8d76d 5043 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5044 break;
5045 default:
dda8d76d 5046 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5047 result = get_solaris_section_type (sh_type);
5048 else
1b4b80bf
NC
5049 {
5050 switch (sh_type)
5051 {
5052 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5053 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5054 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5055 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5056 default:
5057 result = NULL;
5058 break;
5059 }
5060 }
148b93f2
NC
5061 break;
5062 }
5063
5064 if (result != NULL)
5065 return result;
5066
9fb71ee4 5067 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5068 }
252b5132 5069 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5070 {
dda8d76d 5071 switch (filedata->file_header.e_machine)
685080f2
NC
5072 {
5073 case EM_V800:
5074 case EM_V850:
5075 case EM_CYGNUS_V850:
9fb71ee4 5076 result = get_v850_section_type_name (sh_type);
a9fb83be 5077 break;
685080f2 5078 default:
9fb71ee4 5079 result = NULL;
685080f2
NC
5080 break;
5081 }
5082
9fb71ee4
NC
5083 if (result != NULL)
5084 return result;
5085
5086 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5087 }
252b5132 5088 else
a7dbfd1c
NC
5089 /* This message is probably going to be displayed in a 15
5090 character wide field, so put the hex value first. */
5091 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5092
252b5132
RH
5093 return buff;
5094 }
5095}
5096
79bc120c
NC
5097enum long_option_values
5098{
5099 OPTION_DEBUG_DUMP = 512,
5100 OPTION_DYN_SYMS,
0f03783c 5101 OPTION_LTO_SYMS,
79bc120c
NC
5102 OPTION_DWARF_DEPTH,
5103 OPTION_DWARF_START,
5104 OPTION_DWARF_CHECK,
5105 OPTION_CTF_DUMP,
5106 OPTION_CTF_PARENT,
5107 OPTION_CTF_SYMBOLS,
5108 OPTION_CTF_STRINGS,
42b6953b 5109 OPTION_SFRAME_DUMP,
79bc120c
NC
5110 OPTION_WITH_SYMBOL_VERSIONS,
5111 OPTION_RECURSE_LIMIT,
5112 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
5113 OPTION_NO_DEMANGLING,
5114 OPTION_SYM_BASE
79bc120c 5115};
2979dc34 5116
85b1c36d 5117static struct option options[] =
252b5132 5118{
79bc120c
NC
5119 /* Note - This table is alpha-sorted on the 'val'
5120 field in order to make adding new options easier. */
5121 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5122 {"all", no_argument, 0, 'a'},
79bc120c
NC
5123 {"demangle", optional_argument, 0, 'C'},
5124 {"archive-index", no_argument, 0, 'c'},
5125 {"use-dynamic", no_argument, 0, 'D'},
5126 {"dynamic", no_argument, 0, 'd'},
b34976b6 5127 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5128 {"section-groups", no_argument, 0, 'g'},
5129 {"help", no_argument, 0, 'H'},
5130 {"file-header", no_argument, 0, 'h'},
b34976b6 5131 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5132 {"lint", no_argument, 0, 'L'},
5133 {"enable-checks", no_argument, 0, 'L'},
5134 {"program-headers", no_argument, 0, 'l'},
b34976b6 5135 {"segments", no_argument, 0, 'l'},
595cf52e 5136 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5137 {"notes", no_argument, 0, 'n'},
ca0e11aa 5138 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5139 {"string-dump", required_argument, 0, 'p'},
5140 {"relocated-dump", required_argument, 0, 'R'},
5141 {"relocs", no_argument, 0, 'r'},
5142 {"section-headers", no_argument, 0, 'S'},
5143 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5144 {"symbols", no_argument, 0, 's'},
5145 {"syms", no_argument, 0, 's'},
79bc120c
NC
5146 {"silent-truncation",no_argument, 0, 'T'},
5147 {"section-details", no_argument, 0, 't'},
b3aa80b4 5148 {"unicode", required_argument, NULL, 'U'},
09c11c86 5149 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5150 {"version-info", no_argument, 0, 'V'},
5151 {"version", no_argument, 0, 'v'},
5152 {"wide", no_argument, 0, 'W'},
b34976b6 5153 {"hex-dump", required_argument, 0, 'x'},
0e602686 5154 {"decompress", no_argument, 0, 'z'},
252b5132 5155
79bc120c
NC
5156 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5157 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5158 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5159 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5160 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5161 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5162 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5163 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5164 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5165 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5166#ifdef ENABLE_LIBCTF
d344b407 5167 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5168 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5169 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5170 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5171#endif
42b6953b 5172 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
047c3dbf 5173 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5174
b34976b6 5175 {0, no_argument, 0, 0}
252b5132
RH
5176};
5177
5178static void
2cf0635d 5179usage (FILE * stream)
252b5132 5180{
92f01d61
JM
5181 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5182 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5183 fprintf (stream, _(" Options are:\n"));
5184 fprintf (stream, _("\
5185 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5186 fprintf (stream, _("\
5187 -h --file-header Display the ELF file header\n"));
5188 fprintf (stream, _("\
5189 -l --program-headers Display the program headers\n"));
5190 fprintf (stream, _("\
5191 --segments An alias for --program-headers\n"));
5192 fprintf (stream, _("\
5193 -S --section-headers Display the sections' header\n"));
5194 fprintf (stream, _("\
5195 --sections An alias for --section-headers\n"));
5196 fprintf (stream, _("\
5197 -g --section-groups Display the section groups\n"));
5198 fprintf (stream, _("\
5199 -t --section-details Display the section details\n"));
5200 fprintf (stream, _("\
5201 -e --headers Equivalent to: -h -l -S\n"));
5202 fprintf (stream, _("\
5203 -s --syms Display the symbol table\n"));
5204 fprintf (stream, _("\
5205 --symbols An alias for --syms\n"));
5206 fprintf (stream, _("\
5207 --dyn-syms Display the dynamic symbol table\n"));
5208 fprintf (stream, _("\
5209 --lto-syms Display LTO symbol tables\n"));
5210 fprintf (stream, _("\
047c3dbf
NL
5211 --sym-base=[0|8|10|16] \n\
5212 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5213 mixed (the default), octal, decimal, hexadecimal.\n"));
5214 fprintf (stream, _("\
0d646226
AM
5215 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5216 display_demangler_styles (stream, _("\
5217 STYLE can be "));
d6249f5f
AM
5218 fprintf (stream, _("\
5219 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5220 fprintf (stream, _("\
5221 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5222 fprintf (stream, _("\
5223 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5224 fprintf (stream, _("\
5225 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5226 Display unicode characters as determined by the current locale\n\
5227 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5228 escape sequences, or treat them as invalid and display as\n\
5229 \"{hex sequences}\"\n"));
d6249f5f
AM
5230 fprintf (stream, _("\
5231 -n --notes Display the core notes (if present)\n"));
5232 fprintf (stream, _("\
5233 -r --relocs Display the relocations (if present)\n"));
5234 fprintf (stream, _("\
5235 -u --unwind Display the unwind info (if present)\n"));
5236 fprintf (stream, _("\
5237 -d --dynamic Display the dynamic section (if present)\n"));
5238 fprintf (stream, _("\
5239 -V --version-info Display the version sections (if present)\n"));
5240 fprintf (stream, _("\
5241 -A --arch-specific Display architecture specific information (if any)\n"));
5242 fprintf (stream, _("\
5243 -c --archive-index Display the symbol/file index in an archive\n"));
5244 fprintf (stream, _("\
5245 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5246 fprintf (stream, _("\
5247 -L --lint|--enable-checks\n\
5248 Display warning messages for possible problems\n"));
5249 fprintf (stream, _("\
09c11c86 5250 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5251 Dump the contents of section <number|name> as bytes\n"));
5252 fprintf (stream, _("\
09c11c86 5253 -p --string-dump=<number|name>\n\
d6249f5f
AM
5254 Dump the contents of section <number|name> as strings\n"));
5255 fprintf (stream, _("\
cf13d699 5256 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5257 Dump the relocated contents of section <number|name>\n"));
5258 fprintf (stream, _("\
5259 -z --decompress Decompress section before dumping it\n"));
5260 fprintf (stream, _("\
5261 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5262 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5263 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5264 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5265 U/=trace_info]\n\
5266 Display the contents of DWARF debug sections\n"));
5267 fprintf (stream, _("\
5268 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5269 debuginfo files\n"));
5270 fprintf (stream, _("\
5271 -P --process-links Display the contents of non-debug sections in separate\n\
5272 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5273#if DEFAULT_FOR_FOLLOW_LINKS
5274 fprintf (stream, _("\
d6249f5f
AM
5275 -wK --debug-dump=follow-links\n\
5276 Follow links to separate debug info files (default)\n"));
5277 fprintf (stream, _("\
5278 -wN --debug-dump=no-follow-links\n\
5279 Do not follow links to separate debug info files\n"));
c46b7066
NC
5280#else
5281 fprintf (stream, _("\
d6249f5f
AM
5282 -wK --debug-dump=follow-links\n\
5283 Follow links to separate debug info files\n"));
5284 fprintf (stream, _("\
5285 -wN --debug-dump=no-follow-links\n\
5286 Do not follow links to separate debug info files\n\
5287 (default)\n"));
bed566bb
NC
5288#endif
5289#if HAVE_LIBDEBUGINFOD
5290 fprintf (stream, _("\
5291 -wD --debug-dump=use-debuginfod\n\
5292 When following links, also query debuginfod servers (default)\n"));
5293 fprintf (stream, _("\
5294 -wE --debug-dump=do-not-use-debuginfod\n\
5295 When following links, do not query debuginfod servers\n"));
c46b7066 5296#endif
fd2f0033 5297 fprintf (stream, _("\
d6249f5f
AM
5298 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5299 fprintf (stream, _("\
5300 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5301#ifdef ENABLE_LIBCTF
7d9813f1 5302 fprintf (stream, _("\
d6249f5f
AM
5303 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5304 fprintf (stream, _("\
80b56fad 5305 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5306 fprintf (stream, _("\
7d9813f1 5307 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5308 Use section <number|name> as the CTF external symtab\n"));
5309 fprintf (stream, _("\
7d9813f1 5310 --ctf-strings=<number|name>\n\
d6249f5f 5311 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5312#endif
42b6953b
IB
5313 fprintf (stream, _("\
5314 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
7d9813f1 5315
252b5132 5316#ifdef SUPPORT_DISASSEMBLY
92f01d61 5317 fprintf (stream, _("\
09c11c86
NC
5318 -i --instruction-dump=<number|name>\n\
5319 Disassemble the contents of section <number|name>\n"));
252b5132 5320#endif
92f01d61 5321 fprintf (stream, _("\
d6249f5f
AM
5322 -I --histogram Display histogram of bucket list lengths\n"));
5323 fprintf (stream, _("\
5324 -W --wide Allow output width to exceed 80 characters\n"));
5325 fprintf (stream, _("\
5326 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5327 fprintf (stream, _("\
5328 @<file> Read options from <file>\n"));
5329 fprintf (stream, _("\
5330 -H --help Display this information\n"));
5331 fprintf (stream, _("\
8b53311e 5332 -v --version Display the version number of readelf\n"));
1118d252 5333
92f01d61
JM
5334 if (REPORT_BUGS_TO[0] && stream == stdout)
5335 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5336
92f01d61 5337 exit (stream == stdout ? 0 : 1);
252b5132
RH
5338}
5339
18bd398b
NC
5340/* Record the fact that the user wants the contents of section number
5341 SECTION to be displayed using the method(s) encoded as flags bits
5342 in TYPE. Note, TYPE can be zero if we are creating the array for
5343 the first time. */
5344
252b5132 5345static void
6431e409
AM
5346request_dump_bynumber (struct dump_data *dumpdata,
5347 unsigned int section, dump_type type)
252b5132 5348{
6431e409 5349 if (section >= dumpdata->num_dump_sects)
252b5132 5350 {
2cf0635d 5351 dump_type * new_dump_sects;
252b5132 5352
3f5e193b 5353 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5354 sizeof (* new_dump_sects));
252b5132
RH
5355
5356 if (new_dump_sects == NULL)
591a748a 5357 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5358 else
5359 {
6431e409 5360 if (dumpdata->dump_sects)
21b65bac
NC
5361 {
5362 /* Copy current flag settings. */
6431e409
AM
5363 memcpy (new_dump_sects, dumpdata->dump_sects,
5364 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5365
6431e409 5366 free (dumpdata->dump_sects);
21b65bac 5367 }
252b5132 5368
6431e409
AM
5369 dumpdata->dump_sects = new_dump_sects;
5370 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5371 }
5372 }
5373
6431e409
AM
5374 if (dumpdata->dump_sects)
5375 dumpdata->dump_sects[section] |= type;
252b5132
RH
5376}
5377
aef1f6d0
DJ
5378/* Request a dump by section name. */
5379
5380static void
2cf0635d 5381request_dump_byname (const char * section, dump_type type)
aef1f6d0 5382{
2cf0635d 5383 struct dump_list_entry * new_request;
aef1f6d0 5384
3f5e193b
NC
5385 new_request = (struct dump_list_entry *)
5386 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5387 if (!new_request)
591a748a 5388 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5389
5390 new_request->name = strdup (section);
5391 if (!new_request->name)
591a748a 5392 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5393
5394 new_request->type = type;
5395
5396 new_request->next = dump_sects_byname;
5397 dump_sects_byname = new_request;
5398}
5399
cf13d699 5400static inline void
6431e409 5401request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5402{
5403 int section;
5404 char * cp;
5405
015dc7e1 5406 do_dump = true;
cf13d699
NC
5407 section = strtoul (optarg, & cp, 0);
5408
5409 if (! *cp && section >= 0)
6431e409 5410 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5411 else
5412 request_dump_byname (optarg, type);
5413}
5414
252b5132 5415static void
6431e409 5416parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5417{
5418 int c;
5419
5420 if (argc < 2)
92f01d61 5421 usage (stderr);
252b5132
RH
5422
5423 while ((c = getopt_long
b3aa80b4 5424 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5425 {
252b5132
RH
5426 switch (c)
5427 {
5428 case 0:
5429 /* Long options. */
5430 break;
5431 case 'H':
92f01d61 5432 usage (stdout);
252b5132
RH
5433 break;
5434
5435 case 'a':
015dc7e1
AM
5436 do_syms = true;
5437 do_reloc = true;
5438 do_unwind = true;
5439 do_dynamic = true;
5440 do_header = true;
5441 do_sections = true;
5442 do_section_groups = true;
5443 do_segments = true;
5444 do_version = true;
5445 do_histogram = true;
5446 do_arch = true;
5447 do_notes = true;
252b5132 5448 break;
79bc120c 5449
f5842774 5450 case 'g':
015dc7e1 5451 do_section_groups = true;
f5842774 5452 break;
5477e8a0 5453 case 't':
595cf52e 5454 case 'N':
015dc7e1
AM
5455 do_sections = true;
5456 do_section_details = true;
595cf52e 5457 break;
252b5132 5458 case 'e':
015dc7e1
AM
5459 do_header = true;
5460 do_sections = true;
5461 do_segments = true;
252b5132 5462 break;
a952a375 5463 case 'A':
015dc7e1 5464 do_arch = true;
a952a375 5465 break;
252b5132 5466 case 'D':
015dc7e1 5467 do_using_dynamic = true;
252b5132
RH
5468 break;
5469 case 'r':
015dc7e1 5470 do_reloc = true;
252b5132 5471 break;
4d6ed7c8 5472 case 'u':
015dc7e1 5473 do_unwind = true;
4d6ed7c8 5474 break;
252b5132 5475 case 'h':
015dc7e1 5476 do_header = true;
252b5132
RH
5477 break;
5478 case 'l':
015dc7e1 5479 do_segments = true;
252b5132
RH
5480 break;
5481 case 's':
015dc7e1 5482 do_syms = true;
252b5132
RH
5483 break;
5484 case 'S':
015dc7e1 5485 do_sections = true;
252b5132
RH
5486 break;
5487 case 'd':
015dc7e1 5488 do_dynamic = true;
252b5132 5489 break;
a952a375 5490 case 'I':
015dc7e1 5491 do_histogram = true;
a952a375 5492 break;
779fe533 5493 case 'n':
015dc7e1 5494 do_notes = true;
779fe533 5495 break;
4145f1d5 5496 case 'c':
015dc7e1 5497 do_archive_index = true;
4145f1d5 5498 break;
1b513401 5499 case 'L':
015dc7e1 5500 do_checks = true;
1b513401 5501 break;
ca0e11aa 5502 case 'P':
015dc7e1
AM
5503 process_links = true;
5504 do_follow_links = true;
e1dbfc17 5505 dump_any_debugging = true;
ca0e11aa 5506 break;
252b5132 5507 case 'x':
6431e409 5508 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5509 break;
09c11c86 5510 case 'p':
6431e409 5511 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5512 break;
5513 case 'R':
6431e409 5514 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5515 break;
0e602686 5516 case 'z':
015dc7e1 5517 decompress_dumps = true;
0e602686 5518 break;
252b5132 5519 case 'w':
0f03783c 5520 if (optarg == NULL)
613ff48b 5521 {
015dc7e1 5522 do_debugging = true;
94585d6d
NC
5523 do_dump = true;
5524 dump_any_debugging = true;
613ff48b
CC
5525 dwarf_select_sections_all ();
5526 }
252b5132
RH
5527 else
5528 {
015dc7e1 5529 do_debugging = false;
94585d6d
NC
5530 if (dwarf_select_sections_by_letters (optarg))
5531 {
5532 do_dump = true;
5533 dump_any_debugging = true;
5534 }
252b5132
RH
5535 }
5536 break;
2979dc34 5537 case OPTION_DEBUG_DUMP:
0f03783c 5538 if (optarg == NULL)
d6249f5f 5539 {
94585d6d 5540 do_dump = true;
d6249f5f 5541 do_debugging = true;
94585d6d 5542 dump_any_debugging = true;
d6249f5f
AM
5543 dwarf_select_sections_all ();
5544 }
2979dc34
JJ
5545 else
5546 {
015dc7e1 5547 do_debugging = false;
94585d6d
NC
5548 if (dwarf_select_sections_by_names (optarg))
5549 {
5550 do_dump = true;
5551 dump_any_debugging = true;
5552 }
2979dc34
JJ
5553 }
5554 break;
fd2f0033
TT
5555 case OPTION_DWARF_DEPTH:
5556 {
5557 char *cp;
5558
5559 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5560 }
5561 break;
5562 case OPTION_DWARF_START:
5563 {
5564 char *cp;
5565
5566 dwarf_start_die = strtoul (optarg, & cp, 0);
5567 }
5568 break;
4723351a 5569 case OPTION_DWARF_CHECK:
015dc7e1 5570 dwarf_check = true;
4723351a 5571 break;
7d9813f1 5572 case OPTION_CTF_DUMP:
015dc7e1 5573 do_ctf = true;
6431e409 5574 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5575 break;
5576 case OPTION_CTF_SYMBOLS:
df16e041 5577 free (dump_ctf_symtab_name);
7d9813f1
NA
5578 dump_ctf_symtab_name = strdup (optarg);
5579 break;
5580 case OPTION_CTF_STRINGS:
df16e041 5581 free (dump_ctf_strtab_name);
7d9813f1
NA
5582 dump_ctf_strtab_name = strdup (optarg);
5583 break;
5584 case OPTION_CTF_PARENT:
df16e041 5585 free (dump_ctf_parent_name);
7d9813f1
NA
5586 dump_ctf_parent_name = strdup (optarg);
5587 break;
42b6953b
IB
5588 case OPTION_SFRAME_DUMP:
5589 do_sframe = true;
5590 /* Providing section name is optional. request_dump (), however,
5591 thrives on non NULL optarg. Handle it explicitly here. */
5592 if (optarg != NULL)
5593 request_dump (dumpdata, SFRAME_DUMP);
5594 else
5595 {
5596 do_dump = true;
5597 const char *sframe_sec_name = strdup (".sframe");
5598 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
5599 }
5600 break;
2c610e4b 5601 case OPTION_DYN_SYMS:
015dc7e1 5602 do_dyn_syms = true;
2c610e4b 5603 break;
0f03783c 5604 case OPTION_LTO_SYMS:
015dc7e1 5605 do_lto_syms = true;
0f03783c 5606 break;
252b5132
RH
5607#ifdef SUPPORT_DISASSEMBLY
5608 case 'i':
6431e409 5609 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5610 break;
252b5132
RH
5611#endif
5612 case 'v':
5613 print_version (program_name);
5614 break;
5615 case 'V':
015dc7e1 5616 do_version = true;
252b5132 5617 break;
d974e256 5618 case 'W':
015dc7e1 5619 do_wide = true;
d974e256 5620 break;
0942c7ab 5621 case 'T':
015dc7e1 5622 do_not_show_symbol_truncation = true;
0942c7ab 5623 break;
79bc120c 5624 case 'C':
015dc7e1 5625 do_demangle = true;
79bc120c
NC
5626 if (optarg != NULL)
5627 {
5628 enum demangling_styles style;
5629
5630 style = cplus_demangle_name_to_style (optarg);
5631 if (style == unknown_demangling)
5632 error (_("unknown demangling style `%s'"), optarg);
5633
5634 cplus_demangle_set_style (style);
5635 }
5636 break;
5637 case OPTION_NO_DEMANGLING:
015dc7e1 5638 do_demangle = false;
79bc120c
NC
5639 break;
5640 case OPTION_RECURSE_LIMIT:
5641 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5642 break;
5643 case OPTION_NO_RECURSE_LIMIT:
5644 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5645 break;
5646 case OPTION_WITH_SYMBOL_VERSIONS:
5647 /* Ignored for backward compatibility. */
5648 break;
b9e920ec 5649
b3aa80b4
NC
5650 case 'U':
5651 if (optarg == NULL)
5652 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5653 else if (streq (optarg, "default") || streq (optarg, "d"))
5654 unicode_display = unicode_default;
5655 else if (streq (optarg, "locale") || streq (optarg, "l"))
5656 unicode_display = unicode_locale;
5657 else if (streq (optarg, "escape") || streq (optarg, "e"))
5658 unicode_display = unicode_escape;
5659 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5660 unicode_display = unicode_invalid;
5661 else if (streq (optarg, "hex") || streq (optarg, "x"))
5662 unicode_display = unicode_hex;
5663 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5664 unicode_display = unicode_highlight;
5665 else
5666 error (_("invalid argument to -U/--unicode: %s"), optarg);
5667 break;
5668
047c3dbf
NL
5669 case OPTION_SYM_BASE:
5670 sym_base = 0;
5671 if (optarg != NULL)
5672 {
5673 sym_base = strtoul (optarg, NULL, 0);
5674 switch (sym_base)
5675 {
5676 case 0:
5677 case 8:
5678 case 10:
5679 case 16:
5680 break;
5681
5682 default:
5683 sym_base = 0;
5684 break;
5685 }
5686 }
5687 break;
5688
252b5132 5689 default:
252b5132
RH
5690 /* xgettext:c-format */
5691 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5692 /* Fall through. */
252b5132 5693 case '?':
92f01d61 5694 usage (stderr);
252b5132
RH
5695 }
5696 }
5697
4d6ed7c8 5698 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5699 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5700 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5701 && !do_section_groups && !do_archive_index
0f03783c 5702 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5703 {
5704 if (do_checks)
5705 {
015dc7e1
AM
5706 check_all = true;
5707 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5708 do_segments = do_header = do_dump = do_version = true;
5709 do_histogram = do_debugging = do_arch = do_notes = true;
5710 do_section_groups = do_archive_index = do_dyn_syms = true;
5711 do_lto_syms = true;
1b513401
NC
5712 }
5713 else
5714 usage (stderr);
5715 }
252b5132
RH
5716}
5717
5718static const char *
d3ba0551 5719get_elf_class (unsigned int elf_class)
252b5132 5720{
b34976b6 5721 static char buff[32];
103f02d3 5722
252b5132
RH
5723 switch (elf_class)
5724 {
5725 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5726 case ELFCLASS32: return "ELF32";
5727 case ELFCLASS64: return "ELF64";
ab5e7794 5728 default:
e9e44622 5729 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5730 return buff;
252b5132
RH
5731 }
5732}
5733
5734static const char *
d3ba0551 5735get_data_encoding (unsigned int encoding)
252b5132 5736{
b34976b6 5737 static char buff[32];
103f02d3 5738
252b5132
RH
5739 switch (encoding)
5740 {
5741 case ELFDATANONE: return _("none");
33c63f9d
CM
5742 case ELFDATA2LSB: return _("2's complement, little endian");
5743 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5744 default:
e9e44622 5745 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5746 return buff;
252b5132
RH
5747 }
5748}
5749
521f7268
NC
5750static bool
5751check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
5752{
5753 if (header->e_ident[EI_MAG0] == ELFMAG0
5754 && header->e_ident[EI_MAG1] == ELFMAG1
5755 && header->e_ident[EI_MAG2] == ELFMAG2
5756 && header->e_ident[EI_MAG3] == ELFMAG3)
5757 return true;
5758
5759 /* Some compilers produce object files that are not in the ELF file format.
5760 As an aid to users of readelf, try to identify these cases and suggest
5761 alternative tools.
5762
5763 FIXME: It is not clear if all four bytes are used as constant magic
5764 valus by all compilers. It may be necessary to recode this function if
5765 different tools use different length sequences. */
5766
5767 static struct
5768 {
5769 unsigned char magic[4];
5770 const char * obj_message;
5771 const char * ar_message;
5772 }
5773 known_magic[] =
5774 {
5775 { { 'B', 'C', 0xc0, 0xde },
5776 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
5777 N_("This is a LLVM bitcode file - try extracing and then using llvm-bcanalyzer\n")
5778 },
5779 { { 'g', 'o', ' ', 'o' },
5780 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
5781 NULL
5782 }
5783 };
5784 int i;
5785
5786 for (i = ARRAY_SIZE (known_magic); i--;)
5787 {
5788 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
5789 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
5790 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
5791 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
5792 {
5793 /* Some compiler's analyzer tools do not handle archives,
5794 so we provide two different kinds of error message. */
5795 if (filedata->archive_file_size > 0
5796 && known_magic[i].ar_message != NULL)
b3ea2010 5797 error ("%s", known_magic[i].ar_message);
521f7268 5798 else
b3ea2010 5799 error ("%s", known_magic[i].obj_message);
521f7268
NC
5800 return false;
5801 }
5802 }
5803
5804 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
5805 return false;
5806}
5807
dda8d76d 5808/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5809
015dc7e1 5810static bool
dda8d76d 5811process_file_header (Filedata * filedata)
252b5132 5812{
dda8d76d
NC
5813 Elf_Internal_Ehdr * header = & filedata->file_header;
5814
521f7268
NC
5815 if (! check_magic_number (filedata, header))
5816 return false;
252b5132 5817
ca0e11aa
NC
5818 if (! filedata->is_separate)
5819 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5820
252b5132
RH
5821 if (do_header)
5822 {
32ec8896 5823 unsigned i;
252b5132 5824
ca0e11aa
NC
5825 if (filedata->is_separate)
5826 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5827 else
5828 printf (_("ELF Header:\n"));
252b5132 5829 printf (_(" Magic: "));
b34976b6 5830 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5831 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5832 printf ("\n");
5833 printf (_(" Class: %s\n"),
dda8d76d 5834 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5835 printf (_(" Data: %s\n"),
dda8d76d 5836 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5837 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5838 header->e_ident[EI_VERSION],
5839 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5840 ? _(" (current)")
dda8d76d 5841 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5842 ? _(" <unknown>")
789be9f7 5843 : "")));
252b5132 5844 printf (_(" OS/ABI: %s\n"),
dda8d76d 5845 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5846 printf (_(" ABI Version: %d\n"),
dda8d76d 5847 header->e_ident[EI_ABIVERSION]);
252b5132 5848 printf (_(" Type: %s\n"),
93df3340 5849 get_file_type (filedata));
252b5132 5850 printf (_(" Machine: %s\n"),
dda8d76d 5851 get_machine_name (header->e_machine));
252b5132 5852 printf (_(" Version: 0x%lx\n"),
e8a64888 5853 header->e_version);
76da6bbe 5854
f7a99963 5855 printf (_(" Entry point address: "));
e8a64888 5856 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5857 printf (_("\n Start of program headers: "));
e8a64888 5858 print_vma (header->e_phoff, DEC);
f7a99963 5859 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5860 print_vma (header->e_shoff, DEC);
f7a99963 5861 printf (_(" (bytes into file)\n"));
76da6bbe 5862
252b5132 5863 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5864 header->e_flags,
dda8d76d 5865 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5866 printf (_(" Size of this header: %u (bytes)\n"),
5867 header->e_ehsize);
5868 printf (_(" Size of program headers: %u (bytes)\n"),
5869 header->e_phentsize);
5870 printf (_(" Number of program headers: %u"),
5871 header->e_phnum);
dda8d76d
NC
5872 if (filedata->section_headers != NULL
5873 && header->e_phnum == PN_XNUM
5874 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5875 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5876 putc ('\n', stdout);
e8a64888
AM
5877 printf (_(" Size of section headers: %u (bytes)\n"),
5878 header->e_shentsize);
5879 printf (_(" Number of section headers: %u"),
5880 header->e_shnum);
dda8d76d 5881 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5882 {
5883 header->e_shnum = filedata->section_headers[0].sh_size;
5884 printf (" (%u)", header->e_shnum);
5885 }
560f3c1c 5886 putc ('\n', stdout);
e8a64888
AM
5887 printf (_(" Section header string table index: %u"),
5888 header->e_shstrndx);
dda8d76d
NC
5889 if (filedata->section_headers != NULL
5890 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5891 {
5892 header->e_shstrndx = filedata->section_headers[0].sh_link;
5893 printf (" (%u)", header->e_shstrndx);
5894 }
5895 if (header->e_shstrndx != SHN_UNDEF
5896 && header->e_shstrndx >= header->e_shnum)
5897 {
5898 header->e_shstrndx = SHN_UNDEF;
5899 printf (_(" <corrupt: out of range>"));
5900 }
560f3c1c
AM
5901 putc ('\n', stdout);
5902 }
5903
dda8d76d 5904 if (filedata->section_headers != NULL)
560f3c1c 5905 {
dda8d76d
NC
5906 if (header->e_phnum == PN_XNUM
5907 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5908 {
5909 /* Throw away any cached read of PN_XNUM headers. */
5910 free (filedata->program_headers);
5911 filedata->program_headers = NULL;
5912 header->e_phnum = filedata->section_headers[0].sh_info;
5913 }
dda8d76d
NC
5914 if (header->e_shnum == SHN_UNDEF)
5915 header->e_shnum = filedata->section_headers[0].sh_size;
5916 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5917 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5918 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5919 header->e_shstrndx = SHN_UNDEF;
252b5132 5920 }
103f02d3 5921
015dc7e1 5922 return true;
9ea033b2
NC
5923}
5924
dda8d76d
NC
5925/* Read in the program headers from FILEDATA and store them in PHEADERS.
5926 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5927
015dc7e1 5928static bool
dda8d76d 5929get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5930{
2cf0635d
NC
5931 Elf32_External_Phdr * phdrs;
5932 Elf32_External_Phdr * external;
5933 Elf_Internal_Phdr * internal;
b34976b6 5934 unsigned int i;
dda8d76d
NC
5935 unsigned int size = filedata->file_header.e_phentsize;
5936 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5937
5938 /* PR binutils/17531: Cope with unexpected section header sizes. */
5939 if (size == 0 || num == 0)
015dc7e1 5940 return false;
e0a31db1
NC
5941 if (size < sizeof * phdrs)
5942 {
5943 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5944 return false;
e0a31db1
NC
5945 }
5946 if (size > sizeof * phdrs)
5947 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5948
dda8d76d 5949 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5950 size, num, _("program headers"));
5951 if (phdrs == NULL)
015dc7e1 5952 return false;
9ea033b2 5953
91d6fa6a 5954 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5955 i < filedata->file_header.e_phnum;
b34976b6 5956 i++, internal++, external++)
252b5132 5957 {
9ea033b2
NC
5958 internal->p_type = BYTE_GET (external->p_type);
5959 internal->p_offset = BYTE_GET (external->p_offset);
5960 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5961 internal->p_paddr = BYTE_GET (external->p_paddr);
5962 internal->p_filesz = BYTE_GET (external->p_filesz);
5963 internal->p_memsz = BYTE_GET (external->p_memsz);
5964 internal->p_flags = BYTE_GET (external->p_flags);
5965 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5966 }
5967
9ea033b2 5968 free (phdrs);
015dc7e1 5969 return true;
252b5132
RH
5970}
5971
dda8d76d
NC
5972/* Read in the program headers from FILEDATA and store them in PHEADERS.
5973 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5974
015dc7e1 5975static bool
dda8d76d 5976get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5977{
2cf0635d
NC
5978 Elf64_External_Phdr * phdrs;
5979 Elf64_External_Phdr * external;
5980 Elf_Internal_Phdr * internal;
b34976b6 5981 unsigned int i;
dda8d76d
NC
5982 unsigned int size = filedata->file_header.e_phentsize;
5983 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5984
5985 /* PR binutils/17531: Cope with unexpected section header sizes. */
5986 if (size == 0 || num == 0)
015dc7e1 5987 return false;
e0a31db1
NC
5988 if (size < sizeof * phdrs)
5989 {
5990 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5991 return false;
e0a31db1
NC
5992 }
5993 if (size > sizeof * phdrs)
5994 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5995
dda8d76d 5996 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5997 size, num, _("program headers"));
a6e9f9df 5998 if (!phdrs)
015dc7e1 5999 return false;
9ea033b2 6000
91d6fa6a 6001 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6002 i < filedata->file_header.e_phnum;
b34976b6 6003 i++, internal++, external++)
9ea033b2
NC
6004 {
6005 internal->p_type = BYTE_GET (external->p_type);
6006 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
6007 internal->p_offset = BYTE_GET (external->p_offset);
6008 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6009 internal->p_paddr = BYTE_GET (external->p_paddr);
6010 internal->p_filesz = BYTE_GET (external->p_filesz);
6011 internal->p_memsz = BYTE_GET (external->p_memsz);
6012 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
6013 }
6014
6015 free (phdrs);
015dc7e1 6016 return true;
9ea033b2 6017}
252b5132 6018
32ec8896 6019/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 6020
015dc7e1 6021static bool
dda8d76d 6022get_program_headers (Filedata * filedata)
d93f0186 6023{
2cf0635d 6024 Elf_Internal_Phdr * phdrs;
d93f0186
NC
6025
6026 /* Check cache of prior read. */
dda8d76d 6027 if (filedata->program_headers != NULL)
015dc7e1 6028 return true;
d93f0186 6029
82156ab7
NC
6030 /* Be kind to memory checkers by looking for
6031 e_phnum values which we know must be invalid. */
dda8d76d 6032 if (filedata->file_header.e_phnum
82156ab7 6033 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 6034 >= filedata->file_size)
82156ab7
NC
6035 {
6036 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 6037 filedata->file_header.e_phnum);
015dc7e1 6038 return false;
82156ab7 6039 }
d93f0186 6040
dda8d76d 6041 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 6042 sizeof (Elf_Internal_Phdr));
d93f0186
NC
6043 if (phdrs == NULL)
6044 {
8b73c356 6045 error (_("Out of memory reading %u program headers\n"),
dda8d76d 6046 filedata->file_header.e_phnum);
015dc7e1 6047 return false;
d93f0186
NC
6048 }
6049
6050 if (is_32bit_elf
dda8d76d
NC
6051 ? get_32bit_program_headers (filedata, phdrs)
6052 : get_64bit_program_headers (filedata, phdrs))
d93f0186 6053 {
dda8d76d 6054 filedata->program_headers = phdrs;
015dc7e1 6055 return true;
d93f0186
NC
6056 }
6057
6058 free (phdrs);
015dc7e1 6059 return false;
d93f0186
NC
6060}
6061
93df3340 6062/* Print program header info and locate dynamic section. */
2f62977e 6063
93df3340 6064static void
dda8d76d 6065process_program_headers (Filedata * filedata)
252b5132 6066{
2cf0635d 6067 Elf_Internal_Phdr * segment;
b34976b6 6068 unsigned int i;
1a9ccd70 6069 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6070
dda8d76d 6071 if (filedata->file_header.e_phnum == 0)
252b5132 6072 {
82f2dbf7 6073 /* PR binutils/12467. */
dda8d76d 6074 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6075 warn (_("possibly corrupt ELF header - it has a non-zero program"
6076 " header offset, but no program headers\n"));
82f2dbf7 6077 else if (do_segments)
ca0e11aa
NC
6078 {
6079 if (filedata->is_separate)
6080 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6081 filedata->file_name);
6082 else
6083 printf (_("\nThere are no program headers in this file.\n"));
6084 }
93df3340 6085 goto no_headers;
252b5132
RH
6086 }
6087
6088 if (do_segments && !do_header)
6089 {
ca0e11aa
NC
6090 if (filedata->is_separate)
6091 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6092 filedata->file_name, get_file_type (filedata));
ca0e11aa 6093 else
93df3340 6094 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6095 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6096 filedata->file_header.e_entry);
b8281767
AM
6097 printf (ngettext ("There is %d program header,"
6098 " starting at offset %" PRIu64 "\n",
6099 "There are %d program headers,"
6100 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6101 filedata->file_header.e_phnum),
6102 filedata->file_header.e_phnum,
625d49fc 6103 filedata->file_header.e_phoff);
252b5132
RH
6104 }
6105
dda8d76d 6106 if (! get_program_headers (filedata))
93df3340 6107 goto no_headers;
103f02d3 6108
252b5132
RH
6109 if (do_segments)
6110 {
dda8d76d 6111 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6112 printf (_("\nProgram Headers:\n"));
6113 else
6114 printf (_("\nProgram Headers:\n"));
76da6bbe 6115
f7a99963
NC
6116 if (is_32bit_elf)
6117 printf
6118 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6119 else if (do_wide)
6120 printf
6121 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6122 else
6123 {
6124 printf
6125 (_(" Type Offset VirtAddr PhysAddr\n"));
6126 printf
6127 (_(" FileSiz MemSiz Flags Align\n"));
6128 }
252b5132
RH
6129 }
6130
26c527e6 6131 uint64_t dynamic_addr = 0;
be7d229a 6132 uint64_t dynamic_size = 0;
dda8d76d
NC
6133 for (i = 0, segment = filedata->program_headers;
6134 i < filedata->file_header.e_phnum;
b34976b6 6135 i++, segment++)
252b5132
RH
6136 {
6137 if (do_segments)
6138 {
dda8d76d 6139 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6140
6141 if (is_32bit_elf)
6142 {
6143 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6144 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6145 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6146 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6147 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6148 printf ("%c%c%c ",
6149 (segment->p_flags & PF_R ? 'R' : ' '),
6150 (segment->p_flags & PF_W ? 'W' : ' '),
6151 (segment->p_flags & PF_X ? 'E' : ' '));
6152 printf ("%#lx", (unsigned long) segment->p_align);
6153 }
d974e256
JJ
6154 else if (do_wide)
6155 {
6156 if ((unsigned long) segment->p_offset == segment->p_offset)
6157 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6158 else
6159 {
6160 print_vma (segment->p_offset, FULL_HEX);
6161 putchar (' ');
6162 }
6163
6164 print_vma (segment->p_vaddr, FULL_HEX);
6165 putchar (' ');
6166 print_vma (segment->p_paddr, FULL_HEX);
6167 putchar (' ');
6168
6169 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6170 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6171 else
6172 {
6173 print_vma (segment->p_filesz, FULL_HEX);
6174 putchar (' ');
6175 }
6176
6177 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6178 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6179 else
6180 {
f48e6c45 6181 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6182 }
6183
6184 printf (" %c%c%c ",
6185 (segment->p_flags & PF_R ? 'R' : ' '),
6186 (segment->p_flags & PF_W ? 'W' : ' '),
6187 (segment->p_flags & PF_X ? 'E' : ' '));
6188
6189 if ((unsigned long) segment->p_align == segment->p_align)
6190 printf ("%#lx", (unsigned long) segment->p_align);
6191 else
6192 {
6193 print_vma (segment->p_align, PREFIX_HEX);
6194 }
6195 }
f7a99963
NC
6196 else
6197 {
6198 print_vma (segment->p_offset, FULL_HEX);
6199 putchar (' ');
6200 print_vma (segment->p_vaddr, FULL_HEX);
6201 putchar (' ');
6202 print_vma (segment->p_paddr, FULL_HEX);
6203 printf ("\n ");
6204 print_vma (segment->p_filesz, FULL_HEX);
6205 putchar (' ');
6206 print_vma (segment->p_memsz, FULL_HEX);
6207 printf (" %c%c%c ",
6208 (segment->p_flags & PF_R ? 'R' : ' '),
6209 (segment->p_flags & PF_W ? 'W' : ' '),
6210 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6211 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6212 }
252b5132 6213
1a9ccd70
NC
6214 putc ('\n', stdout);
6215 }
f54498b4 6216
252b5132
RH
6217 switch (segment->p_type)
6218 {
1a9ccd70 6219 case PT_LOAD:
502d895c
NC
6220#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6221 required by the ELF standard, several programs, including the Linux
6222 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6223 if (previous_load
6224 && previous_load->p_vaddr > segment->p_vaddr)
6225 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6226#endif
1a9ccd70
NC
6227 if (segment->p_memsz < segment->p_filesz)
6228 error (_("the segment's file size is larger than its memory size\n"));
6229 previous_load = segment;
6230 break;
6231
6232 case PT_PHDR:
6233 /* PR 20815 - Verify that the program header is loaded into memory. */
6234 if (i > 0 && previous_load != NULL)
6235 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6236 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6237 {
6238 unsigned int j;
6239
dda8d76d 6240 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6241 {
6242 Elf_Internal_Phdr *load = filedata->program_headers + j;
6243 if (load->p_type == PT_LOAD
6244 && load->p_offset <= segment->p_offset
6245 && (load->p_offset + load->p_filesz
6246 >= segment->p_offset + segment->p_filesz)
6247 && load->p_vaddr <= segment->p_vaddr
6248 && (load->p_vaddr + load->p_filesz
6249 >= segment->p_vaddr + segment->p_filesz))
6250 break;
6251 }
dda8d76d 6252 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6253 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6254 }
6255 break;
6256
252b5132 6257 case PT_DYNAMIC:
93df3340 6258 if (dynamic_addr)
252b5132
RH
6259 error (_("more than one dynamic segment\n"));
6260
20737c13
AM
6261 /* By default, assume that the .dynamic section is the first
6262 section in the DYNAMIC segment. */
93df3340
AM
6263 dynamic_addr = segment->p_offset;
6264 dynamic_size = segment->p_filesz;
20737c13 6265
b2d38a17
NC
6266 /* Try to locate the .dynamic section. If there is
6267 a section header table, we can easily locate it. */
dda8d76d 6268 if (filedata->section_headers != NULL)
b2d38a17 6269 {
2cf0635d 6270 Elf_Internal_Shdr * sec;
b2d38a17 6271
dda8d76d 6272 sec = find_section (filedata, ".dynamic");
89fac5e3 6273 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6274 {
93df3340
AM
6275 /* A corresponding .dynamic section is expected, but on
6276 IA-64/OpenVMS it is OK for it to be missing. */
6277 if (!is_ia64_vms (filedata))
6278 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6279 break;
6280 }
6281
42bb2e33 6282 if (sec->sh_type == SHT_NOBITS)
20737c13 6283 {
93df3340
AM
6284 dynamic_addr = 0;
6285 dynamic_size = 0;
20737c13
AM
6286 break;
6287 }
42bb2e33 6288
93df3340
AM
6289 dynamic_addr = sec->sh_offset;
6290 dynamic_size = sec->sh_size;
b2d38a17 6291
8ac10c5b
L
6292 /* The PT_DYNAMIC segment, which is used by the run-time
6293 loader, should exactly match the .dynamic section. */
6294 if (do_checks
93df3340
AM
6295 && (dynamic_addr != segment->p_offset
6296 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6297 warn (_("\
6298the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6299 }
39e224f6
MW
6300
6301 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6302 segment. Check this after matching against the section headers
6303 so we don't warn on debuginfo file (which have NOBITS .dynamic
6304 sections). */
93df3340
AM
6305 if (dynamic_addr > filedata->file_size
6306 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6307 {
6308 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6309 dynamic_addr = 0;
6310 dynamic_size = 0;
39e224f6 6311 }
252b5132
RH
6312 break;
6313
6314 case PT_INTERP:
13acb58d
AM
6315 if (segment->p_offset >= filedata->file_size
6316 || segment->p_filesz > filedata->file_size - segment->p_offset
6317 || segment->p_filesz - 1 >= (size_t) -2
63cf857e
AM
6318 || fseek64 (filedata->handle,
6319 filedata->archive_file_offset + segment->p_offset,
6320 SEEK_SET))
252b5132
RH
6321 error (_("Unable to find program interpreter name\n"));
6322 else
6323 {
13acb58d
AM
6324 size_t len = segment->p_filesz;
6325 free (filedata->program_interpreter);
6326 filedata->program_interpreter = xmalloc (len + 1);
6327 len = fread (filedata->program_interpreter, 1, len,
6328 filedata->handle);
6329 filedata->program_interpreter[len] = 0;
252b5132
RH
6330
6331 if (do_segments)
f54498b4 6332 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6333 filedata->program_interpreter);
252b5132
RH
6334 }
6335 break;
6336 }
252b5132
RH
6337 }
6338
dda8d76d
NC
6339 if (do_segments
6340 && filedata->section_headers != NULL
6341 && filedata->string_table != NULL)
252b5132
RH
6342 {
6343 printf (_("\n Section to Segment mapping:\n"));
6344 printf (_(" Segment Sections...\n"));
6345
dda8d76d 6346 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6347 {
9ad5cbcf 6348 unsigned int j;
2cf0635d 6349 Elf_Internal_Shdr * section;
252b5132 6350
dda8d76d
NC
6351 segment = filedata->program_headers + i;
6352 section = filedata->section_headers + 1;
252b5132
RH
6353
6354 printf (" %2.2d ", i);
6355
dda8d76d 6356 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6357 {
f4638467
AM
6358 if (!ELF_TBSS_SPECIAL (section, segment)
6359 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6360 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6361 }
6362
6363 putc ('\n',stdout);
6364 }
6365 }
6366
93df3340
AM
6367 filedata->dynamic_addr = dynamic_addr;
6368 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6369 return;
6370
6371 no_headers:
6372 filedata->dynamic_addr = 0;
6373 filedata->dynamic_size = 1;
252b5132
RH
6374}
6375
6376
d93f0186
NC
6377/* Find the file offset corresponding to VMA by using the program headers. */
6378
26c527e6 6379static int64_t
625d49fc 6380offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 6381{
2cf0635d 6382 Elf_Internal_Phdr * seg;
d93f0186 6383
dda8d76d 6384 if (! get_program_headers (filedata))
d93f0186
NC
6385 {
6386 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6387 return (long) vma;
6388 }
6389
dda8d76d
NC
6390 for (seg = filedata->program_headers;
6391 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6392 ++seg)
6393 {
6394 if (seg->p_type != PT_LOAD)
6395 continue;
6396
6397 if (vma >= (seg->p_vaddr & -seg->p_align)
6398 && vma + size <= seg->p_vaddr + seg->p_filesz)
6399 return vma - seg->p_vaddr + seg->p_offset;
6400 }
6401
26c527e6
AM
6402 warn (_("Virtual address %#" PRIx64
6403 " not located in any PT_LOAD segment.\n"), vma);
6404 return vma;
d93f0186
NC
6405}
6406
6407
dda8d76d
NC
6408/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6409 If PROBE is true, this is just a probe and we do not generate any error
6410 messages if the load fails. */
049b0c3a 6411
015dc7e1
AM
6412static bool
6413get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6414{
2cf0635d
NC
6415 Elf32_External_Shdr * shdrs;
6416 Elf_Internal_Shdr * internal;
dda8d76d
NC
6417 unsigned int i;
6418 unsigned int size = filedata->file_header.e_shentsize;
6419 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6420
6421 /* PR binutils/17531: Cope with unexpected section header sizes. */
6422 if (size == 0 || num == 0)
015dc7e1 6423 return false;
907b52f4
NC
6424
6425 /* The section header cannot be at the start of the file - that is
6426 where the ELF file header is located. A file with absolutely no
6427 sections in it will use a shoff of 0. */
6428 if (filedata->file_header.e_shoff == 0)
6429 return false;
6430
049b0c3a
NC
6431 if (size < sizeof * shdrs)
6432 {
6433 if (! probe)
6434 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6435 return false;
049b0c3a
NC
6436 }
6437 if (!probe && size > sizeof * shdrs)
6438 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6439
dda8d76d 6440 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6441 size, num,
6442 probe ? NULL : _("section headers"));
6443 if (shdrs == NULL)
015dc7e1 6444 return false;
252b5132 6445
dda8d76d
NC
6446 filedata->section_headers = (Elf_Internal_Shdr *)
6447 cmalloc (num, sizeof (Elf_Internal_Shdr));
6448 if (filedata->section_headers == NULL)
252b5132 6449 {
049b0c3a 6450 if (!probe)
8b73c356 6451 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6452 free (shdrs);
015dc7e1 6453 return false;
252b5132
RH
6454 }
6455
dda8d76d 6456 for (i = 0, internal = filedata->section_headers;
560f3c1c 6457 i < num;
b34976b6 6458 i++, internal++)
252b5132
RH
6459 {
6460 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6461 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6462 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6463 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6464 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6465 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6466 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6467 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6468 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6469 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6470 if (!probe && internal->sh_link > num)
6471 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6472 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6473 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6474 }
6475
6476 free (shdrs);
015dc7e1 6477 return true;
252b5132
RH
6478}
6479
dda8d76d
NC
6480/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6481
015dc7e1
AM
6482static bool
6483get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6484{
dda8d76d
NC
6485 Elf64_External_Shdr * shdrs;
6486 Elf_Internal_Shdr * internal;
6487 unsigned int i;
6488 unsigned int size = filedata->file_header.e_shentsize;
6489 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6490
6491 /* PR binutils/17531: Cope with unexpected section header sizes. */
6492 if (size == 0 || num == 0)
015dc7e1 6493 return false;
dda8d76d 6494
907b52f4
NC
6495 /* The section header cannot be at the start of the file - that is
6496 where the ELF file header is located. A file with absolutely no
6497 sections in it will use a shoff of 0. */
6498 if (filedata->file_header.e_shoff == 0)
6499 return false;
6500
049b0c3a
NC
6501 if (size < sizeof * shdrs)
6502 {
6503 if (! probe)
6504 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6505 return false;
049b0c3a 6506 }
dda8d76d 6507
049b0c3a
NC
6508 if (! probe && size > sizeof * shdrs)
6509 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6510
dda8d76d
NC
6511 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6512 filedata->file_header.e_shoff,
049b0c3a
NC
6513 size, num,
6514 probe ? NULL : _("section headers"));
6515 if (shdrs == NULL)
015dc7e1 6516 return false;
9ea033b2 6517
dda8d76d
NC
6518 filedata->section_headers = (Elf_Internal_Shdr *)
6519 cmalloc (num, sizeof (Elf_Internal_Shdr));
6520 if (filedata->section_headers == NULL)
9ea033b2 6521 {
049b0c3a 6522 if (! probe)
8b73c356 6523 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6524 free (shdrs);
015dc7e1 6525 return false;
9ea033b2
NC
6526 }
6527
dda8d76d 6528 for (i = 0, internal = filedata->section_headers;
560f3c1c 6529 i < num;
b34976b6 6530 i++, internal++)
9ea033b2
NC
6531 {
6532 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6533 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6534 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6535 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6536 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6537 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6538 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6539 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6540 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6541 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6542 if (!probe && internal->sh_link > num)
6543 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6544 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6545 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6546 }
6547
6548 free (shdrs);
015dc7e1 6549 return true;
9ea033b2
NC
6550}
6551
4de91c10
AM
6552static bool
6553get_section_headers (Filedata *filedata, bool probe)
6554{
6555 if (filedata->section_headers != NULL)
6556 return true;
6557
4de91c10
AM
6558 if (is_32bit_elf)
6559 return get_32bit_section_headers (filedata, probe);
6560 else
6561 return get_64bit_section_headers (filedata, probe);
6562}
6563
252b5132 6564static Elf_Internal_Sym *
26c527e6
AM
6565get_32bit_elf_symbols (Filedata *filedata,
6566 Elf_Internal_Shdr *section,
6567 uint64_t *num_syms_return)
252b5132 6568{
26c527e6 6569 uint64_t number = 0;
dd24e3da 6570 Elf32_External_Sym * esyms = NULL;
ba5cdace 6571 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6572 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6573 Elf_Internal_Sym * psym;
b34976b6 6574 unsigned int j;
e3d39609 6575 elf_section_list * entry;
252b5132 6576
c9c1d674
EG
6577 if (section->sh_size == 0)
6578 {
6579 if (num_syms_return != NULL)
6580 * num_syms_return = 0;
6581 return NULL;
6582 }
6583
dd24e3da 6584 /* Run some sanity checks first. */
c9c1d674 6585 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6586 {
26c527e6 6587 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 6588 printable_section_name (filedata, section),
26c527e6 6589 section->sh_entsize);
ba5cdace 6590 goto exit_point;
dd24e3da
NC
6591 }
6592
dda8d76d 6593 if (section->sh_size > filedata->file_size)
f54498b4 6594 {
26c527e6 6595 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 6596 printable_section_name (filedata, section),
26c527e6 6597 section->sh_size);
f54498b4
NC
6598 goto exit_point;
6599 }
6600
dd24e3da
NC
6601 number = section->sh_size / section->sh_entsize;
6602
6603 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6604 {
26c527e6
AM
6605 error (_("Size (%#" PRIx64 ") of section %s "
6606 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
6607 section->sh_size,
dda8d76d 6608 printable_section_name (filedata, section),
26c527e6 6609 section->sh_entsize);
ba5cdace 6610 goto exit_point;
dd24e3da
NC
6611 }
6612
dda8d76d 6613 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6614 section->sh_size, _("symbols"));
dd24e3da 6615 if (esyms == NULL)
ba5cdace 6616 goto exit_point;
252b5132 6617
e3d39609 6618 shndx = NULL;
978c4450 6619 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 6620 {
26c527e6 6621 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
6622 continue;
6623
6624 if (shndx != NULL)
6625 {
6626 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6627 free (shndx);
6628 }
6629
6630 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6631 entry->hdr->sh_offset,
6632 1, entry->hdr->sh_size,
6633 _("symbol table section indices"));
6634 if (shndx == NULL)
6635 goto exit_point;
6636
6637 /* PR17531: file: heap-buffer-overflow */
6638 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6639 {
26c527e6 6640 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 6641 printable_section_name (filedata, entry->hdr),
26c527e6
AM
6642 entry->hdr->sh_size,
6643 section->sh_size);
e3d39609 6644 goto exit_point;
c9c1d674 6645 }
e3d39609 6646 }
9ad5cbcf 6647
3f5e193b 6648 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6649
6650 if (isyms == NULL)
6651 {
26c527e6 6652 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
dd24e3da 6653 goto exit_point;
252b5132
RH
6654 }
6655
dd24e3da 6656 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6657 {
6658 psym->st_name = BYTE_GET (esyms[j].st_name);
6659 psym->st_value = BYTE_GET (esyms[j].st_value);
6660 psym->st_size = BYTE_GET (esyms[j].st_size);
6661 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6662 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6663 psym->st_shndx
6664 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6665 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6666 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6667 psym->st_info = BYTE_GET (esyms[j].st_info);
6668 psym->st_other = BYTE_GET (esyms[j].st_other);
6669 }
6670
dd24e3da 6671 exit_point:
e3d39609
NC
6672 free (shndx);
6673 free (esyms);
252b5132 6674
ba5cdace
NC
6675 if (num_syms_return != NULL)
6676 * num_syms_return = isyms == NULL ? 0 : number;
6677
252b5132
RH
6678 return isyms;
6679}
6680
9ea033b2 6681static Elf_Internal_Sym *
26c527e6
AM
6682get_64bit_elf_symbols (Filedata *filedata,
6683 Elf_Internal_Shdr *section,
6684 uint64_t *num_syms_return)
9ea033b2 6685{
26c527e6 6686 uint64_t number = 0;
ba5cdace
NC
6687 Elf64_External_Sym * esyms = NULL;
6688 Elf_External_Sym_Shndx * shndx = NULL;
6689 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6690 Elf_Internal_Sym * psym;
b34976b6 6691 unsigned int j;
e3d39609 6692 elf_section_list * entry;
9ea033b2 6693
c9c1d674
EG
6694 if (section->sh_size == 0)
6695 {
6696 if (num_syms_return != NULL)
6697 * num_syms_return = 0;
6698 return NULL;
6699 }
6700
dd24e3da 6701 /* Run some sanity checks first. */
c9c1d674 6702 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6703 {
26c527e6 6704 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 6705 printable_section_name (filedata, section),
26c527e6 6706 section->sh_entsize);
ba5cdace 6707 goto exit_point;
dd24e3da
NC
6708 }
6709
dda8d76d 6710 if (section->sh_size > filedata->file_size)
f54498b4 6711 {
26c527e6 6712 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 6713 printable_section_name (filedata, section),
26c527e6 6714 section->sh_size);
f54498b4
NC
6715 goto exit_point;
6716 }
6717
dd24e3da
NC
6718 number = section->sh_size / section->sh_entsize;
6719
6720 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6721 {
26c527e6
AM
6722 error (_("Size (%#" PRIx64 ") of section %s "
6723 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
6724 section->sh_size,
dda8d76d 6725 printable_section_name (filedata, section),
26c527e6 6726 section->sh_entsize);
ba5cdace 6727 goto exit_point;
dd24e3da
NC
6728 }
6729
dda8d76d 6730 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6731 section->sh_size, _("symbols"));
a6e9f9df 6732 if (!esyms)
ba5cdace 6733 goto exit_point;
9ea033b2 6734
e3d39609 6735 shndx = NULL;
978c4450 6736 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 6737 {
26c527e6 6738 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
6739 continue;
6740
6741 if (shndx != NULL)
6742 {
6743 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6744 free (shndx);
c9c1d674 6745 }
e3d39609
NC
6746
6747 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6748 entry->hdr->sh_offset,
6749 1, entry->hdr->sh_size,
6750 _("symbol table section indices"));
6751 if (shndx == NULL)
6752 goto exit_point;
6753
6754 /* PR17531: file: heap-buffer-overflow */
6755 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6756 {
26c527e6 6757 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 6758 printable_section_name (filedata, entry->hdr),
26c527e6
AM
6759 entry->hdr->sh_size,
6760 section->sh_size);
e3d39609
NC
6761 goto exit_point;
6762 }
6763 }
9ad5cbcf 6764
3f5e193b 6765 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6766
6767 if (isyms == NULL)
6768 {
26c527e6 6769 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
ba5cdace 6770 goto exit_point;
9ea033b2
NC
6771 }
6772
ba5cdace 6773 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6774 {
6775 psym->st_name = BYTE_GET (esyms[j].st_name);
6776 psym->st_info = BYTE_GET (esyms[j].st_info);
6777 psym->st_other = BYTE_GET (esyms[j].st_other);
6778 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6779
4fbb74a6 6780 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6781 psym->st_shndx
6782 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6783 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6784 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6785
66543521
AM
6786 psym->st_value = BYTE_GET (esyms[j].st_value);
6787 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6788 }
6789
ba5cdace 6790 exit_point:
e3d39609
NC
6791 free (shndx);
6792 free (esyms);
ba5cdace
NC
6793
6794 if (num_syms_return != NULL)
6795 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6796
6797 return isyms;
6798}
6799
4de91c10
AM
6800static Elf_Internal_Sym *
6801get_elf_symbols (Filedata *filedata,
6802 Elf_Internal_Shdr *section,
26c527e6 6803 uint64_t *num_syms_return)
4de91c10
AM
6804{
6805 if (is_32bit_elf)
6806 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6807 else
6808 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6809}
6810
d1133906 6811static const char *
625d49fc 6812get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 6813{
5477e8a0 6814 static char buff[1024];
2cf0635d 6815 char * p = buff;
32ec8896
NC
6816 unsigned int field_size = is_32bit_elf ? 8 : 16;
6817 signed int sindex;
6818 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
6819 uint64_t os_flags = 0;
6820 uint64_t proc_flags = 0;
6821 uint64_t unknown_flags = 0;
148b93f2 6822 static const struct
5477e8a0 6823 {
2cf0635d 6824 const char * str;
32ec8896 6825 unsigned int len;
5477e8a0
L
6826 }
6827 flags [] =
6828 {
cfcac11d
NC
6829 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6830 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6831 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6832 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6833 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6834 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6835 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6836 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6837 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6838 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6839 /* IA-64 specific. */
6840 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6841 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6842 /* IA-64 OpenVMS specific. */
6843 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6844 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6845 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6846 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6847 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6848 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6849 /* Generic. */
cfcac11d 6850 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6851 /* SPARC specific. */
77115a4a 6852 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6853 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6854 /* ARM specific. */
6855 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6856 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6857 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6858 /* GNU specific. */
6859 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6860 /* VLE specific. */
6861 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6862 /* GNU specific. */
6863 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6864 };
6865
6866 if (do_section_details)
6867 {
8d5ff12c
L
6868 sprintf (buff, "[%*.*lx]: ",
6869 field_size, field_size, (unsigned long) sh_flags);
6870 p += field_size + 4;
5477e8a0 6871 }
76da6bbe 6872
d1133906
NC
6873 while (sh_flags)
6874 {
625d49fc 6875 uint64_t flag;
d1133906
NC
6876
6877 flag = sh_flags & - sh_flags;
6878 sh_flags &= ~ flag;
76da6bbe 6879
5477e8a0 6880 if (do_section_details)
d1133906 6881 {
5477e8a0
L
6882 switch (flag)
6883 {
91d6fa6a
NC
6884 case SHF_WRITE: sindex = 0; break;
6885 case SHF_ALLOC: sindex = 1; break;
6886 case SHF_EXECINSTR: sindex = 2; break;
6887 case SHF_MERGE: sindex = 3; break;
6888 case SHF_STRINGS: sindex = 4; break;
6889 case SHF_INFO_LINK: sindex = 5; break;
6890 case SHF_LINK_ORDER: sindex = 6; break;
6891 case SHF_OS_NONCONFORMING: sindex = 7; break;
6892 case SHF_GROUP: sindex = 8; break;
6893 case SHF_TLS: sindex = 9; break;
18ae9cc1 6894 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6895 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6896
5477e8a0 6897 default:
91d6fa6a 6898 sindex = -1;
dda8d76d 6899 switch (filedata->file_header.e_machine)
148b93f2 6900 {
cfcac11d 6901 case EM_IA_64:
148b93f2 6902 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6903 sindex = 10;
148b93f2 6904 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6905 sindex = 11;
dda8d76d 6906 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6907 switch (flag)
6908 {
91d6fa6a
NC
6909 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6910 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6911 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6912 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6913 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6914 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6915 default: break;
6916 }
cfcac11d
NC
6917 break;
6918
caa83f8b 6919 case EM_386:
22abe556 6920 case EM_IAMCU:
caa83f8b 6921 case EM_X86_64:
7f502d6c 6922 case EM_L1OM:
7a9068fe 6923 case EM_K1OM:
cfcac11d
NC
6924 case EM_OLD_SPARCV9:
6925 case EM_SPARC32PLUS:
6926 case EM_SPARCV9:
6927 case EM_SPARC:
18ae9cc1 6928 if (flag == SHF_ORDERED)
91d6fa6a 6929 sindex = 19;
cfcac11d 6930 break;
ac4c9b04
MG
6931
6932 case EM_ARM:
6933 switch (flag)
6934 {
6935 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6936 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6937 case SHF_COMDEF: sindex = 23; break;
6938 default: break;
6939 }
6940 break;
83eef883
AFB
6941 case EM_PPC:
6942 if (flag == SHF_PPC_VLE)
6943 sindex = 25;
6944 break;
99fabbc9
JL
6945 default:
6946 break;
6947 }
ac4c9b04 6948
99fabbc9
JL
6949 switch (filedata->file_header.e_ident[EI_OSABI])
6950 {
6951 case ELFOSABI_GNU:
6952 case ELFOSABI_FREEBSD:
6953 if (flag == SHF_GNU_RETAIN)
6954 sindex = 26;
6955 /* Fall through */
6956 case ELFOSABI_NONE:
6957 if (flag == SHF_GNU_MBIND)
6958 /* We should not recognize SHF_GNU_MBIND for
6959 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6960 not set the EI_OSABI header byte. */
6961 sindex = 24;
6962 break;
cfcac11d
NC
6963 default:
6964 break;
148b93f2 6965 }
99fabbc9 6966 break;
5477e8a0
L
6967 }
6968
91d6fa6a 6969 if (sindex != -1)
5477e8a0 6970 {
8d5ff12c
L
6971 if (p != buff + field_size + 4)
6972 {
6973 if (size < (10 + 2))
bee0ee85
NC
6974 {
6975 warn (_("Internal error: not enough buffer room for section flag info"));
6976 return _("<unknown>");
6977 }
8d5ff12c
L
6978 size -= 2;
6979 *p++ = ',';
6980 *p++ = ' ';
6981 }
6982
91d6fa6a
NC
6983 size -= flags [sindex].len;
6984 p = stpcpy (p, flags [sindex].str);
5477e8a0 6985 }
3b22753a 6986 else if (flag & SHF_MASKOS)
8d5ff12c 6987 os_flags |= flag;
d1133906 6988 else if (flag & SHF_MASKPROC)
8d5ff12c 6989 proc_flags |= flag;
d1133906 6990 else
8d5ff12c 6991 unknown_flags |= flag;
5477e8a0
L
6992 }
6993 else
6994 {
6995 switch (flag)
6996 {
6997 case SHF_WRITE: *p = 'W'; break;
6998 case SHF_ALLOC: *p = 'A'; break;
6999 case SHF_EXECINSTR: *p = 'X'; break;
7000 case SHF_MERGE: *p = 'M'; break;
7001 case SHF_STRINGS: *p = 'S'; break;
7002 case SHF_INFO_LINK: *p = 'I'; break;
7003 case SHF_LINK_ORDER: *p = 'L'; break;
7004 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7005 case SHF_GROUP: *p = 'G'; break;
7006 case SHF_TLS: *p = 'T'; break;
18ae9cc1 7007 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 7008 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
7009
7010 default:
dda8d76d
NC
7011 if ((filedata->file_header.e_machine == EM_X86_64
7012 || filedata->file_header.e_machine == EM_L1OM
7013 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
7014 && flag == SHF_X86_64_LARGE)
7015 *p = 'l';
dda8d76d 7016 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 7017 && flag == SHF_ARM_PURECODE)
99fabbc9 7018 *p = 'y';
dda8d76d 7019 else if (filedata->file_header.e_machine == EM_PPC
83eef883 7020 && flag == SHF_PPC_VLE)
99fabbc9 7021 *p = 'v';
5477e8a0
L
7022 else if (flag & SHF_MASKOS)
7023 {
99fabbc9
JL
7024 switch (filedata->file_header.e_ident[EI_OSABI])
7025 {
7026 case ELFOSABI_GNU:
7027 case ELFOSABI_FREEBSD:
7028 if (flag == SHF_GNU_RETAIN)
7029 {
7030 *p = 'R';
7031 break;
7032 }
7033 /* Fall through */
7034 case ELFOSABI_NONE:
7035 if (flag == SHF_GNU_MBIND)
7036 {
7037 /* We should not recognize SHF_GNU_MBIND for
7038 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7039 not set the EI_OSABI header byte. */
7040 *p = 'D';
7041 break;
7042 }
7043 /* Fall through */
7044 default:
7045 *p = 'o';
7046 sh_flags &= ~SHF_MASKOS;
7047 break;
7048 }
5477e8a0
L
7049 }
7050 else if (flag & SHF_MASKPROC)
7051 {
7052 *p = 'p';
7053 sh_flags &= ~ SHF_MASKPROC;
7054 }
7055 else
7056 *p = 'x';
7057 break;
7058 }
7059 p++;
d1133906
NC
7060 }
7061 }
76da6bbe 7062
8d5ff12c
L
7063 if (do_section_details)
7064 {
7065 if (os_flags)
7066 {
7067 size -= 5 + field_size;
7068 if (p != buff + field_size + 4)
7069 {
7070 if (size < (2 + 1))
bee0ee85
NC
7071 {
7072 warn (_("Internal error: not enough buffer room for section flag info"));
7073 return _("<unknown>");
7074 }
8d5ff12c
L
7075 size -= 2;
7076 *p++ = ',';
7077 *p++ = ' ';
7078 }
7079 sprintf (p, "OS (%*.*lx)", field_size, field_size,
7080 (unsigned long) os_flags);
7081 p += 5 + field_size;
7082 }
7083 if (proc_flags)
7084 {
7085 size -= 7 + field_size;
7086 if (p != buff + field_size + 4)
7087 {
7088 if (size < (2 + 1))
bee0ee85
NC
7089 {
7090 warn (_("Internal error: not enough buffer room for section flag info"));
7091 return _("<unknown>");
7092 }
8d5ff12c
L
7093 size -= 2;
7094 *p++ = ',';
7095 *p++ = ' ';
7096 }
7097 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7098 (unsigned long) proc_flags);
7099 p += 7 + field_size;
7100 }
7101 if (unknown_flags)
7102 {
7103 size -= 10 + field_size;
7104 if (p != buff + field_size + 4)
7105 {
7106 if (size < (2 + 1))
bee0ee85
NC
7107 {
7108 warn (_("Internal error: not enough buffer room for section flag info"));
7109 return _("<unknown>");
7110 }
8d5ff12c
L
7111 size -= 2;
7112 *p++ = ',';
7113 *p++ = ' ';
7114 }
2b692964 7115 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
7116 (unsigned long) unknown_flags);
7117 p += 10 + field_size;
7118 }
7119 }
7120
e9e44622 7121 *p = '\0';
d1133906
NC
7122 return buff;
7123}
7124
5844b465 7125static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7126get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7127 uint64_t size)
77115a4a
L
7128{
7129 if (is_32bit_elf)
7130 {
7131 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7132
ebdf1ebf
NC
7133 if (size < sizeof (* echdr))
7134 {
7135 error (_("Compressed section is too small even for a compression header\n"));
7136 return 0;
7137 }
7138
77115a4a
L
7139 chdr->ch_type = BYTE_GET (echdr->ch_type);
7140 chdr->ch_size = BYTE_GET (echdr->ch_size);
7141 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7142 return sizeof (*echdr);
7143 }
7144 else
7145 {
7146 Elf64_External_Chdr *echdr = (Elf64_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}
7160
015dc7e1 7161static bool
dda8d76d 7162process_section_headers (Filedata * filedata)
252b5132 7163{
2cf0635d 7164 Elf_Internal_Shdr * section;
b34976b6 7165 unsigned int i;
252b5132 7166
dda8d76d 7167 if (filedata->file_header.e_shnum == 0)
252b5132 7168 {
82f2dbf7 7169 /* PR binutils/12467. */
dda8d76d 7170 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7171 {
7172 warn (_("possibly corrupt ELF file header - it has a non-zero"
7173 " section header offset, but no section headers\n"));
015dc7e1 7174 return false;
32ec8896 7175 }
82f2dbf7 7176 else if (do_sections)
252b5132
RH
7177 printf (_("\nThere are no sections in this file.\n"));
7178
015dc7e1 7179 return true;
252b5132
RH
7180 }
7181
7182 if (do_sections && !do_header)
ca0e11aa
NC
7183 {
7184 if (filedata->is_separate && process_links)
7185 printf (_("In linked file '%s': "), filedata->file_name);
7186 if (! filedata->is_separate || process_links)
7187 printf (ngettext ("There is %d section header, "
26c527e6 7188 "starting at offset %#" PRIx64 ":\n",
ca0e11aa 7189 "There are %d section headers, "
26c527e6 7190 "starting at offset %#" PRIx64 ":\n",
ca0e11aa
NC
7191 filedata->file_header.e_shnum),
7192 filedata->file_header.e_shnum,
26c527e6 7193 filedata->file_header.e_shoff);
ca0e11aa 7194 }
252b5132 7195
4de91c10
AM
7196 if (!get_section_headers (filedata, false))
7197 return false;
252b5132
RH
7198
7199 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7200 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7201 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7202 {
dda8d76d 7203 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7204
c256ffe7
JJ
7205 if (section->sh_size != 0)
7206 {
dda8d76d
NC
7207 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7208 1, section->sh_size,
7209 _("string table"));
0de14b54 7210
dda8d76d 7211 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7212 }
252b5132
RH
7213 }
7214
7215 /* Scan the sections for the dynamic symbol table
e3c8793a 7216 and dynamic string table and debug sections. */
89fac5e3 7217 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7218 switch (filedata->file_header.e_machine)
89fac5e3
RS
7219 {
7220 case EM_MIPS:
7221 case EM_MIPS_RS3_LE:
7222 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7223 FDE addresses. However, the ABI also has a semi-official ILP32
7224 variant for which the normal FDE address size rules apply.
7225
7226 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7227 section, where XX is the size of longs in bits. Unfortunately,
7228 earlier compilers provided no way of distinguishing ILP32 objects
7229 from LP64 objects, so if there's any doubt, we should assume that
7230 the official LP64 form is being used. */
dda8d76d
NC
7231 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7232 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7233 eh_addr_size = 8;
7234 break;
0f56a26a
DD
7235
7236 case EM_H8_300:
7237 case EM_H8_300H:
dda8d76d 7238 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7239 {
7240 case E_H8_MACH_H8300:
7241 case E_H8_MACH_H8300HN:
7242 case E_H8_MACH_H8300SN:
7243 case E_H8_MACH_H8300SXN:
7244 eh_addr_size = 2;
7245 break;
7246 case E_H8_MACH_H8300H:
7247 case E_H8_MACH_H8300S:
7248 case E_H8_MACH_H8300SX:
7249 eh_addr_size = 4;
7250 break;
7251 }
f4236fe4
DD
7252 break;
7253
ff7eeb89 7254 case EM_M32C_OLD:
f4236fe4 7255 case EM_M32C:
dda8d76d 7256 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7257 {
7258 case EF_M32C_CPU_M16C:
7259 eh_addr_size = 2;
7260 break;
7261 }
7262 break;
89fac5e3
RS
7263 }
7264
76ca31c0
NC
7265#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7266 do \
7267 { \
be7d229a 7268 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7269 if (section->sh_entsize != expected_entsize) \
9dd3a467 7270 { \
f493c217 7271 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7272 i, section->sh_entsize); \
f493c217 7273 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7274 expected_entsize); \
9dd3a467 7275 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7276 } \
7277 } \
08d8fa11 7278 while (0)
9dd3a467
NC
7279
7280#define CHECK_ENTSIZE(section, i, type) \
1b513401 7281 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7282 sizeof (Elf64_External_##type))
7283
dda8d76d
NC
7284 for (i = 0, section = filedata->section_headers;
7285 i < filedata->file_header.e_shnum;
b34976b6 7286 i++, section++)
252b5132 7287 {
84714f86 7288 const char *name = section_name_print (filedata, section);
252b5132 7289
1b513401
NC
7290 /* Run some sanity checks on the headers and
7291 possibly fill in some file data as well. */
7292 switch (section->sh_type)
252b5132 7293 {
1b513401 7294 case SHT_DYNSYM:
978c4450 7295 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7296 {
7297 error (_("File contains multiple dynamic symbol tables\n"));
7298 continue;
7299 }
7300
08d8fa11 7301 CHECK_ENTSIZE (section, i, Sym);
978c4450 7302 filedata->dynamic_symbols
4de91c10 7303 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7304 filedata->dynamic_symtab_section = section;
1b513401
NC
7305 break;
7306
7307 case SHT_STRTAB:
7308 if (streq (name, ".dynstr"))
252b5132 7309 {
1b513401
NC
7310 if (filedata->dynamic_strings != NULL)
7311 {
7312 error (_("File contains multiple dynamic string tables\n"));
7313 continue;
7314 }
7315
7316 filedata->dynamic_strings
7317 = (char *) get_data (NULL, filedata, section->sh_offset,
7318 1, section->sh_size, _("dynamic strings"));
7319 filedata->dynamic_strings_length
7320 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7321 filedata->dynamic_strtab_section = section;
252b5132 7322 }
1b513401
NC
7323 break;
7324
7325 case SHT_SYMTAB_SHNDX:
7326 {
7327 elf_section_list * entry = xmalloc (sizeof * entry);
7328
7329 entry->hdr = section;
7330 entry->next = filedata->symtab_shndx_list;
7331 filedata->symtab_shndx_list = entry;
7332 }
7333 break;
7334
7335 case SHT_SYMTAB:
7336 CHECK_ENTSIZE (section, i, Sym);
7337 break;
7338
7339 case SHT_GROUP:
7340 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7341 break;
252b5132 7342
1b513401
NC
7343 case SHT_REL:
7344 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7345 if (do_checks && section->sh_size == 0)
1b513401
NC
7346 warn (_("Section '%s': zero-sized relocation section\n"), name);
7347 break;
7348
7349 case SHT_RELA:
7350 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7351 if (do_checks && section->sh_size == 0)
1b513401
NC
7352 warn (_("Section '%s': zero-sized relocation section\n"), name);
7353 break;
7354
682351b9
AM
7355 case SHT_RELR:
7356 CHECK_ENTSIZE (section, i, Relr);
7357 break;
7358
1b513401
NC
7359 case SHT_NOTE:
7360 case SHT_PROGBITS:
546cb2d8
NC
7361 /* Having a zero sized section is not illegal according to the
7362 ELF standard, but it might be an indication that something
7363 is wrong. So issue a warning if we are running in lint mode. */
7364 if (do_checks && section->sh_size == 0)
1b513401
NC
7365 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7366 break;
7367
7368 default:
7369 break;
7370 }
7371
7372 if ((do_debugging || do_debug_info || do_debug_abbrevs
7373 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7374 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7375 || do_debug_str || do_debug_str_offsets || do_debug_loc
7376 || do_debug_ranges
1b513401 7377 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7378 && (startswith (name, ".debug_")
7379 || startswith (name, ".zdebug_")))
252b5132 7380 {
1b315056
CS
7381 if (name[1] == 'z')
7382 name += sizeof (".zdebug_") - 1;
7383 else
7384 name += sizeof (".debug_") - 1;
252b5132
RH
7385
7386 if (do_debugging
24d127aa
ML
7387 || (do_debug_info && startswith (name, "info"))
7388 || (do_debug_info && startswith (name, "types"))
7389 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7390 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7391 || (do_debug_lines && startswith (name, "line."))
7392 || (do_debug_pubnames && startswith (name, "pubnames"))
7393 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7394 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7395 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7396 || (do_debug_aranges && startswith (name, "aranges"))
7397 || (do_debug_ranges && startswith (name, "ranges"))
7398 || (do_debug_ranges && startswith (name, "rnglists"))
7399 || (do_debug_frames && startswith (name, "frame"))
7400 || (do_debug_macinfo && startswith (name, "macinfo"))
7401 || (do_debug_macinfo && startswith (name, "macro"))
7402 || (do_debug_str && startswith (name, "str"))
7403 || (do_debug_links && startswith (name, "sup"))
7404 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7405 || (do_debug_loc && startswith (name, "loc"))
7406 || (do_debug_loc && startswith (name, "loclists"))
7407 || (do_debug_addr && startswith (name, "addr"))
7408 || (do_debug_cu_index && startswith (name, "cu_index"))
7409 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7410 )
6431e409 7411 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7412 }
a262ae96 7413 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7414 else if ((do_debugging || do_debug_info)
24d127aa 7415 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7416 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7417 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7418 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7419 else if (do_gdb_index && (streq (name, ".gdb_index")
7420 || streq (name, ".debug_names")))
6431e409 7421 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7422 /* Trace sections for Itanium VMS. */
7423 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7424 || do_trace_aranges)
24d127aa 7425 && startswith (name, ".trace_"))
6f875884
TG
7426 {
7427 name += sizeof (".trace_") - 1;
7428
7429 if (do_debugging
7430 || (do_trace_info && streq (name, "info"))
7431 || (do_trace_abbrevs && streq (name, "abbrev"))
7432 || (do_trace_aranges && streq (name, "aranges"))
7433 )
6431e409 7434 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7435 }
dda8d76d 7436 else if ((do_debugging || do_debug_links)
24d127aa
ML
7437 && (startswith (name, ".gnu_debuglink")
7438 || startswith (name, ".gnu_debugaltlink")))
6431e409 7439 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7440 }
7441
7442 if (! do_sections)
015dc7e1 7443 return true;
252b5132 7444
ca0e11aa 7445 if (filedata->is_separate && ! process_links)
015dc7e1 7446 return true;
ca0e11aa
NC
7447
7448 if (filedata->is_separate)
7449 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7450 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7451 printf (_("\nSection Headers:\n"));
7452 else
7453 printf (_("\nSection Header:\n"));
76da6bbe 7454
f7a99963 7455 if (is_32bit_elf)
595cf52e 7456 {
5477e8a0 7457 if (do_section_details)
595cf52e
L
7458 {
7459 printf (_(" [Nr] Name\n"));
5477e8a0 7460 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7461 }
7462 else
7463 printf
7464 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7465 }
d974e256 7466 else if (do_wide)
595cf52e 7467 {
5477e8a0 7468 if (do_section_details)
595cf52e
L
7469 {
7470 printf (_(" [Nr] Name\n"));
5477e8a0 7471 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7472 }
7473 else
7474 printf
7475 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7476 }
f7a99963
NC
7477 else
7478 {
5477e8a0 7479 if (do_section_details)
595cf52e
L
7480 {
7481 printf (_(" [Nr] Name\n"));
5477e8a0
L
7482 printf (_(" Type Address Offset Link\n"));
7483 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7484 }
7485 else
7486 {
7487 printf (_(" [Nr] Name Type Address Offset\n"));
7488 printf (_(" Size EntSize Flags Link Info Align\n"));
7489 }
f7a99963 7490 }
252b5132 7491
5477e8a0
L
7492 if (do_section_details)
7493 printf (_(" Flags\n"));
7494
dda8d76d
NC
7495 for (i = 0, section = filedata->section_headers;
7496 i < filedata->file_header.e_shnum;
b34976b6 7497 i++, section++)
252b5132 7498 {
dd905818
NC
7499 /* Run some sanity checks on the section header. */
7500
7501 /* Check the sh_link field. */
7502 switch (section->sh_type)
7503 {
285e3f99
AM
7504 case SHT_REL:
7505 case SHT_RELA:
7506 if (section->sh_link == 0
7507 && (filedata->file_header.e_type == ET_EXEC
7508 || filedata->file_header.e_type == ET_DYN))
7509 /* A dynamic relocation section where all entries use a
7510 zero symbol index need not specify a symtab section. */
7511 break;
7512 /* Fall through. */
dd905818
NC
7513 case SHT_SYMTAB_SHNDX:
7514 case SHT_GROUP:
7515 case SHT_HASH:
7516 case SHT_GNU_HASH:
7517 case SHT_GNU_versym:
285e3f99 7518 if (section->sh_link == 0
dda8d76d
NC
7519 || section->sh_link >= filedata->file_header.e_shnum
7520 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7521 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7522 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7523 i, section->sh_link);
7524 break;
7525
7526 case SHT_DYNAMIC:
7527 case SHT_SYMTAB:
7528 case SHT_DYNSYM:
7529 case SHT_GNU_verneed:
7530 case SHT_GNU_verdef:
7531 case SHT_GNU_LIBLIST:
285e3f99 7532 if (section->sh_link == 0
dda8d76d
NC
7533 || section->sh_link >= filedata->file_header.e_shnum
7534 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7535 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7536 i, section->sh_link);
7537 break;
7538
7539 case SHT_INIT_ARRAY:
7540 case SHT_FINI_ARRAY:
7541 case SHT_PREINIT_ARRAY:
7542 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7543 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7544 i, section->sh_link);
7545 break;
7546
7547 default:
7548 /* FIXME: Add support for target specific section types. */
7549#if 0 /* Currently we do not check other section types as there are too
7550 many special cases. Stab sections for example have a type
7551 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7552 section. */
7553 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7554 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7555 i, section->sh_link);
7556#endif
7557 break;
7558 }
7559
7560 /* Check the sh_info field. */
7561 switch (section->sh_type)
7562 {
7563 case SHT_REL:
7564 case SHT_RELA:
285e3f99
AM
7565 if (section->sh_info == 0
7566 && (filedata->file_header.e_type == ET_EXEC
7567 || filedata->file_header.e_type == ET_DYN))
7568 /* Dynamic relocations apply to segments, so they do not
7569 need to specify the section they relocate. */
7570 break;
7571 if (section->sh_info == 0
dda8d76d
NC
7572 || section->sh_info >= filedata->file_header.e_shnum
7573 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7574 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7575 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7576 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7577 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7578 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7579 /* FIXME: Are other section types valid ? */
dda8d76d 7580 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7581 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7582 i, section->sh_info);
dd905818
NC
7583 break;
7584
7585 case SHT_DYNAMIC:
7586 case SHT_HASH:
7587 case SHT_SYMTAB_SHNDX:
7588 case SHT_INIT_ARRAY:
7589 case SHT_FINI_ARRAY:
7590 case SHT_PREINIT_ARRAY:
7591 if (section->sh_info != 0)
7592 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7593 i, section->sh_info);
7594 break;
7595
7596 case SHT_GROUP:
7597 case SHT_SYMTAB:
7598 case SHT_DYNSYM:
7599 /* A symbol index - we assume that it is valid. */
7600 break;
7601
7602 default:
7603 /* FIXME: Add support for target specific section types. */
7604 if (section->sh_type == SHT_NOBITS)
7605 /* NOBITS section headers with non-zero sh_info fields can be
7606 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7607 information. The stripped sections have their headers
7608 preserved but their types set to SHT_NOBITS. So do not check
7609 this type of section. */
dd905818
NC
7610 ;
7611 else if (section->sh_flags & SHF_INFO_LINK)
7612 {
dda8d76d 7613 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7614 warn (_("[%2u]: Expected link to another section in info field"), i);
7615 }
a91e1603
L
7616 else if (section->sh_type < SHT_LOOS
7617 && (section->sh_flags & SHF_GNU_MBIND) == 0
7618 && section->sh_info != 0)
dd905818
NC
7619 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7620 i, section->sh_info);
7621 break;
7622 }
7623
3e6b6445 7624 /* Check the sh_size field. */
dda8d76d 7625 if (section->sh_size > filedata->file_size
3e6b6445
NC
7626 && section->sh_type != SHT_NOBITS
7627 && section->sh_type != SHT_NULL
7628 && section->sh_type < SHT_LOOS)
7629 warn (_("Size of section %u is larger than the entire file!\n"), i);
7630
7bfd842d 7631 printf (" [%2u] ", i);
5477e8a0 7632 if (do_section_details)
dda8d76d 7633 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7634 else
84714f86 7635 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7636
ea52a088 7637 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7638 get_section_type_name (filedata, section->sh_type));
0b4362b0 7639
f7a99963
NC
7640 if (is_32bit_elf)
7641 {
cfcac11d
NC
7642 const char * link_too_big = NULL;
7643
f7a99963 7644 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7645
f7a99963
NC
7646 printf ( " %6.6lx %6.6lx %2.2lx",
7647 (unsigned long) section->sh_offset,
7648 (unsigned long) section->sh_size,
7649 (unsigned long) section->sh_entsize);
d1133906 7650
5477e8a0
L
7651 if (do_section_details)
7652 fputs (" ", stdout);
7653 else
dda8d76d 7654 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7655
dda8d76d 7656 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7657 {
7658 link_too_big = "";
7659 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7660 an error but it can have special values in Solaris binaries. */
dda8d76d 7661 switch (filedata->file_header.e_machine)
cfcac11d 7662 {
caa83f8b 7663 case EM_386:
22abe556 7664 case EM_IAMCU:
caa83f8b 7665 case EM_X86_64:
7f502d6c 7666 case EM_L1OM:
7a9068fe 7667 case EM_K1OM:
cfcac11d
NC
7668 case EM_OLD_SPARCV9:
7669 case EM_SPARC32PLUS:
7670 case EM_SPARCV9:
7671 case EM_SPARC:
7672 if (section->sh_link == (SHN_BEFORE & 0xffff))
7673 link_too_big = "BEFORE";
7674 else if (section->sh_link == (SHN_AFTER & 0xffff))
7675 link_too_big = "AFTER";
7676 break;
7677 default:
7678 break;
7679 }
7680 }
7681
7682 if (do_section_details)
7683 {
7684 if (link_too_big != NULL && * link_too_big)
7685 printf ("<%s> ", link_too_big);
7686 else
7687 printf ("%2u ", section->sh_link);
7688 printf ("%3u %2lu\n", section->sh_info,
7689 (unsigned long) section->sh_addralign);
7690 }
7691 else
7692 printf ("%2u %3u %2lu\n",
7693 section->sh_link,
7694 section->sh_info,
7695 (unsigned long) section->sh_addralign);
7696
7697 if (link_too_big && ! * link_too_big)
7698 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7699 i, section->sh_link);
f7a99963 7700 }
d974e256
JJ
7701 else if (do_wide)
7702 {
7703 print_vma (section->sh_addr, LONG_HEX);
7704
7705 if ((long) section->sh_offset == section->sh_offset)
7706 printf (" %6.6lx", (unsigned long) section->sh_offset);
7707 else
7708 {
7709 putchar (' ');
7710 print_vma (section->sh_offset, LONG_HEX);
7711 }
7712
7713 if ((unsigned long) section->sh_size == section->sh_size)
7714 printf (" %6.6lx", (unsigned long) section->sh_size);
7715 else
7716 {
7717 putchar (' ');
7718 print_vma (section->sh_size, LONG_HEX);
7719 }
7720
7721 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7722 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7723 else
7724 {
7725 putchar (' ');
7726 print_vma (section->sh_entsize, LONG_HEX);
7727 }
7728
5477e8a0
L
7729 if (do_section_details)
7730 fputs (" ", stdout);
7731 else
dda8d76d 7732 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7733
72de5009 7734 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7735
7736 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7737 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7738 else
7739 {
7740 print_vma (section->sh_addralign, DEC);
7741 putchar ('\n');
7742 }
7743 }
5477e8a0 7744 else if (do_section_details)
595cf52e 7745 {
55cc53e9 7746 putchar (' ');
595cf52e
L
7747 print_vma (section->sh_addr, LONG_HEX);
7748 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7749 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7750 else
7751 {
7752 printf (" ");
7753 print_vma (section->sh_offset, LONG_HEX);
7754 }
72de5009 7755 printf (" %u\n ", section->sh_link);
595cf52e 7756 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7757 putchar (' ');
595cf52e
L
7758 print_vma (section->sh_entsize, LONG_HEX);
7759
72de5009
AM
7760 printf (" %-16u %lu\n",
7761 section->sh_info,
595cf52e
L
7762 (unsigned long) section->sh_addralign);
7763 }
f7a99963
NC
7764 else
7765 {
7766 putchar (' ');
7767 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7768 if ((long) section->sh_offset == section->sh_offset)
7769 printf (" %8.8lx", (unsigned long) section->sh_offset);
7770 else
7771 {
7772 printf (" ");
7773 print_vma (section->sh_offset, LONG_HEX);
7774 }
f7a99963
NC
7775 printf ("\n ");
7776 print_vma (section->sh_size, LONG_HEX);
7777 printf (" ");
7778 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7779
dda8d76d 7780 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7781
72de5009
AM
7782 printf (" %2u %3u %lu\n",
7783 section->sh_link,
7784 section->sh_info,
f7a99963
NC
7785 (unsigned long) section->sh_addralign);
7786 }
5477e8a0
L
7787
7788 if (do_section_details)
77115a4a 7789 {
dda8d76d 7790 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7791 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7792 {
7793 /* Minimum section size is 12 bytes for 32-bit compression
7794 header + 12 bytes for compressed data header. */
7795 unsigned char buf[24];
d8024a91 7796
77115a4a 7797 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7798 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7799 sizeof (buf), _("compression header")))
7800 {
7801 Elf_Internal_Chdr chdr;
d8024a91 7802
5844b465
NC
7803 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7804 printf (_(" [<corrupt>]\n"));
77115a4a 7805 else
5844b465 7806 {
89dbeac7 7807 if (chdr.ch_type == ch_compress_zlib)
5844b465 7808 printf (" ZLIB, ");
89dbeac7 7809 else if (chdr.ch_type == ch_compress_zstd)
1369522f 7810 printf (" ZSTD, ");
5844b465
NC
7811 else
7812 printf (_(" [<unknown>: 0x%x], "),
7813 chdr.ch_type);
7814 print_vma (chdr.ch_size, LONG_HEX);
7815 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7816 }
77115a4a
L
7817 }
7818 }
7819 }
252b5132
RH
7820 }
7821
5477e8a0 7822 if (!do_section_details)
3dbcc61d 7823 {
9fb71ee4
NC
7824 /* The ordering of the letters shown here matches the ordering of the
7825 corresponding SHF_xxx values, and hence the order in which these
7826 letters will be displayed to the user. */
7827 printf (_("Key to Flags:\n\
7828 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7829 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7830 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7831 switch (filedata->file_header.e_ident[EI_OSABI])
7832 {
7833 case ELFOSABI_GNU:
7834 case ELFOSABI_FREEBSD:
7835 printf (_("R (retain), "));
7836 /* Fall through */
7837 case ELFOSABI_NONE:
7838 printf (_("D (mbind), "));
7839 break;
7840 default:
7841 break;
7842 }
dda8d76d
NC
7843 if (filedata->file_header.e_machine == EM_X86_64
7844 || filedata->file_header.e_machine == EM_L1OM
7845 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7846 printf (_("l (large), "));
dda8d76d 7847 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7848 printf (_("y (purecode), "));
dda8d76d 7849 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7850 printf (_("v (VLE), "));
9fb71ee4 7851 printf ("p (processor specific)\n");
0b4362b0 7852 }
d1133906 7853
015dc7e1 7854 return true;
252b5132
RH
7855}
7856
015dc7e1 7857static bool
28d13567 7858get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
26c527e6
AM
7859 Elf_Internal_Sym **symtab, uint64_t *nsyms,
7860 char **strtab, uint64_t *strtablen)
28d13567
AM
7861{
7862 *strtab = NULL;
7863 *strtablen = 0;
4de91c10 7864 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7865
7866 if (*symtab == NULL)
015dc7e1 7867 return false;
28d13567
AM
7868
7869 if (symsec->sh_link != 0)
7870 {
7871 Elf_Internal_Shdr *strsec;
7872
7873 if (symsec->sh_link >= filedata->file_header.e_shnum)
7874 {
7875 error (_("Bad sh_link in symbol table section\n"));
7876 free (*symtab);
7877 *symtab = NULL;
7878 *nsyms = 0;
015dc7e1 7879 return false;
28d13567
AM
7880 }
7881
7882 strsec = filedata->section_headers + symsec->sh_link;
7883
7884 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7885 1, strsec->sh_size, _("string table"));
7886 if (*strtab == NULL)
7887 {
7888 free (*symtab);
7889 *symtab = NULL;
7890 *nsyms = 0;
015dc7e1 7891 return false;
28d13567
AM
7892 }
7893 *strtablen = strsec->sh_size;
7894 }
015dc7e1 7895 return true;
28d13567
AM
7896}
7897
f5842774
L
7898static const char *
7899get_group_flags (unsigned int flags)
7900{
1449284b 7901 static char buff[128];
220453ec 7902
6d913794
NC
7903 if (flags == 0)
7904 return "";
7905 else if (flags == GRP_COMDAT)
7906 return "COMDAT ";
f5842774 7907
89246a0e
AM
7908 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7909 flags,
7910 flags & GRP_MASKOS ? _("<OS specific>") : "",
7911 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7912 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7913 ? _("<unknown>") : ""));
6d913794 7914
f5842774
L
7915 return buff;
7916}
7917
015dc7e1 7918static bool
dda8d76d 7919process_section_groups (Filedata * filedata)
f5842774 7920{
2cf0635d 7921 Elf_Internal_Shdr * section;
f5842774 7922 unsigned int i;
2cf0635d
NC
7923 struct group * group;
7924 Elf_Internal_Shdr * symtab_sec;
7925 Elf_Internal_Shdr * strtab_sec;
7926 Elf_Internal_Sym * symtab;
26c527e6 7927 uint64_t num_syms;
2cf0635d 7928 char * strtab;
c256ffe7 7929 size_t strtab_size;
d1f5c6e3
L
7930
7931 /* Don't process section groups unless needed. */
7932 if (!do_unwind && !do_section_groups)
015dc7e1 7933 return true;
f5842774 7934
dda8d76d 7935 if (filedata->file_header.e_shnum == 0)
f5842774
L
7936 {
7937 if (do_section_groups)
ca0e11aa
NC
7938 {
7939 if (filedata->is_separate)
7940 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7941 filedata->file_name);
7942 else
7943 printf (_("\nThere are no section groups in this file.\n"));
7944 }
015dc7e1 7945 return true;
f5842774
L
7946 }
7947
dda8d76d 7948 if (filedata->section_headers == NULL)
f5842774
L
7949 {
7950 error (_("Section headers are not available!\n"));
fa1908fd 7951 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7952 return false;
f5842774
L
7953 }
7954
978c4450
AM
7955 filedata->section_headers_groups
7956 = (struct group **) calloc (filedata->file_header.e_shnum,
7957 sizeof (struct group *));
e4b17d5c 7958
978c4450 7959 if (filedata->section_headers_groups == NULL)
e4b17d5c 7960 {
8b73c356 7961 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7962 filedata->file_header.e_shnum);
015dc7e1 7963 return false;
e4b17d5c
L
7964 }
7965
f5842774 7966 /* Scan the sections for the group section. */
978c4450 7967 filedata->group_count = 0;
dda8d76d
NC
7968 for (i = 0, section = filedata->section_headers;
7969 i < filedata->file_header.e_shnum;
f5842774 7970 i++, section++)
e4b17d5c 7971 if (section->sh_type == SHT_GROUP)
978c4450 7972 filedata->group_count++;
e4b17d5c 7973
978c4450 7974 if (filedata->group_count == 0)
d1f5c6e3
L
7975 {
7976 if (do_section_groups)
ca0e11aa
NC
7977 {
7978 if (filedata->is_separate)
7979 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7980 filedata->file_name);
7981 else
7982 printf (_("\nThere are no section groups in this file.\n"));
7983 }
d1f5c6e3 7984
015dc7e1 7985 return true;
d1f5c6e3
L
7986 }
7987
978c4450
AM
7988 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7989 sizeof (struct group));
e4b17d5c 7990
978c4450 7991 if (filedata->section_groups == NULL)
e4b17d5c 7992 {
26c527e6 7993 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
015dc7e1 7994 return false;
e4b17d5c
L
7995 }
7996
d1f5c6e3
L
7997 symtab_sec = NULL;
7998 strtab_sec = NULL;
7999 symtab = NULL;
ba5cdace 8000 num_syms = 0;
d1f5c6e3 8001 strtab = NULL;
c256ffe7 8002 strtab_size = 0;
ca0e11aa
NC
8003
8004 if (filedata->is_separate)
8005 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 8006
978c4450 8007 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 8008 i < filedata->file_header.e_shnum;
e4b17d5c 8009 i++, section++)
f5842774
L
8010 {
8011 if (section->sh_type == SHT_GROUP)
8012 {
dda8d76d 8013 const char * name = printable_section_name (filedata, section);
74e1a04b 8014 const char * group_name;
2cf0635d
NC
8015 unsigned char * start;
8016 unsigned char * indices;
f5842774 8017 unsigned int entry, j, size;
2cf0635d
NC
8018 Elf_Internal_Shdr * sec;
8019 Elf_Internal_Sym * sym;
f5842774
L
8020
8021 /* Get the symbol table. */
dda8d76d
NC
8022 if (section->sh_link >= filedata->file_header.e_shnum
8023 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 8024 != SHT_SYMTAB))
f5842774
L
8025 {
8026 error (_("Bad sh_link in group section `%s'\n"), name);
8027 continue;
8028 }
d1f5c6e3
L
8029
8030 if (symtab_sec != sec)
8031 {
8032 symtab_sec = sec;
9db70fc3 8033 free (symtab);
4de91c10 8034 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 8035 }
f5842774 8036
dd24e3da
NC
8037 if (symtab == NULL)
8038 {
8039 error (_("Corrupt header in group section `%s'\n"), name);
8040 continue;
8041 }
8042
ba5cdace
NC
8043 if (section->sh_info >= num_syms)
8044 {
8045 error (_("Bad sh_info in group section `%s'\n"), name);
8046 continue;
8047 }
8048
f5842774
L
8049 sym = symtab + section->sh_info;
8050
8051 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8052 {
4fbb74a6 8053 if (sym->st_shndx == 0
dda8d76d 8054 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
8055 {
8056 error (_("Bad sh_info in group section `%s'\n"), name);
8057 continue;
8058 }
ba2685cc 8059
84714f86
AM
8060 group_name = section_name_print (filedata,
8061 filedata->section_headers
b9e920ec 8062 + sym->st_shndx);
c256ffe7 8063 strtab_sec = NULL;
9db70fc3 8064 free (strtab);
f5842774 8065 strtab = NULL;
c256ffe7 8066 strtab_size = 0;
f5842774
L
8067 }
8068 else
8069 {
8070 /* Get the string table. */
dda8d76d 8071 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8072 {
8073 strtab_sec = NULL;
9db70fc3 8074 free (strtab);
c256ffe7
JJ
8075 strtab = NULL;
8076 strtab_size = 0;
8077 }
8078 else if (strtab_sec
dda8d76d 8079 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8080 {
8081 strtab_sec = sec;
9db70fc3 8082 free (strtab);
071436c6 8083
dda8d76d 8084 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8085 1, strtab_sec->sh_size,
8086 _("string table"));
c256ffe7 8087 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8088 }
c256ffe7 8089 group_name = sym->st_name < strtab_size
2b692964 8090 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8091 }
8092
c9c1d674
EG
8093 /* PR 17531: file: loop. */
8094 if (section->sh_entsize > section->sh_size)
8095 {
26c527e6
AM
8096 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8097 " which is larger than its size (%#" PRIx64 ")\n"),
dda8d76d 8098 printable_section_name (filedata, section),
26c527e6
AM
8099 section->sh_entsize,
8100 section->sh_size);
61dd8e19 8101 continue;
c9c1d674
EG
8102 }
8103
dda8d76d 8104 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8105 1, section->sh_size,
8106 _("section data"));
59245841
NC
8107 if (start == NULL)
8108 continue;
f5842774
L
8109
8110 indices = start;
8111 size = (section->sh_size / section->sh_entsize) - 1;
8112 entry = byte_get (indices, 4);
8113 indices += 4;
e4b17d5c
L
8114
8115 if (do_section_groups)
8116 {
2b692964 8117 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8118 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8119
e4b17d5c
L
8120 printf (_(" [Index] Name\n"));
8121 }
8122
8123 group->group_index = i;
8124
f5842774
L
8125 for (j = 0; j < size; j++)
8126 {
2cf0635d 8127 struct group_list * g;
e4b17d5c 8128
f5842774
L
8129 entry = byte_get (indices, 4);
8130 indices += 4;
8131
dda8d76d 8132 if (entry >= filedata->file_header.e_shnum)
391cb864 8133 {
57028622
NC
8134 static unsigned num_group_errors = 0;
8135
8136 if (num_group_errors ++ < 10)
8137 {
8138 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8139 entry, i, filedata->file_header.e_shnum - 1);
57028622 8140 if (num_group_errors == 10)
67ce483b 8141 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8142 }
391cb864
L
8143 continue;
8144 }
391cb864 8145
978c4450 8146 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8147 {
d1f5c6e3
L
8148 if (entry)
8149 {
57028622
NC
8150 static unsigned num_errs = 0;
8151
8152 if (num_errs ++ < 10)
8153 {
8154 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8155 entry, i,
978c4450 8156 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8157 if (num_errs == 10)
8158 warn (_("Further error messages about already contained group sections suppressed\n"));
8159 }
d1f5c6e3
L
8160 continue;
8161 }
8162 else
8163 {
8164 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8165 section group. We just warn it the first time
d1f5c6e3 8166 and ignore it afterwards. */
015dc7e1 8167 static bool warned = false;
d1f5c6e3
L
8168 if (!warned)
8169 {
8170 error (_("section 0 in group section [%5u]\n"),
978c4450 8171 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8172 warned = true;
d1f5c6e3
L
8173 }
8174 }
e4b17d5c
L
8175 }
8176
978c4450 8177 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8178
8179 if (do_section_groups)
8180 {
dda8d76d
NC
8181 sec = filedata->section_headers + entry;
8182 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8183 }
8184
3f5e193b 8185 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8186 g->section_index = entry;
8187 g->next = group->root;
8188 group->root = g;
f5842774
L
8189 }
8190
9db70fc3 8191 free (start);
e4b17d5c
L
8192
8193 group++;
f5842774
L
8194 }
8195 }
8196
9db70fc3
AM
8197 free (symtab);
8198 free (strtab);
015dc7e1 8199 return true;
f5842774
L
8200}
8201
28f997cf
TG
8202/* Data used to display dynamic fixups. */
8203
8204struct ia64_vms_dynfixup
8205{
625d49fc
AM
8206 uint64_t needed_ident; /* Library ident number. */
8207 uint64_t needed; /* Index in the dstrtab of the library name. */
8208 uint64_t fixup_needed; /* Index of the library. */
8209 uint64_t fixup_rela_cnt; /* Number of fixups. */
8210 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8211};
8212
8213/* Data used to display dynamic relocations. */
8214
8215struct ia64_vms_dynimgrela
8216{
625d49fc
AM
8217 uint64_t img_rela_cnt; /* Number of relocations. */
8218 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8219};
8220
8221/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8222 library). */
8223
015dc7e1 8224static bool
dda8d76d
NC
8225dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8226 struct ia64_vms_dynfixup * fixup,
8227 const char * strtab,
8228 unsigned int strtab_sz)
28f997cf 8229{
32ec8896 8230 Elf64_External_VMS_IMAGE_FIXUP * imfs;
26c527e6 8231 size_t i;
32ec8896 8232 const char * lib_name;
28f997cf 8233
978c4450
AM
8234 imfs = get_data (NULL, filedata,
8235 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8236 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8237 _("dynamic section image fixups"));
8238 if (!imfs)
015dc7e1 8239 return false;
28f997cf
TG
8240
8241 if (fixup->needed < strtab_sz)
8242 lib_name = strtab + fixup->needed;
8243 else
8244 {
26c527e6
AM
8245 warn (_("corrupt library name index of %#" PRIx64
8246 " found in dynamic entry"), fixup->needed);
28f997cf
TG
8247 lib_name = "???";
8248 }
736990c4 8249
26c527e6
AM
8250 printf (_("\nImage fixups for needed library #%" PRId64
8251 ": %s - ident: %" PRIx64 "\n"),
8252 fixup->fixup_needed, lib_name, fixup->needed_ident);
28f997cf
TG
8253 printf
8254 (_("Seg Offset Type SymVec DataType\n"));
8255
26c527e6 8256 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
28f997cf
TG
8257 {
8258 unsigned int type;
8259 const char *rtype;
8260
8261 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8262 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8263 type = BYTE_GET (imfs [i].type);
8264 rtype = elf_ia64_reloc_type (type);
8265 if (rtype == NULL)
f493c217 8266 printf ("0x%08x ", type);
28f997cf 8267 else
f493c217 8268 printf ("%-32s ", rtype);
28f997cf
TG
8269 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8270 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8271 }
8272
8273 free (imfs);
015dc7e1 8274 return true;
28f997cf
TG
8275}
8276
8277/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8278
015dc7e1 8279static bool
dda8d76d 8280dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8281{
8282 Elf64_External_VMS_IMAGE_RELA *imrs;
26c527e6 8283 size_t i;
28f997cf 8284
978c4450
AM
8285 imrs = get_data (NULL, filedata,
8286 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8287 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8288 _("dynamic section image relocations"));
28f997cf 8289 if (!imrs)
015dc7e1 8290 return false;
28f997cf
TG
8291
8292 printf (_("\nImage relocs\n"));
8293 printf
8294 (_("Seg Offset Type Addend Seg Sym Off\n"));
8295
26c527e6 8296 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
28f997cf
TG
8297 {
8298 unsigned int type;
8299 const char *rtype;
8300
8301 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8302 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8303 type = BYTE_GET (imrs [i].type);
8304 rtype = elf_ia64_reloc_type (type);
8305 if (rtype == NULL)
8306 printf ("0x%08x ", type);
8307 else
8308 printf ("%-31s ", rtype);
8309 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8310 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8311 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8312 }
8313
8314 free (imrs);
015dc7e1 8315 return true;
28f997cf
TG
8316}
8317
8318/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8319
015dc7e1 8320static bool
dda8d76d 8321process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8322{
8323 struct ia64_vms_dynfixup fixup;
8324 struct ia64_vms_dynimgrela imgrela;
8325 Elf_Internal_Dyn *entry;
625d49fc
AM
8326 uint64_t strtab_off = 0;
8327 uint64_t strtab_sz = 0;
28f997cf 8328 char *strtab = NULL;
015dc7e1 8329 bool res = true;
28f997cf
TG
8330
8331 memset (&fixup, 0, sizeof (fixup));
8332 memset (&imgrela, 0, sizeof (imgrela));
8333
8334 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8335 for (entry = filedata->dynamic_section;
8336 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8337 entry++)
8338 {
8339 switch (entry->d_tag)
8340 {
8341 case DT_IA_64_VMS_STRTAB_OFFSET:
8342 strtab_off = entry->d_un.d_val;
8343 break;
8344 case DT_STRSZ:
8345 strtab_sz = entry->d_un.d_val;
8346 if (strtab == NULL)
978c4450
AM
8347 strtab = get_data (NULL, filedata,
8348 filedata->dynamic_addr + strtab_off,
28f997cf 8349 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8350 if (strtab == NULL)
8351 strtab_sz = 0;
28f997cf
TG
8352 break;
8353
8354 case DT_IA_64_VMS_NEEDED_IDENT:
8355 fixup.needed_ident = entry->d_un.d_val;
8356 break;
8357 case DT_NEEDED:
8358 fixup.needed = entry->d_un.d_val;
8359 break;
8360 case DT_IA_64_VMS_FIXUP_NEEDED:
8361 fixup.fixup_needed = entry->d_un.d_val;
8362 break;
8363 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8364 fixup.fixup_rela_cnt = entry->d_un.d_val;
8365 break;
8366 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8367 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8368 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8369 res = false;
28f997cf 8370 break;
28f997cf
TG
8371 case DT_IA_64_VMS_IMG_RELA_CNT:
8372 imgrela.img_rela_cnt = entry->d_un.d_val;
8373 break;
8374 case DT_IA_64_VMS_IMG_RELA_OFF:
8375 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8376 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8377 res = false;
28f997cf
TG
8378 break;
8379
8380 default:
8381 break;
8382 }
8383 }
8384
9db70fc3 8385 free (strtab);
28f997cf
TG
8386
8387 return res;
8388}
8389
85b1c36d 8390static struct
566b0d53 8391{
2cf0635d 8392 const char * name;
566b0d53
L
8393 int reloc;
8394 int size;
a7fd1186 8395 relocation_type rel_type;
32ec8896
NC
8396}
8397 dynamic_relocations [] =
566b0d53 8398{
a7fd1186
FS
8399 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8400 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8401 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8402 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8403};
8404
252b5132 8405/* Process the reloc section. */
18bd398b 8406
015dc7e1 8407static bool
dda8d76d 8408process_relocs (Filedata * filedata)
252b5132 8409{
26c527e6
AM
8410 uint64_t rel_size;
8411 uint64_t rel_offset;
252b5132 8412
252b5132 8413 if (!do_reloc)
015dc7e1 8414 return true;
252b5132
RH
8415
8416 if (do_using_dynamic)
8417 {
a7fd1186 8418 relocation_type rel_type;
2cf0635d 8419 const char * name;
015dc7e1 8420 bool has_dynamic_reloc;
566b0d53 8421 unsigned int i;
0de14b54 8422
015dc7e1 8423 has_dynamic_reloc = false;
252b5132 8424
566b0d53 8425 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8426 {
a7fd1186 8427 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8428 name = dynamic_relocations [i].name;
978c4450
AM
8429 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8430 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8431
32ec8896 8432 if (rel_size)
015dc7e1 8433 has_dynamic_reloc = true;
566b0d53 8434
a7fd1186 8435 if (rel_type == reltype_unknown)
aa903cfb 8436 {
566b0d53 8437 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8438 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8439 {
8440 case DT_REL:
a7fd1186 8441 rel_type = reltype_rel;
566b0d53
L
8442 break;
8443 case DT_RELA:
a7fd1186 8444 rel_type = reltype_rela;
566b0d53
L
8445 break;
8446 }
aa903cfb 8447 }
252b5132 8448
566b0d53
L
8449 if (rel_size)
8450 {
ca0e11aa
NC
8451 if (filedata->is_separate)
8452 printf
26c527e6
AM
8453 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
8454 " contains %" PRId64 " bytes:\n"),
ca0e11aa
NC
8455 filedata->file_name, name, rel_offset, rel_size);
8456 else
8457 printf
26c527e6
AM
8458 (_("\n'%s' relocation section at offset %#" PRIx64
8459 " contains %" PRId64 " bytes:\n"),
ca0e11aa 8460 name, rel_offset, rel_size);
252b5132 8461
dda8d76d
NC
8462 dump_relocations (filedata,
8463 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8464 rel_size,
978c4450
AM
8465 filedata->dynamic_symbols,
8466 filedata->num_dynamic_syms,
8467 filedata->dynamic_strings,
8468 filedata->dynamic_strings_length,
a7fd1186 8469 rel_type, true /* is_dynamic */);
566b0d53 8470 }
252b5132 8471 }
566b0d53 8472
dda8d76d
NC
8473 if (is_ia64_vms (filedata))
8474 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8475 has_dynamic_reloc = true;
28f997cf 8476
566b0d53 8477 if (! has_dynamic_reloc)
ca0e11aa
NC
8478 {
8479 if (filedata->is_separate)
8480 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8481 filedata->file_name);
8482 else
8483 printf (_("\nThere are no dynamic relocations in this file.\n"));
8484 }
252b5132
RH
8485 }
8486 else
8487 {
2cf0635d 8488 Elf_Internal_Shdr * section;
26c527e6 8489 size_t i;
015dc7e1 8490 bool found = false;
252b5132 8491
dda8d76d
NC
8492 for (i = 0, section = filedata->section_headers;
8493 i < filedata->file_header.e_shnum;
b34976b6 8494 i++, section++)
252b5132
RH
8495 {
8496 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8497 && section->sh_type != SHT_REL
8498 && section->sh_type != SHT_RELR)
252b5132
RH
8499 continue;
8500
8501 rel_offset = section->sh_offset;
8502 rel_size = section->sh_size;
8503
8504 if (rel_size)
8505 {
a7fd1186 8506 relocation_type rel_type;
26c527e6 8507 uint64_t num_rela;
103f02d3 8508
ca0e11aa
NC
8509 if (filedata->is_separate)
8510 printf (_("\nIn linked file '%s' relocation section "),
8511 filedata->file_name);
8512 else
8513 printf (_("\nRelocation section "));
252b5132 8514
dda8d76d 8515 if (filedata->string_table == NULL)
19936277 8516 printf ("%d", section->sh_name);
252b5132 8517 else
dda8d76d 8518 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8519
d3a49aa8 8520 num_rela = rel_size / section->sh_entsize;
26c527e6
AM
8521 printf (ngettext (" at offset %#" PRIx64
8522 " contains %" PRIu64 " entry:\n",
8523 " at offset %#" PRIx64
8524 " contains %" PRId64 " entries:\n",
d3a49aa8
AM
8525 num_rela),
8526 rel_offset, num_rela);
252b5132 8527
a7fd1186
FS
8528 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8529 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8530
4fbb74a6 8531 if (section->sh_link != 0
dda8d76d 8532 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8533 {
26c527e6
AM
8534 Elf_Internal_Shdr *symsec;
8535 Elf_Internal_Sym *symtab;
8536 uint64_t nsyms;
8537 uint64_t strtablen = 0;
8538 char *strtab = NULL;
57346661 8539
dda8d76d 8540 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8541 if (symsec->sh_type != SHT_SYMTAB
8542 && symsec->sh_type != SHT_DYNSYM)
8543 continue;
8544
28d13567
AM
8545 if (!get_symtab (filedata, symsec,
8546 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8547 continue;
252b5132 8548
dda8d76d 8549 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8550 symtab, nsyms, strtab, strtablen,
a7fd1186 8551 rel_type,
bb4d2ac2 8552 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8553 free (strtab);
d79b3d50
NC
8554 free (symtab);
8555 }
8556 else
dda8d76d 8557 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8558 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8559
015dc7e1 8560 found = true;
252b5132
RH
8561 }
8562 }
8563
8564 if (! found)
45ac8f4f
NC
8565 {
8566 /* Users sometimes forget the -D option, so try to be helpful. */
8567 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8568 {
978c4450 8569 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8570 {
ca0e11aa
NC
8571 if (filedata->is_separate)
8572 printf (_("\nThere are no static relocations in linked file '%s'."),
8573 filedata->file_name);
8574 else
8575 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8576 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8577
8578 break;
8579 }
8580 }
8581 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8582 {
8583 if (filedata->is_separate)
8584 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8585 filedata->file_name);
8586 else
8587 printf (_("\nThere are no relocations in this file.\n"));
8588 }
45ac8f4f 8589 }
252b5132
RH
8590 }
8591
015dc7e1 8592 return true;
252b5132
RH
8593}
8594
4d6ed7c8
NC
8595/* An absolute address consists of a section and an offset. If the
8596 section is NULL, the offset itself is the address, otherwise, the
8597 address equals to LOAD_ADDRESS(section) + offset. */
8598
8599struct absaddr
948f632f
DA
8600{
8601 unsigned short section;
625d49fc 8602 uint64_t offset;
948f632f 8603};
4d6ed7c8 8604
948f632f
DA
8605/* Find the nearest symbol at or below ADDR. Returns the symbol
8606 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8607
4d6ed7c8 8608static void
26c527e6
AM
8609find_symbol_for_address (Filedata *filedata,
8610 Elf_Internal_Sym *symtab,
8611 uint64_t nsyms,
8612 const char *strtab,
8613 uint64_t strtab_size,
8614 struct absaddr addr,
8615 const char **symname,
8616 uint64_t *offset)
4d6ed7c8 8617{
625d49fc 8618 uint64_t dist = 0x100000;
2cf0635d 8619 Elf_Internal_Sym * sym;
948f632f
DA
8620 Elf_Internal_Sym * beg;
8621 Elf_Internal_Sym * end;
2cf0635d 8622 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8623
0b6ae522 8624 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8625 beg = symtab;
8626 end = symtab + nsyms;
0b6ae522 8627
948f632f 8628 while (beg < end)
4d6ed7c8 8629 {
625d49fc 8630 uint64_t value;
948f632f
DA
8631
8632 sym = beg + (end - beg) / 2;
0b6ae522 8633
948f632f 8634 value = sym->st_value;
0b6ae522
DJ
8635 REMOVE_ARCH_BITS (value);
8636
948f632f 8637 if (sym->st_name != 0
4d6ed7c8 8638 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8639 && addr.offset >= value
8640 && addr.offset - value < dist)
4d6ed7c8
NC
8641 {
8642 best = sym;
0b6ae522 8643 dist = addr.offset - value;
4d6ed7c8
NC
8644 if (!dist)
8645 break;
8646 }
948f632f
DA
8647
8648 if (addr.offset < value)
8649 end = sym;
8650 else
8651 beg = sym + 1;
4d6ed7c8 8652 }
1b31d05e 8653
4d6ed7c8
NC
8654 if (best)
8655 {
57346661 8656 *symname = (best->st_name >= strtab_size
2b692964 8657 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8658 *offset = dist;
8659 return;
8660 }
1b31d05e 8661
4d6ed7c8
NC
8662 *symname = NULL;
8663 *offset = addr.offset;
8664}
8665
32ec8896 8666static /* signed */ int
948f632f
DA
8667symcmp (const void *p, const void *q)
8668{
8669 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8670 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8671
8672 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8673}
8674
8675/* Process the unwind section. */
8676
8677#include "unwind-ia64.h"
8678
8679struct ia64_unw_table_entry
8680{
8681 struct absaddr start;
8682 struct absaddr end;
8683 struct absaddr info;
8684};
8685
8686struct ia64_unw_aux_info
8687{
32ec8896 8688 struct ia64_unw_table_entry * table; /* Unwind table. */
26c527e6 8689 uint64_t table_len; /* Length of unwind table. */
32ec8896 8690 unsigned char * info; /* Unwind info. */
26c527e6 8691 uint64_t info_size; /* Size of unwind info. */
625d49fc
AM
8692 uint64_t info_addr; /* Starting address of unwind info. */
8693 uint64_t seg_base; /* Starting address of segment. */
32ec8896 8694 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 8695 uint64_t nsyms; /* Number of symbols. */
32ec8896 8696 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 8697 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 8698 char * strtab; /* The string table. */
26c527e6 8699 uint64_t strtab_size; /* Size of string table. */
948f632f
DA
8700};
8701
015dc7e1 8702static bool
dda8d76d 8703dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8704{
2cf0635d 8705 struct ia64_unw_table_entry * tp;
26c527e6 8706 size_t j, nfuns;
4d6ed7c8 8707 int in_body;
015dc7e1 8708 bool res = true;
7036c0e1 8709
948f632f
DA
8710 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8711 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8712 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8713 aux->funtab[nfuns++] = aux->symtab[j];
8714 aux->nfuns = nfuns;
8715 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8716
4d6ed7c8
NC
8717 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8718 {
625d49fc
AM
8719 uint64_t stamp;
8720 uint64_t offset;
2cf0635d
NC
8721 const unsigned char * dp;
8722 const unsigned char * head;
53774b7e 8723 const unsigned char * end;
2cf0635d 8724 const char * procname;
4d6ed7c8 8725
dda8d76d 8726 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8727 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8728
8729 fputs ("\n<", stdout);
8730
8731 if (procname)
8732 {
8733 fputs (procname, stdout);
8734
8735 if (offset)
26c527e6 8736 printf ("+%" PRIx64, offset);
4d6ed7c8
NC
8737 }
8738
8739 fputs (">: [", stdout);
8740 print_vma (tp->start.offset, PREFIX_HEX);
8741 fputc ('-', stdout);
8742 print_vma (tp->end.offset, PREFIX_HEX);
26c527e6
AM
8743 printf ("], info at +0x%" PRIx64 "\n",
8744 tp->info.offset - aux->seg_base);
4d6ed7c8 8745
53774b7e
NC
8746 /* PR 17531: file: 86232b32. */
8747 if (aux->info == NULL)
8748 continue;
8749
97c0a079
AM
8750 offset = tp->info.offset;
8751 if (tp->info.section)
8752 {
8753 if (tp->info.section >= filedata->file_header.e_shnum)
8754 {
26c527e6
AM
8755 warn (_("Invalid section %u in table entry %td\n"),
8756 tp->info.section, tp - aux->table);
015dc7e1 8757 res = false;
97c0a079
AM
8758 continue;
8759 }
8760 offset += filedata->section_headers[tp->info.section].sh_addr;
8761 }
8762 offset -= aux->info_addr;
53774b7e 8763 /* PR 17531: file: 0997b4d1. */
90679903
AM
8764 if (offset >= aux->info_size
8765 || aux->info_size - offset < 8)
53774b7e 8766 {
26c527e6
AM
8767 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
8768 tp->info.offset, tp - aux->table);
015dc7e1 8769 res = false;
53774b7e
NC
8770 continue;
8771 }
8772
97c0a079 8773 head = aux->info + offset;
a4a00738 8774 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8775
86f55779 8776 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8777 (unsigned) UNW_VER (stamp),
8778 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8779 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8780 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8781 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8782
8783 if (UNW_VER (stamp) != 1)
8784 {
2b692964 8785 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8786 continue;
8787 }
8788
8789 in_body = 0;
53774b7e
NC
8790 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8791 /* PR 17531: file: 16ceda89. */
8792 if (end > aux->info + aux->info_size)
8793 end = aux->info + aux->info_size;
8794 for (dp = head + 8; dp < end;)
b4477bc8 8795 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8796 }
948f632f
DA
8797
8798 free (aux->funtab);
32ec8896
NC
8799
8800 return res;
4d6ed7c8
NC
8801}
8802
015dc7e1 8803static bool
dda8d76d
NC
8804slurp_ia64_unwind_table (Filedata * filedata,
8805 struct ia64_unw_aux_info * aux,
8806 Elf_Internal_Shdr * sec)
4d6ed7c8 8807{
26c527e6 8808 uint64_t size, nrelas, i;
2cf0635d
NC
8809 Elf_Internal_Phdr * seg;
8810 struct ia64_unw_table_entry * tep;
8811 Elf_Internal_Shdr * relsec;
8812 Elf_Internal_Rela * rela;
8813 Elf_Internal_Rela * rp;
8814 unsigned char * table;
8815 unsigned char * tp;
8816 Elf_Internal_Sym * sym;
8817 const char * relname;
4d6ed7c8 8818
53774b7e
NC
8819 aux->table_len = 0;
8820
4d6ed7c8
NC
8821 /* First, find the starting address of the segment that includes
8822 this section: */
8823
dda8d76d 8824 if (filedata->file_header.e_phnum)
4d6ed7c8 8825 {
dda8d76d 8826 if (! get_program_headers (filedata))
015dc7e1 8827 return false;
4d6ed7c8 8828
dda8d76d
NC
8829 for (seg = filedata->program_headers;
8830 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8831 ++seg)
4d6ed7c8
NC
8832 {
8833 if (seg->p_type != PT_LOAD)
8834 continue;
8835
8836 if (sec->sh_addr >= seg->p_vaddr
8837 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8838 {
8839 aux->seg_base = seg->p_vaddr;
8840 break;
8841 }
8842 }
4d6ed7c8
NC
8843 }
8844
8845 /* Second, build the unwind table from the contents of the unwind section: */
8846 size = sec->sh_size;
dda8d76d 8847 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8848 _("unwind table"));
a6e9f9df 8849 if (!table)
015dc7e1 8850 return false;
4d6ed7c8 8851
53774b7e 8852 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8853 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8854 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8855 tep = aux->table;
53774b7e
NC
8856
8857 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8858 {
8859 tep->start.section = SHN_UNDEF;
8860 tep->end.section = SHN_UNDEF;
8861 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8862 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8863 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8864 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8865 tep->start.offset += aux->seg_base;
8866 tep->end.offset += aux->seg_base;
8867 tep->info.offset += aux->seg_base;
8868 }
8869 free (table);
8870
41e92641 8871 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8872 for (relsec = filedata->section_headers;
8873 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8874 ++relsec)
8875 {
8876 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8877 || relsec->sh_info >= filedata->file_header.e_shnum
8878 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8879 continue;
8880
dda8d76d 8881 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8882 & rela, & nrelas))
53774b7e
NC
8883 {
8884 free (aux->table);
8885 aux->table = NULL;
8886 aux->table_len = 0;
015dc7e1 8887 return false;
53774b7e 8888 }
4d6ed7c8
NC
8889
8890 for (rp = rela; rp < rela + nrelas; ++rp)
8891 {
4770fb94 8892 unsigned int sym_ndx;
726bd37d
AM
8893 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8894 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8895
82b1b41b
NC
8896 /* PR 17531: file: 9fa67536. */
8897 if (relname == NULL)
8898 {
726bd37d 8899 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8900 continue;
8901 }
948f632f 8902
24d127aa 8903 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8904 {
82b1b41b 8905 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8906 continue;
8907 }
8908
89fac5e3 8909 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8910
53774b7e
NC
8911 /* PR 17531: file: 5bc8d9bf. */
8912 if (i >= aux->table_len)
8913 {
26c527e6
AM
8914 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
8915 i);
53774b7e
NC
8916 continue;
8917 }
8918
4770fb94
AM
8919 sym_ndx = get_reloc_symindex (rp->r_info);
8920 if (sym_ndx >= aux->nsyms)
8921 {
8922 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8923 sym_ndx);
8924 continue;
8925 }
8926 sym = aux->symtab + sym_ndx;
8927
53774b7e 8928 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8929 {
8930 case 0:
8931 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8932 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8933 break;
8934 case 1:
8935 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8936 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8937 break;
8938 case 2:
8939 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8940 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8941 break;
8942 default:
8943 break;
8944 }
8945 }
8946
8947 free (rela);
8948 }
8949
015dc7e1 8950 return true;
4d6ed7c8
NC
8951}
8952
015dc7e1 8953static bool
dda8d76d 8954ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8955{
2cf0635d
NC
8956 Elf_Internal_Shdr * sec;
8957 Elf_Internal_Shdr * unwsec = NULL;
26c527e6 8958 uint64_t i, unwcount = 0, unwstart = 0;
57346661 8959 struct ia64_unw_aux_info aux;
015dc7e1 8960 bool res = true;
f1467e33 8961
4d6ed7c8
NC
8962 memset (& aux, 0, sizeof (aux));
8963
dda8d76d 8964 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8965 {
28d13567 8966 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8967 {
28d13567 8968 if (aux.symtab)
4082ef84 8969 {
28d13567
AM
8970 error (_("Multiple symbol tables encountered\n"));
8971 free (aux.symtab);
8972 aux.symtab = NULL;
4082ef84 8973 free (aux.strtab);
28d13567 8974 aux.strtab = NULL;
4082ef84 8975 }
28d13567
AM
8976 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8977 &aux.strtab, &aux.strtab_size))
015dc7e1 8978 return false;
4d6ed7c8
NC
8979 }
8980 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8981 unwcount++;
8982 }
8983
8984 if (!unwcount)
8985 printf (_("\nThere are no unwind sections in this file.\n"));
8986
8987 while (unwcount-- > 0)
8988 {
84714f86 8989 const char *suffix;
579f31ac
JJ
8990 size_t len, len2;
8991
dda8d76d
NC
8992 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8993 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8994 if (sec->sh_type == SHT_IA_64_UNWIND)
8995 {
8996 unwsec = sec;
8997 break;
8998 }
4082ef84
NC
8999 /* We have already counted the number of SHT_IA64_UNWIND
9000 sections so the loop above should never fail. */
9001 assert (unwsec != NULL);
579f31ac
JJ
9002
9003 unwstart = i + 1;
9004 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9005
e4b17d5c
L
9006 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9007 {
9008 /* We need to find which section group it is in. */
4082ef84 9009 struct group_list * g;
e4b17d5c 9010
978c4450
AM
9011 if (filedata->section_headers_groups == NULL
9012 || filedata->section_headers_groups[i] == NULL)
dda8d76d 9013 i = filedata->file_header.e_shnum;
4082ef84 9014 else
e4b17d5c 9015 {
978c4450 9016 g = filedata->section_headers_groups[i]->root;
18bd398b 9017
4082ef84
NC
9018 for (; g != NULL; g = g->next)
9019 {
dda8d76d 9020 sec = filedata->section_headers + g->section_index;
e4b17d5c 9021
84714f86
AM
9022 if (section_name_valid (filedata, sec)
9023 && streq (section_name (filedata, sec),
9024 ELF_STRING_ia64_unwind_info))
4082ef84
NC
9025 break;
9026 }
9027
9028 if (g == NULL)
dda8d76d 9029 i = filedata->file_header.e_shnum;
4082ef84 9030 }
e4b17d5c 9031 }
84714f86
AM
9032 else if (section_name_valid (filedata, unwsec)
9033 && startswith (section_name (filedata, unwsec),
e9b095a5 9034 ELF_STRING_ia64_unwind_once))
579f31ac 9035 {
18bd398b 9036 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 9037 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 9038 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9039 for (i = 0, sec = filedata->section_headers;
9040 i < filedata->file_header.e_shnum;
579f31ac 9041 ++i, ++sec)
84714f86
AM
9042 if (section_name_valid (filedata, sec)
9043 && startswith (section_name (filedata, sec),
e9b095a5 9044 ELF_STRING_ia64_unwind_info_once)
84714f86 9045 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9046 break;
9047 }
9048 else
9049 {
9050 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 9051 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
9052 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9053 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9054 suffix = "";
84714f86
AM
9055 if (section_name_valid (filedata, unwsec)
9056 && startswith (section_name (filedata, unwsec),
9057 ELF_STRING_ia64_unwind))
9058 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9059 for (i = 0, sec = filedata->section_headers;
9060 i < filedata->file_header.e_shnum;
579f31ac 9061 ++i, ++sec)
84714f86
AM
9062 if (section_name_valid (filedata, sec)
9063 && startswith (section_name (filedata, sec),
9064 ELF_STRING_ia64_unwind_info)
9065 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9066 break;
9067 }
9068
dda8d76d 9069 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
9070 {
9071 printf (_("\nCould not find unwind info section for "));
9072
dda8d76d 9073 if (filedata->string_table == NULL)
579f31ac
JJ
9074 printf ("%d", unwsec->sh_name);
9075 else
dda8d76d 9076 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9077 }
9078 else
4d6ed7c8 9079 {
4d6ed7c8 9080 aux.info_addr = sec->sh_addr;
dda8d76d 9081 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9082 sec->sh_size,
9083 _("unwind info"));
59245841 9084 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9085
579f31ac 9086 printf (_("\nUnwind section "));
4d6ed7c8 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));
4d6ed7c8 9092
26c527e6
AM
9093 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9094 unwsec->sh_offset,
9095 unwsec->sh_size / (3 * eh_addr_size));
4d6ed7c8 9096
dda8d76d 9097 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9098 && aux.table_len > 0)
dda8d76d 9099 dump_ia64_unwind (filedata, & aux);
579f31ac 9100
9db70fc3
AM
9101 free ((char *) aux.table);
9102 free ((char *) aux.info);
579f31ac
JJ
9103 aux.table = NULL;
9104 aux.info = NULL;
9105 }
4d6ed7c8 9106 }
4d6ed7c8 9107
9db70fc3
AM
9108 free (aux.symtab);
9109 free ((char *) aux.strtab);
32ec8896
NC
9110
9111 return res;
4d6ed7c8
NC
9112}
9113
3f5e193b 9114struct hppa_unw_table_entry
32ec8896
NC
9115{
9116 struct absaddr start;
9117 struct absaddr end;
9118 unsigned int Cannot_unwind:1; /* 0 */
9119 unsigned int Millicode:1; /* 1 */
9120 unsigned int Millicode_save_sr0:1; /* 2 */
9121 unsigned int Region_description:2; /* 3..4 */
9122 unsigned int reserved1:1; /* 5 */
9123 unsigned int Entry_SR:1; /* 6 */
9124 unsigned int Entry_FR:4; /* Number saved 7..10 */
9125 unsigned int Entry_GR:5; /* Number saved 11..15 */
9126 unsigned int Args_stored:1; /* 16 */
9127 unsigned int Variable_Frame:1; /* 17 */
9128 unsigned int Separate_Package_Body:1; /* 18 */
9129 unsigned int Frame_Extension_Millicode:1; /* 19 */
9130 unsigned int Stack_Overflow_Check:1; /* 20 */
9131 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9132 unsigned int Ada_Region:1; /* 22 */
9133 unsigned int cxx_info:1; /* 23 */
9134 unsigned int cxx_try_catch:1; /* 24 */
9135 unsigned int sched_entry_seq:1; /* 25 */
9136 unsigned int reserved2:1; /* 26 */
9137 unsigned int Save_SP:1; /* 27 */
9138 unsigned int Save_RP:1; /* 28 */
9139 unsigned int Save_MRP_in_frame:1; /* 29 */
9140 unsigned int extn_ptr_defined:1; /* 30 */
9141 unsigned int Cleanup_defined:1; /* 31 */
9142
9143 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9144 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9145 unsigned int Large_frame:1; /* 2 */
9146 unsigned int Pseudo_SP_Set:1; /* 3 */
9147 unsigned int reserved4:1; /* 4 */
9148 unsigned int Total_frame_size:27; /* 5..31 */
9149};
3f5e193b 9150
57346661 9151struct hppa_unw_aux_info
948f632f 9152{
32ec8896 9153 struct hppa_unw_table_entry * table; /* Unwind table. */
26c527e6 9154 uint64_t table_len; /* Length of unwind table. */
625d49fc 9155 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9156 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9157 uint64_t nsyms; /* Number of symbols. */
32ec8896 9158 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9159 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9160 char * strtab; /* The string table. */
26c527e6 9161 uint64_t strtab_size; /* Size of string table. */
948f632f 9162};
57346661 9163
015dc7e1 9164static bool
dda8d76d 9165dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9166{
2cf0635d 9167 struct hppa_unw_table_entry * tp;
26c527e6 9168 uint64_t j, nfuns;
015dc7e1 9169 bool res = true;
948f632f
DA
9170
9171 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9172 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9173 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9174 aux->funtab[nfuns++] = aux->symtab[j];
9175 aux->nfuns = nfuns;
9176 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9177
57346661
AM
9178 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9179 {
625d49fc 9180 uint64_t offset;
2cf0635d 9181 const char * procname;
57346661 9182
dda8d76d 9183 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9184 aux->strtab_size, tp->start, &procname,
9185 &offset);
9186
9187 fputs ("\n<", stdout);
9188
9189 if (procname)
9190 {
9191 fputs (procname, stdout);
9192
9193 if (offset)
26c527e6 9194 printf ("+%" PRIx64, offset);
57346661
AM
9195 }
9196
9197 fputs (">: [", stdout);
9198 print_vma (tp->start.offset, PREFIX_HEX);
9199 fputc ('-', stdout);
9200 print_vma (tp->end.offset, PREFIX_HEX);
9201 printf ("]\n\t");
9202
18bd398b
NC
9203#define PF(_m) if (tp->_m) printf (#_m " ");
9204#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9205 PF(Cannot_unwind);
9206 PF(Millicode);
9207 PF(Millicode_save_sr0);
18bd398b 9208 /* PV(Region_description); */
57346661
AM
9209 PF(Entry_SR);
9210 PV(Entry_FR);
9211 PV(Entry_GR);
9212 PF(Args_stored);
9213 PF(Variable_Frame);
9214 PF(Separate_Package_Body);
9215 PF(Frame_Extension_Millicode);
9216 PF(Stack_Overflow_Check);
9217 PF(Two_Instruction_SP_Increment);
9218 PF(Ada_Region);
9219 PF(cxx_info);
9220 PF(cxx_try_catch);
9221 PF(sched_entry_seq);
9222 PF(Save_SP);
9223 PF(Save_RP);
9224 PF(Save_MRP_in_frame);
9225 PF(extn_ptr_defined);
9226 PF(Cleanup_defined);
9227 PF(MPE_XL_interrupt_marker);
9228 PF(HP_UX_interrupt_marker);
9229 PF(Large_frame);
9230 PF(Pseudo_SP_Set);
9231 PV(Total_frame_size);
9232#undef PF
9233#undef PV
9234 }
9235
18bd398b 9236 printf ("\n");
948f632f
DA
9237
9238 free (aux->funtab);
32ec8896
NC
9239
9240 return res;
57346661
AM
9241}
9242
015dc7e1 9243static bool
dda8d76d
NC
9244slurp_hppa_unwind_table (Filedata * filedata,
9245 struct hppa_unw_aux_info * aux,
9246 Elf_Internal_Shdr * sec)
57346661 9247{
26c527e6 9248 uint64_t size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9249 Elf_Internal_Phdr * seg;
9250 struct hppa_unw_table_entry * tep;
9251 Elf_Internal_Shdr * relsec;
9252 Elf_Internal_Rela * rela;
9253 Elf_Internal_Rela * rp;
9254 unsigned char * table;
9255 unsigned char * tp;
9256 Elf_Internal_Sym * sym;
9257 const char * relname;
57346661 9258
57346661
AM
9259 /* First, find the starting address of the segment that includes
9260 this section. */
dda8d76d 9261 if (filedata->file_header.e_phnum)
57346661 9262 {
dda8d76d 9263 if (! get_program_headers (filedata))
015dc7e1 9264 return false;
57346661 9265
dda8d76d
NC
9266 for (seg = filedata->program_headers;
9267 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9268 ++seg)
9269 {
9270 if (seg->p_type != PT_LOAD)
9271 continue;
9272
9273 if (sec->sh_addr >= seg->p_vaddr
9274 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9275 {
9276 aux->seg_base = seg->p_vaddr;
9277 break;
9278 }
9279 }
9280 }
9281
9282 /* Second, build the unwind table from the contents of the unwind
9283 section. */
9284 size = sec->sh_size;
dda8d76d 9285 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9286 _("unwind table"));
57346661 9287 if (!table)
015dc7e1 9288 return false;
57346661 9289
1c0751b2
DA
9290 unw_ent_size = 16;
9291 nentries = size / unw_ent_size;
9292 size = unw_ent_size * nentries;
57346661 9293
e3fdc001 9294 aux->table_len = nentries;
3f5e193b
NC
9295 tep = aux->table = (struct hppa_unw_table_entry *)
9296 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9297
1c0751b2 9298 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9299 {
9300 unsigned int tmp1, tmp2;
9301
9302 tep->start.section = SHN_UNDEF;
9303 tep->end.section = SHN_UNDEF;
9304
1c0751b2
DA
9305 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9306 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9307 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9308 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9309
9310 tep->start.offset += aux->seg_base;
9311 tep->end.offset += aux->seg_base;
57346661
AM
9312
9313 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9314 tep->Millicode = (tmp1 >> 30) & 0x1;
9315 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9316 tep->Region_description = (tmp1 >> 27) & 0x3;
9317 tep->reserved1 = (tmp1 >> 26) & 0x1;
9318 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9319 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9320 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9321 tep->Args_stored = (tmp1 >> 15) & 0x1;
9322 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9323 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9324 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9325 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9326 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9327 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9328 tep->cxx_info = (tmp1 >> 8) & 0x1;
9329 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9330 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9331 tep->reserved2 = (tmp1 >> 5) & 0x1;
9332 tep->Save_SP = (tmp1 >> 4) & 0x1;
9333 tep->Save_RP = (tmp1 >> 3) & 0x1;
9334 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9335 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9336 tep->Cleanup_defined = tmp1 & 0x1;
9337
9338 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9339 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9340 tep->Large_frame = (tmp2 >> 29) & 0x1;
9341 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9342 tep->reserved4 = (tmp2 >> 27) & 0x1;
9343 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9344 }
9345 free (table);
9346
9347 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9348 for (relsec = filedata->section_headers;
9349 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9350 ++relsec)
9351 {
9352 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9353 || relsec->sh_info >= filedata->file_header.e_shnum
9354 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9355 continue;
9356
dda8d76d 9357 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9358 & rela, & nrelas))
015dc7e1 9359 return false;
57346661
AM
9360
9361 for (rp = rela; rp < rela + nrelas; ++rp)
9362 {
4770fb94 9363 unsigned int sym_ndx;
726bd37d
AM
9364 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9365 relname = elf_hppa_reloc_type (r_type);
57346661 9366
726bd37d
AM
9367 if (relname == NULL)
9368 {
9369 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9370 continue;
9371 }
9372
57346661 9373 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9374 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9375 {
726bd37d 9376 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9377 continue;
9378 }
9379
9380 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9381 if (i >= aux->table_len)
9382 {
26c527e6
AM
9383 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9384 i);
726bd37d
AM
9385 continue;
9386 }
57346661 9387
4770fb94
AM
9388 sym_ndx = get_reloc_symindex (rp->r_info);
9389 if (sym_ndx >= aux->nsyms)
9390 {
9391 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9392 sym_ndx);
9393 continue;
9394 }
9395 sym = aux->symtab + sym_ndx;
9396
43f6cd05 9397 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9398 {
9399 case 0:
9400 aux->table[i].start.section = sym->st_shndx;
1e456d54 9401 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9402 break;
9403 case 1:
9404 aux->table[i].end.section = sym->st_shndx;
1e456d54 9405 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9406 break;
9407 default:
9408 break;
9409 }
9410 }
9411
9412 free (rela);
9413 }
9414
015dc7e1 9415 return true;
57346661
AM
9416}
9417
015dc7e1 9418static bool
dda8d76d 9419hppa_process_unwind (Filedata * filedata)
57346661 9420{
57346661 9421 struct hppa_unw_aux_info aux;
2cf0635d 9422 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9423 Elf_Internal_Shdr * sec;
26c527e6 9424 size_t i;
015dc7e1 9425 bool res = true;
57346661 9426
dda8d76d 9427 if (filedata->string_table == NULL)
015dc7e1 9428 return false;
1b31d05e
NC
9429
9430 memset (& aux, 0, sizeof (aux));
57346661 9431
dda8d76d 9432 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9433 {
28d13567 9434 if (sec->sh_type == SHT_SYMTAB)
57346661 9435 {
28d13567 9436 if (aux.symtab)
4082ef84 9437 {
28d13567
AM
9438 error (_("Multiple symbol tables encountered\n"));
9439 free (aux.symtab);
9440 aux.symtab = NULL;
4082ef84 9441 free (aux.strtab);
28d13567 9442 aux.strtab = NULL;
4082ef84 9443 }
28d13567
AM
9444 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9445 &aux.strtab, &aux.strtab_size))
015dc7e1 9446 return false;
57346661 9447 }
84714f86
AM
9448 else if (section_name_valid (filedata, sec)
9449 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9450 unwsec = sec;
9451 }
9452
9453 if (!unwsec)
9454 printf (_("\nThere are no unwind sections in this file.\n"));
9455
dda8d76d 9456 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9457 {
84714f86
AM
9458 if (section_name_valid (filedata, sec)
9459 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9460 {
26c527e6 9461 uint64_t num_unwind = sec->sh_size / 16;
dda8d76d 9462
26c527e6
AM
9463 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
9464 "contains %" PRIu64 " entry:\n",
9465 "\nUnwind section '%s' at offset %#" PRIx64 " "
9466 "contains %" PRIu64 " entries:\n",
d3a49aa8 9467 num_unwind),
dda8d76d 9468 printable_section_name (filedata, sec),
26c527e6 9469 sec->sh_offset,
d3a49aa8 9470 num_unwind);
57346661 9471
dda8d76d 9472 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9473 res = false;
66b09c7e
S
9474
9475 if (res && aux.table_len > 0)
32ec8896 9476 {
dda8d76d 9477 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9478 res = false;
32ec8896 9479 }
57346661 9480
9db70fc3 9481 free ((char *) aux.table);
57346661
AM
9482 aux.table = NULL;
9483 }
9484 }
9485
9db70fc3
AM
9486 free (aux.symtab);
9487 free ((char *) aux.strtab);
32ec8896
NC
9488
9489 return res;
57346661
AM
9490}
9491
0b6ae522
DJ
9492struct arm_section
9493{
a734115a
NC
9494 unsigned char * data; /* The unwind data. */
9495 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9496 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
26c527e6 9497 uint64_t nrelas; /* The number of relocations. */
a734115a
NC
9498 unsigned int rel_type; /* REL or RELA ? */
9499 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9500};
9501
9502struct arm_unw_aux_info
9503{
dda8d76d 9504 Filedata * filedata; /* The file containing the unwind sections. */
a734115a 9505 Elf_Internal_Sym * symtab; /* The file's symbol table. */
26c527e6 9506 uint64_t nsyms; /* Number of symbols. */
948f632f 9507 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9508 uint64_t nfuns; /* Number of these symbols. */
a734115a 9509 char * strtab; /* The file's string table. */
26c527e6 9510 uint64_t strtab_size; /* Size of string table. */
0b6ae522
DJ
9511};
9512
9513static const char *
dda8d76d
NC
9514arm_print_vma_and_name (Filedata * filedata,
9515 struct arm_unw_aux_info * aux,
625d49fc 9516 uint64_t fn,
dda8d76d 9517 struct absaddr addr)
0b6ae522
DJ
9518{
9519 const char *procname;
625d49fc 9520 uint64_t sym_offset;
0b6ae522
DJ
9521
9522 if (addr.section == SHN_UNDEF)
9523 addr.offset = fn;
9524
dda8d76d 9525 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9526 aux->strtab_size, addr, &procname,
9527 &sym_offset);
9528
9529 print_vma (fn, PREFIX_HEX);
9530
9531 if (procname)
9532 {
9533 fputs (" <", stdout);
9534 fputs (procname, stdout);
9535
9536 if (sym_offset)
26c527e6 9537 printf ("+0x%" PRIx64, sym_offset);
0b6ae522
DJ
9538 fputc ('>', stdout);
9539 }
9540
9541 return procname;
9542}
9543
9544static void
9545arm_free_section (struct arm_section *arm_sec)
9546{
9db70fc3
AM
9547 free (arm_sec->data);
9548 free (arm_sec->rela);
0b6ae522
DJ
9549}
9550
a734115a
NC
9551/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9552 cached section and install SEC instead.
9553 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9554 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9555 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9556 relocation's offset in ADDR.
1b31d05e
NC
9557 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9558 into the string table of the symbol associated with the reloc. If no
9559 reloc was applied store -1 there.
9560 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9561
015dc7e1 9562static bool
dda8d76d
NC
9563get_unwind_section_word (Filedata * filedata,
9564 struct arm_unw_aux_info * aux,
1b31d05e
NC
9565 struct arm_section * arm_sec,
9566 Elf_Internal_Shdr * sec,
625d49fc 9567 uint64_t word_offset,
1b31d05e
NC
9568 unsigned int * wordp,
9569 struct absaddr * addr,
625d49fc 9570 uint64_t * sym_name)
0b6ae522
DJ
9571{
9572 Elf_Internal_Rela *rp;
9573 Elf_Internal_Sym *sym;
9574 const char * relname;
9575 unsigned int word;
015dc7e1 9576 bool wrapped;
0b6ae522 9577
e0a31db1 9578 if (sec == NULL || arm_sec == NULL)
015dc7e1 9579 return false;
e0a31db1 9580
0b6ae522
DJ
9581 addr->section = SHN_UNDEF;
9582 addr->offset = 0;
9583
1b31d05e 9584 if (sym_name != NULL)
625d49fc 9585 *sym_name = (uint64_t) -1;
1b31d05e 9586
a734115a 9587 /* If necessary, update the section cache. */
0b6ae522
DJ
9588 if (sec != arm_sec->sec)
9589 {
9590 Elf_Internal_Shdr *relsec;
9591
9592 arm_free_section (arm_sec);
9593
9594 arm_sec->sec = sec;
dda8d76d 9595 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9596 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9597 arm_sec->rela = NULL;
9598 arm_sec->nrelas = 0;
9599
dda8d76d
NC
9600 for (relsec = filedata->section_headers;
9601 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9602 ++relsec)
9603 {
dda8d76d
NC
9604 if (relsec->sh_info >= filedata->file_header.e_shnum
9605 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9606 /* PR 15745: Check the section type as well. */
9607 || (relsec->sh_type != SHT_REL
9608 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9609 continue;
9610
a734115a 9611 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9612 if (relsec->sh_type == SHT_REL)
9613 {
dda8d76d 9614 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9615 relsec->sh_size,
9616 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9617 return false;
0b6ae522 9618 }
1ae40aa4 9619 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9620 {
dda8d76d 9621 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9622 relsec->sh_size,
9623 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9624 return false;
0b6ae522 9625 }
1ae40aa4 9626 break;
0b6ae522
DJ
9627 }
9628
9629 arm_sec->next_rela = arm_sec->rela;
9630 }
9631
a734115a 9632 /* If there is no unwind data we can do nothing. */
0b6ae522 9633 if (arm_sec->data == NULL)
015dc7e1 9634 return false;
0b6ae522 9635
e0a31db1 9636 /* If the offset is invalid then fail. */
f32ba729
NC
9637 if (/* PR 21343 *//* PR 18879 */
9638 sec->sh_size < 4
625d49fc 9639 || word_offset > sec->sh_size - 4)
015dc7e1 9640 return false;
e0a31db1 9641
a734115a 9642 /* Get the word at the required offset. */
0b6ae522
DJ
9643 word = byte_get (arm_sec->data + word_offset, 4);
9644
0eff7165
NC
9645 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9646 if (arm_sec->rela == NULL)
9647 {
9648 * wordp = word;
015dc7e1 9649 return true;
0eff7165
NC
9650 }
9651
a734115a 9652 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9653 wrapped = false;
0b6ae522
DJ
9654 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9655 {
625d49fc 9656 uint64_t prelval, offset;
0b6ae522
DJ
9657
9658 if (rp->r_offset > word_offset && !wrapped)
9659 {
9660 rp = arm_sec->rela;
015dc7e1 9661 wrapped = true;
0b6ae522
DJ
9662 }
9663 if (rp->r_offset > word_offset)
9664 break;
9665
9666 if (rp->r_offset & 3)
9667 {
26c527e6
AM
9668 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
9669 rp->r_offset);
0b6ae522
DJ
9670 continue;
9671 }
9672
9673 if (rp->r_offset < word_offset)
9674 continue;
9675
74e1a04b
NC
9676 /* PR 17531: file: 027-161405-0.004 */
9677 if (aux->symtab == NULL)
9678 continue;
9679
0b6ae522
DJ
9680 if (arm_sec->rel_type == SHT_REL)
9681 {
9682 offset = word & 0x7fffffff;
9683 if (offset & 0x40000000)
625d49fc 9684 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 9685 }
a734115a 9686 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9687 offset = rp->r_addend;
a734115a 9688 else
74e1a04b
NC
9689 {
9690 error (_("Unknown section relocation type %d encountered\n"),
9691 arm_sec->rel_type);
9692 break;
9693 }
0b6ae522 9694
071436c6
NC
9695 /* PR 17531 file: 027-1241568-0.004. */
9696 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9697 {
26c527e6
AM
9698 error (_("Bad symbol index in unwind relocation "
9699 "(%" PRIu64 " > %" PRIu64 ")\n"),
9700 ELF32_R_SYM (rp->r_info), aux->nsyms);
071436c6
NC
9701 break;
9702 }
9703
9704 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9705 offset += sym->st_value;
9706 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9707
a734115a 9708 /* Check that we are processing the expected reloc type. */
dda8d76d 9709 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9710 {
9711 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9712 if (relname == NULL)
9713 {
9714 warn (_("Skipping unknown ARM relocation type: %d\n"),
9715 (int) ELF32_R_TYPE (rp->r_info));
9716 continue;
9717 }
a734115a
NC
9718
9719 if (streq (relname, "R_ARM_NONE"))
9720 continue;
0b4362b0 9721
a734115a
NC
9722 if (! streq (relname, "R_ARM_PREL31"))
9723 {
071436c6 9724 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9725 continue;
9726 }
9727 }
dda8d76d 9728 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9729 {
9730 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9731 if (relname == NULL)
9732 {
9733 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9734 (int) ELF32_R_TYPE (rp->r_info));
9735 continue;
9736 }
0b4362b0 9737
a734115a
NC
9738 if (streq (relname, "R_C6000_NONE"))
9739 continue;
9740
9741 if (! streq (relname, "R_C6000_PREL31"))
9742 {
071436c6 9743 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9744 continue;
9745 }
9746
9747 prelval >>= 1;
9748 }
9749 else
74e1a04b
NC
9750 {
9751 /* This function currently only supports ARM and TI unwinders. */
9752 warn (_("Only TI and ARM unwinders are currently supported\n"));
9753 break;
9754 }
fa197c1c 9755
625d49fc 9756 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
9757 addr->section = sym->st_shndx;
9758 addr->offset = offset;
74e1a04b 9759
1b31d05e
NC
9760 if (sym_name)
9761 * sym_name = sym->st_name;
0b6ae522
DJ
9762 break;
9763 }
9764
9765 *wordp = word;
9766 arm_sec->next_rela = rp;
9767
015dc7e1 9768 return true;
0b6ae522
DJ
9769}
9770
a734115a
NC
9771static const char *tic6x_unwind_regnames[16] =
9772{
0b4362b0
RM
9773 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9774 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9775 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9776};
fa197c1c 9777
0b6ae522 9778static void
fa197c1c 9779decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9780{
fa197c1c
PB
9781 int i;
9782
9783 for (i = 12; mask; mask >>= 1, i--)
9784 {
9785 if (mask & 1)
9786 {
9787 fputs (tic6x_unwind_regnames[i], stdout);
9788 if (mask > 1)
9789 fputs (", ", stdout);
9790 }
9791 }
9792}
0b6ae522
DJ
9793
9794#define ADVANCE \
9795 if (remaining == 0 && more_words) \
9796 { \
9797 data_offset += 4; \
dda8d76d 9798 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9799 data_offset, & word, & addr, NULL)) \
015dc7e1 9800 return false; \
0b6ae522
DJ
9801 remaining = 4; \
9802 more_words--; \
9803 } \
9804
9805#define GET_OP(OP) \
9806 ADVANCE; \
9807 if (remaining) \
9808 { \
9809 remaining--; \
9810 (OP) = word >> 24; \
9811 word <<= 8; \
9812 } \
9813 else \
9814 { \
2b692964 9815 printf (_("[Truncated opcode]\n")); \
015dc7e1 9816 return false; \
0b6ae522 9817 } \
cc5914eb 9818 printf ("0x%02x ", OP)
0b6ae522 9819
015dc7e1 9820static bool
dda8d76d
NC
9821decode_arm_unwind_bytecode (Filedata * filedata,
9822 struct arm_unw_aux_info * aux,
948f632f
DA
9823 unsigned int word,
9824 unsigned int remaining,
9825 unsigned int more_words,
625d49fc 9826 uint64_t data_offset,
948f632f
DA
9827 Elf_Internal_Shdr * data_sec,
9828 struct arm_section * data_arm_sec)
fa197c1c
PB
9829{
9830 struct absaddr addr;
015dc7e1 9831 bool res = true;
0b6ae522
DJ
9832
9833 /* Decode the unwinding instructions. */
9834 while (1)
9835 {
9836 unsigned int op, op2;
9837
9838 ADVANCE;
9839 if (remaining == 0)
9840 break;
9841 remaining--;
9842 op = word >> 24;
9843 word <<= 8;
9844
cc5914eb 9845 printf (" 0x%02x ", op);
0b6ae522
DJ
9846
9847 if ((op & 0xc0) == 0x00)
9848 {
9849 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9850
cc5914eb 9851 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9852 }
9853 else if ((op & 0xc0) == 0x40)
9854 {
9855 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9856
cc5914eb 9857 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9858 }
9859 else if ((op & 0xf0) == 0x80)
9860 {
9861 GET_OP (op2);
9862 if (op == 0x80 && op2 == 0)
9863 printf (_("Refuse to unwind"));
9864 else
9865 {
9866 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9867 bool first = true;
0b6ae522 9868 int i;
2b692964 9869
0b6ae522
DJ
9870 printf ("pop {");
9871 for (i = 0; i < 12; i++)
9872 if (mask & (1 << i))
9873 {
9874 if (first)
015dc7e1 9875 first = false;
0b6ae522
DJ
9876 else
9877 printf (", ");
9878 printf ("r%d", 4 + i);
9879 }
9880 printf ("}");
9881 }
9882 }
9883 else if ((op & 0xf0) == 0x90)
9884 {
9885 if (op == 0x9d || op == 0x9f)
9886 printf (_(" [Reserved]"));
9887 else
cc5914eb 9888 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9889 }
9890 else if ((op & 0xf0) == 0xa0)
9891 {
9892 int end = 4 + (op & 0x07);
015dc7e1 9893 bool first = true;
0b6ae522 9894 int i;
61865e30 9895
0b6ae522
DJ
9896 printf (" pop {");
9897 for (i = 4; i <= end; i++)
9898 {
9899 if (first)
015dc7e1 9900 first = false;
0b6ae522
DJ
9901 else
9902 printf (", ");
9903 printf ("r%d", i);
9904 }
9905 if (op & 0x08)
9906 {
1b31d05e 9907 if (!first)
0b6ae522
DJ
9908 printf (", ");
9909 printf ("r14");
9910 }
9911 printf ("}");
9912 }
9913 else if (op == 0xb0)
9914 printf (_(" finish"));
9915 else if (op == 0xb1)
9916 {
9917 GET_OP (op2);
9918 if (op2 == 0 || (op2 & 0xf0) != 0)
9919 printf (_("[Spare]"));
9920 else
9921 {
9922 unsigned int mask = op2 & 0x0f;
015dc7e1 9923 bool first = true;
0b6ae522 9924 int i;
61865e30 9925
0b6ae522
DJ
9926 printf ("pop {");
9927 for (i = 0; i < 12; i++)
9928 if (mask & (1 << i))
9929 {
9930 if (first)
015dc7e1 9931 first = false;
0b6ae522
DJ
9932 else
9933 printf (", ");
9934 printf ("r%d", i);
9935 }
9936 printf ("}");
9937 }
9938 }
9939 else if (op == 0xb2)
9940 {
b115cf96 9941 unsigned char buf[9];
0b6ae522 9942 unsigned int i, len;
26c527e6 9943 uint64_t offset;
61865e30 9944
b115cf96 9945 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9946 {
9947 GET_OP (buf[i]);
9948 if ((buf[i] & 0x80) == 0)
9949 break;
9950 }
4082ef84 9951 if (i == sizeof (buf))
32ec8896 9952 {
27a45f42 9953 error (_("corrupt change to vsp\n"));
015dc7e1 9954 res = false;
32ec8896 9955 }
4082ef84
NC
9956 else
9957 {
015dc7e1 9958 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9959 assert (len == i + 1);
9960 offset = offset * 4 + 0x204;
26c527e6 9961 printf ("vsp = vsp + %" PRId64, offset);
4082ef84 9962 }
0b6ae522 9963 }
61865e30 9964 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9965 {
61865e30
NC
9966 unsigned int first, last;
9967
9968 GET_OP (op2);
9969 first = op2 >> 4;
9970 last = op2 & 0x0f;
9971 if (op == 0xc8)
9972 first = first + 16;
9973 printf ("pop {D%d", first);
9974 if (last)
9975 printf ("-D%d", first + last);
9976 printf ("}");
9977 }
09854a88
TB
9978 else if (op == 0xb4)
9979 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
9980 else if (op == 0xb5)
9981 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
9982 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9983 {
9984 unsigned int count = op & 0x07;
9985
9986 printf ("pop {D8");
9987 if (count)
9988 printf ("-D%d", 8 + count);
9989 printf ("}");
9990 }
9991 else if (op >= 0xc0 && op <= 0xc5)
9992 {
9993 unsigned int count = op & 0x07;
9994
9995 printf (" pop {wR10");
9996 if (count)
9997 printf ("-wR%d", 10 + count);
9998 printf ("}");
9999 }
10000 else if (op == 0xc6)
10001 {
10002 unsigned int first, last;
10003
10004 GET_OP (op2);
10005 first = op2 >> 4;
10006 last = op2 & 0x0f;
10007 printf ("pop {wR%d", first);
10008 if (last)
10009 printf ("-wR%d", first + last);
10010 printf ("}");
10011 }
10012 else if (op == 0xc7)
10013 {
10014 GET_OP (op2);
10015 if (op2 == 0 || (op2 & 0xf0) != 0)
10016 printf (_("[Spare]"));
0b6ae522
DJ
10017 else
10018 {
61865e30 10019 unsigned int mask = op2 & 0x0f;
015dc7e1 10020 bool first = true;
61865e30
NC
10021 int i;
10022
10023 printf ("pop {");
10024 for (i = 0; i < 4; i++)
10025 if (mask & (1 << i))
10026 {
10027 if (first)
015dc7e1 10028 first = false;
61865e30
NC
10029 else
10030 printf (", ");
10031 printf ("wCGR%d", i);
10032 }
10033 printf ("}");
0b6ae522
DJ
10034 }
10035 }
61865e30 10036 else
32ec8896
NC
10037 {
10038 printf (_(" [unsupported opcode]"));
015dc7e1 10039 res = false;
32ec8896
NC
10040 }
10041
0b6ae522
DJ
10042 printf ("\n");
10043 }
32ec8896
NC
10044
10045 return res;
fa197c1c
PB
10046}
10047
015dc7e1 10048static bool
dda8d76d
NC
10049decode_tic6x_unwind_bytecode (Filedata * filedata,
10050 struct arm_unw_aux_info * aux,
948f632f
DA
10051 unsigned int word,
10052 unsigned int remaining,
10053 unsigned int more_words,
625d49fc 10054 uint64_t data_offset,
948f632f
DA
10055 Elf_Internal_Shdr * data_sec,
10056 struct arm_section * data_arm_sec)
fa197c1c
PB
10057{
10058 struct absaddr addr;
10059
10060 /* Decode the unwinding instructions. */
10061 while (1)
10062 {
10063 unsigned int op, op2;
10064
10065 ADVANCE;
10066 if (remaining == 0)
10067 break;
10068 remaining--;
10069 op = word >> 24;
10070 word <<= 8;
10071
9cf03b7e 10072 printf (" 0x%02x ", op);
fa197c1c
PB
10073
10074 if ((op & 0xc0) == 0x00)
10075 {
10076 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10077 printf (" sp = sp + %d", offset);
fa197c1c
PB
10078 }
10079 else if ((op & 0xc0) == 0x80)
10080 {
10081 GET_OP (op2);
10082 if (op == 0x80 && op2 == 0)
10083 printf (_("Refuse to unwind"));
10084 else
10085 {
10086 unsigned int mask = ((op & 0x1f) << 8) | op2;
10087 if (op & 0x20)
10088 printf ("pop compact {");
10089 else
10090 printf ("pop {");
10091
10092 decode_tic6x_unwind_regmask (mask);
10093 printf("}");
10094 }
10095 }
10096 else if ((op & 0xf0) == 0xc0)
10097 {
10098 unsigned int reg;
10099 unsigned int nregs;
10100 unsigned int i;
10101 const char *name;
a734115a
NC
10102 struct
10103 {
32ec8896
NC
10104 unsigned int offset;
10105 unsigned int reg;
fa197c1c
PB
10106 } regpos[16];
10107
10108 /* Scan entire instruction first so that GET_OP output is not
10109 interleaved with disassembly. */
10110 nregs = 0;
10111 for (i = 0; nregs < (op & 0xf); i++)
10112 {
10113 GET_OP (op2);
10114 reg = op2 >> 4;
10115 if (reg != 0xf)
10116 {
10117 regpos[nregs].offset = i * 2;
10118 regpos[nregs].reg = reg;
10119 nregs++;
10120 }
10121
10122 reg = op2 & 0xf;
10123 if (reg != 0xf)
10124 {
10125 regpos[nregs].offset = i * 2 + 1;
10126 regpos[nregs].reg = reg;
10127 nregs++;
10128 }
10129 }
10130
10131 printf (_("pop frame {"));
18344509 10132 if (nregs == 0)
fa197c1c 10133 {
18344509
NC
10134 printf (_("*corrupt* - no registers specified"));
10135 }
10136 else
10137 {
10138 reg = nregs - 1;
10139 for (i = i * 2; i > 0; i--)
fa197c1c 10140 {
18344509
NC
10141 if (regpos[reg].offset == i - 1)
10142 {
10143 name = tic6x_unwind_regnames[regpos[reg].reg];
10144 if (reg > 0)
10145 reg--;
10146 }
10147 else
10148 name = _("[pad]");
fa197c1c 10149
18344509
NC
10150 fputs (name, stdout);
10151 if (i > 1)
10152 printf (", ");
10153 }
fa197c1c
PB
10154 }
10155
10156 printf ("}");
10157 }
10158 else if (op == 0xd0)
10159 printf (" MOV FP, SP");
10160 else if (op == 0xd1)
10161 printf (" __c6xabi_pop_rts");
10162 else if (op == 0xd2)
10163 {
10164 unsigned char buf[9];
10165 unsigned int i, len;
26c527e6 10166 uint64_t offset;
a734115a 10167
fa197c1c
PB
10168 for (i = 0; i < sizeof (buf); i++)
10169 {
10170 GET_OP (buf[i]);
10171 if ((buf[i] & 0x80) == 0)
10172 break;
10173 }
0eff7165
NC
10174 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10175 if (i == sizeof (buf))
10176 {
0eff7165 10177 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10178 return false;
0eff7165 10179 }
948f632f 10180
015dc7e1 10181 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10182 assert (len == i + 1);
10183 offset = offset * 8 + 0x408;
26c527e6 10184 printf (_("sp = sp + %" PRId64), offset);
fa197c1c
PB
10185 }
10186 else if ((op & 0xf0) == 0xe0)
10187 {
10188 if ((op & 0x0f) == 7)
10189 printf (" RETURN");
10190 else
10191 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10192 }
10193 else
10194 {
10195 printf (_(" [unsupported opcode]"));
10196 }
10197 putchar ('\n');
10198 }
32ec8896 10199
015dc7e1 10200 return true;
fa197c1c
PB
10201}
10202
625d49fc
AM
10203static uint64_t
10204arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10205{
625d49fc 10206 uint64_t offset;
fa197c1c
PB
10207
10208 offset = word & 0x7fffffff;
10209 if (offset & 0x40000000)
625d49fc 10210 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10211
dda8d76d 10212 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10213 offset <<= 1;
10214
10215 return offset + where;
10216}
10217
015dc7e1 10218static bool
dda8d76d
NC
10219decode_arm_unwind (Filedata * filedata,
10220 struct arm_unw_aux_info * aux,
1b31d05e
NC
10221 unsigned int word,
10222 unsigned int remaining,
625d49fc 10223 uint64_t data_offset,
1b31d05e
NC
10224 Elf_Internal_Shdr * data_sec,
10225 struct arm_section * data_arm_sec)
fa197c1c
PB
10226{
10227 int per_index;
10228 unsigned int more_words = 0;
37e14bc3 10229 struct absaddr addr;
625d49fc 10230 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10231 bool res = true;
fa197c1c
PB
10232
10233 if (remaining == 0)
10234 {
1b31d05e
NC
10235 /* Fetch the first word.
10236 Note - when decoding an object file the address extracted
10237 here will always be 0. So we also pass in the sym_name
10238 parameter so that we can find the symbol associated with
10239 the personality routine. */
dda8d76d 10240 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10241 & word, & addr, & sym_name))
015dc7e1 10242 return false;
1b31d05e 10243
fa197c1c
PB
10244 remaining = 4;
10245 }
c93dbb25
CZ
10246 else
10247 {
10248 addr.section = SHN_UNDEF;
10249 addr.offset = 0;
10250 }
fa197c1c
PB
10251
10252 if ((word & 0x80000000) == 0)
10253 {
10254 /* Expand prel31 for personality routine. */
625d49fc 10255 uint64_t fn;
fa197c1c
PB
10256 const char *procname;
10257
dda8d76d 10258 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10259 printf (_(" Personality routine: "));
1b31d05e
NC
10260 if (fn == 0
10261 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10262 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10263 {
10264 procname = aux->strtab + sym_name;
10265 print_vma (fn, PREFIX_HEX);
10266 if (procname)
10267 {
10268 fputs (" <", stdout);
10269 fputs (procname, stdout);
10270 fputc ('>', stdout);
10271 }
10272 }
10273 else
dda8d76d 10274 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10275 fputc ('\n', stdout);
10276
10277 /* The GCC personality routines use the standard compact
10278 encoding, starting with one byte giving the number of
10279 words. */
10280 if (procname != NULL
24d127aa
ML
10281 && (startswith (procname, "__gcc_personality_v0")
10282 || startswith (procname, "__gxx_personality_v0")
10283 || startswith (procname, "__gcj_personality_v0")
10284 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10285 {
10286 remaining = 0;
10287 more_words = 1;
10288 ADVANCE;
10289 if (!remaining)
10290 {
10291 printf (_(" [Truncated data]\n"));
015dc7e1 10292 return false;
fa197c1c
PB
10293 }
10294 more_words = word >> 24;
10295 word <<= 8;
10296 remaining--;
10297 per_index = -1;
10298 }
10299 else
015dc7e1 10300 return true;
fa197c1c
PB
10301 }
10302 else
10303 {
1b31d05e 10304 /* ARM EHABI Section 6.3:
0b4362b0 10305
1b31d05e 10306 An exception-handling table entry for the compact model looks like:
0b4362b0 10307
1b31d05e
NC
10308 31 30-28 27-24 23-0
10309 -- ----- ----- ----
10310 1 0 index Data for personalityRoutine[index] */
10311
dda8d76d 10312 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10313 && (word & 0x70000000))
32ec8896
NC
10314 {
10315 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10316 res = false;
32ec8896 10317 }
1b31d05e 10318
fa197c1c 10319 per_index = (word >> 24) & 0x7f;
1b31d05e 10320 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10321 if (per_index == 0)
10322 {
10323 more_words = 0;
10324 word <<= 8;
10325 remaining--;
10326 }
10327 else if (per_index < 3)
10328 {
10329 more_words = (word >> 16) & 0xff;
10330 word <<= 16;
10331 remaining -= 2;
10332 }
10333 }
10334
dda8d76d 10335 switch (filedata->file_header.e_machine)
fa197c1c
PB
10336 {
10337 case EM_ARM:
10338 if (per_index < 3)
10339 {
dda8d76d 10340 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10341 data_offset, data_sec, data_arm_sec))
015dc7e1 10342 res = false;
fa197c1c
PB
10343 }
10344 else
1b31d05e
NC
10345 {
10346 warn (_("Unknown ARM compact model index encountered\n"));
10347 printf (_(" [reserved]\n"));
015dc7e1 10348 res = false;
1b31d05e 10349 }
fa197c1c
PB
10350 break;
10351
10352 case EM_TI_C6000:
10353 if (per_index < 3)
10354 {
dda8d76d 10355 if (! decode_tic6x_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 if (per_index < 5)
10360 {
10361 if (((word >> 17) & 0x7f) == 0x7f)
10362 printf (_(" Restore stack from frame pointer\n"));
10363 else
10364 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10365 printf (_(" Registers restored: "));
10366 if (per_index == 4)
10367 printf (" (compact) ");
10368 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10369 putchar ('\n');
10370 printf (_(" Return register: %s\n"),
10371 tic6x_unwind_regnames[word & 0xf]);
10372 }
10373 else
1b31d05e 10374 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10375 break;
10376
10377 default:
74e1a04b 10378 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10379 filedata->file_header.e_machine);
015dc7e1 10380 res = false;
fa197c1c 10381 }
0b6ae522
DJ
10382
10383 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10384
10385 return res;
0b6ae522
DJ
10386}
10387
015dc7e1 10388static bool
dda8d76d
NC
10389dump_arm_unwind (Filedata * filedata,
10390 struct arm_unw_aux_info * aux,
10391 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10392{
10393 struct arm_section exidx_arm_sec, extab_arm_sec;
10394 unsigned int i, exidx_len;
26c527e6 10395 uint64_t j, nfuns;
015dc7e1 10396 bool res = true;
0b6ae522
DJ
10397
10398 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10399 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10400 exidx_len = exidx_sec->sh_size / 8;
10401
948f632f
DA
10402 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10403 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10404 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10405 aux->funtab[nfuns++] = aux->symtab[j];
10406 aux->nfuns = nfuns;
10407 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10408
0b6ae522
DJ
10409 for (i = 0; i < exidx_len; i++)
10410 {
10411 unsigned int exidx_fn, exidx_entry;
10412 struct absaddr fn_addr, entry_addr;
625d49fc 10413 uint64_t fn;
0b6ae522
DJ
10414
10415 fputc ('\n', stdout);
10416
dda8d76d 10417 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10418 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10419 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10420 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10421 {
948f632f 10422 free (aux->funtab);
1b31d05e
NC
10423 arm_free_section (& exidx_arm_sec);
10424 arm_free_section (& extab_arm_sec);
015dc7e1 10425 return false;
0b6ae522
DJ
10426 }
10427
83c257ca
NC
10428 /* ARM EHABI, Section 5:
10429 An index table entry consists of 2 words.
10430 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10431 if (exidx_fn & 0x80000000)
32ec8896
NC
10432 {
10433 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10434 res = false;
32ec8896 10435 }
83c257ca 10436
dda8d76d 10437 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10438
dda8d76d 10439 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10440 fputs (": ", stdout);
10441
10442 if (exidx_entry == 1)
10443 {
10444 print_vma (exidx_entry, PREFIX_HEX);
10445 fputs (" [cantunwind]\n", stdout);
10446 }
10447 else if (exidx_entry & 0x80000000)
10448 {
10449 print_vma (exidx_entry, PREFIX_HEX);
10450 fputc ('\n', stdout);
dda8d76d 10451 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10452 }
10453 else
10454 {
625d49fc 10455 uint64_t table, table_offset = 0;
0b6ae522
DJ
10456 Elf_Internal_Shdr *table_sec;
10457
10458 fputs ("@", stdout);
dda8d76d 10459 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10460 print_vma (table, PREFIX_HEX);
10461 printf ("\n");
10462
10463 /* Locate the matching .ARM.extab. */
10464 if (entry_addr.section != SHN_UNDEF
dda8d76d 10465 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10466 {
dda8d76d 10467 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10468 table_offset = entry_addr.offset;
1a915552 10469 /* PR 18879 */
625d49fc 10470 if (table_offset > table_sec->sh_size)
1a915552 10471 {
26c527e6
AM
10472 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
10473 table_offset,
dda8d76d 10474 printable_section_name (filedata, table_sec));
015dc7e1 10475 res = false;
1a915552
NC
10476 continue;
10477 }
0b6ae522
DJ
10478 }
10479 else
10480 {
dda8d76d 10481 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10482 if (table_sec != NULL)
10483 table_offset = table - table_sec->sh_addr;
10484 }
32ec8896 10485
0b6ae522
DJ
10486 if (table_sec == NULL)
10487 {
26c527e6
AM
10488 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
10489 table);
015dc7e1 10490 res = false;
0b6ae522
DJ
10491 continue;
10492 }
32ec8896 10493
dda8d76d 10494 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10495 &extab_arm_sec))
015dc7e1 10496 res = false;
0b6ae522
DJ
10497 }
10498 }
10499
10500 printf ("\n");
10501
948f632f 10502 free (aux->funtab);
0b6ae522
DJ
10503 arm_free_section (&exidx_arm_sec);
10504 arm_free_section (&extab_arm_sec);
32ec8896
NC
10505
10506 return res;
0b6ae522
DJ
10507}
10508
fa197c1c 10509/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10510
015dc7e1 10511static bool
dda8d76d 10512arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10513{
10514 struct arm_unw_aux_info aux;
10515 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522 10516 Elf_Internal_Shdr *sec;
26c527e6 10517 size_t i;
fa197c1c 10518 unsigned int sec_type;
015dc7e1 10519 bool res = true;
0b6ae522 10520
dda8d76d 10521 switch (filedata->file_header.e_machine)
fa197c1c
PB
10522 {
10523 case EM_ARM:
10524 sec_type = SHT_ARM_EXIDX;
10525 break;
10526
10527 case EM_TI_C6000:
10528 sec_type = SHT_C6000_UNWIND;
10529 break;
10530
0b4362b0 10531 default:
74e1a04b 10532 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10533 filedata->file_header.e_machine);
015dc7e1 10534 return false;
fa197c1c
PB
10535 }
10536
dda8d76d 10537 if (filedata->string_table == NULL)
015dc7e1 10538 return false;
1b31d05e
NC
10539
10540 memset (& aux, 0, sizeof (aux));
dda8d76d 10541 aux.filedata = filedata;
0b6ae522 10542
dda8d76d 10543 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10544 {
28d13567 10545 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10546 {
28d13567 10547 if (aux.symtab)
74e1a04b 10548 {
28d13567
AM
10549 error (_("Multiple symbol tables encountered\n"));
10550 free (aux.symtab);
10551 aux.symtab = NULL;
74e1a04b 10552 free (aux.strtab);
28d13567 10553 aux.strtab = NULL;
74e1a04b 10554 }
28d13567
AM
10555 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10556 &aux.strtab, &aux.strtab_size))
015dc7e1 10557 return false;
0b6ae522 10558 }
fa197c1c 10559 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10560 unwsec = sec;
10561 }
10562
1b31d05e 10563 if (unwsec == NULL)
0b6ae522 10564 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10565 else
dda8d76d 10566 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10567 {
10568 if (sec->sh_type == sec_type)
10569 {
26c527e6
AM
10570 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
10571 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
10572 "contains %" PRIu64 " entry:\n",
10573 "\nUnwind section '%s' at offset %#" PRIx64 " "
10574 "contains %" PRIu64 " entries:\n",
d3a49aa8 10575 num_unwind),
dda8d76d 10576 printable_section_name (filedata, sec),
26c527e6 10577 sec->sh_offset,
d3a49aa8 10578 num_unwind);
0b6ae522 10579
dda8d76d 10580 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10581 res = false;
1b31d05e
NC
10582 }
10583 }
0b6ae522 10584
9db70fc3
AM
10585 free (aux.symtab);
10586 free ((char *) aux.strtab);
32ec8896
NC
10587
10588 return res;
0b6ae522
DJ
10589}
10590
3ecc00ec
NC
10591static bool
10592no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10593{
10594 printf (_("No processor specific unwind information to decode\n"));
10595 return true;
10596}
10597
015dc7e1 10598static bool
dda8d76d 10599process_unwind (Filedata * filedata)
57346661 10600{
2cf0635d
NC
10601 struct unwind_handler
10602 {
32ec8896 10603 unsigned int machtype;
015dc7e1 10604 bool (* handler)(Filedata *);
2cf0635d
NC
10605 } handlers[] =
10606 {
0b6ae522 10607 { EM_ARM, arm_process_unwind },
57346661
AM
10608 { EM_IA_64, ia64_process_unwind },
10609 { EM_PARISC, hppa_process_unwind },
fa197c1c 10610 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10611 { EM_386, no_processor_specific_unwind },
10612 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10613 { 0, NULL }
57346661
AM
10614 };
10615 int i;
10616
10617 if (!do_unwind)
015dc7e1 10618 return true;
57346661
AM
10619
10620 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10621 if (filedata->file_header.e_machine == handlers[i].machtype)
10622 return handlers[i].handler (filedata);
57346661 10623
1b31d05e 10624 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10625 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10626 return true;
57346661
AM
10627}
10628
37c18eed
SD
10629static void
10630dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10631{
10632 switch (entry->d_tag)
10633 {
10634 case DT_AARCH64_BTI_PLT:
1dbade74 10635 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10636 break;
10637 default:
10638 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10639 break;
10640 }
10641 putchar ('\n');
10642}
10643
252b5132 10644static void
978c4450 10645dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10646{
10647 switch (entry->d_tag)
10648 {
10649 case DT_MIPS_FLAGS:
10650 if (entry->d_un.d_val == 0)
4b68bca3 10651 printf (_("NONE"));
252b5132
RH
10652 else
10653 {
10654 static const char * opts[] =
10655 {
10656 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10657 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10658 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10659 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10660 "RLD_ORDER_SAFE"
10661 };
10662 unsigned int cnt;
015dc7e1 10663 bool first = true;
2b692964 10664
60bca95a 10665 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10666 if (entry->d_un.d_val & (1 << cnt))
10667 {
10668 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10669 first = false;
252b5132 10670 }
252b5132
RH
10671 }
10672 break;
103f02d3 10673
252b5132 10674 case DT_MIPS_IVERSION:
84714f86 10675 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10676 printf (_("Interface Version: %s"),
84714f86 10677 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10678 else
f493c217 10679 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 10680 entry->d_un.d_ptr);
252b5132 10681 break;
103f02d3 10682
252b5132
RH
10683 case DT_MIPS_TIME_STAMP:
10684 {
d5b07ef4 10685 char timebuf[128];
2cf0635d 10686 struct tm * tmp;
91d6fa6a 10687 time_t atime = entry->d_un.d_val;
82b1b41b 10688
91d6fa6a 10689 tmp = gmtime (&atime);
82b1b41b
NC
10690 /* PR 17531: file: 6accc532. */
10691 if (tmp == NULL)
10692 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10693 else
10694 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10695 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10696 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10697 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10698 }
10699 break;
103f02d3 10700
252b5132
RH
10701 case DT_MIPS_RLD_VERSION:
10702 case DT_MIPS_LOCAL_GOTNO:
10703 case DT_MIPS_CONFLICTNO:
10704 case DT_MIPS_LIBLISTNO:
10705 case DT_MIPS_SYMTABNO:
10706 case DT_MIPS_UNREFEXTNO:
10707 case DT_MIPS_HIPAGENO:
10708 case DT_MIPS_DELTA_CLASS_NO:
10709 case DT_MIPS_DELTA_INSTANCE_NO:
10710 case DT_MIPS_DELTA_RELOC_NO:
10711 case DT_MIPS_DELTA_SYM_NO:
10712 case DT_MIPS_DELTA_CLASSSYM_NO:
10713 case DT_MIPS_COMPACT_SIZE:
c69075ac 10714 print_vma (entry->d_un.d_val, DEC);
252b5132 10715 break;
103f02d3 10716
f16a9783 10717 case DT_MIPS_XHASH:
978c4450
AM
10718 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10719 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10720 /* Falls through. */
10721
103f02d3 10722 default:
4b68bca3 10723 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10724 }
4b68bca3 10725 putchar ('\n');
103f02d3
UD
10726}
10727
103f02d3 10728static void
2cf0635d 10729dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10730{
10731 switch (entry->d_tag)
10732 {
10733 case DT_HP_DLD_FLAGS:
10734 {
10735 static struct
10736 {
26c527e6 10737 unsigned int bit;
2cf0635d 10738 const char * str;
5e220199
NC
10739 }
10740 flags[] =
10741 {
10742 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10743 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10744 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10745 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10746 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10747 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10748 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10749 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10750 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10751 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10752 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10753 { DT_HP_GST, "HP_GST" },
10754 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10755 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10756 { DT_HP_NODELETE, "HP_NODELETE" },
10757 { DT_HP_GROUP, "HP_GROUP" },
10758 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10759 };
015dc7e1 10760 bool first = true;
5e220199 10761 size_t cnt;
625d49fc 10762 uint64_t val = entry->d_un.d_val;
103f02d3 10763
60bca95a 10764 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10765 if (val & flags[cnt].bit)
30800947
NC
10766 {
10767 if (! first)
10768 putchar (' ');
10769 fputs (flags[cnt].str, stdout);
015dc7e1 10770 first = false;
30800947
NC
10771 val ^= flags[cnt].bit;
10772 }
76da6bbe 10773
103f02d3 10774 if (val != 0 || first)
f7a99963
NC
10775 {
10776 if (! first)
10777 putchar (' ');
10778 print_vma (val, HEX);
10779 }
103f02d3
UD
10780 }
10781 break;
76da6bbe 10782
252b5132 10783 default:
f7a99963
NC
10784 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10785 break;
252b5132 10786 }
35b1837e 10787 putchar ('\n');
252b5132
RH
10788}
10789
28f997cf
TG
10790/* VMS vs Unix time offset and factor. */
10791
10792#define VMS_EPOCH_OFFSET 35067168000000000LL
10793#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10794#ifndef INT64_MIN
10795#define INT64_MIN (-9223372036854775807LL - 1)
10796#endif
28f997cf
TG
10797
10798/* Display a VMS time in a human readable format. */
10799
10800static void
0e3c1eeb 10801print_vms_time (int64_t vmstime)
28f997cf 10802{
dccc31de 10803 struct tm *tm = NULL;
28f997cf
TG
10804 time_t unxtime;
10805
dccc31de
AM
10806 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10807 {
10808 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10809 unxtime = vmstime;
10810 if (unxtime == vmstime)
10811 tm = gmtime (&unxtime);
10812 }
10813 if (tm != NULL)
10814 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10815 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10816 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 10817}
28f997cf 10818
ecc51f48 10819static void
2cf0635d 10820dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10821{
10822 switch (entry->d_tag)
10823 {
0de14b54 10824 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10825 /* First 3 slots reserved. */
ecc51f48
NC
10826 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10827 printf (" -- ");
10828 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10829 break;
10830
28f997cf 10831 case DT_IA_64_VMS_LINKTIME:
28f997cf 10832 print_vms_time (entry->d_un.d_val);
28f997cf
TG
10833 break;
10834
10835 case DT_IA_64_VMS_LNKFLAGS:
10836 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10837 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10838 printf (" CALL_DEBUG");
10839 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10840 printf (" NOP0BUFS");
10841 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10842 printf (" P0IMAGE");
10843 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10844 printf (" MKTHREADS");
10845 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10846 printf (" UPCALLS");
10847 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10848 printf (" IMGSTA");
10849 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10850 printf (" INITIALIZE");
10851 if (entry->d_un.d_val & VMS_LF_MAIN)
10852 printf (" MAIN");
10853 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10854 printf (" EXE_INIT");
10855 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10856 printf (" TBK_IN_IMG");
10857 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10858 printf (" DBG_IN_IMG");
10859 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10860 printf (" TBK_IN_DSF");
10861 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10862 printf (" DBG_IN_DSF");
10863 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10864 printf (" SIGNATURES");
10865 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10866 printf (" REL_SEG_OFF");
10867 break;
10868
bdf4d63a
JJ
10869 default:
10870 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10871 break;
ecc51f48 10872 }
bdf4d63a 10873 putchar ('\n');
ecc51f48
NC
10874}
10875
015dc7e1 10876static bool
dda8d76d 10877get_32bit_dynamic_section (Filedata * filedata)
252b5132 10878{
2cf0635d
NC
10879 Elf32_External_Dyn * edyn;
10880 Elf32_External_Dyn * ext;
10881 Elf_Internal_Dyn * entry;
103f02d3 10882
978c4450
AM
10883 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10884 filedata->dynamic_addr, 1,
10885 filedata->dynamic_size,
10886 _("dynamic section"));
a6e9f9df 10887 if (!edyn)
015dc7e1 10888 return false;
103f02d3 10889
071436c6
NC
10890 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10891 might not have the luxury of section headers. Look for the DT_NULL
10892 terminator to determine the number of entries. */
978c4450
AM
10893 for (ext = edyn, filedata->dynamic_nent = 0;
10894 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10895 ext++)
10896 {
978c4450 10897 filedata->dynamic_nent++;
ba2685cc
AM
10898 if (BYTE_GET (ext->d_tag) == DT_NULL)
10899 break;
10900 }
252b5132 10901
978c4450
AM
10902 filedata->dynamic_section
10903 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10904 if (filedata->dynamic_section == NULL)
252b5132 10905 {
26c527e6
AM
10906 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
10907 filedata->dynamic_nent);
9ea033b2 10908 free (edyn);
015dc7e1 10909 return false;
9ea033b2 10910 }
252b5132 10911
978c4450
AM
10912 for (ext = edyn, entry = filedata->dynamic_section;
10913 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10914 ext++, entry++)
9ea033b2 10915 {
fb514b26
AM
10916 entry->d_tag = BYTE_GET (ext->d_tag);
10917 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10918 }
10919
9ea033b2
NC
10920 free (edyn);
10921
015dc7e1 10922 return true;
9ea033b2
NC
10923}
10924
015dc7e1 10925static bool
dda8d76d 10926get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10927{
2cf0635d
NC
10928 Elf64_External_Dyn * edyn;
10929 Elf64_External_Dyn * ext;
10930 Elf_Internal_Dyn * entry;
103f02d3 10931
071436c6 10932 /* Read in the data. */
978c4450
AM
10933 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10934 filedata->dynamic_addr, 1,
10935 filedata->dynamic_size,
10936 _("dynamic section"));
a6e9f9df 10937 if (!edyn)
015dc7e1 10938 return false;
103f02d3 10939
071436c6
NC
10940 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10941 might not have the luxury of section headers. Look for the DT_NULL
10942 terminator to determine the number of entries. */
978c4450 10943 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10944 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10945 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10946 ext++)
10947 {
978c4450 10948 filedata->dynamic_nent++;
66543521 10949 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10950 break;
10951 }
252b5132 10952
978c4450
AM
10953 filedata->dynamic_section
10954 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10955 if (filedata->dynamic_section == NULL)
252b5132 10956 {
26c527e6
AM
10957 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
10958 filedata->dynamic_nent);
252b5132 10959 free (edyn);
015dc7e1 10960 return false;
252b5132
RH
10961 }
10962
071436c6 10963 /* Convert from external to internal formats. */
978c4450
AM
10964 for (ext = edyn, entry = filedata->dynamic_section;
10965 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10966 ext++, entry++)
252b5132 10967 {
66543521
AM
10968 entry->d_tag = BYTE_GET (ext->d_tag);
10969 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10970 }
10971
10972 free (edyn);
10973
015dc7e1 10974 return true;
9ea033b2
NC
10975}
10976
4de91c10
AM
10977static bool
10978get_dynamic_section (Filedata *filedata)
10979{
10980 if (filedata->dynamic_section)
10981 return true;
10982
10983 if (is_32bit_elf)
10984 return get_32bit_dynamic_section (filedata);
10985 else
10986 return get_64bit_dynamic_section (filedata);
10987}
10988
e9e44622 10989static void
625d49fc 10990print_dynamic_flags (uint64_t flags)
d1133906 10991{
015dc7e1 10992 bool first = true;
13ae64f3 10993
d1133906
NC
10994 while (flags)
10995 {
625d49fc 10996 uint64_t flag;
d1133906
NC
10997
10998 flag = flags & - flags;
10999 flags &= ~ flag;
11000
e9e44622 11001 if (first)
015dc7e1 11002 first = false;
e9e44622
JJ
11003 else
11004 putc (' ', stdout);
13ae64f3 11005
d1133906
NC
11006 switch (flag)
11007 {
e9e44622
JJ
11008 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11009 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11010 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11011 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11012 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 11013 default: fputs (_("unknown"), stdout); break;
d1133906
NC
11014 }
11015 }
e9e44622 11016 puts ("");
d1133906
NC
11017}
11018
625d49fc 11019static uint64_t *
be7d229a 11020get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
11021{
11022 unsigned char * e_data;
625d49fc 11023 uint64_t * i_data;
10ca4b04 11024
be7d229a
AM
11025 /* If size_t is smaller than uint64_t, eg because you are building
11026 on a 32-bit host, then make sure that when number is cast to
11027 size_t no information is lost. */
11028 if ((size_t) number != number
11029 || ent_size * number / ent_size != number)
10ca4b04 11030 {
be7d229a 11031 error (_("Size overflow prevents reading %" PRIu64
b8281767 11032 " elements of size %u\n"),
be7d229a 11033 number, ent_size);
10ca4b04
L
11034 return NULL;
11035 }
11036
11037 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11038 attempting to allocate memory when the read is bound to fail. */
11039 if (ent_size * number > filedata->file_size)
11040 {
b8281767 11041 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 11042 number);
10ca4b04
L
11043 return NULL;
11044 }
11045
11046 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11047 if (e_data == NULL)
11048 {
b8281767 11049 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 11050 number);
10ca4b04
L
11051 return NULL;
11052 }
11053
11054 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11055 {
b8281767 11056 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 11057 number * ent_size);
10ca4b04
L
11058 free (e_data);
11059 return NULL;
11060 }
11061
625d49fc 11062 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
11063 if (i_data == NULL)
11064 {
b8281767 11065 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 11066 number);
10ca4b04
L
11067 free (e_data);
11068 return NULL;
11069 }
11070
11071 while (number--)
11072 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11073
11074 free (e_data);
11075
11076 return i_data;
11077}
11078
26c527e6 11079static uint64_t
10ca4b04
L
11080get_num_dynamic_syms (Filedata * filedata)
11081{
26c527e6 11082 uint64_t num_of_syms = 0;
10ca4b04
L
11083
11084 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11085 return num_of_syms;
11086
978c4450 11087 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11088 {
11089 unsigned char nb[8];
11090 unsigned char nc[8];
11091 unsigned int hash_ent_size = 4;
11092
11093 if ((filedata->file_header.e_machine == EM_ALPHA
11094 || filedata->file_header.e_machine == EM_S390
11095 || filedata->file_header.e_machine == EM_S390_OLD)
11096 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11097 hash_ent_size = 8;
11098
63cf857e
AM
11099 if (fseek64 (filedata->handle,
11100 (filedata->archive_file_offset
11101 + offset_from_vma (filedata,
11102 filedata->dynamic_info[DT_HASH],
11103 sizeof nb + sizeof nc)),
11104 SEEK_SET))
10ca4b04
L
11105 {
11106 error (_("Unable to seek to start of dynamic information\n"));
11107 goto no_hash;
11108 }
11109
11110 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11111 {
11112 error (_("Failed to read in number of buckets\n"));
11113 goto no_hash;
11114 }
11115
11116 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11117 {
11118 error (_("Failed to read in number of chains\n"));
11119 goto no_hash;
11120 }
11121
978c4450
AM
11122 filedata->nbuckets = byte_get (nb, hash_ent_size);
11123 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11124
2482f306
AM
11125 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11126 {
11127 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11128 hash_ent_size);
11129 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11130 hash_ent_size);
001890e1 11131
2482f306
AM
11132 if (filedata->buckets != NULL && filedata->chains != NULL)
11133 num_of_syms = filedata->nchains;
11134 }
ceb9bf11 11135 no_hash:
10ca4b04
L
11136 if (num_of_syms == 0)
11137 {
9db70fc3
AM
11138 free (filedata->buckets);
11139 filedata->buckets = NULL;
11140 free (filedata->chains);
11141 filedata->chains = NULL;
978c4450 11142 filedata->nbuckets = 0;
10ca4b04
L
11143 }
11144 }
11145
978c4450 11146 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11147 {
11148 unsigned char nb[16];
625d49fc
AM
11149 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11150 uint64_t buckets_vma;
26c527e6 11151 uint64_t hn;
10ca4b04 11152
63cf857e
AM
11153 if (fseek64 (filedata->handle,
11154 (filedata->archive_file_offset
11155 + offset_from_vma (filedata,
11156 filedata->dynamic_info_DT_GNU_HASH,
11157 sizeof nb)),
11158 SEEK_SET))
10ca4b04
L
11159 {
11160 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11161 goto no_gnu_hash;
11162 }
11163
11164 if (fread (nb, 16, 1, filedata->handle) != 1)
11165 {
11166 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11167 goto no_gnu_hash;
11168 }
11169
978c4450
AM
11170 filedata->ngnubuckets = byte_get (nb, 4);
11171 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11172 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11173 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11174 if (is_32bit_elf)
11175 buckets_vma += bitmaskwords * 4;
11176 else
11177 buckets_vma += bitmaskwords * 8;
11178
63cf857e
AM
11179 if (fseek64 (filedata->handle,
11180 (filedata->archive_file_offset
11181 + offset_from_vma (filedata, buckets_vma, 4)),
11182 SEEK_SET))
10ca4b04
L
11183 {
11184 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11185 goto no_gnu_hash;
11186 }
11187
978c4450
AM
11188 filedata->gnubuckets
11189 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11190
978c4450 11191 if (filedata->gnubuckets == NULL)
90837ea7 11192 goto no_gnu_hash;
10ca4b04 11193
978c4450
AM
11194 for (i = 0; i < filedata->ngnubuckets; i++)
11195 if (filedata->gnubuckets[i] != 0)
10ca4b04 11196 {
978c4450 11197 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11198 goto no_gnu_hash;
10ca4b04 11199
978c4450
AM
11200 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11201 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11202 }
11203
11204 if (maxchain == 0xffffffff)
90837ea7 11205 goto no_gnu_hash;
10ca4b04 11206
978c4450 11207 maxchain -= filedata->gnusymidx;
10ca4b04 11208
63cf857e
AM
11209 if (fseek64 (filedata->handle,
11210 (filedata->archive_file_offset
11211 + offset_from_vma (filedata,
11212 buckets_vma + 4 * (filedata->ngnubuckets
11213 + maxchain),
11214 4)),
11215 SEEK_SET))
10ca4b04
L
11216 {
11217 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11218 goto no_gnu_hash;
11219 }
11220
11221 do
11222 {
11223 if (fread (nb, 4, 1, filedata->handle) != 1)
11224 {
11225 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11226 goto no_gnu_hash;
11227 }
11228
11229 if (maxchain + 1 == 0)
90837ea7 11230 goto no_gnu_hash;
10ca4b04
L
11231
11232 ++maxchain;
11233 }
11234 while ((byte_get (nb, 4) & 1) == 0);
11235
63cf857e
AM
11236 if (fseek64 (filedata->handle,
11237 (filedata->archive_file_offset
11238 + offset_from_vma (filedata, (buckets_vma
11239 + 4 * filedata->ngnubuckets),
11240 4)),
11241 SEEK_SET))
10ca4b04
L
11242 {
11243 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11244 goto no_gnu_hash;
11245 }
11246
978c4450
AM
11247 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11248 filedata->ngnuchains = maxchain;
10ca4b04 11249
978c4450 11250 if (filedata->gnuchains == NULL)
90837ea7 11251 goto no_gnu_hash;
10ca4b04 11252
978c4450 11253 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11254 {
63cf857e
AM
11255 if (fseek64 (filedata->handle,
11256 (filedata->archive_file_offset
11257 + offset_from_vma (filedata, (buckets_vma
11258 + 4 * (filedata->ngnubuckets
11259 + maxchain)), 4)),
11260 SEEK_SET))
10ca4b04
L
11261 {
11262 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11263 goto no_gnu_hash;
11264 }
11265
978c4450 11266 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11267 if (filedata->mipsxlat == NULL)
11268 goto no_gnu_hash;
10ca4b04
L
11269 }
11270
978c4450
AM
11271 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11272 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11273 {
625d49fc
AM
11274 uint64_t si = filedata->gnubuckets[hn];
11275 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11276
11277 do
11278 {
978c4450 11279 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11280 {
c31ab5a0
AM
11281 if (off < filedata->ngnuchains
11282 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11283 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11284 }
11285 else
11286 {
11287 if (si >= num_of_syms)
11288 num_of_syms = si + 1;
11289 }
11290 si++;
11291 }
978c4450
AM
11292 while (off < filedata->ngnuchains
11293 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11294 }
11295
90837ea7 11296 if (num_of_syms == 0)
10ca4b04 11297 {
90837ea7 11298 no_gnu_hash:
9db70fc3
AM
11299 free (filedata->mipsxlat);
11300 filedata->mipsxlat = NULL;
11301 free (filedata->gnuchains);
11302 filedata->gnuchains = NULL;
11303 free (filedata->gnubuckets);
11304 filedata->gnubuckets = NULL;
978c4450
AM
11305 filedata->ngnubuckets = 0;
11306 filedata->ngnuchains = 0;
10ca4b04
L
11307 }
11308 }
11309
11310 return num_of_syms;
11311}
11312
b2d38a17
NC
11313/* Parse and display the contents of the dynamic section. */
11314
015dc7e1 11315static bool
dda8d76d 11316process_dynamic_section (Filedata * filedata)
9ea033b2 11317{
2cf0635d 11318 Elf_Internal_Dyn * entry;
9ea033b2 11319
93df3340 11320 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11321 {
11322 if (do_dynamic)
ca0e11aa
NC
11323 {
11324 if (filedata->is_separate)
11325 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11326 filedata->file_name);
11327 else
11328 printf (_("\nThere is no dynamic section in this file.\n"));
11329 }
9ea033b2 11330
015dc7e1 11331 return true;
9ea033b2
NC
11332 }
11333
4de91c10
AM
11334 if (!get_dynamic_section (filedata))
11335 return false;
9ea033b2 11336
252b5132 11337 /* Find the appropriate symbol table. */
978c4450 11338 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11339 {
26c527e6 11340 uint64_t num_of_syms;
2482f306 11341
978c4450
AM
11342 for (entry = filedata->dynamic_section;
11343 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11344 ++entry)
10ca4b04 11345 if (entry->d_tag == DT_SYMTAB)
978c4450 11346 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11347 else if (entry->d_tag == DT_SYMENT)
978c4450 11348 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11349 else if (entry->d_tag == DT_HASH)
978c4450 11350 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11351 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11352 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11353 else if ((filedata->file_header.e_machine == EM_MIPS
11354 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11355 && entry->d_tag == DT_MIPS_XHASH)
11356 {
978c4450
AM
11357 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11358 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11359 }
252b5132 11360
2482f306
AM
11361 num_of_syms = get_num_dynamic_syms (filedata);
11362
11363 if (num_of_syms != 0
11364 && filedata->dynamic_symbols == NULL
11365 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11366 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11367 {
11368 Elf_Internal_Phdr *seg;
625d49fc 11369 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11370
2482f306
AM
11371 if (! get_program_headers (filedata))
11372 {
11373 error (_("Cannot interpret virtual addresses "
11374 "without program headers.\n"));
015dc7e1 11375 return false;
2482f306 11376 }
252b5132 11377
2482f306
AM
11378 for (seg = filedata->program_headers;
11379 seg < filedata->program_headers + filedata->file_header.e_phnum;
11380 ++seg)
11381 {
11382 if (seg->p_type != PT_LOAD)
11383 continue;
252b5132 11384
2482f306
AM
11385 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11386 {
11387 /* See PR 21379 for a reproducer. */
11388 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11389 return false;
2482f306 11390 }
252b5132 11391
2482f306
AM
11392 if (vma >= (seg->p_vaddr & -seg->p_align)
11393 && vma < seg->p_vaddr + seg->p_filesz)
11394 {
11395 /* Since we do not know how big the symbol table is,
11396 we default to reading in up to the end of PT_LOAD
11397 segment and processing that. This is overkill, I
11398 know, but it should work. */
11399 Elf_Internal_Shdr section;
11400 section.sh_offset = (vma - seg->p_vaddr
11401 + seg->p_offset);
11402 section.sh_size = (num_of_syms
11403 * filedata->dynamic_info[DT_SYMENT]);
11404 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11405
11406 if (do_checks
11407 && filedata->dynamic_symtab_section != NULL
11408 && ((filedata->dynamic_symtab_section->sh_offset
11409 != section.sh_offset)
11410 || (filedata->dynamic_symtab_section->sh_size
11411 != section.sh_size)
11412 || (filedata->dynamic_symtab_section->sh_entsize
11413 != section.sh_entsize)))
11414 warn (_("\
11415the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11416
2482f306
AM
11417 section.sh_name = filedata->string_table_length;
11418 filedata->dynamic_symbols
4de91c10 11419 = get_elf_symbols (filedata, &section,
2482f306
AM
11420 &filedata->num_dynamic_syms);
11421 if (filedata->dynamic_symbols == NULL
11422 || filedata->num_dynamic_syms != num_of_syms)
11423 {
11424 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11425 return false;
2482f306
AM
11426 }
11427 break;
11428 }
11429 }
11430 }
11431 }
252b5132
RH
11432
11433 /* Similarly find a string table. */
978c4450
AM
11434 if (filedata->dynamic_strings == NULL)
11435 for (entry = filedata->dynamic_section;
11436 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11437 ++entry)
11438 {
11439 if (entry->d_tag == DT_STRTAB)
978c4450 11440 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11441
10ca4b04 11442 if (entry->d_tag == DT_STRSZ)
978c4450 11443 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11444
978c4450
AM
11445 if (filedata->dynamic_info[DT_STRTAB]
11446 && filedata->dynamic_info[DT_STRSZ])
10ca4b04 11447 {
26c527e6 11448 uint64_t offset;
be7d229a 11449 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11450
11451 offset = offset_from_vma (filedata,
978c4450 11452 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11453 str_tab_len);
8ac10c5b
L
11454 if (do_checks
11455 && filedata->dynamic_strtab_section
11456 && ((filedata->dynamic_strtab_section->sh_offset
11457 != (file_ptr) offset)
11458 || (filedata->dynamic_strtab_section->sh_size
11459 != str_tab_len)))
11460 warn (_("\
11461the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11462
978c4450
AM
11463 filedata->dynamic_strings
11464 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11465 _("dynamic string table"));
11466 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11467 {
11468 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11469 break;
11470 }
e3d39609 11471
978c4450 11472 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11473 break;
11474 }
11475 }
252b5132
RH
11476
11477 /* And find the syminfo section if available. */
978c4450 11478 if (filedata->dynamic_syminfo == NULL)
252b5132 11479 {
26c527e6 11480 uint64_t syminsz = 0;
252b5132 11481
978c4450
AM
11482 for (entry = filedata->dynamic_section;
11483 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11484 ++entry)
252b5132
RH
11485 {
11486 if (entry->d_tag == DT_SYMINENT)
11487 {
11488 /* Note: these braces are necessary to avoid a syntax
11489 error from the SunOS4 C compiler. */
049b0c3a
NC
11490 /* PR binutils/17531: A corrupt file can trigger this test.
11491 So do not use an assert, instead generate an error message. */
11492 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11493 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11494 (int) entry->d_un.d_val);
252b5132
RH
11495 }
11496 else if (entry->d_tag == DT_SYMINSZ)
11497 syminsz = entry->d_un.d_val;
11498 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11499 filedata->dynamic_syminfo_offset
11500 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11501 }
11502
978c4450 11503 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11504 {
2cf0635d
NC
11505 Elf_External_Syminfo * extsyminfo;
11506 Elf_External_Syminfo * extsym;
11507 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11508
11509 /* There is a syminfo section. Read the data. */
3f5e193b 11510 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11511 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11512 1, syminsz, _("symbol information"));
a6e9f9df 11513 if (!extsyminfo)
015dc7e1 11514 return false;
252b5132 11515
978c4450 11516 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11517 {
11518 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11519 free (filedata->dynamic_syminfo);
e3d39609 11520 }
978c4450
AM
11521 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11522 if (filedata->dynamic_syminfo == NULL)
252b5132 11523 {
26c527e6
AM
11524 error (_("Out of memory allocating %" PRIu64
11525 " bytes for dynamic symbol info\n"),
11526 syminsz);
015dc7e1 11527 return false;
252b5132
RH
11528 }
11529
2482f306
AM
11530 filedata->dynamic_syminfo_nent
11531 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11532 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11533 syminfo < (filedata->dynamic_syminfo
11534 + filedata->dynamic_syminfo_nent);
86dba8ee 11535 ++syminfo, ++extsym)
252b5132 11536 {
86dba8ee
AM
11537 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11538 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11539 }
11540
11541 free (extsyminfo);
11542 }
11543 }
11544
978c4450 11545 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11546 {
f253158f 11547 if (filedata->is_separate)
26c527e6
AM
11548 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
11549 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
11550 filedata->dynamic_nent),
f253158f
NC
11551 filedata->file_name,
11552 filedata->dynamic_addr,
26c527e6 11553 filedata->dynamic_nent);
84a9f195 11554 else
02da71ee 11555 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
26c527e6
AM
11556 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
11557 filedata->dynamic_nent),
84a9f195 11558 filedata->dynamic_addr,
26c527e6 11559 filedata->dynamic_nent);
ca0e11aa 11560 }
252b5132
RH
11561 if (do_dynamic)
11562 printf (_(" Tag Type Name/Value\n"));
11563
978c4450
AM
11564 for (entry = filedata->dynamic_section;
11565 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11566 entry++)
252b5132
RH
11567 {
11568 if (do_dynamic)
f7a99963 11569 {
2cf0635d 11570 const char * dtype;
e699b9ff 11571
f7a99963
NC
11572 putchar (' ');
11573 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11574 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11575 printf (" (%s)%*s", dtype,
32ec8896 11576 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11577 }
252b5132
RH
11578
11579 switch (entry->d_tag)
11580 {
d1133906
NC
11581 case DT_FLAGS:
11582 if (do_dynamic)
e9e44622 11583 print_dynamic_flags (entry->d_un.d_val);
d1133906 11584 break;
76da6bbe 11585
252b5132
RH
11586 case DT_AUXILIARY:
11587 case DT_FILTER:
019148e4
L
11588 case DT_CONFIG:
11589 case DT_DEPAUDIT:
11590 case DT_AUDIT:
252b5132
RH
11591 if (do_dynamic)
11592 {
019148e4 11593 switch (entry->d_tag)
b34976b6 11594 {
019148e4
L
11595 case DT_AUXILIARY:
11596 printf (_("Auxiliary library"));
11597 break;
11598
11599 case DT_FILTER:
11600 printf (_("Filter library"));
11601 break;
11602
b34976b6 11603 case DT_CONFIG:
019148e4
L
11604 printf (_("Configuration file"));
11605 break;
11606
11607 case DT_DEPAUDIT:
11608 printf (_("Dependency audit library"));
11609 break;
11610
11611 case DT_AUDIT:
11612 printf (_("Audit library"));
11613 break;
11614 }
252b5132 11615
84714f86 11616 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11617 printf (": [%s]\n",
84714f86 11618 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11619 else
f7a99963
NC
11620 {
11621 printf (": ");
11622 print_vma (entry->d_un.d_val, PREFIX_HEX);
11623 putchar ('\n');
11624 }
252b5132
RH
11625 }
11626 break;
11627
dcefbbbd 11628 case DT_FEATURE:
252b5132
RH
11629 if (do_dynamic)
11630 {
11631 printf (_("Flags:"));
86f55779 11632
252b5132
RH
11633 if (entry->d_un.d_val == 0)
11634 printf (_(" None\n"));
11635 else
11636 {
26c527e6 11637 uint64_t val = entry->d_un.d_val;
86f55779 11638
252b5132
RH
11639 if (val & DTF_1_PARINIT)
11640 {
11641 printf (" PARINIT");
11642 val ^= DTF_1_PARINIT;
11643 }
dcefbbbd
L
11644 if (val & DTF_1_CONFEXP)
11645 {
11646 printf (" CONFEXP");
11647 val ^= DTF_1_CONFEXP;
11648 }
252b5132 11649 if (val != 0)
26c527e6 11650 printf (" %" PRIx64, val);
252b5132
RH
11651 puts ("");
11652 }
11653 }
11654 break;
11655
11656 case DT_POSFLAG_1:
11657 if (do_dynamic)
11658 {
11659 printf (_("Flags:"));
86f55779 11660
252b5132
RH
11661 if (entry->d_un.d_val == 0)
11662 printf (_(" None\n"));
11663 else
11664 {
26c527e6 11665 uint64_t val = entry->d_un.d_val;
86f55779 11666
252b5132
RH
11667 if (val & DF_P1_LAZYLOAD)
11668 {
11669 printf (" LAZYLOAD");
11670 val ^= DF_P1_LAZYLOAD;
11671 }
11672 if (val & DF_P1_GROUPPERM)
11673 {
11674 printf (" GROUPPERM");
11675 val ^= DF_P1_GROUPPERM;
11676 }
11677 if (val != 0)
26c527e6 11678 printf (" %" PRIx64, val);
252b5132
RH
11679 puts ("");
11680 }
11681 }
11682 break;
11683
11684 case DT_FLAGS_1:
11685 if (do_dynamic)
11686 {
11687 printf (_("Flags:"));
11688 if (entry->d_un.d_val == 0)
11689 printf (_(" None\n"));
11690 else
11691 {
26c527e6 11692 uint64_t val = entry->d_un.d_val;
86f55779 11693
252b5132
RH
11694 if (val & DF_1_NOW)
11695 {
11696 printf (" NOW");
11697 val ^= DF_1_NOW;
11698 }
11699 if (val & DF_1_GLOBAL)
11700 {
11701 printf (" GLOBAL");
11702 val ^= DF_1_GLOBAL;
11703 }
11704 if (val & DF_1_GROUP)
11705 {
11706 printf (" GROUP");
11707 val ^= DF_1_GROUP;
11708 }
11709 if (val & DF_1_NODELETE)
11710 {
11711 printf (" NODELETE");
11712 val ^= DF_1_NODELETE;
11713 }
11714 if (val & DF_1_LOADFLTR)
11715 {
11716 printf (" LOADFLTR");
11717 val ^= DF_1_LOADFLTR;
11718 }
11719 if (val & DF_1_INITFIRST)
11720 {
11721 printf (" INITFIRST");
11722 val ^= DF_1_INITFIRST;
11723 }
11724 if (val & DF_1_NOOPEN)
11725 {
11726 printf (" NOOPEN");
11727 val ^= DF_1_NOOPEN;
11728 }
11729 if (val & DF_1_ORIGIN)
11730 {
11731 printf (" ORIGIN");
11732 val ^= DF_1_ORIGIN;
11733 }
11734 if (val & DF_1_DIRECT)
11735 {
11736 printf (" DIRECT");
11737 val ^= DF_1_DIRECT;
11738 }
11739 if (val & DF_1_TRANS)
11740 {
11741 printf (" TRANS");
11742 val ^= DF_1_TRANS;
11743 }
11744 if (val & DF_1_INTERPOSE)
11745 {
11746 printf (" INTERPOSE");
11747 val ^= DF_1_INTERPOSE;
11748 }
f7db6139 11749 if (val & DF_1_NODEFLIB)
dcefbbbd 11750 {
f7db6139
L
11751 printf (" NODEFLIB");
11752 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11753 }
11754 if (val & DF_1_NODUMP)
11755 {
11756 printf (" NODUMP");
11757 val ^= DF_1_NODUMP;
11758 }
34b60028 11759 if (val & DF_1_CONFALT)
dcefbbbd 11760 {
34b60028
L
11761 printf (" CONFALT");
11762 val ^= DF_1_CONFALT;
11763 }
11764 if (val & DF_1_ENDFILTEE)
11765 {
11766 printf (" ENDFILTEE");
11767 val ^= DF_1_ENDFILTEE;
11768 }
11769 if (val & DF_1_DISPRELDNE)
11770 {
11771 printf (" DISPRELDNE");
11772 val ^= DF_1_DISPRELDNE;
11773 }
11774 if (val & DF_1_DISPRELPND)
11775 {
11776 printf (" DISPRELPND");
11777 val ^= DF_1_DISPRELPND;
11778 }
11779 if (val & DF_1_NODIRECT)
11780 {
11781 printf (" NODIRECT");
11782 val ^= DF_1_NODIRECT;
11783 }
11784 if (val & DF_1_IGNMULDEF)
11785 {
11786 printf (" IGNMULDEF");
11787 val ^= DF_1_IGNMULDEF;
11788 }
11789 if (val & DF_1_NOKSYMS)
11790 {
11791 printf (" NOKSYMS");
11792 val ^= DF_1_NOKSYMS;
11793 }
11794 if (val & DF_1_NOHDR)
11795 {
11796 printf (" NOHDR");
11797 val ^= DF_1_NOHDR;
11798 }
11799 if (val & DF_1_EDITED)
11800 {
11801 printf (" EDITED");
11802 val ^= DF_1_EDITED;
11803 }
11804 if (val & DF_1_NORELOC)
11805 {
11806 printf (" NORELOC");
11807 val ^= DF_1_NORELOC;
11808 }
11809 if (val & DF_1_SYMINTPOSE)
11810 {
11811 printf (" SYMINTPOSE");
11812 val ^= DF_1_SYMINTPOSE;
11813 }
11814 if (val & DF_1_GLOBAUDIT)
11815 {
11816 printf (" GLOBAUDIT");
11817 val ^= DF_1_GLOBAUDIT;
11818 }
11819 if (val & DF_1_SINGLETON)
11820 {
11821 printf (" SINGLETON");
11822 val ^= DF_1_SINGLETON;
dcefbbbd 11823 }
5c383f02
RO
11824 if (val & DF_1_STUB)
11825 {
11826 printf (" STUB");
11827 val ^= DF_1_STUB;
11828 }
11829 if (val & DF_1_PIE)
11830 {
11831 printf (" PIE");
11832 val ^= DF_1_PIE;
11833 }
b1202ffa
L
11834 if (val & DF_1_KMOD)
11835 {
11836 printf (" KMOD");
11837 val ^= DF_1_KMOD;
11838 }
11839 if (val & DF_1_WEAKFILTER)
11840 {
11841 printf (" WEAKFILTER");
11842 val ^= DF_1_WEAKFILTER;
11843 }
11844 if (val & DF_1_NOCOMMON)
11845 {
11846 printf (" NOCOMMON");
11847 val ^= DF_1_NOCOMMON;
11848 }
252b5132 11849 if (val != 0)
26c527e6 11850 printf (" %" PRIx64, val);
252b5132
RH
11851 puts ("");
11852 }
11853 }
11854 break;
11855
11856 case DT_PLTREL:
978c4450 11857 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11858 if (do_dynamic)
dda8d76d 11859 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11860 break;
11861
11862 case DT_NULL :
11863 case DT_NEEDED :
11864 case DT_PLTGOT :
11865 case DT_HASH :
11866 case DT_STRTAB :
11867 case DT_SYMTAB :
11868 case DT_RELA :
11869 case DT_INIT :
11870 case DT_FINI :
11871 case DT_SONAME :
11872 case DT_RPATH :
11873 case DT_SYMBOLIC:
11874 case DT_REL :
a7fd1186 11875 case DT_RELR :
252b5132
RH
11876 case DT_DEBUG :
11877 case DT_TEXTREL :
11878 case DT_JMPREL :
019148e4 11879 case DT_RUNPATH :
978c4450 11880 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11881
11882 if (do_dynamic)
11883 {
84714f86 11884 const char *name;
252b5132 11885
84714f86
AM
11886 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11887 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11888 else
d79b3d50 11889 name = NULL;
252b5132
RH
11890
11891 if (name)
11892 {
11893 switch (entry->d_tag)
11894 {
11895 case DT_NEEDED:
11896 printf (_("Shared library: [%s]"), name);
11897
13acb58d
AM
11898 if (filedata->program_interpreter
11899 && streq (name, filedata->program_interpreter))
f7a99963 11900 printf (_(" program interpreter"));
252b5132
RH
11901 break;
11902
11903 case DT_SONAME:
f7a99963 11904 printf (_("Library soname: [%s]"), name);
252b5132
RH
11905 break;
11906
11907 case DT_RPATH:
f7a99963 11908 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11909 break;
11910
019148e4
L
11911 case DT_RUNPATH:
11912 printf (_("Library runpath: [%s]"), name);
11913 break;
11914
252b5132 11915 default:
f7a99963
NC
11916 print_vma (entry->d_un.d_val, PREFIX_HEX);
11917 break;
252b5132
RH
11918 }
11919 }
11920 else
f7a99963
NC
11921 print_vma (entry->d_un.d_val, PREFIX_HEX);
11922
11923 putchar ('\n');
252b5132
RH
11924 }
11925 break;
11926
11927 case DT_PLTRELSZ:
11928 case DT_RELASZ :
11929 case DT_STRSZ :
11930 case DT_RELSZ :
11931 case DT_RELAENT :
a7fd1186
FS
11932 case DT_RELRENT :
11933 case DT_RELRSZ :
252b5132
RH
11934 case DT_SYMENT :
11935 case DT_RELENT :
978c4450 11936 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11937 /* Fall through. */
252b5132
RH
11938 case DT_PLTPADSZ:
11939 case DT_MOVEENT :
11940 case DT_MOVESZ :
04d8355a 11941 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11942 case DT_INIT_ARRAYSZ:
11943 case DT_FINI_ARRAYSZ:
047b2264
JJ
11944 case DT_GNU_CONFLICTSZ:
11945 case DT_GNU_LIBLISTSZ:
252b5132 11946 if (do_dynamic)
f7a99963
NC
11947 {
11948 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11949 printf (_(" (bytes)\n"));
f7a99963 11950 }
252b5132
RH
11951 break;
11952
11953 case DT_VERDEFNUM:
11954 case DT_VERNEEDNUM:
11955 case DT_RELACOUNT:
11956 case DT_RELCOUNT:
11957 if (do_dynamic)
f7a99963
NC
11958 {
11959 print_vma (entry->d_un.d_val, UNSIGNED);
11960 putchar ('\n');
11961 }
252b5132
RH
11962 break;
11963
11964 case DT_SYMINSZ:
11965 case DT_SYMINENT:
11966 case DT_SYMINFO:
11967 case DT_USED:
11968 case DT_INIT_ARRAY:
11969 case DT_FINI_ARRAY:
11970 if (do_dynamic)
11971 {
d79b3d50 11972 if (entry->d_tag == DT_USED
84714f86 11973 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11974 {
84714f86
AM
11975 const char *name
11976 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11977
b34976b6 11978 if (*name)
252b5132
RH
11979 {
11980 printf (_("Not needed object: [%s]\n"), name);
11981 break;
11982 }
11983 }
103f02d3 11984
f7a99963
NC
11985 print_vma (entry->d_un.d_val, PREFIX_HEX);
11986 putchar ('\n');
252b5132
RH
11987 }
11988 break;
11989
11990 case DT_BIND_NOW:
11991 /* The value of this entry is ignored. */
35b1837e
AM
11992 if (do_dynamic)
11993 putchar ('\n');
252b5132 11994 break;
103f02d3 11995
047b2264
JJ
11996 case DT_GNU_PRELINKED:
11997 if (do_dynamic)
11998 {
2cf0635d 11999 struct tm * tmp;
91d6fa6a 12000 time_t atime = entry->d_un.d_val;
047b2264 12001
91d6fa6a 12002 tmp = gmtime (&atime);
071436c6
NC
12003 /* PR 17533 file: 041-1244816-0.004. */
12004 if (tmp == NULL)
26c527e6
AM
12005 printf (_("<corrupt time val: %" PRIx64),
12006 (uint64_t) atime);
071436c6
NC
12007 else
12008 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12009 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12010 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12011
12012 }
12013 break;
12014
fdc90cb4 12015 case DT_GNU_HASH:
978c4450 12016 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
12017 if (do_dynamic)
12018 {
12019 print_vma (entry->d_un.d_val, PREFIX_HEX);
12020 putchar ('\n');
12021 }
12022 break;
12023
a5da3dee
VDM
12024 case DT_GNU_FLAGS_1:
12025 if (do_dynamic)
12026 {
12027 printf (_("Flags:"));
12028 if (entry->d_un.d_val == 0)
12029 printf (_(" None\n"));
12030 else
12031 {
26c527e6 12032 uint64_t val = entry->d_un.d_val;
a5da3dee
VDM
12033
12034 if (val & DF_GNU_1_UNIQUE)
12035 {
12036 printf (" UNIQUE");
12037 val ^= DF_GNU_1_UNIQUE;
12038 }
12039 if (val != 0)
26c527e6 12040 printf (" %" PRIx64, val);
a5da3dee
VDM
12041 puts ("");
12042 }
12043 }
12044 break;
12045
252b5132
RH
12046 default:
12047 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
12048 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12049 = entry->d_un.d_val;
252b5132
RH
12050
12051 if (do_dynamic)
12052 {
dda8d76d 12053 switch (filedata->file_header.e_machine)
252b5132 12054 {
37c18eed
SD
12055 case EM_AARCH64:
12056 dynamic_section_aarch64_val (entry);
12057 break;
252b5132 12058 case EM_MIPS:
4fe85591 12059 case EM_MIPS_RS3_LE:
978c4450 12060 dynamic_section_mips_val (filedata, entry);
252b5132 12061 break;
103f02d3 12062 case EM_PARISC:
b2d38a17 12063 dynamic_section_parisc_val (entry);
103f02d3 12064 break;
ecc51f48 12065 case EM_IA_64:
b2d38a17 12066 dynamic_section_ia64_val (entry);
ecc51f48 12067 break;
252b5132 12068 default:
f7a99963
NC
12069 print_vma (entry->d_un.d_val, PREFIX_HEX);
12070 putchar ('\n');
252b5132
RH
12071 }
12072 }
12073 break;
12074 }
12075 }
12076
015dc7e1 12077 return true;
252b5132
RH
12078}
12079
12080static char *
d3ba0551 12081get_ver_flags (unsigned int flags)
252b5132 12082{
6d4f21f6 12083 static char buff[128];
252b5132
RH
12084
12085 buff[0] = 0;
12086
12087 if (flags == 0)
12088 return _("none");
12089
12090 if (flags & VER_FLG_BASE)
7bb1ad17 12091 strcat (buff, "BASE");
252b5132
RH
12092
12093 if (flags & VER_FLG_WEAK)
12094 {
12095 if (flags & VER_FLG_BASE)
7bb1ad17 12096 strcat (buff, " | ");
252b5132 12097
7bb1ad17 12098 strcat (buff, "WEAK");
252b5132
RH
12099 }
12100
44ec90b9
RO
12101 if (flags & VER_FLG_INFO)
12102 {
12103 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12104 strcat (buff, " | ");
44ec90b9 12105
7bb1ad17 12106 strcat (buff, "INFO");
44ec90b9
RO
12107 }
12108
12109 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12110 {
12111 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12112 strcat (buff, " | ");
12113
12114 strcat (buff, _("<unknown>"));
12115 }
252b5132
RH
12116
12117 return buff;
12118}
12119
12120/* Display the contents of the version sections. */
98fb390a 12121
015dc7e1 12122static bool
dda8d76d 12123process_version_sections (Filedata * filedata)
252b5132 12124{
2cf0635d 12125 Elf_Internal_Shdr * section;
b34976b6 12126 unsigned i;
015dc7e1 12127 bool found = false;
252b5132
RH
12128
12129 if (! do_version)
015dc7e1 12130 return true;
252b5132 12131
dda8d76d
NC
12132 for (i = 0, section = filedata->section_headers;
12133 i < filedata->file_header.e_shnum;
b34976b6 12134 i++, section++)
252b5132
RH
12135 {
12136 switch (section->sh_type)
12137 {
12138 case SHT_GNU_verdef:
12139 {
2cf0635d 12140 Elf_External_Verdef * edefs;
26c527e6
AM
12141 size_t idx;
12142 size_t cnt;
2cf0635d 12143 char * endbuf;
252b5132 12144
015dc7e1 12145 found = true;
252b5132 12146
ca0e11aa
NC
12147 if (filedata->is_separate)
12148 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12149 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12150 section->sh_info),
12151 filedata->file_name,
12152 printable_section_name (filedata, section),
12153 section->sh_info);
12154 else
12155 printf (ngettext ("\nVersion definition section '%s' "
12156 "contains %u entry:\n",
12157 "\nVersion definition section '%s' "
12158 "contains %u entries:\n",
12159 section->sh_info),
12160 printable_section_name (filedata, section),
12161 section->sh_info);
047c3dbf 12162
625d49fc 12163 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12164 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12165 section->sh_offset, section->sh_link,
dda8d76d 12166 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12167
3f5e193b 12168 edefs = (Elf_External_Verdef *)
dda8d76d 12169 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12170 _("version definition section"));
a6e9f9df
AM
12171 if (!edefs)
12172 break;
59245841 12173 endbuf = (char *) edefs + section->sh_size;
252b5132 12174
1445030f 12175 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12176 {
2cf0635d
NC
12177 char * vstart;
12178 Elf_External_Verdef * edef;
b34976b6 12179 Elf_Internal_Verdef ent;
2cf0635d 12180 Elf_External_Verdaux * eaux;
b34976b6 12181 Elf_Internal_Verdaux aux;
26c527e6 12182 size_t isum;
b34976b6 12183 int j;
103f02d3 12184
252b5132 12185 vstart = ((char *) edefs) + idx;
54806181
AM
12186 if (vstart + sizeof (*edef) > endbuf)
12187 break;
252b5132
RH
12188
12189 edef = (Elf_External_Verdef *) vstart;
12190
12191 ent.vd_version = BYTE_GET (edef->vd_version);
12192 ent.vd_flags = BYTE_GET (edef->vd_flags);
12193 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12194 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12195 ent.vd_hash = BYTE_GET (edef->vd_hash);
12196 ent.vd_aux = BYTE_GET (edef->vd_aux);
12197 ent.vd_next = BYTE_GET (edef->vd_next);
12198
26c527e6 12199 printf (_(" %#06zx: Rev: %d Flags: %s"),
252b5132
RH
12200 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12201
12202 printf (_(" Index: %d Cnt: %d "),
12203 ent.vd_ndx, ent.vd_cnt);
12204
452bf675 12205 /* Check for overflow. */
1445030f 12206 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12207 break;
12208
252b5132
RH
12209 vstart += ent.vd_aux;
12210
1445030f
AM
12211 if (vstart + sizeof (*eaux) > endbuf)
12212 break;
252b5132
RH
12213 eaux = (Elf_External_Verdaux *) vstart;
12214
12215 aux.vda_name = BYTE_GET (eaux->vda_name);
12216 aux.vda_next = BYTE_GET (eaux->vda_next);
12217
84714f86 12218 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12219 printf (_("Name: %s\n"),
84714f86 12220 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12221 else
12222 printf (_("Name index: %ld\n"), aux.vda_name);
12223
12224 isum = idx + ent.vd_aux;
12225
b34976b6 12226 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12227 {
1445030f
AM
12228 if (aux.vda_next < sizeof (*eaux)
12229 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12230 {
12231 warn (_("Invalid vda_next field of %lx\n"),
12232 aux.vda_next);
12233 j = ent.vd_cnt;
12234 break;
12235 }
dd24e3da 12236 /* Check for overflow. */
7e26601c 12237 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12238 break;
12239
252b5132
RH
12240 isum += aux.vda_next;
12241 vstart += aux.vda_next;
12242
54806181
AM
12243 if (vstart + sizeof (*eaux) > endbuf)
12244 break;
1445030f 12245 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12246
12247 aux.vda_name = BYTE_GET (eaux->vda_name);
12248 aux.vda_next = BYTE_GET (eaux->vda_next);
12249
84714f86 12250 if (valid_dynamic_name (filedata, aux.vda_name))
26c527e6 12251 printf (_(" %#06zx: Parent %d: %s\n"),
978c4450 12252 isum, j,
84714f86 12253 get_dynamic_name (filedata, aux.vda_name));
252b5132 12254 else
26c527e6 12255 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
252b5132
RH
12256 isum, j, aux.vda_name);
12257 }
dd24e3da 12258
54806181
AM
12259 if (j < ent.vd_cnt)
12260 printf (_(" Version def aux past end of section\n"));
252b5132 12261
c9f02c3e
MR
12262 /* PR 17531:
12263 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12264 if (ent.vd_next < sizeof (*edef)
12265 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12266 {
12267 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12268 cnt = section->sh_info;
12269 break;
12270 }
452bf675 12271 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12272 break;
12273
252b5132
RH
12274 idx += ent.vd_next;
12275 }
dd24e3da 12276
54806181
AM
12277 if (cnt < section->sh_info)
12278 printf (_(" Version definition past end of section\n"));
252b5132
RH
12279
12280 free (edefs);
12281 }
12282 break;
103f02d3 12283
252b5132
RH
12284 case SHT_GNU_verneed:
12285 {
2cf0635d 12286 Elf_External_Verneed * eneed;
26c527e6
AM
12287 size_t idx;
12288 size_t cnt;
2cf0635d 12289 char * endbuf;
252b5132 12290
015dc7e1 12291 found = true;
252b5132 12292
ca0e11aa
NC
12293 if (filedata->is_separate)
12294 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12295 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12296 section->sh_info),
12297 filedata->file_name,
12298 printable_section_name (filedata, section),
12299 section->sh_info);
12300 else
12301 printf (ngettext ("\nVersion needs section '%s' "
12302 "contains %u entry:\n",
12303 "\nVersion needs section '%s' "
12304 "contains %u entries:\n",
12305 section->sh_info),
12306 printable_section_name (filedata, section),
12307 section->sh_info);
047c3dbf 12308
625d49fc 12309 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12310 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12311 section->sh_offset, section->sh_link,
dda8d76d 12312 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12313
dda8d76d 12314 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12315 section->sh_offset, 1,
12316 section->sh_size,
9cf03b7e 12317 _("Version Needs section"));
a6e9f9df
AM
12318 if (!eneed)
12319 break;
59245841 12320 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12321
12322 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12323 {
2cf0635d 12324 Elf_External_Verneed * entry;
b34976b6 12325 Elf_Internal_Verneed ent;
26c527e6 12326 size_t isum;
b34976b6 12327 int j;
2cf0635d 12328 char * vstart;
252b5132
RH
12329
12330 vstart = ((char *) eneed) + idx;
54806181
AM
12331 if (vstart + sizeof (*entry) > endbuf)
12332 break;
252b5132
RH
12333
12334 entry = (Elf_External_Verneed *) vstart;
12335
12336 ent.vn_version = BYTE_GET (entry->vn_version);
12337 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12338 ent.vn_file = BYTE_GET (entry->vn_file);
12339 ent.vn_aux = BYTE_GET (entry->vn_aux);
12340 ent.vn_next = BYTE_GET (entry->vn_next);
12341
26c527e6 12342 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
252b5132 12343
84714f86 12344 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12345 printf (_(" File: %s"),
84714f86 12346 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12347 else
12348 printf (_(" File: %lx"), ent.vn_file);
12349
12350 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12351
dd24e3da 12352 /* Check for overflow. */
7e26601c 12353 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12354 break;
252b5132
RH
12355 vstart += ent.vn_aux;
12356
12357 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12358 {
2cf0635d 12359 Elf_External_Vernaux * eaux;
b34976b6 12360 Elf_Internal_Vernaux aux;
252b5132 12361
54806181
AM
12362 if (vstart + sizeof (*eaux) > endbuf)
12363 break;
252b5132
RH
12364 eaux = (Elf_External_Vernaux *) vstart;
12365
12366 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12367 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12368 aux.vna_other = BYTE_GET (eaux->vna_other);
12369 aux.vna_name = BYTE_GET (eaux->vna_name);
12370 aux.vna_next = BYTE_GET (eaux->vna_next);
12371
84714f86 12372 if (valid_dynamic_name (filedata, aux.vna_name))
26c527e6 12373 printf (_(" %#06zx: Name: %s"),
84714f86 12374 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12375 else
26c527e6 12376 printf (_(" %#06zx: Name index: %lx"),
252b5132
RH
12377 isum, aux.vna_name);
12378
12379 printf (_(" Flags: %s Version: %d\n"),
12380 get_ver_flags (aux.vna_flags), aux.vna_other);
12381
1445030f
AM
12382 if (aux.vna_next < sizeof (*eaux)
12383 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12384 {
12385 warn (_("Invalid vna_next field of %lx\n"),
12386 aux.vna_next);
12387 j = ent.vn_cnt;
12388 break;
12389 }
1445030f
AM
12390 /* Check for overflow. */
12391 if (aux.vna_next > (size_t) (endbuf - vstart))
12392 break;
252b5132
RH
12393 isum += aux.vna_next;
12394 vstart += aux.vna_next;
12395 }
9cf03b7e 12396
54806181 12397 if (j < ent.vn_cnt)
f9a6a8f0 12398 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12399
1445030f
AM
12400 if (ent.vn_next < sizeof (*entry)
12401 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12402 {
452bf675 12403 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12404 cnt = section->sh_info;
12405 break;
12406 }
1445030f
AM
12407 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12408 break;
252b5132
RH
12409 idx += ent.vn_next;
12410 }
9cf03b7e 12411
54806181 12412 if (cnt < section->sh_info)
9cf03b7e 12413 warn (_("Missing Version Needs information\n"));
103f02d3 12414
252b5132
RH
12415 free (eneed);
12416 }
12417 break;
12418
12419 case SHT_GNU_versym:
12420 {
2cf0635d 12421 Elf_Internal_Shdr * link_section;
26c527e6 12422 uint64_t total;
8b73c356 12423 unsigned int cnt;
2cf0635d
NC
12424 unsigned char * edata;
12425 unsigned short * data;
12426 char * strtab;
12427 Elf_Internal_Sym * symbols;
12428 Elf_Internal_Shdr * string_sec;
26c527e6
AM
12429 uint64_t num_syms;
12430 uint64_t off;
252b5132 12431
dda8d76d 12432 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12433 break;
12434
dda8d76d 12435 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12436 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12437
dda8d76d 12438 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12439 break;
12440
015dc7e1 12441 found = true;
252b5132 12442
4de91c10 12443 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12444 if (symbols == NULL)
12445 break;
252b5132 12446
dda8d76d 12447 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12448
dda8d76d 12449 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12450 string_sec->sh_size,
12451 _("version string table"));
a6e9f9df 12452 if (!strtab)
0429c154
MS
12453 {
12454 free (symbols);
12455 break;
12456 }
252b5132 12457
ca0e11aa 12458 if (filedata->is_separate)
26c527e6
AM
12459 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
12460 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12461 total),
12462 filedata->file_name,
12463 printable_section_name (filedata, section),
26c527e6 12464 total);
ca0e11aa
NC
12465 else
12466 printf (ngettext ("\nVersion symbols section '%s' "
26c527e6 12467 "contains %" PRIu64 " entry:\n",
ca0e11aa 12468 "\nVersion symbols section '%s' "
26c527e6 12469 "contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12470 total),
12471 printable_section_name (filedata, section),
26c527e6 12472 total);
252b5132 12473
625d49fc 12474 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12475 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12476 section->sh_offset, section->sh_link,
dda8d76d 12477 printable_section_name (filedata, link_section));
252b5132 12478
dda8d76d 12479 off = offset_from_vma (filedata,
978c4450 12480 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12481 total * sizeof (short));
95099889
AM
12482 edata = (unsigned char *) get_data (NULL, filedata, off,
12483 sizeof (short), total,
12484 _("version symbol data"));
a6e9f9df
AM
12485 if (!edata)
12486 {
12487 free (strtab);
0429c154 12488 free (symbols);
a6e9f9df
AM
12489 break;
12490 }
252b5132 12491
3f5e193b 12492 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12493
12494 for (cnt = total; cnt --;)
b34976b6
AM
12495 data[cnt] = byte_get (edata + cnt * sizeof (short),
12496 sizeof (short));
252b5132
RH
12497
12498 free (edata);
12499
12500 for (cnt = 0; cnt < total; cnt += 4)
12501 {
12502 int j, nn;
ab273396
AM
12503 char *name;
12504 char *invalid = _("*invalid*");
252b5132
RH
12505
12506 printf (" %03x:", cnt);
12507
12508 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12509 switch (data[cnt + j])
252b5132
RH
12510 {
12511 case 0:
12512 fputs (_(" 0 (*local*) "), stdout);
12513 break;
12514
12515 case 1:
12516 fputs (_(" 1 (*global*) "), stdout);
12517 break;
12518
12519 default:
c244d050
NC
12520 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12521 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12522
dd24e3da 12523 /* If this index value is greater than the size of the symbols
ba5cdace 12524 array, break to avoid an out-of-bounds read. */
26c527e6 12525 if (cnt + j >= num_syms)
dd24e3da
NC
12526 {
12527 warn (_("invalid index into symbol array\n"));
12528 break;
12529 }
12530
ab273396 12531 name = NULL;
978c4450 12532 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12533 {
b34976b6 12534 Elf_Internal_Verneed ivn;
26c527e6 12535 uint64_t offset;
252b5132 12536
d93f0186 12537 offset = offset_from_vma
978c4450
AM
12538 (filedata,
12539 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12540 sizeof (Elf_External_Verneed));
252b5132 12541
b34976b6 12542 do
252b5132 12543 {
b34976b6
AM
12544 Elf_Internal_Vernaux ivna;
12545 Elf_External_Verneed evn;
12546 Elf_External_Vernaux evna;
26c527e6 12547 uint64_t a_off;
252b5132 12548
dda8d76d 12549 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12550 _("version need")) == NULL)
12551 break;
0b4362b0 12552
252b5132
RH
12553 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12554 ivn.vn_next = BYTE_GET (evn.vn_next);
12555
12556 a_off = offset + ivn.vn_aux;
12557
12558 do
12559 {
dda8d76d 12560 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12561 1, _("version need aux (2)")) == NULL)
12562 {
12563 ivna.vna_next = 0;
12564 ivna.vna_other = 0;
12565 }
12566 else
12567 {
12568 ivna.vna_next = BYTE_GET (evna.vna_next);
12569 ivna.vna_other = BYTE_GET (evna.vna_other);
12570 }
252b5132
RH
12571
12572 a_off += ivna.vna_next;
12573 }
b34976b6 12574 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12575 && ivna.vna_next != 0);
12576
b34976b6 12577 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12578 {
12579 ivna.vna_name = BYTE_GET (evna.vna_name);
12580
54806181 12581 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12582 name = invalid;
54806181
AM
12583 else
12584 name = strtab + ivna.vna_name;
252b5132
RH
12585 break;
12586 }
12587
12588 offset += ivn.vn_next;
12589 }
12590 while (ivn.vn_next);
12591 }
00d93f34 12592
ab273396 12593 if (data[cnt + j] != 0x8001
978c4450 12594 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12595 {
b34976b6
AM
12596 Elf_Internal_Verdef ivd;
12597 Elf_External_Verdef evd;
26c527e6 12598 uint64_t offset;
252b5132 12599
d93f0186 12600 offset = offset_from_vma
978c4450
AM
12601 (filedata,
12602 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12603 sizeof evd);
252b5132
RH
12604
12605 do
12606 {
dda8d76d 12607 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12608 _("version def")) == NULL)
12609 {
12610 ivd.vd_next = 0;
948f632f 12611 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12612 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12613 break;
59245841
NC
12614 }
12615 else
12616 {
12617 ivd.vd_next = BYTE_GET (evd.vd_next);
12618 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12619 }
252b5132
RH
12620
12621 offset += ivd.vd_next;
12622 }
c244d050 12623 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12624 && ivd.vd_next != 0);
12625
c244d050 12626 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12627 {
b34976b6
AM
12628 Elf_External_Verdaux evda;
12629 Elf_Internal_Verdaux ivda;
252b5132
RH
12630
12631 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12632
dda8d76d 12633 if (get_data (&evda, filedata,
59245841
NC
12634 offset - ivd.vd_next + ivd.vd_aux,
12635 sizeof (evda), 1,
12636 _("version def aux")) == NULL)
12637 break;
252b5132
RH
12638
12639 ivda.vda_name = BYTE_GET (evda.vda_name);
12640
54806181 12641 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12642 name = invalid;
12643 else if (name != NULL && name != invalid)
12644 name = _("*both*");
54806181
AM
12645 else
12646 name = strtab + ivda.vda_name;
252b5132
RH
12647 }
12648 }
ab273396
AM
12649 if (name != NULL)
12650 nn += printf ("(%s%-*s",
12651 name,
12652 12 - (int) strlen (name),
12653 ")");
252b5132
RH
12654
12655 if (nn < 18)
12656 printf ("%*c", 18 - nn, ' ');
12657 }
12658
12659 putchar ('\n');
12660 }
12661
12662 free (data);
12663 free (strtab);
12664 free (symbols);
12665 }
12666 break;
103f02d3 12667
252b5132
RH
12668 default:
12669 break;
12670 }
12671 }
12672
12673 if (! found)
ca0e11aa
NC
12674 {
12675 if (filedata->is_separate)
12676 printf (_("\nNo version information found in linked file '%s'.\n"),
12677 filedata->file_name);
12678 else
12679 printf (_("\nNo version information found in this file.\n"));
12680 }
252b5132 12681
015dc7e1 12682 return true;
252b5132
RH
12683}
12684
d1133906 12685static const char *
dda8d76d 12686get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12687{
89246a0e 12688 static char buff[64];
252b5132
RH
12689
12690 switch (binding)
12691 {
b34976b6
AM
12692 case STB_LOCAL: return "LOCAL";
12693 case STB_GLOBAL: return "GLOBAL";
12694 case STB_WEAK: return "WEAK";
252b5132
RH
12695 default:
12696 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12697 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12698 binding);
252b5132 12699 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12700 {
12701 if (binding == STB_GNU_UNIQUE
df3a023b 12702 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12703 return "UNIQUE";
12704 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12705 }
252b5132 12706 else
e9e44622 12707 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12708 return buff;
12709 }
12710}
12711
d1133906 12712static const char *
dda8d76d 12713get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12714{
89246a0e 12715 static char buff[64];
252b5132
RH
12716
12717 switch (type)
12718 {
b34976b6
AM
12719 case STT_NOTYPE: return "NOTYPE";
12720 case STT_OBJECT: return "OBJECT";
12721 case STT_FUNC: return "FUNC";
12722 case STT_SECTION: return "SECTION";
12723 case STT_FILE: return "FILE";
12724 case STT_COMMON: return "COMMON";
12725 case STT_TLS: return "TLS";
15ab5209
DB
12726 case STT_RELC: return "RELC";
12727 case STT_SRELC: return "SRELC";
252b5132
RH
12728 default:
12729 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12730 {
dda8d76d 12731 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12732 return "THUMB_FUNC";
103f02d3 12733
dda8d76d 12734 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12735 return "REGISTER";
12736
dda8d76d 12737 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12738 return "PARISC_MILLI";
12739
e9e44622 12740 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12741 }
252b5132 12742 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12743 {
dda8d76d 12744 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12745 {
12746 if (type == STT_HP_OPAQUE)
12747 return "HP_OPAQUE";
12748 if (type == STT_HP_STUB)
12749 return "HP_STUB";
12750 }
12751
8654c01f
ML
12752 if (type == STT_GNU_IFUNC
12753 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
12754 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
12755 return "IFUNC";
12756
e9e44622 12757 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12758 }
252b5132 12759 else
e9e44622 12760 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12761 return buff;
12762 }
12763}
12764
d1133906 12765static const char *
d3ba0551 12766get_symbol_visibility (unsigned int visibility)
d1133906
NC
12767{
12768 switch (visibility)
12769 {
b34976b6
AM
12770 case STV_DEFAULT: return "DEFAULT";
12771 case STV_INTERNAL: return "INTERNAL";
12772 case STV_HIDDEN: return "HIDDEN";
d1133906 12773 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12774 default:
27a45f42 12775 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12776 return _("<unknown>");
d1133906
NC
12777 }
12778}
12779
2057d69d
CZ
12780static const char *
12781get_alpha_symbol_other (unsigned int other)
9abca702 12782{
2057d69d
CZ
12783 switch (other)
12784 {
12785 case STO_ALPHA_NOPV: return "NOPV";
12786 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12787 default:
27a45f42 12788 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12789 return _("<unknown>");
9abca702 12790 }
2057d69d
CZ
12791}
12792
fd85a6a1
NC
12793static const char *
12794get_solaris_symbol_visibility (unsigned int visibility)
12795{
12796 switch (visibility)
12797 {
12798 case 4: return "EXPORTED";
12799 case 5: return "SINGLETON";
12800 case 6: return "ELIMINATE";
12801 default: return get_symbol_visibility (visibility);
12802 }
12803}
12804
2301ed1c
SN
12805static const char *
12806get_aarch64_symbol_other (unsigned int other)
12807{
12808 static char buf[32];
12809
12810 if (other & STO_AARCH64_VARIANT_PCS)
12811 {
12812 other &= ~STO_AARCH64_VARIANT_PCS;
12813 if (other == 0)
12814 return "VARIANT_PCS";
12815 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12816 return buf;
12817 }
12818 return NULL;
12819}
12820
5e2b0d47
NC
12821static const char *
12822get_mips_symbol_other (unsigned int other)
12823{
12824 switch (other)
12825 {
32ec8896
NC
12826 case STO_OPTIONAL: return "OPTIONAL";
12827 case STO_MIPS_PLT: return "MIPS PLT";
12828 case STO_MIPS_PIC: return "MIPS PIC";
12829 case STO_MICROMIPS: return "MICROMIPS";
12830 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12831 case STO_MIPS16: return "MIPS16";
12832 default: return NULL;
5e2b0d47
NC
12833 }
12834}
12835
28f997cf 12836static const char *
dda8d76d 12837get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12838{
dda8d76d 12839 if (is_ia64_vms (filedata))
28f997cf
TG
12840 {
12841 static char res[32];
12842
12843 res[0] = 0;
12844
12845 /* Function types is for images and .STB files only. */
dda8d76d 12846 switch (filedata->file_header.e_type)
28f997cf
TG
12847 {
12848 case ET_DYN:
12849 case ET_EXEC:
12850 switch (VMS_ST_FUNC_TYPE (other))
12851 {
12852 case VMS_SFT_CODE_ADDR:
12853 strcat (res, " CA");
12854 break;
12855 case VMS_SFT_SYMV_IDX:
12856 strcat (res, " VEC");
12857 break;
12858 case VMS_SFT_FD:
12859 strcat (res, " FD");
12860 break;
12861 case VMS_SFT_RESERVE:
12862 strcat (res, " RSV");
12863 break;
12864 default:
bee0ee85
NC
12865 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12866 VMS_ST_FUNC_TYPE (other));
12867 strcat (res, " <unknown>");
12868 break;
28f997cf
TG
12869 }
12870 break;
12871 default:
12872 break;
12873 }
12874 switch (VMS_ST_LINKAGE (other))
12875 {
12876 case VMS_STL_IGNORE:
12877 strcat (res, " IGN");
12878 break;
12879 case VMS_STL_RESERVE:
12880 strcat (res, " RSV");
12881 break;
12882 case VMS_STL_STD:
12883 strcat (res, " STD");
12884 break;
12885 case VMS_STL_LNK:
12886 strcat (res, " LNK");
12887 break;
12888 default:
bee0ee85
NC
12889 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12890 VMS_ST_LINKAGE (other));
12891 strcat (res, " <unknown>");
12892 break;
28f997cf
TG
12893 }
12894
12895 if (res[0] != 0)
12896 return res + 1;
12897 else
12898 return res;
12899 }
12900 return NULL;
12901}
12902
6911b7dc
AM
12903static const char *
12904get_ppc64_symbol_other (unsigned int other)
12905{
14732552
AM
12906 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12907 return NULL;
12908
12909 other >>= STO_PPC64_LOCAL_BIT;
12910 if (other <= 6)
6911b7dc 12911 {
89246a0e 12912 static char buf[64];
14732552
AM
12913 if (other >= 2)
12914 other = ppc64_decode_local_entry (other);
12915 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12916 return buf;
12917 }
12918 return NULL;
12919}
12920
8155b853
NC
12921static const char *
12922get_riscv_symbol_other (unsigned int other)
12923{
12924 static char buf[32];
12925 buf[0] = 0;
12926
12927 if (other & STO_RISCV_VARIANT_CC)
12928 {
12929 strcat (buf, _(" VARIANT_CC"));
12930 other &= ~STO_RISCV_VARIANT_CC;
12931 }
12932
12933 if (other != 0)
12934 snprintf (buf, sizeof buf, " %x", other);
12935
12936
12937 if (buf[0] != 0)
12938 return buf + 1;
12939 else
12940 return buf;
12941}
12942
5e2b0d47 12943static const char *
dda8d76d 12944get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12945{
12946 const char * result = NULL;
89246a0e 12947 static char buff [64];
5e2b0d47
NC
12948
12949 if (other == 0)
12950 return "";
12951
dda8d76d 12952 switch (filedata->file_header.e_machine)
5e2b0d47 12953 {
2057d69d
CZ
12954 case EM_ALPHA:
12955 result = get_alpha_symbol_other (other);
12956 break;
2301ed1c
SN
12957 case EM_AARCH64:
12958 result = get_aarch64_symbol_other (other);
12959 break;
5e2b0d47
NC
12960 case EM_MIPS:
12961 result = get_mips_symbol_other (other);
28f997cf
TG
12962 break;
12963 case EM_IA_64:
dda8d76d 12964 result = get_ia64_symbol_other (filedata, other);
28f997cf 12965 break;
6911b7dc
AM
12966 case EM_PPC64:
12967 result = get_ppc64_symbol_other (other);
12968 break;
8155b853
NC
12969 case EM_RISCV:
12970 result = get_riscv_symbol_other (other);
12971 break;
5e2b0d47 12972 default:
fd85a6a1 12973 result = NULL;
5e2b0d47
NC
12974 break;
12975 }
12976
12977 if (result)
12978 return result;
12979
12980 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12981 return buff;
12982}
12983
d1133906 12984static const char *
dda8d76d 12985get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12986{
b34976b6 12987 static char buff[32];
5cf1065c 12988
252b5132
RH
12989 switch (type)
12990 {
b34976b6
AM
12991 case SHN_UNDEF: return "UND";
12992 case SHN_ABS: return "ABS";
12993 case SHN_COMMON: return "COM";
252b5132 12994 default:
9ce701e2 12995 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12996 && filedata->file_header.e_machine == EM_IA_64
12997 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12998 return "ANSI_COM";
12999 else if ((filedata->file_header.e_machine == EM_X86_64
13000 || filedata->file_header.e_machine == EM_L1OM
13001 || filedata->file_header.e_machine == EM_K1OM)
13002 && type == SHN_X86_64_LCOMMON)
13003 return "LARGE_COM";
13004 else if ((type == SHN_MIPS_SCOMMON
13005 && filedata->file_header.e_machine == EM_MIPS)
13006 || (type == SHN_TIC6X_SCOMMON
13007 && filedata->file_header.e_machine == EM_TI_C6000))
13008 return "SCOM";
13009 else if (type == SHN_MIPS_SUNDEFINED
13010 && filedata->file_header.e_machine == EM_MIPS)
13011 return "SUND";
13012 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
13013 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
13014 else if (type >= SHN_LOOS && type <= SHN_HIOS)
13015 sprintf (buff, "OS [0x%04x]", type & 0xffff);
13016 else if (type >= SHN_LORESERVE)
13017 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
13018 else if (filedata->file_header.e_shnum != 0
13019 && type >= filedata->file_header.e_shnum)
13020 sprintf (buff, _("bad section index[%3d]"), type);
13021 else
13022 sprintf (buff, "%3d", type);
13023 break;
fd85a6a1
NC
13024 }
13025
10ca4b04 13026 return buff;
6bd1a22c
L
13027}
13028
bb4d2ac2 13029static const char *
26c527e6
AM
13030get_symbol_version_string (Filedata *filedata,
13031 bool is_dynsym,
13032 const char *strtab,
13033 size_t strtab_size,
13034 unsigned int si,
13035 Elf_Internal_Sym *psym,
13036 enum versioned_symbol_info *sym_info,
13037 unsigned short *vna_other)
bb4d2ac2 13038{
ab273396
AM
13039 unsigned char data[2];
13040 unsigned short vers_data;
26c527e6 13041 uint64_t offset;
7a815dd5 13042 unsigned short max_vd_ndx;
bb4d2ac2 13043
ab273396 13044 if (!is_dynsym
978c4450 13045 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 13046 return NULL;
bb4d2ac2 13047
978c4450
AM
13048 offset = offset_from_vma (filedata,
13049 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 13050 sizeof data + si * sizeof (vers_data));
bb4d2ac2 13051
dda8d76d 13052 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
13053 sizeof (data), 1, _("version data")) == NULL)
13054 return NULL;
13055
13056 vers_data = byte_get (data, 2);
bb4d2ac2 13057
1f6f5dba 13058 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 13059 return NULL;
bb4d2ac2 13060
0b8b7609 13061 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
13062 max_vd_ndx = 0;
13063
ab273396
AM
13064 /* Usually we'd only see verdef for defined symbols, and verneed for
13065 undefined symbols. However, symbols defined by the linker in
13066 .dynbss for variables copied from a shared library in order to
13067 avoid text relocations are defined yet have verneed. We could
13068 use a heuristic to detect the special case, for example, check
13069 for verneed first on symbols defined in SHT_NOBITS sections, but
13070 it is simpler and more reliable to just look for both verdef and
13071 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13072
ab273396
AM
13073 if (psym->st_shndx != SHN_UNDEF
13074 && vers_data != 0x8001
978c4450 13075 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13076 {
13077 Elf_Internal_Verdef ivd;
13078 Elf_Internal_Verdaux ivda;
13079 Elf_External_Verdaux evda;
26c527e6 13080 uint64_t off;
bb4d2ac2 13081
dda8d76d 13082 off = offset_from_vma (filedata,
978c4450 13083 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13084 sizeof (Elf_External_Verdef));
13085
13086 do
bb4d2ac2 13087 {
ab273396
AM
13088 Elf_External_Verdef evd;
13089
dda8d76d 13090 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13091 _("version def")) == NULL)
13092 {
13093 ivd.vd_ndx = 0;
13094 ivd.vd_aux = 0;
13095 ivd.vd_next = 0;
1f6f5dba 13096 ivd.vd_flags = 0;
ab273396
AM
13097 }
13098 else
bb4d2ac2 13099 {
ab273396
AM
13100 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13101 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13102 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13103 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13104 }
bb4d2ac2 13105
7a815dd5
L
13106 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13107 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13108
ab273396
AM
13109 off += ivd.vd_next;
13110 }
13111 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13112
ab273396
AM
13113 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13114 {
9abca702 13115 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13116 return NULL;
13117
ab273396
AM
13118 off -= ivd.vd_next;
13119 off += ivd.vd_aux;
bb4d2ac2 13120
dda8d76d 13121 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13122 _("version def aux")) != NULL)
13123 {
13124 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13125
ab273396 13126 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13127 return (ivda.vda_name < strtab_size
13128 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13129 }
13130 }
13131 }
bb4d2ac2 13132
978c4450 13133 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13134 {
13135 Elf_External_Verneed evn;
13136 Elf_Internal_Verneed ivn;
13137 Elf_Internal_Vernaux ivna;
bb4d2ac2 13138
dda8d76d 13139 offset = offset_from_vma (filedata,
978c4450 13140 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13141 sizeof evn);
13142 do
13143 {
26c527e6 13144 uint64_t vna_off;
bb4d2ac2 13145
dda8d76d 13146 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13147 _("version need")) == NULL)
13148 {
13149 ivna.vna_next = 0;
13150 ivna.vna_other = 0;
13151 ivna.vna_name = 0;
13152 break;
13153 }
bb4d2ac2 13154
ab273396
AM
13155 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13156 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13157
ab273396 13158 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13159
ab273396
AM
13160 do
13161 {
13162 Elf_External_Vernaux evna;
bb4d2ac2 13163
dda8d76d 13164 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13165 _("version need aux (3)")) == NULL)
bb4d2ac2 13166 {
ab273396
AM
13167 ivna.vna_next = 0;
13168 ivna.vna_other = 0;
13169 ivna.vna_name = 0;
bb4d2ac2 13170 }
bb4d2ac2 13171 else
bb4d2ac2 13172 {
ab273396
AM
13173 ivna.vna_other = BYTE_GET (evna.vna_other);
13174 ivna.vna_next = BYTE_GET (evna.vna_next);
13175 ivna.vna_name = BYTE_GET (evna.vna_name);
13176 }
bb4d2ac2 13177
ab273396
AM
13178 vna_off += ivna.vna_next;
13179 }
13180 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13181
ab273396
AM
13182 if (ivna.vna_other == vers_data)
13183 break;
bb4d2ac2 13184
ab273396
AM
13185 offset += ivn.vn_next;
13186 }
13187 while (ivn.vn_next != 0);
bb4d2ac2 13188
ab273396
AM
13189 if (ivna.vna_other == vers_data)
13190 {
13191 *sym_info = symbol_undefined;
13192 *vna_other = ivna.vna_other;
13193 return (ivna.vna_name < strtab_size
13194 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13195 }
7a815dd5
L
13196 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13197 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13198 return _("<corrupt>");
bb4d2ac2 13199 }
ab273396 13200 return NULL;
bb4d2ac2
L
13201}
13202
047c3dbf
NL
13203/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13204
13205static unsigned int
625d49fc 13206print_dynamic_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13207{
13208 switch (base)
13209 {
13210 case 8:
13211 return print_vma (vma, OCTAL_5);
13212
13213 case 10:
13214 return print_vma (vma, UNSIGNED_5);
13215
13216 case 16:
13217 return print_vma (vma, PREFIX_HEX_5);
13218
13219 case 0:
13220 default:
13221 return print_vma (vma, DEC_5);
13222 }
13223}
13224
10ca4b04 13225static void
26c527e6 13226print_dynamic_symbol (Filedata *filedata, uint64_t si,
10ca4b04
L
13227 Elf_Internal_Sym *symtab,
13228 Elf_Internal_Shdr *section,
13229 char *strtab, size_t strtab_size)
252b5132 13230{
10ca4b04
L
13231 const char *version_string;
13232 enum versioned_symbol_info sym_info;
13233 unsigned short vna_other;
23356397
NC
13234 bool is_valid;
13235 const char * sstr;
10ca4b04 13236 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13237
26c527e6 13238 printf ("%6" PRId64 ": ", si);
10ca4b04
L
13239 print_vma (psym->st_value, LONG_HEX);
13240 putchar (' ');
047c3dbf 13241 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13242 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13243 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13244 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13245 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13246 else
252b5132 13247 {
10ca4b04 13248 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13249
10ca4b04
L
13250 printf (" %-7s", get_symbol_visibility (vis));
13251 /* Check to see if any other bits in the st_other field are set.
13252 Note - displaying this information disrupts the layout of the
13253 table being generated, but for the moment this case is very rare. */
13254 if (psym->st_other ^ vis)
13255 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13256 }
10ca4b04 13257 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13258
23356397
NC
13259 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13260 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13261 && filedata->section_headers != NULL
23356397
NC
13262 && psym->st_name == 0)
13263 {
84714f86
AM
13264 is_valid
13265 = section_name_valid (filedata,
13266 filedata->section_headers + psym->st_shndx);
23356397 13267 sstr = is_valid ?
84714f86
AM
13268 section_name_print (filedata,
13269 filedata->section_headers + psym->st_shndx)
23356397
NC
13270 : _("<corrupt>");
13271 }
13272 else
13273 {
84714f86 13274 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13275 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13276 }
10ca4b04
L
13277
13278 version_string
13279 = get_symbol_version_string (filedata,
13280 (section == NULL
13281 || section->sh_type == SHT_DYNSYM),
13282 strtab, strtab_size, si,
13283 psym, &sym_info, &vna_other);
b9e920ec 13284
0942c7ab
NC
13285 int len_avail = 21;
13286 if (! do_wide && version_string != NULL)
13287 {
ddb43bab 13288 char buffer[16];
0942c7ab 13289
ddb43bab 13290 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13291
13292 if (sym_info == symbol_undefined)
13293 len_avail -= sprintf (buffer," (%d)", vna_other);
13294 else if (sym_info != symbol_hidden)
13295 len_avail -= 1;
13296 }
13297
13298 print_symbol (len_avail, sstr);
b9e920ec 13299
10ca4b04
L
13300 if (version_string)
13301 {
13302 if (sym_info == symbol_undefined)
13303 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13304 else
10ca4b04
L
13305 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13306 version_string);
13307 }
6bd1a22c 13308
10ca4b04 13309 putchar ('\n');
6bd1a22c 13310
10ca4b04
L
13311 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13312 && section != NULL
13313 && si >= section->sh_info
13314 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13315 && filedata->file_header.e_machine != EM_MIPS
13316 /* Solaris binaries have been found to violate this requirement as
13317 well. Not sure if this is a bug or an ABI requirement. */
13318 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
26c527e6 13319 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
10ca4b04
L
13320 si, printable_section_name (filedata, section), section->sh_info);
13321}
f16a9783 13322
0f03783c
NC
13323static const char *
13324get_lto_kind (unsigned int kind)
13325{
13326 switch (kind)
13327 {
13328 case 0: return "DEF";
13329 case 1: return "WEAKDEF";
13330 case 2: return "UNDEF";
13331 case 3: return "WEAKUNDEF";
13332 case 4: return "COMMON";
13333 default:
13334 break;
13335 }
13336
13337 static char buffer[30];
13338 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13339 sprintf (buffer, "<unknown: %u>", kind);
13340 return buffer;
13341}
13342
13343static const char *
13344get_lto_visibility (unsigned int visibility)
13345{
13346 switch (visibility)
13347 {
13348 case 0: return "DEFAULT";
13349 case 1: return "PROTECTED";
13350 case 2: return "INTERNAL";
13351 case 3: return "HIDDEN";
13352 default:
13353 break;
13354 }
13355
13356 static char buffer[30];
13357 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13358 sprintf (buffer, "<unknown: %u>", visibility);
13359 return buffer;
13360}
13361
13362static const char *
13363get_lto_sym_type (unsigned int sym_type)
13364{
13365 switch (sym_type)
13366 {
13367 case 0: return "UNKNOWN";
13368 case 1: return "FUNCTION";
13369 case 2: return "VARIABLE";
13370 default:
13371 break;
13372 }
13373
13374 static char buffer[30];
13375 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13376 sprintf (buffer, "<unknown: %u>", sym_type);
13377 return buffer;
13378}
13379
13380/* Display an LTO format symbol table.
13381 FIXME: The format of LTO symbol tables is not formalized.
13382 So this code could need changing in the future. */
13383
015dc7e1 13384static bool
0f03783c
NC
13385display_lto_symtab (Filedata * filedata,
13386 Elf_Internal_Shdr * section)
13387{
13388 if (section->sh_size == 0)
13389 {
ca0e11aa
NC
13390 if (filedata->is_separate)
13391 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13392 printable_section_name (filedata, section),
13393 filedata->file_name);
13394 else
13395 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13396 printable_section_name (filedata, section));
047c3dbf 13397
015dc7e1 13398 return true;
0f03783c
NC
13399 }
13400
13401 if (section->sh_size > filedata->file_size)
13402 {
26c527e6 13403 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
0f03783c 13404 printable_section_name (filedata, section),
26c527e6 13405 section->sh_size);
015dc7e1 13406 return false;
0f03783c
NC
13407 }
13408
13409 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13410 section->sh_size, 1, _("LTO symbols"));
13411 if (alloced_data == NULL)
015dc7e1 13412 return false;
0f03783c
NC
13413
13414 /* Look for extended data for the symbol table. */
13415 Elf_Internal_Shdr * ext;
13416 void * ext_data_orig = NULL;
13417 char * ext_data = NULL;
13418 char * ext_data_end = NULL;
13419 char * ext_name = NULL;
13420
13421 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13422 (section_name (filedata, section)
13423 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13424 && ext_name != NULL /* Paranoia. */
13425 && (ext = find_section (filedata, ext_name)) != NULL)
13426 {
13427 if (ext->sh_size < 3)
13428 error (_("LTO Symbol extension table '%s' is empty!\n"),
13429 printable_section_name (filedata, ext));
13430 else
13431 {
13432 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13433 ext->sh_size, 1,
13434 _("LTO ext symbol data"));
13435 if (ext_data != NULL)
13436 {
13437 ext_data_end = ext_data + ext->sh_size;
13438 if (* ext_data++ != 1)
13439 error (_("Unexpected version number in symbol extension table\n"));
13440 }
13441 }
13442 }
b9e920ec 13443
0f03783c
NC
13444 const unsigned char * data = (const unsigned char *) alloced_data;
13445 const unsigned char * end = data + section->sh_size;
13446
ca0e11aa
NC
13447 if (filedata->is_separate)
13448 printf (_("\nIn linked file '%s': "), filedata->file_name);
13449 else
13450 printf ("\n");
13451
0f03783c
NC
13452 if (ext_data_orig != NULL)
13453 {
13454 if (do_wide)
ca0e11aa 13455 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13456 printable_section_name (filedata, section),
13457 printable_section_name (filedata, ext));
13458 else
13459 {
ca0e11aa 13460 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13461 printable_section_name (filedata, section));
13462 printf (_(" and extension table '%s' contain:\n"),
13463 printable_section_name (filedata, ext));
13464 }
13465 }
13466 else
ca0e11aa 13467 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13468 printable_section_name (filedata, section));
b9e920ec 13469
0f03783c 13470 /* FIXME: Add a wide version. */
b9e920ec 13471 if (ext_data_orig != NULL)
0f03783c
NC
13472 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13473 else
13474 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13475
13476 /* FIXME: We do not handle style prefixes. */
13477
13478 while (data < end)
13479 {
13480 const unsigned char * sym_name = data;
13481 data += strnlen ((const char *) sym_name, end - data) + 1;
13482 if (data >= end)
13483 goto fail;
13484
13485 const unsigned char * comdat_key = data;
13486 data += strnlen ((const char *) comdat_key, end - data) + 1;
13487 if (data >= end)
13488 goto fail;
13489
13490 if (data + 2 + 8 + 4 > end)
13491 goto fail;
13492
13493 unsigned int kind = *data++;
13494 unsigned int visibility = *data++;
13495
928c411d 13496 uint64_t size = byte_get (data, 8);
0f03783c
NC
13497 data += 8;
13498
928c411d 13499 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13500 data += 4;
13501
13502 if (ext_data != NULL)
13503 {
13504 if (ext_data < (ext_data_end - 1))
13505 {
13506 unsigned int sym_type = * ext_data ++;
13507 unsigned int sec_kind = * ext_data ++;
13508
31e5a3a3 13509 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
13510 * comdat_key == 0 ? "-" : (char *) comdat_key,
13511 get_lto_kind (kind),
13512 get_lto_visibility (visibility),
31e5a3a3
AM
13513 size,
13514 slot,
0f03783c 13515 get_lto_sym_type (sym_type),
31e5a3a3 13516 sec_kind);
0f03783c
NC
13517 print_symbol (6, (const char *) sym_name);
13518 }
13519 else
13520 {
13521 error (_("Ran out of LTO symbol extension data\n"));
13522 ext_data = NULL;
13523 /* FIXME: return FAIL result ? */
13524 }
13525 }
13526 else
13527 {
31e5a3a3 13528 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
13529 * comdat_key == 0 ? "-" : (char *) comdat_key,
13530 get_lto_kind (kind),
13531 get_lto_visibility (visibility),
31e5a3a3
AM
13532 size,
13533 slot);
0f03783c
NC
13534 print_symbol (21, (const char *) sym_name);
13535 }
13536 putchar ('\n');
13537 }
13538
13539 if (ext_data != NULL && ext_data < ext_data_end)
13540 {
13541 error (_("Data remains in the LTO symbol extension table\n"));
13542 goto fail;
13543 }
13544
13545 free (alloced_data);
13546 free (ext_data_orig);
13547 free (ext_name);
015dc7e1 13548 return true;
b9e920ec 13549
0f03783c
NC
13550 fail:
13551 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13552 free (alloced_data);
13553 free (ext_data_orig);
13554 free (ext_name);
015dc7e1 13555 return false;
0f03783c
NC
13556}
13557
13558/* Display LTO symbol tables. */
13559
015dc7e1 13560static bool
0f03783c
NC
13561process_lto_symbol_tables (Filedata * filedata)
13562{
13563 Elf_Internal_Shdr * section;
13564 unsigned int i;
015dc7e1 13565 bool res = true;
0f03783c
NC
13566
13567 if (!do_lto_syms)
015dc7e1 13568 return true;
0f03783c
NC
13569
13570 if (filedata->section_headers == NULL)
015dc7e1 13571 return true;
0f03783c
NC
13572
13573 for (i = 0, section = filedata->section_headers;
13574 i < filedata->file_header.e_shnum;
13575 i++, section++)
84714f86
AM
13576 if (section_name_valid (filedata, section)
13577 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13578 res &= display_lto_symtab (filedata, section);
13579
b9e920ec 13580 return res;
0f03783c
NC
13581}
13582
10ca4b04 13583/* Dump the symbol table. */
0f03783c 13584
015dc7e1 13585static bool
10ca4b04
L
13586process_symbol_table (Filedata * filedata)
13587{
13588 Elf_Internal_Shdr * section;
f16a9783 13589
10ca4b04 13590 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13591 return true;
6bd1a22c 13592
978c4450 13593 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13594 && do_syms
13595 && do_using_dynamic
978c4450
AM
13596 && filedata->dynamic_strings != NULL
13597 && filedata->dynamic_symbols != NULL)
6bd1a22c 13598 {
26c527e6 13599 uint64_t si;
6bd1a22c 13600
ca0e11aa
NC
13601 if (filedata->is_separate)
13602 {
26c527e6
AM
13603 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
13604 " contains %" PRIu64 " entry:\n",
13605 "\nIn linked file '%s' the dynamic symbol table"
13606 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13607 filedata->num_dynamic_syms),
13608 filedata->file_name,
13609 filedata->num_dynamic_syms);
13610 }
13611 else
13612 {
26c527e6
AM
13613 printf (ngettext ("\nSymbol table for image contains %" PRIu64
13614 " entry:\n",
13615 "\nSymbol table for image contains %" PRIu64
13616 " entries:\n",
ca0e11aa
NC
13617 filedata->num_dynamic_syms),
13618 filedata->num_dynamic_syms);
13619 }
10ca4b04
L
13620 if (is_32bit_elf)
13621 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13622 else
13623 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13624
978c4450
AM
13625 for (si = 0; si < filedata->num_dynamic_syms; si++)
13626 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13627 filedata->dynamic_strings,
13628 filedata->dynamic_strings_length);
252b5132 13629 }
8b73c356 13630 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13631 && filedata->section_headers != NULL)
252b5132 13632 {
b34976b6 13633 unsigned int i;
252b5132 13634
dda8d76d
NC
13635 for (i = 0, section = filedata->section_headers;
13636 i < filedata->file_header.e_shnum;
252b5132
RH
13637 i++, section++)
13638 {
2cf0635d 13639 char * strtab = NULL;
26c527e6 13640 uint64_t strtab_size = 0;
2cf0635d 13641 Elf_Internal_Sym * symtab;
26c527e6 13642 uint64_t si, num_syms;
252b5132 13643
2c610e4b
L
13644 if ((section->sh_type != SHT_SYMTAB
13645 && section->sh_type != SHT_DYNSYM)
13646 || (!do_syms
13647 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13648 continue;
13649
dd24e3da
NC
13650 if (section->sh_entsize == 0)
13651 {
13652 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13653 printable_section_name (filedata, section));
dd24e3da
NC
13654 continue;
13655 }
13656
d3a49aa8 13657 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13658
13659 if (filedata->is_separate)
26c527e6
AM
13660 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
13661 " contains %" PRIu64 " entry:\n",
13662 "\nIn linked file '%s' symbol section '%s'"
13663 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13664 num_syms),
13665 filedata->file_name,
13666 printable_section_name (filedata, section),
13667 num_syms);
13668 else
26c527e6
AM
13669 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
13670 " entry:\n",
13671 "\nSymbol table '%s' contains %" PRIu64
13672 " entries:\n",
ca0e11aa
NC
13673 num_syms),
13674 printable_section_name (filedata, section),
13675 num_syms);
dd24e3da 13676
f7a99963 13677 if (is_32bit_elf)
ca47b30c 13678 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13679 else
ca47b30c 13680 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13681
4de91c10 13682 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13683 if (symtab == NULL)
13684 continue;
13685
dda8d76d 13686 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13687 {
dda8d76d
NC
13688 strtab = filedata->string_table;
13689 strtab_size = filedata->string_table_length;
c256ffe7 13690 }
dda8d76d 13691 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13692 {
2cf0635d 13693 Elf_Internal_Shdr * string_sec;
252b5132 13694
dda8d76d 13695 string_sec = filedata->section_headers + section->sh_link;
252b5132 13696
dda8d76d 13697 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13698 1, string_sec->sh_size,
13699 _("string table"));
c256ffe7 13700 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13701 }
13702
10ca4b04
L
13703 for (si = 0; si < num_syms; si++)
13704 print_dynamic_symbol (filedata, si, symtab, section,
13705 strtab, strtab_size);
252b5132
RH
13706
13707 free (symtab);
dda8d76d 13708 if (strtab != filedata->string_table)
252b5132
RH
13709 free (strtab);
13710 }
13711 }
13712 else if (do_syms)
13713 printf
13714 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13715
978c4450 13716 if (do_histogram && filedata->buckets != NULL)
252b5132 13717 {
26c527e6
AM
13718 uint64_t *lengths;
13719 uint64_t *counts;
13720 uint64_t hn;
625d49fc 13721 uint64_t si;
26c527e6
AM
13722 uint64_t maxlength = 0;
13723 uint64_t nzero_counts = 0;
13724 uint64_t nsyms = 0;
6bd6a03d 13725 char *visited;
252b5132 13726
d3a49aa8 13727 printf (ngettext ("\nHistogram for bucket list length "
26c527e6 13728 "(total of %" PRIu64 " bucket):\n",
d3a49aa8 13729 "\nHistogram for bucket list length "
26c527e6
AM
13730 "(total of %" PRIu64 " buckets):\n",
13731 filedata->nbuckets),
13732 filedata->nbuckets);
252b5132 13733
26c527e6 13734 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
252b5132
RH
13735 if (lengths == NULL)
13736 {
8b73c356 13737 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13738 goto err_out;
252b5132 13739 }
978c4450
AM
13740 visited = xcmalloc (filedata->nchains, 1);
13741 memset (visited, 0, filedata->nchains);
8b73c356
NC
13742
13743 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13744 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13745 {
978c4450 13746 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13747 {
b34976b6 13748 ++nsyms;
252b5132 13749 if (maxlength < ++lengths[hn])
b34976b6 13750 ++maxlength;
978c4450 13751 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13752 {
13753 error (_("histogram chain is corrupt\n"));
13754 break;
13755 }
13756 visited[si] = 1;
252b5132
RH
13757 }
13758 }
6bd6a03d 13759 free (visited);
252b5132 13760
26c527e6 13761 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13762 if (counts == NULL)
13763 {
b2e951ec 13764 free (lengths);
8b73c356 13765 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13766 goto err_out;
252b5132
RH
13767 }
13768
978c4450 13769 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13770 ++counts[lengths[hn]];
252b5132 13771
978c4450 13772 if (filedata->nbuckets > 0)
252b5132 13773 {
26c527e6
AM
13774 uint64_t i;
13775 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 13776 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13777 for (i = 1; i <= maxlength; ++i)
103f02d3 13778 {
66543521 13779 nzero_counts += counts[i] * i;
26c527e6 13780 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 13781 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13782 (nzero_counts * 100.0) / nsyms);
13783 }
252b5132
RH
13784 }
13785
13786 free (counts);
13787 free (lengths);
13788 }
13789
978c4450
AM
13790 free (filedata->buckets);
13791 filedata->buckets = NULL;
13792 filedata->nbuckets = 0;
13793 free (filedata->chains);
13794 filedata->chains = NULL;
252b5132 13795
978c4450 13796 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13797 {
26c527e6
AM
13798 uint64_t *lengths;
13799 uint64_t *counts;
13800 uint64_t hn;
13801 uint64_t maxlength = 0;
13802 uint64_t nzero_counts = 0;
13803 uint64_t nsyms = 0;
fdc90cb4 13804
f16a9783 13805 printf (ngettext ("\nHistogram for `%s' bucket list length "
26c527e6 13806 "(total of %" PRIu64 " bucket):\n",
f16a9783 13807 "\nHistogram for `%s' bucket list length "
26c527e6
AM
13808 "(total of %" PRIu64 " buckets):\n",
13809 filedata->ngnubuckets),
978c4450 13810 GNU_HASH_SECTION_NAME (filedata),
26c527e6 13811 filedata->ngnubuckets);
8b73c356 13812
26c527e6 13813 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
13814 if (lengths == NULL)
13815 {
8b73c356 13816 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13817 goto err_out;
fdc90cb4
JJ
13818 }
13819
fdc90cb4
JJ
13820 printf (_(" Length Number %% of total Coverage\n"));
13821
978c4450
AM
13822 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13823 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 13824 {
625d49fc 13825 uint64_t off, length = 1;
fdc90cb4 13826
978c4450 13827 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13828 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13829 off < filedata->ngnuchains
13830 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13831 ++off)
fdc90cb4
JJ
13832 ++length;
13833 lengths[hn] = length;
13834 if (length > maxlength)
13835 maxlength = length;
13836 nsyms += length;
13837 }
13838
26c527e6 13839 counts = calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13840 if (counts == NULL)
13841 {
b2e951ec 13842 free (lengths);
8b73c356 13843 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13844 goto err_out;
fdc90cb4
JJ
13845 }
13846
978c4450 13847 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13848 ++counts[lengths[hn]];
13849
978c4450 13850 if (filedata->ngnubuckets > 0)
fdc90cb4 13851 {
26c527e6
AM
13852 uint64_t j;
13853 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 13854 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13855 for (j = 1; j <= maxlength; ++j)
13856 {
13857 nzero_counts += counts[j] * j;
26c527e6 13858 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 13859 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13860 (nzero_counts * 100.0) / nsyms);
13861 }
13862 }
13863
13864 free (counts);
13865 free (lengths);
fdc90cb4 13866 }
978c4450
AM
13867 free (filedata->gnubuckets);
13868 filedata->gnubuckets = NULL;
13869 filedata->ngnubuckets = 0;
13870 free (filedata->gnuchains);
13871 filedata->gnuchains = NULL;
13872 filedata->ngnuchains = 0;
13873 free (filedata->mipsxlat);
13874 filedata->mipsxlat = NULL;
015dc7e1 13875 return true;
fd486f32
AM
13876
13877 err_out:
978c4450
AM
13878 free (filedata->gnubuckets);
13879 filedata->gnubuckets = NULL;
13880 filedata->ngnubuckets = 0;
13881 free (filedata->gnuchains);
13882 filedata->gnuchains = NULL;
13883 filedata->ngnuchains = 0;
13884 free (filedata->mipsxlat);
13885 filedata->mipsxlat = NULL;
13886 free (filedata->buckets);
13887 filedata->buckets = NULL;
13888 filedata->nbuckets = 0;
13889 free (filedata->chains);
13890 filedata->chains = NULL;
015dc7e1 13891 return false;
252b5132
RH
13892}
13893
015dc7e1 13894static bool
ca0e11aa 13895process_syminfo (Filedata * filedata)
252b5132 13896{
b4c96d0d 13897 unsigned int i;
252b5132 13898
978c4450 13899 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13900 || !do_dynamic)
13901 /* No syminfo, this is ok. */
015dc7e1 13902 return true;
252b5132
RH
13903
13904 /* There better should be a dynamic symbol section. */
978c4450 13905 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13906 return false;
252b5132 13907
ca0e11aa 13908 if (filedata->is_separate)
26c527e6
AM
13909 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
13910 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
ca0e11aa
NC
13911 filedata->dynamic_syminfo_nent),
13912 filedata->file_name,
13913 filedata->dynamic_syminfo_offset,
13914 filedata->dynamic_syminfo_nent);
13915 else
26c527e6
AM
13916 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
13917 " contains %d entry:\n",
13918 "\nDynamic info segment at offset %#" PRIx64
13919 " contains %d entries:\n",
978c4450 13920 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13921 filedata->dynamic_syminfo_offset,
13922 filedata->dynamic_syminfo_nent);
252b5132
RH
13923
13924 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13925 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13926 {
978c4450 13927 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13928
31104126 13929 printf ("%4d: ", i);
978c4450 13930 if (i >= filedata->num_dynamic_syms)
4082ef84 13931 printf (_("<corrupt index>"));
84714f86
AM
13932 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13933 print_symbol (30, get_dynamic_name (filedata,
978c4450 13934 filedata->dynamic_symbols[i].st_name));
d79b3d50 13935 else
978c4450 13936 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13937 putchar (' ');
252b5132 13938
978c4450 13939 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13940 {
13941 case SYMINFO_BT_SELF:
13942 fputs ("SELF ", stdout);
13943 break;
13944 case SYMINFO_BT_PARENT:
13945 fputs ("PARENT ", stdout);
13946 break;
13947 default:
978c4450
AM
13948 if (filedata->dynamic_syminfo[i].si_boundto > 0
13949 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13950 && valid_dynamic_name (filedata,
978c4450 13951 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13952 {
84714f86 13953 print_symbol (10, get_dynamic_name (filedata,
978c4450 13954 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13955 putchar (' ' );
13956 }
252b5132 13957 else
978c4450 13958 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13959 break;
13960 }
13961
13962 if (flags & SYMINFO_FLG_DIRECT)
13963 printf (" DIRECT");
13964 if (flags & SYMINFO_FLG_PASSTHRU)
13965 printf (" PASSTHRU");
13966 if (flags & SYMINFO_FLG_COPY)
13967 printf (" COPY");
13968 if (flags & SYMINFO_FLG_LAZYLOAD)
13969 printf (" LAZYLOAD");
13970
13971 puts ("");
13972 }
13973
015dc7e1 13974 return true;
252b5132
RH
13975}
13976
75802ccb
CE
13977/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13978 is contained by the region START .. END. The types of ADDR, START
13979 and END should all be the same. Note both ADDR + NELEM and END
13980 point to just beyond the end of the regions that are being tested. */
13981#define IN_RANGE(START,END,ADDR,NELEM) \
13982 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13983
cf13d699
NC
13984/* Check to see if the given reloc needs to be handled in a target specific
13985 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13986 FALSE.
13987
13988 If called with reloc == NULL, then this is a signal that reloc processing
13989 for the current section has finished, and any saved state should be
13990 discarded. */
09c11c86 13991
015dc7e1 13992static bool
26c527e6
AM
13993target_specific_reloc_handling (Filedata *filedata,
13994 Elf_Internal_Rela *reloc,
13995 unsigned char *start,
13996 unsigned char *end,
13997 Elf_Internal_Sym *symtab,
13998 uint64_t num_syms)
252b5132 13999{
f84ce13b 14000 unsigned int reloc_type = 0;
26c527e6 14001 uint64_t sym_index = 0;
f84ce13b
NC
14002
14003 if (reloc)
14004 {
dda8d76d 14005 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
14006 sym_index = get_reloc_symindex (reloc->r_info);
14007 }
252b5132 14008
dda8d76d 14009 switch (filedata->file_header.e_machine)
252b5132 14010 {
76244462 14011 case EM_LOONGARCH:
14012 {
14013 switch (reloc_type)
14014 {
14015 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
14016 at assembly time. */
14017 case 107: /* R_LARCH_ADD_ULEB128. */
14018 case 108: /* R_LARCH_SUB_ULEB128. */
14019 {
14020 uint64_t value;
14021 unsigned int reloc_size = 0;
14022 int leb_ret = 0;
14023
89c70cd3
AM
14024 if (reloc->r_offset < (size_t) (end - start))
14025 value = read_leb128 (start + reloc->r_offset, end, false,
14026 &reloc_size, &leb_ret);
76244462 14027 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14028 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
14029 "ULEB128 value\n"),
14030 (long) reloc->r_offset);
14031
74a965d8
AM
14032 else if (sym_index >= num_syms)
14033 error (_("%s reloc contains invalid symbol index "
14034 "%" PRIu64 "\n"),
14035 (reloc_type == 107
14036 ? "R_LARCH_ADD_ULEB128"
14037 : "R_LARCH_SUB_ULEB128"),
14038 sym_index);
14039 else
76244462 14040 {
74a965d8
AM
14041 if (reloc_type == 107)
14042 value += reloc->r_addend + symtab[sym_index].st_value;
14043 else
14044 value -= reloc->r_addend + symtab[sym_index].st_value;
14045
14046 /* Write uleb128 value to p. */
14047 bfd_byte *p = start + reloc->r_offset;
14048 do
14049 {
14050 bfd_byte c = value & 0x7f;
14051 value >>= 7;
14052 if (--reloc_size != 0)
14053 c |= 0x80;
14054 *p++ = c;
14055 }
14056 while (reloc_size);
76244462 14057 }
76244462 14058
14059 return true;
14060 }
14061 }
14062 break;
14063 }
14064
13761a11
NC
14065 case EM_MSP430:
14066 case EM_MSP430_OLD:
14067 {
14068 static Elf_Internal_Sym * saved_sym = NULL;
14069
f84ce13b
NC
14070 if (reloc == NULL)
14071 {
14072 saved_sym = NULL;
015dc7e1 14073 return true;
f84ce13b
NC
14074 }
14075
13761a11
NC
14076 switch (reloc_type)
14077 {
14078 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 14079 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 14080 if (uses_msp430x_relocs (filedata))
13761a11 14081 break;
1a0670f3 14082 /* Fall through. */
13761a11 14083 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 14084 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
14085 /* PR 21139. */
14086 if (sym_index >= num_syms)
74a965d8
AM
14087 error (_("%s reloc contains invalid symbol index "
14088 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
f84ce13b
NC
14089 else
14090 saved_sym = symtab + sym_index;
015dc7e1 14091 return true;
13761a11
NC
14092
14093 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14094 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14095 goto handle_sym_diff;
0b4362b0 14096
13761a11
NC
14097 case 5: /* R_MSP430_16_BYTE */
14098 case 9: /* R_MSP430_8 */
7d81bc93 14099 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 14100 if (uses_msp430x_relocs (filedata))
13761a11
NC
14101 break;
14102 goto handle_sym_diff;
14103
14104 case 2: /* R_MSP430_ABS16 */
14105 case 15: /* R_MSP430X_ABS16 */
7d81bc93 14106 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 14107 if (! uses_msp430x_relocs (filedata))
13761a11
NC
14108 break;
14109 goto handle_sym_diff;
0b4362b0 14110
13761a11
NC
14111 handle_sym_diff:
14112 if (saved_sym != NULL)
14113 {
625d49fc 14114 uint64_t value;
5a805384 14115 unsigned int reloc_size = 0;
7d81bc93
JL
14116 int leb_ret = 0;
14117 switch (reloc_type)
14118 {
14119 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14120 reloc_size = 4;
14121 break;
14122 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14123 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14124 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14125 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14126 &reloc_size, &leb_ret);
7d81bc93
JL
14127 break;
14128 default:
14129 reloc_size = 2;
14130 break;
14131 }
13761a11 14132
5a805384 14133 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
14134 error (_("MSP430 ULEB128 field at %#" PRIx64
14135 " contains invalid ULEB128 value\n"),
14136 reloc->r_offset);
7d81bc93 14137 else if (sym_index >= num_syms)
74a965d8
AM
14138 error (_("%s reloc contains invalid symbol index "
14139 "%" PRIu64 "\n"), "MSP430", sym_index);
03f7786e 14140 else
f84ce13b
NC
14141 {
14142 value = reloc->r_addend + (symtab[sym_index].st_value
14143 - saved_sym->st_value);
14144
b32e566b 14145 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14146 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14147 else
14148 /* PR 21137 */
26c527e6
AM
14149 error (_("MSP430 sym diff reloc contains invalid offset: "
14150 "%#" PRIx64 "\n"),
14151 reloc->r_offset);
f84ce13b 14152 }
13761a11
NC
14153
14154 saved_sym = NULL;
015dc7e1 14155 return true;
13761a11
NC
14156 }
14157 break;
14158
14159 default:
14160 if (saved_sym != NULL)
071436c6 14161 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14162 break;
14163 }
14164 break;
14165 }
14166
cf13d699
NC
14167 case EM_MN10300:
14168 case EM_CYGNUS_MN10300:
14169 {
14170 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14171
f84ce13b
NC
14172 if (reloc == NULL)
14173 {
14174 saved_sym = NULL;
015dc7e1 14175 return true;
f84ce13b
NC
14176 }
14177
cf13d699
NC
14178 switch (reloc_type)
14179 {
14180 case 34: /* R_MN10300_ALIGN */
015dc7e1 14181 return true;
cf13d699 14182 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 14183 if (sym_index >= num_syms)
74a965d8
AM
14184 error (_("%s reloc contains invalid symbol index "
14185 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
f84ce13b
NC
14186 else
14187 saved_sym = symtab + sym_index;
015dc7e1 14188 return true;
f84ce13b 14189
cf13d699
NC
14190 case 1: /* R_MN10300_32 */
14191 case 2: /* R_MN10300_16 */
14192 if (saved_sym != NULL)
14193 {
03f7786e 14194 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14195 uint64_t value;
252b5132 14196
f84ce13b 14197 if (sym_index >= num_syms)
74a965d8
AM
14198 error (_("%s reloc contains invalid symbol index "
14199 "%" PRIu64 "\n"), "MN10300", sym_index);
03f7786e 14200 else
f84ce13b
NC
14201 {
14202 value = reloc->r_addend + (symtab[sym_index].st_value
14203 - saved_sym->st_value);
14204
b32e566b 14205 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14206 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 14207 else
26c527e6
AM
14208 error (_("MN10300 sym diff reloc contains invalid offset:"
14209 " %#" PRIx64 "\n"),
14210 reloc->r_offset);
f84ce13b 14211 }
252b5132 14212
cf13d699 14213 saved_sym = NULL;
015dc7e1 14214 return true;
cf13d699
NC
14215 }
14216 break;
14217 default:
14218 if (saved_sym != NULL)
071436c6 14219 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14220 break;
14221 }
14222 break;
14223 }
6ff71e76
NC
14224
14225 case EM_RL78:
14226 {
625d49fc
AM
14227 static uint64_t saved_sym1 = 0;
14228 static uint64_t saved_sym2 = 0;
14229 static uint64_t value;
6ff71e76 14230
f84ce13b
NC
14231 if (reloc == NULL)
14232 {
14233 saved_sym1 = saved_sym2 = 0;
015dc7e1 14234 return true;
f84ce13b
NC
14235 }
14236
6ff71e76
NC
14237 switch (reloc_type)
14238 {
14239 case 0x80: /* R_RL78_SYM. */
14240 saved_sym1 = saved_sym2;
f84ce13b 14241 if (sym_index >= num_syms)
74a965d8
AM
14242 error (_("%s reloc contains invalid symbol index "
14243 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
f84ce13b
NC
14244 else
14245 {
14246 saved_sym2 = symtab[sym_index].st_value;
14247 saved_sym2 += reloc->r_addend;
14248 }
015dc7e1 14249 return true;
6ff71e76
NC
14250
14251 case 0x83: /* R_RL78_OPsub. */
14252 value = saved_sym1 - saved_sym2;
14253 saved_sym2 = saved_sym1 = 0;
015dc7e1 14254 return true;
6ff71e76
NC
14255 break;
14256
14257 case 0x41: /* R_RL78_ABS32. */
b32e566b 14258 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14259 byte_put (start + reloc->r_offset, value, 4);
b32e566b 14260 else
26c527e6
AM
14261 error (_("RL78 sym diff reloc contains invalid offset: "
14262 "%#" PRIx64 "\n"),
14263 reloc->r_offset);
6ff71e76 14264 value = 0;
015dc7e1 14265 return true;
6ff71e76
NC
14266
14267 case 0x43: /* R_RL78_ABS16. */
b32e566b 14268 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14269 byte_put (start + reloc->r_offset, value, 2);
b32e566b 14270 else
26c527e6
AM
14271 error (_("RL78 sym diff reloc contains invalid offset: "
14272 "%#" PRIx64 "\n"),
14273 reloc->r_offset);
6ff71e76 14274 value = 0;
015dc7e1 14275 return true;
6ff71e76
NC
14276
14277 default:
14278 break;
14279 }
14280 break;
14281 }
252b5132
RH
14282 }
14283
015dc7e1 14284 return false;
252b5132
RH
14285}
14286
aca88567
NC
14287/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14288 DWARF debug sections. This is a target specific test. Note - we do not
14289 go through the whole including-target-headers-multiple-times route, (as
14290 we have already done with <elf/h8.h>) because this would become very
14291 messy and even then this function would have to contain target specific
14292 information (the names of the relocs instead of their numeric values).
14293 FIXME: This is not the correct way to solve this problem. The proper way
14294 is to have target specific reloc sizing and typing functions created by
14295 the reloc-macros.h header, in the same way that it already creates the
14296 reloc naming functions. */
14297
015dc7e1 14298static bool
dda8d76d 14299is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14300{
d347c9df 14301 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14302 switch (filedata->file_header.e_machine)
aca88567 14303 {
41e92641 14304 case EM_386:
22abe556 14305 case EM_IAMCU:
41e92641 14306 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14307 case EM_68K:
14308 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14309 case EM_860:
14310 return reloc_type == 1; /* R_860_32. */
14311 case EM_960:
14312 return reloc_type == 2; /* R_960_32. */
a06ea964 14313 case EM_AARCH64:
9282b95a
JW
14314 return (reloc_type == 258
14315 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14316 case EM_BPF:
14317 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14318 case EM_ADAPTEVA_EPIPHANY:
14319 return reloc_type == 3;
aca88567 14320 case EM_ALPHA:
137b6b5f 14321 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14322 case EM_ARC:
14323 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14324 case EM_ARC_COMPACT:
14325 case EM_ARC_COMPACT2:
14326 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14327 case EM_ARM:
14328 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14329 case EM_AVR_OLD:
aca88567
NC
14330 case EM_AVR:
14331 return reloc_type == 1;
14332 case EM_BLACKFIN:
14333 return reloc_type == 0x12; /* R_byte4_data. */
14334 case EM_CRIS:
14335 return reloc_type == 3; /* R_CRIS_32. */
14336 case EM_CR16:
14337 return reloc_type == 3; /* R_CR16_NUM32. */
14338 case EM_CRX:
14339 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14340 case EM_CSKY:
14341 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14342 case EM_CYGNUS_FRV:
14343 return reloc_type == 1;
41e92641
NC
14344 case EM_CYGNUS_D10V:
14345 case EM_D10V:
14346 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14347 case EM_CYGNUS_D30V:
14348 case EM_D30V:
14349 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14350 case EM_DLX:
14351 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14352 case EM_CYGNUS_FR30:
14353 case EM_FR30:
14354 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14355 case EM_FT32:
14356 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14357 case EM_H8S:
14358 case EM_H8_300:
14359 case EM_H8_300H:
14360 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14361 case EM_IA_64:
262cdac7
AM
14362 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14363 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14364 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14365 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14366 case EM_IP2K_OLD:
14367 case EM_IP2K:
14368 return reloc_type == 2; /* R_IP2K_32. */
14369 case EM_IQ2000:
14370 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14371 case EM_LATTICEMICO32:
14372 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14373 case EM_LOONGARCH:
14374 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14375 case EM_M32C_OLD:
aca88567
NC
14376 case EM_M32C:
14377 return reloc_type == 3; /* R_M32C_32. */
14378 case EM_M32R:
14379 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14380 case EM_68HC11:
14381 case EM_68HC12:
14382 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14383 case EM_S12Z:
2849d19f
JD
14384 return reloc_type == 7 || /* R_S12Z_EXT32 */
14385 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14386 case EM_MCORE:
14387 return reloc_type == 1; /* R_MCORE_ADDR32. */
14388 case EM_CYGNUS_MEP:
14389 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14390 case EM_METAG:
14391 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14392 case EM_MICROBLAZE:
14393 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14394 case EM_MIPS:
14395 return reloc_type == 2; /* R_MIPS_32. */
14396 case EM_MMIX:
14397 return reloc_type == 4; /* R_MMIX_32. */
14398 case EM_CYGNUS_MN10200:
14399 case EM_MN10200:
14400 return reloc_type == 1; /* R_MN10200_32. */
14401 case EM_CYGNUS_MN10300:
14402 case EM_MN10300:
14403 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14404 case EM_MOXIE:
14405 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14406 case EM_MSP430_OLD:
14407 case EM_MSP430:
13761a11 14408 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14409 case EM_MT:
14410 return reloc_type == 2; /* R_MT_32. */
35c08157 14411 case EM_NDS32:
81c5e376 14412 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14413 case EM_ALTERA_NIOS2:
36591ba1 14414 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14415 case EM_NIOS32:
14416 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14417 case EM_OR1K:
14418 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14419 case EM_PARISC:
9abca702 14420 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14421 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14422 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14423 case EM_PJ:
14424 case EM_PJ_OLD:
14425 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14426 case EM_PPC64:
14427 return reloc_type == 1; /* R_PPC64_ADDR32. */
14428 case EM_PPC:
14429 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14430 case EM_TI_PRU:
14431 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14432 case EM_RISCV:
14433 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14434 case EM_RL78:
14435 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14436 case EM_RX:
14437 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14438 case EM_S370:
14439 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14440 case EM_S390_OLD:
14441 case EM_S390:
14442 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14443 case EM_SCORE:
14444 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14445 case EM_SH:
14446 return reloc_type == 1; /* R_SH_DIR32. */
14447 case EM_SPARC32PLUS:
14448 case EM_SPARCV9:
14449 case EM_SPARC:
14450 return reloc_type == 3 /* R_SPARC_32. */
14451 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14452 case EM_SPU:
14453 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14454 case EM_TI_C6000:
14455 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14456 case EM_TILEGX:
14457 return reloc_type == 2; /* R_TILEGX_32. */
14458 case EM_TILEPRO:
14459 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14460 case EM_CYGNUS_V850:
14461 case EM_V850:
14462 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14463 case EM_V800:
14464 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14465 case EM_VAX:
14466 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14467 case EM_VISIUM:
14468 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14469 case EM_WEBASSEMBLY:
14470 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14471 case EM_X86_64:
8a9036a4 14472 case EM_L1OM:
7a9068fe 14473 case EM_K1OM:
aca88567 14474 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14475 case EM_XGATE:
14476 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14477 case EM_XSTORMY16:
14478 return reloc_type == 1; /* R_XSTROMY16_32. */
14479 case EM_XTENSA_OLD:
14480 case EM_XTENSA:
14481 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14482 case EM_Z80:
14483 return reloc_type == 6; /* R_Z80_32. */
aca88567 14484 default:
bee0ee85
NC
14485 {
14486 static unsigned int prev_warn = 0;
14487
14488 /* Avoid repeating the same warning multiple times. */
dda8d76d 14489 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14490 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14491 filedata->file_header.e_machine);
14492 prev_warn = filedata->file_header.e_machine;
015dc7e1 14493 return false;
bee0ee85 14494 }
aca88567
NC
14495 }
14496}
14497
14498/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14499 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14500
015dc7e1 14501static bool
dda8d76d 14502is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14503{
dda8d76d 14504 switch (filedata->file_header.e_machine)
d347c9df 14505 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14506 {
41e92641 14507 case EM_386:
22abe556 14508 case EM_IAMCU:
3e0873ac 14509 return reloc_type == 2; /* R_386_PC32. */
aca88567 14510 case EM_68K:
3e0873ac 14511 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14512 case EM_AARCH64:
14513 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14514 case EM_ADAPTEVA_EPIPHANY:
14515 return reloc_type == 6;
aca88567
NC
14516 case EM_ALPHA:
14517 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14518 case EM_ARC_COMPACT:
14519 case EM_ARC_COMPACT2:
14520 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14521 case EM_ARM:
3e0873ac 14522 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14523 case EM_AVR_OLD:
14524 case EM_AVR:
14525 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14526 case EM_LOONGARCH:
14527 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14528 case EM_MICROBLAZE:
14529 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14530 case EM_OR1K:
14531 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14532 case EM_PARISC:
85acf597 14533 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14534 case EM_PPC:
14535 return reloc_type == 26; /* R_PPC_REL32. */
14536 case EM_PPC64:
3e0873ac 14537 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14538 case EM_RISCV:
14539 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14540 case EM_S390_OLD:
14541 case EM_S390:
3e0873ac 14542 return reloc_type == 5; /* R_390_PC32. */
aca88567 14543 case EM_SH:
3e0873ac 14544 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14545 case EM_SPARC32PLUS:
14546 case EM_SPARCV9:
14547 case EM_SPARC:
3e0873ac 14548 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14549 case EM_SPU:
14550 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14551 case EM_TILEGX:
14552 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14553 case EM_TILEPRO:
14554 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14555 case EM_VISIUM:
14556 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14557 case EM_X86_64:
8a9036a4 14558 case EM_L1OM:
7a9068fe 14559 case EM_K1OM:
3e0873ac 14560 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14561 case EM_VAX:
14562 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14563 case EM_XTENSA_OLD:
14564 case EM_XTENSA:
14565 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14566 default:
14567 /* Do not abort or issue an error message here. Not all targets use
14568 pc-relative 32-bit relocs in their DWARF debug information and we
14569 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14570 more helpful warning message will be generated by apply_relocations
14571 anyway, so just return. */
015dc7e1 14572 return false;
aca88567
NC
14573 }
14574}
14575
14576/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14577 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14578
015dc7e1 14579static bool
dda8d76d 14580is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14581{
dda8d76d 14582 switch (filedata->file_header.e_machine)
aca88567 14583 {
a06ea964
NC
14584 case EM_AARCH64:
14585 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14586 case EM_ALPHA:
14587 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14588 case EM_IA_64:
262cdac7
AM
14589 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14590 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14591 case EM_LOONGARCH:
14592 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14593 case EM_PARISC:
14594 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14595 case EM_PPC64:
14596 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14597 case EM_RISCV:
14598 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14599 case EM_SPARC32PLUS:
14600 case EM_SPARCV9:
14601 case EM_SPARC:
714da62f
NC
14602 return reloc_type == 32 /* R_SPARC_64. */
14603 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14604 case EM_X86_64:
8a9036a4 14605 case EM_L1OM:
7a9068fe 14606 case EM_K1OM:
aca88567 14607 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14608 case EM_S390_OLD:
14609 case EM_S390:
aa137e4d
NC
14610 return reloc_type == 22; /* R_S390_64. */
14611 case EM_TILEGX:
14612 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14613 case EM_MIPS:
aa137e4d 14614 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14615 default:
015dc7e1 14616 return false;
aca88567
NC
14617 }
14618}
14619
85acf597
RH
14620/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14621 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14622
015dc7e1 14623static bool
dda8d76d 14624is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14625{
dda8d76d 14626 switch (filedata->file_header.e_machine)
85acf597 14627 {
a06ea964
NC
14628 case EM_AARCH64:
14629 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14630 case EM_ALPHA:
aa137e4d 14631 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14632 case EM_IA_64:
262cdac7
AM
14633 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14634 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14635 case EM_PARISC:
aa137e4d 14636 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14637 case EM_PPC64:
aa137e4d 14638 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14639 case EM_SPARC32PLUS:
14640 case EM_SPARCV9:
14641 case EM_SPARC:
aa137e4d 14642 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14643 case EM_X86_64:
8a9036a4 14644 case EM_L1OM:
7a9068fe 14645 case EM_K1OM:
aa137e4d 14646 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14647 case EM_S390_OLD:
14648 case EM_S390:
aa137e4d
NC
14649 return reloc_type == 23; /* R_S390_PC64. */
14650 case EM_TILEGX:
14651 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14652 default:
015dc7e1 14653 return false;
85acf597
RH
14654 }
14655}
14656
4dc3c23d
AM
14657/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14658 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14659
015dc7e1 14660static bool
dda8d76d 14661is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14662{
dda8d76d 14663 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14664 {
14665 case EM_CYGNUS_MN10200:
14666 case EM_MN10200:
14667 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14668 case EM_FT32:
14669 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14670 case EM_Z80:
14671 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14672 default:
015dc7e1 14673 return false;
4dc3c23d
AM
14674 }
14675}
14676
aca88567
NC
14677/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14678 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14679
015dc7e1 14680static bool
dda8d76d 14681is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14682{
d347c9df 14683 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14684 switch (filedata->file_header.e_machine)
4b78141a 14685 {
886a2506
NC
14686 case EM_ARC:
14687 case EM_ARC_COMPACT:
14688 case EM_ARC_COMPACT2:
14689 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14690 case EM_ADAPTEVA_EPIPHANY:
14691 return reloc_type == 5;
aca88567
NC
14692 case EM_AVR_OLD:
14693 case EM_AVR:
14694 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14695 case EM_CYGNUS_D10V:
14696 case EM_D10V:
14697 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14698 case EM_FT32:
14699 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14700 case EM_H8S:
14701 case EM_H8_300:
14702 case EM_H8_300H:
aca88567
NC
14703 return reloc_type == R_H8_DIR16;
14704 case EM_IP2K_OLD:
14705 case EM_IP2K:
14706 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14707 case EM_M32C_OLD:
f4236fe4
DD
14708 case EM_M32C:
14709 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14710 case EM_CYGNUS_MN10200:
14711 case EM_MN10200:
14712 return reloc_type == 2; /* R_MN10200_16. */
14713 case EM_CYGNUS_MN10300:
14714 case EM_MN10300:
14715 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14716 case EM_MSP430:
dda8d76d 14717 if (uses_msp430x_relocs (filedata))
13761a11 14718 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14719 /* Fall through. */
78c8d46c 14720 case EM_MSP430_OLD:
aca88567 14721 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 14722 case EM_NDS32:
81c5e376 14723 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 14724 case EM_ALTERA_NIOS2:
36591ba1 14725 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14726 case EM_NIOS32:
14727 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14728 case EM_OR1K:
14729 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14730 case EM_RISCV:
14731 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14732 case EM_TI_PRU:
14733 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14734 case EM_TI_C6000:
14735 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14736 case EM_VISIUM:
14737 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
14738 case EM_XGATE:
14739 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14740 case EM_Z80:
14741 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14742 default:
015dc7e1 14743 return false;
4b78141a
NC
14744 }
14745}
14746
39e07931
AS
14747/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14748 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14749
015dc7e1 14750static bool
39e07931
AS
14751is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14752{
14753 switch (filedata->file_header.e_machine)
14754 {
14755 case EM_RISCV:
14756 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14757 case EM_Z80:
14758 return reloc_type == 1; /* R_Z80_8. */
39e07931 14759 default:
015dc7e1 14760 return false;
39e07931
AS
14761 }
14762}
14763
14764/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14765 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14766
015dc7e1 14767static bool
39e07931
AS
14768is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14769{
14770 switch (filedata->file_header.e_machine)
14771 {
14772 case EM_RISCV:
14773 return reloc_type == 53; /* R_RISCV_SET6. */
14774 default:
015dc7e1 14775 return false;
39e07931
AS
14776 }
14777}
14778
03336641
JW
14779/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14780 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14781
015dc7e1 14782static bool
03336641
JW
14783is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14784{
14785 /* Please keep this table alpha-sorted for ease of visual lookup. */
14786 switch (filedata->file_header.e_machine)
14787 {
76244462 14788 case EM_LOONGARCH:
14789 return reloc_type == 50; /* R_LARCH_ADD32. */
03336641
JW
14790 case EM_RISCV:
14791 return reloc_type == 35; /* R_RISCV_ADD32. */
14792 default:
015dc7e1 14793 return false;
03336641
JW
14794 }
14795}
14796
14797/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14798 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14799
015dc7e1 14800static bool
03336641
JW
14801is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14802{
14803 /* Please keep this table alpha-sorted for ease of visual lookup. */
14804 switch (filedata->file_header.e_machine)
14805 {
76244462 14806 case EM_LOONGARCH:
14807 return reloc_type == 55; /* R_LARCH_SUB32. */
03336641
JW
14808 case EM_RISCV:
14809 return reloc_type == 39; /* R_RISCV_SUB32. */
14810 default:
015dc7e1 14811 return false;
03336641
JW
14812 }
14813}
14814
14815/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14816 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14817
015dc7e1 14818static bool
03336641
JW
14819is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14820{
14821 /* Please keep this table alpha-sorted for ease of visual lookup. */
14822 switch (filedata->file_header.e_machine)
14823 {
76244462 14824 case EM_LOONGARCH:
14825 return reloc_type == 51; /* R_LARCH_ADD64. */
03336641
JW
14826 case EM_RISCV:
14827 return reloc_type == 36; /* R_RISCV_ADD64. */
14828 default:
015dc7e1 14829 return false;
03336641
JW
14830 }
14831}
14832
14833/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14834 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14835
015dc7e1 14836static bool
03336641
JW
14837is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14838{
14839 /* Please keep this table alpha-sorted for ease of visual lookup. */
14840 switch (filedata->file_header.e_machine)
14841 {
76244462 14842 case EM_LOONGARCH:
14843 return reloc_type == 56; /* R_LARCH_SUB64. */
03336641
JW
14844 case EM_RISCV:
14845 return reloc_type == 40; /* R_RISCV_SUB64. */
14846 default:
015dc7e1 14847 return false;
03336641
JW
14848 }
14849}
14850
14851/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14852 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14853
015dc7e1 14854static bool
03336641
JW
14855is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14856{
14857 /* Please keep this table alpha-sorted for ease of visual lookup. */
14858 switch (filedata->file_header.e_machine)
14859 {
76244462 14860 case EM_LOONGARCH:
14861 return reloc_type == 48; /* R_LARCH_ADD16. */
03336641
JW
14862 case EM_RISCV:
14863 return reloc_type == 34; /* R_RISCV_ADD16. */
14864 default:
015dc7e1 14865 return false;
03336641
JW
14866 }
14867}
14868
14869/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14870 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14871
015dc7e1 14872static bool
03336641
JW
14873is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14874{
14875 /* Please keep this table alpha-sorted for ease of visual lookup. */
14876 switch (filedata->file_header.e_machine)
14877 {
76244462 14878 case EM_LOONGARCH:
14879 return reloc_type == 53; /* R_LARCH_SUB16. */
03336641
JW
14880 case EM_RISCV:
14881 return reloc_type == 38; /* R_RISCV_SUB16. */
14882 default:
015dc7e1 14883 return false;
03336641
JW
14884 }
14885}
14886
14887/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14888 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14889
015dc7e1 14890static bool
03336641
JW
14891is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14892{
14893 /* Please keep this table alpha-sorted for ease of visual lookup. */
14894 switch (filedata->file_header.e_machine)
14895 {
76244462 14896 case EM_LOONGARCH:
14897 return reloc_type == 47; /* R_LARCH_ADD8. */
03336641
JW
14898 case EM_RISCV:
14899 return reloc_type == 33; /* R_RISCV_ADD8. */
14900 default:
015dc7e1 14901 return false;
03336641
JW
14902 }
14903}
14904
14905/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14906 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14907
015dc7e1 14908static bool
03336641
JW
14909is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14910{
14911 /* Please keep this table alpha-sorted for ease of visual lookup. */
14912 switch (filedata->file_header.e_machine)
14913 {
76244462 14914 case EM_LOONGARCH:
14915 return reloc_type == 52; /* R_LARCH_SUB8. */
03336641
JW
14916 case EM_RISCV:
14917 return reloc_type == 37; /* R_RISCV_SUB8. */
14918 default:
015dc7e1 14919 return false;
03336641
JW
14920 }
14921}
14922
76244462 14923/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14924 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
14925
14926static bool
14927is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14928{
14929 switch (filedata->file_header.e_machine)
14930 {
14931 case EM_LOONGARCH:
14932 return reloc_type == 105; /* R_LARCH_ADD6. */
14933 default:
14934 return false;
14935 }
14936}
14937
39e07931
AS
14938/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14939 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14940
015dc7e1 14941static bool
39e07931
AS
14942is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14943{
14944 switch (filedata->file_header.e_machine)
14945 {
76244462 14946 case EM_LOONGARCH:
14947 return reloc_type == 106; /* R_LARCH_SUB6. */
39e07931
AS
14948 case EM_RISCV:
14949 return reloc_type == 52; /* R_RISCV_SUB6. */
14950 default:
015dc7e1 14951 return false;
39e07931
AS
14952 }
14953}
14954
2a7b2e88
JK
14955/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14956 relocation entries (possibly formerly used for SHT_GROUP sections). */
14957
015dc7e1 14958static bool
dda8d76d 14959is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14960{
dda8d76d 14961 switch (filedata->file_header.e_machine)
2a7b2e88 14962 {
cb8f3167 14963 case EM_386: /* R_386_NONE. */
d347c9df 14964 case EM_68K: /* R_68K_NONE. */
cfb8c092 14965 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14966 case EM_ALPHA: /* R_ALPHA_NONE. */
14967 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14968 case EM_ARC: /* R_ARC_NONE. */
886a2506 14969 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14970 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14971 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 14972 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14973 case EM_FT32: /* R_FT32_NONE. */
14974 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14975 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14976 case EM_L1OM: /* R_X86_64_NONE. */
14977 case EM_M32R: /* R_M32R_NONE. */
14978 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14979 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14980 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14981 case EM_NIOS32: /* R_NIOS_NONE. */
14982 case EM_OR1K: /* R_OR1K_NONE. */
14983 case EM_PARISC: /* R_PARISC_NONE. */
14984 case EM_PPC64: /* R_PPC64_NONE. */
14985 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14986 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14987 case EM_S390: /* R_390_NONE. */
14988 case EM_S390_OLD:
14989 case EM_SH: /* R_SH_NONE. */
14990 case EM_SPARC32PLUS:
14991 case EM_SPARC: /* R_SPARC_NONE. */
14992 case EM_SPARCV9:
aa137e4d
NC
14993 case EM_TILEGX: /* R_TILEGX_NONE. */
14994 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14995 case EM_TI_C6000:/* R_C6000_NONE. */
14996 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 14997 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14998 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14999 return reloc_type == 0;
d347c9df 15000
a06ea964
NC
15001 case EM_AARCH64:
15002 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
15003 case EM_AVR_OLD:
15004 case EM_AVR:
15005 return (reloc_type == 0 /* R_AVR_NONE. */
15006 || reloc_type == 30 /* R_AVR_DIFF8. */
15007 || reloc_type == 31 /* R_AVR_DIFF16. */
15008 || reloc_type == 32 /* R_AVR_DIFF32. */);
15009 case EM_METAG:
15010 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 15011 case EM_NDS32:
81c5e376
AM
15012 return (reloc_type == 0 /* R_NDS32_NONE. */
15013 || reloc_type == 205 /* R_NDS32_DIFF8. */
15014 || reloc_type == 206 /* R_NDS32_DIFF16. */
15015 || reloc_type == 207 /* R_NDS32_DIFF32. */
15016 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
15017 case EM_TI_PRU:
15018 return (reloc_type == 0 /* R_PRU_NONE. */
15019 || reloc_type == 65 /* R_PRU_DIFF8. */
15020 || reloc_type == 66 /* R_PRU_DIFF16. */
15021 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
15022 case EM_XTENSA_OLD:
15023 case EM_XTENSA:
4dc3c23d
AM
15024 return (reloc_type == 0 /* R_XTENSA_NONE. */
15025 || reloc_type == 17 /* R_XTENSA_DIFF8. */
15026 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
15027 || reloc_type == 19 /* R_XTENSA_DIFF32. */
15028 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
15029 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
15030 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
15031 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
15032 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
15033 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 15034 }
015dc7e1 15035 return false;
2a7b2e88
JK
15036}
15037
d1c4b12b
NC
15038/* Returns TRUE if there is a relocation against
15039 section NAME at OFFSET bytes. */
15040
015dc7e1 15041bool
31e5a3a3 15042reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
15043{
15044 Elf_Internal_Rela * relocs;
15045 Elf_Internal_Rela * rp;
15046
15047 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 15048 return false;
d1c4b12b
NC
15049
15050 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
15051
15052 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
15053 if (rp->r_offset == offset)
015dc7e1 15054 return true;
d1c4b12b 15055
015dc7e1 15056 return false;
d1c4b12b
NC
15057}
15058
cf13d699 15059/* Apply relocations to a section.
32ec8896
NC
15060 Returns TRUE upon success, FALSE otherwise.
15061 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
15062 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
15063 will be set to the number of relocs loaded.
15064
cf13d699 15065 Note: So far support has been added only for those relocations
32ec8896
NC
15066 which can be found in debug sections. FIXME: Add support for
15067 more relocations ? */
1b315056 15068
015dc7e1 15069static bool
be7d229a
AM
15070apply_relocations (Filedata *filedata,
15071 const Elf_Internal_Shdr *section,
15072 unsigned char *start,
15073 size_t size,
15074 void **relocs_return,
26c527e6 15075 uint64_t *num_relocs_return)
1b315056 15076{
cf13d699 15077 Elf_Internal_Shdr * relsec;
0d2a7a93 15078 unsigned char * end = start + size;
cb8f3167 15079
d1c4b12b
NC
15080 if (relocs_return != NULL)
15081 {
15082 * (Elf_Internal_Rela **) relocs_return = NULL;
15083 * num_relocs_return = 0;
15084 }
15085
dda8d76d 15086 if (filedata->file_header.e_type != ET_REL)
32ec8896 15087 /* No relocs to apply. */
015dc7e1 15088 return true;
1b315056 15089
cf13d699 15090 /* Find the reloc section associated with the section. */
dda8d76d
NC
15091 for (relsec = filedata->section_headers;
15092 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 15093 ++relsec)
252b5132 15094 {
015dc7e1 15095 bool is_rela;
26c527e6 15096 uint64_t num_relocs;
2cf0635d
NC
15097 Elf_Internal_Rela * relocs;
15098 Elf_Internal_Rela * rp;
15099 Elf_Internal_Shdr * symsec;
15100 Elf_Internal_Sym * symtab;
26c527e6 15101 uint64_t num_syms;
2cf0635d 15102 Elf_Internal_Sym * sym;
252b5132 15103
41e92641 15104 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15105 || relsec->sh_info >= filedata->file_header.e_shnum
15106 || filedata->section_headers + relsec->sh_info != section
c256ffe7 15107 || relsec->sh_size == 0
dda8d76d 15108 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 15109 continue;
428409d5 15110
a788aedd
AM
15111 symsec = filedata->section_headers + relsec->sh_link;
15112 if (symsec->sh_type != SHT_SYMTAB
15113 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 15114 return false;
a788aedd 15115
41e92641
NC
15116 is_rela = relsec->sh_type == SHT_RELA;
15117
15118 if (is_rela)
15119 {
dda8d76d 15120 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 15121 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15122 return false;
41e92641
NC
15123 }
15124 else
15125 {
dda8d76d 15126 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 15127 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15128 return false;
41e92641
NC
15129 }
15130
15131 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 15132 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 15133 is_rela = false;
428409d5 15134
4de91c10 15135 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 15136
41e92641 15137 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 15138 {
625d49fc 15139 uint64_t addend;
015dc7e1
AM
15140 unsigned int reloc_type;
15141 unsigned int reloc_size;
15142 bool reloc_inplace = false;
15143 bool reloc_subtract = false;
15144 unsigned char *rloc;
26c527e6 15145 uint64_t sym_index;
4b78141a 15146
dda8d76d 15147 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 15148
dda8d76d 15149 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 15150 continue;
dda8d76d 15151 else if (is_none_reloc (filedata, reloc_type))
98fb390a 15152 continue;
dda8d76d
NC
15153 else if (is_32bit_abs_reloc (filedata, reloc_type)
15154 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 15155 reloc_size = 4;
dda8d76d
NC
15156 else if (is_64bit_abs_reloc (filedata, reloc_type)
15157 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 15158 reloc_size = 8;
dda8d76d 15159 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15160 reloc_size = 3;
dda8d76d 15161 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15162 reloc_size = 2;
39e07931
AS
15163 else if (is_8bit_abs_reloc (filedata, reloc_type)
15164 || is_6bit_abs_reloc (filedata, reloc_type))
15165 reloc_size = 1;
03336641
JW
15166 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15167 reloc_type))
15168 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15169 {
15170 reloc_size = 4;
015dc7e1 15171 reloc_inplace = true;
03336641
JW
15172 }
15173 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15174 reloc_type))
15175 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15176 {
15177 reloc_size = 8;
015dc7e1 15178 reloc_inplace = true;
03336641
JW
15179 }
15180 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15181 reloc_type))
15182 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15183 {
15184 reloc_size = 2;
015dc7e1 15185 reloc_inplace = true;
03336641
JW
15186 }
15187 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15188 reloc_type))
15189 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15190 {
15191 reloc_size = 1;
015dc7e1 15192 reloc_inplace = true;
03336641 15193 }
39e07931 15194 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
76244462 15195 reloc_type))
15196 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15197 {
15198 reloc_size = 1;
015dc7e1 15199 reloc_inplace = true;
39e07931 15200 }
aca88567 15201 else
4b78141a 15202 {
bee0ee85 15203 static unsigned int prev_reloc = 0;
dda8d76d 15204
bee0ee85
NC
15205 if (reloc_type != prev_reloc)
15206 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15207 reloc_type, printable_section_name (filedata, section));
bee0ee85 15208 prev_reloc = reloc_type;
4b78141a
NC
15209 continue;
15210 }
103f02d3 15211
91d6fa6a 15212 rloc = start + rp->r_offset;
75802ccb 15213 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 15214 {
26c527e6
AM
15215 warn (_("skipping invalid relocation offset %#" PRIx64
15216 " in section %s\n"),
15217 rp->r_offset,
dda8d76d 15218 printable_section_name (filedata, section));
700dd8b7
L
15219 continue;
15220 }
103f02d3 15221
26c527e6 15222 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
15223 if (sym_index >= num_syms)
15224 {
26c527e6
AM
15225 warn (_("skipping invalid relocation symbol index %#" PRIx64
15226 " in section %s\n"),
dda8d76d 15227 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15228 continue;
15229 }
15230 sym = symtab + sym_index;
41e92641
NC
15231
15232 /* If the reloc has a symbol associated with it,
55f25fc3
L
15233 make sure that it is of an appropriate type.
15234
15235 Relocations against symbols without type can happen.
15236 Gcc -feliminate-dwarf2-dups may generate symbols
15237 without type for debug info.
15238
15239 Icc generates relocations against function symbols
15240 instead of local labels.
15241
15242 Relocations against object symbols can happen, eg when
15243 referencing a global array. For an example of this see
15244 the _clz.o binary in libgcc.a. */
aca88567 15245 if (sym != symtab
b8871f35 15246 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15247 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15248 {
26c527e6 15249 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
15250 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15251 printable_section_name (filedata, relsec),
26c527e6 15252 rp - relocs);
aca88567 15253 continue;
5b18a4bc 15254 }
252b5132 15255
4dc3c23d
AM
15256 addend = 0;
15257 if (is_rela)
15258 addend += rp->r_addend;
c47320c3
AM
15259 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15260 partial_inplace. */
4dc3c23d 15261 if (!is_rela
dda8d76d 15262 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15263 && reloc_type == 1)
dda8d76d
NC
15264 || ((filedata->file_header.e_machine == EM_PJ
15265 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15266 && reloc_type == 1)
dda8d76d
NC
15267 || ((filedata->file_header.e_machine == EM_D30V
15268 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15269 && reloc_type == 12)
15270 || reloc_inplace)
39e07931
AS
15271 {
15272 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15273 addend += byte_get (rloc, reloc_size) & 0x3f;
15274 else
15275 addend += byte_get (rloc, reloc_size);
15276 }
cb8f3167 15277
dda8d76d
NC
15278 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15279 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15280 {
15281 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15282 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15283 addend -= 8;
91d6fa6a 15284 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15285 reloc_size);
15286 }
39e07931 15287 else if (is_6bit_abs_reloc (filedata, reloc_type)
76244462 15288 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
15289 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15290 {
15291 if (reloc_subtract)
15292 addend -= sym->st_value;
15293 else
15294 addend += sym->st_value;
15295 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15296 byte_put (rloc, addend, reloc_size);
15297 }
03336641
JW
15298 else if (reloc_subtract)
15299 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15300 else
91d6fa6a 15301 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15302 }
252b5132 15303
5b18a4bc 15304 free (symtab);
f84ce13b
NC
15305 /* Let the target specific reloc processing code know that
15306 we have finished with these relocs. */
dda8d76d 15307 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15308
15309 if (relocs_return)
15310 {
15311 * (Elf_Internal_Rela **) relocs_return = relocs;
15312 * num_relocs_return = num_relocs;
15313 }
15314 else
15315 free (relocs);
15316
5b18a4bc
NC
15317 break;
15318 }
32ec8896 15319
015dc7e1 15320 return true;
5b18a4bc 15321}
103f02d3 15322
cf13d699 15323#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15324static bool
dda8d76d 15325disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15326{
dda8d76d 15327 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15328
74e1a04b 15329 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15330
015dc7e1 15331 return true;
cf13d699
NC
15332}
15333#endif
15334
15335/* Reads in the contents of SECTION from FILE, returning a pointer
15336 to a malloc'ed buffer or NULL if something went wrong. */
15337
15338static char *
dda8d76d 15339get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15340{
be7d229a 15341 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15342
15343 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15344 {
c6b78c96 15345 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15346 printable_section_name (filedata, section));
cf13d699
NC
15347 return NULL;
15348 }
15349
dda8d76d 15350 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15351 _("section contents"));
cf13d699
NC
15352}
15353
1f5a3546 15354/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 15355
015dc7e1 15356static bool
45f5fe46
NC
15357uncompress_section_contents (bool is_zstd,
15358 unsigned char ** buffer,
15359 uint64_t uncompressed_size,
15360 uint64_t * size,
15361 uint64_t file_size)
0e602686 15362{
31e5a3a3
AM
15363 uint64_t compressed_size = *size;
15364 unsigned char *compressed_buffer = *buffer;
45f5fe46 15365 unsigned char *uncompressed_buffer = NULL;
0e602686
NC
15366 z_stream strm;
15367 int rc;
15368
45f5fe46
NC
15369 /* Similar to _bfd_section_size_insane() in the BFD library we expect an
15370 upper limit of ~10x compression. Any compression larger than that is
15371 thought to be due to fuzzing of the compression header. */
15372 if (uncompressed_size > file_size * 10)
15373 {
15374 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
15375 uncompressed_size);
15376 goto fail;
15377 }
15378
15379 uncompressed_buffer = xmalloc (uncompressed_size);
15380
1f5a3546
FS
15381 if (is_zstd)
15382 {
15383#ifdef HAVE_ZSTD
15384 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15385 compressed_buffer, compressed_size);
15386 if (ZSTD_isError (ret))
15387 goto fail;
15388#endif
15389 }
15390 else
15391 {
15392 /* It is possible the section consists of several compressed
15393 buffers concatenated together, so we uncompress in a loop. */
15394 /* PR 18313: The state field in the z_stream structure is supposed
15395 to be invisible to the user (ie us), but some compilers will
15396 still complain about it being used without initialisation. So
15397 we first zero the entire z_stream structure and then set the fields
15398 that we need. */
15399 memset (&strm, 0, sizeof strm);
15400 strm.avail_in = compressed_size;
15401 strm.next_in = (Bytef *)compressed_buffer;
15402 strm.avail_out = uncompressed_size;
15403
15404 rc = inflateInit (&strm);
15405 while (strm.avail_in > 0)
15406 {
15407 if (rc != Z_OK)
15408 break;
15409 strm.next_out = ((Bytef *)uncompressed_buffer
15410 + (uncompressed_size - strm.avail_out));
15411 rc = inflate (&strm, Z_FINISH);
15412 if (rc != Z_STREAM_END)
15413 break;
15414 rc = inflateReset (&strm);
15415 }
15416 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15417 goto fail;
15418 }
0e602686
NC
15419
15420 *buffer = uncompressed_buffer;
15421 *size = uncompressed_size;
015dc7e1 15422 return true;
0e602686
NC
15423
15424 fail:
15425 free (uncompressed_buffer);
15426 /* Indicate decompression failure. */
15427 *buffer = NULL;
015dc7e1 15428 return false;
0e602686 15429}
dd24e3da 15430
015dc7e1 15431static bool
dda8d76d 15432dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15433{
015dc7e1 15434 Elf_Internal_Shdr *relsec;
be7d229a 15435 uint64_t num_bytes;
015dc7e1
AM
15436 unsigned char *data;
15437 unsigned char *end;
15438 unsigned char *real_start;
15439 unsigned char *start;
15440 bool some_strings_shown;
cf13d699 15441
dda8d76d 15442 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15443 if (start == NULL)
c6b78c96 15444 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15445 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15446
0e602686 15447 num_bytes = section->sh_size;
cf13d699 15448
835f2fae
NC
15449 if (filedata->is_separate)
15450 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15451 printable_section_name (filedata, section),
15452 filedata->file_name);
15453 else
15454 printf (_("\nString dump of section '%s':\n"),
15455 printable_section_name (filedata, section));
cf13d699 15456
0e602686
NC
15457 if (decompress_dumps)
15458 {
31e5a3a3
AM
15459 uint64_t new_size = num_bytes;
15460 uint64_t uncompressed_size = 0;
1f5a3546 15461 bool is_zstd = false;
0e602686
NC
15462
15463 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15464 {
15465 Elf_Internal_Chdr chdr;
15466 unsigned int compression_header_size
ebdf1ebf
NC
15467 = get_compression_header (& chdr, (unsigned char *) start,
15468 num_bytes);
5844b465
NC
15469 if (compression_header_size == 0)
15470 /* An error message will have already been generated
15471 by get_compression_header. */
15472 goto error_out;
0e602686 15473
89dbeac7 15474 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
15475 ;
15476#ifdef HAVE_ZSTD
89dbeac7 15477 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
15478 is_zstd = true;
15479#endif
15480 else
0e602686 15481 {
813dabb9 15482 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15483 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15484 goto error_out;
813dabb9 15485 }
813dabb9
L
15486 uncompressed_size = chdr.ch_size;
15487 start += compression_header_size;
15488 new_size -= compression_header_size;
0e602686
NC
15489 }
15490 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15491 {
15492 /* Read the zlib header. In this case, it should be "ZLIB"
15493 followed by the uncompressed section size, 8 bytes in
15494 big-endian order. */
15495 uncompressed_size = start[4]; uncompressed_size <<= 8;
15496 uncompressed_size += start[5]; uncompressed_size <<= 8;
15497 uncompressed_size += start[6]; uncompressed_size <<= 8;
15498 uncompressed_size += start[7]; uncompressed_size <<= 8;
15499 uncompressed_size += start[8]; uncompressed_size <<= 8;
15500 uncompressed_size += start[9]; uncompressed_size <<= 8;
15501 uncompressed_size += start[10]; uncompressed_size <<= 8;
15502 uncompressed_size += start[11];
15503 start += 12;
15504 new_size -= 12;
15505 }
15506
1835f746
NC
15507 if (uncompressed_size)
15508 {
1f5a3546 15509 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 15510 &new_size, filedata->file_size))
1835f746
NC
15511 num_bytes = new_size;
15512 else
15513 {
15514 error (_("Unable to decompress section %s\n"),
dda8d76d 15515 printable_section_name (filedata, section));
f761cb13 15516 goto error_out;
1835f746
NC
15517 }
15518 }
bc303e5d
NC
15519 else
15520 start = real_start;
0e602686 15521 }
fd8008d8 15522
cf13d699
NC
15523 /* If the section being dumped has relocations against it the user might
15524 be expecting these relocations to have been applied. Check for this
15525 case and issue a warning message in order to avoid confusion.
15526 FIXME: Maybe we ought to have an option that dumps a section with
15527 relocs applied ? */
dda8d76d
NC
15528 for (relsec = filedata->section_headers;
15529 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15530 ++relsec)
15531 {
15532 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15533 || relsec->sh_info >= filedata->file_header.e_shnum
15534 || filedata->section_headers + relsec->sh_info != section
cf13d699 15535 || relsec->sh_size == 0
dda8d76d 15536 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15537 continue;
15538
15539 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15540 break;
15541 }
15542
cf13d699
NC
15543 data = start;
15544 end = start + num_bytes;
015dc7e1 15545 some_strings_shown = false;
cf13d699 15546
ba3265d0
NC
15547#ifdef HAVE_MBSTATE_T
15548 mbstate_t state;
15549 /* Initialise the multibyte conversion state. */
15550 memset (& state, 0, sizeof (state));
15551#endif
15552
015dc7e1 15553 bool continuing = false;
ba3265d0 15554
cf13d699
NC
15555 while (data < end)
15556 {
15557 while (!ISPRINT (* data))
15558 if (++ data >= end)
15559 break;
15560
15561 if (data < end)
15562 {
071436c6
NC
15563 size_t maxlen = end - data;
15564
ba3265d0
NC
15565 if (continuing)
15566 {
15567 printf (" ");
015dc7e1 15568 continuing = false;
ba3265d0
NC
15569 }
15570 else
15571 {
26c527e6 15572 printf (" [%6tx] ", data - start);
ba3265d0
NC
15573 }
15574
4082ef84
NC
15575 if (maxlen > 0)
15576 {
f3da8a96 15577 char c = 0;
ba3265d0
NC
15578
15579 while (maxlen)
15580 {
15581 c = *data++;
15582
15583 if (c == 0)
15584 break;
15585
15586 /* PR 25543: Treat new-lines as string-ending characters. */
15587 if (c == '\n')
15588 {
15589 printf ("\\n\n");
15590 if (*data != 0)
015dc7e1 15591 continuing = true;
ba3265d0
NC
15592 break;
15593 }
15594
15595 /* Do not print control characters directly as they can affect terminal
15596 settings. Such characters usually appear in the names generated
15597 by the assembler for local labels. */
15598 if (ISCNTRL (c))
15599 {
15600 printf ("^%c", c + 0x40);
15601 }
15602 else if (ISPRINT (c))
15603 {
15604 putchar (c);
15605 }
15606 else
15607 {
15608 size_t n;
15609#ifdef HAVE_MBSTATE_T
15610 wchar_t w;
15611#endif
15612 /* Let printf do the hard work of displaying multibyte characters. */
15613 printf ("%.1s", data - 1);
15614#ifdef HAVE_MBSTATE_T
15615 /* Try to find out how many bytes made up the character that was
15616 just printed. Advance the symbol pointer past the bytes that
15617 were displayed. */
15618 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15619#else
15620 n = 1;
15621#endif
15622 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15623 data += (n - 1);
15624 }
15625 }
15626
15627 if (c != '\n')
15628 putchar ('\n');
4082ef84
NC
15629 }
15630 else
15631 {
15632 printf (_("<corrupt>\n"));
15633 data = end;
15634 }
015dc7e1 15635 some_strings_shown = true;
cf13d699
NC
15636 }
15637 }
15638
15639 if (! some_strings_shown)
15640 printf (_(" No strings found in this section."));
15641
0e602686 15642 free (real_start);
cf13d699
NC
15643
15644 putchar ('\n');
015dc7e1 15645 return true;
f761cb13
AM
15646
15647error_out:
15648 free (real_start);
015dc7e1 15649 return false;
cf13d699
NC
15650}
15651
015dc7e1
AM
15652static bool
15653dump_section_as_bytes (Elf_Internal_Shdr *section,
15654 Filedata *filedata,
15655 bool relocate)
cf13d699 15656{
be7d229a
AM
15657 Elf_Internal_Shdr *relsec;
15658 size_t bytes;
15659 uint64_t section_size;
625d49fc 15660 uint64_t addr;
be7d229a
AM
15661 unsigned char *data;
15662 unsigned char *real_start;
15663 unsigned char *start;
0e602686 15664
dda8d76d 15665 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15666 if (start == NULL)
c6b78c96 15667 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15668 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15669
0e602686 15670 section_size = section->sh_size;
cf13d699 15671
835f2fae
NC
15672 if (filedata->is_separate)
15673 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15674 printable_section_name (filedata, section),
15675 filedata->file_name);
15676 else
15677 printf (_("\nHex dump of section '%s':\n"),
15678 printable_section_name (filedata, section));
cf13d699 15679
0e602686
NC
15680 if (decompress_dumps)
15681 {
31e5a3a3
AM
15682 uint64_t new_size = section_size;
15683 uint64_t uncompressed_size = 0;
1f5a3546 15684 bool is_zstd = false;
0e602686
NC
15685
15686 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15687 {
15688 Elf_Internal_Chdr chdr;
15689 unsigned int compression_header_size
ebdf1ebf 15690 = get_compression_header (& chdr, start, section_size);
0e602686 15691
5844b465
NC
15692 if (compression_header_size == 0)
15693 /* An error message will have already been generated
15694 by get_compression_header. */
15695 goto error_out;
15696
89dbeac7 15697 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
15698 ;
15699#ifdef HAVE_ZSTD
89dbeac7 15700 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
15701 is_zstd = true;
15702#endif
15703 else
0e602686 15704 {
813dabb9 15705 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15706 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15707 goto error_out;
0e602686 15708 }
813dabb9
L
15709 uncompressed_size = chdr.ch_size;
15710 start += compression_header_size;
15711 new_size -= compression_header_size;
0e602686
NC
15712 }
15713 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15714 {
15715 /* Read the zlib header. In this case, it should be "ZLIB"
15716 followed by the uncompressed section size, 8 bytes in
15717 big-endian order. */
15718 uncompressed_size = start[4]; uncompressed_size <<= 8;
15719 uncompressed_size += start[5]; uncompressed_size <<= 8;
15720 uncompressed_size += start[6]; uncompressed_size <<= 8;
15721 uncompressed_size += start[7]; uncompressed_size <<= 8;
15722 uncompressed_size += start[8]; uncompressed_size <<= 8;
15723 uncompressed_size += start[9]; uncompressed_size <<= 8;
15724 uncompressed_size += start[10]; uncompressed_size <<= 8;
15725 uncompressed_size += start[11];
15726 start += 12;
15727 new_size -= 12;
15728 }
15729
f055032e
NC
15730 if (uncompressed_size)
15731 {
1f5a3546 15732 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 15733 &new_size, filedata->file_size))
bc303e5d
NC
15734 {
15735 section_size = new_size;
15736 }
f055032e
NC
15737 else
15738 {
15739 error (_("Unable to decompress section %s\n"),
dda8d76d 15740 printable_section_name (filedata, section));
bc303e5d 15741 /* FIXME: Print the section anyway ? */
f761cb13 15742 goto error_out;
f055032e
NC
15743 }
15744 }
bc303e5d
NC
15745 else
15746 start = real_start;
0e602686 15747 }
14ae95f2 15748
cf13d699
NC
15749 if (relocate)
15750 {
dda8d76d 15751 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15752 goto error_out;
cf13d699
NC
15753 }
15754 else
15755 {
15756 /* If the section being dumped has relocations against it the user might
15757 be expecting these relocations to have been applied. Check for this
15758 case and issue a warning message in order to avoid confusion.
15759 FIXME: Maybe we ought to have an option that dumps a section with
15760 relocs applied ? */
dda8d76d
NC
15761 for (relsec = filedata->section_headers;
15762 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15763 ++relsec)
15764 {
15765 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15766 || relsec->sh_info >= filedata->file_header.e_shnum
15767 || filedata->section_headers + relsec->sh_info != section
cf13d699 15768 || relsec->sh_size == 0
dda8d76d 15769 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15770 continue;
15771
15772 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15773 break;
15774 }
15775 }
15776
15777 addr = section->sh_addr;
0e602686 15778 bytes = section_size;
cf13d699
NC
15779 data = start;
15780
15781 while (bytes)
15782 {
15783 int j;
15784 int k;
15785 int lbytes;
15786
15787 lbytes = (bytes > 16 ? 16 : bytes);
15788
26c527e6 15789 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
15790
15791 for (j = 0; j < 16; j++)
15792 {
15793 if (j < lbytes)
15794 printf ("%2.2x", data[j]);
15795 else
15796 printf (" ");
15797
15798 if ((j & 3) == 3)
15799 printf (" ");
15800 }
15801
15802 for (j = 0; j < lbytes; j++)
15803 {
15804 k = data[j];
15805 if (k >= ' ' && k < 0x7f)
15806 printf ("%c", k);
15807 else
15808 printf (".");
15809 }
15810
15811 putchar ('\n');
15812
15813 data += lbytes;
15814 addr += lbytes;
15815 bytes -= lbytes;
15816 }
15817
0e602686 15818 free (real_start);
cf13d699
NC
15819
15820 putchar ('\n');
015dc7e1 15821 return true;
f761cb13
AM
15822
15823 error_out:
15824 free (real_start);
015dc7e1 15825 return false;
cf13d699
NC
15826}
15827
094e34f2 15828#ifdef ENABLE_LIBCTF
7d9813f1
NA
15829static ctf_sect_t *
15830shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15831{
84714f86 15832 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15833 buf->cts_size = shdr->sh_size;
15834 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15835
15836 return buf;
15837}
15838
15839/* Formatting callback function passed to ctf_dump. Returns either the pointer
15840 it is passed, or a pointer to newly-allocated storage, in which case
15841 dump_ctf() will free it when it no longer needs it. */
15842
2f6ecaed
NA
15843static char *
15844dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15845 char *s, void *arg)
7d9813f1 15846{
3e50a591 15847 const char *blanks = arg;
7d9813f1
NA
15848 char *new_s;
15849
3e50a591 15850 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15851 return s;
15852 return new_s;
15853}
15854
926c9e76
NA
15855/* Dump CTF errors/warnings. */
15856static void
139633c3 15857dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15858{
15859 ctf_next_t *it = NULL;
15860 char *errtext;
15861 int is_warning;
15862 int err;
15863
15864 /* Dump accumulated errors and warnings. */
15865 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15866 {
5e9b84f7 15867 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15868 errtext);
15869 free (errtext);
15870 }
15871 if (err != ECTF_NEXT_END)
15872 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15873}
15874
2f6ecaed
NA
15875/* Dump one CTF archive member. */
15876
80b56fad
NA
15877static void
15878dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15879 size_t member)
2f6ecaed 15880{
2f6ecaed
NA
15881 const char *things[] = {"Header", "Labels", "Data objects",
15882 "Function objects", "Variables", "Types", "Strings",
15883 ""};
15884 const char **thing;
15885 size_t i;
15886
80b56fad
NA
15887 /* Don't print out the name of the default-named archive member if it appears
15888 first in the list. The name .ctf appears everywhere, even for things that
15889 aren't really archives, so printing it out is liable to be confusing; also,
15890 the common case by far is for only one archive member to exist, and hiding
15891 it in that case seems worthwhile. */
2f6ecaed 15892
80b56fad
NA
15893 if (strcmp (name, ".ctf") != 0 || member != 0)
15894 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15895
80b56fad
NA
15896 if (ctf_parent_name (ctf) != NULL)
15897 ctf_import (ctf, parent);
2f6ecaed
NA
15898
15899 for (i = 0, thing = things; *thing[0]; thing++, i++)
15900 {
15901 ctf_dump_state_t *s = NULL;
15902 char *item;
15903
15904 printf ("\n %s:\n", *thing);
15905 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15906 (void *) " ")) != NULL)
15907 {
15908 printf ("%s\n", item);
15909 free (item);
15910 }
15911
15912 if (ctf_errno (ctf))
15913 {
15914 error (_("Iteration failed: %s, %s\n"), *thing,
15915 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15916 break;
2f6ecaed
NA
15917 }
15918 }
8b37e7b6 15919
926c9e76 15920 dump_ctf_errs (ctf);
2f6ecaed
NA
15921}
15922
015dc7e1 15923static bool
7d9813f1
NA
15924dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15925{
7d9813f1
NA
15926 Elf_Internal_Shdr * symtab_sec = NULL;
15927 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15928 void * data = NULL;
15929 void * symdata = NULL;
15930 void * strdata = NULL;
80b56fad 15931 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15932 ctf_sect_t * symsectp = NULL;
15933 ctf_sect_t * strsectp = NULL;
2f6ecaed 15934 ctf_archive_t * ctfa = NULL;
139633c3 15935 ctf_dict_t * parent = NULL;
80b56fad 15936 ctf_dict_t * fp;
7d9813f1 15937
80b56fad
NA
15938 ctf_next_t *i = NULL;
15939 const char *name;
15940 size_t member = 0;
7d9813f1 15941 int err;
015dc7e1 15942 bool ret = false;
7d9813f1
NA
15943
15944 shdr_to_ctf_sect (&ctfsect, section, filedata);
15945 data = get_section_contents (section, filedata);
15946 ctfsect.cts_data = data;
15947
616febde 15948 if (!dump_ctf_symtab_name)
3d16b64e 15949 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15950
15951 if (!dump_ctf_strtab_name)
3d16b64e 15952 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15953
15954 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15955 {
15956 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15957 {
15958 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15959 goto fail;
15960 }
15961 if ((symdata = (void *) get_data (NULL, filedata,
15962 symtab_sec->sh_offset, 1,
15963 symtab_sec->sh_size,
15964 _("symbols"))) == NULL)
15965 goto fail;
15966 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15967 symsect.cts_data = symdata;
15968 }
835f2fae 15969
df16e041 15970 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15971 {
15972 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15973 {
15974 error (_("No string table section named %s\n"),
15975 dump_ctf_strtab_name);
15976 goto fail;
15977 }
15978 if ((strdata = (void *) get_data (NULL, filedata,
15979 strtab_sec->sh_offset, 1,
15980 strtab_sec->sh_size,
15981 _("strings"))) == NULL)
15982 goto fail;
15983 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15984 strsect.cts_data = strdata;
15985 }
835f2fae 15986
2f6ecaed
NA
15987 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15988 libctf papers over the difference, so we can pretend it is always an
80b56fad 15989 archive. */
7d9813f1 15990
2f6ecaed 15991 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15992 {
926c9e76 15993 dump_ctf_errs (NULL);
7d9813f1
NA
15994 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15995 goto fail;
15996 }
15997
96c61be5
NA
15998 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15999 != ELFDATA2MSB);
16000
80b56fad
NA
16001 /* Preload the parent dict, since it will need to be imported into every
16002 child in turn. */
16003 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 16004 {
926c9e76 16005 dump_ctf_errs (NULL);
2f6ecaed
NA
16006 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16007 goto fail;
7d9813f1
NA
16008 }
16009
015dc7e1 16010 ret = true;
7d9813f1 16011
835f2fae
NC
16012 if (filedata->is_separate)
16013 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
16014 printable_section_name (filedata, section),
16015 filedata->file_name);
16016 else
16017 printf (_("\nDump of CTF section '%s':\n"),
16018 printable_section_name (filedata, section));
7d9813f1 16019
80b56fad
NA
16020 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
16021 dump_ctf_archive_member (fp, name, parent, member++);
16022 if (err != ECTF_NEXT_END)
16023 {
16024 dump_ctf_errs (NULL);
16025 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
16026 ret = false;
16027 }
7d9813f1
NA
16028
16029 fail:
139633c3 16030 ctf_dict_close (parent);
2f6ecaed 16031 ctf_close (ctfa);
7d9813f1
NA
16032 free (data);
16033 free (symdata);
16034 free (strdata);
16035 return ret;
16036}
094e34f2 16037#endif
7d9813f1 16038
42b6953b
IB
16039static bool
16040dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
16041{
16042 void * data = NULL;
16043 sframe_decoder_ctx *sfd_ctx = NULL;
16044 const char *print_name = printable_section_name (filedata, section);
16045
16046 bool ret = true;
16047 size_t sf_size;
16048 int err = 0;
16049
16050 if (strcmp (print_name, "") == 0)
16051 {
16052 error (_("Section name must be provided \n"));
16053 ret = false;
16054 return ret;
16055 }
16056
16057 data = get_section_contents (section, filedata);
16058 sf_size = section->sh_size;
16059 /* Decode the contents of the section. */
16060 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
16061 if (!sfd_ctx)
16062 {
16063 ret = false;
16064 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
16065 goto fail;
16066 }
16067
16068 printf (_("Contents of the SFrame section %s:"), print_name);
16069 /* Dump the contents as text. */
16070 dump_sframe (sfd_ctx, section->sh_addr);
16071
16072 fail:
16073 free (data);
16074 return ret;
16075}
16076
015dc7e1 16077static bool
dda8d76d
NC
16078load_specific_debug_section (enum dwarf_section_display_enum debug,
16079 const Elf_Internal_Shdr * sec,
16080 void * data)
1007acb3 16081{
2cf0635d 16082 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 16083 char buf [64];
dda8d76d 16084 Filedata * filedata = (Filedata *) data;
9abca702 16085
19e6b90e 16086 if (section->start != NULL)
dda8d76d
NC
16087 {
16088 /* If it is already loaded, do nothing. */
16089 if (streq (section->filename, filedata->file_name))
015dc7e1 16090 return true;
dda8d76d
NC
16091 free (section->start);
16092 }
1007acb3 16093
19e6b90e
L
16094 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16095 section->address = sec->sh_addr;
dda8d76d
NC
16096 section->filename = filedata->file_name;
16097 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
16098 sec->sh_offset, 1,
16099 sec->sh_size, buf);
59245841
NC
16100 if (section->start == NULL)
16101 section->size = 0;
16102 else
16103 {
77115a4a 16104 unsigned char *start = section->start;
31e5a3a3
AM
16105 uint64_t size = sec->sh_size;
16106 uint64_t uncompressed_size = 0;
1f5a3546 16107 bool is_zstd = false;
77115a4a
L
16108
16109 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16110 {
16111 Elf_Internal_Chdr chdr;
d8024a91
NC
16112 unsigned int compression_header_size;
16113
f53be977
L
16114 if (size < (is_32bit_elf
16115 ? sizeof (Elf32_External_Chdr)
16116 : sizeof (Elf64_External_Chdr)))
d8024a91 16117 {
55be8fd0 16118 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 16119 section->name);
015dc7e1 16120 return false;
d8024a91
NC
16121 }
16122
ebdf1ebf 16123 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
16124 if (compression_header_size == 0)
16125 /* An error message will have already been generated
16126 by get_compression_header. */
015dc7e1 16127 return false;
d8024a91 16128
89dbeac7 16129 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16130 ;
16131#ifdef HAVE_ZSTD
89dbeac7 16132 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16133 is_zstd = true;
16134#endif
16135 else
813dabb9
L
16136 {
16137 warn (_("section '%s' has unsupported compress type: %d\n"),
16138 section->name, chdr.ch_type);
015dc7e1 16139 return false;
813dabb9 16140 }
dab394de 16141 uncompressed_size = chdr.ch_size;
77115a4a
L
16142 start += compression_header_size;
16143 size -= compression_header_size;
16144 }
dab394de
L
16145 else if (size > 12 && streq ((char *) start, "ZLIB"))
16146 {
16147 /* Read the zlib header. In this case, it should be "ZLIB"
16148 followed by the uncompressed section size, 8 bytes in
16149 big-endian order. */
16150 uncompressed_size = start[4]; uncompressed_size <<= 8;
16151 uncompressed_size += start[5]; uncompressed_size <<= 8;
16152 uncompressed_size += start[6]; uncompressed_size <<= 8;
16153 uncompressed_size += start[7]; uncompressed_size <<= 8;
16154 uncompressed_size += start[8]; uncompressed_size <<= 8;
16155 uncompressed_size += start[9]; uncompressed_size <<= 8;
16156 uncompressed_size += start[10]; uncompressed_size <<= 8;
16157 uncompressed_size += start[11];
16158 start += 12;
16159 size -= 12;
16160 }
16161
1835f746 16162 if (uncompressed_size)
77115a4a 16163 {
1f5a3546 16164 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16165 &size, filedata->file_size))
1835f746
NC
16166 {
16167 /* Free the compressed buffer, update the section buffer
16168 and the section size if uncompress is successful. */
16169 free (section->start);
16170 section->start = start;
16171 }
16172 else
16173 {
16174 error (_("Unable to decompress section %s\n"),
dda8d76d 16175 printable_section_name (filedata, sec));
015dc7e1 16176 return false;
1835f746 16177 }
77115a4a 16178 }
bc303e5d 16179
77115a4a 16180 section->size = size;
59245841 16181 }
4a114e3e 16182
1b315056 16183 if (section->start == NULL)
015dc7e1 16184 return false;
1b315056 16185
19e6b90e 16186 if (debug_displays [debug].relocate)
32ec8896 16187 {
dda8d76d 16188 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 16189 & section->reloc_info, & section->num_relocs))
015dc7e1 16190 return false;
32ec8896 16191 }
d1c4b12b
NC
16192 else
16193 {
16194 section->reloc_info = NULL;
16195 section->num_relocs = 0;
16196 }
1007acb3 16197
015dc7e1 16198 return true;
1007acb3
L
16199}
16200
301a9420
AM
16201#if HAVE_LIBDEBUGINFOD
16202/* Return a hex string representation of the build-id. */
16203unsigned char *
16204get_build_id (void * data)
16205{
ca0e11aa 16206 Filedata * filedata = (Filedata *) data;
301a9420 16207 Elf_Internal_Shdr * shdr;
26c527e6 16208 size_t i;
301a9420 16209
55be8fd0
NC
16210 /* Iterate through notes to find note.gnu.build-id.
16211 FIXME: Only the first note in any note section is examined. */
301a9420
AM
16212 for (i = 0, shdr = filedata->section_headers;
16213 i < filedata->file_header.e_shnum && shdr != NULL;
16214 i++, shdr++)
16215 {
16216 if (shdr->sh_type != SHT_NOTE)
16217 continue;
16218
16219 char * next;
16220 char * end;
16221 size_t data_remaining;
16222 size_t min_notesz;
16223 Elf_External_Note * enote;
16224 Elf_Internal_Note inote;
16225
625d49fc
AM
16226 uint64_t offset = shdr->sh_offset;
16227 uint64_t align = shdr->sh_addralign;
16228 uint64_t length = shdr->sh_size;
301a9420
AM
16229
16230 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16231 if (enote == NULL)
16232 continue;
16233
16234 if (align < 4)
16235 align = 4;
16236 else if (align != 4 && align != 8)
f761cb13
AM
16237 {
16238 free (enote);
16239 continue;
16240 }
301a9420
AM
16241
16242 end = (char *) enote + length;
16243 data_remaining = end - (char *) enote;
16244
16245 if (!is_ia64_vms (filedata))
16246 {
16247 min_notesz = offsetof (Elf_External_Note, name);
16248 if (data_remaining < min_notesz)
16249 {
55be8fd0
NC
16250 warn (_("\
16251malformed note encountered in section %s whilst scanning for build-id note\n"),
16252 printable_section_name (filedata, shdr));
f761cb13 16253 free (enote);
55be8fd0 16254 continue;
301a9420
AM
16255 }
16256 data_remaining -= min_notesz;
16257
16258 inote.type = BYTE_GET (enote->type);
16259 inote.namesz = BYTE_GET (enote->namesz);
16260 inote.namedata = enote->name;
16261 inote.descsz = BYTE_GET (enote->descsz);
16262 inote.descdata = ((char *) enote
16263 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16264 inote.descpos = offset + (inote.descdata - (char *) enote);
16265 next = ((char *) enote
16266 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16267 }
16268 else
16269 {
16270 Elf64_External_VMS_Note *vms_enote;
16271
16272 /* PR binutils/15191
16273 Make sure that there is enough data to read. */
16274 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16275 if (data_remaining < min_notesz)
16276 {
55be8fd0
NC
16277 warn (_("\
16278malformed note encountered in section %s whilst scanning for build-id note\n"),
16279 printable_section_name (filedata, shdr));
f761cb13 16280 free (enote);
55be8fd0 16281 continue;
301a9420
AM
16282 }
16283 data_remaining -= min_notesz;
16284
16285 vms_enote = (Elf64_External_VMS_Note *) enote;
16286 inote.type = BYTE_GET (vms_enote->type);
16287 inote.namesz = BYTE_GET (vms_enote->namesz);
16288 inote.namedata = vms_enote->name;
16289 inote.descsz = BYTE_GET (vms_enote->descsz);
16290 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16291 inote.descpos = offset + (inote.descdata - (char *) enote);
16292 next = inote.descdata + align_power (inote.descsz, 3);
16293 }
16294
16295 /* Skip malformed notes. */
16296 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16297 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16298 || (size_t) (next - inote.descdata) < inote.descsz
16299 || ((size_t) (next - inote.descdata)
16300 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
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);
301a9420
AM
16306 continue;
16307 }
16308
16309 /* Check if this is the build-id note. If so then convert the build-id
16310 bytes to a hex string. */
16311 if (inote.namesz > 0
24d127aa 16312 && startswith (inote.namedata, "GNU")
301a9420
AM
16313 && inote.type == NT_GNU_BUILD_ID)
16314 {
26c527e6 16315 size_t j;
301a9420
AM
16316 char * build_id;
16317
16318 build_id = malloc (inote.descsz * 2 + 1);
16319 if (build_id == NULL)
f761cb13
AM
16320 {
16321 free (enote);
16322 return NULL;
16323 }
301a9420
AM
16324
16325 for (j = 0; j < inote.descsz; ++j)
16326 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16327 build_id[inote.descsz * 2] = '\0';
f761cb13 16328 free (enote);
301a9420 16329
55be8fd0 16330 return (unsigned char *) build_id;
301a9420 16331 }
f761cb13 16332 free (enote);
301a9420
AM
16333 }
16334
16335 return NULL;
16336}
16337#endif /* HAVE_LIBDEBUGINFOD */
16338
657d0d47
CC
16339/* If this is not NULL, load_debug_section will only look for sections
16340 within the list of sections given here. */
32ec8896 16341static unsigned int * section_subset = NULL;
657d0d47 16342
015dc7e1 16343bool
dda8d76d 16344load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16345{
2cf0635d
NC
16346 struct dwarf_section * section = &debug_displays [debug].section;
16347 Elf_Internal_Shdr * sec;
dda8d76d
NC
16348 Filedata * filedata = (Filedata *) data;
16349
e1dbfc17
L
16350 if (!dump_any_debugging)
16351 return false;
16352
f425ec66
NC
16353 /* Without section headers we cannot find any sections. */
16354 if (filedata->section_headers == NULL)
015dc7e1 16355 return false;
f425ec66 16356
9c1ce108
AM
16357 if (filedata->string_table == NULL
16358 && filedata->file_header.e_shstrndx != SHN_UNDEF
16359 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16360 {
16361 Elf_Internal_Shdr * strs;
16362
16363 /* Read in the string table, so that we have section names to scan. */
16364 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16365
4dff97b2 16366 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16367 {
9c1ce108
AM
16368 filedata->string_table
16369 = (char *) get_data (NULL, filedata, strs->sh_offset,
16370 1, strs->sh_size, _("string table"));
dda8d76d 16371
9c1ce108
AM
16372 filedata->string_table_length
16373 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16374 }
16375 }
d966045b
DJ
16376
16377 /* Locate the debug section. */
dda8d76d 16378 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16379 if (sec != NULL)
16380 section->name = section->uncompressed_name;
16381 else
16382 {
dda8d76d 16383 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16384 if (sec != NULL)
16385 section->name = section->compressed_name;
16386 }
16387 if (sec == NULL)
015dc7e1 16388 return false;
d966045b 16389
657d0d47
CC
16390 /* If we're loading from a subset of sections, and we've loaded
16391 a section matching this name before, it's likely that it's a
16392 different one. */
16393 if (section_subset != NULL)
16394 free_debug_section (debug);
16395
dda8d76d 16396 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16397}
16398
19e6b90e
L
16399void
16400free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16401{
2cf0635d 16402 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16403
19e6b90e
L
16404 if (section->start == NULL)
16405 return;
1007acb3 16406
19e6b90e
L
16407 free ((char *) section->start);
16408 section->start = NULL;
16409 section->address = 0;
16410 section->size = 0;
a788aedd 16411
9db70fc3
AM
16412 free (section->reloc_info);
16413 section->reloc_info = NULL;
16414 section->num_relocs = 0;
1007acb3
L
16415}
16416
015dc7e1 16417static bool
dda8d76d 16418display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16419{
84714f86
AM
16420 const char *name = (section_name_valid (filedata, section)
16421 ? section_name (filedata, section) : "");
16422 const char *print_name = printable_section_name (filedata, section);
be7d229a 16423 uint64_t length;
015dc7e1 16424 bool result = true;
3f5e193b 16425 int i;
1007acb3 16426
19e6b90e
L
16427 length = section->sh_size;
16428 if (length == 0)
1007acb3 16429 {
74e1a04b 16430 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16431 return true;
1007acb3 16432 }
5dff79d8
NC
16433 if (section->sh_type == SHT_NOBITS)
16434 {
16435 /* There is no point in dumping the contents of a debugging section
16436 which has the NOBITS type - the bits in the file will be random.
16437 This can happen when a file containing a .eh_frame section is
16438 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16439 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16440 print_name);
015dc7e1 16441 return false;
5dff79d8 16442 }
1007acb3 16443
24d127aa 16444 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16445 name = ".debug_info";
1007acb3 16446
19e6b90e
L
16447 /* See if we know how to display the contents of this section. */
16448 for (i = 0; i < max; i++)
d85bf2ba
NC
16449 {
16450 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16451 struct dwarf_section_display * display = debug_displays + i;
16452 struct dwarf_section * sec = & display->section;
d966045b 16453
d85bf2ba 16454 if (streq (sec->uncompressed_name, name)
24d127aa 16455 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16456 || streq (sec->compressed_name, name))
16457 {
015dc7e1 16458 bool secondary = (section != find_section (filedata, name));
1007acb3 16459
d85bf2ba
NC
16460 if (secondary)
16461 free_debug_section (id);
dda8d76d 16462
24d127aa 16463 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16464 sec->name = name;
16465 else if (streq (sec->uncompressed_name, name))
16466 sec->name = sec->uncompressed_name;
16467 else
16468 sec->name = sec->compressed_name;
657d0d47 16469
d85bf2ba
NC
16470 if (load_specific_debug_section (id, section, filedata))
16471 {
16472 /* If this debug section is part of a CU/TU set in a .dwp file,
16473 restrict load_debug_section to the sections in that set. */
16474 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16475
d85bf2ba 16476 result &= display->display (sec, filedata);
657d0d47 16477
d85bf2ba 16478 section_subset = NULL;
1007acb3 16479
44266f36 16480 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16481 free_debug_section (id);
16482 }
16483 break;
16484 }
16485 }
1007acb3 16486
19e6b90e 16487 if (i == max)
1007acb3 16488 {
74e1a04b 16489 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16490 result = false;
1007acb3
L
16491 }
16492
19e6b90e 16493 return result;
5b18a4bc 16494}
103f02d3 16495
aef1f6d0
DJ
16496/* Set DUMP_SECTS for all sections where dumps were requested
16497 based on section name. */
16498
16499static void
dda8d76d 16500initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16501{
2cf0635d 16502 struct dump_list_entry * cur;
aef1f6d0
DJ
16503
16504 for (cur = dump_sects_byname; cur; cur = cur->next)
16505 {
16506 unsigned int i;
015dc7e1 16507 bool any = false;
aef1f6d0 16508
dda8d76d 16509 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16510 if (section_name_valid (filedata, filedata->section_headers + i)
16511 && streq (section_name (filedata, filedata->section_headers + i),
16512 cur->name))
aef1f6d0 16513 {
6431e409 16514 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16515 any = true;
aef1f6d0
DJ
16516 }
16517
835f2fae
NC
16518 if (!any && !filedata->is_separate)
16519 warn (_("Section '%s' was not dumped because it does not exist\n"),
16520 cur->name);
aef1f6d0
DJ
16521 }
16522}
16523
015dc7e1 16524static bool
dda8d76d 16525process_section_contents (Filedata * filedata)
5b18a4bc 16526{
2cf0635d 16527 Elf_Internal_Shdr * section;
19e6b90e 16528 unsigned int i;
015dc7e1 16529 bool res = true;
103f02d3 16530
19e6b90e 16531 if (! do_dump)
015dc7e1 16532 return true;
103f02d3 16533
dda8d76d 16534 initialise_dumps_byname (filedata);
aef1f6d0 16535
dda8d76d 16536 for (i = 0, section = filedata->section_headers;
6431e409 16537 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16538 i++, section++)
16539 {
6431e409 16540 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16541
d6bfbc39
NC
16542 if (filedata->is_separate && ! process_links)
16543 dump &= DEBUG_DUMP;
047c3dbf 16544
19e6b90e 16545#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16546 if (dump & DISASS_DUMP)
16547 {
16548 if (! disassemble_section (section, filedata))
015dc7e1 16549 res = false;
dda8d76d 16550 }
19e6b90e 16551#endif
dda8d76d 16552 if (dump & HEX_DUMP)
32ec8896 16553 {
015dc7e1
AM
16554 if (! dump_section_as_bytes (section, filedata, false))
16555 res = false;
32ec8896 16556 }
103f02d3 16557
dda8d76d 16558 if (dump & RELOC_DUMP)
32ec8896 16559 {
015dc7e1
AM
16560 if (! dump_section_as_bytes (section, filedata, true))
16561 res = false;
32ec8896 16562 }
09c11c86 16563
dda8d76d 16564 if (dump & STRING_DUMP)
32ec8896 16565 {
dda8d76d 16566 if (! dump_section_as_strings (section, filedata))
015dc7e1 16567 res = false;
32ec8896 16568 }
cf13d699 16569
dda8d76d 16570 if (dump & DEBUG_DUMP)
32ec8896 16571 {
dda8d76d 16572 if (! display_debug_section (i, section, filedata))
015dc7e1 16573 res = false;
32ec8896 16574 }
7d9813f1 16575
094e34f2 16576#ifdef ENABLE_LIBCTF
7d9813f1
NA
16577 if (dump & CTF_DUMP)
16578 {
16579 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16580 res = false;
7d9813f1 16581 }
094e34f2 16582#endif
42b6953b
IB
16583 if (dump & SFRAME_DUMP)
16584 {
16585 if (! dump_section_as_sframe (section, filedata))
16586 res = false;
16587 }
5b18a4bc 16588 }
103f02d3 16589
835f2fae 16590 if (! filedata->is_separate)
0ee3043f 16591 {
835f2fae
NC
16592 /* Check to see if the user requested a
16593 dump of a section that does not exist. */
16594 for (; i < filedata->dump.num_dump_sects; i++)
16595 if (filedata->dump.dump_sects[i])
16596 {
ca0e11aa 16597 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16598 res = false;
835f2fae 16599 }
0ee3043f 16600 }
32ec8896
NC
16601
16602 return res;
5b18a4bc 16603}
103f02d3 16604
5b18a4bc 16605static void
19e6b90e 16606process_mips_fpe_exception (int mask)
5b18a4bc 16607{
19e6b90e
L
16608 if (mask)
16609 {
015dc7e1 16610 bool first = true;
32ec8896 16611
19e6b90e 16612 if (mask & OEX_FPU_INEX)
015dc7e1 16613 fputs ("INEX", stdout), first = false;
19e6b90e 16614 if (mask & OEX_FPU_UFLO)
015dc7e1 16615 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16616 if (mask & OEX_FPU_OFLO)
015dc7e1 16617 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16618 if (mask & OEX_FPU_DIV0)
015dc7e1 16619 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16620 if (mask & OEX_FPU_INVAL)
16621 printf ("%sINVAL", first ? "" : "|");
16622 }
5b18a4bc 16623 else
19e6b90e 16624 fputs ("0", stdout);
5b18a4bc 16625}
103f02d3 16626
f6f0e17b
NC
16627/* Display's the value of TAG at location P. If TAG is
16628 greater than 0 it is assumed to be an unknown tag, and
16629 a message is printed to this effect. Otherwise it is
16630 assumed that a message has already been printed.
16631
16632 If the bottom bit of TAG is set it assumed to have a
16633 string value, otherwise it is assumed to have an integer
16634 value.
16635
16636 Returns an updated P pointing to the first unread byte
16637 beyond the end of TAG's value.
16638
16639 Reads at or beyond END will not be made. */
16640
16641static unsigned char *
60abdbed 16642display_tag_value (signed int tag,
f6f0e17b
NC
16643 unsigned char * p,
16644 const unsigned char * const end)
16645{
26c527e6 16646 uint64_t val;
f6f0e17b
NC
16647
16648 if (tag > 0)
16649 printf (" Tag_unknown_%d: ", tag);
16650
16651 if (p >= end)
16652 {
4082ef84 16653 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16654 }
16655 else if (tag & 1)
16656 {
071436c6
NC
16657 /* PR 17531 file: 027-19978-0.004. */
16658 size_t maxlen = (end - p) - 1;
16659
16660 putchar ('"');
4082ef84
NC
16661 if (maxlen > 0)
16662 {
16663 print_symbol ((int) maxlen, (const char *) p);
16664 p += strnlen ((char *) p, maxlen) + 1;
16665 }
16666 else
16667 {
16668 printf (_("<corrupt string tag>"));
16669 p = (unsigned char *) end;
16670 }
071436c6 16671 printf ("\"\n");
f6f0e17b
NC
16672 }
16673 else
16674 {
cd30bcef 16675 READ_ULEB (val, p, end);
26c527e6 16676 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
16677 }
16678
4082ef84 16679 assert (p <= end);
f6f0e17b
NC
16680 return p;
16681}
16682
53a346d8
CZ
16683/* ARC ABI attributes section. */
16684
16685static unsigned char *
16686display_arc_attribute (unsigned char * p,
16687 const unsigned char * const end)
16688{
16689 unsigned int tag;
53a346d8
CZ
16690 unsigned int val;
16691
cd30bcef 16692 READ_ULEB (tag, p, end);
53a346d8
CZ
16693
16694 switch (tag)
16695 {
16696 case Tag_ARC_PCS_config:
cd30bcef 16697 READ_ULEB (val, p, end);
53a346d8
CZ
16698 printf (" Tag_ARC_PCS_config: ");
16699 switch (val)
16700 {
16701 case 0:
16702 printf (_("Absent/Non standard\n"));
16703 break;
16704 case 1:
16705 printf (_("Bare metal/mwdt\n"));
16706 break;
16707 case 2:
16708 printf (_("Bare metal/newlib\n"));
16709 break;
16710 case 3:
16711 printf (_("Linux/uclibc\n"));
16712 break;
16713 case 4:
16714 printf (_("Linux/glibc\n"));
16715 break;
16716 default:
16717 printf (_("Unknown\n"));
16718 break;
16719 }
16720 break;
16721
16722 case Tag_ARC_CPU_base:
cd30bcef 16723 READ_ULEB (val, p, end);
53a346d8
CZ
16724 printf (" Tag_ARC_CPU_base: ");
16725 switch (val)
16726 {
16727 default:
16728 case TAG_CPU_NONE:
16729 printf (_("Absent\n"));
16730 break;
16731 case TAG_CPU_ARC6xx:
16732 printf ("ARC6xx\n");
16733 break;
16734 case TAG_CPU_ARC7xx:
16735 printf ("ARC7xx\n");
16736 break;
16737 case TAG_CPU_ARCEM:
16738 printf ("ARCEM\n");
16739 break;
16740 case TAG_CPU_ARCHS:
16741 printf ("ARCHS\n");
16742 break;
16743 }
16744 break;
16745
16746 case Tag_ARC_CPU_variation:
cd30bcef 16747 READ_ULEB (val, p, end);
53a346d8
CZ
16748 printf (" Tag_ARC_CPU_variation: ");
16749 switch (val)
16750 {
16751 default:
16752 if (val > 0 && val < 16)
53a346d8 16753 printf ("Core%d\n", val);
d8cbc93b
JL
16754 else
16755 printf ("Unknown\n");
16756 break;
16757
53a346d8
CZ
16758 case 0:
16759 printf (_("Absent\n"));
16760 break;
16761 }
16762 break;
16763
16764 case Tag_ARC_CPU_name:
16765 printf (" Tag_ARC_CPU_name: ");
16766 p = display_tag_value (-1, p, end);
16767 break;
16768
16769 case Tag_ARC_ABI_rf16:
cd30bcef 16770 READ_ULEB (val, p, end);
53a346d8
CZ
16771 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16772 break;
16773
16774 case Tag_ARC_ABI_osver:
cd30bcef 16775 READ_ULEB (val, p, end);
53a346d8
CZ
16776 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16777 break;
16778
16779 case Tag_ARC_ABI_pic:
16780 case Tag_ARC_ABI_sda:
cd30bcef 16781 READ_ULEB (val, p, end);
53a346d8
CZ
16782 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16783 : " Tag_ARC_ABI_pic: ");
16784 switch (val)
16785 {
16786 case 0:
16787 printf (_("Absent\n"));
16788 break;
16789 case 1:
16790 printf ("MWDT\n");
16791 break;
16792 case 2:
16793 printf ("GNU\n");
16794 break;
16795 default:
16796 printf (_("Unknown\n"));
16797 break;
16798 }
16799 break;
16800
16801 case Tag_ARC_ABI_tls:
cd30bcef 16802 READ_ULEB (val, p, end);
53a346d8
CZ
16803 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16804 break;
16805
16806 case Tag_ARC_ABI_enumsize:
cd30bcef 16807 READ_ULEB (val, p, end);
53a346d8
CZ
16808 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16809 _("smallest"));
16810 break;
16811
16812 case Tag_ARC_ABI_exceptions:
cd30bcef 16813 READ_ULEB (val, p, end);
53a346d8
CZ
16814 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16815 : _("default"));
16816 break;
16817
16818 case Tag_ARC_ABI_double_size:
cd30bcef 16819 READ_ULEB (val, p, end);
53a346d8
CZ
16820 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16821 break;
16822
16823 case Tag_ARC_ISA_config:
16824 printf (" Tag_ARC_ISA_config: ");
16825 p = display_tag_value (-1, p, end);
16826 break;
16827
16828 case Tag_ARC_ISA_apex:
16829 printf (" Tag_ARC_ISA_apex: ");
16830 p = display_tag_value (-1, p, end);
16831 break;
16832
16833 case Tag_ARC_ISA_mpy_option:
cd30bcef 16834 READ_ULEB (val, p, end);
53a346d8
CZ
16835 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16836 break;
16837
db1e1b45 16838 case Tag_ARC_ATR_version:
cd30bcef 16839 READ_ULEB (val, p, end);
db1e1b45 16840 printf (" Tag_ARC_ATR_version: %d\n", val);
16841 break;
16842
53a346d8
CZ
16843 default:
16844 return display_tag_value (tag & 1, p, end);
16845 }
16846
16847 return p;
16848}
16849
11c1ff18
PB
16850/* ARM EABI attributes section. */
16851typedef struct
16852{
70e99720 16853 unsigned int tag;
2cf0635d 16854 const char * name;
11c1ff18 16855 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16856 unsigned int type;
288f0ba2 16857 const char *const *table;
11c1ff18
PB
16858} arm_attr_public_tag;
16859
288f0ba2 16860static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16861 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16862 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16863 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16864 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16865static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16866static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16867 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16868static const char *const arm_attr_tag_FP_arch[] =
bca38921 16869 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16870 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16871static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16872static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16873 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16874 "NEON for ARMv8.1"};
288f0ba2 16875static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16876 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16877 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16878static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16879 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16880static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16881 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16882static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16883 {"Absolute", "PC-relative", "None"};
288f0ba2 16884static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16885 {"None", "direct", "GOT-indirect"};
288f0ba2 16886static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16887 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16888static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16889static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16890 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16891static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16892static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16893static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16894 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16895static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16896 {"Unused", "small", "int", "forced to int"};
288f0ba2 16897static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16898 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16899static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16900 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16901static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16902 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16903static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16904 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16905 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16906static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16907 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16908 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16909static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16910static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16911 {"Not Allowed", "Allowed"};
288f0ba2 16912static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16913 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16914static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16915 {"Follow architecture", "Allowed"};
288f0ba2 16916static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16917 {"Not Allowed", "Allowed"};
288f0ba2 16918static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16919 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16920 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16921static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16922static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16923 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16924 "TrustZone and Virtualization Extensions"};
288f0ba2 16925static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16926 {"Not Allowed", "Allowed"};
11c1ff18 16927
288f0ba2 16928static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16929 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16930
99db83d0
AC
16931static const char * arm_attr_tag_PAC_extension[] =
16932 {"No PAC/AUT instructions",
16933 "PAC/AUT instructions permitted in the NOP space",
16934 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16935
4b535030
AC
16936static const char * arm_attr_tag_BTI_extension[] =
16937 {"BTI instructions not permitted",
16938 "BTI instructions permitted in the NOP space",
16939 "BTI instructions permitted in the NOP and in the non-NOP space"};
16940
b81ee92f
AC
16941static const char * arm_attr_tag_BTI_use[] =
16942 {"Compiled without branch target enforcement",
16943 "Compiled with branch target enforcement"};
16944
c9fed665
AC
16945static const char * arm_attr_tag_PACRET_use[] =
16946 {"Compiled without return address signing and authentication",
16947 "Compiled with return address signing and authentication"};
16948
11c1ff18
PB
16949#define LOOKUP(id, name) \
16950 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16951static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16952{
16953 {4, "CPU_raw_name", 1, NULL},
16954 {5, "CPU_name", 1, NULL},
16955 LOOKUP(6, CPU_arch),
16956 {7, "CPU_arch_profile", 0, NULL},
16957 LOOKUP(8, ARM_ISA_use),
16958 LOOKUP(9, THUMB_ISA_use),
75375b3e 16959 LOOKUP(10, FP_arch),
11c1ff18 16960 LOOKUP(11, WMMX_arch),
f5f53991
AS
16961 LOOKUP(12, Advanced_SIMD_arch),
16962 LOOKUP(13, PCS_config),
11c1ff18
PB
16963 LOOKUP(14, ABI_PCS_R9_use),
16964 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16965 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16966 LOOKUP(17, ABI_PCS_GOT_use),
16967 LOOKUP(18, ABI_PCS_wchar_t),
16968 LOOKUP(19, ABI_FP_rounding),
16969 LOOKUP(20, ABI_FP_denormal),
16970 LOOKUP(21, ABI_FP_exceptions),
16971 LOOKUP(22, ABI_FP_user_exceptions),
16972 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16973 {24, "ABI_align_needed", 0, NULL},
16974 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16975 LOOKUP(26, ABI_enum_size),
16976 LOOKUP(27, ABI_HardFP_use),
16977 LOOKUP(28, ABI_VFP_args),
16978 LOOKUP(29, ABI_WMMX_args),
16979 LOOKUP(30, ABI_optimization_goals),
16980 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16981 {32, "compatibility", 0, NULL},
f5f53991 16982 LOOKUP(34, CPU_unaligned_access),
75375b3e 16983 LOOKUP(36, FP_HP_extension),
8e79c3df 16984 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16985 LOOKUP(42, MPextension_use),
16986 LOOKUP(44, DIV_use),
15afaa63 16987 LOOKUP(46, DSP_extension),
a7ad558c 16988 LOOKUP(48, MVE_arch),
99db83d0 16989 LOOKUP(50, PAC_extension),
4b535030 16990 LOOKUP(52, BTI_extension),
b81ee92f 16991 LOOKUP(74, BTI_use),
c9fed665 16992 LOOKUP(76, PACRET_use),
f5f53991
AS
16993 {64, "nodefaults", 0, NULL},
16994 {65, "also_compatible_with", 0, NULL},
16995 LOOKUP(66, T2EE_use),
16996 {67, "conformance", 1, NULL},
16997 LOOKUP(68, Virtualization_use),
cd21e546 16998 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16999};
17000#undef LOOKUP
17001
11c1ff18 17002static unsigned char *
f6f0e17b
NC
17003display_arm_attribute (unsigned char * p,
17004 const unsigned char * const end)
11c1ff18 17005{
70e99720 17006 unsigned int tag;
70e99720 17007 unsigned int val;
2cf0635d 17008 arm_attr_public_tag * attr;
11c1ff18 17009 unsigned i;
70e99720 17010 unsigned int type;
11c1ff18 17011
cd30bcef 17012 READ_ULEB (tag, p, end);
11c1ff18 17013 attr = NULL;
2cf0635d 17014 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
17015 {
17016 if (arm_attr_public_tags[i].tag == tag)
17017 {
17018 attr = &arm_attr_public_tags[i];
17019 break;
17020 }
17021 }
17022
17023 if (attr)
17024 {
17025 printf (" Tag_%s: ", attr->name);
17026 switch (attr->type)
17027 {
17028 case 0:
17029 switch (tag)
17030 {
17031 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 17032 READ_ULEB (val, p, end);
11c1ff18
PB
17033 switch (val)
17034 {
2b692964
NC
17035 case 0: printf (_("None\n")); break;
17036 case 'A': printf (_("Application\n")); break;
17037 case 'R': printf (_("Realtime\n")); break;
17038 case 'M': printf (_("Microcontroller\n")); break;
17039 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
17040 default: printf ("??? (%d)\n", val); break;
17041 }
17042 break;
17043
75375b3e 17044 case 24: /* Tag_align_needed. */
cd30bcef 17045 READ_ULEB (val, p, end);
75375b3e
MGD
17046 switch (val)
17047 {
2b692964
NC
17048 case 0: printf (_("None\n")); break;
17049 case 1: printf (_("8-byte\n")); break;
17050 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
17051 case 3: printf ("??? 3\n"); break;
17052 default:
17053 if (val <= 12)
dd24e3da 17054 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17055 1 << val);
17056 else
17057 printf ("??? (%d)\n", val);
17058 break;
17059 }
17060 break;
17061
17062 case 25: /* Tag_align_preserved. */
cd30bcef 17063 READ_ULEB (val, p, end);
75375b3e
MGD
17064 switch (val)
17065 {
2b692964
NC
17066 case 0: printf (_("None\n")); break;
17067 case 1: printf (_("8-byte, except leaf SP\n")); break;
17068 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
17069 case 3: printf ("??? 3\n"); break;
17070 default:
17071 if (val <= 12)
dd24e3da 17072 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17073 1 << val);
17074 else
17075 printf ("??? (%d)\n", val);
17076 break;
17077 }
17078 break;
17079
11c1ff18 17080 case 32: /* Tag_compatibility. */
071436c6 17081 {
cd30bcef 17082 READ_ULEB (val, p, end);
071436c6 17083 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17084 if (p < end - 1)
17085 {
17086 size_t maxlen = (end - p) - 1;
17087
17088 print_symbol ((int) maxlen, (const char *) p);
17089 p += strnlen ((char *) p, maxlen) + 1;
17090 }
17091 else
17092 {
17093 printf (_("<corrupt>"));
17094 p = (unsigned char *) end;
17095 }
071436c6 17096 putchar ('\n');
071436c6 17097 }
11c1ff18
PB
17098 break;
17099
f5f53991 17100 case 64: /* Tag_nodefaults. */
541a3cbd
NC
17101 /* PR 17531: file: 001-505008-0.01. */
17102 if (p < end)
17103 p++;
2b692964 17104 printf (_("True\n"));
f5f53991
AS
17105 break;
17106
17107 case 65: /* Tag_also_compatible_with. */
cd30bcef 17108 READ_ULEB (val, p, end);
f5f53991
AS
17109 if (val == 6 /* Tag_CPU_arch. */)
17110 {
cd30bcef 17111 READ_ULEB (val, p, end);
071436c6 17112 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
17113 printf ("??? (%d)\n", val);
17114 else
17115 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17116 }
17117 else
17118 printf ("???\n");
071436c6
NC
17119 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17120 ;
f5f53991
AS
17121 break;
17122
11c1ff18 17123 default:
bee0ee85
NC
17124 printf (_("<unknown: %d>\n"), tag);
17125 break;
11c1ff18
PB
17126 }
17127 return p;
17128
17129 case 1:
f6f0e17b 17130 return display_tag_value (-1, p, end);
11c1ff18 17131 case 2:
f6f0e17b 17132 return display_tag_value (0, p, end);
11c1ff18
PB
17133
17134 default:
17135 assert (attr->type & 0x80);
cd30bcef 17136 READ_ULEB (val, p, end);
11c1ff18
PB
17137 type = attr->type & 0x7f;
17138 if (val >= type)
17139 printf ("??? (%d)\n", val);
17140 else
17141 printf ("%s\n", attr->table[val]);
17142 return p;
17143 }
17144 }
11c1ff18 17145
f6f0e17b 17146 return display_tag_value (tag, p, end);
11c1ff18
PB
17147}
17148
104d59d1 17149static unsigned char *
60bca95a 17150display_gnu_attribute (unsigned char * p,
60abdbed 17151 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 17152 const unsigned char * const end)
104d59d1 17153{
cd30bcef 17154 unsigned int tag;
60abdbed 17155 unsigned int val;
104d59d1 17156
cd30bcef 17157 READ_ULEB (tag, p, end);
104d59d1
JM
17158
17159 /* Tag_compatibility is the only generic GNU attribute defined at
17160 present. */
17161 if (tag == 32)
17162 {
cd30bcef 17163 READ_ULEB (val, p, end);
071436c6
NC
17164
17165 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
17166 if (p == end)
17167 {
071436c6 17168 printf (_("<corrupt>\n"));
f6f0e17b
NC
17169 warn (_("corrupt vendor attribute\n"));
17170 }
17171 else
17172 {
4082ef84
NC
17173 if (p < end - 1)
17174 {
17175 size_t maxlen = (end - p) - 1;
071436c6 17176
4082ef84
NC
17177 print_symbol ((int) maxlen, (const char *) p);
17178 p += strnlen ((char *) p, maxlen) + 1;
17179 }
17180 else
17181 {
17182 printf (_("<corrupt>"));
17183 p = (unsigned char *) end;
17184 }
071436c6 17185 putchar ('\n');
f6f0e17b 17186 }
104d59d1
JM
17187 return p;
17188 }
17189
17190 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 17191 return display_proc_gnu_attribute (p, tag, end);
104d59d1 17192
f6f0e17b 17193 return display_tag_value (tag, p, end);
104d59d1
JM
17194}
17195
85f7484a
PB
17196static unsigned char *
17197display_m68k_gnu_attribute (unsigned char * p,
17198 unsigned int tag,
17199 const unsigned char * const end)
17200{
17201 unsigned int val;
17202
17203 if (tag == Tag_GNU_M68K_ABI_FP)
17204 {
17205 printf (" Tag_GNU_M68K_ABI_FP: ");
17206 if (p == end)
17207 {
17208 printf (_("<corrupt>\n"));
17209 return p;
17210 }
17211 READ_ULEB (val, p, end);
17212
17213 if (val > 3)
17214 printf ("(%#x), ", val);
17215
17216 switch (val & 3)
17217 {
17218 case 0:
17219 printf (_("unspecified hard/soft float\n"));
17220 break;
17221 case 1:
17222 printf (_("hard float\n"));
17223 break;
17224 case 2:
17225 printf (_("soft float\n"));
17226 break;
17227 }
17228 return p;
17229 }
17230
17231 return display_tag_value (tag & 1, p, end);
17232}
17233
34c8bcba 17234static unsigned char *
f6f0e17b 17235display_power_gnu_attribute (unsigned char * p,
60abdbed 17236 unsigned int tag,
f6f0e17b 17237 const unsigned char * const end)
34c8bcba 17238{
005d79fd 17239 unsigned int val;
34c8bcba
JM
17240
17241 if (tag == Tag_GNU_Power_ABI_FP)
17242 {
34c8bcba 17243 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 17244 if (p == end)
005d79fd
AM
17245 {
17246 printf (_("<corrupt>\n"));
17247 return p;
17248 }
cd30bcef 17249 READ_ULEB (val, p, end);
60bca95a 17250
005d79fd
AM
17251 if (val > 15)
17252 printf ("(%#x), ", val);
17253
17254 switch (val & 3)
34c8bcba
JM
17255 {
17256 case 0:
005d79fd 17257 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17258 break;
17259 case 1:
005d79fd 17260 printf (_("hard float, "));
34c8bcba
JM
17261 break;
17262 case 2:
005d79fd 17263 printf (_("soft float, "));
34c8bcba 17264 break;
3c7b9897 17265 case 3:
005d79fd 17266 printf (_("single-precision hard float, "));
3c7b9897 17267 break;
005d79fd
AM
17268 }
17269
17270 switch (val & 0xC)
17271 {
17272 case 0:
17273 printf (_("unspecified long double\n"));
17274 break;
17275 case 4:
17276 printf (_("128-bit IBM long double\n"));
17277 break;
17278 case 8:
17279 printf (_("64-bit long double\n"));
17280 break;
17281 case 12:
17282 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17283 break;
17284 }
17285 return p;
005d79fd 17286 }
34c8bcba 17287
c6e65352
DJ
17288 if (tag == Tag_GNU_Power_ABI_Vector)
17289 {
c6e65352 17290 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17291 if (p == end)
005d79fd
AM
17292 {
17293 printf (_("<corrupt>\n"));
17294 return p;
17295 }
cd30bcef 17296 READ_ULEB (val, p, end);
005d79fd
AM
17297
17298 if (val > 3)
17299 printf ("(%#x), ", val);
17300
17301 switch (val & 3)
c6e65352
DJ
17302 {
17303 case 0:
005d79fd 17304 printf (_("unspecified\n"));
c6e65352
DJ
17305 break;
17306 case 1:
005d79fd 17307 printf (_("generic\n"));
c6e65352
DJ
17308 break;
17309 case 2:
17310 printf ("AltiVec\n");
17311 break;
17312 case 3:
17313 printf ("SPE\n");
17314 break;
c6e65352
DJ
17315 }
17316 return p;
005d79fd 17317 }
c6e65352 17318
f82e0623
NF
17319 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17320 {
005d79fd 17321 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17322 if (p == end)
f6f0e17b 17323 {
005d79fd 17324 printf (_("<corrupt>\n"));
f6f0e17b
NC
17325 return p;
17326 }
cd30bcef 17327 READ_ULEB (val, p, end);
0b4362b0 17328
005d79fd
AM
17329 if (val > 2)
17330 printf ("(%#x), ", val);
17331
17332 switch (val & 3)
17333 {
17334 case 0:
17335 printf (_("unspecified\n"));
17336 break;
17337 case 1:
17338 printf ("r3/r4\n");
17339 break;
17340 case 2:
17341 printf (_("memory\n"));
17342 break;
17343 case 3:
17344 printf ("???\n");
17345 break;
17346 }
f82e0623
NF
17347 return p;
17348 }
17349
f6f0e17b 17350 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17351}
17352
643f7afb
AK
17353static unsigned char *
17354display_s390_gnu_attribute (unsigned char * p,
60abdbed 17355 unsigned int tag,
643f7afb
AK
17356 const unsigned char * const end)
17357{
cd30bcef 17358 unsigned int val;
643f7afb
AK
17359
17360 if (tag == Tag_GNU_S390_ABI_Vector)
17361 {
643f7afb 17362 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17363 READ_ULEB (val, p, end);
643f7afb
AK
17364
17365 switch (val)
17366 {
17367 case 0:
17368 printf (_("any\n"));
17369 break;
17370 case 1:
17371 printf (_("software\n"));
17372 break;
17373 case 2:
17374 printf (_("hardware\n"));
17375 break;
17376 default:
17377 printf ("??? (%d)\n", val);
17378 break;
17379 }
17380 return p;
17381 }
17382
17383 return display_tag_value (tag & 1, p, end);
17384}
17385
9e8c70f9 17386static void
60abdbed 17387display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17388{
17389 if (mask)
17390 {
015dc7e1 17391 bool first = true;
071436c6 17392
9e8c70f9 17393 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17394 fputs ("mul32", stdout), first = false;
9e8c70f9 17395 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17396 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17397 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17398 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17399 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17400 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17401 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17402 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17403 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17404 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17405 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17406 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17407 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17408 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17409 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17410 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17411 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17412 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17413 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17414 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17415 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17416 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17417 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17418 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17419 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17420 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17421 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17422 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17423 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17424 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17425 }
17426 else
071436c6
NC
17427 fputc ('0', stdout);
17428 fputc ('\n', stdout);
9e8c70f9
DM
17429}
17430
3d68f91c 17431static void
60abdbed 17432display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17433{
17434 if (mask)
17435 {
015dc7e1 17436 bool first = true;
071436c6 17437
3d68f91c 17438 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17439 fputs ("fjathplus", stdout), first = false;
3d68f91c 17440 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17441 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17442 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17443 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17444 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17445 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17446 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17447 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17448 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17449 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17450 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17451 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17452 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17453 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17454 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17455 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17456 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17457 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17458 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17459 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17460 }
17461 else
071436c6
NC
17462 fputc ('0', stdout);
17463 fputc ('\n', stdout);
3d68f91c
JM
17464}
17465
9e8c70f9 17466static unsigned char *
f6f0e17b 17467display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17468 unsigned int tag,
f6f0e17b 17469 const unsigned char * const end)
9e8c70f9 17470{
cd30bcef 17471 unsigned int val;
3d68f91c 17472
9e8c70f9
DM
17473 if (tag == Tag_GNU_Sparc_HWCAPS)
17474 {
cd30bcef 17475 READ_ULEB (val, p, end);
9e8c70f9 17476 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17477 display_sparc_hwcaps (val);
17478 return p;
3d68f91c
JM
17479 }
17480 if (tag == Tag_GNU_Sparc_HWCAPS2)
17481 {
cd30bcef 17482 READ_ULEB (val, p, end);
3d68f91c
JM
17483 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17484 display_sparc_hwcaps2 (val);
17485 return p;
17486 }
9e8c70f9 17487
f6f0e17b 17488 return display_tag_value (tag, p, end);
9e8c70f9
DM
17489}
17490
351cdf24 17491static void
32ec8896 17492print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17493{
17494 switch (val)
17495 {
17496 case Val_GNU_MIPS_ABI_FP_ANY:
17497 printf (_("Hard or soft float\n"));
17498 break;
17499 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17500 printf (_("Hard float (double precision)\n"));
17501 break;
17502 case Val_GNU_MIPS_ABI_FP_SINGLE:
17503 printf (_("Hard float (single precision)\n"));
17504 break;
17505 case Val_GNU_MIPS_ABI_FP_SOFT:
17506 printf (_("Soft float\n"));
17507 break;
17508 case Val_GNU_MIPS_ABI_FP_OLD_64:
17509 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17510 break;
17511 case Val_GNU_MIPS_ABI_FP_XX:
17512 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17513 break;
17514 case Val_GNU_MIPS_ABI_FP_64:
17515 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17516 break;
17517 case Val_GNU_MIPS_ABI_FP_64A:
17518 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17519 break;
3350cc01
CM
17520 case Val_GNU_MIPS_ABI_FP_NAN2008:
17521 printf (_("NaN 2008 compatibility\n"));
17522 break;
351cdf24
MF
17523 default:
17524 printf ("??? (%d)\n", val);
17525 break;
17526 }
17527}
17528
2cf19d5c 17529static unsigned char *
f6f0e17b 17530display_mips_gnu_attribute (unsigned char * p,
60abdbed 17531 unsigned int tag,
f6f0e17b 17532 const unsigned char * const end)
2cf19d5c 17533{
2cf19d5c
JM
17534 if (tag == Tag_GNU_MIPS_ABI_FP)
17535 {
32ec8896 17536 unsigned int val;
f6f0e17b 17537
2cf19d5c 17538 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17539 READ_ULEB (val, p, end);
351cdf24 17540 print_mips_fp_abi_value (val);
2cf19d5c
JM
17541 return p;
17542 }
17543
a9f58168
CF
17544 if (tag == Tag_GNU_MIPS_ABI_MSA)
17545 {
32ec8896 17546 unsigned int val;
a9f58168 17547
a9f58168 17548 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17549 READ_ULEB (val, p, end);
a9f58168
CF
17550
17551 switch (val)
17552 {
17553 case Val_GNU_MIPS_ABI_MSA_ANY:
17554 printf (_("Any MSA or not\n"));
17555 break;
17556 case Val_GNU_MIPS_ABI_MSA_128:
17557 printf (_("128-bit MSA\n"));
17558 break;
17559 default:
17560 printf ("??? (%d)\n", val);
17561 break;
17562 }
17563 return p;
17564 }
17565
f6f0e17b 17566 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17567}
17568
59e6276b 17569static unsigned char *
f6f0e17b
NC
17570display_tic6x_attribute (unsigned char * p,
17571 const unsigned char * const end)
59e6276b 17572{
60abdbed 17573 unsigned int tag;
cd30bcef 17574 unsigned int val;
59e6276b 17575
cd30bcef 17576 READ_ULEB (tag, p, end);
59e6276b
JM
17577
17578 switch (tag)
17579 {
75fa6dc1 17580 case Tag_ISA:
75fa6dc1 17581 printf (" Tag_ISA: ");
cd30bcef 17582 READ_ULEB (val, p, end);
59e6276b
JM
17583
17584 switch (val)
17585 {
75fa6dc1 17586 case C6XABI_Tag_ISA_none:
59e6276b
JM
17587 printf (_("None\n"));
17588 break;
75fa6dc1 17589 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17590 printf ("C62x\n");
17591 break;
75fa6dc1 17592 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17593 printf ("C67x\n");
17594 break;
75fa6dc1 17595 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17596 printf ("C67x+\n");
17597 break;
75fa6dc1 17598 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17599 printf ("C64x\n");
17600 break;
75fa6dc1 17601 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17602 printf ("C64x+\n");
17603 break;
75fa6dc1 17604 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17605 printf ("C674x\n");
17606 break;
17607 default:
17608 printf ("??? (%d)\n", val);
17609 break;
17610 }
17611 return p;
17612
87779176 17613 case Tag_ABI_wchar_t:
87779176 17614 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17615 READ_ULEB (val, p, end);
87779176
JM
17616 switch (val)
17617 {
17618 case 0:
17619 printf (_("Not used\n"));
17620 break;
17621 case 1:
17622 printf (_("2 bytes\n"));
17623 break;
17624 case 2:
17625 printf (_("4 bytes\n"));
17626 break;
17627 default:
17628 printf ("??? (%d)\n", val);
17629 break;
17630 }
17631 return p;
17632
17633 case Tag_ABI_stack_align_needed:
87779176 17634 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17635 READ_ULEB (val, p, end);
87779176
JM
17636 switch (val)
17637 {
17638 case 0:
17639 printf (_("8-byte\n"));
17640 break;
17641 case 1:
17642 printf (_("16-byte\n"));
17643 break;
17644 default:
17645 printf ("??? (%d)\n", val);
17646 break;
17647 }
17648 return p;
17649
17650 case Tag_ABI_stack_align_preserved:
cd30bcef 17651 READ_ULEB (val, p, end);
87779176
JM
17652 printf (" Tag_ABI_stack_align_preserved: ");
17653 switch (val)
17654 {
17655 case 0:
17656 printf (_("8-byte\n"));
17657 break;
17658 case 1:
17659 printf (_("16-byte\n"));
17660 break;
17661 default:
17662 printf ("??? (%d)\n", val);
17663 break;
17664 }
17665 return p;
17666
b5593623 17667 case Tag_ABI_DSBT:
cd30bcef 17668 READ_ULEB (val, p, end);
b5593623
JM
17669 printf (" Tag_ABI_DSBT: ");
17670 switch (val)
17671 {
17672 case 0:
17673 printf (_("DSBT addressing not used\n"));
17674 break;
17675 case 1:
17676 printf (_("DSBT addressing used\n"));
17677 break;
17678 default:
17679 printf ("??? (%d)\n", val);
17680 break;
17681 }
17682 return p;
17683
87779176 17684 case Tag_ABI_PID:
cd30bcef 17685 READ_ULEB (val, p, end);
87779176
JM
17686 printf (" Tag_ABI_PID: ");
17687 switch (val)
17688 {
17689 case 0:
17690 printf (_("Data addressing position-dependent\n"));
17691 break;
17692 case 1:
17693 printf (_("Data addressing position-independent, GOT near DP\n"));
17694 break;
17695 case 2:
17696 printf (_("Data addressing position-independent, GOT far from DP\n"));
17697 break;
17698 default:
17699 printf ("??? (%d)\n", val);
17700 break;
17701 }
17702 return p;
17703
17704 case Tag_ABI_PIC:
cd30bcef 17705 READ_ULEB (val, p, end);
87779176
JM
17706 printf (" Tag_ABI_PIC: ");
17707 switch (val)
17708 {
17709 case 0:
17710 printf (_("Code addressing position-dependent\n"));
17711 break;
17712 case 1:
17713 printf (_("Code addressing position-independent\n"));
17714 break;
17715 default:
17716 printf ("??? (%d)\n", val);
17717 break;
17718 }
17719 return p;
17720
17721 case Tag_ABI_array_object_alignment:
cd30bcef 17722 READ_ULEB (val, p, end);
87779176
JM
17723 printf (" Tag_ABI_array_object_alignment: ");
17724 switch (val)
17725 {
17726 case 0:
17727 printf (_("8-byte\n"));
17728 break;
17729 case 1:
17730 printf (_("4-byte\n"));
17731 break;
17732 case 2:
17733 printf (_("16-byte\n"));
17734 break;
17735 default:
17736 printf ("??? (%d)\n", val);
17737 break;
17738 }
17739 return p;
17740
17741 case Tag_ABI_array_object_align_expected:
cd30bcef 17742 READ_ULEB (val, p, end);
87779176
JM
17743 printf (" Tag_ABI_array_object_align_expected: ");
17744 switch (val)
17745 {
17746 case 0:
17747 printf (_("8-byte\n"));
17748 break;
17749 case 1:
17750 printf (_("4-byte\n"));
17751 break;
17752 case 2:
17753 printf (_("16-byte\n"));
17754 break;
17755 default:
17756 printf ("??? (%d)\n", val);
17757 break;
17758 }
17759 return p;
17760
3cbd1c06 17761 case Tag_ABI_compatibility:
071436c6 17762 {
cd30bcef 17763 READ_ULEB (val, p, end);
071436c6 17764 printf (" Tag_ABI_compatibility: ");
071436c6 17765 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17766 if (p < end - 1)
17767 {
17768 size_t maxlen = (end - p) - 1;
17769
17770 print_symbol ((int) maxlen, (const char *) p);
17771 p += strnlen ((char *) p, maxlen) + 1;
17772 }
17773 else
17774 {
17775 printf (_("<corrupt>"));
17776 p = (unsigned char *) end;
17777 }
071436c6 17778 putchar ('\n');
071436c6
NC
17779 return p;
17780 }
87779176
JM
17781
17782 case Tag_ABI_conformance:
071436c6 17783 {
4082ef84
NC
17784 printf (" Tag_ABI_conformance: \"");
17785 if (p < end - 1)
17786 {
17787 size_t maxlen = (end - p) - 1;
071436c6 17788
4082ef84
NC
17789 print_symbol ((int) maxlen, (const char *) p);
17790 p += strnlen ((char *) p, maxlen) + 1;
17791 }
17792 else
17793 {
17794 printf (_("<corrupt>"));
17795 p = (unsigned char *) end;
17796 }
071436c6 17797 printf ("\"\n");
071436c6
NC
17798 return p;
17799 }
59e6276b
JM
17800 }
17801
f6f0e17b
NC
17802 return display_tag_value (tag, p, end);
17803}
59e6276b 17804
f6f0e17b 17805static void
60abdbed 17806display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 17807{
26c527e6 17808 uint64_t addr = 0;
f6f0e17b
NC
17809 size_t bytes = end - p;
17810
feceaa59 17811 assert (end >= p);
f6f0e17b 17812 while (bytes)
87779176 17813 {
f6f0e17b
NC
17814 int j;
17815 int k;
17816 int lbytes = (bytes > 16 ? 16 : bytes);
17817
26c527e6 17818 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
17819
17820 for (j = 0; j < 16; j++)
17821 {
17822 if (j < lbytes)
17823 printf ("%2.2x", p[j]);
17824 else
17825 printf (" ");
17826
17827 if ((j & 3) == 3)
17828 printf (" ");
17829 }
17830
17831 for (j = 0; j < lbytes; j++)
17832 {
17833 k = p[j];
17834 if (k >= ' ' && k < 0x7f)
17835 printf ("%c", k);
17836 else
17837 printf (".");
17838 }
17839
17840 putchar ('\n');
17841
17842 p += lbytes;
17843 bytes -= lbytes;
17844 addr += lbytes;
87779176 17845 }
59e6276b 17846
f6f0e17b 17847 putchar ('\n');
59e6276b
JM
17848}
17849
13761a11 17850static unsigned char *
b0191216 17851display_msp430_attribute (unsigned char * p,
26c527e6 17852 const unsigned char * const end)
13761a11 17853{
26c527e6
AM
17854 uint64_t val;
17855 uint64_t tag;
13761a11 17856
cd30bcef 17857 READ_ULEB (tag, p, end);
0b4362b0 17858
13761a11
NC
17859 switch (tag)
17860 {
17861 case OFBA_MSPABI_Tag_ISA:
13761a11 17862 printf (" Tag_ISA: ");
cd30bcef 17863 READ_ULEB (val, p, end);
13761a11
NC
17864 switch (val)
17865 {
17866 case 0: printf (_("None\n")); break;
17867 case 1: printf (_("MSP430\n")); break;
17868 case 2: printf (_("MSP430X\n")); break;
26c527e6 17869 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17870 }
17871 break;
17872
17873 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17874 printf (" Tag_Code_Model: ");
cd30bcef 17875 READ_ULEB (val, p, end);
13761a11
NC
17876 switch (val)
17877 {
17878 case 0: printf (_("None\n")); break;
17879 case 1: printf (_("Small\n")); break;
17880 case 2: printf (_("Large\n")); break;
26c527e6 17881 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17882 }
17883 break;
17884
17885 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17886 printf (" Tag_Data_Model: ");
cd30bcef 17887 READ_ULEB (val, p, end);
13761a11
NC
17888 switch (val)
17889 {
17890 case 0: printf (_("None\n")); break;
17891 case 1: printf (_("Small\n")); break;
17892 case 2: printf (_("Large\n")); break;
17893 case 3: printf (_("Restricted Large\n")); break;
26c527e6 17894 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17895 }
17896 break;
17897
17898 default:
26c527e6 17899 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
17900
17901 if (tag & 1)
17902 {
071436c6 17903 putchar ('"');
4082ef84
NC
17904 if (p < end - 1)
17905 {
17906 size_t maxlen = (end - p) - 1;
17907
17908 print_symbol ((int) maxlen, (const char *) p);
17909 p += strnlen ((char *) p, maxlen) + 1;
17910 }
17911 else
17912 {
17913 printf (_("<corrupt>"));
17914 p = (unsigned char *) end;
17915 }
071436c6 17916 printf ("\"\n");
13761a11
NC
17917 }
17918 else
17919 {
cd30bcef 17920 READ_ULEB (val, p, end);
26c527e6 17921 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
17922 }
17923 break;
17924 }
17925
4082ef84 17926 assert (p <= end);
13761a11
NC
17927 return p;
17928}
17929
c0ea7c52
JL
17930static unsigned char *
17931display_msp430_gnu_attribute (unsigned char * p,
17932 unsigned int tag,
17933 const unsigned char * const end)
17934{
17935 if (tag == Tag_GNU_MSP430_Data_Region)
17936 {
26c527e6 17937 uint64_t val;
c0ea7c52 17938
c0ea7c52 17939 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17940 READ_ULEB (val, p, end);
c0ea7c52
JL
17941
17942 switch (val)
17943 {
17944 case Val_GNU_MSP430_Data_Region_Any:
17945 printf (_("Any Region\n"));
17946 break;
17947 case Val_GNU_MSP430_Data_Region_Lower:
17948 printf (_("Lower Region Only\n"));
17949 break;
17950 default:
26c527e6 17951 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
17952 }
17953 return p;
17954 }
17955 return display_tag_value (tag & 1, p, end);
17956}
17957
2dc8dd17
JW
17958struct riscv_attr_tag_t {
17959 const char *name;
cd30bcef 17960 unsigned int tag;
2dc8dd17
JW
17961};
17962
17963static struct riscv_attr_tag_t riscv_attr_tag[] =
17964{
17965#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17966 T(arch),
17967 T(priv_spec),
17968 T(priv_spec_minor),
17969 T(priv_spec_revision),
17970 T(unaligned_access),
17971 T(stack_align),
17972#undef T
17973};
17974
17975static unsigned char *
17976display_riscv_attribute (unsigned char *p,
17977 const unsigned char * const end)
17978{
26c527e6
AM
17979 uint64_t val;
17980 uint64_t tag;
2dc8dd17
JW
17981 struct riscv_attr_tag_t *attr = NULL;
17982 unsigned i;
17983
cd30bcef 17984 READ_ULEB (tag, p, end);
2dc8dd17
JW
17985
17986 /* Find the name of attribute. */
17987 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17988 {
17989 if (riscv_attr_tag[i].tag == tag)
17990 {
17991 attr = &riscv_attr_tag[i];
17992 break;
17993 }
17994 }
17995
17996 if (attr)
17997 printf (" %s: ", attr->name);
17998 else
17999 return display_tag_value (tag, p, end);
18000
18001 switch (tag)
18002 {
18003 case Tag_RISCV_priv_spec:
18004 case Tag_RISCV_priv_spec_minor:
18005 case Tag_RISCV_priv_spec_revision:
cd30bcef 18006 READ_ULEB (val, p, end);
26c527e6 18007 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
18008 break;
18009 case Tag_RISCV_unaligned_access:
cd30bcef 18010 READ_ULEB (val, p, end);
2dc8dd17
JW
18011 switch (val)
18012 {
18013 case 0:
18014 printf (_("No unaligned access\n"));
18015 break;
18016 case 1:
18017 printf (_("Unaligned access\n"));
18018 break;
18019 }
18020 break;
18021 case Tag_RISCV_stack_align:
cd30bcef 18022 READ_ULEB (val, p, end);
26c527e6 18023 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
18024 break;
18025 case Tag_RISCV_arch:
18026 p = display_tag_value (-1, p, end);
18027 break;
18028 default:
18029 return display_tag_value (tag, p, end);
18030 }
18031
18032 return p;
18033}
18034
0861f561
CQ
18035static unsigned char *
18036display_csky_attribute (unsigned char * p,
18037 const unsigned char * const end)
18038{
26c527e6
AM
18039 uint64_t tag;
18040 uint64_t val;
0861f561
CQ
18041 READ_ULEB (tag, p, end);
18042
18043 if (tag >= Tag_CSKY_MAX)
18044 {
18045 return display_tag_value (-1, p, end);
18046 }
18047
18048 switch (tag)
18049 {
18050 case Tag_CSKY_ARCH_NAME:
18051 printf (" Tag_CSKY_ARCH_NAME:\t\t");
18052 return display_tag_value (-1, p, end);
18053 case Tag_CSKY_CPU_NAME:
18054 printf (" Tag_CSKY_CPU_NAME:\t\t");
18055 return display_tag_value (-1, p, end);
18056
18057 case Tag_CSKY_ISA_FLAGS:
18058 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
18059 return display_tag_value (0, p, end);
18060 case Tag_CSKY_ISA_EXT_FLAGS:
18061 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
18062 return display_tag_value (0, p, end);
18063
18064 case Tag_CSKY_DSP_VERSION:
18065 printf (" Tag_CSKY_DSP_VERSION:\t\t");
18066 READ_ULEB (val, p, end);
18067 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
18068 printf ("DSP Extension\n");
18069 else if (val == VAL_CSKY_DSP_VERSION_2)
18070 printf ("DSP 2.0\n");
18071 break;
18072
18073 case Tag_CSKY_VDSP_VERSION:
18074 printf (" Tag_CSKY_VDSP_VERSION:\t");
18075 READ_ULEB (val, p, end);
26c527e6 18076 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
18077 break;
18078
18079 case Tag_CSKY_FPU_VERSION:
18080 printf (" Tag_CSKY_FPU_VERSION:\t\t");
18081 READ_ULEB (val, p, end);
18082 if (val == VAL_CSKY_FPU_VERSION_1)
18083 printf ("ABIV1 FPU Version 1\n");
18084 else if (val == VAL_CSKY_FPU_VERSION_2)
18085 printf ("FPU Version 2\n");
18086 break;
18087
18088 case Tag_CSKY_FPU_ABI:
18089 printf (" Tag_CSKY_FPU_ABI:\t\t");
18090 READ_ULEB (val, p, end);
18091 if (val == VAL_CSKY_FPU_ABI_HARD)
18092 printf ("Hard\n");
18093 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18094 printf ("SoftFP\n");
18095 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18096 printf ("Soft\n");
18097 break;
18098 case Tag_CSKY_FPU_ROUNDING:
18099 READ_ULEB (val, p, end);
f253158f
NC
18100 if (val == 1)
18101 {
18102 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18103 printf ("Needed\n");
18104 }
0861f561
CQ
18105 break;
18106 case Tag_CSKY_FPU_DENORMAL:
18107 READ_ULEB (val, p, end);
f253158f
NC
18108 if (val == 1)
18109 {
18110 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18111 printf ("Needed\n");
18112 }
0861f561
CQ
18113 break;
18114 case Tag_CSKY_FPU_Exception:
18115 READ_ULEB (val, p, end);
f253158f
NC
18116 if (val == 1)
18117 {
18118 printf (" Tag_CSKY_FPU_Exception:\t");
18119 printf ("Needed\n");
18120 }
0861f561
CQ
18121 break;
18122 case Tag_CSKY_FPU_NUMBER_MODULE:
18123 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18124 return display_tag_value (-1, p, end);
18125 case Tag_CSKY_FPU_HARDFP:
18126 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18127 READ_ULEB (val, p, end);
18128 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18129 printf (" Half");
18130 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18131 printf (" Single");
18132 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18133 printf (" Double");
18134 printf ("\n");
18135 break;
18136 default:
18137 return display_tag_value (tag, p, end);
18138 }
18139 return p;
18140}
18141
015dc7e1 18142static bool
dda8d76d 18143process_attributes (Filedata * filedata,
60bca95a 18144 const char * public_name,
104d59d1 18145 unsigned int proc_type,
f6f0e17b 18146 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 18147 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 18148{
2cf0635d 18149 Elf_Internal_Shdr * sect;
11c1ff18 18150 unsigned i;
015dc7e1 18151 bool res = true;
11c1ff18
PB
18152
18153 /* Find the section header so that we get the size. */
dda8d76d
NC
18154 for (i = 0, sect = filedata->section_headers;
18155 i < filedata->file_header.e_shnum;
11c1ff18
PB
18156 i++, sect++)
18157 {
071436c6
NC
18158 unsigned char * contents;
18159 unsigned char * p;
18160
104d59d1 18161 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
18162 continue;
18163
dda8d76d 18164 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 18165 sect->sh_size, _("attributes"));
60bca95a 18166 if (contents == NULL)
32ec8896 18167 {
015dc7e1 18168 res = false;
32ec8896
NC
18169 continue;
18170 }
60bca95a 18171
11c1ff18 18172 p = contents;
60abdbed
NC
18173 /* The first character is the version of the attributes.
18174 Currently only version 1, (aka 'A') is recognised here. */
18175 if (*p != 'A')
32ec8896
NC
18176 {
18177 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 18178 res = false;
32ec8896 18179 }
60abdbed 18180 else
11c1ff18 18181 {
625d49fc 18182 uint64_t section_len;
071436c6
NC
18183
18184 section_len = sect->sh_size - 1;
11c1ff18 18185 p++;
60bca95a 18186
071436c6 18187 while (section_len > 0)
11c1ff18 18188 {
625d49fc 18189 uint64_t attr_len;
e9847026 18190 unsigned int namelen;
015dc7e1
AM
18191 bool public_section;
18192 bool gnu_section;
11c1ff18 18193
071436c6 18194 if (section_len <= 4)
e0a31db1
NC
18195 {
18196 error (_("Tag section ends prematurely\n"));
015dc7e1 18197 res = false;
e0a31db1
NC
18198 break;
18199 }
071436c6 18200 attr_len = byte_get (p, 4);
11c1ff18 18201 p += 4;
60bca95a 18202
071436c6 18203 if (attr_len > section_len)
11c1ff18 18204 {
071436c6
NC
18205 error (_("Bad attribute length (%u > %u)\n"),
18206 (unsigned) attr_len, (unsigned) section_len);
18207 attr_len = section_len;
015dc7e1 18208 res = false;
11c1ff18 18209 }
74e1a04b 18210 /* PR 17531: file: 001-101425-0.004 */
071436c6 18211 else if (attr_len < 5)
74e1a04b 18212 {
071436c6 18213 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 18214 res = false;
74e1a04b
NC
18215 break;
18216 }
e9847026 18217
071436c6
NC
18218 section_len -= attr_len;
18219 attr_len -= 4;
18220
18221 namelen = strnlen ((char *) p, attr_len) + 1;
18222 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
18223 {
18224 error (_("Corrupt attribute section name\n"));
015dc7e1 18225 res = false;
e9847026
NC
18226 break;
18227 }
18228
071436c6
NC
18229 printf (_("Attribute Section: "));
18230 print_symbol (INT_MAX, (const char *) p);
18231 putchar ('\n');
60bca95a
NC
18232
18233 if (public_name && streq ((char *) p, public_name))
015dc7e1 18234 public_section = true;
11c1ff18 18235 else
015dc7e1 18236 public_section = false;
60bca95a
NC
18237
18238 if (streq ((char *) p, "gnu"))
015dc7e1 18239 gnu_section = true;
104d59d1 18240 else
015dc7e1 18241 gnu_section = false;
60bca95a 18242
11c1ff18 18243 p += namelen;
071436c6 18244 attr_len -= namelen;
e0a31db1 18245
071436c6 18246 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18247 {
e0a31db1 18248 int tag;
cd30bcef 18249 unsigned int val;
625d49fc 18250 uint64_t size;
071436c6 18251 unsigned char * end;
60bca95a 18252
e0a31db1 18253 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18254 if (attr_len < 6)
e0a31db1
NC
18255 {
18256 error (_("Unused bytes at end of section\n"));
015dc7e1 18257 res = false;
e0a31db1
NC
18258 section_len = 0;
18259 break;
18260 }
18261
18262 tag = *(p++);
11c1ff18 18263 size = byte_get (p, 4);
071436c6 18264 if (size > attr_len)
11c1ff18 18265 {
e9847026 18266 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18267 (unsigned) size, (unsigned) attr_len);
015dc7e1 18268 res = false;
071436c6 18269 size = attr_len;
11c1ff18 18270 }
e0a31db1
NC
18271 /* PR binutils/17531: Safe handling of corrupt files. */
18272 if (size < 6)
18273 {
18274 error (_("Bad subsection length (%u < 6)\n"),
18275 (unsigned) size);
015dc7e1 18276 res = false;
e0a31db1
NC
18277 section_len = 0;
18278 break;
18279 }
60bca95a 18280
071436c6 18281 attr_len -= size;
11c1ff18 18282 end = p + size - 1;
071436c6 18283 assert (end <= contents + sect->sh_size);
11c1ff18 18284 p += 4;
60bca95a 18285
11c1ff18
PB
18286 switch (tag)
18287 {
18288 case 1:
2b692964 18289 printf (_("File Attributes\n"));
11c1ff18
PB
18290 break;
18291 case 2:
2b692964 18292 printf (_("Section Attributes:"));
11c1ff18
PB
18293 goto do_numlist;
18294 case 3:
2b692964 18295 printf (_("Symbol Attributes:"));
1a0670f3 18296 /* Fall through. */
11c1ff18
PB
18297 do_numlist:
18298 for (;;)
18299 {
cd30bcef 18300 READ_ULEB (val, p, end);
11c1ff18
PB
18301 if (val == 0)
18302 break;
18303 printf (" %d", val);
18304 }
18305 printf ("\n");
18306 break;
18307 default:
2b692964 18308 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18309 public_section = false;
11c1ff18
PB
18310 break;
18311 }
60bca95a 18312
071436c6 18313 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18314 {
18315 while (p < end)
f6f0e17b 18316 p = display_pub_attribute (p, end);
60abdbed 18317 assert (p == end);
104d59d1 18318 }
071436c6 18319 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18320 {
18321 while (p < end)
18322 p = display_gnu_attribute (p,
f6f0e17b
NC
18323 display_proc_gnu_attribute,
18324 end);
60abdbed 18325 assert (p == end);
11c1ff18 18326 }
071436c6 18327 else if (p < end)
11c1ff18 18328 {
071436c6 18329 printf (_(" Unknown attribute:\n"));
f6f0e17b 18330 display_raw_attribute (p, end);
11c1ff18
PB
18331 p = end;
18332 }
071436c6
NC
18333 else
18334 attr_len = 0;
11c1ff18
PB
18335 }
18336 }
18337 }
d70c5fc7 18338
60bca95a 18339 free (contents);
11c1ff18 18340 }
32ec8896
NC
18341
18342 return res;
11c1ff18
PB
18343}
18344
ccb4c951
RS
18345/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18346 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18347 and return the VMA of the next entry, or -1 if there was a problem.
18348 Does not read from DATA_END or beyond. */
ccb4c951 18349
625d49fc
AM
18350static uint64_t
18351print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18352 unsigned char * data_end)
ccb4c951
RS
18353{
18354 printf (" ");
18355 print_vma (addr, LONG_HEX);
18356 printf (" ");
18357 if (addr < pltgot + 0xfff0)
18358 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18359 else
18360 printf ("%10s", "");
18361 printf (" ");
18362 if (data == NULL)
2b692964 18363 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18364 else
18365 {
625d49fc 18366 uint64_t entry;
82b1b41b 18367 unsigned char * from = data + addr - pltgot;
ccb4c951 18368
82b1b41b
NC
18369 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18370 {
18371 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18372 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18373 return (uint64_t) -1;
82b1b41b
NC
18374 }
18375 else
18376 {
18377 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18378 print_vma (entry, LONG_HEX);
18379 }
ccb4c951
RS
18380 }
18381 return addr + (is_32bit_elf ? 4 : 8);
18382}
18383
861fb55a
DJ
18384/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18385 PLTGOT. Print the Address and Initial fields of an entry at VMA
18386 ADDR and return the VMA of the next entry. */
18387
625d49fc
AM
18388static uint64_t
18389print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18390{
18391 printf (" ");
18392 print_vma (addr, LONG_HEX);
18393 printf (" ");
18394 if (data == NULL)
2b692964 18395 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18396 else
18397 {
625d49fc 18398 uint64_t entry;
861fb55a
DJ
18399
18400 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18401 print_vma (entry, LONG_HEX);
18402 }
18403 return addr + (is_32bit_elf ? 4 : 8);
18404}
18405
351cdf24
MF
18406static void
18407print_mips_ases (unsigned int mask)
18408{
18409 if (mask & AFL_ASE_DSP)
18410 fputs ("\n\tDSP ASE", stdout);
18411 if (mask & AFL_ASE_DSPR2)
18412 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18413 if (mask & AFL_ASE_DSPR3)
18414 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18415 if (mask & AFL_ASE_EVA)
18416 fputs ("\n\tEnhanced VA Scheme", stdout);
18417 if (mask & AFL_ASE_MCU)
18418 fputs ("\n\tMCU (MicroController) ASE", stdout);
18419 if (mask & AFL_ASE_MDMX)
18420 fputs ("\n\tMDMX ASE", stdout);
18421 if (mask & AFL_ASE_MIPS3D)
18422 fputs ("\n\tMIPS-3D ASE", stdout);
18423 if (mask & AFL_ASE_MT)
18424 fputs ("\n\tMT ASE", stdout);
18425 if (mask & AFL_ASE_SMARTMIPS)
18426 fputs ("\n\tSmartMIPS ASE", stdout);
18427 if (mask & AFL_ASE_VIRT)
18428 fputs ("\n\tVZ ASE", stdout);
18429 if (mask & AFL_ASE_MSA)
18430 fputs ("\n\tMSA ASE", stdout);
18431 if (mask & AFL_ASE_MIPS16)
18432 fputs ("\n\tMIPS16 ASE", stdout);
18433 if (mask & AFL_ASE_MICROMIPS)
18434 fputs ("\n\tMICROMIPS ASE", stdout);
18435 if (mask & AFL_ASE_XPA)
18436 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18437 if (mask & AFL_ASE_MIPS16E2)
18438 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18439 if (mask & AFL_ASE_CRC)
18440 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18441 if (mask & AFL_ASE_GINV)
18442 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18443 if (mask & AFL_ASE_LOONGSON_MMI)
18444 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18445 if (mask & AFL_ASE_LOONGSON_CAM)
18446 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18447 if (mask & AFL_ASE_LOONGSON_EXT)
18448 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18449 if (mask & AFL_ASE_LOONGSON_EXT2)
18450 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18451 if (mask == 0)
18452 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18453 else if ((mask & ~AFL_ASE_MASK) != 0)
18454 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18455}
18456
18457static void
18458print_mips_isa_ext (unsigned int isa_ext)
18459{
18460 switch (isa_ext)
18461 {
18462 case 0:
18463 fputs (_("None"), stdout);
18464 break;
18465 case AFL_EXT_XLR:
18466 fputs ("RMI XLR", stdout);
18467 break;
2c629856
N
18468 case AFL_EXT_OCTEON3:
18469 fputs ("Cavium Networks Octeon3", stdout);
18470 break;
351cdf24
MF
18471 case AFL_EXT_OCTEON2:
18472 fputs ("Cavium Networks Octeon2", stdout);
18473 break;
18474 case AFL_EXT_OCTEONP:
18475 fputs ("Cavium Networks OcteonP", stdout);
18476 break;
351cdf24
MF
18477 case AFL_EXT_OCTEON:
18478 fputs ("Cavium Networks Octeon", stdout);
18479 break;
18480 case AFL_EXT_5900:
18481 fputs ("Toshiba R5900", stdout);
18482 break;
18483 case AFL_EXT_4650:
18484 fputs ("MIPS R4650", stdout);
18485 break;
18486 case AFL_EXT_4010:
18487 fputs ("LSI R4010", stdout);
18488 break;
18489 case AFL_EXT_4100:
18490 fputs ("NEC VR4100", stdout);
18491 break;
18492 case AFL_EXT_3900:
18493 fputs ("Toshiba R3900", stdout);
18494 break;
18495 case AFL_EXT_10000:
18496 fputs ("MIPS R10000", stdout);
18497 break;
18498 case AFL_EXT_SB1:
18499 fputs ("Broadcom SB-1", stdout);
18500 break;
18501 case AFL_EXT_4111:
18502 fputs ("NEC VR4111/VR4181", stdout);
18503 break;
18504 case AFL_EXT_4120:
18505 fputs ("NEC VR4120", stdout);
18506 break;
18507 case AFL_EXT_5400:
18508 fputs ("NEC VR5400", stdout);
18509 break;
18510 case AFL_EXT_5500:
18511 fputs ("NEC VR5500", stdout);
18512 break;
18513 case AFL_EXT_LOONGSON_2E:
18514 fputs ("ST Microelectronics Loongson 2E", stdout);
18515 break;
18516 case AFL_EXT_LOONGSON_2F:
18517 fputs ("ST Microelectronics Loongson 2F", stdout);
18518 break;
38bf472a
MR
18519 case AFL_EXT_INTERAPTIV_MR2:
18520 fputs ("Imagination interAptiv MR2", stdout);
18521 break;
351cdf24 18522 default:
00ac7aa0 18523 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18524 }
18525}
18526
32ec8896 18527static signed int
351cdf24
MF
18528get_mips_reg_size (int reg_size)
18529{
18530 return (reg_size == AFL_REG_NONE) ? 0
18531 : (reg_size == AFL_REG_32) ? 32
18532 : (reg_size == AFL_REG_64) ? 64
18533 : (reg_size == AFL_REG_128) ? 128
18534 : -1;
18535}
18536
015dc7e1 18537static bool
dda8d76d 18538process_mips_specific (Filedata * filedata)
5b18a4bc 18539{
2cf0635d 18540 Elf_Internal_Dyn * entry;
351cdf24 18541 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18542 size_t liblist_offset = 0;
18543 size_t liblistno = 0;
18544 size_t conflictsno = 0;
18545 size_t options_offset = 0;
18546 size_t conflicts_offset = 0;
861fb55a
DJ
18547 size_t pltrelsz = 0;
18548 size_t pltrel = 0;
625d49fc
AM
18549 uint64_t pltgot = 0;
18550 uint64_t mips_pltgot = 0;
18551 uint64_t jmprel = 0;
18552 uint64_t local_gotno = 0;
18553 uint64_t gotsym = 0;
18554 uint64_t symtabno = 0;
015dc7e1 18555 bool res = true;
103f02d3 18556
dda8d76d 18557 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18558 display_mips_gnu_attribute))
015dc7e1 18559 res = false;
2cf19d5c 18560
dda8d76d 18561 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18562
18563 if (sect != NULL)
18564 {
18565 Elf_External_ABIFlags_v0 *abiflags_ext;
18566 Elf_Internal_ABIFlags_v0 abiflags_in;
18567
18568 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18569 {
18570 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18571 res = false;
32ec8896 18572 }
351cdf24
MF
18573 else
18574 {
dda8d76d 18575 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18576 sect->sh_size, _("MIPS ABI Flags section"));
18577 if (abiflags_ext)
18578 {
18579 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18580 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18581 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18582 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18583 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18584 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18585 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18586 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18587 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18588 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18589 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18590
18591 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18592 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18593 if (abiflags_in.isa_rev > 1)
18594 printf ("r%d", abiflags_in.isa_rev);
18595 printf ("\nGPR size: %d",
18596 get_mips_reg_size (abiflags_in.gpr_size));
18597 printf ("\nCPR1 size: %d",
18598 get_mips_reg_size (abiflags_in.cpr1_size));
18599 printf ("\nCPR2 size: %d",
18600 get_mips_reg_size (abiflags_in.cpr2_size));
18601 fputs ("\nFP ABI: ", stdout);
18602 print_mips_fp_abi_value (abiflags_in.fp_abi);
18603 fputs ("ISA Extension: ", stdout);
18604 print_mips_isa_ext (abiflags_in.isa_ext);
18605 fputs ("\nASEs:", stdout);
18606 print_mips_ases (abiflags_in.ases);
18607 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18608 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18609 fputc ('\n', stdout);
18610 free (abiflags_ext);
18611 }
18612 }
18613 }
18614
19e6b90e 18615 /* We have a lot of special sections. Thanks SGI! */
978c4450 18616 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18617 {
18618 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18619 sect = find_section (filedata, ".got");
bbdd9a68
MR
18620 if (sect != NULL)
18621 {
18622 unsigned char *data_end;
18623 unsigned char *data;
625d49fc 18624 uint64_t ent, end;
bbdd9a68
MR
18625 int addr_size;
18626
18627 pltgot = sect->sh_addr;
18628
18629 ent = pltgot;
18630 addr_size = (is_32bit_elf ? 4 : 8);
18631 end = pltgot + sect->sh_size;
18632
dda8d76d 18633 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18634 end - pltgot, 1,
18635 _("Global Offset Table data"));
18636 /* PR 12855: Null data is handled gracefully throughout. */
18637 data_end = data + (end - pltgot);
18638
18639 printf (_("\nStatic GOT:\n"));
18640 printf (_(" Canonical gp value: "));
18641 print_vma (ent + 0x7ff0, LONG_HEX);
18642 printf ("\n\n");
18643
18644 /* In a dynamic binary GOT[0] is reserved for the dynamic
18645 loader to store the lazy resolver pointer, however in
18646 a static binary it may well have been omitted and GOT
18647 reduced to a table of addresses.
18648 PR 21344: Check for the entry being fully available
18649 before fetching it. */
18650 if (data
18651 && data + ent - pltgot + addr_size <= data_end
18652 && byte_get (data + ent - pltgot, addr_size) == 0)
18653 {
18654 printf (_(" Reserved entries:\n"));
18655 printf (_(" %*s %10s %*s\n"),
18656 addr_size * 2, _("Address"), _("Access"),
18657 addr_size * 2, _("Value"));
18658 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18659 printf ("\n");
625d49fc 18660 if (ent == (uint64_t) -1)
bbdd9a68
MR
18661 goto sgot_print_fail;
18662
18663 /* Check for the MSB of GOT[1] being set, identifying a
18664 GNU object. This entry will be used by some runtime
18665 loaders, to store the module pointer. Otherwise this
18666 is an ordinary local entry.
18667 PR 21344: Check for the entry being fully available
18668 before fetching it. */
18669 if (data
18670 && data + ent - pltgot + addr_size <= data_end
18671 && (byte_get (data + ent - pltgot, addr_size)
18672 >> (addr_size * 8 - 1)) != 0)
18673 {
18674 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18675 printf ("\n");
625d49fc 18676 if (ent == (uint64_t) -1)
bbdd9a68
MR
18677 goto sgot_print_fail;
18678 }
18679 printf ("\n");
18680 }
18681
f17e9d8a 18682 if (data != NULL && ent < end)
bbdd9a68
MR
18683 {
18684 printf (_(" Local entries:\n"));
18685 printf (" %*s %10s %*s\n",
18686 addr_size * 2, _("Address"), _("Access"),
18687 addr_size * 2, _("Value"));
18688 while (ent < end)
18689 {
18690 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18691 printf ("\n");
625d49fc 18692 if (ent == (uint64_t) -1)
bbdd9a68
MR
18693 goto sgot_print_fail;
18694 }
18695 printf ("\n");
18696 }
18697
18698 sgot_print_fail:
9db70fc3 18699 free (data);
bbdd9a68
MR
18700 }
18701 return res;
18702 }
252b5132 18703
978c4450 18704 for (entry = filedata->dynamic_section;
071436c6 18705 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18706 (entry < filedata->dynamic_section + filedata->dynamic_nent
18707 && entry->d_tag != DT_NULL);
071436c6 18708 ++entry)
252b5132
RH
18709 switch (entry->d_tag)
18710 {
18711 case DT_MIPS_LIBLIST:
d93f0186 18712 liblist_offset
dda8d76d 18713 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18714 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18715 break;
18716 case DT_MIPS_LIBLISTNO:
18717 liblistno = entry->d_un.d_val;
18718 break;
18719 case DT_MIPS_OPTIONS:
dda8d76d 18720 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18721 break;
18722 case DT_MIPS_CONFLICT:
d93f0186 18723 conflicts_offset
dda8d76d 18724 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18725 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18726 break;
18727 case DT_MIPS_CONFLICTNO:
18728 conflictsno = entry->d_un.d_val;
18729 break;
ccb4c951 18730 case DT_PLTGOT:
861fb55a
DJ
18731 pltgot = entry->d_un.d_ptr;
18732 break;
ccb4c951
RS
18733 case DT_MIPS_LOCAL_GOTNO:
18734 local_gotno = entry->d_un.d_val;
18735 break;
18736 case DT_MIPS_GOTSYM:
18737 gotsym = entry->d_un.d_val;
18738 break;
18739 case DT_MIPS_SYMTABNO:
18740 symtabno = entry->d_un.d_val;
18741 break;
861fb55a
DJ
18742 case DT_MIPS_PLTGOT:
18743 mips_pltgot = entry->d_un.d_ptr;
18744 break;
18745 case DT_PLTREL:
18746 pltrel = entry->d_un.d_val;
18747 break;
18748 case DT_PLTRELSZ:
18749 pltrelsz = entry->d_un.d_val;
18750 break;
18751 case DT_JMPREL:
18752 jmprel = entry->d_un.d_ptr;
18753 break;
252b5132
RH
18754 default:
18755 break;
18756 }
18757
18758 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18759 {
2cf0635d 18760 Elf32_External_Lib * elib;
252b5132
RH
18761 size_t cnt;
18762
dda8d76d 18763 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18764 sizeof (Elf32_External_Lib),
18765 liblistno,
18766 _("liblist section data"));
a6e9f9df 18767 if (elib)
252b5132 18768 {
26c527e6
AM
18769 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
18770 "\nSection '.liblist' contains %zu entries:\n",
18771 liblistno),
18772 liblistno);
2b692964 18773 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18774 stdout);
18775
18776 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18777 {
a6e9f9df 18778 Elf32_Lib liblist;
91d6fa6a 18779 time_t atime;
d5b07ef4 18780 char timebuf[128];
2cf0635d 18781 struct tm * tmp;
a6e9f9df
AM
18782
18783 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18784 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18785 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18786 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18787 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18788
91d6fa6a 18789 tmp = gmtime (&atime);
e9e44622
JJ
18790 snprintf (timebuf, sizeof (timebuf),
18791 "%04u-%02u-%02uT%02u:%02u:%02u",
18792 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18793 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18794
26c527e6 18795 printf ("%3zu: ", cnt);
84714f86
AM
18796 if (valid_dynamic_name (filedata, liblist.l_name))
18797 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18798 else
2b692964 18799 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18800 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18801 liblist.l_version);
a6e9f9df
AM
18802
18803 if (liblist.l_flags == 0)
2b692964 18804 puts (_(" NONE"));
a6e9f9df
AM
18805 else
18806 {
18807 static const struct
252b5132 18808 {
2cf0635d 18809 const char * name;
a6e9f9df 18810 int bit;
252b5132 18811 }
a6e9f9df
AM
18812 l_flags_vals[] =
18813 {
18814 { " EXACT_MATCH", LL_EXACT_MATCH },
18815 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18816 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18817 { " EXPORTS", LL_EXPORTS },
18818 { " DELAY_LOAD", LL_DELAY_LOAD },
18819 { " DELTA", LL_DELTA }
18820 };
18821 int flags = liblist.l_flags;
18822 size_t fcnt;
18823
60bca95a 18824 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18825 if ((flags & l_flags_vals[fcnt].bit) != 0)
18826 {
18827 fputs (l_flags_vals[fcnt].name, stdout);
18828 flags ^= l_flags_vals[fcnt].bit;
18829 }
18830 if (flags != 0)
18831 printf (" %#x", (unsigned int) flags);
252b5132 18832
a6e9f9df
AM
18833 puts ("");
18834 }
252b5132 18835 }
252b5132 18836
a6e9f9df
AM
18837 free (elib);
18838 }
32ec8896 18839 else
015dc7e1 18840 res = false;
252b5132
RH
18841 }
18842
18843 if (options_offset != 0)
18844 {
2cf0635d 18845 Elf_External_Options * eopt;
252b5132
RH
18846 size_t offset;
18847 int cnt;
18848
18849 /* Find the section header so that we get the size. */
dda8d76d 18850 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18851 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18852 if (sect == NULL)
18853 {
18854 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18855 return false;
071436c6 18856 }
7fc0c668
NC
18857 /* PR 24243 */
18858 if (sect->sh_size < sizeof (* eopt))
18859 {
18860 error (_("The MIPS options section is too small.\n"));
015dc7e1 18861 return false;
7fc0c668 18862 }
252b5132 18863
dda8d76d 18864 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18865 sect->sh_size, _("options"));
a6e9f9df 18866 if (eopt)
252b5132 18867 {
fd17d1e6 18868 Elf_Internal_Options option;
76da6bbe 18869
a6e9f9df 18870 offset = cnt = 0;
82b1b41b 18871 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18872 {
2cf0635d 18873 Elf_External_Options * eoption;
fd17d1e6 18874 unsigned int optsize;
252b5132 18875
a6e9f9df 18876 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18877
fd17d1e6 18878 optsize = BYTE_GET (eoption->size);
76da6bbe 18879
82b1b41b 18880 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18881 if (optsize < sizeof (* eopt)
18882 || optsize > sect->sh_size - offset)
82b1b41b 18883 {
645f43a8 18884 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18885 optsize);
645f43a8 18886 free (eopt);
015dc7e1 18887 return false;
82b1b41b 18888 }
fd17d1e6 18889 offset += optsize;
a6e9f9df
AM
18890 ++cnt;
18891 }
252b5132 18892
d3a49aa8
AM
18893 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18894 "\nSection '%s' contains %d entries:\n",
18895 cnt),
dda8d76d 18896 printable_section_name (filedata, sect), cnt);
76da6bbe 18897
82b1b41b 18898 offset = 0;
a6e9f9df 18899 while (cnt-- > 0)
252b5132 18900 {
a6e9f9df 18901 size_t len;
fd17d1e6
AM
18902 Elf_External_Options * eoption;
18903
18904 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18905
18906 option.kind = BYTE_GET (eoption->kind);
18907 option.size = BYTE_GET (eoption->size);
18908 option.section = BYTE_GET (eoption->section);
18909 option.info = BYTE_GET (eoption->info);
a6e9f9df 18910
fd17d1e6 18911 switch (option.kind)
252b5132 18912 {
a6e9f9df
AM
18913 case ODK_NULL:
18914 /* This shouldn't happen. */
d0c4e780 18915 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18916 option.section, option.info);
a6e9f9df 18917 break;
2e6be59c 18918
a6e9f9df
AM
18919 case ODK_REGINFO:
18920 printf (" REGINFO ");
dda8d76d 18921 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18922 {
2cf0635d 18923 Elf32_External_RegInfo * ereg;
b34976b6 18924 Elf32_RegInfo reginfo;
a6e9f9df 18925
2e6be59c 18926 /* 32bit form. */
fd17d1e6
AM
18927 if (option.size < (sizeof (Elf_External_Options)
18928 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18929 {
18930 printf (_("<corrupt>\n"));
18931 error (_("Truncated MIPS REGINFO option\n"));
18932 cnt = 0;
18933 break;
18934 }
18935
fd17d1e6 18936 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18937
a6e9f9df
AM
18938 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18939 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18940 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18941 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18942 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18943 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18944
d0c4e780
AM
18945 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18946 reginfo.ri_gprmask, reginfo.ri_gp_value);
18947 printf (" "
18948 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18949 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18950 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18951 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18952 }
18953 else
18954 {
18955 /* 64 bit form. */
2cf0635d 18956 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18957 Elf64_Internal_RegInfo reginfo;
18958
fd17d1e6
AM
18959 if (option.size < (sizeof (Elf_External_Options)
18960 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18961 {
18962 printf (_("<corrupt>\n"));
18963 error (_("Truncated MIPS REGINFO option\n"));
18964 cnt = 0;
18965 break;
18966 }
18967
fd17d1e6 18968 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18969 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18970 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18971 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18972 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18973 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18974 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18975
d0c4e780
AM
18976 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18977 reginfo.ri_gprmask, reginfo.ri_gp_value);
18978 printf (" "
18979 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18980 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18981 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18982 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18983 }
fd17d1e6 18984 offset += option.size;
a6e9f9df 18985 continue;
2e6be59c 18986
a6e9f9df
AM
18987 case ODK_EXCEPTIONS:
18988 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18989 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18990 fputs (") fpe_max(", stdout);
fd17d1e6 18991 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18992 fputs (")", stdout);
18993
fd17d1e6 18994 if (option.info & OEX_PAGE0)
a6e9f9df 18995 fputs (" PAGE0", stdout);
fd17d1e6 18996 if (option.info & OEX_SMM)
a6e9f9df 18997 fputs (" SMM", stdout);
fd17d1e6 18998 if (option.info & OEX_FPDBUG)
a6e9f9df 18999 fputs (" FPDBUG", stdout);
fd17d1e6 19000 if (option.info & OEX_DISMISS)
a6e9f9df
AM
19001 fputs (" DISMISS", stdout);
19002 break;
2e6be59c 19003
a6e9f9df
AM
19004 case ODK_PAD:
19005 fputs (" PAD ", stdout);
fd17d1e6 19006 if (option.info & OPAD_PREFIX)
a6e9f9df 19007 fputs (" PREFIX", stdout);
fd17d1e6 19008 if (option.info & OPAD_POSTFIX)
a6e9f9df 19009 fputs (" POSTFIX", stdout);
fd17d1e6 19010 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
19011 fputs (" SYMBOL", stdout);
19012 break;
2e6be59c 19013
a6e9f9df
AM
19014 case ODK_HWPATCH:
19015 fputs (" HWPATCH ", stdout);
fd17d1e6 19016 if (option.info & OHW_R4KEOP)
a6e9f9df 19017 fputs (" R4KEOP", stdout);
fd17d1e6 19018 if (option.info & OHW_R8KPFETCH)
a6e9f9df 19019 fputs (" R8KPFETCH", stdout);
fd17d1e6 19020 if (option.info & OHW_R5KEOP)
a6e9f9df 19021 fputs (" R5KEOP", stdout);
fd17d1e6 19022 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
19023 fputs (" R5KCVTL", stdout);
19024 break;
2e6be59c 19025
a6e9f9df
AM
19026 case ODK_FILL:
19027 fputs (" FILL ", stdout);
19028 /* XXX Print content of info word? */
19029 break;
2e6be59c 19030
a6e9f9df
AM
19031 case ODK_TAGS:
19032 fputs (" TAGS ", stdout);
19033 /* XXX Print content of info word? */
19034 break;
2e6be59c 19035
a6e9f9df
AM
19036 case ODK_HWAND:
19037 fputs (" HWAND ", stdout);
fd17d1e6 19038 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19039 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19040 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19041 fputs (" R4KEOP_CLEAN", stdout);
19042 break;
2e6be59c 19043
a6e9f9df
AM
19044 case ODK_HWOR:
19045 fputs (" HWOR ", stdout);
fd17d1e6 19046 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19047 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19048 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19049 fputs (" R4KEOP_CLEAN", stdout);
19050 break;
2e6be59c 19051
a6e9f9df 19052 case ODK_GP_GROUP:
d0c4e780 19053 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
19054 option.info & OGP_GROUP,
19055 (option.info & OGP_SELF) >> 16);
a6e9f9df 19056 break;
2e6be59c 19057
a6e9f9df 19058 case ODK_IDENT:
d0c4e780 19059 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
19060 option.info & OGP_GROUP,
19061 (option.info & OGP_SELF) >> 16);
a6e9f9df 19062 break;
2e6be59c 19063
a6e9f9df
AM
19064 default:
19065 /* This shouldn't happen. */
d0c4e780 19066 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 19067 option.kind, option.section, option.info);
a6e9f9df 19068 break;
252b5132 19069 }
a6e9f9df 19070
2cf0635d 19071 len = sizeof (* eopt);
fd17d1e6 19072 while (len < option.size)
82b1b41b 19073 {
fd17d1e6 19074 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 19075
82b1b41b
NC
19076 if (ISPRINT (datum))
19077 printf ("%c", datum);
19078 else
19079 printf ("\\%03o", datum);
19080 len ++;
19081 }
a6e9f9df 19082 fputs ("\n", stdout);
82b1b41b 19083
fd17d1e6 19084 offset += option.size;
252b5132 19085 }
a6e9f9df 19086 free (eopt);
252b5132 19087 }
32ec8896 19088 else
015dc7e1 19089 res = false;
252b5132
RH
19090 }
19091
19092 if (conflicts_offset != 0 && conflictsno != 0)
19093 {
2cf0635d 19094 Elf32_Conflict * iconf;
252b5132
RH
19095 size_t cnt;
19096
978c4450 19097 if (filedata->dynamic_symbols == NULL)
252b5132 19098 {
591a748a 19099 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 19100 return false;
252b5132
RH
19101 }
19102
7296a62a
NC
19103 /* PR 21345 - print a slightly more helpful error message
19104 if we are sure that the cmalloc will fail. */
645f43a8 19105 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 19106 {
26c527e6
AM
19107 error (_("Overlarge number of conflicts detected: %zx\n"),
19108 conflictsno);
015dc7e1 19109 return false;
7296a62a
NC
19110 }
19111
3f5e193b 19112 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
19113 if (iconf == NULL)
19114 {
8b73c356 19115 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 19116 return false;
252b5132
RH
19117 }
19118
9ea033b2 19119 if (is_32bit_elf)
252b5132 19120 {
2cf0635d 19121 Elf32_External_Conflict * econf32;
a6e9f9df 19122
3f5e193b 19123 econf32 = (Elf32_External_Conflict *)
95099889
AM
19124 get_data (NULL, filedata, conflicts_offset,
19125 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 19126 if (!econf32)
5a814d6d
AM
19127 {
19128 free (iconf);
015dc7e1 19129 return false;
5a814d6d 19130 }
252b5132
RH
19131
19132 for (cnt = 0; cnt < conflictsno; ++cnt)
19133 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
19134
19135 free (econf32);
252b5132
RH
19136 }
19137 else
19138 {
2cf0635d 19139 Elf64_External_Conflict * econf64;
a6e9f9df 19140
3f5e193b 19141 econf64 = (Elf64_External_Conflict *)
95099889
AM
19142 get_data (NULL, filedata, conflicts_offset,
19143 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 19144 if (!econf64)
5a814d6d
AM
19145 {
19146 free (iconf);
015dc7e1 19147 return false;
5a814d6d 19148 }
252b5132
RH
19149
19150 for (cnt = 0; cnt < conflictsno; ++cnt)
19151 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
19152
19153 free (econf64);
252b5132
RH
19154 }
19155
26c527e6
AM
19156 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19157 "\nSection '.conflict' contains %zu entries:\n",
19158 conflictsno),
19159 conflictsno);
252b5132
RH
19160 puts (_(" Num: Index Value Name"));
19161
19162 for (cnt = 0; cnt < conflictsno; ++cnt)
19163 {
26c527e6 19164 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 19165
978c4450 19166 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 19167 printf (_("<corrupt symbol index>"));
d79b3d50 19168 else
e0a31db1
NC
19169 {
19170 Elf_Internal_Sym * psym;
19171
978c4450 19172 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
19173 print_vma (psym->st_value, FULL_HEX);
19174 putchar (' ');
84714f86
AM
19175 if (valid_dynamic_name (filedata, psym->st_name))
19176 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19177 else
19178 printf (_("<corrupt: %14ld>"), psym->st_name);
19179 }
31104126 19180 putchar ('\n');
252b5132
RH
19181 }
19182
252b5132
RH
19183 free (iconf);
19184 }
19185
ccb4c951
RS
19186 if (pltgot != 0 && local_gotno != 0)
19187 {
625d49fc 19188 uint64_t ent, local_end, global_end;
bbeee7ea 19189 size_t i, offset;
2cf0635d 19190 unsigned char * data;
82b1b41b 19191 unsigned char * data_end;
bbeee7ea 19192 int addr_size;
ccb4c951 19193
91d6fa6a 19194 ent = pltgot;
ccb4c951
RS
19195 addr_size = (is_32bit_elf ? 4 : 8);
19196 local_end = pltgot + local_gotno * addr_size;
ccb4c951 19197
74e1a04b
NC
19198 /* PR binutils/17533 file: 012-111227-0.004 */
19199 if (symtabno < gotsym)
19200 {
26c527e6
AM
19201 error (_("The GOT symbol offset (%" PRIu64
19202 ") is greater than the symbol table size (%" PRIu64 ")\n"),
19203 gotsym, symtabno);
015dc7e1 19204 return false;
74e1a04b 19205 }
82b1b41b 19206
74e1a04b 19207 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
19208 /* PR 17531: file: 54c91a34. */
19209 if (global_end < local_end)
19210 {
26c527e6 19211 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 19212 return false;
82b1b41b 19213 }
948f632f 19214
dda8d76d
NC
19215 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
19216 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
19217 global_end - pltgot, 1,
19218 _("Global Offset Table data"));
919383ac 19219 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 19220 data_end = data + (global_end - pltgot);
59245841 19221
ccb4c951
RS
19222 printf (_("\nPrimary GOT:\n"));
19223 printf (_(" Canonical gp value: "));
19224 print_vma (pltgot + 0x7ff0, LONG_HEX);
19225 printf ("\n\n");
19226
19227 printf (_(" Reserved entries:\n"));
19228 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
19229 addr_size * 2, _("Address"), _("Access"),
19230 addr_size * 2, _("Initial"));
82b1b41b 19231 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 19232 printf (_(" Lazy resolver\n"));
625d49fc 19233 if (ent == (uint64_t) -1)
82b1b41b 19234 goto got_print_fail;
75ec1fdb 19235
c4ab9505
MR
19236 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19237 This entry will be used by some runtime loaders, to store the
19238 module pointer. Otherwise this is an ordinary local entry.
19239 PR 21344: Check for the entry being fully available before
19240 fetching it. */
19241 if (data
19242 && data + ent - pltgot + addr_size <= data_end
19243 && (byte_get (data + ent - pltgot, addr_size)
19244 >> (addr_size * 8 - 1)) != 0)
19245 {
19246 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19247 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 19248 if (ent == (uint64_t) -1)
c4ab9505 19249 goto got_print_fail;
ccb4c951
RS
19250 }
19251 printf ("\n");
19252
f17e9d8a 19253 if (data != NULL && ent < local_end)
ccb4c951
RS
19254 {
19255 printf (_(" Local entries:\n"));
cc5914eb 19256 printf (" %*s %10s %*s\n",
2b692964
NC
19257 addr_size * 2, _("Address"), _("Access"),
19258 addr_size * 2, _("Initial"));
91d6fa6a 19259 while (ent < local_end)
ccb4c951 19260 {
82b1b41b 19261 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19262 printf ("\n");
625d49fc 19263 if (ent == (uint64_t) -1)
82b1b41b 19264 goto got_print_fail;
ccb4c951
RS
19265 }
19266 printf ("\n");
19267 }
19268
f17e9d8a 19269 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19270 {
19271 int sym_width;
19272
19273 printf (_(" Global entries:\n"));
cc5914eb 19274 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19275 addr_size * 2, _("Address"),
19276 _("Access"),
2b692964 19277 addr_size * 2, _("Initial"),
9cf03b7e
NC
19278 addr_size * 2, _("Sym.Val."),
19279 _("Type"),
19280 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19281 _("Ndx"), _("Name"));
0b4362b0 19282
ccb4c951 19283 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19284
ccb4c951
RS
19285 for (i = gotsym; i < symtabno; i++)
19286 {
82b1b41b 19287 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19288 printf (" ");
e0a31db1 19289
978c4450 19290 if (filedata->dynamic_symbols == NULL)
e0a31db1 19291 printf (_("<no dynamic symbols>"));
978c4450 19292 else if (i < filedata->num_dynamic_syms)
e0a31db1 19293 {
978c4450 19294 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19295
19296 print_vma (psym->st_value, LONG_HEX);
19297 printf (" %-7s %3s ",
dda8d76d
NC
19298 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19299 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19300
84714f86 19301 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19302 print_symbol (sym_width,
84714f86 19303 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19304 else
19305 printf (_("<corrupt: %14ld>"), psym->st_name);
19306 }
ccb4c951 19307 else
26c527e6
AM
19308 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
19309 i);
e0a31db1 19310
ccb4c951 19311 printf ("\n");
625d49fc 19312 if (ent == (uint64_t) -1)
82b1b41b 19313 break;
ccb4c951
RS
19314 }
19315 printf ("\n");
19316 }
19317
82b1b41b 19318 got_print_fail:
9db70fc3 19319 free (data);
ccb4c951
RS
19320 }
19321
861fb55a
DJ
19322 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19323 {
625d49fc 19324 uint64_t ent, end;
26c527e6
AM
19325 uint64_t offset, rel_offset;
19326 uint64_t count, i;
2cf0635d 19327 unsigned char * data;
861fb55a 19328 int addr_size, sym_width;
2cf0635d 19329 Elf_Internal_Rela * rels;
861fb55a 19330
dda8d76d 19331 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19332 if (pltrel == DT_RELA)
19333 {
dda8d76d 19334 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19335 return false;
861fb55a
DJ
19336 }
19337 else
19338 {
dda8d76d 19339 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19340 return false;
861fb55a
DJ
19341 }
19342
91d6fa6a 19343 ent = mips_pltgot;
861fb55a
DJ
19344 addr_size = (is_32bit_elf ? 4 : 8);
19345 end = mips_pltgot + (2 + count) * addr_size;
19346
dda8d76d
NC
19347 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19348 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19349 1, _("Procedure Linkage Table data"));
59245841 19350 if (data == NULL)
288f0ba2
AM
19351 {
19352 free (rels);
015dc7e1 19353 return false;
288f0ba2 19354 }
59245841 19355
9cf03b7e 19356 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19357 printf (_(" Reserved entries:\n"));
19358 printf (_(" %*s %*s Purpose\n"),
2b692964 19359 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19360 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19361 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19362 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19363 printf (_(" Module pointer\n"));
861fb55a
DJ
19364 printf ("\n");
19365
19366 printf (_(" Entries:\n"));
cc5914eb 19367 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19368 addr_size * 2, _("Address"),
19369 addr_size * 2, _("Initial"),
19370 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19371 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19372 for (i = 0; i < count; i++)
19373 {
26c527e6 19374 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19375
91d6fa6a 19376 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19377 printf (" ");
e0a31db1 19378
978c4450 19379 if (idx >= filedata->num_dynamic_syms)
26c527e6 19380 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 19381 else
e0a31db1 19382 {
978c4450 19383 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19384
19385 print_vma (psym->st_value, LONG_HEX);
19386 printf (" %-7s %3s ",
dda8d76d
NC
19387 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19388 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19389 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19390 print_symbol (sym_width,
84714f86 19391 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19392 else
19393 printf (_("<corrupt: %14ld>"), psym->st_name);
19394 }
861fb55a
DJ
19395 printf ("\n");
19396 }
19397 printf ("\n");
19398
9db70fc3 19399 free (data);
861fb55a
DJ
19400 free (rels);
19401 }
19402
32ec8896 19403 return res;
252b5132
RH
19404}
19405
015dc7e1 19406static bool
dda8d76d 19407process_nds32_specific (Filedata * filedata)
35c08157
KLC
19408{
19409 Elf_Internal_Shdr *sect = NULL;
19410
dda8d76d 19411 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19412 if (sect != NULL && sect->sh_size >= 4)
35c08157 19413 {
9c7b8e9b
AM
19414 unsigned char *buf;
19415 unsigned int flag;
35c08157
KLC
19416
19417 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19418 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19419 _("NDS32 elf flags section"));
35c08157 19420
9c7b8e9b 19421 if (buf == NULL)
015dc7e1 19422 return false;
32ec8896 19423
9c7b8e9b
AM
19424 flag = byte_get (buf, 4);
19425 free (buf);
19426 switch (flag & 0x3)
35c08157
KLC
19427 {
19428 case 0:
19429 printf ("(VEC_SIZE):\tNo entry.\n");
19430 break;
19431 case 1:
19432 printf ("(VEC_SIZE):\t4 bytes\n");
19433 break;
19434 case 2:
19435 printf ("(VEC_SIZE):\t16 bytes\n");
19436 break;
19437 case 3:
19438 printf ("(VEC_SIZE):\treserved\n");
19439 break;
19440 }
19441 }
19442
015dc7e1 19443 return true;
35c08157
KLC
19444}
19445
015dc7e1 19446static bool
dda8d76d 19447process_gnu_liblist (Filedata * filedata)
047b2264 19448{
2cf0635d
NC
19449 Elf_Internal_Shdr * section;
19450 Elf_Internal_Shdr * string_sec;
19451 Elf32_External_Lib * elib;
19452 char * strtab;
c256ffe7 19453 size_t strtab_size;
047b2264 19454 size_t cnt;
26c527e6 19455 uint64_t num_liblist;
047b2264 19456 unsigned i;
015dc7e1 19457 bool res = true;
047b2264
JJ
19458
19459 if (! do_arch)
015dc7e1 19460 return true;
047b2264 19461
dda8d76d
NC
19462 for (i = 0, section = filedata->section_headers;
19463 i < filedata->file_header.e_shnum;
b34976b6 19464 i++, section++)
047b2264
JJ
19465 {
19466 switch (section->sh_type)
19467 {
19468 case SHT_GNU_LIBLIST:
dda8d76d 19469 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19470 break;
19471
3f5e193b 19472 elib = (Elf32_External_Lib *)
dda8d76d 19473 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19474 _("liblist section data"));
047b2264
JJ
19475
19476 if (elib == NULL)
32ec8896 19477 {
015dc7e1 19478 res = false;
32ec8896
NC
19479 break;
19480 }
047b2264 19481
dda8d76d
NC
19482 string_sec = filedata->section_headers + section->sh_link;
19483 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19484 string_sec->sh_size,
19485 _("liblist string table"));
047b2264
JJ
19486 if (strtab == NULL
19487 || section->sh_entsize != sizeof (Elf32_External_Lib))
19488 {
19489 free (elib);
2842702f 19490 free (strtab);
015dc7e1 19491 res = false;
047b2264
JJ
19492 break;
19493 }
59245841 19494 strtab_size = string_sec->sh_size;
047b2264 19495
d3a49aa8 19496 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
19497 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
19498 " entries:\n",
19499 "\nLibrary list section '%s' contains %" PRIu64
19500 " entries:\n",
d3a49aa8 19501 num_liblist),
dda8d76d 19502 printable_section_name (filedata, section),
d3a49aa8 19503 num_liblist);
047b2264 19504
2b692964 19505 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19506
19507 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19508 ++cnt)
19509 {
19510 Elf32_Lib liblist;
91d6fa6a 19511 time_t atime;
d5b07ef4 19512 char timebuf[128];
2cf0635d 19513 struct tm * tmp;
047b2264
JJ
19514
19515 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19516 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19517 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19518 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19519 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19520
91d6fa6a 19521 tmp = gmtime (&atime);
e9e44622
JJ
19522 snprintf (timebuf, sizeof (timebuf),
19523 "%04u-%02u-%02uT%02u:%02u:%02u",
19524 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19525 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 19526
26c527e6 19527 printf ("%3zu: ", cnt);
047b2264 19528 if (do_wide)
c256ffe7 19529 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19530 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19531 else
c256ffe7 19532 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19533 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19534 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19535 liblist.l_version, liblist.l_flags);
19536 }
19537
19538 free (elib);
2842702f 19539 free (strtab);
047b2264
JJ
19540 }
19541 }
19542
32ec8896 19543 return res;
047b2264
JJ
19544}
19545
9437c45b 19546static const char *
dda8d76d 19547get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19548{
19549 static char buff[64];
103f02d3 19550
dda8d76d 19551 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19552 switch (e_type)
19553 {
57346661 19554 case NT_AUXV:
1ec5cd37 19555 return _("NT_AUXV (auxiliary vector)");
57346661 19556 case NT_PRSTATUS:
1ec5cd37 19557 return _("NT_PRSTATUS (prstatus structure)");
57346661 19558 case NT_FPREGSET:
1ec5cd37 19559 return _("NT_FPREGSET (floating point registers)");
57346661 19560 case NT_PRPSINFO:
1ec5cd37 19561 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19562 case NT_TASKSTRUCT:
1ec5cd37 19563 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19564 case NT_GDB_TDESC:
19565 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19566 case NT_PRXFPREG:
1ec5cd37 19567 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19568 case NT_PPC_VMX:
19569 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19570 case NT_PPC_VSX:
19571 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19572 case NT_PPC_TAR:
19573 return _("NT_PPC_TAR (ppc TAR register)");
19574 case NT_PPC_PPR:
19575 return _("NT_PPC_PPR (ppc PPR register)");
19576 case NT_PPC_DSCR:
19577 return _("NT_PPC_DSCR (ppc DSCR register)");
19578 case NT_PPC_EBB:
19579 return _("NT_PPC_EBB (ppc EBB registers)");
19580 case NT_PPC_PMU:
19581 return _("NT_PPC_PMU (ppc PMU registers)");
19582 case NT_PPC_TM_CGPR:
19583 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19584 case NT_PPC_TM_CFPR:
19585 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19586 case NT_PPC_TM_CVMX:
19587 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19588 case NT_PPC_TM_CVSX:
3fd21718 19589 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19590 case NT_PPC_TM_SPR:
19591 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19592 case NT_PPC_TM_CTAR:
19593 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19594 case NT_PPC_TM_CPPR:
19595 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19596 case NT_PPC_TM_CDSCR:
19597 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19598 case NT_386_TLS:
19599 return _("NT_386_TLS (x86 TLS information)");
19600 case NT_386_IOPERM:
19601 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19602 case NT_X86_XSTATE:
19603 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19604 case NT_X86_CET:
19605 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19606 case NT_S390_HIGH_GPRS:
19607 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19608 case NT_S390_TIMER:
19609 return _("NT_S390_TIMER (s390 timer register)");
19610 case NT_S390_TODCMP:
19611 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19612 case NT_S390_TODPREG:
19613 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19614 case NT_S390_CTRS:
19615 return _("NT_S390_CTRS (s390 control registers)");
19616 case NT_S390_PREFIX:
19617 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19618 case NT_S390_LAST_BREAK:
19619 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19620 case NT_S390_SYSTEM_CALL:
19621 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19622 case NT_S390_TDB:
19623 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19624 case NT_S390_VXRS_LOW:
19625 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19626 case NT_S390_VXRS_HIGH:
19627 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19628 case NT_S390_GS_CB:
19629 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19630 case NT_S390_GS_BC:
19631 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19632 case NT_ARM_VFP:
19633 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19634 case NT_ARM_TLS:
19635 return _("NT_ARM_TLS (AArch TLS registers)");
19636 case NT_ARM_HW_BREAK:
19637 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19638 case NT_ARM_HW_WATCH:
19639 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
19640 case NT_ARM_SYSTEM_CALL:
19641 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
19642 case NT_ARM_SVE:
19643 return _("NT_ARM_SVE (AArch SVE registers)");
19644 case NT_ARM_PAC_MASK:
19645 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19646 case NT_ARM_PACA_KEYS:
19647 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19648 case NT_ARM_PACG_KEYS:
19649 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19650 case NT_ARM_TAGGED_ADDR_CTRL:
19651 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
a8f175d9
LM
19652 case NT_ARM_SSVE:
19653 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
19654 case NT_ARM_ZA:
19655 return _("NT_ARM_ZA (AArch64 SME ZA register)");
3af2785c
LM
19656 case NT_ARM_PAC_ENABLED_KEYS:
19657 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19658 case NT_ARC_V2:
19659 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19660 case NT_RISCV_CSR:
19661 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19662 case NT_PSTATUS:
1ec5cd37 19663 return _("NT_PSTATUS (pstatus structure)");
57346661 19664 case NT_FPREGS:
1ec5cd37 19665 return _("NT_FPREGS (floating point registers)");
57346661 19666 case NT_PSINFO:
1ec5cd37 19667 return _("NT_PSINFO (psinfo structure)");
57346661 19668 case NT_LWPSTATUS:
1ec5cd37 19669 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19670 case NT_LWPSINFO:
1ec5cd37 19671 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19672 case NT_WIN32PSTATUS:
1ec5cd37 19673 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19674 case NT_SIGINFO:
19675 return _("NT_SIGINFO (siginfo_t data)");
19676 case NT_FILE:
19677 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19678 default:
19679 break;
19680 }
19681 else
19682 switch (e_type)
19683 {
19684 case NT_VERSION:
19685 return _("NT_VERSION (version)");
19686 case NT_ARCH:
19687 return _("NT_ARCH (architecture)");
9ef920e9 19688 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19689 return _("OPEN");
9ef920e9 19690 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19691 return _("func");
c8795e1f
NC
19692 case NT_GO_BUILDID:
19693 return _("GO BUILDID");
3ac925fc
LB
19694 case FDO_PACKAGING_METADATA:
19695 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19696 default:
19697 break;
19698 }
19699
e9e44622 19700 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19701 return buff;
779fe533
NC
19702}
19703
015dc7e1 19704static bool
9ece1fa9
TT
19705print_core_note (Elf_Internal_Note *pnote)
19706{
19707 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 19708 uint64_t count, page_size;
9ece1fa9
TT
19709 unsigned char *descdata, *filenames, *descend;
19710
19711 if (pnote->type != NT_FILE)
04ac15ab
AS
19712 {
19713 if (do_wide)
19714 printf ("\n");
015dc7e1 19715 return true;
04ac15ab 19716 }
9ece1fa9 19717
9ece1fa9
TT
19718 if (!is_32bit_elf)
19719 {
19720 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19721 /* Still "successful". */
015dc7e1 19722 return true;
9ece1fa9 19723 }
9ece1fa9
TT
19724
19725 if (pnote->descsz < 2 * addr_size)
19726 {
32ec8896 19727 error (_(" Malformed note - too short for header\n"));
015dc7e1 19728 return false;
9ece1fa9
TT
19729 }
19730
19731 descdata = (unsigned char *) pnote->descdata;
19732 descend = descdata + pnote->descsz;
19733
19734 if (descdata[pnote->descsz - 1] != '\0')
19735 {
32ec8896 19736 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19737 return false;
9ece1fa9
TT
19738 }
19739
19740 count = byte_get (descdata, addr_size);
19741 descdata += addr_size;
19742
19743 page_size = byte_get (descdata, addr_size);
19744 descdata += addr_size;
19745
625d49fc 19746 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 19747 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19748 {
32ec8896 19749 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19750 return false;
9ece1fa9
TT
19751 }
19752
19753 printf (_(" Page size: "));
19754 print_vma (page_size, DEC);
19755 printf ("\n");
19756
19757 printf (_(" %*s%*s%*s\n"),
19758 (int) (2 + 2 * addr_size), _("Start"),
19759 (int) (4 + 2 * addr_size), _("End"),
19760 (int) (4 + 2 * addr_size), _("Page Offset"));
19761 filenames = descdata + count * 3 * addr_size;
595712bb 19762 while (count-- > 0)
9ece1fa9 19763 {
625d49fc 19764 uint64_t start, end, file_ofs;
9ece1fa9
TT
19765
19766 if (filenames == descend)
19767 {
32ec8896 19768 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19769 return false;
9ece1fa9
TT
19770 }
19771
19772 start = byte_get (descdata, addr_size);
19773 descdata += addr_size;
19774 end = byte_get (descdata, addr_size);
19775 descdata += addr_size;
19776 file_ofs = byte_get (descdata, addr_size);
19777 descdata += addr_size;
19778
19779 printf (" ");
19780 print_vma (start, FULL_HEX);
19781 printf (" ");
19782 print_vma (end, FULL_HEX);
19783 printf (" ");
19784 print_vma (file_ofs, FULL_HEX);
19785 printf ("\n %s\n", filenames);
19786
19787 filenames += 1 + strlen ((char *) filenames);
19788 }
19789
015dc7e1 19790 return true;
9ece1fa9
TT
19791}
19792
1118d252
RM
19793static const char *
19794get_gnu_elf_note_type (unsigned e_type)
19795{
1449284b 19796 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19797 switch (e_type)
19798 {
19799 case NT_GNU_ABI_TAG:
19800 return _("NT_GNU_ABI_TAG (ABI version tag)");
19801 case NT_GNU_HWCAP:
19802 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19803 case NT_GNU_BUILD_ID:
19804 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19805 case NT_GNU_GOLD_VERSION:
19806 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19807 case NT_GNU_PROPERTY_TYPE_0:
19808 return _("NT_GNU_PROPERTY_TYPE_0");
19809 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19810 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19811 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19812 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19813 default:
1449284b
NC
19814 {
19815 static char buff[64];
1118d252 19816
1449284b
NC
19817 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19818 return buff;
19819 }
19820 }
1118d252
RM
19821}
19822
a9eafb08
L
19823static void
19824decode_x86_compat_isa (unsigned int bitmask)
19825{
19826 while (bitmask)
19827 {
19828 unsigned int bit = bitmask & (- bitmask);
19829
19830 bitmask &= ~ bit;
19831 switch (bit)
19832 {
19833 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19834 printf ("i486");
19835 break;
19836 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19837 printf ("586");
19838 break;
19839 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19840 printf ("686");
19841 break;
19842 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19843 printf ("SSE");
19844 break;
19845 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19846 printf ("SSE2");
19847 break;
19848 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19849 printf ("SSE3");
19850 break;
19851 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19852 printf ("SSSE3");
19853 break;
19854 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19855 printf ("SSE4_1");
19856 break;
19857 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19858 printf ("SSE4_2");
19859 break;
19860 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19861 printf ("AVX");
19862 break;
19863 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19864 printf ("AVX2");
19865 break;
19866 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19867 printf ("AVX512F");
19868 break;
19869 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19870 printf ("AVX512CD");
19871 break;
19872 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19873 printf ("AVX512ER");
19874 break;
19875 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19876 printf ("AVX512PF");
19877 break;
19878 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19879 printf ("AVX512VL");
19880 break;
19881 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19882 printf ("AVX512DQ");
19883 break;
19884 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19885 printf ("AVX512BW");
19886 break;
65b3d26e
L
19887 default:
19888 printf (_("<unknown: %x>"), bit);
19889 break;
a9eafb08
L
19890 }
19891 if (bitmask)
19892 printf (", ");
19893 }
19894}
19895
9ef920e9 19896static void
32930e4e 19897decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19898{
0a59decb 19899 if (!bitmask)
90c745dc
L
19900 {
19901 printf (_("<None>"));
19902 return;
19903 }
90c745dc 19904
9ef920e9
NC
19905 while (bitmask)
19906 {
1fc87489 19907 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19908
19909 bitmask &= ~ bit;
19910 switch (bit)
19911 {
32930e4e 19912 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19913 printf ("CMOV");
19914 break;
32930e4e 19915 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19916 printf ("SSE");
19917 break;
32930e4e 19918 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19919 printf ("SSE2");
19920 break;
32930e4e 19921 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19922 printf ("SSE3");
19923 break;
32930e4e 19924 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19925 printf ("SSSE3");
19926 break;
32930e4e 19927 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19928 printf ("SSE4_1");
19929 break;
32930e4e 19930 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19931 printf ("SSE4_2");
19932 break;
32930e4e 19933 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19934 printf ("AVX");
19935 break;
32930e4e 19936 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19937 printf ("AVX2");
19938 break;
32930e4e 19939 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19940 printf ("FMA");
19941 break;
32930e4e 19942 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19943 printf ("AVX512F");
19944 break;
32930e4e 19945 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19946 printf ("AVX512CD");
19947 break;
32930e4e 19948 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19949 printf ("AVX512ER");
19950 break;
32930e4e 19951 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19952 printf ("AVX512PF");
19953 break;
32930e4e 19954 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19955 printf ("AVX512VL");
19956 break;
32930e4e 19957 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19958 printf ("AVX512DQ");
19959 break;
32930e4e 19960 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19961 printf ("AVX512BW");
19962 break;
32930e4e 19963 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19964 printf ("AVX512_4FMAPS");
19965 break;
32930e4e 19966 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19967 printf ("AVX512_4VNNIW");
19968 break;
32930e4e 19969 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19970 printf ("AVX512_BITALG");
19971 break;
32930e4e 19972 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19973 printf ("AVX512_IFMA");
19974 break;
32930e4e 19975 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19976 printf ("AVX512_VBMI");
19977 break;
32930e4e 19978 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19979 printf ("AVX512_VBMI2");
19980 break;
32930e4e 19981 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19982 printf ("AVX512_VNNI");
19983 break;
32930e4e 19984 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19985 printf ("AVX512_BF16");
19986 break;
65b3d26e
L
19987 default:
19988 printf (_("<unknown: %x>"), bit);
19989 break;
9ef920e9
NC
19990 }
19991 if (bitmask)
19992 printf (", ");
19993 }
19994}
19995
28cdbb18
SM
19996static const char *
19997get_amdgpu_elf_note_type (unsigned int e_type)
19998{
19999 switch (e_type)
20000 {
20001 case NT_AMDGPU_METADATA:
20002 return _("NT_AMDGPU_METADATA (code object metadata)");
20003 default:
20004 {
20005 static char buf[64];
20006 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
20007 return buf;
20008 }
20009 }
20010}
20011
32930e4e
L
20012static void
20013decode_x86_isa (unsigned int bitmask)
20014{
32930e4e
L
20015 while (bitmask)
20016 {
20017 unsigned int bit = bitmask & (- bitmask);
20018
20019 bitmask &= ~ bit;
20020 switch (bit)
20021 {
b0ab0693
L
20022 case GNU_PROPERTY_X86_ISA_1_BASELINE:
20023 printf ("x86-64-baseline");
20024 break;
32930e4e
L
20025 case GNU_PROPERTY_X86_ISA_1_V2:
20026 printf ("x86-64-v2");
20027 break;
20028 case GNU_PROPERTY_X86_ISA_1_V3:
20029 printf ("x86-64-v3");
20030 break;
20031 case GNU_PROPERTY_X86_ISA_1_V4:
20032 printf ("x86-64-v4");
20033 break;
20034 default:
20035 printf (_("<unknown: %x>"), bit);
20036 break;
20037 }
20038 if (bitmask)
20039 printf (", ");
20040 }
20041}
20042
ee2fdd6f 20043static void
a9eafb08 20044decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 20045{
0a59decb 20046 if (!bitmask)
90c745dc
L
20047 {
20048 printf (_("<None>"));
20049 return;
20050 }
90c745dc 20051
ee2fdd6f
L
20052 while (bitmask)
20053 {
20054 unsigned int bit = bitmask & (- bitmask);
20055
20056 bitmask &= ~ bit;
20057 switch (bit)
20058 {
20059 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 20060 printf ("IBT");
ee2fdd6f 20061 break;
48580982 20062 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 20063 printf ("SHSTK");
48580982 20064 break;
279d901e
L
20065 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
20066 printf ("LAM_U48");
20067 break;
20068 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
20069 printf ("LAM_U57");
20070 break;
ee2fdd6f
L
20071 default:
20072 printf (_("<unknown: %x>"), bit);
20073 break;
20074 }
20075 if (bitmask)
20076 printf (", ");
20077 }
20078}
20079
a9eafb08
L
20080static void
20081decode_x86_feature_2 (unsigned int bitmask)
20082{
0a59decb 20083 if (!bitmask)
90c745dc
L
20084 {
20085 printf (_("<None>"));
20086 return;
20087 }
90c745dc 20088
a9eafb08
L
20089 while (bitmask)
20090 {
20091 unsigned int bit = bitmask & (- bitmask);
20092
20093 bitmask &= ~ bit;
20094 switch (bit)
20095 {
20096 case GNU_PROPERTY_X86_FEATURE_2_X86:
20097 printf ("x86");
20098 break;
20099 case GNU_PROPERTY_X86_FEATURE_2_X87:
20100 printf ("x87");
20101 break;
20102 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20103 printf ("MMX");
20104 break;
20105 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20106 printf ("XMM");
20107 break;
20108 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20109 printf ("YMM");
20110 break;
20111 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20112 printf ("ZMM");
20113 break;
a308b89d
L
20114 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20115 printf ("TMM");
20116 break;
32930e4e
L
20117 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20118 printf ("MASK");
20119 break;
a9eafb08
L
20120 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20121 printf ("FXSR");
20122 break;
20123 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20124 printf ("XSAVE");
20125 break;
20126 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20127 printf ("XSAVEOPT");
20128 break;
20129 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20130 printf ("XSAVEC");
20131 break;
65b3d26e
L
20132 default:
20133 printf (_("<unknown: %x>"), bit);
20134 break;
a9eafb08
L
20135 }
20136 if (bitmask)
20137 printf (", ");
20138 }
20139}
20140
cd702818
SD
20141static void
20142decode_aarch64_feature_1_and (unsigned int bitmask)
20143{
20144 while (bitmask)
20145 {
20146 unsigned int bit = bitmask & (- bitmask);
20147
20148 bitmask &= ~ bit;
20149 switch (bit)
20150 {
20151 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20152 printf ("BTI");
20153 break;
20154
20155 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20156 printf ("PAC");
20157 break;
20158
20159 default:
20160 printf (_("<unknown: %x>"), bit);
20161 break;
20162 }
20163 if (bitmask)
20164 printf (", ");
20165 }
20166}
20167
6320fd00
L
20168static void
20169decode_1_needed (unsigned int bitmask)
20170{
20171 while (bitmask)
20172 {
20173 unsigned int bit = bitmask & (- bitmask);
20174
20175 bitmask &= ~ bit;
20176 switch (bit)
20177 {
20178 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20179 printf ("indirect external access");
20180 break;
20181 default:
20182 printf (_("<unknown: %x>"), bit);
20183 break;
20184 }
20185 if (bitmask)
20186 printf (", ");
20187 }
20188}
20189
9ef920e9 20190static void
dda8d76d 20191print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
20192{
20193 unsigned char * ptr = (unsigned char *) pnote->descdata;
20194 unsigned char * ptr_end = ptr + pnote->descsz;
20195 unsigned int size = is_32bit_elf ? 4 : 8;
20196
20197 printf (_(" Properties: "));
20198
1fc87489 20199 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
20200 {
20201 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
20202 return;
20203 }
20204
6ab2c4ed 20205 while (ptr < ptr_end)
9ef920e9 20206 {
1fc87489 20207 unsigned int j;
6ab2c4ed
MC
20208 unsigned int type;
20209 unsigned int datasz;
20210
20211 if ((size_t) (ptr_end - ptr) < 8)
20212 {
20213 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
20214 break;
20215 }
20216
20217 type = byte_get (ptr, 4);
20218 datasz = byte_get (ptr + 4, 4);
9ef920e9 20219
1fc87489 20220 ptr += 8;
9ef920e9 20221
6ab2c4ed 20222 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 20223 {
1fc87489
L
20224 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
20225 type, datasz);
9ef920e9 20226 break;
1fc87489 20227 }
9ef920e9 20228
1fc87489
L
20229 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20230 {
dda8d76d
NC
20231 if (filedata->file_header.e_machine == EM_X86_64
20232 || filedata->file_header.e_machine == EM_IAMCU
20233 || filedata->file_header.e_machine == EM_386)
1fc87489 20234 {
aa7bca9b
L
20235 unsigned int bitmask;
20236
20237 if (datasz == 4)
0a59decb 20238 bitmask = byte_get (ptr, 4);
aa7bca9b
L
20239 else
20240 bitmask = 0;
20241
1fc87489
L
20242 switch (type)
20243 {
20244 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 20245 if (datasz != 4)
aa7bca9b
L
20246 printf (_("x86 ISA used: <corrupt length: %#x> "),
20247 datasz);
1fc87489 20248 else
aa7bca9b
L
20249 {
20250 printf ("x86 ISA used: ");
20251 decode_x86_isa (bitmask);
20252 }
1fc87489 20253 goto next;
9ef920e9 20254
1fc87489 20255 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20256 if (datasz != 4)
aa7bca9b
L
20257 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20258 datasz);
1fc87489 20259 else
aa7bca9b
L
20260 {
20261 printf ("x86 ISA needed: ");
20262 decode_x86_isa (bitmask);
20263 }
1fc87489 20264 goto next;
9ef920e9 20265
ee2fdd6f 20266 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20267 if (datasz != 4)
aa7bca9b
L
20268 printf (_("x86 feature: <corrupt length: %#x> "),
20269 datasz);
ee2fdd6f 20270 else
aa7bca9b
L
20271 {
20272 printf ("x86 feature: ");
a9eafb08
L
20273 decode_x86_feature_1 (bitmask);
20274 }
20275 goto next;
20276
20277 case GNU_PROPERTY_X86_FEATURE_2_USED:
20278 if (datasz != 4)
20279 printf (_("x86 feature used: <corrupt length: %#x> "),
20280 datasz);
20281 else
20282 {
20283 printf ("x86 feature used: ");
20284 decode_x86_feature_2 (bitmask);
20285 }
20286 goto next;
20287
20288 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20289 if (datasz != 4)
20290 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20291 else
20292 {
20293 printf ("x86 feature needed: ");
20294 decode_x86_feature_2 (bitmask);
20295 }
20296 goto next;
20297
20298 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20299 if (datasz != 4)
20300 printf (_("x86 ISA used: <corrupt length: %#x> "),
20301 datasz);
20302 else
20303 {
20304 printf ("x86 ISA used: ");
20305 decode_x86_compat_isa (bitmask);
20306 }
20307 goto next;
20308
20309 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20310 if (datasz != 4)
20311 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20312 datasz);
20313 else
20314 {
20315 printf ("x86 ISA needed: ");
20316 decode_x86_compat_isa (bitmask);
aa7bca9b 20317 }
ee2fdd6f
L
20318 goto next;
20319
32930e4e
L
20320 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20321 if (datasz != 4)
20322 printf (_("x86 ISA used: <corrupt length: %#x> "),
20323 datasz);
20324 else
20325 {
20326 printf ("x86 ISA used: ");
20327 decode_x86_compat_2_isa (bitmask);
20328 }
20329 goto next;
20330
20331 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20332 if (datasz != 4)
20333 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20334 datasz);
20335 else
20336 {
20337 printf ("x86 ISA needed: ");
20338 decode_x86_compat_2_isa (bitmask);
20339 }
20340 goto next;
20341
1fc87489
L
20342 default:
20343 break;
20344 }
20345 }
cd702818
SD
20346 else if (filedata->file_header.e_machine == EM_AARCH64)
20347 {
20348 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20349 {
20350 printf ("AArch64 feature: ");
20351 if (datasz != 4)
20352 printf (_("<corrupt length: %#x> "), datasz);
20353 else
20354 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20355 goto next;
20356 }
20357 }
1fc87489
L
20358 }
20359 else
20360 {
20361 switch (type)
9ef920e9 20362 {
1fc87489
L
20363 case GNU_PROPERTY_STACK_SIZE:
20364 printf (_("stack size: "));
20365 if (datasz != size)
20366 printf (_("<corrupt length: %#x> "), datasz);
20367 else
26c527e6 20368 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
20369 goto next;
20370
20371 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20372 printf ("no copy on protected ");
20373 if (datasz)
20374 printf (_("<corrupt length: %#x> "), datasz);
20375 goto next;
20376
20377 default:
5a767724
L
20378 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20379 && type <= GNU_PROPERTY_UINT32_AND_HI)
20380 || (type >= GNU_PROPERTY_UINT32_OR_LO
20381 && type <= GNU_PROPERTY_UINT32_OR_HI))
20382 {
6320fd00
L
20383 switch (type)
20384 {
20385 case GNU_PROPERTY_1_NEEDED:
20386 if (datasz != 4)
20387 printf (_("1_needed: <corrupt length: %#x> "),
20388 datasz);
20389 else
20390 {
20391 unsigned int bitmask = byte_get (ptr, 4);
20392 printf ("1_needed: ");
20393 decode_1_needed (bitmask);
20394 }
20395 goto next;
20396
20397 default:
20398 break;
20399 }
5a767724
L
20400 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20401 printf (_("UINT32_AND (%#x): "), type);
20402 else
20403 printf (_("UINT32_OR (%#x): "), type);
20404 if (datasz != 4)
20405 printf (_("<corrupt length: %#x> "), datasz);
20406 else
20407 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20408 goto next;
20409 }
9ef920e9
NC
20410 break;
20411 }
9ef920e9
NC
20412 }
20413
1fc87489
L
20414 if (type < GNU_PROPERTY_LOPROC)
20415 printf (_("<unknown type %#x data: "), type);
20416 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20417 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20418 else
20419 printf (_("<application-specific type %#x data: "), type);
20420 for (j = 0; j < datasz; ++j)
20421 printf ("%02x ", ptr[j] & 0xff);
20422 printf (">");
20423
dc1e8a47 20424 next:
9ef920e9 20425 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20426 if (ptr == ptr_end)
20427 break;
1fc87489 20428
6ab2c4ed
MC
20429 if (do_wide)
20430 printf (", ");
20431 else
20432 printf ("\n\t");
9ef920e9
NC
20433 }
20434
20435 printf ("\n");
20436}
20437
015dc7e1 20438static bool
dda8d76d 20439print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20440{
1449284b 20441 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20442 switch (pnote->type)
20443 {
20444 case NT_GNU_BUILD_ID:
20445 {
26c527e6 20446 size_t i;
664f90a3
TT
20447
20448 printf (_(" Build ID: "));
20449 for (i = 0; i < pnote->descsz; ++i)
20450 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20451 printf ("\n");
664f90a3
TT
20452 }
20453 break;
20454
20455 case NT_GNU_ABI_TAG:
20456 {
26c527e6 20457 unsigned int os, major, minor, subminor;
664f90a3
TT
20458 const char *osname;
20459
3102e897
NC
20460 /* PR 17531: file: 030-599401-0.004. */
20461 if (pnote->descsz < 16)
20462 {
20463 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20464 break;
20465 }
20466
664f90a3
TT
20467 os = byte_get ((unsigned char *) pnote->descdata, 4);
20468 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20469 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20470 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20471
20472 switch (os)
20473 {
20474 case GNU_ABI_TAG_LINUX:
20475 osname = "Linux";
20476 break;
20477 case GNU_ABI_TAG_HURD:
20478 osname = "Hurd";
20479 break;
20480 case GNU_ABI_TAG_SOLARIS:
20481 osname = "Solaris";
20482 break;
20483 case GNU_ABI_TAG_FREEBSD:
20484 osname = "FreeBSD";
20485 break;
20486 case GNU_ABI_TAG_NETBSD:
20487 osname = "NetBSD";
20488 break;
14ae95f2
RM
20489 case GNU_ABI_TAG_SYLLABLE:
20490 osname = "Syllable";
20491 break;
20492 case GNU_ABI_TAG_NACL:
20493 osname = "NaCl";
20494 break;
664f90a3
TT
20495 default:
20496 osname = "Unknown";
20497 break;
20498 }
20499
26c527e6 20500 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
20501 major, minor, subminor);
20502 }
20503 break;
926c5385
CC
20504
20505 case NT_GNU_GOLD_VERSION:
20506 {
26c527e6 20507 size_t i;
926c5385
CC
20508
20509 printf (_(" Version: "));
20510 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20511 printf ("%c", pnote->descdata[i]);
20512 printf ("\n");
20513 }
20514 break;
1449284b
NC
20515
20516 case NT_GNU_HWCAP:
20517 {
26c527e6 20518 unsigned int num_entries, mask;
1449284b
NC
20519
20520 /* Hardware capabilities information. Word 0 is the number of entries.
20521 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20522 is a series of entries, where each entry is a single byte followed
20523 by a nul terminated string. The byte gives the bit number to test
20524 if enabled in the bitmask. */
20525 printf (_(" Hardware Capabilities: "));
20526 if (pnote->descsz < 8)
20527 {
32ec8896 20528 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20529 return false;
1449284b
NC
20530 }
20531 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20532 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 20533 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
20534 /* FIXME: Add code to display the entries... */
20535 }
20536 break;
20537
9ef920e9 20538 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20539 print_gnu_property_note (filedata, pnote);
9ef920e9 20540 break;
9abca702 20541
1449284b
NC
20542 default:
20543 /* Handle unrecognised types. An error message should have already been
20544 created by get_gnu_elf_note_type(), so all that we need to do is to
20545 display the data. */
20546 {
26c527e6 20547 size_t i;
1449284b
NC
20548
20549 printf (_(" Description data: "));
20550 for (i = 0; i < pnote->descsz; ++i)
20551 printf ("%02x ", pnote->descdata[i] & 0xff);
20552 printf ("\n");
20553 }
20554 break;
664f90a3
TT
20555 }
20556
015dc7e1 20557 return true;
664f90a3
TT
20558}
20559
685080f2
NC
20560static const char *
20561get_v850_elf_note_type (enum v850_notes n_type)
20562{
20563 static char buff[64];
20564
20565 switch (n_type)
20566 {
20567 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20568 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20569 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20570 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20571 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20572 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20573 default:
20574 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20575 return buff;
20576 }
20577}
20578
015dc7e1 20579static bool
685080f2
NC
20580print_v850_note (Elf_Internal_Note * pnote)
20581{
20582 unsigned int val;
20583
20584 if (pnote->descsz != 4)
015dc7e1 20585 return false;
32ec8896 20586
685080f2
NC
20587 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20588
20589 if (val == 0)
20590 {
20591 printf (_("not set\n"));
015dc7e1 20592 return true;
685080f2
NC
20593 }
20594
20595 switch (pnote->type)
20596 {
20597 case V850_NOTE_ALIGNMENT:
20598 switch (val)
20599 {
015dc7e1
AM
20600 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20601 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20602 }
20603 break;
14ae95f2 20604
685080f2
NC
20605 case V850_NOTE_DATA_SIZE:
20606 switch (val)
20607 {
015dc7e1
AM
20608 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20609 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20610 }
20611 break;
14ae95f2 20612
685080f2
NC
20613 case V850_NOTE_FPU_INFO:
20614 switch (val)
20615 {
015dc7e1
AM
20616 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20617 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20618 }
20619 break;
14ae95f2 20620
685080f2
NC
20621 case V850_NOTE_MMU_INFO:
20622 case V850_NOTE_CACHE_INFO:
20623 case V850_NOTE_SIMD_INFO:
20624 if (val == EF_RH850_SIMD)
20625 {
20626 printf (_("yes\n"));
015dc7e1 20627 return true;
685080f2
NC
20628 }
20629 break;
20630
20631 default:
20632 /* An 'unknown note type' message will already have been displayed. */
20633 break;
20634 }
20635
20636 printf (_("unknown value: %x\n"), val);
015dc7e1 20637 return false;
685080f2
NC
20638}
20639
015dc7e1 20640static bool
c6056a74
SF
20641process_netbsd_elf_note (Elf_Internal_Note * pnote)
20642{
20643 unsigned int version;
20644
20645 switch (pnote->type)
20646 {
20647 case NT_NETBSD_IDENT:
b966f55f
AM
20648 if (pnote->descsz < 1)
20649 break;
c6056a74
SF
20650 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20651 if ((version / 10000) % 100)
b966f55f 20652 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20653 version, version / 100000000, (version / 1000000) % 100,
20654 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20655 'A' + (version / 10000) % 26);
c6056a74
SF
20656 else
20657 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20658 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20659 (version / 100) % 100);
015dc7e1 20660 return true;
c6056a74
SF
20661
20662 case NT_NETBSD_MARCH:
9abca702 20663 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20664 pnote->descdata);
015dc7e1 20665 return true;
c6056a74 20666
9abca702 20667 case NT_NETBSD_PAX:
b966f55f
AM
20668 if (pnote->descsz < 1)
20669 break;
9abca702
CZ
20670 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20671 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20672 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20673 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20674 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20675 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20676 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20677 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20678 return true;
c6056a74 20679 }
b966f55f
AM
20680
20681 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20682 pnote->descsz, pnote->type);
015dc7e1 20683 return false;
c6056a74
SF
20684}
20685
f4ddf30f 20686static const char *
dda8d76d 20687get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20688{
f4ddf30f
JB
20689 switch (e_type)
20690 {
20691 case NT_FREEBSD_THRMISC:
20692 return _("NT_THRMISC (thrmisc structure)");
20693 case NT_FREEBSD_PROCSTAT_PROC:
20694 return _("NT_PROCSTAT_PROC (proc data)");
20695 case NT_FREEBSD_PROCSTAT_FILES:
20696 return _("NT_PROCSTAT_FILES (files data)");
20697 case NT_FREEBSD_PROCSTAT_VMMAP:
20698 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20699 case NT_FREEBSD_PROCSTAT_GROUPS:
20700 return _("NT_PROCSTAT_GROUPS (groups data)");
20701 case NT_FREEBSD_PROCSTAT_UMASK:
20702 return _("NT_PROCSTAT_UMASK (umask data)");
20703 case NT_FREEBSD_PROCSTAT_RLIMIT:
20704 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20705 case NT_FREEBSD_PROCSTAT_OSREL:
20706 return _("NT_PROCSTAT_OSREL (osreldate data)");
20707 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20708 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20709 case NT_FREEBSD_PROCSTAT_AUXV:
20710 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20711 case NT_FREEBSD_PTLWPINFO:
20712 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
20713 case NT_FREEBSD_X86_SEGBASES:
20714 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 20715 }
dda8d76d 20716 return get_note_type (filedata, e_type);
f4ddf30f
JB
20717}
20718
9437c45b 20719static const char *
dda8d76d 20720get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20721{
20722 static char buff[64];
20723
540e6170
CZ
20724 switch (e_type)
20725 {
20726 case NT_NETBSDCORE_PROCINFO:
20727 /* NetBSD core "procinfo" structure. */
20728 return _("NetBSD procinfo structure");
9437c45b 20729
540e6170
CZ
20730 case NT_NETBSDCORE_AUXV:
20731 return _("NetBSD ELF auxiliary vector data");
9437c45b 20732
06d949ec
KR
20733 case NT_NETBSDCORE_LWPSTATUS:
20734 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20735
540e6170 20736 default:
06d949ec 20737 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20738 defined for NetBSD core files. If the note type is less
20739 than the start of the machine-dependent note types, we don't
20740 understand it. */
20741
20742 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20743 {
20744 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20745 return buff;
20746 }
20747 break;
9437c45b
JT
20748 }
20749
dda8d76d 20750 switch (filedata->file_header.e_machine)
9437c45b
JT
20751 {
20752 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20753 and PT_GETFPREGS == mach+2. */
20754
20755 case EM_OLD_ALPHA:
20756 case EM_ALPHA:
20757 case EM_SPARC:
20758 case EM_SPARC32PLUS:
20759 case EM_SPARCV9:
20760 switch (e_type)
20761 {
2b692964 20762 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20763 return _("PT_GETREGS (reg structure)");
2b692964 20764 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20765 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20766 default:
20767 break;
20768 }
20769 break;
20770
c0d38b0e
CZ
20771 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20772 There's also old PT___GETREGS40 == mach + 1 for old reg
20773 structure which lacks GBR. */
20774 case EM_SH:
20775 switch (e_type)
20776 {
20777 case NT_NETBSDCORE_FIRSTMACH + 1:
20778 return _("PT___GETREGS40 (old reg structure)");
20779 case NT_NETBSDCORE_FIRSTMACH + 3:
20780 return _("PT_GETREGS (reg structure)");
20781 case NT_NETBSDCORE_FIRSTMACH + 5:
20782 return _("PT_GETFPREGS (fpreg structure)");
20783 default:
20784 break;
20785 }
20786 break;
20787
9437c45b
JT
20788 /* On all other arch's, PT_GETREGS == mach+1 and
20789 PT_GETFPREGS == mach+3. */
20790 default:
20791 switch (e_type)
20792 {
2b692964 20793 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20794 return _("PT_GETREGS (reg structure)");
2b692964 20795 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20796 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20797 default:
20798 break;
20799 }
20800 }
20801
9cf03b7e 20802 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20803 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20804 return buff;
20805}
20806
98ca73af
FC
20807static const char *
20808get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20809{
20810 switch (e_type)
20811 {
20812 case NT_OPENBSD_PROCINFO:
20813 return _("OpenBSD procinfo structure");
20814 case NT_OPENBSD_AUXV:
20815 return _("OpenBSD ELF auxiliary vector data");
20816 case NT_OPENBSD_REGS:
20817 return _("OpenBSD regular registers");
20818 case NT_OPENBSD_FPREGS:
20819 return _("OpenBSD floating point registers");
20820 case NT_OPENBSD_WCOOKIE:
20821 return _("OpenBSD window cookie");
20822 }
20823
20824 return get_note_type (filedata, e_type);
20825}
20826
e263a66b
CC
20827static const char *
20828get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
20829{
20830 switch (e_type)
20831 {
20832 case QNT_DEBUG_FULLPATH:
20833 return _("QNX debug fullpath");
20834 case QNT_DEBUG_RELOC:
20835 return _("QNX debug relocation");
20836 case QNT_STACK:
20837 return _("QNX stack");
20838 case QNT_GENERATOR:
20839 return _("QNX generator");
20840 case QNT_DEFAULT_LIB:
20841 return _("QNX default library");
20842 case QNT_CORE_SYSINFO:
20843 return _("QNX core sysinfo");
20844 case QNT_CORE_INFO:
20845 return _("QNX core info");
20846 case QNT_CORE_STATUS:
20847 return _("QNX core status");
20848 case QNT_CORE_GREG:
20849 return _("QNX general registers");
20850 case QNT_CORE_FPREG:
20851 return _("QNX floating point registers");
20852 case QNT_LINK_MAP:
20853 return _("QNX link map");
20854 }
20855
20856 return get_note_type (filedata, e_type);
20857}
20858
70616151
TT
20859static const char *
20860get_stapsdt_note_type (unsigned e_type)
20861{
20862 static char buff[64];
20863
20864 switch (e_type)
20865 {
20866 case NT_STAPSDT:
20867 return _("NT_STAPSDT (SystemTap probe descriptors)");
20868
20869 default:
20870 break;
20871 }
20872
20873 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20874 return buff;
20875}
20876
015dc7e1 20877static bool
c6a9fc58
TT
20878print_stapsdt_note (Elf_Internal_Note *pnote)
20879{
3ca60c57 20880 size_t len, maxlen;
26c527e6 20881 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20882 char *data = pnote->descdata;
20883 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 20884 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
20885 char *provider, *probe, *arg_fmt;
20886
3ca60c57
NC
20887 if (pnote->descsz < (addr_size * 3))
20888 goto stapdt_note_too_small;
20889
c6a9fc58
TT
20890 pc = byte_get ((unsigned char *) data, addr_size);
20891 data += addr_size;
3ca60c57 20892
c6a9fc58
TT
20893 base_addr = byte_get ((unsigned char *) data, addr_size);
20894 data += addr_size;
3ca60c57 20895
c6a9fc58
TT
20896 semaphore = byte_get ((unsigned char *) data, addr_size);
20897 data += addr_size;
20898
3ca60c57
NC
20899 if (data >= data_end)
20900 goto stapdt_note_too_small;
20901 maxlen = data_end - data;
20902 len = strnlen (data, maxlen);
20903 if (len < maxlen)
20904 {
20905 provider = data;
20906 data += len + 1;
20907 }
20908 else
20909 goto stapdt_note_too_small;
20910
20911 if (data >= data_end)
20912 goto stapdt_note_too_small;
20913 maxlen = data_end - data;
20914 len = strnlen (data, maxlen);
20915 if (len < maxlen)
20916 {
20917 probe = data;
20918 data += len + 1;
20919 }
20920 else
20921 goto stapdt_note_too_small;
9abca702 20922
3ca60c57
NC
20923 if (data >= data_end)
20924 goto stapdt_note_too_small;
20925 maxlen = data_end - data;
20926 len = strnlen (data, maxlen);
20927 if (len < maxlen)
20928 {
20929 arg_fmt = data;
20930 data += len + 1;
20931 }
20932 else
20933 goto stapdt_note_too_small;
c6a9fc58
TT
20934
20935 printf (_(" Provider: %s\n"), provider);
20936 printf (_(" Name: %s\n"), probe);
20937 printf (_(" Location: "));
20938 print_vma (pc, FULL_HEX);
20939 printf (_(", Base: "));
20940 print_vma (base_addr, FULL_HEX);
20941 printf (_(", Semaphore: "));
20942 print_vma (semaphore, FULL_HEX);
9cf03b7e 20943 printf ("\n");
c6a9fc58
TT
20944 printf (_(" Arguments: %s\n"), arg_fmt);
20945
20946 return data == data_end;
3ca60c57
NC
20947
20948 stapdt_note_too_small:
20949 printf (_(" <corrupt - note is too small>\n"));
20950 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20951 return false;
c6a9fc58
TT
20952}
20953
e5382207
LB
20954static bool
20955print_fdo_note (Elf_Internal_Note * pnote)
20956{
20957 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20958 {
20959 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20960 return true;
20961 }
20962 return false;
20963}
20964
00e98fc7
TG
20965static const char *
20966get_ia64_vms_note_type (unsigned e_type)
20967{
20968 static char buff[64];
20969
20970 switch (e_type)
20971 {
20972 case NT_VMS_MHD:
20973 return _("NT_VMS_MHD (module header)");
20974 case NT_VMS_LNM:
20975 return _("NT_VMS_LNM (language name)");
20976 case NT_VMS_SRC:
20977 return _("NT_VMS_SRC (source files)");
20978 case NT_VMS_TITLE:
9cf03b7e 20979 return "NT_VMS_TITLE";
00e98fc7
TG
20980 case NT_VMS_EIDC:
20981 return _("NT_VMS_EIDC (consistency check)");
20982 case NT_VMS_FPMODE:
20983 return _("NT_VMS_FPMODE (FP mode)");
20984 case NT_VMS_LINKTIME:
9cf03b7e 20985 return "NT_VMS_LINKTIME";
00e98fc7
TG
20986 case NT_VMS_IMGNAM:
20987 return _("NT_VMS_IMGNAM (image name)");
20988 case NT_VMS_IMGID:
20989 return _("NT_VMS_IMGID (image id)");
20990 case NT_VMS_LINKID:
20991 return _("NT_VMS_LINKID (link id)");
20992 case NT_VMS_IMGBID:
20993 return _("NT_VMS_IMGBID (build id)");
20994 case NT_VMS_GSTNAM:
20995 return _("NT_VMS_GSTNAM (sym table name)");
20996 case NT_VMS_ORIG_DYN:
9cf03b7e 20997 return "NT_VMS_ORIG_DYN";
00e98fc7 20998 case NT_VMS_PATCHTIME:
9cf03b7e 20999 return "NT_VMS_PATCHTIME";
00e98fc7
TG
21000 default:
21001 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21002 return buff;
21003 }
21004}
21005
015dc7e1 21006static bool
00e98fc7
TG
21007print_ia64_vms_note (Elf_Internal_Note * pnote)
21008{
26c527e6 21009 unsigned int maxlen = pnote->descsz;
8d18bf79 21010
26c527e6 21011 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
21012 goto desc_size_fail;
21013
00e98fc7
TG
21014 switch (pnote->type)
21015 {
21016 case NT_VMS_MHD:
8d18bf79
NC
21017 if (maxlen <= 36)
21018 goto desc_size_fail;
21019
26c527e6 21020 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
21021
21022 printf (_(" Creation date : %.17s\n"), pnote->descdata);
21023 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
21024 if (l + 34 < maxlen)
21025 {
21026 printf (_(" Module name : %s\n"), pnote->descdata + 34);
21027 if (l + 35 < maxlen)
21028 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
21029 else
21030 printf (_(" Module version : <missing>\n"));
21031 }
00e98fc7 21032 else
8d18bf79
NC
21033 {
21034 printf (_(" Module name : <missing>\n"));
21035 printf (_(" Module version : <missing>\n"));
21036 }
00e98fc7 21037 break;
8d18bf79 21038
00e98fc7 21039 case NT_VMS_LNM:
8d18bf79 21040 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21041 break;
8d18bf79 21042
00e98fc7 21043 case NT_VMS_FPMODE:
9cf03b7e 21044 printf (_(" Floating Point mode: "));
8d18bf79
NC
21045 if (maxlen < 8)
21046 goto desc_size_fail;
21047 /* FIXME: Generate an error if descsz > 8 ? */
21048
b8281767 21049 printf ("0x%016" PRIx64 "\n",
625d49fc 21050 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 21051 break;
8d18bf79 21052
00e98fc7
TG
21053 case NT_VMS_LINKTIME:
21054 printf (_(" Link time: "));
8d18bf79
NC
21055 if (maxlen < 8)
21056 goto desc_size_fail;
21057 /* FIXME: Generate an error if descsz > 8 ? */
21058
0e3c1eeb 21059 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21060 printf ("\n");
21061 break;
8d18bf79 21062
00e98fc7
TG
21063 case NT_VMS_PATCHTIME:
21064 printf (_(" Patch time: "));
8d18bf79
NC
21065 if (maxlen < 8)
21066 goto desc_size_fail;
21067 /* FIXME: Generate an error if descsz > 8 ? */
21068
0e3c1eeb 21069 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21070 printf ("\n");
21071 break;
8d18bf79 21072
00e98fc7 21073 case NT_VMS_ORIG_DYN:
8d18bf79
NC
21074 if (maxlen < 34)
21075 goto desc_size_fail;
21076
00e98fc7 21077 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
21078 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
21079 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 21080 printf (_(" Last modified : "));
0e3c1eeb 21081 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 21082 printf (_("\n Link flags : "));
b8281767 21083 printf ("0x%016" PRIx64 "\n",
625d49fc 21084 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 21085 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 21086 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 21087 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 21088 break;
8d18bf79 21089
00e98fc7 21090 case NT_VMS_IMGNAM:
8d18bf79 21091 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21092 break;
8d18bf79 21093
00e98fc7 21094 case NT_VMS_GSTNAM:
8d18bf79 21095 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21096 break;
8d18bf79 21097
00e98fc7 21098 case NT_VMS_IMGID:
8d18bf79 21099 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21100 break;
8d18bf79 21101
00e98fc7 21102 case NT_VMS_LINKID:
8d18bf79 21103 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21104 break;
8d18bf79 21105
00e98fc7 21106 default:
015dc7e1 21107 return false;
00e98fc7 21108 }
8d18bf79 21109
015dc7e1 21110 return true;
8d18bf79
NC
21111
21112 desc_size_fail:
21113 printf (_(" <corrupt - data size is too small>\n"));
21114 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 21115 return false;
00e98fc7
TG
21116}
21117
fd486f32
AM
21118struct build_attr_cache {
21119 Filedata *filedata;
21120 char *strtab;
26c527e6 21121 uint64_t strtablen;
fd486f32 21122 Elf_Internal_Sym *symtab;
26c527e6 21123 uint64_t nsyms;
fd486f32
AM
21124} ba_cache;
21125
6f156d7a
NC
21126/* Find the symbol associated with a build attribute that is attached
21127 to address OFFSET. If PNAME is non-NULL then store the name of
21128 the symbol (if found) in the provided pointer, Returns NULL if a
21129 symbol could not be found. */
c799a79d 21130
6f156d7a 21131static Elf_Internal_Sym *
015dc7e1 21132get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 21133 uint64_t offset,
015dc7e1
AM
21134 bool is_open_attr,
21135 const char **pname)
9ef920e9 21136{
fd486f32
AM
21137 Elf_Internal_Sym *saved_sym = NULL;
21138 Elf_Internal_Sym *sym;
9ef920e9 21139
dda8d76d 21140 if (filedata->section_headers != NULL
fd486f32 21141 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 21142 {
c799a79d 21143 Elf_Internal_Shdr * symsec;
9ef920e9 21144
fd486f32
AM
21145 free (ba_cache.strtab);
21146 ba_cache.strtab = NULL;
21147 free (ba_cache.symtab);
21148 ba_cache.symtab = NULL;
21149
c799a79d 21150 /* Load the symbol and string sections. */
dda8d76d
NC
21151 for (symsec = filedata->section_headers;
21152 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 21153 symsec ++)
9ef920e9 21154 {
28d13567
AM
21155 if (symsec->sh_type == SHT_SYMTAB
21156 && get_symtab (filedata, symsec,
21157 &ba_cache.symtab, &ba_cache.nsyms,
21158 &ba_cache.strtab, &ba_cache.strtablen))
21159 break;
9ef920e9 21160 }
fd486f32 21161 ba_cache.filedata = filedata;
9ef920e9
NC
21162 }
21163
fd486f32 21164 if (ba_cache.symtab == NULL)
6f156d7a 21165 return NULL;
9ef920e9 21166
c799a79d 21167 /* Find a symbol whose value matches offset. */
fd486f32 21168 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
21169 if (sym->st_value == offset)
21170 {
fd486f32 21171 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
21172 /* Huh ? This should not happen. */
21173 continue;
9ef920e9 21174
fd486f32 21175 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 21176 continue;
9ef920e9 21177
9b9b1092 21178 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 21179 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
21180 if (ba_cache.strtab[sym->st_name] == '$'
21181 && ba_cache.strtab[sym->st_name + 1] != 0
21182 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
21183 continue;
21184
c799a79d
NC
21185 if (is_open_attr)
21186 {
21187 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
21188 and FILE or OBJECT symbols over NOTYPE symbols. We skip
21189 FUNC symbols entirely. */
21190 switch (ELF_ST_TYPE (sym->st_info))
21191 {
c799a79d 21192 case STT_OBJECT:
6f156d7a 21193 case STT_FILE:
c799a79d 21194 saved_sym = sym;
6f156d7a
NC
21195 if (sym->st_size)
21196 {
21197 /* If the symbol has a size associated
21198 with it then we can stop searching. */
fd486f32 21199 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 21200 }
c799a79d 21201 continue;
9ef920e9 21202
c799a79d
NC
21203 case STT_FUNC:
21204 /* Ignore function symbols. */
21205 continue;
21206
21207 default:
21208 break;
21209 }
21210
21211 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 21212 {
c799a79d
NC
21213 case STB_GLOBAL:
21214 if (saved_sym == NULL
21215 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
21216 saved_sym = sym;
21217 break;
c871dade 21218
c799a79d
NC
21219 case STB_LOCAL:
21220 if (saved_sym == NULL)
21221 saved_sym = sym;
21222 break;
21223
21224 default:
9ef920e9
NC
21225 break;
21226 }
21227 }
c799a79d
NC
21228 else
21229 {
21230 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
21231 continue;
21232
21233 saved_sym = sym;
21234 break;
21235 }
21236 }
21237
6f156d7a 21238 if (saved_sym && pname)
fd486f32 21239 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
21240
21241 return saved_sym;
c799a79d
NC
21242}
21243
d20e98ab
NC
21244/* Returns true iff addr1 and addr2 are in the same section. */
21245
015dc7e1 21246static bool
26c527e6 21247same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
21248{
21249 Elf_Internal_Shdr * a1;
21250 Elf_Internal_Shdr * a2;
21251
21252 a1 = find_section_by_address (filedata, addr1);
21253 a2 = find_section_by_address (filedata, addr2);
9abca702 21254
d20e98ab
NC
21255 return a1 == a2 && a1 != NULL;
21256}
21257
015dc7e1 21258static bool
dda8d76d
NC
21259print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21260 Filedata * filedata)
c799a79d 21261{
26c527e6
AM
21262 static uint64_t global_offset = 0;
21263 static uint64_t global_end = 0;
21264 static uint64_t func_offset = 0;
21265 static uint64_t func_end = 0;
c871dade 21266
015dc7e1
AM
21267 Elf_Internal_Sym *sym;
21268 const char *name;
26c527e6
AM
21269 uint64_t start;
21270 uint64_t end;
015dc7e1 21271 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
21272
21273 switch (pnote->descsz)
c799a79d 21274 {
6f156d7a
NC
21275 case 0:
21276 /* A zero-length description means that the range of
21277 the previous note of the same type should be used. */
c799a79d 21278 if (is_open_attr)
c871dade 21279 {
6f156d7a 21280 if (global_end > global_offset)
26c527e6
AM
21281 printf (_(" Applies to region from %#" PRIx64
21282 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 21283 else
26c527e6
AM
21284 printf (_(" Applies to region from %#" PRIx64
21285 "\n"), global_offset);
c799a79d
NC
21286 }
21287 else
21288 {
6f156d7a 21289 if (func_end > func_offset)
26c527e6
AM
21290 printf (_(" Applies to region from %#" PRIx64
21291 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 21292 else
26c527e6
AM
21293 printf (_(" Applies to region from %#" PRIx64
21294 "\n"), func_offset);
c871dade 21295 }
015dc7e1 21296 return true;
9ef920e9 21297
6f156d7a
NC
21298 case 4:
21299 start = byte_get ((unsigned char *) pnote->descdata, 4);
21300 end = 0;
21301 break;
21302
21303 case 8:
c74147bb
NC
21304 start = byte_get ((unsigned char *) pnote->descdata, 4);
21305 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21306 break;
21307
21308 case 16:
21309 start = byte_get ((unsigned char *) pnote->descdata, 8);
21310 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21311 break;
9abca702 21312
6f156d7a 21313 default:
c799a79d
NC
21314 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21315 printf (_(" <invalid descsz>"));
015dc7e1 21316 return false;
c799a79d
NC
21317 }
21318
6f156d7a
NC
21319 name = NULL;
21320 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21321 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21322 in order to avoid them being confused with the start address of the
21323 first function in the file... */
21324 if (sym == NULL && is_open_attr)
21325 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21326 & name);
6f156d7a
NC
21327
21328 if (end == 0 && sym != NULL && sym->st_size > 0)
21329 end = start + sym->st_size;
c799a79d
NC
21330
21331 if (is_open_attr)
21332 {
d20e98ab
NC
21333 /* FIXME: Need to properly allow for section alignment.
21334 16 is just the alignment used on x86_64. */
21335 if (global_end > 0
21336 && start > BFD_ALIGN (global_end, 16)
21337 /* Build notes are not guaranteed to be organised in order of
21338 increasing address, but we should find the all of the notes
21339 for one section in the same place. */
21340 && same_section (filedata, start, global_end))
26c527e6
AM
21341 warn (_("Gap in build notes detected from %#" PRIx64
21342 " to %#" PRIx64 "\n"),
6f156d7a
NC
21343 global_end + 1, start - 1);
21344
26c527e6 21345 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21346 global_offset = start;
21347
21348 if (end)
21349 {
26c527e6 21350 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21351 global_end = end;
21352 }
c799a79d
NC
21353 }
21354 else
21355 {
26c527e6 21356 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21357 func_offset = start;
21358
21359 if (end)
21360 {
26c527e6 21361 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21362 func_end = end;
21363 }
c799a79d
NC
21364 }
21365
6f156d7a
NC
21366 if (sym && name)
21367 printf (_(" (%s)"), name);
21368
21369 printf ("\n");
015dc7e1 21370 return true;
9ef920e9
NC
21371}
21372
015dc7e1 21373static bool
9ef920e9
NC
21374print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21375{
1d15e434
NC
21376 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21377 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21378 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21379 char name_type;
21380 char name_attribute;
1d15e434 21381 const char * expected_types;
9ef920e9
NC
21382 const char * name = pnote->namedata;
21383 const char * text;
88305e1b 21384 signed int left;
9ef920e9
NC
21385
21386 if (name == NULL || pnote->namesz < 2)
21387 {
21388 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21389 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21390 return false;
9ef920e9
NC
21391 }
21392
6f156d7a
NC
21393 if (do_wide)
21394 left = 28;
21395 else
21396 left = 20;
88305e1b
NC
21397
21398 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21399 if (name[0] == 'G' && name[1] == 'A')
21400 {
6f156d7a
NC
21401 if (pnote->namesz < 4)
21402 {
21403 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21404 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21405 return false;
6f156d7a
NC
21406 }
21407
88305e1b
NC
21408 printf ("GA");
21409 name += 2;
21410 left -= 2;
21411 }
21412
9ef920e9
NC
21413 switch ((name_type = * name))
21414 {
21415 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21416 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21417 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21418 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21419 printf ("%c", * name);
88305e1b 21420 left --;
9ef920e9
NC
21421 break;
21422 default:
21423 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21424 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21425 return false;
9ef920e9
NC
21426 }
21427
9ef920e9
NC
21428 ++ name;
21429 text = NULL;
21430
21431 switch ((name_attribute = * name))
21432 {
21433 case GNU_BUILD_ATTRIBUTE_VERSION:
21434 text = _("<version>");
1d15e434 21435 expected_types = string_expected;
9ef920e9
NC
21436 ++ name;
21437 break;
21438 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21439 text = _("<stack prot>");
75d7d298 21440 expected_types = "!+*";
9ef920e9
NC
21441 ++ name;
21442 break;
21443 case GNU_BUILD_ATTRIBUTE_RELRO:
21444 text = _("<relro>");
1d15e434 21445 expected_types = bool_expected;
9ef920e9
NC
21446 ++ name;
21447 break;
21448 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21449 text = _("<stack size>");
1d15e434 21450 expected_types = number_expected;
9ef920e9
NC
21451 ++ name;
21452 break;
21453 case GNU_BUILD_ATTRIBUTE_TOOL:
21454 text = _("<tool>");
1d15e434 21455 expected_types = string_expected;
9ef920e9
NC
21456 ++ name;
21457 break;
21458 case GNU_BUILD_ATTRIBUTE_ABI:
21459 text = _("<ABI>");
21460 expected_types = "$*";
21461 ++ name;
21462 break;
21463 case GNU_BUILD_ATTRIBUTE_PIC:
21464 text = _("<PIC>");
1d15e434 21465 expected_types = number_expected;
9ef920e9
NC
21466 ++ name;
21467 break;
a8be5506
NC
21468 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21469 text = _("<short enum>");
1d15e434 21470 expected_types = bool_expected;
a8be5506
NC
21471 ++ name;
21472 break;
9ef920e9
NC
21473 default:
21474 if (ISPRINT (* name))
21475 {
21476 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21477
21478 if (len > left && ! do_wide)
21479 len = left;
75d7d298 21480 printf ("%.*s:", len, name);
9ef920e9 21481 left -= len;
0dd6ae21 21482 name += len;
9ef920e9
NC
21483 }
21484 else
21485 {
3e6b6445 21486 static char tmpbuf [128];
88305e1b 21487
3e6b6445
NC
21488 error (_("unrecognised byte in name field: %d\n"), * name);
21489 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21490 text = tmpbuf;
21491 name ++;
9ef920e9
NC
21492 }
21493 expected_types = "*$!+";
21494 break;
21495 }
21496
21497 if (text)
88305e1b 21498 left -= printf ("%s", text);
9ef920e9
NC
21499
21500 if (strchr (expected_types, name_type) == NULL)
75d7d298 21501 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 21502
26c527e6 21503 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 21504 {
26c527e6
AM
21505 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
21506 pnote->namesz,
21507 name - pnote->namedata);
015dc7e1 21508 return false;
9ef920e9
NC
21509 }
21510
21511 if (left < 1 && ! do_wide)
015dc7e1 21512 return true;
9ef920e9
NC
21513
21514 switch (name_type)
21515 {
21516 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21517 {
26c527e6
AM
21518 unsigned int bytes;
21519 uint64_t val = 0;
21520 unsigned int shift = 0;
21521 char *decoded = NULL;
ddef72cd 21522
b06b2c92
NC
21523 bytes = pnote->namesz - (name - pnote->namedata);
21524 if (bytes > 0)
21525 /* The -1 is because the name field is always 0 terminated, and we
21526 want to be able to ensure that the shift in the while loop below
21527 will not overflow. */
21528 -- bytes;
21529
ddef72cd
NC
21530 if (bytes > sizeof (val))
21531 {
3e6b6445
NC
21532 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21533 bytes);
21534 bytes = sizeof (val);
ddef72cd 21535 }
3e6b6445
NC
21536 /* We do not bother to warn if bytes == 0 as this can
21537 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21538
21539 while (bytes --)
21540 {
26c527e6 21541 uint64_t byte = *name++ & 0xff;
79a964dc
NC
21542
21543 val |= byte << shift;
9ef920e9
NC
21544 shift += 8;
21545 }
21546
75d7d298 21547 switch (name_attribute)
9ef920e9 21548 {
75d7d298 21549 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21550 switch (val)
21551 {
75d7d298
NC
21552 case 0: decoded = "static"; break;
21553 case 1: decoded = "pic"; break;
21554 case 2: decoded = "PIC"; break;
21555 case 3: decoded = "pie"; break;
21556 case 4: decoded = "PIE"; break;
21557 default: break;
9ef920e9 21558 }
75d7d298
NC
21559 break;
21560 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21561 switch (val)
9ef920e9 21562 {
75d7d298
NC
21563 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21564 case 0: decoded = "off"; break;
21565 case 1: decoded = "on"; break;
21566 case 2: decoded = "all"; break;
21567 case 3: decoded = "strong"; break;
21568 case 4: decoded = "explicit"; break;
21569 default: break;
9ef920e9 21570 }
75d7d298
NC
21571 break;
21572 default:
21573 break;
9ef920e9
NC
21574 }
21575
75d7d298 21576 if (decoded != NULL)
3e6b6445
NC
21577 {
21578 print_symbol (-left, decoded);
21579 left = 0;
21580 }
21581 else if (val == 0)
21582 {
21583 printf ("0x0");
21584 left -= 3;
21585 }
9ef920e9 21586 else
75d7d298
NC
21587 {
21588 if (do_wide)
26c527e6 21589 left -= printf ("0x%" PRIx64, val);
75d7d298 21590 else
26c527e6 21591 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 21592 }
9ef920e9
NC
21593 }
21594 break;
21595 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21596 left -= print_symbol (- left, name);
21597 break;
21598 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21599 left -= print_symbol (- left, "true");
21600 break;
21601 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21602 left -= print_symbol (- left, "false");
21603 break;
21604 }
21605
21606 if (do_wide && left > 0)
21607 printf ("%-*s", left, " ");
9abca702 21608
015dc7e1 21609 return true;
9ef920e9
NC
21610}
21611
2952f10c
SM
21612/* Print the contents of PNOTE as hex. */
21613
21614static void
21615print_note_contents_hex (Elf_Internal_Note *pnote)
21616{
21617 if (pnote->descsz)
21618 {
26c527e6 21619 size_t i;
2952f10c
SM
21620
21621 printf (_(" description data: "));
21622 for (i = 0; i < pnote->descsz; i++)
21623 printf ("%02x ", pnote->descdata[i] & 0xff);
21624 if (!do_wide)
21625 printf ("\n");
21626 }
21627
21628 if (do_wide)
21629 printf ("\n");
21630}
21631
21632#if defined HAVE_MSGPACK
21633
21634static void
21635print_indents (int n)
21636{
21637 printf (" ");
21638
21639 for (int i = 0; i < n; i++)
21640 printf (" ");
21641}
21642
21643/* Print OBJ in human-readable form. */
21644
21645static void
21646dump_msgpack_obj (const msgpack_object *obj, int indent)
21647{
21648 switch (obj->type)
21649 {
21650 case MSGPACK_OBJECT_NIL:
21651 printf ("(nil)");
21652 break;
21653
21654 case MSGPACK_OBJECT_BOOLEAN:
21655 printf ("%s", obj->via.boolean ? "true" : "false");
21656 break;
21657
21658 case MSGPACK_OBJECT_POSITIVE_INTEGER:
21659 printf ("%" PRIu64, obj->via.u64);
21660 break;
21661
21662 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
21663 printf ("%" PRIi64, obj->via.i64);
21664 break;
21665
21666 case MSGPACK_OBJECT_FLOAT32:
21667 case MSGPACK_OBJECT_FLOAT64:
21668 printf ("%f", obj->via.f64);
21669 break;
21670
21671 case MSGPACK_OBJECT_STR:
21672 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
21673 break;
21674
21675 case MSGPACK_OBJECT_ARRAY:
21676 {
21677 const msgpack_object_array *array = &obj->via.array;
21678
21679 printf ("[\n");
21680 ++indent;
21681
21682 for (uint32_t i = 0; i < array->size; ++i)
21683 {
21684 const msgpack_object *item = &array->ptr[i];
21685
21686 print_indents (indent);
21687 dump_msgpack_obj (item, indent);
21688 printf (",\n");
21689 }
21690
21691 --indent;
21692 print_indents (indent);
21693 printf ("]");
21694 break;
21695 }
21696 break;
21697
21698 case MSGPACK_OBJECT_MAP:
21699 {
21700 const msgpack_object_map *map = &obj->via.map;
21701
21702 printf ("{\n");
21703 ++indent;
21704
21705 for (uint32_t i = 0; i < map->size; ++i)
21706 {
21707 const msgpack_object_kv *kv = &map->ptr[i];
21708 const msgpack_object *key = &kv->key;
21709 const msgpack_object *val = &kv->val;
21710
21711 print_indents (indent);
21712 dump_msgpack_obj (key, indent);
21713 printf (": ");
21714 dump_msgpack_obj (val, indent);
21715
21716 printf (",\n");
21717 }
21718
21719 --indent;
21720 print_indents (indent);
21721 printf ("}");
21722
21723 break;
21724 }
21725
21726 case MSGPACK_OBJECT_BIN:
21727 printf ("(bin)");
21728 break;
21729
21730 case MSGPACK_OBJECT_EXT:
21731 printf ("(ext)");
21732 break;
21733 }
21734}
21735
21736static void
21737dump_msgpack (const msgpack_unpacked *msg)
21738{
21739 print_indents (0);
21740 dump_msgpack_obj (&msg->data, 0);
21741 printf ("\n");
21742}
21743
21744#endif /* defined HAVE_MSGPACK */
21745
21746static bool
21747print_amdgpu_note (Elf_Internal_Note *pnote)
21748{
21749#if defined HAVE_MSGPACK
21750 /* If msgpack is available, decode and dump the note's content. */
21751 bool ret;
21752 msgpack_unpacked msg;
21753 msgpack_unpack_return msgpack_ret;
21754
21755 assert (pnote->type == NT_AMDGPU_METADATA);
21756
21757 msgpack_unpacked_init (&msg);
21758 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
21759 NULL);
21760
21761 switch (msgpack_ret)
21762 {
21763 case MSGPACK_UNPACK_SUCCESS:
21764 dump_msgpack (&msg);
21765 ret = true;
21766 break;
21767
21768 default:
21769 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
21770 ret = false;
21771 break;
21772 }
21773
21774 msgpack_unpacked_destroy (&msg);
21775 return ret;
21776#else
21777 /* msgpack is not available, dump contents as hex. */
21778 print_note_contents_hex (pnote);
21779 return true;
21780#endif
21781}
21782
e263a66b
CC
21783static bool
21784print_qnx_note (Elf_Internal_Note *pnote)
21785{
21786 switch (pnote->type)
21787 {
21788 case QNT_STACK:
21789 if (pnote->descsz != 12)
21790 goto desc_size_fail;
21791
21792 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
21793 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
21794 printf (_(" Stack allocated: %" PRIx32 "\n"),
21795 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
21796 printf (_(" Executable: %s\n"),
21797 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
21798 break;
21799
21800 default:
21801 print_note_contents_hex(pnote);
21802 }
21803 return true;
21804
21805desc_size_fail:
21806 printf (_(" <corrupt - data size is too small>\n"));
21807 error (_("corrupt QNX note: data size is too small\n"));
21808 return false;
21809}
21810
21811
6d118b09
NC
21812/* Note that by the ELF standard, the name field is already null byte
21813 terminated, and namesz includes the terminating null byte.
21814 I.E. the value of namesz for the name "FSF" is 4.
21815
e3c8793a 21816 If the value of namesz is zero, there is no name present. */
9ef920e9 21817
015dc7e1 21818static bool
9ef920e9 21819process_note (Elf_Internal_Note * pnote,
dda8d76d 21820 Filedata * filedata)
779fe533 21821{
2cf0635d
NC
21822 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21823 const char * nt;
9437c45b
JT
21824
21825 if (pnote->namesz == 0)
1ec5cd37
NC
21826 /* If there is no note name, then use the default set of
21827 note type strings. */
dda8d76d 21828 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21829
24d127aa 21830 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21831 /* GNU-specific object file notes. */
21832 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21833
28cdbb18
SM
21834 else if (startswith (pnote->namedata, "AMDGPU"))
21835 /* AMDGPU-specific object file notes. */
21836 nt = get_amdgpu_elf_note_type (pnote->type);
21837
24d127aa 21838 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21839 /* FreeBSD-specific core file notes. */
dda8d76d 21840 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21841
24d127aa 21842 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21843 /* NetBSD-specific core file notes. */
dda8d76d 21844 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21845
24d127aa 21846 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21847 /* NetBSD-specific core file notes. */
21848 return process_netbsd_elf_note (pnote);
21849
24d127aa 21850 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21851 /* NetBSD-specific core file notes. */
21852 return process_netbsd_elf_note (pnote);
21853
98ca73af
FC
21854 else if (startswith (pnote->namedata, "OpenBSD"))
21855 /* OpenBSD-specific core file notes. */
21856 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21857
e263a66b
CC
21858 else if (startswith (pnote->namedata, "QNX"))
21859 /* QNX-specific core file notes. */
21860 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
21861
e9b095a5 21862 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21863 {
21864 /* SPU-specific core file notes. */
21865 nt = pnote->namedata + 4;
21866 name = "SPU";
21867 }
21868
24d127aa 21869 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21870 /* VMS/ia64-specific file notes. */
21871 nt = get_ia64_vms_note_type (pnote->type);
21872
24d127aa 21873 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21874 nt = get_stapsdt_note_type (pnote->type);
21875
9437c45b 21876 else
1ec5cd37
NC
21877 /* Don't recognize this note name; just use the default set of
21878 note type strings. */
dda8d76d 21879 nt = get_note_type (filedata, pnote->type);
9437c45b 21880
1449284b 21881 printf (" ");
9ef920e9 21882
24d127aa 21883 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21884 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21885 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21886 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21887 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21888 print_gnu_build_attribute_name (pnote);
21889 else
21890 print_symbol (-20, name);
21891
21892 if (do_wide)
21893 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21894 else
21895 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21896
24d127aa 21897 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21898 return print_ia64_vms_note (pnote);
24d127aa 21899 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21900 return print_gnu_note (filedata, pnote);
24d127aa 21901 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21902 return print_stapsdt_note (pnote);
24d127aa 21903 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21904 return print_core_note (pnote);
e5382207
LB
21905 else if (startswith (pnote->namedata, "FDO"))
21906 return print_fdo_note (pnote);
24d127aa 21907 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21908 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21909 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21910 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21911 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21912 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
21913 else if (startswith (pnote->namedata, "AMDGPU")
21914 && pnote->type == NT_AMDGPU_METADATA)
21915 return print_amdgpu_note (pnote);
e263a66b
CC
21916 else if (startswith (pnote->namedata, "QNX"))
21917 return print_qnx_note (pnote);
779fe533 21918
2952f10c 21919 print_note_contents_hex (pnote);
015dc7e1 21920 return true;
1449284b 21921}
6d118b09 21922
015dc7e1 21923static bool
dda8d76d
NC
21924process_notes_at (Filedata * filedata,
21925 Elf_Internal_Shdr * section,
625d49fc
AM
21926 uint64_t offset,
21927 uint64_t length,
21928 uint64_t align)
779fe533 21929{
015dc7e1
AM
21930 Elf_External_Note *pnotes;
21931 Elf_External_Note *external;
21932 char *end;
21933 bool res = true;
103f02d3 21934
779fe533 21935 if (length <= 0)
015dc7e1 21936 return false;
103f02d3 21937
1449284b
NC
21938 if (section)
21939 {
dda8d76d 21940 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21941 if (pnotes)
32ec8896 21942 {
dda8d76d 21943 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21944 {
21945 free (pnotes);
015dc7e1 21946 return false;
f761cb13 21947 }
32ec8896 21948 }
1449284b
NC
21949 }
21950 else
82ed9683 21951 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21952 _("notes"));
4dff97b2 21953
dd24e3da 21954 if (pnotes == NULL)
015dc7e1 21955 return false;
779fe533 21956
103f02d3 21957 external = pnotes;
103f02d3 21958
ca0e11aa
NC
21959 if (filedata->is_separate)
21960 printf (_("In linked file '%s': "), filedata->file_name);
21961 else
21962 printf ("\n");
1449284b 21963 if (section)
ca0e11aa 21964 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21965 else
26c527e6
AM
21966 printf (_("Displaying notes found at file offset 0x%08" PRIx64
21967 " with length 0x%08" PRIx64 ":\n"),
21968 offset, length);
1449284b 21969
82ed9683
L
21970 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21971 specifies that notes should be aligned to 4 bytes in 32-bit
21972 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21973 we also support 4 byte alignment in 64-bit objects. If section
21974 alignment is less than 4, we treate alignment as 4 bytes. */
21975 if (align < 4)
21976 align = 4;
21977 else if (align != 4 && align != 8)
21978 {
26c527e6
AM
21979 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
21980 align);
a788aedd 21981 free (pnotes);
015dc7e1 21982 return false;
82ed9683
L
21983 }
21984
dbe15e4e 21985 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21986
c8071705
NC
21987 end = (char *) pnotes + length;
21988 while ((char *) external < end)
779fe533 21989 {
b34976b6 21990 Elf_Internal_Note inote;
15b42fb0 21991 size_t min_notesz;
4dff97b2 21992 char * next;
2cf0635d 21993 char * temp = NULL;
c8071705 21994 size_t data_remaining = end - (char *) external;
6d118b09 21995
dda8d76d 21996 if (!is_ia64_vms (filedata))
15b42fb0 21997 {
9dd3a467
NC
21998 /* PR binutils/15191
21999 Make sure that there is enough data to read. */
15b42fb0
AM
22000 min_notesz = offsetof (Elf_External_Note, name);
22001 if (data_remaining < min_notesz)
9dd3a467 22002 {
26c527e6 22003 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22004 "not enough for a full note\n",
26c527e6 22005 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22006 "not enough for a full note\n",
22007 data_remaining),
26c527e6 22008 data_remaining);
9dd3a467
NC
22009 break;
22010 }
5396a86e
AM
22011 data_remaining -= min_notesz;
22012
15b42fb0
AM
22013 inote.type = BYTE_GET (external->type);
22014 inote.namesz = BYTE_GET (external->namesz);
22015 inote.namedata = external->name;
22016 inote.descsz = BYTE_GET (external->descsz);
276da9b3 22017 inote.descdata = ((char *) external
4dff97b2 22018 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 22019 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 22020 next = ((char *) external
4dff97b2 22021 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 22022 }
00e98fc7 22023 else
15b42fb0
AM
22024 {
22025 Elf64_External_VMS_Note *vms_external;
00e98fc7 22026
9dd3a467
NC
22027 /* PR binutils/15191
22028 Make sure that there is enough data to read. */
15b42fb0
AM
22029 min_notesz = offsetof (Elf64_External_VMS_Note, name);
22030 if (data_remaining < min_notesz)
9dd3a467 22031 {
26c527e6 22032 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22033 "not enough for a full note\n",
26c527e6 22034 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22035 "not enough for a full note\n",
22036 data_remaining),
26c527e6 22037 data_remaining);
9dd3a467
NC
22038 break;
22039 }
5396a86e 22040 data_remaining -= min_notesz;
3e55a963 22041
15b42fb0
AM
22042 vms_external = (Elf64_External_VMS_Note *) external;
22043 inote.type = BYTE_GET (vms_external->type);
22044 inote.namesz = BYTE_GET (vms_external->namesz);
22045 inote.namedata = vms_external->name;
22046 inote.descsz = BYTE_GET (vms_external->descsz);
22047 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
22048 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22049 next = inote.descdata + align_power (inote.descsz, 3);
22050 }
22051
5396a86e
AM
22052 /* PR 17531: file: 3443835e. */
22053 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
22054 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
22055 || (size_t) (inote.descdata - inote.namedata) > data_remaining
22056 || (size_t) (next - inote.descdata) < inote.descsz
22057 || ((size_t) (next - inote.descdata)
22058 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 22059 {
26c527e6
AM
22060 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
22061 (char *) external - (char *) pnotes);
22062 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 22063 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
22064 break;
22065 }
22066
15b42fb0 22067 external = (Elf_External_Note *) next;
dd24e3da 22068
6d118b09
NC
22069 /* Verify that name is null terminated. It appears that at least
22070 one version of Linux (RedHat 6.0) generates corefiles that don't
22071 comply with the ELF spec by failing to include the null byte in
22072 namesz. */
18344509 22073 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 22074 {
5396a86e 22075 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 22076 {
5396a86e
AM
22077 temp = (char *) malloc (inote.namesz + 1);
22078 if (temp == NULL)
22079 {
22080 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 22081 res = false;
5396a86e
AM
22082 break;
22083 }
76da6bbe 22084
5396a86e
AM
22085 memcpy (temp, inote.namedata, inote.namesz);
22086 inote.namedata = temp;
22087 }
22088 inote.namedata[inote.namesz] = 0;
6d118b09
NC
22089 }
22090
dda8d76d 22091 if (! process_note (& inote, filedata))
015dc7e1 22092 res = false;
103f02d3 22093
9db70fc3
AM
22094 free (temp);
22095 temp = NULL;
779fe533
NC
22096 }
22097
22098 free (pnotes);
103f02d3 22099
779fe533
NC
22100 return res;
22101}
22102
015dc7e1 22103static bool
dda8d76d 22104process_corefile_note_segments (Filedata * filedata)
779fe533 22105{
015dc7e1 22106 Elf_Internal_Phdr *segment;
b34976b6 22107 unsigned int i;
015dc7e1 22108 bool res = true;
103f02d3 22109
dda8d76d 22110 if (! get_program_headers (filedata))
015dc7e1 22111 return true;
103f02d3 22112
dda8d76d
NC
22113 for (i = 0, segment = filedata->program_headers;
22114 i < filedata->file_header.e_phnum;
b34976b6 22115 i++, segment++)
779fe533
NC
22116 {
22117 if (segment->p_type == PT_NOTE)
625d49fc
AM
22118 if (! process_notes_at (filedata, NULL, segment->p_offset,
22119 segment->p_filesz, segment->p_align))
015dc7e1 22120 res = false;
779fe533 22121 }
103f02d3 22122
779fe533
NC
22123 return res;
22124}
22125
015dc7e1 22126static bool
625d49fc 22127process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
22128{
22129 Elf_External_Note * pnotes;
22130 Elf_External_Note * external;
c8071705 22131 char * end;
015dc7e1 22132 bool res = true;
685080f2
NC
22133
22134 if (length <= 0)
015dc7e1 22135 return false;
685080f2 22136
dda8d76d 22137 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
22138 _("v850 notes"));
22139 if (pnotes == NULL)
015dc7e1 22140 return false;
685080f2
NC
22141
22142 external = pnotes;
c8071705 22143 end = (char*) pnotes + length;
685080f2 22144
26c527e6
AM
22145 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22146 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22147 offset, length);
685080f2 22148
c8071705 22149 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
22150 {
22151 Elf_External_Note * next;
22152 Elf_Internal_Note inote;
22153
22154 inote.type = BYTE_GET (external->type);
22155 inote.namesz = BYTE_GET (external->namesz);
22156 inote.namedata = external->name;
22157 inote.descsz = BYTE_GET (external->descsz);
22158 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22159 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22160
c8071705
NC
22161 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22162 {
22163 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22164 inote.descdata = inote.namedata;
22165 inote.namesz = 0;
22166 }
22167
685080f2
NC
22168 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22169
c8071705 22170 if ( ((char *) next > end)
685080f2
NC
22171 || ((char *) next < (char *) pnotes))
22172 {
26c527e6
AM
22173 warn (_("corrupt descsz found in note at offset %#tx\n"),
22174 (char *) external - (char *) pnotes);
22175 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22176 inote.type, inote.namesz, inote.descsz);
22177 break;
22178 }
22179
22180 external = next;
22181
22182 /* Prevent out-of-bounds indexing. */
c8071705 22183 if ( inote.namedata + inote.namesz > end
685080f2
NC
22184 || inote.namedata + inote.namesz < inote.namedata)
22185 {
26c527e6
AM
22186 warn (_("corrupt namesz found in note at offset %#zx\n"),
22187 (char *) external - (char *) pnotes);
22188 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22189 inote.type, inote.namesz, inote.descsz);
22190 break;
22191 }
22192
22193 printf (" %s: ", get_v850_elf_note_type (inote.type));
22194
22195 if (! print_v850_note (& inote))
22196 {
015dc7e1 22197 res = false;
26c527e6 22198 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
22199 inote.namesz, inote.descsz);
22200 }
22201 }
22202
22203 free (pnotes);
22204
22205 return res;
22206}
22207
015dc7e1 22208static bool
dda8d76d 22209process_note_sections (Filedata * filedata)
1ec5cd37 22210{
015dc7e1 22211 Elf_Internal_Shdr *section;
26c527e6 22212 size_t i;
32ec8896 22213 unsigned int n = 0;
015dc7e1 22214 bool res = true;
1ec5cd37 22215
dda8d76d
NC
22216 for (i = 0, section = filedata->section_headers;
22217 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 22218 i++, section++)
685080f2
NC
22219 {
22220 if (section->sh_type == SHT_NOTE)
22221 {
625d49fc
AM
22222 if (! process_notes_at (filedata, section, section->sh_offset,
22223 section->sh_size, section->sh_addralign))
015dc7e1 22224 res = false;
685080f2
NC
22225 n++;
22226 }
22227
dda8d76d
NC
22228 if (( filedata->file_header.e_machine == EM_V800
22229 || filedata->file_header.e_machine == EM_V850
22230 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
22231 && section->sh_type == SHT_RENESAS_INFO)
22232 {
625d49fc
AM
22233 if (! process_v850_notes (filedata, section->sh_offset,
22234 section->sh_size))
015dc7e1 22235 res = false;
685080f2
NC
22236 n++;
22237 }
22238 }
df565f32
NC
22239
22240 if (n == 0)
22241 /* Try processing NOTE segments instead. */
dda8d76d 22242 return process_corefile_note_segments (filedata);
1ec5cd37
NC
22243
22244 return res;
22245}
22246
015dc7e1 22247static bool
dda8d76d 22248process_notes (Filedata * filedata)
779fe533
NC
22249{
22250 /* If we have not been asked to display the notes then do nothing. */
22251 if (! do_notes)
015dc7e1 22252 return true;
103f02d3 22253
dda8d76d
NC
22254 if (filedata->file_header.e_type != ET_CORE)
22255 return process_note_sections (filedata);
103f02d3 22256
779fe533 22257 /* No program headers means no NOTE segment. */
dda8d76d
NC
22258 if (filedata->file_header.e_phnum > 0)
22259 return process_corefile_note_segments (filedata);
779fe533 22260
ca0e11aa
NC
22261 if (filedata->is_separate)
22262 printf (_("No notes found in linked file '%s'.\n"),
22263 filedata->file_name);
22264 else
22265 printf (_("No notes found file.\n"));
22266
015dc7e1 22267 return true;
779fe533
NC
22268}
22269
60abdbed
NC
22270static unsigned char *
22271display_public_gnu_attributes (unsigned char * start,
22272 const unsigned char * const end)
22273{
22274 printf (_(" Unknown GNU attribute: %s\n"), start);
22275
22276 start += strnlen ((char *) start, end - start);
22277 display_raw_attribute (start, end);
22278
22279 return (unsigned char *) end;
22280}
22281
22282static unsigned char *
22283display_generic_attribute (unsigned char * start,
22284 unsigned int tag,
22285 const unsigned char * const end)
22286{
22287 if (tag == 0)
22288 return (unsigned char *) end;
22289
22290 return display_tag_value (tag, start, end);
22291}
22292
015dc7e1 22293static bool
dda8d76d 22294process_arch_specific (Filedata * filedata)
252b5132 22295{
a952a375 22296 if (! do_arch)
015dc7e1 22297 return true;
a952a375 22298
dda8d76d 22299 switch (filedata->file_header.e_machine)
252b5132 22300 {
53a346d8
CZ
22301 case EM_ARC:
22302 case EM_ARC_COMPACT:
22303 case EM_ARC_COMPACT2:
dda8d76d 22304 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
22305 display_arc_attribute,
22306 display_generic_attribute);
11c1ff18 22307 case EM_ARM:
dda8d76d 22308 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
22309 display_arm_attribute,
22310 display_generic_attribute);
22311
252b5132 22312 case EM_MIPS:
4fe85591 22313 case EM_MIPS_RS3_LE:
dda8d76d 22314 return process_mips_specific (filedata);
60abdbed
NC
22315
22316 case EM_MSP430:
dda8d76d 22317 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 22318 display_msp430_attribute,
c0ea7c52 22319 display_msp430_gnu_attribute);
60abdbed 22320
2dc8dd17
JW
22321 case EM_RISCV:
22322 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22323 display_riscv_attribute,
22324 display_generic_attribute);
22325
35c08157 22326 case EM_NDS32:
dda8d76d 22327 return process_nds32_specific (filedata);
60abdbed 22328
85f7484a
PB
22329 case EM_68K:
22330 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22331 display_m68k_gnu_attribute);
22332
34c8bcba 22333 case EM_PPC:
b82317dd 22334 case EM_PPC64:
dda8d76d 22335 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22336 display_power_gnu_attribute);
22337
643f7afb
AK
22338 case EM_S390:
22339 case EM_S390_OLD:
dda8d76d 22340 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22341 display_s390_gnu_attribute);
22342
9e8c70f9
DM
22343 case EM_SPARC:
22344 case EM_SPARC32PLUS:
22345 case EM_SPARCV9:
dda8d76d 22346 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22347 display_sparc_gnu_attribute);
22348
59e6276b 22349 case EM_TI_C6000:
dda8d76d 22350 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22351 display_tic6x_attribute,
22352 display_generic_attribute);
22353
0861f561
CQ
22354 case EM_CSKY:
22355 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22356 display_csky_attribute, NULL);
22357
252b5132 22358 default:
dda8d76d 22359 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22360 display_public_gnu_attributes,
22361 display_generic_attribute);
252b5132 22362 }
252b5132
RH
22363}
22364
015dc7e1 22365static bool
dda8d76d 22366get_file_header (Filedata * filedata)
252b5132 22367{
9ea033b2 22368 /* Read in the identity array. */
dda8d76d 22369 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22370 return false;
252b5132 22371
9ea033b2 22372 /* Determine how to read the rest of the header. */
dda8d76d 22373 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22374 {
1a0670f3
AM
22375 default:
22376 case ELFDATANONE:
adab8cdc
AO
22377 case ELFDATA2LSB:
22378 byte_get = byte_get_little_endian;
22379 byte_put = byte_put_little_endian;
22380 break;
22381 case ELFDATA2MSB:
22382 byte_get = byte_get_big_endian;
22383 byte_put = byte_put_big_endian;
22384 break;
9ea033b2
NC
22385 }
22386
22387 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22388 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22389
22390 /* Read in the rest of the header. */
22391 if (is_32bit_elf)
22392 {
22393 Elf32_External_Ehdr ehdr32;
252b5132 22394
dda8d76d 22395 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22396 return false;
103f02d3 22397
dda8d76d
NC
22398 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22399 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22400 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22401 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22402 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22403 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22404 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22405 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22406 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22407 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22408 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22409 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22410 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22411 }
252b5132 22412 else
9ea033b2
NC
22413 {
22414 Elf64_External_Ehdr ehdr64;
a952a375 22415
dda8d76d 22416 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22417 return false;
103f02d3 22418
dda8d76d
NC
22419 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22420 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22421 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22422 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22423 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22424 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22425 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22426 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22427 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22428 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22429 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22430 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22431 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22432 }
252b5132 22433
015dc7e1 22434 return true;
252b5132
RH
22435}
22436
13acb58d
AM
22437static void
22438free_filedata (Filedata *filedata)
22439{
22440 free (filedata->program_interpreter);
13acb58d 22441 free (filedata->program_headers);
13acb58d 22442 free (filedata->section_headers);
13acb58d 22443 free (filedata->string_table);
13acb58d 22444 free (filedata->dump.dump_sects);
13acb58d 22445 free (filedata->dynamic_strings);
13acb58d 22446 free (filedata->dynamic_symbols);
13acb58d 22447 free (filedata->dynamic_syminfo);
13acb58d 22448 free (filedata->dynamic_section);
13acb58d
AM
22449
22450 while (filedata->symtab_shndx_list != NULL)
22451 {
22452 elf_section_list *next = filedata->symtab_shndx_list->next;
22453 free (filedata->symtab_shndx_list);
22454 filedata->symtab_shndx_list = next;
22455 }
22456
22457 free (filedata->section_headers_groups);
13acb58d
AM
22458
22459 if (filedata->section_groups)
22460 {
22461 size_t i;
22462 struct group_list * g;
22463 struct group_list * next;
22464
22465 for (i = 0; i < filedata->group_count; i++)
22466 {
22467 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22468 {
22469 next = g->next;
22470 free (g);
22471 }
22472 }
22473
22474 free (filedata->section_groups);
13acb58d 22475 }
066f8fbe
AM
22476 memset (&filedata->section_headers, 0,
22477 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22478}
22479
dda8d76d
NC
22480static void
22481close_file (Filedata * filedata)
22482{
22483 if (filedata)
22484 {
22485 if (filedata->handle)
22486 fclose (filedata->handle);
22487 free (filedata);
22488 }
22489}
22490
22491void
22492close_debug_file (void * data)
22493{
13acb58d 22494 free_filedata ((Filedata *) data);
dda8d76d
NC
22495 close_file ((Filedata *) data);
22496}
22497
22498static Filedata *
015dc7e1 22499open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22500{
22501 struct stat statbuf;
22502 Filedata * filedata = NULL;
22503
22504 if (stat (pathname, & statbuf) < 0
22505 || ! S_ISREG (statbuf.st_mode))
22506 goto fail;
22507
22508 filedata = calloc (1, sizeof * filedata);
22509 if (filedata == NULL)
22510 goto fail;
22511
22512 filedata->handle = fopen (pathname, "rb");
22513 if (filedata->handle == NULL)
22514 goto fail;
22515
be7d229a 22516 filedata->file_size = statbuf.st_size;
dda8d76d 22517 filedata->file_name = pathname;
ca0e11aa 22518 filedata->is_separate = is_separate;
dda8d76d
NC
22519
22520 if (! get_file_header (filedata))
22521 goto fail;
22522
4de91c10
AM
22523 if (!get_section_headers (filedata, false))
22524 goto fail;
dda8d76d
NC
22525
22526 return filedata;
22527
22528 fail:
22529 if (filedata)
22530 {
22531 if (filedata->handle)
22532 fclose (filedata->handle);
22533 free (filedata);
22534 }
22535 return NULL;
22536}
22537
22538void *
22539open_debug_file (const char * pathname)
22540{
015dc7e1 22541 return open_file (pathname, true);
dda8d76d
NC
22542}
22543
835f2fae
NC
22544static void
22545initialise_dump_sects (Filedata * filedata)
22546{
22547 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22548 Note we do this even if cmdline_dump_sects is empty because we
22549 must make sure that the dump_sets array is zeroed out before each
22550 object file is processed. */
22551 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22552 memset (filedata->dump.dump_sects, 0,
22553 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22554
22555 if (cmdline.num_dump_sects > 0)
22556 {
22557 if (filedata->dump.num_dump_sects == 0)
22558 /* A sneaky way of allocating the dump_sects array. */
22559 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22560
22561 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22562 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22563 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22564 }
22565}
22566
94585d6d
NC
22567static bool
22568might_need_separate_debug_info (Filedata * filedata)
22569{
22570 /* Debuginfo files do not need further separate file loading. */
22571 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22572 return false;
22573
22574 /* Since do_follow_links might be enabled by default, only treat it as an
22575 indication that separate files should be loaded if setting it was a
22576 deliberate user action. */
22577 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22578 return true;
22579
22580 if (process_links || do_syms || do_unwind
22581 || dump_any_debugging || do_dump || do_debugging)
22582 return true;
22583
22584 return false;
22585}
22586
fb52b2f4
NC
22587/* Process one ELF object file according to the command line options.
22588 This file may actually be stored in an archive. The file is
32ec8896
NC
22589 positioned at the start of the ELF object. Returns TRUE if no
22590 problems were encountered, FALSE otherwise. */
fb52b2f4 22591
015dc7e1 22592static bool
dda8d76d 22593process_object (Filedata * filedata)
252b5132 22594{
015dc7e1 22595 bool have_separate_files;
252b5132 22596 unsigned int i;
015dc7e1 22597 bool res;
252b5132 22598
dda8d76d 22599 if (! get_file_header (filedata))
252b5132 22600 {
dda8d76d 22601 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22602 return false;
252b5132
RH
22603 }
22604
22605 /* Initialise per file variables. */
978c4450
AM
22606 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22607 filedata->version_info[i] = 0;
252b5132 22608
978c4450
AM
22609 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22610 filedata->dynamic_info[i] = 0;
22611 filedata->dynamic_info_DT_GNU_HASH = 0;
22612 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22613
22614 /* Process the file. */
22615 if (show_name)
dda8d76d 22616 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22617
835f2fae 22618 initialise_dump_sects (filedata);
d70c5fc7 22619
4de91c10
AM
22620 /* There may be some extensions in the first section header. Don't
22621 bomb if we can't read it. */
22622 get_section_headers (filedata, true);
22623
dda8d76d 22624 if (! process_file_header (filedata))
4de91c10
AM
22625 {
22626 res = false;
22627 goto out;
22628 }
252b5132 22629
e331b18d
AM
22630 /* Throw away the single section header read above, so that we
22631 re-read the entire set. */
22632 free (filedata->section_headers);
22633 filedata->section_headers = NULL;
22634
dda8d76d 22635 if (! process_section_headers (filedata))
2f62977e 22636 {
32ec8896 22637 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22638 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22639
2f62977e 22640 if (! do_using_dynamic)
015dc7e1 22641 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22642 }
252b5132 22643
dda8d76d 22644 if (! process_section_groups (filedata))
32ec8896 22645 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22646 do_unwind = false;
d1f5c6e3 22647
93df3340
AM
22648 process_program_headers (filedata);
22649
22650 res = process_dynamic_section (filedata);
252b5132 22651
dda8d76d 22652 if (! process_relocs (filedata))
015dc7e1 22653 res = false;
252b5132 22654
dda8d76d 22655 if (! process_unwind (filedata))
015dc7e1 22656 res = false;
4d6ed7c8 22657
dda8d76d 22658 if (! process_symbol_table (filedata))
015dc7e1 22659 res = false;
252b5132 22660
0f03783c 22661 if (! process_lto_symbol_tables (filedata))
015dc7e1 22662 res = false;
b9e920ec 22663
dda8d76d 22664 if (! process_syminfo (filedata))
015dc7e1 22665 res = false;
252b5132 22666
dda8d76d 22667 if (! process_version_sections (filedata))
015dc7e1 22668 res = false;
252b5132 22669
94585d6d 22670 if (might_need_separate_debug_info (filedata))
24841daa 22671 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22672 else
015dc7e1 22673 have_separate_files = false;
dda8d76d
NC
22674
22675 if (! process_section_contents (filedata))
015dc7e1 22676 res = false;
f5842774 22677
24841daa 22678 if (have_separate_files)
dda8d76d 22679 {
24841daa
NC
22680 separate_info * d;
22681
22682 for (d = first_separate_info; d != NULL; d = d->next)
22683 {
835f2fae
NC
22684 initialise_dump_sects (d->handle);
22685
ca0e11aa 22686 if (process_links && ! process_file_header (d->handle))
015dc7e1 22687 res = false;
ca0e11aa 22688 else if (! process_section_headers (d->handle))
015dc7e1 22689 res = false;
d6bfbc39 22690 else if (! process_section_contents (d->handle))
015dc7e1 22691 res = false;
ca0e11aa
NC
22692 else if (process_links)
22693 {
ca0e11aa 22694 if (! process_section_groups (d->handle))
015dc7e1 22695 res = false;
93df3340 22696 process_program_headers (d->handle);
ca0e11aa 22697 if (! process_dynamic_section (d->handle))
015dc7e1 22698 res = false;
ca0e11aa 22699 if (! process_relocs (d->handle))
015dc7e1 22700 res = false;
ca0e11aa 22701 if (! process_unwind (d->handle))
015dc7e1 22702 res = false;
ca0e11aa 22703 if (! process_symbol_table (d->handle))
015dc7e1 22704 res = false;
ca0e11aa 22705 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22706 res = false;
ca0e11aa 22707 if (! process_syminfo (d->handle))
015dc7e1 22708 res = false;
ca0e11aa 22709 if (! process_version_sections (d->handle))
015dc7e1 22710 res = false;
ca0e11aa 22711 if (! process_notes (d->handle))
015dc7e1 22712 res = false;
ca0e11aa 22713 }
24841daa
NC
22714 }
22715
22716 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22717 }
22718
22719 if (! process_notes (filedata))
015dc7e1 22720 res = false;
103f02d3 22721
dda8d76d 22722 if (! process_gnu_liblist (filedata))
015dc7e1 22723 res = false;
047b2264 22724
dda8d76d 22725 if (! process_arch_specific (filedata))
015dc7e1 22726 res = false;
252b5132 22727
4de91c10 22728 out:
13acb58d 22729 free_filedata (filedata);
e4b17d5c 22730
19e6b90e 22731 free_debug_memory ();
18bd398b 22732
32ec8896 22733 return res;
252b5132
RH
22734}
22735
2cf0635d 22736/* Process an ELF archive.
32ec8896
NC
22737 On entry the file is positioned just after the ARMAG string.
22738 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22739
015dc7e1
AM
22740static bool
22741process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22742{
22743 struct archive_info arch;
22744 struct archive_info nested_arch;
22745 size_t got;
015dc7e1 22746 bool ret = true;
2cf0635d 22747
015dc7e1 22748 show_name = true;
2cf0635d
NC
22749
22750 /* The ARCH structure is used to hold information about this archive. */
22751 arch.file_name = NULL;
22752 arch.file = NULL;
22753 arch.index_array = NULL;
22754 arch.sym_table = NULL;
22755 arch.longnames = NULL;
22756
22757 /* The NESTED_ARCH structure is used as a single-item cache of information
22758 about a nested archive (when members of a thin archive reside within
22759 another regular archive file). */
22760 nested_arch.file_name = NULL;
22761 nested_arch.file = NULL;
22762 nested_arch.index_array = NULL;
22763 nested_arch.sym_table = NULL;
22764 nested_arch.longnames = NULL;
22765
dda8d76d 22766 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22767 filedata->file_size, is_thin_archive,
22768 do_archive_index) != 0)
2cf0635d 22769 {
015dc7e1 22770 ret = false;
2cf0635d 22771 goto out;
4145f1d5 22772 }
fb52b2f4 22773
4145f1d5
NC
22774 if (do_archive_index)
22775 {
2cf0635d 22776 if (arch.sym_table == NULL)
1cb7d8b1
AM
22777 error (_("%s: unable to dump the index as none was found\n"),
22778 filedata->file_name);
4145f1d5
NC
22779 else
22780 {
26c527e6
AM
22781 uint64_t i, l;
22782 uint64_t current_pos;
4145f1d5 22783
26c527e6
AM
22784 printf (_("Index of archive %s: (%" PRIu64 " entries,"
22785 " %#" PRIx64 " bytes in the symbol table)\n"),
22786 filedata->file_name, arch.index_num,
1cb7d8b1 22787 arch.sym_size);
dda8d76d
NC
22788
22789 current_pos = ftell (filedata->handle);
4145f1d5 22790
2cf0635d 22791 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22792 {
1cb7d8b1
AM
22793 if (i == 0
22794 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22795 {
22796 char * member_name
22797 = get_archive_member_name_at (&arch, arch.index_array[i],
22798 &nested_arch);
2cf0635d 22799
1cb7d8b1
AM
22800 if (member_name != NULL)
22801 {
22802 char * qualified_name
22803 = make_qualified_name (&arch, &nested_arch,
22804 member_name);
2cf0635d 22805
1cb7d8b1
AM
22806 if (qualified_name != NULL)
22807 {
22808 printf (_("Contents of binary %s at offset "),
22809 qualified_name);
c2a7d3f5
NC
22810 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22811 putchar ('\n');
1cb7d8b1
AM
22812 free (qualified_name);
22813 }
fd486f32 22814 free (member_name);
4145f1d5
NC
22815 }
22816 }
2cf0635d
NC
22817
22818 if (l >= arch.sym_size)
4145f1d5 22819 {
1cb7d8b1
AM
22820 error (_("%s: end of the symbol table reached "
22821 "before the end of the index\n"),
dda8d76d 22822 filedata->file_name);
015dc7e1 22823 ret = false;
cb8f3167 22824 break;
4145f1d5 22825 }
591f7597 22826 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22827 printf ("\t%.*s\n",
22828 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22829 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22830 }
22831
67ce483b 22832 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22833 l = (l + 7) & ~ 7;
22834 else
22835 l += l & 1;
22836
2cf0635d 22837 if (l < arch.sym_size)
32ec8896 22838 {
26c527e6 22839 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
22840 "but without corresponding entries in "
22841 "the index table\n",
26c527e6 22842 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
22843 "but without corresponding entries in "
22844 "the index table\n",
22845 arch.sym_size - l),
dda8d76d 22846 filedata->file_name, arch.sym_size - l);
015dc7e1 22847 ret = false;
32ec8896 22848 }
4145f1d5 22849
63cf857e 22850 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22851 {
1cb7d8b1
AM
22852 error (_("%s: failed to seek back to start of object files "
22853 "in the archive\n"),
dda8d76d 22854 filedata->file_name);
015dc7e1 22855 ret = false;
2cf0635d 22856 goto out;
4145f1d5 22857 }
fb52b2f4 22858 }
4145f1d5
NC
22859
22860 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22861 && !do_segments && !do_header && !do_dump && !do_version
22862 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22863 && !do_section_groups && !do_dyn_syms)
2cf0635d 22864 {
015dc7e1 22865 ret = true; /* Archive index only. */
2cf0635d
NC
22866 goto out;
22867 }
fb52b2f4
NC
22868 }
22869
fb52b2f4
NC
22870 while (1)
22871 {
2cf0635d
NC
22872 char * name;
22873 size_t namelen;
22874 char * qualified_name;
22875
22876 /* Read the next archive header. */
63cf857e 22877 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22878 {
22879 error (_("%s: failed to seek to next archive header\n"),
22880 arch.file_name);
015dc7e1 22881 ret = false;
1cb7d8b1
AM
22882 break;
22883 }
dda8d76d 22884 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22885 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22886 {
22887 if (got == 0)
2cf0635d 22888 break;
28e817cc
NC
22889 /* PR 24049 - we cannot use filedata->file_name as this will
22890 have already been freed. */
22891 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22892
015dc7e1 22893 ret = false;
1cb7d8b1
AM
22894 break;
22895 }
2cf0635d 22896 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22897 {
22898 error (_("%s: did not find a valid archive header\n"),
22899 arch.file_name);
015dc7e1 22900 ret = false;
1cb7d8b1
AM
22901 break;
22902 }
2cf0635d
NC
22903
22904 arch.next_arhdr_offset += sizeof arch.arhdr;
22905
978c4450 22906 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22907
22908 name = get_archive_member_name (&arch, &nested_arch);
22909 if (name == NULL)
fb52b2f4 22910 {
28e817cc 22911 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22912 ret = false;
d989285c 22913 break;
fb52b2f4 22914 }
2cf0635d 22915 namelen = strlen (name);
fb52b2f4 22916
2cf0635d
NC
22917 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22918 if (qualified_name == NULL)
fb52b2f4 22919 {
28e817cc 22920 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22921 free (name);
015dc7e1 22922 ret = false;
d989285c 22923 break;
fb52b2f4
NC
22924 }
22925
2cf0635d 22926 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22927 {
22928 /* This is a proxy for an external member of a thin archive. */
22929 Filedata * member_filedata;
22930 char * member_file_name = adjust_relative_path
dda8d76d 22931 (filedata->file_name, name, namelen);
32ec8896 22932
fd486f32 22933 free (name);
1cb7d8b1
AM
22934 if (member_file_name == NULL)
22935 {
fd486f32 22936 free (qualified_name);
015dc7e1 22937 ret = false;
1cb7d8b1
AM
22938 break;
22939 }
2cf0635d 22940
015dc7e1 22941 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22942 if (member_filedata == NULL)
22943 {
22944 error (_("Input file '%s' is not readable.\n"), member_file_name);
22945 free (member_file_name);
fd486f32 22946 free (qualified_name);
015dc7e1 22947 ret = false;
1cb7d8b1
AM
22948 break;
22949 }
2cf0635d 22950
978c4450 22951 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22952 member_filedata->file_name = qualified_name;
2cf0635d 22953
75a2da57
AH
22954 /* The call to process_object() expects the file to be at the beginning. */
22955 rewind (member_filedata->handle);
22956
1cb7d8b1 22957 if (! process_object (member_filedata))
015dc7e1 22958 ret = false;
2cf0635d 22959
1cb7d8b1
AM
22960 close_file (member_filedata);
22961 free (member_file_name);
1cb7d8b1 22962 }
2cf0635d 22963 else if (is_thin_archive)
1cb7d8b1
AM
22964 {
22965 Filedata thin_filedata;
eb02c04d 22966
1cb7d8b1 22967 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22968
a043396b
NC
22969 /* PR 15140: Allow for corrupt thin archives. */
22970 if (nested_arch.file == NULL)
22971 {
22972 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22973 qualified_name, name);
fd486f32
AM
22974 free (qualified_name);
22975 free (name);
015dc7e1 22976 ret = false;
a043396b
NC
22977 break;
22978 }
fd486f32 22979 free (name);
a043396b 22980
1cb7d8b1 22981 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22982 filedata->archive_file_offset
22983 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22984
1cb7d8b1
AM
22985 /* The nested archive file will have been opened and setup by
22986 get_archive_member_name. */
63cf857e
AM
22987 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
22988 SEEK_SET) != 0)
1cb7d8b1
AM
22989 {
22990 error (_("%s: failed to seek to archive member.\n"),
22991 nested_arch.file_name);
fd486f32 22992 free (qualified_name);
015dc7e1 22993 ret = false;
1cb7d8b1
AM
22994 break;
22995 }
2cf0635d 22996
dda8d76d
NC
22997 thin_filedata.handle = nested_arch.file;
22998 thin_filedata.file_name = qualified_name;
9abca702 22999
1cb7d8b1 23000 if (! process_object (& thin_filedata))
015dc7e1 23001 ret = false;
1cb7d8b1 23002 }
2cf0635d 23003 else
1cb7d8b1 23004 {
fd486f32 23005 free (name);
978c4450 23006 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 23007 filedata->file_name = qualified_name;
1cb7d8b1 23008 if (! process_object (filedata))
015dc7e1 23009 ret = false;
237877b8 23010 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 23011 /* Stop looping with "negative" archive_file_size. */
978c4450 23012 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 23013 arch.next_arhdr_offset = -1ul;
1cb7d8b1 23014 }
fb52b2f4 23015
2cf0635d 23016 free (qualified_name);
fb52b2f4
NC
23017 }
23018
4145f1d5 23019 out:
2cf0635d
NC
23020 if (nested_arch.file != NULL)
23021 fclose (nested_arch.file);
23022 release_archive (&nested_arch);
23023 release_archive (&arch);
fb52b2f4 23024
d989285c 23025 return ret;
fb52b2f4
NC
23026}
23027
015dc7e1 23028static bool
2cf0635d 23029process_file (char * file_name)
fb52b2f4 23030{
dda8d76d 23031 Filedata * filedata = NULL;
fb52b2f4
NC
23032 struct stat statbuf;
23033 char armag[SARMAG];
015dc7e1 23034 bool ret = true;
fb52b2f4
NC
23035
23036 if (stat (file_name, &statbuf) < 0)
23037 {
f24ddbdd
NC
23038 if (errno == ENOENT)
23039 error (_("'%s': No such file\n"), file_name);
23040 else
23041 error (_("Could not locate '%s'. System error message: %s\n"),
23042 file_name, strerror (errno));
015dc7e1 23043 return false;
f24ddbdd
NC
23044 }
23045
23046 if (! S_ISREG (statbuf.st_mode))
23047 {
23048 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 23049 return false;
fb52b2f4
NC
23050 }
23051
dda8d76d
NC
23052 filedata = calloc (1, sizeof * filedata);
23053 if (filedata == NULL)
23054 {
23055 error (_("Out of memory allocating file data structure\n"));
015dc7e1 23056 return false;
dda8d76d
NC
23057 }
23058
23059 filedata->file_name = file_name;
23060 filedata->handle = fopen (file_name, "rb");
23061 if (filedata->handle == NULL)
fb52b2f4 23062 {
f24ddbdd 23063 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 23064 free (filedata);
015dc7e1 23065 return false;
fb52b2f4
NC
23066 }
23067
dda8d76d 23068 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 23069 {
4145f1d5 23070 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
23071 fclose (filedata->handle);
23072 free (filedata);
015dc7e1 23073 return false;
fb52b2f4
NC
23074 }
23075
be7d229a 23076 filedata->file_size = statbuf.st_size;
015dc7e1 23077 filedata->is_separate = false;
f54498b4 23078
fb52b2f4 23079 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 23080 {
015dc7e1
AM
23081 if (! process_archive (filedata, false))
23082 ret = false;
32ec8896 23083 }
2cf0635d 23084 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 23085 {
015dc7e1
AM
23086 if ( ! process_archive (filedata, true))
23087 ret = false;
32ec8896 23088 }
fb52b2f4
NC
23089 else
23090 {
1b513401 23091 if (do_archive_index && !check_all)
4145f1d5
NC
23092 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23093 file_name);
23094
dda8d76d 23095 rewind (filedata->handle);
978c4450 23096 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 23097
dda8d76d 23098 if (! process_object (filedata))
015dc7e1 23099 ret = false;
fb52b2f4
NC
23100 }
23101
dda8d76d 23102 fclose (filedata->handle);
8fb879cd
AM
23103 free (filedata->section_headers);
23104 free (filedata->program_headers);
23105 free (filedata->string_table);
6431e409 23106 free (filedata->dump.dump_sects);
dda8d76d 23107 free (filedata);
32ec8896 23108
fd486f32 23109 free (ba_cache.strtab);
1bd6175a 23110 ba_cache.strtab = NULL;
fd486f32 23111 free (ba_cache.symtab);
1bd6175a 23112 ba_cache.symtab = NULL;
fd486f32
AM
23113 ba_cache.filedata = NULL;
23114
fb52b2f4
NC
23115 return ret;
23116}
23117
252b5132
RH
23118#ifdef SUPPORT_DISASSEMBLY
23119/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 23120 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 23121 symbols. */
252b5132
RH
23122
23123void
2cf0635d 23124print_address (unsigned int addr, FILE * outfile)
252b5132
RH
23125{
23126 fprintf (outfile,"0x%8.8x", addr);
23127}
23128
e3c8793a 23129/* Needed by the i386 disassembler. */
dda8d76d 23130
252b5132
RH
23131void
23132db_task_printsym (unsigned int addr)
23133{
23134 print_address (addr, stderr);
23135}
23136#endif
23137
23138int
2cf0635d 23139main (int argc, char ** argv)
252b5132 23140{
ff78d6d6
L
23141 int err;
23142
87b9f255 23143#ifdef HAVE_LC_MESSAGES
252b5132 23144 setlocale (LC_MESSAGES, "");
3882b010 23145#endif
3882b010 23146 setlocale (LC_CTYPE, "");
252b5132
RH
23147 bindtextdomain (PACKAGE, LOCALEDIR);
23148 textdomain (PACKAGE);
23149
869b9d07
MM
23150 expandargv (&argc, &argv);
23151
dda8d76d 23152 parse_args (& cmdline, argc, argv);
59f14fc0 23153
18bd398b 23154 if (optind < (argc - 1))
1b513401
NC
23155 /* When displaying information for more than one file,
23156 prefix the information with the file name. */
015dc7e1 23157 show_name = true;
5656ba2c
L
23158 else if (optind >= argc)
23159 {
1b513401 23160 /* Ensure that the warning is always displayed. */
015dc7e1 23161 do_checks = true;
1b513401 23162
5656ba2c
L
23163 warn (_("Nothing to do.\n"));
23164 usage (stderr);
23165 }
18bd398b 23166
015dc7e1 23167 err = false;
252b5132 23168 while (optind < argc)
32ec8896 23169 if (! process_file (argv[optind++]))
015dc7e1 23170 err = true;
252b5132 23171
9db70fc3 23172 free (cmdline.dump_sects);
252b5132 23173
7d9813f1
NA
23174 free (dump_ctf_symtab_name);
23175 free (dump_ctf_strtab_name);
23176 free (dump_ctf_parent_name);
23177
32ec8896 23178 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 23179}