]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Minor objcopy optimisation for copy_relocations_in_section
[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
14024 value = read_leb128 (start + reloc->r_offset, end, false,
14025 &reloc_size, &leb_ret);
14026 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14027 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
14028 "ULEB128 value\n"),
14029 (long) reloc->r_offset);
14030
14031 if (107 == reloc_type)
14032 value += (reloc->r_addend + symtab[sym_index].st_value);
14033 else if (108 == reloc_type)
14034 value -= (reloc->r_addend + symtab[sym_index].st_value);
14035
14036 /* Write uleb128 value to p. */
14037 bfd_byte c;
14038 bfd_byte *p = start + reloc->r_offset;
14039 do
14040 {
14041 c = value & 0x7f;
14042 if (reloc_size > 1)
14043 c |= 0x80;
14044 *(p++) = c;
14045 value >>= 7;
14046 reloc_size--;
14047 }
14048 while (reloc_size);
14049
14050 return true;
14051 }
14052 }
14053 break;
14054 }
14055
13761a11
NC
14056 case EM_MSP430:
14057 case EM_MSP430_OLD:
14058 {
14059 static Elf_Internal_Sym * saved_sym = NULL;
14060
f84ce13b
NC
14061 if (reloc == NULL)
14062 {
14063 saved_sym = NULL;
015dc7e1 14064 return true;
f84ce13b
NC
14065 }
14066
13761a11
NC
14067 switch (reloc_type)
14068 {
14069 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 14070 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 14071 if (uses_msp430x_relocs (filedata))
13761a11 14072 break;
1a0670f3 14073 /* Fall through. */
13761a11 14074 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 14075 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
14076 /* PR 21139. */
14077 if (sym_index >= num_syms)
26c527e6
AM
14078 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index"
14079 " %" PRIu64 "\n"), sym_index);
f84ce13b
NC
14080 else
14081 saved_sym = symtab + sym_index;
015dc7e1 14082 return true;
13761a11
NC
14083
14084 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14085 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14086 goto handle_sym_diff;
0b4362b0 14087
13761a11
NC
14088 case 5: /* R_MSP430_16_BYTE */
14089 case 9: /* R_MSP430_8 */
7d81bc93 14090 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 14091 if (uses_msp430x_relocs (filedata))
13761a11
NC
14092 break;
14093 goto handle_sym_diff;
14094
14095 case 2: /* R_MSP430_ABS16 */
14096 case 15: /* R_MSP430X_ABS16 */
7d81bc93 14097 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 14098 if (! uses_msp430x_relocs (filedata))
13761a11
NC
14099 break;
14100 goto handle_sym_diff;
0b4362b0 14101
13761a11
NC
14102 handle_sym_diff:
14103 if (saved_sym != NULL)
14104 {
625d49fc 14105 uint64_t value;
5a805384 14106 unsigned int reloc_size = 0;
7d81bc93
JL
14107 int leb_ret = 0;
14108 switch (reloc_type)
14109 {
14110 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14111 reloc_size = 4;
14112 break;
14113 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14114 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14115 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14116 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14117 &reloc_size, &leb_ret);
7d81bc93
JL
14118 break;
14119 default:
14120 reloc_size = 2;
14121 break;
14122 }
13761a11 14123
5a805384 14124 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
14125 error (_("MSP430 ULEB128 field at %#" PRIx64
14126 " contains invalid ULEB128 value\n"),
14127 reloc->r_offset);
7d81bc93 14128 else if (sym_index >= num_syms)
26c527e6
AM
14129 error (_("MSP430 reloc contains invalid symbol index "
14130 "%" PRIu64 "\n"),
f84ce13b 14131 sym_index);
03f7786e 14132 else
f84ce13b
NC
14133 {
14134 value = reloc->r_addend + (symtab[sym_index].st_value
14135 - saved_sym->st_value);
14136
b32e566b 14137 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14138 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14139 else
14140 /* PR 21137 */
26c527e6
AM
14141 error (_("MSP430 sym diff reloc contains invalid offset: "
14142 "%#" PRIx64 "\n"),
14143 reloc->r_offset);
f84ce13b 14144 }
13761a11
NC
14145
14146 saved_sym = NULL;
015dc7e1 14147 return true;
13761a11
NC
14148 }
14149 break;
14150
14151 default:
14152 if (saved_sym != NULL)
071436c6 14153 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14154 break;
14155 }
14156 break;
14157 }
14158
cf13d699
NC
14159 case EM_MN10300:
14160 case EM_CYGNUS_MN10300:
14161 {
14162 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14163
f84ce13b
NC
14164 if (reloc == NULL)
14165 {
14166 saved_sym = NULL;
015dc7e1 14167 return true;
f84ce13b
NC
14168 }
14169
cf13d699
NC
14170 switch (reloc_type)
14171 {
14172 case 34: /* R_MN10300_ALIGN */
015dc7e1 14173 return true;
cf13d699 14174 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 14175 if (sym_index >= num_syms)
26c527e6
AM
14176 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index "
14177 "%" PRIu64 "\n"),
f84ce13b
NC
14178 sym_index);
14179 else
14180 saved_sym = symtab + sym_index;
015dc7e1 14181 return true;
f84ce13b 14182
cf13d699
NC
14183 case 1: /* R_MN10300_32 */
14184 case 2: /* R_MN10300_16 */
14185 if (saved_sym != NULL)
14186 {
03f7786e 14187 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14188 uint64_t value;
252b5132 14189
f84ce13b 14190 if (sym_index >= num_syms)
26c527e6
AM
14191 error (_("MN10300 reloc contains invalid symbol index "
14192 "%" PRIu64 "\n"),
f84ce13b 14193 sym_index);
03f7786e 14194 else
f84ce13b
NC
14195 {
14196 value = reloc->r_addend + (symtab[sym_index].st_value
14197 - saved_sym->st_value);
14198
b32e566b 14199 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14200 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 14201 else
26c527e6
AM
14202 error (_("MN10300 sym diff reloc contains invalid offset:"
14203 " %#" PRIx64 "\n"),
14204 reloc->r_offset);
f84ce13b 14205 }
252b5132 14206
cf13d699 14207 saved_sym = NULL;
015dc7e1 14208 return true;
cf13d699
NC
14209 }
14210 break;
14211 default:
14212 if (saved_sym != NULL)
071436c6 14213 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14214 break;
14215 }
14216 break;
14217 }
6ff71e76
NC
14218
14219 case EM_RL78:
14220 {
625d49fc
AM
14221 static uint64_t saved_sym1 = 0;
14222 static uint64_t saved_sym2 = 0;
14223 static uint64_t value;
6ff71e76 14224
f84ce13b
NC
14225 if (reloc == NULL)
14226 {
14227 saved_sym1 = saved_sym2 = 0;
015dc7e1 14228 return true;
f84ce13b
NC
14229 }
14230
6ff71e76
NC
14231 switch (reloc_type)
14232 {
14233 case 0x80: /* R_RL78_SYM. */
14234 saved_sym1 = saved_sym2;
f84ce13b 14235 if (sym_index >= num_syms)
26c527e6
AM
14236 error (_("RL78_SYM reloc contains invalid symbol index "
14237 "%" PRIu64 "\n"), sym_index);
f84ce13b
NC
14238 else
14239 {
14240 saved_sym2 = symtab[sym_index].st_value;
14241 saved_sym2 += reloc->r_addend;
14242 }
015dc7e1 14243 return true;
6ff71e76
NC
14244
14245 case 0x83: /* R_RL78_OPsub. */
14246 value = saved_sym1 - saved_sym2;
14247 saved_sym2 = saved_sym1 = 0;
015dc7e1 14248 return true;
6ff71e76
NC
14249 break;
14250
14251 case 0x41: /* R_RL78_ABS32. */
b32e566b 14252 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14253 byte_put (start + reloc->r_offset, value, 4);
b32e566b 14254 else
26c527e6
AM
14255 error (_("RL78 sym diff reloc contains invalid offset: "
14256 "%#" PRIx64 "\n"),
14257 reloc->r_offset);
6ff71e76 14258 value = 0;
015dc7e1 14259 return true;
6ff71e76
NC
14260
14261 case 0x43: /* R_RL78_ABS16. */
b32e566b 14262 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14263 byte_put (start + reloc->r_offset, value, 2);
b32e566b 14264 else
26c527e6
AM
14265 error (_("RL78 sym diff reloc contains invalid offset: "
14266 "%#" PRIx64 "\n"),
14267 reloc->r_offset);
6ff71e76 14268 value = 0;
015dc7e1 14269 return true;
6ff71e76
NC
14270
14271 default:
14272 break;
14273 }
14274 break;
14275 }
252b5132
RH
14276 }
14277
015dc7e1 14278 return false;
252b5132
RH
14279}
14280
aca88567
NC
14281/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14282 DWARF debug sections. This is a target specific test. Note - we do not
14283 go through the whole including-target-headers-multiple-times route, (as
14284 we have already done with <elf/h8.h>) because this would become very
14285 messy and even then this function would have to contain target specific
14286 information (the names of the relocs instead of their numeric values).
14287 FIXME: This is not the correct way to solve this problem. The proper way
14288 is to have target specific reloc sizing and typing functions created by
14289 the reloc-macros.h header, in the same way that it already creates the
14290 reloc naming functions. */
14291
015dc7e1 14292static bool
dda8d76d 14293is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14294{
d347c9df 14295 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14296 switch (filedata->file_header.e_machine)
aca88567 14297 {
41e92641 14298 case EM_386:
22abe556 14299 case EM_IAMCU:
41e92641 14300 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14301 case EM_68K:
14302 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14303 case EM_860:
14304 return reloc_type == 1; /* R_860_32. */
14305 case EM_960:
14306 return reloc_type == 2; /* R_960_32. */
a06ea964 14307 case EM_AARCH64:
9282b95a
JW
14308 return (reloc_type == 258
14309 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14310 case EM_BPF:
14311 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14312 case EM_ADAPTEVA_EPIPHANY:
14313 return reloc_type == 3;
aca88567 14314 case EM_ALPHA:
137b6b5f 14315 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14316 case EM_ARC:
14317 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14318 case EM_ARC_COMPACT:
14319 case EM_ARC_COMPACT2:
14320 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14321 case EM_ARM:
14322 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14323 case EM_AVR_OLD:
aca88567
NC
14324 case EM_AVR:
14325 return reloc_type == 1;
14326 case EM_BLACKFIN:
14327 return reloc_type == 0x12; /* R_byte4_data. */
14328 case EM_CRIS:
14329 return reloc_type == 3; /* R_CRIS_32. */
14330 case EM_CR16:
14331 return reloc_type == 3; /* R_CR16_NUM32. */
14332 case EM_CRX:
14333 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14334 case EM_CSKY:
14335 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14336 case EM_CYGNUS_FRV:
14337 return reloc_type == 1;
41e92641
NC
14338 case EM_CYGNUS_D10V:
14339 case EM_D10V:
14340 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14341 case EM_CYGNUS_D30V:
14342 case EM_D30V:
14343 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14344 case EM_DLX:
14345 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14346 case EM_CYGNUS_FR30:
14347 case EM_FR30:
14348 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14349 case EM_FT32:
14350 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14351 case EM_H8S:
14352 case EM_H8_300:
14353 case EM_H8_300H:
14354 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14355 case EM_IA_64:
262cdac7
AM
14356 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14357 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14358 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14359 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14360 case EM_IP2K_OLD:
14361 case EM_IP2K:
14362 return reloc_type == 2; /* R_IP2K_32. */
14363 case EM_IQ2000:
14364 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14365 case EM_LATTICEMICO32:
14366 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14367 case EM_LOONGARCH:
14368 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14369 case EM_M32C_OLD:
aca88567
NC
14370 case EM_M32C:
14371 return reloc_type == 3; /* R_M32C_32. */
14372 case EM_M32R:
14373 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14374 case EM_68HC11:
14375 case EM_68HC12:
14376 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14377 case EM_S12Z:
2849d19f
JD
14378 return reloc_type == 7 || /* R_S12Z_EXT32 */
14379 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14380 case EM_MCORE:
14381 return reloc_type == 1; /* R_MCORE_ADDR32. */
14382 case EM_CYGNUS_MEP:
14383 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14384 case EM_METAG:
14385 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14386 case EM_MICROBLAZE:
14387 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14388 case EM_MIPS:
14389 return reloc_type == 2; /* R_MIPS_32. */
14390 case EM_MMIX:
14391 return reloc_type == 4; /* R_MMIX_32. */
14392 case EM_CYGNUS_MN10200:
14393 case EM_MN10200:
14394 return reloc_type == 1; /* R_MN10200_32. */
14395 case EM_CYGNUS_MN10300:
14396 case EM_MN10300:
14397 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14398 case EM_MOXIE:
14399 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14400 case EM_MSP430_OLD:
14401 case EM_MSP430:
13761a11 14402 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14403 case EM_MT:
14404 return reloc_type == 2; /* R_MT_32. */
35c08157 14405 case EM_NDS32:
81c5e376 14406 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14407 case EM_ALTERA_NIOS2:
36591ba1 14408 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14409 case EM_NIOS32:
14410 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14411 case EM_OR1K:
14412 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14413 case EM_PARISC:
9abca702 14414 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14415 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14416 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14417 case EM_PJ:
14418 case EM_PJ_OLD:
14419 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14420 case EM_PPC64:
14421 return reloc_type == 1; /* R_PPC64_ADDR32. */
14422 case EM_PPC:
14423 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14424 case EM_TI_PRU:
14425 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14426 case EM_RISCV:
14427 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14428 case EM_RL78:
14429 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14430 case EM_RX:
14431 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14432 case EM_S370:
14433 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14434 case EM_S390_OLD:
14435 case EM_S390:
14436 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14437 case EM_SCORE:
14438 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14439 case EM_SH:
14440 return reloc_type == 1; /* R_SH_DIR32. */
14441 case EM_SPARC32PLUS:
14442 case EM_SPARCV9:
14443 case EM_SPARC:
14444 return reloc_type == 3 /* R_SPARC_32. */
14445 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14446 case EM_SPU:
14447 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14448 case EM_TI_C6000:
14449 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14450 case EM_TILEGX:
14451 return reloc_type == 2; /* R_TILEGX_32. */
14452 case EM_TILEPRO:
14453 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14454 case EM_CYGNUS_V850:
14455 case EM_V850:
14456 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14457 case EM_V800:
14458 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14459 case EM_VAX:
14460 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14461 case EM_VISIUM:
14462 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14463 case EM_WEBASSEMBLY:
14464 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14465 case EM_X86_64:
8a9036a4 14466 case EM_L1OM:
7a9068fe 14467 case EM_K1OM:
aca88567 14468 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14469 case EM_XGATE:
14470 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14471 case EM_XSTORMY16:
14472 return reloc_type == 1; /* R_XSTROMY16_32. */
14473 case EM_XTENSA_OLD:
14474 case EM_XTENSA:
14475 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14476 case EM_Z80:
14477 return reloc_type == 6; /* R_Z80_32. */
aca88567 14478 default:
bee0ee85
NC
14479 {
14480 static unsigned int prev_warn = 0;
14481
14482 /* Avoid repeating the same warning multiple times. */
dda8d76d 14483 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14484 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14485 filedata->file_header.e_machine);
14486 prev_warn = filedata->file_header.e_machine;
015dc7e1 14487 return false;
bee0ee85 14488 }
aca88567
NC
14489 }
14490}
14491
14492/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14493 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14494
015dc7e1 14495static bool
dda8d76d 14496is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14497{
dda8d76d 14498 switch (filedata->file_header.e_machine)
d347c9df 14499 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14500 {
41e92641 14501 case EM_386:
22abe556 14502 case EM_IAMCU:
3e0873ac 14503 return reloc_type == 2; /* R_386_PC32. */
aca88567 14504 case EM_68K:
3e0873ac 14505 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14506 case EM_AARCH64:
14507 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14508 case EM_ADAPTEVA_EPIPHANY:
14509 return reloc_type == 6;
aca88567
NC
14510 case EM_ALPHA:
14511 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14512 case EM_ARC_COMPACT:
14513 case EM_ARC_COMPACT2:
14514 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14515 case EM_ARM:
3e0873ac 14516 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14517 case EM_AVR_OLD:
14518 case EM_AVR:
14519 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14520 case EM_LOONGARCH:
14521 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14522 case EM_MICROBLAZE:
14523 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14524 case EM_OR1K:
14525 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14526 case EM_PARISC:
85acf597 14527 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14528 case EM_PPC:
14529 return reloc_type == 26; /* R_PPC_REL32. */
14530 case EM_PPC64:
3e0873ac 14531 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14532 case EM_RISCV:
14533 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14534 case EM_S390_OLD:
14535 case EM_S390:
3e0873ac 14536 return reloc_type == 5; /* R_390_PC32. */
aca88567 14537 case EM_SH:
3e0873ac 14538 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14539 case EM_SPARC32PLUS:
14540 case EM_SPARCV9:
14541 case EM_SPARC:
3e0873ac 14542 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14543 case EM_SPU:
14544 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14545 case EM_TILEGX:
14546 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14547 case EM_TILEPRO:
14548 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14549 case EM_VISIUM:
14550 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14551 case EM_X86_64:
8a9036a4 14552 case EM_L1OM:
7a9068fe 14553 case EM_K1OM:
3e0873ac 14554 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14555 case EM_VAX:
14556 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14557 case EM_XTENSA_OLD:
14558 case EM_XTENSA:
14559 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14560 default:
14561 /* Do not abort or issue an error message here. Not all targets use
14562 pc-relative 32-bit relocs in their DWARF debug information and we
14563 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14564 more helpful warning message will be generated by apply_relocations
14565 anyway, so just return. */
015dc7e1 14566 return false;
aca88567
NC
14567 }
14568}
14569
14570/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14571 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14572
015dc7e1 14573static bool
dda8d76d 14574is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14575{
dda8d76d 14576 switch (filedata->file_header.e_machine)
aca88567 14577 {
a06ea964
NC
14578 case EM_AARCH64:
14579 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14580 case EM_ALPHA:
14581 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14582 case EM_IA_64:
262cdac7
AM
14583 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14584 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14585 case EM_LOONGARCH:
14586 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14587 case EM_PARISC:
14588 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14589 case EM_PPC64:
14590 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14591 case EM_RISCV:
14592 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14593 case EM_SPARC32PLUS:
14594 case EM_SPARCV9:
14595 case EM_SPARC:
714da62f
NC
14596 return reloc_type == 32 /* R_SPARC_64. */
14597 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14598 case EM_X86_64:
8a9036a4 14599 case EM_L1OM:
7a9068fe 14600 case EM_K1OM:
aca88567 14601 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14602 case EM_S390_OLD:
14603 case EM_S390:
aa137e4d
NC
14604 return reloc_type == 22; /* R_S390_64. */
14605 case EM_TILEGX:
14606 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14607 case EM_MIPS:
aa137e4d 14608 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14609 default:
015dc7e1 14610 return false;
aca88567
NC
14611 }
14612}
14613
85acf597
RH
14614/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14615 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14616
015dc7e1 14617static bool
dda8d76d 14618is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14619{
dda8d76d 14620 switch (filedata->file_header.e_machine)
85acf597 14621 {
a06ea964
NC
14622 case EM_AARCH64:
14623 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14624 case EM_ALPHA:
aa137e4d 14625 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14626 case EM_IA_64:
262cdac7
AM
14627 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14628 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14629 case EM_PARISC:
aa137e4d 14630 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14631 case EM_PPC64:
aa137e4d 14632 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14633 case EM_SPARC32PLUS:
14634 case EM_SPARCV9:
14635 case EM_SPARC:
aa137e4d 14636 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14637 case EM_X86_64:
8a9036a4 14638 case EM_L1OM:
7a9068fe 14639 case EM_K1OM:
aa137e4d 14640 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14641 case EM_S390_OLD:
14642 case EM_S390:
aa137e4d
NC
14643 return reloc_type == 23; /* R_S390_PC64. */
14644 case EM_TILEGX:
14645 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14646 default:
015dc7e1 14647 return false;
85acf597
RH
14648 }
14649}
14650
4dc3c23d
AM
14651/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14652 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14653
015dc7e1 14654static bool
dda8d76d 14655is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14656{
dda8d76d 14657 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14658 {
14659 case EM_CYGNUS_MN10200:
14660 case EM_MN10200:
14661 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14662 case EM_FT32:
14663 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14664 case EM_Z80:
14665 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14666 default:
015dc7e1 14667 return false;
4dc3c23d
AM
14668 }
14669}
14670
aca88567
NC
14671/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14672 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14673
015dc7e1 14674static bool
dda8d76d 14675is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14676{
d347c9df 14677 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14678 switch (filedata->file_header.e_machine)
4b78141a 14679 {
886a2506
NC
14680 case EM_ARC:
14681 case EM_ARC_COMPACT:
14682 case EM_ARC_COMPACT2:
14683 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14684 case EM_ADAPTEVA_EPIPHANY:
14685 return reloc_type == 5;
aca88567
NC
14686 case EM_AVR_OLD:
14687 case EM_AVR:
14688 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14689 case EM_CYGNUS_D10V:
14690 case EM_D10V:
14691 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14692 case EM_FT32:
14693 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14694 case EM_H8S:
14695 case EM_H8_300:
14696 case EM_H8_300H:
aca88567
NC
14697 return reloc_type == R_H8_DIR16;
14698 case EM_IP2K_OLD:
14699 case EM_IP2K:
14700 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14701 case EM_M32C_OLD:
f4236fe4
DD
14702 case EM_M32C:
14703 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14704 case EM_CYGNUS_MN10200:
14705 case EM_MN10200:
14706 return reloc_type == 2; /* R_MN10200_16. */
14707 case EM_CYGNUS_MN10300:
14708 case EM_MN10300:
14709 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14710 case EM_MSP430:
dda8d76d 14711 if (uses_msp430x_relocs (filedata))
13761a11 14712 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14713 /* Fall through. */
78c8d46c 14714 case EM_MSP430_OLD:
aca88567 14715 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 14716 case EM_NDS32:
81c5e376 14717 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 14718 case EM_ALTERA_NIOS2:
36591ba1 14719 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14720 case EM_NIOS32:
14721 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14722 case EM_OR1K:
14723 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14724 case EM_RISCV:
14725 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14726 case EM_TI_PRU:
14727 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14728 case EM_TI_C6000:
14729 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14730 case EM_VISIUM:
14731 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
14732 case EM_XGATE:
14733 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14734 case EM_Z80:
14735 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14736 default:
015dc7e1 14737 return false;
4b78141a
NC
14738 }
14739}
14740
39e07931
AS
14741/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14742 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14743
015dc7e1 14744static bool
39e07931
AS
14745is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14746{
14747 switch (filedata->file_header.e_machine)
14748 {
14749 case EM_RISCV:
14750 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14751 case EM_Z80:
14752 return reloc_type == 1; /* R_Z80_8. */
39e07931 14753 default:
015dc7e1 14754 return false;
39e07931
AS
14755 }
14756}
14757
14758/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14759 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14760
015dc7e1 14761static bool
39e07931
AS
14762is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14763{
14764 switch (filedata->file_header.e_machine)
14765 {
14766 case EM_RISCV:
14767 return reloc_type == 53; /* R_RISCV_SET6. */
14768 default:
015dc7e1 14769 return false;
39e07931
AS
14770 }
14771}
14772
03336641
JW
14773/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14774 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14775
015dc7e1 14776static bool
03336641
JW
14777is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14778{
14779 /* Please keep this table alpha-sorted for ease of visual lookup. */
14780 switch (filedata->file_header.e_machine)
14781 {
76244462 14782 case EM_LOONGARCH:
14783 return reloc_type == 50; /* R_LARCH_ADD32. */
03336641
JW
14784 case EM_RISCV:
14785 return reloc_type == 35; /* R_RISCV_ADD32. */
14786 default:
015dc7e1 14787 return false;
03336641
JW
14788 }
14789}
14790
14791/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14792 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14793
015dc7e1 14794static bool
03336641
JW
14795is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14796{
14797 /* Please keep this table alpha-sorted for ease of visual lookup. */
14798 switch (filedata->file_header.e_machine)
14799 {
76244462 14800 case EM_LOONGARCH:
14801 return reloc_type == 55; /* R_LARCH_SUB32. */
03336641
JW
14802 case EM_RISCV:
14803 return reloc_type == 39; /* R_RISCV_SUB32. */
14804 default:
015dc7e1 14805 return false;
03336641
JW
14806 }
14807}
14808
14809/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14810 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14811
015dc7e1 14812static bool
03336641
JW
14813is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14814{
14815 /* Please keep this table alpha-sorted for ease of visual lookup. */
14816 switch (filedata->file_header.e_machine)
14817 {
76244462 14818 case EM_LOONGARCH:
14819 return reloc_type == 51; /* R_LARCH_ADD64. */
03336641
JW
14820 case EM_RISCV:
14821 return reloc_type == 36; /* R_RISCV_ADD64. */
14822 default:
015dc7e1 14823 return false;
03336641
JW
14824 }
14825}
14826
14827/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14828 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14829
015dc7e1 14830static bool
03336641
JW
14831is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14832{
14833 /* Please keep this table alpha-sorted for ease of visual lookup. */
14834 switch (filedata->file_header.e_machine)
14835 {
76244462 14836 case EM_LOONGARCH:
14837 return reloc_type == 56; /* R_LARCH_SUB64. */
03336641
JW
14838 case EM_RISCV:
14839 return reloc_type == 40; /* R_RISCV_SUB64. */
14840 default:
015dc7e1 14841 return false;
03336641
JW
14842 }
14843}
14844
14845/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14846 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14847
015dc7e1 14848static bool
03336641
JW
14849is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14850{
14851 /* Please keep this table alpha-sorted for ease of visual lookup. */
14852 switch (filedata->file_header.e_machine)
14853 {
76244462 14854 case EM_LOONGARCH:
14855 return reloc_type == 48; /* R_LARCH_ADD16. */
03336641
JW
14856 case EM_RISCV:
14857 return reloc_type == 34; /* R_RISCV_ADD16. */
14858 default:
015dc7e1 14859 return false;
03336641
JW
14860 }
14861}
14862
14863/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14864 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14865
015dc7e1 14866static bool
03336641
JW
14867is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14868{
14869 /* Please keep this table alpha-sorted for ease of visual lookup. */
14870 switch (filedata->file_header.e_machine)
14871 {
76244462 14872 case EM_LOONGARCH:
14873 return reloc_type == 53; /* R_LARCH_SUB16. */
03336641
JW
14874 case EM_RISCV:
14875 return reloc_type == 38; /* R_RISCV_SUB16. */
14876 default:
015dc7e1 14877 return false;
03336641
JW
14878 }
14879}
14880
14881/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14882 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14883
015dc7e1 14884static bool
03336641
JW
14885is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14886{
14887 /* Please keep this table alpha-sorted for ease of visual lookup. */
14888 switch (filedata->file_header.e_machine)
14889 {
76244462 14890 case EM_LOONGARCH:
14891 return reloc_type == 47; /* R_LARCH_ADD8. */
03336641
JW
14892 case EM_RISCV:
14893 return reloc_type == 33; /* R_RISCV_ADD8. */
14894 default:
015dc7e1 14895 return false;
03336641
JW
14896 }
14897}
14898
14899/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14900 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14901
015dc7e1 14902static bool
03336641
JW
14903is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14904{
14905 /* Please keep this table alpha-sorted for ease of visual lookup. */
14906 switch (filedata->file_header.e_machine)
14907 {
76244462 14908 case EM_LOONGARCH:
14909 return reloc_type == 52; /* R_LARCH_SUB8. */
03336641
JW
14910 case EM_RISCV:
14911 return reloc_type == 37; /* R_RISCV_SUB8. */
14912 default:
015dc7e1 14913 return false;
03336641
JW
14914 }
14915}
14916
76244462 14917/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14918 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
14919
14920static bool
14921is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14922{
14923 switch (filedata->file_header.e_machine)
14924 {
14925 case EM_LOONGARCH:
14926 return reloc_type == 105; /* R_LARCH_ADD6. */
14927 default:
14928 return false;
14929 }
14930}
14931
39e07931
AS
14932/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14933 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14934
015dc7e1 14935static bool
39e07931
AS
14936is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14937{
14938 switch (filedata->file_header.e_machine)
14939 {
76244462 14940 case EM_LOONGARCH:
14941 return reloc_type == 106; /* R_LARCH_SUB6. */
39e07931
AS
14942 case EM_RISCV:
14943 return reloc_type == 52; /* R_RISCV_SUB6. */
14944 default:
015dc7e1 14945 return false;
39e07931
AS
14946 }
14947}
14948
2a7b2e88
JK
14949/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14950 relocation entries (possibly formerly used for SHT_GROUP sections). */
14951
015dc7e1 14952static bool
dda8d76d 14953is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14954{
dda8d76d 14955 switch (filedata->file_header.e_machine)
2a7b2e88 14956 {
cb8f3167 14957 case EM_386: /* R_386_NONE. */
d347c9df 14958 case EM_68K: /* R_68K_NONE. */
cfb8c092 14959 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14960 case EM_ALPHA: /* R_ALPHA_NONE. */
14961 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14962 case EM_ARC: /* R_ARC_NONE. */
886a2506 14963 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14964 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14965 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 14966 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14967 case EM_FT32: /* R_FT32_NONE. */
14968 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14969 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14970 case EM_L1OM: /* R_X86_64_NONE. */
14971 case EM_M32R: /* R_M32R_NONE. */
14972 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14973 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14974 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14975 case EM_NIOS32: /* R_NIOS_NONE. */
14976 case EM_OR1K: /* R_OR1K_NONE. */
14977 case EM_PARISC: /* R_PARISC_NONE. */
14978 case EM_PPC64: /* R_PPC64_NONE. */
14979 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14980 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14981 case EM_S390: /* R_390_NONE. */
14982 case EM_S390_OLD:
14983 case EM_SH: /* R_SH_NONE. */
14984 case EM_SPARC32PLUS:
14985 case EM_SPARC: /* R_SPARC_NONE. */
14986 case EM_SPARCV9:
aa137e4d
NC
14987 case EM_TILEGX: /* R_TILEGX_NONE. */
14988 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14989 case EM_TI_C6000:/* R_C6000_NONE. */
14990 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 14991 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14992 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14993 return reloc_type == 0;
d347c9df 14994
a06ea964
NC
14995 case EM_AARCH64:
14996 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14997 case EM_AVR_OLD:
14998 case EM_AVR:
14999 return (reloc_type == 0 /* R_AVR_NONE. */
15000 || reloc_type == 30 /* R_AVR_DIFF8. */
15001 || reloc_type == 31 /* R_AVR_DIFF16. */
15002 || reloc_type == 32 /* R_AVR_DIFF32. */);
15003 case EM_METAG:
15004 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 15005 case EM_NDS32:
81c5e376
AM
15006 return (reloc_type == 0 /* R_NDS32_NONE. */
15007 || reloc_type == 205 /* R_NDS32_DIFF8. */
15008 || reloc_type == 206 /* R_NDS32_DIFF16. */
15009 || reloc_type == 207 /* R_NDS32_DIFF32. */
15010 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
15011 case EM_TI_PRU:
15012 return (reloc_type == 0 /* R_PRU_NONE. */
15013 || reloc_type == 65 /* R_PRU_DIFF8. */
15014 || reloc_type == 66 /* R_PRU_DIFF16. */
15015 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
15016 case EM_XTENSA_OLD:
15017 case EM_XTENSA:
4dc3c23d
AM
15018 return (reloc_type == 0 /* R_XTENSA_NONE. */
15019 || reloc_type == 17 /* R_XTENSA_DIFF8. */
15020 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
15021 || reloc_type == 19 /* R_XTENSA_DIFF32. */
15022 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
15023 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
15024 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
15025 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
15026 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
15027 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 15028 }
015dc7e1 15029 return false;
2a7b2e88
JK
15030}
15031
d1c4b12b
NC
15032/* Returns TRUE if there is a relocation against
15033 section NAME at OFFSET bytes. */
15034
015dc7e1 15035bool
31e5a3a3 15036reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
15037{
15038 Elf_Internal_Rela * relocs;
15039 Elf_Internal_Rela * rp;
15040
15041 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 15042 return false;
d1c4b12b
NC
15043
15044 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
15045
15046 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
15047 if (rp->r_offset == offset)
015dc7e1 15048 return true;
d1c4b12b 15049
015dc7e1 15050 return false;
d1c4b12b
NC
15051}
15052
cf13d699 15053/* Apply relocations to a section.
32ec8896
NC
15054 Returns TRUE upon success, FALSE otherwise.
15055 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
15056 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
15057 will be set to the number of relocs loaded.
15058
cf13d699 15059 Note: So far support has been added only for those relocations
32ec8896
NC
15060 which can be found in debug sections. FIXME: Add support for
15061 more relocations ? */
1b315056 15062
015dc7e1 15063static bool
be7d229a
AM
15064apply_relocations (Filedata *filedata,
15065 const Elf_Internal_Shdr *section,
15066 unsigned char *start,
15067 size_t size,
15068 void **relocs_return,
26c527e6 15069 uint64_t *num_relocs_return)
1b315056 15070{
cf13d699 15071 Elf_Internal_Shdr * relsec;
0d2a7a93 15072 unsigned char * end = start + size;
cb8f3167 15073
d1c4b12b
NC
15074 if (relocs_return != NULL)
15075 {
15076 * (Elf_Internal_Rela **) relocs_return = NULL;
15077 * num_relocs_return = 0;
15078 }
15079
dda8d76d 15080 if (filedata->file_header.e_type != ET_REL)
32ec8896 15081 /* No relocs to apply. */
015dc7e1 15082 return true;
1b315056 15083
cf13d699 15084 /* Find the reloc section associated with the section. */
dda8d76d
NC
15085 for (relsec = filedata->section_headers;
15086 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 15087 ++relsec)
252b5132 15088 {
015dc7e1 15089 bool is_rela;
26c527e6 15090 uint64_t num_relocs;
2cf0635d
NC
15091 Elf_Internal_Rela * relocs;
15092 Elf_Internal_Rela * rp;
15093 Elf_Internal_Shdr * symsec;
15094 Elf_Internal_Sym * symtab;
26c527e6 15095 uint64_t num_syms;
2cf0635d 15096 Elf_Internal_Sym * sym;
252b5132 15097
41e92641 15098 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15099 || relsec->sh_info >= filedata->file_header.e_shnum
15100 || filedata->section_headers + relsec->sh_info != section
c256ffe7 15101 || relsec->sh_size == 0
dda8d76d 15102 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 15103 continue;
428409d5 15104
a788aedd
AM
15105 symsec = filedata->section_headers + relsec->sh_link;
15106 if (symsec->sh_type != SHT_SYMTAB
15107 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 15108 return false;
a788aedd 15109
41e92641
NC
15110 is_rela = relsec->sh_type == SHT_RELA;
15111
15112 if (is_rela)
15113 {
dda8d76d 15114 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 15115 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15116 return false;
41e92641
NC
15117 }
15118 else
15119 {
dda8d76d 15120 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 15121 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15122 return false;
41e92641
NC
15123 }
15124
15125 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 15126 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 15127 is_rela = false;
428409d5 15128
4de91c10 15129 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 15130
41e92641 15131 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 15132 {
625d49fc 15133 uint64_t addend;
015dc7e1
AM
15134 unsigned int reloc_type;
15135 unsigned int reloc_size;
15136 bool reloc_inplace = false;
15137 bool reloc_subtract = false;
15138 unsigned char *rloc;
26c527e6 15139 uint64_t sym_index;
4b78141a 15140
dda8d76d 15141 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 15142
dda8d76d 15143 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 15144 continue;
dda8d76d 15145 else if (is_none_reloc (filedata, reloc_type))
98fb390a 15146 continue;
dda8d76d
NC
15147 else if (is_32bit_abs_reloc (filedata, reloc_type)
15148 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 15149 reloc_size = 4;
dda8d76d
NC
15150 else if (is_64bit_abs_reloc (filedata, reloc_type)
15151 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 15152 reloc_size = 8;
dda8d76d 15153 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15154 reloc_size = 3;
dda8d76d 15155 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15156 reloc_size = 2;
39e07931
AS
15157 else if (is_8bit_abs_reloc (filedata, reloc_type)
15158 || is_6bit_abs_reloc (filedata, reloc_type))
15159 reloc_size = 1;
03336641
JW
15160 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15161 reloc_type))
15162 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15163 {
15164 reloc_size = 4;
015dc7e1 15165 reloc_inplace = true;
03336641
JW
15166 }
15167 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15168 reloc_type))
15169 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15170 {
15171 reloc_size = 8;
015dc7e1 15172 reloc_inplace = true;
03336641
JW
15173 }
15174 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15175 reloc_type))
15176 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15177 {
15178 reloc_size = 2;
015dc7e1 15179 reloc_inplace = true;
03336641
JW
15180 }
15181 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15182 reloc_type))
15183 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15184 {
15185 reloc_size = 1;
015dc7e1 15186 reloc_inplace = true;
03336641 15187 }
39e07931 15188 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
76244462 15189 reloc_type))
15190 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15191 {
15192 reloc_size = 1;
015dc7e1 15193 reloc_inplace = true;
39e07931 15194 }
aca88567 15195 else
4b78141a 15196 {
bee0ee85 15197 static unsigned int prev_reloc = 0;
dda8d76d 15198
bee0ee85
NC
15199 if (reloc_type != prev_reloc)
15200 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15201 reloc_type, printable_section_name (filedata, section));
bee0ee85 15202 prev_reloc = reloc_type;
4b78141a
NC
15203 continue;
15204 }
103f02d3 15205
91d6fa6a 15206 rloc = start + rp->r_offset;
75802ccb 15207 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 15208 {
26c527e6
AM
15209 warn (_("skipping invalid relocation offset %#" PRIx64
15210 " in section %s\n"),
15211 rp->r_offset,
dda8d76d 15212 printable_section_name (filedata, section));
700dd8b7
L
15213 continue;
15214 }
103f02d3 15215
26c527e6 15216 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
15217 if (sym_index >= num_syms)
15218 {
26c527e6
AM
15219 warn (_("skipping invalid relocation symbol index %#" PRIx64
15220 " in section %s\n"),
dda8d76d 15221 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15222 continue;
15223 }
15224 sym = symtab + sym_index;
41e92641
NC
15225
15226 /* If the reloc has a symbol associated with it,
55f25fc3
L
15227 make sure that it is of an appropriate type.
15228
15229 Relocations against symbols without type can happen.
15230 Gcc -feliminate-dwarf2-dups may generate symbols
15231 without type for debug info.
15232
15233 Icc generates relocations against function symbols
15234 instead of local labels.
15235
15236 Relocations against object symbols can happen, eg when
15237 referencing a global array. For an example of this see
15238 the _clz.o binary in libgcc.a. */
aca88567 15239 if (sym != symtab
b8871f35 15240 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15241 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15242 {
26c527e6 15243 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
15244 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15245 printable_section_name (filedata, relsec),
26c527e6 15246 rp - relocs);
aca88567 15247 continue;
5b18a4bc 15248 }
252b5132 15249
4dc3c23d
AM
15250 addend = 0;
15251 if (is_rela)
15252 addend += rp->r_addend;
c47320c3
AM
15253 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15254 partial_inplace. */
4dc3c23d 15255 if (!is_rela
dda8d76d 15256 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15257 && reloc_type == 1)
dda8d76d
NC
15258 || ((filedata->file_header.e_machine == EM_PJ
15259 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15260 && reloc_type == 1)
dda8d76d
NC
15261 || ((filedata->file_header.e_machine == EM_D30V
15262 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15263 && reloc_type == 12)
15264 || reloc_inplace)
39e07931
AS
15265 {
15266 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15267 addend += byte_get (rloc, reloc_size) & 0x3f;
15268 else
15269 addend += byte_get (rloc, reloc_size);
15270 }
cb8f3167 15271
dda8d76d
NC
15272 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15273 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15274 {
15275 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15276 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15277 addend -= 8;
91d6fa6a 15278 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15279 reloc_size);
15280 }
39e07931 15281 else if (is_6bit_abs_reloc (filedata, reloc_type)
76244462 15282 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
15283 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15284 {
15285 if (reloc_subtract)
15286 addend -= sym->st_value;
15287 else
15288 addend += sym->st_value;
15289 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15290 byte_put (rloc, addend, reloc_size);
15291 }
03336641
JW
15292 else if (reloc_subtract)
15293 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15294 else
91d6fa6a 15295 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15296 }
252b5132 15297
5b18a4bc 15298 free (symtab);
f84ce13b
NC
15299 /* Let the target specific reloc processing code know that
15300 we have finished with these relocs. */
dda8d76d 15301 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15302
15303 if (relocs_return)
15304 {
15305 * (Elf_Internal_Rela **) relocs_return = relocs;
15306 * num_relocs_return = num_relocs;
15307 }
15308 else
15309 free (relocs);
15310
5b18a4bc
NC
15311 break;
15312 }
32ec8896 15313
015dc7e1 15314 return true;
5b18a4bc 15315}
103f02d3 15316
cf13d699 15317#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15318static bool
dda8d76d 15319disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15320{
dda8d76d 15321 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15322
74e1a04b 15323 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15324
015dc7e1 15325 return true;
cf13d699
NC
15326}
15327#endif
15328
15329/* Reads in the contents of SECTION from FILE, returning a pointer
15330 to a malloc'ed buffer or NULL if something went wrong. */
15331
15332static char *
dda8d76d 15333get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15334{
be7d229a 15335 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15336
15337 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15338 {
c6b78c96 15339 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15340 printable_section_name (filedata, section));
cf13d699
NC
15341 return NULL;
15342 }
15343
dda8d76d 15344 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15345 _("section contents"));
cf13d699
NC
15346}
15347
1f5a3546 15348/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 15349
015dc7e1 15350static bool
45f5fe46
NC
15351uncompress_section_contents (bool is_zstd,
15352 unsigned char ** buffer,
15353 uint64_t uncompressed_size,
15354 uint64_t * size,
15355 uint64_t file_size)
0e602686 15356{
31e5a3a3
AM
15357 uint64_t compressed_size = *size;
15358 unsigned char *compressed_buffer = *buffer;
45f5fe46 15359 unsigned char *uncompressed_buffer = NULL;
0e602686
NC
15360 z_stream strm;
15361 int rc;
15362
45f5fe46
NC
15363 /* Similar to _bfd_section_size_insane() in the BFD library we expect an
15364 upper limit of ~10x compression. Any compression larger than that is
15365 thought to be due to fuzzing of the compression header. */
15366 if (uncompressed_size > file_size * 10)
15367 {
15368 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
15369 uncompressed_size);
15370 goto fail;
15371 }
15372
15373 uncompressed_buffer = xmalloc (uncompressed_size);
15374
1f5a3546
FS
15375 if (is_zstd)
15376 {
15377#ifdef HAVE_ZSTD
15378 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15379 compressed_buffer, compressed_size);
15380 if (ZSTD_isError (ret))
15381 goto fail;
15382#endif
15383 }
15384 else
15385 {
15386 /* It is possible the section consists of several compressed
15387 buffers concatenated together, so we uncompress in a loop. */
15388 /* PR 18313: The state field in the z_stream structure is supposed
15389 to be invisible to the user (ie us), but some compilers will
15390 still complain about it being used without initialisation. So
15391 we first zero the entire z_stream structure and then set the fields
15392 that we need. */
15393 memset (&strm, 0, sizeof strm);
15394 strm.avail_in = compressed_size;
15395 strm.next_in = (Bytef *)compressed_buffer;
15396 strm.avail_out = uncompressed_size;
15397
15398 rc = inflateInit (&strm);
15399 while (strm.avail_in > 0)
15400 {
15401 if (rc != Z_OK)
15402 break;
15403 strm.next_out = ((Bytef *)uncompressed_buffer
15404 + (uncompressed_size - strm.avail_out));
15405 rc = inflate (&strm, Z_FINISH);
15406 if (rc != Z_STREAM_END)
15407 break;
15408 rc = inflateReset (&strm);
15409 }
15410 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15411 goto fail;
15412 }
0e602686
NC
15413
15414 *buffer = uncompressed_buffer;
15415 *size = uncompressed_size;
015dc7e1 15416 return true;
0e602686
NC
15417
15418 fail:
15419 free (uncompressed_buffer);
15420 /* Indicate decompression failure. */
15421 *buffer = NULL;
015dc7e1 15422 return false;
0e602686 15423}
dd24e3da 15424
015dc7e1 15425static bool
dda8d76d 15426dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15427{
015dc7e1 15428 Elf_Internal_Shdr *relsec;
be7d229a 15429 uint64_t num_bytes;
015dc7e1
AM
15430 unsigned char *data;
15431 unsigned char *end;
15432 unsigned char *real_start;
15433 unsigned char *start;
15434 bool some_strings_shown;
cf13d699 15435
dda8d76d 15436 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15437 if (start == NULL)
c6b78c96 15438 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15439 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15440
0e602686 15441 num_bytes = section->sh_size;
cf13d699 15442
835f2fae
NC
15443 if (filedata->is_separate)
15444 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15445 printable_section_name (filedata, section),
15446 filedata->file_name);
15447 else
15448 printf (_("\nString dump of section '%s':\n"),
15449 printable_section_name (filedata, section));
cf13d699 15450
0e602686
NC
15451 if (decompress_dumps)
15452 {
31e5a3a3
AM
15453 uint64_t new_size = num_bytes;
15454 uint64_t uncompressed_size = 0;
1f5a3546 15455 bool is_zstd = false;
0e602686
NC
15456
15457 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15458 {
15459 Elf_Internal_Chdr chdr;
15460 unsigned int compression_header_size
ebdf1ebf
NC
15461 = get_compression_header (& chdr, (unsigned char *) start,
15462 num_bytes);
5844b465
NC
15463 if (compression_header_size == 0)
15464 /* An error message will have already been generated
15465 by get_compression_header. */
15466 goto error_out;
0e602686 15467
89dbeac7 15468 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
15469 ;
15470#ifdef HAVE_ZSTD
89dbeac7 15471 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
15472 is_zstd = true;
15473#endif
15474 else
0e602686 15475 {
813dabb9 15476 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15477 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15478 goto error_out;
813dabb9 15479 }
813dabb9
L
15480 uncompressed_size = chdr.ch_size;
15481 start += compression_header_size;
15482 new_size -= compression_header_size;
0e602686
NC
15483 }
15484 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15485 {
15486 /* Read the zlib header. In this case, it should be "ZLIB"
15487 followed by the uncompressed section size, 8 bytes in
15488 big-endian order. */
15489 uncompressed_size = start[4]; uncompressed_size <<= 8;
15490 uncompressed_size += start[5]; uncompressed_size <<= 8;
15491 uncompressed_size += start[6]; uncompressed_size <<= 8;
15492 uncompressed_size += start[7]; uncompressed_size <<= 8;
15493 uncompressed_size += start[8]; uncompressed_size <<= 8;
15494 uncompressed_size += start[9]; uncompressed_size <<= 8;
15495 uncompressed_size += start[10]; uncompressed_size <<= 8;
15496 uncompressed_size += start[11];
15497 start += 12;
15498 new_size -= 12;
15499 }
15500
1835f746
NC
15501 if (uncompressed_size)
15502 {
1f5a3546 15503 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 15504 &new_size, filedata->file_size))
1835f746
NC
15505 num_bytes = new_size;
15506 else
15507 {
15508 error (_("Unable to decompress section %s\n"),
dda8d76d 15509 printable_section_name (filedata, section));
f761cb13 15510 goto error_out;
1835f746
NC
15511 }
15512 }
bc303e5d
NC
15513 else
15514 start = real_start;
0e602686 15515 }
fd8008d8 15516
cf13d699
NC
15517 /* If the section being dumped has relocations against it the user might
15518 be expecting these relocations to have been applied. Check for this
15519 case and issue a warning message in order to avoid confusion.
15520 FIXME: Maybe we ought to have an option that dumps a section with
15521 relocs applied ? */
dda8d76d
NC
15522 for (relsec = filedata->section_headers;
15523 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15524 ++relsec)
15525 {
15526 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15527 || relsec->sh_info >= filedata->file_header.e_shnum
15528 || filedata->section_headers + relsec->sh_info != section
cf13d699 15529 || relsec->sh_size == 0
dda8d76d 15530 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15531 continue;
15532
15533 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15534 break;
15535 }
15536
cf13d699
NC
15537 data = start;
15538 end = start + num_bytes;
015dc7e1 15539 some_strings_shown = false;
cf13d699 15540
ba3265d0
NC
15541#ifdef HAVE_MBSTATE_T
15542 mbstate_t state;
15543 /* Initialise the multibyte conversion state. */
15544 memset (& state, 0, sizeof (state));
15545#endif
15546
015dc7e1 15547 bool continuing = false;
ba3265d0 15548
cf13d699
NC
15549 while (data < end)
15550 {
15551 while (!ISPRINT (* data))
15552 if (++ data >= end)
15553 break;
15554
15555 if (data < end)
15556 {
071436c6
NC
15557 size_t maxlen = end - data;
15558
ba3265d0
NC
15559 if (continuing)
15560 {
15561 printf (" ");
015dc7e1 15562 continuing = false;
ba3265d0
NC
15563 }
15564 else
15565 {
26c527e6 15566 printf (" [%6tx] ", data - start);
ba3265d0
NC
15567 }
15568
4082ef84
NC
15569 if (maxlen > 0)
15570 {
f3da8a96 15571 char c = 0;
ba3265d0
NC
15572
15573 while (maxlen)
15574 {
15575 c = *data++;
15576
15577 if (c == 0)
15578 break;
15579
15580 /* PR 25543: Treat new-lines as string-ending characters. */
15581 if (c == '\n')
15582 {
15583 printf ("\\n\n");
15584 if (*data != 0)
015dc7e1 15585 continuing = true;
ba3265d0
NC
15586 break;
15587 }
15588
15589 /* Do not print control characters directly as they can affect terminal
15590 settings. Such characters usually appear in the names generated
15591 by the assembler for local labels. */
15592 if (ISCNTRL (c))
15593 {
15594 printf ("^%c", c + 0x40);
15595 }
15596 else if (ISPRINT (c))
15597 {
15598 putchar (c);
15599 }
15600 else
15601 {
15602 size_t n;
15603#ifdef HAVE_MBSTATE_T
15604 wchar_t w;
15605#endif
15606 /* Let printf do the hard work of displaying multibyte characters. */
15607 printf ("%.1s", data - 1);
15608#ifdef HAVE_MBSTATE_T
15609 /* Try to find out how many bytes made up the character that was
15610 just printed. Advance the symbol pointer past the bytes that
15611 were displayed. */
15612 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15613#else
15614 n = 1;
15615#endif
15616 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15617 data += (n - 1);
15618 }
15619 }
15620
15621 if (c != '\n')
15622 putchar ('\n');
4082ef84
NC
15623 }
15624 else
15625 {
15626 printf (_("<corrupt>\n"));
15627 data = end;
15628 }
015dc7e1 15629 some_strings_shown = true;
cf13d699
NC
15630 }
15631 }
15632
15633 if (! some_strings_shown)
15634 printf (_(" No strings found in this section."));
15635
0e602686 15636 free (real_start);
cf13d699
NC
15637
15638 putchar ('\n');
015dc7e1 15639 return true;
f761cb13
AM
15640
15641error_out:
15642 free (real_start);
015dc7e1 15643 return false;
cf13d699
NC
15644}
15645
015dc7e1
AM
15646static bool
15647dump_section_as_bytes (Elf_Internal_Shdr *section,
15648 Filedata *filedata,
15649 bool relocate)
cf13d699 15650{
be7d229a
AM
15651 Elf_Internal_Shdr *relsec;
15652 size_t bytes;
15653 uint64_t section_size;
625d49fc 15654 uint64_t addr;
be7d229a
AM
15655 unsigned char *data;
15656 unsigned char *real_start;
15657 unsigned char *start;
0e602686 15658
dda8d76d 15659 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15660 if (start == NULL)
c6b78c96 15661 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15662 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15663
0e602686 15664 section_size = section->sh_size;
cf13d699 15665
835f2fae
NC
15666 if (filedata->is_separate)
15667 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15668 printable_section_name (filedata, section),
15669 filedata->file_name);
15670 else
15671 printf (_("\nHex dump of section '%s':\n"),
15672 printable_section_name (filedata, section));
cf13d699 15673
0e602686
NC
15674 if (decompress_dumps)
15675 {
31e5a3a3
AM
15676 uint64_t new_size = section_size;
15677 uint64_t uncompressed_size = 0;
1f5a3546 15678 bool is_zstd = false;
0e602686
NC
15679
15680 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15681 {
15682 Elf_Internal_Chdr chdr;
15683 unsigned int compression_header_size
ebdf1ebf 15684 = get_compression_header (& chdr, start, section_size);
0e602686 15685
5844b465
NC
15686 if (compression_header_size == 0)
15687 /* An error message will have already been generated
15688 by get_compression_header. */
15689 goto error_out;
15690
89dbeac7 15691 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
15692 ;
15693#ifdef HAVE_ZSTD
89dbeac7 15694 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
15695 is_zstd = true;
15696#endif
15697 else
0e602686 15698 {
813dabb9 15699 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15700 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15701 goto error_out;
0e602686 15702 }
813dabb9
L
15703 uncompressed_size = chdr.ch_size;
15704 start += compression_header_size;
15705 new_size -= compression_header_size;
0e602686
NC
15706 }
15707 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15708 {
15709 /* Read the zlib header. In this case, it should be "ZLIB"
15710 followed by the uncompressed section size, 8 bytes in
15711 big-endian order. */
15712 uncompressed_size = start[4]; uncompressed_size <<= 8;
15713 uncompressed_size += start[5]; uncompressed_size <<= 8;
15714 uncompressed_size += start[6]; uncompressed_size <<= 8;
15715 uncompressed_size += start[7]; uncompressed_size <<= 8;
15716 uncompressed_size += start[8]; uncompressed_size <<= 8;
15717 uncompressed_size += start[9]; uncompressed_size <<= 8;
15718 uncompressed_size += start[10]; uncompressed_size <<= 8;
15719 uncompressed_size += start[11];
15720 start += 12;
15721 new_size -= 12;
15722 }
15723
f055032e
NC
15724 if (uncompressed_size)
15725 {
1f5a3546 15726 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 15727 &new_size, filedata->file_size))
bc303e5d
NC
15728 {
15729 section_size = new_size;
15730 }
f055032e
NC
15731 else
15732 {
15733 error (_("Unable to decompress section %s\n"),
dda8d76d 15734 printable_section_name (filedata, section));
bc303e5d 15735 /* FIXME: Print the section anyway ? */
f761cb13 15736 goto error_out;
f055032e
NC
15737 }
15738 }
bc303e5d
NC
15739 else
15740 start = real_start;
0e602686 15741 }
14ae95f2 15742
cf13d699
NC
15743 if (relocate)
15744 {
dda8d76d 15745 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15746 goto error_out;
cf13d699
NC
15747 }
15748 else
15749 {
15750 /* If the section being dumped has relocations against it the user might
15751 be expecting these relocations to have been applied. Check for this
15752 case and issue a warning message in order to avoid confusion.
15753 FIXME: Maybe we ought to have an option that dumps a section with
15754 relocs applied ? */
dda8d76d
NC
15755 for (relsec = filedata->section_headers;
15756 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15757 ++relsec)
15758 {
15759 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15760 || relsec->sh_info >= filedata->file_header.e_shnum
15761 || filedata->section_headers + relsec->sh_info != section
cf13d699 15762 || relsec->sh_size == 0
dda8d76d 15763 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15764 continue;
15765
15766 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15767 break;
15768 }
15769 }
15770
15771 addr = section->sh_addr;
0e602686 15772 bytes = section_size;
cf13d699
NC
15773 data = start;
15774
15775 while (bytes)
15776 {
15777 int j;
15778 int k;
15779 int lbytes;
15780
15781 lbytes = (bytes > 16 ? 16 : bytes);
15782
26c527e6 15783 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
15784
15785 for (j = 0; j < 16; j++)
15786 {
15787 if (j < lbytes)
15788 printf ("%2.2x", data[j]);
15789 else
15790 printf (" ");
15791
15792 if ((j & 3) == 3)
15793 printf (" ");
15794 }
15795
15796 for (j = 0; j < lbytes; j++)
15797 {
15798 k = data[j];
15799 if (k >= ' ' && k < 0x7f)
15800 printf ("%c", k);
15801 else
15802 printf (".");
15803 }
15804
15805 putchar ('\n');
15806
15807 data += lbytes;
15808 addr += lbytes;
15809 bytes -= lbytes;
15810 }
15811
0e602686 15812 free (real_start);
cf13d699
NC
15813
15814 putchar ('\n');
015dc7e1 15815 return true;
f761cb13
AM
15816
15817 error_out:
15818 free (real_start);
015dc7e1 15819 return false;
cf13d699
NC
15820}
15821
094e34f2 15822#ifdef ENABLE_LIBCTF
7d9813f1
NA
15823static ctf_sect_t *
15824shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15825{
84714f86 15826 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15827 buf->cts_size = shdr->sh_size;
15828 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15829
15830 return buf;
15831}
15832
15833/* Formatting callback function passed to ctf_dump. Returns either the pointer
15834 it is passed, or a pointer to newly-allocated storage, in which case
15835 dump_ctf() will free it when it no longer needs it. */
15836
2f6ecaed
NA
15837static char *
15838dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15839 char *s, void *arg)
7d9813f1 15840{
3e50a591 15841 const char *blanks = arg;
7d9813f1
NA
15842 char *new_s;
15843
3e50a591 15844 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15845 return s;
15846 return new_s;
15847}
15848
926c9e76
NA
15849/* Dump CTF errors/warnings. */
15850static void
139633c3 15851dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15852{
15853 ctf_next_t *it = NULL;
15854 char *errtext;
15855 int is_warning;
15856 int err;
15857
15858 /* Dump accumulated errors and warnings. */
15859 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15860 {
5e9b84f7 15861 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15862 errtext);
15863 free (errtext);
15864 }
15865 if (err != ECTF_NEXT_END)
15866 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15867}
15868
2f6ecaed
NA
15869/* Dump one CTF archive member. */
15870
80b56fad
NA
15871static void
15872dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15873 size_t member)
2f6ecaed 15874{
2f6ecaed
NA
15875 const char *things[] = {"Header", "Labels", "Data objects",
15876 "Function objects", "Variables", "Types", "Strings",
15877 ""};
15878 const char **thing;
15879 size_t i;
15880
80b56fad
NA
15881 /* Don't print out the name of the default-named archive member if it appears
15882 first in the list. The name .ctf appears everywhere, even for things that
15883 aren't really archives, so printing it out is liable to be confusing; also,
15884 the common case by far is for only one archive member to exist, and hiding
15885 it in that case seems worthwhile. */
2f6ecaed 15886
80b56fad
NA
15887 if (strcmp (name, ".ctf") != 0 || member != 0)
15888 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15889
80b56fad
NA
15890 if (ctf_parent_name (ctf) != NULL)
15891 ctf_import (ctf, parent);
2f6ecaed
NA
15892
15893 for (i = 0, thing = things; *thing[0]; thing++, i++)
15894 {
15895 ctf_dump_state_t *s = NULL;
15896 char *item;
15897
15898 printf ("\n %s:\n", *thing);
15899 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15900 (void *) " ")) != NULL)
15901 {
15902 printf ("%s\n", item);
15903 free (item);
15904 }
15905
15906 if (ctf_errno (ctf))
15907 {
15908 error (_("Iteration failed: %s, %s\n"), *thing,
15909 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15910 break;
2f6ecaed
NA
15911 }
15912 }
8b37e7b6 15913
926c9e76 15914 dump_ctf_errs (ctf);
2f6ecaed
NA
15915}
15916
015dc7e1 15917static bool
7d9813f1
NA
15918dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15919{
7d9813f1
NA
15920 Elf_Internal_Shdr * symtab_sec = NULL;
15921 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15922 void * data = NULL;
15923 void * symdata = NULL;
15924 void * strdata = NULL;
80b56fad 15925 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15926 ctf_sect_t * symsectp = NULL;
15927 ctf_sect_t * strsectp = NULL;
2f6ecaed 15928 ctf_archive_t * ctfa = NULL;
139633c3 15929 ctf_dict_t * parent = NULL;
80b56fad 15930 ctf_dict_t * fp;
7d9813f1 15931
80b56fad
NA
15932 ctf_next_t *i = NULL;
15933 const char *name;
15934 size_t member = 0;
7d9813f1 15935 int err;
015dc7e1 15936 bool ret = false;
7d9813f1
NA
15937
15938 shdr_to_ctf_sect (&ctfsect, section, filedata);
15939 data = get_section_contents (section, filedata);
15940 ctfsect.cts_data = data;
15941
616febde 15942 if (!dump_ctf_symtab_name)
3d16b64e 15943 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15944
15945 if (!dump_ctf_strtab_name)
3d16b64e 15946 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15947
15948 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15949 {
15950 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15951 {
15952 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15953 goto fail;
15954 }
15955 if ((symdata = (void *) get_data (NULL, filedata,
15956 symtab_sec->sh_offset, 1,
15957 symtab_sec->sh_size,
15958 _("symbols"))) == NULL)
15959 goto fail;
15960 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15961 symsect.cts_data = symdata;
15962 }
835f2fae 15963
df16e041 15964 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15965 {
15966 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15967 {
15968 error (_("No string table section named %s\n"),
15969 dump_ctf_strtab_name);
15970 goto fail;
15971 }
15972 if ((strdata = (void *) get_data (NULL, filedata,
15973 strtab_sec->sh_offset, 1,
15974 strtab_sec->sh_size,
15975 _("strings"))) == NULL)
15976 goto fail;
15977 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15978 strsect.cts_data = strdata;
15979 }
835f2fae 15980
2f6ecaed
NA
15981 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15982 libctf papers over the difference, so we can pretend it is always an
80b56fad 15983 archive. */
7d9813f1 15984
2f6ecaed 15985 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15986 {
926c9e76 15987 dump_ctf_errs (NULL);
7d9813f1
NA
15988 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15989 goto fail;
15990 }
15991
96c61be5
NA
15992 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15993 != ELFDATA2MSB);
15994
80b56fad
NA
15995 /* Preload the parent dict, since it will need to be imported into every
15996 child in turn. */
15997 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15998 {
926c9e76 15999 dump_ctf_errs (NULL);
2f6ecaed
NA
16000 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16001 goto fail;
7d9813f1
NA
16002 }
16003
015dc7e1 16004 ret = true;
7d9813f1 16005
835f2fae
NC
16006 if (filedata->is_separate)
16007 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
16008 printable_section_name (filedata, section),
16009 filedata->file_name);
16010 else
16011 printf (_("\nDump of CTF section '%s':\n"),
16012 printable_section_name (filedata, section));
7d9813f1 16013
80b56fad
NA
16014 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
16015 dump_ctf_archive_member (fp, name, parent, member++);
16016 if (err != ECTF_NEXT_END)
16017 {
16018 dump_ctf_errs (NULL);
16019 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
16020 ret = false;
16021 }
7d9813f1
NA
16022
16023 fail:
139633c3 16024 ctf_dict_close (parent);
2f6ecaed 16025 ctf_close (ctfa);
7d9813f1
NA
16026 free (data);
16027 free (symdata);
16028 free (strdata);
16029 return ret;
16030}
094e34f2 16031#endif
7d9813f1 16032
42b6953b
IB
16033static bool
16034dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
16035{
16036 void * data = NULL;
16037 sframe_decoder_ctx *sfd_ctx = NULL;
16038 const char *print_name = printable_section_name (filedata, section);
16039
16040 bool ret = true;
16041 size_t sf_size;
16042 int err = 0;
16043
16044 if (strcmp (print_name, "") == 0)
16045 {
16046 error (_("Section name must be provided \n"));
16047 ret = false;
16048 return ret;
16049 }
16050
16051 data = get_section_contents (section, filedata);
16052 sf_size = section->sh_size;
16053 /* Decode the contents of the section. */
16054 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
16055 if (!sfd_ctx)
16056 {
16057 ret = false;
16058 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
16059 goto fail;
16060 }
16061
16062 printf (_("Contents of the SFrame section %s:"), print_name);
16063 /* Dump the contents as text. */
16064 dump_sframe (sfd_ctx, section->sh_addr);
16065
16066 fail:
16067 free (data);
16068 return ret;
16069}
16070
015dc7e1 16071static bool
dda8d76d
NC
16072load_specific_debug_section (enum dwarf_section_display_enum debug,
16073 const Elf_Internal_Shdr * sec,
16074 void * data)
1007acb3 16075{
2cf0635d 16076 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 16077 char buf [64];
dda8d76d 16078 Filedata * filedata = (Filedata *) data;
9abca702 16079
19e6b90e 16080 if (section->start != NULL)
dda8d76d
NC
16081 {
16082 /* If it is already loaded, do nothing. */
16083 if (streq (section->filename, filedata->file_name))
015dc7e1 16084 return true;
dda8d76d
NC
16085 free (section->start);
16086 }
1007acb3 16087
19e6b90e
L
16088 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16089 section->address = sec->sh_addr;
dda8d76d
NC
16090 section->filename = filedata->file_name;
16091 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
16092 sec->sh_offset, 1,
16093 sec->sh_size, buf);
59245841
NC
16094 if (section->start == NULL)
16095 section->size = 0;
16096 else
16097 {
77115a4a 16098 unsigned char *start = section->start;
31e5a3a3
AM
16099 uint64_t size = sec->sh_size;
16100 uint64_t uncompressed_size = 0;
1f5a3546 16101 bool is_zstd = false;
77115a4a
L
16102
16103 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16104 {
16105 Elf_Internal_Chdr chdr;
d8024a91
NC
16106 unsigned int compression_header_size;
16107
f53be977
L
16108 if (size < (is_32bit_elf
16109 ? sizeof (Elf32_External_Chdr)
16110 : sizeof (Elf64_External_Chdr)))
d8024a91 16111 {
55be8fd0 16112 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 16113 section->name);
015dc7e1 16114 return false;
d8024a91
NC
16115 }
16116
ebdf1ebf 16117 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
16118 if (compression_header_size == 0)
16119 /* An error message will have already been generated
16120 by get_compression_header. */
015dc7e1 16121 return false;
d8024a91 16122
89dbeac7 16123 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16124 ;
16125#ifdef HAVE_ZSTD
89dbeac7 16126 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16127 is_zstd = true;
16128#endif
16129 else
813dabb9
L
16130 {
16131 warn (_("section '%s' has unsupported compress type: %d\n"),
16132 section->name, chdr.ch_type);
015dc7e1 16133 return false;
813dabb9 16134 }
dab394de 16135 uncompressed_size = chdr.ch_size;
77115a4a
L
16136 start += compression_header_size;
16137 size -= compression_header_size;
16138 }
dab394de
L
16139 else if (size > 12 && streq ((char *) start, "ZLIB"))
16140 {
16141 /* Read the zlib header. In this case, it should be "ZLIB"
16142 followed by the uncompressed section size, 8 bytes in
16143 big-endian order. */
16144 uncompressed_size = start[4]; uncompressed_size <<= 8;
16145 uncompressed_size += start[5]; uncompressed_size <<= 8;
16146 uncompressed_size += start[6]; uncompressed_size <<= 8;
16147 uncompressed_size += start[7]; uncompressed_size <<= 8;
16148 uncompressed_size += start[8]; uncompressed_size <<= 8;
16149 uncompressed_size += start[9]; uncompressed_size <<= 8;
16150 uncompressed_size += start[10]; uncompressed_size <<= 8;
16151 uncompressed_size += start[11];
16152 start += 12;
16153 size -= 12;
16154 }
16155
1835f746 16156 if (uncompressed_size)
77115a4a 16157 {
1f5a3546 16158 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16159 &size, filedata->file_size))
1835f746
NC
16160 {
16161 /* Free the compressed buffer, update the section buffer
16162 and the section size if uncompress is successful. */
16163 free (section->start);
16164 section->start = start;
16165 }
16166 else
16167 {
16168 error (_("Unable to decompress section %s\n"),
dda8d76d 16169 printable_section_name (filedata, sec));
015dc7e1 16170 return false;
1835f746 16171 }
77115a4a 16172 }
bc303e5d 16173
77115a4a 16174 section->size = size;
59245841 16175 }
4a114e3e 16176
1b315056 16177 if (section->start == NULL)
015dc7e1 16178 return false;
1b315056 16179
19e6b90e 16180 if (debug_displays [debug].relocate)
32ec8896 16181 {
dda8d76d 16182 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 16183 & section->reloc_info, & section->num_relocs))
015dc7e1 16184 return false;
32ec8896 16185 }
d1c4b12b
NC
16186 else
16187 {
16188 section->reloc_info = NULL;
16189 section->num_relocs = 0;
16190 }
1007acb3 16191
015dc7e1 16192 return true;
1007acb3
L
16193}
16194
301a9420
AM
16195#if HAVE_LIBDEBUGINFOD
16196/* Return a hex string representation of the build-id. */
16197unsigned char *
16198get_build_id (void * data)
16199{
ca0e11aa 16200 Filedata * filedata = (Filedata *) data;
301a9420 16201 Elf_Internal_Shdr * shdr;
26c527e6 16202 size_t i;
301a9420 16203
55be8fd0
NC
16204 /* Iterate through notes to find note.gnu.build-id.
16205 FIXME: Only the first note in any note section is examined. */
301a9420
AM
16206 for (i = 0, shdr = filedata->section_headers;
16207 i < filedata->file_header.e_shnum && shdr != NULL;
16208 i++, shdr++)
16209 {
16210 if (shdr->sh_type != SHT_NOTE)
16211 continue;
16212
16213 char * next;
16214 char * end;
16215 size_t data_remaining;
16216 size_t min_notesz;
16217 Elf_External_Note * enote;
16218 Elf_Internal_Note inote;
16219
625d49fc
AM
16220 uint64_t offset = shdr->sh_offset;
16221 uint64_t align = shdr->sh_addralign;
16222 uint64_t length = shdr->sh_size;
301a9420
AM
16223
16224 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16225 if (enote == NULL)
16226 continue;
16227
16228 if (align < 4)
16229 align = 4;
16230 else if (align != 4 && align != 8)
f761cb13
AM
16231 {
16232 free (enote);
16233 continue;
16234 }
301a9420
AM
16235
16236 end = (char *) enote + length;
16237 data_remaining = end - (char *) enote;
16238
16239 if (!is_ia64_vms (filedata))
16240 {
16241 min_notesz = offsetof (Elf_External_Note, name);
16242 if (data_remaining < min_notesz)
16243 {
55be8fd0
NC
16244 warn (_("\
16245malformed note encountered in section %s whilst scanning for build-id note\n"),
16246 printable_section_name (filedata, shdr));
f761cb13 16247 free (enote);
55be8fd0 16248 continue;
301a9420
AM
16249 }
16250 data_remaining -= min_notesz;
16251
16252 inote.type = BYTE_GET (enote->type);
16253 inote.namesz = BYTE_GET (enote->namesz);
16254 inote.namedata = enote->name;
16255 inote.descsz = BYTE_GET (enote->descsz);
16256 inote.descdata = ((char *) enote
16257 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16258 inote.descpos = offset + (inote.descdata - (char *) enote);
16259 next = ((char *) enote
16260 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16261 }
16262 else
16263 {
16264 Elf64_External_VMS_Note *vms_enote;
16265
16266 /* PR binutils/15191
16267 Make sure that there is enough data to read. */
16268 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16269 if (data_remaining < min_notesz)
16270 {
55be8fd0
NC
16271 warn (_("\
16272malformed note encountered in section %s whilst scanning for build-id note\n"),
16273 printable_section_name (filedata, shdr));
f761cb13 16274 free (enote);
55be8fd0 16275 continue;
301a9420
AM
16276 }
16277 data_remaining -= min_notesz;
16278
16279 vms_enote = (Elf64_External_VMS_Note *) enote;
16280 inote.type = BYTE_GET (vms_enote->type);
16281 inote.namesz = BYTE_GET (vms_enote->namesz);
16282 inote.namedata = vms_enote->name;
16283 inote.descsz = BYTE_GET (vms_enote->descsz);
16284 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16285 inote.descpos = offset + (inote.descdata - (char *) enote);
16286 next = inote.descdata + align_power (inote.descsz, 3);
16287 }
16288
16289 /* Skip malformed notes. */
16290 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16291 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16292 || (size_t) (next - inote.descdata) < inote.descsz
16293 || ((size_t) (next - inote.descdata)
16294 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16295 {
55be8fd0
NC
16296 warn (_("\
16297malformed note encountered in section %s whilst scanning for build-id note\n"),
16298 printable_section_name (filedata, shdr));
f761cb13 16299 free (enote);
301a9420
AM
16300 continue;
16301 }
16302
16303 /* Check if this is the build-id note. If so then convert the build-id
16304 bytes to a hex string. */
16305 if (inote.namesz > 0
24d127aa 16306 && startswith (inote.namedata, "GNU")
301a9420
AM
16307 && inote.type == NT_GNU_BUILD_ID)
16308 {
26c527e6 16309 size_t j;
301a9420
AM
16310 char * build_id;
16311
16312 build_id = malloc (inote.descsz * 2 + 1);
16313 if (build_id == NULL)
f761cb13
AM
16314 {
16315 free (enote);
16316 return NULL;
16317 }
301a9420
AM
16318
16319 for (j = 0; j < inote.descsz; ++j)
16320 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16321 build_id[inote.descsz * 2] = '\0';
f761cb13 16322 free (enote);
301a9420 16323
55be8fd0 16324 return (unsigned char *) build_id;
301a9420 16325 }
f761cb13 16326 free (enote);
301a9420
AM
16327 }
16328
16329 return NULL;
16330}
16331#endif /* HAVE_LIBDEBUGINFOD */
16332
657d0d47
CC
16333/* If this is not NULL, load_debug_section will only look for sections
16334 within the list of sections given here. */
32ec8896 16335static unsigned int * section_subset = NULL;
657d0d47 16336
015dc7e1 16337bool
dda8d76d 16338load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16339{
2cf0635d
NC
16340 struct dwarf_section * section = &debug_displays [debug].section;
16341 Elf_Internal_Shdr * sec;
dda8d76d
NC
16342 Filedata * filedata = (Filedata *) data;
16343
e1dbfc17
L
16344 if (!dump_any_debugging)
16345 return false;
16346
f425ec66
NC
16347 /* Without section headers we cannot find any sections. */
16348 if (filedata->section_headers == NULL)
015dc7e1 16349 return false;
f425ec66 16350
9c1ce108
AM
16351 if (filedata->string_table == NULL
16352 && filedata->file_header.e_shstrndx != SHN_UNDEF
16353 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16354 {
16355 Elf_Internal_Shdr * strs;
16356
16357 /* Read in the string table, so that we have section names to scan. */
16358 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16359
4dff97b2 16360 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16361 {
9c1ce108
AM
16362 filedata->string_table
16363 = (char *) get_data (NULL, filedata, strs->sh_offset,
16364 1, strs->sh_size, _("string table"));
dda8d76d 16365
9c1ce108
AM
16366 filedata->string_table_length
16367 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16368 }
16369 }
d966045b
DJ
16370
16371 /* Locate the debug section. */
dda8d76d 16372 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16373 if (sec != NULL)
16374 section->name = section->uncompressed_name;
16375 else
16376 {
dda8d76d 16377 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16378 if (sec != NULL)
16379 section->name = section->compressed_name;
16380 }
16381 if (sec == NULL)
015dc7e1 16382 return false;
d966045b 16383
657d0d47
CC
16384 /* If we're loading from a subset of sections, and we've loaded
16385 a section matching this name before, it's likely that it's a
16386 different one. */
16387 if (section_subset != NULL)
16388 free_debug_section (debug);
16389
dda8d76d 16390 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16391}
16392
19e6b90e
L
16393void
16394free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16395{
2cf0635d 16396 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16397
19e6b90e
L
16398 if (section->start == NULL)
16399 return;
1007acb3 16400
19e6b90e
L
16401 free ((char *) section->start);
16402 section->start = NULL;
16403 section->address = 0;
16404 section->size = 0;
a788aedd 16405
9db70fc3
AM
16406 free (section->reloc_info);
16407 section->reloc_info = NULL;
16408 section->num_relocs = 0;
1007acb3
L
16409}
16410
015dc7e1 16411static bool
dda8d76d 16412display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16413{
84714f86
AM
16414 const char *name = (section_name_valid (filedata, section)
16415 ? section_name (filedata, section) : "");
16416 const char *print_name = printable_section_name (filedata, section);
be7d229a 16417 uint64_t length;
015dc7e1 16418 bool result = true;
3f5e193b 16419 int i;
1007acb3 16420
19e6b90e
L
16421 length = section->sh_size;
16422 if (length == 0)
1007acb3 16423 {
74e1a04b 16424 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16425 return true;
1007acb3 16426 }
5dff79d8
NC
16427 if (section->sh_type == SHT_NOBITS)
16428 {
16429 /* There is no point in dumping the contents of a debugging section
16430 which has the NOBITS type - the bits in the file will be random.
16431 This can happen when a file containing a .eh_frame section is
16432 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16433 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16434 print_name);
015dc7e1 16435 return false;
5dff79d8 16436 }
1007acb3 16437
24d127aa 16438 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16439 name = ".debug_info";
1007acb3 16440
19e6b90e
L
16441 /* See if we know how to display the contents of this section. */
16442 for (i = 0; i < max; i++)
d85bf2ba
NC
16443 {
16444 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16445 struct dwarf_section_display * display = debug_displays + i;
16446 struct dwarf_section * sec = & display->section;
d966045b 16447
d85bf2ba 16448 if (streq (sec->uncompressed_name, name)
24d127aa 16449 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16450 || streq (sec->compressed_name, name))
16451 {
015dc7e1 16452 bool secondary = (section != find_section (filedata, name));
1007acb3 16453
d85bf2ba
NC
16454 if (secondary)
16455 free_debug_section (id);
dda8d76d 16456
24d127aa 16457 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16458 sec->name = name;
16459 else if (streq (sec->uncompressed_name, name))
16460 sec->name = sec->uncompressed_name;
16461 else
16462 sec->name = sec->compressed_name;
657d0d47 16463
d85bf2ba
NC
16464 if (load_specific_debug_section (id, section, filedata))
16465 {
16466 /* If this debug section is part of a CU/TU set in a .dwp file,
16467 restrict load_debug_section to the sections in that set. */
16468 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16469
d85bf2ba 16470 result &= display->display (sec, filedata);
657d0d47 16471
d85bf2ba 16472 section_subset = NULL;
1007acb3 16473
44266f36 16474 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16475 free_debug_section (id);
16476 }
16477 break;
16478 }
16479 }
1007acb3 16480
19e6b90e 16481 if (i == max)
1007acb3 16482 {
74e1a04b 16483 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16484 result = false;
1007acb3
L
16485 }
16486
19e6b90e 16487 return result;
5b18a4bc 16488}
103f02d3 16489
aef1f6d0
DJ
16490/* Set DUMP_SECTS for all sections where dumps were requested
16491 based on section name. */
16492
16493static void
dda8d76d 16494initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16495{
2cf0635d 16496 struct dump_list_entry * cur;
aef1f6d0
DJ
16497
16498 for (cur = dump_sects_byname; cur; cur = cur->next)
16499 {
16500 unsigned int i;
015dc7e1 16501 bool any = false;
aef1f6d0 16502
dda8d76d 16503 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16504 if (section_name_valid (filedata, filedata->section_headers + i)
16505 && streq (section_name (filedata, filedata->section_headers + i),
16506 cur->name))
aef1f6d0 16507 {
6431e409 16508 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16509 any = true;
aef1f6d0
DJ
16510 }
16511
835f2fae
NC
16512 if (!any && !filedata->is_separate)
16513 warn (_("Section '%s' was not dumped because it does not exist\n"),
16514 cur->name);
aef1f6d0
DJ
16515 }
16516}
16517
015dc7e1 16518static bool
dda8d76d 16519process_section_contents (Filedata * filedata)
5b18a4bc 16520{
2cf0635d 16521 Elf_Internal_Shdr * section;
19e6b90e 16522 unsigned int i;
015dc7e1 16523 bool res = true;
103f02d3 16524
19e6b90e 16525 if (! do_dump)
015dc7e1 16526 return true;
103f02d3 16527
dda8d76d 16528 initialise_dumps_byname (filedata);
aef1f6d0 16529
dda8d76d 16530 for (i = 0, section = filedata->section_headers;
6431e409 16531 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16532 i++, section++)
16533 {
6431e409 16534 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16535
d6bfbc39
NC
16536 if (filedata->is_separate && ! process_links)
16537 dump &= DEBUG_DUMP;
047c3dbf 16538
19e6b90e 16539#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16540 if (dump & DISASS_DUMP)
16541 {
16542 if (! disassemble_section (section, filedata))
015dc7e1 16543 res = false;
dda8d76d 16544 }
19e6b90e 16545#endif
dda8d76d 16546 if (dump & HEX_DUMP)
32ec8896 16547 {
015dc7e1
AM
16548 if (! dump_section_as_bytes (section, filedata, false))
16549 res = false;
32ec8896 16550 }
103f02d3 16551
dda8d76d 16552 if (dump & RELOC_DUMP)
32ec8896 16553 {
015dc7e1
AM
16554 if (! dump_section_as_bytes (section, filedata, true))
16555 res = false;
32ec8896 16556 }
09c11c86 16557
dda8d76d 16558 if (dump & STRING_DUMP)
32ec8896 16559 {
dda8d76d 16560 if (! dump_section_as_strings (section, filedata))
015dc7e1 16561 res = false;
32ec8896 16562 }
cf13d699 16563
dda8d76d 16564 if (dump & DEBUG_DUMP)
32ec8896 16565 {
dda8d76d 16566 if (! display_debug_section (i, section, filedata))
015dc7e1 16567 res = false;
32ec8896 16568 }
7d9813f1 16569
094e34f2 16570#ifdef ENABLE_LIBCTF
7d9813f1
NA
16571 if (dump & CTF_DUMP)
16572 {
16573 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16574 res = false;
7d9813f1 16575 }
094e34f2 16576#endif
42b6953b
IB
16577 if (dump & SFRAME_DUMP)
16578 {
16579 if (! dump_section_as_sframe (section, filedata))
16580 res = false;
16581 }
5b18a4bc 16582 }
103f02d3 16583
835f2fae 16584 if (! filedata->is_separate)
0ee3043f 16585 {
835f2fae
NC
16586 /* Check to see if the user requested a
16587 dump of a section that does not exist. */
16588 for (; i < filedata->dump.num_dump_sects; i++)
16589 if (filedata->dump.dump_sects[i])
16590 {
ca0e11aa 16591 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16592 res = false;
835f2fae 16593 }
0ee3043f 16594 }
32ec8896
NC
16595
16596 return res;
5b18a4bc 16597}
103f02d3 16598
5b18a4bc 16599static void
19e6b90e 16600process_mips_fpe_exception (int mask)
5b18a4bc 16601{
19e6b90e
L
16602 if (mask)
16603 {
015dc7e1 16604 bool first = true;
32ec8896 16605
19e6b90e 16606 if (mask & OEX_FPU_INEX)
015dc7e1 16607 fputs ("INEX", stdout), first = false;
19e6b90e 16608 if (mask & OEX_FPU_UFLO)
015dc7e1 16609 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16610 if (mask & OEX_FPU_OFLO)
015dc7e1 16611 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16612 if (mask & OEX_FPU_DIV0)
015dc7e1 16613 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16614 if (mask & OEX_FPU_INVAL)
16615 printf ("%sINVAL", first ? "" : "|");
16616 }
5b18a4bc 16617 else
19e6b90e 16618 fputs ("0", stdout);
5b18a4bc 16619}
103f02d3 16620
f6f0e17b
NC
16621/* Display's the value of TAG at location P. If TAG is
16622 greater than 0 it is assumed to be an unknown tag, and
16623 a message is printed to this effect. Otherwise it is
16624 assumed that a message has already been printed.
16625
16626 If the bottom bit of TAG is set it assumed to have a
16627 string value, otherwise it is assumed to have an integer
16628 value.
16629
16630 Returns an updated P pointing to the first unread byte
16631 beyond the end of TAG's value.
16632
16633 Reads at or beyond END will not be made. */
16634
16635static unsigned char *
60abdbed 16636display_tag_value (signed int tag,
f6f0e17b
NC
16637 unsigned char * p,
16638 const unsigned char * const end)
16639{
26c527e6 16640 uint64_t val;
f6f0e17b
NC
16641
16642 if (tag > 0)
16643 printf (" Tag_unknown_%d: ", tag);
16644
16645 if (p >= end)
16646 {
4082ef84 16647 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16648 }
16649 else if (tag & 1)
16650 {
071436c6
NC
16651 /* PR 17531 file: 027-19978-0.004. */
16652 size_t maxlen = (end - p) - 1;
16653
16654 putchar ('"');
4082ef84
NC
16655 if (maxlen > 0)
16656 {
16657 print_symbol ((int) maxlen, (const char *) p);
16658 p += strnlen ((char *) p, maxlen) + 1;
16659 }
16660 else
16661 {
16662 printf (_("<corrupt string tag>"));
16663 p = (unsigned char *) end;
16664 }
071436c6 16665 printf ("\"\n");
f6f0e17b
NC
16666 }
16667 else
16668 {
cd30bcef 16669 READ_ULEB (val, p, end);
26c527e6 16670 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
16671 }
16672
4082ef84 16673 assert (p <= end);
f6f0e17b
NC
16674 return p;
16675}
16676
53a346d8
CZ
16677/* ARC ABI attributes section. */
16678
16679static unsigned char *
16680display_arc_attribute (unsigned char * p,
16681 const unsigned char * const end)
16682{
16683 unsigned int tag;
53a346d8
CZ
16684 unsigned int val;
16685
cd30bcef 16686 READ_ULEB (tag, p, end);
53a346d8
CZ
16687
16688 switch (tag)
16689 {
16690 case Tag_ARC_PCS_config:
cd30bcef 16691 READ_ULEB (val, p, end);
53a346d8
CZ
16692 printf (" Tag_ARC_PCS_config: ");
16693 switch (val)
16694 {
16695 case 0:
16696 printf (_("Absent/Non standard\n"));
16697 break;
16698 case 1:
16699 printf (_("Bare metal/mwdt\n"));
16700 break;
16701 case 2:
16702 printf (_("Bare metal/newlib\n"));
16703 break;
16704 case 3:
16705 printf (_("Linux/uclibc\n"));
16706 break;
16707 case 4:
16708 printf (_("Linux/glibc\n"));
16709 break;
16710 default:
16711 printf (_("Unknown\n"));
16712 break;
16713 }
16714 break;
16715
16716 case Tag_ARC_CPU_base:
cd30bcef 16717 READ_ULEB (val, p, end);
53a346d8
CZ
16718 printf (" Tag_ARC_CPU_base: ");
16719 switch (val)
16720 {
16721 default:
16722 case TAG_CPU_NONE:
16723 printf (_("Absent\n"));
16724 break;
16725 case TAG_CPU_ARC6xx:
16726 printf ("ARC6xx\n");
16727 break;
16728 case TAG_CPU_ARC7xx:
16729 printf ("ARC7xx\n");
16730 break;
16731 case TAG_CPU_ARCEM:
16732 printf ("ARCEM\n");
16733 break;
16734 case TAG_CPU_ARCHS:
16735 printf ("ARCHS\n");
16736 break;
16737 }
16738 break;
16739
16740 case Tag_ARC_CPU_variation:
cd30bcef 16741 READ_ULEB (val, p, end);
53a346d8
CZ
16742 printf (" Tag_ARC_CPU_variation: ");
16743 switch (val)
16744 {
16745 default:
16746 if (val > 0 && val < 16)
53a346d8 16747 printf ("Core%d\n", val);
d8cbc93b
JL
16748 else
16749 printf ("Unknown\n");
16750 break;
16751
53a346d8
CZ
16752 case 0:
16753 printf (_("Absent\n"));
16754 break;
16755 }
16756 break;
16757
16758 case Tag_ARC_CPU_name:
16759 printf (" Tag_ARC_CPU_name: ");
16760 p = display_tag_value (-1, p, end);
16761 break;
16762
16763 case Tag_ARC_ABI_rf16:
cd30bcef 16764 READ_ULEB (val, p, end);
53a346d8
CZ
16765 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16766 break;
16767
16768 case Tag_ARC_ABI_osver:
cd30bcef 16769 READ_ULEB (val, p, end);
53a346d8
CZ
16770 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16771 break;
16772
16773 case Tag_ARC_ABI_pic:
16774 case Tag_ARC_ABI_sda:
cd30bcef 16775 READ_ULEB (val, p, end);
53a346d8
CZ
16776 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16777 : " Tag_ARC_ABI_pic: ");
16778 switch (val)
16779 {
16780 case 0:
16781 printf (_("Absent\n"));
16782 break;
16783 case 1:
16784 printf ("MWDT\n");
16785 break;
16786 case 2:
16787 printf ("GNU\n");
16788 break;
16789 default:
16790 printf (_("Unknown\n"));
16791 break;
16792 }
16793 break;
16794
16795 case Tag_ARC_ABI_tls:
cd30bcef 16796 READ_ULEB (val, p, end);
53a346d8
CZ
16797 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16798 break;
16799
16800 case Tag_ARC_ABI_enumsize:
cd30bcef 16801 READ_ULEB (val, p, end);
53a346d8
CZ
16802 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16803 _("smallest"));
16804 break;
16805
16806 case Tag_ARC_ABI_exceptions:
cd30bcef 16807 READ_ULEB (val, p, end);
53a346d8
CZ
16808 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16809 : _("default"));
16810 break;
16811
16812 case Tag_ARC_ABI_double_size:
cd30bcef 16813 READ_ULEB (val, p, end);
53a346d8
CZ
16814 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16815 break;
16816
16817 case Tag_ARC_ISA_config:
16818 printf (" Tag_ARC_ISA_config: ");
16819 p = display_tag_value (-1, p, end);
16820 break;
16821
16822 case Tag_ARC_ISA_apex:
16823 printf (" Tag_ARC_ISA_apex: ");
16824 p = display_tag_value (-1, p, end);
16825 break;
16826
16827 case Tag_ARC_ISA_mpy_option:
cd30bcef 16828 READ_ULEB (val, p, end);
53a346d8
CZ
16829 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16830 break;
16831
db1e1b45 16832 case Tag_ARC_ATR_version:
cd30bcef 16833 READ_ULEB (val, p, end);
db1e1b45 16834 printf (" Tag_ARC_ATR_version: %d\n", val);
16835 break;
16836
53a346d8
CZ
16837 default:
16838 return display_tag_value (tag & 1, p, end);
16839 }
16840
16841 return p;
16842}
16843
11c1ff18
PB
16844/* ARM EABI attributes section. */
16845typedef struct
16846{
70e99720 16847 unsigned int tag;
2cf0635d 16848 const char * name;
11c1ff18 16849 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16850 unsigned int type;
288f0ba2 16851 const char *const *table;
11c1ff18
PB
16852} arm_attr_public_tag;
16853
288f0ba2 16854static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16855 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16856 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16857 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16858 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16859static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16860static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16861 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16862static const char *const arm_attr_tag_FP_arch[] =
bca38921 16863 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16864 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16865static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16866static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16867 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16868 "NEON for ARMv8.1"};
288f0ba2 16869static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16870 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16871 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16872static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16873 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16874static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16875 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16876static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16877 {"Absolute", "PC-relative", "None"};
288f0ba2 16878static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16879 {"None", "direct", "GOT-indirect"};
288f0ba2 16880static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16881 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16882static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16883static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16884 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16885static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16886static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16887static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16888 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16889static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16890 {"Unused", "small", "int", "forced to int"};
288f0ba2 16891static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16892 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16893static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16894 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16895static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16896 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16897static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16898 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16899 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16900static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16901 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16902 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16903static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16904static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16905 {"Not Allowed", "Allowed"};
288f0ba2 16906static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16907 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16908static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16909 {"Follow architecture", "Allowed"};
288f0ba2 16910static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16911 {"Not Allowed", "Allowed"};
288f0ba2 16912static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16913 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16914 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16915static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16916static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16917 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16918 "TrustZone and Virtualization Extensions"};
288f0ba2 16919static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16920 {"Not Allowed", "Allowed"};
11c1ff18 16921
288f0ba2 16922static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16923 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16924
99db83d0
AC
16925static const char * arm_attr_tag_PAC_extension[] =
16926 {"No PAC/AUT instructions",
16927 "PAC/AUT instructions permitted in the NOP space",
16928 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16929
4b535030
AC
16930static const char * arm_attr_tag_BTI_extension[] =
16931 {"BTI instructions not permitted",
16932 "BTI instructions permitted in the NOP space",
16933 "BTI instructions permitted in the NOP and in the non-NOP space"};
16934
b81ee92f
AC
16935static const char * arm_attr_tag_BTI_use[] =
16936 {"Compiled without branch target enforcement",
16937 "Compiled with branch target enforcement"};
16938
c9fed665
AC
16939static const char * arm_attr_tag_PACRET_use[] =
16940 {"Compiled without return address signing and authentication",
16941 "Compiled with return address signing and authentication"};
16942
11c1ff18
PB
16943#define LOOKUP(id, name) \
16944 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16945static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16946{
16947 {4, "CPU_raw_name", 1, NULL},
16948 {5, "CPU_name", 1, NULL},
16949 LOOKUP(6, CPU_arch),
16950 {7, "CPU_arch_profile", 0, NULL},
16951 LOOKUP(8, ARM_ISA_use),
16952 LOOKUP(9, THUMB_ISA_use),
75375b3e 16953 LOOKUP(10, FP_arch),
11c1ff18 16954 LOOKUP(11, WMMX_arch),
f5f53991
AS
16955 LOOKUP(12, Advanced_SIMD_arch),
16956 LOOKUP(13, PCS_config),
11c1ff18
PB
16957 LOOKUP(14, ABI_PCS_R9_use),
16958 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16959 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16960 LOOKUP(17, ABI_PCS_GOT_use),
16961 LOOKUP(18, ABI_PCS_wchar_t),
16962 LOOKUP(19, ABI_FP_rounding),
16963 LOOKUP(20, ABI_FP_denormal),
16964 LOOKUP(21, ABI_FP_exceptions),
16965 LOOKUP(22, ABI_FP_user_exceptions),
16966 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16967 {24, "ABI_align_needed", 0, NULL},
16968 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16969 LOOKUP(26, ABI_enum_size),
16970 LOOKUP(27, ABI_HardFP_use),
16971 LOOKUP(28, ABI_VFP_args),
16972 LOOKUP(29, ABI_WMMX_args),
16973 LOOKUP(30, ABI_optimization_goals),
16974 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16975 {32, "compatibility", 0, NULL},
f5f53991 16976 LOOKUP(34, CPU_unaligned_access),
75375b3e 16977 LOOKUP(36, FP_HP_extension),
8e79c3df 16978 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16979 LOOKUP(42, MPextension_use),
16980 LOOKUP(44, DIV_use),
15afaa63 16981 LOOKUP(46, DSP_extension),
a7ad558c 16982 LOOKUP(48, MVE_arch),
99db83d0 16983 LOOKUP(50, PAC_extension),
4b535030 16984 LOOKUP(52, BTI_extension),
b81ee92f 16985 LOOKUP(74, BTI_use),
c9fed665 16986 LOOKUP(76, PACRET_use),
f5f53991
AS
16987 {64, "nodefaults", 0, NULL},
16988 {65, "also_compatible_with", 0, NULL},
16989 LOOKUP(66, T2EE_use),
16990 {67, "conformance", 1, NULL},
16991 LOOKUP(68, Virtualization_use),
cd21e546 16992 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16993};
16994#undef LOOKUP
16995
11c1ff18 16996static unsigned char *
f6f0e17b
NC
16997display_arm_attribute (unsigned char * p,
16998 const unsigned char * const end)
11c1ff18 16999{
70e99720 17000 unsigned int tag;
70e99720 17001 unsigned int val;
2cf0635d 17002 arm_attr_public_tag * attr;
11c1ff18 17003 unsigned i;
70e99720 17004 unsigned int type;
11c1ff18 17005
cd30bcef 17006 READ_ULEB (tag, p, end);
11c1ff18 17007 attr = NULL;
2cf0635d 17008 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
17009 {
17010 if (arm_attr_public_tags[i].tag == tag)
17011 {
17012 attr = &arm_attr_public_tags[i];
17013 break;
17014 }
17015 }
17016
17017 if (attr)
17018 {
17019 printf (" Tag_%s: ", attr->name);
17020 switch (attr->type)
17021 {
17022 case 0:
17023 switch (tag)
17024 {
17025 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 17026 READ_ULEB (val, p, end);
11c1ff18
PB
17027 switch (val)
17028 {
2b692964
NC
17029 case 0: printf (_("None\n")); break;
17030 case 'A': printf (_("Application\n")); break;
17031 case 'R': printf (_("Realtime\n")); break;
17032 case 'M': printf (_("Microcontroller\n")); break;
17033 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
17034 default: printf ("??? (%d)\n", val); break;
17035 }
17036 break;
17037
75375b3e 17038 case 24: /* Tag_align_needed. */
cd30bcef 17039 READ_ULEB (val, p, end);
75375b3e
MGD
17040 switch (val)
17041 {
2b692964
NC
17042 case 0: printf (_("None\n")); break;
17043 case 1: printf (_("8-byte\n")); break;
17044 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
17045 case 3: printf ("??? 3\n"); break;
17046 default:
17047 if (val <= 12)
dd24e3da 17048 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17049 1 << val);
17050 else
17051 printf ("??? (%d)\n", val);
17052 break;
17053 }
17054 break;
17055
17056 case 25: /* Tag_align_preserved. */
cd30bcef 17057 READ_ULEB (val, p, end);
75375b3e
MGD
17058 switch (val)
17059 {
2b692964
NC
17060 case 0: printf (_("None\n")); break;
17061 case 1: printf (_("8-byte, except leaf SP\n")); break;
17062 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
17063 case 3: printf ("??? 3\n"); break;
17064 default:
17065 if (val <= 12)
dd24e3da 17066 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17067 1 << val);
17068 else
17069 printf ("??? (%d)\n", val);
17070 break;
17071 }
17072 break;
17073
11c1ff18 17074 case 32: /* Tag_compatibility. */
071436c6 17075 {
cd30bcef 17076 READ_ULEB (val, p, end);
071436c6 17077 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17078 if (p < end - 1)
17079 {
17080 size_t maxlen = (end - p) - 1;
17081
17082 print_symbol ((int) maxlen, (const char *) p);
17083 p += strnlen ((char *) p, maxlen) + 1;
17084 }
17085 else
17086 {
17087 printf (_("<corrupt>"));
17088 p = (unsigned char *) end;
17089 }
071436c6 17090 putchar ('\n');
071436c6 17091 }
11c1ff18
PB
17092 break;
17093
f5f53991 17094 case 64: /* Tag_nodefaults. */
541a3cbd
NC
17095 /* PR 17531: file: 001-505008-0.01. */
17096 if (p < end)
17097 p++;
2b692964 17098 printf (_("True\n"));
f5f53991
AS
17099 break;
17100
17101 case 65: /* Tag_also_compatible_with. */
cd30bcef 17102 READ_ULEB (val, p, end);
f5f53991
AS
17103 if (val == 6 /* Tag_CPU_arch. */)
17104 {
cd30bcef 17105 READ_ULEB (val, p, end);
071436c6 17106 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
17107 printf ("??? (%d)\n", val);
17108 else
17109 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17110 }
17111 else
17112 printf ("???\n");
071436c6
NC
17113 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17114 ;
f5f53991
AS
17115 break;
17116
11c1ff18 17117 default:
bee0ee85
NC
17118 printf (_("<unknown: %d>\n"), tag);
17119 break;
11c1ff18
PB
17120 }
17121 return p;
17122
17123 case 1:
f6f0e17b 17124 return display_tag_value (-1, p, end);
11c1ff18 17125 case 2:
f6f0e17b 17126 return display_tag_value (0, p, end);
11c1ff18
PB
17127
17128 default:
17129 assert (attr->type & 0x80);
cd30bcef 17130 READ_ULEB (val, p, end);
11c1ff18
PB
17131 type = attr->type & 0x7f;
17132 if (val >= type)
17133 printf ("??? (%d)\n", val);
17134 else
17135 printf ("%s\n", attr->table[val]);
17136 return p;
17137 }
17138 }
11c1ff18 17139
f6f0e17b 17140 return display_tag_value (tag, p, end);
11c1ff18
PB
17141}
17142
104d59d1 17143static unsigned char *
60bca95a 17144display_gnu_attribute (unsigned char * p,
60abdbed 17145 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 17146 const unsigned char * const end)
104d59d1 17147{
cd30bcef 17148 unsigned int tag;
60abdbed 17149 unsigned int val;
104d59d1 17150
cd30bcef 17151 READ_ULEB (tag, p, end);
104d59d1
JM
17152
17153 /* Tag_compatibility is the only generic GNU attribute defined at
17154 present. */
17155 if (tag == 32)
17156 {
cd30bcef 17157 READ_ULEB (val, p, end);
071436c6
NC
17158
17159 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
17160 if (p == end)
17161 {
071436c6 17162 printf (_("<corrupt>\n"));
f6f0e17b
NC
17163 warn (_("corrupt vendor attribute\n"));
17164 }
17165 else
17166 {
4082ef84
NC
17167 if (p < end - 1)
17168 {
17169 size_t maxlen = (end - p) - 1;
071436c6 17170
4082ef84
NC
17171 print_symbol ((int) maxlen, (const char *) p);
17172 p += strnlen ((char *) p, maxlen) + 1;
17173 }
17174 else
17175 {
17176 printf (_("<corrupt>"));
17177 p = (unsigned char *) end;
17178 }
071436c6 17179 putchar ('\n');
f6f0e17b 17180 }
104d59d1
JM
17181 return p;
17182 }
17183
17184 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 17185 return display_proc_gnu_attribute (p, tag, end);
104d59d1 17186
f6f0e17b 17187 return display_tag_value (tag, p, end);
104d59d1
JM
17188}
17189
85f7484a
PB
17190static unsigned char *
17191display_m68k_gnu_attribute (unsigned char * p,
17192 unsigned int tag,
17193 const unsigned char * const end)
17194{
17195 unsigned int val;
17196
17197 if (tag == Tag_GNU_M68K_ABI_FP)
17198 {
17199 printf (" Tag_GNU_M68K_ABI_FP: ");
17200 if (p == end)
17201 {
17202 printf (_("<corrupt>\n"));
17203 return p;
17204 }
17205 READ_ULEB (val, p, end);
17206
17207 if (val > 3)
17208 printf ("(%#x), ", val);
17209
17210 switch (val & 3)
17211 {
17212 case 0:
17213 printf (_("unspecified hard/soft float\n"));
17214 break;
17215 case 1:
17216 printf (_("hard float\n"));
17217 break;
17218 case 2:
17219 printf (_("soft float\n"));
17220 break;
17221 }
17222 return p;
17223 }
17224
17225 return display_tag_value (tag & 1, p, end);
17226}
17227
34c8bcba 17228static unsigned char *
f6f0e17b 17229display_power_gnu_attribute (unsigned char * p,
60abdbed 17230 unsigned int tag,
f6f0e17b 17231 const unsigned char * const end)
34c8bcba 17232{
005d79fd 17233 unsigned int val;
34c8bcba
JM
17234
17235 if (tag == Tag_GNU_Power_ABI_FP)
17236 {
34c8bcba 17237 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 17238 if (p == end)
005d79fd
AM
17239 {
17240 printf (_("<corrupt>\n"));
17241 return p;
17242 }
cd30bcef 17243 READ_ULEB (val, p, end);
60bca95a 17244
005d79fd
AM
17245 if (val > 15)
17246 printf ("(%#x), ", val);
17247
17248 switch (val & 3)
34c8bcba
JM
17249 {
17250 case 0:
005d79fd 17251 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17252 break;
17253 case 1:
005d79fd 17254 printf (_("hard float, "));
34c8bcba
JM
17255 break;
17256 case 2:
005d79fd 17257 printf (_("soft float, "));
34c8bcba 17258 break;
3c7b9897 17259 case 3:
005d79fd 17260 printf (_("single-precision hard float, "));
3c7b9897 17261 break;
005d79fd
AM
17262 }
17263
17264 switch (val & 0xC)
17265 {
17266 case 0:
17267 printf (_("unspecified long double\n"));
17268 break;
17269 case 4:
17270 printf (_("128-bit IBM long double\n"));
17271 break;
17272 case 8:
17273 printf (_("64-bit long double\n"));
17274 break;
17275 case 12:
17276 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17277 break;
17278 }
17279 return p;
005d79fd 17280 }
34c8bcba 17281
c6e65352
DJ
17282 if (tag == Tag_GNU_Power_ABI_Vector)
17283 {
c6e65352 17284 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17285 if (p == end)
005d79fd
AM
17286 {
17287 printf (_("<corrupt>\n"));
17288 return p;
17289 }
cd30bcef 17290 READ_ULEB (val, p, end);
005d79fd
AM
17291
17292 if (val > 3)
17293 printf ("(%#x), ", val);
17294
17295 switch (val & 3)
c6e65352
DJ
17296 {
17297 case 0:
005d79fd 17298 printf (_("unspecified\n"));
c6e65352
DJ
17299 break;
17300 case 1:
005d79fd 17301 printf (_("generic\n"));
c6e65352
DJ
17302 break;
17303 case 2:
17304 printf ("AltiVec\n");
17305 break;
17306 case 3:
17307 printf ("SPE\n");
17308 break;
c6e65352
DJ
17309 }
17310 return p;
005d79fd 17311 }
c6e65352 17312
f82e0623
NF
17313 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17314 {
005d79fd 17315 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17316 if (p == end)
f6f0e17b 17317 {
005d79fd 17318 printf (_("<corrupt>\n"));
f6f0e17b
NC
17319 return p;
17320 }
cd30bcef 17321 READ_ULEB (val, p, end);
0b4362b0 17322
005d79fd
AM
17323 if (val > 2)
17324 printf ("(%#x), ", val);
17325
17326 switch (val & 3)
17327 {
17328 case 0:
17329 printf (_("unspecified\n"));
17330 break;
17331 case 1:
17332 printf ("r3/r4\n");
17333 break;
17334 case 2:
17335 printf (_("memory\n"));
17336 break;
17337 case 3:
17338 printf ("???\n");
17339 break;
17340 }
f82e0623
NF
17341 return p;
17342 }
17343
f6f0e17b 17344 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17345}
17346
643f7afb
AK
17347static unsigned char *
17348display_s390_gnu_attribute (unsigned char * p,
60abdbed 17349 unsigned int tag,
643f7afb
AK
17350 const unsigned char * const end)
17351{
cd30bcef 17352 unsigned int val;
643f7afb
AK
17353
17354 if (tag == Tag_GNU_S390_ABI_Vector)
17355 {
643f7afb 17356 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17357 READ_ULEB (val, p, end);
643f7afb
AK
17358
17359 switch (val)
17360 {
17361 case 0:
17362 printf (_("any\n"));
17363 break;
17364 case 1:
17365 printf (_("software\n"));
17366 break;
17367 case 2:
17368 printf (_("hardware\n"));
17369 break;
17370 default:
17371 printf ("??? (%d)\n", val);
17372 break;
17373 }
17374 return p;
17375 }
17376
17377 return display_tag_value (tag & 1, p, end);
17378}
17379
9e8c70f9 17380static void
60abdbed 17381display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17382{
17383 if (mask)
17384 {
015dc7e1 17385 bool first = true;
071436c6 17386
9e8c70f9 17387 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17388 fputs ("mul32", stdout), first = false;
9e8c70f9 17389 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17390 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17391 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17392 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17393 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17394 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17395 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17396 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17397 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17398 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17399 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17400 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17401 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17402 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17403 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17404 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17405 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17406 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17407 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17408 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17409 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17410 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17411 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17412 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17413 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17414 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17415 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17416 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17417 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17418 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17419 }
17420 else
071436c6
NC
17421 fputc ('0', stdout);
17422 fputc ('\n', stdout);
9e8c70f9
DM
17423}
17424
3d68f91c 17425static void
60abdbed 17426display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17427{
17428 if (mask)
17429 {
015dc7e1 17430 bool first = true;
071436c6 17431
3d68f91c 17432 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17433 fputs ("fjathplus", stdout), first = false;
3d68f91c 17434 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17435 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17436 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17437 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17438 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17439 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17440 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17441 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17442 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17443 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17444 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17445 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17446 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17447 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17448 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17449 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17450 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17451 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17452 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17453 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17454 }
17455 else
071436c6
NC
17456 fputc ('0', stdout);
17457 fputc ('\n', stdout);
3d68f91c
JM
17458}
17459
9e8c70f9 17460static unsigned char *
f6f0e17b 17461display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17462 unsigned int tag,
f6f0e17b 17463 const unsigned char * const end)
9e8c70f9 17464{
cd30bcef 17465 unsigned int val;
3d68f91c 17466
9e8c70f9
DM
17467 if (tag == Tag_GNU_Sparc_HWCAPS)
17468 {
cd30bcef 17469 READ_ULEB (val, p, end);
9e8c70f9 17470 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17471 display_sparc_hwcaps (val);
17472 return p;
3d68f91c
JM
17473 }
17474 if (tag == Tag_GNU_Sparc_HWCAPS2)
17475 {
cd30bcef 17476 READ_ULEB (val, p, end);
3d68f91c
JM
17477 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17478 display_sparc_hwcaps2 (val);
17479 return p;
17480 }
9e8c70f9 17481
f6f0e17b 17482 return display_tag_value (tag, p, end);
9e8c70f9
DM
17483}
17484
351cdf24 17485static void
32ec8896 17486print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17487{
17488 switch (val)
17489 {
17490 case Val_GNU_MIPS_ABI_FP_ANY:
17491 printf (_("Hard or soft float\n"));
17492 break;
17493 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17494 printf (_("Hard float (double precision)\n"));
17495 break;
17496 case Val_GNU_MIPS_ABI_FP_SINGLE:
17497 printf (_("Hard float (single precision)\n"));
17498 break;
17499 case Val_GNU_MIPS_ABI_FP_SOFT:
17500 printf (_("Soft float\n"));
17501 break;
17502 case Val_GNU_MIPS_ABI_FP_OLD_64:
17503 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17504 break;
17505 case Val_GNU_MIPS_ABI_FP_XX:
17506 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17507 break;
17508 case Val_GNU_MIPS_ABI_FP_64:
17509 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17510 break;
17511 case Val_GNU_MIPS_ABI_FP_64A:
17512 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17513 break;
3350cc01
CM
17514 case Val_GNU_MIPS_ABI_FP_NAN2008:
17515 printf (_("NaN 2008 compatibility\n"));
17516 break;
351cdf24
MF
17517 default:
17518 printf ("??? (%d)\n", val);
17519 break;
17520 }
17521}
17522
2cf19d5c 17523static unsigned char *
f6f0e17b 17524display_mips_gnu_attribute (unsigned char * p,
60abdbed 17525 unsigned int tag,
f6f0e17b 17526 const unsigned char * const end)
2cf19d5c 17527{
2cf19d5c
JM
17528 if (tag == Tag_GNU_MIPS_ABI_FP)
17529 {
32ec8896 17530 unsigned int val;
f6f0e17b 17531
2cf19d5c 17532 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17533 READ_ULEB (val, p, end);
351cdf24 17534 print_mips_fp_abi_value (val);
2cf19d5c
JM
17535 return p;
17536 }
17537
a9f58168
CF
17538 if (tag == Tag_GNU_MIPS_ABI_MSA)
17539 {
32ec8896 17540 unsigned int val;
a9f58168 17541
a9f58168 17542 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17543 READ_ULEB (val, p, end);
a9f58168
CF
17544
17545 switch (val)
17546 {
17547 case Val_GNU_MIPS_ABI_MSA_ANY:
17548 printf (_("Any MSA or not\n"));
17549 break;
17550 case Val_GNU_MIPS_ABI_MSA_128:
17551 printf (_("128-bit MSA\n"));
17552 break;
17553 default:
17554 printf ("??? (%d)\n", val);
17555 break;
17556 }
17557 return p;
17558 }
17559
f6f0e17b 17560 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17561}
17562
59e6276b 17563static unsigned char *
f6f0e17b
NC
17564display_tic6x_attribute (unsigned char * p,
17565 const unsigned char * const end)
59e6276b 17566{
60abdbed 17567 unsigned int tag;
cd30bcef 17568 unsigned int val;
59e6276b 17569
cd30bcef 17570 READ_ULEB (tag, p, end);
59e6276b
JM
17571
17572 switch (tag)
17573 {
75fa6dc1 17574 case Tag_ISA:
75fa6dc1 17575 printf (" Tag_ISA: ");
cd30bcef 17576 READ_ULEB (val, p, end);
59e6276b
JM
17577
17578 switch (val)
17579 {
75fa6dc1 17580 case C6XABI_Tag_ISA_none:
59e6276b
JM
17581 printf (_("None\n"));
17582 break;
75fa6dc1 17583 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17584 printf ("C62x\n");
17585 break;
75fa6dc1 17586 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17587 printf ("C67x\n");
17588 break;
75fa6dc1 17589 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17590 printf ("C67x+\n");
17591 break;
75fa6dc1 17592 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17593 printf ("C64x\n");
17594 break;
75fa6dc1 17595 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17596 printf ("C64x+\n");
17597 break;
75fa6dc1 17598 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17599 printf ("C674x\n");
17600 break;
17601 default:
17602 printf ("??? (%d)\n", val);
17603 break;
17604 }
17605 return p;
17606
87779176 17607 case Tag_ABI_wchar_t:
87779176 17608 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17609 READ_ULEB (val, p, end);
87779176
JM
17610 switch (val)
17611 {
17612 case 0:
17613 printf (_("Not used\n"));
17614 break;
17615 case 1:
17616 printf (_("2 bytes\n"));
17617 break;
17618 case 2:
17619 printf (_("4 bytes\n"));
17620 break;
17621 default:
17622 printf ("??? (%d)\n", val);
17623 break;
17624 }
17625 return p;
17626
17627 case Tag_ABI_stack_align_needed:
87779176 17628 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17629 READ_ULEB (val, p, end);
87779176
JM
17630 switch (val)
17631 {
17632 case 0:
17633 printf (_("8-byte\n"));
17634 break;
17635 case 1:
17636 printf (_("16-byte\n"));
17637 break;
17638 default:
17639 printf ("??? (%d)\n", val);
17640 break;
17641 }
17642 return p;
17643
17644 case Tag_ABI_stack_align_preserved:
cd30bcef 17645 READ_ULEB (val, p, end);
87779176
JM
17646 printf (" Tag_ABI_stack_align_preserved: ");
17647 switch (val)
17648 {
17649 case 0:
17650 printf (_("8-byte\n"));
17651 break;
17652 case 1:
17653 printf (_("16-byte\n"));
17654 break;
17655 default:
17656 printf ("??? (%d)\n", val);
17657 break;
17658 }
17659 return p;
17660
b5593623 17661 case Tag_ABI_DSBT:
cd30bcef 17662 READ_ULEB (val, p, end);
b5593623
JM
17663 printf (" Tag_ABI_DSBT: ");
17664 switch (val)
17665 {
17666 case 0:
17667 printf (_("DSBT addressing not used\n"));
17668 break;
17669 case 1:
17670 printf (_("DSBT addressing used\n"));
17671 break;
17672 default:
17673 printf ("??? (%d)\n", val);
17674 break;
17675 }
17676 return p;
17677
87779176 17678 case Tag_ABI_PID:
cd30bcef 17679 READ_ULEB (val, p, end);
87779176
JM
17680 printf (" Tag_ABI_PID: ");
17681 switch (val)
17682 {
17683 case 0:
17684 printf (_("Data addressing position-dependent\n"));
17685 break;
17686 case 1:
17687 printf (_("Data addressing position-independent, GOT near DP\n"));
17688 break;
17689 case 2:
17690 printf (_("Data addressing position-independent, GOT far from DP\n"));
17691 break;
17692 default:
17693 printf ("??? (%d)\n", val);
17694 break;
17695 }
17696 return p;
17697
17698 case Tag_ABI_PIC:
cd30bcef 17699 READ_ULEB (val, p, end);
87779176
JM
17700 printf (" Tag_ABI_PIC: ");
17701 switch (val)
17702 {
17703 case 0:
17704 printf (_("Code addressing position-dependent\n"));
17705 break;
17706 case 1:
17707 printf (_("Code addressing position-independent\n"));
17708 break;
17709 default:
17710 printf ("??? (%d)\n", val);
17711 break;
17712 }
17713 return p;
17714
17715 case Tag_ABI_array_object_alignment:
cd30bcef 17716 READ_ULEB (val, p, end);
87779176
JM
17717 printf (" Tag_ABI_array_object_alignment: ");
17718 switch (val)
17719 {
17720 case 0:
17721 printf (_("8-byte\n"));
17722 break;
17723 case 1:
17724 printf (_("4-byte\n"));
17725 break;
17726 case 2:
17727 printf (_("16-byte\n"));
17728 break;
17729 default:
17730 printf ("??? (%d)\n", val);
17731 break;
17732 }
17733 return p;
17734
17735 case Tag_ABI_array_object_align_expected:
cd30bcef 17736 READ_ULEB (val, p, end);
87779176
JM
17737 printf (" Tag_ABI_array_object_align_expected: ");
17738 switch (val)
17739 {
17740 case 0:
17741 printf (_("8-byte\n"));
17742 break;
17743 case 1:
17744 printf (_("4-byte\n"));
17745 break;
17746 case 2:
17747 printf (_("16-byte\n"));
17748 break;
17749 default:
17750 printf ("??? (%d)\n", val);
17751 break;
17752 }
17753 return p;
17754
3cbd1c06 17755 case Tag_ABI_compatibility:
071436c6 17756 {
cd30bcef 17757 READ_ULEB (val, p, end);
071436c6 17758 printf (" Tag_ABI_compatibility: ");
071436c6 17759 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17760 if (p < end - 1)
17761 {
17762 size_t maxlen = (end - p) - 1;
17763
17764 print_symbol ((int) maxlen, (const char *) p);
17765 p += strnlen ((char *) p, maxlen) + 1;
17766 }
17767 else
17768 {
17769 printf (_("<corrupt>"));
17770 p = (unsigned char *) end;
17771 }
071436c6 17772 putchar ('\n');
071436c6
NC
17773 return p;
17774 }
87779176
JM
17775
17776 case Tag_ABI_conformance:
071436c6 17777 {
4082ef84
NC
17778 printf (" Tag_ABI_conformance: \"");
17779 if (p < end - 1)
17780 {
17781 size_t maxlen = (end - p) - 1;
071436c6 17782
4082ef84
NC
17783 print_symbol ((int) maxlen, (const char *) p);
17784 p += strnlen ((char *) p, maxlen) + 1;
17785 }
17786 else
17787 {
17788 printf (_("<corrupt>"));
17789 p = (unsigned char *) end;
17790 }
071436c6 17791 printf ("\"\n");
071436c6
NC
17792 return p;
17793 }
59e6276b
JM
17794 }
17795
f6f0e17b
NC
17796 return display_tag_value (tag, p, end);
17797}
59e6276b 17798
f6f0e17b 17799static void
60abdbed 17800display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 17801{
26c527e6 17802 uint64_t addr = 0;
f6f0e17b
NC
17803 size_t bytes = end - p;
17804
feceaa59 17805 assert (end >= p);
f6f0e17b 17806 while (bytes)
87779176 17807 {
f6f0e17b
NC
17808 int j;
17809 int k;
17810 int lbytes = (bytes > 16 ? 16 : bytes);
17811
26c527e6 17812 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
17813
17814 for (j = 0; j < 16; j++)
17815 {
17816 if (j < lbytes)
17817 printf ("%2.2x", p[j]);
17818 else
17819 printf (" ");
17820
17821 if ((j & 3) == 3)
17822 printf (" ");
17823 }
17824
17825 for (j = 0; j < lbytes; j++)
17826 {
17827 k = p[j];
17828 if (k >= ' ' && k < 0x7f)
17829 printf ("%c", k);
17830 else
17831 printf (".");
17832 }
17833
17834 putchar ('\n');
17835
17836 p += lbytes;
17837 bytes -= lbytes;
17838 addr += lbytes;
87779176 17839 }
59e6276b 17840
f6f0e17b 17841 putchar ('\n');
59e6276b
JM
17842}
17843
13761a11 17844static unsigned char *
b0191216 17845display_msp430_attribute (unsigned char * p,
26c527e6 17846 const unsigned char * const end)
13761a11 17847{
26c527e6
AM
17848 uint64_t val;
17849 uint64_t tag;
13761a11 17850
cd30bcef 17851 READ_ULEB (tag, p, end);
0b4362b0 17852
13761a11
NC
17853 switch (tag)
17854 {
17855 case OFBA_MSPABI_Tag_ISA:
13761a11 17856 printf (" Tag_ISA: ");
cd30bcef 17857 READ_ULEB (val, p, end);
13761a11
NC
17858 switch (val)
17859 {
17860 case 0: printf (_("None\n")); break;
17861 case 1: printf (_("MSP430\n")); break;
17862 case 2: printf (_("MSP430X\n")); break;
26c527e6 17863 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17864 }
17865 break;
17866
17867 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17868 printf (" Tag_Code_Model: ");
cd30bcef 17869 READ_ULEB (val, p, end);
13761a11
NC
17870 switch (val)
17871 {
17872 case 0: printf (_("None\n")); break;
17873 case 1: printf (_("Small\n")); break;
17874 case 2: printf (_("Large\n")); break;
26c527e6 17875 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17876 }
17877 break;
17878
17879 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17880 printf (" Tag_Data_Model: ");
cd30bcef 17881 READ_ULEB (val, p, end);
13761a11
NC
17882 switch (val)
17883 {
17884 case 0: printf (_("None\n")); break;
17885 case 1: printf (_("Small\n")); break;
17886 case 2: printf (_("Large\n")); break;
17887 case 3: printf (_("Restricted Large\n")); break;
26c527e6 17888 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17889 }
17890 break;
17891
17892 default:
26c527e6 17893 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
17894
17895 if (tag & 1)
17896 {
071436c6 17897 putchar ('"');
4082ef84
NC
17898 if (p < end - 1)
17899 {
17900 size_t maxlen = (end - p) - 1;
17901
17902 print_symbol ((int) maxlen, (const char *) p);
17903 p += strnlen ((char *) p, maxlen) + 1;
17904 }
17905 else
17906 {
17907 printf (_("<corrupt>"));
17908 p = (unsigned char *) end;
17909 }
071436c6 17910 printf ("\"\n");
13761a11
NC
17911 }
17912 else
17913 {
cd30bcef 17914 READ_ULEB (val, p, end);
26c527e6 17915 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
17916 }
17917 break;
17918 }
17919
4082ef84 17920 assert (p <= end);
13761a11
NC
17921 return p;
17922}
17923
c0ea7c52
JL
17924static unsigned char *
17925display_msp430_gnu_attribute (unsigned char * p,
17926 unsigned int tag,
17927 const unsigned char * const end)
17928{
17929 if (tag == Tag_GNU_MSP430_Data_Region)
17930 {
26c527e6 17931 uint64_t val;
c0ea7c52 17932
c0ea7c52 17933 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17934 READ_ULEB (val, p, end);
c0ea7c52
JL
17935
17936 switch (val)
17937 {
17938 case Val_GNU_MSP430_Data_Region_Any:
17939 printf (_("Any Region\n"));
17940 break;
17941 case Val_GNU_MSP430_Data_Region_Lower:
17942 printf (_("Lower Region Only\n"));
17943 break;
17944 default:
26c527e6 17945 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
17946 }
17947 return p;
17948 }
17949 return display_tag_value (tag & 1, p, end);
17950}
17951
2dc8dd17
JW
17952struct riscv_attr_tag_t {
17953 const char *name;
cd30bcef 17954 unsigned int tag;
2dc8dd17
JW
17955};
17956
17957static struct riscv_attr_tag_t riscv_attr_tag[] =
17958{
17959#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17960 T(arch),
17961 T(priv_spec),
17962 T(priv_spec_minor),
17963 T(priv_spec_revision),
17964 T(unaligned_access),
17965 T(stack_align),
17966#undef T
17967};
17968
17969static unsigned char *
17970display_riscv_attribute (unsigned char *p,
17971 const unsigned char * const end)
17972{
26c527e6
AM
17973 uint64_t val;
17974 uint64_t tag;
2dc8dd17
JW
17975 struct riscv_attr_tag_t *attr = NULL;
17976 unsigned i;
17977
cd30bcef 17978 READ_ULEB (tag, p, end);
2dc8dd17
JW
17979
17980 /* Find the name of attribute. */
17981 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17982 {
17983 if (riscv_attr_tag[i].tag == tag)
17984 {
17985 attr = &riscv_attr_tag[i];
17986 break;
17987 }
17988 }
17989
17990 if (attr)
17991 printf (" %s: ", attr->name);
17992 else
17993 return display_tag_value (tag, p, end);
17994
17995 switch (tag)
17996 {
17997 case Tag_RISCV_priv_spec:
17998 case Tag_RISCV_priv_spec_minor:
17999 case Tag_RISCV_priv_spec_revision:
cd30bcef 18000 READ_ULEB (val, p, end);
26c527e6 18001 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
18002 break;
18003 case Tag_RISCV_unaligned_access:
cd30bcef 18004 READ_ULEB (val, p, end);
2dc8dd17
JW
18005 switch (val)
18006 {
18007 case 0:
18008 printf (_("No unaligned access\n"));
18009 break;
18010 case 1:
18011 printf (_("Unaligned access\n"));
18012 break;
18013 }
18014 break;
18015 case Tag_RISCV_stack_align:
cd30bcef 18016 READ_ULEB (val, p, end);
26c527e6 18017 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
18018 break;
18019 case Tag_RISCV_arch:
18020 p = display_tag_value (-1, p, end);
18021 break;
18022 default:
18023 return display_tag_value (tag, p, end);
18024 }
18025
18026 return p;
18027}
18028
0861f561
CQ
18029static unsigned char *
18030display_csky_attribute (unsigned char * p,
18031 const unsigned char * const end)
18032{
26c527e6
AM
18033 uint64_t tag;
18034 uint64_t val;
0861f561
CQ
18035 READ_ULEB (tag, p, end);
18036
18037 if (tag >= Tag_CSKY_MAX)
18038 {
18039 return display_tag_value (-1, p, end);
18040 }
18041
18042 switch (tag)
18043 {
18044 case Tag_CSKY_ARCH_NAME:
18045 printf (" Tag_CSKY_ARCH_NAME:\t\t");
18046 return display_tag_value (-1, p, end);
18047 case Tag_CSKY_CPU_NAME:
18048 printf (" Tag_CSKY_CPU_NAME:\t\t");
18049 return display_tag_value (-1, p, end);
18050
18051 case Tag_CSKY_ISA_FLAGS:
18052 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
18053 return display_tag_value (0, p, end);
18054 case Tag_CSKY_ISA_EXT_FLAGS:
18055 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
18056 return display_tag_value (0, p, end);
18057
18058 case Tag_CSKY_DSP_VERSION:
18059 printf (" Tag_CSKY_DSP_VERSION:\t\t");
18060 READ_ULEB (val, p, end);
18061 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
18062 printf ("DSP Extension\n");
18063 else if (val == VAL_CSKY_DSP_VERSION_2)
18064 printf ("DSP 2.0\n");
18065 break;
18066
18067 case Tag_CSKY_VDSP_VERSION:
18068 printf (" Tag_CSKY_VDSP_VERSION:\t");
18069 READ_ULEB (val, p, end);
26c527e6 18070 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
18071 break;
18072
18073 case Tag_CSKY_FPU_VERSION:
18074 printf (" Tag_CSKY_FPU_VERSION:\t\t");
18075 READ_ULEB (val, p, end);
18076 if (val == VAL_CSKY_FPU_VERSION_1)
18077 printf ("ABIV1 FPU Version 1\n");
18078 else if (val == VAL_CSKY_FPU_VERSION_2)
18079 printf ("FPU Version 2\n");
18080 break;
18081
18082 case Tag_CSKY_FPU_ABI:
18083 printf (" Tag_CSKY_FPU_ABI:\t\t");
18084 READ_ULEB (val, p, end);
18085 if (val == VAL_CSKY_FPU_ABI_HARD)
18086 printf ("Hard\n");
18087 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18088 printf ("SoftFP\n");
18089 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18090 printf ("Soft\n");
18091 break;
18092 case Tag_CSKY_FPU_ROUNDING:
18093 READ_ULEB (val, p, end);
f253158f
NC
18094 if (val == 1)
18095 {
18096 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18097 printf ("Needed\n");
18098 }
0861f561
CQ
18099 break;
18100 case Tag_CSKY_FPU_DENORMAL:
18101 READ_ULEB (val, p, end);
f253158f
NC
18102 if (val == 1)
18103 {
18104 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18105 printf ("Needed\n");
18106 }
0861f561
CQ
18107 break;
18108 case Tag_CSKY_FPU_Exception:
18109 READ_ULEB (val, p, end);
f253158f
NC
18110 if (val == 1)
18111 {
18112 printf (" Tag_CSKY_FPU_Exception:\t");
18113 printf ("Needed\n");
18114 }
0861f561
CQ
18115 break;
18116 case Tag_CSKY_FPU_NUMBER_MODULE:
18117 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18118 return display_tag_value (-1, p, end);
18119 case Tag_CSKY_FPU_HARDFP:
18120 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18121 READ_ULEB (val, p, end);
18122 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18123 printf (" Half");
18124 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18125 printf (" Single");
18126 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18127 printf (" Double");
18128 printf ("\n");
18129 break;
18130 default:
18131 return display_tag_value (tag, p, end);
18132 }
18133 return p;
18134}
18135
015dc7e1 18136static bool
dda8d76d 18137process_attributes (Filedata * filedata,
60bca95a 18138 const char * public_name,
104d59d1 18139 unsigned int proc_type,
f6f0e17b 18140 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 18141 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 18142{
2cf0635d 18143 Elf_Internal_Shdr * sect;
11c1ff18 18144 unsigned i;
015dc7e1 18145 bool res = true;
11c1ff18
PB
18146
18147 /* Find the section header so that we get the size. */
dda8d76d
NC
18148 for (i = 0, sect = filedata->section_headers;
18149 i < filedata->file_header.e_shnum;
11c1ff18
PB
18150 i++, sect++)
18151 {
071436c6
NC
18152 unsigned char * contents;
18153 unsigned char * p;
18154
104d59d1 18155 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
18156 continue;
18157
dda8d76d 18158 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 18159 sect->sh_size, _("attributes"));
60bca95a 18160 if (contents == NULL)
32ec8896 18161 {
015dc7e1 18162 res = false;
32ec8896
NC
18163 continue;
18164 }
60bca95a 18165
11c1ff18 18166 p = contents;
60abdbed
NC
18167 /* The first character is the version of the attributes.
18168 Currently only version 1, (aka 'A') is recognised here. */
18169 if (*p != 'A')
32ec8896
NC
18170 {
18171 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 18172 res = false;
32ec8896 18173 }
60abdbed 18174 else
11c1ff18 18175 {
625d49fc 18176 uint64_t section_len;
071436c6
NC
18177
18178 section_len = sect->sh_size - 1;
11c1ff18 18179 p++;
60bca95a 18180
071436c6 18181 while (section_len > 0)
11c1ff18 18182 {
625d49fc 18183 uint64_t attr_len;
e9847026 18184 unsigned int namelen;
015dc7e1
AM
18185 bool public_section;
18186 bool gnu_section;
11c1ff18 18187
071436c6 18188 if (section_len <= 4)
e0a31db1
NC
18189 {
18190 error (_("Tag section ends prematurely\n"));
015dc7e1 18191 res = false;
e0a31db1
NC
18192 break;
18193 }
071436c6 18194 attr_len = byte_get (p, 4);
11c1ff18 18195 p += 4;
60bca95a 18196
071436c6 18197 if (attr_len > section_len)
11c1ff18 18198 {
071436c6
NC
18199 error (_("Bad attribute length (%u > %u)\n"),
18200 (unsigned) attr_len, (unsigned) section_len);
18201 attr_len = section_len;
015dc7e1 18202 res = false;
11c1ff18 18203 }
74e1a04b 18204 /* PR 17531: file: 001-101425-0.004 */
071436c6 18205 else if (attr_len < 5)
74e1a04b 18206 {
071436c6 18207 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 18208 res = false;
74e1a04b
NC
18209 break;
18210 }
e9847026 18211
071436c6
NC
18212 section_len -= attr_len;
18213 attr_len -= 4;
18214
18215 namelen = strnlen ((char *) p, attr_len) + 1;
18216 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
18217 {
18218 error (_("Corrupt attribute section name\n"));
015dc7e1 18219 res = false;
e9847026
NC
18220 break;
18221 }
18222
071436c6
NC
18223 printf (_("Attribute Section: "));
18224 print_symbol (INT_MAX, (const char *) p);
18225 putchar ('\n');
60bca95a
NC
18226
18227 if (public_name && streq ((char *) p, public_name))
015dc7e1 18228 public_section = true;
11c1ff18 18229 else
015dc7e1 18230 public_section = false;
60bca95a
NC
18231
18232 if (streq ((char *) p, "gnu"))
015dc7e1 18233 gnu_section = true;
104d59d1 18234 else
015dc7e1 18235 gnu_section = false;
60bca95a 18236
11c1ff18 18237 p += namelen;
071436c6 18238 attr_len -= namelen;
e0a31db1 18239
071436c6 18240 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18241 {
e0a31db1 18242 int tag;
cd30bcef 18243 unsigned int val;
625d49fc 18244 uint64_t size;
071436c6 18245 unsigned char * end;
60bca95a 18246
e0a31db1 18247 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18248 if (attr_len < 6)
e0a31db1
NC
18249 {
18250 error (_("Unused bytes at end of section\n"));
015dc7e1 18251 res = false;
e0a31db1
NC
18252 section_len = 0;
18253 break;
18254 }
18255
18256 tag = *(p++);
11c1ff18 18257 size = byte_get (p, 4);
071436c6 18258 if (size > attr_len)
11c1ff18 18259 {
e9847026 18260 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18261 (unsigned) size, (unsigned) attr_len);
015dc7e1 18262 res = false;
071436c6 18263 size = attr_len;
11c1ff18 18264 }
e0a31db1
NC
18265 /* PR binutils/17531: Safe handling of corrupt files. */
18266 if (size < 6)
18267 {
18268 error (_("Bad subsection length (%u < 6)\n"),
18269 (unsigned) size);
015dc7e1 18270 res = false;
e0a31db1
NC
18271 section_len = 0;
18272 break;
18273 }
60bca95a 18274
071436c6 18275 attr_len -= size;
11c1ff18 18276 end = p + size - 1;
071436c6 18277 assert (end <= contents + sect->sh_size);
11c1ff18 18278 p += 4;
60bca95a 18279
11c1ff18
PB
18280 switch (tag)
18281 {
18282 case 1:
2b692964 18283 printf (_("File Attributes\n"));
11c1ff18
PB
18284 break;
18285 case 2:
2b692964 18286 printf (_("Section Attributes:"));
11c1ff18
PB
18287 goto do_numlist;
18288 case 3:
2b692964 18289 printf (_("Symbol Attributes:"));
1a0670f3 18290 /* Fall through. */
11c1ff18
PB
18291 do_numlist:
18292 for (;;)
18293 {
cd30bcef 18294 READ_ULEB (val, p, end);
11c1ff18
PB
18295 if (val == 0)
18296 break;
18297 printf (" %d", val);
18298 }
18299 printf ("\n");
18300 break;
18301 default:
2b692964 18302 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18303 public_section = false;
11c1ff18
PB
18304 break;
18305 }
60bca95a 18306
071436c6 18307 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18308 {
18309 while (p < end)
f6f0e17b 18310 p = display_pub_attribute (p, end);
60abdbed 18311 assert (p == end);
104d59d1 18312 }
071436c6 18313 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18314 {
18315 while (p < end)
18316 p = display_gnu_attribute (p,
f6f0e17b
NC
18317 display_proc_gnu_attribute,
18318 end);
60abdbed 18319 assert (p == end);
11c1ff18 18320 }
071436c6 18321 else if (p < end)
11c1ff18 18322 {
071436c6 18323 printf (_(" Unknown attribute:\n"));
f6f0e17b 18324 display_raw_attribute (p, end);
11c1ff18
PB
18325 p = end;
18326 }
071436c6
NC
18327 else
18328 attr_len = 0;
11c1ff18
PB
18329 }
18330 }
18331 }
d70c5fc7 18332
60bca95a 18333 free (contents);
11c1ff18 18334 }
32ec8896
NC
18335
18336 return res;
11c1ff18
PB
18337}
18338
ccb4c951
RS
18339/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18340 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18341 and return the VMA of the next entry, or -1 if there was a problem.
18342 Does not read from DATA_END or beyond. */
ccb4c951 18343
625d49fc
AM
18344static uint64_t
18345print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18346 unsigned char * data_end)
ccb4c951
RS
18347{
18348 printf (" ");
18349 print_vma (addr, LONG_HEX);
18350 printf (" ");
18351 if (addr < pltgot + 0xfff0)
18352 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18353 else
18354 printf ("%10s", "");
18355 printf (" ");
18356 if (data == NULL)
2b692964 18357 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18358 else
18359 {
625d49fc 18360 uint64_t entry;
82b1b41b 18361 unsigned char * from = data + addr - pltgot;
ccb4c951 18362
82b1b41b
NC
18363 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18364 {
18365 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18366 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18367 return (uint64_t) -1;
82b1b41b
NC
18368 }
18369 else
18370 {
18371 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18372 print_vma (entry, LONG_HEX);
18373 }
ccb4c951
RS
18374 }
18375 return addr + (is_32bit_elf ? 4 : 8);
18376}
18377
861fb55a
DJ
18378/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18379 PLTGOT. Print the Address and Initial fields of an entry at VMA
18380 ADDR and return the VMA of the next entry. */
18381
625d49fc
AM
18382static uint64_t
18383print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18384{
18385 printf (" ");
18386 print_vma (addr, LONG_HEX);
18387 printf (" ");
18388 if (data == NULL)
2b692964 18389 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18390 else
18391 {
625d49fc 18392 uint64_t entry;
861fb55a
DJ
18393
18394 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18395 print_vma (entry, LONG_HEX);
18396 }
18397 return addr + (is_32bit_elf ? 4 : 8);
18398}
18399
351cdf24
MF
18400static void
18401print_mips_ases (unsigned int mask)
18402{
18403 if (mask & AFL_ASE_DSP)
18404 fputs ("\n\tDSP ASE", stdout);
18405 if (mask & AFL_ASE_DSPR2)
18406 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18407 if (mask & AFL_ASE_DSPR3)
18408 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18409 if (mask & AFL_ASE_EVA)
18410 fputs ("\n\tEnhanced VA Scheme", stdout);
18411 if (mask & AFL_ASE_MCU)
18412 fputs ("\n\tMCU (MicroController) ASE", stdout);
18413 if (mask & AFL_ASE_MDMX)
18414 fputs ("\n\tMDMX ASE", stdout);
18415 if (mask & AFL_ASE_MIPS3D)
18416 fputs ("\n\tMIPS-3D ASE", stdout);
18417 if (mask & AFL_ASE_MT)
18418 fputs ("\n\tMT ASE", stdout);
18419 if (mask & AFL_ASE_SMARTMIPS)
18420 fputs ("\n\tSmartMIPS ASE", stdout);
18421 if (mask & AFL_ASE_VIRT)
18422 fputs ("\n\tVZ ASE", stdout);
18423 if (mask & AFL_ASE_MSA)
18424 fputs ("\n\tMSA ASE", stdout);
18425 if (mask & AFL_ASE_MIPS16)
18426 fputs ("\n\tMIPS16 ASE", stdout);
18427 if (mask & AFL_ASE_MICROMIPS)
18428 fputs ("\n\tMICROMIPS ASE", stdout);
18429 if (mask & AFL_ASE_XPA)
18430 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18431 if (mask & AFL_ASE_MIPS16E2)
18432 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18433 if (mask & AFL_ASE_CRC)
18434 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18435 if (mask & AFL_ASE_GINV)
18436 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18437 if (mask & AFL_ASE_LOONGSON_MMI)
18438 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18439 if (mask & AFL_ASE_LOONGSON_CAM)
18440 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18441 if (mask & AFL_ASE_LOONGSON_EXT)
18442 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18443 if (mask & AFL_ASE_LOONGSON_EXT2)
18444 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18445 if (mask == 0)
18446 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18447 else if ((mask & ~AFL_ASE_MASK) != 0)
18448 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18449}
18450
18451static void
18452print_mips_isa_ext (unsigned int isa_ext)
18453{
18454 switch (isa_ext)
18455 {
18456 case 0:
18457 fputs (_("None"), stdout);
18458 break;
18459 case AFL_EXT_XLR:
18460 fputs ("RMI XLR", stdout);
18461 break;
2c629856
N
18462 case AFL_EXT_OCTEON3:
18463 fputs ("Cavium Networks Octeon3", stdout);
18464 break;
351cdf24
MF
18465 case AFL_EXT_OCTEON2:
18466 fputs ("Cavium Networks Octeon2", stdout);
18467 break;
18468 case AFL_EXT_OCTEONP:
18469 fputs ("Cavium Networks OcteonP", stdout);
18470 break;
351cdf24
MF
18471 case AFL_EXT_OCTEON:
18472 fputs ("Cavium Networks Octeon", stdout);
18473 break;
18474 case AFL_EXT_5900:
18475 fputs ("Toshiba R5900", stdout);
18476 break;
18477 case AFL_EXT_4650:
18478 fputs ("MIPS R4650", stdout);
18479 break;
18480 case AFL_EXT_4010:
18481 fputs ("LSI R4010", stdout);
18482 break;
18483 case AFL_EXT_4100:
18484 fputs ("NEC VR4100", stdout);
18485 break;
18486 case AFL_EXT_3900:
18487 fputs ("Toshiba R3900", stdout);
18488 break;
18489 case AFL_EXT_10000:
18490 fputs ("MIPS R10000", stdout);
18491 break;
18492 case AFL_EXT_SB1:
18493 fputs ("Broadcom SB-1", stdout);
18494 break;
18495 case AFL_EXT_4111:
18496 fputs ("NEC VR4111/VR4181", stdout);
18497 break;
18498 case AFL_EXT_4120:
18499 fputs ("NEC VR4120", stdout);
18500 break;
18501 case AFL_EXT_5400:
18502 fputs ("NEC VR5400", stdout);
18503 break;
18504 case AFL_EXT_5500:
18505 fputs ("NEC VR5500", stdout);
18506 break;
18507 case AFL_EXT_LOONGSON_2E:
18508 fputs ("ST Microelectronics Loongson 2E", stdout);
18509 break;
18510 case AFL_EXT_LOONGSON_2F:
18511 fputs ("ST Microelectronics Loongson 2F", stdout);
18512 break;
38bf472a
MR
18513 case AFL_EXT_INTERAPTIV_MR2:
18514 fputs ("Imagination interAptiv MR2", stdout);
18515 break;
351cdf24 18516 default:
00ac7aa0 18517 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18518 }
18519}
18520
32ec8896 18521static signed int
351cdf24
MF
18522get_mips_reg_size (int reg_size)
18523{
18524 return (reg_size == AFL_REG_NONE) ? 0
18525 : (reg_size == AFL_REG_32) ? 32
18526 : (reg_size == AFL_REG_64) ? 64
18527 : (reg_size == AFL_REG_128) ? 128
18528 : -1;
18529}
18530
015dc7e1 18531static bool
dda8d76d 18532process_mips_specific (Filedata * filedata)
5b18a4bc 18533{
2cf0635d 18534 Elf_Internal_Dyn * entry;
351cdf24 18535 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18536 size_t liblist_offset = 0;
18537 size_t liblistno = 0;
18538 size_t conflictsno = 0;
18539 size_t options_offset = 0;
18540 size_t conflicts_offset = 0;
861fb55a
DJ
18541 size_t pltrelsz = 0;
18542 size_t pltrel = 0;
625d49fc
AM
18543 uint64_t pltgot = 0;
18544 uint64_t mips_pltgot = 0;
18545 uint64_t jmprel = 0;
18546 uint64_t local_gotno = 0;
18547 uint64_t gotsym = 0;
18548 uint64_t symtabno = 0;
015dc7e1 18549 bool res = true;
103f02d3 18550
dda8d76d 18551 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18552 display_mips_gnu_attribute))
015dc7e1 18553 res = false;
2cf19d5c 18554
dda8d76d 18555 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18556
18557 if (sect != NULL)
18558 {
18559 Elf_External_ABIFlags_v0 *abiflags_ext;
18560 Elf_Internal_ABIFlags_v0 abiflags_in;
18561
18562 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18563 {
18564 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18565 res = false;
32ec8896 18566 }
351cdf24
MF
18567 else
18568 {
dda8d76d 18569 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18570 sect->sh_size, _("MIPS ABI Flags section"));
18571 if (abiflags_ext)
18572 {
18573 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18574 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18575 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18576 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18577 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18578 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18579 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18580 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18581 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18582 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18583 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18584
18585 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18586 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18587 if (abiflags_in.isa_rev > 1)
18588 printf ("r%d", abiflags_in.isa_rev);
18589 printf ("\nGPR size: %d",
18590 get_mips_reg_size (abiflags_in.gpr_size));
18591 printf ("\nCPR1 size: %d",
18592 get_mips_reg_size (abiflags_in.cpr1_size));
18593 printf ("\nCPR2 size: %d",
18594 get_mips_reg_size (abiflags_in.cpr2_size));
18595 fputs ("\nFP ABI: ", stdout);
18596 print_mips_fp_abi_value (abiflags_in.fp_abi);
18597 fputs ("ISA Extension: ", stdout);
18598 print_mips_isa_ext (abiflags_in.isa_ext);
18599 fputs ("\nASEs:", stdout);
18600 print_mips_ases (abiflags_in.ases);
18601 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18602 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18603 fputc ('\n', stdout);
18604 free (abiflags_ext);
18605 }
18606 }
18607 }
18608
19e6b90e 18609 /* We have a lot of special sections. Thanks SGI! */
978c4450 18610 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18611 {
18612 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18613 sect = find_section (filedata, ".got");
bbdd9a68
MR
18614 if (sect != NULL)
18615 {
18616 unsigned char *data_end;
18617 unsigned char *data;
625d49fc 18618 uint64_t ent, end;
bbdd9a68
MR
18619 int addr_size;
18620
18621 pltgot = sect->sh_addr;
18622
18623 ent = pltgot;
18624 addr_size = (is_32bit_elf ? 4 : 8);
18625 end = pltgot + sect->sh_size;
18626
dda8d76d 18627 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18628 end - pltgot, 1,
18629 _("Global Offset Table data"));
18630 /* PR 12855: Null data is handled gracefully throughout. */
18631 data_end = data + (end - pltgot);
18632
18633 printf (_("\nStatic GOT:\n"));
18634 printf (_(" Canonical gp value: "));
18635 print_vma (ent + 0x7ff0, LONG_HEX);
18636 printf ("\n\n");
18637
18638 /* In a dynamic binary GOT[0] is reserved for the dynamic
18639 loader to store the lazy resolver pointer, however in
18640 a static binary it may well have been omitted and GOT
18641 reduced to a table of addresses.
18642 PR 21344: Check for the entry being fully available
18643 before fetching it. */
18644 if (data
18645 && data + ent - pltgot + addr_size <= data_end
18646 && byte_get (data + ent - pltgot, addr_size) == 0)
18647 {
18648 printf (_(" Reserved entries:\n"));
18649 printf (_(" %*s %10s %*s\n"),
18650 addr_size * 2, _("Address"), _("Access"),
18651 addr_size * 2, _("Value"));
18652 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18653 printf ("\n");
625d49fc 18654 if (ent == (uint64_t) -1)
bbdd9a68
MR
18655 goto sgot_print_fail;
18656
18657 /* Check for the MSB of GOT[1] being set, identifying a
18658 GNU object. This entry will be used by some runtime
18659 loaders, to store the module pointer. Otherwise this
18660 is an ordinary local entry.
18661 PR 21344: Check for the entry being fully available
18662 before fetching it. */
18663 if (data
18664 && data + ent - pltgot + addr_size <= data_end
18665 && (byte_get (data + ent - pltgot, addr_size)
18666 >> (addr_size * 8 - 1)) != 0)
18667 {
18668 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18669 printf ("\n");
625d49fc 18670 if (ent == (uint64_t) -1)
bbdd9a68
MR
18671 goto sgot_print_fail;
18672 }
18673 printf ("\n");
18674 }
18675
f17e9d8a 18676 if (data != NULL && ent < end)
bbdd9a68
MR
18677 {
18678 printf (_(" Local entries:\n"));
18679 printf (" %*s %10s %*s\n",
18680 addr_size * 2, _("Address"), _("Access"),
18681 addr_size * 2, _("Value"));
18682 while (ent < end)
18683 {
18684 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18685 printf ("\n");
625d49fc 18686 if (ent == (uint64_t) -1)
bbdd9a68
MR
18687 goto sgot_print_fail;
18688 }
18689 printf ("\n");
18690 }
18691
18692 sgot_print_fail:
9db70fc3 18693 free (data);
bbdd9a68
MR
18694 }
18695 return res;
18696 }
252b5132 18697
978c4450 18698 for (entry = filedata->dynamic_section;
071436c6 18699 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18700 (entry < filedata->dynamic_section + filedata->dynamic_nent
18701 && entry->d_tag != DT_NULL);
071436c6 18702 ++entry)
252b5132
RH
18703 switch (entry->d_tag)
18704 {
18705 case DT_MIPS_LIBLIST:
d93f0186 18706 liblist_offset
dda8d76d 18707 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18708 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18709 break;
18710 case DT_MIPS_LIBLISTNO:
18711 liblistno = entry->d_un.d_val;
18712 break;
18713 case DT_MIPS_OPTIONS:
dda8d76d 18714 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18715 break;
18716 case DT_MIPS_CONFLICT:
d93f0186 18717 conflicts_offset
dda8d76d 18718 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18719 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18720 break;
18721 case DT_MIPS_CONFLICTNO:
18722 conflictsno = entry->d_un.d_val;
18723 break;
ccb4c951 18724 case DT_PLTGOT:
861fb55a
DJ
18725 pltgot = entry->d_un.d_ptr;
18726 break;
ccb4c951
RS
18727 case DT_MIPS_LOCAL_GOTNO:
18728 local_gotno = entry->d_un.d_val;
18729 break;
18730 case DT_MIPS_GOTSYM:
18731 gotsym = entry->d_un.d_val;
18732 break;
18733 case DT_MIPS_SYMTABNO:
18734 symtabno = entry->d_un.d_val;
18735 break;
861fb55a
DJ
18736 case DT_MIPS_PLTGOT:
18737 mips_pltgot = entry->d_un.d_ptr;
18738 break;
18739 case DT_PLTREL:
18740 pltrel = entry->d_un.d_val;
18741 break;
18742 case DT_PLTRELSZ:
18743 pltrelsz = entry->d_un.d_val;
18744 break;
18745 case DT_JMPREL:
18746 jmprel = entry->d_un.d_ptr;
18747 break;
252b5132
RH
18748 default:
18749 break;
18750 }
18751
18752 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18753 {
2cf0635d 18754 Elf32_External_Lib * elib;
252b5132
RH
18755 size_t cnt;
18756
dda8d76d 18757 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18758 sizeof (Elf32_External_Lib),
18759 liblistno,
18760 _("liblist section data"));
a6e9f9df 18761 if (elib)
252b5132 18762 {
26c527e6
AM
18763 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
18764 "\nSection '.liblist' contains %zu entries:\n",
18765 liblistno),
18766 liblistno);
2b692964 18767 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18768 stdout);
18769
18770 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18771 {
a6e9f9df 18772 Elf32_Lib liblist;
91d6fa6a 18773 time_t atime;
d5b07ef4 18774 char timebuf[128];
2cf0635d 18775 struct tm * tmp;
a6e9f9df
AM
18776
18777 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18778 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18779 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18780 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18781 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18782
91d6fa6a 18783 tmp = gmtime (&atime);
e9e44622
JJ
18784 snprintf (timebuf, sizeof (timebuf),
18785 "%04u-%02u-%02uT%02u:%02u:%02u",
18786 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18787 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18788
26c527e6 18789 printf ("%3zu: ", cnt);
84714f86
AM
18790 if (valid_dynamic_name (filedata, liblist.l_name))
18791 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18792 else
2b692964 18793 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18794 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18795 liblist.l_version);
a6e9f9df
AM
18796
18797 if (liblist.l_flags == 0)
2b692964 18798 puts (_(" NONE"));
a6e9f9df
AM
18799 else
18800 {
18801 static const struct
252b5132 18802 {
2cf0635d 18803 const char * name;
a6e9f9df 18804 int bit;
252b5132 18805 }
a6e9f9df
AM
18806 l_flags_vals[] =
18807 {
18808 { " EXACT_MATCH", LL_EXACT_MATCH },
18809 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18810 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18811 { " EXPORTS", LL_EXPORTS },
18812 { " DELAY_LOAD", LL_DELAY_LOAD },
18813 { " DELTA", LL_DELTA }
18814 };
18815 int flags = liblist.l_flags;
18816 size_t fcnt;
18817
60bca95a 18818 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18819 if ((flags & l_flags_vals[fcnt].bit) != 0)
18820 {
18821 fputs (l_flags_vals[fcnt].name, stdout);
18822 flags ^= l_flags_vals[fcnt].bit;
18823 }
18824 if (flags != 0)
18825 printf (" %#x", (unsigned int) flags);
252b5132 18826
a6e9f9df
AM
18827 puts ("");
18828 }
252b5132 18829 }
252b5132 18830
a6e9f9df
AM
18831 free (elib);
18832 }
32ec8896 18833 else
015dc7e1 18834 res = false;
252b5132
RH
18835 }
18836
18837 if (options_offset != 0)
18838 {
2cf0635d 18839 Elf_External_Options * eopt;
252b5132
RH
18840 size_t offset;
18841 int cnt;
18842
18843 /* Find the section header so that we get the size. */
dda8d76d 18844 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18845 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18846 if (sect == NULL)
18847 {
18848 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18849 return false;
071436c6 18850 }
7fc0c668
NC
18851 /* PR 24243 */
18852 if (sect->sh_size < sizeof (* eopt))
18853 {
18854 error (_("The MIPS options section is too small.\n"));
015dc7e1 18855 return false;
7fc0c668 18856 }
252b5132 18857
dda8d76d 18858 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18859 sect->sh_size, _("options"));
a6e9f9df 18860 if (eopt)
252b5132 18861 {
fd17d1e6 18862 Elf_Internal_Options option;
76da6bbe 18863
a6e9f9df 18864 offset = cnt = 0;
82b1b41b 18865 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18866 {
2cf0635d 18867 Elf_External_Options * eoption;
fd17d1e6 18868 unsigned int optsize;
252b5132 18869
a6e9f9df 18870 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18871
fd17d1e6 18872 optsize = BYTE_GET (eoption->size);
76da6bbe 18873
82b1b41b 18874 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18875 if (optsize < sizeof (* eopt)
18876 || optsize > sect->sh_size - offset)
82b1b41b 18877 {
645f43a8 18878 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18879 optsize);
645f43a8 18880 free (eopt);
015dc7e1 18881 return false;
82b1b41b 18882 }
fd17d1e6 18883 offset += optsize;
a6e9f9df
AM
18884 ++cnt;
18885 }
252b5132 18886
d3a49aa8
AM
18887 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18888 "\nSection '%s' contains %d entries:\n",
18889 cnt),
dda8d76d 18890 printable_section_name (filedata, sect), cnt);
76da6bbe 18891
82b1b41b 18892 offset = 0;
a6e9f9df 18893 while (cnt-- > 0)
252b5132 18894 {
a6e9f9df 18895 size_t len;
fd17d1e6
AM
18896 Elf_External_Options * eoption;
18897
18898 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18899
18900 option.kind = BYTE_GET (eoption->kind);
18901 option.size = BYTE_GET (eoption->size);
18902 option.section = BYTE_GET (eoption->section);
18903 option.info = BYTE_GET (eoption->info);
a6e9f9df 18904
fd17d1e6 18905 switch (option.kind)
252b5132 18906 {
a6e9f9df
AM
18907 case ODK_NULL:
18908 /* This shouldn't happen. */
d0c4e780 18909 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18910 option.section, option.info);
a6e9f9df 18911 break;
2e6be59c 18912
a6e9f9df
AM
18913 case ODK_REGINFO:
18914 printf (" REGINFO ");
dda8d76d 18915 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18916 {
2cf0635d 18917 Elf32_External_RegInfo * ereg;
b34976b6 18918 Elf32_RegInfo reginfo;
a6e9f9df 18919
2e6be59c 18920 /* 32bit form. */
fd17d1e6
AM
18921 if (option.size < (sizeof (Elf_External_Options)
18922 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18923 {
18924 printf (_("<corrupt>\n"));
18925 error (_("Truncated MIPS REGINFO option\n"));
18926 cnt = 0;
18927 break;
18928 }
18929
fd17d1e6 18930 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18931
a6e9f9df
AM
18932 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18933 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18934 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18935 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18936 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18937 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18938
d0c4e780
AM
18939 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18940 reginfo.ri_gprmask, reginfo.ri_gp_value);
18941 printf (" "
18942 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18943 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18944 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18945 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18946 }
18947 else
18948 {
18949 /* 64 bit form. */
2cf0635d 18950 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18951 Elf64_Internal_RegInfo reginfo;
18952
fd17d1e6
AM
18953 if (option.size < (sizeof (Elf_External_Options)
18954 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18955 {
18956 printf (_("<corrupt>\n"));
18957 error (_("Truncated MIPS REGINFO option\n"));
18958 cnt = 0;
18959 break;
18960 }
18961
fd17d1e6 18962 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18963 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18964 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18965 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18966 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18967 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18968 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18969
d0c4e780
AM
18970 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18971 reginfo.ri_gprmask, reginfo.ri_gp_value);
18972 printf (" "
18973 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18974 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18975 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18976 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18977 }
fd17d1e6 18978 offset += option.size;
a6e9f9df 18979 continue;
2e6be59c 18980
a6e9f9df
AM
18981 case ODK_EXCEPTIONS:
18982 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18983 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18984 fputs (") fpe_max(", stdout);
fd17d1e6 18985 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18986 fputs (")", stdout);
18987
fd17d1e6 18988 if (option.info & OEX_PAGE0)
a6e9f9df 18989 fputs (" PAGE0", stdout);
fd17d1e6 18990 if (option.info & OEX_SMM)
a6e9f9df 18991 fputs (" SMM", stdout);
fd17d1e6 18992 if (option.info & OEX_FPDBUG)
a6e9f9df 18993 fputs (" FPDBUG", stdout);
fd17d1e6 18994 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18995 fputs (" DISMISS", stdout);
18996 break;
2e6be59c 18997
a6e9f9df
AM
18998 case ODK_PAD:
18999 fputs (" PAD ", stdout);
fd17d1e6 19000 if (option.info & OPAD_PREFIX)
a6e9f9df 19001 fputs (" PREFIX", stdout);
fd17d1e6 19002 if (option.info & OPAD_POSTFIX)
a6e9f9df 19003 fputs (" POSTFIX", stdout);
fd17d1e6 19004 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
19005 fputs (" SYMBOL", stdout);
19006 break;
2e6be59c 19007
a6e9f9df
AM
19008 case ODK_HWPATCH:
19009 fputs (" HWPATCH ", stdout);
fd17d1e6 19010 if (option.info & OHW_R4KEOP)
a6e9f9df 19011 fputs (" R4KEOP", stdout);
fd17d1e6 19012 if (option.info & OHW_R8KPFETCH)
a6e9f9df 19013 fputs (" R8KPFETCH", stdout);
fd17d1e6 19014 if (option.info & OHW_R5KEOP)
a6e9f9df 19015 fputs (" R5KEOP", stdout);
fd17d1e6 19016 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
19017 fputs (" R5KCVTL", stdout);
19018 break;
2e6be59c 19019
a6e9f9df
AM
19020 case ODK_FILL:
19021 fputs (" FILL ", stdout);
19022 /* XXX Print content of info word? */
19023 break;
2e6be59c 19024
a6e9f9df
AM
19025 case ODK_TAGS:
19026 fputs (" TAGS ", stdout);
19027 /* XXX Print content of info word? */
19028 break;
2e6be59c 19029
a6e9f9df
AM
19030 case ODK_HWAND:
19031 fputs (" HWAND ", stdout);
fd17d1e6 19032 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19033 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19034 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19035 fputs (" R4KEOP_CLEAN", stdout);
19036 break;
2e6be59c 19037
a6e9f9df
AM
19038 case ODK_HWOR:
19039 fputs (" HWOR ", stdout);
fd17d1e6 19040 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19041 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19042 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19043 fputs (" R4KEOP_CLEAN", stdout);
19044 break;
2e6be59c 19045
a6e9f9df 19046 case ODK_GP_GROUP:
d0c4e780 19047 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
19048 option.info & OGP_GROUP,
19049 (option.info & OGP_SELF) >> 16);
a6e9f9df 19050 break;
2e6be59c 19051
a6e9f9df 19052 case ODK_IDENT:
d0c4e780 19053 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
19054 option.info & OGP_GROUP,
19055 (option.info & OGP_SELF) >> 16);
a6e9f9df 19056 break;
2e6be59c 19057
a6e9f9df
AM
19058 default:
19059 /* This shouldn't happen. */
d0c4e780 19060 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 19061 option.kind, option.section, option.info);
a6e9f9df 19062 break;
252b5132 19063 }
a6e9f9df 19064
2cf0635d 19065 len = sizeof (* eopt);
fd17d1e6 19066 while (len < option.size)
82b1b41b 19067 {
fd17d1e6 19068 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 19069
82b1b41b
NC
19070 if (ISPRINT (datum))
19071 printf ("%c", datum);
19072 else
19073 printf ("\\%03o", datum);
19074 len ++;
19075 }
a6e9f9df 19076 fputs ("\n", stdout);
82b1b41b 19077
fd17d1e6 19078 offset += option.size;
252b5132 19079 }
a6e9f9df 19080 free (eopt);
252b5132 19081 }
32ec8896 19082 else
015dc7e1 19083 res = false;
252b5132
RH
19084 }
19085
19086 if (conflicts_offset != 0 && conflictsno != 0)
19087 {
2cf0635d 19088 Elf32_Conflict * iconf;
252b5132
RH
19089 size_t cnt;
19090
978c4450 19091 if (filedata->dynamic_symbols == NULL)
252b5132 19092 {
591a748a 19093 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 19094 return false;
252b5132
RH
19095 }
19096
7296a62a
NC
19097 /* PR 21345 - print a slightly more helpful error message
19098 if we are sure that the cmalloc will fail. */
645f43a8 19099 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 19100 {
26c527e6
AM
19101 error (_("Overlarge number of conflicts detected: %zx\n"),
19102 conflictsno);
015dc7e1 19103 return false;
7296a62a
NC
19104 }
19105
3f5e193b 19106 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
19107 if (iconf == NULL)
19108 {
8b73c356 19109 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 19110 return false;
252b5132
RH
19111 }
19112
9ea033b2 19113 if (is_32bit_elf)
252b5132 19114 {
2cf0635d 19115 Elf32_External_Conflict * econf32;
a6e9f9df 19116
3f5e193b 19117 econf32 = (Elf32_External_Conflict *)
95099889
AM
19118 get_data (NULL, filedata, conflicts_offset,
19119 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 19120 if (!econf32)
5a814d6d
AM
19121 {
19122 free (iconf);
015dc7e1 19123 return false;
5a814d6d 19124 }
252b5132
RH
19125
19126 for (cnt = 0; cnt < conflictsno; ++cnt)
19127 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
19128
19129 free (econf32);
252b5132
RH
19130 }
19131 else
19132 {
2cf0635d 19133 Elf64_External_Conflict * econf64;
a6e9f9df 19134
3f5e193b 19135 econf64 = (Elf64_External_Conflict *)
95099889
AM
19136 get_data (NULL, filedata, conflicts_offset,
19137 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 19138 if (!econf64)
5a814d6d
AM
19139 {
19140 free (iconf);
015dc7e1 19141 return false;
5a814d6d 19142 }
252b5132
RH
19143
19144 for (cnt = 0; cnt < conflictsno; ++cnt)
19145 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
19146
19147 free (econf64);
252b5132
RH
19148 }
19149
26c527e6
AM
19150 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19151 "\nSection '.conflict' contains %zu entries:\n",
19152 conflictsno),
19153 conflictsno);
252b5132
RH
19154 puts (_(" Num: Index Value Name"));
19155
19156 for (cnt = 0; cnt < conflictsno; ++cnt)
19157 {
26c527e6 19158 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 19159
978c4450 19160 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 19161 printf (_("<corrupt symbol index>"));
d79b3d50 19162 else
e0a31db1
NC
19163 {
19164 Elf_Internal_Sym * psym;
19165
978c4450 19166 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
19167 print_vma (psym->st_value, FULL_HEX);
19168 putchar (' ');
84714f86
AM
19169 if (valid_dynamic_name (filedata, psym->st_name))
19170 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19171 else
19172 printf (_("<corrupt: %14ld>"), psym->st_name);
19173 }
31104126 19174 putchar ('\n');
252b5132
RH
19175 }
19176
252b5132
RH
19177 free (iconf);
19178 }
19179
ccb4c951
RS
19180 if (pltgot != 0 && local_gotno != 0)
19181 {
625d49fc 19182 uint64_t ent, local_end, global_end;
bbeee7ea 19183 size_t i, offset;
2cf0635d 19184 unsigned char * data;
82b1b41b 19185 unsigned char * data_end;
bbeee7ea 19186 int addr_size;
ccb4c951 19187
91d6fa6a 19188 ent = pltgot;
ccb4c951
RS
19189 addr_size = (is_32bit_elf ? 4 : 8);
19190 local_end = pltgot + local_gotno * addr_size;
ccb4c951 19191
74e1a04b
NC
19192 /* PR binutils/17533 file: 012-111227-0.004 */
19193 if (symtabno < gotsym)
19194 {
26c527e6
AM
19195 error (_("The GOT symbol offset (%" PRIu64
19196 ") is greater than the symbol table size (%" PRIu64 ")\n"),
19197 gotsym, symtabno);
015dc7e1 19198 return false;
74e1a04b 19199 }
82b1b41b 19200
74e1a04b 19201 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
19202 /* PR 17531: file: 54c91a34. */
19203 if (global_end < local_end)
19204 {
26c527e6 19205 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 19206 return false;
82b1b41b 19207 }
948f632f 19208
dda8d76d
NC
19209 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
19210 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
19211 global_end - pltgot, 1,
19212 _("Global Offset Table data"));
919383ac 19213 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 19214 data_end = data + (global_end - pltgot);
59245841 19215
ccb4c951
RS
19216 printf (_("\nPrimary GOT:\n"));
19217 printf (_(" Canonical gp value: "));
19218 print_vma (pltgot + 0x7ff0, LONG_HEX);
19219 printf ("\n\n");
19220
19221 printf (_(" Reserved entries:\n"));
19222 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
19223 addr_size * 2, _("Address"), _("Access"),
19224 addr_size * 2, _("Initial"));
82b1b41b 19225 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 19226 printf (_(" Lazy resolver\n"));
625d49fc 19227 if (ent == (uint64_t) -1)
82b1b41b 19228 goto got_print_fail;
75ec1fdb 19229
c4ab9505
MR
19230 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19231 This entry will be used by some runtime loaders, to store the
19232 module pointer. Otherwise this is an ordinary local entry.
19233 PR 21344: Check for the entry being fully available before
19234 fetching it. */
19235 if (data
19236 && data + ent - pltgot + addr_size <= data_end
19237 && (byte_get (data + ent - pltgot, addr_size)
19238 >> (addr_size * 8 - 1)) != 0)
19239 {
19240 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19241 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 19242 if (ent == (uint64_t) -1)
c4ab9505 19243 goto got_print_fail;
ccb4c951
RS
19244 }
19245 printf ("\n");
19246
f17e9d8a 19247 if (data != NULL && ent < local_end)
ccb4c951
RS
19248 {
19249 printf (_(" Local entries:\n"));
cc5914eb 19250 printf (" %*s %10s %*s\n",
2b692964
NC
19251 addr_size * 2, _("Address"), _("Access"),
19252 addr_size * 2, _("Initial"));
91d6fa6a 19253 while (ent < local_end)
ccb4c951 19254 {
82b1b41b 19255 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19256 printf ("\n");
625d49fc 19257 if (ent == (uint64_t) -1)
82b1b41b 19258 goto got_print_fail;
ccb4c951
RS
19259 }
19260 printf ("\n");
19261 }
19262
f17e9d8a 19263 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19264 {
19265 int sym_width;
19266
19267 printf (_(" Global entries:\n"));
cc5914eb 19268 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19269 addr_size * 2, _("Address"),
19270 _("Access"),
2b692964 19271 addr_size * 2, _("Initial"),
9cf03b7e
NC
19272 addr_size * 2, _("Sym.Val."),
19273 _("Type"),
19274 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19275 _("Ndx"), _("Name"));
0b4362b0 19276
ccb4c951 19277 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19278
ccb4c951
RS
19279 for (i = gotsym; i < symtabno; i++)
19280 {
82b1b41b 19281 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19282 printf (" ");
e0a31db1 19283
978c4450 19284 if (filedata->dynamic_symbols == NULL)
e0a31db1 19285 printf (_("<no dynamic symbols>"));
978c4450 19286 else if (i < filedata->num_dynamic_syms)
e0a31db1 19287 {
978c4450 19288 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19289
19290 print_vma (psym->st_value, LONG_HEX);
19291 printf (" %-7s %3s ",
dda8d76d
NC
19292 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19293 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19294
84714f86 19295 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19296 print_symbol (sym_width,
84714f86 19297 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19298 else
19299 printf (_("<corrupt: %14ld>"), psym->st_name);
19300 }
ccb4c951 19301 else
26c527e6
AM
19302 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
19303 i);
e0a31db1 19304
ccb4c951 19305 printf ("\n");
625d49fc 19306 if (ent == (uint64_t) -1)
82b1b41b 19307 break;
ccb4c951
RS
19308 }
19309 printf ("\n");
19310 }
19311
82b1b41b 19312 got_print_fail:
9db70fc3 19313 free (data);
ccb4c951
RS
19314 }
19315
861fb55a
DJ
19316 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19317 {
625d49fc 19318 uint64_t ent, end;
26c527e6
AM
19319 uint64_t offset, rel_offset;
19320 uint64_t count, i;
2cf0635d 19321 unsigned char * data;
861fb55a 19322 int addr_size, sym_width;
2cf0635d 19323 Elf_Internal_Rela * rels;
861fb55a 19324
dda8d76d 19325 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19326 if (pltrel == DT_RELA)
19327 {
dda8d76d 19328 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19329 return false;
861fb55a
DJ
19330 }
19331 else
19332 {
dda8d76d 19333 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19334 return false;
861fb55a
DJ
19335 }
19336
91d6fa6a 19337 ent = mips_pltgot;
861fb55a
DJ
19338 addr_size = (is_32bit_elf ? 4 : 8);
19339 end = mips_pltgot + (2 + count) * addr_size;
19340
dda8d76d
NC
19341 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19342 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19343 1, _("Procedure Linkage Table data"));
59245841 19344 if (data == NULL)
288f0ba2
AM
19345 {
19346 free (rels);
015dc7e1 19347 return false;
288f0ba2 19348 }
59245841 19349
9cf03b7e 19350 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19351 printf (_(" Reserved entries:\n"));
19352 printf (_(" %*s %*s Purpose\n"),
2b692964 19353 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19354 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19355 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19356 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19357 printf (_(" Module pointer\n"));
861fb55a
DJ
19358 printf ("\n");
19359
19360 printf (_(" Entries:\n"));
cc5914eb 19361 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19362 addr_size * 2, _("Address"),
19363 addr_size * 2, _("Initial"),
19364 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19365 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19366 for (i = 0; i < count; i++)
19367 {
26c527e6 19368 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19369
91d6fa6a 19370 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19371 printf (" ");
e0a31db1 19372
978c4450 19373 if (idx >= filedata->num_dynamic_syms)
26c527e6 19374 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 19375 else
e0a31db1 19376 {
978c4450 19377 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19378
19379 print_vma (psym->st_value, LONG_HEX);
19380 printf (" %-7s %3s ",
dda8d76d
NC
19381 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19382 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19383 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19384 print_symbol (sym_width,
84714f86 19385 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19386 else
19387 printf (_("<corrupt: %14ld>"), psym->st_name);
19388 }
861fb55a
DJ
19389 printf ("\n");
19390 }
19391 printf ("\n");
19392
9db70fc3 19393 free (data);
861fb55a
DJ
19394 free (rels);
19395 }
19396
32ec8896 19397 return res;
252b5132
RH
19398}
19399
015dc7e1 19400static bool
dda8d76d 19401process_nds32_specific (Filedata * filedata)
35c08157
KLC
19402{
19403 Elf_Internal_Shdr *sect = NULL;
19404
dda8d76d 19405 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19406 if (sect != NULL && sect->sh_size >= 4)
35c08157 19407 {
9c7b8e9b
AM
19408 unsigned char *buf;
19409 unsigned int flag;
35c08157
KLC
19410
19411 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19412 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19413 _("NDS32 elf flags section"));
35c08157 19414
9c7b8e9b 19415 if (buf == NULL)
015dc7e1 19416 return false;
32ec8896 19417
9c7b8e9b
AM
19418 flag = byte_get (buf, 4);
19419 free (buf);
19420 switch (flag & 0x3)
35c08157
KLC
19421 {
19422 case 0:
19423 printf ("(VEC_SIZE):\tNo entry.\n");
19424 break;
19425 case 1:
19426 printf ("(VEC_SIZE):\t4 bytes\n");
19427 break;
19428 case 2:
19429 printf ("(VEC_SIZE):\t16 bytes\n");
19430 break;
19431 case 3:
19432 printf ("(VEC_SIZE):\treserved\n");
19433 break;
19434 }
19435 }
19436
015dc7e1 19437 return true;
35c08157
KLC
19438}
19439
015dc7e1 19440static bool
dda8d76d 19441process_gnu_liblist (Filedata * filedata)
047b2264 19442{
2cf0635d
NC
19443 Elf_Internal_Shdr * section;
19444 Elf_Internal_Shdr * string_sec;
19445 Elf32_External_Lib * elib;
19446 char * strtab;
c256ffe7 19447 size_t strtab_size;
047b2264 19448 size_t cnt;
26c527e6 19449 uint64_t num_liblist;
047b2264 19450 unsigned i;
015dc7e1 19451 bool res = true;
047b2264
JJ
19452
19453 if (! do_arch)
015dc7e1 19454 return true;
047b2264 19455
dda8d76d
NC
19456 for (i = 0, section = filedata->section_headers;
19457 i < filedata->file_header.e_shnum;
b34976b6 19458 i++, section++)
047b2264
JJ
19459 {
19460 switch (section->sh_type)
19461 {
19462 case SHT_GNU_LIBLIST:
dda8d76d 19463 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19464 break;
19465
3f5e193b 19466 elib = (Elf32_External_Lib *)
dda8d76d 19467 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19468 _("liblist section data"));
047b2264
JJ
19469
19470 if (elib == NULL)
32ec8896 19471 {
015dc7e1 19472 res = false;
32ec8896
NC
19473 break;
19474 }
047b2264 19475
dda8d76d
NC
19476 string_sec = filedata->section_headers + section->sh_link;
19477 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19478 string_sec->sh_size,
19479 _("liblist string table"));
047b2264
JJ
19480 if (strtab == NULL
19481 || section->sh_entsize != sizeof (Elf32_External_Lib))
19482 {
19483 free (elib);
2842702f 19484 free (strtab);
015dc7e1 19485 res = false;
047b2264
JJ
19486 break;
19487 }
59245841 19488 strtab_size = string_sec->sh_size;
047b2264 19489
d3a49aa8 19490 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
19491 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
19492 " entries:\n",
19493 "\nLibrary list section '%s' contains %" PRIu64
19494 " entries:\n",
d3a49aa8 19495 num_liblist),
dda8d76d 19496 printable_section_name (filedata, section),
d3a49aa8 19497 num_liblist);
047b2264 19498
2b692964 19499 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19500
19501 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19502 ++cnt)
19503 {
19504 Elf32_Lib liblist;
91d6fa6a 19505 time_t atime;
d5b07ef4 19506 char timebuf[128];
2cf0635d 19507 struct tm * tmp;
047b2264
JJ
19508
19509 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19510 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19511 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19512 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19513 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19514
91d6fa6a 19515 tmp = gmtime (&atime);
e9e44622
JJ
19516 snprintf (timebuf, sizeof (timebuf),
19517 "%04u-%02u-%02uT%02u:%02u:%02u",
19518 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19519 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 19520
26c527e6 19521 printf ("%3zu: ", cnt);
047b2264 19522 if (do_wide)
c256ffe7 19523 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19524 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19525 else
c256ffe7 19526 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19527 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19528 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19529 liblist.l_version, liblist.l_flags);
19530 }
19531
19532 free (elib);
2842702f 19533 free (strtab);
047b2264
JJ
19534 }
19535 }
19536
32ec8896 19537 return res;
047b2264
JJ
19538}
19539
9437c45b 19540static const char *
dda8d76d 19541get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19542{
19543 static char buff[64];
103f02d3 19544
dda8d76d 19545 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19546 switch (e_type)
19547 {
57346661 19548 case NT_AUXV:
1ec5cd37 19549 return _("NT_AUXV (auxiliary vector)");
57346661 19550 case NT_PRSTATUS:
1ec5cd37 19551 return _("NT_PRSTATUS (prstatus structure)");
57346661 19552 case NT_FPREGSET:
1ec5cd37 19553 return _("NT_FPREGSET (floating point registers)");
57346661 19554 case NT_PRPSINFO:
1ec5cd37 19555 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19556 case NT_TASKSTRUCT:
1ec5cd37 19557 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19558 case NT_GDB_TDESC:
19559 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19560 case NT_PRXFPREG:
1ec5cd37 19561 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19562 case NT_PPC_VMX:
19563 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19564 case NT_PPC_VSX:
19565 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19566 case NT_PPC_TAR:
19567 return _("NT_PPC_TAR (ppc TAR register)");
19568 case NT_PPC_PPR:
19569 return _("NT_PPC_PPR (ppc PPR register)");
19570 case NT_PPC_DSCR:
19571 return _("NT_PPC_DSCR (ppc DSCR register)");
19572 case NT_PPC_EBB:
19573 return _("NT_PPC_EBB (ppc EBB registers)");
19574 case NT_PPC_PMU:
19575 return _("NT_PPC_PMU (ppc PMU registers)");
19576 case NT_PPC_TM_CGPR:
19577 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19578 case NT_PPC_TM_CFPR:
19579 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19580 case NT_PPC_TM_CVMX:
19581 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19582 case NT_PPC_TM_CVSX:
3fd21718 19583 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19584 case NT_PPC_TM_SPR:
19585 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19586 case NT_PPC_TM_CTAR:
19587 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19588 case NT_PPC_TM_CPPR:
19589 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19590 case NT_PPC_TM_CDSCR:
19591 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19592 case NT_386_TLS:
19593 return _("NT_386_TLS (x86 TLS information)");
19594 case NT_386_IOPERM:
19595 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19596 case NT_X86_XSTATE:
19597 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19598 case NT_X86_CET:
19599 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19600 case NT_S390_HIGH_GPRS:
19601 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19602 case NT_S390_TIMER:
19603 return _("NT_S390_TIMER (s390 timer register)");
19604 case NT_S390_TODCMP:
19605 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19606 case NT_S390_TODPREG:
19607 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19608 case NT_S390_CTRS:
19609 return _("NT_S390_CTRS (s390 control registers)");
19610 case NT_S390_PREFIX:
19611 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19612 case NT_S390_LAST_BREAK:
19613 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19614 case NT_S390_SYSTEM_CALL:
19615 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19616 case NT_S390_TDB:
19617 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19618 case NT_S390_VXRS_LOW:
19619 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19620 case NT_S390_VXRS_HIGH:
19621 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19622 case NT_S390_GS_CB:
19623 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19624 case NT_S390_GS_BC:
19625 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19626 case NT_ARM_VFP:
19627 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19628 case NT_ARM_TLS:
19629 return _("NT_ARM_TLS (AArch TLS registers)");
19630 case NT_ARM_HW_BREAK:
19631 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19632 case NT_ARM_HW_WATCH:
19633 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
19634 case NT_ARM_SYSTEM_CALL:
19635 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
19636 case NT_ARM_SVE:
19637 return _("NT_ARM_SVE (AArch SVE registers)");
19638 case NT_ARM_PAC_MASK:
19639 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19640 case NT_ARM_PACA_KEYS:
19641 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19642 case NT_ARM_PACG_KEYS:
19643 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19644 case NT_ARM_TAGGED_ADDR_CTRL:
19645 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
a8f175d9
LM
19646 case NT_ARM_SSVE:
19647 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
19648 case NT_ARM_ZA:
19649 return _("NT_ARM_ZA (AArch64 SME ZA register)");
3af2785c
LM
19650 case NT_ARM_PAC_ENABLED_KEYS:
19651 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19652 case NT_ARC_V2:
19653 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19654 case NT_RISCV_CSR:
19655 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19656 case NT_PSTATUS:
1ec5cd37 19657 return _("NT_PSTATUS (pstatus structure)");
57346661 19658 case NT_FPREGS:
1ec5cd37 19659 return _("NT_FPREGS (floating point registers)");
57346661 19660 case NT_PSINFO:
1ec5cd37 19661 return _("NT_PSINFO (psinfo structure)");
57346661 19662 case NT_LWPSTATUS:
1ec5cd37 19663 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19664 case NT_LWPSINFO:
1ec5cd37 19665 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19666 case NT_WIN32PSTATUS:
1ec5cd37 19667 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19668 case NT_SIGINFO:
19669 return _("NT_SIGINFO (siginfo_t data)");
19670 case NT_FILE:
19671 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19672 default:
19673 break;
19674 }
19675 else
19676 switch (e_type)
19677 {
19678 case NT_VERSION:
19679 return _("NT_VERSION (version)");
19680 case NT_ARCH:
19681 return _("NT_ARCH (architecture)");
9ef920e9 19682 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19683 return _("OPEN");
9ef920e9 19684 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19685 return _("func");
c8795e1f
NC
19686 case NT_GO_BUILDID:
19687 return _("GO BUILDID");
3ac925fc
LB
19688 case FDO_PACKAGING_METADATA:
19689 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19690 default:
19691 break;
19692 }
19693
e9e44622 19694 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19695 return buff;
779fe533
NC
19696}
19697
015dc7e1 19698static bool
9ece1fa9
TT
19699print_core_note (Elf_Internal_Note *pnote)
19700{
19701 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 19702 uint64_t count, page_size;
9ece1fa9
TT
19703 unsigned char *descdata, *filenames, *descend;
19704
19705 if (pnote->type != NT_FILE)
04ac15ab
AS
19706 {
19707 if (do_wide)
19708 printf ("\n");
015dc7e1 19709 return true;
04ac15ab 19710 }
9ece1fa9 19711
9ece1fa9
TT
19712 if (!is_32bit_elf)
19713 {
19714 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19715 /* Still "successful". */
015dc7e1 19716 return true;
9ece1fa9 19717 }
9ece1fa9
TT
19718
19719 if (pnote->descsz < 2 * addr_size)
19720 {
32ec8896 19721 error (_(" Malformed note - too short for header\n"));
015dc7e1 19722 return false;
9ece1fa9
TT
19723 }
19724
19725 descdata = (unsigned char *) pnote->descdata;
19726 descend = descdata + pnote->descsz;
19727
19728 if (descdata[pnote->descsz - 1] != '\0')
19729 {
32ec8896 19730 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19731 return false;
9ece1fa9
TT
19732 }
19733
19734 count = byte_get (descdata, addr_size);
19735 descdata += addr_size;
19736
19737 page_size = byte_get (descdata, addr_size);
19738 descdata += addr_size;
19739
625d49fc 19740 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 19741 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19742 {
32ec8896 19743 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19744 return false;
9ece1fa9
TT
19745 }
19746
19747 printf (_(" Page size: "));
19748 print_vma (page_size, DEC);
19749 printf ("\n");
19750
19751 printf (_(" %*s%*s%*s\n"),
19752 (int) (2 + 2 * addr_size), _("Start"),
19753 (int) (4 + 2 * addr_size), _("End"),
19754 (int) (4 + 2 * addr_size), _("Page Offset"));
19755 filenames = descdata + count * 3 * addr_size;
595712bb 19756 while (count-- > 0)
9ece1fa9 19757 {
625d49fc 19758 uint64_t start, end, file_ofs;
9ece1fa9
TT
19759
19760 if (filenames == descend)
19761 {
32ec8896 19762 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19763 return false;
9ece1fa9
TT
19764 }
19765
19766 start = byte_get (descdata, addr_size);
19767 descdata += addr_size;
19768 end = byte_get (descdata, addr_size);
19769 descdata += addr_size;
19770 file_ofs = byte_get (descdata, addr_size);
19771 descdata += addr_size;
19772
19773 printf (" ");
19774 print_vma (start, FULL_HEX);
19775 printf (" ");
19776 print_vma (end, FULL_HEX);
19777 printf (" ");
19778 print_vma (file_ofs, FULL_HEX);
19779 printf ("\n %s\n", filenames);
19780
19781 filenames += 1 + strlen ((char *) filenames);
19782 }
19783
015dc7e1 19784 return true;
9ece1fa9
TT
19785}
19786
1118d252
RM
19787static const char *
19788get_gnu_elf_note_type (unsigned e_type)
19789{
1449284b 19790 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19791 switch (e_type)
19792 {
19793 case NT_GNU_ABI_TAG:
19794 return _("NT_GNU_ABI_TAG (ABI version tag)");
19795 case NT_GNU_HWCAP:
19796 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19797 case NT_GNU_BUILD_ID:
19798 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19799 case NT_GNU_GOLD_VERSION:
19800 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19801 case NT_GNU_PROPERTY_TYPE_0:
19802 return _("NT_GNU_PROPERTY_TYPE_0");
19803 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19804 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19805 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19806 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19807 default:
1449284b
NC
19808 {
19809 static char buff[64];
1118d252 19810
1449284b
NC
19811 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19812 return buff;
19813 }
19814 }
1118d252
RM
19815}
19816
a9eafb08
L
19817static void
19818decode_x86_compat_isa (unsigned int bitmask)
19819{
19820 while (bitmask)
19821 {
19822 unsigned int bit = bitmask & (- bitmask);
19823
19824 bitmask &= ~ bit;
19825 switch (bit)
19826 {
19827 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19828 printf ("i486");
19829 break;
19830 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19831 printf ("586");
19832 break;
19833 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19834 printf ("686");
19835 break;
19836 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19837 printf ("SSE");
19838 break;
19839 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19840 printf ("SSE2");
19841 break;
19842 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19843 printf ("SSE3");
19844 break;
19845 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19846 printf ("SSSE3");
19847 break;
19848 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19849 printf ("SSE4_1");
19850 break;
19851 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19852 printf ("SSE4_2");
19853 break;
19854 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19855 printf ("AVX");
19856 break;
19857 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19858 printf ("AVX2");
19859 break;
19860 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19861 printf ("AVX512F");
19862 break;
19863 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19864 printf ("AVX512CD");
19865 break;
19866 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19867 printf ("AVX512ER");
19868 break;
19869 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19870 printf ("AVX512PF");
19871 break;
19872 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19873 printf ("AVX512VL");
19874 break;
19875 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19876 printf ("AVX512DQ");
19877 break;
19878 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19879 printf ("AVX512BW");
19880 break;
65b3d26e
L
19881 default:
19882 printf (_("<unknown: %x>"), bit);
19883 break;
a9eafb08
L
19884 }
19885 if (bitmask)
19886 printf (", ");
19887 }
19888}
19889
9ef920e9 19890static void
32930e4e 19891decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19892{
0a59decb 19893 if (!bitmask)
90c745dc
L
19894 {
19895 printf (_("<None>"));
19896 return;
19897 }
90c745dc 19898
9ef920e9
NC
19899 while (bitmask)
19900 {
1fc87489 19901 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19902
19903 bitmask &= ~ bit;
19904 switch (bit)
19905 {
32930e4e 19906 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19907 printf ("CMOV");
19908 break;
32930e4e 19909 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19910 printf ("SSE");
19911 break;
32930e4e 19912 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19913 printf ("SSE2");
19914 break;
32930e4e 19915 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19916 printf ("SSE3");
19917 break;
32930e4e 19918 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19919 printf ("SSSE3");
19920 break;
32930e4e 19921 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19922 printf ("SSE4_1");
19923 break;
32930e4e 19924 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19925 printf ("SSE4_2");
19926 break;
32930e4e 19927 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19928 printf ("AVX");
19929 break;
32930e4e 19930 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19931 printf ("AVX2");
19932 break;
32930e4e 19933 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19934 printf ("FMA");
19935 break;
32930e4e 19936 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19937 printf ("AVX512F");
19938 break;
32930e4e 19939 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19940 printf ("AVX512CD");
19941 break;
32930e4e 19942 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19943 printf ("AVX512ER");
19944 break;
32930e4e 19945 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19946 printf ("AVX512PF");
19947 break;
32930e4e 19948 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19949 printf ("AVX512VL");
19950 break;
32930e4e 19951 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19952 printf ("AVX512DQ");
19953 break;
32930e4e 19954 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19955 printf ("AVX512BW");
19956 break;
32930e4e 19957 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19958 printf ("AVX512_4FMAPS");
19959 break;
32930e4e 19960 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19961 printf ("AVX512_4VNNIW");
19962 break;
32930e4e 19963 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19964 printf ("AVX512_BITALG");
19965 break;
32930e4e 19966 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19967 printf ("AVX512_IFMA");
19968 break;
32930e4e 19969 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19970 printf ("AVX512_VBMI");
19971 break;
32930e4e 19972 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19973 printf ("AVX512_VBMI2");
19974 break;
32930e4e 19975 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19976 printf ("AVX512_VNNI");
19977 break;
32930e4e 19978 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19979 printf ("AVX512_BF16");
19980 break;
65b3d26e
L
19981 default:
19982 printf (_("<unknown: %x>"), bit);
19983 break;
9ef920e9
NC
19984 }
19985 if (bitmask)
19986 printf (", ");
19987 }
19988}
19989
28cdbb18
SM
19990static const char *
19991get_amdgpu_elf_note_type (unsigned int e_type)
19992{
19993 switch (e_type)
19994 {
19995 case NT_AMDGPU_METADATA:
19996 return _("NT_AMDGPU_METADATA (code object metadata)");
19997 default:
19998 {
19999 static char buf[64];
20000 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
20001 return buf;
20002 }
20003 }
20004}
20005
32930e4e
L
20006static void
20007decode_x86_isa (unsigned int bitmask)
20008{
32930e4e
L
20009 while (bitmask)
20010 {
20011 unsigned int bit = bitmask & (- bitmask);
20012
20013 bitmask &= ~ bit;
20014 switch (bit)
20015 {
b0ab0693
L
20016 case GNU_PROPERTY_X86_ISA_1_BASELINE:
20017 printf ("x86-64-baseline");
20018 break;
32930e4e
L
20019 case GNU_PROPERTY_X86_ISA_1_V2:
20020 printf ("x86-64-v2");
20021 break;
20022 case GNU_PROPERTY_X86_ISA_1_V3:
20023 printf ("x86-64-v3");
20024 break;
20025 case GNU_PROPERTY_X86_ISA_1_V4:
20026 printf ("x86-64-v4");
20027 break;
20028 default:
20029 printf (_("<unknown: %x>"), bit);
20030 break;
20031 }
20032 if (bitmask)
20033 printf (", ");
20034 }
20035}
20036
ee2fdd6f 20037static void
a9eafb08 20038decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 20039{
0a59decb 20040 if (!bitmask)
90c745dc
L
20041 {
20042 printf (_("<None>"));
20043 return;
20044 }
90c745dc 20045
ee2fdd6f
L
20046 while (bitmask)
20047 {
20048 unsigned int bit = bitmask & (- bitmask);
20049
20050 bitmask &= ~ bit;
20051 switch (bit)
20052 {
20053 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 20054 printf ("IBT");
ee2fdd6f 20055 break;
48580982 20056 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 20057 printf ("SHSTK");
48580982 20058 break;
279d901e
L
20059 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
20060 printf ("LAM_U48");
20061 break;
20062 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
20063 printf ("LAM_U57");
20064 break;
ee2fdd6f
L
20065 default:
20066 printf (_("<unknown: %x>"), bit);
20067 break;
20068 }
20069 if (bitmask)
20070 printf (", ");
20071 }
20072}
20073
a9eafb08
L
20074static void
20075decode_x86_feature_2 (unsigned int bitmask)
20076{
0a59decb 20077 if (!bitmask)
90c745dc
L
20078 {
20079 printf (_("<None>"));
20080 return;
20081 }
90c745dc 20082
a9eafb08
L
20083 while (bitmask)
20084 {
20085 unsigned int bit = bitmask & (- bitmask);
20086
20087 bitmask &= ~ bit;
20088 switch (bit)
20089 {
20090 case GNU_PROPERTY_X86_FEATURE_2_X86:
20091 printf ("x86");
20092 break;
20093 case GNU_PROPERTY_X86_FEATURE_2_X87:
20094 printf ("x87");
20095 break;
20096 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20097 printf ("MMX");
20098 break;
20099 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20100 printf ("XMM");
20101 break;
20102 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20103 printf ("YMM");
20104 break;
20105 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20106 printf ("ZMM");
20107 break;
a308b89d
L
20108 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20109 printf ("TMM");
20110 break;
32930e4e
L
20111 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20112 printf ("MASK");
20113 break;
a9eafb08
L
20114 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20115 printf ("FXSR");
20116 break;
20117 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20118 printf ("XSAVE");
20119 break;
20120 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20121 printf ("XSAVEOPT");
20122 break;
20123 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20124 printf ("XSAVEC");
20125 break;
65b3d26e
L
20126 default:
20127 printf (_("<unknown: %x>"), bit);
20128 break;
a9eafb08
L
20129 }
20130 if (bitmask)
20131 printf (", ");
20132 }
20133}
20134
cd702818
SD
20135static void
20136decode_aarch64_feature_1_and (unsigned int bitmask)
20137{
20138 while (bitmask)
20139 {
20140 unsigned int bit = bitmask & (- bitmask);
20141
20142 bitmask &= ~ bit;
20143 switch (bit)
20144 {
20145 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20146 printf ("BTI");
20147 break;
20148
20149 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20150 printf ("PAC");
20151 break;
20152
20153 default:
20154 printf (_("<unknown: %x>"), bit);
20155 break;
20156 }
20157 if (bitmask)
20158 printf (", ");
20159 }
20160}
20161
6320fd00
L
20162static void
20163decode_1_needed (unsigned int bitmask)
20164{
20165 while (bitmask)
20166 {
20167 unsigned int bit = bitmask & (- bitmask);
20168
20169 bitmask &= ~ bit;
20170 switch (bit)
20171 {
20172 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20173 printf ("indirect external access");
20174 break;
20175 default:
20176 printf (_("<unknown: %x>"), bit);
20177 break;
20178 }
20179 if (bitmask)
20180 printf (", ");
20181 }
20182}
20183
9ef920e9 20184static void
dda8d76d 20185print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
20186{
20187 unsigned char * ptr = (unsigned char *) pnote->descdata;
20188 unsigned char * ptr_end = ptr + pnote->descsz;
20189 unsigned int size = is_32bit_elf ? 4 : 8;
20190
20191 printf (_(" Properties: "));
20192
1fc87489 20193 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
20194 {
20195 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
20196 return;
20197 }
20198
6ab2c4ed 20199 while (ptr < ptr_end)
9ef920e9 20200 {
1fc87489 20201 unsigned int j;
6ab2c4ed
MC
20202 unsigned int type;
20203 unsigned int datasz;
20204
20205 if ((size_t) (ptr_end - ptr) < 8)
20206 {
20207 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
20208 break;
20209 }
20210
20211 type = byte_get (ptr, 4);
20212 datasz = byte_get (ptr + 4, 4);
9ef920e9 20213
1fc87489 20214 ptr += 8;
9ef920e9 20215
6ab2c4ed 20216 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 20217 {
1fc87489
L
20218 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
20219 type, datasz);
9ef920e9 20220 break;
1fc87489 20221 }
9ef920e9 20222
1fc87489
L
20223 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20224 {
dda8d76d
NC
20225 if (filedata->file_header.e_machine == EM_X86_64
20226 || filedata->file_header.e_machine == EM_IAMCU
20227 || filedata->file_header.e_machine == EM_386)
1fc87489 20228 {
aa7bca9b
L
20229 unsigned int bitmask;
20230
20231 if (datasz == 4)
0a59decb 20232 bitmask = byte_get (ptr, 4);
aa7bca9b
L
20233 else
20234 bitmask = 0;
20235
1fc87489
L
20236 switch (type)
20237 {
20238 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 20239 if (datasz != 4)
aa7bca9b
L
20240 printf (_("x86 ISA used: <corrupt length: %#x> "),
20241 datasz);
1fc87489 20242 else
aa7bca9b
L
20243 {
20244 printf ("x86 ISA used: ");
20245 decode_x86_isa (bitmask);
20246 }
1fc87489 20247 goto next;
9ef920e9 20248
1fc87489 20249 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20250 if (datasz != 4)
aa7bca9b
L
20251 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20252 datasz);
1fc87489 20253 else
aa7bca9b
L
20254 {
20255 printf ("x86 ISA needed: ");
20256 decode_x86_isa (bitmask);
20257 }
1fc87489 20258 goto next;
9ef920e9 20259
ee2fdd6f 20260 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20261 if (datasz != 4)
aa7bca9b
L
20262 printf (_("x86 feature: <corrupt length: %#x> "),
20263 datasz);
ee2fdd6f 20264 else
aa7bca9b
L
20265 {
20266 printf ("x86 feature: ");
a9eafb08
L
20267 decode_x86_feature_1 (bitmask);
20268 }
20269 goto next;
20270
20271 case GNU_PROPERTY_X86_FEATURE_2_USED:
20272 if (datasz != 4)
20273 printf (_("x86 feature used: <corrupt length: %#x> "),
20274 datasz);
20275 else
20276 {
20277 printf ("x86 feature used: ");
20278 decode_x86_feature_2 (bitmask);
20279 }
20280 goto next;
20281
20282 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20283 if (datasz != 4)
20284 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20285 else
20286 {
20287 printf ("x86 feature needed: ");
20288 decode_x86_feature_2 (bitmask);
20289 }
20290 goto next;
20291
20292 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20293 if (datasz != 4)
20294 printf (_("x86 ISA used: <corrupt length: %#x> "),
20295 datasz);
20296 else
20297 {
20298 printf ("x86 ISA used: ");
20299 decode_x86_compat_isa (bitmask);
20300 }
20301 goto next;
20302
20303 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20304 if (datasz != 4)
20305 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20306 datasz);
20307 else
20308 {
20309 printf ("x86 ISA needed: ");
20310 decode_x86_compat_isa (bitmask);
aa7bca9b 20311 }
ee2fdd6f
L
20312 goto next;
20313
32930e4e
L
20314 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20315 if (datasz != 4)
20316 printf (_("x86 ISA used: <corrupt length: %#x> "),
20317 datasz);
20318 else
20319 {
20320 printf ("x86 ISA used: ");
20321 decode_x86_compat_2_isa (bitmask);
20322 }
20323 goto next;
20324
20325 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20326 if (datasz != 4)
20327 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20328 datasz);
20329 else
20330 {
20331 printf ("x86 ISA needed: ");
20332 decode_x86_compat_2_isa (bitmask);
20333 }
20334 goto next;
20335
1fc87489
L
20336 default:
20337 break;
20338 }
20339 }
cd702818
SD
20340 else if (filedata->file_header.e_machine == EM_AARCH64)
20341 {
20342 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20343 {
20344 printf ("AArch64 feature: ");
20345 if (datasz != 4)
20346 printf (_("<corrupt length: %#x> "), datasz);
20347 else
20348 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20349 goto next;
20350 }
20351 }
1fc87489
L
20352 }
20353 else
20354 {
20355 switch (type)
9ef920e9 20356 {
1fc87489
L
20357 case GNU_PROPERTY_STACK_SIZE:
20358 printf (_("stack size: "));
20359 if (datasz != size)
20360 printf (_("<corrupt length: %#x> "), datasz);
20361 else
26c527e6 20362 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
20363 goto next;
20364
20365 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20366 printf ("no copy on protected ");
20367 if (datasz)
20368 printf (_("<corrupt length: %#x> "), datasz);
20369 goto next;
20370
20371 default:
5a767724
L
20372 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20373 && type <= GNU_PROPERTY_UINT32_AND_HI)
20374 || (type >= GNU_PROPERTY_UINT32_OR_LO
20375 && type <= GNU_PROPERTY_UINT32_OR_HI))
20376 {
6320fd00
L
20377 switch (type)
20378 {
20379 case GNU_PROPERTY_1_NEEDED:
20380 if (datasz != 4)
20381 printf (_("1_needed: <corrupt length: %#x> "),
20382 datasz);
20383 else
20384 {
20385 unsigned int bitmask = byte_get (ptr, 4);
20386 printf ("1_needed: ");
20387 decode_1_needed (bitmask);
20388 }
20389 goto next;
20390
20391 default:
20392 break;
20393 }
5a767724
L
20394 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20395 printf (_("UINT32_AND (%#x): "), type);
20396 else
20397 printf (_("UINT32_OR (%#x): "), type);
20398 if (datasz != 4)
20399 printf (_("<corrupt length: %#x> "), datasz);
20400 else
20401 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20402 goto next;
20403 }
9ef920e9
NC
20404 break;
20405 }
9ef920e9
NC
20406 }
20407
1fc87489
L
20408 if (type < GNU_PROPERTY_LOPROC)
20409 printf (_("<unknown type %#x data: "), type);
20410 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20411 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20412 else
20413 printf (_("<application-specific type %#x data: "), type);
20414 for (j = 0; j < datasz; ++j)
20415 printf ("%02x ", ptr[j] & 0xff);
20416 printf (">");
20417
dc1e8a47 20418 next:
9ef920e9 20419 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20420 if (ptr == ptr_end)
20421 break;
1fc87489 20422
6ab2c4ed
MC
20423 if (do_wide)
20424 printf (", ");
20425 else
20426 printf ("\n\t");
9ef920e9
NC
20427 }
20428
20429 printf ("\n");
20430}
20431
015dc7e1 20432static bool
dda8d76d 20433print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20434{
1449284b 20435 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20436 switch (pnote->type)
20437 {
20438 case NT_GNU_BUILD_ID:
20439 {
26c527e6 20440 size_t i;
664f90a3
TT
20441
20442 printf (_(" Build ID: "));
20443 for (i = 0; i < pnote->descsz; ++i)
20444 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20445 printf ("\n");
664f90a3
TT
20446 }
20447 break;
20448
20449 case NT_GNU_ABI_TAG:
20450 {
26c527e6 20451 unsigned int os, major, minor, subminor;
664f90a3
TT
20452 const char *osname;
20453
3102e897
NC
20454 /* PR 17531: file: 030-599401-0.004. */
20455 if (pnote->descsz < 16)
20456 {
20457 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20458 break;
20459 }
20460
664f90a3
TT
20461 os = byte_get ((unsigned char *) pnote->descdata, 4);
20462 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20463 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20464 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20465
20466 switch (os)
20467 {
20468 case GNU_ABI_TAG_LINUX:
20469 osname = "Linux";
20470 break;
20471 case GNU_ABI_TAG_HURD:
20472 osname = "Hurd";
20473 break;
20474 case GNU_ABI_TAG_SOLARIS:
20475 osname = "Solaris";
20476 break;
20477 case GNU_ABI_TAG_FREEBSD:
20478 osname = "FreeBSD";
20479 break;
20480 case GNU_ABI_TAG_NETBSD:
20481 osname = "NetBSD";
20482 break;
14ae95f2
RM
20483 case GNU_ABI_TAG_SYLLABLE:
20484 osname = "Syllable";
20485 break;
20486 case GNU_ABI_TAG_NACL:
20487 osname = "NaCl";
20488 break;
664f90a3
TT
20489 default:
20490 osname = "Unknown";
20491 break;
20492 }
20493
26c527e6 20494 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
20495 major, minor, subminor);
20496 }
20497 break;
926c5385
CC
20498
20499 case NT_GNU_GOLD_VERSION:
20500 {
26c527e6 20501 size_t i;
926c5385
CC
20502
20503 printf (_(" Version: "));
20504 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20505 printf ("%c", pnote->descdata[i]);
20506 printf ("\n");
20507 }
20508 break;
1449284b
NC
20509
20510 case NT_GNU_HWCAP:
20511 {
26c527e6 20512 unsigned int num_entries, mask;
1449284b
NC
20513
20514 /* Hardware capabilities information. Word 0 is the number of entries.
20515 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20516 is a series of entries, where each entry is a single byte followed
20517 by a nul terminated string. The byte gives the bit number to test
20518 if enabled in the bitmask. */
20519 printf (_(" Hardware Capabilities: "));
20520 if (pnote->descsz < 8)
20521 {
32ec8896 20522 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20523 return false;
1449284b
NC
20524 }
20525 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20526 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 20527 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
20528 /* FIXME: Add code to display the entries... */
20529 }
20530 break;
20531
9ef920e9 20532 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20533 print_gnu_property_note (filedata, pnote);
9ef920e9 20534 break;
9abca702 20535
1449284b
NC
20536 default:
20537 /* Handle unrecognised types. An error message should have already been
20538 created by get_gnu_elf_note_type(), so all that we need to do is to
20539 display the data. */
20540 {
26c527e6 20541 size_t i;
1449284b
NC
20542
20543 printf (_(" Description data: "));
20544 for (i = 0; i < pnote->descsz; ++i)
20545 printf ("%02x ", pnote->descdata[i] & 0xff);
20546 printf ("\n");
20547 }
20548 break;
664f90a3
TT
20549 }
20550
015dc7e1 20551 return true;
664f90a3
TT
20552}
20553
685080f2
NC
20554static const char *
20555get_v850_elf_note_type (enum v850_notes n_type)
20556{
20557 static char buff[64];
20558
20559 switch (n_type)
20560 {
20561 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20562 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20563 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20564 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20565 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20566 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20567 default:
20568 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20569 return buff;
20570 }
20571}
20572
015dc7e1 20573static bool
685080f2
NC
20574print_v850_note (Elf_Internal_Note * pnote)
20575{
20576 unsigned int val;
20577
20578 if (pnote->descsz != 4)
015dc7e1 20579 return false;
32ec8896 20580
685080f2
NC
20581 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20582
20583 if (val == 0)
20584 {
20585 printf (_("not set\n"));
015dc7e1 20586 return true;
685080f2
NC
20587 }
20588
20589 switch (pnote->type)
20590 {
20591 case V850_NOTE_ALIGNMENT:
20592 switch (val)
20593 {
015dc7e1
AM
20594 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20595 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20596 }
20597 break;
14ae95f2 20598
685080f2
NC
20599 case V850_NOTE_DATA_SIZE:
20600 switch (val)
20601 {
015dc7e1
AM
20602 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20603 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20604 }
20605 break;
14ae95f2 20606
685080f2
NC
20607 case V850_NOTE_FPU_INFO:
20608 switch (val)
20609 {
015dc7e1
AM
20610 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20611 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20612 }
20613 break;
14ae95f2 20614
685080f2
NC
20615 case V850_NOTE_MMU_INFO:
20616 case V850_NOTE_CACHE_INFO:
20617 case V850_NOTE_SIMD_INFO:
20618 if (val == EF_RH850_SIMD)
20619 {
20620 printf (_("yes\n"));
015dc7e1 20621 return true;
685080f2
NC
20622 }
20623 break;
20624
20625 default:
20626 /* An 'unknown note type' message will already have been displayed. */
20627 break;
20628 }
20629
20630 printf (_("unknown value: %x\n"), val);
015dc7e1 20631 return false;
685080f2
NC
20632}
20633
015dc7e1 20634static bool
c6056a74
SF
20635process_netbsd_elf_note (Elf_Internal_Note * pnote)
20636{
20637 unsigned int version;
20638
20639 switch (pnote->type)
20640 {
20641 case NT_NETBSD_IDENT:
b966f55f
AM
20642 if (pnote->descsz < 1)
20643 break;
c6056a74
SF
20644 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20645 if ((version / 10000) % 100)
b966f55f 20646 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20647 version, version / 100000000, (version / 1000000) % 100,
20648 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20649 'A' + (version / 10000) % 26);
c6056a74
SF
20650 else
20651 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20652 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20653 (version / 100) % 100);
015dc7e1 20654 return true;
c6056a74
SF
20655
20656 case NT_NETBSD_MARCH:
9abca702 20657 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20658 pnote->descdata);
015dc7e1 20659 return true;
c6056a74 20660
9abca702 20661 case NT_NETBSD_PAX:
b966f55f
AM
20662 if (pnote->descsz < 1)
20663 break;
9abca702
CZ
20664 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20665 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20666 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20667 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20668 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20669 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20670 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20671 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20672 return true;
c6056a74 20673 }
b966f55f
AM
20674
20675 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20676 pnote->descsz, pnote->type);
015dc7e1 20677 return false;
c6056a74
SF
20678}
20679
f4ddf30f 20680static const char *
dda8d76d 20681get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20682{
f4ddf30f
JB
20683 switch (e_type)
20684 {
20685 case NT_FREEBSD_THRMISC:
20686 return _("NT_THRMISC (thrmisc structure)");
20687 case NT_FREEBSD_PROCSTAT_PROC:
20688 return _("NT_PROCSTAT_PROC (proc data)");
20689 case NT_FREEBSD_PROCSTAT_FILES:
20690 return _("NT_PROCSTAT_FILES (files data)");
20691 case NT_FREEBSD_PROCSTAT_VMMAP:
20692 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20693 case NT_FREEBSD_PROCSTAT_GROUPS:
20694 return _("NT_PROCSTAT_GROUPS (groups data)");
20695 case NT_FREEBSD_PROCSTAT_UMASK:
20696 return _("NT_PROCSTAT_UMASK (umask data)");
20697 case NT_FREEBSD_PROCSTAT_RLIMIT:
20698 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20699 case NT_FREEBSD_PROCSTAT_OSREL:
20700 return _("NT_PROCSTAT_OSREL (osreldate data)");
20701 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20702 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20703 case NT_FREEBSD_PROCSTAT_AUXV:
20704 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20705 case NT_FREEBSD_PTLWPINFO:
20706 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
20707 case NT_FREEBSD_X86_SEGBASES:
20708 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 20709 }
dda8d76d 20710 return get_note_type (filedata, e_type);
f4ddf30f
JB
20711}
20712
9437c45b 20713static const char *
dda8d76d 20714get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20715{
20716 static char buff[64];
20717
540e6170
CZ
20718 switch (e_type)
20719 {
20720 case NT_NETBSDCORE_PROCINFO:
20721 /* NetBSD core "procinfo" structure. */
20722 return _("NetBSD procinfo structure");
9437c45b 20723
540e6170
CZ
20724 case NT_NETBSDCORE_AUXV:
20725 return _("NetBSD ELF auxiliary vector data");
9437c45b 20726
06d949ec
KR
20727 case NT_NETBSDCORE_LWPSTATUS:
20728 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20729
540e6170 20730 default:
06d949ec 20731 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20732 defined for NetBSD core files. If the note type is less
20733 than the start of the machine-dependent note types, we don't
20734 understand it. */
20735
20736 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20737 {
20738 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20739 return buff;
20740 }
20741 break;
9437c45b
JT
20742 }
20743
dda8d76d 20744 switch (filedata->file_header.e_machine)
9437c45b
JT
20745 {
20746 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20747 and PT_GETFPREGS == mach+2. */
20748
20749 case EM_OLD_ALPHA:
20750 case EM_ALPHA:
20751 case EM_SPARC:
20752 case EM_SPARC32PLUS:
20753 case EM_SPARCV9:
20754 switch (e_type)
20755 {
2b692964 20756 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20757 return _("PT_GETREGS (reg structure)");
2b692964 20758 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20759 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20760 default:
20761 break;
20762 }
20763 break;
20764
c0d38b0e
CZ
20765 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20766 There's also old PT___GETREGS40 == mach + 1 for old reg
20767 structure which lacks GBR. */
20768 case EM_SH:
20769 switch (e_type)
20770 {
20771 case NT_NETBSDCORE_FIRSTMACH + 1:
20772 return _("PT___GETREGS40 (old reg structure)");
20773 case NT_NETBSDCORE_FIRSTMACH + 3:
20774 return _("PT_GETREGS (reg structure)");
20775 case NT_NETBSDCORE_FIRSTMACH + 5:
20776 return _("PT_GETFPREGS (fpreg structure)");
20777 default:
20778 break;
20779 }
20780 break;
20781
9437c45b
JT
20782 /* On all other arch's, PT_GETREGS == mach+1 and
20783 PT_GETFPREGS == mach+3. */
20784 default:
20785 switch (e_type)
20786 {
2b692964 20787 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20788 return _("PT_GETREGS (reg structure)");
2b692964 20789 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20790 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20791 default:
20792 break;
20793 }
20794 }
20795
9cf03b7e 20796 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20797 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20798 return buff;
20799}
20800
98ca73af
FC
20801static const char *
20802get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20803{
20804 switch (e_type)
20805 {
20806 case NT_OPENBSD_PROCINFO:
20807 return _("OpenBSD procinfo structure");
20808 case NT_OPENBSD_AUXV:
20809 return _("OpenBSD ELF auxiliary vector data");
20810 case NT_OPENBSD_REGS:
20811 return _("OpenBSD regular registers");
20812 case NT_OPENBSD_FPREGS:
20813 return _("OpenBSD floating point registers");
20814 case NT_OPENBSD_WCOOKIE:
20815 return _("OpenBSD window cookie");
20816 }
20817
20818 return get_note_type (filedata, e_type);
20819}
20820
e263a66b
CC
20821static const char *
20822get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
20823{
20824 switch (e_type)
20825 {
20826 case QNT_DEBUG_FULLPATH:
20827 return _("QNX debug fullpath");
20828 case QNT_DEBUG_RELOC:
20829 return _("QNX debug relocation");
20830 case QNT_STACK:
20831 return _("QNX stack");
20832 case QNT_GENERATOR:
20833 return _("QNX generator");
20834 case QNT_DEFAULT_LIB:
20835 return _("QNX default library");
20836 case QNT_CORE_SYSINFO:
20837 return _("QNX core sysinfo");
20838 case QNT_CORE_INFO:
20839 return _("QNX core info");
20840 case QNT_CORE_STATUS:
20841 return _("QNX core status");
20842 case QNT_CORE_GREG:
20843 return _("QNX general registers");
20844 case QNT_CORE_FPREG:
20845 return _("QNX floating point registers");
20846 case QNT_LINK_MAP:
20847 return _("QNX link map");
20848 }
20849
20850 return get_note_type (filedata, e_type);
20851}
20852
70616151
TT
20853static const char *
20854get_stapsdt_note_type (unsigned e_type)
20855{
20856 static char buff[64];
20857
20858 switch (e_type)
20859 {
20860 case NT_STAPSDT:
20861 return _("NT_STAPSDT (SystemTap probe descriptors)");
20862
20863 default:
20864 break;
20865 }
20866
20867 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20868 return buff;
20869}
20870
015dc7e1 20871static bool
c6a9fc58
TT
20872print_stapsdt_note (Elf_Internal_Note *pnote)
20873{
3ca60c57 20874 size_t len, maxlen;
26c527e6 20875 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20876 char *data = pnote->descdata;
20877 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 20878 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
20879 char *provider, *probe, *arg_fmt;
20880
3ca60c57
NC
20881 if (pnote->descsz < (addr_size * 3))
20882 goto stapdt_note_too_small;
20883
c6a9fc58
TT
20884 pc = byte_get ((unsigned char *) data, addr_size);
20885 data += addr_size;
3ca60c57 20886
c6a9fc58
TT
20887 base_addr = byte_get ((unsigned char *) data, addr_size);
20888 data += addr_size;
3ca60c57 20889
c6a9fc58
TT
20890 semaphore = byte_get ((unsigned char *) data, addr_size);
20891 data += addr_size;
20892
3ca60c57
NC
20893 if (data >= data_end)
20894 goto stapdt_note_too_small;
20895 maxlen = data_end - data;
20896 len = strnlen (data, maxlen);
20897 if (len < maxlen)
20898 {
20899 provider = data;
20900 data += len + 1;
20901 }
20902 else
20903 goto stapdt_note_too_small;
20904
20905 if (data >= data_end)
20906 goto stapdt_note_too_small;
20907 maxlen = data_end - data;
20908 len = strnlen (data, maxlen);
20909 if (len < maxlen)
20910 {
20911 probe = data;
20912 data += len + 1;
20913 }
20914 else
20915 goto stapdt_note_too_small;
9abca702 20916
3ca60c57
NC
20917 if (data >= data_end)
20918 goto stapdt_note_too_small;
20919 maxlen = data_end - data;
20920 len = strnlen (data, maxlen);
20921 if (len < maxlen)
20922 {
20923 arg_fmt = data;
20924 data += len + 1;
20925 }
20926 else
20927 goto stapdt_note_too_small;
c6a9fc58
TT
20928
20929 printf (_(" Provider: %s\n"), provider);
20930 printf (_(" Name: %s\n"), probe);
20931 printf (_(" Location: "));
20932 print_vma (pc, FULL_HEX);
20933 printf (_(", Base: "));
20934 print_vma (base_addr, FULL_HEX);
20935 printf (_(", Semaphore: "));
20936 print_vma (semaphore, FULL_HEX);
9cf03b7e 20937 printf ("\n");
c6a9fc58
TT
20938 printf (_(" Arguments: %s\n"), arg_fmt);
20939
20940 return data == data_end;
3ca60c57
NC
20941
20942 stapdt_note_too_small:
20943 printf (_(" <corrupt - note is too small>\n"));
20944 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20945 return false;
c6a9fc58
TT
20946}
20947
e5382207
LB
20948static bool
20949print_fdo_note (Elf_Internal_Note * pnote)
20950{
20951 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20952 {
20953 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20954 return true;
20955 }
20956 return false;
20957}
20958
00e98fc7
TG
20959static const char *
20960get_ia64_vms_note_type (unsigned e_type)
20961{
20962 static char buff[64];
20963
20964 switch (e_type)
20965 {
20966 case NT_VMS_MHD:
20967 return _("NT_VMS_MHD (module header)");
20968 case NT_VMS_LNM:
20969 return _("NT_VMS_LNM (language name)");
20970 case NT_VMS_SRC:
20971 return _("NT_VMS_SRC (source files)");
20972 case NT_VMS_TITLE:
9cf03b7e 20973 return "NT_VMS_TITLE";
00e98fc7
TG
20974 case NT_VMS_EIDC:
20975 return _("NT_VMS_EIDC (consistency check)");
20976 case NT_VMS_FPMODE:
20977 return _("NT_VMS_FPMODE (FP mode)");
20978 case NT_VMS_LINKTIME:
9cf03b7e 20979 return "NT_VMS_LINKTIME";
00e98fc7
TG
20980 case NT_VMS_IMGNAM:
20981 return _("NT_VMS_IMGNAM (image name)");
20982 case NT_VMS_IMGID:
20983 return _("NT_VMS_IMGID (image id)");
20984 case NT_VMS_LINKID:
20985 return _("NT_VMS_LINKID (link id)");
20986 case NT_VMS_IMGBID:
20987 return _("NT_VMS_IMGBID (build id)");
20988 case NT_VMS_GSTNAM:
20989 return _("NT_VMS_GSTNAM (sym table name)");
20990 case NT_VMS_ORIG_DYN:
9cf03b7e 20991 return "NT_VMS_ORIG_DYN";
00e98fc7 20992 case NT_VMS_PATCHTIME:
9cf03b7e 20993 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20994 default:
20995 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20996 return buff;
20997 }
20998}
20999
015dc7e1 21000static bool
00e98fc7
TG
21001print_ia64_vms_note (Elf_Internal_Note * pnote)
21002{
26c527e6 21003 unsigned int maxlen = pnote->descsz;
8d18bf79 21004
26c527e6 21005 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
21006 goto desc_size_fail;
21007
00e98fc7
TG
21008 switch (pnote->type)
21009 {
21010 case NT_VMS_MHD:
8d18bf79
NC
21011 if (maxlen <= 36)
21012 goto desc_size_fail;
21013
26c527e6 21014 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
21015
21016 printf (_(" Creation date : %.17s\n"), pnote->descdata);
21017 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
21018 if (l + 34 < maxlen)
21019 {
21020 printf (_(" Module name : %s\n"), pnote->descdata + 34);
21021 if (l + 35 < maxlen)
21022 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
21023 else
21024 printf (_(" Module version : <missing>\n"));
21025 }
00e98fc7 21026 else
8d18bf79
NC
21027 {
21028 printf (_(" Module name : <missing>\n"));
21029 printf (_(" Module version : <missing>\n"));
21030 }
00e98fc7 21031 break;
8d18bf79 21032
00e98fc7 21033 case NT_VMS_LNM:
8d18bf79 21034 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21035 break;
8d18bf79 21036
00e98fc7 21037 case NT_VMS_FPMODE:
9cf03b7e 21038 printf (_(" Floating Point mode: "));
8d18bf79
NC
21039 if (maxlen < 8)
21040 goto desc_size_fail;
21041 /* FIXME: Generate an error if descsz > 8 ? */
21042
b8281767 21043 printf ("0x%016" PRIx64 "\n",
625d49fc 21044 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 21045 break;
8d18bf79 21046
00e98fc7
TG
21047 case NT_VMS_LINKTIME:
21048 printf (_(" Link time: "));
8d18bf79
NC
21049 if (maxlen < 8)
21050 goto desc_size_fail;
21051 /* FIXME: Generate an error if descsz > 8 ? */
21052
0e3c1eeb 21053 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21054 printf ("\n");
21055 break;
8d18bf79 21056
00e98fc7
TG
21057 case NT_VMS_PATCHTIME:
21058 printf (_(" Patch time: "));
8d18bf79
NC
21059 if (maxlen < 8)
21060 goto desc_size_fail;
21061 /* FIXME: Generate an error if descsz > 8 ? */
21062
0e3c1eeb 21063 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21064 printf ("\n");
21065 break;
8d18bf79 21066
00e98fc7 21067 case NT_VMS_ORIG_DYN:
8d18bf79
NC
21068 if (maxlen < 34)
21069 goto desc_size_fail;
21070
00e98fc7 21071 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
21072 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
21073 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 21074 printf (_(" Last modified : "));
0e3c1eeb 21075 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 21076 printf (_("\n Link flags : "));
b8281767 21077 printf ("0x%016" PRIx64 "\n",
625d49fc 21078 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 21079 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 21080 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 21081 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 21082 break;
8d18bf79 21083
00e98fc7 21084 case NT_VMS_IMGNAM:
8d18bf79 21085 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21086 break;
8d18bf79 21087
00e98fc7 21088 case NT_VMS_GSTNAM:
8d18bf79 21089 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21090 break;
8d18bf79 21091
00e98fc7 21092 case NT_VMS_IMGID:
8d18bf79 21093 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21094 break;
8d18bf79 21095
00e98fc7 21096 case NT_VMS_LINKID:
8d18bf79 21097 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21098 break;
8d18bf79 21099
00e98fc7 21100 default:
015dc7e1 21101 return false;
00e98fc7 21102 }
8d18bf79 21103
015dc7e1 21104 return true;
8d18bf79
NC
21105
21106 desc_size_fail:
21107 printf (_(" <corrupt - data size is too small>\n"));
21108 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 21109 return false;
00e98fc7
TG
21110}
21111
fd486f32
AM
21112struct build_attr_cache {
21113 Filedata *filedata;
21114 char *strtab;
26c527e6 21115 uint64_t strtablen;
fd486f32 21116 Elf_Internal_Sym *symtab;
26c527e6 21117 uint64_t nsyms;
fd486f32
AM
21118} ba_cache;
21119
6f156d7a
NC
21120/* Find the symbol associated with a build attribute that is attached
21121 to address OFFSET. If PNAME is non-NULL then store the name of
21122 the symbol (if found) in the provided pointer, Returns NULL if a
21123 symbol could not be found. */
c799a79d 21124
6f156d7a 21125static Elf_Internal_Sym *
015dc7e1 21126get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 21127 uint64_t offset,
015dc7e1
AM
21128 bool is_open_attr,
21129 const char **pname)
9ef920e9 21130{
fd486f32
AM
21131 Elf_Internal_Sym *saved_sym = NULL;
21132 Elf_Internal_Sym *sym;
9ef920e9 21133
dda8d76d 21134 if (filedata->section_headers != NULL
fd486f32 21135 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 21136 {
c799a79d 21137 Elf_Internal_Shdr * symsec;
9ef920e9 21138
fd486f32
AM
21139 free (ba_cache.strtab);
21140 ba_cache.strtab = NULL;
21141 free (ba_cache.symtab);
21142 ba_cache.symtab = NULL;
21143
c799a79d 21144 /* Load the symbol and string sections. */
dda8d76d
NC
21145 for (symsec = filedata->section_headers;
21146 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 21147 symsec ++)
9ef920e9 21148 {
28d13567
AM
21149 if (symsec->sh_type == SHT_SYMTAB
21150 && get_symtab (filedata, symsec,
21151 &ba_cache.symtab, &ba_cache.nsyms,
21152 &ba_cache.strtab, &ba_cache.strtablen))
21153 break;
9ef920e9 21154 }
fd486f32 21155 ba_cache.filedata = filedata;
9ef920e9
NC
21156 }
21157
fd486f32 21158 if (ba_cache.symtab == NULL)
6f156d7a 21159 return NULL;
9ef920e9 21160
c799a79d 21161 /* Find a symbol whose value matches offset. */
fd486f32 21162 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
21163 if (sym->st_value == offset)
21164 {
fd486f32 21165 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
21166 /* Huh ? This should not happen. */
21167 continue;
9ef920e9 21168
fd486f32 21169 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 21170 continue;
9ef920e9 21171
9b9b1092 21172 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 21173 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
21174 if (ba_cache.strtab[sym->st_name] == '$'
21175 && ba_cache.strtab[sym->st_name + 1] != 0
21176 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
21177 continue;
21178
c799a79d
NC
21179 if (is_open_attr)
21180 {
21181 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
21182 and FILE or OBJECT symbols over NOTYPE symbols. We skip
21183 FUNC symbols entirely. */
21184 switch (ELF_ST_TYPE (sym->st_info))
21185 {
c799a79d 21186 case STT_OBJECT:
6f156d7a 21187 case STT_FILE:
c799a79d 21188 saved_sym = sym;
6f156d7a
NC
21189 if (sym->st_size)
21190 {
21191 /* If the symbol has a size associated
21192 with it then we can stop searching. */
fd486f32 21193 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 21194 }
c799a79d 21195 continue;
9ef920e9 21196
c799a79d
NC
21197 case STT_FUNC:
21198 /* Ignore function symbols. */
21199 continue;
21200
21201 default:
21202 break;
21203 }
21204
21205 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 21206 {
c799a79d
NC
21207 case STB_GLOBAL:
21208 if (saved_sym == NULL
21209 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
21210 saved_sym = sym;
21211 break;
c871dade 21212
c799a79d
NC
21213 case STB_LOCAL:
21214 if (saved_sym == NULL)
21215 saved_sym = sym;
21216 break;
21217
21218 default:
9ef920e9
NC
21219 break;
21220 }
21221 }
c799a79d
NC
21222 else
21223 {
21224 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
21225 continue;
21226
21227 saved_sym = sym;
21228 break;
21229 }
21230 }
21231
6f156d7a 21232 if (saved_sym && pname)
fd486f32 21233 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
21234
21235 return saved_sym;
c799a79d
NC
21236}
21237
d20e98ab
NC
21238/* Returns true iff addr1 and addr2 are in the same section. */
21239
015dc7e1 21240static bool
26c527e6 21241same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
21242{
21243 Elf_Internal_Shdr * a1;
21244 Elf_Internal_Shdr * a2;
21245
21246 a1 = find_section_by_address (filedata, addr1);
21247 a2 = find_section_by_address (filedata, addr2);
9abca702 21248
d20e98ab
NC
21249 return a1 == a2 && a1 != NULL;
21250}
21251
015dc7e1 21252static bool
dda8d76d
NC
21253print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21254 Filedata * filedata)
c799a79d 21255{
26c527e6
AM
21256 static uint64_t global_offset = 0;
21257 static uint64_t global_end = 0;
21258 static uint64_t func_offset = 0;
21259 static uint64_t func_end = 0;
c871dade 21260
015dc7e1
AM
21261 Elf_Internal_Sym *sym;
21262 const char *name;
26c527e6
AM
21263 uint64_t start;
21264 uint64_t end;
015dc7e1 21265 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
21266
21267 switch (pnote->descsz)
c799a79d 21268 {
6f156d7a
NC
21269 case 0:
21270 /* A zero-length description means that the range of
21271 the previous note of the same type should be used. */
c799a79d 21272 if (is_open_attr)
c871dade 21273 {
6f156d7a 21274 if (global_end > global_offset)
26c527e6
AM
21275 printf (_(" Applies to region from %#" PRIx64
21276 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 21277 else
26c527e6
AM
21278 printf (_(" Applies to region from %#" PRIx64
21279 "\n"), global_offset);
c799a79d
NC
21280 }
21281 else
21282 {
6f156d7a 21283 if (func_end > func_offset)
26c527e6
AM
21284 printf (_(" Applies to region from %#" PRIx64
21285 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 21286 else
26c527e6
AM
21287 printf (_(" Applies to region from %#" PRIx64
21288 "\n"), func_offset);
c871dade 21289 }
015dc7e1 21290 return true;
9ef920e9 21291
6f156d7a
NC
21292 case 4:
21293 start = byte_get ((unsigned char *) pnote->descdata, 4);
21294 end = 0;
21295 break;
21296
21297 case 8:
c74147bb
NC
21298 start = byte_get ((unsigned char *) pnote->descdata, 4);
21299 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21300 break;
21301
21302 case 16:
21303 start = byte_get ((unsigned char *) pnote->descdata, 8);
21304 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21305 break;
9abca702 21306
6f156d7a 21307 default:
c799a79d
NC
21308 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21309 printf (_(" <invalid descsz>"));
015dc7e1 21310 return false;
c799a79d
NC
21311 }
21312
6f156d7a
NC
21313 name = NULL;
21314 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21315 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21316 in order to avoid them being confused with the start address of the
21317 first function in the file... */
21318 if (sym == NULL && is_open_attr)
21319 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21320 & name);
6f156d7a
NC
21321
21322 if (end == 0 && sym != NULL && sym->st_size > 0)
21323 end = start + sym->st_size;
c799a79d
NC
21324
21325 if (is_open_attr)
21326 {
d20e98ab
NC
21327 /* FIXME: Need to properly allow for section alignment.
21328 16 is just the alignment used on x86_64. */
21329 if (global_end > 0
21330 && start > BFD_ALIGN (global_end, 16)
21331 /* Build notes are not guaranteed to be organised in order of
21332 increasing address, but we should find the all of the notes
21333 for one section in the same place. */
21334 && same_section (filedata, start, global_end))
26c527e6
AM
21335 warn (_("Gap in build notes detected from %#" PRIx64
21336 " to %#" PRIx64 "\n"),
6f156d7a
NC
21337 global_end + 1, start - 1);
21338
26c527e6 21339 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21340 global_offset = start;
21341
21342 if (end)
21343 {
26c527e6 21344 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21345 global_end = end;
21346 }
c799a79d
NC
21347 }
21348 else
21349 {
26c527e6 21350 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21351 func_offset = start;
21352
21353 if (end)
21354 {
26c527e6 21355 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21356 func_end = end;
21357 }
c799a79d
NC
21358 }
21359
6f156d7a
NC
21360 if (sym && name)
21361 printf (_(" (%s)"), name);
21362
21363 printf ("\n");
015dc7e1 21364 return true;
9ef920e9
NC
21365}
21366
015dc7e1 21367static bool
9ef920e9
NC
21368print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21369{
1d15e434
NC
21370 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21371 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21372 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21373 char name_type;
21374 char name_attribute;
1d15e434 21375 const char * expected_types;
9ef920e9
NC
21376 const char * name = pnote->namedata;
21377 const char * text;
88305e1b 21378 signed int left;
9ef920e9
NC
21379
21380 if (name == NULL || pnote->namesz < 2)
21381 {
21382 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21383 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21384 return false;
9ef920e9
NC
21385 }
21386
6f156d7a
NC
21387 if (do_wide)
21388 left = 28;
21389 else
21390 left = 20;
88305e1b
NC
21391
21392 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21393 if (name[0] == 'G' && name[1] == 'A')
21394 {
6f156d7a
NC
21395 if (pnote->namesz < 4)
21396 {
21397 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21398 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21399 return false;
6f156d7a
NC
21400 }
21401
88305e1b
NC
21402 printf ("GA");
21403 name += 2;
21404 left -= 2;
21405 }
21406
9ef920e9
NC
21407 switch ((name_type = * name))
21408 {
21409 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21410 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21411 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21412 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21413 printf ("%c", * name);
88305e1b 21414 left --;
9ef920e9
NC
21415 break;
21416 default:
21417 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21418 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21419 return false;
9ef920e9
NC
21420 }
21421
9ef920e9
NC
21422 ++ name;
21423 text = NULL;
21424
21425 switch ((name_attribute = * name))
21426 {
21427 case GNU_BUILD_ATTRIBUTE_VERSION:
21428 text = _("<version>");
1d15e434 21429 expected_types = string_expected;
9ef920e9
NC
21430 ++ name;
21431 break;
21432 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21433 text = _("<stack prot>");
75d7d298 21434 expected_types = "!+*";
9ef920e9
NC
21435 ++ name;
21436 break;
21437 case GNU_BUILD_ATTRIBUTE_RELRO:
21438 text = _("<relro>");
1d15e434 21439 expected_types = bool_expected;
9ef920e9
NC
21440 ++ name;
21441 break;
21442 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21443 text = _("<stack size>");
1d15e434 21444 expected_types = number_expected;
9ef920e9
NC
21445 ++ name;
21446 break;
21447 case GNU_BUILD_ATTRIBUTE_TOOL:
21448 text = _("<tool>");
1d15e434 21449 expected_types = string_expected;
9ef920e9
NC
21450 ++ name;
21451 break;
21452 case GNU_BUILD_ATTRIBUTE_ABI:
21453 text = _("<ABI>");
21454 expected_types = "$*";
21455 ++ name;
21456 break;
21457 case GNU_BUILD_ATTRIBUTE_PIC:
21458 text = _("<PIC>");
1d15e434 21459 expected_types = number_expected;
9ef920e9
NC
21460 ++ name;
21461 break;
a8be5506
NC
21462 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21463 text = _("<short enum>");
1d15e434 21464 expected_types = bool_expected;
a8be5506
NC
21465 ++ name;
21466 break;
9ef920e9
NC
21467 default:
21468 if (ISPRINT (* name))
21469 {
21470 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21471
21472 if (len > left && ! do_wide)
21473 len = left;
75d7d298 21474 printf ("%.*s:", len, name);
9ef920e9 21475 left -= len;
0dd6ae21 21476 name += len;
9ef920e9
NC
21477 }
21478 else
21479 {
3e6b6445 21480 static char tmpbuf [128];
88305e1b 21481
3e6b6445
NC
21482 error (_("unrecognised byte in name field: %d\n"), * name);
21483 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21484 text = tmpbuf;
21485 name ++;
9ef920e9
NC
21486 }
21487 expected_types = "*$!+";
21488 break;
21489 }
21490
21491 if (text)
88305e1b 21492 left -= printf ("%s", text);
9ef920e9
NC
21493
21494 if (strchr (expected_types, name_type) == NULL)
75d7d298 21495 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 21496
26c527e6 21497 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 21498 {
26c527e6
AM
21499 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
21500 pnote->namesz,
21501 name - pnote->namedata);
015dc7e1 21502 return false;
9ef920e9
NC
21503 }
21504
21505 if (left < 1 && ! do_wide)
015dc7e1 21506 return true;
9ef920e9
NC
21507
21508 switch (name_type)
21509 {
21510 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21511 {
26c527e6
AM
21512 unsigned int bytes;
21513 uint64_t val = 0;
21514 unsigned int shift = 0;
21515 char *decoded = NULL;
ddef72cd 21516
b06b2c92
NC
21517 bytes = pnote->namesz - (name - pnote->namedata);
21518 if (bytes > 0)
21519 /* The -1 is because the name field is always 0 terminated, and we
21520 want to be able to ensure that the shift in the while loop below
21521 will not overflow. */
21522 -- bytes;
21523
ddef72cd
NC
21524 if (bytes > sizeof (val))
21525 {
3e6b6445
NC
21526 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21527 bytes);
21528 bytes = sizeof (val);
ddef72cd 21529 }
3e6b6445
NC
21530 /* We do not bother to warn if bytes == 0 as this can
21531 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21532
21533 while (bytes --)
21534 {
26c527e6 21535 uint64_t byte = *name++ & 0xff;
79a964dc
NC
21536
21537 val |= byte << shift;
9ef920e9
NC
21538 shift += 8;
21539 }
21540
75d7d298 21541 switch (name_attribute)
9ef920e9 21542 {
75d7d298 21543 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21544 switch (val)
21545 {
75d7d298
NC
21546 case 0: decoded = "static"; break;
21547 case 1: decoded = "pic"; break;
21548 case 2: decoded = "PIC"; break;
21549 case 3: decoded = "pie"; break;
21550 case 4: decoded = "PIE"; break;
21551 default: break;
9ef920e9 21552 }
75d7d298
NC
21553 break;
21554 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21555 switch (val)
9ef920e9 21556 {
75d7d298
NC
21557 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21558 case 0: decoded = "off"; break;
21559 case 1: decoded = "on"; break;
21560 case 2: decoded = "all"; break;
21561 case 3: decoded = "strong"; break;
21562 case 4: decoded = "explicit"; break;
21563 default: break;
9ef920e9 21564 }
75d7d298
NC
21565 break;
21566 default:
21567 break;
9ef920e9
NC
21568 }
21569
75d7d298 21570 if (decoded != NULL)
3e6b6445
NC
21571 {
21572 print_symbol (-left, decoded);
21573 left = 0;
21574 }
21575 else if (val == 0)
21576 {
21577 printf ("0x0");
21578 left -= 3;
21579 }
9ef920e9 21580 else
75d7d298
NC
21581 {
21582 if (do_wide)
26c527e6 21583 left -= printf ("0x%" PRIx64, val);
75d7d298 21584 else
26c527e6 21585 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 21586 }
9ef920e9
NC
21587 }
21588 break;
21589 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21590 left -= print_symbol (- left, name);
21591 break;
21592 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21593 left -= print_symbol (- left, "true");
21594 break;
21595 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21596 left -= print_symbol (- left, "false");
21597 break;
21598 }
21599
21600 if (do_wide && left > 0)
21601 printf ("%-*s", left, " ");
9abca702 21602
015dc7e1 21603 return true;
9ef920e9
NC
21604}
21605
2952f10c
SM
21606/* Print the contents of PNOTE as hex. */
21607
21608static void
21609print_note_contents_hex (Elf_Internal_Note *pnote)
21610{
21611 if (pnote->descsz)
21612 {
26c527e6 21613 size_t i;
2952f10c
SM
21614
21615 printf (_(" description data: "));
21616 for (i = 0; i < pnote->descsz; i++)
21617 printf ("%02x ", pnote->descdata[i] & 0xff);
21618 if (!do_wide)
21619 printf ("\n");
21620 }
21621
21622 if (do_wide)
21623 printf ("\n");
21624}
21625
21626#if defined HAVE_MSGPACK
21627
21628static void
21629print_indents (int n)
21630{
21631 printf (" ");
21632
21633 for (int i = 0; i < n; i++)
21634 printf (" ");
21635}
21636
21637/* Print OBJ in human-readable form. */
21638
21639static void
21640dump_msgpack_obj (const msgpack_object *obj, int indent)
21641{
21642 switch (obj->type)
21643 {
21644 case MSGPACK_OBJECT_NIL:
21645 printf ("(nil)");
21646 break;
21647
21648 case MSGPACK_OBJECT_BOOLEAN:
21649 printf ("%s", obj->via.boolean ? "true" : "false");
21650 break;
21651
21652 case MSGPACK_OBJECT_POSITIVE_INTEGER:
21653 printf ("%" PRIu64, obj->via.u64);
21654 break;
21655
21656 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
21657 printf ("%" PRIi64, obj->via.i64);
21658 break;
21659
21660 case MSGPACK_OBJECT_FLOAT32:
21661 case MSGPACK_OBJECT_FLOAT64:
21662 printf ("%f", obj->via.f64);
21663 break;
21664
21665 case MSGPACK_OBJECT_STR:
21666 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
21667 break;
21668
21669 case MSGPACK_OBJECT_ARRAY:
21670 {
21671 const msgpack_object_array *array = &obj->via.array;
21672
21673 printf ("[\n");
21674 ++indent;
21675
21676 for (uint32_t i = 0; i < array->size; ++i)
21677 {
21678 const msgpack_object *item = &array->ptr[i];
21679
21680 print_indents (indent);
21681 dump_msgpack_obj (item, indent);
21682 printf (",\n");
21683 }
21684
21685 --indent;
21686 print_indents (indent);
21687 printf ("]");
21688 break;
21689 }
21690 break;
21691
21692 case MSGPACK_OBJECT_MAP:
21693 {
21694 const msgpack_object_map *map = &obj->via.map;
21695
21696 printf ("{\n");
21697 ++indent;
21698
21699 for (uint32_t i = 0; i < map->size; ++i)
21700 {
21701 const msgpack_object_kv *kv = &map->ptr[i];
21702 const msgpack_object *key = &kv->key;
21703 const msgpack_object *val = &kv->val;
21704
21705 print_indents (indent);
21706 dump_msgpack_obj (key, indent);
21707 printf (": ");
21708 dump_msgpack_obj (val, indent);
21709
21710 printf (",\n");
21711 }
21712
21713 --indent;
21714 print_indents (indent);
21715 printf ("}");
21716
21717 break;
21718 }
21719
21720 case MSGPACK_OBJECT_BIN:
21721 printf ("(bin)");
21722 break;
21723
21724 case MSGPACK_OBJECT_EXT:
21725 printf ("(ext)");
21726 break;
21727 }
21728}
21729
21730static void
21731dump_msgpack (const msgpack_unpacked *msg)
21732{
21733 print_indents (0);
21734 dump_msgpack_obj (&msg->data, 0);
21735 printf ("\n");
21736}
21737
21738#endif /* defined HAVE_MSGPACK */
21739
21740static bool
21741print_amdgpu_note (Elf_Internal_Note *pnote)
21742{
21743#if defined HAVE_MSGPACK
21744 /* If msgpack is available, decode and dump the note's content. */
21745 bool ret;
21746 msgpack_unpacked msg;
21747 msgpack_unpack_return msgpack_ret;
21748
21749 assert (pnote->type == NT_AMDGPU_METADATA);
21750
21751 msgpack_unpacked_init (&msg);
21752 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
21753 NULL);
21754
21755 switch (msgpack_ret)
21756 {
21757 case MSGPACK_UNPACK_SUCCESS:
21758 dump_msgpack (&msg);
21759 ret = true;
21760 break;
21761
21762 default:
21763 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
21764 ret = false;
21765 break;
21766 }
21767
21768 msgpack_unpacked_destroy (&msg);
21769 return ret;
21770#else
21771 /* msgpack is not available, dump contents as hex. */
21772 print_note_contents_hex (pnote);
21773 return true;
21774#endif
21775}
21776
e263a66b
CC
21777static bool
21778print_qnx_note (Elf_Internal_Note *pnote)
21779{
21780 switch (pnote->type)
21781 {
21782 case QNT_STACK:
21783 if (pnote->descsz != 12)
21784 goto desc_size_fail;
21785
21786 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
21787 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
21788 printf (_(" Stack allocated: %" PRIx32 "\n"),
21789 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
21790 printf (_(" Executable: %s\n"),
21791 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
21792 break;
21793
21794 default:
21795 print_note_contents_hex(pnote);
21796 }
21797 return true;
21798
21799desc_size_fail:
21800 printf (_(" <corrupt - data size is too small>\n"));
21801 error (_("corrupt QNX note: data size is too small\n"));
21802 return false;
21803}
21804
21805
6d118b09
NC
21806/* Note that by the ELF standard, the name field is already null byte
21807 terminated, and namesz includes the terminating null byte.
21808 I.E. the value of namesz for the name "FSF" is 4.
21809
e3c8793a 21810 If the value of namesz is zero, there is no name present. */
9ef920e9 21811
015dc7e1 21812static bool
9ef920e9 21813process_note (Elf_Internal_Note * pnote,
dda8d76d 21814 Filedata * filedata)
779fe533 21815{
2cf0635d
NC
21816 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21817 const char * nt;
9437c45b
JT
21818
21819 if (pnote->namesz == 0)
1ec5cd37
NC
21820 /* If there is no note name, then use the default set of
21821 note type strings. */
dda8d76d 21822 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21823
24d127aa 21824 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21825 /* GNU-specific object file notes. */
21826 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21827
28cdbb18
SM
21828 else if (startswith (pnote->namedata, "AMDGPU"))
21829 /* AMDGPU-specific object file notes. */
21830 nt = get_amdgpu_elf_note_type (pnote->type);
21831
24d127aa 21832 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21833 /* FreeBSD-specific core file notes. */
dda8d76d 21834 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21835
24d127aa 21836 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21837 /* NetBSD-specific core file notes. */
dda8d76d 21838 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21839
24d127aa 21840 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21841 /* NetBSD-specific core file notes. */
21842 return process_netbsd_elf_note (pnote);
21843
24d127aa 21844 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21845 /* NetBSD-specific core file notes. */
21846 return process_netbsd_elf_note (pnote);
21847
98ca73af
FC
21848 else if (startswith (pnote->namedata, "OpenBSD"))
21849 /* OpenBSD-specific core file notes. */
21850 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21851
e263a66b
CC
21852 else if (startswith (pnote->namedata, "QNX"))
21853 /* QNX-specific core file notes. */
21854 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
21855
e9b095a5 21856 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21857 {
21858 /* SPU-specific core file notes. */
21859 nt = pnote->namedata + 4;
21860 name = "SPU";
21861 }
21862
24d127aa 21863 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21864 /* VMS/ia64-specific file notes. */
21865 nt = get_ia64_vms_note_type (pnote->type);
21866
24d127aa 21867 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21868 nt = get_stapsdt_note_type (pnote->type);
21869
9437c45b 21870 else
1ec5cd37
NC
21871 /* Don't recognize this note name; just use the default set of
21872 note type strings. */
dda8d76d 21873 nt = get_note_type (filedata, pnote->type);
9437c45b 21874
1449284b 21875 printf (" ");
9ef920e9 21876
24d127aa 21877 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21878 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21879 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21880 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21881 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21882 print_gnu_build_attribute_name (pnote);
21883 else
21884 print_symbol (-20, name);
21885
21886 if (do_wide)
21887 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21888 else
21889 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21890
24d127aa 21891 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21892 return print_ia64_vms_note (pnote);
24d127aa 21893 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21894 return print_gnu_note (filedata, pnote);
24d127aa 21895 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21896 return print_stapsdt_note (pnote);
24d127aa 21897 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21898 return print_core_note (pnote);
e5382207
LB
21899 else if (startswith (pnote->namedata, "FDO"))
21900 return print_fdo_note (pnote);
24d127aa 21901 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21902 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21903 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21904 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21905 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21906 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
21907 else if (startswith (pnote->namedata, "AMDGPU")
21908 && pnote->type == NT_AMDGPU_METADATA)
21909 return print_amdgpu_note (pnote);
e263a66b
CC
21910 else if (startswith (pnote->namedata, "QNX"))
21911 return print_qnx_note (pnote);
779fe533 21912
2952f10c 21913 print_note_contents_hex (pnote);
015dc7e1 21914 return true;
1449284b 21915}
6d118b09 21916
015dc7e1 21917static bool
dda8d76d
NC
21918process_notes_at (Filedata * filedata,
21919 Elf_Internal_Shdr * section,
625d49fc
AM
21920 uint64_t offset,
21921 uint64_t length,
21922 uint64_t align)
779fe533 21923{
015dc7e1
AM
21924 Elf_External_Note *pnotes;
21925 Elf_External_Note *external;
21926 char *end;
21927 bool res = true;
103f02d3 21928
779fe533 21929 if (length <= 0)
015dc7e1 21930 return false;
103f02d3 21931
1449284b
NC
21932 if (section)
21933 {
dda8d76d 21934 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21935 if (pnotes)
32ec8896 21936 {
dda8d76d 21937 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21938 {
21939 free (pnotes);
015dc7e1 21940 return false;
f761cb13 21941 }
32ec8896 21942 }
1449284b
NC
21943 }
21944 else
82ed9683 21945 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21946 _("notes"));
4dff97b2 21947
dd24e3da 21948 if (pnotes == NULL)
015dc7e1 21949 return false;
779fe533 21950
103f02d3 21951 external = pnotes;
103f02d3 21952
ca0e11aa
NC
21953 if (filedata->is_separate)
21954 printf (_("In linked file '%s': "), filedata->file_name);
21955 else
21956 printf ("\n");
1449284b 21957 if (section)
ca0e11aa 21958 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21959 else
26c527e6
AM
21960 printf (_("Displaying notes found at file offset 0x%08" PRIx64
21961 " with length 0x%08" PRIx64 ":\n"),
21962 offset, length);
1449284b 21963
82ed9683
L
21964 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21965 specifies that notes should be aligned to 4 bytes in 32-bit
21966 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21967 we also support 4 byte alignment in 64-bit objects. If section
21968 alignment is less than 4, we treate alignment as 4 bytes. */
21969 if (align < 4)
21970 align = 4;
21971 else if (align != 4 && align != 8)
21972 {
26c527e6
AM
21973 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
21974 align);
a788aedd 21975 free (pnotes);
015dc7e1 21976 return false;
82ed9683
L
21977 }
21978
dbe15e4e 21979 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21980
c8071705
NC
21981 end = (char *) pnotes + length;
21982 while ((char *) external < end)
779fe533 21983 {
b34976b6 21984 Elf_Internal_Note inote;
15b42fb0 21985 size_t min_notesz;
4dff97b2 21986 char * next;
2cf0635d 21987 char * temp = NULL;
c8071705 21988 size_t data_remaining = end - (char *) external;
6d118b09 21989
dda8d76d 21990 if (!is_ia64_vms (filedata))
15b42fb0 21991 {
9dd3a467
NC
21992 /* PR binutils/15191
21993 Make sure that there is enough data to read. */
15b42fb0
AM
21994 min_notesz = offsetof (Elf_External_Note, name);
21995 if (data_remaining < min_notesz)
9dd3a467 21996 {
26c527e6 21997 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 21998 "not enough for a full note\n",
26c527e6 21999 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22000 "not enough for a full note\n",
22001 data_remaining),
26c527e6 22002 data_remaining);
9dd3a467
NC
22003 break;
22004 }
5396a86e
AM
22005 data_remaining -= min_notesz;
22006
15b42fb0
AM
22007 inote.type = BYTE_GET (external->type);
22008 inote.namesz = BYTE_GET (external->namesz);
22009 inote.namedata = external->name;
22010 inote.descsz = BYTE_GET (external->descsz);
276da9b3 22011 inote.descdata = ((char *) external
4dff97b2 22012 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 22013 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 22014 next = ((char *) external
4dff97b2 22015 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 22016 }
00e98fc7 22017 else
15b42fb0
AM
22018 {
22019 Elf64_External_VMS_Note *vms_external;
00e98fc7 22020
9dd3a467
NC
22021 /* PR binutils/15191
22022 Make sure that there is enough data to read. */
15b42fb0
AM
22023 min_notesz = offsetof (Elf64_External_VMS_Note, name);
22024 if (data_remaining < min_notesz)
9dd3a467 22025 {
26c527e6 22026 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22027 "not enough for a full note\n",
26c527e6 22028 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22029 "not enough for a full note\n",
22030 data_remaining),
26c527e6 22031 data_remaining);
9dd3a467
NC
22032 break;
22033 }
5396a86e 22034 data_remaining -= min_notesz;
3e55a963 22035
15b42fb0
AM
22036 vms_external = (Elf64_External_VMS_Note *) external;
22037 inote.type = BYTE_GET (vms_external->type);
22038 inote.namesz = BYTE_GET (vms_external->namesz);
22039 inote.namedata = vms_external->name;
22040 inote.descsz = BYTE_GET (vms_external->descsz);
22041 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
22042 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22043 next = inote.descdata + align_power (inote.descsz, 3);
22044 }
22045
5396a86e
AM
22046 /* PR 17531: file: 3443835e. */
22047 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
22048 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
22049 || (size_t) (inote.descdata - inote.namedata) > data_remaining
22050 || (size_t) (next - inote.descdata) < inote.descsz
22051 || ((size_t) (next - inote.descdata)
22052 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 22053 {
26c527e6
AM
22054 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
22055 (char *) external - (char *) pnotes);
22056 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 22057 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
22058 break;
22059 }
22060
15b42fb0 22061 external = (Elf_External_Note *) next;
dd24e3da 22062
6d118b09
NC
22063 /* Verify that name is null terminated. It appears that at least
22064 one version of Linux (RedHat 6.0) generates corefiles that don't
22065 comply with the ELF spec by failing to include the null byte in
22066 namesz. */
18344509 22067 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 22068 {
5396a86e 22069 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 22070 {
5396a86e
AM
22071 temp = (char *) malloc (inote.namesz + 1);
22072 if (temp == NULL)
22073 {
22074 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 22075 res = false;
5396a86e
AM
22076 break;
22077 }
76da6bbe 22078
5396a86e
AM
22079 memcpy (temp, inote.namedata, inote.namesz);
22080 inote.namedata = temp;
22081 }
22082 inote.namedata[inote.namesz] = 0;
6d118b09
NC
22083 }
22084
dda8d76d 22085 if (! process_note (& inote, filedata))
015dc7e1 22086 res = false;
103f02d3 22087
9db70fc3
AM
22088 free (temp);
22089 temp = NULL;
779fe533
NC
22090 }
22091
22092 free (pnotes);
103f02d3 22093
779fe533
NC
22094 return res;
22095}
22096
015dc7e1 22097static bool
dda8d76d 22098process_corefile_note_segments (Filedata * filedata)
779fe533 22099{
015dc7e1 22100 Elf_Internal_Phdr *segment;
b34976b6 22101 unsigned int i;
015dc7e1 22102 bool res = true;
103f02d3 22103
dda8d76d 22104 if (! get_program_headers (filedata))
015dc7e1 22105 return true;
103f02d3 22106
dda8d76d
NC
22107 for (i = 0, segment = filedata->program_headers;
22108 i < filedata->file_header.e_phnum;
b34976b6 22109 i++, segment++)
779fe533
NC
22110 {
22111 if (segment->p_type == PT_NOTE)
625d49fc
AM
22112 if (! process_notes_at (filedata, NULL, segment->p_offset,
22113 segment->p_filesz, segment->p_align))
015dc7e1 22114 res = false;
779fe533 22115 }
103f02d3 22116
779fe533
NC
22117 return res;
22118}
22119
015dc7e1 22120static bool
625d49fc 22121process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
22122{
22123 Elf_External_Note * pnotes;
22124 Elf_External_Note * external;
c8071705 22125 char * end;
015dc7e1 22126 bool res = true;
685080f2
NC
22127
22128 if (length <= 0)
015dc7e1 22129 return false;
685080f2 22130
dda8d76d 22131 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
22132 _("v850 notes"));
22133 if (pnotes == NULL)
015dc7e1 22134 return false;
685080f2
NC
22135
22136 external = pnotes;
c8071705 22137 end = (char*) pnotes + length;
685080f2 22138
26c527e6
AM
22139 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22140 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22141 offset, length);
685080f2 22142
c8071705 22143 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
22144 {
22145 Elf_External_Note * next;
22146 Elf_Internal_Note inote;
22147
22148 inote.type = BYTE_GET (external->type);
22149 inote.namesz = BYTE_GET (external->namesz);
22150 inote.namedata = external->name;
22151 inote.descsz = BYTE_GET (external->descsz);
22152 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22153 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22154
c8071705
NC
22155 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22156 {
22157 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22158 inote.descdata = inote.namedata;
22159 inote.namesz = 0;
22160 }
22161
685080f2
NC
22162 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22163
c8071705 22164 if ( ((char *) next > end)
685080f2
NC
22165 || ((char *) next < (char *) pnotes))
22166 {
26c527e6
AM
22167 warn (_("corrupt descsz found in note at offset %#tx\n"),
22168 (char *) external - (char *) pnotes);
22169 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22170 inote.type, inote.namesz, inote.descsz);
22171 break;
22172 }
22173
22174 external = next;
22175
22176 /* Prevent out-of-bounds indexing. */
c8071705 22177 if ( inote.namedata + inote.namesz > end
685080f2
NC
22178 || inote.namedata + inote.namesz < inote.namedata)
22179 {
26c527e6
AM
22180 warn (_("corrupt namesz found in note at offset %#zx\n"),
22181 (char *) external - (char *) pnotes);
22182 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22183 inote.type, inote.namesz, inote.descsz);
22184 break;
22185 }
22186
22187 printf (" %s: ", get_v850_elf_note_type (inote.type));
22188
22189 if (! print_v850_note (& inote))
22190 {
015dc7e1 22191 res = false;
26c527e6 22192 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
22193 inote.namesz, inote.descsz);
22194 }
22195 }
22196
22197 free (pnotes);
22198
22199 return res;
22200}
22201
015dc7e1 22202static bool
dda8d76d 22203process_note_sections (Filedata * filedata)
1ec5cd37 22204{
015dc7e1 22205 Elf_Internal_Shdr *section;
26c527e6 22206 size_t i;
32ec8896 22207 unsigned int n = 0;
015dc7e1 22208 bool res = true;
1ec5cd37 22209
dda8d76d
NC
22210 for (i = 0, section = filedata->section_headers;
22211 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 22212 i++, section++)
685080f2
NC
22213 {
22214 if (section->sh_type == SHT_NOTE)
22215 {
625d49fc
AM
22216 if (! process_notes_at (filedata, section, section->sh_offset,
22217 section->sh_size, section->sh_addralign))
015dc7e1 22218 res = false;
685080f2
NC
22219 n++;
22220 }
22221
dda8d76d
NC
22222 if (( filedata->file_header.e_machine == EM_V800
22223 || filedata->file_header.e_machine == EM_V850
22224 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
22225 && section->sh_type == SHT_RENESAS_INFO)
22226 {
625d49fc
AM
22227 if (! process_v850_notes (filedata, section->sh_offset,
22228 section->sh_size))
015dc7e1 22229 res = false;
685080f2
NC
22230 n++;
22231 }
22232 }
df565f32
NC
22233
22234 if (n == 0)
22235 /* Try processing NOTE segments instead. */
dda8d76d 22236 return process_corefile_note_segments (filedata);
1ec5cd37
NC
22237
22238 return res;
22239}
22240
015dc7e1 22241static bool
dda8d76d 22242process_notes (Filedata * filedata)
779fe533
NC
22243{
22244 /* If we have not been asked to display the notes then do nothing. */
22245 if (! do_notes)
015dc7e1 22246 return true;
103f02d3 22247
dda8d76d
NC
22248 if (filedata->file_header.e_type != ET_CORE)
22249 return process_note_sections (filedata);
103f02d3 22250
779fe533 22251 /* No program headers means no NOTE segment. */
dda8d76d
NC
22252 if (filedata->file_header.e_phnum > 0)
22253 return process_corefile_note_segments (filedata);
779fe533 22254
ca0e11aa
NC
22255 if (filedata->is_separate)
22256 printf (_("No notes found in linked file '%s'.\n"),
22257 filedata->file_name);
22258 else
22259 printf (_("No notes found file.\n"));
22260
015dc7e1 22261 return true;
779fe533
NC
22262}
22263
60abdbed
NC
22264static unsigned char *
22265display_public_gnu_attributes (unsigned char * start,
22266 const unsigned char * const end)
22267{
22268 printf (_(" Unknown GNU attribute: %s\n"), start);
22269
22270 start += strnlen ((char *) start, end - start);
22271 display_raw_attribute (start, end);
22272
22273 return (unsigned char *) end;
22274}
22275
22276static unsigned char *
22277display_generic_attribute (unsigned char * start,
22278 unsigned int tag,
22279 const unsigned char * const end)
22280{
22281 if (tag == 0)
22282 return (unsigned char *) end;
22283
22284 return display_tag_value (tag, start, end);
22285}
22286
015dc7e1 22287static bool
dda8d76d 22288process_arch_specific (Filedata * filedata)
252b5132 22289{
a952a375 22290 if (! do_arch)
015dc7e1 22291 return true;
a952a375 22292
dda8d76d 22293 switch (filedata->file_header.e_machine)
252b5132 22294 {
53a346d8
CZ
22295 case EM_ARC:
22296 case EM_ARC_COMPACT:
22297 case EM_ARC_COMPACT2:
dda8d76d 22298 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
22299 display_arc_attribute,
22300 display_generic_attribute);
11c1ff18 22301 case EM_ARM:
dda8d76d 22302 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
22303 display_arm_attribute,
22304 display_generic_attribute);
22305
252b5132 22306 case EM_MIPS:
4fe85591 22307 case EM_MIPS_RS3_LE:
dda8d76d 22308 return process_mips_specific (filedata);
60abdbed
NC
22309
22310 case EM_MSP430:
dda8d76d 22311 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 22312 display_msp430_attribute,
c0ea7c52 22313 display_msp430_gnu_attribute);
60abdbed 22314
2dc8dd17
JW
22315 case EM_RISCV:
22316 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22317 display_riscv_attribute,
22318 display_generic_attribute);
22319
35c08157 22320 case EM_NDS32:
dda8d76d 22321 return process_nds32_specific (filedata);
60abdbed 22322
85f7484a
PB
22323 case EM_68K:
22324 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22325 display_m68k_gnu_attribute);
22326
34c8bcba 22327 case EM_PPC:
b82317dd 22328 case EM_PPC64:
dda8d76d 22329 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22330 display_power_gnu_attribute);
22331
643f7afb
AK
22332 case EM_S390:
22333 case EM_S390_OLD:
dda8d76d 22334 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22335 display_s390_gnu_attribute);
22336
9e8c70f9
DM
22337 case EM_SPARC:
22338 case EM_SPARC32PLUS:
22339 case EM_SPARCV9:
dda8d76d 22340 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22341 display_sparc_gnu_attribute);
22342
59e6276b 22343 case EM_TI_C6000:
dda8d76d 22344 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22345 display_tic6x_attribute,
22346 display_generic_attribute);
22347
0861f561
CQ
22348 case EM_CSKY:
22349 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22350 display_csky_attribute, NULL);
22351
252b5132 22352 default:
dda8d76d 22353 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22354 display_public_gnu_attributes,
22355 display_generic_attribute);
252b5132 22356 }
252b5132
RH
22357}
22358
015dc7e1 22359static bool
dda8d76d 22360get_file_header (Filedata * filedata)
252b5132 22361{
9ea033b2 22362 /* Read in the identity array. */
dda8d76d 22363 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22364 return false;
252b5132 22365
9ea033b2 22366 /* Determine how to read the rest of the header. */
dda8d76d 22367 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22368 {
1a0670f3
AM
22369 default:
22370 case ELFDATANONE:
adab8cdc
AO
22371 case ELFDATA2LSB:
22372 byte_get = byte_get_little_endian;
22373 byte_put = byte_put_little_endian;
22374 break;
22375 case ELFDATA2MSB:
22376 byte_get = byte_get_big_endian;
22377 byte_put = byte_put_big_endian;
22378 break;
9ea033b2
NC
22379 }
22380
22381 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22382 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22383
22384 /* Read in the rest of the header. */
22385 if (is_32bit_elf)
22386 {
22387 Elf32_External_Ehdr ehdr32;
252b5132 22388
dda8d76d 22389 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22390 return false;
103f02d3 22391
dda8d76d
NC
22392 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22393 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22394 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22395 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22396 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22397 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22398 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22399 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22400 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22401 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22402 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22403 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22404 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22405 }
252b5132 22406 else
9ea033b2
NC
22407 {
22408 Elf64_External_Ehdr ehdr64;
a952a375 22409
dda8d76d 22410 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22411 return false;
103f02d3 22412
dda8d76d
NC
22413 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22414 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22415 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22416 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22417 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22418 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22419 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22420 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22421 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22422 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22423 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22424 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22425 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22426 }
252b5132 22427
015dc7e1 22428 return true;
252b5132
RH
22429}
22430
13acb58d
AM
22431static void
22432free_filedata (Filedata *filedata)
22433{
22434 free (filedata->program_interpreter);
13acb58d 22435 free (filedata->program_headers);
13acb58d 22436 free (filedata->section_headers);
13acb58d 22437 free (filedata->string_table);
13acb58d 22438 free (filedata->dump.dump_sects);
13acb58d 22439 free (filedata->dynamic_strings);
13acb58d 22440 free (filedata->dynamic_symbols);
13acb58d 22441 free (filedata->dynamic_syminfo);
13acb58d 22442 free (filedata->dynamic_section);
13acb58d
AM
22443
22444 while (filedata->symtab_shndx_list != NULL)
22445 {
22446 elf_section_list *next = filedata->symtab_shndx_list->next;
22447 free (filedata->symtab_shndx_list);
22448 filedata->symtab_shndx_list = next;
22449 }
22450
22451 free (filedata->section_headers_groups);
13acb58d
AM
22452
22453 if (filedata->section_groups)
22454 {
22455 size_t i;
22456 struct group_list * g;
22457 struct group_list * next;
22458
22459 for (i = 0; i < filedata->group_count; i++)
22460 {
22461 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22462 {
22463 next = g->next;
22464 free (g);
22465 }
22466 }
22467
22468 free (filedata->section_groups);
13acb58d 22469 }
066f8fbe
AM
22470 memset (&filedata->section_headers, 0,
22471 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22472}
22473
dda8d76d
NC
22474static void
22475close_file (Filedata * filedata)
22476{
22477 if (filedata)
22478 {
22479 if (filedata->handle)
22480 fclose (filedata->handle);
22481 free (filedata);
22482 }
22483}
22484
22485void
22486close_debug_file (void * data)
22487{
13acb58d 22488 free_filedata ((Filedata *) data);
dda8d76d
NC
22489 close_file ((Filedata *) data);
22490}
22491
22492static Filedata *
015dc7e1 22493open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22494{
22495 struct stat statbuf;
22496 Filedata * filedata = NULL;
22497
22498 if (stat (pathname, & statbuf) < 0
22499 || ! S_ISREG (statbuf.st_mode))
22500 goto fail;
22501
22502 filedata = calloc (1, sizeof * filedata);
22503 if (filedata == NULL)
22504 goto fail;
22505
22506 filedata->handle = fopen (pathname, "rb");
22507 if (filedata->handle == NULL)
22508 goto fail;
22509
be7d229a 22510 filedata->file_size = statbuf.st_size;
dda8d76d 22511 filedata->file_name = pathname;
ca0e11aa 22512 filedata->is_separate = is_separate;
dda8d76d
NC
22513
22514 if (! get_file_header (filedata))
22515 goto fail;
22516
4de91c10
AM
22517 if (!get_section_headers (filedata, false))
22518 goto fail;
dda8d76d
NC
22519
22520 return filedata;
22521
22522 fail:
22523 if (filedata)
22524 {
22525 if (filedata->handle)
22526 fclose (filedata->handle);
22527 free (filedata);
22528 }
22529 return NULL;
22530}
22531
22532void *
22533open_debug_file (const char * pathname)
22534{
015dc7e1 22535 return open_file (pathname, true);
dda8d76d
NC
22536}
22537
835f2fae
NC
22538static void
22539initialise_dump_sects (Filedata * filedata)
22540{
22541 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22542 Note we do this even if cmdline_dump_sects is empty because we
22543 must make sure that the dump_sets array is zeroed out before each
22544 object file is processed. */
22545 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22546 memset (filedata->dump.dump_sects, 0,
22547 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22548
22549 if (cmdline.num_dump_sects > 0)
22550 {
22551 if (filedata->dump.num_dump_sects == 0)
22552 /* A sneaky way of allocating the dump_sects array. */
22553 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22554
22555 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22556 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22557 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22558 }
22559}
22560
94585d6d
NC
22561static bool
22562might_need_separate_debug_info (Filedata * filedata)
22563{
22564 /* Debuginfo files do not need further separate file loading. */
22565 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22566 return false;
22567
22568 /* Since do_follow_links might be enabled by default, only treat it as an
22569 indication that separate files should be loaded if setting it was a
22570 deliberate user action. */
22571 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22572 return true;
22573
22574 if (process_links || do_syms || do_unwind
22575 || dump_any_debugging || do_dump || do_debugging)
22576 return true;
22577
22578 return false;
22579}
22580
fb52b2f4
NC
22581/* Process one ELF object file according to the command line options.
22582 This file may actually be stored in an archive. The file is
32ec8896
NC
22583 positioned at the start of the ELF object. Returns TRUE if no
22584 problems were encountered, FALSE otherwise. */
fb52b2f4 22585
015dc7e1 22586static bool
dda8d76d 22587process_object (Filedata * filedata)
252b5132 22588{
015dc7e1 22589 bool have_separate_files;
252b5132 22590 unsigned int i;
015dc7e1 22591 bool res;
252b5132 22592
dda8d76d 22593 if (! get_file_header (filedata))
252b5132 22594 {
dda8d76d 22595 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22596 return false;
252b5132
RH
22597 }
22598
22599 /* Initialise per file variables. */
978c4450
AM
22600 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22601 filedata->version_info[i] = 0;
252b5132 22602
978c4450
AM
22603 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22604 filedata->dynamic_info[i] = 0;
22605 filedata->dynamic_info_DT_GNU_HASH = 0;
22606 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22607
22608 /* Process the file. */
22609 if (show_name)
dda8d76d 22610 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22611
835f2fae 22612 initialise_dump_sects (filedata);
d70c5fc7 22613
4de91c10
AM
22614 /* There may be some extensions in the first section header. Don't
22615 bomb if we can't read it. */
22616 get_section_headers (filedata, true);
22617
dda8d76d 22618 if (! process_file_header (filedata))
4de91c10
AM
22619 {
22620 res = false;
22621 goto out;
22622 }
252b5132 22623
e331b18d
AM
22624 /* Throw away the single section header read above, so that we
22625 re-read the entire set. */
22626 free (filedata->section_headers);
22627 filedata->section_headers = NULL;
22628
dda8d76d 22629 if (! process_section_headers (filedata))
2f62977e 22630 {
32ec8896 22631 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22632 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22633
2f62977e 22634 if (! do_using_dynamic)
015dc7e1 22635 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22636 }
252b5132 22637
dda8d76d 22638 if (! process_section_groups (filedata))
32ec8896 22639 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22640 do_unwind = false;
d1f5c6e3 22641
93df3340
AM
22642 process_program_headers (filedata);
22643
22644 res = process_dynamic_section (filedata);
252b5132 22645
dda8d76d 22646 if (! process_relocs (filedata))
015dc7e1 22647 res = false;
252b5132 22648
dda8d76d 22649 if (! process_unwind (filedata))
015dc7e1 22650 res = false;
4d6ed7c8 22651
dda8d76d 22652 if (! process_symbol_table (filedata))
015dc7e1 22653 res = false;
252b5132 22654
0f03783c 22655 if (! process_lto_symbol_tables (filedata))
015dc7e1 22656 res = false;
b9e920ec 22657
dda8d76d 22658 if (! process_syminfo (filedata))
015dc7e1 22659 res = false;
252b5132 22660
dda8d76d 22661 if (! process_version_sections (filedata))
015dc7e1 22662 res = false;
252b5132 22663
94585d6d 22664 if (might_need_separate_debug_info (filedata))
24841daa 22665 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22666 else
015dc7e1 22667 have_separate_files = false;
dda8d76d
NC
22668
22669 if (! process_section_contents (filedata))
015dc7e1 22670 res = false;
f5842774 22671
24841daa 22672 if (have_separate_files)
dda8d76d 22673 {
24841daa
NC
22674 separate_info * d;
22675
22676 for (d = first_separate_info; d != NULL; d = d->next)
22677 {
835f2fae
NC
22678 initialise_dump_sects (d->handle);
22679
ca0e11aa 22680 if (process_links && ! process_file_header (d->handle))
015dc7e1 22681 res = false;
ca0e11aa 22682 else if (! process_section_headers (d->handle))
015dc7e1 22683 res = false;
d6bfbc39 22684 else if (! process_section_contents (d->handle))
015dc7e1 22685 res = false;
ca0e11aa
NC
22686 else if (process_links)
22687 {
ca0e11aa 22688 if (! process_section_groups (d->handle))
015dc7e1 22689 res = false;
93df3340 22690 process_program_headers (d->handle);
ca0e11aa 22691 if (! process_dynamic_section (d->handle))
015dc7e1 22692 res = false;
ca0e11aa 22693 if (! process_relocs (d->handle))
015dc7e1 22694 res = false;
ca0e11aa 22695 if (! process_unwind (d->handle))
015dc7e1 22696 res = false;
ca0e11aa 22697 if (! process_symbol_table (d->handle))
015dc7e1 22698 res = false;
ca0e11aa 22699 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22700 res = false;
ca0e11aa 22701 if (! process_syminfo (d->handle))
015dc7e1 22702 res = false;
ca0e11aa 22703 if (! process_version_sections (d->handle))
015dc7e1 22704 res = false;
ca0e11aa 22705 if (! process_notes (d->handle))
015dc7e1 22706 res = false;
ca0e11aa 22707 }
24841daa
NC
22708 }
22709
22710 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22711 }
22712
22713 if (! process_notes (filedata))
015dc7e1 22714 res = false;
103f02d3 22715
dda8d76d 22716 if (! process_gnu_liblist (filedata))
015dc7e1 22717 res = false;
047b2264 22718
dda8d76d 22719 if (! process_arch_specific (filedata))
015dc7e1 22720 res = false;
252b5132 22721
4de91c10 22722 out:
13acb58d 22723 free_filedata (filedata);
e4b17d5c 22724
19e6b90e 22725 free_debug_memory ();
18bd398b 22726
32ec8896 22727 return res;
252b5132
RH
22728}
22729
2cf0635d 22730/* Process an ELF archive.
32ec8896
NC
22731 On entry the file is positioned just after the ARMAG string.
22732 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22733
015dc7e1
AM
22734static bool
22735process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22736{
22737 struct archive_info arch;
22738 struct archive_info nested_arch;
22739 size_t got;
015dc7e1 22740 bool ret = true;
2cf0635d 22741
015dc7e1 22742 show_name = true;
2cf0635d
NC
22743
22744 /* The ARCH structure is used to hold information about this archive. */
22745 arch.file_name = NULL;
22746 arch.file = NULL;
22747 arch.index_array = NULL;
22748 arch.sym_table = NULL;
22749 arch.longnames = NULL;
22750
22751 /* The NESTED_ARCH structure is used as a single-item cache of information
22752 about a nested archive (when members of a thin archive reside within
22753 another regular archive file). */
22754 nested_arch.file_name = NULL;
22755 nested_arch.file = NULL;
22756 nested_arch.index_array = NULL;
22757 nested_arch.sym_table = NULL;
22758 nested_arch.longnames = NULL;
22759
dda8d76d 22760 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22761 filedata->file_size, is_thin_archive,
22762 do_archive_index) != 0)
2cf0635d 22763 {
015dc7e1 22764 ret = false;
2cf0635d 22765 goto out;
4145f1d5 22766 }
fb52b2f4 22767
4145f1d5
NC
22768 if (do_archive_index)
22769 {
2cf0635d 22770 if (arch.sym_table == NULL)
1cb7d8b1
AM
22771 error (_("%s: unable to dump the index as none was found\n"),
22772 filedata->file_name);
4145f1d5
NC
22773 else
22774 {
26c527e6
AM
22775 uint64_t i, l;
22776 uint64_t current_pos;
4145f1d5 22777
26c527e6
AM
22778 printf (_("Index of archive %s: (%" PRIu64 " entries,"
22779 " %#" PRIx64 " bytes in the symbol table)\n"),
22780 filedata->file_name, arch.index_num,
1cb7d8b1 22781 arch.sym_size);
dda8d76d
NC
22782
22783 current_pos = ftell (filedata->handle);
4145f1d5 22784
2cf0635d 22785 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22786 {
1cb7d8b1
AM
22787 if (i == 0
22788 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22789 {
22790 char * member_name
22791 = get_archive_member_name_at (&arch, arch.index_array[i],
22792 &nested_arch);
2cf0635d 22793
1cb7d8b1
AM
22794 if (member_name != NULL)
22795 {
22796 char * qualified_name
22797 = make_qualified_name (&arch, &nested_arch,
22798 member_name);
2cf0635d 22799
1cb7d8b1
AM
22800 if (qualified_name != NULL)
22801 {
22802 printf (_("Contents of binary %s at offset "),
22803 qualified_name);
c2a7d3f5
NC
22804 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22805 putchar ('\n');
1cb7d8b1
AM
22806 free (qualified_name);
22807 }
fd486f32 22808 free (member_name);
4145f1d5
NC
22809 }
22810 }
2cf0635d
NC
22811
22812 if (l >= arch.sym_size)
4145f1d5 22813 {
1cb7d8b1
AM
22814 error (_("%s: end of the symbol table reached "
22815 "before the end of the index\n"),
dda8d76d 22816 filedata->file_name);
015dc7e1 22817 ret = false;
cb8f3167 22818 break;
4145f1d5 22819 }
591f7597 22820 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22821 printf ("\t%.*s\n",
22822 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22823 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22824 }
22825
67ce483b 22826 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22827 l = (l + 7) & ~ 7;
22828 else
22829 l += l & 1;
22830
2cf0635d 22831 if (l < arch.sym_size)
32ec8896 22832 {
26c527e6 22833 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
22834 "but without corresponding entries in "
22835 "the index table\n",
26c527e6 22836 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
22837 "but without corresponding entries in "
22838 "the index table\n",
22839 arch.sym_size - l),
dda8d76d 22840 filedata->file_name, arch.sym_size - l);
015dc7e1 22841 ret = false;
32ec8896 22842 }
4145f1d5 22843
63cf857e 22844 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22845 {
1cb7d8b1
AM
22846 error (_("%s: failed to seek back to start of object files "
22847 "in the archive\n"),
dda8d76d 22848 filedata->file_name);
015dc7e1 22849 ret = false;
2cf0635d 22850 goto out;
4145f1d5 22851 }
fb52b2f4 22852 }
4145f1d5
NC
22853
22854 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22855 && !do_segments && !do_header && !do_dump && !do_version
22856 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22857 && !do_section_groups && !do_dyn_syms)
2cf0635d 22858 {
015dc7e1 22859 ret = true; /* Archive index only. */
2cf0635d
NC
22860 goto out;
22861 }
fb52b2f4
NC
22862 }
22863
fb52b2f4
NC
22864 while (1)
22865 {
2cf0635d
NC
22866 char * name;
22867 size_t namelen;
22868 char * qualified_name;
22869
22870 /* Read the next archive header. */
63cf857e 22871 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22872 {
22873 error (_("%s: failed to seek to next archive header\n"),
22874 arch.file_name);
015dc7e1 22875 ret = false;
1cb7d8b1
AM
22876 break;
22877 }
dda8d76d 22878 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22879 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22880 {
22881 if (got == 0)
2cf0635d 22882 break;
28e817cc
NC
22883 /* PR 24049 - we cannot use filedata->file_name as this will
22884 have already been freed. */
22885 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22886
015dc7e1 22887 ret = false;
1cb7d8b1
AM
22888 break;
22889 }
2cf0635d 22890 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22891 {
22892 error (_("%s: did not find a valid archive header\n"),
22893 arch.file_name);
015dc7e1 22894 ret = false;
1cb7d8b1
AM
22895 break;
22896 }
2cf0635d
NC
22897
22898 arch.next_arhdr_offset += sizeof arch.arhdr;
22899
978c4450 22900 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22901
22902 name = get_archive_member_name (&arch, &nested_arch);
22903 if (name == NULL)
fb52b2f4 22904 {
28e817cc 22905 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22906 ret = false;
d989285c 22907 break;
fb52b2f4 22908 }
2cf0635d 22909 namelen = strlen (name);
fb52b2f4 22910
2cf0635d
NC
22911 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22912 if (qualified_name == NULL)
fb52b2f4 22913 {
28e817cc 22914 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22915 free (name);
015dc7e1 22916 ret = false;
d989285c 22917 break;
fb52b2f4
NC
22918 }
22919
2cf0635d 22920 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22921 {
22922 /* This is a proxy for an external member of a thin archive. */
22923 Filedata * member_filedata;
22924 char * member_file_name = adjust_relative_path
dda8d76d 22925 (filedata->file_name, name, namelen);
32ec8896 22926
fd486f32 22927 free (name);
1cb7d8b1
AM
22928 if (member_file_name == NULL)
22929 {
fd486f32 22930 free (qualified_name);
015dc7e1 22931 ret = false;
1cb7d8b1
AM
22932 break;
22933 }
2cf0635d 22934
015dc7e1 22935 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22936 if (member_filedata == NULL)
22937 {
22938 error (_("Input file '%s' is not readable.\n"), member_file_name);
22939 free (member_file_name);
fd486f32 22940 free (qualified_name);
015dc7e1 22941 ret = false;
1cb7d8b1
AM
22942 break;
22943 }
2cf0635d 22944
978c4450 22945 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22946 member_filedata->file_name = qualified_name;
2cf0635d 22947
75a2da57
AH
22948 /* The call to process_object() expects the file to be at the beginning. */
22949 rewind (member_filedata->handle);
22950
1cb7d8b1 22951 if (! process_object (member_filedata))
015dc7e1 22952 ret = false;
2cf0635d 22953
1cb7d8b1
AM
22954 close_file (member_filedata);
22955 free (member_file_name);
1cb7d8b1 22956 }
2cf0635d 22957 else if (is_thin_archive)
1cb7d8b1
AM
22958 {
22959 Filedata thin_filedata;
eb02c04d 22960
1cb7d8b1 22961 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22962
a043396b
NC
22963 /* PR 15140: Allow for corrupt thin archives. */
22964 if (nested_arch.file == NULL)
22965 {
22966 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22967 qualified_name, name);
fd486f32
AM
22968 free (qualified_name);
22969 free (name);
015dc7e1 22970 ret = false;
a043396b
NC
22971 break;
22972 }
fd486f32 22973 free (name);
a043396b 22974
1cb7d8b1 22975 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22976 filedata->archive_file_offset
22977 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22978
1cb7d8b1
AM
22979 /* The nested archive file will have been opened and setup by
22980 get_archive_member_name. */
63cf857e
AM
22981 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
22982 SEEK_SET) != 0)
1cb7d8b1
AM
22983 {
22984 error (_("%s: failed to seek to archive member.\n"),
22985 nested_arch.file_name);
fd486f32 22986 free (qualified_name);
015dc7e1 22987 ret = false;
1cb7d8b1
AM
22988 break;
22989 }
2cf0635d 22990
dda8d76d
NC
22991 thin_filedata.handle = nested_arch.file;
22992 thin_filedata.file_name = qualified_name;
9abca702 22993
1cb7d8b1 22994 if (! process_object (& thin_filedata))
015dc7e1 22995 ret = false;
1cb7d8b1 22996 }
2cf0635d 22997 else
1cb7d8b1 22998 {
fd486f32 22999 free (name);
978c4450 23000 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 23001 filedata->file_name = qualified_name;
1cb7d8b1 23002 if (! process_object (filedata))
015dc7e1 23003 ret = false;
237877b8 23004 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 23005 /* Stop looping with "negative" archive_file_size. */
978c4450 23006 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 23007 arch.next_arhdr_offset = -1ul;
1cb7d8b1 23008 }
fb52b2f4 23009
2cf0635d 23010 free (qualified_name);
fb52b2f4
NC
23011 }
23012
4145f1d5 23013 out:
2cf0635d
NC
23014 if (nested_arch.file != NULL)
23015 fclose (nested_arch.file);
23016 release_archive (&nested_arch);
23017 release_archive (&arch);
fb52b2f4 23018
d989285c 23019 return ret;
fb52b2f4
NC
23020}
23021
015dc7e1 23022static bool
2cf0635d 23023process_file (char * file_name)
fb52b2f4 23024{
dda8d76d 23025 Filedata * filedata = NULL;
fb52b2f4
NC
23026 struct stat statbuf;
23027 char armag[SARMAG];
015dc7e1 23028 bool ret = true;
fb52b2f4
NC
23029
23030 if (stat (file_name, &statbuf) < 0)
23031 {
f24ddbdd
NC
23032 if (errno == ENOENT)
23033 error (_("'%s': No such file\n"), file_name);
23034 else
23035 error (_("Could not locate '%s'. System error message: %s\n"),
23036 file_name, strerror (errno));
015dc7e1 23037 return false;
f24ddbdd
NC
23038 }
23039
23040 if (! S_ISREG (statbuf.st_mode))
23041 {
23042 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 23043 return false;
fb52b2f4
NC
23044 }
23045
dda8d76d
NC
23046 filedata = calloc (1, sizeof * filedata);
23047 if (filedata == NULL)
23048 {
23049 error (_("Out of memory allocating file data structure\n"));
015dc7e1 23050 return false;
dda8d76d
NC
23051 }
23052
23053 filedata->file_name = file_name;
23054 filedata->handle = fopen (file_name, "rb");
23055 if (filedata->handle == NULL)
fb52b2f4 23056 {
f24ddbdd 23057 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 23058 free (filedata);
015dc7e1 23059 return false;
fb52b2f4
NC
23060 }
23061
dda8d76d 23062 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 23063 {
4145f1d5 23064 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
23065 fclose (filedata->handle);
23066 free (filedata);
015dc7e1 23067 return false;
fb52b2f4
NC
23068 }
23069
be7d229a 23070 filedata->file_size = statbuf.st_size;
015dc7e1 23071 filedata->is_separate = false;
f54498b4 23072
fb52b2f4 23073 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 23074 {
015dc7e1
AM
23075 if (! process_archive (filedata, false))
23076 ret = false;
32ec8896 23077 }
2cf0635d 23078 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 23079 {
015dc7e1
AM
23080 if ( ! process_archive (filedata, true))
23081 ret = false;
32ec8896 23082 }
fb52b2f4
NC
23083 else
23084 {
1b513401 23085 if (do_archive_index && !check_all)
4145f1d5
NC
23086 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23087 file_name);
23088
dda8d76d 23089 rewind (filedata->handle);
978c4450 23090 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 23091
dda8d76d 23092 if (! process_object (filedata))
015dc7e1 23093 ret = false;
fb52b2f4
NC
23094 }
23095
dda8d76d 23096 fclose (filedata->handle);
8fb879cd
AM
23097 free (filedata->section_headers);
23098 free (filedata->program_headers);
23099 free (filedata->string_table);
6431e409 23100 free (filedata->dump.dump_sects);
dda8d76d 23101 free (filedata);
32ec8896 23102
fd486f32 23103 free (ba_cache.strtab);
1bd6175a 23104 ba_cache.strtab = NULL;
fd486f32 23105 free (ba_cache.symtab);
1bd6175a 23106 ba_cache.symtab = NULL;
fd486f32
AM
23107 ba_cache.filedata = NULL;
23108
fb52b2f4
NC
23109 return ret;
23110}
23111
252b5132
RH
23112#ifdef SUPPORT_DISASSEMBLY
23113/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 23114 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 23115 symbols. */
252b5132
RH
23116
23117void
2cf0635d 23118print_address (unsigned int addr, FILE * outfile)
252b5132
RH
23119{
23120 fprintf (outfile,"0x%8.8x", addr);
23121}
23122
e3c8793a 23123/* Needed by the i386 disassembler. */
dda8d76d 23124
252b5132
RH
23125void
23126db_task_printsym (unsigned int addr)
23127{
23128 print_address (addr, stderr);
23129}
23130#endif
23131
23132int
2cf0635d 23133main (int argc, char ** argv)
252b5132 23134{
ff78d6d6
L
23135 int err;
23136
87b9f255 23137#ifdef HAVE_LC_MESSAGES
252b5132 23138 setlocale (LC_MESSAGES, "");
3882b010 23139#endif
3882b010 23140 setlocale (LC_CTYPE, "");
252b5132
RH
23141 bindtextdomain (PACKAGE, LOCALEDIR);
23142 textdomain (PACKAGE);
23143
869b9d07
MM
23144 expandargv (&argc, &argv);
23145
dda8d76d 23146 parse_args (& cmdline, argc, argv);
59f14fc0 23147
18bd398b 23148 if (optind < (argc - 1))
1b513401
NC
23149 /* When displaying information for more than one file,
23150 prefix the information with the file name. */
015dc7e1 23151 show_name = true;
5656ba2c
L
23152 else if (optind >= argc)
23153 {
1b513401 23154 /* Ensure that the warning is always displayed. */
015dc7e1 23155 do_checks = true;
1b513401 23156
5656ba2c
L
23157 warn (_("Nothing to do.\n"));
23158 usage (stderr);
23159 }
18bd398b 23160
015dc7e1 23161 err = false;
252b5132 23162 while (optind < argc)
32ec8896 23163 if (! process_file (argv[optind++]))
015dc7e1 23164 err = true;
252b5132 23165
9db70fc3 23166 free (cmdline.dump_sects);
252b5132 23167
7d9813f1
NA
23168 free (dump_ctf_symtab_name);
23169 free (dump_ctf_strtab_name);
23170 free (dump_ctf_parent_name);
23171
32ec8896 23172 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 23173}