]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
gdb/testsuite: fix license on recently added file
[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;
df18f71b 4047 case E_MIPS_MACH_ALLEGREX: strcat(buf, ", allegrex"); break;
43521d43
TS
4048 case 0:
4049 /* We simply ignore the field in this case to avoid confusion:
4050 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4051 extension. */
4052 break;
2b692964 4053 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 4054 }
43521d43
TS
4055
4056 switch ((e_flags & EF_MIPS_ABI))
4057 {
4058 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
4059 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
4060 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
4061 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
4062 case 0:
4063 /* We simply ignore the field in this case to avoid confusion:
4064 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4065 This means it is likely to be an o32 file, but not for
4066 sure. */
4067 break;
2b692964 4068 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
4069 }
4070
4071 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4072 strcat (buf, ", mdmx");
4073
4074 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4075 strcat (buf, ", mips16");
4076
df58fc94
RS
4077 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4078 strcat (buf, ", micromips");
4079
43521d43
TS
4080 switch ((e_flags & EF_MIPS_ARCH))
4081 {
4082 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
4083 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
4084 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
4085 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
4086 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
4087 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 4088 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 4089 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 4090 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 4091 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 4092 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 4093 default: strcat (buf, _(", unknown ISA")); break;
43521d43 4094 }
252b5132 4095 break;
351b4b40 4096
35c08157
KLC
4097 case EM_NDS32:
4098 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
4099 break;
4100
fe944acf
FT
4101 case EM_NFP:
4102 switch (EF_NFP_MACH (e_flags))
4103 {
4104 case E_NFP_MACH_3200:
4105 strcat (buf, ", NFP-32xx");
4106 break;
4107 case E_NFP_MACH_6000:
4108 strcat (buf, ", NFP-6xxx");
4109 break;
4110 }
4111 break;
4112
e23eba97
NC
4113 case EM_RISCV:
4114 if (e_flags & EF_RISCV_RVC)
4115 strcat (buf, ", RVC");
2922d21d 4116
7f999549
JW
4117 if (e_flags & EF_RISCV_RVE)
4118 strcat (buf, ", RVE");
4119
96462b01
S
4120 if (e_flags & EF_RISCV_TSO)
4121 strcat (buf, ", TSO");
4122
2922d21d
AW
4123 switch (e_flags & EF_RISCV_FLOAT_ABI)
4124 {
4125 case EF_RISCV_FLOAT_ABI_SOFT:
4126 strcat (buf, ", soft-float ABI");
4127 break;
4128
4129 case EF_RISCV_FLOAT_ABI_SINGLE:
4130 strcat (buf, ", single-float ABI");
4131 break;
4132
4133 case EF_RISCV_FLOAT_ABI_DOUBLE:
4134 strcat (buf, ", double-float ABI");
4135 break;
4136
4137 case EF_RISCV_FLOAT_ABI_QUAD:
4138 strcat (buf, ", quad-float ABI");
4139 break;
4140 }
e23eba97
NC
4141 break;
4142
ccde1100
AO
4143 case EM_SH:
4144 switch ((e_flags & EF_SH_MACH_MASK))
4145 {
4146 case EF_SH1: strcat (buf, ", sh1"); break;
4147 case EF_SH2: strcat (buf, ", sh2"); break;
4148 case EF_SH3: strcat (buf, ", sh3"); break;
4149 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
4150 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
4151 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
4152 case EF_SH3E: strcat (buf, ", sh3e"); break;
4153 case EF_SH4: strcat (buf, ", sh4"); break;
4154 case EF_SH5: strcat (buf, ", sh5"); break;
4155 case EF_SH2E: strcat (buf, ", sh2e"); break;
4156 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 4157 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
4158 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
4159 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 4160 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
4161 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
4162 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
4163 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
4164 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
4165 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
4166 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 4167 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
4168 }
4169
cec6a5b8
MR
4170 if (e_flags & EF_SH_PIC)
4171 strcat (buf, ", pic");
4172
4173 if (e_flags & EF_SH_FDPIC)
4174 strcat (buf, ", fdpic");
ccde1100 4175 break;
948f632f 4176
73589c9d
CS
4177 case EM_OR1K:
4178 if (e_flags & EF_OR1K_NODELAY)
4179 strcat (buf, ", no delay");
4180 break;
57346661 4181
351b4b40
RH
4182 case EM_SPARCV9:
4183 if (e_flags & EF_SPARC_32PLUS)
4184 strcat (buf, ", v8+");
4185
4186 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
4187 strcat (buf, ", ultrasparcI");
4188
4189 if (e_flags & EF_SPARC_SUN_US3)
4190 strcat (buf, ", ultrasparcIII");
351b4b40
RH
4191
4192 if (e_flags & EF_SPARC_HAL_R1)
4193 strcat (buf, ", halr1");
4194
4195 if (e_flags & EF_SPARC_LEDATA)
4196 strcat (buf, ", ledata");
4197
4198 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4199 strcat (buf, ", tso");
4200
4201 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4202 strcat (buf, ", pso");
4203
4204 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4205 strcat (buf, ", rmo");
4206 break;
7d466069 4207
103f02d3
UD
4208 case EM_PARISC:
4209 switch (e_flags & EF_PARISC_ARCH)
4210 {
4211 case EFA_PARISC_1_0:
4212 strcpy (buf, ", PA-RISC 1.0");
4213 break;
4214 case EFA_PARISC_1_1:
4215 strcpy (buf, ", PA-RISC 1.1");
4216 break;
4217 case EFA_PARISC_2_0:
4218 strcpy (buf, ", PA-RISC 2.0");
4219 break;
4220 default:
4221 break;
4222 }
4223 if (e_flags & EF_PARISC_TRAPNIL)
4224 strcat (buf, ", trapnil");
4225 if (e_flags & EF_PARISC_EXT)
4226 strcat (buf, ", ext");
4227 if (e_flags & EF_PARISC_LSB)
4228 strcat (buf, ", lsb");
4229 if (e_flags & EF_PARISC_WIDE)
4230 strcat (buf, ", wide");
4231 if (e_flags & EF_PARISC_NO_KABP)
4232 strcat (buf, ", no kabp");
4233 if (e_flags & EF_PARISC_LAZYSWAP)
4234 strcat (buf, ", lazyswap");
30800947 4235 break;
76da6bbe 4236
7d466069 4237 case EM_PJ:
2b0337b0 4238 case EM_PJ_OLD:
7d466069
ILT
4239 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4240 strcat (buf, ", new calling convention");
4241
4242 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4243 strcat (buf, ", gnu calling convention");
4244 break;
4d6ed7c8
NC
4245
4246 case EM_IA_64:
4247 if ((e_flags & EF_IA_64_ABI64))
4248 strcat (buf, ", 64-bit");
4249 else
4250 strcat (buf, ", 32-bit");
4251 if ((e_flags & EF_IA_64_REDUCEDFP))
4252 strcat (buf, ", reduced fp model");
4253 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4254 strcat (buf, ", no function descriptors, constant gp");
4255 else if ((e_flags & EF_IA_64_CONS_GP))
4256 strcat (buf, ", constant gp");
4257 if ((e_flags & EF_IA_64_ABSOLUTE))
4258 strcat (buf, ", absolute");
dda8d76d 4259 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
4260 {
4261 if ((e_flags & EF_IA_64_VMS_LINKAGES))
4262 strcat (buf, ", vms_linkages");
4263 switch ((e_flags & EF_IA_64_VMS_COMCOD))
4264 {
4265 case EF_IA_64_VMS_COMCOD_SUCCESS:
4266 break;
4267 case EF_IA_64_VMS_COMCOD_WARNING:
4268 strcat (buf, ", warning");
4269 break;
4270 case EF_IA_64_VMS_COMCOD_ERROR:
4271 strcat (buf, ", error");
4272 break;
4273 case EF_IA_64_VMS_COMCOD_ABORT:
4274 strcat (buf, ", abort");
4275 break;
4276 default:
bee0ee85
NC
4277 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
4278 e_flags & EF_IA_64_VMS_COMCOD);
4279 strcat (buf, ", <unknown>");
28f997cf
TG
4280 }
4281 }
4d6ed7c8 4282 break;
179d3252
JT
4283
4284 case EM_VAX:
4285 if ((e_flags & EF_VAX_NONPIC))
4286 strcat (buf, ", non-PIC");
4287 if ((e_flags & EF_VAX_DFLOAT))
4288 strcat (buf, ", D-Float");
4289 if ((e_flags & EF_VAX_GFLOAT))
4290 strcat (buf, ", G-Float");
4291 break;
c7927a3c 4292
619ed720
EB
4293 case EM_VISIUM:
4294 if (e_flags & EF_VISIUM_ARCH_MCM)
4295 strcat (buf, ", mcm");
4296 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4297 strcat (buf, ", mcm24");
4298 if (e_flags & EF_VISIUM_ARCH_GR6)
4299 strcat (buf, ", gr6");
4300 break;
4301
4046d87a 4302 case EM_RL78:
1740ba0c
NC
4303 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4304 {
4305 case E_FLAG_RL78_ANY_CPU: break;
4306 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
4307 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
4308 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
4309 }
856ea05c
KP
4310 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4311 strcat (buf, ", 64-bit doubles");
4046d87a 4312 break;
0b4362b0 4313
c7927a3c
NC
4314 case EM_RX:
4315 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4316 strcat (buf, ", 64-bit doubles");
4317 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 4318 strcat (buf, ", dsp");
d4cb0ea0 4319 if (e_flags & E_FLAG_RX_PID)
0b4362b0 4320 strcat (buf, ", pid");
708e2187
NC
4321 if (e_flags & E_FLAG_RX_ABI)
4322 strcat (buf, ", RX ABI");
3525236c
NC
4323 if (e_flags & E_FLAG_RX_SINSNS_SET)
4324 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
4325 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
4326 if (e_flags & E_FLAG_RX_V2)
4327 strcat (buf, ", V2");
f87673e0
YS
4328 if (e_flags & E_FLAG_RX_V3)
4329 strcat (buf, ", V3");
d4cb0ea0 4330 break;
55786da2
AK
4331
4332 case EM_S390:
4333 if (e_flags & EF_S390_HIGH_GPRS)
4334 strcat (buf, ", highgprs");
d4cb0ea0 4335 break;
40b36596
JM
4336
4337 case EM_TI_C6000:
4338 if ((e_flags & EF_C6000_REL))
4339 strcat (buf, ", relocatable module");
d4cb0ea0 4340 break;
13761a11
NC
4341
4342 case EM_MSP430:
4343 strcat (buf, _(": architecture variant: "));
4344 switch (e_flags & EF_MSP430_MACH)
4345 {
4346 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
4347 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
4348 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
4349 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
4350 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
4351 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
4352 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
4353 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
4354 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
4355 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
4356 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
4357 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
4358 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
4359 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
4360 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
4361 default:
4362 strcat (buf, _(": unknown")); break;
4363 }
4364
4365 if (e_flags & ~ EF_MSP430_MACH)
4366 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
4367 break;
4368
4369 case EM_Z80:
4370 switch (e_flags & EF_Z80_MACH_MSK)
4371 {
4372 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
4373 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
4374 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
4375 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
4376 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
4377 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 4378 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
4379 default:
4380 strcat (buf, _(", unknown")); break;
4381 }
4382 break;
e9a0721f 4383 case EM_LOONGARCH:
e9a0721f 4384 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
4385 strcat (buf, ", SOFT-FLOAT");
4386 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
4387 strcat (buf, ", SINGLE-FLOAT");
4388 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
4389 strcat (buf, ", DOUBLE-FLOAT");
4390
c4a7e6b5 4391 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
4392 strcat (buf, ", OBJ-v0");
4393 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
4394 strcat (buf, ", OBJ-v1");
4395
e9a0721f 4396 break;
252b5132
RH
4397 }
4398 }
4399
4400 return buf;
4401}
4402
252b5132 4403static const char *
dda8d76d 4404get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4405{
4406 static char buff[32];
4407
4408 switch (osabi)
4409 {
4410 case ELFOSABI_NONE: return "UNIX - System V";
4411 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4412 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4413 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4414 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4415 case ELFOSABI_AIX: return "UNIX - AIX";
4416 case ELFOSABI_IRIX: return "UNIX - IRIX";
4417 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4418 case ELFOSABI_TRU64: return "UNIX - TRU64";
4419 case ELFOSABI_MODESTO: return "Novell - Modesto";
4420 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4421 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4422 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4423 case ELFOSABI_AROS: return "AROS";
11636f9e 4424 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4425 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4426 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4427 default:
40b36596 4428 if (osabi >= 64)
dda8d76d 4429 switch (filedata->file_header.e_machine)
40b36596 4430 {
37870be8
SM
4431 case EM_AMDGPU:
4432 switch (osabi)
4433 {
4434 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4435 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4436 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4437 default:
4438 break;
4439 }
4440 break;
4441
40b36596
JM
4442 case EM_ARM:
4443 switch (osabi)
4444 {
4445 case ELFOSABI_ARM: return "ARM";
18a20338 4446 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4447 default:
4448 break;
4449 }
4450 break;
4451
4452 case EM_MSP430:
4453 case EM_MSP430_OLD:
619ed720 4454 case EM_VISIUM:
40b36596
JM
4455 switch (osabi)
4456 {
4457 case ELFOSABI_STANDALONE: return _("Standalone App");
4458 default:
4459 break;
4460 }
4461 break;
4462
4463 case EM_TI_C6000:
4464 switch (osabi)
4465 {
4466 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4467 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4468 default:
4469 break;
4470 }
4471 break;
4472
4473 default:
4474 break;
4475 }
e9e44622 4476 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4477 return buff;
4478 }
4479}
4480
a06ea964
NC
4481static const char *
4482get_aarch64_segment_type (unsigned long type)
4483{
4484 switch (type)
4485 {
32ec8896 4486 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4487 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4488 default: return NULL;
a06ea964 4489 }
a06ea964
NC
4490}
4491
b294bdf8
MM
4492static const char *
4493get_arm_segment_type (unsigned long type)
4494{
4495 switch (type)
4496 {
32ec8896
NC
4497 case PT_ARM_EXIDX: return "EXIDX";
4498 default: return NULL;
b294bdf8 4499 }
b294bdf8
MM
4500}
4501
b4cbbe8f
AK
4502static const char *
4503get_s390_segment_type (unsigned long type)
4504{
4505 switch (type)
4506 {
4507 case PT_S390_PGSTE: return "S390_PGSTE";
4508 default: return NULL;
4509 }
4510}
4511
d3ba0551
AM
4512static const char *
4513get_mips_segment_type (unsigned long type)
252b5132
RH
4514{
4515 switch (type)
4516 {
32ec8896
NC
4517 case PT_MIPS_REGINFO: return "REGINFO";
4518 case PT_MIPS_RTPROC: return "RTPROC";
4519 case PT_MIPS_OPTIONS: return "OPTIONS";
4520 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4521 default: return NULL;
252b5132 4522 }
252b5132
RH
4523}
4524
103f02d3 4525static const char *
d3ba0551 4526get_parisc_segment_type (unsigned long type)
103f02d3
UD
4527{
4528 switch (type)
4529 {
103f02d3
UD
4530 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4531 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4532 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4533 default: return NULL;
103f02d3 4534 }
103f02d3
UD
4535}
4536
4d6ed7c8 4537static const char *
d3ba0551 4538get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4539{
4540 switch (type)
4541 {
4542 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4543 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4544 default: return NULL;
4d6ed7c8 4545 }
4d6ed7c8
NC
4546}
4547
40b36596
JM
4548static const char *
4549get_tic6x_segment_type (unsigned long type)
4550{
4551 switch (type)
4552 {
32ec8896
NC
4553 case PT_C6000_PHATTR: return "C6000_PHATTR";
4554 default: return NULL;
40b36596 4555 }
40b36596
JM
4556}
4557
fbc95f1e
KC
4558static const char *
4559get_riscv_segment_type (unsigned long type)
4560{
4561 switch (type)
4562 {
4563 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4564 default: return NULL;
4565 }
4566}
4567
df3a023b
AM
4568static const char *
4569get_hpux_segment_type (unsigned long type, unsigned e_machine)
4570{
4571 if (e_machine == EM_PARISC)
4572 switch (type)
4573 {
4574 case PT_HP_TLS: return "HP_TLS";
4575 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4576 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4577 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4578 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4579 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4580 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4581 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4582 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4583 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4584 case PT_HP_PARALLEL: return "HP_PARALLEL";
4585 case PT_HP_FASTBIND: return "HP_FASTBIND";
4586 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4587 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4588 case PT_HP_STACK: return "HP_STACK";
4589 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4590 default: return NULL;
4591 }
4592
4593 if (e_machine == EM_IA_64)
4594 switch (type)
4595 {
4596 case PT_HP_TLS: return "HP_TLS";
4597 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4598 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4599 case PT_IA_64_HP_STACK: return "HP_STACK";
4600 default: return NULL;
4601 }
4602
4603 return NULL;
4604}
4605
5522f910
NC
4606static const char *
4607get_solaris_segment_type (unsigned long type)
4608{
4609 switch (type)
4610 {
4611 case 0x6464e550: return "PT_SUNW_UNWIND";
4612 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4613 case 0x6ffffff7: return "PT_LOSUNW";
4614 case 0x6ffffffa: return "PT_SUNWBSS";
4615 case 0x6ffffffb: return "PT_SUNWSTACK";
4616 case 0x6ffffffc: return "PT_SUNWDTRACE";
4617 case 0x6ffffffd: return "PT_SUNWCAP";
4618 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4619 default: return NULL;
5522f910
NC
4620 }
4621}
4622
252b5132 4623static const char *
dda8d76d 4624get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4625{
b34976b6 4626 static char buff[32];
252b5132
RH
4627
4628 switch (p_type)
4629 {
b34976b6
AM
4630 case PT_NULL: return "NULL";
4631 case PT_LOAD: return "LOAD";
252b5132 4632 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4633 case PT_INTERP: return "INTERP";
4634 case PT_NOTE: return "NOTE";
4635 case PT_SHLIB: return "SHLIB";
4636 case PT_PHDR: return "PHDR";
13ae64f3 4637 case PT_TLS: return "TLS";
32ec8896 4638 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4639 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4640 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4641 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
cf0e0a0b 4642 case PT_GNU_SFRAME: return "GNU_SFRAME";
65765700 4643
80251d41 4644 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
3eba3ef3
NC
4645 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4646 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4647 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4648
252b5132 4649 default:
df3a023b 4650 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4651 {
2cf0635d 4652 const char * result;
103f02d3 4653
dda8d76d 4654 switch (filedata->file_header.e_machine)
252b5132 4655 {
a06ea964
NC
4656 case EM_AARCH64:
4657 result = get_aarch64_segment_type (p_type);
4658 break;
b294bdf8
MM
4659 case EM_ARM:
4660 result = get_arm_segment_type (p_type);
4661 break;
252b5132 4662 case EM_MIPS:
4fe85591 4663 case EM_MIPS_RS3_LE:
252b5132
RH
4664 result = get_mips_segment_type (p_type);
4665 break;
103f02d3
UD
4666 case EM_PARISC:
4667 result = get_parisc_segment_type (p_type);
4668 break;
4d6ed7c8
NC
4669 case EM_IA_64:
4670 result = get_ia64_segment_type (p_type);
4671 break;
40b36596
JM
4672 case EM_TI_C6000:
4673 result = get_tic6x_segment_type (p_type);
4674 break;
b4cbbe8f
AK
4675 case EM_S390:
4676 case EM_S390_OLD:
4677 result = get_s390_segment_type (p_type);
4678 break;
fbc95f1e
KC
4679 case EM_RISCV:
4680 result = get_riscv_segment_type (p_type);
4681 break;
252b5132
RH
4682 default:
4683 result = NULL;
4684 break;
4685 }
103f02d3 4686
252b5132
RH
4687 if (result != NULL)
4688 return result;
103f02d3 4689
1a9ccd70 4690 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4691 }
4692 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4693 {
df3a023b 4694 const char * result = NULL;
103f02d3 4695
df3a023b 4696 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4697 {
df3a023b
AM
4698 case ELFOSABI_GNU:
4699 case ELFOSABI_FREEBSD:
4700 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4701 {
4702 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4703 result = buff;
4704 }
103f02d3 4705 break;
df3a023b
AM
4706 case ELFOSABI_HPUX:
4707 result = get_hpux_segment_type (p_type,
4708 filedata->file_header.e_machine);
4709 break;
4710 case ELFOSABI_SOLARIS:
4711 result = get_solaris_segment_type (p_type);
00428cca 4712 break;
103f02d3 4713 default:
103f02d3
UD
4714 break;
4715 }
103f02d3
UD
4716 if (result != NULL)
4717 return result;
4718
1a9ccd70 4719 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4720 }
252b5132 4721 else
e9e44622 4722 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4723
4724 return buff;
4725 }
4726}
4727
53a346d8
CZ
4728static const char *
4729get_arc_section_type_name (unsigned int sh_type)
4730{
4731 switch (sh_type)
4732 {
4733 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4734 default:
4735 break;
4736 }
4737 return NULL;
4738}
4739
252b5132 4740static const char *
d3ba0551 4741get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4742{
4743 switch (sh_type)
4744 {
b34976b6
AM
4745 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4746 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4747 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4748 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4749 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4750 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4751 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4752 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4753 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4754 case SHT_MIPS_RELD: return "MIPS_RELD";
4755 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4756 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4757 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4758 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4759 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4760 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4761 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4762 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4763 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4764 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4765 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4766 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4767 case SHT_MIPS_LINE: return "MIPS_LINE";
4768 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4769 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4770 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4771 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4772 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4773 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4774 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4775 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4776 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4777 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4778 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4779 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4780 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4781 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4782 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4783 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4784 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4785 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4786 default:
4787 break;
4788 }
4789 return NULL;
4790}
4791
103f02d3 4792static const char *
d3ba0551 4793get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4794{
4795 switch (sh_type)
4796 {
4797 case SHT_PARISC_EXT: return "PARISC_EXT";
4798 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4799 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4800 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4801 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4802 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4803 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4804 default: return NULL;
103f02d3 4805 }
103f02d3
UD
4806}
4807
4d6ed7c8 4808static const char *
dda8d76d 4809get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4810{
18bd398b 4811 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4812 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4813 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4814
4d6ed7c8
NC
4815 switch (sh_type)
4816 {
148b93f2
NC
4817 case SHT_IA_64_EXT: return "IA_64_EXT";
4818 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4819 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4820 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4821 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4822 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4823 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4824 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4825 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4826 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4827 default:
4828 break;
4829 }
4830 return NULL;
4831}
4832
d2b2c203
DJ
4833static const char *
4834get_x86_64_section_type_name (unsigned int sh_type)
4835{
4836 switch (sh_type)
4837 {
4838 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4839 default: return NULL;
d2b2c203 4840 }
d2b2c203
DJ
4841}
4842
a06ea964
NC
4843static const char *
4844get_aarch64_section_type_name (unsigned int sh_type)
4845{
4846 switch (sh_type)
4847 {
32ec8896
NC
4848 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4849 default: return NULL;
a06ea964 4850 }
a06ea964
NC
4851}
4852
40a18ebd
NC
4853static const char *
4854get_arm_section_type_name (unsigned int sh_type)
4855{
4856 switch (sh_type)
4857 {
7f6fed87
NC
4858 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4859 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4860 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4861 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4862 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4863 default: return NULL;
40a18ebd 4864 }
40a18ebd
NC
4865}
4866
40b36596
JM
4867static const char *
4868get_tic6x_section_type_name (unsigned int sh_type)
4869{
4870 switch (sh_type)
4871 {
32ec8896
NC
4872 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4873 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4874 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4875 case SHT_TI_ICODE: return "TI_ICODE";
4876 case SHT_TI_XREF: return "TI_XREF";
4877 case SHT_TI_HANDLER: return "TI_HANDLER";
4878 case SHT_TI_INITINFO: return "TI_INITINFO";
4879 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4880 default: return NULL;
40b36596 4881 }
40b36596
JM
4882}
4883
13761a11 4884static const char *
b0191216 4885get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4886{
4887 switch (sh_type)
4888 {
32ec8896
NC
4889 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4890 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4891 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4892 default: return NULL;
13761a11
NC
4893 }
4894}
4895
fe944acf
FT
4896static const char *
4897get_nfp_section_type_name (unsigned int sh_type)
4898{
4899 switch (sh_type)
4900 {
4901 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4902 case SHT_NFP_INITREG: return "NFP_INITREG";
4903 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4904 default: return NULL;
4905 }
4906}
4907
685080f2
NC
4908static const char *
4909get_v850_section_type_name (unsigned int sh_type)
4910{
4911 switch (sh_type)
4912 {
32ec8896
NC
4913 case SHT_V850_SCOMMON: return "V850 Small Common";
4914 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4915 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4916 case SHT_RENESAS_IOP: return "RENESAS IOP";
4917 case SHT_RENESAS_INFO: return "RENESAS INFO";
4918 default: return NULL;
685080f2
NC
4919 }
4920}
4921
2dc8dd17
JW
4922static const char *
4923get_riscv_section_type_name (unsigned int sh_type)
4924{
4925 switch (sh_type)
4926 {
4927 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4928 default: return NULL;
4929 }
4930}
4931
0861f561
CQ
4932static const char *
4933get_csky_section_type_name (unsigned int sh_type)
4934{
4935 switch (sh_type)
4936 {
4937 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4938 default: return NULL;
4939 }
4940}
4941
252b5132 4942static const char *
dda8d76d 4943get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4944{
b34976b6 4945 static char buff[32];
9fb71ee4 4946 const char * result;
252b5132
RH
4947
4948 switch (sh_type)
4949 {
4950 case SHT_NULL: return "NULL";
4951 case SHT_PROGBITS: return "PROGBITS";
4952 case SHT_SYMTAB: return "SYMTAB";
4953 case SHT_STRTAB: return "STRTAB";
4954 case SHT_RELA: return "RELA";
dd207c13 4955 case SHT_RELR: return "RELR";
252b5132
RH
4956 case SHT_HASH: return "HASH";
4957 case SHT_DYNAMIC: return "DYNAMIC";
4958 case SHT_NOTE: return "NOTE";
4959 case SHT_NOBITS: return "NOBITS";
4960 case SHT_REL: return "REL";
4961 case SHT_SHLIB: return "SHLIB";
4962 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4963 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4964 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4965 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4966 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4967 case SHT_GROUP: return "GROUP";
67ce483b 4968 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4969 case SHT_GNU_verdef: return "VERDEF";
4970 case SHT_GNU_verneed: return "VERNEED";
4971 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4972 case 0x6ffffff0: return "VERSYM";
4973 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4974 case 0x7ffffffd: return "AUXILIARY";
4975 case 0x7fffffff: return "FILTER";
047b2264 4976 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4977
4978 default:
4979 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4980 {
dda8d76d 4981 switch (filedata->file_header.e_machine)
252b5132 4982 {
53a346d8
CZ
4983 case EM_ARC:
4984 case EM_ARC_COMPACT:
4985 case EM_ARC_COMPACT2:
4986 result = get_arc_section_type_name (sh_type);
4987 break;
252b5132 4988 case EM_MIPS:
4fe85591 4989 case EM_MIPS_RS3_LE:
252b5132
RH
4990 result = get_mips_section_type_name (sh_type);
4991 break;
103f02d3
UD
4992 case EM_PARISC:
4993 result = get_parisc_section_type_name (sh_type);
4994 break;
4d6ed7c8 4995 case EM_IA_64:
dda8d76d 4996 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4997 break;
d2b2c203 4998 case EM_X86_64:
8a9036a4 4999 case EM_L1OM:
7a9068fe 5000 case EM_K1OM:
d2b2c203
DJ
5001 result = get_x86_64_section_type_name (sh_type);
5002 break;
a06ea964
NC
5003 case EM_AARCH64:
5004 result = get_aarch64_section_type_name (sh_type);
5005 break;
40a18ebd
NC
5006 case EM_ARM:
5007 result = get_arm_section_type_name (sh_type);
5008 break;
40b36596
JM
5009 case EM_TI_C6000:
5010 result = get_tic6x_section_type_name (sh_type);
5011 break;
13761a11 5012 case EM_MSP430:
b0191216 5013 result = get_msp430_section_type_name (sh_type);
13761a11 5014 break;
fe944acf
FT
5015 case EM_NFP:
5016 result = get_nfp_section_type_name (sh_type);
5017 break;
685080f2
NC
5018 case EM_V800:
5019 case EM_V850:
5020 case EM_CYGNUS_V850:
5021 result = get_v850_section_type_name (sh_type);
5022 break;
2dc8dd17
JW
5023 case EM_RISCV:
5024 result = get_riscv_section_type_name (sh_type);
5025 break;
0861f561
CQ
5026 case EM_CSKY:
5027 result = get_csky_section_type_name (sh_type);
5028 break;
252b5132
RH
5029 default:
5030 result = NULL;
5031 break;
5032 }
5033
5034 if (result != NULL)
5035 return result;
5036
9fb71ee4 5037 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5038 }
5039 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5040 {
dda8d76d 5041 switch (filedata->file_header.e_machine)
148b93f2
NC
5042 {
5043 case EM_IA_64:
dda8d76d 5044 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5045 break;
5046 default:
dda8d76d 5047 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5048 result = get_solaris_section_type (sh_type);
5049 else
1b4b80bf
NC
5050 {
5051 switch (sh_type)
5052 {
5053 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5054 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5055 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5056 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5057 default:
5058 result = NULL;
5059 break;
5060 }
5061 }
148b93f2
NC
5062 break;
5063 }
5064
5065 if (result != NULL)
5066 return result;
5067
9fb71ee4 5068 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5069 }
252b5132 5070 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5071 {
dda8d76d 5072 switch (filedata->file_header.e_machine)
685080f2
NC
5073 {
5074 case EM_V800:
5075 case EM_V850:
5076 case EM_CYGNUS_V850:
9fb71ee4 5077 result = get_v850_section_type_name (sh_type);
a9fb83be 5078 break;
685080f2 5079 default:
9fb71ee4 5080 result = NULL;
685080f2
NC
5081 break;
5082 }
5083
9fb71ee4
NC
5084 if (result != NULL)
5085 return result;
5086
5087 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5088 }
252b5132 5089 else
a7dbfd1c
NC
5090 /* This message is probably going to be displayed in a 15
5091 character wide field, so put the hex value first. */
5092 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5093
252b5132
RH
5094 return buff;
5095 }
5096}
5097
79bc120c
NC
5098enum long_option_values
5099{
5100 OPTION_DEBUG_DUMP = 512,
5101 OPTION_DYN_SYMS,
0f03783c 5102 OPTION_LTO_SYMS,
79bc120c
NC
5103 OPTION_DWARF_DEPTH,
5104 OPTION_DWARF_START,
5105 OPTION_DWARF_CHECK,
5106 OPTION_CTF_DUMP,
5107 OPTION_CTF_PARENT,
5108 OPTION_CTF_SYMBOLS,
5109 OPTION_CTF_STRINGS,
42b6953b 5110 OPTION_SFRAME_DUMP,
79bc120c
NC
5111 OPTION_WITH_SYMBOL_VERSIONS,
5112 OPTION_RECURSE_LIMIT,
5113 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
5114 OPTION_NO_DEMANGLING,
5115 OPTION_SYM_BASE
79bc120c 5116};
2979dc34 5117
85b1c36d 5118static struct option options[] =
252b5132 5119{
79bc120c
NC
5120 /* Note - This table is alpha-sorted on the 'val'
5121 field in order to make adding new options easier. */
5122 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5123 {"all", no_argument, 0, 'a'},
79bc120c
NC
5124 {"demangle", optional_argument, 0, 'C'},
5125 {"archive-index", no_argument, 0, 'c'},
5126 {"use-dynamic", no_argument, 0, 'D'},
5127 {"dynamic", no_argument, 0, 'd'},
b34976b6 5128 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5129 {"section-groups", no_argument, 0, 'g'},
5130 {"help", no_argument, 0, 'H'},
5131 {"file-header", no_argument, 0, 'h'},
b34976b6 5132 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5133 {"lint", no_argument, 0, 'L'},
5134 {"enable-checks", no_argument, 0, 'L'},
5135 {"program-headers", no_argument, 0, 'l'},
b34976b6 5136 {"segments", no_argument, 0, 'l'},
595cf52e 5137 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5138 {"notes", no_argument, 0, 'n'},
ca0e11aa 5139 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5140 {"string-dump", required_argument, 0, 'p'},
5141 {"relocated-dump", required_argument, 0, 'R'},
5142 {"relocs", no_argument, 0, 'r'},
5143 {"section-headers", no_argument, 0, 'S'},
5144 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5145 {"symbols", no_argument, 0, 's'},
5146 {"syms", no_argument, 0, 's'},
79bc120c
NC
5147 {"silent-truncation",no_argument, 0, 'T'},
5148 {"section-details", no_argument, 0, 't'},
b3aa80b4 5149 {"unicode", required_argument, NULL, 'U'},
09c11c86 5150 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5151 {"version-info", no_argument, 0, 'V'},
5152 {"version", no_argument, 0, 'v'},
5153 {"wide", no_argument, 0, 'W'},
b34976b6 5154 {"hex-dump", required_argument, 0, 'x'},
0e602686 5155 {"decompress", no_argument, 0, 'z'},
252b5132 5156
79bc120c
NC
5157 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5158 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5159 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5160 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5161 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5162 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5163 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5164 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5165 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5166 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5167#ifdef ENABLE_LIBCTF
d344b407 5168 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5169 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5170 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5171 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5172#endif
42b6953b 5173 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
047c3dbf 5174 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5175
b34976b6 5176 {0, no_argument, 0, 0}
252b5132
RH
5177};
5178
5179static void
2cf0635d 5180usage (FILE * stream)
252b5132 5181{
92f01d61
JM
5182 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5183 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5184 fprintf (stream, _(" Options are:\n"));
5185 fprintf (stream, _("\
5186 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5187 fprintf (stream, _("\
5188 -h --file-header Display the ELF file header\n"));
5189 fprintf (stream, _("\
5190 -l --program-headers Display the program headers\n"));
5191 fprintf (stream, _("\
5192 --segments An alias for --program-headers\n"));
5193 fprintf (stream, _("\
5194 -S --section-headers Display the sections' header\n"));
5195 fprintf (stream, _("\
5196 --sections An alias for --section-headers\n"));
5197 fprintf (stream, _("\
5198 -g --section-groups Display the section groups\n"));
5199 fprintf (stream, _("\
5200 -t --section-details Display the section details\n"));
5201 fprintf (stream, _("\
5202 -e --headers Equivalent to: -h -l -S\n"));
5203 fprintf (stream, _("\
5204 -s --syms Display the symbol table\n"));
5205 fprintf (stream, _("\
5206 --symbols An alias for --syms\n"));
5207 fprintf (stream, _("\
5208 --dyn-syms Display the dynamic symbol table\n"));
5209 fprintf (stream, _("\
5210 --lto-syms Display LTO symbol tables\n"));
5211 fprintf (stream, _("\
047c3dbf
NL
5212 --sym-base=[0|8|10|16] \n\
5213 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5214 mixed (the default), octal, decimal, hexadecimal.\n"));
5215 fprintf (stream, _("\
0d646226
AM
5216 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5217 display_demangler_styles (stream, _("\
5218 STYLE can be "));
d6249f5f
AM
5219 fprintf (stream, _("\
5220 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5221 fprintf (stream, _("\
5222 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5223 fprintf (stream, _("\
5224 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5225 fprintf (stream, _("\
5226 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5227 Display unicode characters as determined by the current locale\n\
5228 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5229 escape sequences, or treat them as invalid and display as\n\
5230 \"{hex sequences}\"\n"));
d6249f5f
AM
5231 fprintf (stream, _("\
5232 -n --notes Display the core notes (if present)\n"));
5233 fprintf (stream, _("\
5234 -r --relocs Display the relocations (if present)\n"));
5235 fprintf (stream, _("\
5236 -u --unwind Display the unwind info (if present)\n"));
5237 fprintf (stream, _("\
5238 -d --dynamic Display the dynamic section (if present)\n"));
5239 fprintf (stream, _("\
5240 -V --version-info Display the version sections (if present)\n"));
5241 fprintf (stream, _("\
5242 -A --arch-specific Display architecture specific information (if any)\n"));
5243 fprintf (stream, _("\
5244 -c --archive-index Display the symbol/file index in an archive\n"));
5245 fprintf (stream, _("\
5246 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5247 fprintf (stream, _("\
5248 -L --lint|--enable-checks\n\
5249 Display warning messages for possible problems\n"));
5250 fprintf (stream, _("\
09c11c86 5251 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5252 Dump the contents of section <number|name> as bytes\n"));
5253 fprintf (stream, _("\
09c11c86 5254 -p --string-dump=<number|name>\n\
d6249f5f
AM
5255 Dump the contents of section <number|name> as strings\n"));
5256 fprintf (stream, _("\
cf13d699 5257 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5258 Dump the relocated contents of section <number|name>\n"));
5259 fprintf (stream, _("\
5260 -z --decompress Decompress section before dumping it\n"));
5261 fprintf (stream, _("\
5262 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5263 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5264 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5265 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5266 U/=trace_info]\n\
5267 Display the contents of DWARF debug sections\n"));
5268 fprintf (stream, _("\
5269 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5270 debuginfo files\n"));
5271 fprintf (stream, _("\
5272 -P --process-links Display the contents of non-debug sections in separate\n\
5273 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5274#if DEFAULT_FOR_FOLLOW_LINKS
5275 fprintf (stream, _("\
d6249f5f
AM
5276 -wK --debug-dump=follow-links\n\
5277 Follow links to separate debug info files (default)\n"));
5278 fprintf (stream, _("\
5279 -wN --debug-dump=no-follow-links\n\
5280 Do not follow links to separate debug info files\n"));
c46b7066
NC
5281#else
5282 fprintf (stream, _("\
d6249f5f
AM
5283 -wK --debug-dump=follow-links\n\
5284 Follow links to separate debug info files\n"));
5285 fprintf (stream, _("\
5286 -wN --debug-dump=no-follow-links\n\
5287 Do not follow links to separate debug info files\n\
5288 (default)\n"));
bed566bb
NC
5289#endif
5290#if HAVE_LIBDEBUGINFOD
5291 fprintf (stream, _("\
5292 -wD --debug-dump=use-debuginfod\n\
5293 When following links, also query debuginfod servers (default)\n"));
5294 fprintf (stream, _("\
5295 -wE --debug-dump=do-not-use-debuginfod\n\
5296 When following links, do not query debuginfod servers\n"));
c46b7066 5297#endif
fd2f0033 5298 fprintf (stream, _("\
d6249f5f
AM
5299 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5300 fprintf (stream, _("\
5301 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5302#ifdef ENABLE_LIBCTF
7d9813f1 5303 fprintf (stream, _("\
d6249f5f
AM
5304 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5305 fprintf (stream, _("\
80b56fad 5306 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5307 fprintf (stream, _("\
7d9813f1 5308 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5309 Use section <number|name> as the CTF external symtab\n"));
5310 fprintf (stream, _("\
7d9813f1 5311 --ctf-strings=<number|name>\n\
d6249f5f 5312 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5313#endif
42b6953b
IB
5314 fprintf (stream, _("\
5315 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
7d9813f1 5316
252b5132 5317#ifdef SUPPORT_DISASSEMBLY
92f01d61 5318 fprintf (stream, _("\
09c11c86
NC
5319 -i --instruction-dump=<number|name>\n\
5320 Disassemble the contents of section <number|name>\n"));
252b5132 5321#endif
92f01d61 5322 fprintf (stream, _("\
d6249f5f
AM
5323 -I --histogram Display histogram of bucket list lengths\n"));
5324 fprintf (stream, _("\
5325 -W --wide Allow output width to exceed 80 characters\n"));
5326 fprintf (stream, _("\
5327 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5328 fprintf (stream, _("\
5329 @<file> Read options from <file>\n"));
5330 fprintf (stream, _("\
5331 -H --help Display this information\n"));
5332 fprintf (stream, _("\
8b53311e 5333 -v --version Display the version number of readelf\n"));
1118d252 5334
92f01d61
JM
5335 if (REPORT_BUGS_TO[0] && stream == stdout)
5336 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5337
92f01d61 5338 exit (stream == stdout ? 0 : 1);
252b5132
RH
5339}
5340
18bd398b
NC
5341/* Record the fact that the user wants the contents of section number
5342 SECTION to be displayed using the method(s) encoded as flags bits
5343 in TYPE. Note, TYPE can be zero if we are creating the array for
5344 the first time. */
5345
252b5132 5346static void
6431e409
AM
5347request_dump_bynumber (struct dump_data *dumpdata,
5348 unsigned int section, dump_type type)
252b5132 5349{
6431e409 5350 if (section >= dumpdata->num_dump_sects)
252b5132 5351 {
2cf0635d 5352 dump_type * new_dump_sects;
252b5132 5353
3f5e193b 5354 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5355 sizeof (* new_dump_sects));
252b5132
RH
5356
5357 if (new_dump_sects == NULL)
591a748a 5358 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5359 else
5360 {
6431e409 5361 if (dumpdata->dump_sects)
21b65bac
NC
5362 {
5363 /* Copy current flag settings. */
6431e409
AM
5364 memcpy (new_dump_sects, dumpdata->dump_sects,
5365 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5366
6431e409 5367 free (dumpdata->dump_sects);
21b65bac 5368 }
252b5132 5369
6431e409
AM
5370 dumpdata->dump_sects = new_dump_sects;
5371 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5372 }
5373 }
5374
6431e409
AM
5375 if (dumpdata->dump_sects)
5376 dumpdata->dump_sects[section] |= type;
252b5132
RH
5377}
5378
aef1f6d0
DJ
5379/* Request a dump by section name. */
5380
5381static void
2cf0635d 5382request_dump_byname (const char * section, dump_type type)
aef1f6d0 5383{
2cf0635d 5384 struct dump_list_entry * new_request;
aef1f6d0 5385
3f5e193b
NC
5386 new_request = (struct dump_list_entry *)
5387 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5388 if (!new_request)
591a748a 5389 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5390
5391 new_request->name = strdup (section);
5392 if (!new_request->name)
591a748a 5393 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5394
5395 new_request->type = type;
5396
5397 new_request->next = dump_sects_byname;
5398 dump_sects_byname = new_request;
5399}
5400
cf13d699 5401static inline void
6431e409 5402request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5403{
5404 int section;
5405 char * cp;
5406
015dc7e1 5407 do_dump = true;
cf13d699
NC
5408 section = strtoul (optarg, & cp, 0);
5409
5410 if (! *cp && section >= 0)
6431e409 5411 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5412 else
5413 request_dump_byname (optarg, type);
5414}
5415
252b5132 5416static void
6431e409 5417parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5418{
5419 int c;
5420
5421 if (argc < 2)
92f01d61 5422 usage (stderr);
252b5132
RH
5423
5424 while ((c = getopt_long
b3aa80b4 5425 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5426 {
252b5132
RH
5427 switch (c)
5428 {
5429 case 0:
5430 /* Long options. */
5431 break;
5432 case 'H':
92f01d61 5433 usage (stdout);
252b5132
RH
5434 break;
5435
5436 case 'a':
015dc7e1
AM
5437 do_syms = true;
5438 do_reloc = true;
5439 do_unwind = true;
5440 do_dynamic = true;
5441 do_header = true;
5442 do_sections = true;
5443 do_section_groups = true;
5444 do_segments = true;
5445 do_version = true;
5446 do_histogram = true;
5447 do_arch = true;
5448 do_notes = true;
252b5132 5449 break;
79bc120c 5450
f5842774 5451 case 'g':
015dc7e1 5452 do_section_groups = true;
f5842774 5453 break;
5477e8a0 5454 case 't':
595cf52e 5455 case 'N':
015dc7e1
AM
5456 do_sections = true;
5457 do_section_details = true;
595cf52e 5458 break;
252b5132 5459 case 'e':
015dc7e1
AM
5460 do_header = true;
5461 do_sections = true;
5462 do_segments = true;
252b5132 5463 break;
a952a375 5464 case 'A':
015dc7e1 5465 do_arch = true;
a952a375 5466 break;
252b5132 5467 case 'D':
015dc7e1 5468 do_using_dynamic = true;
252b5132
RH
5469 break;
5470 case 'r':
015dc7e1 5471 do_reloc = true;
252b5132 5472 break;
4d6ed7c8 5473 case 'u':
015dc7e1 5474 do_unwind = true;
4d6ed7c8 5475 break;
252b5132 5476 case 'h':
015dc7e1 5477 do_header = true;
252b5132
RH
5478 break;
5479 case 'l':
015dc7e1 5480 do_segments = true;
252b5132
RH
5481 break;
5482 case 's':
015dc7e1 5483 do_syms = true;
252b5132
RH
5484 break;
5485 case 'S':
015dc7e1 5486 do_sections = true;
252b5132
RH
5487 break;
5488 case 'd':
015dc7e1 5489 do_dynamic = true;
252b5132 5490 break;
a952a375 5491 case 'I':
015dc7e1 5492 do_histogram = true;
a952a375 5493 break;
779fe533 5494 case 'n':
015dc7e1 5495 do_notes = true;
779fe533 5496 break;
4145f1d5 5497 case 'c':
015dc7e1 5498 do_archive_index = true;
4145f1d5 5499 break;
1b513401 5500 case 'L':
015dc7e1 5501 do_checks = true;
1b513401 5502 break;
ca0e11aa 5503 case 'P':
015dc7e1
AM
5504 process_links = true;
5505 do_follow_links = true;
e1dbfc17 5506 dump_any_debugging = true;
ca0e11aa 5507 break;
252b5132 5508 case 'x':
6431e409 5509 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5510 break;
09c11c86 5511 case 'p':
6431e409 5512 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5513 break;
5514 case 'R':
6431e409 5515 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5516 break;
0e602686 5517 case 'z':
015dc7e1 5518 decompress_dumps = true;
0e602686 5519 break;
252b5132 5520 case 'w':
0f03783c 5521 if (optarg == NULL)
613ff48b 5522 {
015dc7e1 5523 do_debugging = true;
94585d6d
NC
5524 do_dump = true;
5525 dump_any_debugging = true;
613ff48b
CC
5526 dwarf_select_sections_all ();
5527 }
252b5132
RH
5528 else
5529 {
015dc7e1 5530 do_debugging = false;
94585d6d
NC
5531 if (dwarf_select_sections_by_letters (optarg))
5532 {
5533 do_dump = true;
5534 dump_any_debugging = true;
5535 }
252b5132
RH
5536 }
5537 break;
2979dc34 5538 case OPTION_DEBUG_DUMP:
0f03783c 5539 if (optarg == NULL)
d6249f5f 5540 {
94585d6d 5541 do_dump = true;
d6249f5f 5542 do_debugging = true;
94585d6d 5543 dump_any_debugging = true;
d6249f5f
AM
5544 dwarf_select_sections_all ();
5545 }
2979dc34
JJ
5546 else
5547 {
015dc7e1 5548 do_debugging = false;
94585d6d
NC
5549 if (dwarf_select_sections_by_names (optarg))
5550 {
5551 do_dump = true;
5552 dump_any_debugging = true;
5553 }
2979dc34
JJ
5554 }
5555 break;
fd2f0033
TT
5556 case OPTION_DWARF_DEPTH:
5557 {
5558 char *cp;
5559
5560 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5561 }
5562 break;
5563 case OPTION_DWARF_START:
5564 {
5565 char *cp;
5566
5567 dwarf_start_die = strtoul (optarg, & cp, 0);
5568 }
5569 break;
4723351a 5570 case OPTION_DWARF_CHECK:
015dc7e1 5571 dwarf_check = true;
4723351a 5572 break;
7d9813f1 5573 case OPTION_CTF_DUMP:
015dc7e1 5574 do_ctf = true;
6431e409 5575 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5576 break;
5577 case OPTION_CTF_SYMBOLS:
df16e041 5578 free (dump_ctf_symtab_name);
7d9813f1
NA
5579 dump_ctf_symtab_name = strdup (optarg);
5580 break;
5581 case OPTION_CTF_STRINGS:
df16e041 5582 free (dump_ctf_strtab_name);
7d9813f1
NA
5583 dump_ctf_strtab_name = strdup (optarg);
5584 break;
5585 case OPTION_CTF_PARENT:
df16e041 5586 free (dump_ctf_parent_name);
7d9813f1
NA
5587 dump_ctf_parent_name = strdup (optarg);
5588 break;
42b6953b
IB
5589 case OPTION_SFRAME_DUMP:
5590 do_sframe = true;
5591 /* Providing section name is optional. request_dump (), however,
5592 thrives on non NULL optarg. Handle it explicitly here. */
5593 if (optarg != NULL)
5594 request_dump (dumpdata, SFRAME_DUMP);
5595 else
5596 {
5597 do_dump = true;
5598 const char *sframe_sec_name = strdup (".sframe");
5599 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
5600 }
5601 break;
2c610e4b 5602 case OPTION_DYN_SYMS:
015dc7e1 5603 do_dyn_syms = true;
2c610e4b 5604 break;
0f03783c 5605 case OPTION_LTO_SYMS:
015dc7e1 5606 do_lto_syms = true;
0f03783c 5607 break;
252b5132
RH
5608#ifdef SUPPORT_DISASSEMBLY
5609 case 'i':
6431e409 5610 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5611 break;
252b5132
RH
5612#endif
5613 case 'v':
5614 print_version (program_name);
5615 break;
5616 case 'V':
015dc7e1 5617 do_version = true;
252b5132 5618 break;
d974e256 5619 case 'W':
015dc7e1 5620 do_wide = true;
d974e256 5621 break;
0942c7ab 5622 case 'T':
015dc7e1 5623 do_not_show_symbol_truncation = true;
0942c7ab 5624 break;
79bc120c 5625 case 'C':
015dc7e1 5626 do_demangle = true;
79bc120c
NC
5627 if (optarg != NULL)
5628 {
5629 enum demangling_styles style;
5630
5631 style = cplus_demangle_name_to_style (optarg);
5632 if (style == unknown_demangling)
5633 error (_("unknown demangling style `%s'"), optarg);
5634
5635 cplus_demangle_set_style (style);
5636 }
5637 break;
5638 case OPTION_NO_DEMANGLING:
015dc7e1 5639 do_demangle = false;
79bc120c
NC
5640 break;
5641 case OPTION_RECURSE_LIMIT:
5642 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5643 break;
5644 case OPTION_NO_RECURSE_LIMIT:
5645 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5646 break;
5647 case OPTION_WITH_SYMBOL_VERSIONS:
5648 /* Ignored for backward compatibility. */
5649 break;
b9e920ec 5650
b3aa80b4
NC
5651 case 'U':
5652 if (optarg == NULL)
5653 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5654 else if (streq (optarg, "default") || streq (optarg, "d"))
5655 unicode_display = unicode_default;
5656 else if (streq (optarg, "locale") || streq (optarg, "l"))
5657 unicode_display = unicode_locale;
5658 else if (streq (optarg, "escape") || streq (optarg, "e"))
5659 unicode_display = unicode_escape;
5660 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5661 unicode_display = unicode_invalid;
5662 else if (streq (optarg, "hex") || streq (optarg, "x"))
5663 unicode_display = unicode_hex;
5664 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5665 unicode_display = unicode_highlight;
5666 else
5667 error (_("invalid argument to -U/--unicode: %s"), optarg);
5668 break;
5669
047c3dbf
NL
5670 case OPTION_SYM_BASE:
5671 sym_base = 0;
5672 if (optarg != NULL)
5673 {
5674 sym_base = strtoul (optarg, NULL, 0);
5675 switch (sym_base)
5676 {
5677 case 0:
5678 case 8:
5679 case 10:
5680 case 16:
5681 break;
5682
5683 default:
5684 sym_base = 0;
5685 break;
5686 }
5687 }
5688 break;
5689
252b5132 5690 default:
252b5132
RH
5691 /* xgettext:c-format */
5692 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5693 /* Fall through. */
252b5132 5694 case '?':
92f01d61 5695 usage (stderr);
252b5132
RH
5696 }
5697 }
5698
4d6ed7c8 5699 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5700 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5701 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5702 && !do_section_groups && !do_archive_index
0f03783c 5703 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5704 {
5705 if (do_checks)
5706 {
015dc7e1
AM
5707 check_all = true;
5708 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5709 do_segments = do_header = do_dump = do_version = true;
5710 do_histogram = do_debugging = do_arch = do_notes = true;
5711 do_section_groups = do_archive_index = do_dyn_syms = true;
5712 do_lto_syms = true;
1b513401
NC
5713 }
5714 else
5715 usage (stderr);
5716 }
252b5132
RH
5717}
5718
5719static const char *
d3ba0551 5720get_elf_class (unsigned int elf_class)
252b5132 5721{
b34976b6 5722 static char buff[32];
103f02d3 5723
252b5132
RH
5724 switch (elf_class)
5725 {
5726 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5727 case ELFCLASS32: return "ELF32";
5728 case ELFCLASS64: return "ELF64";
ab5e7794 5729 default:
e9e44622 5730 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5731 return buff;
252b5132
RH
5732 }
5733}
5734
5735static const char *
d3ba0551 5736get_data_encoding (unsigned int encoding)
252b5132 5737{
b34976b6 5738 static char buff[32];
103f02d3 5739
252b5132
RH
5740 switch (encoding)
5741 {
5742 case ELFDATANONE: return _("none");
33c63f9d
CM
5743 case ELFDATA2LSB: return _("2's complement, little endian");
5744 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5745 default:
e9e44622 5746 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5747 return buff;
252b5132
RH
5748 }
5749}
5750
521f7268
NC
5751static bool
5752check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
5753{
5754 if (header->e_ident[EI_MAG0] == ELFMAG0
5755 && header->e_ident[EI_MAG1] == ELFMAG1
5756 && header->e_ident[EI_MAG2] == ELFMAG2
5757 && header->e_ident[EI_MAG3] == ELFMAG3)
5758 return true;
5759
5760 /* Some compilers produce object files that are not in the ELF file format.
5761 As an aid to users of readelf, try to identify these cases and suggest
5762 alternative tools.
5763
5764 FIXME: It is not clear if all four bytes are used as constant magic
5765 valus by all compilers. It may be necessary to recode this function if
5766 different tools use different length sequences. */
5767
5768 static struct
5769 {
5770 unsigned char magic[4];
5771 const char * obj_message;
5772 const char * ar_message;
5773 }
5774 known_magic[] =
5775 {
5776 { { 'B', 'C', 0xc0, 0xde },
5777 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
5778 N_("This is a LLVM bitcode file - try extracing and then using llvm-bcanalyzer\n")
5779 },
5780 { { 'g', 'o', ' ', 'o' },
5781 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
5782 NULL
5783 }
5784 };
5785 int i;
5786
5787 for (i = ARRAY_SIZE (known_magic); i--;)
5788 {
5789 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
5790 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
5791 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
5792 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
5793 {
5794 /* Some compiler's analyzer tools do not handle archives,
5795 so we provide two different kinds of error message. */
5796 if (filedata->archive_file_size > 0
5797 && known_magic[i].ar_message != NULL)
b3ea2010 5798 error ("%s", known_magic[i].ar_message);
521f7268 5799 else
b3ea2010 5800 error ("%s", known_magic[i].obj_message);
521f7268
NC
5801 return false;
5802 }
5803 }
5804
5805 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
5806 return false;
5807}
5808
dda8d76d 5809/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5810
015dc7e1 5811static bool
dda8d76d 5812process_file_header (Filedata * filedata)
252b5132 5813{
dda8d76d
NC
5814 Elf_Internal_Ehdr * header = & filedata->file_header;
5815
521f7268
NC
5816 if (! check_magic_number (filedata, header))
5817 return false;
252b5132 5818
ca0e11aa
NC
5819 if (! filedata->is_separate)
5820 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5821
252b5132
RH
5822 if (do_header)
5823 {
32ec8896 5824 unsigned i;
252b5132 5825
ca0e11aa
NC
5826 if (filedata->is_separate)
5827 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5828 else
5829 printf (_("ELF Header:\n"));
252b5132 5830 printf (_(" Magic: "));
b34976b6 5831 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5832 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5833 printf ("\n");
5834 printf (_(" Class: %s\n"),
dda8d76d 5835 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5836 printf (_(" Data: %s\n"),
dda8d76d 5837 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5838 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5839 header->e_ident[EI_VERSION],
5840 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5841 ? _(" (current)")
dda8d76d 5842 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5843 ? _(" <unknown>")
789be9f7 5844 : "")));
252b5132 5845 printf (_(" OS/ABI: %s\n"),
dda8d76d 5846 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5847 printf (_(" ABI Version: %d\n"),
dda8d76d 5848 header->e_ident[EI_ABIVERSION]);
252b5132 5849 printf (_(" Type: %s\n"),
93df3340 5850 get_file_type (filedata));
252b5132 5851 printf (_(" Machine: %s\n"),
dda8d76d 5852 get_machine_name (header->e_machine));
252b5132 5853 printf (_(" Version: 0x%lx\n"),
e8a64888 5854 header->e_version);
76da6bbe 5855
f7a99963 5856 printf (_(" Entry point address: "));
e8a64888 5857 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5858 printf (_("\n Start of program headers: "));
e8a64888 5859 print_vma (header->e_phoff, DEC);
f7a99963 5860 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5861 print_vma (header->e_shoff, DEC);
f7a99963 5862 printf (_(" (bytes into file)\n"));
76da6bbe 5863
252b5132 5864 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5865 header->e_flags,
dda8d76d 5866 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5867 printf (_(" Size of this header: %u (bytes)\n"),
5868 header->e_ehsize);
5869 printf (_(" Size of program headers: %u (bytes)\n"),
5870 header->e_phentsize);
5871 printf (_(" Number of program headers: %u"),
5872 header->e_phnum);
dda8d76d
NC
5873 if (filedata->section_headers != NULL
5874 && header->e_phnum == PN_XNUM
5875 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5876 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5877 putc ('\n', stdout);
e8a64888
AM
5878 printf (_(" Size of section headers: %u (bytes)\n"),
5879 header->e_shentsize);
5880 printf (_(" Number of section headers: %u"),
5881 header->e_shnum);
dda8d76d 5882 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5883 {
5884 header->e_shnum = filedata->section_headers[0].sh_size;
5885 printf (" (%u)", header->e_shnum);
5886 }
560f3c1c 5887 putc ('\n', stdout);
e8a64888
AM
5888 printf (_(" Section header string table index: %u"),
5889 header->e_shstrndx);
dda8d76d
NC
5890 if (filedata->section_headers != NULL
5891 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5892 {
5893 header->e_shstrndx = filedata->section_headers[0].sh_link;
5894 printf (" (%u)", header->e_shstrndx);
5895 }
5896 if (header->e_shstrndx != SHN_UNDEF
5897 && header->e_shstrndx >= header->e_shnum)
5898 {
5899 header->e_shstrndx = SHN_UNDEF;
5900 printf (_(" <corrupt: out of range>"));
5901 }
560f3c1c
AM
5902 putc ('\n', stdout);
5903 }
5904
dda8d76d 5905 if (filedata->section_headers != NULL)
560f3c1c 5906 {
dda8d76d
NC
5907 if (header->e_phnum == PN_XNUM
5908 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5909 {
5910 /* Throw away any cached read of PN_XNUM headers. */
5911 free (filedata->program_headers);
5912 filedata->program_headers = NULL;
5913 header->e_phnum = filedata->section_headers[0].sh_info;
5914 }
dda8d76d
NC
5915 if (header->e_shnum == SHN_UNDEF)
5916 header->e_shnum = filedata->section_headers[0].sh_size;
5917 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5918 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5919 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5920 header->e_shstrndx = SHN_UNDEF;
252b5132 5921 }
103f02d3 5922
015dc7e1 5923 return true;
9ea033b2
NC
5924}
5925
dda8d76d
NC
5926/* Read in the program headers from FILEDATA and store them in PHEADERS.
5927 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5928
015dc7e1 5929static bool
dda8d76d 5930get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5931{
2cf0635d
NC
5932 Elf32_External_Phdr * phdrs;
5933 Elf32_External_Phdr * external;
5934 Elf_Internal_Phdr * internal;
b34976b6 5935 unsigned int i;
dda8d76d
NC
5936 unsigned int size = filedata->file_header.e_phentsize;
5937 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5938
5939 /* PR binutils/17531: Cope with unexpected section header sizes. */
5940 if (size == 0 || num == 0)
015dc7e1 5941 return false;
e0a31db1
NC
5942 if (size < sizeof * phdrs)
5943 {
5944 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5945 return false;
e0a31db1
NC
5946 }
5947 if (size > sizeof * phdrs)
5948 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5949
dda8d76d 5950 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5951 size, num, _("program headers"));
5952 if (phdrs == NULL)
015dc7e1 5953 return false;
9ea033b2 5954
91d6fa6a 5955 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5956 i < filedata->file_header.e_phnum;
b34976b6 5957 i++, internal++, external++)
252b5132 5958 {
9ea033b2
NC
5959 internal->p_type = BYTE_GET (external->p_type);
5960 internal->p_offset = BYTE_GET (external->p_offset);
5961 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5962 internal->p_paddr = BYTE_GET (external->p_paddr);
5963 internal->p_filesz = BYTE_GET (external->p_filesz);
5964 internal->p_memsz = BYTE_GET (external->p_memsz);
5965 internal->p_flags = BYTE_GET (external->p_flags);
5966 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5967 }
5968
9ea033b2 5969 free (phdrs);
015dc7e1 5970 return true;
252b5132
RH
5971}
5972
dda8d76d
NC
5973/* Read in the program headers from FILEDATA and store them in PHEADERS.
5974 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5975
015dc7e1 5976static bool
dda8d76d 5977get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5978{
2cf0635d
NC
5979 Elf64_External_Phdr * phdrs;
5980 Elf64_External_Phdr * external;
5981 Elf_Internal_Phdr * internal;
b34976b6 5982 unsigned int i;
dda8d76d
NC
5983 unsigned int size = filedata->file_header.e_phentsize;
5984 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5985
5986 /* PR binutils/17531: Cope with unexpected section header sizes. */
5987 if (size == 0 || num == 0)
015dc7e1 5988 return false;
e0a31db1
NC
5989 if (size < sizeof * phdrs)
5990 {
5991 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5992 return false;
e0a31db1
NC
5993 }
5994 if (size > sizeof * phdrs)
5995 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5996
dda8d76d 5997 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5998 size, num, _("program headers"));
a6e9f9df 5999 if (!phdrs)
015dc7e1 6000 return false;
9ea033b2 6001
91d6fa6a 6002 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6003 i < filedata->file_header.e_phnum;
b34976b6 6004 i++, internal++, external++)
9ea033b2
NC
6005 {
6006 internal->p_type = BYTE_GET (external->p_type);
6007 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
6008 internal->p_offset = BYTE_GET (external->p_offset);
6009 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6010 internal->p_paddr = BYTE_GET (external->p_paddr);
6011 internal->p_filesz = BYTE_GET (external->p_filesz);
6012 internal->p_memsz = BYTE_GET (external->p_memsz);
6013 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
6014 }
6015
6016 free (phdrs);
015dc7e1 6017 return true;
9ea033b2 6018}
252b5132 6019
32ec8896 6020/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 6021
015dc7e1 6022static bool
dda8d76d 6023get_program_headers (Filedata * filedata)
d93f0186 6024{
2cf0635d 6025 Elf_Internal_Phdr * phdrs;
d93f0186
NC
6026
6027 /* Check cache of prior read. */
dda8d76d 6028 if (filedata->program_headers != NULL)
015dc7e1 6029 return true;
d93f0186 6030
82156ab7
NC
6031 /* Be kind to memory checkers by looking for
6032 e_phnum values which we know must be invalid. */
dda8d76d 6033 if (filedata->file_header.e_phnum
82156ab7 6034 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 6035 >= filedata->file_size)
82156ab7
NC
6036 {
6037 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 6038 filedata->file_header.e_phnum);
015dc7e1 6039 return false;
82156ab7 6040 }
d93f0186 6041
dda8d76d 6042 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 6043 sizeof (Elf_Internal_Phdr));
d93f0186
NC
6044 if (phdrs == NULL)
6045 {
8b73c356 6046 error (_("Out of memory reading %u program headers\n"),
dda8d76d 6047 filedata->file_header.e_phnum);
015dc7e1 6048 return false;
d93f0186
NC
6049 }
6050
6051 if (is_32bit_elf
dda8d76d
NC
6052 ? get_32bit_program_headers (filedata, phdrs)
6053 : get_64bit_program_headers (filedata, phdrs))
d93f0186 6054 {
dda8d76d 6055 filedata->program_headers = phdrs;
015dc7e1 6056 return true;
d93f0186
NC
6057 }
6058
6059 free (phdrs);
015dc7e1 6060 return false;
d93f0186
NC
6061}
6062
93df3340 6063/* Print program header info and locate dynamic section. */
2f62977e 6064
93df3340 6065static void
dda8d76d 6066process_program_headers (Filedata * filedata)
252b5132 6067{
2cf0635d 6068 Elf_Internal_Phdr * segment;
b34976b6 6069 unsigned int i;
1a9ccd70 6070 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6071
dda8d76d 6072 if (filedata->file_header.e_phnum == 0)
252b5132 6073 {
82f2dbf7 6074 /* PR binutils/12467. */
dda8d76d 6075 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6076 warn (_("possibly corrupt ELF header - it has a non-zero program"
6077 " header offset, but no program headers\n"));
82f2dbf7 6078 else if (do_segments)
ca0e11aa
NC
6079 {
6080 if (filedata->is_separate)
6081 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6082 filedata->file_name);
6083 else
6084 printf (_("\nThere are no program headers in this file.\n"));
6085 }
93df3340 6086 goto no_headers;
252b5132
RH
6087 }
6088
6089 if (do_segments && !do_header)
6090 {
ca0e11aa
NC
6091 if (filedata->is_separate)
6092 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6093 filedata->file_name, get_file_type (filedata));
ca0e11aa 6094 else
93df3340 6095 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6096 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6097 filedata->file_header.e_entry);
b8281767
AM
6098 printf (ngettext ("There is %d program header,"
6099 " starting at offset %" PRIu64 "\n",
6100 "There are %d program headers,"
6101 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6102 filedata->file_header.e_phnum),
6103 filedata->file_header.e_phnum,
625d49fc 6104 filedata->file_header.e_phoff);
252b5132
RH
6105 }
6106
dda8d76d 6107 if (! get_program_headers (filedata))
93df3340 6108 goto no_headers;
103f02d3 6109
252b5132
RH
6110 if (do_segments)
6111 {
dda8d76d 6112 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6113 printf (_("\nProgram Headers:\n"));
6114 else
6115 printf (_("\nProgram Headers:\n"));
76da6bbe 6116
f7a99963
NC
6117 if (is_32bit_elf)
6118 printf
6119 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6120 else if (do_wide)
6121 printf
6122 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6123 else
6124 {
6125 printf
6126 (_(" Type Offset VirtAddr PhysAddr\n"));
6127 printf
6128 (_(" FileSiz MemSiz Flags Align\n"));
6129 }
252b5132
RH
6130 }
6131
26c527e6 6132 uint64_t dynamic_addr = 0;
be7d229a 6133 uint64_t dynamic_size = 0;
dda8d76d
NC
6134 for (i = 0, segment = filedata->program_headers;
6135 i < filedata->file_header.e_phnum;
b34976b6 6136 i++, segment++)
252b5132
RH
6137 {
6138 if (do_segments)
6139 {
dda8d76d 6140 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6141
6142 if (is_32bit_elf)
6143 {
6144 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6145 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6146 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6147 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6148 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6149 printf ("%c%c%c ",
6150 (segment->p_flags & PF_R ? 'R' : ' '),
6151 (segment->p_flags & PF_W ? 'W' : ' '),
6152 (segment->p_flags & PF_X ? 'E' : ' '));
6153 printf ("%#lx", (unsigned long) segment->p_align);
6154 }
d974e256
JJ
6155 else if (do_wide)
6156 {
6157 if ((unsigned long) segment->p_offset == segment->p_offset)
6158 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6159 else
6160 {
6161 print_vma (segment->p_offset, FULL_HEX);
6162 putchar (' ');
6163 }
6164
6165 print_vma (segment->p_vaddr, FULL_HEX);
6166 putchar (' ');
6167 print_vma (segment->p_paddr, FULL_HEX);
6168 putchar (' ');
6169
6170 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6171 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6172 else
6173 {
6174 print_vma (segment->p_filesz, FULL_HEX);
6175 putchar (' ');
6176 }
6177
6178 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6179 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6180 else
6181 {
f48e6c45 6182 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6183 }
6184
6185 printf (" %c%c%c ",
6186 (segment->p_flags & PF_R ? 'R' : ' '),
6187 (segment->p_flags & PF_W ? 'W' : ' '),
6188 (segment->p_flags & PF_X ? 'E' : ' '));
6189
6190 if ((unsigned long) segment->p_align == segment->p_align)
6191 printf ("%#lx", (unsigned long) segment->p_align);
6192 else
6193 {
6194 print_vma (segment->p_align, PREFIX_HEX);
6195 }
6196 }
f7a99963
NC
6197 else
6198 {
6199 print_vma (segment->p_offset, FULL_HEX);
6200 putchar (' ');
6201 print_vma (segment->p_vaddr, FULL_HEX);
6202 putchar (' ');
6203 print_vma (segment->p_paddr, FULL_HEX);
6204 printf ("\n ");
6205 print_vma (segment->p_filesz, FULL_HEX);
6206 putchar (' ');
6207 print_vma (segment->p_memsz, FULL_HEX);
6208 printf (" %c%c%c ",
6209 (segment->p_flags & PF_R ? 'R' : ' '),
6210 (segment->p_flags & PF_W ? 'W' : ' '),
6211 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6212 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6213 }
252b5132 6214
1a9ccd70
NC
6215 putc ('\n', stdout);
6216 }
f54498b4 6217
252b5132
RH
6218 switch (segment->p_type)
6219 {
1a9ccd70 6220 case PT_LOAD:
502d895c
NC
6221#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6222 required by the ELF standard, several programs, including the Linux
6223 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6224 if (previous_load
6225 && previous_load->p_vaddr > segment->p_vaddr)
6226 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6227#endif
1a9ccd70
NC
6228 if (segment->p_memsz < segment->p_filesz)
6229 error (_("the segment's file size is larger than its memory size\n"));
6230 previous_load = segment;
6231 break;
6232
6233 case PT_PHDR:
6234 /* PR 20815 - Verify that the program header is loaded into memory. */
6235 if (i > 0 && previous_load != NULL)
6236 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6237 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6238 {
6239 unsigned int j;
6240
dda8d76d 6241 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6242 {
6243 Elf_Internal_Phdr *load = filedata->program_headers + j;
6244 if (load->p_type == PT_LOAD
6245 && load->p_offset <= segment->p_offset
6246 && (load->p_offset + load->p_filesz
6247 >= segment->p_offset + segment->p_filesz)
6248 && load->p_vaddr <= segment->p_vaddr
6249 && (load->p_vaddr + load->p_filesz
6250 >= segment->p_vaddr + segment->p_filesz))
6251 break;
6252 }
dda8d76d 6253 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6254 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6255 }
6256 break;
6257
252b5132 6258 case PT_DYNAMIC:
93df3340 6259 if (dynamic_addr)
252b5132
RH
6260 error (_("more than one dynamic segment\n"));
6261
20737c13
AM
6262 /* By default, assume that the .dynamic section is the first
6263 section in the DYNAMIC segment. */
93df3340
AM
6264 dynamic_addr = segment->p_offset;
6265 dynamic_size = segment->p_filesz;
20737c13 6266
b2d38a17
NC
6267 /* Try to locate the .dynamic section. If there is
6268 a section header table, we can easily locate it. */
dda8d76d 6269 if (filedata->section_headers != NULL)
b2d38a17 6270 {
2cf0635d 6271 Elf_Internal_Shdr * sec;
b2d38a17 6272
dda8d76d 6273 sec = find_section (filedata, ".dynamic");
89fac5e3 6274 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6275 {
93df3340
AM
6276 /* A corresponding .dynamic section is expected, but on
6277 IA-64/OpenVMS it is OK for it to be missing. */
6278 if (!is_ia64_vms (filedata))
6279 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6280 break;
6281 }
6282
42bb2e33 6283 if (sec->sh_type == SHT_NOBITS)
20737c13 6284 {
93df3340
AM
6285 dynamic_addr = 0;
6286 dynamic_size = 0;
20737c13
AM
6287 break;
6288 }
42bb2e33 6289
93df3340
AM
6290 dynamic_addr = sec->sh_offset;
6291 dynamic_size = sec->sh_size;
b2d38a17 6292
8ac10c5b
L
6293 /* The PT_DYNAMIC segment, which is used by the run-time
6294 loader, should exactly match the .dynamic section. */
6295 if (do_checks
93df3340
AM
6296 && (dynamic_addr != segment->p_offset
6297 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6298 warn (_("\
6299the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6300 }
39e224f6
MW
6301
6302 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6303 segment. Check this after matching against the section headers
6304 so we don't warn on debuginfo file (which have NOBITS .dynamic
6305 sections). */
93df3340
AM
6306 if (dynamic_addr > filedata->file_size
6307 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6308 {
6309 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6310 dynamic_addr = 0;
6311 dynamic_size = 0;
39e224f6 6312 }
252b5132
RH
6313 break;
6314
6315 case PT_INTERP:
13acb58d
AM
6316 if (segment->p_offset >= filedata->file_size
6317 || segment->p_filesz > filedata->file_size - segment->p_offset
6318 || segment->p_filesz - 1 >= (size_t) -2
63cf857e
AM
6319 || fseek64 (filedata->handle,
6320 filedata->archive_file_offset + segment->p_offset,
6321 SEEK_SET))
252b5132
RH
6322 error (_("Unable to find program interpreter name\n"));
6323 else
6324 {
13acb58d
AM
6325 size_t len = segment->p_filesz;
6326 free (filedata->program_interpreter);
6327 filedata->program_interpreter = xmalloc (len + 1);
6328 len = fread (filedata->program_interpreter, 1, len,
6329 filedata->handle);
6330 filedata->program_interpreter[len] = 0;
252b5132
RH
6331
6332 if (do_segments)
f54498b4 6333 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6334 filedata->program_interpreter);
252b5132
RH
6335 }
6336 break;
6337 }
252b5132
RH
6338 }
6339
dda8d76d
NC
6340 if (do_segments
6341 && filedata->section_headers != NULL
6342 && filedata->string_table != NULL)
252b5132
RH
6343 {
6344 printf (_("\n Section to Segment mapping:\n"));
6345 printf (_(" Segment Sections...\n"));
6346
dda8d76d 6347 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6348 {
9ad5cbcf 6349 unsigned int j;
2cf0635d 6350 Elf_Internal_Shdr * section;
252b5132 6351
dda8d76d
NC
6352 segment = filedata->program_headers + i;
6353 section = filedata->section_headers + 1;
252b5132
RH
6354
6355 printf (" %2.2d ", i);
6356
dda8d76d 6357 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6358 {
f4638467
AM
6359 if (!ELF_TBSS_SPECIAL (section, segment)
6360 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6361 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6362 }
6363
6364 putc ('\n',stdout);
6365 }
6366 }
6367
93df3340
AM
6368 filedata->dynamic_addr = dynamic_addr;
6369 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6370 return;
6371
6372 no_headers:
6373 filedata->dynamic_addr = 0;
6374 filedata->dynamic_size = 1;
252b5132
RH
6375}
6376
6377
d93f0186
NC
6378/* Find the file offset corresponding to VMA by using the program headers. */
6379
26c527e6 6380static int64_t
625d49fc 6381offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 6382{
2cf0635d 6383 Elf_Internal_Phdr * seg;
d93f0186 6384
dda8d76d 6385 if (! get_program_headers (filedata))
d93f0186
NC
6386 {
6387 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6388 return (long) vma;
6389 }
6390
dda8d76d
NC
6391 for (seg = filedata->program_headers;
6392 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6393 ++seg)
6394 {
6395 if (seg->p_type != PT_LOAD)
6396 continue;
6397
6398 if (vma >= (seg->p_vaddr & -seg->p_align)
6399 && vma + size <= seg->p_vaddr + seg->p_filesz)
6400 return vma - seg->p_vaddr + seg->p_offset;
6401 }
6402
26c527e6
AM
6403 warn (_("Virtual address %#" PRIx64
6404 " not located in any PT_LOAD segment.\n"), vma);
6405 return vma;
d93f0186
NC
6406}
6407
6408
dda8d76d
NC
6409/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6410 If PROBE is true, this is just a probe and we do not generate any error
6411 messages if the load fails. */
049b0c3a 6412
015dc7e1
AM
6413static bool
6414get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6415{
2cf0635d
NC
6416 Elf32_External_Shdr * shdrs;
6417 Elf_Internal_Shdr * internal;
dda8d76d
NC
6418 unsigned int i;
6419 unsigned int size = filedata->file_header.e_shentsize;
6420 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6421
6422 /* PR binutils/17531: Cope with unexpected section header sizes. */
6423 if (size == 0 || num == 0)
015dc7e1 6424 return false;
907b52f4
NC
6425
6426 /* The section header cannot be at the start of the file - that is
6427 where the ELF file header is located. A file with absolutely no
6428 sections in it will use a shoff of 0. */
6429 if (filedata->file_header.e_shoff == 0)
6430 return false;
6431
049b0c3a
NC
6432 if (size < sizeof * shdrs)
6433 {
6434 if (! probe)
6435 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6436 return false;
049b0c3a
NC
6437 }
6438 if (!probe && size > sizeof * shdrs)
6439 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6440
dda8d76d 6441 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6442 size, num,
6443 probe ? NULL : _("section headers"));
6444 if (shdrs == NULL)
015dc7e1 6445 return false;
252b5132 6446
dda8d76d
NC
6447 filedata->section_headers = (Elf_Internal_Shdr *)
6448 cmalloc (num, sizeof (Elf_Internal_Shdr));
6449 if (filedata->section_headers == NULL)
252b5132 6450 {
049b0c3a 6451 if (!probe)
8b73c356 6452 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6453 free (shdrs);
015dc7e1 6454 return false;
252b5132
RH
6455 }
6456
dda8d76d 6457 for (i = 0, internal = filedata->section_headers;
560f3c1c 6458 i < num;
b34976b6 6459 i++, internal++)
252b5132
RH
6460 {
6461 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6462 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6463 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6464 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6465 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6466 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6467 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6468 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6469 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6470 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6471 if (!probe && internal->sh_link > num)
6472 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6473 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6474 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6475 }
6476
6477 free (shdrs);
015dc7e1 6478 return true;
252b5132
RH
6479}
6480
dda8d76d
NC
6481/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6482
015dc7e1
AM
6483static bool
6484get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6485{
dda8d76d
NC
6486 Elf64_External_Shdr * shdrs;
6487 Elf_Internal_Shdr * internal;
6488 unsigned int i;
6489 unsigned int size = filedata->file_header.e_shentsize;
6490 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6491
6492 /* PR binutils/17531: Cope with unexpected section header sizes. */
6493 if (size == 0 || num == 0)
015dc7e1 6494 return false;
dda8d76d 6495
907b52f4
NC
6496 /* The section header cannot be at the start of the file - that is
6497 where the ELF file header is located. A file with absolutely no
6498 sections in it will use a shoff of 0. */
6499 if (filedata->file_header.e_shoff == 0)
6500 return false;
6501
049b0c3a
NC
6502 if (size < sizeof * shdrs)
6503 {
6504 if (! probe)
6505 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6506 return false;
049b0c3a 6507 }
dda8d76d 6508
049b0c3a
NC
6509 if (! probe && size > sizeof * shdrs)
6510 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6511
dda8d76d
NC
6512 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6513 filedata->file_header.e_shoff,
049b0c3a
NC
6514 size, num,
6515 probe ? NULL : _("section headers"));
6516 if (shdrs == NULL)
015dc7e1 6517 return false;
9ea033b2 6518
dda8d76d
NC
6519 filedata->section_headers = (Elf_Internal_Shdr *)
6520 cmalloc (num, sizeof (Elf_Internal_Shdr));
6521 if (filedata->section_headers == NULL)
9ea033b2 6522 {
049b0c3a 6523 if (! probe)
8b73c356 6524 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6525 free (shdrs);
015dc7e1 6526 return false;
9ea033b2
NC
6527 }
6528
dda8d76d 6529 for (i = 0, internal = filedata->section_headers;
560f3c1c 6530 i < num;
b34976b6 6531 i++, internal++)
9ea033b2
NC
6532 {
6533 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6534 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6535 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6536 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6537 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6538 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6539 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6540 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6541 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6542 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6543 if (!probe && internal->sh_link > num)
6544 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6545 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6546 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6547 }
6548
6549 free (shdrs);
015dc7e1 6550 return true;
9ea033b2
NC
6551}
6552
4de91c10
AM
6553static bool
6554get_section_headers (Filedata *filedata, bool probe)
6555{
6556 if (filedata->section_headers != NULL)
6557 return true;
6558
4de91c10
AM
6559 if (is_32bit_elf)
6560 return get_32bit_section_headers (filedata, probe);
6561 else
6562 return get_64bit_section_headers (filedata, probe);
6563}
6564
252b5132 6565static Elf_Internal_Sym *
26c527e6
AM
6566get_32bit_elf_symbols (Filedata *filedata,
6567 Elf_Internal_Shdr *section,
6568 uint64_t *num_syms_return)
252b5132 6569{
26c527e6 6570 uint64_t number = 0;
dd24e3da 6571 Elf32_External_Sym * esyms = NULL;
ba5cdace 6572 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6573 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6574 Elf_Internal_Sym * psym;
b34976b6 6575 unsigned int j;
e3d39609 6576 elf_section_list * entry;
252b5132 6577
c9c1d674
EG
6578 if (section->sh_size == 0)
6579 {
6580 if (num_syms_return != NULL)
6581 * num_syms_return = 0;
6582 return NULL;
6583 }
6584
dd24e3da 6585 /* Run some sanity checks first. */
c9c1d674 6586 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6587 {
26c527e6 6588 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 6589 printable_section_name (filedata, section),
26c527e6 6590 section->sh_entsize);
ba5cdace 6591 goto exit_point;
dd24e3da
NC
6592 }
6593
dda8d76d 6594 if (section->sh_size > filedata->file_size)
f54498b4 6595 {
26c527e6 6596 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 6597 printable_section_name (filedata, section),
26c527e6 6598 section->sh_size);
f54498b4
NC
6599 goto exit_point;
6600 }
6601
dd24e3da
NC
6602 number = section->sh_size / section->sh_entsize;
6603
6604 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6605 {
26c527e6
AM
6606 error (_("Size (%#" PRIx64 ") of section %s "
6607 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
6608 section->sh_size,
dda8d76d 6609 printable_section_name (filedata, section),
26c527e6 6610 section->sh_entsize);
ba5cdace 6611 goto exit_point;
dd24e3da
NC
6612 }
6613
dda8d76d 6614 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6615 section->sh_size, _("symbols"));
dd24e3da 6616 if (esyms == NULL)
ba5cdace 6617 goto exit_point;
252b5132 6618
e3d39609 6619 shndx = NULL;
978c4450 6620 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 6621 {
26c527e6 6622 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
6623 continue;
6624
6625 if (shndx != NULL)
6626 {
6627 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6628 free (shndx);
6629 }
6630
6631 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6632 entry->hdr->sh_offset,
6633 1, entry->hdr->sh_size,
6634 _("symbol table section indices"));
6635 if (shndx == NULL)
6636 goto exit_point;
6637
6638 /* PR17531: file: heap-buffer-overflow */
6639 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6640 {
26c527e6 6641 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 6642 printable_section_name (filedata, entry->hdr),
26c527e6
AM
6643 entry->hdr->sh_size,
6644 section->sh_size);
e3d39609 6645 goto exit_point;
c9c1d674 6646 }
e3d39609 6647 }
9ad5cbcf 6648
3f5e193b 6649 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6650
6651 if (isyms == NULL)
6652 {
26c527e6 6653 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
dd24e3da 6654 goto exit_point;
252b5132
RH
6655 }
6656
dd24e3da 6657 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6658 {
6659 psym->st_name = BYTE_GET (esyms[j].st_name);
6660 psym->st_value = BYTE_GET (esyms[j].st_value);
6661 psym->st_size = BYTE_GET (esyms[j].st_size);
6662 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6663 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6664 psym->st_shndx
6665 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6666 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6667 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6668 psym->st_info = BYTE_GET (esyms[j].st_info);
6669 psym->st_other = BYTE_GET (esyms[j].st_other);
6670 }
6671
dd24e3da 6672 exit_point:
e3d39609
NC
6673 free (shndx);
6674 free (esyms);
252b5132 6675
ba5cdace
NC
6676 if (num_syms_return != NULL)
6677 * num_syms_return = isyms == NULL ? 0 : number;
6678
252b5132
RH
6679 return isyms;
6680}
6681
9ea033b2 6682static Elf_Internal_Sym *
26c527e6
AM
6683get_64bit_elf_symbols (Filedata *filedata,
6684 Elf_Internal_Shdr *section,
6685 uint64_t *num_syms_return)
9ea033b2 6686{
26c527e6 6687 uint64_t number = 0;
ba5cdace
NC
6688 Elf64_External_Sym * esyms = NULL;
6689 Elf_External_Sym_Shndx * shndx = NULL;
6690 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6691 Elf_Internal_Sym * psym;
b34976b6 6692 unsigned int j;
e3d39609 6693 elf_section_list * entry;
9ea033b2 6694
c9c1d674
EG
6695 if (section->sh_size == 0)
6696 {
6697 if (num_syms_return != NULL)
6698 * num_syms_return = 0;
6699 return NULL;
6700 }
6701
dd24e3da 6702 /* Run some sanity checks first. */
c9c1d674 6703 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6704 {
26c527e6 6705 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 6706 printable_section_name (filedata, section),
26c527e6 6707 section->sh_entsize);
ba5cdace 6708 goto exit_point;
dd24e3da
NC
6709 }
6710
dda8d76d 6711 if (section->sh_size > filedata->file_size)
f54498b4 6712 {
26c527e6 6713 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 6714 printable_section_name (filedata, section),
26c527e6 6715 section->sh_size);
f54498b4
NC
6716 goto exit_point;
6717 }
6718
dd24e3da
NC
6719 number = section->sh_size / section->sh_entsize;
6720
6721 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6722 {
26c527e6
AM
6723 error (_("Size (%#" PRIx64 ") of section %s "
6724 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
6725 section->sh_size,
dda8d76d 6726 printable_section_name (filedata, section),
26c527e6 6727 section->sh_entsize);
ba5cdace 6728 goto exit_point;
dd24e3da
NC
6729 }
6730
dda8d76d 6731 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6732 section->sh_size, _("symbols"));
a6e9f9df 6733 if (!esyms)
ba5cdace 6734 goto exit_point;
9ea033b2 6735
e3d39609 6736 shndx = NULL;
978c4450 6737 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 6738 {
26c527e6 6739 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
6740 continue;
6741
6742 if (shndx != NULL)
6743 {
6744 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6745 free (shndx);
c9c1d674 6746 }
e3d39609
NC
6747
6748 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6749 entry->hdr->sh_offset,
6750 1, entry->hdr->sh_size,
6751 _("symbol table section indices"));
6752 if (shndx == NULL)
6753 goto exit_point;
6754
6755 /* PR17531: file: heap-buffer-overflow */
6756 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6757 {
26c527e6 6758 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 6759 printable_section_name (filedata, entry->hdr),
26c527e6
AM
6760 entry->hdr->sh_size,
6761 section->sh_size);
e3d39609
NC
6762 goto exit_point;
6763 }
6764 }
9ad5cbcf 6765
3f5e193b 6766 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6767
6768 if (isyms == NULL)
6769 {
26c527e6 6770 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
ba5cdace 6771 goto exit_point;
9ea033b2
NC
6772 }
6773
ba5cdace 6774 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6775 {
6776 psym->st_name = BYTE_GET (esyms[j].st_name);
6777 psym->st_info = BYTE_GET (esyms[j].st_info);
6778 psym->st_other = BYTE_GET (esyms[j].st_other);
6779 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6780
4fbb74a6 6781 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6782 psym->st_shndx
6783 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6784 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6785 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6786
66543521
AM
6787 psym->st_value = BYTE_GET (esyms[j].st_value);
6788 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6789 }
6790
ba5cdace 6791 exit_point:
e3d39609
NC
6792 free (shndx);
6793 free (esyms);
ba5cdace
NC
6794
6795 if (num_syms_return != NULL)
6796 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6797
6798 return isyms;
6799}
6800
4de91c10
AM
6801static Elf_Internal_Sym *
6802get_elf_symbols (Filedata *filedata,
6803 Elf_Internal_Shdr *section,
26c527e6 6804 uint64_t *num_syms_return)
4de91c10
AM
6805{
6806 if (is_32bit_elf)
6807 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6808 else
6809 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6810}
6811
d1133906 6812static const char *
625d49fc 6813get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 6814{
5477e8a0 6815 static char buff[1024];
2cf0635d 6816 char * p = buff;
32ec8896
NC
6817 unsigned int field_size = is_32bit_elf ? 8 : 16;
6818 signed int sindex;
6819 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
6820 uint64_t os_flags = 0;
6821 uint64_t proc_flags = 0;
6822 uint64_t unknown_flags = 0;
148b93f2 6823 static const struct
5477e8a0 6824 {
2cf0635d 6825 const char * str;
32ec8896 6826 unsigned int len;
5477e8a0
L
6827 }
6828 flags [] =
6829 {
cfcac11d
NC
6830 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6831 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6832 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6833 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6834 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6835 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6836 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6837 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6838 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6839 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6840 /* IA-64 specific. */
6841 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6842 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6843 /* IA-64 OpenVMS specific. */
6844 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6845 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6846 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6847 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6848 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6849 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6850 /* Generic. */
cfcac11d 6851 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6852 /* SPARC specific. */
77115a4a 6853 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6854 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6855 /* ARM specific. */
6856 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6857 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6858 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6859 /* GNU specific. */
6860 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6861 /* VLE specific. */
6862 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6863 /* GNU specific. */
6864 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6865 };
6866
6867 if (do_section_details)
6868 {
8d5ff12c
L
6869 sprintf (buff, "[%*.*lx]: ",
6870 field_size, field_size, (unsigned long) sh_flags);
6871 p += field_size + 4;
5477e8a0 6872 }
76da6bbe 6873
d1133906
NC
6874 while (sh_flags)
6875 {
625d49fc 6876 uint64_t flag;
d1133906
NC
6877
6878 flag = sh_flags & - sh_flags;
6879 sh_flags &= ~ flag;
76da6bbe 6880
5477e8a0 6881 if (do_section_details)
d1133906 6882 {
5477e8a0
L
6883 switch (flag)
6884 {
91d6fa6a
NC
6885 case SHF_WRITE: sindex = 0; break;
6886 case SHF_ALLOC: sindex = 1; break;
6887 case SHF_EXECINSTR: sindex = 2; break;
6888 case SHF_MERGE: sindex = 3; break;
6889 case SHF_STRINGS: sindex = 4; break;
6890 case SHF_INFO_LINK: sindex = 5; break;
6891 case SHF_LINK_ORDER: sindex = 6; break;
6892 case SHF_OS_NONCONFORMING: sindex = 7; break;
6893 case SHF_GROUP: sindex = 8; break;
6894 case SHF_TLS: sindex = 9; break;
18ae9cc1 6895 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6896 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6897
5477e8a0 6898 default:
91d6fa6a 6899 sindex = -1;
dda8d76d 6900 switch (filedata->file_header.e_machine)
148b93f2 6901 {
cfcac11d 6902 case EM_IA_64:
148b93f2 6903 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6904 sindex = 10;
148b93f2 6905 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6906 sindex = 11;
dda8d76d 6907 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6908 switch (flag)
6909 {
91d6fa6a
NC
6910 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6911 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6912 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6913 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6914 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6915 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6916 default: break;
6917 }
cfcac11d
NC
6918 break;
6919
caa83f8b 6920 case EM_386:
22abe556 6921 case EM_IAMCU:
caa83f8b 6922 case EM_X86_64:
7f502d6c 6923 case EM_L1OM:
7a9068fe 6924 case EM_K1OM:
cfcac11d
NC
6925 case EM_OLD_SPARCV9:
6926 case EM_SPARC32PLUS:
6927 case EM_SPARCV9:
6928 case EM_SPARC:
18ae9cc1 6929 if (flag == SHF_ORDERED)
91d6fa6a 6930 sindex = 19;
cfcac11d 6931 break;
ac4c9b04
MG
6932
6933 case EM_ARM:
6934 switch (flag)
6935 {
6936 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6937 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6938 case SHF_COMDEF: sindex = 23; break;
6939 default: break;
6940 }
6941 break;
83eef883
AFB
6942 case EM_PPC:
6943 if (flag == SHF_PPC_VLE)
6944 sindex = 25;
6945 break;
99fabbc9
JL
6946 default:
6947 break;
6948 }
ac4c9b04 6949
99fabbc9
JL
6950 switch (filedata->file_header.e_ident[EI_OSABI])
6951 {
6952 case ELFOSABI_GNU:
6953 case ELFOSABI_FREEBSD:
6954 if (flag == SHF_GNU_RETAIN)
6955 sindex = 26;
6956 /* Fall through */
6957 case ELFOSABI_NONE:
6958 if (flag == SHF_GNU_MBIND)
6959 /* We should not recognize SHF_GNU_MBIND for
6960 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6961 not set the EI_OSABI header byte. */
6962 sindex = 24;
6963 break;
cfcac11d
NC
6964 default:
6965 break;
148b93f2 6966 }
99fabbc9 6967 break;
5477e8a0
L
6968 }
6969
91d6fa6a 6970 if (sindex != -1)
5477e8a0 6971 {
8d5ff12c
L
6972 if (p != buff + field_size + 4)
6973 {
6974 if (size < (10 + 2))
bee0ee85
NC
6975 {
6976 warn (_("Internal error: not enough buffer room for section flag info"));
6977 return _("<unknown>");
6978 }
8d5ff12c
L
6979 size -= 2;
6980 *p++ = ',';
6981 *p++ = ' ';
6982 }
6983
91d6fa6a
NC
6984 size -= flags [sindex].len;
6985 p = stpcpy (p, flags [sindex].str);
5477e8a0 6986 }
3b22753a 6987 else if (flag & SHF_MASKOS)
8d5ff12c 6988 os_flags |= flag;
d1133906 6989 else if (flag & SHF_MASKPROC)
8d5ff12c 6990 proc_flags |= flag;
d1133906 6991 else
8d5ff12c 6992 unknown_flags |= flag;
5477e8a0
L
6993 }
6994 else
6995 {
6996 switch (flag)
6997 {
6998 case SHF_WRITE: *p = 'W'; break;
6999 case SHF_ALLOC: *p = 'A'; break;
7000 case SHF_EXECINSTR: *p = 'X'; break;
7001 case SHF_MERGE: *p = 'M'; break;
7002 case SHF_STRINGS: *p = 'S'; break;
7003 case SHF_INFO_LINK: *p = 'I'; break;
7004 case SHF_LINK_ORDER: *p = 'L'; break;
7005 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7006 case SHF_GROUP: *p = 'G'; break;
7007 case SHF_TLS: *p = 'T'; break;
18ae9cc1 7008 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 7009 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
7010
7011 default:
dda8d76d
NC
7012 if ((filedata->file_header.e_machine == EM_X86_64
7013 || filedata->file_header.e_machine == EM_L1OM
7014 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
7015 && flag == SHF_X86_64_LARGE)
7016 *p = 'l';
dda8d76d 7017 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 7018 && flag == SHF_ARM_PURECODE)
99fabbc9 7019 *p = 'y';
dda8d76d 7020 else if (filedata->file_header.e_machine == EM_PPC
83eef883 7021 && flag == SHF_PPC_VLE)
99fabbc9 7022 *p = 'v';
5477e8a0
L
7023 else if (flag & SHF_MASKOS)
7024 {
99fabbc9
JL
7025 switch (filedata->file_header.e_ident[EI_OSABI])
7026 {
7027 case ELFOSABI_GNU:
7028 case ELFOSABI_FREEBSD:
7029 if (flag == SHF_GNU_RETAIN)
7030 {
7031 *p = 'R';
7032 break;
7033 }
7034 /* Fall through */
7035 case ELFOSABI_NONE:
7036 if (flag == SHF_GNU_MBIND)
7037 {
7038 /* We should not recognize SHF_GNU_MBIND for
7039 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7040 not set the EI_OSABI header byte. */
7041 *p = 'D';
7042 break;
7043 }
7044 /* Fall through */
7045 default:
7046 *p = 'o';
7047 sh_flags &= ~SHF_MASKOS;
7048 break;
7049 }
5477e8a0
L
7050 }
7051 else if (flag & SHF_MASKPROC)
7052 {
7053 *p = 'p';
7054 sh_flags &= ~ SHF_MASKPROC;
7055 }
7056 else
7057 *p = 'x';
7058 break;
7059 }
7060 p++;
d1133906
NC
7061 }
7062 }
76da6bbe 7063
8d5ff12c
L
7064 if (do_section_details)
7065 {
7066 if (os_flags)
7067 {
7068 size -= 5 + field_size;
7069 if (p != buff + field_size + 4)
7070 {
7071 if (size < (2 + 1))
bee0ee85
NC
7072 {
7073 warn (_("Internal error: not enough buffer room for section flag info"));
7074 return _("<unknown>");
7075 }
8d5ff12c
L
7076 size -= 2;
7077 *p++ = ',';
7078 *p++ = ' ';
7079 }
7080 sprintf (p, "OS (%*.*lx)", field_size, field_size,
7081 (unsigned long) os_flags);
7082 p += 5 + field_size;
7083 }
7084 if (proc_flags)
7085 {
7086 size -= 7 + field_size;
7087 if (p != buff + field_size + 4)
7088 {
7089 if (size < (2 + 1))
bee0ee85
NC
7090 {
7091 warn (_("Internal error: not enough buffer room for section flag info"));
7092 return _("<unknown>");
7093 }
8d5ff12c
L
7094 size -= 2;
7095 *p++ = ',';
7096 *p++ = ' ';
7097 }
7098 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7099 (unsigned long) proc_flags);
7100 p += 7 + field_size;
7101 }
7102 if (unknown_flags)
7103 {
7104 size -= 10 + field_size;
7105 if (p != buff + field_size + 4)
7106 {
7107 if (size < (2 + 1))
bee0ee85
NC
7108 {
7109 warn (_("Internal error: not enough buffer room for section flag info"));
7110 return _("<unknown>");
7111 }
8d5ff12c
L
7112 size -= 2;
7113 *p++ = ',';
7114 *p++ = ' ';
7115 }
2b692964 7116 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
7117 (unsigned long) unknown_flags);
7118 p += 10 + field_size;
7119 }
7120 }
7121
e9e44622 7122 *p = '\0';
d1133906
NC
7123 return buff;
7124}
7125
5844b465 7126static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7127get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7128 uint64_t size)
77115a4a
L
7129{
7130 if (is_32bit_elf)
7131 {
7132 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7133
ebdf1ebf
NC
7134 if (size < sizeof (* echdr))
7135 {
7136 error (_("Compressed section is too small even for a compression header\n"));
7137 return 0;
7138 }
7139
77115a4a
L
7140 chdr->ch_type = BYTE_GET (echdr->ch_type);
7141 chdr->ch_size = BYTE_GET (echdr->ch_size);
7142 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7143 return sizeof (*echdr);
7144 }
7145 else
7146 {
7147 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7148
ebdf1ebf
NC
7149 if (size < sizeof (* echdr))
7150 {
7151 error (_("Compressed section is too small even for a compression header\n"));
7152 return 0;
7153 }
7154
77115a4a
L
7155 chdr->ch_type = BYTE_GET (echdr->ch_type);
7156 chdr->ch_size = BYTE_GET (echdr->ch_size);
7157 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7158 return sizeof (*echdr);
7159 }
7160}
7161
015dc7e1 7162static bool
dda8d76d 7163process_section_headers (Filedata * filedata)
252b5132 7164{
2cf0635d 7165 Elf_Internal_Shdr * section;
b34976b6 7166 unsigned int i;
252b5132 7167
dda8d76d 7168 if (filedata->file_header.e_shnum == 0)
252b5132 7169 {
82f2dbf7 7170 /* PR binutils/12467. */
dda8d76d 7171 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7172 {
7173 warn (_("possibly corrupt ELF file header - it has a non-zero"
7174 " section header offset, but no section headers\n"));
015dc7e1 7175 return false;
32ec8896 7176 }
82f2dbf7 7177 else if (do_sections)
252b5132
RH
7178 printf (_("\nThere are no sections in this file.\n"));
7179
015dc7e1 7180 return true;
252b5132
RH
7181 }
7182
7183 if (do_sections && !do_header)
ca0e11aa
NC
7184 {
7185 if (filedata->is_separate && process_links)
7186 printf (_("In linked file '%s': "), filedata->file_name);
7187 if (! filedata->is_separate || process_links)
7188 printf (ngettext ("There is %d section header, "
26c527e6 7189 "starting at offset %#" PRIx64 ":\n",
ca0e11aa 7190 "There are %d section headers, "
26c527e6 7191 "starting at offset %#" PRIx64 ":\n",
ca0e11aa
NC
7192 filedata->file_header.e_shnum),
7193 filedata->file_header.e_shnum,
26c527e6 7194 filedata->file_header.e_shoff);
ca0e11aa 7195 }
252b5132 7196
4de91c10
AM
7197 if (!get_section_headers (filedata, false))
7198 return false;
252b5132
RH
7199
7200 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7201 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7202 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7203 {
dda8d76d 7204 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7205
c256ffe7
JJ
7206 if (section->sh_size != 0)
7207 {
dda8d76d
NC
7208 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7209 1, section->sh_size,
7210 _("string table"));
0de14b54 7211
dda8d76d 7212 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7213 }
252b5132
RH
7214 }
7215
7216 /* Scan the sections for the dynamic symbol table
e3c8793a 7217 and dynamic string table and debug sections. */
89fac5e3 7218 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7219 switch (filedata->file_header.e_machine)
89fac5e3
RS
7220 {
7221 case EM_MIPS:
7222 case EM_MIPS_RS3_LE:
7223 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7224 FDE addresses. However, the ABI also has a semi-official ILP32
7225 variant for which the normal FDE address size rules apply.
7226
7227 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7228 section, where XX is the size of longs in bits. Unfortunately,
7229 earlier compilers provided no way of distinguishing ILP32 objects
7230 from LP64 objects, so if there's any doubt, we should assume that
7231 the official LP64 form is being used. */
dda8d76d
NC
7232 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7233 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7234 eh_addr_size = 8;
7235 break;
0f56a26a
DD
7236
7237 case EM_H8_300:
7238 case EM_H8_300H:
dda8d76d 7239 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7240 {
7241 case E_H8_MACH_H8300:
7242 case E_H8_MACH_H8300HN:
7243 case E_H8_MACH_H8300SN:
7244 case E_H8_MACH_H8300SXN:
7245 eh_addr_size = 2;
7246 break;
7247 case E_H8_MACH_H8300H:
7248 case E_H8_MACH_H8300S:
7249 case E_H8_MACH_H8300SX:
7250 eh_addr_size = 4;
7251 break;
7252 }
f4236fe4
DD
7253 break;
7254
ff7eeb89 7255 case EM_M32C_OLD:
f4236fe4 7256 case EM_M32C:
dda8d76d 7257 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7258 {
7259 case EF_M32C_CPU_M16C:
7260 eh_addr_size = 2;
7261 break;
7262 }
7263 break;
89fac5e3
RS
7264 }
7265
76ca31c0
NC
7266#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7267 do \
7268 { \
be7d229a 7269 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7270 if (section->sh_entsize != expected_entsize) \
9dd3a467 7271 { \
f493c217 7272 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7273 i, section->sh_entsize); \
f493c217 7274 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7275 expected_entsize); \
9dd3a467 7276 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7277 } \
7278 } \
08d8fa11 7279 while (0)
9dd3a467
NC
7280
7281#define CHECK_ENTSIZE(section, i, type) \
1b513401 7282 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7283 sizeof (Elf64_External_##type))
7284
dda8d76d
NC
7285 for (i = 0, section = filedata->section_headers;
7286 i < filedata->file_header.e_shnum;
b34976b6 7287 i++, section++)
252b5132 7288 {
84714f86 7289 const char *name = section_name_print (filedata, section);
252b5132 7290
1b513401
NC
7291 /* Run some sanity checks on the headers and
7292 possibly fill in some file data as well. */
7293 switch (section->sh_type)
252b5132 7294 {
1b513401 7295 case SHT_DYNSYM:
978c4450 7296 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7297 {
7298 error (_("File contains multiple dynamic symbol tables\n"));
7299 continue;
7300 }
7301
08d8fa11 7302 CHECK_ENTSIZE (section, i, Sym);
978c4450 7303 filedata->dynamic_symbols
4de91c10 7304 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7305 filedata->dynamic_symtab_section = section;
1b513401
NC
7306 break;
7307
7308 case SHT_STRTAB:
7309 if (streq (name, ".dynstr"))
252b5132 7310 {
1b513401
NC
7311 if (filedata->dynamic_strings != NULL)
7312 {
7313 error (_("File contains multiple dynamic string tables\n"));
7314 continue;
7315 }
7316
7317 filedata->dynamic_strings
7318 = (char *) get_data (NULL, filedata, section->sh_offset,
7319 1, section->sh_size, _("dynamic strings"));
7320 filedata->dynamic_strings_length
7321 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7322 filedata->dynamic_strtab_section = section;
252b5132 7323 }
1b513401
NC
7324 break;
7325
7326 case SHT_SYMTAB_SHNDX:
7327 {
7328 elf_section_list * entry = xmalloc (sizeof * entry);
7329
7330 entry->hdr = section;
7331 entry->next = filedata->symtab_shndx_list;
7332 filedata->symtab_shndx_list = entry;
7333 }
7334 break;
7335
7336 case SHT_SYMTAB:
7337 CHECK_ENTSIZE (section, i, Sym);
7338 break;
7339
7340 case SHT_GROUP:
7341 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7342 break;
252b5132 7343
1b513401
NC
7344 case SHT_REL:
7345 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7346 if (do_checks && section->sh_size == 0)
1b513401
NC
7347 warn (_("Section '%s': zero-sized relocation section\n"), name);
7348 break;
7349
7350 case SHT_RELA:
7351 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7352 if (do_checks && section->sh_size == 0)
1b513401
NC
7353 warn (_("Section '%s': zero-sized relocation section\n"), name);
7354 break;
7355
682351b9
AM
7356 case SHT_RELR:
7357 CHECK_ENTSIZE (section, i, Relr);
7358 break;
7359
1b513401
NC
7360 case SHT_NOTE:
7361 case SHT_PROGBITS:
546cb2d8
NC
7362 /* Having a zero sized section is not illegal according to the
7363 ELF standard, but it might be an indication that something
7364 is wrong. So issue a warning if we are running in lint mode. */
7365 if (do_checks && section->sh_size == 0)
1b513401
NC
7366 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7367 break;
7368
7369 default:
7370 break;
7371 }
7372
7373 if ((do_debugging || do_debug_info || do_debug_abbrevs
7374 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7375 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7376 || do_debug_str || do_debug_str_offsets || do_debug_loc
7377 || do_debug_ranges
1b513401 7378 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7379 && (startswith (name, ".debug_")
7380 || startswith (name, ".zdebug_")))
252b5132 7381 {
1b315056
CS
7382 if (name[1] == 'z')
7383 name += sizeof (".zdebug_") - 1;
7384 else
7385 name += sizeof (".debug_") - 1;
252b5132
RH
7386
7387 if (do_debugging
24d127aa
ML
7388 || (do_debug_info && startswith (name, "info"))
7389 || (do_debug_info && startswith (name, "types"))
7390 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7391 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7392 || (do_debug_lines && startswith (name, "line."))
7393 || (do_debug_pubnames && startswith (name, "pubnames"))
7394 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7395 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7396 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7397 || (do_debug_aranges && startswith (name, "aranges"))
7398 || (do_debug_ranges && startswith (name, "ranges"))
7399 || (do_debug_ranges && startswith (name, "rnglists"))
7400 || (do_debug_frames && startswith (name, "frame"))
7401 || (do_debug_macinfo && startswith (name, "macinfo"))
7402 || (do_debug_macinfo && startswith (name, "macro"))
7403 || (do_debug_str && startswith (name, "str"))
7404 || (do_debug_links && startswith (name, "sup"))
7405 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7406 || (do_debug_loc && startswith (name, "loc"))
7407 || (do_debug_loc && startswith (name, "loclists"))
7408 || (do_debug_addr && startswith (name, "addr"))
7409 || (do_debug_cu_index && startswith (name, "cu_index"))
7410 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7411 )
6431e409 7412 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7413 }
a262ae96 7414 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7415 else if ((do_debugging || do_debug_info)
24d127aa 7416 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7417 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7418 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7419 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7420 else if (do_gdb_index && (streq (name, ".gdb_index")
7421 || streq (name, ".debug_names")))
6431e409 7422 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7423 /* Trace sections for Itanium VMS. */
7424 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7425 || do_trace_aranges)
24d127aa 7426 && startswith (name, ".trace_"))
6f875884
TG
7427 {
7428 name += sizeof (".trace_") - 1;
7429
7430 if (do_debugging
7431 || (do_trace_info && streq (name, "info"))
7432 || (do_trace_abbrevs && streq (name, "abbrev"))
7433 || (do_trace_aranges && streq (name, "aranges"))
7434 )
6431e409 7435 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7436 }
dda8d76d 7437 else if ((do_debugging || do_debug_links)
24d127aa
ML
7438 && (startswith (name, ".gnu_debuglink")
7439 || startswith (name, ".gnu_debugaltlink")))
6431e409 7440 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7441 }
7442
7443 if (! do_sections)
015dc7e1 7444 return true;
252b5132 7445
ca0e11aa 7446 if (filedata->is_separate && ! process_links)
015dc7e1 7447 return true;
ca0e11aa
NC
7448
7449 if (filedata->is_separate)
7450 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7451 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7452 printf (_("\nSection Headers:\n"));
7453 else
7454 printf (_("\nSection Header:\n"));
76da6bbe 7455
f7a99963 7456 if (is_32bit_elf)
595cf52e 7457 {
5477e8a0 7458 if (do_section_details)
595cf52e
L
7459 {
7460 printf (_(" [Nr] Name\n"));
5477e8a0 7461 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7462 }
7463 else
7464 printf
7465 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7466 }
d974e256 7467 else if (do_wide)
595cf52e 7468 {
5477e8a0 7469 if (do_section_details)
595cf52e
L
7470 {
7471 printf (_(" [Nr] Name\n"));
5477e8a0 7472 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7473 }
7474 else
7475 printf
7476 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7477 }
f7a99963
NC
7478 else
7479 {
5477e8a0 7480 if (do_section_details)
595cf52e
L
7481 {
7482 printf (_(" [Nr] Name\n"));
5477e8a0
L
7483 printf (_(" Type Address Offset Link\n"));
7484 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7485 }
7486 else
7487 {
7488 printf (_(" [Nr] Name Type Address Offset\n"));
7489 printf (_(" Size EntSize Flags Link Info Align\n"));
7490 }
f7a99963 7491 }
252b5132 7492
5477e8a0
L
7493 if (do_section_details)
7494 printf (_(" Flags\n"));
7495
dda8d76d
NC
7496 for (i = 0, section = filedata->section_headers;
7497 i < filedata->file_header.e_shnum;
b34976b6 7498 i++, section++)
252b5132 7499 {
dd905818
NC
7500 /* Run some sanity checks on the section header. */
7501
7502 /* Check the sh_link field. */
7503 switch (section->sh_type)
7504 {
285e3f99
AM
7505 case SHT_REL:
7506 case SHT_RELA:
7507 if (section->sh_link == 0
7508 && (filedata->file_header.e_type == ET_EXEC
7509 || filedata->file_header.e_type == ET_DYN))
7510 /* A dynamic relocation section where all entries use a
7511 zero symbol index need not specify a symtab section. */
7512 break;
7513 /* Fall through. */
dd905818
NC
7514 case SHT_SYMTAB_SHNDX:
7515 case SHT_GROUP:
7516 case SHT_HASH:
7517 case SHT_GNU_HASH:
7518 case SHT_GNU_versym:
285e3f99 7519 if (section->sh_link == 0
dda8d76d
NC
7520 || section->sh_link >= filedata->file_header.e_shnum
7521 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7522 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7523 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7524 i, section->sh_link);
7525 break;
7526
7527 case SHT_DYNAMIC:
7528 case SHT_SYMTAB:
7529 case SHT_DYNSYM:
7530 case SHT_GNU_verneed:
7531 case SHT_GNU_verdef:
7532 case SHT_GNU_LIBLIST:
285e3f99 7533 if (section->sh_link == 0
dda8d76d
NC
7534 || section->sh_link >= filedata->file_header.e_shnum
7535 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7536 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7537 i, section->sh_link);
7538 break;
7539
7540 case SHT_INIT_ARRAY:
7541 case SHT_FINI_ARRAY:
7542 case SHT_PREINIT_ARRAY:
7543 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7544 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7545 i, section->sh_link);
7546 break;
7547
7548 default:
7549 /* FIXME: Add support for target specific section types. */
7550#if 0 /* Currently we do not check other section types as there are too
7551 many special cases. Stab sections for example have a type
7552 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7553 section. */
7554 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7555 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7556 i, section->sh_link);
7557#endif
7558 break;
7559 }
7560
7561 /* Check the sh_info field. */
7562 switch (section->sh_type)
7563 {
7564 case SHT_REL:
7565 case SHT_RELA:
285e3f99
AM
7566 if (section->sh_info == 0
7567 && (filedata->file_header.e_type == ET_EXEC
7568 || filedata->file_header.e_type == ET_DYN))
7569 /* Dynamic relocations apply to segments, so they do not
7570 need to specify the section they relocate. */
7571 break;
7572 if (section->sh_info == 0
dda8d76d
NC
7573 || section->sh_info >= filedata->file_header.e_shnum
7574 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7575 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7576 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7577 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7578 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7579 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7580 /* FIXME: Are other section types valid ? */
dda8d76d 7581 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7582 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7583 i, section->sh_info);
dd905818
NC
7584 break;
7585
7586 case SHT_DYNAMIC:
7587 case SHT_HASH:
7588 case SHT_SYMTAB_SHNDX:
7589 case SHT_INIT_ARRAY:
7590 case SHT_FINI_ARRAY:
7591 case SHT_PREINIT_ARRAY:
7592 if (section->sh_info != 0)
7593 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7594 i, section->sh_info);
7595 break;
7596
7597 case SHT_GROUP:
7598 case SHT_SYMTAB:
7599 case SHT_DYNSYM:
7600 /* A symbol index - we assume that it is valid. */
7601 break;
7602
7603 default:
7604 /* FIXME: Add support for target specific section types. */
7605 if (section->sh_type == SHT_NOBITS)
7606 /* NOBITS section headers with non-zero sh_info fields can be
7607 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7608 information. The stripped sections have their headers
7609 preserved but their types set to SHT_NOBITS. So do not check
7610 this type of section. */
dd905818
NC
7611 ;
7612 else if (section->sh_flags & SHF_INFO_LINK)
7613 {
dda8d76d 7614 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7615 warn (_("[%2u]: Expected link to another section in info field"), i);
7616 }
a91e1603
L
7617 else if (section->sh_type < SHT_LOOS
7618 && (section->sh_flags & SHF_GNU_MBIND) == 0
7619 && section->sh_info != 0)
dd905818
NC
7620 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7621 i, section->sh_info);
7622 break;
7623 }
7624
3e6b6445 7625 /* Check the sh_size field. */
dda8d76d 7626 if (section->sh_size > filedata->file_size
3e6b6445
NC
7627 && section->sh_type != SHT_NOBITS
7628 && section->sh_type != SHT_NULL
7629 && section->sh_type < SHT_LOOS)
7630 warn (_("Size of section %u is larger than the entire file!\n"), i);
7631
7bfd842d 7632 printf (" [%2u] ", i);
5477e8a0 7633 if (do_section_details)
dda8d76d 7634 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7635 else
84714f86 7636 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7637
ea52a088 7638 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7639 get_section_type_name (filedata, section->sh_type));
0b4362b0 7640
f7a99963
NC
7641 if (is_32bit_elf)
7642 {
cfcac11d
NC
7643 const char * link_too_big = NULL;
7644
f7a99963 7645 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7646
f7a99963
NC
7647 printf ( " %6.6lx %6.6lx %2.2lx",
7648 (unsigned long) section->sh_offset,
7649 (unsigned long) section->sh_size,
7650 (unsigned long) section->sh_entsize);
d1133906 7651
5477e8a0
L
7652 if (do_section_details)
7653 fputs (" ", stdout);
7654 else
dda8d76d 7655 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7656
dda8d76d 7657 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7658 {
7659 link_too_big = "";
7660 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7661 an error but it can have special values in Solaris binaries. */
dda8d76d 7662 switch (filedata->file_header.e_machine)
cfcac11d 7663 {
caa83f8b 7664 case EM_386:
22abe556 7665 case EM_IAMCU:
caa83f8b 7666 case EM_X86_64:
7f502d6c 7667 case EM_L1OM:
7a9068fe 7668 case EM_K1OM:
cfcac11d
NC
7669 case EM_OLD_SPARCV9:
7670 case EM_SPARC32PLUS:
7671 case EM_SPARCV9:
7672 case EM_SPARC:
7673 if (section->sh_link == (SHN_BEFORE & 0xffff))
7674 link_too_big = "BEFORE";
7675 else if (section->sh_link == (SHN_AFTER & 0xffff))
7676 link_too_big = "AFTER";
7677 break;
7678 default:
7679 break;
7680 }
7681 }
7682
7683 if (do_section_details)
7684 {
7685 if (link_too_big != NULL && * link_too_big)
7686 printf ("<%s> ", link_too_big);
7687 else
7688 printf ("%2u ", section->sh_link);
7689 printf ("%3u %2lu\n", section->sh_info,
7690 (unsigned long) section->sh_addralign);
7691 }
7692 else
7693 printf ("%2u %3u %2lu\n",
7694 section->sh_link,
7695 section->sh_info,
7696 (unsigned long) section->sh_addralign);
7697
7698 if (link_too_big && ! * link_too_big)
7699 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7700 i, section->sh_link);
f7a99963 7701 }
d974e256
JJ
7702 else if (do_wide)
7703 {
7704 print_vma (section->sh_addr, LONG_HEX);
7705
7706 if ((long) section->sh_offset == section->sh_offset)
7707 printf (" %6.6lx", (unsigned long) section->sh_offset);
7708 else
7709 {
7710 putchar (' ');
7711 print_vma (section->sh_offset, LONG_HEX);
7712 }
7713
7714 if ((unsigned long) section->sh_size == section->sh_size)
7715 printf (" %6.6lx", (unsigned long) section->sh_size);
7716 else
7717 {
7718 putchar (' ');
7719 print_vma (section->sh_size, LONG_HEX);
7720 }
7721
7722 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7723 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7724 else
7725 {
7726 putchar (' ');
7727 print_vma (section->sh_entsize, LONG_HEX);
7728 }
7729
5477e8a0
L
7730 if (do_section_details)
7731 fputs (" ", stdout);
7732 else
dda8d76d 7733 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7734
72de5009 7735 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7736
7737 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7738 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7739 else
7740 {
7741 print_vma (section->sh_addralign, DEC);
7742 putchar ('\n');
7743 }
7744 }
5477e8a0 7745 else if (do_section_details)
595cf52e 7746 {
55cc53e9 7747 putchar (' ');
595cf52e
L
7748 print_vma (section->sh_addr, LONG_HEX);
7749 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7750 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7751 else
7752 {
7753 printf (" ");
7754 print_vma (section->sh_offset, LONG_HEX);
7755 }
72de5009 7756 printf (" %u\n ", section->sh_link);
595cf52e 7757 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7758 putchar (' ');
595cf52e
L
7759 print_vma (section->sh_entsize, LONG_HEX);
7760
72de5009
AM
7761 printf (" %-16u %lu\n",
7762 section->sh_info,
595cf52e
L
7763 (unsigned long) section->sh_addralign);
7764 }
f7a99963
NC
7765 else
7766 {
7767 putchar (' ');
7768 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7769 if ((long) section->sh_offset == section->sh_offset)
7770 printf (" %8.8lx", (unsigned long) section->sh_offset);
7771 else
7772 {
7773 printf (" ");
7774 print_vma (section->sh_offset, LONG_HEX);
7775 }
f7a99963
NC
7776 printf ("\n ");
7777 print_vma (section->sh_size, LONG_HEX);
7778 printf (" ");
7779 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7780
dda8d76d 7781 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7782
72de5009
AM
7783 printf (" %2u %3u %lu\n",
7784 section->sh_link,
7785 section->sh_info,
f7a99963
NC
7786 (unsigned long) section->sh_addralign);
7787 }
5477e8a0
L
7788
7789 if (do_section_details)
77115a4a 7790 {
dda8d76d 7791 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7792 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7793 {
7794 /* Minimum section size is 12 bytes for 32-bit compression
7795 header + 12 bytes for compressed data header. */
7796 unsigned char buf[24];
d8024a91 7797
77115a4a 7798 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7799 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7800 sizeof (buf), _("compression header")))
7801 {
7802 Elf_Internal_Chdr chdr;
d8024a91 7803
5844b465
NC
7804 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7805 printf (_(" [<corrupt>]\n"));
77115a4a 7806 else
5844b465 7807 {
89dbeac7 7808 if (chdr.ch_type == ch_compress_zlib)
5844b465 7809 printf (" ZLIB, ");
89dbeac7 7810 else if (chdr.ch_type == ch_compress_zstd)
1369522f 7811 printf (" ZSTD, ");
5844b465
NC
7812 else
7813 printf (_(" [<unknown>: 0x%x], "),
7814 chdr.ch_type);
7815 print_vma (chdr.ch_size, LONG_HEX);
7816 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7817 }
77115a4a
L
7818 }
7819 }
7820 }
252b5132
RH
7821 }
7822
5477e8a0 7823 if (!do_section_details)
3dbcc61d 7824 {
9fb71ee4
NC
7825 /* The ordering of the letters shown here matches the ordering of the
7826 corresponding SHF_xxx values, and hence the order in which these
7827 letters will be displayed to the user. */
7828 printf (_("Key to Flags:\n\
7829 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7830 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7831 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7832 switch (filedata->file_header.e_ident[EI_OSABI])
7833 {
7834 case ELFOSABI_GNU:
7835 case ELFOSABI_FREEBSD:
7836 printf (_("R (retain), "));
7837 /* Fall through */
7838 case ELFOSABI_NONE:
7839 printf (_("D (mbind), "));
7840 break;
7841 default:
7842 break;
7843 }
dda8d76d
NC
7844 if (filedata->file_header.e_machine == EM_X86_64
7845 || filedata->file_header.e_machine == EM_L1OM
7846 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7847 printf (_("l (large), "));
dda8d76d 7848 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7849 printf (_("y (purecode), "));
dda8d76d 7850 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7851 printf (_("v (VLE), "));
9fb71ee4 7852 printf ("p (processor specific)\n");
0b4362b0 7853 }
d1133906 7854
015dc7e1 7855 return true;
252b5132
RH
7856}
7857
015dc7e1 7858static bool
28d13567 7859get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
26c527e6
AM
7860 Elf_Internal_Sym **symtab, uint64_t *nsyms,
7861 char **strtab, uint64_t *strtablen)
28d13567
AM
7862{
7863 *strtab = NULL;
7864 *strtablen = 0;
4de91c10 7865 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7866
7867 if (*symtab == NULL)
015dc7e1 7868 return false;
28d13567
AM
7869
7870 if (symsec->sh_link != 0)
7871 {
7872 Elf_Internal_Shdr *strsec;
7873
7874 if (symsec->sh_link >= filedata->file_header.e_shnum)
7875 {
7876 error (_("Bad sh_link in symbol table section\n"));
7877 free (*symtab);
7878 *symtab = NULL;
7879 *nsyms = 0;
015dc7e1 7880 return false;
28d13567
AM
7881 }
7882
7883 strsec = filedata->section_headers + symsec->sh_link;
7884
7885 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7886 1, strsec->sh_size, _("string table"));
7887 if (*strtab == NULL)
7888 {
7889 free (*symtab);
7890 *symtab = NULL;
7891 *nsyms = 0;
015dc7e1 7892 return false;
28d13567
AM
7893 }
7894 *strtablen = strsec->sh_size;
7895 }
015dc7e1 7896 return true;
28d13567
AM
7897}
7898
f5842774
L
7899static const char *
7900get_group_flags (unsigned int flags)
7901{
1449284b 7902 static char buff[128];
220453ec 7903
6d913794
NC
7904 if (flags == 0)
7905 return "";
7906 else if (flags == GRP_COMDAT)
7907 return "COMDAT ";
f5842774 7908
89246a0e
AM
7909 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7910 flags,
7911 flags & GRP_MASKOS ? _("<OS specific>") : "",
7912 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7913 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7914 ? _("<unknown>") : ""));
6d913794 7915
f5842774
L
7916 return buff;
7917}
7918
015dc7e1 7919static bool
dda8d76d 7920process_section_groups (Filedata * filedata)
f5842774 7921{
2cf0635d 7922 Elf_Internal_Shdr * section;
f5842774 7923 unsigned int i;
2cf0635d
NC
7924 struct group * group;
7925 Elf_Internal_Shdr * symtab_sec;
7926 Elf_Internal_Shdr * strtab_sec;
7927 Elf_Internal_Sym * symtab;
26c527e6 7928 uint64_t num_syms;
2cf0635d 7929 char * strtab;
c256ffe7 7930 size_t strtab_size;
d1f5c6e3
L
7931
7932 /* Don't process section groups unless needed. */
7933 if (!do_unwind && !do_section_groups)
015dc7e1 7934 return true;
f5842774 7935
dda8d76d 7936 if (filedata->file_header.e_shnum == 0)
f5842774
L
7937 {
7938 if (do_section_groups)
ca0e11aa
NC
7939 {
7940 if (filedata->is_separate)
7941 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7942 filedata->file_name);
7943 else
7944 printf (_("\nThere are no section groups in this file.\n"));
7945 }
015dc7e1 7946 return true;
f5842774
L
7947 }
7948
dda8d76d 7949 if (filedata->section_headers == NULL)
f5842774
L
7950 {
7951 error (_("Section headers are not available!\n"));
fa1908fd 7952 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7953 return false;
f5842774
L
7954 }
7955
978c4450
AM
7956 filedata->section_headers_groups
7957 = (struct group **) calloc (filedata->file_header.e_shnum,
7958 sizeof (struct group *));
e4b17d5c 7959
978c4450 7960 if (filedata->section_headers_groups == NULL)
e4b17d5c 7961 {
8b73c356 7962 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7963 filedata->file_header.e_shnum);
015dc7e1 7964 return false;
e4b17d5c
L
7965 }
7966
f5842774 7967 /* Scan the sections for the group section. */
978c4450 7968 filedata->group_count = 0;
dda8d76d
NC
7969 for (i = 0, section = filedata->section_headers;
7970 i < filedata->file_header.e_shnum;
f5842774 7971 i++, section++)
e4b17d5c 7972 if (section->sh_type == SHT_GROUP)
978c4450 7973 filedata->group_count++;
e4b17d5c 7974
978c4450 7975 if (filedata->group_count == 0)
d1f5c6e3
L
7976 {
7977 if (do_section_groups)
ca0e11aa
NC
7978 {
7979 if (filedata->is_separate)
7980 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7981 filedata->file_name);
7982 else
7983 printf (_("\nThere are no section groups in this file.\n"));
7984 }
d1f5c6e3 7985
015dc7e1 7986 return true;
d1f5c6e3
L
7987 }
7988
978c4450
AM
7989 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7990 sizeof (struct group));
e4b17d5c 7991
978c4450 7992 if (filedata->section_groups == NULL)
e4b17d5c 7993 {
26c527e6 7994 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
015dc7e1 7995 return false;
e4b17d5c
L
7996 }
7997
d1f5c6e3
L
7998 symtab_sec = NULL;
7999 strtab_sec = NULL;
8000 symtab = NULL;
ba5cdace 8001 num_syms = 0;
d1f5c6e3 8002 strtab = NULL;
c256ffe7 8003 strtab_size = 0;
ca0e11aa
NC
8004
8005 if (filedata->is_separate)
8006 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 8007
978c4450 8008 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 8009 i < filedata->file_header.e_shnum;
e4b17d5c 8010 i++, section++)
f5842774
L
8011 {
8012 if (section->sh_type == SHT_GROUP)
8013 {
dda8d76d 8014 const char * name = printable_section_name (filedata, section);
74e1a04b 8015 const char * group_name;
2cf0635d
NC
8016 unsigned char * start;
8017 unsigned char * indices;
f5842774 8018 unsigned int entry, j, size;
2cf0635d
NC
8019 Elf_Internal_Shdr * sec;
8020 Elf_Internal_Sym * sym;
f5842774
L
8021
8022 /* Get the symbol table. */
dda8d76d
NC
8023 if (section->sh_link >= filedata->file_header.e_shnum
8024 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 8025 != SHT_SYMTAB))
f5842774
L
8026 {
8027 error (_("Bad sh_link in group section `%s'\n"), name);
8028 continue;
8029 }
d1f5c6e3
L
8030
8031 if (symtab_sec != sec)
8032 {
8033 symtab_sec = sec;
9db70fc3 8034 free (symtab);
4de91c10 8035 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 8036 }
f5842774 8037
dd24e3da
NC
8038 if (symtab == NULL)
8039 {
8040 error (_("Corrupt header in group section `%s'\n"), name);
8041 continue;
8042 }
8043
ba5cdace
NC
8044 if (section->sh_info >= num_syms)
8045 {
8046 error (_("Bad sh_info in group section `%s'\n"), name);
8047 continue;
8048 }
8049
f5842774
L
8050 sym = symtab + section->sh_info;
8051
8052 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8053 {
4fbb74a6 8054 if (sym->st_shndx == 0
dda8d76d 8055 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
8056 {
8057 error (_("Bad sh_info in group section `%s'\n"), name);
8058 continue;
8059 }
ba2685cc 8060
84714f86
AM
8061 group_name = section_name_print (filedata,
8062 filedata->section_headers
b9e920ec 8063 + sym->st_shndx);
c256ffe7 8064 strtab_sec = NULL;
9db70fc3 8065 free (strtab);
f5842774 8066 strtab = NULL;
c256ffe7 8067 strtab_size = 0;
f5842774
L
8068 }
8069 else
8070 {
8071 /* Get the string table. */
dda8d76d 8072 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8073 {
8074 strtab_sec = NULL;
9db70fc3 8075 free (strtab);
c256ffe7
JJ
8076 strtab = NULL;
8077 strtab_size = 0;
8078 }
8079 else if (strtab_sec
dda8d76d 8080 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8081 {
8082 strtab_sec = sec;
9db70fc3 8083 free (strtab);
071436c6 8084
dda8d76d 8085 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8086 1, strtab_sec->sh_size,
8087 _("string table"));
c256ffe7 8088 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8089 }
c256ffe7 8090 group_name = sym->st_name < strtab_size
2b692964 8091 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8092 }
8093
c9c1d674
EG
8094 /* PR 17531: file: loop. */
8095 if (section->sh_entsize > section->sh_size)
8096 {
26c527e6
AM
8097 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8098 " which is larger than its size (%#" PRIx64 ")\n"),
dda8d76d 8099 printable_section_name (filedata, section),
26c527e6
AM
8100 section->sh_entsize,
8101 section->sh_size);
61dd8e19 8102 continue;
c9c1d674
EG
8103 }
8104
dda8d76d 8105 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8106 1, section->sh_size,
8107 _("section data"));
59245841
NC
8108 if (start == NULL)
8109 continue;
f5842774
L
8110
8111 indices = start;
8112 size = (section->sh_size / section->sh_entsize) - 1;
8113 entry = byte_get (indices, 4);
8114 indices += 4;
e4b17d5c
L
8115
8116 if (do_section_groups)
8117 {
2b692964 8118 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8119 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8120
e4b17d5c
L
8121 printf (_(" [Index] Name\n"));
8122 }
8123
8124 group->group_index = i;
8125
f5842774
L
8126 for (j = 0; j < size; j++)
8127 {
2cf0635d 8128 struct group_list * g;
e4b17d5c 8129
f5842774
L
8130 entry = byte_get (indices, 4);
8131 indices += 4;
8132
dda8d76d 8133 if (entry >= filedata->file_header.e_shnum)
391cb864 8134 {
57028622
NC
8135 static unsigned num_group_errors = 0;
8136
8137 if (num_group_errors ++ < 10)
8138 {
8139 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8140 entry, i, filedata->file_header.e_shnum - 1);
57028622 8141 if (num_group_errors == 10)
67ce483b 8142 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8143 }
391cb864
L
8144 continue;
8145 }
391cb864 8146
978c4450 8147 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8148 {
d1f5c6e3
L
8149 if (entry)
8150 {
57028622
NC
8151 static unsigned num_errs = 0;
8152
8153 if (num_errs ++ < 10)
8154 {
8155 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8156 entry, i,
978c4450 8157 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8158 if (num_errs == 10)
8159 warn (_("Further error messages about already contained group sections suppressed\n"));
8160 }
d1f5c6e3
L
8161 continue;
8162 }
8163 else
8164 {
8165 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8166 section group. We just warn it the first time
d1f5c6e3 8167 and ignore it afterwards. */
015dc7e1 8168 static bool warned = false;
d1f5c6e3
L
8169 if (!warned)
8170 {
8171 error (_("section 0 in group section [%5u]\n"),
978c4450 8172 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8173 warned = true;
d1f5c6e3
L
8174 }
8175 }
e4b17d5c
L
8176 }
8177
978c4450 8178 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8179
8180 if (do_section_groups)
8181 {
dda8d76d
NC
8182 sec = filedata->section_headers + entry;
8183 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8184 }
8185
3f5e193b 8186 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8187 g->section_index = entry;
8188 g->next = group->root;
8189 group->root = g;
f5842774
L
8190 }
8191
9db70fc3 8192 free (start);
e4b17d5c
L
8193
8194 group++;
f5842774
L
8195 }
8196 }
8197
9db70fc3
AM
8198 free (symtab);
8199 free (strtab);
015dc7e1 8200 return true;
f5842774
L
8201}
8202
28f997cf
TG
8203/* Data used to display dynamic fixups. */
8204
8205struct ia64_vms_dynfixup
8206{
625d49fc
AM
8207 uint64_t needed_ident; /* Library ident number. */
8208 uint64_t needed; /* Index in the dstrtab of the library name. */
8209 uint64_t fixup_needed; /* Index of the library. */
8210 uint64_t fixup_rela_cnt; /* Number of fixups. */
8211 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8212};
8213
8214/* Data used to display dynamic relocations. */
8215
8216struct ia64_vms_dynimgrela
8217{
625d49fc
AM
8218 uint64_t img_rela_cnt; /* Number of relocations. */
8219 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8220};
8221
8222/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8223 library). */
8224
015dc7e1 8225static bool
dda8d76d
NC
8226dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8227 struct ia64_vms_dynfixup * fixup,
8228 const char * strtab,
8229 unsigned int strtab_sz)
28f997cf 8230{
32ec8896 8231 Elf64_External_VMS_IMAGE_FIXUP * imfs;
26c527e6 8232 size_t i;
32ec8896 8233 const char * lib_name;
28f997cf 8234
978c4450
AM
8235 imfs = get_data (NULL, filedata,
8236 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8237 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8238 _("dynamic section image fixups"));
8239 if (!imfs)
015dc7e1 8240 return false;
28f997cf
TG
8241
8242 if (fixup->needed < strtab_sz)
8243 lib_name = strtab + fixup->needed;
8244 else
8245 {
26c527e6
AM
8246 warn (_("corrupt library name index of %#" PRIx64
8247 " found in dynamic entry"), fixup->needed);
28f997cf
TG
8248 lib_name = "???";
8249 }
736990c4 8250
26c527e6
AM
8251 printf (_("\nImage fixups for needed library #%" PRId64
8252 ": %s - ident: %" PRIx64 "\n"),
8253 fixup->fixup_needed, lib_name, fixup->needed_ident);
28f997cf
TG
8254 printf
8255 (_("Seg Offset Type SymVec DataType\n"));
8256
26c527e6 8257 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
28f997cf
TG
8258 {
8259 unsigned int type;
8260 const char *rtype;
8261
8262 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8263 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8264 type = BYTE_GET (imfs [i].type);
8265 rtype = elf_ia64_reloc_type (type);
8266 if (rtype == NULL)
f493c217 8267 printf ("0x%08x ", type);
28f997cf 8268 else
f493c217 8269 printf ("%-32s ", rtype);
28f997cf
TG
8270 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8271 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8272 }
8273
8274 free (imfs);
015dc7e1 8275 return true;
28f997cf
TG
8276}
8277
8278/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8279
015dc7e1 8280static bool
dda8d76d 8281dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8282{
8283 Elf64_External_VMS_IMAGE_RELA *imrs;
26c527e6 8284 size_t i;
28f997cf 8285
978c4450
AM
8286 imrs = get_data (NULL, filedata,
8287 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8288 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8289 _("dynamic section image relocations"));
28f997cf 8290 if (!imrs)
015dc7e1 8291 return false;
28f997cf
TG
8292
8293 printf (_("\nImage relocs\n"));
8294 printf
8295 (_("Seg Offset Type Addend Seg Sym Off\n"));
8296
26c527e6 8297 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
28f997cf
TG
8298 {
8299 unsigned int type;
8300 const char *rtype;
8301
8302 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8303 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8304 type = BYTE_GET (imrs [i].type);
8305 rtype = elf_ia64_reloc_type (type);
8306 if (rtype == NULL)
8307 printf ("0x%08x ", type);
8308 else
8309 printf ("%-31s ", rtype);
8310 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8311 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8312 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8313 }
8314
8315 free (imrs);
015dc7e1 8316 return true;
28f997cf
TG
8317}
8318
8319/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8320
015dc7e1 8321static bool
dda8d76d 8322process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8323{
8324 struct ia64_vms_dynfixup fixup;
8325 struct ia64_vms_dynimgrela imgrela;
8326 Elf_Internal_Dyn *entry;
625d49fc
AM
8327 uint64_t strtab_off = 0;
8328 uint64_t strtab_sz = 0;
28f997cf 8329 char *strtab = NULL;
015dc7e1 8330 bool res = true;
28f997cf
TG
8331
8332 memset (&fixup, 0, sizeof (fixup));
8333 memset (&imgrela, 0, sizeof (imgrela));
8334
8335 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8336 for (entry = filedata->dynamic_section;
8337 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8338 entry++)
8339 {
8340 switch (entry->d_tag)
8341 {
8342 case DT_IA_64_VMS_STRTAB_OFFSET:
8343 strtab_off = entry->d_un.d_val;
8344 break;
8345 case DT_STRSZ:
8346 strtab_sz = entry->d_un.d_val;
8347 if (strtab == NULL)
978c4450
AM
8348 strtab = get_data (NULL, filedata,
8349 filedata->dynamic_addr + strtab_off,
28f997cf 8350 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8351 if (strtab == NULL)
8352 strtab_sz = 0;
28f997cf
TG
8353 break;
8354
8355 case DT_IA_64_VMS_NEEDED_IDENT:
8356 fixup.needed_ident = entry->d_un.d_val;
8357 break;
8358 case DT_NEEDED:
8359 fixup.needed = entry->d_un.d_val;
8360 break;
8361 case DT_IA_64_VMS_FIXUP_NEEDED:
8362 fixup.fixup_needed = entry->d_un.d_val;
8363 break;
8364 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8365 fixup.fixup_rela_cnt = entry->d_un.d_val;
8366 break;
8367 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8368 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8369 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8370 res = false;
28f997cf 8371 break;
28f997cf
TG
8372 case DT_IA_64_VMS_IMG_RELA_CNT:
8373 imgrela.img_rela_cnt = entry->d_un.d_val;
8374 break;
8375 case DT_IA_64_VMS_IMG_RELA_OFF:
8376 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8377 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8378 res = false;
28f997cf
TG
8379 break;
8380
8381 default:
8382 break;
8383 }
8384 }
8385
9db70fc3 8386 free (strtab);
28f997cf
TG
8387
8388 return res;
8389}
8390
85b1c36d 8391static struct
566b0d53 8392{
2cf0635d 8393 const char * name;
566b0d53
L
8394 int reloc;
8395 int size;
a7fd1186 8396 relocation_type rel_type;
32ec8896
NC
8397}
8398 dynamic_relocations [] =
566b0d53 8399{
a7fd1186
FS
8400 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8401 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8402 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8403 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8404};
8405
252b5132 8406/* Process the reloc section. */
18bd398b 8407
015dc7e1 8408static bool
dda8d76d 8409process_relocs (Filedata * filedata)
252b5132 8410{
26c527e6
AM
8411 uint64_t rel_size;
8412 uint64_t rel_offset;
252b5132 8413
252b5132 8414 if (!do_reloc)
015dc7e1 8415 return true;
252b5132
RH
8416
8417 if (do_using_dynamic)
8418 {
a7fd1186 8419 relocation_type rel_type;
2cf0635d 8420 const char * name;
015dc7e1 8421 bool has_dynamic_reloc;
566b0d53 8422 unsigned int i;
0de14b54 8423
015dc7e1 8424 has_dynamic_reloc = false;
252b5132 8425
566b0d53 8426 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8427 {
a7fd1186 8428 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8429 name = dynamic_relocations [i].name;
978c4450
AM
8430 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8431 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8432
32ec8896 8433 if (rel_size)
015dc7e1 8434 has_dynamic_reloc = true;
566b0d53 8435
a7fd1186 8436 if (rel_type == reltype_unknown)
aa903cfb 8437 {
566b0d53 8438 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8439 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8440 {
8441 case DT_REL:
a7fd1186 8442 rel_type = reltype_rel;
566b0d53
L
8443 break;
8444 case DT_RELA:
a7fd1186 8445 rel_type = reltype_rela;
566b0d53
L
8446 break;
8447 }
aa903cfb 8448 }
252b5132 8449
566b0d53
L
8450 if (rel_size)
8451 {
ca0e11aa
NC
8452 if (filedata->is_separate)
8453 printf
26c527e6
AM
8454 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
8455 " contains %" PRId64 " bytes:\n"),
ca0e11aa
NC
8456 filedata->file_name, name, rel_offset, rel_size);
8457 else
8458 printf
26c527e6
AM
8459 (_("\n'%s' relocation section at offset %#" PRIx64
8460 " contains %" PRId64 " bytes:\n"),
ca0e11aa 8461 name, rel_offset, rel_size);
252b5132 8462
dda8d76d
NC
8463 dump_relocations (filedata,
8464 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8465 rel_size,
978c4450
AM
8466 filedata->dynamic_symbols,
8467 filedata->num_dynamic_syms,
8468 filedata->dynamic_strings,
8469 filedata->dynamic_strings_length,
a7fd1186 8470 rel_type, true /* is_dynamic */);
566b0d53 8471 }
252b5132 8472 }
566b0d53 8473
dda8d76d
NC
8474 if (is_ia64_vms (filedata))
8475 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8476 has_dynamic_reloc = true;
28f997cf 8477
566b0d53 8478 if (! has_dynamic_reloc)
ca0e11aa
NC
8479 {
8480 if (filedata->is_separate)
8481 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8482 filedata->file_name);
8483 else
8484 printf (_("\nThere are no dynamic relocations in this file.\n"));
8485 }
252b5132
RH
8486 }
8487 else
8488 {
2cf0635d 8489 Elf_Internal_Shdr * section;
26c527e6 8490 size_t i;
015dc7e1 8491 bool found = false;
252b5132 8492
dda8d76d
NC
8493 for (i = 0, section = filedata->section_headers;
8494 i < filedata->file_header.e_shnum;
b34976b6 8495 i++, section++)
252b5132
RH
8496 {
8497 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8498 && section->sh_type != SHT_REL
8499 && section->sh_type != SHT_RELR)
252b5132
RH
8500 continue;
8501
8502 rel_offset = section->sh_offset;
8503 rel_size = section->sh_size;
8504
8505 if (rel_size)
8506 {
a7fd1186 8507 relocation_type rel_type;
26c527e6 8508 uint64_t num_rela;
103f02d3 8509
ca0e11aa
NC
8510 if (filedata->is_separate)
8511 printf (_("\nIn linked file '%s' relocation section "),
8512 filedata->file_name);
8513 else
8514 printf (_("\nRelocation section "));
252b5132 8515
dda8d76d 8516 if (filedata->string_table == NULL)
19936277 8517 printf ("%d", section->sh_name);
252b5132 8518 else
dda8d76d 8519 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8520
d3a49aa8 8521 num_rela = rel_size / section->sh_entsize;
26c527e6
AM
8522 printf (ngettext (" at offset %#" PRIx64
8523 " contains %" PRIu64 " entry:\n",
8524 " at offset %#" PRIx64
8525 " contains %" PRId64 " entries:\n",
d3a49aa8
AM
8526 num_rela),
8527 rel_offset, num_rela);
252b5132 8528
a7fd1186
FS
8529 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8530 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8531
4fbb74a6 8532 if (section->sh_link != 0
dda8d76d 8533 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8534 {
26c527e6
AM
8535 Elf_Internal_Shdr *symsec;
8536 Elf_Internal_Sym *symtab;
8537 uint64_t nsyms;
8538 uint64_t strtablen = 0;
8539 char *strtab = NULL;
57346661 8540
dda8d76d 8541 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8542 if (symsec->sh_type != SHT_SYMTAB
8543 && symsec->sh_type != SHT_DYNSYM)
8544 continue;
8545
28d13567
AM
8546 if (!get_symtab (filedata, symsec,
8547 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8548 continue;
252b5132 8549
dda8d76d 8550 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8551 symtab, nsyms, strtab, strtablen,
a7fd1186 8552 rel_type,
bb4d2ac2 8553 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8554 free (strtab);
d79b3d50
NC
8555 free (symtab);
8556 }
8557 else
dda8d76d 8558 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8559 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8560
015dc7e1 8561 found = true;
252b5132
RH
8562 }
8563 }
8564
8565 if (! found)
45ac8f4f
NC
8566 {
8567 /* Users sometimes forget the -D option, so try to be helpful. */
8568 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8569 {
978c4450 8570 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8571 {
ca0e11aa
NC
8572 if (filedata->is_separate)
8573 printf (_("\nThere are no static relocations in linked file '%s'."),
8574 filedata->file_name);
8575 else
8576 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8577 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8578
8579 break;
8580 }
8581 }
8582 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8583 {
8584 if (filedata->is_separate)
8585 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8586 filedata->file_name);
8587 else
8588 printf (_("\nThere are no relocations in this file.\n"));
8589 }
45ac8f4f 8590 }
252b5132
RH
8591 }
8592
015dc7e1 8593 return true;
252b5132
RH
8594}
8595
4d6ed7c8
NC
8596/* An absolute address consists of a section and an offset. If the
8597 section is NULL, the offset itself is the address, otherwise, the
8598 address equals to LOAD_ADDRESS(section) + offset. */
8599
8600struct absaddr
948f632f
DA
8601{
8602 unsigned short section;
625d49fc 8603 uint64_t offset;
948f632f 8604};
4d6ed7c8 8605
948f632f
DA
8606/* Find the nearest symbol at or below ADDR. Returns the symbol
8607 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8608
4d6ed7c8 8609static void
26c527e6
AM
8610find_symbol_for_address (Filedata *filedata,
8611 Elf_Internal_Sym *symtab,
8612 uint64_t nsyms,
8613 const char *strtab,
8614 uint64_t strtab_size,
8615 struct absaddr addr,
8616 const char **symname,
8617 uint64_t *offset)
4d6ed7c8 8618{
625d49fc 8619 uint64_t dist = 0x100000;
2cf0635d 8620 Elf_Internal_Sym * sym;
948f632f
DA
8621 Elf_Internal_Sym * beg;
8622 Elf_Internal_Sym * end;
2cf0635d 8623 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8624
0b6ae522 8625 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8626 beg = symtab;
8627 end = symtab + nsyms;
0b6ae522 8628
948f632f 8629 while (beg < end)
4d6ed7c8 8630 {
625d49fc 8631 uint64_t value;
948f632f
DA
8632
8633 sym = beg + (end - beg) / 2;
0b6ae522 8634
948f632f 8635 value = sym->st_value;
0b6ae522
DJ
8636 REMOVE_ARCH_BITS (value);
8637
948f632f 8638 if (sym->st_name != 0
4d6ed7c8 8639 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8640 && addr.offset >= value
8641 && addr.offset - value < dist)
4d6ed7c8
NC
8642 {
8643 best = sym;
0b6ae522 8644 dist = addr.offset - value;
4d6ed7c8
NC
8645 if (!dist)
8646 break;
8647 }
948f632f
DA
8648
8649 if (addr.offset < value)
8650 end = sym;
8651 else
8652 beg = sym + 1;
4d6ed7c8 8653 }
1b31d05e 8654
4d6ed7c8
NC
8655 if (best)
8656 {
57346661 8657 *symname = (best->st_name >= strtab_size
2b692964 8658 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8659 *offset = dist;
8660 return;
8661 }
1b31d05e 8662
4d6ed7c8
NC
8663 *symname = NULL;
8664 *offset = addr.offset;
8665}
8666
32ec8896 8667static /* signed */ int
948f632f
DA
8668symcmp (const void *p, const void *q)
8669{
8670 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8671 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8672
8673 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8674}
8675
8676/* Process the unwind section. */
8677
8678#include "unwind-ia64.h"
8679
8680struct ia64_unw_table_entry
8681{
8682 struct absaddr start;
8683 struct absaddr end;
8684 struct absaddr info;
8685};
8686
8687struct ia64_unw_aux_info
8688{
32ec8896 8689 struct ia64_unw_table_entry * table; /* Unwind table. */
26c527e6 8690 uint64_t table_len; /* Length of unwind table. */
32ec8896 8691 unsigned char * info; /* Unwind info. */
26c527e6 8692 uint64_t info_size; /* Size of unwind info. */
625d49fc
AM
8693 uint64_t info_addr; /* Starting address of unwind info. */
8694 uint64_t seg_base; /* Starting address of segment. */
32ec8896 8695 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 8696 uint64_t nsyms; /* Number of symbols. */
32ec8896 8697 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 8698 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 8699 char * strtab; /* The string table. */
26c527e6 8700 uint64_t strtab_size; /* Size of string table. */
948f632f
DA
8701};
8702
015dc7e1 8703static bool
dda8d76d 8704dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8705{
2cf0635d 8706 struct ia64_unw_table_entry * tp;
26c527e6 8707 size_t j, nfuns;
4d6ed7c8 8708 int in_body;
015dc7e1 8709 bool res = true;
7036c0e1 8710
948f632f
DA
8711 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8712 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8713 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8714 aux->funtab[nfuns++] = aux->symtab[j];
8715 aux->nfuns = nfuns;
8716 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8717
4d6ed7c8
NC
8718 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8719 {
625d49fc
AM
8720 uint64_t stamp;
8721 uint64_t offset;
2cf0635d
NC
8722 const unsigned char * dp;
8723 const unsigned char * head;
53774b7e 8724 const unsigned char * end;
2cf0635d 8725 const char * procname;
4d6ed7c8 8726
dda8d76d 8727 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8728 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8729
8730 fputs ("\n<", stdout);
8731
8732 if (procname)
8733 {
8734 fputs (procname, stdout);
8735
8736 if (offset)
26c527e6 8737 printf ("+%" PRIx64, offset);
4d6ed7c8
NC
8738 }
8739
8740 fputs (">: [", stdout);
8741 print_vma (tp->start.offset, PREFIX_HEX);
8742 fputc ('-', stdout);
8743 print_vma (tp->end.offset, PREFIX_HEX);
26c527e6
AM
8744 printf ("], info at +0x%" PRIx64 "\n",
8745 tp->info.offset - aux->seg_base);
4d6ed7c8 8746
53774b7e
NC
8747 /* PR 17531: file: 86232b32. */
8748 if (aux->info == NULL)
8749 continue;
8750
97c0a079
AM
8751 offset = tp->info.offset;
8752 if (tp->info.section)
8753 {
8754 if (tp->info.section >= filedata->file_header.e_shnum)
8755 {
26c527e6
AM
8756 warn (_("Invalid section %u in table entry %td\n"),
8757 tp->info.section, tp - aux->table);
015dc7e1 8758 res = false;
97c0a079
AM
8759 continue;
8760 }
8761 offset += filedata->section_headers[tp->info.section].sh_addr;
8762 }
8763 offset -= aux->info_addr;
53774b7e 8764 /* PR 17531: file: 0997b4d1. */
90679903
AM
8765 if (offset >= aux->info_size
8766 || aux->info_size - offset < 8)
53774b7e 8767 {
26c527e6
AM
8768 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
8769 tp->info.offset, tp - aux->table);
015dc7e1 8770 res = false;
53774b7e
NC
8771 continue;
8772 }
8773
97c0a079 8774 head = aux->info + offset;
a4a00738 8775 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8776
86f55779 8777 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8778 (unsigned) UNW_VER (stamp),
8779 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8780 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8781 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8782 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8783
8784 if (UNW_VER (stamp) != 1)
8785 {
2b692964 8786 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8787 continue;
8788 }
8789
8790 in_body = 0;
53774b7e
NC
8791 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8792 /* PR 17531: file: 16ceda89. */
8793 if (end > aux->info + aux->info_size)
8794 end = aux->info + aux->info_size;
8795 for (dp = head + 8; dp < end;)
b4477bc8 8796 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8797 }
948f632f
DA
8798
8799 free (aux->funtab);
32ec8896
NC
8800
8801 return res;
4d6ed7c8
NC
8802}
8803
015dc7e1 8804static bool
dda8d76d
NC
8805slurp_ia64_unwind_table (Filedata * filedata,
8806 struct ia64_unw_aux_info * aux,
8807 Elf_Internal_Shdr * sec)
4d6ed7c8 8808{
26c527e6 8809 uint64_t size, nrelas, i;
2cf0635d
NC
8810 Elf_Internal_Phdr * seg;
8811 struct ia64_unw_table_entry * tep;
8812 Elf_Internal_Shdr * relsec;
8813 Elf_Internal_Rela * rela;
8814 Elf_Internal_Rela * rp;
8815 unsigned char * table;
8816 unsigned char * tp;
8817 Elf_Internal_Sym * sym;
8818 const char * relname;
4d6ed7c8 8819
53774b7e
NC
8820 aux->table_len = 0;
8821
4d6ed7c8
NC
8822 /* First, find the starting address of the segment that includes
8823 this section: */
8824
dda8d76d 8825 if (filedata->file_header.e_phnum)
4d6ed7c8 8826 {
dda8d76d 8827 if (! get_program_headers (filedata))
015dc7e1 8828 return false;
4d6ed7c8 8829
dda8d76d
NC
8830 for (seg = filedata->program_headers;
8831 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8832 ++seg)
4d6ed7c8
NC
8833 {
8834 if (seg->p_type != PT_LOAD)
8835 continue;
8836
8837 if (sec->sh_addr >= seg->p_vaddr
8838 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8839 {
8840 aux->seg_base = seg->p_vaddr;
8841 break;
8842 }
8843 }
4d6ed7c8
NC
8844 }
8845
8846 /* Second, build the unwind table from the contents of the unwind section: */
8847 size = sec->sh_size;
dda8d76d 8848 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8849 _("unwind table"));
a6e9f9df 8850 if (!table)
015dc7e1 8851 return false;
4d6ed7c8 8852
53774b7e 8853 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8854 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8855 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8856 tep = aux->table;
53774b7e
NC
8857
8858 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8859 {
8860 tep->start.section = SHN_UNDEF;
8861 tep->end.section = SHN_UNDEF;
8862 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8863 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8864 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8865 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8866 tep->start.offset += aux->seg_base;
8867 tep->end.offset += aux->seg_base;
8868 tep->info.offset += aux->seg_base;
8869 }
8870 free (table);
8871
41e92641 8872 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8873 for (relsec = filedata->section_headers;
8874 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8875 ++relsec)
8876 {
8877 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8878 || relsec->sh_info >= filedata->file_header.e_shnum
8879 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8880 continue;
8881
dda8d76d 8882 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8883 & rela, & nrelas))
53774b7e
NC
8884 {
8885 free (aux->table);
8886 aux->table = NULL;
8887 aux->table_len = 0;
015dc7e1 8888 return false;
53774b7e 8889 }
4d6ed7c8
NC
8890
8891 for (rp = rela; rp < rela + nrelas; ++rp)
8892 {
4770fb94 8893 unsigned int sym_ndx;
726bd37d
AM
8894 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8895 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8896
82b1b41b
NC
8897 /* PR 17531: file: 9fa67536. */
8898 if (relname == NULL)
8899 {
726bd37d 8900 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8901 continue;
8902 }
948f632f 8903
24d127aa 8904 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8905 {
82b1b41b 8906 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8907 continue;
8908 }
8909
89fac5e3 8910 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8911
53774b7e
NC
8912 /* PR 17531: file: 5bc8d9bf. */
8913 if (i >= aux->table_len)
8914 {
26c527e6
AM
8915 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
8916 i);
53774b7e
NC
8917 continue;
8918 }
8919
4770fb94
AM
8920 sym_ndx = get_reloc_symindex (rp->r_info);
8921 if (sym_ndx >= aux->nsyms)
8922 {
8923 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8924 sym_ndx);
8925 continue;
8926 }
8927 sym = aux->symtab + sym_ndx;
8928
53774b7e 8929 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8930 {
8931 case 0:
8932 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8933 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8934 break;
8935 case 1:
8936 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8937 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8938 break;
8939 case 2:
8940 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8941 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8942 break;
8943 default:
8944 break;
8945 }
8946 }
8947
8948 free (rela);
8949 }
8950
015dc7e1 8951 return true;
4d6ed7c8
NC
8952}
8953
015dc7e1 8954static bool
dda8d76d 8955ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8956{
2cf0635d
NC
8957 Elf_Internal_Shdr * sec;
8958 Elf_Internal_Shdr * unwsec = NULL;
26c527e6 8959 uint64_t i, unwcount = 0, unwstart = 0;
57346661 8960 struct ia64_unw_aux_info aux;
015dc7e1 8961 bool res = true;
f1467e33 8962
4d6ed7c8
NC
8963 memset (& aux, 0, sizeof (aux));
8964
dda8d76d 8965 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8966 {
28d13567 8967 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8968 {
28d13567 8969 if (aux.symtab)
4082ef84 8970 {
28d13567
AM
8971 error (_("Multiple symbol tables encountered\n"));
8972 free (aux.symtab);
8973 aux.symtab = NULL;
4082ef84 8974 free (aux.strtab);
28d13567 8975 aux.strtab = NULL;
4082ef84 8976 }
28d13567
AM
8977 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8978 &aux.strtab, &aux.strtab_size))
015dc7e1 8979 return false;
4d6ed7c8
NC
8980 }
8981 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8982 unwcount++;
8983 }
8984
8985 if (!unwcount)
8986 printf (_("\nThere are no unwind sections in this file.\n"));
8987
8988 while (unwcount-- > 0)
8989 {
84714f86 8990 const char *suffix;
579f31ac
JJ
8991 size_t len, len2;
8992
dda8d76d
NC
8993 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8994 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8995 if (sec->sh_type == SHT_IA_64_UNWIND)
8996 {
8997 unwsec = sec;
8998 break;
8999 }
4082ef84
NC
9000 /* We have already counted the number of SHT_IA64_UNWIND
9001 sections so the loop above should never fail. */
9002 assert (unwsec != NULL);
579f31ac
JJ
9003
9004 unwstart = i + 1;
9005 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9006
e4b17d5c
L
9007 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9008 {
9009 /* We need to find which section group it is in. */
4082ef84 9010 struct group_list * g;
e4b17d5c 9011
978c4450
AM
9012 if (filedata->section_headers_groups == NULL
9013 || filedata->section_headers_groups[i] == NULL)
dda8d76d 9014 i = filedata->file_header.e_shnum;
4082ef84 9015 else
e4b17d5c 9016 {
978c4450 9017 g = filedata->section_headers_groups[i]->root;
18bd398b 9018
4082ef84
NC
9019 for (; g != NULL; g = g->next)
9020 {
dda8d76d 9021 sec = filedata->section_headers + g->section_index;
e4b17d5c 9022
84714f86
AM
9023 if (section_name_valid (filedata, sec)
9024 && streq (section_name (filedata, sec),
9025 ELF_STRING_ia64_unwind_info))
4082ef84
NC
9026 break;
9027 }
9028
9029 if (g == NULL)
dda8d76d 9030 i = filedata->file_header.e_shnum;
4082ef84 9031 }
e4b17d5c 9032 }
84714f86
AM
9033 else if (section_name_valid (filedata, unwsec)
9034 && startswith (section_name (filedata, unwsec),
e9b095a5 9035 ELF_STRING_ia64_unwind_once))
579f31ac 9036 {
18bd398b 9037 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 9038 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 9039 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9040 for (i = 0, sec = filedata->section_headers;
9041 i < filedata->file_header.e_shnum;
579f31ac 9042 ++i, ++sec)
84714f86
AM
9043 if (section_name_valid (filedata, sec)
9044 && startswith (section_name (filedata, sec),
e9b095a5 9045 ELF_STRING_ia64_unwind_info_once)
84714f86 9046 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9047 break;
9048 }
9049 else
9050 {
9051 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 9052 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
9053 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9054 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9055 suffix = "";
84714f86
AM
9056 if (section_name_valid (filedata, unwsec)
9057 && startswith (section_name (filedata, unwsec),
9058 ELF_STRING_ia64_unwind))
9059 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9060 for (i = 0, sec = filedata->section_headers;
9061 i < filedata->file_header.e_shnum;
579f31ac 9062 ++i, ++sec)
84714f86
AM
9063 if (section_name_valid (filedata, sec)
9064 && startswith (section_name (filedata, sec),
9065 ELF_STRING_ia64_unwind_info)
9066 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9067 break;
9068 }
9069
dda8d76d 9070 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
9071 {
9072 printf (_("\nCould not find unwind info section for "));
9073
dda8d76d 9074 if (filedata->string_table == NULL)
579f31ac
JJ
9075 printf ("%d", unwsec->sh_name);
9076 else
dda8d76d 9077 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9078 }
9079 else
4d6ed7c8 9080 {
4d6ed7c8 9081 aux.info_addr = sec->sh_addr;
dda8d76d 9082 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9083 sec->sh_size,
9084 _("unwind info"));
59245841 9085 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9086
579f31ac 9087 printf (_("\nUnwind section "));
4d6ed7c8 9088
dda8d76d 9089 if (filedata->string_table == NULL)
579f31ac
JJ
9090 printf ("%d", unwsec->sh_name);
9091 else
dda8d76d 9092 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9093
26c527e6
AM
9094 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9095 unwsec->sh_offset,
9096 unwsec->sh_size / (3 * eh_addr_size));
4d6ed7c8 9097
dda8d76d 9098 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9099 && aux.table_len > 0)
dda8d76d 9100 dump_ia64_unwind (filedata, & aux);
579f31ac 9101
9db70fc3
AM
9102 free ((char *) aux.table);
9103 free ((char *) aux.info);
579f31ac
JJ
9104 aux.table = NULL;
9105 aux.info = NULL;
9106 }
4d6ed7c8 9107 }
4d6ed7c8 9108
9db70fc3
AM
9109 free (aux.symtab);
9110 free ((char *) aux.strtab);
32ec8896
NC
9111
9112 return res;
4d6ed7c8
NC
9113}
9114
3f5e193b 9115struct hppa_unw_table_entry
32ec8896
NC
9116{
9117 struct absaddr start;
9118 struct absaddr end;
9119 unsigned int Cannot_unwind:1; /* 0 */
9120 unsigned int Millicode:1; /* 1 */
9121 unsigned int Millicode_save_sr0:1; /* 2 */
9122 unsigned int Region_description:2; /* 3..4 */
9123 unsigned int reserved1:1; /* 5 */
9124 unsigned int Entry_SR:1; /* 6 */
9125 unsigned int Entry_FR:4; /* Number saved 7..10 */
9126 unsigned int Entry_GR:5; /* Number saved 11..15 */
9127 unsigned int Args_stored:1; /* 16 */
9128 unsigned int Variable_Frame:1; /* 17 */
9129 unsigned int Separate_Package_Body:1; /* 18 */
9130 unsigned int Frame_Extension_Millicode:1; /* 19 */
9131 unsigned int Stack_Overflow_Check:1; /* 20 */
9132 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9133 unsigned int Ada_Region:1; /* 22 */
9134 unsigned int cxx_info:1; /* 23 */
9135 unsigned int cxx_try_catch:1; /* 24 */
9136 unsigned int sched_entry_seq:1; /* 25 */
9137 unsigned int reserved2:1; /* 26 */
9138 unsigned int Save_SP:1; /* 27 */
9139 unsigned int Save_RP:1; /* 28 */
9140 unsigned int Save_MRP_in_frame:1; /* 29 */
9141 unsigned int extn_ptr_defined:1; /* 30 */
9142 unsigned int Cleanup_defined:1; /* 31 */
9143
9144 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9145 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9146 unsigned int Large_frame:1; /* 2 */
9147 unsigned int Pseudo_SP_Set:1; /* 3 */
9148 unsigned int reserved4:1; /* 4 */
9149 unsigned int Total_frame_size:27; /* 5..31 */
9150};
3f5e193b 9151
57346661 9152struct hppa_unw_aux_info
948f632f 9153{
32ec8896 9154 struct hppa_unw_table_entry * table; /* Unwind table. */
26c527e6 9155 uint64_t table_len; /* Length of unwind table. */
625d49fc 9156 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9157 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9158 uint64_t nsyms; /* Number of symbols. */
32ec8896 9159 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9160 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9161 char * strtab; /* The string table. */
26c527e6 9162 uint64_t strtab_size; /* Size of string table. */
948f632f 9163};
57346661 9164
015dc7e1 9165static bool
dda8d76d 9166dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9167{
2cf0635d 9168 struct hppa_unw_table_entry * tp;
26c527e6 9169 uint64_t j, nfuns;
015dc7e1 9170 bool res = true;
948f632f
DA
9171
9172 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9173 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9174 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9175 aux->funtab[nfuns++] = aux->symtab[j];
9176 aux->nfuns = nfuns;
9177 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9178
57346661
AM
9179 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9180 {
625d49fc 9181 uint64_t offset;
2cf0635d 9182 const char * procname;
57346661 9183
dda8d76d 9184 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9185 aux->strtab_size, tp->start, &procname,
9186 &offset);
9187
9188 fputs ("\n<", stdout);
9189
9190 if (procname)
9191 {
9192 fputs (procname, stdout);
9193
9194 if (offset)
26c527e6 9195 printf ("+%" PRIx64, offset);
57346661
AM
9196 }
9197
9198 fputs (">: [", stdout);
9199 print_vma (tp->start.offset, PREFIX_HEX);
9200 fputc ('-', stdout);
9201 print_vma (tp->end.offset, PREFIX_HEX);
9202 printf ("]\n\t");
9203
18bd398b
NC
9204#define PF(_m) if (tp->_m) printf (#_m " ");
9205#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9206 PF(Cannot_unwind);
9207 PF(Millicode);
9208 PF(Millicode_save_sr0);
18bd398b 9209 /* PV(Region_description); */
57346661
AM
9210 PF(Entry_SR);
9211 PV(Entry_FR);
9212 PV(Entry_GR);
9213 PF(Args_stored);
9214 PF(Variable_Frame);
9215 PF(Separate_Package_Body);
9216 PF(Frame_Extension_Millicode);
9217 PF(Stack_Overflow_Check);
9218 PF(Two_Instruction_SP_Increment);
9219 PF(Ada_Region);
9220 PF(cxx_info);
9221 PF(cxx_try_catch);
9222 PF(sched_entry_seq);
9223 PF(Save_SP);
9224 PF(Save_RP);
9225 PF(Save_MRP_in_frame);
9226 PF(extn_ptr_defined);
9227 PF(Cleanup_defined);
9228 PF(MPE_XL_interrupt_marker);
9229 PF(HP_UX_interrupt_marker);
9230 PF(Large_frame);
9231 PF(Pseudo_SP_Set);
9232 PV(Total_frame_size);
9233#undef PF
9234#undef PV
9235 }
9236
18bd398b 9237 printf ("\n");
948f632f
DA
9238
9239 free (aux->funtab);
32ec8896
NC
9240
9241 return res;
57346661
AM
9242}
9243
015dc7e1 9244static bool
dda8d76d
NC
9245slurp_hppa_unwind_table (Filedata * filedata,
9246 struct hppa_unw_aux_info * aux,
9247 Elf_Internal_Shdr * sec)
57346661 9248{
26c527e6 9249 uint64_t size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9250 Elf_Internal_Phdr * seg;
9251 struct hppa_unw_table_entry * tep;
9252 Elf_Internal_Shdr * relsec;
9253 Elf_Internal_Rela * rela;
9254 Elf_Internal_Rela * rp;
9255 unsigned char * table;
9256 unsigned char * tp;
9257 Elf_Internal_Sym * sym;
9258 const char * relname;
57346661 9259
57346661
AM
9260 /* First, find the starting address of the segment that includes
9261 this section. */
dda8d76d 9262 if (filedata->file_header.e_phnum)
57346661 9263 {
dda8d76d 9264 if (! get_program_headers (filedata))
015dc7e1 9265 return false;
57346661 9266
dda8d76d
NC
9267 for (seg = filedata->program_headers;
9268 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9269 ++seg)
9270 {
9271 if (seg->p_type != PT_LOAD)
9272 continue;
9273
9274 if (sec->sh_addr >= seg->p_vaddr
9275 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9276 {
9277 aux->seg_base = seg->p_vaddr;
9278 break;
9279 }
9280 }
9281 }
9282
9283 /* Second, build the unwind table from the contents of the unwind
9284 section. */
9285 size = sec->sh_size;
dda8d76d 9286 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9287 _("unwind table"));
57346661 9288 if (!table)
015dc7e1 9289 return false;
57346661 9290
1c0751b2
DA
9291 unw_ent_size = 16;
9292 nentries = size / unw_ent_size;
9293 size = unw_ent_size * nentries;
57346661 9294
e3fdc001 9295 aux->table_len = nentries;
3f5e193b
NC
9296 tep = aux->table = (struct hppa_unw_table_entry *)
9297 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9298
1c0751b2 9299 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9300 {
9301 unsigned int tmp1, tmp2;
9302
9303 tep->start.section = SHN_UNDEF;
9304 tep->end.section = SHN_UNDEF;
9305
1c0751b2
DA
9306 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9307 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9308 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9309 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9310
9311 tep->start.offset += aux->seg_base;
9312 tep->end.offset += aux->seg_base;
57346661
AM
9313
9314 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9315 tep->Millicode = (tmp1 >> 30) & 0x1;
9316 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9317 tep->Region_description = (tmp1 >> 27) & 0x3;
9318 tep->reserved1 = (tmp1 >> 26) & 0x1;
9319 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9320 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9321 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9322 tep->Args_stored = (tmp1 >> 15) & 0x1;
9323 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9324 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9325 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9326 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9327 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9328 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9329 tep->cxx_info = (tmp1 >> 8) & 0x1;
9330 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9331 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9332 tep->reserved2 = (tmp1 >> 5) & 0x1;
9333 tep->Save_SP = (tmp1 >> 4) & 0x1;
9334 tep->Save_RP = (tmp1 >> 3) & 0x1;
9335 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9336 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9337 tep->Cleanup_defined = tmp1 & 0x1;
9338
9339 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9340 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9341 tep->Large_frame = (tmp2 >> 29) & 0x1;
9342 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9343 tep->reserved4 = (tmp2 >> 27) & 0x1;
9344 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9345 }
9346 free (table);
9347
9348 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9349 for (relsec = filedata->section_headers;
9350 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9351 ++relsec)
9352 {
9353 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9354 || relsec->sh_info >= filedata->file_header.e_shnum
9355 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9356 continue;
9357
dda8d76d 9358 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9359 & rela, & nrelas))
015dc7e1 9360 return false;
57346661
AM
9361
9362 for (rp = rela; rp < rela + nrelas; ++rp)
9363 {
4770fb94 9364 unsigned int sym_ndx;
726bd37d
AM
9365 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9366 relname = elf_hppa_reloc_type (r_type);
57346661 9367
726bd37d
AM
9368 if (relname == NULL)
9369 {
9370 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9371 continue;
9372 }
9373
57346661 9374 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9375 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9376 {
726bd37d 9377 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9378 continue;
9379 }
9380
9381 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9382 if (i >= aux->table_len)
9383 {
26c527e6
AM
9384 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9385 i);
726bd37d
AM
9386 continue;
9387 }
57346661 9388
4770fb94
AM
9389 sym_ndx = get_reloc_symindex (rp->r_info);
9390 if (sym_ndx >= aux->nsyms)
9391 {
9392 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9393 sym_ndx);
9394 continue;
9395 }
9396 sym = aux->symtab + sym_ndx;
9397
43f6cd05 9398 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9399 {
9400 case 0:
9401 aux->table[i].start.section = sym->st_shndx;
1e456d54 9402 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9403 break;
9404 case 1:
9405 aux->table[i].end.section = sym->st_shndx;
1e456d54 9406 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9407 break;
9408 default:
9409 break;
9410 }
9411 }
9412
9413 free (rela);
9414 }
9415
015dc7e1 9416 return true;
57346661
AM
9417}
9418
015dc7e1 9419static bool
dda8d76d 9420hppa_process_unwind (Filedata * filedata)
57346661 9421{
57346661 9422 struct hppa_unw_aux_info aux;
2cf0635d 9423 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9424 Elf_Internal_Shdr * sec;
26c527e6 9425 size_t i;
015dc7e1 9426 bool res = true;
57346661 9427
dda8d76d 9428 if (filedata->string_table == NULL)
015dc7e1 9429 return false;
1b31d05e
NC
9430
9431 memset (& aux, 0, sizeof (aux));
57346661 9432
dda8d76d 9433 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9434 {
28d13567 9435 if (sec->sh_type == SHT_SYMTAB)
57346661 9436 {
28d13567 9437 if (aux.symtab)
4082ef84 9438 {
28d13567
AM
9439 error (_("Multiple symbol tables encountered\n"));
9440 free (aux.symtab);
9441 aux.symtab = NULL;
4082ef84 9442 free (aux.strtab);
28d13567 9443 aux.strtab = NULL;
4082ef84 9444 }
28d13567
AM
9445 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9446 &aux.strtab, &aux.strtab_size))
015dc7e1 9447 return false;
57346661 9448 }
84714f86
AM
9449 else if (section_name_valid (filedata, sec)
9450 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9451 unwsec = sec;
9452 }
9453
9454 if (!unwsec)
9455 printf (_("\nThere are no unwind sections in this file.\n"));
9456
dda8d76d 9457 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9458 {
84714f86
AM
9459 if (section_name_valid (filedata, sec)
9460 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9461 {
26c527e6 9462 uint64_t num_unwind = sec->sh_size / 16;
dda8d76d 9463
26c527e6
AM
9464 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
9465 "contains %" PRIu64 " entry:\n",
9466 "\nUnwind section '%s' at offset %#" PRIx64 " "
9467 "contains %" PRIu64 " entries:\n",
d3a49aa8 9468 num_unwind),
dda8d76d 9469 printable_section_name (filedata, sec),
26c527e6 9470 sec->sh_offset,
d3a49aa8 9471 num_unwind);
57346661 9472
dda8d76d 9473 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9474 res = false;
66b09c7e
S
9475
9476 if (res && aux.table_len > 0)
32ec8896 9477 {
dda8d76d 9478 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9479 res = false;
32ec8896 9480 }
57346661 9481
9db70fc3 9482 free ((char *) aux.table);
57346661
AM
9483 aux.table = NULL;
9484 }
9485 }
9486
9db70fc3
AM
9487 free (aux.symtab);
9488 free ((char *) aux.strtab);
32ec8896
NC
9489
9490 return res;
57346661
AM
9491}
9492
0b6ae522
DJ
9493struct arm_section
9494{
a734115a
NC
9495 unsigned char * data; /* The unwind data. */
9496 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9497 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
26c527e6 9498 uint64_t nrelas; /* The number of relocations. */
a734115a
NC
9499 unsigned int rel_type; /* REL or RELA ? */
9500 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9501};
9502
9503struct arm_unw_aux_info
9504{
dda8d76d 9505 Filedata * filedata; /* The file containing the unwind sections. */
a734115a 9506 Elf_Internal_Sym * symtab; /* The file's symbol table. */
26c527e6 9507 uint64_t nsyms; /* Number of symbols. */
948f632f 9508 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9509 uint64_t nfuns; /* Number of these symbols. */
a734115a 9510 char * strtab; /* The file's string table. */
26c527e6 9511 uint64_t strtab_size; /* Size of string table. */
0b6ae522
DJ
9512};
9513
9514static const char *
dda8d76d
NC
9515arm_print_vma_and_name (Filedata * filedata,
9516 struct arm_unw_aux_info * aux,
625d49fc 9517 uint64_t fn,
dda8d76d 9518 struct absaddr addr)
0b6ae522
DJ
9519{
9520 const char *procname;
625d49fc 9521 uint64_t sym_offset;
0b6ae522
DJ
9522
9523 if (addr.section == SHN_UNDEF)
9524 addr.offset = fn;
9525
dda8d76d 9526 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9527 aux->strtab_size, addr, &procname,
9528 &sym_offset);
9529
9530 print_vma (fn, PREFIX_HEX);
9531
9532 if (procname)
9533 {
9534 fputs (" <", stdout);
9535 fputs (procname, stdout);
9536
9537 if (sym_offset)
26c527e6 9538 printf ("+0x%" PRIx64, sym_offset);
0b6ae522
DJ
9539 fputc ('>', stdout);
9540 }
9541
9542 return procname;
9543}
9544
9545static void
9546arm_free_section (struct arm_section *arm_sec)
9547{
9db70fc3
AM
9548 free (arm_sec->data);
9549 free (arm_sec->rela);
0b6ae522
DJ
9550}
9551
a734115a
NC
9552/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9553 cached section and install SEC instead.
9554 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9555 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9556 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9557 relocation's offset in ADDR.
1b31d05e
NC
9558 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9559 into the string table of the symbol associated with the reloc. If no
9560 reloc was applied store -1 there.
9561 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9562
015dc7e1 9563static bool
dda8d76d
NC
9564get_unwind_section_word (Filedata * filedata,
9565 struct arm_unw_aux_info * aux,
1b31d05e
NC
9566 struct arm_section * arm_sec,
9567 Elf_Internal_Shdr * sec,
625d49fc 9568 uint64_t word_offset,
1b31d05e
NC
9569 unsigned int * wordp,
9570 struct absaddr * addr,
625d49fc 9571 uint64_t * sym_name)
0b6ae522
DJ
9572{
9573 Elf_Internal_Rela *rp;
9574 Elf_Internal_Sym *sym;
9575 const char * relname;
9576 unsigned int word;
015dc7e1 9577 bool wrapped;
0b6ae522 9578
e0a31db1 9579 if (sec == NULL || arm_sec == NULL)
015dc7e1 9580 return false;
e0a31db1 9581
0b6ae522
DJ
9582 addr->section = SHN_UNDEF;
9583 addr->offset = 0;
9584
1b31d05e 9585 if (sym_name != NULL)
625d49fc 9586 *sym_name = (uint64_t) -1;
1b31d05e 9587
a734115a 9588 /* If necessary, update the section cache. */
0b6ae522
DJ
9589 if (sec != arm_sec->sec)
9590 {
9591 Elf_Internal_Shdr *relsec;
9592
9593 arm_free_section (arm_sec);
9594
9595 arm_sec->sec = sec;
dda8d76d 9596 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9597 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9598 arm_sec->rela = NULL;
9599 arm_sec->nrelas = 0;
9600
dda8d76d
NC
9601 for (relsec = filedata->section_headers;
9602 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9603 ++relsec)
9604 {
dda8d76d
NC
9605 if (relsec->sh_info >= filedata->file_header.e_shnum
9606 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9607 /* PR 15745: Check the section type as well. */
9608 || (relsec->sh_type != SHT_REL
9609 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9610 continue;
9611
a734115a 9612 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9613 if (relsec->sh_type == SHT_REL)
9614 {
dda8d76d 9615 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9616 relsec->sh_size,
9617 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9618 return false;
0b6ae522 9619 }
1ae40aa4 9620 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9621 {
dda8d76d 9622 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9623 relsec->sh_size,
9624 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9625 return false;
0b6ae522 9626 }
1ae40aa4 9627 break;
0b6ae522
DJ
9628 }
9629
9630 arm_sec->next_rela = arm_sec->rela;
9631 }
9632
a734115a 9633 /* If there is no unwind data we can do nothing. */
0b6ae522 9634 if (arm_sec->data == NULL)
015dc7e1 9635 return false;
0b6ae522 9636
e0a31db1 9637 /* If the offset is invalid then fail. */
f32ba729
NC
9638 if (/* PR 21343 *//* PR 18879 */
9639 sec->sh_size < 4
625d49fc 9640 || word_offset > sec->sh_size - 4)
015dc7e1 9641 return false;
e0a31db1 9642
a734115a 9643 /* Get the word at the required offset. */
0b6ae522
DJ
9644 word = byte_get (arm_sec->data + word_offset, 4);
9645
0eff7165
NC
9646 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9647 if (arm_sec->rela == NULL)
9648 {
9649 * wordp = word;
015dc7e1 9650 return true;
0eff7165
NC
9651 }
9652
a734115a 9653 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9654 wrapped = false;
0b6ae522
DJ
9655 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9656 {
625d49fc 9657 uint64_t prelval, offset;
0b6ae522
DJ
9658
9659 if (rp->r_offset > word_offset && !wrapped)
9660 {
9661 rp = arm_sec->rela;
015dc7e1 9662 wrapped = true;
0b6ae522
DJ
9663 }
9664 if (rp->r_offset > word_offset)
9665 break;
9666
9667 if (rp->r_offset & 3)
9668 {
26c527e6
AM
9669 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
9670 rp->r_offset);
0b6ae522
DJ
9671 continue;
9672 }
9673
9674 if (rp->r_offset < word_offset)
9675 continue;
9676
74e1a04b
NC
9677 /* PR 17531: file: 027-161405-0.004 */
9678 if (aux->symtab == NULL)
9679 continue;
9680
0b6ae522
DJ
9681 if (arm_sec->rel_type == SHT_REL)
9682 {
9683 offset = word & 0x7fffffff;
9684 if (offset & 0x40000000)
625d49fc 9685 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 9686 }
a734115a 9687 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9688 offset = rp->r_addend;
a734115a 9689 else
74e1a04b
NC
9690 {
9691 error (_("Unknown section relocation type %d encountered\n"),
9692 arm_sec->rel_type);
9693 break;
9694 }
0b6ae522 9695
071436c6
NC
9696 /* PR 17531 file: 027-1241568-0.004. */
9697 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9698 {
26c527e6
AM
9699 error (_("Bad symbol index in unwind relocation "
9700 "(%" PRIu64 " > %" PRIu64 ")\n"),
9701 ELF32_R_SYM (rp->r_info), aux->nsyms);
071436c6
NC
9702 break;
9703 }
9704
9705 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9706 offset += sym->st_value;
9707 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9708
a734115a 9709 /* Check that we are processing the expected reloc type. */
dda8d76d 9710 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9711 {
9712 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9713 if (relname == NULL)
9714 {
9715 warn (_("Skipping unknown ARM relocation type: %d\n"),
9716 (int) ELF32_R_TYPE (rp->r_info));
9717 continue;
9718 }
a734115a
NC
9719
9720 if (streq (relname, "R_ARM_NONE"))
9721 continue;
0b4362b0 9722
a734115a
NC
9723 if (! streq (relname, "R_ARM_PREL31"))
9724 {
071436c6 9725 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9726 continue;
9727 }
9728 }
dda8d76d 9729 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9730 {
9731 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9732 if (relname == NULL)
9733 {
9734 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9735 (int) ELF32_R_TYPE (rp->r_info));
9736 continue;
9737 }
0b4362b0 9738
a734115a
NC
9739 if (streq (relname, "R_C6000_NONE"))
9740 continue;
9741
9742 if (! streq (relname, "R_C6000_PREL31"))
9743 {
071436c6 9744 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9745 continue;
9746 }
9747
9748 prelval >>= 1;
9749 }
9750 else
74e1a04b
NC
9751 {
9752 /* This function currently only supports ARM and TI unwinders. */
9753 warn (_("Only TI and ARM unwinders are currently supported\n"));
9754 break;
9755 }
fa197c1c 9756
625d49fc 9757 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
9758 addr->section = sym->st_shndx;
9759 addr->offset = offset;
74e1a04b 9760
1b31d05e
NC
9761 if (sym_name)
9762 * sym_name = sym->st_name;
0b6ae522
DJ
9763 break;
9764 }
9765
9766 *wordp = word;
9767 arm_sec->next_rela = rp;
9768
015dc7e1 9769 return true;
0b6ae522
DJ
9770}
9771
a734115a
NC
9772static const char *tic6x_unwind_regnames[16] =
9773{
0b4362b0
RM
9774 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9775 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9776 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9777};
fa197c1c 9778
0b6ae522 9779static void
fa197c1c 9780decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9781{
fa197c1c
PB
9782 int i;
9783
9784 for (i = 12; mask; mask >>= 1, i--)
9785 {
9786 if (mask & 1)
9787 {
9788 fputs (tic6x_unwind_regnames[i], stdout);
9789 if (mask > 1)
9790 fputs (", ", stdout);
9791 }
9792 }
9793}
0b6ae522
DJ
9794
9795#define ADVANCE \
9796 if (remaining == 0 && more_words) \
9797 { \
9798 data_offset += 4; \
dda8d76d 9799 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9800 data_offset, & word, & addr, NULL)) \
015dc7e1 9801 return false; \
0b6ae522
DJ
9802 remaining = 4; \
9803 more_words--; \
9804 } \
9805
9806#define GET_OP(OP) \
9807 ADVANCE; \
9808 if (remaining) \
9809 { \
9810 remaining--; \
9811 (OP) = word >> 24; \
9812 word <<= 8; \
9813 } \
9814 else \
9815 { \
2b692964 9816 printf (_("[Truncated opcode]\n")); \
015dc7e1 9817 return false; \
0b6ae522 9818 } \
cc5914eb 9819 printf ("0x%02x ", OP)
0b6ae522 9820
015dc7e1 9821static bool
dda8d76d
NC
9822decode_arm_unwind_bytecode (Filedata * filedata,
9823 struct arm_unw_aux_info * aux,
948f632f
DA
9824 unsigned int word,
9825 unsigned int remaining,
9826 unsigned int more_words,
625d49fc 9827 uint64_t data_offset,
948f632f
DA
9828 Elf_Internal_Shdr * data_sec,
9829 struct arm_section * data_arm_sec)
fa197c1c
PB
9830{
9831 struct absaddr addr;
015dc7e1 9832 bool res = true;
0b6ae522
DJ
9833
9834 /* Decode the unwinding instructions. */
9835 while (1)
9836 {
9837 unsigned int op, op2;
9838
9839 ADVANCE;
9840 if (remaining == 0)
9841 break;
9842 remaining--;
9843 op = word >> 24;
9844 word <<= 8;
9845
cc5914eb 9846 printf (" 0x%02x ", op);
0b6ae522
DJ
9847
9848 if ((op & 0xc0) == 0x00)
9849 {
9850 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9851
cc5914eb 9852 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9853 }
9854 else if ((op & 0xc0) == 0x40)
9855 {
9856 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9857
cc5914eb 9858 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9859 }
9860 else if ((op & 0xf0) == 0x80)
9861 {
9862 GET_OP (op2);
9863 if (op == 0x80 && op2 == 0)
9864 printf (_("Refuse to unwind"));
9865 else
9866 {
9867 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9868 bool first = true;
0b6ae522 9869 int i;
2b692964 9870
0b6ae522
DJ
9871 printf ("pop {");
9872 for (i = 0; i < 12; i++)
9873 if (mask & (1 << i))
9874 {
9875 if (first)
015dc7e1 9876 first = false;
0b6ae522
DJ
9877 else
9878 printf (", ");
9879 printf ("r%d", 4 + i);
9880 }
9881 printf ("}");
9882 }
9883 }
9884 else if ((op & 0xf0) == 0x90)
9885 {
9886 if (op == 0x9d || op == 0x9f)
9887 printf (_(" [Reserved]"));
9888 else
cc5914eb 9889 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9890 }
9891 else if ((op & 0xf0) == 0xa0)
9892 {
9893 int end = 4 + (op & 0x07);
015dc7e1 9894 bool first = true;
0b6ae522 9895 int i;
61865e30 9896
0b6ae522
DJ
9897 printf (" pop {");
9898 for (i = 4; i <= end; i++)
9899 {
9900 if (first)
015dc7e1 9901 first = false;
0b6ae522
DJ
9902 else
9903 printf (", ");
9904 printf ("r%d", i);
9905 }
9906 if (op & 0x08)
9907 {
1b31d05e 9908 if (!first)
0b6ae522
DJ
9909 printf (", ");
9910 printf ("r14");
9911 }
9912 printf ("}");
9913 }
9914 else if (op == 0xb0)
9915 printf (_(" finish"));
9916 else if (op == 0xb1)
9917 {
9918 GET_OP (op2);
9919 if (op2 == 0 || (op2 & 0xf0) != 0)
9920 printf (_("[Spare]"));
9921 else
9922 {
9923 unsigned int mask = op2 & 0x0f;
015dc7e1 9924 bool first = true;
0b6ae522 9925 int i;
61865e30 9926
0b6ae522
DJ
9927 printf ("pop {");
9928 for (i = 0; i < 12; i++)
9929 if (mask & (1 << i))
9930 {
9931 if (first)
015dc7e1 9932 first = false;
0b6ae522
DJ
9933 else
9934 printf (", ");
9935 printf ("r%d", i);
9936 }
9937 printf ("}");
9938 }
9939 }
9940 else if (op == 0xb2)
9941 {
b115cf96 9942 unsigned char buf[9];
0b6ae522 9943 unsigned int i, len;
26c527e6 9944 uint64_t offset;
61865e30 9945
b115cf96 9946 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9947 {
9948 GET_OP (buf[i]);
9949 if ((buf[i] & 0x80) == 0)
9950 break;
9951 }
4082ef84 9952 if (i == sizeof (buf))
32ec8896 9953 {
27a45f42 9954 error (_("corrupt change to vsp\n"));
015dc7e1 9955 res = false;
32ec8896 9956 }
4082ef84
NC
9957 else
9958 {
015dc7e1 9959 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9960 assert (len == i + 1);
9961 offset = offset * 4 + 0x204;
26c527e6 9962 printf ("vsp = vsp + %" PRId64, offset);
4082ef84 9963 }
0b6ae522 9964 }
61865e30 9965 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9966 {
61865e30
NC
9967 unsigned int first, last;
9968
9969 GET_OP (op2);
9970 first = op2 >> 4;
9971 last = op2 & 0x0f;
9972 if (op == 0xc8)
9973 first = first + 16;
9974 printf ("pop {D%d", first);
9975 if (last)
9976 printf ("-D%d", first + last);
9977 printf ("}");
9978 }
09854a88
TB
9979 else if (op == 0xb4)
9980 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
9981 else if (op == 0xb5)
9982 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
9983 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9984 {
9985 unsigned int count = op & 0x07;
9986
9987 printf ("pop {D8");
9988 if (count)
9989 printf ("-D%d", 8 + count);
9990 printf ("}");
9991 }
9992 else if (op >= 0xc0 && op <= 0xc5)
9993 {
9994 unsigned int count = op & 0x07;
9995
9996 printf (" pop {wR10");
9997 if (count)
9998 printf ("-wR%d", 10 + count);
9999 printf ("}");
10000 }
10001 else if (op == 0xc6)
10002 {
10003 unsigned int first, last;
10004
10005 GET_OP (op2);
10006 first = op2 >> 4;
10007 last = op2 & 0x0f;
10008 printf ("pop {wR%d", first);
10009 if (last)
10010 printf ("-wR%d", first + last);
10011 printf ("}");
10012 }
10013 else if (op == 0xc7)
10014 {
10015 GET_OP (op2);
10016 if (op2 == 0 || (op2 & 0xf0) != 0)
10017 printf (_("[Spare]"));
0b6ae522
DJ
10018 else
10019 {
61865e30 10020 unsigned int mask = op2 & 0x0f;
015dc7e1 10021 bool first = true;
61865e30
NC
10022 int i;
10023
10024 printf ("pop {");
10025 for (i = 0; i < 4; i++)
10026 if (mask & (1 << i))
10027 {
10028 if (first)
015dc7e1 10029 first = false;
61865e30
NC
10030 else
10031 printf (", ");
10032 printf ("wCGR%d", i);
10033 }
10034 printf ("}");
0b6ae522
DJ
10035 }
10036 }
61865e30 10037 else
32ec8896
NC
10038 {
10039 printf (_(" [unsupported opcode]"));
015dc7e1 10040 res = false;
32ec8896
NC
10041 }
10042
0b6ae522
DJ
10043 printf ("\n");
10044 }
32ec8896
NC
10045
10046 return res;
fa197c1c
PB
10047}
10048
015dc7e1 10049static bool
dda8d76d
NC
10050decode_tic6x_unwind_bytecode (Filedata * filedata,
10051 struct arm_unw_aux_info * aux,
948f632f
DA
10052 unsigned int word,
10053 unsigned int remaining,
10054 unsigned int more_words,
625d49fc 10055 uint64_t data_offset,
948f632f
DA
10056 Elf_Internal_Shdr * data_sec,
10057 struct arm_section * data_arm_sec)
fa197c1c
PB
10058{
10059 struct absaddr addr;
10060
10061 /* Decode the unwinding instructions. */
10062 while (1)
10063 {
10064 unsigned int op, op2;
10065
10066 ADVANCE;
10067 if (remaining == 0)
10068 break;
10069 remaining--;
10070 op = word >> 24;
10071 word <<= 8;
10072
9cf03b7e 10073 printf (" 0x%02x ", op);
fa197c1c
PB
10074
10075 if ((op & 0xc0) == 0x00)
10076 {
10077 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10078 printf (" sp = sp + %d", offset);
fa197c1c
PB
10079 }
10080 else if ((op & 0xc0) == 0x80)
10081 {
10082 GET_OP (op2);
10083 if (op == 0x80 && op2 == 0)
10084 printf (_("Refuse to unwind"));
10085 else
10086 {
10087 unsigned int mask = ((op & 0x1f) << 8) | op2;
10088 if (op & 0x20)
10089 printf ("pop compact {");
10090 else
10091 printf ("pop {");
10092
10093 decode_tic6x_unwind_regmask (mask);
10094 printf("}");
10095 }
10096 }
10097 else if ((op & 0xf0) == 0xc0)
10098 {
10099 unsigned int reg;
10100 unsigned int nregs;
10101 unsigned int i;
10102 const char *name;
a734115a
NC
10103 struct
10104 {
32ec8896
NC
10105 unsigned int offset;
10106 unsigned int reg;
fa197c1c
PB
10107 } regpos[16];
10108
10109 /* Scan entire instruction first so that GET_OP output is not
10110 interleaved with disassembly. */
10111 nregs = 0;
10112 for (i = 0; nregs < (op & 0xf); i++)
10113 {
10114 GET_OP (op2);
10115 reg = op2 >> 4;
10116 if (reg != 0xf)
10117 {
10118 regpos[nregs].offset = i * 2;
10119 regpos[nregs].reg = reg;
10120 nregs++;
10121 }
10122
10123 reg = op2 & 0xf;
10124 if (reg != 0xf)
10125 {
10126 regpos[nregs].offset = i * 2 + 1;
10127 regpos[nregs].reg = reg;
10128 nregs++;
10129 }
10130 }
10131
10132 printf (_("pop frame {"));
18344509 10133 if (nregs == 0)
fa197c1c 10134 {
18344509
NC
10135 printf (_("*corrupt* - no registers specified"));
10136 }
10137 else
10138 {
10139 reg = nregs - 1;
10140 for (i = i * 2; i > 0; i--)
fa197c1c 10141 {
18344509
NC
10142 if (regpos[reg].offset == i - 1)
10143 {
10144 name = tic6x_unwind_regnames[regpos[reg].reg];
10145 if (reg > 0)
10146 reg--;
10147 }
10148 else
10149 name = _("[pad]");
fa197c1c 10150
18344509
NC
10151 fputs (name, stdout);
10152 if (i > 1)
10153 printf (", ");
10154 }
fa197c1c
PB
10155 }
10156
10157 printf ("}");
10158 }
10159 else if (op == 0xd0)
10160 printf (" MOV FP, SP");
10161 else if (op == 0xd1)
10162 printf (" __c6xabi_pop_rts");
10163 else if (op == 0xd2)
10164 {
10165 unsigned char buf[9];
10166 unsigned int i, len;
26c527e6 10167 uint64_t offset;
a734115a 10168
fa197c1c
PB
10169 for (i = 0; i < sizeof (buf); i++)
10170 {
10171 GET_OP (buf[i]);
10172 if ((buf[i] & 0x80) == 0)
10173 break;
10174 }
0eff7165
NC
10175 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10176 if (i == sizeof (buf))
10177 {
0eff7165 10178 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10179 return false;
0eff7165 10180 }
948f632f 10181
015dc7e1 10182 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10183 assert (len == i + 1);
10184 offset = offset * 8 + 0x408;
26c527e6 10185 printf (_("sp = sp + %" PRId64), offset);
fa197c1c
PB
10186 }
10187 else if ((op & 0xf0) == 0xe0)
10188 {
10189 if ((op & 0x0f) == 7)
10190 printf (" RETURN");
10191 else
10192 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10193 }
10194 else
10195 {
10196 printf (_(" [unsupported opcode]"));
10197 }
10198 putchar ('\n');
10199 }
32ec8896 10200
015dc7e1 10201 return true;
fa197c1c
PB
10202}
10203
625d49fc
AM
10204static uint64_t
10205arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10206{
625d49fc 10207 uint64_t offset;
fa197c1c
PB
10208
10209 offset = word & 0x7fffffff;
10210 if (offset & 0x40000000)
625d49fc 10211 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10212
dda8d76d 10213 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10214 offset <<= 1;
10215
10216 return offset + where;
10217}
10218
015dc7e1 10219static bool
dda8d76d
NC
10220decode_arm_unwind (Filedata * filedata,
10221 struct arm_unw_aux_info * aux,
1b31d05e
NC
10222 unsigned int word,
10223 unsigned int remaining,
625d49fc 10224 uint64_t data_offset,
1b31d05e
NC
10225 Elf_Internal_Shdr * data_sec,
10226 struct arm_section * data_arm_sec)
fa197c1c
PB
10227{
10228 int per_index;
10229 unsigned int more_words = 0;
37e14bc3 10230 struct absaddr addr;
625d49fc 10231 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10232 bool res = true;
fa197c1c
PB
10233
10234 if (remaining == 0)
10235 {
1b31d05e
NC
10236 /* Fetch the first word.
10237 Note - when decoding an object file the address extracted
10238 here will always be 0. So we also pass in the sym_name
10239 parameter so that we can find the symbol associated with
10240 the personality routine. */
dda8d76d 10241 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10242 & word, & addr, & sym_name))
015dc7e1 10243 return false;
1b31d05e 10244
fa197c1c
PB
10245 remaining = 4;
10246 }
c93dbb25
CZ
10247 else
10248 {
10249 addr.section = SHN_UNDEF;
10250 addr.offset = 0;
10251 }
fa197c1c
PB
10252
10253 if ((word & 0x80000000) == 0)
10254 {
10255 /* Expand prel31 for personality routine. */
625d49fc 10256 uint64_t fn;
fa197c1c
PB
10257 const char *procname;
10258
dda8d76d 10259 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10260 printf (_(" Personality routine: "));
1b31d05e
NC
10261 if (fn == 0
10262 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10263 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10264 {
10265 procname = aux->strtab + sym_name;
10266 print_vma (fn, PREFIX_HEX);
10267 if (procname)
10268 {
10269 fputs (" <", stdout);
10270 fputs (procname, stdout);
10271 fputc ('>', stdout);
10272 }
10273 }
10274 else
dda8d76d 10275 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10276 fputc ('\n', stdout);
10277
10278 /* The GCC personality routines use the standard compact
10279 encoding, starting with one byte giving the number of
10280 words. */
10281 if (procname != NULL
24d127aa
ML
10282 && (startswith (procname, "__gcc_personality_v0")
10283 || startswith (procname, "__gxx_personality_v0")
10284 || startswith (procname, "__gcj_personality_v0")
10285 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10286 {
10287 remaining = 0;
10288 more_words = 1;
10289 ADVANCE;
10290 if (!remaining)
10291 {
10292 printf (_(" [Truncated data]\n"));
015dc7e1 10293 return false;
fa197c1c
PB
10294 }
10295 more_words = word >> 24;
10296 word <<= 8;
10297 remaining--;
10298 per_index = -1;
10299 }
10300 else
015dc7e1 10301 return true;
fa197c1c
PB
10302 }
10303 else
10304 {
1b31d05e 10305 /* ARM EHABI Section 6.3:
0b4362b0 10306
1b31d05e 10307 An exception-handling table entry for the compact model looks like:
0b4362b0 10308
1b31d05e
NC
10309 31 30-28 27-24 23-0
10310 -- ----- ----- ----
10311 1 0 index Data for personalityRoutine[index] */
10312
dda8d76d 10313 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10314 && (word & 0x70000000))
32ec8896
NC
10315 {
10316 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10317 res = false;
32ec8896 10318 }
1b31d05e 10319
fa197c1c 10320 per_index = (word >> 24) & 0x7f;
1b31d05e 10321 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10322 if (per_index == 0)
10323 {
10324 more_words = 0;
10325 word <<= 8;
10326 remaining--;
10327 }
10328 else if (per_index < 3)
10329 {
10330 more_words = (word >> 16) & 0xff;
10331 word <<= 16;
10332 remaining -= 2;
10333 }
10334 }
10335
dda8d76d 10336 switch (filedata->file_header.e_machine)
fa197c1c
PB
10337 {
10338 case EM_ARM:
10339 if (per_index < 3)
10340 {
dda8d76d 10341 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10342 data_offset, data_sec, data_arm_sec))
015dc7e1 10343 res = false;
fa197c1c
PB
10344 }
10345 else
1b31d05e
NC
10346 {
10347 warn (_("Unknown ARM compact model index encountered\n"));
10348 printf (_(" [reserved]\n"));
015dc7e1 10349 res = false;
1b31d05e 10350 }
fa197c1c
PB
10351 break;
10352
10353 case EM_TI_C6000:
10354 if (per_index < 3)
10355 {
dda8d76d 10356 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10357 data_offset, data_sec, data_arm_sec))
015dc7e1 10358 res = false;
fa197c1c
PB
10359 }
10360 else if (per_index < 5)
10361 {
10362 if (((word >> 17) & 0x7f) == 0x7f)
10363 printf (_(" Restore stack from frame pointer\n"));
10364 else
10365 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10366 printf (_(" Registers restored: "));
10367 if (per_index == 4)
10368 printf (" (compact) ");
10369 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10370 putchar ('\n');
10371 printf (_(" Return register: %s\n"),
10372 tic6x_unwind_regnames[word & 0xf]);
10373 }
10374 else
1b31d05e 10375 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10376 break;
10377
10378 default:
74e1a04b 10379 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10380 filedata->file_header.e_machine);
015dc7e1 10381 res = false;
fa197c1c 10382 }
0b6ae522
DJ
10383
10384 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10385
10386 return res;
0b6ae522
DJ
10387}
10388
015dc7e1 10389static bool
dda8d76d
NC
10390dump_arm_unwind (Filedata * filedata,
10391 struct arm_unw_aux_info * aux,
10392 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10393{
10394 struct arm_section exidx_arm_sec, extab_arm_sec;
10395 unsigned int i, exidx_len;
26c527e6 10396 uint64_t j, nfuns;
015dc7e1 10397 bool res = true;
0b6ae522
DJ
10398
10399 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10400 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10401 exidx_len = exidx_sec->sh_size / 8;
10402
948f632f
DA
10403 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10404 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10405 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10406 aux->funtab[nfuns++] = aux->symtab[j];
10407 aux->nfuns = nfuns;
10408 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10409
0b6ae522
DJ
10410 for (i = 0; i < exidx_len; i++)
10411 {
10412 unsigned int exidx_fn, exidx_entry;
10413 struct absaddr fn_addr, entry_addr;
625d49fc 10414 uint64_t fn;
0b6ae522
DJ
10415
10416 fputc ('\n', stdout);
10417
dda8d76d 10418 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10419 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10420 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10421 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10422 {
948f632f 10423 free (aux->funtab);
1b31d05e
NC
10424 arm_free_section (& exidx_arm_sec);
10425 arm_free_section (& extab_arm_sec);
015dc7e1 10426 return false;
0b6ae522
DJ
10427 }
10428
83c257ca
NC
10429 /* ARM EHABI, Section 5:
10430 An index table entry consists of 2 words.
10431 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10432 if (exidx_fn & 0x80000000)
32ec8896
NC
10433 {
10434 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10435 res = false;
32ec8896 10436 }
83c257ca 10437
dda8d76d 10438 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10439
dda8d76d 10440 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10441 fputs (": ", stdout);
10442
10443 if (exidx_entry == 1)
10444 {
10445 print_vma (exidx_entry, PREFIX_HEX);
10446 fputs (" [cantunwind]\n", stdout);
10447 }
10448 else if (exidx_entry & 0x80000000)
10449 {
10450 print_vma (exidx_entry, PREFIX_HEX);
10451 fputc ('\n', stdout);
dda8d76d 10452 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10453 }
10454 else
10455 {
625d49fc 10456 uint64_t table, table_offset = 0;
0b6ae522
DJ
10457 Elf_Internal_Shdr *table_sec;
10458
10459 fputs ("@", stdout);
dda8d76d 10460 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10461 print_vma (table, PREFIX_HEX);
10462 printf ("\n");
10463
10464 /* Locate the matching .ARM.extab. */
10465 if (entry_addr.section != SHN_UNDEF
dda8d76d 10466 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10467 {
dda8d76d 10468 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10469 table_offset = entry_addr.offset;
1a915552 10470 /* PR 18879 */
625d49fc 10471 if (table_offset > table_sec->sh_size)
1a915552 10472 {
26c527e6
AM
10473 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
10474 table_offset,
dda8d76d 10475 printable_section_name (filedata, table_sec));
015dc7e1 10476 res = false;
1a915552
NC
10477 continue;
10478 }
0b6ae522
DJ
10479 }
10480 else
10481 {
dda8d76d 10482 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10483 if (table_sec != NULL)
10484 table_offset = table - table_sec->sh_addr;
10485 }
32ec8896 10486
0b6ae522
DJ
10487 if (table_sec == NULL)
10488 {
26c527e6
AM
10489 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
10490 table);
015dc7e1 10491 res = false;
0b6ae522
DJ
10492 continue;
10493 }
32ec8896 10494
dda8d76d 10495 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10496 &extab_arm_sec))
015dc7e1 10497 res = false;
0b6ae522
DJ
10498 }
10499 }
10500
10501 printf ("\n");
10502
948f632f 10503 free (aux->funtab);
0b6ae522
DJ
10504 arm_free_section (&exidx_arm_sec);
10505 arm_free_section (&extab_arm_sec);
32ec8896
NC
10506
10507 return res;
0b6ae522
DJ
10508}
10509
fa197c1c 10510/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10511
015dc7e1 10512static bool
dda8d76d 10513arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10514{
10515 struct arm_unw_aux_info aux;
10516 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522 10517 Elf_Internal_Shdr *sec;
26c527e6 10518 size_t i;
fa197c1c 10519 unsigned int sec_type;
015dc7e1 10520 bool res = true;
0b6ae522 10521
dda8d76d 10522 switch (filedata->file_header.e_machine)
fa197c1c
PB
10523 {
10524 case EM_ARM:
10525 sec_type = SHT_ARM_EXIDX;
10526 break;
10527
10528 case EM_TI_C6000:
10529 sec_type = SHT_C6000_UNWIND;
10530 break;
10531
0b4362b0 10532 default:
74e1a04b 10533 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10534 filedata->file_header.e_machine);
015dc7e1 10535 return false;
fa197c1c
PB
10536 }
10537
dda8d76d 10538 if (filedata->string_table == NULL)
015dc7e1 10539 return false;
1b31d05e
NC
10540
10541 memset (& aux, 0, sizeof (aux));
dda8d76d 10542 aux.filedata = filedata;
0b6ae522 10543
dda8d76d 10544 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10545 {
28d13567 10546 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10547 {
28d13567 10548 if (aux.symtab)
74e1a04b 10549 {
28d13567
AM
10550 error (_("Multiple symbol tables encountered\n"));
10551 free (aux.symtab);
10552 aux.symtab = NULL;
74e1a04b 10553 free (aux.strtab);
28d13567 10554 aux.strtab = NULL;
74e1a04b 10555 }
28d13567
AM
10556 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10557 &aux.strtab, &aux.strtab_size))
015dc7e1 10558 return false;
0b6ae522 10559 }
fa197c1c 10560 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10561 unwsec = sec;
10562 }
10563
1b31d05e 10564 if (unwsec == NULL)
0b6ae522 10565 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10566 else
dda8d76d 10567 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10568 {
10569 if (sec->sh_type == sec_type)
10570 {
26c527e6
AM
10571 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
10572 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
10573 "contains %" PRIu64 " entry:\n",
10574 "\nUnwind section '%s' at offset %#" PRIx64 " "
10575 "contains %" PRIu64 " entries:\n",
d3a49aa8 10576 num_unwind),
dda8d76d 10577 printable_section_name (filedata, sec),
26c527e6 10578 sec->sh_offset,
d3a49aa8 10579 num_unwind);
0b6ae522 10580
dda8d76d 10581 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10582 res = false;
1b31d05e
NC
10583 }
10584 }
0b6ae522 10585
9db70fc3
AM
10586 free (aux.symtab);
10587 free ((char *) aux.strtab);
32ec8896
NC
10588
10589 return res;
0b6ae522
DJ
10590}
10591
3ecc00ec
NC
10592static bool
10593no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10594{
10595 printf (_("No processor specific unwind information to decode\n"));
10596 return true;
10597}
10598
015dc7e1 10599static bool
dda8d76d 10600process_unwind (Filedata * filedata)
57346661 10601{
2cf0635d
NC
10602 struct unwind_handler
10603 {
32ec8896 10604 unsigned int machtype;
015dc7e1 10605 bool (* handler)(Filedata *);
2cf0635d
NC
10606 } handlers[] =
10607 {
0b6ae522 10608 { EM_ARM, arm_process_unwind },
57346661
AM
10609 { EM_IA_64, ia64_process_unwind },
10610 { EM_PARISC, hppa_process_unwind },
fa197c1c 10611 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10612 { EM_386, no_processor_specific_unwind },
10613 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10614 { 0, NULL }
57346661
AM
10615 };
10616 int i;
10617
10618 if (!do_unwind)
015dc7e1 10619 return true;
57346661
AM
10620
10621 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10622 if (filedata->file_header.e_machine == handlers[i].machtype)
10623 return handlers[i].handler (filedata);
57346661 10624
1b31d05e 10625 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10626 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10627 return true;
57346661
AM
10628}
10629
37c18eed
SD
10630static void
10631dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10632{
10633 switch (entry->d_tag)
10634 {
10635 case DT_AARCH64_BTI_PLT:
1dbade74 10636 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10637 break;
10638 default:
10639 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10640 break;
10641 }
10642 putchar ('\n');
10643}
10644
252b5132 10645static void
978c4450 10646dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10647{
10648 switch (entry->d_tag)
10649 {
10650 case DT_MIPS_FLAGS:
10651 if (entry->d_un.d_val == 0)
4b68bca3 10652 printf (_("NONE"));
252b5132
RH
10653 else
10654 {
10655 static const char * opts[] =
10656 {
10657 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10658 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10659 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10660 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10661 "RLD_ORDER_SAFE"
10662 };
10663 unsigned int cnt;
015dc7e1 10664 bool first = true;
2b692964 10665
60bca95a 10666 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10667 if (entry->d_un.d_val & (1 << cnt))
10668 {
10669 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10670 first = false;
252b5132 10671 }
252b5132
RH
10672 }
10673 break;
103f02d3 10674
252b5132 10675 case DT_MIPS_IVERSION:
84714f86 10676 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10677 printf (_("Interface Version: %s"),
84714f86 10678 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10679 else
f493c217 10680 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 10681 entry->d_un.d_ptr);
252b5132 10682 break;
103f02d3 10683
252b5132
RH
10684 case DT_MIPS_TIME_STAMP:
10685 {
d5b07ef4 10686 char timebuf[128];
2cf0635d 10687 struct tm * tmp;
91d6fa6a 10688 time_t atime = entry->d_un.d_val;
82b1b41b 10689
91d6fa6a 10690 tmp = gmtime (&atime);
82b1b41b
NC
10691 /* PR 17531: file: 6accc532. */
10692 if (tmp == NULL)
10693 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10694 else
10695 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10696 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10697 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10698 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10699 }
10700 break;
103f02d3 10701
252b5132
RH
10702 case DT_MIPS_RLD_VERSION:
10703 case DT_MIPS_LOCAL_GOTNO:
10704 case DT_MIPS_CONFLICTNO:
10705 case DT_MIPS_LIBLISTNO:
10706 case DT_MIPS_SYMTABNO:
10707 case DT_MIPS_UNREFEXTNO:
10708 case DT_MIPS_HIPAGENO:
10709 case DT_MIPS_DELTA_CLASS_NO:
10710 case DT_MIPS_DELTA_INSTANCE_NO:
10711 case DT_MIPS_DELTA_RELOC_NO:
10712 case DT_MIPS_DELTA_SYM_NO:
10713 case DT_MIPS_DELTA_CLASSSYM_NO:
10714 case DT_MIPS_COMPACT_SIZE:
c69075ac 10715 print_vma (entry->d_un.d_val, DEC);
252b5132 10716 break;
103f02d3 10717
f16a9783 10718 case DT_MIPS_XHASH:
978c4450
AM
10719 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10720 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10721 /* Falls through. */
10722
103f02d3 10723 default:
4b68bca3 10724 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10725 }
4b68bca3 10726 putchar ('\n');
103f02d3
UD
10727}
10728
103f02d3 10729static void
2cf0635d 10730dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10731{
10732 switch (entry->d_tag)
10733 {
10734 case DT_HP_DLD_FLAGS:
10735 {
10736 static struct
10737 {
26c527e6 10738 unsigned int bit;
2cf0635d 10739 const char * str;
5e220199
NC
10740 }
10741 flags[] =
10742 {
10743 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10744 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10745 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10746 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10747 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10748 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10749 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10750 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10751 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10752 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10753 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10754 { DT_HP_GST, "HP_GST" },
10755 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10756 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10757 { DT_HP_NODELETE, "HP_NODELETE" },
10758 { DT_HP_GROUP, "HP_GROUP" },
10759 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10760 };
015dc7e1 10761 bool first = true;
5e220199 10762 size_t cnt;
625d49fc 10763 uint64_t val = entry->d_un.d_val;
103f02d3 10764
60bca95a 10765 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10766 if (val & flags[cnt].bit)
30800947
NC
10767 {
10768 if (! first)
10769 putchar (' ');
10770 fputs (flags[cnt].str, stdout);
015dc7e1 10771 first = false;
30800947
NC
10772 val ^= flags[cnt].bit;
10773 }
76da6bbe 10774
103f02d3 10775 if (val != 0 || first)
f7a99963
NC
10776 {
10777 if (! first)
10778 putchar (' ');
10779 print_vma (val, HEX);
10780 }
103f02d3
UD
10781 }
10782 break;
76da6bbe 10783
252b5132 10784 default:
f7a99963
NC
10785 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10786 break;
252b5132 10787 }
35b1837e 10788 putchar ('\n');
252b5132
RH
10789}
10790
28f997cf
TG
10791/* VMS vs Unix time offset and factor. */
10792
10793#define VMS_EPOCH_OFFSET 35067168000000000LL
10794#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10795#ifndef INT64_MIN
10796#define INT64_MIN (-9223372036854775807LL - 1)
10797#endif
28f997cf
TG
10798
10799/* Display a VMS time in a human readable format. */
10800
10801static void
0e3c1eeb 10802print_vms_time (int64_t vmstime)
28f997cf 10803{
dccc31de 10804 struct tm *tm = NULL;
28f997cf
TG
10805 time_t unxtime;
10806
dccc31de
AM
10807 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10808 {
10809 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10810 unxtime = vmstime;
10811 if (unxtime == vmstime)
10812 tm = gmtime (&unxtime);
10813 }
10814 if (tm != NULL)
10815 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10816 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10817 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 10818}
28f997cf 10819
ecc51f48 10820static void
2cf0635d 10821dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10822{
10823 switch (entry->d_tag)
10824 {
0de14b54 10825 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10826 /* First 3 slots reserved. */
ecc51f48
NC
10827 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10828 printf (" -- ");
10829 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10830 break;
10831
28f997cf 10832 case DT_IA_64_VMS_LINKTIME:
28f997cf 10833 print_vms_time (entry->d_un.d_val);
28f997cf
TG
10834 break;
10835
10836 case DT_IA_64_VMS_LNKFLAGS:
10837 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10838 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10839 printf (" CALL_DEBUG");
10840 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10841 printf (" NOP0BUFS");
10842 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10843 printf (" P0IMAGE");
10844 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10845 printf (" MKTHREADS");
10846 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10847 printf (" UPCALLS");
10848 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10849 printf (" IMGSTA");
10850 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10851 printf (" INITIALIZE");
10852 if (entry->d_un.d_val & VMS_LF_MAIN)
10853 printf (" MAIN");
10854 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10855 printf (" EXE_INIT");
10856 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10857 printf (" TBK_IN_IMG");
10858 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10859 printf (" DBG_IN_IMG");
10860 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10861 printf (" TBK_IN_DSF");
10862 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10863 printf (" DBG_IN_DSF");
10864 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10865 printf (" SIGNATURES");
10866 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10867 printf (" REL_SEG_OFF");
10868 break;
10869
bdf4d63a
JJ
10870 default:
10871 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10872 break;
ecc51f48 10873 }
bdf4d63a 10874 putchar ('\n');
ecc51f48
NC
10875}
10876
015dc7e1 10877static bool
dda8d76d 10878get_32bit_dynamic_section (Filedata * filedata)
252b5132 10879{
2cf0635d
NC
10880 Elf32_External_Dyn * edyn;
10881 Elf32_External_Dyn * ext;
10882 Elf_Internal_Dyn * entry;
103f02d3 10883
978c4450
AM
10884 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10885 filedata->dynamic_addr, 1,
10886 filedata->dynamic_size,
10887 _("dynamic section"));
a6e9f9df 10888 if (!edyn)
015dc7e1 10889 return false;
103f02d3 10890
071436c6
NC
10891 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10892 might not have the luxury of section headers. Look for the DT_NULL
10893 terminator to determine the number of entries. */
978c4450
AM
10894 for (ext = edyn, filedata->dynamic_nent = 0;
10895 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10896 ext++)
10897 {
978c4450 10898 filedata->dynamic_nent++;
ba2685cc
AM
10899 if (BYTE_GET (ext->d_tag) == DT_NULL)
10900 break;
10901 }
252b5132 10902
978c4450
AM
10903 filedata->dynamic_section
10904 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10905 if (filedata->dynamic_section == NULL)
252b5132 10906 {
26c527e6
AM
10907 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
10908 filedata->dynamic_nent);
9ea033b2 10909 free (edyn);
015dc7e1 10910 return false;
9ea033b2 10911 }
252b5132 10912
978c4450
AM
10913 for (ext = edyn, entry = filedata->dynamic_section;
10914 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10915 ext++, entry++)
9ea033b2 10916 {
fb514b26
AM
10917 entry->d_tag = BYTE_GET (ext->d_tag);
10918 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10919 }
10920
9ea033b2
NC
10921 free (edyn);
10922
015dc7e1 10923 return true;
9ea033b2
NC
10924}
10925
015dc7e1 10926static bool
dda8d76d 10927get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10928{
2cf0635d
NC
10929 Elf64_External_Dyn * edyn;
10930 Elf64_External_Dyn * ext;
10931 Elf_Internal_Dyn * entry;
103f02d3 10932
071436c6 10933 /* Read in the data. */
978c4450
AM
10934 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10935 filedata->dynamic_addr, 1,
10936 filedata->dynamic_size,
10937 _("dynamic section"));
a6e9f9df 10938 if (!edyn)
015dc7e1 10939 return false;
103f02d3 10940
071436c6
NC
10941 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10942 might not have the luxury of section headers. Look for the DT_NULL
10943 terminator to determine the number of entries. */
978c4450 10944 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10945 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10946 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10947 ext++)
10948 {
978c4450 10949 filedata->dynamic_nent++;
66543521 10950 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10951 break;
10952 }
252b5132 10953
978c4450
AM
10954 filedata->dynamic_section
10955 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10956 if (filedata->dynamic_section == NULL)
252b5132 10957 {
26c527e6
AM
10958 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
10959 filedata->dynamic_nent);
252b5132 10960 free (edyn);
015dc7e1 10961 return false;
252b5132
RH
10962 }
10963
071436c6 10964 /* Convert from external to internal formats. */
978c4450
AM
10965 for (ext = edyn, entry = filedata->dynamic_section;
10966 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10967 ext++, entry++)
252b5132 10968 {
66543521
AM
10969 entry->d_tag = BYTE_GET (ext->d_tag);
10970 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10971 }
10972
10973 free (edyn);
10974
015dc7e1 10975 return true;
9ea033b2
NC
10976}
10977
4de91c10
AM
10978static bool
10979get_dynamic_section (Filedata *filedata)
10980{
10981 if (filedata->dynamic_section)
10982 return true;
10983
10984 if (is_32bit_elf)
10985 return get_32bit_dynamic_section (filedata);
10986 else
10987 return get_64bit_dynamic_section (filedata);
10988}
10989
e9e44622 10990static void
625d49fc 10991print_dynamic_flags (uint64_t flags)
d1133906 10992{
015dc7e1 10993 bool first = true;
13ae64f3 10994
d1133906
NC
10995 while (flags)
10996 {
625d49fc 10997 uint64_t flag;
d1133906
NC
10998
10999 flag = flags & - flags;
11000 flags &= ~ flag;
11001
e9e44622 11002 if (first)
015dc7e1 11003 first = false;
e9e44622
JJ
11004 else
11005 putc (' ', stdout);
13ae64f3 11006
d1133906
NC
11007 switch (flag)
11008 {
e9e44622
JJ
11009 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11010 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11011 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11012 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11013 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 11014 default: fputs (_("unknown"), stdout); break;
d1133906
NC
11015 }
11016 }
e9e44622 11017 puts ("");
d1133906
NC
11018}
11019
625d49fc 11020static uint64_t *
be7d229a 11021get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
11022{
11023 unsigned char * e_data;
625d49fc 11024 uint64_t * i_data;
10ca4b04 11025
be7d229a
AM
11026 /* If size_t is smaller than uint64_t, eg because you are building
11027 on a 32-bit host, then make sure that when number is cast to
11028 size_t no information is lost. */
11029 if ((size_t) number != number
11030 || ent_size * number / ent_size != number)
10ca4b04 11031 {
be7d229a 11032 error (_("Size overflow prevents reading %" PRIu64
b8281767 11033 " elements of size %u\n"),
be7d229a 11034 number, ent_size);
10ca4b04
L
11035 return NULL;
11036 }
11037
11038 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11039 attempting to allocate memory when the read is bound to fail. */
11040 if (ent_size * number > filedata->file_size)
11041 {
b8281767 11042 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 11043 number);
10ca4b04
L
11044 return NULL;
11045 }
11046
11047 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11048 if (e_data == NULL)
11049 {
b8281767 11050 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 11051 number);
10ca4b04
L
11052 return NULL;
11053 }
11054
11055 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11056 {
b8281767 11057 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 11058 number * ent_size);
10ca4b04
L
11059 free (e_data);
11060 return NULL;
11061 }
11062
625d49fc 11063 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
11064 if (i_data == NULL)
11065 {
b8281767 11066 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 11067 number);
10ca4b04
L
11068 free (e_data);
11069 return NULL;
11070 }
11071
11072 while (number--)
11073 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11074
11075 free (e_data);
11076
11077 return i_data;
11078}
11079
26c527e6 11080static uint64_t
10ca4b04
L
11081get_num_dynamic_syms (Filedata * filedata)
11082{
26c527e6 11083 uint64_t num_of_syms = 0;
10ca4b04
L
11084
11085 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11086 return num_of_syms;
11087
978c4450 11088 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11089 {
11090 unsigned char nb[8];
11091 unsigned char nc[8];
11092 unsigned int hash_ent_size = 4;
11093
11094 if ((filedata->file_header.e_machine == EM_ALPHA
11095 || filedata->file_header.e_machine == EM_S390
11096 || filedata->file_header.e_machine == EM_S390_OLD)
11097 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11098 hash_ent_size = 8;
11099
63cf857e
AM
11100 if (fseek64 (filedata->handle,
11101 (filedata->archive_file_offset
11102 + offset_from_vma (filedata,
11103 filedata->dynamic_info[DT_HASH],
11104 sizeof nb + sizeof nc)),
11105 SEEK_SET))
10ca4b04
L
11106 {
11107 error (_("Unable to seek to start of dynamic information\n"));
11108 goto no_hash;
11109 }
11110
11111 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11112 {
11113 error (_("Failed to read in number of buckets\n"));
11114 goto no_hash;
11115 }
11116
11117 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11118 {
11119 error (_("Failed to read in number of chains\n"));
11120 goto no_hash;
11121 }
11122
978c4450
AM
11123 filedata->nbuckets = byte_get (nb, hash_ent_size);
11124 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11125
2482f306
AM
11126 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11127 {
11128 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11129 hash_ent_size);
11130 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11131 hash_ent_size);
001890e1 11132
2482f306
AM
11133 if (filedata->buckets != NULL && filedata->chains != NULL)
11134 num_of_syms = filedata->nchains;
11135 }
ceb9bf11 11136 no_hash:
10ca4b04
L
11137 if (num_of_syms == 0)
11138 {
9db70fc3
AM
11139 free (filedata->buckets);
11140 filedata->buckets = NULL;
11141 free (filedata->chains);
11142 filedata->chains = NULL;
978c4450 11143 filedata->nbuckets = 0;
10ca4b04
L
11144 }
11145 }
11146
978c4450 11147 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11148 {
11149 unsigned char nb[16];
625d49fc
AM
11150 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11151 uint64_t buckets_vma;
26c527e6 11152 uint64_t hn;
10ca4b04 11153
63cf857e
AM
11154 if (fseek64 (filedata->handle,
11155 (filedata->archive_file_offset
11156 + offset_from_vma (filedata,
11157 filedata->dynamic_info_DT_GNU_HASH,
11158 sizeof nb)),
11159 SEEK_SET))
10ca4b04
L
11160 {
11161 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11162 goto no_gnu_hash;
11163 }
11164
11165 if (fread (nb, 16, 1, filedata->handle) != 1)
11166 {
11167 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11168 goto no_gnu_hash;
11169 }
11170
978c4450
AM
11171 filedata->ngnubuckets = byte_get (nb, 4);
11172 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11173 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11174 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11175 if (is_32bit_elf)
11176 buckets_vma += bitmaskwords * 4;
11177 else
11178 buckets_vma += bitmaskwords * 8;
11179
63cf857e
AM
11180 if (fseek64 (filedata->handle,
11181 (filedata->archive_file_offset
11182 + offset_from_vma (filedata, buckets_vma, 4)),
11183 SEEK_SET))
10ca4b04
L
11184 {
11185 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11186 goto no_gnu_hash;
11187 }
11188
978c4450
AM
11189 filedata->gnubuckets
11190 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11191
978c4450 11192 if (filedata->gnubuckets == NULL)
90837ea7 11193 goto no_gnu_hash;
10ca4b04 11194
978c4450
AM
11195 for (i = 0; i < filedata->ngnubuckets; i++)
11196 if (filedata->gnubuckets[i] != 0)
10ca4b04 11197 {
978c4450 11198 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11199 goto no_gnu_hash;
10ca4b04 11200
978c4450
AM
11201 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11202 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11203 }
11204
11205 if (maxchain == 0xffffffff)
90837ea7 11206 goto no_gnu_hash;
10ca4b04 11207
978c4450 11208 maxchain -= filedata->gnusymidx;
10ca4b04 11209
63cf857e
AM
11210 if (fseek64 (filedata->handle,
11211 (filedata->archive_file_offset
11212 + offset_from_vma (filedata,
11213 buckets_vma + 4 * (filedata->ngnubuckets
11214 + maxchain),
11215 4)),
11216 SEEK_SET))
10ca4b04
L
11217 {
11218 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11219 goto no_gnu_hash;
11220 }
11221
11222 do
11223 {
11224 if (fread (nb, 4, 1, filedata->handle) != 1)
11225 {
11226 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11227 goto no_gnu_hash;
11228 }
11229
11230 if (maxchain + 1 == 0)
90837ea7 11231 goto no_gnu_hash;
10ca4b04
L
11232
11233 ++maxchain;
11234 }
11235 while ((byte_get (nb, 4) & 1) == 0);
11236
63cf857e
AM
11237 if (fseek64 (filedata->handle,
11238 (filedata->archive_file_offset
11239 + offset_from_vma (filedata, (buckets_vma
11240 + 4 * filedata->ngnubuckets),
11241 4)),
11242 SEEK_SET))
10ca4b04
L
11243 {
11244 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11245 goto no_gnu_hash;
11246 }
11247
978c4450
AM
11248 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11249 filedata->ngnuchains = maxchain;
10ca4b04 11250
978c4450 11251 if (filedata->gnuchains == NULL)
90837ea7 11252 goto no_gnu_hash;
10ca4b04 11253
978c4450 11254 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11255 {
63cf857e
AM
11256 if (fseek64 (filedata->handle,
11257 (filedata->archive_file_offset
11258 + offset_from_vma (filedata, (buckets_vma
11259 + 4 * (filedata->ngnubuckets
11260 + maxchain)), 4)),
11261 SEEK_SET))
10ca4b04
L
11262 {
11263 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11264 goto no_gnu_hash;
11265 }
11266
978c4450 11267 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11268 if (filedata->mipsxlat == NULL)
11269 goto no_gnu_hash;
10ca4b04
L
11270 }
11271
978c4450
AM
11272 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11273 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11274 {
625d49fc
AM
11275 uint64_t si = filedata->gnubuckets[hn];
11276 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11277
11278 do
11279 {
978c4450 11280 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11281 {
c31ab5a0
AM
11282 if (off < filedata->ngnuchains
11283 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11284 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11285 }
11286 else
11287 {
11288 if (si >= num_of_syms)
11289 num_of_syms = si + 1;
11290 }
11291 si++;
11292 }
978c4450
AM
11293 while (off < filedata->ngnuchains
11294 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11295 }
11296
90837ea7 11297 if (num_of_syms == 0)
10ca4b04 11298 {
90837ea7 11299 no_gnu_hash:
9db70fc3
AM
11300 free (filedata->mipsxlat);
11301 filedata->mipsxlat = NULL;
11302 free (filedata->gnuchains);
11303 filedata->gnuchains = NULL;
11304 free (filedata->gnubuckets);
11305 filedata->gnubuckets = NULL;
978c4450
AM
11306 filedata->ngnubuckets = 0;
11307 filedata->ngnuchains = 0;
10ca4b04
L
11308 }
11309 }
11310
11311 return num_of_syms;
11312}
11313
b2d38a17
NC
11314/* Parse and display the contents of the dynamic section. */
11315
015dc7e1 11316static bool
dda8d76d 11317process_dynamic_section (Filedata * filedata)
9ea033b2 11318{
2cf0635d 11319 Elf_Internal_Dyn * entry;
9ea033b2 11320
93df3340 11321 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11322 {
11323 if (do_dynamic)
ca0e11aa
NC
11324 {
11325 if (filedata->is_separate)
11326 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11327 filedata->file_name);
11328 else
11329 printf (_("\nThere is no dynamic section in this file.\n"));
11330 }
9ea033b2 11331
015dc7e1 11332 return true;
9ea033b2
NC
11333 }
11334
4de91c10
AM
11335 if (!get_dynamic_section (filedata))
11336 return false;
9ea033b2 11337
252b5132 11338 /* Find the appropriate symbol table. */
978c4450 11339 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11340 {
26c527e6 11341 uint64_t num_of_syms;
2482f306 11342
978c4450
AM
11343 for (entry = filedata->dynamic_section;
11344 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11345 ++entry)
10ca4b04 11346 if (entry->d_tag == DT_SYMTAB)
978c4450 11347 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11348 else if (entry->d_tag == DT_SYMENT)
978c4450 11349 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11350 else if (entry->d_tag == DT_HASH)
978c4450 11351 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11352 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11353 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11354 else if ((filedata->file_header.e_machine == EM_MIPS
11355 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11356 && entry->d_tag == DT_MIPS_XHASH)
11357 {
978c4450
AM
11358 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11359 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11360 }
252b5132 11361
2482f306
AM
11362 num_of_syms = get_num_dynamic_syms (filedata);
11363
11364 if (num_of_syms != 0
11365 && filedata->dynamic_symbols == NULL
11366 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11367 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11368 {
11369 Elf_Internal_Phdr *seg;
625d49fc 11370 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11371
2482f306
AM
11372 if (! get_program_headers (filedata))
11373 {
11374 error (_("Cannot interpret virtual addresses "
11375 "without program headers.\n"));
015dc7e1 11376 return false;
2482f306 11377 }
252b5132 11378
2482f306
AM
11379 for (seg = filedata->program_headers;
11380 seg < filedata->program_headers + filedata->file_header.e_phnum;
11381 ++seg)
11382 {
11383 if (seg->p_type != PT_LOAD)
11384 continue;
252b5132 11385
2482f306
AM
11386 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11387 {
11388 /* See PR 21379 for a reproducer. */
11389 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11390 return false;
2482f306 11391 }
252b5132 11392
2482f306
AM
11393 if (vma >= (seg->p_vaddr & -seg->p_align)
11394 && vma < seg->p_vaddr + seg->p_filesz)
11395 {
11396 /* Since we do not know how big the symbol table is,
11397 we default to reading in up to the end of PT_LOAD
11398 segment and processing that. This is overkill, I
11399 know, but it should work. */
11400 Elf_Internal_Shdr section;
11401 section.sh_offset = (vma - seg->p_vaddr
11402 + seg->p_offset);
11403 section.sh_size = (num_of_syms
11404 * filedata->dynamic_info[DT_SYMENT]);
11405 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11406
11407 if (do_checks
11408 && filedata->dynamic_symtab_section != NULL
11409 && ((filedata->dynamic_symtab_section->sh_offset
11410 != section.sh_offset)
11411 || (filedata->dynamic_symtab_section->sh_size
11412 != section.sh_size)
11413 || (filedata->dynamic_symtab_section->sh_entsize
11414 != section.sh_entsize)))
11415 warn (_("\
11416the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11417
2482f306
AM
11418 section.sh_name = filedata->string_table_length;
11419 filedata->dynamic_symbols
4de91c10 11420 = get_elf_symbols (filedata, &section,
2482f306
AM
11421 &filedata->num_dynamic_syms);
11422 if (filedata->dynamic_symbols == NULL
11423 || filedata->num_dynamic_syms != num_of_syms)
11424 {
11425 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11426 return false;
2482f306
AM
11427 }
11428 break;
11429 }
11430 }
11431 }
11432 }
252b5132
RH
11433
11434 /* Similarly find a string table. */
978c4450
AM
11435 if (filedata->dynamic_strings == NULL)
11436 for (entry = filedata->dynamic_section;
11437 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11438 ++entry)
11439 {
11440 if (entry->d_tag == DT_STRTAB)
978c4450 11441 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11442
10ca4b04 11443 if (entry->d_tag == DT_STRSZ)
978c4450 11444 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11445
978c4450
AM
11446 if (filedata->dynamic_info[DT_STRTAB]
11447 && filedata->dynamic_info[DT_STRSZ])
10ca4b04 11448 {
26c527e6 11449 uint64_t offset;
be7d229a 11450 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11451
11452 offset = offset_from_vma (filedata,
978c4450 11453 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11454 str_tab_len);
8ac10c5b
L
11455 if (do_checks
11456 && filedata->dynamic_strtab_section
11457 && ((filedata->dynamic_strtab_section->sh_offset
11458 != (file_ptr) offset)
11459 || (filedata->dynamic_strtab_section->sh_size
11460 != str_tab_len)))
11461 warn (_("\
11462the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11463
978c4450
AM
11464 filedata->dynamic_strings
11465 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11466 _("dynamic string table"));
11467 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11468 {
11469 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11470 break;
11471 }
e3d39609 11472
978c4450 11473 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11474 break;
11475 }
11476 }
252b5132
RH
11477
11478 /* And find the syminfo section if available. */
978c4450 11479 if (filedata->dynamic_syminfo == NULL)
252b5132 11480 {
26c527e6 11481 uint64_t syminsz = 0;
252b5132 11482
978c4450
AM
11483 for (entry = filedata->dynamic_section;
11484 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11485 ++entry)
252b5132
RH
11486 {
11487 if (entry->d_tag == DT_SYMINENT)
11488 {
11489 /* Note: these braces are necessary to avoid a syntax
11490 error from the SunOS4 C compiler. */
049b0c3a
NC
11491 /* PR binutils/17531: A corrupt file can trigger this test.
11492 So do not use an assert, instead generate an error message. */
11493 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11494 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11495 (int) entry->d_un.d_val);
252b5132
RH
11496 }
11497 else if (entry->d_tag == DT_SYMINSZ)
11498 syminsz = entry->d_un.d_val;
11499 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11500 filedata->dynamic_syminfo_offset
11501 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11502 }
11503
978c4450 11504 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11505 {
2cf0635d
NC
11506 Elf_External_Syminfo * extsyminfo;
11507 Elf_External_Syminfo * extsym;
11508 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11509
11510 /* There is a syminfo section. Read the data. */
3f5e193b 11511 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11512 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11513 1, syminsz, _("symbol information"));
a6e9f9df 11514 if (!extsyminfo)
015dc7e1 11515 return false;
252b5132 11516
978c4450 11517 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11518 {
11519 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11520 free (filedata->dynamic_syminfo);
e3d39609 11521 }
978c4450
AM
11522 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11523 if (filedata->dynamic_syminfo == NULL)
252b5132 11524 {
26c527e6
AM
11525 error (_("Out of memory allocating %" PRIu64
11526 " bytes for dynamic symbol info\n"),
11527 syminsz);
015dc7e1 11528 return false;
252b5132
RH
11529 }
11530
2482f306
AM
11531 filedata->dynamic_syminfo_nent
11532 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11533 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11534 syminfo < (filedata->dynamic_syminfo
11535 + filedata->dynamic_syminfo_nent);
86dba8ee 11536 ++syminfo, ++extsym)
252b5132 11537 {
86dba8ee
AM
11538 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11539 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11540 }
11541
11542 free (extsyminfo);
11543 }
11544 }
11545
978c4450 11546 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11547 {
f253158f 11548 if (filedata->is_separate)
26c527e6
AM
11549 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
11550 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
11551 filedata->dynamic_nent),
f253158f
NC
11552 filedata->file_name,
11553 filedata->dynamic_addr,
26c527e6 11554 filedata->dynamic_nent);
84a9f195 11555 else
02da71ee 11556 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
26c527e6
AM
11557 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
11558 filedata->dynamic_nent),
84a9f195 11559 filedata->dynamic_addr,
26c527e6 11560 filedata->dynamic_nent);
ca0e11aa 11561 }
252b5132
RH
11562 if (do_dynamic)
11563 printf (_(" Tag Type Name/Value\n"));
11564
978c4450
AM
11565 for (entry = filedata->dynamic_section;
11566 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11567 entry++)
252b5132
RH
11568 {
11569 if (do_dynamic)
f7a99963 11570 {
2cf0635d 11571 const char * dtype;
e699b9ff 11572
f7a99963
NC
11573 putchar (' ');
11574 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11575 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11576 printf (" (%s)%*s", dtype,
32ec8896 11577 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11578 }
252b5132
RH
11579
11580 switch (entry->d_tag)
11581 {
d1133906
NC
11582 case DT_FLAGS:
11583 if (do_dynamic)
e9e44622 11584 print_dynamic_flags (entry->d_un.d_val);
d1133906 11585 break;
76da6bbe 11586
252b5132
RH
11587 case DT_AUXILIARY:
11588 case DT_FILTER:
019148e4
L
11589 case DT_CONFIG:
11590 case DT_DEPAUDIT:
11591 case DT_AUDIT:
252b5132
RH
11592 if (do_dynamic)
11593 {
019148e4 11594 switch (entry->d_tag)
b34976b6 11595 {
019148e4
L
11596 case DT_AUXILIARY:
11597 printf (_("Auxiliary library"));
11598 break;
11599
11600 case DT_FILTER:
11601 printf (_("Filter library"));
11602 break;
11603
b34976b6 11604 case DT_CONFIG:
019148e4
L
11605 printf (_("Configuration file"));
11606 break;
11607
11608 case DT_DEPAUDIT:
11609 printf (_("Dependency audit library"));
11610 break;
11611
11612 case DT_AUDIT:
11613 printf (_("Audit library"));
11614 break;
11615 }
252b5132 11616
84714f86 11617 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11618 printf (": [%s]\n",
84714f86 11619 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11620 else
f7a99963
NC
11621 {
11622 printf (": ");
11623 print_vma (entry->d_un.d_val, PREFIX_HEX);
11624 putchar ('\n');
11625 }
252b5132
RH
11626 }
11627 break;
11628
dcefbbbd 11629 case DT_FEATURE:
252b5132
RH
11630 if (do_dynamic)
11631 {
11632 printf (_("Flags:"));
86f55779 11633
252b5132
RH
11634 if (entry->d_un.d_val == 0)
11635 printf (_(" None\n"));
11636 else
11637 {
26c527e6 11638 uint64_t val = entry->d_un.d_val;
86f55779 11639
252b5132
RH
11640 if (val & DTF_1_PARINIT)
11641 {
11642 printf (" PARINIT");
11643 val ^= DTF_1_PARINIT;
11644 }
dcefbbbd
L
11645 if (val & DTF_1_CONFEXP)
11646 {
11647 printf (" CONFEXP");
11648 val ^= DTF_1_CONFEXP;
11649 }
252b5132 11650 if (val != 0)
26c527e6 11651 printf (" %" PRIx64, val);
252b5132
RH
11652 puts ("");
11653 }
11654 }
11655 break;
11656
11657 case DT_POSFLAG_1:
11658 if (do_dynamic)
11659 {
11660 printf (_("Flags:"));
86f55779 11661
252b5132
RH
11662 if (entry->d_un.d_val == 0)
11663 printf (_(" None\n"));
11664 else
11665 {
26c527e6 11666 uint64_t val = entry->d_un.d_val;
86f55779 11667
252b5132
RH
11668 if (val & DF_P1_LAZYLOAD)
11669 {
11670 printf (" LAZYLOAD");
11671 val ^= DF_P1_LAZYLOAD;
11672 }
11673 if (val & DF_P1_GROUPPERM)
11674 {
11675 printf (" GROUPPERM");
11676 val ^= DF_P1_GROUPPERM;
11677 }
11678 if (val != 0)
26c527e6 11679 printf (" %" PRIx64, val);
252b5132
RH
11680 puts ("");
11681 }
11682 }
11683 break;
11684
11685 case DT_FLAGS_1:
11686 if (do_dynamic)
11687 {
11688 printf (_("Flags:"));
11689 if (entry->d_un.d_val == 0)
11690 printf (_(" None\n"));
11691 else
11692 {
26c527e6 11693 uint64_t val = entry->d_un.d_val;
86f55779 11694
252b5132
RH
11695 if (val & DF_1_NOW)
11696 {
11697 printf (" NOW");
11698 val ^= DF_1_NOW;
11699 }
11700 if (val & DF_1_GLOBAL)
11701 {
11702 printf (" GLOBAL");
11703 val ^= DF_1_GLOBAL;
11704 }
11705 if (val & DF_1_GROUP)
11706 {
11707 printf (" GROUP");
11708 val ^= DF_1_GROUP;
11709 }
11710 if (val & DF_1_NODELETE)
11711 {
11712 printf (" NODELETE");
11713 val ^= DF_1_NODELETE;
11714 }
11715 if (val & DF_1_LOADFLTR)
11716 {
11717 printf (" LOADFLTR");
11718 val ^= DF_1_LOADFLTR;
11719 }
11720 if (val & DF_1_INITFIRST)
11721 {
11722 printf (" INITFIRST");
11723 val ^= DF_1_INITFIRST;
11724 }
11725 if (val & DF_1_NOOPEN)
11726 {
11727 printf (" NOOPEN");
11728 val ^= DF_1_NOOPEN;
11729 }
11730 if (val & DF_1_ORIGIN)
11731 {
11732 printf (" ORIGIN");
11733 val ^= DF_1_ORIGIN;
11734 }
11735 if (val & DF_1_DIRECT)
11736 {
11737 printf (" DIRECT");
11738 val ^= DF_1_DIRECT;
11739 }
11740 if (val & DF_1_TRANS)
11741 {
11742 printf (" TRANS");
11743 val ^= DF_1_TRANS;
11744 }
11745 if (val & DF_1_INTERPOSE)
11746 {
11747 printf (" INTERPOSE");
11748 val ^= DF_1_INTERPOSE;
11749 }
f7db6139 11750 if (val & DF_1_NODEFLIB)
dcefbbbd 11751 {
f7db6139
L
11752 printf (" NODEFLIB");
11753 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11754 }
11755 if (val & DF_1_NODUMP)
11756 {
11757 printf (" NODUMP");
11758 val ^= DF_1_NODUMP;
11759 }
34b60028 11760 if (val & DF_1_CONFALT)
dcefbbbd 11761 {
34b60028
L
11762 printf (" CONFALT");
11763 val ^= DF_1_CONFALT;
11764 }
11765 if (val & DF_1_ENDFILTEE)
11766 {
11767 printf (" ENDFILTEE");
11768 val ^= DF_1_ENDFILTEE;
11769 }
11770 if (val & DF_1_DISPRELDNE)
11771 {
11772 printf (" DISPRELDNE");
11773 val ^= DF_1_DISPRELDNE;
11774 }
11775 if (val & DF_1_DISPRELPND)
11776 {
11777 printf (" DISPRELPND");
11778 val ^= DF_1_DISPRELPND;
11779 }
11780 if (val & DF_1_NODIRECT)
11781 {
11782 printf (" NODIRECT");
11783 val ^= DF_1_NODIRECT;
11784 }
11785 if (val & DF_1_IGNMULDEF)
11786 {
11787 printf (" IGNMULDEF");
11788 val ^= DF_1_IGNMULDEF;
11789 }
11790 if (val & DF_1_NOKSYMS)
11791 {
11792 printf (" NOKSYMS");
11793 val ^= DF_1_NOKSYMS;
11794 }
11795 if (val & DF_1_NOHDR)
11796 {
11797 printf (" NOHDR");
11798 val ^= DF_1_NOHDR;
11799 }
11800 if (val & DF_1_EDITED)
11801 {
11802 printf (" EDITED");
11803 val ^= DF_1_EDITED;
11804 }
11805 if (val & DF_1_NORELOC)
11806 {
11807 printf (" NORELOC");
11808 val ^= DF_1_NORELOC;
11809 }
11810 if (val & DF_1_SYMINTPOSE)
11811 {
11812 printf (" SYMINTPOSE");
11813 val ^= DF_1_SYMINTPOSE;
11814 }
11815 if (val & DF_1_GLOBAUDIT)
11816 {
11817 printf (" GLOBAUDIT");
11818 val ^= DF_1_GLOBAUDIT;
11819 }
11820 if (val & DF_1_SINGLETON)
11821 {
11822 printf (" SINGLETON");
11823 val ^= DF_1_SINGLETON;
dcefbbbd 11824 }
5c383f02
RO
11825 if (val & DF_1_STUB)
11826 {
11827 printf (" STUB");
11828 val ^= DF_1_STUB;
11829 }
11830 if (val & DF_1_PIE)
11831 {
11832 printf (" PIE");
11833 val ^= DF_1_PIE;
11834 }
b1202ffa
L
11835 if (val & DF_1_KMOD)
11836 {
11837 printf (" KMOD");
11838 val ^= DF_1_KMOD;
11839 }
11840 if (val & DF_1_WEAKFILTER)
11841 {
11842 printf (" WEAKFILTER");
11843 val ^= DF_1_WEAKFILTER;
11844 }
11845 if (val & DF_1_NOCOMMON)
11846 {
11847 printf (" NOCOMMON");
11848 val ^= DF_1_NOCOMMON;
11849 }
252b5132 11850 if (val != 0)
26c527e6 11851 printf (" %" PRIx64, val);
252b5132
RH
11852 puts ("");
11853 }
11854 }
11855 break;
11856
11857 case DT_PLTREL:
978c4450 11858 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11859 if (do_dynamic)
dda8d76d 11860 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11861 break;
11862
11863 case DT_NULL :
11864 case DT_NEEDED :
11865 case DT_PLTGOT :
11866 case DT_HASH :
11867 case DT_STRTAB :
11868 case DT_SYMTAB :
11869 case DT_RELA :
11870 case DT_INIT :
11871 case DT_FINI :
11872 case DT_SONAME :
11873 case DT_RPATH :
11874 case DT_SYMBOLIC:
11875 case DT_REL :
a7fd1186 11876 case DT_RELR :
252b5132
RH
11877 case DT_DEBUG :
11878 case DT_TEXTREL :
11879 case DT_JMPREL :
019148e4 11880 case DT_RUNPATH :
978c4450 11881 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11882
11883 if (do_dynamic)
11884 {
84714f86 11885 const char *name;
252b5132 11886
84714f86
AM
11887 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11888 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11889 else
d79b3d50 11890 name = NULL;
252b5132
RH
11891
11892 if (name)
11893 {
11894 switch (entry->d_tag)
11895 {
11896 case DT_NEEDED:
11897 printf (_("Shared library: [%s]"), name);
11898
13acb58d
AM
11899 if (filedata->program_interpreter
11900 && streq (name, filedata->program_interpreter))
f7a99963 11901 printf (_(" program interpreter"));
252b5132
RH
11902 break;
11903
11904 case DT_SONAME:
f7a99963 11905 printf (_("Library soname: [%s]"), name);
252b5132
RH
11906 break;
11907
11908 case DT_RPATH:
f7a99963 11909 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11910 break;
11911
019148e4
L
11912 case DT_RUNPATH:
11913 printf (_("Library runpath: [%s]"), name);
11914 break;
11915
252b5132 11916 default:
f7a99963
NC
11917 print_vma (entry->d_un.d_val, PREFIX_HEX);
11918 break;
252b5132
RH
11919 }
11920 }
11921 else
f7a99963
NC
11922 print_vma (entry->d_un.d_val, PREFIX_HEX);
11923
11924 putchar ('\n');
252b5132
RH
11925 }
11926 break;
11927
11928 case DT_PLTRELSZ:
11929 case DT_RELASZ :
11930 case DT_STRSZ :
11931 case DT_RELSZ :
11932 case DT_RELAENT :
a7fd1186
FS
11933 case DT_RELRENT :
11934 case DT_RELRSZ :
252b5132
RH
11935 case DT_SYMENT :
11936 case DT_RELENT :
978c4450 11937 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11938 /* Fall through. */
252b5132
RH
11939 case DT_PLTPADSZ:
11940 case DT_MOVEENT :
11941 case DT_MOVESZ :
04d8355a 11942 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11943 case DT_INIT_ARRAYSZ:
11944 case DT_FINI_ARRAYSZ:
047b2264
JJ
11945 case DT_GNU_CONFLICTSZ:
11946 case DT_GNU_LIBLISTSZ:
252b5132 11947 if (do_dynamic)
f7a99963
NC
11948 {
11949 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11950 printf (_(" (bytes)\n"));
f7a99963 11951 }
252b5132
RH
11952 break;
11953
11954 case DT_VERDEFNUM:
11955 case DT_VERNEEDNUM:
11956 case DT_RELACOUNT:
11957 case DT_RELCOUNT:
11958 if (do_dynamic)
f7a99963
NC
11959 {
11960 print_vma (entry->d_un.d_val, UNSIGNED);
11961 putchar ('\n');
11962 }
252b5132
RH
11963 break;
11964
11965 case DT_SYMINSZ:
11966 case DT_SYMINENT:
11967 case DT_SYMINFO:
11968 case DT_USED:
11969 case DT_INIT_ARRAY:
11970 case DT_FINI_ARRAY:
11971 if (do_dynamic)
11972 {
d79b3d50 11973 if (entry->d_tag == DT_USED
84714f86 11974 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11975 {
84714f86
AM
11976 const char *name
11977 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11978
b34976b6 11979 if (*name)
252b5132
RH
11980 {
11981 printf (_("Not needed object: [%s]\n"), name);
11982 break;
11983 }
11984 }
103f02d3 11985
f7a99963
NC
11986 print_vma (entry->d_un.d_val, PREFIX_HEX);
11987 putchar ('\n');
252b5132
RH
11988 }
11989 break;
11990
11991 case DT_BIND_NOW:
11992 /* The value of this entry is ignored. */
35b1837e
AM
11993 if (do_dynamic)
11994 putchar ('\n');
252b5132 11995 break;
103f02d3 11996
047b2264
JJ
11997 case DT_GNU_PRELINKED:
11998 if (do_dynamic)
11999 {
2cf0635d 12000 struct tm * tmp;
91d6fa6a 12001 time_t atime = entry->d_un.d_val;
047b2264 12002
91d6fa6a 12003 tmp = gmtime (&atime);
071436c6
NC
12004 /* PR 17533 file: 041-1244816-0.004. */
12005 if (tmp == NULL)
26c527e6
AM
12006 printf (_("<corrupt time val: %" PRIx64),
12007 (uint64_t) atime);
071436c6
NC
12008 else
12009 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12010 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12011 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12012
12013 }
12014 break;
12015
fdc90cb4 12016 case DT_GNU_HASH:
978c4450 12017 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
12018 if (do_dynamic)
12019 {
12020 print_vma (entry->d_un.d_val, PREFIX_HEX);
12021 putchar ('\n');
12022 }
12023 break;
12024
a5da3dee
VDM
12025 case DT_GNU_FLAGS_1:
12026 if (do_dynamic)
12027 {
12028 printf (_("Flags:"));
12029 if (entry->d_un.d_val == 0)
12030 printf (_(" None\n"));
12031 else
12032 {
26c527e6 12033 uint64_t val = entry->d_un.d_val;
a5da3dee
VDM
12034
12035 if (val & DF_GNU_1_UNIQUE)
12036 {
12037 printf (" UNIQUE");
12038 val ^= DF_GNU_1_UNIQUE;
12039 }
12040 if (val != 0)
26c527e6 12041 printf (" %" PRIx64, val);
a5da3dee
VDM
12042 puts ("");
12043 }
12044 }
12045 break;
12046
252b5132
RH
12047 default:
12048 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
12049 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12050 = entry->d_un.d_val;
252b5132
RH
12051
12052 if (do_dynamic)
12053 {
dda8d76d 12054 switch (filedata->file_header.e_machine)
252b5132 12055 {
37c18eed
SD
12056 case EM_AARCH64:
12057 dynamic_section_aarch64_val (entry);
12058 break;
252b5132 12059 case EM_MIPS:
4fe85591 12060 case EM_MIPS_RS3_LE:
978c4450 12061 dynamic_section_mips_val (filedata, entry);
252b5132 12062 break;
103f02d3 12063 case EM_PARISC:
b2d38a17 12064 dynamic_section_parisc_val (entry);
103f02d3 12065 break;
ecc51f48 12066 case EM_IA_64:
b2d38a17 12067 dynamic_section_ia64_val (entry);
ecc51f48 12068 break;
252b5132 12069 default:
f7a99963
NC
12070 print_vma (entry->d_un.d_val, PREFIX_HEX);
12071 putchar ('\n');
252b5132
RH
12072 }
12073 }
12074 break;
12075 }
12076 }
12077
015dc7e1 12078 return true;
252b5132
RH
12079}
12080
12081static char *
d3ba0551 12082get_ver_flags (unsigned int flags)
252b5132 12083{
6d4f21f6 12084 static char buff[128];
252b5132
RH
12085
12086 buff[0] = 0;
12087
12088 if (flags == 0)
12089 return _("none");
12090
12091 if (flags & VER_FLG_BASE)
7bb1ad17 12092 strcat (buff, "BASE");
252b5132
RH
12093
12094 if (flags & VER_FLG_WEAK)
12095 {
12096 if (flags & VER_FLG_BASE)
7bb1ad17 12097 strcat (buff, " | ");
252b5132 12098
7bb1ad17 12099 strcat (buff, "WEAK");
252b5132
RH
12100 }
12101
44ec90b9
RO
12102 if (flags & VER_FLG_INFO)
12103 {
12104 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12105 strcat (buff, " | ");
44ec90b9 12106
7bb1ad17 12107 strcat (buff, "INFO");
44ec90b9
RO
12108 }
12109
12110 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12111 {
12112 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12113 strcat (buff, " | ");
12114
12115 strcat (buff, _("<unknown>"));
12116 }
252b5132
RH
12117
12118 return buff;
12119}
12120
12121/* Display the contents of the version sections. */
98fb390a 12122
015dc7e1 12123static bool
dda8d76d 12124process_version_sections (Filedata * filedata)
252b5132 12125{
2cf0635d 12126 Elf_Internal_Shdr * section;
b34976b6 12127 unsigned i;
015dc7e1 12128 bool found = false;
252b5132
RH
12129
12130 if (! do_version)
015dc7e1 12131 return true;
252b5132 12132
dda8d76d
NC
12133 for (i = 0, section = filedata->section_headers;
12134 i < filedata->file_header.e_shnum;
b34976b6 12135 i++, section++)
252b5132
RH
12136 {
12137 switch (section->sh_type)
12138 {
12139 case SHT_GNU_verdef:
12140 {
2cf0635d 12141 Elf_External_Verdef * edefs;
26c527e6
AM
12142 size_t idx;
12143 size_t cnt;
2cf0635d 12144 char * endbuf;
252b5132 12145
015dc7e1 12146 found = true;
252b5132 12147
ca0e11aa
NC
12148 if (filedata->is_separate)
12149 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12150 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12151 section->sh_info),
12152 filedata->file_name,
12153 printable_section_name (filedata, section),
12154 section->sh_info);
12155 else
12156 printf (ngettext ("\nVersion definition section '%s' "
12157 "contains %u entry:\n",
12158 "\nVersion definition section '%s' "
12159 "contains %u entries:\n",
12160 section->sh_info),
12161 printable_section_name (filedata, section),
12162 section->sh_info);
047c3dbf 12163
625d49fc 12164 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12165 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12166 section->sh_offset, section->sh_link,
dda8d76d 12167 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12168
3f5e193b 12169 edefs = (Elf_External_Verdef *)
dda8d76d 12170 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12171 _("version definition section"));
a6e9f9df
AM
12172 if (!edefs)
12173 break;
59245841 12174 endbuf = (char *) edefs + section->sh_size;
252b5132 12175
1445030f 12176 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12177 {
2cf0635d
NC
12178 char * vstart;
12179 Elf_External_Verdef * edef;
b34976b6 12180 Elf_Internal_Verdef ent;
2cf0635d 12181 Elf_External_Verdaux * eaux;
b34976b6 12182 Elf_Internal_Verdaux aux;
26c527e6 12183 size_t isum;
b34976b6 12184 int j;
103f02d3 12185
252b5132 12186 vstart = ((char *) edefs) + idx;
54806181
AM
12187 if (vstart + sizeof (*edef) > endbuf)
12188 break;
252b5132
RH
12189
12190 edef = (Elf_External_Verdef *) vstart;
12191
12192 ent.vd_version = BYTE_GET (edef->vd_version);
12193 ent.vd_flags = BYTE_GET (edef->vd_flags);
12194 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12195 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12196 ent.vd_hash = BYTE_GET (edef->vd_hash);
12197 ent.vd_aux = BYTE_GET (edef->vd_aux);
12198 ent.vd_next = BYTE_GET (edef->vd_next);
12199
26c527e6 12200 printf (_(" %#06zx: Rev: %d Flags: %s"),
252b5132
RH
12201 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12202
12203 printf (_(" Index: %d Cnt: %d "),
12204 ent.vd_ndx, ent.vd_cnt);
12205
452bf675 12206 /* Check for overflow. */
1445030f 12207 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12208 break;
12209
252b5132
RH
12210 vstart += ent.vd_aux;
12211
1445030f
AM
12212 if (vstart + sizeof (*eaux) > endbuf)
12213 break;
252b5132
RH
12214 eaux = (Elf_External_Verdaux *) vstart;
12215
12216 aux.vda_name = BYTE_GET (eaux->vda_name);
12217 aux.vda_next = BYTE_GET (eaux->vda_next);
12218
84714f86 12219 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12220 printf (_("Name: %s\n"),
84714f86 12221 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12222 else
12223 printf (_("Name index: %ld\n"), aux.vda_name);
12224
12225 isum = idx + ent.vd_aux;
12226
b34976b6 12227 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12228 {
1445030f
AM
12229 if (aux.vda_next < sizeof (*eaux)
12230 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12231 {
12232 warn (_("Invalid vda_next field of %lx\n"),
12233 aux.vda_next);
12234 j = ent.vd_cnt;
12235 break;
12236 }
dd24e3da 12237 /* Check for overflow. */
7e26601c 12238 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12239 break;
12240
252b5132
RH
12241 isum += aux.vda_next;
12242 vstart += aux.vda_next;
12243
54806181
AM
12244 if (vstart + sizeof (*eaux) > endbuf)
12245 break;
1445030f 12246 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12247
12248 aux.vda_name = BYTE_GET (eaux->vda_name);
12249 aux.vda_next = BYTE_GET (eaux->vda_next);
12250
84714f86 12251 if (valid_dynamic_name (filedata, aux.vda_name))
26c527e6 12252 printf (_(" %#06zx: Parent %d: %s\n"),
978c4450 12253 isum, j,
84714f86 12254 get_dynamic_name (filedata, aux.vda_name));
252b5132 12255 else
26c527e6 12256 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
252b5132
RH
12257 isum, j, aux.vda_name);
12258 }
dd24e3da 12259
54806181
AM
12260 if (j < ent.vd_cnt)
12261 printf (_(" Version def aux past end of section\n"));
252b5132 12262
c9f02c3e
MR
12263 /* PR 17531:
12264 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12265 if (ent.vd_next < sizeof (*edef)
12266 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12267 {
12268 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12269 cnt = section->sh_info;
12270 break;
12271 }
452bf675 12272 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12273 break;
12274
252b5132
RH
12275 idx += ent.vd_next;
12276 }
dd24e3da 12277
54806181
AM
12278 if (cnt < section->sh_info)
12279 printf (_(" Version definition past end of section\n"));
252b5132
RH
12280
12281 free (edefs);
12282 }
12283 break;
103f02d3 12284
252b5132
RH
12285 case SHT_GNU_verneed:
12286 {
2cf0635d 12287 Elf_External_Verneed * eneed;
26c527e6
AM
12288 size_t idx;
12289 size_t cnt;
2cf0635d 12290 char * endbuf;
252b5132 12291
015dc7e1 12292 found = true;
252b5132 12293
ca0e11aa
NC
12294 if (filedata->is_separate)
12295 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12296 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12297 section->sh_info),
12298 filedata->file_name,
12299 printable_section_name (filedata, section),
12300 section->sh_info);
12301 else
12302 printf (ngettext ("\nVersion needs section '%s' "
12303 "contains %u entry:\n",
12304 "\nVersion needs section '%s' "
12305 "contains %u entries:\n",
12306 section->sh_info),
12307 printable_section_name (filedata, section),
12308 section->sh_info);
047c3dbf 12309
625d49fc 12310 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12311 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12312 section->sh_offset, section->sh_link,
dda8d76d 12313 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12314
dda8d76d 12315 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12316 section->sh_offset, 1,
12317 section->sh_size,
9cf03b7e 12318 _("Version Needs section"));
a6e9f9df
AM
12319 if (!eneed)
12320 break;
59245841 12321 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12322
12323 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12324 {
2cf0635d 12325 Elf_External_Verneed * entry;
b34976b6 12326 Elf_Internal_Verneed ent;
26c527e6 12327 size_t isum;
b34976b6 12328 int j;
2cf0635d 12329 char * vstart;
252b5132
RH
12330
12331 vstart = ((char *) eneed) + idx;
54806181
AM
12332 if (vstart + sizeof (*entry) > endbuf)
12333 break;
252b5132
RH
12334
12335 entry = (Elf_External_Verneed *) vstart;
12336
12337 ent.vn_version = BYTE_GET (entry->vn_version);
12338 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12339 ent.vn_file = BYTE_GET (entry->vn_file);
12340 ent.vn_aux = BYTE_GET (entry->vn_aux);
12341 ent.vn_next = BYTE_GET (entry->vn_next);
12342
26c527e6 12343 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
252b5132 12344
84714f86 12345 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12346 printf (_(" File: %s"),
84714f86 12347 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12348 else
12349 printf (_(" File: %lx"), ent.vn_file);
12350
12351 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12352
dd24e3da 12353 /* Check for overflow. */
7e26601c 12354 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12355 break;
252b5132
RH
12356 vstart += ent.vn_aux;
12357
12358 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12359 {
2cf0635d 12360 Elf_External_Vernaux * eaux;
b34976b6 12361 Elf_Internal_Vernaux aux;
252b5132 12362
54806181
AM
12363 if (vstart + sizeof (*eaux) > endbuf)
12364 break;
252b5132
RH
12365 eaux = (Elf_External_Vernaux *) vstart;
12366
12367 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12368 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12369 aux.vna_other = BYTE_GET (eaux->vna_other);
12370 aux.vna_name = BYTE_GET (eaux->vna_name);
12371 aux.vna_next = BYTE_GET (eaux->vna_next);
12372
84714f86 12373 if (valid_dynamic_name (filedata, aux.vna_name))
26c527e6 12374 printf (_(" %#06zx: Name: %s"),
84714f86 12375 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12376 else
26c527e6 12377 printf (_(" %#06zx: Name index: %lx"),
252b5132
RH
12378 isum, aux.vna_name);
12379
12380 printf (_(" Flags: %s Version: %d\n"),
12381 get_ver_flags (aux.vna_flags), aux.vna_other);
12382
1445030f
AM
12383 if (aux.vna_next < sizeof (*eaux)
12384 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12385 {
12386 warn (_("Invalid vna_next field of %lx\n"),
12387 aux.vna_next);
12388 j = ent.vn_cnt;
12389 break;
12390 }
1445030f
AM
12391 /* Check for overflow. */
12392 if (aux.vna_next > (size_t) (endbuf - vstart))
12393 break;
252b5132
RH
12394 isum += aux.vna_next;
12395 vstart += aux.vna_next;
12396 }
9cf03b7e 12397
54806181 12398 if (j < ent.vn_cnt)
f9a6a8f0 12399 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12400
1445030f
AM
12401 if (ent.vn_next < sizeof (*entry)
12402 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12403 {
452bf675 12404 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12405 cnt = section->sh_info;
12406 break;
12407 }
1445030f
AM
12408 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12409 break;
252b5132
RH
12410 idx += ent.vn_next;
12411 }
9cf03b7e 12412
54806181 12413 if (cnt < section->sh_info)
9cf03b7e 12414 warn (_("Missing Version Needs information\n"));
103f02d3 12415
252b5132
RH
12416 free (eneed);
12417 }
12418 break;
12419
12420 case SHT_GNU_versym:
12421 {
2cf0635d 12422 Elf_Internal_Shdr * link_section;
26c527e6 12423 uint64_t total;
8b73c356 12424 unsigned int cnt;
2cf0635d
NC
12425 unsigned char * edata;
12426 unsigned short * data;
12427 char * strtab;
12428 Elf_Internal_Sym * symbols;
12429 Elf_Internal_Shdr * string_sec;
26c527e6
AM
12430 uint64_t num_syms;
12431 uint64_t off;
252b5132 12432
dda8d76d 12433 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12434 break;
12435
dda8d76d 12436 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12437 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12438
dda8d76d 12439 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12440 break;
12441
015dc7e1 12442 found = true;
252b5132 12443
4de91c10 12444 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12445 if (symbols == NULL)
12446 break;
252b5132 12447
dda8d76d 12448 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12449
dda8d76d 12450 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12451 string_sec->sh_size,
12452 _("version string table"));
a6e9f9df 12453 if (!strtab)
0429c154
MS
12454 {
12455 free (symbols);
12456 break;
12457 }
252b5132 12458
ca0e11aa 12459 if (filedata->is_separate)
26c527e6
AM
12460 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
12461 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12462 total),
12463 filedata->file_name,
12464 printable_section_name (filedata, section),
26c527e6 12465 total);
ca0e11aa
NC
12466 else
12467 printf (ngettext ("\nVersion symbols section '%s' "
26c527e6 12468 "contains %" PRIu64 " entry:\n",
ca0e11aa 12469 "\nVersion symbols section '%s' "
26c527e6 12470 "contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12471 total),
12472 printable_section_name (filedata, section),
26c527e6 12473 total);
252b5132 12474
625d49fc 12475 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12476 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12477 section->sh_offset, section->sh_link,
dda8d76d 12478 printable_section_name (filedata, link_section));
252b5132 12479
dda8d76d 12480 off = offset_from_vma (filedata,
978c4450 12481 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12482 total * sizeof (short));
95099889
AM
12483 edata = (unsigned char *) get_data (NULL, filedata, off,
12484 sizeof (short), total,
12485 _("version symbol data"));
a6e9f9df
AM
12486 if (!edata)
12487 {
12488 free (strtab);
0429c154 12489 free (symbols);
a6e9f9df
AM
12490 break;
12491 }
252b5132 12492
3f5e193b 12493 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12494
12495 for (cnt = total; cnt --;)
b34976b6
AM
12496 data[cnt] = byte_get (edata + cnt * sizeof (short),
12497 sizeof (short));
252b5132
RH
12498
12499 free (edata);
12500
12501 for (cnt = 0; cnt < total; cnt += 4)
12502 {
12503 int j, nn;
ab273396
AM
12504 char *name;
12505 char *invalid = _("*invalid*");
252b5132
RH
12506
12507 printf (" %03x:", cnt);
12508
12509 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12510 switch (data[cnt + j])
252b5132
RH
12511 {
12512 case 0:
12513 fputs (_(" 0 (*local*) "), stdout);
12514 break;
12515
12516 case 1:
12517 fputs (_(" 1 (*global*) "), stdout);
12518 break;
12519
12520 default:
c244d050
NC
12521 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12522 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12523
dd24e3da 12524 /* If this index value is greater than the size of the symbols
ba5cdace 12525 array, break to avoid an out-of-bounds read. */
26c527e6 12526 if (cnt + j >= num_syms)
dd24e3da
NC
12527 {
12528 warn (_("invalid index into symbol array\n"));
12529 break;
12530 }
12531
ab273396 12532 name = NULL;
978c4450 12533 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12534 {
b34976b6 12535 Elf_Internal_Verneed ivn;
26c527e6 12536 uint64_t offset;
252b5132 12537
d93f0186 12538 offset = offset_from_vma
978c4450
AM
12539 (filedata,
12540 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12541 sizeof (Elf_External_Verneed));
252b5132 12542
b34976b6 12543 do
252b5132 12544 {
b34976b6
AM
12545 Elf_Internal_Vernaux ivna;
12546 Elf_External_Verneed evn;
12547 Elf_External_Vernaux evna;
26c527e6 12548 uint64_t a_off;
252b5132 12549
dda8d76d 12550 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12551 _("version need")) == NULL)
12552 break;
0b4362b0 12553
252b5132
RH
12554 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12555 ivn.vn_next = BYTE_GET (evn.vn_next);
12556
12557 a_off = offset + ivn.vn_aux;
12558
12559 do
12560 {
dda8d76d 12561 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12562 1, _("version need aux (2)")) == NULL)
12563 {
12564 ivna.vna_next = 0;
12565 ivna.vna_other = 0;
12566 }
12567 else
12568 {
12569 ivna.vna_next = BYTE_GET (evna.vna_next);
12570 ivna.vna_other = BYTE_GET (evna.vna_other);
12571 }
252b5132
RH
12572
12573 a_off += ivna.vna_next;
12574 }
b34976b6 12575 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12576 && ivna.vna_next != 0);
12577
b34976b6 12578 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12579 {
12580 ivna.vna_name = BYTE_GET (evna.vna_name);
12581
54806181 12582 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12583 name = invalid;
54806181
AM
12584 else
12585 name = strtab + ivna.vna_name;
252b5132
RH
12586 break;
12587 }
12588
12589 offset += ivn.vn_next;
12590 }
12591 while (ivn.vn_next);
12592 }
00d93f34 12593
ab273396 12594 if (data[cnt + j] != 0x8001
978c4450 12595 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12596 {
b34976b6
AM
12597 Elf_Internal_Verdef ivd;
12598 Elf_External_Verdef evd;
26c527e6 12599 uint64_t offset;
252b5132 12600
d93f0186 12601 offset = offset_from_vma
978c4450
AM
12602 (filedata,
12603 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12604 sizeof evd);
252b5132
RH
12605
12606 do
12607 {
dda8d76d 12608 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12609 _("version def")) == NULL)
12610 {
12611 ivd.vd_next = 0;
948f632f 12612 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12613 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12614 break;
59245841
NC
12615 }
12616 else
12617 {
12618 ivd.vd_next = BYTE_GET (evd.vd_next);
12619 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12620 }
252b5132
RH
12621
12622 offset += ivd.vd_next;
12623 }
c244d050 12624 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12625 && ivd.vd_next != 0);
12626
c244d050 12627 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12628 {
b34976b6
AM
12629 Elf_External_Verdaux evda;
12630 Elf_Internal_Verdaux ivda;
252b5132
RH
12631
12632 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12633
dda8d76d 12634 if (get_data (&evda, filedata,
59245841
NC
12635 offset - ivd.vd_next + ivd.vd_aux,
12636 sizeof (evda), 1,
12637 _("version def aux")) == NULL)
12638 break;
252b5132
RH
12639
12640 ivda.vda_name = BYTE_GET (evda.vda_name);
12641
54806181 12642 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12643 name = invalid;
12644 else if (name != NULL && name != invalid)
12645 name = _("*both*");
54806181
AM
12646 else
12647 name = strtab + ivda.vda_name;
252b5132
RH
12648 }
12649 }
ab273396
AM
12650 if (name != NULL)
12651 nn += printf ("(%s%-*s",
12652 name,
12653 12 - (int) strlen (name),
12654 ")");
252b5132
RH
12655
12656 if (nn < 18)
12657 printf ("%*c", 18 - nn, ' ');
12658 }
12659
12660 putchar ('\n');
12661 }
12662
12663 free (data);
12664 free (strtab);
12665 free (symbols);
12666 }
12667 break;
103f02d3 12668
252b5132
RH
12669 default:
12670 break;
12671 }
12672 }
12673
12674 if (! found)
ca0e11aa
NC
12675 {
12676 if (filedata->is_separate)
12677 printf (_("\nNo version information found in linked file '%s'.\n"),
12678 filedata->file_name);
12679 else
12680 printf (_("\nNo version information found in this file.\n"));
12681 }
252b5132 12682
015dc7e1 12683 return true;
252b5132
RH
12684}
12685
d1133906 12686static const char *
dda8d76d 12687get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12688{
89246a0e 12689 static char buff[64];
252b5132
RH
12690
12691 switch (binding)
12692 {
b34976b6
AM
12693 case STB_LOCAL: return "LOCAL";
12694 case STB_GLOBAL: return "GLOBAL";
12695 case STB_WEAK: return "WEAK";
252b5132
RH
12696 default:
12697 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12698 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12699 binding);
252b5132 12700 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12701 {
12702 if (binding == STB_GNU_UNIQUE
df3a023b 12703 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12704 return "UNIQUE";
12705 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12706 }
252b5132 12707 else
e9e44622 12708 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12709 return buff;
12710 }
12711}
12712
d1133906 12713static const char *
dda8d76d 12714get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12715{
89246a0e 12716 static char buff[64];
252b5132
RH
12717
12718 switch (type)
12719 {
b34976b6
AM
12720 case STT_NOTYPE: return "NOTYPE";
12721 case STT_OBJECT: return "OBJECT";
12722 case STT_FUNC: return "FUNC";
12723 case STT_SECTION: return "SECTION";
12724 case STT_FILE: return "FILE";
12725 case STT_COMMON: return "COMMON";
12726 case STT_TLS: return "TLS";
15ab5209
DB
12727 case STT_RELC: return "RELC";
12728 case STT_SRELC: return "SRELC";
252b5132
RH
12729 default:
12730 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12731 {
dda8d76d 12732 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12733 return "THUMB_FUNC";
103f02d3 12734
dda8d76d 12735 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12736 return "REGISTER";
12737
dda8d76d 12738 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12739 return "PARISC_MILLI";
12740
e9e44622 12741 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12742 }
252b5132 12743 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12744 {
dda8d76d 12745 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12746 {
12747 if (type == STT_HP_OPAQUE)
12748 return "HP_OPAQUE";
12749 if (type == STT_HP_STUB)
12750 return "HP_STUB";
12751 }
12752
8654c01f
ML
12753 if (type == STT_GNU_IFUNC
12754 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
12755 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
12756 return "IFUNC";
12757
e9e44622 12758 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12759 }
252b5132 12760 else
e9e44622 12761 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12762 return buff;
12763 }
12764}
12765
d1133906 12766static const char *
d3ba0551 12767get_symbol_visibility (unsigned int visibility)
d1133906
NC
12768{
12769 switch (visibility)
12770 {
b34976b6
AM
12771 case STV_DEFAULT: return "DEFAULT";
12772 case STV_INTERNAL: return "INTERNAL";
12773 case STV_HIDDEN: return "HIDDEN";
d1133906 12774 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12775 default:
27a45f42 12776 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12777 return _("<unknown>");
d1133906
NC
12778 }
12779}
12780
2057d69d
CZ
12781static const char *
12782get_alpha_symbol_other (unsigned int other)
9abca702 12783{
2057d69d
CZ
12784 switch (other)
12785 {
12786 case STO_ALPHA_NOPV: return "NOPV";
12787 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12788 default:
27a45f42 12789 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12790 return _("<unknown>");
9abca702 12791 }
2057d69d
CZ
12792}
12793
fd85a6a1
NC
12794static const char *
12795get_solaris_symbol_visibility (unsigned int visibility)
12796{
12797 switch (visibility)
12798 {
12799 case 4: return "EXPORTED";
12800 case 5: return "SINGLETON";
12801 case 6: return "ELIMINATE";
12802 default: return get_symbol_visibility (visibility);
12803 }
12804}
12805
2301ed1c
SN
12806static const char *
12807get_aarch64_symbol_other (unsigned int other)
12808{
12809 static char buf[32];
12810
12811 if (other & STO_AARCH64_VARIANT_PCS)
12812 {
12813 other &= ~STO_AARCH64_VARIANT_PCS;
12814 if (other == 0)
12815 return "VARIANT_PCS";
12816 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12817 return buf;
12818 }
12819 return NULL;
12820}
12821
5e2b0d47
NC
12822static const char *
12823get_mips_symbol_other (unsigned int other)
12824{
12825 switch (other)
12826 {
32ec8896
NC
12827 case STO_OPTIONAL: return "OPTIONAL";
12828 case STO_MIPS_PLT: return "MIPS PLT";
12829 case STO_MIPS_PIC: return "MIPS PIC";
12830 case STO_MICROMIPS: return "MICROMIPS";
12831 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12832 case STO_MIPS16: return "MIPS16";
12833 default: return NULL;
5e2b0d47
NC
12834 }
12835}
12836
28f997cf 12837static const char *
dda8d76d 12838get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12839{
dda8d76d 12840 if (is_ia64_vms (filedata))
28f997cf
TG
12841 {
12842 static char res[32];
12843
12844 res[0] = 0;
12845
12846 /* Function types is for images and .STB files only. */
dda8d76d 12847 switch (filedata->file_header.e_type)
28f997cf
TG
12848 {
12849 case ET_DYN:
12850 case ET_EXEC:
12851 switch (VMS_ST_FUNC_TYPE (other))
12852 {
12853 case VMS_SFT_CODE_ADDR:
12854 strcat (res, " CA");
12855 break;
12856 case VMS_SFT_SYMV_IDX:
12857 strcat (res, " VEC");
12858 break;
12859 case VMS_SFT_FD:
12860 strcat (res, " FD");
12861 break;
12862 case VMS_SFT_RESERVE:
12863 strcat (res, " RSV");
12864 break;
12865 default:
bee0ee85
NC
12866 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12867 VMS_ST_FUNC_TYPE (other));
12868 strcat (res, " <unknown>");
12869 break;
28f997cf
TG
12870 }
12871 break;
12872 default:
12873 break;
12874 }
12875 switch (VMS_ST_LINKAGE (other))
12876 {
12877 case VMS_STL_IGNORE:
12878 strcat (res, " IGN");
12879 break;
12880 case VMS_STL_RESERVE:
12881 strcat (res, " RSV");
12882 break;
12883 case VMS_STL_STD:
12884 strcat (res, " STD");
12885 break;
12886 case VMS_STL_LNK:
12887 strcat (res, " LNK");
12888 break;
12889 default:
bee0ee85
NC
12890 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12891 VMS_ST_LINKAGE (other));
12892 strcat (res, " <unknown>");
12893 break;
28f997cf
TG
12894 }
12895
12896 if (res[0] != 0)
12897 return res + 1;
12898 else
12899 return res;
12900 }
12901 return NULL;
12902}
12903
6911b7dc
AM
12904static const char *
12905get_ppc64_symbol_other (unsigned int other)
12906{
14732552
AM
12907 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12908 return NULL;
12909
12910 other >>= STO_PPC64_LOCAL_BIT;
12911 if (other <= 6)
6911b7dc 12912 {
89246a0e 12913 static char buf[64];
14732552
AM
12914 if (other >= 2)
12915 other = ppc64_decode_local_entry (other);
12916 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12917 return buf;
12918 }
12919 return NULL;
12920}
12921
8155b853
NC
12922static const char *
12923get_riscv_symbol_other (unsigned int other)
12924{
12925 static char buf[32];
12926 buf[0] = 0;
12927
12928 if (other & STO_RISCV_VARIANT_CC)
12929 {
12930 strcat (buf, _(" VARIANT_CC"));
12931 other &= ~STO_RISCV_VARIANT_CC;
12932 }
12933
12934 if (other != 0)
12935 snprintf (buf, sizeof buf, " %x", other);
12936
12937
12938 if (buf[0] != 0)
12939 return buf + 1;
12940 else
12941 return buf;
12942}
12943
5e2b0d47 12944static const char *
dda8d76d 12945get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12946{
12947 const char * result = NULL;
89246a0e 12948 static char buff [64];
5e2b0d47
NC
12949
12950 if (other == 0)
12951 return "";
12952
dda8d76d 12953 switch (filedata->file_header.e_machine)
5e2b0d47 12954 {
2057d69d
CZ
12955 case EM_ALPHA:
12956 result = get_alpha_symbol_other (other);
12957 break;
2301ed1c
SN
12958 case EM_AARCH64:
12959 result = get_aarch64_symbol_other (other);
12960 break;
5e2b0d47
NC
12961 case EM_MIPS:
12962 result = get_mips_symbol_other (other);
28f997cf
TG
12963 break;
12964 case EM_IA_64:
dda8d76d 12965 result = get_ia64_symbol_other (filedata, other);
28f997cf 12966 break;
6911b7dc
AM
12967 case EM_PPC64:
12968 result = get_ppc64_symbol_other (other);
12969 break;
8155b853
NC
12970 case EM_RISCV:
12971 result = get_riscv_symbol_other (other);
12972 break;
5e2b0d47 12973 default:
fd85a6a1 12974 result = NULL;
5e2b0d47
NC
12975 break;
12976 }
12977
12978 if (result)
12979 return result;
12980
12981 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12982 return buff;
12983}
12984
d1133906 12985static const char *
dda8d76d 12986get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12987{
b34976b6 12988 static char buff[32];
5cf1065c 12989
252b5132
RH
12990 switch (type)
12991 {
b34976b6
AM
12992 case SHN_UNDEF: return "UND";
12993 case SHN_ABS: return "ABS";
12994 case SHN_COMMON: return "COM";
252b5132 12995 default:
9ce701e2 12996 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12997 && filedata->file_header.e_machine == EM_IA_64
12998 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12999 return "ANSI_COM";
13000 else if ((filedata->file_header.e_machine == EM_X86_64
13001 || filedata->file_header.e_machine == EM_L1OM
13002 || filedata->file_header.e_machine == EM_K1OM)
13003 && type == SHN_X86_64_LCOMMON)
13004 return "LARGE_COM";
13005 else if ((type == SHN_MIPS_SCOMMON
13006 && filedata->file_header.e_machine == EM_MIPS)
13007 || (type == SHN_TIC6X_SCOMMON
13008 && filedata->file_header.e_machine == EM_TI_C6000))
13009 return "SCOM";
13010 else if (type == SHN_MIPS_SUNDEFINED
13011 && filedata->file_header.e_machine == EM_MIPS)
13012 return "SUND";
13013 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
13014 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
13015 else if (type >= SHN_LOOS && type <= SHN_HIOS)
13016 sprintf (buff, "OS [0x%04x]", type & 0xffff);
13017 else if (type >= SHN_LORESERVE)
13018 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
13019 else if (filedata->file_header.e_shnum != 0
13020 && type >= filedata->file_header.e_shnum)
13021 sprintf (buff, _("bad section index[%3d]"), type);
13022 else
13023 sprintf (buff, "%3d", type);
13024 break;
fd85a6a1
NC
13025 }
13026
10ca4b04 13027 return buff;
6bd1a22c
L
13028}
13029
bb4d2ac2 13030static const char *
26c527e6
AM
13031get_symbol_version_string (Filedata *filedata,
13032 bool is_dynsym,
13033 const char *strtab,
13034 size_t strtab_size,
13035 unsigned int si,
13036 Elf_Internal_Sym *psym,
13037 enum versioned_symbol_info *sym_info,
13038 unsigned short *vna_other)
bb4d2ac2 13039{
ab273396
AM
13040 unsigned char data[2];
13041 unsigned short vers_data;
26c527e6 13042 uint64_t offset;
7a815dd5 13043 unsigned short max_vd_ndx;
bb4d2ac2 13044
ab273396 13045 if (!is_dynsym
978c4450 13046 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 13047 return NULL;
bb4d2ac2 13048
978c4450
AM
13049 offset = offset_from_vma (filedata,
13050 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 13051 sizeof data + si * sizeof (vers_data));
bb4d2ac2 13052
dda8d76d 13053 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
13054 sizeof (data), 1, _("version data")) == NULL)
13055 return NULL;
13056
13057 vers_data = byte_get (data, 2);
bb4d2ac2 13058
1f6f5dba 13059 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 13060 return NULL;
bb4d2ac2 13061
0b8b7609 13062 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
13063 max_vd_ndx = 0;
13064
ab273396
AM
13065 /* Usually we'd only see verdef for defined symbols, and verneed for
13066 undefined symbols. However, symbols defined by the linker in
13067 .dynbss for variables copied from a shared library in order to
13068 avoid text relocations are defined yet have verneed. We could
13069 use a heuristic to detect the special case, for example, check
13070 for verneed first on symbols defined in SHT_NOBITS sections, but
13071 it is simpler and more reliable to just look for both verdef and
13072 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13073
ab273396
AM
13074 if (psym->st_shndx != SHN_UNDEF
13075 && vers_data != 0x8001
978c4450 13076 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13077 {
13078 Elf_Internal_Verdef ivd;
13079 Elf_Internal_Verdaux ivda;
13080 Elf_External_Verdaux evda;
26c527e6 13081 uint64_t off;
bb4d2ac2 13082
dda8d76d 13083 off = offset_from_vma (filedata,
978c4450 13084 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13085 sizeof (Elf_External_Verdef));
13086
13087 do
bb4d2ac2 13088 {
ab273396
AM
13089 Elf_External_Verdef evd;
13090
dda8d76d 13091 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13092 _("version def")) == NULL)
13093 {
13094 ivd.vd_ndx = 0;
13095 ivd.vd_aux = 0;
13096 ivd.vd_next = 0;
1f6f5dba 13097 ivd.vd_flags = 0;
ab273396
AM
13098 }
13099 else
bb4d2ac2 13100 {
ab273396
AM
13101 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13102 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13103 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13104 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13105 }
bb4d2ac2 13106
7a815dd5
L
13107 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13108 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13109
ab273396
AM
13110 off += ivd.vd_next;
13111 }
13112 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13113
ab273396
AM
13114 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13115 {
9abca702 13116 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13117 return NULL;
13118
ab273396
AM
13119 off -= ivd.vd_next;
13120 off += ivd.vd_aux;
bb4d2ac2 13121
dda8d76d 13122 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13123 _("version def aux")) != NULL)
13124 {
13125 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13126
ab273396 13127 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13128 return (ivda.vda_name < strtab_size
13129 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13130 }
13131 }
13132 }
bb4d2ac2 13133
978c4450 13134 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13135 {
13136 Elf_External_Verneed evn;
13137 Elf_Internal_Verneed ivn;
13138 Elf_Internal_Vernaux ivna;
bb4d2ac2 13139
dda8d76d 13140 offset = offset_from_vma (filedata,
978c4450 13141 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13142 sizeof evn);
13143 do
13144 {
26c527e6 13145 uint64_t vna_off;
bb4d2ac2 13146
dda8d76d 13147 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13148 _("version need")) == NULL)
13149 {
13150 ivna.vna_next = 0;
13151 ivna.vna_other = 0;
13152 ivna.vna_name = 0;
13153 break;
13154 }
bb4d2ac2 13155
ab273396
AM
13156 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13157 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13158
ab273396 13159 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13160
ab273396
AM
13161 do
13162 {
13163 Elf_External_Vernaux evna;
bb4d2ac2 13164
dda8d76d 13165 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13166 _("version need aux (3)")) == NULL)
bb4d2ac2 13167 {
ab273396
AM
13168 ivna.vna_next = 0;
13169 ivna.vna_other = 0;
13170 ivna.vna_name = 0;
bb4d2ac2 13171 }
bb4d2ac2 13172 else
bb4d2ac2 13173 {
ab273396
AM
13174 ivna.vna_other = BYTE_GET (evna.vna_other);
13175 ivna.vna_next = BYTE_GET (evna.vna_next);
13176 ivna.vna_name = BYTE_GET (evna.vna_name);
13177 }
bb4d2ac2 13178
ab273396
AM
13179 vna_off += ivna.vna_next;
13180 }
13181 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13182
ab273396
AM
13183 if (ivna.vna_other == vers_data)
13184 break;
bb4d2ac2 13185
ab273396
AM
13186 offset += ivn.vn_next;
13187 }
13188 while (ivn.vn_next != 0);
bb4d2ac2 13189
ab273396
AM
13190 if (ivna.vna_other == vers_data)
13191 {
13192 *sym_info = symbol_undefined;
13193 *vna_other = ivna.vna_other;
13194 return (ivna.vna_name < strtab_size
13195 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13196 }
7a815dd5
L
13197 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13198 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13199 return _("<corrupt>");
bb4d2ac2 13200 }
ab273396 13201 return NULL;
bb4d2ac2
L
13202}
13203
047c3dbf
NL
13204/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13205
13206static unsigned int
625d49fc 13207print_dynamic_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13208{
13209 switch (base)
13210 {
13211 case 8:
13212 return print_vma (vma, OCTAL_5);
13213
13214 case 10:
13215 return print_vma (vma, UNSIGNED_5);
13216
13217 case 16:
13218 return print_vma (vma, PREFIX_HEX_5);
13219
13220 case 0:
13221 default:
13222 return print_vma (vma, DEC_5);
13223 }
13224}
13225
10ca4b04 13226static void
26c527e6 13227print_dynamic_symbol (Filedata *filedata, uint64_t si,
10ca4b04
L
13228 Elf_Internal_Sym *symtab,
13229 Elf_Internal_Shdr *section,
13230 char *strtab, size_t strtab_size)
252b5132 13231{
10ca4b04
L
13232 const char *version_string;
13233 enum versioned_symbol_info sym_info;
13234 unsigned short vna_other;
23356397
NC
13235 bool is_valid;
13236 const char * sstr;
10ca4b04 13237 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13238
26c527e6 13239 printf ("%6" PRId64 ": ", si);
10ca4b04
L
13240 print_vma (psym->st_value, LONG_HEX);
13241 putchar (' ');
047c3dbf 13242 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13243 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13244 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13245 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13246 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13247 else
252b5132 13248 {
10ca4b04 13249 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13250
10ca4b04
L
13251 printf (" %-7s", get_symbol_visibility (vis));
13252 /* Check to see if any other bits in the st_other field are set.
13253 Note - displaying this information disrupts the layout of the
13254 table being generated, but for the moment this case is very rare. */
13255 if (psym->st_other ^ vis)
13256 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13257 }
10ca4b04 13258 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13259
23356397
NC
13260 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13261 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13262 && filedata->section_headers != NULL
23356397
NC
13263 && psym->st_name == 0)
13264 {
84714f86
AM
13265 is_valid
13266 = section_name_valid (filedata,
13267 filedata->section_headers + psym->st_shndx);
23356397 13268 sstr = is_valid ?
84714f86
AM
13269 section_name_print (filedata,
13270 filedata->section_headers + psym->st_shndx)
23356397
NC
13271 : _("<corrupt>");
13272 }
13273 else
13274 {
84714f86 13275 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13276 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13277 }
10ca4b04
L
13278
13279 version_string
13280 = get_symbol_version_string (filedata,
13281 (section == NULL
13282 || section->sh_type == SHT_DYNSYM),
13283 strtab, strtab_size, si,
13284 psym, &sym_info, &vna_other);
b9e920ec 13285
0942c7ab
NC
13286 int len_avail = 21;
13287 if (! do_wide && version_string != NULL)
13288 {
ddb43bab 13289 char buffer[16];
0942c7ab 13290
ddb43bab 13291 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13292
13293 if (sym_info == symbol_undefined)
13294 len_avail -= sprintf (buffer," (%d)", vna_other);
13295 else if (sym_info != symbol_hidden)
13296 len_avail -= 1;
13297 }
13298
13299 print_symbol (len_avail, sstr);
b9e920ec 13300
10ca4b04
L
13301 if (version_string)
13302 {
13303 if (sym_info == symbol_undefined)
13304 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13305 else
10ca4b04
L
13306 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13307 version_string);
13308 }
6bd1a22c 13309
10ca4b04 13310 putchar ('\n');
6bd1a22c 13311
10ca4b04
L
13312 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13313 && section != NULL
13314 && si >= section->sh_info
13315 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13316 && filedata->file_header.e_machine != EM_MIPS
13317 /* Solaris binaries have been found to violate this requirement as
13318 well. Not sure if this is a bug or an ABI requirement. */
13319 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
26c527e6 13320 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
10ca4b04
L
13321 si, printable_section_name (filedata, section), section->sh_info);
13322}
f16a9783 13323
0f03783c
NC
13324static const char *
13325get_lto_kind (unsigned int kind)
13326{
13327 switch (kind)
13328 {
13329 case 0: return "DEF";
13330 case 1: return "WEAKDEF";
13331 case 2: return "UNDEF";
13332 case 3: return "WEAKUNDEF";
13333 case 4: return "COMMON";
13334 default:
13335 break;
13336 }
13337
13338 static char buffer[30];
13339 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13340 sprintf (buffer, "<unknown: %u>", kind);
13341 return buffer;
13342}
13343
13344static const char *
13345get_lto_visibility (unsigned int visibility)
13346{
13347 switch (visibility)
13348 {
13349 case 0: return "DEFAULT";
13350 case 1: return "PROTECTED";
13351 case 2: return "INTERNAL";
13352 case 3: return "HIDDEN";
13353 default:
13354 break;
13355 }
13356
13357 static char buffer[30];
13358 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13359 sprintf (buffer, "<unknown: %u>", visibility);
13360 return buffer;
13361}
13362
13363static const char *
13364get_lto_sym_type (unsigned int sym_type)
13365{
13366 switch (sym_type)
13367 {
13368 case 0: return "UNKNOWN";
13369 case 1: return "FUNCTION";
13370 case 2: return "VARIABLE";
13371 default:
13372 break;
13373 }
13374
13375 static char buffer[30];
13376 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13377 sprintf (buffer, "<unknown: %u>", sym_type);
13378 return buffer;
13379}
13380
13381/* Display an LTO format symbol table.
13382 FIXME: The format of LTO symbol tables is not formalized.
13383 So this code could need changing in the future. */
13384
015dc7e1 13385static bool
0f03783c
NC
13386display_lto_symtab (Filedata * filedata,
13387 Elf_Internal_Shdr * section)
13388{
13389 if (section->sh_size == 0)
13390 {
ca0e11aa
NC
13391 if (filedata->is_separate)
13392 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13393 printable_section_name (filedata, section),
13394 filedata->file_name);
13395 else
13396 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13397 printable_section_name (filedata, section));
047c3dbf 13398
015dc7e1 13399 return true;
0f03783c
NC
13400 }
13401
13402 if (section->sh_size > filedata->file_size)
13403 {
26c527e6 13404 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
0f03783c 13405 printable_section_name (filedata, section),
26c527e6 13406 section->sh_size);
015dc7e1 13407 return false;
0f03783c
NC
13408 }
13409
13410 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13411 section->sh_size, 1, _("LTO symbols"));
13412 if (alloced_data == NULL)
015dc7e1 13413 return false;
0f03783c
NC
13414
13415 /* Look for extended data for the symbol table. */
13416 Elf_Internal_Shdr * ext;
13417 void * ext_data_orig = NULL;
13418 char * ext_data = NULL;
13419 char * ext_data_end = NULL;
13420 char * ext_name = NULL;
13421
13422 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13423 (section_name (filedata, section)
13424 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13425 && ext_name != NULL /* Paranoia. */
13426 && (ext = find_section (filedata, ext_name)) != NULL)
13427 {
13428 if (ext->sh_size < 3)
13429 error (_("LTO Symbol extension table '%s' is empty!\n"),
13430 printable_section_name (filedata, ext));
13431 else
13432 {
13433 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13434 ext->sh_size, 1,
13435 _("LTO ext symbol data"));
13436 if (ext_data != NULL)
13437 {
13438 ext_data_end = ext_data + ext->sh_size;
13439 if (* ext_data++ != 1)
13440 error (_("Unexpected version number in symbol extension table\n"));
13441 }
13442 }
13443 }
b9e920ec 13444
0f03783c
NC
13445 const unsigned char * data = (const unsigned char *) alloced_data;
13446 const unsigned char * end = data + section->sh_size;
13447
ca0e11aa
NC
13448 if (filedata->is_separate)
13449 printf (_("\nIn linked file '%s': "), filedata->file_name);
13450 else
13451 printf ("\n");
13452
0f03783c
NC
13453 if (ext_data_orig != NULL)
13454 {
13455 if (do_wide)
ca0e11aa 13456 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13457 printable_section_name (filedata, section),
13458 printable_section_name (filedata, ext));
13459 else
13460 {
ca0e11aa 13461 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13462 printable_section_name (filedata, section));
13463 printf (_(" and extension table '%s' contain:\n"),
13464 printable_section_name (filedata, ext));
13465 }
13466 }
13467 else
ca0e11aa 13468 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13469 printable_section_name (filedata, section));
b9e920ec 13470
0f03783c 13471 /* FIXME: Add a wide version. */
b9e920ec 13472 if (ext_data_orig != NULL)
0f03783c
NC
13473 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13474 else
13475 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13476
13477 /* FIXME: We do not handle style prefixes. */
13478
13479 while (data < end)
13480 {
13481 const unsigned char * sym_name = data;
13482 data += strnlen ((const char *) sym_name, end - data) + 1;
13483 if (data >= end)
13484 goto fail;
13485
13486 const unsigned char * comdat_key = data;
13487 data += strnlen ((const char *) comdat_key, end - data) + 1;
13488 if (data >= end)
13489 goto fail;
13490
13491 if (data + 2 + 8 + 4 > end)
13492 goto fail;
13493
13494 unsigned int kind = *data++;
13495 unsigned int visibility = *data++;
13496
928c411d 13497 uint64_t size = byte_get (data, 8);
0f03783c
NC
13498 data += 8;
13499
928c411d 13500 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13501 data += 4;
13502
13503 if (ext_data != NULL)
13504 {
13505 if (ext_data < (ext_data_end - 1))
13506 {
13507 unsigned int sym_type = * ext_data ++;
13508 unsigned int sec_kind = * ext_data ++;
13509
31e5a3a3 13510 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
13511 * comdat_key == 0 ? "-" : (char *) comdat_key,
13512 get_lto_kind (kind),
13513 get_lto_visibility (visibility),
31e5a3a3
AM
13514 size,
13515 slot,
0f03783c 13516 get_lto_sym_type (sym_type),
31e5a3a3 13517 sec_kind);
0f03783c
NC
13518 print_symbol (6, (const char *) sym_name);
13519 }
13520 else
13521 {
13522 error (_("Ran out of LTO symbol extension data\n"));
13523 ext_data = NULL;
13524 /* FIXME: return FAIL result ? */
13525 }
13526 }
13527 else
13528 {
31e5a3a3 13529 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
13530 * comdat_key == 0 ? "-" : (char *) comdat_key,
13531 get_lto_kind (kind),
13532 get_lto_visibility (visibility),
31e5a3a3
AM
13533 size,
13534 slot);
0f03783c
NC
13535 print_symbol (21, (const char *) sym_name);
13536 }
13537 putchar ('\n');
13538 }
13539
13540 if (ext_data != NULL && ext_data < ext_data_end)
13541 {
13542 error (_("Data remains in the LTO symbol extension table\n"));
13543 goto fail;
13544 }
13545
13546 free (alloced_data);
13547 free (ext_data_orig);
13548 free (ext_name);
015dc7e1 13549 return true;
b9e920ec 13550
0f03783c
NC
13551 fail:
13552 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13553 free (alloced_data);
13554 free (ext_data_orig);
13555 free (ext_name);
015dc7e1 13556 return false;
0f03783c
NC
13557}
13558
13559/* Display LTO symbol tables. */
13560
015dc7e1 13561static bool
0f03783c
NC
13562process_lto_symbol_tables (Filedata * filedata)
13563{
13564 Elf_Internal_Shdr * section;
13565 unsigned int i;
015dc7e1 13566 bool res = true;
0f03783c
NC
13567
13568 if (!do_lto_syms)
015dc7e1 13569 return true;
0f03783c
NC
13570
13571 if (filedata->section_headers == NULL)
015dc7e1 13572 return true;
0f03783c
NC
13573
13574 for (i = 0, section = filedata->section_headers;
13575 i < filedata->file_header.e_shnum;
13576 i++, section++)
84714f86
AM
13577 if (section_name_valid (filedata, section)
13578 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13579 res &= display_lto_symtab (filedata, section);
13580
b9e920ec 13581 return res;
0f03783c
NC
13582}
13583
10ca4b04 13584/* Dump the symbol table. */
0f03783c 13585
015dc7e1 13586static bool
10ca4b04
L
13587process_symbol_table (Filedata * filedata)
13588{
13589 Elf_Internal_Shdr * section;
f16a9783 13590
10ca4b04 13591 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13592 return true;
6bd1a22c 13593
978c4450 13594 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13595 && do_syms
13596 && do_using_dynamic
978c4450
AM
13597 && filedata->dynamic_strings != NULL
13598 && filedata->dynamic_symbols != NULL)
6bd1a22c 13599 {
26c527e6 13600 uint64_t si;
6bd1a22c 13601
ca0e11aa
NC
13602 if (filedata->is_separate)
13603 {
26c527e6
AM
13604 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
13605 " contains %" PRIu64 " entry:\n",
13606 "\nIn linked file '%s' the dynamic symbol table"
13607 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13608 filedata->num_dynamic_syms),
13609 filedata->file_name,
13610 filedata->num_dynamic_syms);
13611 }
13612 else
13613 {
26c527e6
AM
13614 printf (ngettext ("\nSymbol table for image contains %" PRIu64
13615 " entry:\n",
13616 "\nSymbol table for image contains %" PRIu64
13617 " entries:\n",
ca0e11aa
NC
13618 filedata->num_dynamic_syms),
13619 filedata->num_dynamic_syms);
13620 }
10ca4b04
L
13621 if (is_32bit_elf)
13622 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13623 else
13624 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13625
978c4450
AM
13626 for (si = 0; si < filedata->num_dynamic_syms; si++)
13627 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13628 filedata->dynamic_strings,
13629 filedata->dynamic_strings_length);
252b5132 13630 }
8b73c356 13631 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13632 && filedata->section_headers != NULL)
252b5132 13633 {
b34976b6 13634 unsigned int i;
252b5132 13635
dda8d76d
NC
13636 for (i = 0, section = filedata->section_headers;
13637 i < filedata->file_header.e_shnum;
252b5132
RH
13638 i++, section++)
13639 {
2cf0635d 13640 char * strtab = NULL;
26c527e6 13641 uint64_t strtab_size = 0;
2cf0635d 13642 Elf_Internal_Sym * symtab;
26c527e6 13643 uint64_t si, num_syms;
252b5132 13644
2c610e4b
L
13645 if ((section->sh_type != SHT_SYMTAB
13646 && section->sh_type != SHT_DYNSYM)
13647 || (!do_syms
13648 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13649 continue;
13650
dd24e3da
NC
13651 if (section->sh_entsize == 0)
13652 {
13653 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13654 printable_section_name (filedata, section));
dd24e3da
NC
13655 continue;
13656 }
13657
d3a49aa8 13658 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13659
13660 if (filedata->is_separate)
26c527e6
AM
13661 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
13662 " contains %" PRIu64 " entry:\n",
13663 "\nIn linked file '%s' symbol section '%s'"
13664 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13665 num_syms),
13666 filedata->file_name,
13667 printable_section_name (filedata, section),
13668 num_syms);
13669 else
26c527e6
AM
13670 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
13671 " entry:\n",
13672 "\nSymbol table '%s' contains %" PRIu64
13673 " entries:\n",
ca0e11aa
NC
13674 num_syms),
13675 printable_section_name (filedata, section),
13676 num_syms);
dd24e3da 13677
f7a99963 13678 if (is_32bit_elf)
ca47b30c 13679 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13680 else
ca47b30c 13681 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13682
4de91c10 13683 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13684 if (symtab == NULL)
13685 continue;
13686
dda8d76d 13687 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13688 {
dda8d76d
NC
13689 strtab = filedata->string_table;
13690 strtab_size = filedata->string_table_length;
c256ffe7 13691 }
dda8d76d 13692 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13693 {
2cf0635d 13694 Elf_Internal_Shdr * string_sec;
252b5132 13695
dda8d76d 13696 string_sec = filedata->section_headers + section->sh_link;
252b5132 13697
dda8d76d 13698 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13699 1, string_sec->sh_size,
13700 _("string table"));
c256ffe7 13701 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13702 }
13703
10ca4b04
L
13704 for (si = 0; si < num_syms; si++)
13705 print_dynamic_symbol (filedata, si, symtab, section,
13706 strtab, strtab_size);
252b5132
RH
13707
13708 free (symtab);
dda8d76d 13709 if (strtab != filedata->string_table)
252b5132
RH
13710 free (strtab);
13711 }
13712 }
13713 else if (do_syms)
13714 printf
13715 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13716
978c4450 13717 if (do_histogram && filedata->buckets != NULL)
252b5132 13718 {
26c527e6
AM
13719 uint64_t *lengths;
13720 uint64_t *counts;
13721 uint64_t hn;
625d49fc 13722 uint64_t si;
26c527e6
AM
13723 uint64_t maxlength = 0;
13724 uint64_t nzero_counts = 0;
13725 uint64_t nsyms = 0;
6bd6a03d 13726 char *visited;
252b5132 13727
d3a49aa8 13728 printf (ngettext ("\nHistogram for bucket list length "
26c527e6 13729 "(total of %" PRIu64 " bucket):\n",
d3a49aa8 13730 "\nHistogram for bucket list length "
26c527e6
AM
13731 "(total of %" PRIu64 " buckets):\n",
13732 filedata->nbuckets),
13733 filedata->nbuckets);
252b5132 13734
26c527e6 13735 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
252b5132
RH
13736 if (lengths == NULL)
13737 {
8b73c356 13738 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13739 goto err_out;
252b5132 13740 }
978c4450
AM
13741 visited = xcmalloc (filedata->nchains, 1);
13742 memset (visited, 0, filedata->nchains);
8b73c356
NC
13743
13744 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13745 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13746 {
978c4450 13747 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13748 {
b34976b6 13749 ++nsyms;
252b5132 13750 if (maxlength < ++lengths[hn])
b34976b6 13751 ++maxlength;
978c4450 13752 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13753 {
13754 error (_("histogram chain is corrupt\n"));
13755 break;
13756 }
13757 visited[si] = 1;
252b5132
RH
13758 }
13759 }
6bd6a03d 13760 free (visited);
252b5132 13761
26c527e6 13762 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13763 if (counts == NULL)
13764 {
b2e951ec 13765 free (lengths);
8b73c356 13766 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13767 goto err_out;
252b5132
RH
13768 }
13769
978c4450 13770 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13771 ++counts[lengths[hn]];
252b5132 13772
978c4450 13773 if (filedata->nbuckets > 0)
252b5132 13774 {
26c527e6
AM
13775 uint64_t i;
13776 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 13777 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13778 for (i = 1; i <= maxlength; ++i)
103f02d3 13779 {
66543521 13780 nzero_counts += counts[i] * i;
26c527e6 13781 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 13782 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13783 (nzero_counts * 100.0) / nsyms);
13784 }
252b5132
RH
13785 }
13786
13787 free (counts);
13788 free (lengths);
13789 }
13790
978c4450
AM
13791 free (filedata->buckets);
13792 filedata->buckets = NULL;
13793 filedata->nbuckets = 0;
13794 free (filedata->chains);
13795 filedata->chains = NULL;
252b5132 13796
978c4450 13797 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13798 {
26c527e6
AM
13799 uint64_t *lengths;
13800 uint64_t *counts;
13801 uint64_t hn;
13802 uint64_t maxlength = 0;
13803 uint64_t nzero_counts = 0;
13804 uint64_t nsyms = 0;
fdc90cb4 13805
f16a9783 13806 printf (ngettext ("\nHistogram for `%s' bucket list length "
26c527e6 13807 "(total of %" PRIu64 " bucket):\n",
f16a9783 13808 "\nHistogram for `%s' bucket list length "
26c527e6
AM
13809 "(total of %" PRIu64 " buckets):\n",
13810 filedata->ngnubuckets),
978c4450 13811 GNU_HASH_SECTION_NAME (filedata),
26c527e6 13812 filedata->ngnubuckets);
8b73c356 13813
26c527e6 13814 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
13815 if (lengths == NULL)
13816 {
8b73c356 13817 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13818 goto err_out;
fdc90cb4
JJ
13819 }
13820
fdc90cb4
JJ
13821 printf (_(" Length Number %% of total Coverage\n"));
13822
978c4450
AM
13823 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13824 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 13825 {
625d49fc 13826 uint64_t off, length = 1;
fdc90cb4 13827
978c4450 13828 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13829 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13830 off < filedata->ngnuchains
13831 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13832 ++off)
fdc90cb4
JJ
13833 ++length;
13834 lengths[hn] = length;
13835 if (length > maxlength)
13836 maxlength = length;
13837 nsyms += length;
13838 }
13839
26c527e6 13840 counts = calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13841 if (counts == NULL)
13842 {
b2e951ec 13843 free (lengths);
8b73c356 13844 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13845 goto err_out;
fdc90cb4
JJ
13846 }
13847
978c4450 13848 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13849 ++counts[lengths[hn]];
13850
978c4450 13851 if (filedata->ngnubuckets > 0)
fdc90cb4 13852 {
26c527e6
AM
13853 uint64_t j;
13854 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 13855 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13856 for (j = 1; j <= maxlength; ++j)
13857 {
13858 nzero_counts += counts[j] * j;
26c527e6 13859 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 13860 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13861 (nzero_counts * 100.0) / nsyms);
13862 }
13863 }
13864
13865 free (counts);
13866 free (lengths);
fdc90cb4 13867 }
978c4450
AM
13868 free (filedata->gnubuckets);
13869 filedata->gnubuckets = NULL;
13870 filedata->ngnubuckets = 0;
13871 free (filedata->gnuchains);
13872 filedata->gnuchains = NULL;
13873 filedata->ngnuchains = 0;
13874 free (filedata->mipsxlat);
13875 filedata->mipsxlat = NULL;
015dc7e1 13876 return true;
fd486f32
AM
13877
13878 err_out:
978c4450
AM
13879 free (filedata->gnubuckets);
13880 filedata->gnubuckets = NULL;
13881 filedata->ngnubuckets = 0;
13882 free (filedata->gnuchains);
13883 filedata->gnuchains = NULL;
13884 filedata->ngnuchains = 0;
13885 free (filedata->mipsxlat);
13886 filedata->mipsxlat = NULL;
13887 free (filedata->buckets);
13888 filedata->buckets = NULL;
13889 filedata->nbuckets = 0;
13890 free (filedata->chains);
13891 filedata->chains = NULL;
015dc7e1 13892 return false;
252b5132
RH
13893}
13894
015dc7e1 13895static bool
ca0e11aa 13896process_syminfo (Filedata * filedata)
252b5132 13897{
b4c96d0d 13898 unsigned int i;
252b5132 13899
978c4450 13900 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13901 || !do_dynamic)
13902 /* No syminfo, this is ok. */
015dc7e1 13903 return true;
252b5132
RH
13904
13905 /* There better should be a dynamic symbol section. */
978c4450 13906 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13907 return false;
252b5132 13908
ca0e11aa 13909 if (filedata->is_separate)
26c527e6
AM
13910 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
13911 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
ca0e11aa
NC
13912 filedata->dynamic_syminfo_nent),
13913 filedata->file_name,
13914 filedata->dynamic_syminfo_offset,
13915 filedata->dynamic_syminfo_nent);
13916 else
26c527e6
AM
13917 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
13918 " contains %d entry:\n",
13919 "\nDynamic info segment at offset %#" PRIx64
13920 " contains %d entries:\n",
978c4450 13921 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13922 filedata->dynamic_syminfo_offset,
13923 filedata->dynamic_syminfo_nent);
252b5132
RH
13924
13925 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13926 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13927 {
978c4450 13928 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13929
31104126 13930 printf ("%4d: ", i);
978c4450 13931 if (i >= filedata->num_dynamic_syms)
4082ef84 13932 printf (_("<corrupt index>"));
84714f86
AM
13933 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13934 print_symbol (30, get_dynamic_name (filedata,
978c4450 13935 filedata->dynamic_symbols[i].st_name));
d79b3d50 13936 else
978c4450 13937 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13938 putchar (' ');
252b5132 13939
978c4450 13940 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13941 {
13942 case SYMINFO_BT_SELF:
13943 fputs ("SELF ", stdout);
13944 break;
13945 case SYMINFO_BT_PARENT:
13946 fputs ("PARENT ", stdout);
13947 break;
13948 default:
978c4450
AM
13949 if (filedata->dynamic_syminfo[i].si_boundto > 0
13950 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13951 && valid_dynamic_name (filedata,
978c4450 13952 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13953 {
84714f86 13954 print_symbol (10, get_dynamic_name (filedata,
978c4450 13955 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13956 putchar (' ' );
13957 }
252b5132 13958 else
978c4450 13959 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13960 break;
13961 }
13962
13963 if (flags & SYMINFO_FLG_DIRECT)
13964 printf (" DIRECT");
13965 if (flags & SYMINFO_FLG_PASSTHRU)
13966 printf (" PASSTHRU");
13967 if (flags & SYMINFO_FLG_COPY)
13968 printf (" COPY");
13969 if (flags & SYMINFO_FLG_LAZYLOAD)
13970 printf (" LAZYLOAD");
13971
13972 puts ("");
13973 }
13974
015dc7e1 13975 return true;
252b5132
RH
13976}
13977
75802ccb
CE
13978/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13979 is contained by the region START .. END. The types of ADDR, START
13980 and END should all be the same. Note both ADDR + NELEM and END
13981 point to just beyond the end of the regions that are being tested. */
13982#define IN_RANGE(START,END,ADDR,NELEM) \
13983 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13984
cf13d699
NC
13985/* Check to see if the given reloc needs to be handled in a target specific
13986 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13987 FALSE.
13988
13989 If called with reloc == NULL, then this is a signal that reloc processing
13990 for the current section has finished, and any saved state should be
13991 discarded. */
09c11c86 13992
015dc7e1 13993static bool
26c527e6
AM
13994target_specific_reloc_handling (Filedata *filedata,
13995 Elf_Internal_Rela *reloc,
13996 unsigned char *start,
13997 unsigned char *end,
13998 Elf_Internal_Sym *symtab,
13999 uint64_t num_syms)
252b5132 14000{
f84ce13b 14001 unsigned int reloc_type = 0;
26c527e6 14002 uint64_t sym_index = 0;
f84ce13b
NC
14003
14004 if (reloc)
14005 {
dda8d76d 14006 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
14007 sym_index = get_reloc_symindex (reloc->r_info);
14008 }
252b5132 14009
dda8d76d 14010 switch (filedata->file_header.e_machine)
252b5132 14011 {
76244462 14012 case EM_LOONGARCH:
14013 {
14014 switch (reloc_type)
14015 {
14016 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
14017 at assembly time. */
14018 case 107: /* R_LARCH_ADD_ULEB128. */
14019 case 108: /* R_LARCH_SUB_ULEB128. */
14020 {
d3f34076 14021 uint64_t value = 0;
76244462 14022 unsigned int reloc_size = 0;
14023 int leb_ret = 0;
14024
89c70cd3
AM
14025 if (reloc->r_offset < (size_t) (end - start))
14026 value = read_leb128 (start + reloc->r_offset, end, false,
14027 &reloc_size, &leb_ret);
76244462 14028 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14029 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
14030 "ULEB128 value\n"),
14031 (long) reloc->r_offset);
14032
74a965d8
AM
14033 else if (sym_index >= num_syms)
14034 error (_("%s reloc contains invalid symbol index "
14035 "%" PRIu64 "\n"),
14036 (reloc_type == 107
14037 ? "R_LARCH_ADD_ULEB128"
14038 : "R_LARCH_SUB_ULEB128"),
14039 sym_index);
14040 else
76244462 14041 {
74a965d8
AM
14042 if (reloc_type == 107)
14043 value += reloc->r_addend + symtab[sym_index].st_value;
14044 else
14045 value -= reloc->r_addend + symtab[sym_index].st_value;
14046
14047 /* Write uleb128 value to p. */
14048 bfd_byte *p = start + reloc->r_offset;
14049 do
14050 {
14051 bfd_byte c = value & 0x7f;
14052 value >>= 7;
14053 if (--reloc_size != 0)
14054 c |= 0x80;
14055 *p++ = c;
14056 }
14057 while (reloc_size);
76244462 14058 }
76244462 14059
14060 return true;
14061 }
14062 }
14063 break;
14064 }
14065
13761a11
NC
14066 case EM_MSP430:
14067 case EM_MSP430_OLD:
14068 {
14069 static Elf_Internal_Sym * saved_sym = NULL;
14070
f84ce13b
NC
14071 if (reloc == NULL)
14072 {
14073 saved_sym = NULL;
015dc7e1 14074 return true;
f84ce13b
NC
14075 }
14076
13761a11
NC
14077 switch (reloc_type)
14078 {
14079 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 14080 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 14081 if (uses_msp430x_relocs (filedata))
13761a11 14082 break;
1a0670f3 14083 /* Fall through. */
13761a11 14084 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 14085 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
14086 /* PR 21139. */
14087 if (sym_index >= num_syms)
74a965d8
AM
14088 error (_("%s reloc contains invalid symbol index "
14089 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
f84ce13b
NC
14090 else
14091 saved_sym = symtab + sym_index;
015dc7e1 14092 return true;
13761a11
NC
14093
14094 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14095 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14096 goto handle_sym_diff;
0b4362b0 14097
13761a11
NC
14098 case 5: /* R_MSP430_16_BYTE */
14099 case 9: /* R_MSP430_8 */
7d81bc93 14100 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 14101 if (uses_msp430x_relocs (filedata))
13761a11
NC
14102 break;
14103 goto handle_sym_diff;
14104
14105 case 2: /* R_MSP430_ABS16 */
14106 case 15: /* R_MSP430X_ABS16 */
7d81bc93 14107 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 14108 if (! uses_msp430x_relocs (filedata))
13761a11
NC
14109 break;
14110 goto handle_sym_diff;
0b4362b0 14111
13761a11
NC
14112 handle_sym_diff:
14113 if (saved_sym != NULL)
14114 {
625d49fc 14115 uint64_t value;
5a805384 14116 unsigned int reloc_size = 0;
7d81bc93
JL
14117 int leb_ret = 0;
14118 switch (reloc_type)
14119 {
14120 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14121 reloc_size = 4;
14122 break;
14123 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14124 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14125 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14126 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14127 &reloc_size, &leb_ret);
7d81bc93
JL
14128 break;
14129 default:
14130 reloc_size = 2;
14131 break;
14132 }
13761a11 14133
5a805384 14134 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
14135 error (_("MSP430 ULEB128 field at %#" PRIx64
14136 " contains invalid ULEB128 value\n"),
14137 reloc->r_offset);
7d81bc93 14138 else if (sym_index >= num_syms)
74a965d8
AM
14139 error (_("%s reloc contains invalid symbol index "
14140 "%" PRIu64 "\n"), "MSP430", sym_index);
03f7786e 14141 else
f84ce13b
NC
14142 {
14143 value = reloc->r_addend + (symtab[sym_index].st_value
14144 - saved_sym->st_value);
14145
b32e566b 14146 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14147 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14148 else
14149 /* PR 21137 */
26c527e6
AM
14150 error (_("MSP430 sym diff reloc contains invalid offset: "
14151 "%#" PRIx64 "\n"),
14152 reloc->r_offset);
f84ce13b 14153 }
13761a11
NC
14154
14155 saved_sym = NULL;
015dc7e1 14156 return true;
13761a11
NC
14157 }
14158 break;
14159
14160 default:
14161 if (saved_sym != NULL)
071436c6 14162 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14163 break;
14164 }
14165 break;
14166 }
14167
cf13d699
NC
14168 case EM_MN10300:
14169 case EM_CYGNUS_MN10300:
14170 {
14171 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14172
f84ce13b
NC
14173 if (reloc == NULL)
14174 {
14175 saved_sym = NULL;
015dc7e1 14176 return true;
f84ce13b
NC
14177 }
14178
cf13d699
NC
14179 switch (reloc_type)
14180 {
14181 case 34: /* R_MN10300_ALIGN */
015dc7e1 14182 return true;
cf13d699 14183 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 14184 if (sym_index >= num_syms)
74a965d8
AM
14185 error (_("%s reloc contains invalid symbol index "
14186 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
f84ce13b
NC
14187 else
14188 saved_sym = symtab + sym_index;
015dc7e1 14189 return true;
f84ce13b 14190
cf13d699
NC
14191 case 1: /* R_MN10300_32 */
14192 case 2: /* R_MN10300_16 */
14193 if (saved_sym != NULL)
14194 {
03f7786e 14195 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14196 uint64_t value;
252b5132 14197
f84ce13b 14198 if (sym_index >= num_syms)
74a965d8
AM
14199 error (_("%s reloc contains invalid symbol index "
14200 "%" PRIu64 "\n"), "MN10300", sym_index);
03f7786e 14201 else
f84ce13b
NC
14202 {
14203 value = reloc->r_addend + (symtab[sym_index].st_value
14204 - saved_sym->st_value);
14205
b32e566b 14206 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14207 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 14208 else
26c527e6
AM
14209 error (_("MN10300 sym diff reloc contains invalid offset:"
14210 " %#" PRIx64 "\n"),
14211 reloc->r_offset);
f84ce13b 14212 }
252b5132 14213
cf13d699 14214 saved_sym = NULL;
015dc7e1 14215 return true;
cf13d699
NC
14216 }
14217 break;
14218 default:
14219 if (saved_sym != NULL)
071436c6 14220 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14221 break;
14222 }
14223 break;
14224 }
6ff71e76
NC
14225
14226 case EM_RL78:
14227 {
625d49fc
AM
14228 static uint64_t saved_sym1 = 0;
14229 static uint64_t saved_sym2 = 0;
14230 static uint64_t value;
6ff71e76 14231
f84ce13b
NC
14232 if (reloc == NULL)
14233 {
14234 saved_sym1 = saved_sym2 = 0;
015dc7e1 14235 return true;
f84ce13b
NC
14236 }
14237
6ff71e76
NC
14238 switch (reloc_type)
14239 {
14240 case 0x80: /* R_RL78_SYM. */
14241 saved_sym1 = saved_sym2;
f84ce13b 14242 if (sym_index >= num_syms)
74a965d8
AM
14243 error (_("%s reloc contains invalid symbol index "
14244 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
f84ce13b
NC
14245 else
14246 {
14247 saved_sym2 = symtab[sym_index].st_value;
14248 saved_sym2 += reloc->r_addend;
14249 }
015dc7e1 14250 return true;
6ff71e76
NC
14251
14252 case 0x83: /* R_RL78_OPsub. */
14253 value = saved_sym1 - saved_sym2;
14254 saved_sym2 = saved_sym1 = 0;
015dc7e1 14255 return true;
6ff71e76
NC
14256 break;
14257
14258 case 0x41: /* R_RL78_ABS32. */
b32e566b 14259 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14260 byte_put (start + reloc->r_offset, value, 4);
b32e566b 14261 else
26c527e6
AM
14262 error (_("RL78 sym diff reloc contains invalid offset: "
14263 "%#" PRIx64 "\n"),
14264 reloc->r_offset);
6ff71e76 14265 value = 0;
015dc7e1 14266 return true;
6ff71e76
NC
14267
14268 case 0x43: /* R_RL78_ABS16. */
b32e566b 14269 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14270 byte_put (start + reloc->r_offset, value, 2);
b32e566b 14271 else
26c527e6
AM
14272 error (_("RL78 sym diff reloc contains invalid offset: "
14273 "%#" PRIx64 "\n"),
14274 reloc->r_offset);
6ff71e76 14275 value = 0;
015dc7e1 14276 return true;
6ff71e76
NC
14277
14278 default:
14279 break;
14280 }
14281 break;
14282 }
252b5132
RH
14283 }
14284
015dc7e1 14285 return false;
252b5132
RH
14286}
14287
aca88567
NC
14288/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14289 DWARF debug sections. This is a target specific test. Note - we do not
14290 go through the whole including-target-headers-multiple-times route, (as
14291 we have already done with <elf/h8.h>) because this would become very
14292 messy and even then this function would have to contain target specific
14293 information (the names of the relocs instead of their numeric values).
14294 FIXME: This is not the correct way to solve this problem. The proper way
14295 is to have target specific reloc sizing and typing functions created by
14296 the reloc-macros.h header, in the same way that it already creates the
14297 reloc naming functions. */
14298
015dc7e1 14299static bool
dda8d76d 14300is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14301{
d347c9df 14302 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14303 switch (filedata->file_header.e_machine)
aca88567 14304 {
41e92641 14305 case EM_386:
22abe556 14306 case EM_IAMCU:
41e92641 14307 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14308 case EM_68K:
14309 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14310 case EM_860:
14311 return reloc_type == 1; /* R_860_32. */
14312 case EM_960:
14313 return reloc_type == 2; /* R_960_32. */
a06ea964 14314 case EM_AARCH64:
9282b95a
JW
14315 return (reloc_type == 258
14316 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14317 case EM_BPF:
14318 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14319 case EM_ADAPTEVA_EPIPHANY:
14320 return reloc_type == 3;
aca88567 14321 case EM_ALPHA:
137b6b5f 14322 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14323 case EM_ARC:
14324 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14325 case EM_ARC_COMPACT:
14326 case EM_ARC_COMPACT2:
14327 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14328 case EM_ARM:
14329 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14330 case EM_AVR_OLD:
aca88567
NC
14331 case EM_AVR:
14332 return reloc_type == 1;
14333 case EM_BLACKFIN:
14334 return reloc_type == 0x12; /* R_byte4_data. */
14335 case EM_CRIS:
14336 return reloc_type == 3; /* R_CRIS_32. */
14337 case EM_CR16:
14338 return reloc_type == 3; /* R_CR16_NUM32. */
14339 case EM_CRX:
14340 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14341 case EM_CSKY:
14342 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14343 case EM_CYGNUS_FRV:
14344 return reloc_type == 1;
41e92641
NC
14345 case EM_CYGNUS_D10V:
14346 case EM_D10V:
14347 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14348 case EM_CYGNUS_D30V:
14349 case EM_D30V:
14350 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14351 case EM_DLX:
14352 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14353 case EM_CYGNUS_FR30:
14354 case EM_FR30:
14355 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14356 case EM_FT32:
14357 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14358 case EM_H8S:
14359 case EM_H8_300:
14360 case EM_H8_300H:
14361 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14362 case EM_IA_64:
262cdac7
AM
14363 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14364 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14365 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14366 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14367 case EM_IP2K_OLD:
14368 case EM_IP2K:
14369 return reloc_type == 2; /* R_IP2K_32. */
14370 case EM_IQ2000:
14371 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14372 case EM_LATTICEMICO32:
14373 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14374 case EM_LOONGARCH:
14375 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14376 case EM_M32C_OLD:
aca88567
NC
14377 case EM_M32C:
14378 return reloc_type == 3; /* R_M32C_32. */
14379 case EM_M32R:
14380 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14381 case EM_68HC11:
14382 case EM_68HC12:
14383 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14384 case EM_S12Z:
2849d19f
JD
14385 return reloc_type == 7 || /* R_S12Z_EXT32 */
14386 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14387 case EM_MCORE:
14388 return reloc_type == 1; /* R_MCORE_ADDR32. */
14389 case EM_CYGNUS_MEP:
14390 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14391 case EM_METAG:
14392 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14393 case EM_MICROBLAZE:
14394 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14395 case EM_MIPS:
14396 return reloc_type == 2; /* R_MIPS_32. */
14397 case EM_MMIX:
14398 return reloc_type == 4; /* R_MMIX_32. */
14399 case EM_CYGNUS_MN10200:
14400 case EM_MN10200:
14401 return reloc_type == 1; /* R_MN10200_32. */
14402 case EM_CYGNUS_MN10300:
14403 case EM_MN10300:
14404 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14405 case EM_MOXIE:
14406 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14407 case EM_MSP430_OLD:
14408 case EM_MSP430:
13761a11 14409 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14410 case EM_MT:
14411 return reloc_type == 2; /* R_MT_32. */
35c08157 14412 case EM_NDS32:
81c5e376 14413 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14414 case EM_ALTERA_NIOS2:
36591ba1 14415 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14416 case EM_NIOS32:
14417 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14418 case EM_OR1K:
14419 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14420 case EM_PARISC:
9abca702 14421 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14422 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14423 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14424 case EM_PJ:
14425 case EM_PJ_OLD:
14426 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14427 case EM_PPC64:
14428 return reloc_type == 1; /* R_PPC64_ADDR32. */
14429 case EM_PPC:
14430 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14431 case EM_TI_PRU:
14432 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14433 case EM_RISCV:
14434 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14435 case EM_RL78:
14436 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14437 case EM_RX:
14438 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14439 case EM_S370:
14440 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14441 case EM_S390_OLD:
14442 case EM_S390:
14443 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14444 case EM_SCORE:
14445 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14446 case EM_SH:
14447 return reloc_type == 1; /* R_SH_DIR32. */
14448 case EM_SPARC32PLUS:
14449 case EM_SPARCV9:
14450 case EM_SPARC:
14451 return reloc_type == 3 /* R_SPARC_32. */
14452 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14453 case EM_SPU:
14454 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14455 case EM_TI_C6000:
14456 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14457 case EM_TILEGX:
14458 return reloc_type == 2; /* R_TILEGX_32. */
14459 case EM_TILEPRO:
14460 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14461 case EM_CYGNUS_V850:
14462 case EM_V850:
14463 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14464 case EM_V800:
14465 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14466 case EM_VAX:
14467 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14468 case EM_VISIUM:
14469 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14470 case EM_WEBASSEMBLY:
14471 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14472 case EM_X86_64:
8a9036a4 14473 case EM_L1OM:
7a9068fe 14474 case EM_K1OM:
aca88567 14475 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14476 case EM_XGATE:
14477 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14478 case EM_XSTORMY16:
14479 return reloc_type == 1; /* R_XSTROMY16_32. */
14480 case EM_XTENSA_OLD:
14481 case EM_XTENSA:
14482 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14483 case EM_Z80:
14484 return reloc_type == 6; /* R_Z80_32. */
aca88567 14485 default:
bee0ee85
NC
14486 {
14487 static unsigned int prev_warn = 0;
14488
14489 /* Avoid repeating the same warning multiple times. */
dda8d76d 14490 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14491 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14492 filedata->file_header.e_machine);
14493 prev_warn = filedata->file_header.e_machine;
015dc7e1 14494 return false;
bee0ee85 14495 }
aca88567
NC
14496 }
14497}
14498
14499/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14500 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14501
015dc7e1 14502static bool
dda8d76d 14503is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14504{
dda8d76d 14505 switch (filedata->file_header.e_machine)
d347c9df 14506 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14507 {
41e92641 14508 case EM_386:
22abe556 14509 case EM_IAMCU:
3e0873ac 14510 return reloc_type == 2; /* R_386_PC32. */
aca88567 14511 case EM_68K:
3e0873ac 14512 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14513 case EM_AARCH64:
14514 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14515 case EM_ADAPTEVA_EPIPHANY:
14516 return reloc_type == 6;
aca88567
NC
14517 case EM_ALPHA:
14518 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14519 case EM_ARC_COMPACT:
14520 case EM_ARC_COMPACT2:
14521 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14522 case EM_ARM:
3e0873ac 14523 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14524 case EM_AVR_OLD:
14525 case EM_AVR:
14526 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14527 case EM_LOONGARCH:
14528 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14529 case EM_MICROBLAZE:
14530 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14531 case EM_OR1K:
14532 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14533 case EM_PARISC:
85acf597 14534 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14535 case EM_PPC:
14536 return reloc_type == 26; /* R_PPC_REL32. */
14537 case EM_PPC64:
3e0873ac 14538 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14539 case EM_RISCV:
14540 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14541 case EM_S390_OLD:
14542 case EM_S390:
3e0873ac 14543 return reloc_type == 5; /* R_390_PC32. */
aca88567 14544 case EM_SH:
3e0873ac 14545 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14546 case EM_SPARC32PLUS:
14547 case EM_SPARCV9:
14548 case EM_SPARC:
3e0873ac 14549 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14550 case EM_SPU:
14551 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14552 case EM_TILEGX:
14553 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14554 case EM_TILEPRO:
14555 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14556 case EM_VISIUM:
14557 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14558 case EM_X86_64:
8a9036a4 14559 case EM_L1OM:
7a9068fe 14560 case EM_K1OM:
3e0873ac 14561 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14562 case EM_VAX:
14563 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14564 case EM_XTENSA_OLD:
14565 case EM_XTENSA:
14566 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14567 default:
14568 /* Do not abort or issue an error message here. Not all targets use
14569 pc-relative 32-bit relocs in their DWARF debug information and we
14570 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14571 more helpful warning message will be generated by apply_relocations
14572 anyway, so just return. */
015dc7e1 14573 return false;
aca88567
NC
14574 }
14575}
14576
14577/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14578 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14579
015dc7e1 14580static bool
dda8d76d 14581is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14582{
dda8d76d 14583 switch (filedata->file_header.e_machine)
aca88567 14584 {
a06ea964
NC
14585 case EM_AARCH64:
14586 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14587 case EM_ALPHA:
14588 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14589 case EM_IA_64:
262cdac7
AM
14590 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14591 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14592 case EM_LOONGARCH:
14593 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14594 case EM_PARISC:
14595 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14596 case EM_PPC64:
14597 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14598 case EM_RISCV:
14599 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14600 case EM_SPARC32PLUS:
14601 case EM_SPARCV9:
14602 case EM_SPARC:
714da62f
NC
14603 return reloc_type == 32 /* R_SPARC_64. */
14604 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14605 case EM_X86_64:
8a9036a4 14606 case EM_L1OM:
7a9068fe 14607 case EM_K1OM:
aca88567 14608 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14609 case EM_S390_OLD:
14610 case EM_S390:
aa137e4d
NC
14611 return reloc_type == 22; /* R_S390_64. */
14612 case EM_TILEGX:
14613 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14614 case EM_MIPS:
aa137e4d 14615 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14616 default:
015dc7e1 14617 return false;
aca88567
NC
14618 }
14619}
14620
85acf597
RH
14621/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14622 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14623
015dc7e1 14624static bool
dda8d76d 14625is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14626{
dda8d76d 14627 switch (filedata->file_header.e_machine)
85acf597 14628 {
a06ea964
NC
14629 case EM_AARCH64:
14630 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14631 case EM_ALPHA:
aa137e4d 14632 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14633 case EM_IA_64:
262cdac7
AM
14634 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14635 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14636 case EM_PARISC:
aa137e4d 14637 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14638 case EM_PPC64:
aa137e4d 14639 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14640 case EM_SPARC32PLUS:
14641 case EM_SPARCV9:
14642 case EM_SPARC:
aa137e4d 14643 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14644 case EM_X86_64:
8a9036a4 14645 case EM_L1OM:
7a9068fe 14646 case EM_K1OM:
aa137e4d 14647 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14648 case EM_S390_OLD:
14649 case EM_S390:
aa137e4d
NC
14650 return reloc_type == 23; /* R_S390_PC64. */
14651 case EM_TILEGX:
14652 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14653 default:
015dc7e1 14654 return false;
85acf597
RH
14655 }
14656}
14657
4dc3c23d
AM
14658/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14659 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14660
015dc7e1 14661static bool
dda8d76d 14662is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14663{
dda8d76d 14664 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14665 {
14666 case EM_CYGNUS_MN10200:
14667 case EM_MN10200:
14668 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14669 case EM_FT32:
14670 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14671 case EM_Z80:
14672 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14673 default:
015dc7e1 14674 return false;
4dc3c23d
AM
14675 }
14676}
14677
aca88567
NC
14678/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14679 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14680
015dc7e1 14681static bool
dda8d76d 14682is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14683{
d347c9df 14684 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14685 switch (filedata->file_header.e_machine)
4b78141a 14686 {
886a2506
NC
14687 case EM_ARC:
14688 case EM_ARC_COMPACT:
14689 case EM_ARC_COMPACT2:
14690 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14691 case EM_ADAPTEVA_EPIPHANY:
14692 return reloc_type == 5;
aca88567
NC
14693 case EM_AVR_OLD:
14694 case EM_AVR:
14695 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14696 case EM_CYGNUS_D10V:
14697 case EM_D10V:
14698 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14699 case EM_FT32:
14700 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14701 case EM_H8S:
14702 case EM_H8_300:
14703 case EM_H8_300H:
aca88567
NC
14704 return reloc_type == R_H8_DIR16;
14705 case EM_IP2K_OLD:
14706 case EM_IP2K:
14707 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14708 case EM_M32C_OLD:
f4236fe4
DD
14709 case EM_M32C:
14710 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14711 case EM_CYGNUS_MN10200:
14712 case EM_MN10200:
14713 return reloc_type == 2; /* R_MN10200_16. */
14714 case EM_CYGNUS_MN10300:
14715 case EM_MN10300:
14716 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14717 case EM_MSP430:
dda8d76d 14718 if (uses_msp430x_relocs (filedata))
13761a11 14719 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14720 /* Fall through. */
78c8d46c 14721 case EM_MSP430_OLD:
aca88567 14722 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 14723 case EM_NDS32:
81c5e376 14724 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 14725 case EM_ALTERA_NIOS2:
36591ba1 14726 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14727 case EM_NIOS32:
14728 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14729 case EM_OR1K:
14730 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14731 case EM_RISCV:
14732 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14733 case EM_TI_PRU:
14734 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14735 case EM_TI_C6000:
14736 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14737 case EM_VISIUM:
14738 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
14739 case EM_XGATE:
14740 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14741 case EM_Z80:
14742 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14743 default:
015dc7e1 14744 return false;
4b78141a
NC
14745 }
14746}
14747
39e07931
AS
14748/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14749 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14750
015dc7e1 14751static bool
39e07931
AS
14752is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14753{
14754 switch (filedata->file_header.e_machine)
14755 {
14756 case EM_RISCV:
14757 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14758 case EM_Z80:
14759 return reloc_type == 1; /* R_Z80_8. */
39e07931 14760 default:
015dc7e1 14761 return false;
39e07931
AS
14762 }
14763}
14764
14765/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14766 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14767
015dc7e1 14768static bool
39e07931
AS
14769is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14770{
14771 switch (filedata->file_header.e_machine)
14772 {
14773 case EM_RISCV:
14774 return reloc_type == 53; /* R_RISCV_SET6. */
14775 default:
015dc7e1 14776 return false;
39e07931
AS
14777 }
14778}
14779
03336641
JW
14780/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14781 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14782
015dc7e1 14783static bool
03336641
JW
14784is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14785{
14786 /* Please keep this table alpha-sorted for ease of visual lookup. */
14787 switch (filedata->file_header.e_machine)
14788 {
76244462 14789 case EM_LOONGARCH:
14790 return reloc_type == 50; /* R_LARCH_ADD32. */
03336641
JW
14791 case EM_RISCV:
14792 return reloc_type == 35; /* R_RISCV_ADD32. */
14793 default:
015dc7e1 14794 return false;
03336641
JW
14795 }
14796}
14797
14798/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14799 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14800
015dc7e1 14801static bool
03336641
JW
14802is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14803{
14804 /* Please keep this table alpha-sorted for ease of visual lookup. */
14805 switch (filedata->file_header.e_machine)
14806 {
76244462 14807 case EM_LOONGARCH:
14808 return reloc_type == 55; /* R_LARCH_SUB32. */
03336641
JW
14809 case EM_RISCV:
14810 return reloc_type == 39; /* R_RISCV_SUB32. */
14811 default:
015dc7e1 14812 return false;
03336641
JW
14813 }
14814}
14815
14816/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14817 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14818
015dc7e1 14819static bool
03336641
JW
14820is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14821{
14822 /* Please keep this table alpha-sorted for ease of visual lookup. */
14823 switch (filedata->file_header.e_machine)
14824 {
76244462 14825 case EM_LOONGARCH:
14826 return reloc_type == 51; /* R_LARCH_ADD64. */
03336641
JW
14827 case EM_RISCV:
14828 return reloc_type == 36; /* R_RISCV_ADD64. */
14829 default:
015dc7e1 14830 return false;
03336641
JW
14831 }
14832}
14833
14834/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14835 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14836
015dc7e1 14837static bool
03336641
JW
14838is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14839{
14840 /* Please keep this table alpha-sorted for ease of visual lookup. */
14841 switch (filedata->file_header.e_machine)
14842 {
76244462 14843 case EM_LOONGARCH:
14844 return reloc_type == 56; /* R_LARCH_SUB64. */
03336641
JW
14845 case EM_RISCV:
14846 return reloc_type == 40; /* R_RISCV_SUB64. */
14847 default:
015dc7e1 14848 return false;
03336641
JW
14849 }
14850}
14851
14852/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14853 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14854
015dc7e1 14855static bool
03336641
JW
14856is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14857{
14858 /* Please keep this table alpha-sorted for ease of visual lookup. */
14859 switch (filedata->file_header.e_machine)
14860 {
76244462 14861 case EM_LOONGARCH:
14862 return reloc_type == 48; /* R_LARCH_ADD16. */
03336641
JW
14863 case EM_RISCV:
14864 return reloc_type == 34; /* R_RISCV_ADD16. */
14865 default:
015dc7e1 14866 return false;
03336641
JW
14867 }
14868}
14869
14870/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14871 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14872
015dc7e1 14873static bool
03336641
JW
14874is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14875{
14876 /* Please keep this table alpha-sorted for ease of visual lookup. */
14877 switch (filedata->file_header.e_machine)
14878 {
76244462 14879 case EM_LOONGARCH:
14880 return reloc_type == 53; /* R_LARCH_SUB16. */
03336641
JW
14881 case EM_RISCV:
14882 return reloc_type == 38; /* R_RISCV_SUB16. */
14883 default:
015dc7e1 14884 return false;
03336641
JW
14885 }
14886}
14887
14888/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14889 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14890
015dc7e1 14891static bool
03336641
JW
14892is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14893{
14894 /* Please keep this table alpha-sorted for ease of visual lookup. */
14895 switch (filedata->file_header.e_machine)
14896 {
76244462 14897 case EM_LOONGARCH:
14898 return reloc_type == 47; /* R_LARCH_ADD8. */
03336641
JW
14899 case EM_RISCV:
14900 return reloc_type == 33; /* R_RISCV_ADD8. */
14901 default:
015dc7e1 14902 return false;
03336641
JW
14903 }
14904}
14905
14906/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14907 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14908
015dc7e1 14909static bool
03336641
JW
14910is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14911{
14912 /* Please keep this table alpha-sorted for ease of visual lookup. */
14913 switch (filedata->file_header.e_machine)
14914 {
76244462 14915 case EM_LOONGARCH:
14916 return reloc_type == 52; /* R_LARCH_SUB8. */
03336641
JW
14917 case EM_RISCV:
14918 return reloc_type == 37; /* R_RISCV_SUB8. */
14919 default:
015dc7e1 14920 return false;
03336641
JW
14921 }
14922}
14923
76244462 14924/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14925 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
14926
14927static bool
14928is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14929{
14930 switch (filedata->file_header.e_machine)
14931 {
14932 case EM_LOONGARCH:
14933 return reloc_type == 105; /* R_LARCH_ADD6. */
14934 default:
14935 return false;
14936 }
14937}
14938
39e07931
AS
14939/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14940 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14941
015dc7e1 14942static bool
39e07931
AS
14943is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14944{
14945 switch (filedata->file_header.e_machine)
14946 {
76244462 14947 case EM_LOONGARCH:
14948 return reloc_type == 106; /* R_LARCH_SUB6. */
39e07931
AS
14949 case EM_RISCV:
14950 return reloc_type == 52; /* R_RISCV_SUB6. */
14951 default:
015dc7e1 14952 return false;
39e07931
AS
14953 }
14954}
14955
2a7b2e88
JK
14956/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14957 relocation entries (possibly formerly used for SHT_GROUP sections). */
14958
015dc7e1 14959static bool
dda8d76d 14960is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14961{
dda8d76d 14962 switch (filedata->file_header.e_machine)
2a7b2e88 14963 {
cb8f3167 14964 case EM_386: /* R_386_NONE. */
d347c9df 14965 case EM_68K: /* R_68K_NONE. */
cfb8c092 14966 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14967 case EM_ALPHA: /* R_ALPHA_NONE. */
14968 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14969 case EM_ARC: /* R_ARC_NONE. */
886a2506 14970 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14971 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14972 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 14973 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14974 case EM_FT32: /* R_FT32_NONE. */
14975 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14976 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14977 case EM_L1OM: /* R_X86_64_NONE. */
14978 case EM_M32R: /* R_M32R_NONE. */
14979 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14980 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14981 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14982 case EM_NIOS32: /* R_NIOS_NONE. */
14983 case EM_OR1K: /* R_OR1K_NONE. */
14984 case EM_PARISC: /* R_PARISC_NONE. */
14985 case EM_PPC64: /* R_PPC64_NONE. */
14986 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14987 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14988 case EM_S390: /* R_390_NONE. */
14989 case EM_S390_OLD:
14990 case EM_SH: /* R_SH_NONE. */
14991 case EM_SPARC32PLUS:
14992 case EM_SPARC: /* R_SPARC_NONE. */
14993 case EM_SPARCV9:
aa137e4d
NC
14994 case EM_TILEGX: /* R_TILEGX_NONE. */
14995 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14996 case EM_TI_C6000:/* R_C6000_NONE. */
14997 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 14998 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14999 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 15000 return reloc_type == 0;
d347c9df 15001
a06ea964
NC
15002 case EM_AARCH64:
15003 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
15004 case EM_AVR_OLD:
15005 case EM_AVR:
15006 return (reloc_type == 0 /* R_AVR_NONE. */
15007 || reloc_type == 30 /* R_AVR_DIFF8. */
15008 || reloc_type == 31 /* R_AVR_DIFF16. */
15009 || reloc_type == 32 /* R_AVR_DIFF32. */);
15010 case EM_METAG:
15011 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 15012 case EM_NDS32:
81c5e376
AM
15013 return (reloc_type == 0 /* R_NDS32_NONE. */
15014 || reloc_type == 205 /* R_NDS32_DIFF8. */
15015 || reloc_type == 206 /* R_NDS32_DIFF16. */
15016 || reloc_type == 207 /* R_NDS32_DIFF32. */
15017 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
15018 case EM_TI_PRU:
15019 return (reloc_type == 0 /* R_PRU_NONE. */
15020 || reloc_type == 65 /* R_PRU_DIFF8. */
15021 || reloc_type == 66 /* R_PRU_DIFF16. */
15022 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
15023 case EM_XTENSA_OLD:
15024 case EM_XTENSA:
4dc3c23d
AM
15025 return (reloc_type == 0 /* R_XTENSA_NONE. */
15026 || reloc_type == 17 /* R_XTENSA_DIFF8. */
15027 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
15028 || reloc_type == 19 /* R_XTENSA_DIFF32. */
15029 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
15030 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
15031 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
15032 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
15033 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
15034 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 15035 }
015dc7e1 15036 return false;
2a7b2e88
JK
15037}
15038
d1c4b12b
NC
15039/* Returns TRUE if there is a relocation against
15040 section NAME at OFFSET bytes. */
15041
015dc7e1 15042bool
31e5a3a3 15043reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
15044{
15045 Elf_Internal_Rela * relocs;
15046 Elf_Internal_Rela * rp;
15047
15048 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 15049 return false;
d1c4b12b
NC
15050
15051 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
15052
15053 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
15054 if (rp->r_offset == offset)
015dc7e1 15055 return true;
d1c4b12b 15056
015dc7e1 15057 return false;
d1c4b12b
NC
15058}
15059
cf13d699 15060/* Apply relocations to a section.
32ec8896
NC
15061 Returns TRUE upon success, FALSE otherwise.
15062 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
15063 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
15064 will be set to the number of relocs loaded.
15065
cf13d699 15066 Note: So far support has been added only for those relocations
32ec8896
NC
15067 which can be found in debug sections. FIXME: Add support for
15068 more relocations ? */
1b315056 15069
015dc7e1 15070static bool
be7d229a
AM
15071apply_relocations (Filedata *filedata,
15072 const Elf_Internal_Shdr *section,
15073 unsigned char *start,
15074 size_t size,
15075 void **relocs_return,
26c527e6 15076 uint64_t *num_relocs_return)
1b315056 15077{
cf13d699 15078 Elf_Internal_Shdr * relsec;
0d2a7a93 15079 unsigned char * end = start + size;
cb8f3167 15080
d1c4b12b
NC
15081 if (relocs_return != NULL)
15082 {
15083 * (Elf_Internal_Rela **) relocs_return = NULL;
15084 * num_relocs_return = 0;
15085 }
15086
dda8d76d 15087 if (filedata->file_header.e_type != ET_REL)
32ec8896 15088 /* No relocs to apply. */
015dc7e1 15089 return true;
1b315056 15090
cf13d699 15091 /* Find the reloc section associated with the section. */
dda8d76d
NC
15092 for (relsec = filedata->section_headers;
15093 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 15094 ++relsec)
252b5132 15095 {
015dc7e1 15096 bool is_rela;
26c527e6 15097 uint64_t num_relocs;
2cf0635d
NC
15098 Elf_Internal_Rela * relocs;
15099 Elf_Internal_Rela * rp;
15100 Elf_Internal_Shdr * symsec;
15101 Elf_Internal_Sym * symtab;
26c527e6 15102 uint64_t num_syms;
2cf0635d 15103 Elf_Internal_Sym * sym;
252b5132 15104
41e92641 15105 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15106 || relsec->sh_info >= filedata->file_header.e_shnum
15107 || filedata->section_headers + relsec->sh_info != section
c256ffe7 15108 || relsec->sh_size == 0
dda8d76d 15109 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 15110 continue;
428409d5 15111
a788aedd
AM
15112 symsec = filedata->section_headers + relsec->sh_link;
15113 if (symsec->sh_type != SHT_SYMTAB
15114 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 15115 return false;
a788aedd 15116
41e92641
NC
15117 is_rela = relsec->sh_type == SHT_RELA;
15118
15119 if (is_rela)
15120 {
dda8d76d 15121 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 15122 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15123 return false;
41e92641
NC
15124 }
15125 else
15126 {
dda8d76d 15127 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 15128 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15129 return false;
41e92641
NC
15130 }
15131
15132 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 15133 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 15134 is_rela = false;
428409d5 15135
4de91c10 15136 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 15137
41e92641 15138 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 15139 {
625d49fc 15140 uint64_t addend;
015dc7e1
AM
15141 unsigned int reloc_type;
15142 unsigned int reloc_size;
15143 bool reloc_inplace = false;
15144 bool reloc_subtract = false;
15145 unsigned char *rloc;
26c527e6 15146 uint64_t sym_index;
4b78141a 15147
dda8d76d 15148 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 15149
dda8d76d 15150 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 15151 continue;
dda8d76d 15152 else if (is_none_reloc (filedata, reloc_type))
98fb390a 15153 continue;
dda8d76d
NC
15154 else if (is_32bit_abs_reloc (filedata, reloc_type)
15155 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 15156 reloc_size = 4;
dda8d76d
NC
15157 else if (is_64bit_abs_reloc (filedata, reloc_type)
15158 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 15159 reloc_size = 8;
dda8d76d 15160 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15161 reloc_size = 3;
dda8d76d 15162 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15163 reloc_size = 2;
39e07931
AS
15164 else if (is_8bit_abs_reloc (filedata, reloc_type)
15165 || is_6bit_abs_reloc (filedata, reloc_type))
15166 reloc_size = 1;
03336641
JW
15167 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15168 reloc_type))
15169 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15170 {
15171 reloc_size = 4;
015dc7e1 15172 reloc_inplace = true;
03336641
JW
15173 }
15174 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15175 reloc_type))
15176 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15177 {
15178 reloc_size = 8;
015dc7e1 15179 reloc_inplace = true;
03336641
JW
15180 }
15181 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15182 reloc_type))
15183 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15184 {
15185 reloc_size = 2;
015dc7e1 15186 reloc_inplace = true;
03336641
JW
15187 }
15188 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15189 reloc_type))
15190 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15191 {
15192 reloc_size = 1;
015dc7e1 15193 reloc_inplace = true;
03336641 15194 }
39e07931 15195 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
76244462 15196 reloc_type))
15197 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15198 {
15199 reloc_size = 1;
015dc7e1 15200 reloc_inplace = true;
39e07931 15201 }
aca88567 15202 else
4b78141a 15203 {
bee0ee85 15204 static unsigned int prev_reloc = 0;
dda8d76d 15205
bee0ee85
NC
15206 if (reloc_type != prev_reloc)
15207 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15208 reloc_type, printable_section_name (filedata, section));
bee0ee85 15209 prev_reloc = reloc_type;
4b78141a
NC
15210 continue;
15211 }
103f02d3 15212
91d6fa6a 15213 rloc = start + rp->r_offset;
75802ccb 15214 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 15215 {
26c527e6
AM
15216 warn (_("skipping invalid relocation offset %#" PRIx64
15217 " in section %s\n"),
15218 rp->r_offset,
dda8d76d 15219 printable_section_name (filedata, section));
700dd8b7
L
15220 continue;
15221 }
103f02d3 15222
26c527e6 15223 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
15224 if (sym_index >= num_syms)
15225 {
26c527e6
AM
15226 warn (_("skipping invalid relocation symbol index %#" PRIx64
15227 " in section %s\n"),
dda8d76d 15228 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15229 continue;
15230 }
15231 sym = symtab + sym_index;
41e92641
NC
15232
15233 /* If the reloc has a symbol associated with it,
55f25fc3
L
15234 make sure that it is of an appropriate type.
15235
15236 Relocations against symbols without type can happen.
15237 Gcc -feliminate-dwarf2-dups may generate symbols
15238 without type for debug info.
15239
15240 Icc generates relocations against function symbols
15241 instead of local labels.
15242
15243 Relocations against object symbols can happen, eg when
15244 referencing a global array. For an example of this see
15245 the _clz.o binary in libgcc.a. */
aca88567 15246 if (sym != symtab
b8871f35 15247 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15248 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15249 {
26c527e6 15250 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
15251 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15252 printable_section_name (filedata, relsec),
26c527e6 15253 rp - relocs);
aca88567 15254 continue;
5b18a4bc 15255 }
252b5132 15256
4dc3c23d
AM
15257 addend = 0;
15258 if (is_rela)
15259 addend += rp->r_addend;
c47320c3
AM
15260 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15261 partial_inplace. */
4dc3c23d 15262 if (!is_rela
dda8d76d 15263 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15264 && reloc_type == 1)
dda8d76d
NC
15265 || ((filedata->file_header.e_machine == EM_PJ
15266 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15267 && reloc_type == 1)
dda8d76d
NC
15268 || ((filedata->file_header.e_machine == EM_D30V
15269 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15270 && reloc_type == 12)
15271 || reloc_inplace)
39e07931
AS
15272 {
15273 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15274 addend += byte_get (rloc, reloc_size) & 0x3f;
15275 else
15276 addend += byte_get (rloc, reloc_size);
15277 }
cb8f3167 15278
dda8d76d
NC
15279 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15280 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15281 {
15282 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15283 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15284 addend -= 8;
91d6fa6a 15285 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15286 reloc_size);
15287 }
39e07931 15288 else if (is_6bit_abs_reloc (filedata, reloc_type)
76244462 15289 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
15290 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15291 {
15292 if (reloc_subtract)
15293 addend -= sym->st_value;
15294 else
15295 addend += sym->st_value;
15296 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15297 byte_put (rloc, addend, reloc_size);
15298 }
03336641
JW
15299 else if (reloc_subtract)
15300 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15301 else
91d6fa6a 15302 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15303 }
252b5132 15304
5b18a4bc 15305 free (symtab);
f84ce13b
NC
15306 /* Let the target specific reloc processing code know that
15307 we have finished with these relocs. */
dda8d76d 15308 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15309
15310 if (relocs_return)
15311 {
15312 * (Elf_Internal_Rela **) relocs_return = relocs;
15313 * num_relocs_return = num_relocs;
15314 }
15315 else
15316 free (relocs);
15317
5b18a4bc
NC
15318 break;
15319 }
32ec8896 15320
015dc7e1 15321 return true;
5b18a4bc 15322}
103f02d3 15323
cf13d699 15324#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15325static bool
dda8d76d 15326disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15327{
dda8d76d 15328 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15329
74e1a04b 15330 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15331
015dc7e1 15332 return true;
cf13d699
NC
15333}
15334#endif
15335
15336/* Reads in the contents of SECTION from FILE, returning a pointer
15337 to a malloc'ed buffer or NULL if something went wrong. */
15338
15339static char *
dda8d76d 15340get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15341{
be7d229a 15342 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15343
15344 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15345 {
c6b78c96 15346 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15347 printable_section_name (filedata, section));
cf13d699
NC
15348 return NULL;
15349 }
15350
dda8d76d 15351 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15352 _("section contents"));
cf13d699
NC
15353}
15354
1f5a3546 15355/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 15356
015dc7e1 15357static bool
45f5fe46
NC
15358uncompress_section_contents (bool is_zstd,
15359 unsigned char ** buffer,
15360 uint64_t uncompressed_size,
15361 uint64_t * size,
15362 uint64_t file_size)
0e602686 15363{
31e5a3a3
AM
15364 uint64_t compressed_size = *size;
15365 unsigned char *compressed_buffer = *buffer;
45f5fe46 15366 unsigned char *uncompressed_buffer = NULL;
0e602686
NC
15367 z_stream strm;
15368 int rc;
15369
45f5fe46
NC
15370 /* Similar to _bfd_section_size_insane() in the BFD library we expect an
15371 upper limit of ~10x compression. Any compression larger than that is
15372 thought to be due to fuzzing of the compression header. */
15373 if (uncompressed_size > file_size * 10)
15374 {
15375 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
15376 uncompressed_size);
15377 goto fail;
15378 }
15379
15380 uncompressed_buffer = xmalloc (uncompressed_size);
15381
1f5a3546
FS
15382 if (is_zstd)
15383 {
15384#ifdef HAVE_ZSTD
15385 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15386 compressed_buffer, compressed_size);
15387 if (ZSTD_isError (ret))
15388 goto fail;
15389#endif
15390 }
15391 else
15392 {
15393 /* It is possible the section consists of several compressed
15394 buffers concatenated together, so we uncompress in a loop. */
15395 /* PR 18313: The state field in the z_stream structure is supposed
15396 to be invisible to the user (ie us), but some compilers will
15397 still complain about it being used without initialisation. So
15398 we first zero the entire z_stream structure and then set the fields
15399 that we need. */
15400 memset (&strm, 0, sizeof strm);
15401 strm.avail_in = compressed_size;
15402 strm.next_in = (Bytef *)compressed_buffer;
15403 strm.avail_out = uncompressed_size;
15404
15405 rc = inflateInit (&strm);
15406 while (strm.avail_in > 0)
15407 {
15408 if (rc != Z_OK)
15409 break;
15410 strm.next_out = ((Bytef *)uncompressed_buffer
15411 + (uncompressed_size - strm.avail_out));
15412 rc = inflate (&strm, Z_FINISH);
15413 if (rc != Z_STREAM_END)
15414 break;
15415 rc = inflateReset (&strm);
15416 }
15417 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15418 goto fail;
15419 }
0e602686
NC
15420
15421 *buffer = uncompressed_buffer;
15422 *size = uncompressed_size;
015dc7e1 15423 return true;
0e602686
NC
15424
15425 fail:
15426 free (uncompressed_buffer);
15427 /* Indicate decompression failure. */
15428 *buffer = NULL;
015dc7e1 15429 return false;
0e602686 15430}
dd24e3da 15431
015dc7e1 15432static bool
dda8d76d 15433dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15434{
015dc7e1 15435 Elf_Internal_Shdr *relsec;
be7d229a 15436 uint64_t num_bytes;
015dc7e1
AM
15437 unsigned char *data;
15438 unsigned char *end;
15439 unsigned char *real_start;
15440 unsigned char *start;
15441 bool some_strings_shown;
cf13d699 15442
dda8d76d 15443 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15444 if (start == NULL)
c6b78c96 15445 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15446 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15447
0e602686 15448 num_bytes = section->sh_size;
cf13d699 15449
835f2fae
NC
15450 if (filedata->is_separate)
15451 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15452 printable_section_name (filedata, section),
15453 filedata->file_name);
15454 else
15455 printf (_("\nString dump of section '%s':\n"),
15456 printable_section_name (filedata, section));
cf13d699 15457
0e602686
NC
15458 if (decompress_dumps)
15459 {
31e5a3a3
AM
15460 uint64_t new_size = num_bytes;
15461 uint64_t uncompressed_size = 0;
1f5a3546 15462 bool is_zstd = false;
0e602686
NC
15463
15464 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15465 {
15466 Elf_Internal_Chdr chdr;
15467 unsigned int compression_header_size
ebdf1ebf
NC
15468 = get_compression_header (& chdr, (unsigned char *) start,
15469 num_bytes);
5844b465
NC
15470 if (compression_header_size == 0)
15471 /* An error message will have already been generated
15472 by get_compression_header. */
15473 goto error_out;
0e602686 15474
89dbeac7 15475 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
15476 ;
15477#ifdef HAVE_ZSTD
89dbeac7 15478 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
15479 is_zstd = true;
15480#endif
15481 else
0e602686 15482 {
813dabb9 15483 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15484 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15485 goto error_out;
813dabb9 15486 }
813dabb9
L
15487 uncompressed_size = chdr.ch_size;
15488 start += compression_header_size;
15489 new_size -= compression_header_size;
0e602686
NC
15490 }
15491 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15492 {
15493 /* Read the zlib header. In this case, it should be "ZLIB"
15494 followed by the uncompressed section size, 8 bytes in
15495 big-endian order. */
15496 uncompressed_size = start[4]; uncompressed_size <<= 8;
15497 uncompressed_size += start[5]; uncompressed_size <<= 8;
15498 uncompressed_size += start[6]; uncompressed_size <<= 8;
15499 uncompressed_size += start[7]; uncompressed_size <<= 8;
15500 uncompressed_size += start[8]; uncompressed_size <<= 8;
15501 uncompressed_size += start[9]; uncompressed_size <<= 8;
15502 uncompressed_size += start[10]; uncompressed_size <<= 8;
15503 uncompressed_size += start[11];
15504 start += 12;
15505 new_size -= 12;
15506 }
15507
1835f746
NC
15508 if (uncompressed_size)
15509 {
1f5a3546 15510 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 15511 &new_size, filedata->file_size))
1835f746
NC
15512 num_bytes = new_size;
15513 else
15514 {
15515 error (_("Unable to decompress section %s\n"),
dda8d76d 15516 printable_section_name (filedata, section));
f761cb13 15517 goto error_out;
1835f746
NC
15518 }
15519 }
bc303e5d
NC
15520 else
15521 start = real_start;
0e602686 15522 }
fd8008d8 15523
cf13d699
NC
15524 /* If the section being dumped has relocations against it the user might
15525 be expecting these relocations to have been applied. Check for this
15526 case and issue a warning message in order to avoid confusion.
15527 FIXME: Maybe we ought to have an option that dumps a section with
15528 relocs applied ? */
dda8d76d
NC
15529 for (relsec = filedata->section_headers;
15530 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15531 ++relsec)
15532 {
15533 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15534 || relsec->sh_info >= filedata->file_header.e_shnum
15535 || filedata->section_headers + relsec->sh_info != section
cf13d699 15536 || relsec->sh_size == 0
dda8d76d 15537 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15538 continue;
15539
15540 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15541 break;
15542 }
15543
cf13d699
NC
15544 data = start;
15545 end = start + num_bytes;
015dc7e1 15546 some_strings_shown = false;
cf13d699 15547
ba3265d0
NC
15548#ifdef HAVE_MBSTATE_T
15549 mbstate_t state;
15550 /* Initialise the multibyte conversion state. */
15551 memset (& state, 0, sizeof (state));
15552#endif
15553
015dc7e1 15554 bool continuing = false;
ba3265d0 15555
cf13d699
NC
15556 while (data < end)
15557 {
15558 while (!ISPRINT (* data))
15559 if (++ data >= end)
15560 break;
15561
15562 if (data < end)
15563 {
071436c6
NC
15564 size_t maxlen = end - data;
15565
ba3265d0
NC
15566 if (continuing)
15567 {
15568 printf (" ");
015dc7e1 15569 continuing = false;
ba3265d0
NC
15570 }
15571 else
15572 {
26c527e6 15573 printf (" [%6tx] ", data - start);
ba3265d0
NC
15574 }
15575
4082ef84
NC
15576 if (maxlen > 0)
15577 {
f3da8a96 15578 char c = 0;
ba3265d0
NC
15579
15580 while (maxlen)
15581 {
15582 c = *data++;
15583
15584 if (c == 0)
15585 break;
15586
15587 /* PR 25543: Treat new-lines as string-ending characters. */
15588 if (c == '\n')
15589 {
15590 printf ("\\n\n");
15591 if (*data != 0)
015dc7e1 15592 continuing = true;
ba3265d0
NC
15593 break;
15594 }
15595
15596 /* Do not print control characters directly as they can affect terminal
15597 settings. Such characters usually appear in the names generated
15598 by the assembler for local labels. */
15599 if (ISCNTRL (c))
15600 {
15601 printf ("^%c", c + 0x40);
15602 }
15603 else if (ISPRINT (c))
15604 {
15605 putchar (c);
15606 }
15607 else
15608 {
15609 size_t n;
15610#ifdef HAVE_MBSTATE_T
15611 wchar_t w;
15612#endif
15613 /* Let printf do the hard work of displaying multibyte characters. */
15614 printf ("%.1s", data - 1);
15615#ifdef HAVE_MBSTATE_T
15616 /* Try to find out how many bytes made up the character that was
15617 just printed. Advance the symbol pointer past the bytes that
15618 were displayed. */
15619 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15620#else
15621 n = 1;
15622#endif
15623 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15624 data += (n - 1);
15625 }
15626 }
15627
15628 if (c != '\n')
15629 putchar ('\n');
4082ef84
NC
15630 }
15631 else
15632 {
15633 printf (_("<corrupt>\n"));
15634 data = end;
15635 }
015dc7e1 15636 some_strings_shown = true;
cf13d699
NC
15637 }
15638 }
15639
15640 if (! some_strings_shown)
15641 printf (_(" No strings found in this section."));
15642
0e602686 15643 free (real_start);
cf13d699
NC
15644
15645 putchar ('\n');
015dc7e1 15646 return true;
f761cb13
AM
15647
15648error_out:
15649 free (real_start);
015dc7e1 15650 return false;
cf13d699
NC
15651}
15652
015dc7e1
AM
15653static bool
15654dump_section_as_bytes (Elf_Internal_Shdr *section,
15655 Filedata *filedata,
15656 bool relocate)
cf13d699 15657{
be7d229a
AM
15658 Elf_Internal_Shdr *relsec;
15659 size_t bytes;
15660 uint64_t section_size;
625d49fc 15661 uint64_t addr;
be7d229a
AM
15662 unsigned char *data;
15663 unsigned char *real_start;
15664 unsigned char *start;
0e602686 15665
dda8d76d 15666 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15667 if (start == NULL)
c6b78c96 15668 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15669 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15670
0e602686 15671 section_size = section->sh_size;
cf13d699 15672
835f2fae
NC
15673 if (filedata->is_separate)
15674 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15675 printable_section_name (filedata, section),
15676 filedata->file_name);
15677 else
15678 printf (_("\nHex dump of section '%s':\n"),
15679 printable_section_name (filedata, section));
cf13d699 15680
0e602686
NC
15681 if (decompress_dumps)
15682 {
31e5a3a3
AM
15683 uint64_t new_size = section_size;
15684 uint64_t uncompressed_size = 0;
1f5a3546 15685 bool is_zstd = false;
0e602686
NC
15686
15687 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15688 {
15689 Elf_Internal_Chdr chdr;
15690 unsigned int compression_header_size
ebdf1ebf 15691 = get_compression_header (& chdr, start, section_size);
0e602686 15692
5844b465
NC
15693 if (compression_header_size == 0)
15694 /* An error message will have already been generated
15695 by get_compression_header. */
15696 goto error_out;
15697
89dbeac7 15698 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
15699 ;
15700#ifdef HAVE_ZSTD
89dbeac7 15701 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
15702 is_zstd = true;
15703#endif
15704 else
0e602686 15705 {
813dabb9 15706 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15707 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15708 goto error_out;
0e602686 15709 }
813dabb9
L
15710 uncompressed_size = chdr.ch_size;
15711 start += compression_header_size;
15712 new_size -= compression_header_size;
0e602686
NC
15713 }
15714 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15715 {
15716 /* Read the zlib header. In this case, it should be "ZLIB"
15717 followed by the uncompressed section size, 8 bytes in
15718 big-endian order. */
15719 uncompressed_size = start[4]; uncompressed_size <<= 8;
15720 uncompressed_size += start[5]; uncompressed_size <<= 8;
15721 uncompressed_size += start[6]; uncompressed_size <<= 8;
15722 uncompressed_size += start[7]; uncompressed_size <<= 8;
15723 uncompressed_size += start[8]; uncompressed_size <<= 8;
15724 uncompressed_size += start[9]; uncompressed_size <<= 8;
15725 uncompressed_size += start[10]; uncompressed_size <<= 8;
15726 uncompressed_size += start[11];
15727 start += 12;
15728 new_size -= 12;
15729 }
15730
f055032e
NC
15731 if (uncompressed_size)
15732 {
1f5a3546 15733 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 15734 &new_size, filedata->file_size))
bc303e5d
NC
15735 {
15736 section_size = new_size;
15737 }
f055032e
NC
15738 else
15739 {
15740 error (_("Unable to decompress section %s\n"),
dda8d76d 15741 printable_section_name (filedata, section));
bc303e5d 15742 /* FIXME: Print the section anyway ? */
f761cb13 15743 goto error_out;
f055032e
NC
15744 }
15745 }
bc303e5d
NC
15746 else
15747 start = real_start;
0e602686 15748 }
14ae95f2 15749
cf13d699
NC
15750 if (relocate)
15751 {
dda8d76d 15752 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15753 goto error_out;
cf13d699
NC
15754 }
15755 else
15756 {
15757 /* If the section being dumped has relocations against it the user might
15758 be expecting these relocations to have been applied. Check for this
15759 case and issue a warning message in order to avoid confusion.
15760 FIXME: Maybe we ought to have an option that dumps a section with
15761 relocs applied ? */
dda8d76d
NC
15762 for (relsec = filedata->section_headers;
15763 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15764 ++relsec)
15765 {
15766 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15767 || relsec->sh_info >= filedata->file_header.e_shnum
15768 || filedata->section_headers + relsec->sh_info != section
cf13d699 15769 || relsec->sh_size == 0
dda8d76d 15770 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15771 continue;
15772
15773 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15774 break;
15775 }
15776 }
15777
15778 addr = section->sh_addr;
0e602686 15779 bytes = section_size;
cf13d699
NC
15780 data = start;
15781
15782 while (bytes)
15783 {
15784 int j;
15785 int k;
15786 int lbytes;
15787
15788 lbytes = (bytes > 16 ? 16 : bytes);
15789
26c527e6 15790 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
15791
15792 for (j = 0; j < 16; j++)
15793 {
15794 if (j < lbytes)
15795 printf ("%2.2x", data[j]);
15796 else
15797 printf (" ");
15798
15799 if ((j & 3) == 3)
15800 printf (" ");
15801 }
15802
15803 for (j = 0; j < lbytes; j++)
15804 {
15805 k = data[j];
15806 if (k >= ' ' && k < 0x7f)
15807 printf ("%c", k);
15808 else
15809 printf (".");
15810 }
15811
15812 putchar ('\n');
15813
15814 data += lbytes;
15815 addr += lbytes;
15816 bytes -= lbytes;
15817 }
15818
0e602686 15819 free (real_start);
cf13d699
NC
15820
15821 putchar ('\n');
015dc7e1 15822 return true;
f761cb13
AM
15823
15824 error_out:
15825 free (real_start);
015dc7e1 15826 return false;
cf13d699
NC
15827}
15828
094e34f2 15829#ifdef ENABLE_LIBCTF
7d9813f1
NA
15830static ctf_sect_t *
15831shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15832{
84714f86 15833 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15834 buf->cts_size = shdr->sh_size;
15835 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15836
15837 return buf;
15838}
15839
15840/* Formatting callback function passed to ctf_dump. Returns either the pointer
15841 it is passed, or a pointer to newly-allocated storage, in which case
15842 dump_ctf() will free it when it no longer needs it. */
15843
2f6ecaed
NA
15844static char *
15845dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15846 char *s, void *arg)
7d9813f1 15847{
3e50a591 15848 const char *blanks = arg;
7d9813f1
NA
15849 char *new_s;
15850
3e50a591 15851 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15852 return s;
15853 return new_s;
15854}
15855
926c9e76
NA
15856/* Dump CTF errors/warnings. */
15857static void
139633c3 15858dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15859{
15860 ctf_next_t *it = NULL;
15861 char *errtext;
15862 int is_warning;
15863 int err;
15864
15865 /* Dump accumulated errors and warnings. */
15866 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15867 {
5e9b84f7 15868 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15869 errtext);
15870 free (errtext);
15871 }
15872 if (err != ECTF_NEXT_END)
15873 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15874}
15875
2f6ecaed
NA
15876/* Dump one CTF archive member. */
15877
80b56fad
NA
15878static void
15879dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15880 size_t member)
2f6ecaed 15881{
2f6ecaed
NA
15882 const char *things[] = {"Header", "Labels", "Data objects",
15883 "Function objects", "Variables", "Types", "Strings",
15884 ""};
15885 const char **thing;
15886 size_t i;
15887
80b56fad
NA
15888 /* Don't print out the name of the default-named archive member if it appears
15889 first in the list. The name .ctf appears everywhere, even for things that
15890 aren't really archives, so printing it out is liable to be confusing; also,
15891 the common case by far is for only one archive member to exist, and hiding
15892 it in that case seems worthwhile. */
2f6ecaed 15893
80b56fad
NA
15894 if (strcmp (name, ".ctf") != 0 || member != 0)
15895 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15896
80b56fad
NA
15897 if (ctf_parent_name (ctf) != NULL)
15898 ctf_import (ctf, parent);
2f6ecaed
NA
15899
15900 for (i = 0, thing = things; *thing[0]; thing++, i++)
15901 {
15902 ctf_dump_state_t *s = NULL;
15903 char *item;
15904
15905 printf ("\n %s:\n", *thing);
15906 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15907 (void *) " ")) != NULL)
15908 {
15909 printf ("%s\n", item);
15910 free (item);
15911 }
15912
15913 if (ctf_errno (ctf))
15914 {
15915 error (_("Iteration failed: %s, %s\n"), *thing,
15916 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15917 break;
2f6ecaed
NA
15918 }
15919 }
8b37e7b6 15920
926c9e76 15921 dump_ctf_errs (ctf);
2f6ecaed
NA
15922}
15923
015dc7e1 15924static bool
7d9813f1
NA
15925dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15926{
7d9813f1
NA
15927 Elf_Internal_Shdr * symtab_sec = NULL;
15928 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15929 void * data = NULL;
15930 void * symdata = NULL;
15931 void * strdata = NULL;
80b56fad 15932 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15933 ctf_sect_t * symsectp = NULL;
15934 ctf_sect_t * strsectp = NULL;
2f6ecaed 15935 ctf_archive_t * ctfa = NULL;
139633c3 15936 ctf_dict_t * parent = NULL;
80b56fad 15937 ctf_dict_t * fp;
7d9813f1 15938
80b56fad
NA
15939 ctf_next_t *i = NULL;
15940 const char *name;
15941 size_t member = 0;
7d9813f1 15942 int err;
015dc7e1 15943 bool ret = false;
7d9813f1
NA
15944
15945 shdr_to_ctf_sect (&ctfsect, section, filedata);
15946 data = get_section_contents (section, filedata);
15947 ctfsect.cts_data = data;
15948
616febde 15949 if (!dump_ctf_symtab_name)
3d16b64e 15950 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15951
15952 if (!dump_ctf_strtab_name)
3d16b64e 15953 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15954
15955 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15956 {
15957 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15958 {
15959 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15960 goto fail;
15961 }
15962 if ((symdata = (void *) get_data (NULL, filedata,
15963 symtab_sec->sh_offset, 1,
15964 symtab_sec->sh_size,
15965 _("symbols"))) == NULL)
15966 goto fail;
15967 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15968 symsect.cts_data = symdata;
15969 }
835f2fae 15970
df16e041 15971 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15972 {
15973 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15974 {
15975 error (_("No string table section named %s\n"),
15976 dump_ctf_strtab_name);
15977 goto fail;
15978 }
15979 if ((strdata = (void *) get_data (NULL, filedata,
15980 strtab_sec->sh_offset, 1,
15981 strtab_sec->sh_size,
15982 _("strings"))) == NULL)
15983 goto fail;
15984 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15985 strsect.cts_data = strdata;
15986 }
835f2fae 15987
2f6ecaed
NA
15988 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15989 libctf papers over the difference, so we can pretend it is always an
80b56fad 15990 archive. */
7d9813f1 15991
2f6ecaed 15992 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15993 {
926c9e76 15994 dump_ctf_errs (NULL);
7d9813f1
NA
15995 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15996 goto fail;
15997 }
15998
96c61be5
NA
15999 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
16000 != ELFDATA2MSB);
16001
80b56fad
NA
16002 /* Preload the parent dict, since it will need to be imported into every
16003 child in turn. */
16004 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 16005 {
926c9e76 16006 dump_ctf_errs (NULL);
2f6ecaed
NA
16007 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16008 goto fail;
7d9813f1
NA
16009 }
16010
015dc7e1 16011 ret = true;
7d9813f1 16012
835f2fae
NC
16013 if (filedata->is_separate)
16014 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
16015 printable_section_name (filedata, section),
16016 filedata->file_name);
16017 else
16018 printf (_("\nDump of CTF section '%s':\n"),
16019 printable_section_name (filedata, section));
7d9813f1 16020
80b56fad
NA
16021 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
16022 dump_ctf_archive_member (fp, name, parent, member++);
16023 if (err != ECTF_NEXT_END)
16024 {
16025 dump_ctf_errs (NULL);
16026 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
16027 ret = false;
16028 }
7d9813f1
NA
16029
16030 fail:
139633c3 16031 ctf_dict_close (parent);
2f6ecaed 16032 ctf_close (ctfa);
7d9813f1
NA
16033 free (data);
16034 free (symdata);
16035 free (strdata);
16036 return ret;
16037}
094e34f2 16038#endif
7d9813f1 16039
42b6953b
IB
16040static bool
16041dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
16042{
16043 void * data = NULL;
16044 sframe_decoder_ctx *sfd_ctx = NULL;
16045 const char *print_name = printable_section_name (filedata, section);
16046
16047 bool ret = true;
16048 size_t sf_size;
16049 int err = 0;
16050
16051 if (strcmp (print_name, "") == 0)
16052 {
16053 error (_("Section name must be provided \n"));
16054 ret = false;
16055 return ret;
16056 }
16057
16058 data = get_section_contents (section, filedata);
16059 sf_size = section->sh_size;
16060 /* Decode the contents of the section. */
16061 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
16062 if (!sfd_ctx)
16063 {
16064 ret = false;
16065 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
16066 goto fail;
16067 }
16068
16069 printf (_("Contents of the SFrame section %s:"), print_name);
16070 /* Dump the contents as text. */
16071 dump_sframe (sfd_ctx, section->sh_addr);
16072
16073 fail:
16074 free (data);
16075 return ret;
16076}
16077
015dc7e1 16078static bool
dda8d76d
NC
16079load_specific_debug_section (enum dwarf_section_display_enum debug,
16080 const Elf_Internal_Shdr * sec,
16081 void * data)
1007acb3 16082{
2cf0635d 16083 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 16084 char buf [64];
dda8d76d 16085 Filedata * filedata = (Filedata *) data;
9abca702 16086
19e6b90e 16087 if (section->start != NULL)
dda8d76d
NC
16088 {
16089 /* If it is already loaded, do nothing. */
16090 if (streq (section->filename, filedata->file_name))
015dc7e1 16091 return true;
dda8d76d
NC
16092 free (section->start);
16093 }
1007acb3 16094
19e6b90e
L
16095 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16096 section->address = sec->sh_addr;
dda8d76d
NC
16097 section->filename = filedata->file_name;
16098 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
16099 sec->sh_offset, 1,
16100 sec->sh_size, buf);
59245841
NC
16101 if (section->start == NULL)
16102 section->size = 0;
16103 else
16104 {
77115a4a 16105 unsigned char *start = section->start;
31e5a3a3
AM
16106 uint64_t size = sec->sh_size;
16107 uint64_t uncompressed_size = 0;
1f5a3546 16108 bool is_zstd = false;
77115a4a
L
16109
16110 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16111 {
16112 Elf_Internal_Chdr chdr;
d8024a91
NC
16113 unsigned int compression_header_size;
16114
f53be977
L
16115 if (size < (is_32bit_elf
16116 ? sizeof (Elf32_External_Chdr)
16117 : sizeof (Elf64_External_Chdr)))
d8024a91 16118 {
55be8fd0 16119 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 16120 section->name);
015dc7e1 16121 return false;
d8024a91
NC
16122 }
16123
ebdf1ebf 16124 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
16125 if (compression_header_size == 0)
16126 /* An error message will have already been generated
16127 by get_compression_header. */
015dc7e1 16128 return false;
d8024a91 16129
89dbeac7 16130 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16131 ;
16132#ifdef HAVE_ZSTD
89dbeac7 16133 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16134 is_zstd = true;
16135#endif
16136 else
813dabb9
L
16137 {
16138 warn (_("section '%s' has unsupported compress type: %d\n"),
16139 section->name, chdr.ch_type);
015dc7e1 16140 return false;
813dabb9 16141 }
dab394de 16142 uncompressed_size = chdr.ch_size;
77115a4a
L
16143 start += compression_header_size;
16144 size -= compression_header_size;
16145 }
dab394de
L
16146 else if (size > 12 && streq ((char *) start, "ZLIB"))
16147 {
16148 /* Read the zlib header. In this case, it should be "ZLIB"
16149 followed by the uncompressed section size, 8 bytes in
16150 big-endian order. */
16151 uncompressed_size = start[4]; uncompressed_size <<= 8;
16152 uncompressed_size += start[5]; uncompressed_size <<= 8;
16153 uncompressed_size += start[6]; uncompressed_size <<= 8;
16154 uncompressed_size += start[7]; uncompressed_size <<= 8;
16155 uncompressed_size += start[8]; uncompressed_size <<= 8;
16156 uncompressed_size += start[9]; uncompressed_size <<= 8;
16157 uncompressed_size += start[10]; uncompressed_size <<= 8;
16158 uncompressed_size += start[11];
16159 start += 12;
16160 size -= 12;
16161 }
16162
1835f746 16163 if (uncompressed_size)
77115a4a 16164 {
1f5a3546 16165 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16166 &size, filedata->file_size))
1835f746
NC
16167 {
16168 /* Free the compressed buffer, update the section buffer
16169 and the section size if uncompress is successful. */
16170 free (section->start);
16171 section->start = start;
16172 }
16173 else
16174 {
16175 error (_("Unable to decompress section %s\n"),
dda8d76d 16176 printable_section_name (filedata, sec));
015dc7e1 16177 return false;
1835f746 16178 }
77115a4a 16179 }
bc303e5d 16180
77115a4a 16181 section->size = size;
59245841 16182 }
4a114e3e 16183
1b315056 16184 if (section->start == NULL)
015dc7e1 16185 return false;
1b315056 16186
19e6b90e 16187 if (debug_displays [debug].relocate)
32ec8896 16188 {
dda8d76d 16189 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 16190 & section->reloc_info, & section->num_relocs))
015dc7e1 16191 return false;
32ec8896 16192 }
d1c4b12b
NC
16193 else
16194 {
16195 section->reloc_info = NULL;
16196 section->num_relocs = 0;
16197 }
1007acb3 16198
015dc7e1 16199 return true;
1007acb3
L
16200}
16201
301a9420
AM
16202#if HAVE_LIBDEBUGINFOD
16203/* Return a hex string representation of the build-id. */
16204unsigned char *
16205get_build_id (void * data)
16206{
ca0e11aa 16207 Filedata * filedata = (Filedata *) data;
301a9420 16208 Elf_Internal_Shdr * shdr;
26c527e6 16209 size_t i;
301a9420 16210
55be8fd0
NC
16211 /* Iterate through notes to find note.gnu.build-id.
16212 FIXME: Only the first note in any note section is examined. */
301a9420
AM
16213 for (i = 0, shdr = filedata->section_headers;
16214 i < filedata->file_header.e_shnum && shdr != NULL;
16215 i++, shdr++)
16216 {
16217 if (shdr->sh_type != SHT_NOTE)
16218 continue;
16219
16220 char * next;
16221 char * end;
16222 size_t data_remaining;
16223 size_t min_notesz;
16224 Elf_External_Note * enote;
16225 Elf_Internal_Note inote;
16226
625d49fc
AM
16227 uint64_t offset = shdr->sh_offset;
16228 uint64_t align = shdr->sh_addralign;
16229 uint64_t length = shdr->sh_size;
301a9420
AM
16230
16231 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16232 if (enote == NULL)
16233 continue;
16234
16235 if (align < 4)
16236 align = 4;
16237 else if (align != 4 && align != 8)
f761cb13
AM
16238 {
16239 free (enote);
16240 continue;
16241 }
301a9420
AM
16242
16243 end = (char *) enote + length;
16244 data_remaining = end - (char *) enote;
16245
16246 if (!is_ia64_vms (filedata))
16247 {
16248 min_notesz = offsetof (Elf_External_Note, name);
16249 if (data_remaining < min_notesz)
16250 {
55be8fd0
NC
16251 warn (_("\
16252malformed note encountered in section %s whilst scanning for build-id note\n"),
16253 printable_section_name (filedata, shdr));
f761cb13 16254 free (enote);
55be8fd0 16255 continue;
301a9420
AM
16256 }
16257 data_remaining -= min_notesz;
16258
16259 inote.type = BYTE_GET (enote->type);
16260 inote.namesz = BYTE_GET (enote->namesz);
16261 inote.namedata = enote->name;
16262 inote.descsz = BYTE_GET (enote->descsz);
16263 inote.descdata = ((char *) enote
16264 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16265 inote.descpos = offset + (inote.descdata - (char *) enote);
16266 next = ((char *) enote
16267 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16268 }
16269 else
16270 {
16271 Elf64_External_VMS_Note *vms_enote;
16272
16273 /* PR binutils/15191
16274 Make sure that there is enough data to read. */
16275 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16276 if (data_remaining < min_notesz)
16277 {
55be8fd0
NC
16278 warn (_("\
16279malformed note encountered in section %s whilst scanning for build-id note\n"),
16280 printable_section_name (filedata, shdr));
f761cb13 16281 free (enote);
55be8fd0 16282 continue;
301a9420
AM
16283 }
16284 data_remaining -= min_notesz;
16285
16286 vms_enote = (Elf64_External_VMS_Note *) enote;
16287 inote.type = BYTE_GET (vms_enote->type);
16288 inote.namesz = BYTE_GET (vms_enote->namesz);
16289 inote.namedata = vms_enote->name;
16290 inote.descsz = BYTE_GET (vms_enote->descsz);
16291 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16292 inote.descpos = offset + (inote.descdata - (char *) enote);
16293 next = inote.descdata + align_power (inote.descsz, 3);
16294 }
16295
16296 /* Skip malformed notes. */
16297 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16298 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16299 || (size_t) (next - inote.descdata) < inote.descsz
16300 || ((size_t) (next - inote.descdata)
16301 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16302 {
55be8fd0
NC
16303 warn (_("\
16304malformed note encountered in section %s whilst scanning for build-id note\n"),
16305 printable_section_name (filedata, shdr));
f761cb13 16306 free (enote);
301a9420
AM
16307 continue;
16308 }
16309
16310 /* Check if this is the build-id note. If so then convert the build-id
16311 bytes to a hex string. */
16312 if (inote.namesz > 0
24d127aa 16313 && startswith (inote.namedata, "GNU")
301a9420
AM
16314 && inote.type == NT_GNU_BUILD_ID)
16315 {
26c527e6 16316 size_t j;
301a9420
AM
16317 char * build_id;
16318
16319 build_id = malloc (inote.descsz * 2 + 1);
16320 if (build_id == NULL)
f761cb13
AM
16321 {
16322 free (enote);
16323 return NULL;
16324 }
301a9420
AM
16325
16326 for (j = 0; j < inote.descsz; ++j)
16327 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16328 build_id[inote.descsz * 2] = '\0';
f761cb13 16329 free (enote);
301a9420 16330
55be8fd0 16331 return (unsigned char *) build_id;
301a9420 16332 }
f761cb13 16333 free (enote);
301a9420
AM
16334 }
16335
16336 return NULL;
16337}
16338#endif /* HAVE_LIBDEBUGINFOD */
16339
657d0d47
CC
16340/* If this is not NULL, load_debug_section will only look for sections
16341 within the list of sections given here. */
32ec8896 16342static unsigned int * section_subset = NULL;
657d0d47 16343
015dc7e1 16344bool
dda8d76d 16345load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16346{
2cf0635d
NC
16347 struct dwarf_section * section = &debug_displays [debug].section;
16348 Elf_Internal_Shdr * sec;
dda8d76d
NC
16349 Filedata * filedata = (Filedata *) data;
16350
e1dbfc17
L
16351 if (!dump_any_debugging)
16352 return false;
16353
f425ec66
NC
16354 /* Without section headers we cannot find any sections. */
16355 if (filedata->section_headers == NULL)
015dc7e1 16356 return false;
f425ec66 16357
9c1ce108
AM
16358 if (filedata->string_table == NULL
16359 && filedata->file_header.e_shstrndx != SHN_UNDEF
16360 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16361 {
16362 Elf_Internal_Shdr * strs;
16363
16364 /* Read in the string table, so that we have section names to scan. */
16365 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16366
4dff97b2 16367 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16368 {
9c1ce108
AM
16369 filedata->string_table
16370 = (char *) get_data (NULL, filedata, strs->sh_offset,
16371 1, strs->sh_size, _("string table"));
dda8d76d 16372
9c1ce108
AM
16373 filedata->string_table_length
16374 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16375 }
16376 }
d966045b
DJ
16377
16378 /* Locate the debug section. */
dda8d76d 16379 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16380 if (sec != NULL)
16381 section->name = section->uncompressed_name;
16382 else
16383 {
dda8d76d 16384 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16385 if (sec != NULL)
16386 section->name = section->compressed_name;
16387 }
16388 if (sec == NULL)
015dc7e1 16389 return false;
d966045b 16390
657d0d47
CC
16391 /* If we're loading from a subset of sections, and we've loaded
16392 a section matching this name before, it's likely that it's a
16393 different one. */
16394 if (section_subset != NULL)
16395 free_debug_section (debug);
16396
dda8d76d 16397 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16398}
16399
19e6b90e
L
16400void
16401free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16402{
2cf0635d 16403 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16404
19e6b90e
L
16405 if (section->start == NULL)
16406 return;
1007acb3 16407
19e6b90e
L
16408 free ((char *) section->start);
16409 section->start = NULL;
16410 section->address = 0;
16411 section->size = 0;
a788aedd 16412
9db70fc3
AM
16413 free (section->reloc_info);
16414 section->reloc_info = NULL;
16415 section->num_relocs = 0;
1007acb3
L
16416}
16417
015dc7e1 16418static bool
dda8d76d 16419display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16420{
84714f86
AM
16421 const char *name = (section_name_valid (filedata, section)
16422 ? section_name (filedata, section) : "");
16423 const char *print_name = printable_section_name (filedata, section);
be7d229a 16424 uint64_t length;
015dc7e1 16425 bool result = true;
3f5e193b 16426 int i;
1007acb3 16427
19e6b90e
L
16428 length = section->sh_size;
16429 if (length == 0)
1007acb3 16430 {
74e1a04b 16431 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16432 return true;
1007acb3 16433 }
5dff79d8
NC
16434 if (section->sh_type == SHT_NOBITS)
16435 {
16436 /* There is no point in dumping the contents of a debugging section
16437 which has the NOBITS type - the bits in the file will be random.
16438 This can happen when a file containing a .eh_frame section is
16439 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16440 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16441 print_name);
015dc7e1 16442 return false;
5dff79d8 16443 }
1007acb3 16444
24d127aa 16445 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16446 name = ".debug_info";
1007acb3 16447
19e6b90e
L
16448 /* See if we know how to display the contents of this section. */
16449 for (i = 0; i < max; i++)
d85bf2ba
NC
16450 {
16451 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16452 struct dwarf_section_display * display = debug_displays + i;
16453 struct dwarf_section * sec = & display->section;
d966045b 16454
d85bf2ba 16455 if (streq (sec->uncompressed_name, name)
24d127aa 16456 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16457 || streq (sec->compressed_name, name))
16458 {
015dc7e1 16459 bool secondary = (section != find_section (filedata, name));
1007acb3 16460
d85bf2ba
NC
16461 if (secondary)
16462 free_debug_section (id);
dda8d76d 16463
24d127aa 16464 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16465 sec->name = name;
16466 else if (streq (sec->uncompressed_name, name))
16467 sec->name = sec->uncompressed_name;
16468 else
16469 sec->name = sec->compressed_name;
657d0d47 16470
d85bf2ba
NC
16471 if (load_specific_debug_section (id, section, filedata))
16472 {
16473 /* If this debug section is part of a CU/TU set in a .dwp file,
16474 restrict load_debug_section to the sections in that set. */
16475 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16476
d85bf2ba 16477 result &= display->display (sec, filedata);
657d0d47 16478
d85bf2ba 16479 section_subset = NULL;
1007acb3 16480
44266f36 16481 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16482 free_debug_section (id);
16483 }
16484 break;
16485 }
16486 }
1007acb3 16487
19e6b90e 16488 if (i == max)
1007acb3 16489 {
74e1a04b 16490 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16491 result = false;
1007acb3
L
16492 }
16493
19e6b90e 16494 return result;
5b18a4bc 16495}
103f02d3 16496
aef1f6d0
DJ
16497/* Set DUMP_SECTS for all sections where dumps were requested
16498 based on section name. */
16499
16500static void
dda8d76d 16501initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16502{
2cf0635d 16503 struct dump_list_entry * cur;
aef1f6d0
DJ
16504
16505 for (cur = dump_sects_byname; cur; cur = cur->next)
16506 {
16507 unsigned int i;
015dc7e1 16508 bool any = false;
aef1f6d0 16509
dda8d76d 16510 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16511 if (section_name_valid (filedata, filedata->section_headers + i)
16512 && streq (section_name (filedata, filedata->section_headers + i),
16513 cur->name))
aef1f6d0 16514 {
6431e409 16515 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16516 any = true;
aef1f6d0
DJ
16517 }
16518
835f2fae
NC
16519 if (!any && !filedata->is_separate)
16520 warn (_("Section '%s' was not dumped because it does not exist\n"),
16521 cur->name);
aef1f6d0
DJ
16522 }
16523}
16524
015dc7e1 16525static bool
dda8d76d 16526process_section_contents (Filedata * filedata)
5b18a4bc 16527{
2cf0635d 16528 Elf_Internal_Shdr * section;
19e6b90e 16529 unsigned int i;
015dc7e1 16530 bool res = true;
103f02d3 16531
19e6b90e 16532 if (! do_dump)
015dc7e1 16533 return true;
103f02d3 16534
dda8d76d 16535 initialise_dumps_byname (filedata);
aef1f6d0 16536
dda8d76d 16537 for (i = 0, section = filedata->section_headers;
6431e409 16538 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16539 i++, section++)
16540 {
6431e409 16541 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16542
d6bfbc39
NC
16543 if (filedata->is_separate && ! process_links)
16544 dump &= DEBUG_DUMP;
047c3dbf 16545
19e6b90e 16546#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16547 if (dump & DISASS_DUMP)
16548 {
16549 if (! disassemble_section (section, filedata))
015dc7e1 16550 res = false;
dda8d76d 16551 }
19e6b90e 16552#endif
dda8d76d 16553 if (dump & HEX_DUMP)
32ec8896 16554 {
015dc7e1
AM
16555 if (! dump_section_as_bytes (section, filedata, false))
16556 res = false;
32ec8896 16557 }
103f02d3 16558
dda8d76d 16559 if (dump & RELOC_DUMP)
32ec8896 16560 {
015dc7e1
AM
16561 if (! dump_section_as_bytes (section, filedata, true))
16562 res = false;
32ec8896 16563 }
09c11c86 16564
dda8d76d 16565 if (dump & STRING_DUMP)
32ec8896 16566 {
dda8d76d 16567 if (! dump_section_as_strings (section, filedata))
015dc7e1 16568 res = false;
32ec8896 16569 }
cf13d699 16570
dda8d76d 16571 if (dump & DEBUG_DUMP)
32ec8896 16572 {
dda8d76d 16573 if (! display_debug_section (i, section, filedata))
015dc7e1 16574 res = false;
32ec8896 16575 }
7d9813f1 16576
094e34f2 16577#ifdef ENABLE_LIBCTF
7d9813f1
NA
16578 if (dump & CTF_DUMP)
16579 {
16580 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16581 res = false;
7d9813f1 16582 }
094e34f2 16583#endif
42b6953b
IB
16584 if (dump & SFRAME_DUMP)
16585 {
16586 if (! dump_section_as_sframe (section, filedata))
16587 res = false;
16588 }
5b18a4bc 16589 }
103f02d3 16590
835f2fae 16591 if (! filedata->is_separate)
0ee3043f 16592 {
835f2fae
NC
16593 /* Check to see if the user requested a
16594 dump of a section that does not exist. */
16595 for (; i < filedata->dump.num_dump_sects; i++)
16596 if (filedata->dump.dump_sects[i])
16597 {
ca0e11aa 16598 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16599 res = false;
835f2fae 16600 }
0ee3043f 16601 }
32ec8896
NC
16602
16603 return res;
5b18a4bc 16604}
103f02d3 16605
5b18a4bc 16606static void
19e6b90e 16607process_mips_fpe_exception (int mask)
5b18a4bc 16608{
19e6b90e
L
16609 if (mask)
16610 {
015dc7e1 16611 bool first = true;
32ec8896 16612
19e6b90e 16613 if (mask & OEX_FPU_INEX)
015dc7e1 16614 fputs ("INEX", stdout), first = false;
19e6b90e 16615 if (mask & OEX_FPU_UFLO)
015dc7e1 16616 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16617 if (mask & OEX_FPU_OFLO)
015dc7e1 16618 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16619 if (mask & OEX_FPU_DIV0)
015dc7e1 16620 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16621 if (mask & OEX_FPU_INVAL)
16622 printf ("%sINVAL", first ? "" : "|");
16623 }
5b18a4bc 16624 else
19e6b90e 16625 fputs ("0", stdout);
5b18a4bc 16626}
103f02d3 16627
f6f0e17b
NC
16628/* Display's the value of TAG at location P. If TAG is
16629 greater than 0 it is assumed to be an unknown tag, and
16630 a message is printed to this effect. Otherwise it is
16631 assumed that a message has already been printed.
16632
16633 If the bottom bit of TAG is set it assumed to have a
16634 string value, otherwise it is assumed to have an integer
16635 value.
16636
16637 Returns an updated P pointing to the first unread byte
16638 beyond the end of TAG's value.
16639
16640 Reads at or beyond END will not be made. */
16641
16642static unsigned char *
60abdbed 16643display_tag_value (signed int tag,
f6f0e17b
NC
16644 unsigned char * p,
16645 const unsigned char * const end)
16646{
26c527e6 16647 uint64_t val;
f6f0e17b
NC
16648
16649 if (tag > 0)
16650 printf (" Tag_unknown_%d: ", tag);
16651
16652 if (p >= end)
16653 {
4082ef84 16654 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16655 }
16656 else if (tag & 1)
16657 {
071436c6
NC
16658 /* PR 17531 file: 027-19978-0.004. */
16659 size_t maxlen = (end - p) - 1;
16660
16661 putchar ('"');
4082ef84
NC
16662 if (maxlen > 0)
16663 {
16664 print_symbol ((int) maxlen, (const char *) p);
16665 p += strnlen ((char *) p, maxlen) + 1;
16666 }
16667 else
16668 {
16669 printf (_("<corrupt string tag>"));
16670 p = (unsigned char *) end;
16671 }
071436c6 16672 printf ("\"\n");
f6f0e17b
NC
16673 }
16674 else
16675 {
cd30bcef 16676 READ_ULEB (val, p, end);
26c527e6 16677 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
16678 }
16679
4082ef84 16680 assert (p <= end);
f6f0e17b
NC
16681 return p;
16682}
16683
53a346d8
CZ
16684/* ARC ABI attributes section. */
16685
16686static unsigned char *
16687display_arc_attribute (unsigned char * p,
16688 const unsigned char * const end)
16689{
16690 unsigned int tag;
53a346d8
CZ
16691 unsigned int val;
16692
cd30bcef 16693 READ_ULEB (tag, p, end);
53a346d8
CZ
16694
16695 switch (tag)
16696 {
16697 case Tag_ARC_PCS_config:
cd30bcef 16698 READ_ULEB (val, p, end);
53a346d8
CZ
16699 printf (" Tag_ARC_PCS_config: ");
16700 switch (val)
16701 {
16702 case 0:
16703 printf (_("Absent/Non standard\n"));
16704 break;
16705 case 1:
16706 printf (_("Bare metal/mwdt\n"));
16707 break;
16708 case 2:
16709 printf (_("Bare metal/newlib\n"));
16710 break;
16711 case 3:
16712 printf (_("Linux/uclibc\n"));
16713 break;
16714 case 4:
16715 printf (_("Linux/glibc\n"));
16716 break;
16717 default:
16718 printf (_("Unknown\n"));
16719 break;
16720 }
16721 break;
16722
16723 case Tag_ARC_CPU_base:
cd30bcef 16724 READ_ULEB (val, p, end);
53a346d8
CZ
16725 printf (" Tag_ARC_CPU_base: ");
16726 switch (val)
16727 {
16728 default:
16729 case TAG_CPU_NONE:
16730 printf (_("Absent\n"));
16731 break;
16732 case TAG_CPU_ARC6xx:
16733 printf ("ARC6xx\n");
16734 break;
16735 case TAG_CPU_ARC7xx:
16736 printf ("ARC7xx\n");
16737 break;
16738 case TAG_CPU_ARCEM:
16739 printf ("ARCEM\n");
16740 break;
16741 case TAG_CPU_ARCHS:
16742 printf ("ARCHS\n");
16743 break;
16744 }
16745 break;
16746
16747 case Tag_ARC_CPU_variation:
cd30bcef 16748 READ_ULEB (val, p, end);
53a346d8
CZ
16749 printf (" Tag_ARC_CPU_variation: ");
16750 switch (val)
16751 {
16752 default:
16753 if (val > 0 && val < 16)
53a346d8 16754 printf ("Core%d\n", val);
d8cbc93b
JL
16755 else
16756 printf ("Unknown\n");
16757 break;
16758
53a346d8
CZ
16759 case 0:
16760 printf (_("Absent\n"));
16761 break;
16762 }
16763 break;
16764
16765 case Tag_ARC_CPU_name:
16766 printf (" Tag_ARC_CPU_name: ");
16767 p = display_tag_value (-1, p, end);
16768 break;
16769
16770 case Tag_ARC_ABI_rf16:
cd30bcef 16771 READ_ULEB (val, p, end);
53a346d8
CZ
16772 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16773 break;
16774
16775 case Tag_ARC_ABI_osver:
cd30bcef 16776 READ_ULEB (val, p, end);
53a346d8
CZ
16777 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16778 break;
16779
16780 case Tag_ARC_ABI_pic:
16781 case Tag_ARC_ABI_sda:
cd30bcef 16782 READ_ULEB (val, p, end);
53a346d8
CZ
16783 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16784 : " Tag_ARC_ABI_pic: ");
16785 switch (val)
16786 {
16787 case 0:
16788 printf (_("Absent\n"));
16789 break;
16790 case 1:
16791 printf ("MWDT\n");
16792 break;
16793 case 2:
16794 printf ("GNU\n");
16795 break;
16796 default:
16797 printf (_("Unknown\n"));
16798 break;
16799 }
16800 break;
16801
16802 case Tag_ARC_ABI_tls:
cd30bcef 16803 READ_ULEB (val, p, end);
53a346d8
CZ
16804 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16805 break;
16806
16807 case Tag_ARC_ABI_enumsize:
cd30bcef 16808 READ_ULEB (val, p, end);
53a346d8
CZ
16809 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16810 _("smallest"));
16811 break;
16812
16813 case Tag_ARC_ABI_exceptions:
cd30bcef 16814 READ_ULEB (val, p, end);
53a346d8
CZ
16815 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16816 : _("default"));
16817 break;
16818
16819 case Tag_ARC_ABI_double_size:
cd30bcef 16820 READ_ULEB (val, p, end);
53a346d8
CZ
16821 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16822 break;
16823
16824 case Tag_ARC_ISA_config:
16825 printf (" Tag_ARC_ISA_config: ");
16826 p = display_tag_value (-1, p, end);
16827 break;
16828
16829 case Tag_ARC_ISA_apex:
16830 printf (" Tag_ARC_ISA_apex: ");
16831 p = display_tag_value (-1, p, end);
16832 break;
16833
16834 case Tag_ARC_ISA_mpy_option:
cd30bcef 16835 READ_ULEB (val, p, end);
53a346d8
CZ
16836 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16837 break;
16838
db1e1b45 16839 case Tag_ARC_ATR_version:
cd30bcef 16840 READ_ULEB (val, p, end);
db1e1b45 16841 printf (" Tag_ARC_ATR_version: %d\n", val);
16842 break;
16843
53a346d8
CZ
16844 default:
16845 return display_tag_value (tag & 1, p, end);
16846 }
16847
16848 return p;
16849}
16850
11c1ff18
PB
16851/* ARM EABI attributes section. */
16852typedef struct
16853{
70e99720 16854 unsigned int tag;
2cf0635d 16855 const char * name;
11c1ff18 16856 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16857 unsigned int type;
288f0ba2 16858 const char *const *table;
11c1ff18
PB
16859} arm_attr_public_tag;
16860
288f0ba2 16861static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16862 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16863 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16864 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16865 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16866static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16867static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16868 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16869static const char *const arm_attr_tag_FP_arch[] =
bca38921 16870 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16871 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16872static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16873static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16874 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16875 "NEON for ARMv8.1"};
288f0ba2 16876static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16877 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16878 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16879static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16880 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16881static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16882 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16883static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16884 {"Absolute", "PC-relative", "None"};
288f0ba2 16885static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16886 {"None", "direct", "GOT-indirect"};
288f0ba2 16887static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16888 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16889static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16890static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16891 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16892static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16893static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16894static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16895 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16896static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16897 {"Unused", "small", "int", "forced to int"};
288f0ba2 16898static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16899 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16900static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16901 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16902static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16903 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16904static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16905 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16906 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16907static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16908 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16909 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16910static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16911static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16912 {"Not Allowed", "Allowed"};
288f0ba2 16913static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16914 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16915static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16916 {"Follow architecture", "Allowed"};
288f0ba2 16917static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16918 {"Not Allowed", "Allowed"};
288f0ba2 16919static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16920 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16921 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16922static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16923static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16924 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16925 "TrustZone and Virtualization Extensions"};
288f0ba2 16926static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16927 {"Not Allowed", "Allowed"};
11c1ff18 16928
288f0ba2 16929static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16930 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16931
99db83d0
AC
16932static const char * arm_attr_tag_PAC_extension[] =
16933 {"No PAC/AUT instructions",
16934 "PAC/AUT instructions permitted in the NOP space",
16935 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16936
4b535030
AC
16937static const char * arm_attr_tag_BTI_extension[] =
16938 {"BTI instructions not permitted",
16939 "BTI instructions permitted in the NOP space",
16940 "BTI instructions permitted in the NOP and in the non-NOP space"};
16941
b81ee92f
AC
16942static const char * arm_attr_tag_BTI_use[] =
16943 {"Compiled without branch target enforcement",
16944 "Compiled with branch target enforcement"};
16945
c9fed665
AC
16946static const char * arm_attr_tag_PACRET_use[] =
16947 {"Compiled without return address signing and authentication",
16948 "Compiled with return address signing and authentication"};
16949
11c1ff18
PB
16950#define LOOKUP(id, name) \
16951 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16952static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16953{
16954 {4, "CPU_raw_name", 1, NULL},
16955 {5, "CPU_name", 1, NULL},
16956 LOOKUP(6, CPU_arch),
16957 {7, "CPU_arch_profile", 0, NULL},
16958 LOOKUP(8, ARM_ISA_use),
16959 LOOKUP(9, THUMB_ISA_use),
75375b3e 16960 LOOKUP(10, FP_arch),
11c1ff18 16961 LOOKUP(11, WMMX_arch),
f5f53991
AS
16962 LOOKUP(12, Advanced_SIMD_arch),
16963 LOOKUP(13, PCS_config),
11c1ff18
PB
16964 LOOKUP(14, ABI_PCS_R9_use),
16965 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16966 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16967 LOOKUP(17, ABI_PCS_GOT_use),
16968 LOOKUP(18, ABI_PCS_wchar_t),
16969 LOOKUP(19, ABI_FP_rounding),
16970 LOOKUP(20, ABI_FP_denormal),
16971 LOOKUP(21, ABI_FP_exceptions),
16972 LOOKUP(22, ABI_FP_user_exceptions),
16973 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16974 {24, "ABI_align_needed", 0, NULL},
16975 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16976 LOOKUP(26, ABI_enum_size),
16977 LOOKUP(27, ABI_HardFP_use),
16978 LOOKUP(28, ABI_VFP_args),
16979 LOOKUP(29, ABI_WMMX_args),
16980 LOOKUP(30, ABI_optimization_goals),
16981 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16982 {32, "compatibility", 0, NULL},
f5f53991 16983 LOOKUP(34, CPU_unaligned_access),
75375b3e 16984 LOOKUP(36, FP_HP_extension),
8e79c3df 16985 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16986 LOOKUP(42, MPextension_use),
16987 LOOKUP(44, DIV_use),
15afaa63 16988 LOOKUP(46, DSP_extension),
a7ad558c 16989 LOOKUP(48, MVE_arch),
99db83d0 16990 LOOKUP(50, PAC_extension),
4b535030 16991 LOOKUP(52, BTI_extension),
b81ee92f 16992 LOOKUP(74, BTI_use),
c9fed665 16993 LOOKUP(76, PACRET_use),
f5f53991
AS
16994 {64, "nodefaults", 0, NULL},
16995 {65, "also_compatible_with", 0, NULL},
16996 LOOKUP(66, T2EE_use),
16997 {67, "conformance", 1, NULL},
16998 LOOKUP(68, Virtualization_use),
cd21e546 16999 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
17000};
17001#undef LOOKUP
17002
11c1ff18 17003static unsigned char *
f6f0e17b
NC
17004display_arm_attribute (unsigned char * p,
17005 const unsigned char * const end)
11c1ff18 17006{
70e99720 17007 unsigned int tag;
70e99720 17008 unsigned int val;
2cf0635d 17009 arm_attr_public_tag * attr;
11c1ff18 17010 unsigned i;
70e99720 17011 unsigned int type;
11c1ff18 17012
cd30bcef 17013 READ_ULEB (tag, p, end);
11c1ff18 17014 attr = NULL;
2cf0635d 17015 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
17016 {
17017 if (arm_attr_public_tags[i].tag == tag)
17018 {
17019 attr = &arm_attr_public_tags[i];
17020 break;
17021 }
17022 }
17023
17024 if (attr)
17025 {
17026 printf (" Tag_%s: ", attr->name);
17027 switch (attr->type)
17028 {
17029 case 0:
17030 switch (tag)
17031 {
17032 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 17033 READ_ULEB (val, p, end);
11c1ff18
PB
17034 switch (val)
17035 {
2b692964
NC
17036 case 0: printf (_("None\n")); break;
17037 case 'A': printf (_("Application\n")); break;
17038 case 'R': printf (_("Realtime\n")); break;
17039 case 'M': printf (_("Microcontroller\n")); break;
17040 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
17041 default: printf ("??? (%d)\n", val); break;
17042 }
17043 break;
17044
75375b3e 17045 case 24: /* Tag_align_needed. */
cd30bcef 17046 READ_ULEB (val, p, end);
75375b3e
MGD
17047 switch (val)
17048 {
2b692964
NC
17049 case 0: printf (_("None\n")); break;
17050 case 1: printf (_("8-byte\n")); break;
17051 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
17052 case 3: printf ("??? 3\n"); break;
17053 default:
17054 if (val <= 12)
dd24e3da 17055 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17056 1 << val);
17057 else
17058 printf ("??? (%d)\n", val);
17059 break;
17060 }
17061 break;
17062
17063 case 25: /* Tag_align_preserved. */
cd30bcef 17064 READ_ULEB (val, p, end);
75375b3e
MGD
17065 switch (val)
17066 {
2b692964
NC
17067 case 0: printf (_("None\n")); break;
17068 case 1: printf (_("8-byte, except leaf SP\n")); break;
17069 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
17070 case 3: printf ("??? 3\n"); break;
17071 default:
17072 if (val <= 12)
dd24e3da 17073 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17074 1 << val);
17075 else
17076 printf ("??? (%d)\n", val);
17077 break;
17078 }
17079 break;
17080
11c1ff18 17081 case 32: /* Tag_compatibility. */
071436c6 17082 {
cd30bcef 17083 READ_ULEB (val, p, end);
071436c6 17084 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17085 if (p < end - 1)
17086 {
17087 size_t maxlen = (end - p) - 1;
17088
17089 print_symbol ((int) maxlen, (const char *) p);
17090 p += strnlen ((char *) p, maxlen) + 1;
17091 }
17092 else
17093 {
17094 printf (_("<corrupt>"));
17095 p = (unsigned char *) end;
17096 }
071436c6 17097 putchar ('\n');
071436c6 17098 }
11c1ff18
PB
17099 break;
17100
f5f53991 17101 case 64: /* Tag_nodefaults. */
541a3cbd
NC
17102 /* PR 17531: file: 001-505008-0.01. */
17103 if (p < end)
17104 p++;
2b692964 17105 printf (_("True\n"));
f5f53991
AS
17106 break;
17107
17108 case 65: /* Tag_also_compatible_with. */
cd30bcef 17109 READ_ULEB (val, p, end);
f5f53991
AS
17110 if (val == 6 /* Tag_CPU_arch. */)
17111 {
cd30bcef 17112 READ_ULEB (val, p, end);
071436c6 17113 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
17114 printf ("??? (%d)\n", val);
17115 else
17116 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17117 }
17118 else
17119 printf ("???\n");
071436c6
NC
17120 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17121 ;
f5f53991
AS
17122 break;
17123
11c1ff18 17124 default:
bee0ee85
NC
17125 printf (_("<unknown: %d>\n"), tag);
17126 break;
11c1ff18
PB
17127 }
17128 return p;
17129
17130 case 1:
f6f0e17b 17131 return display_tag_value (-1, p, end);
11c1ff18 17132 case 2:
f6f0e17b 17133 return display_tag_value (0, p, end);
11c1ff18
PB
17134
17135 default:
17136 assert (attr->type & 0x80);
cd30bcef 17137 READ_ULEB (val, p, end);
11c1ff18
PB
17138 type = attr->type & 0x7f;
17139 if (val >= type)
17140 printf ("??? (%d)\n", val);
17141 else
17142 printf ("%s\n", attr->table[val]);
17143 return p;
17144 }
17145 }
11c1ff18 17146
f6f0e17b 17147 return display_tag_value (tag, p, end);
11c1ff18
PB
17148}
17149
104d59d1 17150static unsigned char *
60bca95a 17151display_gnu_attribute (unsigned char * p,
60abdbed 17152 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 17153 const unsigned char * const end)
104d59d1 17154{
cd30bcef 17155 unsigned int tag;
60abdbed 17156 unsigned int val;
104d59d1 17157
cd30bcef 17158 READ_ULEB (tag, p, end);
104d59d1
JM
17159
17160 /* Tag_compatibility is the only generic GNU attribute defined at
17161 present. */
17162 if (tag == 32)
17163 {
cd30bcef 17164 READ_ULEB (val, p, end);
071436c6
NC
17165
17166 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
17167 if (p == end)
17168 {
071436c6 17169 printf (_("<corrupt>\n"));
f6f0e17b
NC
17170 warn (_("corrupt vendor attribute\n"));
17171 }
17172 else
17173 {
4082ef84
NC
17174 if (p < end - 1)
17175 {
17176 size_t maxlen = (end - p) - 1;
071436c6 17177
4082ef84
NC
17178 print_symbol ((int) maxlen, (const char *) p);
17179 p += strnlen ((char *) p, maxlen) + 1;
17180 }
17181 else
17182 {
17183 printf (_("<corrupt>"));
17184 p = (unsigned char *) end;
17185 }
071436c6 17186 putchar ('\n');
f6f0e17b 17187 }
104d59d1
JM
17188 return p;
17189 }
17190
17191 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 17192 return display_proc_gnu_attribute (p, tag, end);
104d59d1 17193
f6f0e17b 17194 return display_tag_value (tag, p, end);
104d59d1
JM
17195}
17196
85f7484a
PB
17197static unsigned char *
17198display_m68k_gnu_attribute (unsigned char * p,
17199 unsigned int tag,
17200 const unsigned char * const end)
17201{
17202 unsigned int val;
17203
17204 if (tag == Tag_GNU_M68K_ABI_FP)
17205 {
17206 printf (" Tag_GNU_M68K_ABI_FP: ");
17207 if (p == end)
17208 {
17209 printf (_("<corrupt>\n"));
17210 return p;
17211 }
17212 READ_ULEB (val, p, end);
17213
17214 if (val > 3)
17215 printf ("(%#x), ", val);
17216
17217 switch (val & 3)
17218 {
17219 case 0:
17220 printf (_("unspecified hard/soft float\n"));
17221 break;
17222 case 1:
17223 printf (_("hard float\n"));
17224 break;
17225 case 2:
17226 printf (_("soft float\n"));
17227 break;
17228 }
17229 return p;
17230 }
17231
17232 return display_tag_value (tag & 1, p, end);
17233}
17234
34c8bcba 17235static unsigned char *
f6f0e17b 17236display_power_gnu_attribute (unsigned char * p,
60abdbed 17237 unsigned int tag,
f6f0e17b 17238 const unsigned char * const end)
34c8bcba 17239{
005d79fd 17240 unsigned int val;
34c8bcba
JM
17241
17242 if (tag == Tag_GNU_Power_ABI_FP)
17243 {
34c8bcba 17244 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 17245 if (p == end)
005d79fd
AM
17246 {
17247 printf (_("<corrupt>\n"));
17248 return p;
17249 }
cd30bcef 17250 READ_ULEB (val, p, end);
60bca95a 17251
005d79fd
AM
17252 if (val > 15)
17253 printf ("(%#x), ", val);
17254
17255 switch (val & 3)
34c8bcba
JM
17256 {
17257 case 0:
005d79fd 17258 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17259 break;
17260 case 1:
005d79fd 17261 printf (_("hard float, "));
34c8bcba
JM
17262 break;
17263 case 2:
005d79fd 17264 printf (_("soft float, "));
34c8bcba 17265 break;
3c7b9897 17266 case 3:
005d79fd 17267 printf (_("single-precision hard float, "));
3c7b9897 17268 break;
005d79fd
AM
17269 }
17270
17271 switch (val & 0xC)
17272 {
17273 case 0:
17274 printf (_("unspecified long double\n"));
17275 break;
17276 case 4:
17277 printf (_("128-bit IBM long double\n"));
17278 break;
17279 case 8:
17280 printf (_("64-bit long double\n"));
17281 break;
17282 case 12:
17283 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17284 break;
17285 }
17286 return p;
005d79fd 17287 }
34c8bcba 17288
c6e65352
DJ
17289 if (tag == Tag_GNU_Power_ABI_Vector)
17290 {
c6e65352 17291 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17292 if (p == end)
005d79fd
AM
17293 {
17294 printf (_("<corrupt>\n"));
17295 return p;
17296 }
cd30bcef 17297 READ_ULEB (val, p, end);
005d79fd
AM
17298
17299 if (val > 3)
17300 printf ("(%#x), ", val);
17301
17302 switch (val & 3)
c6e65352
DJ
17303 {
17304 case 0:
005d79fd 17305 printf (_("unspecified\n"));
c6e65352
DJ
17306 break;
17307 case 1:
005d79fd 17308 printf (_("generic\n"));
c6e65352
DJ
17309 break;
17310 case 2:
17311 printf ("AltiVec\n");
17312 break;
17313 case 3:
17314 printf ("SPE\n");
17315 break;
c6e65352
DJ
17316 }
17317 return p;
005d79fd 17318 }
c6e65352 17319
f82e0623
NF
17320 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17321 {
005d79fd 17322 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17323 if (p == end)
f6f0e17b 17324 {
005d79fd 17325 printf (_("<corrupt>\n"));
f6f0e17b
NC
17326 return p;
17327 }
cd30bcef 17328 READ_ULEB (val, p, end);
0b4362b0 17329
005d79fd
AM
17330 if (val > 2)
17331 printf ("(%#x), ", val);
17332
17333 switch (val & 3)
17334 {
17335 case 0:
17336 printf (_("unspecified\n"));
17337 break;
17338 case 1:
17339 printf ("r3/r4\n");
17340 break;
17341 case 2:
17342 printf (_("memory\n"));
17343 break;
17344 case 3:
17345 printf ("???\n");
17346 break;
17347 }
f82e0623
NF
17348 return p;
17349 }
17350
f6f0e17b 17351 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17352}
17353
643f7afb
AK
17354static unsigned char *
17355display_s390_gnu_attribute (unsigned char * p,
60abdbed 17356 unsigned int tag,
643f7afb
AK
17357 const unsigned char * const end)
17358{
cd30bcef 17359 unsigned int val;
643f7afb
AK
17360
17361 if (tag == Tag_GNU_S390_ABI_Vector)
17362 {
643f7afb 17363 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17364 READ_ULEB (val, p, end);
643f7afb
AK
17365
17366 switch (val)
17367 {
17368 case 0:
17369 printf (_("any\n"));
17370 break;
17371 case 1:
17372 printf (_("software\n"));
17373 break;
17374 case 2:
17375 printf (_("hardware\n"));
17376 break;
17377 default:
17378 printf ("??? (%d)\n", val);
17379 break;
17380 }
17381 return p;
17382 }
17383
17384 return display_tag_value (tag & 1, p, end);
17385}
17386
9e8c70f9 17387static void
60abdbed 17388display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17389{
17390 if (mask)
17391 {
015dc7e1 17392 bool first = true;
071436c6 17393
9e8c70f9 17394 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17395 fputs ("mul32", stdout), first = false;
9e8c70f9 17396 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17397 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17398 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17399 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17400 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17401 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17402 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17403 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17404 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17405 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17406 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17407 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17408 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17409 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17410 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17411 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17412 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17413 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17414 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17415 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17416 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17417 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17418 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17419 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17420 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17421 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17422 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17423 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17424 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17425 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17426 }
17427 else
071436c6
NC
17428 fputc ('0', stdout);
17429 fputc ('\n', stdout);
9e8c70f9
DM
17430}
17431
3d68f91c 17432static void
60abdbed 17433display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17434{
17435 if (mask)
17436 {
015dc7e1 17437 bool first = true;
071436c6 17438
3d68f91c 17439 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17440 fputs ("fjathplus", stdout), first = false;
3d68f91c 17441 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17442 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17443 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17444 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17445 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17446 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17447 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17448 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17449 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17450 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17451 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17452 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17453 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17454 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17455 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17456 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17457 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17458 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17459 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17460 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17461 }
17462 else
071436c6
NC
17463 fputc ('0', stdout);
17464 fputc ('\n', stdout);
3d68f91c
JM
17465}
17466
9e8c70f9 17467static unsigned char *
f6f0e17b 17468display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17469 unsigned int tag,
f6f0e17b 17470 const unsigned char * const end)
9e8c70f9 17471{
cd30bcef 17472 unsigned int val;
3d68f91c 17473
9e8c70f9
DM
17474 if (tag == Tag_GNU_Sparc_HWCAPS)
17475 {
cd30bcef 17476 READ_ULEB (val, p, end);
9e8c70f9 17477 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17478 display_sparc_hwcaps (val);
17479 return p;
3d68f91c
JM
17480 }
17481 if (tag == Tag_GNU_Sparc_HWCAPS2)
17482 {
cd30bcef 17483 READ_ULEB (val, p, end);
3d68f91c
JM
17484 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17485 display_sparc_hwcaps2 (val);
17486 return p;
17487 }
9e8c70f9 17488
f6f0e17b 17489 return display_tag_value (tag, p, end);
9e8c70f9
DM
17490}
17491
351cdf24 17492static void
32ec8896 17493print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17494{
17495 switch (val)
17496 {
17497 case Val_GNU_MIPS_ABI_FP_ANY:
17498 printf (_("Hard or soft float\n"));
17499 break;
17500 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17501 printf (_("Hard float (double precision)\n"));
17502 break;
17503 case Val_GNU_MIPS_ABI_FP_SINGLE:
17504 printf (_("Hard float (single precision)\n"));
17505 break;
17506 case Val_GNU_MIPS_ABI_FP_SOFT:
17507 printf (_("Soft float\n"));
17508 break;
17509 case Val_GNU_MIPS_ABI_FP_OLD_64:
17510 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17511 break;
17512 case Val_GNU_MIPS_ABI_FP_XX:
17513 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17514 break;
17515 case Val_GNU_MIPS_ABI_FP_64:
17516 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17517 break;
17518 case Val_GNU_MIPS_ABI_FP_64A:
17519 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17520 break;
3350cc01
CM
17521 case Val_GNU_MIPS_ABI_FP_NAN2008:
17522 printf (_("NaN 2008 compatibility\n"));
17523 break;
351cdf24
MF
17524 default:
17525 printf ("??? (%d)\n", val);
17526 break;
17527 }
17528}
17529
2cf19d5c 17530static unsigned char *
f6f0e17b 17531display_mips_gnu_attribute (unsigned char * p,
60abdbed 17532 unsigned int tag,
f6f0e17b 17533 const unsigned char * const end)
2cf19d5c 17534{
2cf19d5c
JM
17535 if (tag == Tag_GNU_MIPS_ABI_FP)
17536 {
32ec8896 17537 unsigned int val;
f6f0e17b 17538
2cf19d5c 17539 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17540 READ_ULEB (val, p, end);
351cdf24 17541 print_mips_fp_abi_value (val);
2cf19d5c
JM
17542 return p;
17543 }
17544
a9f58168
CF
17545 if (tag == Tag_GNU_MIPS_ABI_MSA)
17546 {
32ec8896 17547 unsigned int val;
a9f58168 17548
a9f58168 17549 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17550 READ_ULEB (val, p, end);
a9f58168
CF
17551
17552 switch (val)
17553 {
17554 case Val_GNU_MIPS_ABI_MSA_ANY:
17555 printf (_("Any MSA or not\n"));
17556 break;
17557 case Val_GNU_MIPS_ABI_MSA_128:
17558 printf (_("128-bit MSA\n"));
17559 break;
17560 default:
17561 printf ("??? (%d)\n", val);
17562 break;
17563 }
17564 return p;
17565 }
17566
f6f0e17b 17567 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17568}
17569
59e6276b 17570static unsigned char *
f6f0e17b
NC
17571display_tic6x_attribute (unsigned char * p,
17572 const unsigned char * const end)
59e6276b 17573{
60abdbed 17574 unsigned int tag;
cd30bcef 17575 unsigned int val;
59e6276b 17576
cd30bcef 17577 READ_ULEB (tag, p, end);
59e6276b
JM
17578
17579 switch (tag)
17580 {
75fa6dc1 17581 case Tag_ISA:
75fa6dc1 17582 printf (" Tag_ISA: ");
cd30bcef 17583 READ_ULEB (val, p, end);
59e6276b
JM
17584
17585 switch (val)
17586 {
75fa6dc1 17587 case C6XABI_Tag_ISA_none:
59e6276b
JM
17588 printf (_("None\n"));
17589 break;
75fa6dc1 17590 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17591 printf ("C62x\n");
17592 break;
75fa6dc1 17593 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17594 printf ("C67x\n");
17595 break;
75fa6dc1 17596 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17597 printf ("C67x+\n");
17598 break;
75fa6dc1 17599 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17600 printf ("C64x\n");
17601 break;
75fa6dc1 17602 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17603 printf ("C64x+\n");
17604 break;
75fa6dc1 17605 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17606 printf ("C674x\n");
17607 break;
17608 default:
17609 printf ("??? (%d)\n", val);
17610 break;
17611 }
17612 return p;
17613
87779176 17614 case Tag_ABI_wchar_t:
87779176 17615 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17616 READ_ULEB (val, p, end);
87779176
JM
17617 switch (val)
17618 {
17619 case 0:
17620 printf (_("Not used\n"));
17621 break;
17622 case 1:
17623 printf (_("2 bytes\n"));
17624 break;
17625 case 2:
17626 printf (_("4 bytes\n"));
17627 break;
17628 default:
17629 printf ("??? (%d)\n", val);
17630 break;
17631 }
17632 return p;
17633
17634 case Tag_ABI_stack_align_needed:
87779176 17635 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17636 READ_ULEB (val, p, end);
87779176
JM
17637 switch (val)
17638 {
17639 case 0:
17640 printf (_("8-byte\n"));
17641 break;
17642 case 1:
17643 printf (_("16-byte\n"));
17644 break;
17645 default:
17646 printf ("??? (%d)\n", val);
17647 break;
17648 }
17649 return p;
17650
17651 case Tag_ABI_stack_align_preserved:
cd30bcef 17652 READ_ULEB (val, p, end);
87779176
JM
17653 printf (" Tag_ABI_stack_align_preserved: ");
17654 switch (val)
17655 {
17656 case 0:
17657 printf (_("8-byte\n"));
17658 break;
17659 case 1:
17660 printf (_("16-byte\n"));
17661 break;
17662 default:
17663 printf ("??? (%d)\n", val);
17664 break;
17665 }
17666 return p;
17667
b5593623 17668 case Tag_ABI_DSBT:
cd30bcef 17669 READ_ULEB (val, p, end);
b5593623
JM
17670 printf (" Tag_ABI_DSBT: ");
17671 switch (val)
17672 {
17673 case 0:
17674 printf (_("DSBT addressing not used\n"));
17675 break;
17676 case 1:
17677 printf (_("DSBT addressing used\n"));
17678 break;
17679 default:
17680 printf ("??? (%d)\n", val);
17681 break;
17682 }
17683 return p;
17684
87779176 17685 case Tag_ABI_PID:
cd30bcef 17686 READ_ULEB (val, p, end);
87779176
JM
17687 printf (" Tag_ABI_PID: ");
17688 switch (val)
17689 {
17690 case 0:
17691 printf (_("Data addressing position-dependent\n"));
17692 break;
17693 case 1:
17694 printf (_("Data addressing position-independent, GOT near DP\n"));
17695 break;
17696 case 2:
17697 printf (_("Data addressing position-independent, GOT far from DP\n"));
17698 break;
17699 default:
17700 printf ("??? (%d)\n", val);
17701 break;
17702 }
17703 return p;
17704
17705 case Tag_ABI_PIC:
cd30bcef 17706 READ_ULEB (val, p, end);
87779176
JM
17707 printf (" Tag_ABI_PIC: ");
17708 switch (val)
17709 {
17710 case 0:
17711 printf (_("Code addressing position-dependent\n"));
17712 break;
17713 case 1:
17714 printf (_("Code addressing position-independent\n"));
17715 break;
17716 default:
17717 printf ("??? (%d)\n", val);
17718 break;
17719 }
17720 return p;
17721
17722 case Tag_ABI_array_object_alignment:
cd30bcef 17723 READ_ULEB (val, p, end);
87779176
JM
17724 printf (" Tag_ABI_array_object_alignment: ");
17725 switch (val)
17726 {
17727 case 0:
17728 printf (_("8-byte\n"));
17729 break;
17730 case 1:
17731 printf (_("4-byte\n"));
17732 break;
17733 case 2:
17734 printf (_("16-byte\n"));
17735 break;
17736 default:
17737 printf ("??? (%d)\n", val);
17738 break;
17739 }
17740 return p;
17741
17742 case Tag_ABI_array_object_align_expected:
cd30bcef 17743 READ_ULEB (val, p, end);
87779176
JM
17744 printf (" Tag_ABI_array_object_align_expected: ");
17745 switch (val)
17746 {
17747 case 0:
17748 printf (_("8-byte\n"));
17749 break;
17750 case 1:
17751 printf (_("4-byte\n"));
17752 break;
17753 case 2:
17754 printf (_("16-byte\n"));
17755 break;
17756 default:
17757 printf ("??? (%d)\n", val);
17758 break;
17759 }
17760 return p;
17761
3cbd1c06 17762 case Tag_ABI_compatibility:
071436c6 17763 {
cd30bcef 17764 READ_ULEB (val, p, end);
071436c6 17765 printf (" Tag_ABI_compatibility: ");
071436c6 17766 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17767 if (p < end - 1)
17768 {
17769 size_t maxlen = (end - p) - 1;
17770
17771 print_symbol ((int) maxlen, (const char *) p);
17772 p += strnlen ((char *) p, maxlen) + 1;
17773 }
17774 else
17775 {
17776 printf (_("<corrupt>"));
17777 p = (unsigned char *) end;
17778 }
071436c6 17779 putchar ('\n');
071436c6
NC
17780 return p;
17781 }
87779176
JM
17782
17783 case Tag_ABI_conformance:
071436c6 17784 {
4082ef84
NC
17785 printf (" Tag_ABI_conformance: \"");
17786 if (p < end - 1)
17787 {
17788 size_t maxlen = (end - p) - 1;
071436c6 17789
4082ef84
NC
17790 print_symbol ((int) maxlen, (const char *) p);
17791 p += strnlen ((char *) p, maxlen) + 1;
17792 }
17793 else
17794 {
17795 printf (_("<corrupt>"));
17796 p = (unsigned char *) end;
17797 }
071436c6 17798 printf ("\"\n");
071436c6
NC
17799 return p;
17800 }
59e6276b
JM
17801 }
17802
f6f0e17b
NC
17803 return display_tag_value (tag, p, end);
17804}
59e6276b 17805
f6f0e17b 17806static void
60abdbed 17807display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 17808{
26c527e6 17809 uint64_t addr = 0;
f6f0e17b
NC
17810 size_t bytes = end - p;
17811
feceaa59 17812 assert (end >= p);
f6f0e17b 17813 while (bytes)
87779176 17814 {
f6f0e17b
NC
17815 int j;
17816 int k;
17817 int lbytes = (bytes > 16 ? 16 : bytes);
17818
26c527e6 17819 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
17820
17821 for (j = 0; j < 16; j++)
17822 {
17823 if (j < lbytes)
17824 printf ("%2.2x", p[j]);
17825 else
17826 printf (" ");
17827
17828 if ((j & 3) == 3)
17829 printf (" ");
17830 }
17831
17832 for (j = 0; j < lbytes; j++)
17833 {
17834 k = p[j];
17835 if (k >= ' ' && k < 0x7f)
17836 printf ("%c", k);
17837 else
17838 printf (".");
17839 }
17840
17841 putchar ('\n');
17842
17843 p += lbytes;
17844 bytes -= lbytes;
17845 addr += lbytes;
87779176 17846 }
59e6276b 17847
f6f0e17b 17848 putchar ('\n');
59e6276b
JM
17849}
17850
13761a11 17851static unsigned char *
b0191216 17852display_msp430_attribute (unsigned char * p,
26c527e6 17853 const unsigned char * const end)
13761a11 17854{
26c527e6
AM
17855 uint64_t val;
17856 uint64_t tag;
13761a11 17857
cd30bcef 17858 READ_ULEB (tag, p, end);
0b4362b0 17859
13761a11
NC
17860 switch (tag)
17861 {
17862 case OFBA_MSPABI_Tag_ISA:
13761a11 17863 printf (" Tag_ISA: ");
cd30bcef 17864 READ_ULEB (val, p, end);
13761a11
NC
17865 switch (val)
17866 {
17867 case 0: printf (_("None\n")); break;
17868 case 1: printf (_("MSP430\n")); break;
17869 case 2: printf (_("MSP430X\n")); break;
26c527e6 17870 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17871 }
17872 break;
17873
17874 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17875 printf (" Tag_Code_Model: ");
cd30bcef 17876 READ_ULEB (val, p, end);
13761a11
NC
17877 switch (val)
17878 {
17879 case 0: printf (_("None\n")); break;
17880 case 1: printf (_("Small\n")); break;
17881 case 2: printf (_("Large\n")); break;
26c527e6 17882 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17883 }
17884 break;
17885
17886 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17887 printf (" Tag_Data_Model: ");
cd30bcef 17888 READ_ULEB (val, p, end);
13761a11
NC
17889 switch (val)
17890 {
17891 case 0: printf (_("None\n")); break;
17892 case 1: printf (_("Small\n")); break;
17893 case 2: printf (_("Large\n")); break;
17894 case 3: printf (_("Restricted Large\n")); break;
26c527e6 17895 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17896 }
17897 break;
17898
17899 default:
26c527e6 17900 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
17901
17902 if (tag & 1)
17903 {
071436c6 17904 putchar ('"');
4082ef84
NC
17905 if (p < end - 1)
17906 {
17907 size_t maxlen = (end - p) - 1;
17908
17909 print_symbol ((int) maxlen, (const char *) p);
17910 p += strnlen ((char *) p, maxlen) + 1;
17911 }
17912 else
17913 {
17914 printf (_("<corrupt>"));
17915 p = (unsigned char *) end;
17916 }
071436c6 17917 printf ("\"\n");
13761a11
NC
17918 }
17919 else
17920 {
cd30bcef 17921 READ_ULEB (val, p, end);
26c527e6 17922 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
17923 }
17924 break;
17925 }
17926
4082ef84 17927 assert (p <= end);
13761a11
NC
17928 return p;
17929}
17930
c0ea7c52
JL
17931static unsigned char *
17932display_msp430_gnu_attribute (unsigned char * p,
17933 unsigned int tag,
17934 const unsigned char * const end)
17935{
17936 if (tag == Tag_GNU_MSP430_Data_Region)
17937 {
26c527e6 17938 uint64_t val;
c0ea7c52 17939
c0ea7c52 17940 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17941 READ_ULEB (val, p, end);
c0ea7c52
JL
17942
17943 switch (val)
17944 {
17945 case Val_GNU_MSP430_Data_Region_Any:
17946 printf (_("Any Region\n"));
17947 break;
17948 case Val_GNU_MSP430_Data_Region_Lower:
17949 printf (_("Lower Region Only\n"));
17950 break;
17951 default:
26c527e6 17952 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
17953 }
17954 return p;
17955 }
17956 return display_tag_value (tag & 1, p, end);
17957}
17958
2dc8dd17
JW
17959struct riscv_attr_tag_t {
17960 const char *name;
cd30bcef 17961 unsigned int tag;
2dc8dd17
JW
17962};
17963
17964static struct riscv_attr_tag_t riscv_attr_tag[] =
17965{
17966#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17967 T(arch),
17968 T(priv_spec),
17969 T(priv_spec_minor),
17970 T(priv_spec_revision),
17971 T(unaligned_access),
17972 T(stack_align),
17973#undef T
17974};
17975
17976static unsigned char *
17977display_riscv_attribute (unsigned char *p,
17978 const unsigned char * const end)
17979{
26c527e6
AM
17980 uint64_t val;
17981 uint64_t tag;
2dc8dd17
JW
17982 struct riscv_attr_tag_t *attr = NULL;
17983 unsigned i;
17984
cd30bcef 17985 READ_ULEB (tag, p, end);
2dc8dd17
JW
17986
17987 /* Find the name of attribute. */
17988 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17989 {
17990 if (riscv_attr_tag[i].tag == tag)
17991 {
17992 attr = &riscv_attr_tag[i];
17993 break;
17994 }
17995 }
17996
17997 if (attr)
17998 printf (" %s: ", attr->name);
17999 else
18000 return display_tag_value (tag, p, end);
18001
18002 switch (tag)
18003 {
18004 case Tag_RISCV_priv_spec:
18005 case Tag_RISCV_priv_spec_minor:
18006 case Tag_RISCV_priv_spec_revision:
cd30bcef 18007 READ_ULEB (val, p, end);
26c527e6 18008 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
18009 break;
18010 case Tag_RISCV_unaligned_access:
cd30bcef 18011 READ_ULEB (val, p, end);
2dc8dd17
JW
18012 switch (val)
18013 {
18014 case 0:
18015 printf (_("No unaligned access\n"));
18016 break;
18017 case 1:
18018 printf (_("Unaligned access\n"));
18019 break;
18020 }
18021 break;
18022 case Tag_RISCV_stack_align:
cd30bcef 18023 READ_ULEB (val, p, end);
26c527e6 18024 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
18025 break;
18026 case Tag_RISCV_arch:
18027 p = display_tag_value (-1, p, end);
18028 break;
18029 default:
18030 return display_tag_value (tag, p, end);
18031 }
18032
18033 return p;
18034}
18035
0861f561
CQ
18036static unsigned char *
18037display_csky_attribute (unsigned char * p,
18038 const unsigned char * const end)
18039{
26c527e6
AM
18040 uint64_t tag;
18041 uint64_t val;
0861f561
CQ
18042 READ_ULEB (tag, p, end);
18043
18044 if (tag >= Tag_CSKY_MAX)
18045 {
18046 return display_tag_value (-1, p, end);
18047 }
18048
18049 switch (tag)
18050 {
18051 case Tag_CSKY_ARCH_NAME:
18052 printf (" Tag_CSKY_ARCH_NAME:\t\t");
18053 return display_tag_value (-1, p, end);
18054 case Tag_CSKY_CPU_NAME:
18055 printf (" Tag_CSKY_CPU_NAME:\t\t");
18056 return display_tag_value (-1, p, end);
18057
18058 case Tag_CSKY_ISA_FLAGS:
18059 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
18060 return display_tag_value (0, p, end);
18061 case Tag_CSKY_ISA_EXT_FLAGS:
18062 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
18063 return display_tag_value (0, p, end);
18064
18065 case Tag_CSKY_DSP_VERSION:
18066 printf (" Tag_CSKY_DSP_VERSION:\t\t");
18067 READ_ULEB (val, p, end);
18068 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
18069 printf ("DSP Extension\n");
18070 else if (val == VAL_CSKY_DSP_VERSION_2)
18071 printf ("DSP 2.0\n");
18072 break;
18073
18074 case Tag_CSKY_VDSP_VERSION:
18075 printf (" Tag_CSKY_VDSP_VERSION:\t");
18076 READ_ULEB (val, p, end);
26c527e6 18077 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
18078 break;
18079
18080 case Tag_CSKY_FPU_VERSION:
18081 printf (" Tag_CSKY_FPU_VERSION:\t\t");
18082 READ_ULEB (val, p, end);
18083 if (val == VAL_CSKY_FPU_VERSION_1)
18084 printf ("ABIV1 FPU Version 1\n");
18085 else if (val == VAL_CSKY_FPU_VERSION_2)
18086 printf ("FPU Version 2\n");
18087 break;
18088
18089 case Tag_CSKY_FPU_ABI:
18090 printf (" Tag_CSKY_FPU_ABI:\t\t");
18091 READ_ULEB (val, p, end);
18092 if (val == VAL_CSKY_FPU_ABI_HARD)
18093 printf ("Hard\n");
18094 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18095 printf ("SoftFP\n");
18096 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18097 printf ("Soft\n");
18098 break;
18099 case Tag_CSKY_FPU_ROUNDING:
18100 READ_ULEB (val, p, end);
f253158f
NC
18101 if (val == 1)
18102 {
18103 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18104 printf ("Needed\n");
18105 }
0861f561
CQ
18106 break;
18107 case Tag_CSKY_FPU_DENORMAL:
18108 READ_ULEB (val, p, end);
f253158f
NC
18109 if (val == 1)
18110 {
18111 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18112 printf ("Needed\n");
18113 }
0861f561
CQ
18114 break;
18115 case Tag_CSKY_FPU_Exception:
18116 READ_ULEB (val, p, end);
f253158f
NC
18117 if (val == 1)
18118 {
18119 printf (" Tag_CSKY_FPU_Exception:\t");
18120 printf ("Needed\n");
18121 }
0861f561
CQ
18122 break;
18123 case Tag_CSKY_FPU_NUMBER_MODULE:
18124 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18125 return display_tag_value (-1, p, end);
18126 case Tag_CSKY_FPU_HARDFP:
18127 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18128 READ_ULEB (val, p, end);
18129 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18130 printf (" Half");
18131 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18132 printf (" Single");
18133 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18134 printf (" Double");
18135 printf ("\n");
18136 break;
18137 default:
18138 return display_tag_value (tag, p, end);
18139 }
18140 return p;
18141}
18142
015dc7e1 18143static bool
dda8d76d 18144process_attributes (Filedata * filedata,
60bca95a 18145 const char * public_name,
104d59d1 18146 unsigned int proc_type,
f6f0e17b 18147 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 18148 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 18149{
2cf0635d 18150 Elf_Internal_Shdr * sect;
11c1ff18 18151 unsigned i;
015dc7e1 18152 bool res = true;
11c1ff18
PB
18153
18154 /* Find the section header so that we get the size. */
dda8d76d
NC
18155 for (i = 0, sect = filedata->section_headers;
18156 i < filedata->file_header.e_shnum;
11c1ff18
PB
18157 i++, sect++)
18158 {
071436c6
NC
18159 unsigned char * contents;
18160 unsigned char * p;
18161
104d59d1 18162 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
18163 continue;
18164
dda8d76d 18165 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 18166 sect->sh_size, _("attributes"));
60bca95a 18167 if (contents == NULL)
32ec8896 18168 {
015dc7e1 18169 res = false;
32ec8896
NC
18170 continue;
18171 }
60bca95a 18172
11c1ff18 18173 p = contents;
60abdbed
NC
18174 /* The first character is the version of the attributes.
18175 Currently only version 1, (aka 'A') is recognised here. */
18176 if (*p != 'A')
32ec8896
NC
18177 {
18178 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 18179 res = false;
32ec8896 18180 }
60abdbed 18181 else
11c1ff18 18182 {
625d49fc 18183 uint64_t section_len;
071436c6
NC
18184
18185 section_len = sect->sh_size - 1;
11c1ff18 18186 p++;
60bca95a 18187
071436c6 18188 while (section_len > 0)
11c1ff18 18189 {
625d49fc 18190 uint64_t attr_len;
e9847026 18191 unsigned int namelen;
015dc7e1
AM
18192 bool public_section;
18193 bool gnu_section;
11c1ff18 18194
071436c6 18195 if (section_len <= 4)
e0a31db1
NC
18196 {
18197 error (_("Tag section ends prematurely\n"));
015dc7e1 18198 res = false;
e0a31db1
NC
18199 break;
18200 }
071436c6 18201 attr_len = byte_get (p, 4);
11c1ff18 18202 p += 4;
60bca95a 18203
071436c6 18204 if (attr_len > section_len)
11c1ff18 18205 {
071436c6
NC
18206 error (_("Bad attribute length (%u > %u)\n"),
18207 (unsigned) attr_len, (unsigned) section_len);
18208 attr_len = section_len;
015dc7e1 18209 res = false;
11c1ff18 18210 }
74e1a04b 18211 /* PR 17531: file: 001-101425-0.004 */
071436c6 18212 else if (attr_len < 5)
74e1a04b 18213 {
071436c6 18214 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 18215 res = false;
74e1a04b
NC
18216 break;
18217 }
e9847026 18218
071436c6
NC
18219 section_len -= attr_len;
18220 attr_len -= 4;
18221
18222 namelen = strnlen ((char *) p, attr_len) + 1;
18223 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
18224 {
18225 error (_("Corrupt attribute section name\n"));
015dc7e1 18226 res = false;
e9847026
NC
18227 break;
18228 }
18229
071436c6
NC
18230 printf (_("Attribute Section: "));
18231 print_symbol (INT_MAX, (const char *) p);
18232 putchar ('\n');
60bca95a
NC
18233
18234 if (public_name && streq ((char *) p, public_name))
015dc7e1 18235 public_section = true;
11c1ff18 18236 else
015dc7e1 18237 public_section = false;
60bca95a
NC
18238
18239 if (streq ((char *) p, "gnu"))
015dc7e1 18240 gnu_section = true;
104d59d1 18241 else
015dc7e1 18242 gnu_section = false;
60bca95a 18243
11c1ff18 18244 p += namelen;
071436c6 18245 attr_len -= namelen;
e0a31db1 18246
071436c6 18247 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18248 {
e0a31db1 18249 int tag;
cd30bcef 18250 unsigned int val;
625d49fc 18251 uint64_t size;
071436c6 18252 unsigned char * end;
60bca95a 18253
e0a31db1 18254 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18255 if (attr_len < 6)
e0a31db1
NC
18256 {
18257 error (_("Unused bytes at end of section\n"));
015dc7e1 18258 res = false;
e0a31db1
NC
18259 section_len = 0;
18260 break;
18261 }
18262
18263 tag = *(p++);
11c1ff18 18264 size = byte_get (p, 4);
071436c6 18265 if (size > attr_len)
11c1ff18 18266 {
e9847026 18267 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18268 (unsigned) size, (unsigned) attr_len);
015dc7e1 18269 res = false;
071436c6 18270 size = attr_len;
11c1ff18 18271 }
e0a31db1
NC
18272 /* PR binutils/17531: Safe handling of corrupt files. */
18273 if (size < 6)
18274 {
18275 error (_("Bad subsection length (%u < 6)\n"),
18276 (unsigned) size);
015dc7e1 18277 res = false;
e0a31db1
NC
18278 section_len = 0;
18279 break;
18280 }
60bca95a 18281
071436c6 18282 attr_len -= size;
11c1ff18 18283 end = p + size - 1;
071436c6 18284 assert (end <= contents + sect->sh_size);
11c1ff18 18285 p += 4;
60bca95a 18286
11c1ff18
PB
18287 switch (tag)
18288 {
18289 case 1:
2b692964 18290 printf (_("File Attributes\n"));
11c1ff18
PB
18291 break;
18292 case 2:
2b692964 18293 printf (_("Section Attributes:"));
11c1ff18
PB
18294 goto do_numlist;
18295 case 3:
2b692964 18296 printf (_("Symbol Attributes:"));
1a0670f3 18297 /* Fall through. */
11c1ff18
PB
18298 do_numlist:
18299 for (;;)
18300 {
cd30bcef 18301 READ_ULEB (val, p, end);
11c1ff18
PB
18302 if (val == 0)
18303 break;
18304 printf (" %d", val);
18305 }
18306 printf ("\n");
18307 break;
18308 default:
2b692964 18309 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18310 public_section = false;
11c1ff18
PB
18311 break;
18312 }
60bca95a 18313
071436c6 18314 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18315 {
18316 while (p < end)
f6f0e17b 18317 p = display_pub_attribute (p, end);
60abdbed 18318 assert (p == end);
104d59d1 18319 }
071436c6 18320 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18321 {
18322 while (p < end)
18323 p = display_gnu_attribute (p,
f6f0e17b
NC
18324 display_proc_gnu_attribute,
18325 end);
60abdbed 18326 assert (p == end);
11c1ff18 18327 }
071436c6 18328 else if (p < end)
11c1ff18 18329 {
071436c6 18330 printf (_(" Unknown attribute:\n"));
f6f0e17b 18331 display_raw_attribute (p, end);
11c1ff18
PB
18332 p = end;
18333 }
071436c6
NC
18334 else
18335 attr_len = 0;
11c1ff18
PB
18336 }
18337 }
18338 }
d70c5fc7 18339
60bca95a 18340 free (contents);
11c1ff18 18341 }
32ec8896
NC
18342
18343 return res;
11c1ff18
PB
18344}
18345
ccb4c951
RS
18346/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18347 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18348 and return the VMA of the next entry, or -1 if there was a problem.
18349 Does not read from DATA_END or beyond. */
ccb4c951 18350
625d49fc
AM
18351static uint64_t
18352print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18353 unsigned char * data_end)
ccb4c951
RS
18354{
18355 printf (" ");
18356 print_vma (addr, LONG_HEX);
18357 printf (" ");
18358 if (addr < pltgot + 0xfff0)
18359 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18360 else
18361 printf ("%10s", "");
18362 printf (" ");
18363 if (data == NULL)
2b692964 18364 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18365 else
18366 {
625d49fc 18367 uint64_t entry;
82b1b41b 18368 unsigned char * from = data + addr - pltgot;
ccb4c951 18369
82b1b41b
NC
18370 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18371 {
18372 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18373 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18374 return (uint64_t) -1;
82b1b41b
NC
18375 }
18376 else
18377 {
18378 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18379 print_vma (entry, LONG_HEX);
18380 }
ccb4c951
RS
18381 }
18382 return addr + (is_32bit_elf ? 4 : 8);
18383}
18384
861fb55a
DJ
18385/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18386 PLTGOT. Print the Address and Initial fields of an entry at VMA
18387 ADDR and return the VMA of the next entry. */
18388
625d49fc
AM
18389static uint64_t
18390print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18391{
18392 printf (" ");
18393 print_vma (addr, LONG_HEX);
18394 printf (" ");
18395 if (data == NULL)
2b692964 18396 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18397 else
18398 {
625d49fc 18399 uint64_t entry;
861fb55a
DJ
18400
18401 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18402 print_vma (entry, LONG_HEX);
18403 }
18404 return addr + (is_32bit_elf ? 4 : 8);
18405}
18406
351cdf24
MF
18407static void
18408print_mips_ases (unsigned int mask)
18409{
18410 if (mask & AFL_ASE_DSP)
18411 fputs ("\n\tDSP ASE", stdout);
18412 if (mask & AFL_ASE_DSPR2)
18413 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18414 if (mask & AFL_ASE_DSPR3)
18415 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18416 if (mask & AFL_ASE_EVA)
18417 fputs ("\n\tEnhanced VA Scheme", stdout);
18418 if (mask & AFL_ASE_MCU)
18419 fputs ("\n\tMCU (MicroController) ASE", stdout);
18420 if (mask & AFL_ASE_MDMX)
18421 fputs ("\n\tMDMX ASE", stdout);
18422 if (mask & AFL_ASE_MIPS3D)
18423 fputs ("\n\tMIPS-3D ASE", stdout);
18424 if (mask & AFL_ASE_MT)
18425 fputs ("\n\tMT ASE", stdout);
18426 if (mask & AFL_ASE_SMARTMIPS)
18427 fputs ("\n\tSmartMIPS ASE", stdout);
18428 if (mask & AFL_ASE_VIRT)
18429 fputs ("\n\tVZ ASE", stdout);
18430 if (mask & AFL_ASE_MSA)
18431 fputs ("\n\tMSA ASE", stdout);
18432 if (mask & AFL_ASE_MIPS16)
18433 fputs ("\n\tMIPS16 ASE", stdout);
18434 if (mask & AFL_ASE_MICROMIPS)
18435 fputs ("\n\tMICROMIPS ASE", stdout);
18436 if (mask & AFL_ASE_XPA)
18437 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18438 if (mask & AFL_ASE_MIPS16E2)
18439 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18440 if (mask & AFL_ASE_CRC)
18441 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18442 if (mask & AFL_ASE_GINV)
18443 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18444 if (mask & AFL_ASE_LOONGSON_MMI)
18445 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18446 if (mask & AFL_ASE_LOONGSON_CAM)
18447 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18448 if (mask & AFL_ASE_LOONGSON_EXT)
18449 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18450 if (mask & AFL_ASE_LOONGSON_EXT2)
18451 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18452 if (mask == 0)
18453 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18454 else if ((mask & ~AFL_ASE_MASK) != 0)
18455 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18456}
18457
18458static void
18459print_mips_isa_ext (unsigned int isa_ext)
18460{
18461 switch (isa_ext)
18462 {
18463 case 0:
18464 fputs (_("None"), stdout);
18465 break;
18466 case AFL_EXT_XLR:
18467 fputs ("RMI XLR", stdout);
18468 break;
2c629856
N
18469 case AFL_EXT_OCTEON3:
18470 fputs ("Cavium Networks Octeon3", stdout);
18471 break;
351cdf24
MF
18472 case AFL_EXT_OCTEON2:
18473 fputs ("Cavium Networks Octeon2", stdout);
18474 break;
18475 case AFL_EXT_OCTEONP:
18476 fputs ("Cavium Networks OcteonP", stdout);
18477 break;
351cdf24
MF
18478 case AFL_EXT_OCTEON:
18479 fputs ("Cavium Networks Octeon", stdout);
18480 break;
18481 case AFL_EXT_5900:
18482 fputs ("Toshiba R5900", stdout);
18483 break;
18484 case AFL_EXT_4650:
18485 fputs ("MIPS R4650", stdout);
18486 break;
18487 case AFL_EXT_4010:
18488 fputs ("LSI R4010", stdout);
18489 break;
18490 case AFL_EXT_4100:
18491 fputs ("NEC VR4100", stdout);
18492 break;
18493 case AFL_EXT_3900:
18494 fputs ("Toshiba R3900", stdout);
18495 break;
18496 case AFL_EXT_10000:
18497 fputs ("MIPS R10000", stdout);
18498 break;
18499 case AFL_EXT_SB1:
18500 fputs ("Broadcom SB-1", stdout);
18501 break;
18502 case AFL_EXT_4111:
18503 fputs ("NEC VR4111/VR4181", stdout);
18504 break;
18505 case AFL_EXT_4120:
18506 fputs ("NEC VR4120", stdout);
18507 break;
18508 case AFL_EXT_5400:
18509 fputs ("NEC VR5400", stdout);
18510 break;
18511 case AFL_EXT_5500:
18512 fputs ("NEC VR5500", stdout);
18513 break;
18514 case AFL_EXT_LOONGSON_2E:
18515 fputs ("ST Microelectronics Loongson 2E", stdout);
18516 break;
18517 case AFL_EXT_LOONGSON_2F:
18518 fputs ("ST Microelectronics Loongson 2F", stdout);
18519 break;
38bf472a
MR
18520 case AFL_EXT_INTERAPTIV_MR2:
18521 fputs ("Imagination interAptiv MR2", stdout);
18522 break;
351cdf24 18523 default:
00ac7aa0 18524 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18525 }
18526}
18527
32ec8896 18528static signed int
351cdf24
MF
18529get_mips_reg_size (int reg_size)
18530{
18531 return (reg_size == AFL_REG_NONE) ? 0
18532 : (reg_size == AFL_REG_32) ? 32
18533 : (reg_size == AFL_REG_64) ? 64
18534 : (reg_size == AFL_REG_128) ? 128
18535 : -1;
18536}
18537
015dc7e1 18538static bool
dda8d76d 18539process_mips_specific (Filedata * filedata)
5b18a4bc 18540{
2cf0635d 18541 Elf_Internal_Dyn * entry;
351cdf24 18542 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18543 size_t liblist_offset = 0;
18544 size_t liblistno = 0;
18545 size_t conflictsno = 0;
18546 size_t options_offset = 0;
18547 size_t conflicts_offset = 0;
861fb55a
DJ
18548 size_t pltrelsz = 0;
18549 size_t pltrel = 0;
625d49fc
AM
18550 uint64_t pltgot = 0;
18551 uint64_t mips_pltgot = 0;
18552 uint64_t jmprel = 0;
18553 uint64_t local_gotno = 0;
18554 uint64_t gotsym = 0;
18555 uint64_t symtabno = 0;
015dc7e1 18556 bool res = true;
103f02d3 18557
dda8d76d 18558 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18559 display_mips_gnu_attribute))
015dc7e1 18560 res = false;
2cf19d5c 18561
dda8d76d 18562 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18563
18564 if (sect != NULL)
18565 {
18566 Elf_External_ABIFlags_v0 *abiflags_ext;
18567 Elf_Internal_ABIFlags_v0 abiflags_in;
18568
18569 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18570 {
18571 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18572 res = false;
32ec8896 18573 }
351cdf24
MF
18574 else
18575 {
dda8d76d 18576 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18577 sect->sh_size, _("MIPS ABI Flags section"));
18578 if (abiflags_ext)
18579 {
18580 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18581 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18582 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18583 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18584 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18585 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18586 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18587 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18588 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18589 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18590 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18591
18592 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18593 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18594 if (abiflags_in.isa_rev > 1)
18595 printf ("r%d", abiflags_in.isa_rev);
18596 printf ("\nGPR size: %d",
18597 get_mips_reg_size (abiflags_in.gpr_size));
18598 printf ("\nCPR1 size: %d",
18599 get_mips_reg_size (abiflags_in.cpr1_size));
18600 printf ("\nCPR2 size: %d",
18601 get_mips_reg_size (abiflags_in.cpr2_size));
18602 fputs ("\nFP ABI: ", stdout);
18603 print_mips_fp_abi_value (abiflags_in.fp_abi);
18604 fputs ("ISA Extension: ", stdout);
18605 print_mips_isa_ext (abiflags_in.isa_ext);
18606 fputs ("\nASEs:", stdout);
18607 print_mips_ases (abiflags_in.ases);
18608 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18609 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18610 fputc ('\n', stdout);
18611 free (abiflags_ext);
18612 }
18613 }
18614 }
18615
19e6b90e 18616 /* We have a lot of special sections. Thanks SGI! */
978c4450 18617 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18618 {
18619 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18620 sect = find_section (filedata, ".got");
bbdd9a68
MR
18621 if (sect != NULL)
18622 {
18623 unsigned char *data_end;
18624 unsigned char *data;
625d49fc 18625 uint64_t ent, end;
bbdd9a68
MR
18626 int addr_size;
18627
18628 pltgot = sect->sh_addr;
18629
18630 ent = pltgot;
18631 addr_size = (is_32bit_elf ? 4 : 8);
18632 end = pltgot + sect->sh_size;
18633
dda8d76d 18634 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18635 end - pltgot, 1,
18636 _("Global Offset Table data"));
18637 /* PR 12855: Null data is handled gracefully throughout. */
18638 data_end = data + (end - pltgot);
18639
18640 printf (_("\nStatic GOT:\n"));
18641 printf (_(" Canonical gp value: "));
18642 print_vma (ent + 0x7ff0, LONG_HEX);
18643 printf ("\n\n");
18644
18645 /* In a dynamic binary GOT[0] is reserved for the dynamic
18646 loader to store the lazy resolver pointer, however in
18647 a static binary it may well have been omitted and GOT
18648 reduced to a table of addresses.
18649 PR 21344: Check for the entry being fully available
18650 before fetching it. */
18651 if (data
18652 && data + ent - pltgot + addr_size <= data_end
18653 && byte_get (data + ent - pltgot, addr_size) == 0)
18654 {
18655 printf (_(" Reserved entries:\n"));
18656 printf (_(" %*s %10s %*s\n"),
18657 addr_size * 2, _("Address"), _("Access"),
18658 addr_size * 2, _("Value"));
18659 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18660 printf ("\n");
625d49fc 18661 if (ent == (uint64_t) -1)
bbdd9a68
MR
18662 goto sgot_print_fail;
18663
18664 /* Check for the MSB of GOT[1] being set, identifying a
18665 GNU object. This entry will be used by some runtime
18666 loaders, to store the module pointer. Otherwise this
18667 is an ordinary local entry.
18668 PR 21344: Check for the entry being fully available
18669 before fetching it. */
18670 if (data
18671 && data + ent - pltgot + addr_size <= data_end
18672 && (byte_get (data + ent - pltgot, addr_size)
18673 >> (addr_size * 8 - 1)) != 0)
18674 {
18675 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18676 printf ("\n");
625d49fc 18677 if (ent == (uint64_t) -1)
bbdd9a68
MR
18678 goto sgot_print_fail;
18679 }
18680 printf ("\n");
18681 }
18682
f17e9d8a 18683 if (data != NULL && ent < end)
bbdd9a68
MR
18684 {
18685 printf (_(" Local entries:\n"));
18686 printf (" %*s %10s %*s\n",
18687 addr_size * 2, _("Address"), _("Access"),
18688 addr_size * 2, _("Value"));
18689 while (ent < end)
18690 {
18691 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18692 printf ("\n");
625d49fc 18693 if (ent == (uint64_t) -1)
bbdd9a68
MR
18694 goto sgot_print_fail;
18695 }
18696 printf ("\n");
18697 }
18698
18699 sgot_print_fail:
9db70fc3 18700 free (data);
bbdd9a68
MR
18701 }
18702 return res;
18703 }
252b5132 18704
978c4450 18705 for (entry = filedata->dynamic_section;
071436c6 18706 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18707 (entry < filedata->dynamic_section + filedata->dynamic_nent
18708 && entry->d_tag != DT_NULL);
071436c6 18709 ++entry)
252b5132
RH
18710 switch (entry->d_tag)
18711 {
18712 case DT_MIPS_LIBLIST:
d93f0186 18713 liblist_offset
dda8d76d 18714 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18715 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18716 break;
18717 case DT_MIPS_LIBLISTNO:
18718 liblistno = entry->d_un.d_val;
18719 break;
18720 case DT_MIPS_OPTIONS:
dda8d76d 18721 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18722 break;
18723 case DT_MIPS_CONFLICT:
d93f0186 18724 conflicts_offset
dda8d76d 18725 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18726 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18727 break;
18728 case DT_MIPS_CONFLICTNO:
18729 conflictsno = entry->d_un.d_val;
18730 break;
ccb4c951 18731 case DT_PLTGOT:
861fb55a
DJ
18732 pltgot = entry->d_un.d_ptr;
18733 break;
ccb4c951
RS
18734 case DT_MIPS_LOCAL_GOTNO:
18735 local_gotno = entry->d_un.d_val;
18736 break;
18737 case DT_MIPS_GOTSYM:
18738 gotsym = entry->d_un.d_val;
18739 break;
18740 case DT_MIPS_SYMTABNO:
18741 symtabno = entry->d_un.d_val;
18742 break;
861fb55a
DJ
18743 case DT_MIPS_PLTGOT:
18744 mips_pltgot = entry->d_un.d_ptr;
18745 break;
18746 case DT_PLTREL:
18747 pltrel = entry->d_un.d_val;
18748 break;
18749 case DT_PLTRELSZ:
18750 pltrelsz = entry->d_un.d_val;
18751 break;
18752 case DT_JMPREL:
18753 jmprel = entry->d_un.d_ptr;
18754 break;
252b5132
RH
18755 default:
18756 break;
18757 }
18758
18759 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18760 {
2cf0635d 18761 Elf32_External_Lib * elib;
252b5132
RH
18762 size_t cnt;
18763
dda8d76d 18764 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18765 sizeof (Elf32_External_Lib),
18766 liblistno,
18767 _("liblist section data"));
a6e9f9df 18768 if (elib)
252b5132 18769 {
26c527e6
AM
18770 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
18771 "\nSection '.liblist' contains %zu entries:\n",
18772 liblistno),
18773 liblistno);
2b692964 18774 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18775 stdout);
18776
18777 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18778 {
a6e9f9df 18779 Elf32_Lib liblist;
91d6fa6a 18780 time_t atime;
d5b07ef4 18781 char timebuf[128];
2cf0635d 18782 struct tm * tmp;
a6e9f9df
AM
18783
18784 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18785 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18786 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18787 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18788 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18789
91d6fa6a 18790 tmp = gmtime (&atime);
e9e44622
JJ
18791 snprintf (timebuf, sizeof (timebuf),
18792 "%04u-%02u-%02uT%02u:%02u:%02u",
18793 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18794 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18795
26c527e6 18796 printf ("%3zu: ", cnt);
84714f86
AM
18797 if (valid_dynamic_name (filedata, liblist.l_name))
18798 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18799 else
2b692964 18800 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18801 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18802 liblist.l_version);
a6e9f9df
AM
18803
18804 if (liblist.l_flags == 0)
2b692964 18805 puts (_(" NONE"));
a6e9f9df
AM
18806 else
18807 {
18808 static const struct
252b5132 18809 {
2cf0635d 18810 const char * name;
a6e9f9df 18811 int bit;
252b5132 18812 }
a6e9f9df
AM
18813 l_flags_vals[] =
18814 {
18815 { " EXACT_MATCH", LL_EXACT_MATCH },
18816 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18817 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18818 { " EXPORTS", LL_EXPORTS },
18819 { " DELAY_LOAD", LL_DELAY_LOAD },
18820 { " DELTA", LL_DELTA }
18821 };
18822 int flags = liblist.l_flags;
18823 size_t fcnt;
18824
60bca95a 18825 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18826 if ((flags & l_flags_vals[fcnt].bit) != 0)
18827 {
18828 fputs (l_flags_vals[fcnt].name, stdout);
18829 flags ^= l_flags_vals[fcnt].bit;
18830 }
18831 if (flags != 0)
18832 printf (" %#x", (unsigned int) flags);
252b5132 18833
a6e9f9df
AM
18834 puts ("");
18835 }
252b5132 18836 }
252b5132 18837
a6e9f9df
AM
18838 free (elib);
18839 }
32ec8896 18840 else
015dc7e1 18841 res = false;
252b5132
RH
18842 }
18843
18844 if (options_offset != 0)
18845 {
2cf0635d 18846 Elf_External_Options * eopt;
252b5132
RH
18847 size_t offset;
18848 int cnt;
18849
18850 /* Find the section header so that we get the size. */
dda8d76d 18851 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18852 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18853 if (sect == NULL)
18854 {
18855 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18856 return false;
071436c6 18857 }
7fc0c668
NC
18858 /* PR 24243 */
18859 if (sect->sh_size < sizeof (* eopt))
18860 {
18861 error (_("The MIPS options section is too small.\n"));
015dc7e1 18862 return false;
7fc0c668 18863 }
252b5132 18864
dda8d76d 18865 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18866 sect->sh_size, _("options"));
a6e9f9df 18867 if (eopt)
252b5132 18868 {
fd17d1e6 18869 Elf_Internal_Options option;
76da6bbe 18870
a6e9f9df 18871 offset = cnt = 0;
82b1b41b 18872 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18873 {
2cf0635d 18874 Elf_External_Options * eoption;
fd17d1e6 18875 unsigned int optsize;
252b5132 18876
a6e9f9df 18877 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18878
fd17d1e6 18879 optsize = BYTE_GET (eoption->size);
76da6bbe 18880
82b1b41b 18881 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18882 if (optsize < sizeof (* eopt)
18883 || optsize > sect->sh_size - offset)
82b1b41b 18884 {
645f43a8 18885 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18886 optsize);
645f43a8 18887 free (eopt);
015dc7e1 18888 return false;
82b1b41b 18889 }
fd17d1e6 18890 offset += optsize;
a6e9f9df
AM
18891 ++cnt;
18892 }
252b5132 18893
d3a49aa8
AM
18894 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18895 "\nSection '%s' contains %d entries:\n",
18896 cnt),
dda8d76d 18897 printable_section_name (filedata, sect), cnt);
76da6bbe 18898
82b1b41b 18899 offset = 0;
a6e9f9df 18900 while (cnt-- > 0)
252b5132 18901 {
a6e9f9df 18902 size_t len;
fd17d1e6
AM
18903 Elf_External_Options * eoption;
18904
18905 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18906
18907 option.kind = BYTE_GET (eoption->kind);
18908 option.size = BYTE_GET (eoption->size);
18909 option.section = BYTE_GET (eoption->section);
18910 option.info = BYTE_GET (eoption->info);
a6e9f9df 18911
fd17d1e6 18912 switch (option.kind)
252b5132 18913 {
a6e9f9df
AM
18914 case ODK_NULL:
18915 /* This shouldn't happen. */
d0c4e780 18916 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18917 option.section, option.info);
a6e9f9df 18918 break;
2e6be59c 18919
a6e9f9df
AM
18920 case ODK_REGINFO:
18921 printf (" REGINFO ");
dda8d76d 18922 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18923 {
2cf0635d 18924 Elf32_External_RegInfo * ereg;
b34976b6 18925 Elf32_RegInfo reginfo;
a6e9f9df 18926
2e6be59c 18927 /* 32bit form. */
fd17d1e6
AM
18928 if (option.size < (sizeof (Elf_External_Options)
18929 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18930 {
18931 printf (_("<corrupt>\n"));
18932 error (_("Truncated MIPS REGINFO option\n"));
18933 cnt = 0;
18934 break;
18935 }
18936
fd17d1e6 18937 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18938
a6e9f9df
AM
18939 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18940 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18941 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18942 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18943 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18944 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18945
d0c4e780
AM
18946 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18947 reginfo.ri_gprmask, reginfo.ri_gp_value);
18948 printf (" "
18949 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18950 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18951 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18952 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18953 }
18954 else
18955 {
18956 /* 64 bit form. */
2cf0635d 18957 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18958 Elf64_Internal_RegInfo reginfo;
18959
fd17d1e6
AM
18960 if (option.size < (sizeof (Elf_External_Options)
18961 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18962 {
18963 printf (_("<corrupt>\n"));
18964 error (_("Truncated MIPS REGINFO option\n"));
18965 cnt = 0;
18966 break;
18967 }
18968
fd17d1e6 18969 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18970 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18971 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18972 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18973 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18974 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18975 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18976
d0c4e780
AM
18977 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18978 reginfo.ri_gprmask, reginfo.ri_gp_value);
18979 printf (" "
18980 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18981 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18982 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18983 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18984 }
fd17d1e6 18985 offset += option.size;
a6e9f9df 18986 continue;
2e6be59c 18987
a6e9f9df
AM
18988 case ODK_EXCEPTIONS:
18989 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18990 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18991 fputs (") fpe_max(", stdout);
fd17d1e6 18992 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18993 fputs (")", stdout);
18994
fd17d1e6 18995 if (option.info & OEX_PAGE0)
a6e9f9df 18996 fputs (" PAGE0", stdout);
fd17d1e6 18997 if (option.info & OEX_SMM)
a6e9f9df 18998 fputs (" SMM", stdout);
fd17d1e6 18999 if (option.info & OEX_FPDBUG)
a6e9f9df 19000 fputs (" FPDBUG", stdout);
fd17d1e6 19001 if (option.info & OEX_DISMISS)
a6e9f9df
AM
19002 fputs (" DISMISS", stdout);
19003 break;
2e6be59c 19004
a6e9f9df
AM
19005 case ODK_PAD:
19006 fputs (" PAD ", stdout);
fd17d1e6 19007 if (option.info & OPAD_PREFIX)
a6e9f9df 19008 fputs (" PREFIX", stdout);
fd17d1e6 19009 if (option.info & OPAD_POSTFIX)
a6e9f9df 19010 fputs (" POSTFIX", stdout);
fd17d1e6 19011 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
19012 fputs (" SYMBOL", stdout);
19013 break;
2e6be59c 19014
a6e9f9df
AM
19015 case ODK_HWPATCH:
19016 fputs (" HWPATCH ", stdout);
fd17d1e6 19017 if (option.info & OHW_R4KEOP)
a6e9f9df 19018 fputs (" R4KEOP", stdout);
fd17d1e6 19019 if (option.info & OHW_R8KPFETCH)
a6e9f9df 19020 fputs (" R8KPFETCH", stdout);
fd17d1e6 19021 if (option.info & OHW_R5KEOP)
a6e9f9df 19022 fputs (" R5KEOP", stdout);
fd17d1e6 19023 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
19024 fputs (" R5KCVTL", stdout);
19025 break;
2e6be59c 19026
a6e9f9df
AM
19027 case ODK_FILL:
19028 fputs (" FILL ", stdout);
19029 /* XXX Print content of info word? */
19030 break;
2e6be59c 19031
a6e9f9df
AM
19032 case ODK_TAGS:
19033 fputs (" TAGS ", stdout);
19034 /* XXX Print content of info word? */
19035 break;
2e6be59c 19036
a6e9f9df
AM
19037 case ODK_HWAND:
19038 fputs (" HWAND ", stdout);
fd17d1e6 19039 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19040 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19041 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19042 fputs (" R4KEOP_CLEAN", stdout);
19043 break;
2e6be59c 19044
a6e9f9df
AM
19045 case ODK_HWOR:
19046 fputs (" HWOR ", stdout);
fd17d1e6 19047 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19048 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19049 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19050 fputs (" R4KEOP_CLEAN", stdout);
19051 break;
2e6be59c 19052
a6e9f9df 19053 case ODK_GP_GROUP:
d0c4e780 19054 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
19055 option.info & OGP_GROUP,
19056 (option.info & OGP_SELF) >> 16);
a6e9f9df 19057 break;
2e6be59c 19058
a6e9f9df 19059 case ODK_IDENT:
d0c4e780 19060 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
19061 option.info & OGP_GROUP,
19062 (option.info & OGP_SELF) >> 16);
a6e9f9df 19063 break;
2e6be59c 19064
a6e9f9df
AM
19065 default:
19066 /* This shouldn't happen. */
d0c4e780 19067 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 19068 option.kind, option.section, option.info);
a6e9f9df 19069 break;
252b5132 19070 }
a6e9f9df 19071
2cf0635d 19072 len = sizeof (* eopt);
fd17d1e6 19073 while (len < option.size)
82b1b41b 19074 {
fd17d1e6 19075 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 19076
82b1b41b
NC
19077 if (ISPRINT (datum))
19078 printf ("%c", datum);
19079 else
19080 printf ("\\%03o", datum);
19081 len ++;
19082 }
a6e9f9df 19083 fputs ("\n", stdout);
82b1b41b 19084
fd17d1e6 19085 offset += option.size;
252b5132 19086 }
a6e9f9df 19087 free (eopt);
252b5132 19088 }
32ec8896 19089 else
015dc7e1 19090 res = false;
252b5132
RH
19091 }
19092
19093 if (conflicts_offset != 0 && conflictsno != 0)
19094 {
2cf0635d 19095 Elf32_Conflict * iconf;
252b5132
RH
19096 size_t cnt;
19097
978c4450 19098 if (filedata->dynamic_symbols == NULL)
252b5132 19099 {
591a748a 19100 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 19101 return false;
252b5132
RH
19102 }
19103
7296a62a
NC
19104 /* PR 21345 - print a slightly more helpful error message
19105 if we are sure that the cmalloc will fail. */
645f43a8 19106 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 19107 {
26c527e6
AM
19108 error (_("Overlarge number of conflicts detected: %zx\n"),
19109 conflictsno);
015dc7e1 19110 return false;
7296a62a
NC
19111 }
19112
3f5e193b 19113 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
19114 if (iconf == NULL)
19115 {
8b73c356 19116 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 19117 return false;
252b5132
RH
19118 }
19119
9ea033b2 19120 if (is_32bit_elf)
252b5132 19121 {
2cf0635d 19122 Elf32_External_Conflict * econf32;
a6e9f9df 19123
3f5e193b 19124 econf32 = (Elf32_External_Conflict *)
95099889
AM
19125 get_data (NULL, filedata, conflicts_offset,
19126 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 19127 if (!econf32)
5a814d6d
AM
19128 {
19129 free (iconf);
015dc7e1 19130 return false;
5a814d6d 19131 }
252b5132
RH
19132
19133 for (cnt = 0; cnt < conflictsno; ++cnt)
19134 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
19135
19136 free (econf32);
252b5132
RH
19137 }
19138 else
19139 {
2cf0635d 19140 Elf64_External_Conflict * econf64;
a6e9f9df 19141
3f5e193b 19142 econf64 = (Elf64_External_Conflict *)
95099889
AM
19143 get_data (NULL, filedata, conflicts_offset,
19144 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 19145 if (!econf64)
5a814d6d
AM
19146 {
19147 free (iconf);
015dc7e1 19148 return false;
5a814d6d 19149 }
252b5132
RH
19150
19151 for (cnt = 0; cnt < conflictsno; ++cnt)
19152 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
19153
19154 free (econf64);
252b5132
RH
19155 }
19156
26c527e6
AM
19157 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19158 "\nSection '.conflict' contains %zu entries:\n",
19159 conflictsno),
19160 conflictsno);
252b5132
RH
19161 puts (_(" Num: Index Value Name"));
19162
19163 for (cnt = 0; cnt < conflictsno; ++cnt)
19164 {
26c527e6 19165 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 19166
978c4450 19167 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 19168 printf (_("<corrupt symbol index>"));
d79b3d50 19169 else
e0a31db1
NC
19170 {
19171 Elf_Internal_Sym * psym;
19172
978c4450 19173 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
19174 print_vma (psym->st_value, FULL_HEX);
19175 putchar (' ');
84714f86
AM
19176 if (valid_dynamic_name (filedata, psym->st_name))
19177 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19178 else
19179 printf (_("<corrupt: %14ld>"), psym->st_name);
19180 }
31104126 19181 putchar ('\n');
252b5132
RH
19182 }
19183
252b5132
RH
19184 free (iconf);
19185 }
19186
ccb4c951
RS
19187 if (pltgot != 0 && local_gotno != 0)
19188 {
625d49fc 19189 uint64_t ent, local_end, global_end;
bbeee7ea 19190 size_t i, offset;
2cf0635d 19191 unsigned char * data;
82b1b41b 19192 unsigned char * data_end;
bbeee7ea 19193 int addr_size;
ccb4c951 19194
91d6fa6a 19195 ent = pltgot;
ccb4c951
RS
19196 addr_size = (is_32bit_elf ? 4 : 8);
19197 local_end = pltgot + local_gotno * addr_size;
ccb4c951 19198
74e1a04b
NC
19199 /* PR binutils/17533 file: 012-111227-0.004 */
19200 if (symtabno < gotsym)
19201 {
26c527e6
AM
19202 error (_("The GOT symbol offset (%" PRIu64
19203 ") is greater than the symbol table size (%" PRIu64 ")\n"),
19204 gotsym, symtabno);
015dc7e1 19205 return false;
74e1a04b 19206 }
82b1b41b 19207
74e1a04b 19208 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
19209 /* PR 17531: file: 54c91a34. */
19210 if (global_end < local_end)
19211 {
26c527e6 19212 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 19213 return false;
82b1b41b 19214 }
948f632f 19215
dda8d76d
NC
19216 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
19217 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
19218 global_end - pltgot, 1,
19219 _("Global Offset Table data"));
919383ac 19220 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 19221 data_end = data + (global_end - pltgot);
59245841 19222
ccb4c951
RS
19223 printf (_("\nPrimary GOT:\n"));
19224 printf (_(" Canonical gp value: "));
19225 print_vma (pltgot + 0x7ff0, LONG_HEX);
19226 printf ("\n\n");
19227
19228 printf (_(" Reserved entries:\n"));
19229 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
19230 addr_size * 2, _("Address"), _("Access"),
19231 addr_size * 2, _("Initial"));
82b1b41b 19232 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 19233 printf (_(" Lazy resolver\n"));
625d49fc 19234 if (ent == (uint64_t) -1)
82b1b41b 19235 goto got_print_fail;
75ec1fdb 19236
c4ab9505
MR
19237 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19238 This entry will be used by some runtime loaders, to store the
19239 module pointer. Otherwise this is an ordinary local entry.
19240 PR 21344: Check for the entry being fully available before
19241 fetching it. */
19242 if (data
19243 && data + ent - pltgot + addr_size <= data_end
19244 && (byte_get (data + ent - pltgot, addr_size)
19245 >> (addr_size * 8 - 1)) != 0)
19246 {
19247 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19248 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 19249 if (ent == (uint64_t) -1)
c4ab9505 19250 goto got_print_fail;
ccb4c951
RS
19251 }
19252 printf ("\n");
19253
f17e9d8a 19254 if (data != NULL && ent < local_end)
ccb4c951
RS
19255 {
19256 printf (_(" Local entries:\n"));
cc5914eb 19257 printf (" %*s %10s %*s\n",
2b692964
NC
19258 addr_size * 2, _("Address"), _("Access"),
19259 addr_size * 2, _("Initial"));
91d6fa6a 19260 while (ent < local_end)
ccb4c951 19261 {
82b1b41b 19262 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19263 printf ("\n");
625d49fc 19264 if (ent == (uint64_t) -1)
82b1b41b 19265 goto got_print_fail;
ccb4c951
RS
19266 }
19267 printf ("\n");
19268 }
19269
f17e9d8a 19270 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19271 {
19272 int sym_width;
19273
19274 printf (_(" Global entries:\n"));
cc5914eb 19275 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19276 addr_size * 2, _("Address"),
19277 _("Access"),
2b692964 19278 addr_size * 2, _("Initial"),
9cf03b7e
NC
19279 addr_size * 2, _("Sym.Val."),
19280 _("Type"),
19281 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19282 _("Ndx"), _("Name"));
0b4362b0 19283
ccb4c951 19284 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19285
ccb4c951
RS
19286 for (i = gotsym; i < symtabno; i++)
19287 {
82b1b41b 19288 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19289 printf (" ");
e0a31db1 19290
978c4450 19291 if (filedata->dynamic_symbols == NULL)
e0a31db1 19292 printf (_("<no dynamic symbols>"));
978c4450 19293 else if (i < filedata->num_dynamic_syms)
e0a31db1 19294 {
978c4450 19295 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19296
19297 print_vma (psym->st_value, LONG_HEX);
19298 printf (" %-7s %3s ",
dda8d76d
NC
19299 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19300 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19301
84714f86 19302 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19303 print_symbol (sym_width,
84714f86 19304 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19305 else
19306 printf (_("<corrupt: %14ld>"), psym->st_name);
19307 }
ccb4c951 19308 else
26c527e6
AM
19309 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
19310 i);
e0a31db1 19311
ccb4c951 19312 printf ("\n");
625d49fc 19313 if (ent == (uint64_t) -1)
82b1b41b 19314 break;
ccb4c951
RS
19315 }
19316 printf ("\n");
19317 }
19318
82b1b41b 19319 got_print_fail:
9db70fc3 19320 free (data);
ccb4c951
RS
19321 }
19322
861fb55a
DJ
19323 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19324 {
625d49fc 19325 uint64_t ent, end;
26c527e6
AM
19326 uint64_t offset, rel_offset;
19327 uint64_t count, i;
2cf0635d 19328 unsigned char * data;
861fb55a 19329 int addr_size, sym_width;
2cf0635d 19330 Elf_Internal_Rela * rels;
861fb55a 19331
dda8d76d 19332 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19333 if (pltrel == DT_RELA)
19334 {
dda8d76d 19335 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19336 return false;
861fb55a
DJ
19337 }
19338 else
19339 {
dda8d76d 19340 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19341 return false;
861fb55a
DJ
19342 }
19343
91d6fa6a 19344 ent = mips_pltgot;
861fb55a
DJ
19345 addr_size = (is_32bit_elf ? 4 : 8);
19346 end = mips_pltgot + (2 + count) * addr_size;
19347
dda8d76d
NC
19348 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19349 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19350 1, _("Procedure Linkage Table data"));
59245841 19351 if (data == NULL)
288f0ba2
AM
19352 {
19353 free (rels);
015dc7e1 19354 return false;
288f0ba2 19355 }
59245841 19356
9cf03b7e 19357 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19358 printf (_(" Reserved entries:\n"));
19359 printf (_(" %*s %*s Purpose\n"),
2b692964 19360 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19361 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19362 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19363 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19364 printf (_(" Module pointer\n"));
861fb55a
DJ
19365 printf ("\n");
19366
19367 printf (_(" Entries:\n"));
cc5914eb 19368 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19369 addr_size * 2, _("Address"),
19370 addr_size * 2, _("Initial"),
19371 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19372 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19373 for (i = 0; i < count; i++)
19374 {
26c527e6 19375 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19376
91d6fa6a 19377 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19378 printf (" ");
e0a31db1 19379
978c4450 19380 if (idx >= filedata->num_dynamic_syms)
26c527e6 19381 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 19382 else
e0a31db1 19383 {
978c4450 19384 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19385
19386 print_vma (psym->st_value, LONG_HEX);
19387 printf (" %-7s %3s ",
dda8d76d
NC
19388 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19389 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19390 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19391 print_symbol (sym_width,
84714f86 19392 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19393 else
19394 printf (_("<corrupt: %14ld>"), psym->st_name);
19395 }
861fb55a
DJ
19396 printf ("\n");
19397 }
19398 printf ("\n");
19399
9db70fc3 19400 free (data);
861fb55a
DJ
19401 free (rels);
19402 }
19403
32ec8896 19404 return res;
252b5132
RH
19405}
19406
015dc7e1 19407static bool
dda8d76d 19408process_nds32_specific (Filedata * filedata)
35c08157
KLC
19409{
19410 Elf_Internal_Shdr *sect = NULL;
19411
dda8d76d 19412 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19413 if (sect != NULL && sect->sh_size >= 4)
35c08157 19414 {
9c7b8e9b
AM
19415 unsigned char *buf;
19416 unsigned int flag;
35c08157
KLC
19417
19418 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19419 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19420 _("NDS32 elf flags section"));
35c08157 19421
9c7b8e9b 19422 if (buf == NULL)
015dc7e1 19423 return false;
32ec8896 19424
9c7b8e9b
AM
19425 flag = byte_get (buf, 4);
19426 free (buf);
19427 switch (flag & 0x3)
35c08157
KLC
19428 {
19429 case 0:
19430 printf ("(VEC_SIZE):\tNo entry.\n");
19431 break;
19432 case 1:
19433 printf ("(VEC_SIZE):\t4 bytes\n");
19434 break;
19435 case 2:
19436 printf ("(VEC_SIZE):\t16 bytes\n");
19437 break;
19438 case 3:
19439 printf ("(VEC_SIZE):\treserved\n");
19440 break;
19441 }
19442 }
19443
015dc7e1 19444 return true;
35c08157
KLC
19445}
19446
015dc7e1 19447static bool
dda8d76d 19448process_gnu_liblist (Filedata * filedata)
047b2264 19449{
2cf0635d
NC
19450 Elf_Internal_Shdr * section;
19451 Elf_Internal_Shdr * string_sec;
19452 Elf32_External_Lib * elib;
19453 char * strtab;
c256ffe7 19454 size_t strtab_size;
047b2264 19455 size_t cnt;
26c527e6 19456 uint64_t num_liblist;
047b2264 19457 unsigned i;
015dc7e1 19458 bool res = true;
047b2264
JJ
19459
19460 if (! do_arch)
015dc7e1 19461 return true;
047b2264 19462
dda8d76d
NC
19463 for (i = 0, section = filedata->section_headers;
19464 i < filedata->file_header.e_shnum;
b34976b6 19465 i++, section++)
047b2264
JJ
19466 {
19467 switch (section->sh_type)
19468 {
19469 case SHT_GNU_LIBLIST:
dda8d76d 19470 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19471 break;
19472
3f5e193b 19473 elib = (Elf32_External_Lib *)
dda8d76d 19474 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19475 _("liblist section data"));
047b2264
JJ
19476
19477 if (elib == NULL)
32ec8896 19478 {
015dc7e1 19479 res = false;
32ec8896
NC
19480 break;
19481 }
047b2264 19482
dda8d76d
NC
19483 string_sec = filedata->section_headers + section->sh_link;
19484 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19485 string_sec->sh_size,
19486 _("liblist string table"));
047b2264
JJ
19487 if (strtab == NULL
19488 || section->sh_entsize != sizeof (Elf32_External_Lib))
19489 {
19490 free (elib);
2842702f 19491 free (strtab);
015dc7e1 19492 res = false;
047b2264
JJ
19493 break;
19494 }
59245841 19495 strtab_size = string_sec->sh_size;
047b2264 19496
d3a49aa8 19497 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
19498 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
19499 " entries:\n",
19500 "\nLibrary list section '%s' contains %" PRIu64
19501 " entries:\n",
d3a49aa8 19502 num_liblist),
dda8d76d 19503 printable_section_name (filedata, section),
d3a49aa8 19504 num_liblist);
047b2264 19505
2b692964 19506 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19507
19508 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19509 ++cnt)
19510 {
19511 Elf32_Lib liblist;
91d6fa6a 19512 time_t atime;
d5b07ef4 19513 char timebuf[128];
2cf0635d 19514 struct tm * tmp;
047b2264
JJ
19515
19516 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19517 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19518 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19519 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19520 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19521
91d6fa6a 19522 tmp = gmtime (&atime);
e9e44622
JJ
19523 snprintf (timebuf, sizeof (timebuf),
19524 "%04u-%02u-%02uT%02u:%02u:%02u",
19525 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19526 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 19527
26c527e6 19528 printf ("%3zu: ", cnt);
047b2264 19529 if (do_wide)
c256ffe7 19530 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19531 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19532 else
c256ffe7 19533 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19534 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19535 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19536 liblist.l_version, liblist.l_flags);
19537 }
19538
19539 free (elib);
2842702f 19540 free (strtab);
047b2264
JJ
19541 }
19542 }
19543
32ec8896 19544 return res;
047b2264
JJ
19545}
19546
9437c45b 19547static const char *
dda8d76d 19548get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19549{
19550 static char buff[64];
103f02d3 19551
dda8d76d 19552 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19553 switch (e_type)
19554 {
57346661 19555 case NT_AUXV:
1ec5cd37 19556 return _("NT_AUXV (auxiliary vector)");
57346661 19557 case NT_PRSTATUS:
1ec5cd37 19558 return _("NT_PRSTATUS (prstatus structure)");
57346661 19559 case NT_FPREGSET:
1ec5cd37 19560 return _("NT_FPREGSET (floating point registers)");
57346661 19561 case NT_PRPSINFO:
1ec5cd37 19562 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19563 case NT_TASKSTRUCT:
1ec5cd37 19564 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19565 case NT_GDB_TDESC:
19566 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19567 case NT_PRXFPREG:
1ec5cd37 19568 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19569 case NT_PPC_VMX:
19570 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19571 case NT_PPC_VSX:
19572 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19573 case NT_PPC_TAR:
19574 return _("NT_PPC_TAR (ppc TAR register)");
19575 case NT_PPC_PPR:
19576 return _("NT_PPC_PPR (ppc PPR register)");
19577 case NT_PPC_DSCR:
19578 return _("NT_PPC_DSCR (ppc DSCR register)");
19579 case NT_PPC_EBB:
19580 return _("NT_PPC_EBB (ppc EBB registers)");
19581 case NT_PPC_PMU:
19582 return _("NT_PPC_PMU (ppc PMU registers)");
19583 case NT_PPC_TM_CGPR:
19584 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19585 case NT_PPC_TM_CFPR:
19586 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19587 case NT_PPC_TM_CVMX:
19588 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19589 case NT_PPC_TM_CVSX:
3fd21718 19590 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19591 case NT_PPC_TM_SPR:
19592 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19593 case NT_PPC_TM_CTAR:
19594 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19595 case NT_PPC_TM_CPPR:
19596 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19597 case NT_PPC_TM_CDSCR:
19598 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19599 case NT_386_TLS:
19600 return _("NT_386_TLS (x86 TLS information)");
19601 case NT_386_IOPERM:
19602 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19603 case NT_X86_XSTATE:
19604 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19605 case NT_X86_CET:
19606 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19607 case NT_S390_HIGH_GPRS:
19608 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19609 case NT_S390_TIMER:
19610 return _("NT_S390_TIMER (s390 timer register)");
19611 case NT_S390_TODCMP:
19612 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19613 case NT_S390_TODPREG:
19614 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19615 case NT_S390_CTRS:
19616 return _("NT_S390_CTRS (s390 control registers)");
19617 case NT_S390_PREFIX:
19618 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19619 case NT_S390_LAST_BREAK:
19620 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19621 case NT_S390_SYSTEM_CALL:
19622 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19623 case NT_S390_TDB:
19624 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19625 case NT_S390_VXRS_LOW:
19626 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19627 case NT_S390_VXRS_HIGH:
19628 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19629 case NT_S390_GS_CB:
19630 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19631 case NT_S390_GS_BC:
19632 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19633 case NT_ARM_VFP:
19634 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19635 case NT_ARM_TLS:
19636 return _("NT_ARM_TLS (AArch TLS registers)");
19637 case NT_ARM_HW_BREAK:
19638 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19639 case NT_ARM_HW_WATCH:
19640 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
19641 case NT_ARM_SYSTEM_CALL:
19642 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
19643 case NT_ARM_SVE:
19644 return _("NT_ARM_SVE (AArch SVE registers)");
19645 case NT_ARM_PAC_MASK:
19646 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19647 case NT_ARM_PACA_KEYS:
19648 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19649 case NT_ARM_PACG_KEYS:
19650 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19651 case NT_ARM_TAGGED_ADDR_CTRL:
19652 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
a8f175d9
LM
19653 case NT_ARM_SSVE:
19654 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
19655 case NT_ARM_ZA:
19656 return _("NT_ARM_ZA (AArch64 SME ZA register)");
3af2785c
LM
19657 case NT_ARM_PAC_ENABLED_KEYS:
19658 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19659 case NT_ARC_V2:
19660 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19661 case NT_RISCV_CSR:
19662 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19663 case NT_PSTATUS:
1ec5cd37 19664 return _("NT_PSTATUS (pstatus structure)");
57346661 19665 case NT_FPREGS:
1ec5cd37 19666 return _("NT_FPREGS (floating point registers)");
57346661 19667 case NT_PSINFO:
1ec5cd37 19668 return _("NT_PSINFO (psinfo structure)");
57346661 19669 case NT_LWPSTATUS:
1ec5cd37 19670 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19671 case NT_LWPSINFO:
1ec5cd37 19672 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19673 case NT_WIN32PSTATUS:
1ec5cd37 19674 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19675 case NT_SIGINFO:
19676 return _("NT_SIGINFO (siginfo_t data)");
19677 case NT_FILE:
19678 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19679 default:
19680 break;
19681 }
19682 else
19683 switch (e_type)
19684 {
19685 case NT_VERSION:
19686 return _("NT_VERSION (version)");
19687 case NT_ARCH:
19688 return _("NT_ARCH (architecture)");
9ef920e9 19689 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19690 return _("OPEN");
9ef920e9 19691 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19692 return _("func");
c8795e1f
NC
19693 case NT_GO_BUILDID:
19694 return _("GO BUILDID");
3ac925fc
LB
19695 case FDO_PACKAGING_METADATA:
19696 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19697 default:
19698 break;
19699 }
19700
e9e44622 19701 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19702 return buff;
779fe533
NC
19703}
19704
015dc7e1 19705static bool
9ece1fa9
TT
19706print_core_note (Elf_Internal_Note *pnote)
19707{
19708 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 19709 uint64_t count, page_size;
9ece1fa9
TT
19710 unsigned char *descdata, *filenames, *descend;
19711
19712 if (pnote->type != NT_FILE)
04ac15ab
AS
19713 {
19714 if (do_wide)
19715 printf ("\n");
015dc7e1 19716 return true;
04ac15ab 19717 }
9ece1fa9 19718
9ece1fa9
TT
19719 if (!is_32bit_elf)
19720 {
19721 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19722 /* Still "successful". */
015dc7e1 19723 return true;
9ece1fa9 19724 }
9ece1fa9
TT
19725
19726 if (pnote->descsz < 2 * addr_size)
19727 {
32ec8896 19728 error (_(" Malformed note - too short for header\n"));
015dc7e1 19729 return false;
9ece1fa9
TT
19730 }
19731
19732 descdata = (unsigned char *) pnote->descdata;
19733 descend = descdata + pnote->descsz;
19734
19735 if (descdata[pnote->descsz - 1] != '\0')
19736 {
32ec8896 19737 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19738 return false;
9ece1fa9
TT
19739 }
19740
19741 count = byte_get (descdata, addr_size);
19742 descdata += addr_size;
19743
19744 page_size = byte_get (descdata, addr_size);
19745 descdata += addr_size;
19746
625d49fc 19747 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 19748 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19749 {
32ec8896 19750 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19751 return false;
9ece1fa9
TT
19752 }
19753
19754 printf (_(" Page size: "));
19755 print_vma (page_size, DEC);
19756 printf ("\n");
19757
19758 printf (_(" %*s%*s%*s\n"),
19759 (int) (2 + 2 * addr_size), _("Start"),
19760 (int) (4 + 2 * addr_size), _("End"),
19761 (int) (4 + 2 * addr_size), _("Page Offset"));
19762 filenames = descdata + count * 3 * addr_size;
595712bb 19763 while (count-- > 0)
9ece1fa9 19764 {
625d49fc 19765 uint64_t start, end, file_ofs;
9ece1fa9
TT
19766
19767 if (filenames == descend)
19768 {
32ec8896 19769 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19770 return false;
9ece1fa9
TT
19771 }
19772
19773 start = byte_get (descdata, addr_size);
19774 descdata += addr_size;
19775 end = byte_get (descdata, addr_size);
19776 descdata += addr_size;
19777 file_ofs = byte_get (descdata, addr_size);
19778 descdata += addr_size;
19779
19780 printf (" ");
19781 print_vma (start, FULL_HEX);
19782 printf (" ");
19783 print_vma (end, FULL_HEX);
19784 printf (" ");
19785 print_vma (file_ofs, FULL_HEX);
19786 printf ("\n %s\n", filenames);
19787
19788 filenames += 1 + strlen ((char *) filenames);
19789 }
19790
015dc7e1 19791 return true;
9ece1fa9
TT
19792}
19793
1118d252
RM
19794static const char *
19795get_gnu_elf_note_type (unsigned e_type)
19796{
1449284b 19797 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19798 switch (e_type)
19799 {
19800 case NT_GNU_ABI_TAG:
19801 return _("NT_GNU_ABI_TAG (ABI version tag)");
19802 case NT_GNU_HWCAP:
19803 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19804 case NT_GNU_BUILD_ID:
19805 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19806 case NT_GNU_GOLD_VERSION:
19807 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19808 case NT_GNU_PROPERTY_TYPE_0:
19809 return _("NT_GNU_PROPERTY_TYPE_0");
19810 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19811 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19812 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19813 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19814 default:
1449284b
NC
19815 {
19816 static char buff[64];
1118d252 19817
1449284b
NC
19818 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19819 return buff;
19820 }
19821 }
1118d252
RM
19822}
19823
a9eafb08
L
19824static void
19825decode_x86_compat_isa (unsigned int bitmask)
19826{
19827 while (bitmask)
19828 {
19829 unsigned int bit = bitmask & (- bitmask);
19830
19831 bitmask &= ~ bit;
19832 switch (bit)
19833 {
19834 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19835 printf ("i486");
19836 break;
19837 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19838 printf ("586");
19839 break;
19840 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19841 printf ("686");
19842 break;
19843 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19844 printf ("SSE");
19845 break;
19846 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19847 printf ("SSE2");
19848 break;
19849 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19850 printf ("SSE3");
19851 break;
19852 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19853 printf ("SSSE3");
19854 break;
19855 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19856 printf ("SSE4_1");
19857 break;
19858 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19859 printf ("SSE4_2");
19860 break;
19861 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19862 printf ("AVX");
19863 break;
19864 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19865 printf ("AVX2");
19866 break;
19867 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19868 printf ("AVX512F");
19869 break;
19870 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19871 printf ("AVX512CD");
19872 break;
19873 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19874 printf ("AVX512ER");
19875 break;
19876 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19877 printf ("AVX512PF");
19878 break;
19879 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19880 printf ("AVX512VL");
19881 break;
19882 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19883 printf ("AVX512DQ");
19884 break;
19885 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19886 printf ("AVX512BW");
19887 break;
65b3d26e
L
19888 default:
19889 printf (_("<unknown: %x>"), bit);
19890 break;
a9eafb08
L
19891 }
19892 if (bitmask)
19893 printf (", ");
19894 }
19895}
19896
9ef920e9 19897static void
32930e4e 19898decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19899{
0a59decb 19900 if (!bitmask)
90c745dc
L
19901 {
19902 printf (_("<None>"));
19903 return;
19904 }
90c745dc 19905
9ef920e9
NC
19906 while (bitmask)
19907 {
1fc87489 19908 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19909
19910 bitmask &= ~ bit;
19911 switch (bit)
19912 {
32930e4e 19913 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19914 printf ("CMOV");
19915 break;
32930e4e 19916 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19917 printf ("SSE");
19918 break;
32930e4e 19919 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19920 printf ("SSE2");
19921 break;
32930e4e 19922 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19923 printf ("SSE3");
19924 break;
32930e4e 19925 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19926 printf ("SSSE3");
19927 break;
32930e4e 19928 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19929 printf ("SSE4_1");
19930 break;
32930e4e 19931 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19932 printf ("SSE4_2");
19933 break;
32930e4e 19934 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19935 printf ("AVX");
19936 break;
32930e4e 19937 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19938 printf ("AVX2");
19939 break;
32930e4e 19940 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19941 printf ("FMA");
19942 break;
32930e4e 19943 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19944 printf ("AVX512F");
19945 break;
32930e4e 19946 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19947 printf ("AVX512CD");
19948 break;
32930e4e 19949 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19950 printf ("AVX512ER");
19951 break;
32930e4e 19952 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19953 printf ("AVX512PF");
19954 break;
32930e4e 19955 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19956 printf ("AVX512VL");
19957 break;
32930e4e 19958 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19959 printf ("AVX512DQ");
19960 break;
32930e4e 19961 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19962 printf ("AVX512BW");
19963 break;
32930e4e 19964 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19965 printf ("AVX512_4FMAPS");
19966 break;
32930e4e 19967 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19968 printf ("AVX512_4VNNIW");
19969 break;
32930e4e 19970 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19971 printf ("AVX512_BITALG");
19972 break;
32930e4e 19973 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19974 printf ("AVX512_IFMA");
19975 break;
32930e4e 19976 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19977 printf ("AVX512_VBMI");
19978 break;
32930e4e 19979 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19980 printf ("AVX512_VBMI2");
19981 break;
32930e4e 19982 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19983 printf ("AVX512_VNNI");
19984 break;
32930e4e 19985 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19986 printf ("AVX512_BF16");
19987 break;
65b3d26e
L
19988 default:
19989 printf (_("<unknown: %x>"), bit);
19990 break;
9ef920e9
NC
19991 }
19992 if (bitmask)
19993 printf (", ");
19994 }
19995}
19996
28cdbb18
SM
19997static const char *
19998get_amdgpu_elf_note_type (unsigned int e_type)
19999{
20000 switch (e_type)
20001 {
20002 case NT_AMDGPU_METADATA:
20003 return _("NT_AMDGPU_METADATA (code object metadata)");
20004 default:
20005 {
20006 static char buf[64];
20007 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
20008 return buf;
20009 }
20010 }
20011}
20012
32930e4e
L
20013static void
20014decode_x86_isa (unsigned int bitmask)
20015{
32930e4e
L
20016 while (bitmask)
20017 {
20018 unsigned int bit = bitmask & (- bitmask);
20019
20020 bitmask &= ~ bit;
20021 switch (bit)
20022 {
b0ab0693
L
20023 case GNU_PROPERTY_X86_ISA_1_BASELINE:
20024 printf ("x86-64-baseline");
20025 break;
32930e4e
L
20026 case GNU_PROPERTY_X86_ISA_1_V2:
20027 printf ("x86-64-v2");
20028 break;
20029 case GNU_PROPERTY_X86_ISA_1_V3:
20030 printf ("x86-64-v3");
20031 break;
20032 case GNU_PROPERTY_X86_ISA_1_V4:
20033 printf ("x86-64-v4");
20034 break;
20035 default:
20036 printf (_("<unknown: %x>"), bit);
20037 break;
20038 }
20039 if (bitmask)
20040 printf (", ");
20041 }
20042}
20043
ee2fdd6f 20044static void
a9eafb08 20045decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 20046{
0a59decb 20047 if (!bitmask)
90c745dc
L
20048 {
20049 printf (_("<None>"));
20050 return;
20051 }
90c745dc 20052
ee2fdd6f
L
20053 while (bitmask)
20054 {
20055 unsigned int bit = bitmask & (- bitmask);
20056
20057 bitmask &= ~ bit;
20058 switch (bit)
20059 {
20060 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 20061 printf ("IBT");
ee2fdd6f 20062 break;
48580982 20063 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 20064 printf ("SHSTK");
48580982 20065 break;
279d901e
L
20066 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
20067 printf ("LAM_U48");
20068 break;
20069 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
20070 printf ("LAM_U57");
20071 break;
ee2fdd6f
L
20072 default:
20073 printf (_("<unknown: %x>"), bit);
20074 break;
20075 }
20076 if (bitmask)
20077 printf (", ");
20078 }
20079}
20080
a9eafb08
L
20081static void
20082decode_x86_feature_2 (unsigned int bitmask)
20083{
0a59decb 20084 if (!bitmask)
90c745dc
L
20085 {
20086 printf (_("<None>"));
20087 return;
20088 }
90c745dc 20089
a9eafb08
L
20090 while (bitmask)
20091 {
20092 unsigned int bit = bitmask & (- bitmask);
20093
20094 bitmask &= ~ bit;
20095 switch (bit)
20096 {
20097 case GNU_PROPERTY_X86_FEATURE_2_X86:
20098 printf ("x86");
20099 break;
20100 case GNU_PROPERTY_X86_FEATURE_2_X87:
20101 printf ("x87");
20102 break;
20103 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20104 printf ("MMX");
20105 break;
20106 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20107 printf ("XMM");
20108 break;
20109 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20110 printf ("YMM");
20111 break;
20112 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20113 printf ("ZMM");
20114 break;
a308b89d
L
20115 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20116 printf ("TMM");
20117 break;
32930e4e
L
20118 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20119 printf ("MASK");
20120 break;
a9eafb08
L
20121 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20122 printf ("FXSR");
20123 break;
20124 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20125 printf ("XSAVE");
20126 break;
20127 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20128 printf ("XSAVEOPT");
20129 break;
20130 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20131 printf ("XSAVEC");
20132 break;
65b3d26e
L
20133 default:
20134 printf (_("<unknown: %x>"), bit);
20135 break;
a9eafb08
L
20136 }
20137 if (bitmask)
20138 printf (", ");
20139 }
20140}
20141
cd702818
SD
20142static void
20143decode_aarch64_feature_1_and (unsigned int bitmask)
20144{
20145 while (bitmask)
20146 {
20147 unsigned int bit = bitmask & (- bitmask);
20148
20149 bitmask &= ~ bit;
20150 switch (bit)
20151 {
20152 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20153 printf ("BTI");
20154 break;
20155
20156 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20157 printf ("PAC");
20158 break;
20159
20160 default:
20161 printf (_("<unknown: %x>"), bit);
20162 break;
20163 }
20164 if (bitmask)
20165 printf (", ");
20166 }
20167}
20168
6320fd00
L
20169static void
20170decode_1_needed (unsigned int bitmask)
20171{
20172 while (bitmask)
20173 {
20174 unsigned int bit = bitmask & (- bitmask);
20175
20176 bitmask &= ~ bit;
20177 switch (bit)
20178 {
20179 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20180 printf ("indirect external access");
20181 break;
20182 default:
20183 printf (_("<unknown: %x>"), bit);
20184 break;
20185 }
20186 if (bitmask)
20187 printf (", ");
20188 }
20189}
20190
9ef920e9 20191static void
dda8d76d 20192print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
20193{
20194 unsigned char * ptr = (unsigned char *) pnote->descdata;
20195 unsigned char * ptr_end = ptr + pnote->descsz;
20196 unsigned int size = is_32bit_elf ? 4 : 8;
20197
20198 printf (_(" Properties: "));
20199
1fc87489 20200 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
20201 {
20202 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
20203 return;
20204 }
20205
6ab2c4ed 20206 while (ptr < ptr_end)
9ef920e9 20207 {
1fc87489 20208 unsigned int j;
6ab2c4ed
MC
20209 unsigned int type;
20210 unsigned int datasz;
20211
20212 if ((size_t) (ptr_end - ptr) < 8)
20213 {
20214 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
20215 break;
20216 }
20217
20218 type = byte_get (ptr, 4);
20219 datasz = byte_get (ptr + 4, 4);
9ef920e9 20220
1fc87489 20221 ptr += 8;
9ef920e9 20222
6ab2c4ed 20223 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 20224 {
1fc87489
L
20225 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
20226 type, datasz);
9ef920e9 20227 break;
1fc87489 20228 }
9ef920e9 20229
1fc87489
L
20230 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20231 {
dda8d76d
NC
20232 if (filedata->file_header.e_machine == EM_X86_64
20233 || filedata->file_header.e_machine == EM_IAMCU
20234 || filedata->file_header.e_machine == EM_386)
1fc87489 20235 {
aa7bca9b
L
20236 unsigned int bitmask;
20237
20238 if (datasz == 4)
0a59decb 20239 bitmask = byte_get (ptr, 4);
aa7bca9b
L
20240 else
20241 bitmask = 0;
20242
1fc87489
L
20243 switch (type)
20244 {
20245 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 20246 if (datasz != 4)
aa7bca9b
L
20247 printf (_("x86 ISA used: <corrupt length: %#x> "),
20248 datasz);
1fc87489 20249 else
aa7bca9b
L
20250 {
20251 printf ("x86 ISA used: ");
20252 decode_x86_isa (bitmask);
20253 }
1fc87489 20254 goto next;
9ef920e9 20255
1fc87489 20256 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20257 if (datasz != 4)
aa7bca9b
L
20258 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20259 datasz);
1fc87489 20260 else
aa7bca9b
L
20261 {
20262 printf ("x86 ISA needed: ");
20263 decode_x86_isa (bitmask);
20264 }
1fc87489 20265 goto next;
9ef920e9 20266
ee2fdd6f 20267 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20268 if (datasz != 4)
aa7bca9b
L
20269 printf (_("x86 feature: <corrupt length: %#x> "),
20270 datasz);
ee2fdd6f 20271 else
aa7bca9b
L
20272 {
20273 printf ("x86 feature: ");
a9eafb08
L
20274 decode_x86_feature_1 (bitmask);
20275 }
20276 goto next;
20277
20278 case GNU_PROPERTY_X86_FEATURE_2_USED:
20279 if (datasz != 4)
20280 printf (_("x86 feature used: <corrupt length: %#x> "),
20281 datasz);
20282 else
20283 {
20284 printf ("x86 feature used: ");
20285 decode_x86_feature_2 (bitmask);
20286 }
20287 goto next;
20288
20289 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20290 if (datasz != 4)
20291 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20292 else
20293 {
20294 printf ("x86 feature needed: ");
20295 decode_x86_feature_2 (bitmask);
20296 }
20297 goto next;
20298
20299 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20300 if (datasz != 4)
20301 printf (_("x86 ISA used: <corrupt length: %#x> "),
20302 datasz);
20303 else
20304 {
20305 printf ("x86 ISA used: ");
20306 decode_x86_compat_isa (bitmask);
20307 }
20308 goto next;
20309
20310 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20311 if (datasz != 4)
20312 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20313 datasz);
20314 else
20315 {
20316 printf ("x86 ISA needed: ");
20317 decode_x86_compat_isa (bitmask);
aa7bca9b 20318 }
ee2fdd6f
L
20319 goto next;
20320
32930e4e
L
20321 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20322 if (datasz != 4)
20323 printf (_("x86 ISA used: <corrupt length: %#x> "),
20324 datasz);
20325 else
20326 {
20327 printf ("x86 ISA used: ");
20328 decode_x86_compat_2_isa (bitmask);
20329 }
20330 goto next;
20331
20332 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20333 if (datasz != 4)
20334 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20335 datasz);
20336 else
20337 {
20338 printf ("x86 ISA needed: ");
20339 decode_x86_compat_2_isa (bitmask);
20340 }
20341 goto next;
20342
1fc87489
L
20343 default:
20344 break;
20345 }
20346 }
cd702818
SD
20347 else if (filedata->file_header.e_machine == EM_AARCH64)
20348 {
20349 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20350 {
20351 printf ("AArch64 feature: ");
20352 if (datasz != 4)
20353 printf (_("<corrupt length: %#x> "), datasz);
20354 else
20355 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20356 goto next;
20357 }
20358 }
1fc87489
L
20359 }
20360 else
20361 {
20362 switch (type)
9ef920e9 20363 {
1fc87489
L
20364 case GNU_PROPERTY_STACK_SIZE:
20365 printf (_("stack size: "));
20366 if (datasz != size)
20367 printf (_("<corrupt length: %#x> "), datasz);
20368 else
26c527e6 20369 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
20370 goto next;
20371
20372 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20373 printf ("no copy on protected ");
20374 if (datasz)
20375 printf (_("<corrupt length: %#x> "), datasz);
20376 goto next;
20377
20378 default:
5a767724
L
20379 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20380 && type <= GNU_PROPERTY_UINT32_AND_HI)
20381 || (type >= GNU_PROPERTY_UINT32_OR_LO
20382 && type <= GNU_PROPERTY_UINT32_OR_HI))
20383 {
6320fd00
L
20384 switch (type)
20385 {
20386 case GNU_PROPERTY_1_NEEDED:
20387 if (datasz != 4)
20388 printf (_("1_needed: <corrupt length: %#x> "),
20389 datasz);
20390 else
20391 {
20392 unsigned int bitmask = byte_get (ptr, 4);
20393 printf ("1_needed: ");
20394 decode_1_needed (bitmask);
20395 }
20396 goto next;
20397
20398 default:
20399 break;
20400 }
5a767724
L
20401 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20402 printf (_("UINT32_AND (%#x): "), type);
20403 else
20404 printf (_("UINT32_OR (%#x): "), type);
20405 if (datasz != 4)
20406 printf (_("<corrupt length: %#x> "), datasz);
20407 else
20408 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20409 goto next;
20410 }
9ef920e9
NC
20411 break;
20412 }
9ef920e9
NC
20413 }
20414
1fc87489
L
20415 if (type < GNU_PROPERTY_LOPROC)
20416 printf (_("<unknown type %#x data: "), type);
20417 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20418 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20419 else
20420 printf (_("<application-specific type %#x data: "), type);
20421 for (j = 0; j < datasz; ++j)
20422 printf ("%02x ", ptr[j] & 0xff);
20423 printf (">");
20424
dc1e8a47 20425 next:
9ef920e9 20426 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20427 if (ptr == ptr_end)
20428 break;
1fc87489 20429
6ab2c4ed
MC
20430 if (do_wide)
20431 printf (", ");
20432 else
20433 printf ("\n\t");
9ef920e9
NC
20434 }
20435
20436 printf ("\n");
20437}
20438
015dc7e1 20439static bool
dda8d76d 20440print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20441{
1449284b 20442 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20443 switch (pnote->type)
20444 {
20445 case NT_GNU_BUILD_ID:
20446 {
26c527e6 20447 size_t i;
664f90a3
TT
20448
20449 printf (_(" Build ID: "));
20450 for (i = 0; i < pnote->descsz; ++i)
20451 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20452 printf ("\n");
664f90a3
TT
20453 }
20454 break;
20455
20456 case NT_GNU_ABI_TAG:
20457 {
26c527e6 20458 unsigned int os, major, minor, subminor;
664f90a3
TT
20459 const char *osname;
20460
3102e897
NC
20461 /* PR 17531: file: 030-599401-0.004. */
20462 if (pnote->descsz < 16)
20463 {
20464 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20465 break;
20466 }
20467
664f90a3
TT
20468 os = byte_get ((unsigned char *) pnote->descdata, 4);
20469 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20470 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20471 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20472
20473 switch (os)
20474 {
20475 case GNU_ABI_TAG_LINUX:
20476 osname = "Linux";
20477 break;
20478 case GNU_ABI_TAG_HURD:
20479 osname = "Hurd";
20480 break;
20481 case GNU_ABI_TAG_SOLARIS:
20482 osname = "Solaris";
20483 break;
20484 case GNU_ABI_TAG_FREEBSD:
20485 osname = "FreeBSD";
20486 break;
20487 case GNU_ABI_TAG_NETBSD:
20488 osname = "NetBSD";
20489 break;
14ae95f2
RM
20490 case GNU_ABI_TAG_SYLLABLE:
20491 osname = "Syllable";
20492 break;
20493 case GNU_ABI_TAG_NACL:
20494 osname = "NaCl";
20495 break;
664f90a3
TT
20496 default:
20497 osname = "Unknown";
20498 break;
20499 }
20500
26c527e6 20501 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
20502 major, minor, subminor);
20503 }
20504 break;
926c5385
CC
20505
20506 case NT_GNU_GOLD_VERSION:
20507 {
26c527e6 20508 size_t i;
926c5385
CC
20509
20510 printf (_(" Version: "));
20511 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20512 printf ("%c", pnote->descdata[i]);
20513 printf ("\n");
20514 }
20515 break;
1449284b
NC
20516
20517 case NT_GNU_HWCAP:
20518 {
26c527e6 20519 unsigned int num_entries, mask;
1449284b
NC
20520
20521 /* Hardware capabilities information. Word 0 is the number of entries.
20522 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20523 is a series of entries, where each entry is a single byte followed
20524 by a nul terminated string. The byte gives the bit number to test
20525 if enabled in the bitmask. */
20526 printf (_(" Hardware Capabilities: "));
20527 if (pnote->descsz < 8)
20528 {
32ec8896 20529 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20530 return false;
1449284b
NC
20531 }
20532 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20533 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 20534 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
20535 /* FIXME: Add code to display the entries... */
20536 }
20537 break;
20538
9ef920e9 20539 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20540 print_gnu_property_note (filedata, pnote);
9ef920e9 20541 break;
9abca702 20542
1449284b
NC
20543 default:
20544 /* Handle unrecognised types. An error message should have already been
20545 created by get_gnu_elf_note_type(), so all that we need to do is to
20546 display the data. */
20547 {
26c527e6 20548 size_t i;
1449284b
NC
20549
20550 printf (_(" Description data: "));
20551 for (i = 0; i < pnote->descsz; ++i)
20552 printf ("%02x ", pnote->descdata[i] & 0xff);
20553 printf ("\n");
20554 }
20555 break;
664f90a3
TT
20556 }
20557
015dc7e1 20558 return true;
664f90a3
TT
20559}
20560
685080f2
NC
20561static const char *
20562get_v850_elf_note_type (enum v850_notes n_type)
20563{
20564 static char buff[64];
20565
20566 switch (n_type)
20567 {
20568 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20569 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20570 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20571 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20572 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20573 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20574 default:
20575 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20576 return buff;
20577 }
20578}
20579
015dc7e1 20580static bool
685080f2
NC
20581print_v850_note (Elf_Internal_Note * pnote)
20582{
20583 unsigned int val;
20584
20585 if (pnote->descsz != 4)
015dc7e1 20586 return false;
32ec8896 20587
685080f2
NC
20588 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20589
20590 if (val == 0)
20591 {
20592 printf (_("not set\n"));
015dc7e1 20593 return true;
685080f2
NC
20594 }
20595
20596 switch (pnote->type)
20597 {
20598 case V850_NOTE_ALIGNMENT:
20599 switch (val)
20600 {
015dc7e1
AM
20601 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20602 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20603 }
20604 break;
14ae95f2 20605
685080f2
NC
20606 case V850_NOTE_DATA_SIZE:
20607 switch (val)
20608 {
015dc7e1
AM
20609 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20610 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20611 }
20612 break;
14ae95f2 20613
685080f2
NC
20614 case V850_NOTE_FPU_INFO:
20615 switch (val)
20616 {
015dc7e1
AM
20617 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20618 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20619 }
20620 break;
14ae95f2 20621
685080f2
NC
20622 case V850_NOTE_MMU_INFO:
20623 case V850_NOTE_CACHE_INFO:
20624 case V850_NOTE_SIMD_INFO:
20625 if (val == EF_RH850_SIMD)
20626 {
20627 printf (_("yes\n"));
015dc7e1 20628 return true;
685080f2
NC
20629 }
20630 break;
20631
20632 default:
20633 /* An 'unknown note type' message will already have been displayed. */
20634 break;
20635 }
20636
20637 printf (_("unknown value: %x\n"), val);
015dc7e1 20638 return false;
685080f2
NC
20639}
20640
015dc7e1 20641static bool
c6056a74
SF
20642process_netbsd_elf_note (Elf_Internal_Note * pnote)
20643{
20644 unsigned int version;
20645
20646 switch (pnote->type)
20647 {
20648 case NT_NETBSD_IDENT:
b966f55f
AM
20649 if (pnote->descsz < 1)
20650 break;
c6056a74
SF
20651 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20652 if ((version / 10000) % 100)
b966f55f 20653 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20654 version, version / 100000000, (version / 1000000) % 100,
20655 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20656 'A' + (version / 10000) % 26);
c6056a74
SF
20657 else
20658 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20659 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20660 (version / 100) % 100);
015dc7e1 20661 return true;
c6056a74
SF
20662
20663 case NT_NETBSD_MARCH:
9abca702 20664 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20665 pnote->descdata);
015dc7e1 20666 return true;
c6056a74 20667
9abca702 20668 case NT_NETBSD_PAX:
b966f55f
AM
20669 if (pnote->descsz < 1)
20670 break;
9abca702
CZ
20671 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20672 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20673 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20674 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20675 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20676 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20677 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20678 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20679 return true;
c6056a74 20680 }
b966f55f
AM
20681
20682 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20683 pnote->descsz, pnote->type);
015dc7e1 20684 return false;
c6056a74
SF
20685}
20686
f4ddf30f 20687static const char *
dda8d76d 20688get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20689{
f4ddf30f
JB
20690 switch (e_type)
20691 {
20692 case NT_FREEBSD_THRMISC:
20693 return _("NT_THRMISC (thrmisc structure)");
20694 case NT_FREEBSD_PROCSTAT_PROC:
20695 return _("NT_PROCSTAT_PROC (proc data)");
20696 case NT_FREEBSD_PROCSTAT_FILES:
20697 return _("NT_PROCSTAT_FILES (files data)");
20698 case NT_FREEBSD_PROCSTAT_VMMAP:
20699 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20700 case NT_FREEBSD_PROCSTAT_GROUPS:
20701 return _("NT_PROCSTAT_GROUPS (groups data)");
20702 case NT_FREEBSD_PROCSTAT_UMASK:
20703 return _("NT_PROCSTAT_UMASK (umask data)");
20704 case NT_FREEBSD_PROCSTAT_RLIMIT:
20705 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20706 case NT_FREEBSD_PROCSTAT_OSREL:
20707 return _("NT_PROCSTAT_OSREL (osreldate data)");
20708 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20709 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20710 case NT_FREEBSD_PROCSTAT_AUXV:
20711 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20712 case NT_FREEBSD_PTLWPINFO:
20713 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
20714 case NT_FREEBSD_X86_SEGBASES:
20715 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 20716 }
dda8d76d 20717 return get_note_type (filedata, e_type);
f4ddf30f
JB
20718}
20719
9437c45b 20720static const char *
dda8d76d 20721get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20722{
20723 static char buff[64];
20724
540e6170
CZ
20725 switch (e_type)
20726 {
20727 case NT_NETBSDCORE_PROCINFO:
20728 /* NetBSD core "procinfo" structure. */
20729 return _("NetBSD procinfo structure");
9437c45b 20730
540e6170
CZ
20731 case NT_NETBSDCORE_AUXV:
20732 return _("NetBSD ELF auxiliary vector data");
9437c45b 20733
06d949ec
KR
20734 case NT_NETBSDCORE_LWPSTATUS:
20735 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20736
540e6170 20737 default:
06d949ec 20738 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20739 defined for NetBSD core files. If the note type is less
20740 than the start of the machine-dependent note types, we don't
20741 understand it. */
20742
20743 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20744 {
20745 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20746 return buff;
20747 }
20748 break;
9437c45b
JT
20749 }
20750
dda8d76d 20751 switch (filedata->file_header.e_machine)
9437c45b
JT
20752 {
20753 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20754 and PT_GETFPREGS == mach+2. */
20755
20756 case EM_OLD_ALPHA:
20757 case EM_ALPHA:
20758 case EM_SPARC:
20759 case EM_SPARC32PLUS:
20760 case EM_SPARCV9:
20761 switch (e_type)
20762 {
2b692964 20763 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20764 return _("PT_GETREGS (reg structure)");
2b692964 20765 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20766 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20767 default:
20768 break;
20769 }
20770 break;
20771
c0d38b0e
CZ
20772 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20773 There's also old PT___GETREGS40 == mach + 1 for old reg
20774 structure which lacks GBR. */
20775 case EM_SH:
20776 switch (e_type)
20777 {
20778 case NT_NETBSDCORE_FIRSTMACH + 1:
20779 return _("PT___GETREGS40 (old reg structure)");
20780 case NT_NETBSDCORE_FIRSTMACH + 3:
20781 return _("PT_GETREGS (reg structure)");
20782 case NT_NETBSDCORE_FIRSTMACH + 5:
20783 return _("PT_GETFPREGS (fpreg structure)");
20784 default:
20785 break;
20786 }
20787 break;
20788
9437c45b
JT
20789 /* On all other arch's, PT_GETREGS == mach+1 and
20790 PT_GETFPREGS == mach+3. */
20791 default:
20792 switch (e_type)
20793 {
2b692964 20794 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20795 return _("PT_GETREGS (reg structure)");
2b692964 20796 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20797 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20798 default:
20799 break;
20800 }
20801 }
20802
9cf03b7e 20803 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20804 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20805 return buff;
20806}
20807
98ca73af
FC
20808static const char *
20809get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20810{
20811 switch (e_type)
20812 {
20813 case NT_OPENBSD_PROCINFO:
20814 return _("OpenBSD procinfo structure");
20815 case NT_OPENBSD_AUXV:
20816 return _("OpenBSD ELF auxiliary vector data");
20817 case NT_OPENBSD_REGS:
20818 return _("OpenBSD regular registers");
20819 case NT_OPENBSD_FPREGS:
20820 return _("OpenBSD floating point registers");
20821 case NT_OPENBSD_WCOOKIE:
20822 return _("OpenBSD window cookie");
20823 }
20824
20825 return get_note_type (filedata, e_type);
20826}
20827
e263a66b
CC
20828static const char *
20829get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
20830{
20831 switch (e_type)
20832 {
20833 case QNT_DEBUG_FULLPATH:
20834 return _("QNX debug fullpath");
20835 case QNT_DEBUG_RELOC:
20836 return _("QNX debug relocation");
20837 case QNT_STACK:
20838 return _("QNX stack");
20839 case QNT_GENERATOR:
20840 return _("QNX generator");
20841 case QNT_DEFAULT_LIB:
20842 return _("QNX default library");
20843 case QNT_CORE_SYSINFO:
20844 return _("QNX core sysinfo");
20845 case QNT_CORE_INFO:
20846 return _("QNX core info");
20847 case QNT_CORE_STATUS:
20848 return _("QNX core status");
20849 case QNT_CORE_GREG:
20850 return _("QNX general registers");
20851 case QNT_CORE_FPREG:
20852 return _("QNX floating point registers");
20853 case QNT_LINK_MAP:
20854 return _("QNX link map");
20855 }
20856
20857 return get_note_type (filedata, e_type);
20858}
20859
70616151
TT
20860static const char *
20861get_stapsdt_note_type (unsigned e_type)
20862{
20863 static char buff[64];
20864
20865 switch (e_type)
20866 {
20867 case NT_STAPSDT:
20868 return _("NT_STAPSDT (SystemTap probe descriptors)");
20869
20870 default:
20871 break;
20872 }
20873
20874 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20875 return buff;
20876}
20877
015dc7e1 20878static bool
c6a9fc58
TT
20879print_stapsdt_note (Elf_Internal_Note *pnote)
20880{
3ca60c57 20881 size_t len, maxlen;
26c527e6 20882 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20883 char *data = pnote->descdata;
20884 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 20885 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
20886 char *provider, *probe, *arg_fmt;
20887
3ca60c57
NC
20888 if (pnote->descsz < (addr_size * 3))
20889 goto stapdt_note_too_small;
20890
c6a9fc58
TT
20891 pc = byte_get ((unsigned char *) data, addr_size);
20892 data += addr_size;
3ca60c57 20893
c6a9fc58
TT
20894 base_addr = byte_get ((unsigned char *) data, addr_size);
20895 data += addr_size;
3ca60c57 20896
c6a9fc58
TT
20897 semaphore = byte_get ((unsigned char *) data, addr_size);
20898 data += addr_size;
20899
3ca60c57
NC
20900 if (data >= data_end)
20901 goto stapdt_note_too_small;
20902 maxlen = data_end - data;
20903 len = strnlen (data, maxlen);
20904 if (len < maxlen)
20905 {
20906 provider = data;
20907 data += len + 1;
20908 }
20909 else
20910 goto stapdt_note_too_small;
20911
20912 if (data >= data_end)
20913 goto stapdt_note_too_small;
20914 maxlen = data_end - data;
20915 len = strnlen (data, maxlen);
20916 if (len < maxlen)
20917 {
20918 probe = data;
20919 data += len + 1;
20920 }
20921 else
20922 goto stapdt_note_too_small;
9abca702 20923
3ca60c57
NC
20924 if (data >= data_end)
20925 goto stapdt_note_too_small;
20926 maxlen = data_end - data;
20927 len = strnlen (data, maxlen);
20928 if (len < maxlen)
20929 {
20930 arg_fmt = data;
20931 data += len + 1;
20932 }
20933 else
20934 goto stapdt_note_too_small;
c6a9fc58
TT
20935
20936 printf (_(" Provider: %s\n"), provider);
20937 printf (_(" Name: %s\n"), probe);
20938 printf (_(" Location: "));
20939 print_vma (pc, FULL_HEX);
20940 printf (_(", Base: "));
20941 print_vma (base_addr, FULL_HEX);
20942 printf (_(", Semaphore: "));
20943 print_vma (semaphore, FULL_HEX);
9cf03b7e 20944 printf ("\n");
c6a9fc58
TT
20945 printf (_(" Arguments: %s\n"), arg_fmt);
20946
20947 return data == data_end;
3ca60c57
NC
20948
20949 stapdt_note_too_small:
20950 printf (_(" <corrupt - note is too small>\n"));
20951 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20952 return false;
c6a9fc58
TT
20953}
20954
e5382207
LB
20955static bool
20956print_fdo_note (Elf_Internal_Note * pnote)
20957{
20958 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20959 {
20960 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20961 return true;
20962 }
20963 return false;
20964}
20965
00e98fc7
TG
20966static const char *
20967get_ia64_vms_note_type (unsigned e_type)
20968{
20969 static char buff[64];
20970
20971 switch (e_type)
20972 {
20973 case NT_VMS_MHD:
20974 return _("NT_VMS_MHD (module header)");
20975 case NT_VMS_LNM:
20976 return _("NT_VMS_LNM (language name)");
20977 case NT_VMS_SRC:
20978 return _("NT_VMS_SRC (source files)");
20979 case NT_VMS_TITLE:
9cf03b7e 20980 return "NT_VMS_TITLE";
00e98fc7
TG
20981 case NT_VMS_EIDC:
20982 return _("NT_VMS_EIDC (consistency check)");
20983 case NT_VMS_FPMODE:
20984 return _("NT_VMS_FPMODE (FP mode)");
20985 case NT_VMS_LINKTIME:
9cf03b7e 20986 return "NT_VMS_LINKTIME";
00e98fc7
TG
20987 case NT_VMS_IMGNAM:
20988 return _("NT_VMS_IMGNAM (image name)");
20989 case NT_VMS_IMGID:
20990 return _("NT_VMS_IMGID (image id)");
20991 case NT_VMS_LINKID:
20992 return _("NT_VMS_LINKID (link id)");
20993 case NT_VMS_IMGBID:
20994 return _("NT_VMS_IMGBID (build id)");
20995 case NT_VMS_GSTNAM:
20996 return _("NT_VMS_GSTNAM (sym table name)");
20997 case NT_VMS_ORIG_DYN:
9cf03b7e 20998 return "NT_VMS_ORIG_DYN";
00e98fc7 20999 case NT_VMS_PATCHTIME:
9cf03b7e 21000 return "NT_VMS_PATCHTIME";
00e98fc7
TG
21001 default:
21002 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21003 return buff;
21004 }
21005}
21006
015dc7e1 21007static bool
00e98fc7
TG
21008print_ia64_vms_note (Elf_Internal_Note * pnote)
21009{
26c527e6 21010 unsigned int maxlen = pnote->descsz;
8d18bf79 21011
26c527e6 21012 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
21013 goto desc_size_fail;
21014
00e98fc7
TG
21015 switch (pnote->type)
21016 {
21017 case NT_VMS_MHD:
8d18bf79
NC
21018 if (maxlen <= 36)
21019 goto desc_size_fail;
21020
26c527e6 21021 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
21022
21023 printf (_(" Creation date : %.17s\n"), pnote->descdata);
21024 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
21025 if (l + 34 < maxlen)
21026 {
21027 printf (_(" Module name : %s\n"), pnote->descdata + 34);
21028 if (l + 35 < maxlen)
21029 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
21030 else
21031 printf (_(" Module version : <missing>\n"));
21032 }
00e98fc7 21033 else
8d18bf79
NC
21034 {
21035 printf (_(" Module name : <missing>\n"));
21036 printf (_(" Module version : <missing>\n"));
21037 }
00e98fc7 21038 break;
8d18bf79 21039
00e98fc7 21040 case NT_VMS_LNM:
8d18bf79 21041 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21042 break;
8d18bf79 21043
00e98fc7 21044 case NT_VMS_FPMODE:
9cf03b7e 21045 printf (_(" Floating Point mode: "));
8d18bf79
NC
21046 if (maxlen < 8)
21047 goto desc_size_fail;
21048 /* FIXME: Generate an error if descsz > 8 ? */
21049
b8281767 21050 printf ("0x%016" PRIx64 "\n",
625d49fc 21051 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 21052 break;
8d18bf79 21053
00e98fc7
TG
21054 case NT_VMS_LINKTIME:
21055 printf (_(" Link time: "));
8d18bf79
NC
21056 if (maxlen < 8)
21057 goto desc_size_fail;
21058 /* FIXME: Generate an error if descsz > 8 ? */
21059
0e3c1eeb 21060 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21061 printf ("\n");
21062 break;
8d18bf79 21063
00e98fc7
TG
21064 case NT_VMS_PATCHTIME:
21065 printf (_(" Patch time: "));
8d18bf79
NC
21066 if (maxlen < 8)
21067 goto desc_size_fail;
21068 /* FIXME: Generate an error if descsz > 8 ? */
21069
0e3c1eeb 21070 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21071 printf ("\n");
21072 break;
8d18bf79 21073
00e98fc7 21074 case NT_VMS_ORIG_DYN:
8d18bf79
NC
21075 if (maxlen < 34)
21076 goto desc_size_fail;
21077
00e98fc7 21078 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
21079 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
21080 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 21081 printf (_(" Last modified : "));
0e3c1eeb 21082 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 21083 printf (_("\n Link flags : "));
b8281767 21084 printf ("0x%016" PRIx64 "\n",
625d49fc 21085 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 21086 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 21087 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 21088 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 21089 break;
8d18bf79 21090
00e98fc7 21091 case NT_VMS_IMGNAM:
8d18bf79 21092 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21093 break;
8d18bf79 21094
00e98fc7 21095 case NT_VMS_GSTNAM:
8d18bf79 21096 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21097 break;
8d18bf79 21098
00e98fc7 21099 case NT_VMS_IMGID:
8d18bf79 21100 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21101 break;
8d18bf79 21102
00e98fc7 21103 case NT_VMS_LINKID:
8d18bf79 21104 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21105 break;
8d18bf79 21106
00e98fc7 21107 default:
015dc7e1 21108 return false;
00e98fc7 21109 }
8d18bf79 21110
015dc7e1 21111 return true;
8d18bf79
NC
21112
21113 desc_size_fail:
21114 printf (_(" <corrupt - data size is too small>\n"));
21115 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 21116 return false;
00e98fc7
TG
21117}
21118
fd486f32
AM
21119struct build_attr_cache {
21120 Filedata *filedata;
21121 char *strtab;
26c527e6 21122 uint64_t strtablen;
fd486f32 21123 Elf_Internal_Sym *symtab;
26c527e6 21124 uint64_t nsyms;
fd486f32
AM
21125} ba_cache;
21126
6f156d7a
NC
21127/* Find the symbol associated with a build attribute that is attached
21128 to address OFFSET. If PNAME is non-NULL then store the name of
21129 the symbol (if found) in the provided pointer, Returns NULL if a
21130 symbol could not be found. */
c799a79d 21131
6f156d7a 21132static Elf_Internal_Sym *
015dc7e1 21133get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 21134 uint64_t offset,
015dc7e1
AM
21135 bool is_open_attr,
21136 const char **pname)
9ef920e9 21137{
fd486f32
AM
21138 Elf_Internal_Sym *saved_sym = NULL;
21139 Elf_Internal_Sym *sym;
9ef920e9 21140
dda8d76d 21141 if (filedata->section_headers != NULL
fd486f32 21142 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 21143 {
c799a79d 21144 Elf_Internal_Shdr * symsec;
9ef920e9 21145
fd486f32
AM
21146 free (ba_cache.strtab);
21147 ba_cache.strtab = NULL;
21148 free (ba_cache.symtab);
21149 ba_cache.symtab = NULL;
21150
c799a79d 21151 /* Load the symbol and string sections. */
dda8d76d
NC
21152 for (symsec = filedata->section_headers;
21153 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 21154 symsec ++)
9ef920e9 21155 {
28d13567
AM
21156 if (symsec->sh_type == SHT_SYMTAB
21157 && get_symtab (filedata, symsec,
21158 &ba_cache.symtab, &ba_cache.nsyms,
21159 &ba_cache.strtab, &ba_cache.strtablen))
21160 break;
9ef920e9 21161 }
fd486f32 21162 ba_cache.filedata = filedata;
9ef920e9
NC
21163 }
21164
fd486f32 21165 if (ba_cache.symtab == NULL)
6f156d7a 21166 return NULL;
9ef920e9 21167
c799a79d 21168 /* Find a symbol whose value matches offset. */
fd486f32 21169 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
21170 if (sym->st_value == offset)
21171 {
fd486f32 21172 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
21173 /* Huh ? This should not happen. */
21174 continue;
9ef920e9 21175
fd486f32 21176 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 21177 continue;
9ef920e9 21178
9b9b1092 21179 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 21180 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
21181 if (ba_cache.strtab[sym->st_name] == '$'
21182 && ba_cache.strtab[sym->st_name + 1] != 0
21183 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
21184 continue;
21185
c799a79d
NC
21186 if (is_open_attr)
21187 {
21188 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
21189 and FILE or OBJECT symbols over NOTYPE symbols. We skip
21190 FUNC symbols entirely. */
21191 switch (ELF_ST_TYPE (sym->st_info))
21192 {
c799a79d 21193 case STT_OBJECT:
6f156d7a 21194 case STT_FILE:
c799a79d 21195 saved_sym = sym;
6f156d7a
NC
21196 if (sym->st_size)
21197 {
21198 /* If the symbol has a size associated
21199 with it then we can stop searching. */
fd486f32 21200 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 21201 }
c799a79d 21202 continue;
9ef920e9 21203
c799a79d
NC
21204 case STT_FUNC:
21205 /* Ignore function symbols. */
21206 continue;
21207
21208 default:
21209 break;
21210 }
21211
21212 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 21213 {
c799a79d
NC
21214 case STB_GLOBAL:
21215 if (saved_sym == NULL
21216 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
21217 saved_sym = sym;
21218 break;
c871dade 21219
c799a79d
NC
21220 case STB_LOCAL:
21221 if (saved_sym == NULL)
21222 saved_sym = sym;
21223 break;
21224
21225 default:
9ef920e9
NC
21226 break;
21227 }
21228 }
c799a79d
NC
21229 else
21230 {
21231 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
21232 continue;
21233
21234 saved_sym = sym;
21235 break;
21236 }
21237 }
21238
6f156d7a 21239 if (saved_sym && pname)
fd486f32 21240 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
21241
21242 return saved_sym;
c799a79d
NC
21243}
21244
d20e98ab
NC
21245/* Returns true iff addr1 and addr2 are in the same section. */
21246
015dc7e1 21247static bool
26c527e6 21248same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
21249{
21250 Elf_Internal_Shdr * a1;
21251 Elf_Internal_Shdr * a2;
21252
21253 a1 = find_section_by_address (filedata, addr1);
21254 a2 = find_section_by_address (filedata, addr2);
9abca702 21255
d20e98ab
NC
21256 return a1 == a2 && a1 != NULL;
21257}
21258
015dc7e1 21259static bool
dda8d76d
NC
21260print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21261 Filedata * filedata)
c799a79d 21262{
26c527e6
AM
21263 static uint64_t global_offset = 0;
21264 static uint64_t global_end = 0;
21265 static uint64_t func_offset = 0;
21266 static uint64_t func_end = 0;
c871dade 21267
015dc7e1
AM
21268 Elf_Internal_Sym *sym;
21269 const char *name;
26c527e6
AM
21270 uint64_t start;
21271 uint64_t end;
015dc7e1 21272 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
21273
21274 switch (pnote->descsz)
c799a79d 21275 {
6f156d7a
NC
21276 case 0:
21277 /* A zero-length description means that the range of
21278 the previous note of the same type should be used. */
c799a79d 21279 if (is_open_attr)
c871dade 21280 {
6f156d7a 21281 if (global_end > global_offset)
26c527e6
AM
21282 printf (_(" Applies to region from %#" PRIx64
21283 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 21284 else
26c527e6
AM
21285 printf (_(" Applies to region from %#" PRIx64
21286 "\n"), global_offset);
c799a79d
NC
21287 }
21288 else
21289 {
6f156d7a 21290 if (func_end > func_offset)
26c527e6
AM
21291 printf (_(" Applies to region from %#" PRIx64
21292 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 21293 else
26c527e6
AM
21294 printf (_(" Applies to region from %#" PRIx64
21295 "\n"), func_offset);
c871dade 21296 }
015dc7e1 21297 return true;
9ef920e9 21298
6f156d7a
NC
21299 case 4:
21300 start = byte_get ((unsigned char *) pnote->descdata, 4);
21301 end = 0;
21302 break;
21303
21304 case 8:
c74147bb
NC
21305 start = byte_get ((unsigned char *) pnote->descdata, 4);
21306 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21307 break;
21308
21309 case 16:
21310 start = byte_get ((unsigned char *) pnote->descdata, 8);
21311 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21312 break;
9abca702 21313
6f156d7a 21314 default:
c799a79d
NC
21315 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21316 printf (_(" <invalid descsz>"));
015dc7e1 21317 return false;
c799a79d
NC
21318 }
21319
6f156d7a
NC
21320 name = NULL;
21321 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21322 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21323 in order to avoid them being confused with the start address of the
21324 first function in the file... */
21325 if (sym == NULL && is_open_attr)
21326 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21327 & name);
6f156d7a
NC
21328
21329 if (end == 0 && sym != NULL && sym->st_size > 0)
21330 end = start + sym->st_size;
c799a79d
NC
21331
21332 if (is_open_attr)
21333 {
d20e98ab
NC
21334 /* FIXME: Need to properly allow for section alignment.
21335 16 is just the alignment used on x86_64. */
21336 if (global_end > 0
21337 && start > BFD_ALIGN (global_end, 16)
21338 /* Build notes are not guaranteed to be organised in order of
21339 increasing address, but we should find the all of the notes
21340 for one section in the same place. */
21341 && same_section (filedata, start, global_end))
26c527e6
AM
21342 warn (_("Gap in build notes detected from %#" PRIx64
21343 " to %#" PRIx64 "\n"),
6f156d7a
NC
21344 global_end + 1, start - 1);
21345
26c527e6 21346 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21347 global_offset = start;
21348
21349 if (end)
21350 {
26c527e6 21351 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21352 global_end = end;
21353 }
c799a79d
NC
21354 }
21355 else
21356 {
26c527e6 21357 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21358 func_offset = start;
21359
21360 if (end)
21361 {
26c527e6 21362 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21363 func_end = end;
21364 }
c799a79d
NC
21365 }
21366
6f156d7a
NC
21367 if (sym && name)
21368 printf (_(" (%s)"), name);
21369
21370 printf ("\n");
015dc7e1 21371 return true;
9ef920e9
NC
21372}
21373
015dc7e1 21374static bool
9ef920e9
NC
21375print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21376{
1d15e434
NC
21377 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21378 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21379 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21380 char name_type;
21381 char name_attribute;
1d15e434 21382 const char * expected_types;
9ef920e9
NC
21383 const char * name = pnote->namedata;
21384 const char * text;
88305e1b 21385 signed int left;
9ef920e9
NC
21386
21387 if (name == NULL || pnote->namesz < 2)
21388 {
21389 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21390 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21391 return false;
9ef920e9
NC
21392 }
21393
6f156d7a
NC
21394 if (do_wide)
21395 left = 28;
21396 else
21397 left = 20;
88305e1b
NC
21398
21399 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21400 if (name[0] == 'G' && name[1] == 'A')
21401 {
6f156d7a
NC
21402 if (pnote->namesz < 4)
21403 {
21404 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21405 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21406 return false;
6f156d7a
NC
21407 }
21408
88305e1b
NC
21409 printf ("GA");
21410 name += 2;
21411 left -= 2;
21412 }
21413
9ef920e9
NC
21414 switch ((name_type = * name))
21415 {
21416 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21417 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21418 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21419 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21420 printf ("%c", * name);
88305e1b 21421 left --;
9ef920e9
NC
21422 break;
21423 default:
21424 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21425 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21426 return false;
9ef920e9
NC
21427 }
21428
9ef920e9
NC
21429 ++ name;
21430 text = NULL;
21431
21432 switch ((name_attribute = * name))
21433 {
21434 case GNU_BUILD_ATTRIBUTE_VERSION:
21435 text = _("<version>");
1d15e434 21436 expected_types = string_expected;
9ef920e9
NC
21437 ++ name;
21438 break;
21439 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21440 text = _("<stack prot>");
75d7d298 21441 expected_types = "!+*";
9ef920e9
NC
21442 ++ name;
21443 break;
21444 case GNU_BUILD_ATTRIBUTE_RELRO:
21445 text = _("<relro>");
1d15e434 21446 expected_types = bool_expected;
9ef920e9
NC
21447 ++ name;
21448 break;
21449 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21450 text = _("<stack size>");
1d15e434 21451 expected_types = number_expected;
9ef920e9
NC
21452 ++ name;
21453 break;
21454 case GNU_BUILD_ATTRIBUTE_TOOL:
21455 text = _("<tool>");
1d15e434 21456 expected_types = string_expected;
9ef920e9
NC
21457 ++ name;
21458 break;
21459 case GNU_BUILD_ATTRIBUTE_ABI:
21460 text = _("<ABI>");
21461 expected_types = "$*";
21462 ++ name;
21463 break;
21464 case GNU_BUILD_ATTRIBUTE_PIC:
21465 text = _("<PIC>");
1d15e434 21466 expected_types = number_expected;
9ef920e9
NC
21467 ++ name;
21468 break;
a8be5506
NC
21469 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21470 text = _("<short enum>");
1d15e434 21471 expected_types = bool_expected;
a8be5506
NC
21472 ++ name;
21473 break;
9ef920e9
NC
21474 default:
21475 if (ISPRINT (* name))
21476 {
21477 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21478
21479 if (len > left && ! do_wide)
21480 len = left;
75d7d298 21481 printf ("%.*s:", len, name);
9ef920e9 21482 left -= len;
0dd6ae21 21483 name += len;
9ef920e9
NC
21484 }
21485 else
21486 {
3e6b6445 21487 static char tmpbuf [128];
88305e1b 21488
3e6b6445
NC
21489 error (_("unrecognised byte in name field: %d\n"), * name);
21490 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21491 text = tmpbuf;
21492 name ++;
9ef920e9
NC
21493 }
21494 expected_types = "*$!+";
21495 break;
21496 }
21497
21498 if (text)
88305e1b 21499 left -= printf ("%s", text);
9ef920e9
NC
21500
21501 if (strchr (expected_types, name_type) == NULL)
75d7d298 21502 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 21503
26c527e6 21504 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 21505 {
26c527e6
AM
21506 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
21507 pnote->namesz,
21508 name - pnote->namedata);
015dc7e1 21509 return false;
9ef920e9
NC
21510 }
21511
21512 if (left < 1 && ! do_wide)
015dc7e1 21513 return true;
9ef920e9
NC
21514
21515 switch (name_type)
21516 {
21517 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21518 {
26c527e6
AM
21519 unsigned int bytes;
21520 uint64_t val = 0;
21521 unsigned int shift = 0;
21522 char *decoded = NULL;
ddef72cd 21523
b06b2c92
NC
21524 bytes = pnote->namesz - (name - pnote->namedata);
21525 if (bytes > 0)
21526 /* The -1 is because the name field is always 0 terminated, and we
21527 want to be able to ensure that the shift in the while loop below
21528 will not overflow. */
21529 -- bytes;
21530
ddef72cd
NC
21531 if (bytes > sizeof (val))
21532 {
3e6b6445
NC
21533 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21534 bytes);
21535 bytes = sizeof (val);
ddef72cd 21536 }
3e6b6445
NC
21537 /* We do not bother to warn if bytes == 0 as this can
21538 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21539
21540 while (bytes --)
21541 {
26c527e6 21542 uint64_t byte = *name++ & 0xff;
79a964dc
NC
21543
21544 val |= byte << shift;
9ef920e9
NC
21545 shift += 8;
21546 }
21547
75d7d298 21548 switch (name_attribute)
9ef920e9 21549 {
75d7d298 21550 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21551 switch (val)
21552 {
75d7d298
NC
21553 case 0: decoded = "static"; break;
21554 case 1: decoded = "pic"; break;
21555 case 2: decoded = "PIC"; break;
21556 case 3: decoded = "pie"; break;
21557 case 4: decoded = "PIE"; break;
21558 default: break;
9ef920e9 21559 }
75d7d298
NC
21560 break;
21561 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21562 switch (val)
9ef920e9 21563 {
75d7d298
NC
21564 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21565 case 0: decoded = "off"; break;
21566 case 1: decoded = "on"; break;
21567 case 2: decoded = "all"; break;
21568 case 3: decoded = "strong"; break;
21569 case 4: decoded = "explicit"; break;
21570 default: break;
9ef920e9 21571 }
75d7d298
NC
21572 break;
21573 default:
21574 break;
9ef920e9
NC
21575 }
21576
75d7d298 21577 if (decoded != NULL)
3e6b6445
NC
21578 {
21579 print_symbol (-left, decoded);
21580 left = 0;
21581 }
21582 else if (val == 0)
21583 {
21584 printf ("0x0");
21585 left -= 3;
21586 }
9ef920e9 21587 else
75d7d298
NC
21588 {
21589 if (do_wide)
26c527e6 21590 left -= printf ("0x%" PRIx64, val);
75d7d298 21591 else
26c527e6 21592 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 21593 }
9ef920e9
NC
21594 }
21595 break;
21596 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21597 left -= print_symbol (- left, name);
21598 break;
21599 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21600 left -= print_symbol (- left, "true");
21601 break;
21602 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21603 left -= print_symbol (- left, "false");
21604 break;
21605 }
21606
21607 if (do_wide && left > 0)
21608 printf ("%-*s", left, " ");
9abca702 21609
015dc7e1 21610 return true;
9ef920e9
NC
21611}
21612
2952f10c
SM
21613/* Print the contents of PNOTE as hex. */
21614
21615static void
21616print_note_contents_hex (Elf_Internal_Note *pnote)
21617{
21618 if (pnote->descsz)
21619 {
26c527e6 21620 size_t i;
2952f10c
SM
21621
21622 printf (_(" description data: "));
21623 for (i = 0; i < pnote->descsz; i++)
21624 printf ("%02x ", pnote->descdata[i] & 0xff);
21625 if (!do_wide)
21626 printf ("\n");
21627 }
21628
21629 if (do_wide)
21630 printf ("\n");
21631}
21632
21633#if defined HAVE_MSGPACK
21634
21635static void
21636print_indents (int n)
21637{
21638 printf (" ");
21639
21640 for (int i = 0; i < n; i++)
21641 printf (" ");
21642}
21643
21644/* Print OBJ in human-readable form. */
21645
21646static void
21647dump_msgpack_obj (const msgpack_object *obj, int indent)
21648{
21649 switch (obj->type)
21650 {
21651 case MSGPACK_OBJECT_NIL:
21652 printf ("(nil)");
21653 break;
21654
21655 case MSGPACK_OBJECT_BOOLEAN:
21656 printf ("%s", obj->via.boolean ? "true" : "false");
21657 break;
21658
21659 case MSGPACK_OBJECT_POSITIVE_INTEGER:
21660 printf ("%" PRIu64, obj->via.u64);
21661 break;
21662
21663 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
21664 printf ("%" PRIi64, obj->via.i64);
21665 break;
21666
21667 case MSGPACK_OBJECT_FLOAT32:
21668 case MSGPACK_OBJECT_FLOAT64:
21669 printf ("%f", obj->via.f64);
21670 break;
21671
21672 case MSGPACK_OBJECT_STR:
21673 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
21674 break;
21675
21676 case MSGPACK_OBJECT_ARRAY:
21677 {
21678 const msgpack_object_array *array = &obj->via.array;
21679
21680 printf ("[\n");
21681 ++indent;
21682
21683 for (uint32_t i = 0; i < array->size; ++i)
21684 {
21685 const msgpack_object *item = &array->ptr[i];
21686
21687 print_indents (indent);
21688 dump_msgpack_obj (item, indent);
21689 printf (",\n");
21690 }
21691
21692 --indent;
21693 print_indents (indent);
21694 printf ("]");
21695 break;
21696 }
21697 break;
21698
21699 case MSGPACK_OBJECT_MAP:
21700 {
21701 const msgpack_object_map *map = &obj->via.map;
21702
21703 printf ("{\n");
21704 ++indent;
21705
21706 for (uint32_t i = 0; i < map->size; ++i)
21707 {
21708 const msgpack_object_kv *kv = &map->ptr[i];
21709 const msgpack_object *key = &kv->key;
21710 const msgpack_object *val = &kv->val;
21711
21712 print_indents (indent);
21713 dump_msgpack_obj (key, indent);
21714 printf (": ");
21715 dump_msgpack_obj (val, indent);
21716
21717 printf (",\n");
21718 }
21719
21720 --indent;
21721 print_indents (indent);
21722 printf ("}");
21723
21724 break;
21725 }
21726
21727 case MSGPACK_OBJECT_BIN:
21728 printf ("(bin)");
21729 break;
21730
21731 case MSGPACK_OBJECT_EXT:
21732 printf ("(ext)");
21733 break;
21734 }
21735}
21736
21737static void
21738dump_msgpack (const msgpack_unpacked *msg)
21739{
21740 print_indents (0);
21741 dump_msgpack_obj (&msg->data, 0);
21742 printf ("\n");
21743}
21744
21745#endif /* defined HAVE_MSGPACK */
21746
21747static bool
21748print_amdgpu_note (Elf_Internal_Note *pnote)
21749{
21750#if defined HAVE_MSGPACK
21751 /* If msgpack is available, decode and dump the note's content. */
21752 bool ret;
21753 msgpack_unpacked msg;
21754 msgpack_unpack_return msgpack_ret;
21755
21756 assert (pnote->type == NT_AMDGPU_METADATA);
21757
21758 msgpack_unpacked_init (&msg);
21759 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
21760 NULL);
21761
21762 switch (msgpack_ret)
21763 {
21764 case MSGPACK_UNPACK_SUCCESS:
21765 dump_msgpack (&msg);
21766 ret = true;
21767 break;
21768
21769 default:
21770 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
21771 ret = false;
21772 break;
21773 }
21774
21775 msgpack_unpacked_destroy (&msg);
21776 return ret;
21777#else
21778 /* msgpack is not available, dump contents as hex. */
21779 print_note_contents_hex (pnote);
21780 return true;
21781#endif
21782}
21783
e263a66b
CC
21784static bool
21785print_qnx_note (Elf_Internal_Note *pnote)
21786{
21787 switch (pnote->type)
21788 {
21789 case QNT_STACK:
21790 if (pnote->descsz != 12)
21791 goto desc_size_fail;
21792
21793 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
21794 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
21795 printf (_(" Stack allocated: %" PRIx32 "\n"),
21796 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
21797 printf (_(" Executable: %s\n"),
21798 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
21799 break;
21800
21801 default:
21802 print_note_contents_hex(pnote);
21803 }
21804 return true;
21805
21806desc_size_fail:
21807 printf (_(" <corrupt - data size is too small>\n"));
21808 error (_("corrupt QNX note: data size is too small\n"));
21809 return false;
21810}
21811
21812
6d118b09
NC
21813/* Note that by the ELF standard, the name field is already null byte
21814 terminated, and namesz includes the terminating null byte.
21815 I.E. the value of namesz for the name "FSF" is 4.
21816
e3c8793a 21817 If the value of namesz is zero, there is no name present. */
9ef920e9 21818
015dc7e1 21819static bool
9ef920e9 21820process_note (Elf_Internal_Note * pnote,
dda8d76d 21821 Filedata * filedata)
779fe533 21822{
2cf0635d
NC
21823 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21824 const char * nt;
9437c45b
JT
21825
21826 if (pnote->namesz == 0)
1ec5cd37
NC
21827 /* If there is no note name, then use the default set of
21828 note type strings. */
dda8d76d 21829 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21830
24d127aa 21831 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21832 /* GNU-specific object file notes. */
21833 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21834
28cdbb18
SM
21835 else if (startswith (pnote->namedata, "AMDGPU"))
21836 /* AMDGPU-specific object file notes. */
21837 nt = get_amdgpu_elf_note_type (pnote->type);
21838
24d127aa 21839 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21840 /* FreeBSD-specific core file notes. */
dda8d76d 21841 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21842
24d127aa 21843 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21844 /* NetBSD-specific core file notes. */
dda8d76d 21845 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21846
24d127aa 21847 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21848 /* NetBSD-specific core file notes. */
21849 return process_netbsd_elf_note (pnote);
21850
24d127aa 21851 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21852 /* NetBSD-specific core file notes. */
21853 return process_netbsd_elf_note (pnote);
21854
98ca73af
FC
21855 else if (startswith (pnote->namedata, "OpenBSD"))
21856 /* OpenBSD-specific core file notes. */
21857 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21858
e263a66b
CC
21859 else if (startswith (pnote->namedata, "QNX"))
21860 /* QNX-specific core file notes. */
21861 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
21862
e9b095a5 21863 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21864 {
21865 /* SPU-specific core file notes. */
21866 nt = pnote->namedata + 4;
21867 name = "SPU";
21868 }
21869
24d127aa 21870 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21871 /* VMS/ia64-specific file notes. */
21872 nt = get_ia64_vms_note_type (pnote->type);
21873
24d127aa 21874 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21875 nt = get_stapsdt_note_type (pnote->type);
21876
9437c45b 21877 else
1ec5cd37
NC
21878 /* Don't recognize this note name; just use the default set of
21879 note type strings. */
dda8d76d 21880 nt = get_note_type (filedata, pnote->type);
9437c45b 21881
1449284b 21882 printf (" ");
9ef920e9 21883
24d127aa 21884 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21885 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21886 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21887 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21888 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21889 print_gnu_build_attribute_name (pnote);
21890 else
21891 print_symbol (-20, name);
21892
21893 if (do_wide)
21894 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21895 else
21896 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21897
24d127aa 21898 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21899 return print_ia64_vms_note (pnote);
24d127aa 21900 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21901 return print_gnu_note (filedata, pnote);
24d127aa 21902 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21903 return print_stapsdt_note (pnote);
24d127aa 21904 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21905 return print_core_note (pnote);
e5382207
LB
21906 else if (startswith (pnote->namedata, "FDO"))
21907 return print_fdo_note (pnote);
24d127aa 21908 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21909 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21910 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21911 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21912 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21913 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
21914 else if (startswith (pnote->namedata, "AMDGPU")
21915 && pnote->type == NT_AMDGPU_METADATA)
21916 return print_amdgpu_note (pnote);
e263a66b
CC
21917 else if (startswith (pnote->namedata, "QNX"))
21918 return print_qnx_note (pnote);
779fe533 21919
2952f10c 21920 print_note_contents_hex (pnote);
015dc7e1 21921 return true;
1449284b 21922}
6d118b09 21923
015dc7e1 21924static bool
dda8d76d
NC
21925process_notes_at (Filedata * filedata,
21926 Elf_Internal_Shdr * section,
625d49fc
AM
21927 uint64_t offset,
21928 uint64_t length,
21929 uint64_t align)
779fe533 21930{
015dc7e1
AM
21931 Elf_External_Note *pnotes;
21932 Elf_External_Note *external;
21933 char *end;
21934 bool res = true;
103f02d3 21935
779fe533 21936 if (length <= 0)
015dc7e1 21937 return false;
103f02d3 21938
1449284b
NC
21939 if (section)
21940 {
dda8d76d 21941 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21942 if (pnotes)
32ec8896 21943 {
dda8d76d 21944 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21945 {
21946 free (pnotes);
015dc7e1 21947 return false;
f761cb13 21948 }
32ec8896 21949 }
1449284b
NC
21950 }
21951 else
82ed9683 21952 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21953 _("notes"));
4dff97b2 21954
dd24e3da 21955 if (pnotes == NULL)
015dc7e1 21956 return false;
779fe533 21957
103f02d3 21958 external = pnotes;
103f02d3 21959
ca0e11aa
NC
21960 if (filedata->is_separate)
21961 printf (_("In linked file '%s': "), filedata->file_name);
21962 else
21963 printf ("\n");
1449284b 21964 if (section)
ca0e11aa 21965 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21966 else
26c527e6
AM
21967 printf (_("Displaying notes found at file offset 0x%08" PRIx64
21968 " with length 0x%08" PRIx64 ":\n"),
21969 offset, length);
1449284b 21970
82ed9683
L
21971 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21972 specifies that notes should be aligned to 4 bytes in 32-bit
21973 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21974 we also support 4 byte alignment in 64-bit objects. If section
21975 alignment is less than 4, we treate alignment as 4 bytes. */
21976 if (align < 4)
21977 align = 4;
21978 else if (align != 4 && align != 8)
21979 {
26c527e6
AM
21980 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
21981 align);
a788aedd 21982 free (pnotes);
015dc7e1 21983 return false;
82ed9683
L
21984 }
21985
dbe15e4e 21986 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21987
c8071705
NC
21988 end = (char *) pnotes + length;
21989 while ((char *) external < end)
779fe533 21990 {
b34976b6 21991 Elf_Internal_Note inote;
15b42fb0 21992 size_t min_notesz;
4dff97b2 21993 char * next;
2cf0635d 21994 char * temp = NULL;
c8071705 21995 size_t data_remaining = end - (char *) external;
6d118b09 21996
dda8d76d 21997 if (!is_ia64_vms (filedata))
15b42fb0 21998 {
9dd3a467
NC
21999 /* PR binutils/15191
22000 Make sure that there is enough data to read. */
15b42fb0
AM
22001 min_notesz = offsetof (Elf_External_Note, name);
22002 if (data_remaining < min_notesz)
9dd3a467 22003 {
26c527e6 22004 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22005 "not enough for a full note\n",
26c527e6 22006 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22007 "not enough for a full note\n",
22008 data_remaining),
26c527e6 22009 data_remaining);
9dd3a467
NC
22010 break;
22011 }
5396a86e
AM
22012 data_remaining -= min_notesz;
22013
15b42fb0
AM
22014 inote.type = BYTE_GET (external->type);
22015 inote.namesz = BYTE_GET (external->namesz);
22016 inote.namedata = external->name;
22017 inote.descsz = BYTE_GET (external->descsz);
276da9b3 22018 inote.descdata = ((char *) external
4dff97b2 22019 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 22020 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 22021 next = ((char *) external
4dff97b2 22022 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 22023 }
00e98fc7 22024 else
15b42fb0
AM
22025 {
22026 Elf64_External_VMS_Note *vms_external;
00e98fc7 22027
9dd3a467
NC
22028 /* PR binutils/15191
22029 Make sure that there is enough data to read. */
15b42fb0
AM
22030 min_notesz = offsetof (Elf64_External_VMS_Note, name);
22031 if (data_remaining < min_notesz)
9dd3a467 22032 {
26c527e6 22033 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22034 "not enough for a full note\n",
26c527e6 22035 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22036 "not enough for a full note\n",
22037 data_remaining),
26c527e6 22038 data_remaining);
9dd3a467
NC
22039 break;
22040 }
5396a86e 22041 data_remaining -= min_notesz;
3e55a963 22042
15b42fb0
AM
22043 vms_external = (Elf64_External_VMS_Note *) external;
22044 inote.type = BYTE_GET (vms_external->type);
22045 inote.namesz = BYTE_GET (vms_external->namesz);
22046 inote.namedata = vms_external->name;
22047 inote.descsz = BYTE_GET (vms_external->descsz);
22048 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
22049 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22050 next = inote.descdata + align_power (inote.descsz, 3);
22051 }
22052
5396a86e
AM
22053 /* PR 17531: file: 3443835e. */
22054 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
22055 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
22056 || (size_t) (inote.descdata - inote.namedata) > data_remaining
22057 || (size_t) (next - inote.descdata) < inote.descsz
22058 || ((size_t) (next - inote.descdata)
22059 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 22060 {
26c527e6
AM
22061 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
22062 (char *) external - (char *) pnotes);
22063 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 22064 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
22065 break;
22066 }
22067
15b42fb0 22068 external = (Elf_External_Note *) next;
dd24e3da 22069
6d118b09
NC
22070 /* Verify that name is null terminated. It appears that at least
22071 one version of Linux (RedHat 6.0) generates corefiles that don't
22072 comply with the ELF spec by failing to include the null byte in
22073 namesz. */
18344509 22074 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 22075 {
5396a86e 22076 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 22077 {
5396a86e
AM
22078 temp = (char *) malloc (inote.namesz + 1);
22079 if (temp == NULL)
22080 {
22081 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 22082 res = false;
5396a86e
AM
22083 break;
22084 }
76da6bbe 22085
5396a86e
AM
22086 memcpy (temp, inote.namedata, inote.namesz);
22087 inote.namedata = temp;
22088 }
22089 inote.namedata[inote.namesz] = 0;
6d118b09
NC
22090 }
22091
dda8d76d 22092 if (! process_note (& inote, filedata))
015dc7e1 22093 res = false;
103f02d3 22094
9db70fc3
AM
22095 free (temp);
22096 temp = NULL;
779fe533
NC
22097 }
22098
22099 free (pnotes);
103f02d3 22100
779fe533
NC
22101 return res;
22102}
22103
015dc7e1 22104static bool
dda8d76d 22105process_corefile_note_segments (Filedata * filedata)
779fe533 22106{
015dc7e1 22107 Elf_Internal_Phdr *segment;
b34976b6 22108 unsigned int i;
015dc7e1 22109 bool res = true;
103f02d3 22110
dda8d76d 22111 if (! get_program_headers (filedata))
015dc7e1 22112 return true;
103f02d3 22113
dda8d76d
NC
22114 for (i = 0, segment = filedata->program_headers;
22115 i < filedata->file_header.e_phnum;
b34976b6 22116 i++, segment++)
779fe533
NC
22117 {
22118 if (segment->p_type == PT_NOTE)
625d49fc
AM
22119 if (! process_notes_at (filedata, NULL, segment->p_offset,
22120 segment->p_filesz, segment->p_align))
015dc7e1 22121 res = false;
779fe533 22122 }
103f02d3 22123
779fe533
NC
22124 return res;
22125}
22126
015dc7e1 22127static bool
625d49fc 22128process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
22129{
22130 Elf_External_Note * pnotes;
22131 Elf_External_Note * external;
c8071705 22132 char * end;
015dc7e1 22133 bool res = true;
685080f2
NC
22134
22135 if (length <= 0)
015dc7e1 22136 return false;
685080f2 22137
dda8d76d 22138 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
22139 _("v850 notes"));
22140 if (pnotes == NULL)
015dc7e1 22141 return false;
685080f2
NC
22142
22143 external = pnotes;
c8071705 22144 end = (char*) pnotes + length;
685080f2 22145
26c527e6
AM
22146 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22147 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22148 offset, length);
685080f2 22149
c8071705 22150 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
22151 {
22152 Elf_External_Note * next;
22153 Elf_Internal_Note inote;
22154
22155 inote.type = BYTE_GET (external->type);
22156 inote.namesz = BYTE_GET (external->namesz);
22157 inote.namedata = external->name;
22158 inote.descsz = BYTE_GET (external->descsz);
22159 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22160 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22161
c8071705
NC
22162 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22163 {
22164 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22165 inote.descdata = inote.namedata;
22166 inote.namesz = 0;
22167 }
22168
685080f2
NC
22169 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22170
c8071705 22171 if ( ((char *) next > end)
685080f2
NC
22172 || ((char *) next < (char *) pnotes))
22173 {
26c527e6
AM
22174 warn (_("corrupt descsz found in note at offset %#tx\n"),
22175 (char *) external - (char *) pnotes);
22176 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22177 inote.type, inote.namesz, inote.descsz);
22178 break;
22179 }
22180
22181 external = next;
22182
22183 /* Prevent out-of-bounds indexing. */
c8071705 22184 if ( inote.namedata + inote.namesz > end
685080f2
NC
22185 || inote.namedata + inote.namesz < inote.namedata)
22186 {
26c527e6
AM
22187 warn (_("corrupt namesz found in note at offset %#zx\n"),
22188 (char *) external - (char *) pnotes);
22189 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22190 inote.type, inote.namesz, inote.descsz);
22191 break;
22192 }
22193
22194 printf (" %s: ", get_v850_elf_note_type (inote.type));
22195
22196 if (! print_v850_note (& inote))
22197 {
015dc7e1 22198 res = false;
26c527e6 22199 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
22200 inote.namesz, inote.descsz);
22201 }
22202 }
22203
22204 free (pnotes);
22205
22206 return res;
22207}
22208
015dc7e1 22209static bool
dda8d76d 22210process_note_sections (Filedata * filedata)
1ec5cd37 22211{
015dc7e1 22212 Elf_Internal_Shdr *section;
26c527e6 22213 size_t i;
32ec8896 22214 unsigned int n = 0;
015dc7e1 22215 bool res = true;
1ec5cd37 22216
dda8d76d
NC
22217 for (i = 0, section = filedata->section_headers;
22218 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 22219 i++, section++)
685080f2
NC
22220 {
22221 if (section->sh_type == SHT_NOTE)
22222 {
625d49fc
AM
22223 if (! process_notes_at (filedata, section, section->sh_offset,
22224 section->sh_size, section->sh_addralign))
015dc7e1 22225 res = false;
685080f2
NC
22226 n++;
22227 }
22228
dda8d76d
NC
22229 if (( filedata->file_header.e_machine == EM_V800
22230 || filedata->file_header.e_machine == EM_V850
22231 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
22232 && section->sh_type == SHT_RENESAS_INFO)
22233 {
625d49fc
AM
22234 if (! process_v850_notes (filedata, section->sh_offset,
22235 section->sh_size))
015dc7e1 22236 res = false;
685080f2
NC
22237 n++;
22238 }
22239 }
df565f32
NC
22240
22241 if (n == 0)
22242 /* Try processing NOTE segments instead. */
dda8d76d 22243 return process_corefile_note_segments (filedata);
1ec5cd37
NC
22244
22245 return res;
22246}
22247
015dc7e1 22248static bool
dda8d76d 22249process_notes (Filedata * filedata)
779fe533
NC
22250{
22251 /* If we have not been asked to display the notes then do nothing. */
22252 if (! do_notes)
015dc7e1 22253 return true;
103f02d3 22254
dda8d76d
NC
22255 if (filedata->file_header.e_type != ET_CORE)
22256 return process_note_sections (filedata);
103f02d3 22257
779fe533 22258 /* No program headers means no NOTE segment. */
dda8d76d
NC
22259 if (filedata->file_header.e_phnum > 0)
22260 return process_corefile_note_segments (filedata);
779fe533 22261
ca0e11aa
NC
22262 if (filedata->is_separate)
22263 printf (_("No notes found in linked file '%s'.\n"),
22264 filedata->file_name);
22265 else
22266 printf (_("No notes found file.\n"));
22267
015dc7e1 22268 return true;
779fe533
NC
22269}
22270
60abdbed
NC
22271static unsigned char *
22272display_public_gnu_attributes (unsigned char * start,
22273 const unsigned char * const end)
22274{
22275 printf (_(" Unknown GNU attribute: %s\n"), start);
22276
22277 start += strnlen ((char *) start, end - start);
22278 display_raw_attribute (start, end);
22279
22280 return (unsigned char *) end;
22281}
22282
22283static unsigned char *
22284display_generic_attribute (unsigned char * start,
22285 unsigned int tag,
22286 const unsigned char * const end)
22287{
22288 if (tag == 0)
22289 return (unsigned char *) end;
22290
22291 return display_tag_value (tag, start, end);
22292}
22293
015dc7e1 22294static bool
dda8d76d 22295process_arch_specific (Filedata * filedata)
252b5132 22296{
a952a375 22297 if (! do_arch)
015dc7e1 22298 return true;
a952a375 22299
dda8d76d 22300 switch (filedata->file_header.e_machine)
252b5132 22301 {
53a346d8
CZ
22302 case EM_ARC:
22303 case EM_ARC_COMPACT:
22304 case EM_ARC_COMPACT2:
dda8d76d 22305 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
22306 display_arc_attribute,
22307 display_generic_attribute);
11c1ff18 22308 case EM_ARM:
dda8d76d 22309 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
22310 display_arm_attribute,
22311 display_generic_attribute);
22312
252b5132 22313 case EM_MIPS:
4fe85591 22314 case EM_MIPS_RS3_LE:
dda8d76d 22315 return process_mips_specific (filedata);
60abdbed
NC
22316
22317 case EM_MSP430:
dda8d76d 22318 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 22319 display_msp430_attribute,
c0ea7c52 22320 display_msp430_gnu_attribute);
60abdbed 22321
2dc8dd17
JW
22322 case EM_RISCV:
22323 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22324 display_riscv_attribute,
22325 display_generic_attribute);
22326
35c08157 22327 case EM_NDS32:
dda8d76d 22328 return process_nds32_specific (filedata);
60abdbed 22329
85f7484a
PB
22330 case EM_68K:
22331 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22332 display_m68k_gnu_attribute);
22333
34c8bcba 22334 case EM_PPC:
b82317dd 22335 case EM_PPC64:
dda8d76d 22336 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22337 display_power_gnu_attribute);
22338
643f7afb
AK
22339 case EM_S390:
22340 case EM_S390_OLD:
dda8d76d 22341 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22342 display_s390_gnu_attribute);
22343
9e8c70f9
DM
22344 case EM_SPARC:
22345 case EM_SPARC32PLUS:
22346 case EM_SPARCV9:
dda8d76d 22347 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22348 display_sparc_gnu_attribute);
22349
59e6276b 22350 case EM_TI_C6000:
dda8d76d 22351 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22352 display_tic6x_attribute,
22353 display_generic_attribute);
22354
0861f561
CQ
22355 case EM_CSKY:
22356 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22357 display_csky_attribute, NULL);
22358
252b5132 22359 default:
dda8d76d 22360 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22361 display_public_gnu_attributes,
22362 display_generic_attribute);
252b5132 22363 }
252b5132
RH
22364}
22365
015dc7e1 22366static bool
dda8d76d 22367get_file_header (Filedata * filedata)
252b5132 22368{
9ea033b2 22369 /* Read in the identity array. */
dda8d76d 22370 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22371 return false;
252b5132 22372
9ea033b2 22373 /* Determine how to read the rest of the header. */
dda8d76d 22374 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22375 {
1a0670f3
AM
22376 default:
22377 case ELFDATANONE:
adab8cdc
AO
22378 case ELFDATA2LSB:
22379 byte_get = byte_get_little_endian;
22380 byte_put = byte_put_little_endian;
22381 break;
22382 case ELFDATA2MSB:
22383 byte_get = byte_get_big_endian;
22384 byte_put = byte_put_big_endian;
22385 break;
9ea033b2
NC
22386 }
22387
22388 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22389 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22390
22391 /* Read in the rest of the header. */
22392 if (is_32bit_elf)
22393 {
22394 Elf32_External_Ehdr ehdr32;
252b5132 22395
dda8d76d 22396 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22397 return false;
103f02d3 22398
dda8d76d
NC
22399 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22400 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22401 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22402 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22403 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22404 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22405 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22406 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22407 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22408 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22409 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22410 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22411 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22412 }
252b5132 22413 else
9ea033b2
NC
22414 {
22415 Elf64_External_Ehdr ehdr64;
a952a375 22416
dda8d76d 22417 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22418 return false;
103f02d3 22419
dda8d76d
NC
22420 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22421 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22422 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22423 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22424 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22425 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22426 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22427 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22428 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22429 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22430 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22431 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22432 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22433 }
252b5132 22434
015dc7e1 22435 return true;
252b5132
RH
22436}
22437
13acb58d
AM
22438static void
22439free_filedata (Filedata *filedata)
22440{
22441 free (filedata->program_interpreter);
13acb58d 22442 free (filedata->program_headers);
13acb58d 22443 free (filedata->section_headers);
13acb58d 22444 free (filedata->string_table);
13acb58d 22445 free (filedata->dump.dump_sects);
13acb58d 22446 free (filedata->dynamic_strings);
13acb58d 22447 free (filedata->dynamic_symbols);
13acb58d 22448 free (filedata->dynamic_syminfo);
13acb58d 22449 free (filedata->dynamic_section);
13acb58d
AM
22450
22451 while (filedata->symtab_shndx_list != NULL)
22452 {
22453 elf_section_list *next = filedata->symtab_shndx_list->next;
22454 free (filedata->symtab_shndx_list);
22455 filedata->symtab_shndx_list = next;
22456 }
22457
22458 free (filedata->section_headers_groups);
13acb58d
AM
22459
22460 if (filedata->section_groups)
22461 {
22462 size_t i;
22463 struct group_list * g;
22464 struct group_list * next;
22465
22466 for (i = 0; i < filedata->group_count; i++)
22467 {
22468 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22469 {
22470 next = g->next;
22471 free (g);
22472 }
22473 }
22474
22475 free (filedata->section_groups);
13acb58d 22476 }
066f8fbe
AM
22477 memset (&filedata->section_headers, 0,
22478 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22479}
22480
dda8d76d
NC
22481static void
22482close_file (Filedata * filedata)
22483{
22484 if (filedata)
22485 {
22486 if (filedata->handle)
22487 fclose (filedata->handle);
22488 free (filedata);
22489 }
22490}
22491
22492void
22493close_debug_file (void * data)
22494{
13acb58d 22495 free_filedata ((Filedata *) data);
dda8d76d
NC
22496 close_file ((Filedata *) data);
22497}
22498
22499static Filedata *
015dc7e1 22500open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22501{
22502 struct stat statbuf;
22503 Filedata * filedata = NULL;
22504
22505 if (stat (pathname, & statbuf) < 0
22506 || ! S_ISREG (statbuf.st_mode))
22507 goto fail;
22508
22509 filedata = calloc (1, sizeof * filedata);
22510 if (filedata == NULL)
22511 goto fail;
22512
22513 filedata->handle = fopen (pathname, "rb");
22514 if (filedata->handle == NULL)
22515 goto fail;
22516
be7d229a 22517 filedata->file_size = statbuf.st_size;
dda8d76d 22518 filedata->file_name = pathname;
ca0e11aa 22519 filedata->is_separate = is_separate;
dda8d76d
NC
22520
22521 if (! get_file_header (filedata))
22522 goto fail;
22523
4de91c10
AM
22524 if (!get_section_headers (filedata, false))
22525 goto fail;
dda8d76d
NC
22526
22527 return filedata;
22528
22529 fail:
22530 if (filedata)
22531 {
22532 if (filedata->handle)
22533 fclose (filedata->handle);
22534 free (filedata);
22535 }
22536 return NULL;
22537}
22538
22539void *
22540open_debug_file (const char * pathname)
22541{
015dc7e1 22542 return open_file (pathname, true);
dda8d76d
NC
22543}
22544
835f2fae
NC
22545static void
22546initialise_dump_sects (Filedata * filedata)
22547{
22548 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22549 Note we do this even if cmdline_dump_sects is empty because we
22550 must make sure that the dump_sets array is zeroed out before each
22551 object file is processed. */
22552 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22553 memset (filedata->dump.dump_sects, 0,
22554 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22555
22556 if (cmdline.num_dump_sects > 0)
22557 {
22558 if (filedata->dump.num_dump_sects == 0)
22559 /* A sneaky way of allocating the dump_sects array. */
22560 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22561
22562 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22563 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22564 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22565 }
22566}
22567
94585d6d
NC
22568static bool
22569might_need_separate_debug_info (Filedata * filedata)
22570{
22571 /* Debuginfo files do not need further separate file loading. */
22572 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22573 return false;
22574
22575 /* Since do_follow_links might be enabled by default, only treat it as an
22576 indication that separate files should be loaded if setting it was a
22577 deliberate user action. */
22578 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22579 return true;
22580
22581 if (process_links || do_syms || do_unwind
22582 || dump_any_debugging || do_dump || do_debugging)
22583 return true;
22584
22585 return false;
22586}
22587
fb52b2f4
NC
22588/* Process one ELF object file according to the command line options.
22589 This file may actually be stored in an archive. The file is
32ec8896
NC
22590 positioned at the start of the ELF object. Returns TRUE if no
22591 problems were encountered, FALSE otherwise. */
fb52b2f4 22592
015dc7e1 22593static bool
dda8d76d 22594process_object (Filedata * filedata)
252b5132 22595{
015dc7e1 22596 bool have_separate_files;
252b5132 22597 unsigned int i;
015dc7e1 22598 bool res;
252b5132 22599
dda8d76d 22600 if (! get_file_header (filedata))
252b5132 22601 {
dda8d76d 22602 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22603 return false;
252b5132
RH
22604 }
22605
22606 /* Initialise per file variables. */
978c4450
AM
22607 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22608 filedata->version_info[i] = 0;
252b5132 22609
978c4450
AM
22610 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22611 filedata->dynamic_info[i] = 0;
22612 filedata->dynamic_info_DT_GNU_HASH = 0;
22613 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22614
22615 /* Process the file. */
22616 if (show_name)
dda8d76d 22617 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22618
835f2fae 22619 initialise_dump_sects (filedata);
d70c5fc7 22620
4de91c10
AM
22621 /* There may be some extensions in the first section header. Don't
22622 bomb if we can't read it. */
22623 get_section_headers (filedata, true);
22624
dda8d76d 22625 if (! process_file_header (filedata))
4de91c10
AM
22626 {
22627 res = false;
22628 goto out;
22629 }
252b5132 22630
e331b18d
AM
22631 /* Throw away the single section header read above, so that we
22632 re-read the entire set. */
22633 free (filedata->section_headers);
22634 filedata->section_headers = NULL;
22635
dda8d76d 22636 if (! process_section_headers (filedata))
2f62977e 22637 {
32ec8896 22638 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22639 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22640
2f62977e 22641 if (! do_using_dynamic)
015dc7e1 22642 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22643 }
252b5132 22644
dda8d76d 22645 if (! process_section_groups (filedata))
32ec8896 22646 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22647 do_unwind = false;
d1f5c6e3 22648
93df3340
AM
22649 process_program_headers (filedata);
22650
22651 res = process_dynamic_section (filedata);
252b5132 22652
dda8d76d 22653 if (! process_relocs (filedata))
015dc7e1 22654 res = false;
252b5132 22655
dda8d76d 22656 if (! process_unwind (filedata))
015dc7e1 22657 res = false;
4d6ed7c8 22658
dda8d76d 22659 if (! process_symbol_table (filedata))
015dc7e1 22660 res = false;
252b5132 22661
0f03783c 22662 if (! process_lto_symbol_tables (filedata))
015dc7e1 22663 res = false;
b9e920ec 22664
dda8d76d 22665 if (! process_syminfo (filedata))
015dc7e1 22666 res = false;
252b5132 22667
dda8d76d 22668 if (! process_version_sections (filedata))
015dc7e1 22669 res = false;
252b5132 22670
94585d6d 22671 if (might_need_separate_debug_info (filedata))
24841daa 22672 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22673 else
015dc7e1 22674 have_separate_files = false;
dda8d76d
NC
22675
22676 if (! process_section_contents (filedata))
015dc7e1 22677 res = false;
f5842774 22678
24841daa 22679 if (have_separate_files)
dda8d76d 22680 {
24841daa
NC
22681 separate_info * d;
22682
22683 for (d = first_separate_info; d != NULL; d = d->next)
22684 {
835f2fae
NC
22685 initialise_dump_sects (d->handle);
22686
ca0e11aa 22687 if (process_links && ! process_file_header (d->handle))
015dc7e1 22688 res = false;
ca0e11aa 22689 else if (! process_section_headers (d->handle))
015dc7e1 22690 res = false;
d6bfbc39 22691 else if (! process_section_contents (d->handle))
015dc7e1 22692 res = false;
ca0e11aa
NC
22693 else if (process_links)
22694 {
ca0e11aa 22695 if (! process_section_groups (d->handle))
015dc7e1 22696 res = false;
93df3340 22697 process_program_headers (d->handle);
ca0e11aa 22698 if (! process_dynamic_section (d->handle))
015dc7e1 22699 res = false;
ca0e11aa 22700 if (! process_relocs (d->handle))
015dc7e1 22701 res = false;
ca0e11aa 22702 if (! process_unwind (d->handle))
015dc7e1 22703 res = false;
ca0e11aa 22704 if (! process_symbol_table (d->handle))
015dc7e1 22705 res = false;
ca0e11aa 22706 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22707 res = false;
ca0e11aa 22708 if (! process_syminfo (d->handle))
015dc7e1 22709 res = false;
ca0e11aa 22710 if (! process_version_sections (d->handle))
015dc7e1 22711 res = false;
ca0e11aa 22712 if (! process_notes (d->handle))
015dc7e1 22713 res = false;
ca0e11aa 22714 }
24841daa
NC
22715 }
22716
22717 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22718 }
22719
22720 if (! process_notes (filedata))
015dc7e1 22721 res = false;
103f02d3 22722
dda8d76d 22723 if (! process_gnu_liblist (filedata))
015dc7e1 22724 res = false;
047b2264 22725
dda8d76d 22726 if (! process_arch_specific (filedata))
015dc7e1 22727 res = false;
252b5132 22728
4de91c10 22729 out:
13acb58d 22730 free_filedata (filedata);
e4b17d5c 22731
19e6b90e 22732 free_debug_memory ();
18bd398b 22733
32ec8896 22734 return res;
252b5132
RH
22735}
22736
2cf0635d 22737/* Process an ELF archive.
32ec8896
NC
22738 On entry the file is positioned just after the ARMAG string.
22739 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22740
015dc7e1
AM
22741static bool
22742process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22743{
22744 struct archive_info arch;
22745 struct archive_info nested_arch;
22746 size_t got;
015dc7e1 22747 bool ret = true;
2cf0635d 22748
015dc7e1 22749 show_name = true;
2cf0635d
NC
22750
22751 /* The ARCH structure is used to hold information about this archive. */
22752 arch.file_name = NULL;
22753 arch.file = NULL;
22754 arch.index_array = NULL;
22755 arch.sym_table = NULL;
22756 arch.longnames = NULL;
22757
22758 /* The NESTED_ARCH structure is used as a single-item cache of information
22759 about a nested archive (when members of a thin archive reside within
22760 another regular archive file). */
22761 nested_arch.file_name = NULL;
22762 nested_arch.file = NULL;
22763 nested_arch.index_array = NULL;
22764 nested_arch.sym_table = NULL;
22765 nested_arch.longnames = NULL;
22766
dda8d76d 22767 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22768 filedata->file_size, is_thin_archive,
22769 do_archive_index) != 0)
2cf0635d 22770 {
015dc7e1 22771 ret = false;
2cf0635d 22772 goto out;
4145f1d5 22773 }
fb52b2f4 22774
4145f1d5
NC
22775 if (do_archive_index)
22776 {
2cf0635d 22777 if (arch.sym_table == NULL)
1cb7d8b1
AM
22778 error (_("%s: unable to dump the index as none was found\n"),
22779 filedata->file_name);
4145f1d5
NC
22780 else
22781 {
26c527e6
AM
22782 uint64_t i, l;
22783 uint64_t current_pos;
4145f1d5 22784
26c527e6
AM
22785 printf (_("Index of archive %s: (%" PRIu64 " entries,"
22786 " %#" PRIx64 " bytes in the symbol table)\n"),
22787 filedata->file_name, arch.index_num,
1cb7d8b1 22788 arch.sym_size);
dda8d76d
NC
22789
22790 current_pos = ftell (filedata->handle);
4145f1d5 22791
2cf0635d 22792 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22793 {
1cb7d8b1
AM
22794 if (i == 0
22795 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22796 {
22797 char * member_name
22798 = get_archive_member_name_at (&arch, arch.index_array[i],
22799 &nested_arch);
2cf0635d 22800
1cb7d8b1
AM
22801 if (member_name != NULL)
22802 {
22803 char * qualified_name
22804 = make_qualified_name (&arch, &nested_arch,
22805 member_name);
2cf0635d 22806
1cb7d8b1
AM
22807 if (qualified_name != NULL)
22808 {
22809 printf (_("Contents of binary %s at offset "),
22810 qualified_name);
c2a7d3f5
NC
22811 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22812 putchar ('\n');
1cb7d8b1
AM
22813 free (qualified_name);
22814 }
fd486f32 22815 free (member_name);
4145f1d5
NC
22816 }
22817 }
2cf0635d
NC
22818
22819 if (l >= arch.sym_size)
4145f1d5 22820 {
1cb7d8b1
AM
22821 error (_("%s: end of the symbol table reached "
22822 "before the end of the index\n"),
dda8d76d 22823 filedata->file_name);
015dc7e1 22824 ret = false;
cb8f3167 22825 break;
4145f1d5 22826 }
591f7597 22827 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22828 printf ("\t%.*s\n",
22829 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22830 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22831 }
22832
67ce483b 22833 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22834 l = (l + 7) & ~ 7;
22835 else
22836 l += l & 1;
22837
2cf0635d 22838 if (l < arch.sym_size)
32ec8896 22839 {
26c527e6 22840 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
22841 "but without corresponding entries in "
22842 "the index table\n",
26c527e6 22843 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
22844 "but without corresponding entries in "
22845 "the index table\n",
22846 arch.sym_size - l),
dda8d76d 22847 filedata->file_name, arch.sym_size - l);
015dc7e1 22848 ret = false;
32ec8896 22849 }
4145f1d5 22850
63cf857e 22851 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22852 {
1cb7d8b1
AM
22853 error (_("%s: failed to seek back to start of object files "
22854 "in the archive\n"),
dda8d76d 22855 filedata->file_name);
015dc7e1 22856 ret = false;
2cf0635d 22857 goto out;
4145f1d5 22858 }
fb52b2f4 22859 }
4145f1d5
NC
22860
22861 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22862 && !do_segments && !do_header && !do_dump && !do_version
22863 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22864 && !do_section_groups && !do_dyn_syms)
2cf0635d 22865 {
015dc7e1 22866 ret = true; /* Archive index only. */
2cf0635d
NC
22867 goto out;
22868 }
fb52b2f4
NC
22869 }
22870
fb52b2f4
NC
22871 while (1)
22872 {
2cf0635d
NC
22873 char * name;
22874 size_t namelen;
22875 char * qualified_name;
22876
22877 /* Read the next archive header. */
63cf857e 22878 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22879 {
22880 error (_("%s: failed to seek to next archive header\n"),
22881 arch.file_name);
015dc7e1 22882 ret = false;
1cb7d8b1
AM
22883 break;
22884 }
dda8d76d 22885 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22886 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22887 {
22888 if (got == 0)
2cf0635d 22889 break;
28e817cc
NC
22890 /* PR 24049 - we cannot use filedata->file_name as this will
22891 have already been freed. */
22892 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22893
015dc7e1 22894 ret = false;
1cb7d8b1
AM
22895 break;
22896 }
2cf0635d 22897 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22898 {
22899 error (_("%s: did not find a valid archive header\n"),
22900 arch.file_name);
015dc7e1 22901 ret = false;
1cb7d8b1
AM
22902 break;
22903 }
2cf0635d
NC
22904
22905 arch.next_arhdr_offset += sizeof arch.arhdr;
22906
978c4450 22907 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22908
22909 name = get_archive_member_name (&arch, &nested_arch);
22910 if (name == NULL)
fb52b2f4 22911 {
28e817cc 22912 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22913 ret = false;
d989285c 22914 break;
fb52b2f4 22915 }
2cf0635d 22916 namelen = strlen (name);
fb52b2f4 22917
2cf0635d
NC
22918 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22919 if (qualified_name == NULL)
fb52b2f4 22920 {
28e817cc 22921 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22922 free (name);
015dc7e1 22923 ret = false;
d989285c 22924 break;
fb52b2f4
NC
22925 }
22926
2cf0635d 22927 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22928 {
22929 /* This is a proxy for an external member of a thin archive. */
22930 Filedata * member_filedata;
22931 char * member_file_name = adjust_relative_path
dda8d76d 22932 (filedata->file_name, name, namelen);
32ec8896 22933
fd486f32 22934 free (name);
1cb7d8b1
AM
22935 if (member_file_name == NULL)
22936 {
fd486f32 22937 free (qualified_name);
015dc7e1 22938 ret = false;
1cb7d8b1
AM
22939 break;
22940 }
2cf0635d 22941
015dc7e1 22942 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22943 if (member_filedata == NULL)
22944 {
22945 error (_("Input file '%s' is not readable.\n"), member_file_name);
22946 free (member_file_name);
fd486f32 22947 free (qualified_name);
015dc7e1 22948 ret = false;
1cb7d8b1
AM
22949 break;
22950 }
2cf0635d 22951
978c4450 22952 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22953 member_filedata->file_name = qualified_name;
2cf0635d 22954
75a2da57
AH
22955 /* The call to process_object() expects the file to be at the beginning. */
22956 rewind (member_filedata->handle);
22957
1cb7d8b1 22958 if (! process_object (member_filedata))
015dc7e1 22959 ret = false;
2cf0635d 22960
1cb7d8b1
AM
22961 close_file (member_filedata);
22962 free (member_file_name);
1cb7d8b1 22963 }
2cf0635d 22964 else if (is_thin_archive)
1cb7d8b1
AM
22965 {
22966 Filedata thin_filedata;
eb02c04d 22967
1cb7d8b1 22968 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22969
a043396b
NC
22970 /* PR 15140: Allow for corrupt thin archives. */
22971 if (nested_arch.file == NULL)
22972 {
22973 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22974 qualified_name, name);
fd486f32
AM
22975 free (qualified_name);
22976 free (name);
015dc7e1 22977 ret = false;
a043396b
NC
22978 break;
22979 }
fd486f32 22980 free (name);
a043396b 22981
1cb7d8b1 22982 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22983 filedata->archive_file_offset
22984 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22985
1cb7d8b1
AM
22986 /* The nested archive file will have been opened and setup by
22987 get_archive_member_name. */
63cf857e
AM
22988 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
22989 SEEK_SET) != 0)
1cb7d8b1
AM
22990 {
22991 error (_("%s: failed to seek to archive member.\n"),
22992 nested_arch.file_name);
fd486f32 22993 free (qualified_name);
015dc7e1 22994 ret = false;
1cb7d8b1
AM
22995 break;
22996 }
2cf0635d 22997
dda8d76d
NC
22998 thin_filedata.handle = nested_arch.file;
22999 thin_filedata.file_name = qualified_name;
9abca702 23000
1cb7d8b1 23001 if (! process_object (& thin_filedata))
015dc7e1 23002 ret = false;
1cb7d8b1 23003 }
2cf0635d 23004 else
1cb7d8b1 23005 {
fd486f32 23006 free (name);
978c4450 23007 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 23008 filedata->file_name = qualified_name;
1cb7d8b1 23009 if (! process_object (filedata))
015dc7e1 23010 ret = false;
237877b8 23011 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 23012 /* Stop looping with "negative" archive_file_size. */
978c4450 23013 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 23014 arch.next_arhdr_offset = -1ul;
1cb7d8b1 23015 }
fb52b2f4 23016
2cf0635d 23017 free (qualified_name);
fb52b2f4
NC
23018 }
23019
4145f1d5 23020 out:
2cf0635d
NC
23021 if (nested_arch.file != NULL)
23022 fclose (nested_arch.file);
23023 release_archive (&nested_arch);
23024 release_archive (&arch);
fb52b2f4 23025
d989285c 23026 return ret;
fb52b2f4
NC
23027}
23028
015dc7e1 23029static bool
2cf0635d 23030process_file (char * file_name)
fb52b2f4 23031{
dda8d76d 23032 Filedata * filedata = NULL;
fb52b2f4
NC
23033 struct stat statbuf;
23034 char armag[SARMAG];
015dc7e1 23035 bool ret = true;
fb52b2f4
NC
23036
23037 if (stat (file_name, &statbuf) < 0)
23038 {
f24ddbdd
NC
23039 if (errno == ENOENT)
23040 error (_("'%s': No such file\n"), file_name);
23041 else
23042 error (_("Could not locate '%s'. System error message: %s\n"),
23043 file_name, strerror (errno));
015dc7e1 23044 return false;
f24ddbdd
NC
23045 }
23046
23047 if (! S_ISREG (statbuf.st_mode))
23048 {
23049 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 23050 return false;
fb52b2f4
NC
23051 }
23052
dda8d76d
NC
23053 filedata = calloc (1, sizeof * filedata);
23054 if (filedata == NULL)
23055 {
23056 error (_("Out of memory allocating file data structure\n"));
015dc7e1 23057 return false;
dda8d76d
NC
23058 }
23059
23060 filedata->file_name = file_name;
23061 filedata->handle = fopen (file_name, "rb");
23062 if (filedata->handle == NULL)
fb52b2f4 23063 {
f24ddbdd 23064 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 23065 free (filedata);
015dc7e1 23066 return false;
fb52b2f4
NC
23067 }
23068
dda8d76d 23069 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 23070 {
4145f1d5 23071 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
23072 fclose (filedata->handle);
23073 free (filedata);
015dc7e1 23074 return false;
fb52b2f4
NC
23075 }
23076
be7d229a 23077 filedata->file_size = statbuf.st_size;
015dc7e1 23078 filedata->is_separate = false;
f54498b4 23079
fb52b2f4 23080 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 23081 {
015dc7e1
AM
23082 if (! process_archive (filedata, false))
23083 ret = false;
32ec8896 23084 }
2cf0635d 23085 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 23086 {
015dc7e1
AM
23087 if ( ! process_archive (filedata, true))
23088 ret = false;
32ec8896 23089 }
fb52b2f4
NC
23090 else
23091 {
1b513401 23092 if (do_archive_index && !check_all)
4145f1d5
NC
23093 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23094 file_name);
23095
dda8d76d 23096 rewind (filedata->handle);
978c4450 23097 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 23098
dda8d76d 23099 if (! process_object (filedata))
015dc7e1 23100 ret = false;
fb52b2f4
NC
23101 }
23102
dda8d76d 23103 fclose (filedata->handle);
8fb879cd
AM
23104 free (filedata->section_headers);
23105 free (filedata->program_headers);
23106 free (filedata->string_table);
6431e409 23107 free (filedata->dump.dump_sects);
dda8d76d 23108 free (filedata);
32ec8896 23109
fd486f32 23110 free (ba_cache.strtab);
1bd6175a 23111 ba_cache.strtab = NULL;
fd486f32 23112 free (ba_cache.symtab);
1bd6175a 23113 ba_cache.symtab = NULL;
fd486f32
AM
23114 ba_cache.filedata = NULL;
23115
fb52b2f4
NC
23116 return ret;
23117}
23118
252b5132
RH
23119#ifdef SUPPORT_DISASSEMBLY
23120/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 23121 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 23122 symbols. */
252b5132
RH
23123
23124void
2cf0635d 23125print_address (unsigned int addr, FILE * outfile)
252b5132
RH
23126{
23127 fprintf (outfile,"0x%8.8x", addr);
23128}
23129
e3c8793a 23130/* Needed by the i386 disassembler. */
dda8d76d 23131
252b5132
RH
23132void
23133db_task_printsym (unsigned int addr)
23134{
23135 print_address (addr, stderr);
23136}
23137#endif
23138
23139int
2cf0635d 23140main (int argc, char ** argv)
252b5132 23141{
ff78d6d6
L
23142 int err;
23143
87b9f255 23144#ifdef HAVE_LC_MESSAGES
252b5132 23145 setlocale (LC_MESSAGES, "");
3882b010 23146#endif
3882b010 23147 setlocale (LC_CTYPE, "");
252b5132
RH
23148 bindtextdomain (PACKAGE, LOCALEDIR);
23149 textdomain (PACKAGE);
23150
869b9d07
MM
23151 expandargv (&argc, &argv);
23152
dda8d76d 23153 parse_args (& cmdline, argc, argv);
59f14fc0 23154
18bd398b 23155 if (optind < (argc - 1))
1b513401
NC
23156 /* When displaying information for more than one file,
23157 prefix the information with the file name. */
015dc7e1 23158 show_name = true;
5656ba2c
L
23159 else if (optind >= argc)
23160 {
1b513401 23161 /* Ensure that the warning is always displayed. */
015dc7e1 23162 do_checks = true;
1b513401 23163
5656ba2c
L
23164 warn (_("Nothing to do.\n"));
23165 usage (stderr);
23166 }
18bd398b 23167
015dc7e1 23168 err = false;
252b5132 23169 while (optind < argc)
32ec8896 23170 if (! process_file (argv[optind++]))
015dc7e1 23171 err = true;
252b5132 23172
9db70fc3 23173 free (cmdline.dump_sects);
252b5132 23174
7d9813f1
NA
23175 free (dump_ctf_symtab_name);
23176 free (dump_ctf_strtab_name);
23177 free (dump_ctf_parent_name);
23178
32ec8896 23179 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 23180}