]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
LoongArch: opcodes: Add support for linker relaxation.
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
d87bef3a 2 Copyright (C) 1998-2023 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056 46#include <zlib.h>
1f5a3546
FS
47#ifdef HAVE_ZSTD
48#include <zstd.h>
49#endif
7bfd842d 50#include <wchar.h>
252b5132 51
2952f10c
SM
52#if defined HAVE_MSGPACK
53#include <msgpack.h>
54#endif
55
19936277 56/* Define BFD64 here, even if our default architecture is 32 bit ELF
625d49fc 57 as this will allow us to read in and parse 64bit and 32bit ELF files. */
19936277 58#define BFD64
a952a375 59
3db64b00
AM
60#include "bfd.h"
61#include "bucomm.h"
3284fe0c 62#include "elfcomm.h"
0d646226 63#include "demanguse.h"
19e6b90e 64#include "dwarf.h"
7d9813f1 65#include "ctf-api.h"
42b6953b 66#include "sframe-api.h"
79bc120c 67#include "demangle.h"
252b5132
RH
68
69#include "elf/common.h"
70#include "elf/external.h"
71#include "elf/internal.h"
252b5132 72
4b78141a
NC
73
74/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
75 we can obtain the H8 reloc numbers. We need these for the
76 get_reloc_size() function. We include h8.h again after defining
77 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
78
79#include "elf/h8.h"
80#undef _ELF_H8_H
81
82/* Undo the effects of #including reloc-macros.h. */
83
84#undef START_RELOC_NUMBERS
85#undef RELOC_NUMBER
86#undef FAKE_RELOC
87#undef EMPTY_RELOC
88#undef END_RELOC_NUMBERS
89#undef _RELOC_MACROS_H
90
252b5132
RH
91/* The following headers use the elf/reloc-macros.h file to
92 automatically generate relocation recognition functions
93 such as elf_mips_reloc_type() */
94
95#define RELOC_MACROS_GEN_FUNC
96
a06ea964 97#include "elf/aarch64.h"
252b5132 98#include "elf/alpha.h"
c077c580 99#include "elf/amdgpu.h"
3b16e843 100#include "elf/arc.h"
252b5132 101#include "elf/arm.h"
3b16e843 102#include "elf/avr.h"
1d65ded4 103#include "elf/bfin.h"
60bca95a 104#include "elf/cr16.h"
3b16e843 105#include "elf/cris.h"
1c0d3aa6 106#include "elf/crx.h"
b8891f8d 107#include "elf/csky.h"
252b5132
RH
108#include "elf/d10v.h"
109#include "elf/d30v.h"
d172d4ba 110#include "elf/dlx.h"
aca4efc7 111#include "elf/bpf.h"
cfb8c092 112#include "elf/epiphany.h"
252b5132 113#include "elf/fr30.h"
5c70f934 114#include "elf/frv.h"
3f8107ab 115#include "elf/ft32.h"
3b16e843
NC
116#include "elf/h8.h"
117#include "elf/hppa.h"
118#include "elf/i386.h"
f954747f
AM
119#include "elf/i370.h"
120#include "elf/i860.h"
121#include "elf/i960.h"
3b16e843 122#include "elf/ia64.h"
1e4cf259 123#include "elf/ip2k.h"
84e94c90 124#include "elf/lm32.h"
1c0d3aa6 125#include "elf/iq2000.h"
49f58d10 126#include "elf/m32c.h"
3b16e843
NC
127#include "elf/m32r.h"
128#include "elf/m68k.h"
75751cd9 129#include "elf/m68hc11.h"
7b4ae824 130#include "elf/s12z.h"
252b5132 131#include "elf/mcore.h"
15ab5209 132#include "elf/mep.h"
a3c62988 133#include "elf/metag.h"
7ba29e2a 134#include "elf/microblaze.h"
3b16e843 135#include "elf/mips.h"
3c3bdf30 136#include "elf/mmix.h"
3b16e843
NC
137#include "elf/mn10200.h"
138#include "elf/mn10300.h"
5506d11a 139#include "elf/moxie.h"
4970f871 140#include "elf/mt.h"
2469cfa2 141#include "elf/msp430.h"
35c08157 142#include "elf/nds32.h"
fe944acf 143#include "elf/nfp.h"
13761a11 144#include "elf/nios2.h"
73589c9d 145#include "elf/or1k.h"
7d466069 146#include "elf/pj.h"
3b16e843 147#include "elf/ppc.h"
c833c019 148#include "elf/ppc64.h"
2b100bb5 149#include "elf/pru.h"
03336641 150#include "elf/riscv.h"
99c513f6 151#include "elf/rl78.h"
c7927a3c 152#include "elf/rx.h"
a85d7ed0 153#include "elf/s390.h"
1c0d3aa6 154#include "elf/score.h"
3b16e843
NC
155#include "elf/sh.h"
156#include "elf/sparc.h"
e9f53129 157#include "elf/spu.h"
40b36596 158#include "elf/tic6x.h"
aa137e4d
NC
159#include "elf/tilegx.h"
160#include "elf/tilepro.h"
3b16e843 161#include "elf/v850.h"
179d3252 162#include "elf/vax.h"
619ed720 163#include "elf/visium.h"
f96bd6c2 164#include "elf/wasm32.h"
3b16e843 165#include "elf/x86-64.h"
f6c1a2d5 166#include "elf/xgate.h"
93fbbb04 167#include "elf/xstormy16.h"
88da6820 168#include "elf/xtensa.h"
6655dba2 169#include "elf/z80.h"
e9a0721f 170#include "elf/loongarch.h"
252b5132 171
252b5132 172#include "getopt.h"
566b0d53 173#include "libiberty.h"
09c11c86 174#include "safe-ctype.h"
2cf0635d 175#include "filenames.h"
252b5132 176
15b42fb0
AM
177#ifndef offsetof
178#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
179#endif
180
6a40cf0c
NC
181typedef struct elf_section_list
182{
dda8d76d
NC
183 Elf_Internal_Shdr * hdr;
184 struct elf_section_list * next;
6a40cf0c
NC
185} elf_section_list;
186
dda8d76d
NC
187/* Flag bits indicating particular types of dump. */
188#define HEX_DUMP (1 << 0) /* The -x command line switch. */
189#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
190#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
191#define STRING_DUMP (1 << 3) /* The -p command line switch. */
192#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 193#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
42b6953b 194#define SFRAME_DUMP (1 << 6) /* The --sframe command line switch. */
dda8d76d
NC
195
196typedef unsigned char dump_type;
197
198/* A linked list of the section names for which dumps were requested. */
199struct dump_list_entry
200{
201 char * name;
202 dump_type type;
203 struct dump_list_entry * next;
204};
205
6431e409
AM
206/* A dynamic array of flags indicating for which sections a dump
207 has been requested via command line switches. */
1b513401
NC
208struct dump_data
209{
6431e409
AM
210 dump_type * dump_sects;
211 unsigned int num_dump_sects;
212};
213
214static struct dump_data cmdline;
215
216static struct dump_list_entry * dump_sects_byname;
217
2cf0635d 218char * program_name = "readelf";
dda8d76d 219
015dc7e1
AM
220static bool show_name = false;
221static bool do_dynamic = false;
222static bool do_syms = false;
223static bool do_dyn_syms = false;
224static bool do_lto_syms = false;
225static bool do_reloc = false;
226static bool do_sections = false;
227static bool do_section_groups = false;
228static bool do_section_details = false;
229static bool do_segments = false;
230static bool do_unwind = false;
231static bool do_using_dynamic = false;
232static bool do_header = false;
233static bool do_dump = false;
234static bool do_version = false;
235static bool do_histogram = false;
236static bool do_debugging = false;
237static bool do_ctf = false;
42b6953b 238static bool do_sframe = false;
015dc7e1
AM
239static bool do_arch = false;
240static bool do_notes = false;
241static bool do_archive_index = false;
242static bool check_all = false;
243static bool is_32bit_elf = false;
244static bool decompress_dumps = false;
245static bool do_not_show_symbol_truncation = false;
246static bool do_demangle = false; /* Pretty print C++ symbol names. */
247static bool process_links = false;
e1dbfc17 248static bool dump_any_debugging = false;
79bc120c 249static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 250static int sym_base = 0;
252b5132 251
7d9813f1
NA
252static char *dump_ctf_parent_name;
253static char *dump_ctf_symtab_name;
254static char *dump_ctf_strtab_name;
255
e4b17d5c
L
256struct group_list
257{
dda8d76d
NC
258 struct group_list * next;
259 unsigned int section_index;
e4b17d5c
L
260};
261
262struct group
263{
dda8d76d
NC
264 struct group_list * root;
265 unsigned int group_index;
e4b17d5c
L
266};
267
978c4450
AM
268typedef struct filedata
269{
270 const char * file_name;
015dc7e1 271 bool is_separate;
978c4450 272 FILE * handle;
be7d229a 273 uint64_t file_size;
978c4450 274 Elf_Internal_Ehdr file_header;
26c527e6
AM
275 uint64_t archive_file_offset;
276 uint64_t archive_file_size;
066f8fbe 277 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
278 Elf_Internal_Shdr * section_headers;
279 Elf_Internal_Phdr * program_headers;
280 char * string_table;
26c527e6
AM
281 uint64_t string_table_length;
282 uint64_t dynamic_addr;
be7d229a 283 uint64_t dynamic_size;
26c527e6 284 uint64_t dynamic_nent;
978c4450 285 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 286 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450 287 char * dynamic_strings;
26c527e6 288 uint64_t dynamic_strings_length;
8ac10c5b 289 Elf_Internal_Shdr * dynamic_symtab_section;
26c527e6 290 uint64_t num_dynamic_syms;
978c4450 291 Elf_Internal_Sym * dynamic_symbols;
26c527e6 292 uint64_t version_info[16];
978c4450
AM
293 unsigned int dynamic_syminfo_nent;
294 Elf_Internal_Syminfo * dynamic_syminfo;
26c527e6 295 uint64_t dynamic_syminfo_offset;
be7d229a
AM
296 uint64_t nbuckets;
297 uint64_t nchains;
625d49fc
AM
298 uint64_t * buckets;
299 uint64_t * chains;
be7d229a
AM
300 uint64_t ngnubuckets;
301 uint64_t ngnuchains;
625d49fc
AM
302 uint64_t * gnubuckets;
303 uint64_t * gnuchains;
304 uint64_t * mipsxlat;
305 uint64_t gnusymidx;
13acb58d 306 char * program_interpreter;
bc227f4c 307 uint64_t dynamic_info[DT_RELRENT + 1];
625d49fc
AM
308 uint64_t dynamic_info_DT_GNU_HASH;
309 uint64_t dynamic_info_DT_MIPS_XHASH;
978c4450
AM
310 elf_section_list * symtab_shndx_list;
311 size_t group_count;
312 struct group * section_groups;
313 struct group ** section_headers_groups;
314 /* A dynamic array of flags indicating for which sections a dump of
315 some kind has been requested. It is reset on a per-object file
316 basis and then initialised from the cmdline_dump_sects array,
317 the results of interpreting the -w switch, and the
318 dump_sects_byname list. */
319 struct dump_data dump;
320} Filedata;
aef1f6d0 321
c256ffe7 322/* How to print a vma value. */
843dd992
NC
323typedef enum print_mode
324{
325 HEX,
047c3dbf 326 HEX_5,
843dd992
NC
327 DEC,
328 DEC_5,
329 UNSIGNED,
047c3dbf 330 UNSIGNED_5,
843dd992 331 PREFIX_HEX,
047c3dbf 332 PREFIX_HEX_5,
843dd992 333 FULL_HEX,
047c3dbf
NL
334 LONG_HEX,
335 OCTAL,
336 OCTAL_5
843dd992
NC
337}
338print_mode;
339
b3aa80b4
NC
340typedef enum unicode_display_type
341{
342 unicode_default = 0,
343 unicode_locale,
344 unicode_escape,
345 unicode_hex,
346 unicode_highlight,
347 unicode_invalid
348} unicode_display_type;
349
350static unicode_display_type unicode_display = unicode_default;
351
a7fd1186
FS
352typedef enum
353{
354 reltype_unknown,
355 reltype_rel,
356 reltype_rela,
357 reltype_relr
358} relocation_type;
359
bb4d2ac2
L
360/* Versioned symbol info. */
361enum versioned_symbol_info
362{
363 symbol_undefined,
364 symbol_hidden,
365 symbol_public
366};
367
63cf857e
AM
368static int
369fseek64 (FILE *stream, int64_t offset, int whence)
370{
371#if defined (HAVE_FSEEKO64)
372 off64_t o = offset;
373 if (o != offset)
374 {
375 errno = EINVAL;
376 return -1;
377 }
378 return fseeko64 (stream, o, whence);
379#elif defined (HAVE_FSEEKO)
380 off_t o = offset;
381 if (o != offset)
382 {
383 errno = EINVAL;
384 return -1;
385 }
386 return fseeko (stream, o, whence);
387#else
388 long o = offset;
389 if (o != offset)
390 {
391 errno = EINVAL;
392 return -1;
393 }
394 return fseek (stream, o, whence);
395#endif
396}
397
32ec8896 398static const char * get_symbol_version_string
26c527e6 399 (Filedata *, bool, const char *, size_t, unsigned,
32ec8896 400 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 401
9c19a809
NC
402#define UNKNOWN -1
403
84714f86
AM
404static inline const char *
405section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
406{
407 return filedata->string_table + hdr->sh_name;
408}
b9e920ec 409
84714f86
AM
410static inline bool
411section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
412{
413 return (hdr != NULL
414 && filedata->string_table != NULL
415 && hdr->sh_name < filedata->string_table_length);
416}
b9e920ec 417
84714f86
AM
418static inline const char *
419section_name_print (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
420{
421 if (hdr == NULL)
422 return _("<none>");
423 if (filedata->string_table == NULL)
424 return _("<no-strings>");
425 if (hdr->sh_name >= filedata->string_table_length)
426 return _("<corrupt>");
427 return section_name (filedata, hdr);
428}
252b5132 429
ee42cf8c 430#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 431
84714f86
AM
432static inline bool
433valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
434{
435 return strtab != NULL && offset < strtab_size;
436}
437
438static inline bool
439valid_dynamic_name (const Filedata *filedata, uint64_t offset)
440{
441 return valid_symbol_name (filedata->dynamic_strings,
442 filedata->dynamic_strings_length, offset);
443}
444
d79b3d50
NC
445/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
446 already been called and verified that the string exists. */
84714f86
AM
447static inline const char *
448get_dynamic_name (const Filedata *filedata, size_t offset)
449{
450 return filedata->dynamic_strings + offset;
451}
18bd398b 452
61865e30
NC
453#define REMOVE_ARCH_BITS(ADDR) \
454 do \
455 { \
dda8d76d 456 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
457 (ADDR) &= ~1; \
458 } \
459 while (0)
f16a9783
MS
460
461/* Get the correct GNU hash section name. */
978c4450
AM
462#define GNU_HASH_SECTION_NAME(filedata) \
463 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 464\f
dda8d76d
NC
465/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
466 OFFSET + the offset of the current archive member, if we are examining an
467 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
468 allocate a buffer using malloc and fill that. In either case return the
469 pointer to the start of the retrieved data or NULL if something went wrong.
470 If something does go wrong and REASON is not NULL then emit an error
471 message using REASON as part of the context. */
59245841 472
c256ffe7 473static void *
be7d229a
AM
474get_data (void *var,
475 Filedata *filedata,
26c527e6 476 uint64_t offset,
be7d229a
AM
477 uint64_t size,
478 uint64_t nmemb,
479 const char *reason)
a6e9f9df 480{
2cf0635d 481 void * mvar;
be7d229a 482 uint64_t amt = size * nmemb;
a6e9f9df 483
c256ffe7 484 if (size == 0 || nmemb == 0)
a6e9f9df
AM
485 return NULL;
486
be7d229a
AM
487 /* If size_t is smaller than uint64_t, eg because you are building
488 on a 32-bit host, then make sure that when the sizes are cast to
489 size_t no information is lost. */
7c1c1904
AM
490 if ((size_t) size != size
491 || (size_t) nmemb != nmemb
be7d229a
AM
492 || (size_t) amt != amt
493 || amt / size != nmemb
494 || (size_t) amt + 1 == 0)
57028622
NC
495 {
496 if (reason)
b8281767
AM
497 error (_("Size overflow prevents reading %" PRIu64
498 " elements of size %" PRIu64 " for %s\n"),
be7d229a 499 nmemb, size, reason);
57028622
NC
500 return NULL;
501 }
502
c22b42ce 503 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 504 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
505 if (filedata->archive_file_offset > filedata->file_size
506 || offset > filedata->file_size - filedata->archive_file_offset
507 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 508 {
049b0c3a 509 if (reason)
b8281767 510 error (_("Reading %" PRIu64 " bytes extends past end of file for %s\n"),
be7d229a 511 amt, reason);
a6e9f9df
AM
512 return NULL;
513 }
514
63cf857e
AM
515 if (fseek64 (filedata->handle, filedata->archive_file_offset + offset,
516 SEEK_SET))
071436c6
NC
517 {
518 if (reason)
26c527e6 519 error (_("Unable to seek to %#" PRIx64 " for %s\n"),
978c4450 520 filedata->archive_file_offset + offset, reason);
071436c6
NC
521 return NULL;
522 }
523
a6e9f9df
AM
524 mvar = var;
525 if (mvar == NULL)
526 {
7c1c1904
AM
527 /* + 1 so that we can '\0' terminate invalid string table sections. */
528 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
529
530 if (mvar == NULL)
531 {
049b0c3a 532 if (reason)
b8281767 533 error (_("Out of memory allocating %" PRIu64 " bytes for %s\n"),
be7d229a 534 amt, reason);
a6e9f9df
AM
535 return NULL;
536 }
c256ffe7 537
c9c1d674 538 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
539 }
540
dda8d76d 541 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 542 {
049b0c3a 543 if (reason)
b8281767 544 error (_("Unable to read in %" PRIu64 " bytes of %s\n"),
be7d229a 545 amt, reason);
a6e9f9df
AM
546 if (mvar != var)
547 free (mvar);
548 return NULL;
549 }
550
551 return mvar;
552}
553
32ec8896
NC
554/* Print a VMA value in the MODE specified.
555 Returns the number of characters displayed. */
cb8f3167 556
32ec8896 557static unsigned int
625d49fc 558print_vma (uint64_t vma, print_mode mode)
66543521 559{
32ec8896 560 unsigned int nc = 0;
66543521 561
14a91970 562 switch (mode)
66543521 563 {
14a91970
AM
564 case FULL_HEX:
565 nc = printf ("0x");
1a0670f3 566 /* Fall through. */
14a91970 567 case LONG_HEX:
f493c217 568 if (!is_32bit_elf)
625d49fc
AM
569 return nc + printf ("%16.16" PRIx64, vma);
570 return nc + printf ("%8.8" PRIx64, vma);
b19aac67 571
14a91970
AM
572 case DEC_5:
573 if (vma <= 99999)
625d49fc 574 return printf ("%5" PRId64, vma);
1a0670f3 575 /* Fall through. */
14a91970
AM
576 case PREFIX_HEX:
577 nc = printf ("0x");
1a0670f3 578 /* Fall through. */
14a91970 579 case HEX:
625d49fc 580 return nc + printf ("%" PRIx64, vma);
b19aac67 581
047c3dbf
NL
582 case PREFIX_HEX_5:
583 nc = printf ("0x");
584 /* Fall through. */
585 case HEX_5:
625d49fc 586 return nc + printf ("%05" PRIx64, vma);
047c3dbf 587
14a91970 588 case DEC:
625d49fc 589 return printf ("%" PRId64, vma);
b19aac67 590
14a91970 591 case UNSIGNED:
625d49fc 592 return printf ("%" PRIu64, vma);
32ec8896 593
047c3dbf 594 case UNSIGNED_5:
625d49fc 595 return printf ("%5" PRIu64, vma);
047c3dbf
NL
596
597 case OCTAL:
625d49fc 598 return printf ("%" PRIo64, vma);
047c3dbf
NL
599
600 case OCTAL_5:
625d49fc 601 return printf ("%5" PRIo64, vma);
047c3dbf 602
32ec8896
NC
603 default:
604 /* FIXME: Report unrecognised mode ? */
605 return 0;
f7a99963 606 }
f7a99963
NC
607}
608
047c3dbf 609
7bfd842d 610/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 611 multibye characters (assuming the host environment supports them).
31104126 612
7bfd842d
NC
613 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
614
0942c7ab
NC
615 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
616 abs(WIDTH) - 5 characters followed by "[...]".
617
7bfd842d
NC
618 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
619 padding as necessary.
171191ba
NC
620
621 Returns the number of emitted characters. */
622
623static unsigned int
0942c7ab 624print_symbol (signed int width, const char * symbol)
31104126 625{
015dc7e1
AM
626 bool extra_padding = false;
627 bool do_dots = false;
32ec8896 628 signed int num_printed = 0;
3bfcb652 629#ifdef HAVE_MBSTATE_T
7bfd842d 630 mbstate_t state;
3bfcb652 631#endif
32ec8896 632 unsigned int width_remaining;
79bc120c 633 const void * alloced_symbol = NULL;
961c521f 634
7bfd842d 635 if (width < 0)
961c521f 636 {
88305e1b 637 /* Keep the width positive. This helps the code below. */
961c521f 638 width = - width;
015dc7e1 639 extra_padding = true;
0b4362b0 640 }
56d8f8a9
NC
641 else if (width == 0)
642 return 0;
961c521f 643
7bfd842d
NC
644 if (do_wide)
645 /* Set the remaining width to a very large value.
646 This simplifies the code below. */
647 width_remaining = INT_MAX;
648 else
0942c7ab
NC
649 {
650 width_remaining = width;
651 if (! do_not_show_symbol_truncation
652 && (int) strlen (symbol) > width)
653 {
654 width_remaining -= 5;
655 if ((int) width_remaining < 0)
656 width_remaining = 0;
015dc7e1 657 do_dots = true;
0942c7ab
NC
658 }
659 }
cb8f3167 660
3bfcb652 661#ifdef HAVE_MBSTATE_T
7bfd842d
NC
662 /* Initialise the multibyte conversion state. */
663 memset (& state, 0, sizeof (state));
3bfcb652 664#endif
961c521f 665
79bc120c
NC
666 if (do_demangle && *symbol)
667 {
668 const char * res = cplus_demangle (symbol, demangle_flags);
669
670 if (res != NULL)
671 alloced_symbol = symbol = res;
672 }
673
7bfd842d
NC
674 while (width_remaining)
675 {
676 size_t n;
7bfd842d 677 const char c = *symbol++;
961c521f 678
7bfd842d 679 if (c == 0)
961c521f
NC
680 break;
681
b3aa80b4
NC
682 if (ISPRINT (c))
683 {
684 putchar (c);
685 width_remaining --;
686 num_printed ++;
687 }
688 else if (ISCNTRL (c))
961c521f 689 {
b3aa80b4
NC
690 /* Do not print control characters directly as they can affect terminal
691 settings. Such characters usually appear in the names generated
692 by the assembler for local labels. */
693
7bfd842d 694 if (width_remaining < 2)
961c521f
NC
695 break;
696
7bfd842d
NC
697 printf ("^%c", c + 0x40);
698 width_remaining -= 2;
171191ba 699 num_printed += 2;
961c521f 700 }
b3aa80b4 701 else if (c == 0x7f)
7bfd842d 702 {
b3aa80b4
NC
703 if (width_remaining < 5)
704 break;
705 printf ("<DEL>");
706 width_remaining -= 5;
707 num_printed += 5;
708 }
709 else if (unicode_display != unicode_locale
710 && unicode_display != unicode_default)
711 {
712 /* Display unicode characters as something else. */
713 unsigned char bytes[4];
714 bool is_utf8;
795588ae 715 unsigned int nbytes;
b3aa80b4
NC
716
717 bytes[0] = c;
718
719 if (bytes[0] < 0xc0)
720 {
721 nbytes = 1;
722 is_utf8 = false;
723 }
724 else
725 {
726 bytes[1] = *symbol++;
727
728 if ((bytes[1] & 0xc0) != 0x80)
729 {
730 is_utf8 = false;
731 /* Do not consume this character. It may only
732 be the first byte in the sequence that was
733 corrupt. */
734 --symbol;
735 nbytes = 1;
736 }
737 else if ((bytes[0] & 0x20) == 0)
738 {
739 is_utf8 = true;
740 nbytes = 2;
741 }
742 else
743 {
744 bytes[2] = *symbol++;
745
746 if ((bytes[2] & 0xc0) != 0x80)
747 {
748 is_utf8 = false;
749 symbol -= 2;
750 nbytes = 1;
751 }
752 else if ((bytes[0] & 0x10) == 0)
753 {
754 is_utf8 = true;
755 nbytes = 3;
756 }
757 else
758 {
759 bytes[3] = *symbol++;
760
761 nbytes = 4;
762
763 if ((bytes[3] & 0xc0) != 0x80)
764 {
765 is_utf8 = false;
766 symbol -= 3;
767 nbytes = 1;
768 }
769 else
770 is_utf8 = true;
771 }
772 }
773 }
774
775 if (unicode_display == unicode_invalid)
776 is_utf8 = false;
777
778 if (unicode_display == unicode_hex || ! is_utf8)
779 {
795588ae 780 unsigned int i;
b3aa80b4
NC
781
782 if (width_remaining < (nbytes * 2) + 2)
783 break;
784
785 putchar (is_utf8 ? '<' : '{');
786 printf ("0x");
787 for (i = 0; i < nbytes; i++)
788 printf ("%02x", bytes[i]);
789 putchar (is_utf8 ? '>' : '}');
790 }
791 else
792 {
793 if (unicode_display == unicode_highlight && isatty (1))
794 printf ("\x1B[31;47m"); /* Red. */
795
796 switch (nbytes)
797 {
798 case 2:
799 if (width_remaining < 6)
800 break;
801 printf ("\\u%02x%02x",
802 (bytes[0] & 0x1c) >> 2,
803 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
804 break;
805 case 3:
806 if (width_remaining < 6)
807 break;
808 printf ("\\u%02x%02x",
809 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
810 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
811 break;
812 case 4:
813 if (width_remaining < 8)
814 break;
815 printf ("\\u%02x%02x%02x",
816 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
817 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
818 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
819
820 break;
821 default:
822 /* URG. */
823 break;
824 }
825
826 if (unicode_display == unicode_highlight && isatty (1))
827 printf ("\033[0m"); /* Default colour. */
828 }
829
830 if (bytes[nbytes - 1] == 0)
831 break;
7bfd842d 832 }
961c521f
NC
833 else
834 {
3bfcb652
NC
835#ifdef HAVE_MBSTATE_T
836 wchar_t w;
837#endif
7bfd842d
NC
838 /* Let printf do the hard work of displaying multibyte characters. */
839 printf ("%.1s", symbol - 1);
840 width_remaining --;
841 num_printed ++;
842
3bfcb652 843#ifdef HAVE_MBSTATE_T
7bfd842d
NC
844 /* Try to find out how many bytes made up the character that was
845 just printed. Advance the symbol pointer past the bytes that
846 were displayed. */
847 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
848#else
849 n = 1;
850#endif
7bfd842d
NC
851 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
852 symbol += (n - 1);
961c521f 853 }
961c521f 854 }
171191ba 855
0942c7ab
NC
856 if (do_dots)
857 num_printed += printf ("[...]");
858
7bfd842d 859 if (extra_padding && num_printed < width)
171191ba
NC
860 {
861 /* Fill in the remaining spaces. */
7bfd842d
NC
862 printf ("%-*s", width - num_printed, " ");
863 num_printed = width;
171191ba
NC
864 }
865
79bc120c 866 free ((void *) alloced_symbol);
171191ba 867 return num_printed;
31104126
NC
868}
869
1449284b 870/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
871 the given section's name. Like print_symbol, except that it does not try
872 to print multibyte characters, it just interprets them as hex values. */
873
874static const char *
dda8d76d 875printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 876{
ca0e11aa 877#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 878 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
84714f86 879 const char * name = section_name_print (filedata, sec);
74e1a04b
NC
880 char * buf = sec_name_buf;
881 char c;
882 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
883
884 while ((c = * name ++) != 0)
885 {
886 if (ISCNTRL (c))
887 {
888 if (remaining < 2)
889 break;
948f632f 890
74e1a04b
NC
891 * buf ++ = '^';
892 * buf ++ = c + 0x40;
893 remaining -= 2;
894 }
895 else if (ISPRINT (c))
896 {
897 * buf ++ = c;
898 remaining -= 1;
899 }
900 else
901 {
902 static char hex[17] = "0123456789ABCDEF";
903
904 if (remaining < 4)
905 break;
906 * buf ++ = '<';
907 * buf ++ = hex[(c & 0xf0) >> 4];
908 * buf ++ = hex[c & 0x0f];
909 * buf ++ = '>';
910 remaining -= 4;
911 }
912
913 if (remaining == 0)
914 break;
915 }
916
917 * buf = 0;
918 return sec_name_buf;
919}
920
921static const char *
26c527e6 922printable_section_name_from_index (Filedata *filedata, size_t ndx)
74e1a04b 923{
dda8d76d 924 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
925 return _("<corrupt>");
926
dda8d76d 927 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
928}
929
89fac5e3
RS
930/* Return a pointer to section NAME, or NULL if no such section exists. */
931
932static Elf_Internal_Shdr *
dda8d76d 933find_section (Filedata * filedata, const char * name)
89fac5e3
RS
934{
935 unsigned int i;
936
68807c3c
NC
937 if (filedata->section_headers == NULL)
938 return NULL;
dda8d76d
NC
939
940 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
941 if (section_name_valid (filedata, filedata->section_headers + i)
942 && streq (section_name (filedata, filedata->section_headers + i),
943 name))
dda8d76d 944 return filedata->section_headers + i;
89fac5e3
RS
945
946 return NULL;
947}
948
0b6ae522
DJ
949/* Return a pointer to a section containing ADDR, or NULL if no such
950 section exists. */
951
952static Elf_Internal_Shdr *
625d49fc 953find_section_by_address (Filedata * filedata, uint64_t addr)
0b6ae522
DJ
954{
955 unsigned int i;
956
68807c3c
NC
957 if (filedata->section_headers == NULL)
958 return NULL;
959
dda8d76d 960 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 961 {
dda8d76d
NC
962 Elf_Internal_Shdr *sec = filedata->section_headers + i;
963
0b6ae522
DJ
964 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
965 return sec;
966 }
967
968 return NULL;
969}
970
071436c6 971static Elf_Internal_Shdr *
dda8d76d 972find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
973{
974 unsigned int i;
975
68807c3c
NC
976 if (filedata->section_headers == NULL)
977 return NULL;
978
dda8d76d 979 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 980 {
dda8d76d
NC
981 Elf_Internal_Shdr *sec = filedata->section_headers + i;
982
071436c6
NC
983 if (sec->sh_type == type)
984 return sec;
985 }
986
987 return NULL;
988}
989
657d0d47
CC
990/* Return a pointer to section NAME, or NULL if no such section exists,
991 restricted to the list of sections given in SET. */
992
993static Elf_Internal_Shdr *
dda8d76d 994find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
995{
996 unsigned int i;
997
68807c3c
NC
998 if (filedata->section_headers == NULL)
999 return NULL;
1000
657d0d47
CC
1001 if (set != NULL)
1002 {
1003 while ((i = *set++) > 0)
b814a36d
NC
1004 {
1005 /* See PR 21156 for a reproducer. */
dda8d76d 1006 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
1007 continue; /* FIXME: Should we issue an error message ? */
1008
84714f86
AM
1009 if (section_name_valid (filedata, filedata->section_headers + i)
1010 && streq (section_name (filedata, filedata->section_headers + i),
1011 name))
dda8d76d 1012 return filedata->section_headers + i;
b814a36d 1013 }
657d0d47
CC
1014 }
1015
dda8d76d 1016 return find_section (filedata, name);
657d0d47
CC
1017}
1018
32ec8896 1019/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
1020 This OS has so many departures from the ELF standard that we test it at
1021 many places. */
1022
015dc7e1 1023static inline bool
dda8d76d 1024is_ia64_vms (Filedata * filedata)
28f997cf 1025{
dda8d76d
NC
1026 return filedata->file_header.e_machine == EM_IA_64
1027 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
1028}
1029
bcedfee6 1030/* Guess the relocation size commonly used by the specific machines. */
252b5132 1031
015dc7e1 1032static bool
2dc4cec1 1033guess_is_rela (unsigned int e_machine)
252b5132 1034{
9c19a809 1035 switch (e_machine)
252b5132
RH
1036 {
1037 /* Targets that use REL relocations. */
252b5132 1038 case EM_386:
22abe556 1039 case EM_IAMCU:
f954747f 1040 case EM_960:
e9f53129 1041 case EM_ARM:
2b0337b0 1042 case EM_D10V:
252b5132 1043 case EM_CYGNUS_D10V:
e9f53129 1044 case EM_DLX:
252b5132 1045 case EM_MIPS:
4fe85591 1046 case EM_MIPS_RS3_LE:
e9f53129 1047 case EM_CYGNUS_M32R:
1c0d3aa6 1048 case EM_SCORE:
f6c1a2d5 1049 case EM_XGATE:
fe944acf 1050 case EM_NFP:
aca4efc7 1051 case EM_BPF:
015dc7e1 1052 return false;
103f02d3 1053
252b5132
RH
1054 /* Targets that use RELA relocations. */
1055 case EM_68K:
f954747f 1056 case EM_860:
a06ea964 1057 case EM_AARCH64:
cfb8c092 1058 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1059 case EM_ALPHA:
1060 case EM_ALTERA_NIOS2:
886a2506
NC
1061 case EM_ARC:
1062 case EM_ARC_COMPACT:
1063 case EM_ARC_COMPACT2:
e9f53129
AM
1064 case EM_AVR:
1065 case EM_AVR_OLD:
1066 case EM_BLACKFIN:
60bca95a 1067 case EM_CR16:
e9f53129
AM
1068 case EM_CRIS:
1069 case EM_CRX:
b8891f8d 1070 case EM_CSKY:
2b0337b0 1071 case EM_D30V:
252b5132 1072 case EM_CYGNUS_D30V:
2b0337b0 1073 case EM_FR30:
3f8107ab 1074 case EM_FT32:
252b5132 1075 case EM_CYGNUS_FR30:
5c70f934 1076 case EM_CYGNUS_FRV:
e9f53129
AM
1077 case EM_H8S:
1078 case EM_H8_300:
1079 case EM_H8_300H:
800eeca4 1080 case EM_IA_64:
1e4cf259
NC
1081 case EM_IP2K:
1082 case EM_IP2K_OLD:
3b36097d 1083 case EM_IQ2000:
84e94c90 1084 case EM_LATTICEMICO32:
ff7eeb89 1085 case EM_M32C_OLD:
49f58d10 1086 case EM_M32C:
e9f53129
AM
1087 case EM_M32R:
1088 case EM_MCORE:
15ab5209 1089 case EM_CYGNUS_MEP:
a3c62988 1090 case EM_METAG:
e9f53129
AM
1091 case EM_MMIX:
1092 case EM_MN10200:
1093 case EM_CYGNUS_MN10200:
1094 case EM_MN10300:
1095 case EM_CYGNUS_MN10300:
5506d11a 1096 case EM_MOXIE:
e9f53129
AM
1097 case EM_MSP430:
1098 case EM_MSP430_OLD:
d031aafb 1099 case EM_MT:
35c08157 1100 case EM_NDS32:
64fd6348 1101 case EM_NIOS32:
73589c9d 1102 case EM_OR1K:
e9f53129
AM
1103 case EM_PPC64:
1104 case EM_PPC:
2b100bb5 1105 case EM_TI_PRU:
e23eba97 1106 case EM_RISCV:
99c513f6 1107 case EM_RL78:
c7927a3c 1108 case EM_RX:
e9f53129
AM
1109 case EM_S390:
1110 case EM_S390_OLD:
1111 case EM_SH:
1112 case EM_SPARC:
1113 case EM_SPARC32PLUS:
1114 case EM_SPARCV9:
1115 case EM_SPU:
40b36596 1116 case EM_TI_C6000:
aa137e4d
NC
1117 case EM_TILEGX:
1118 case EM_TILEPRO:
708e2187 1119 case EM_V800:
e9f53129
AM
1120 case EM_V850:
1121 case EM_CYGNUS_V850:
1122 case EM_VAX:
619ed720 1123 case EM_VISIUM:
e9f53129 1124 case EM_X86_64:
8a9036a4 1125 case EM_L1OM:
7a9068fe 1126 case EM_K1OM:
e9f53129
AM
1127 case EM_XSTORMY16:
1128 case EM_XTENSA:
1129 case EM_XTENSA_OLD:
7ba29e2a
NC
1130 case EM_MICROBLAZE:
1131 case EM_MICROBLAZE_OLD:
f96bd6c2 1132 case EM_WEBASSEMBLY:
015dc7e1 1133 return true;
103f02d3 1134
e9f53129
AM
1135 case EM_68HC05:
1136 case EM_68HC08:
1137 case EM_68HC11:
1138 case EM_68HC16:
1139 case EM_FX66:
1140 case EM_ME16:
d1133906 1141 case EM_MMA:
d1133906
NC
1142 case EM_NCPU:
1143 case EM_NDR1:
e9f53129 1144 case EM_PCP:
d1133906 1145 case EM_ST100:
e9f53129 1146 case EM_ST19:
d1133906 1147 case EM_ST7:
e9f53129
AM
1148 case EM_ST9PLUS:
1149 case EM_STARCORE:
d1133906 1150 case EM_SVX:
e9f53129 1151 case EM_TINYJ:
9c19a809
NC
1152 default:
1153 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1154 return false;
9c19a809
NC
1155 }
1156}
252b5132 1157
dda8d76d 1158/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1159 Returns TRUE upon success, FALSE otherwise. If successful then a
1160 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1161 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1162 responsibility to free the allocated buffer. */
1163
015dc7e1 1164static bool
26c527e6
AM
1165slurp_rela_relocs (Filedata *filedata,
1166 uint64_t rel_offset,
1167 uint64_t rel_size,
1168 Elf_Internal_Rela **relasp,
1169 uint64_t *nrelasp)
9c19a809 1170{
2cf0635d 1171 Elf_Internal_Rela * relas;
26c527e6 1172 uint64_t nrelas;
4d6ed7c8 1173 unsigned int i;
252b5132 1174
4d6ed7c8
NC
1175 if (is_32bit_elf)
1176 {
2cf0635d 1177 Elf32_External_Rela * erelas;
103f02d3 1178
dda8d76d 1179 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1180 rel_size, _("32-bit relocation data"));
a6e9f9df 1181 if (!erelas)
015dc7e1 1182 return false;
252b5132 1183
4d6ed7c8 1184 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1185
3f5e193b
NC
1186 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1187 sizeof (Elf_Internal_Rela));
103f02d3 1188
4d6ed7c8
NC
1189 if (relas == NULL)
1190 {
c256ffe7 1191 free (erelas);
591a748a 1192 error (_("out of memory parsing relocs\n"));
015dc7e1 1193 return false;
4d6ed7c8 1194 }
103f02d3 1195
4d6ed7c8
NC
1196 for (i = 0; i < nrelas; i++)
1197 {
1198 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1199 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1200 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1201 }
103f02d3 1202
4d6ed7c8
NC
1203 free (erelas);
1204 }
1205 else
1206 {
2cf0635d 1207 Elf64_External_Rela * erelas;
103f02d3 1208
dda8d76d 1209 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1210 rel_size, _("64-bit relocation data"));
a6e9f9df 1211 if (!erelas)
015dc7e1 1212 return false;
4d6ed7c8
NC
1213
1214 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1215
3f5e193b
NC
1216 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1217 sizeof (Elf_Internal_Rela));
103f02d3 1218
4d6ed7c8
NC
1219 if (relas == NULL)
1220 {
c256ffe7 1221 free (erelas);
591a748a 1222 error (_("out of memory parsing relocs\n"));
015dc7e1 1223 return false;
9c19a809 1224 }
4d6ed7c8
NC
1225
1226 for (i = 0; i < nrelas; i++)
9c19a809 1227 {
66543521
AM
1228 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1229 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1230 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a 1231
dda8d76d
NC
1232 if (filedata->file_header.e_machine == EM_MIPS
1233 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1234 {
1235 /* In little-endian objects, r_info isn't really a
1236 64-bit little-endian value: it has a 32-bit
1237 little-endian symbol index followed by four
1238 individual byte fields. Reorder INFO
1239 accordingly. */
625d49fc 1240 uint64_t inf = relas[i].r_info;
91d6fa6a
NC
1241 inf = (((inf & 0xffffffff) << 32)
1242 | ((inf >> 56) & 0xff)
1243 | ((inf >> 40) & 0xff00)
1244 | ((inf >> 24) & 0xff0000)
1245 | ((inf >> 8) & 0xff000000));
1246 relas[i].r_info = inf;
861fb55a 1247 }
4d6ed7c8 1248 }
103f02d3 1249
4d6ed7c8
NC
1250 free (erelas);
1251 }
32ec8896 1252
4d6ed7c8
NC
1253 *relasp = relas;
1254 *nrelasp = nrelas;
015dc7e1 1255 return true;
4d6ed7c8 1256}
103f02d3 1257
dda8d76d 1258/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1259 Returns TRUE upon success, FALSE otherwise. If successful then a
1260 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1261 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1262 responsibility to free the allocated buffer. */
1263
015dc7e1 1264static bool
26c527e6
AM
1265slurp_rel_relocs (Filedata *filedata,
1266 uint64_t rel_offset,
1267 uint64_t rel_size,
1268 Elf_Internal_Rela **relsp,
1269 uint64_t *nrelsp)
4d6ed7c8 1270{
2cf0635d 1271 Elf_Internal_Rela * rels;
26c527e6 1272 uint64_t nrels;
4d6ed7c8 1273 unsigned int i;
103f02d3 1274
4d6ed7c8
NC
1275 if (is_32bit_elf)
1276 {
2cf0635d 1277 Elf32_External_Rel * erels;
103f02d3 1278
dda8d76d 1279 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1280 rel_size, _("32-bit relocation data"));
a6e9f9df 1281 if (!erels)
015dc7e1 1282 return false;
103f02d3 1283
4d6ed7c8 1284 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1285
3f5e193b 1286 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1287
4d6ed7c8
NC
1288 if (rels == NULL)
1289 {
c256ffe7 1290 free (erels);
591a748a 1291 error (_("out of memory parsing relocs\n"));
015dc7e1 1292 return false;
4d6ed7c8
NC
1293 }
1294
1295 for (i = 0; i < nrels; i++)
1296 {
1297 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1298 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1299 rels[i].r_addend = 0;
9ea033b2 1300 }
4d6ed7c8
NC
1301
1302 free (erels);
9c19a809
NC
1303 }
1304 else
1305 {
2cf0635d 1306 Elf64_External_Rel * erels;
9ea033b2 1307
dda8d76d 1308 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1309 rel_size, _("64-bit relocation data"));
a6e9f9df 1310 if (!erels)
015dc7e1 1311 return false;
103f02d3 1312
4d6ed7c8 1313 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1314
3f5e193b 1315 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1316
4d6ed7c8 1317 if (rels == NULL)
9c19a809 1318 {
c256ffe7 1319 free (erels);
591a748a 1320 error (_("out of memory parsing relocs\n"));
015dc7e1 1321 return false;
4d6ed7c8 1322 }
103f02d3 1323
4d6ed7c8
NC
1324 for (i = 0; i < nrels; i++)
1325 {
66543521
AM
1326 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1327 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1328 rels[i].r_addend = 0;
861fb55a 1329
dda8d76d
NC
1330 if (filedata->file_header.e_machine == EM_MIPS
1331 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1332 {
1333 /* In little-endian objects, r_info isn't really a
1334 64-bit little-endian value: it has a 32-bit
1335 little-endian symbol index followed by four
1336 individual byte fields. Reorder INFO
1337 accordingly. */
625d49fc 1338 uint64_t inf = rels[i].r_info;
91d6fa6a
NC
1339 inf = (((inf & 0xffffffff) << 32)
1340 | ((inf >> 56) & 0xff)
1341 | ((inf >> 40) & 0xff00)
1342 | ((inf >> 24) & 0xff0000)
1343 | ((inf >> 8) & 0xff000000));
1344 rels[i].r_info = inf;
861fb55a 1345 }
4d6ed7c8 1346 }
103f02d3 1347
4d6ed7c8
NC
1348 free (erels);
1349 }
32ec8896 1350
4d6ed7c8
NC
1351 *relsp = rels;
1352 *nrelsp = nrels;
015dc7e1 1353 return true;
4d6ed7c8 1354}
103f02d3 1355
a7fd1186 1356static bool
26c527e6
AM
1357slurp_relr_relocs (Filedata *filedata,
1358 uint64_t relr_offset,
1359 uint64_t relr_size,
1360 uint64_t **relrsp,
1361 uint64_t *nrelrsp)
a7fd1186
FS
1362{
1363 void *relrs;
1364 size_t size = 0, nentries, i;
625d49fc 1365 uint64_t base = 0, addr, entry;
a7fd1186
FS
1366
1367 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1368 _("RELR relocation data"));
1369 if (!relrs)
1370 return false;
1371
1372 if (is_32bit_elf)
1373 nentries = relr_size / sizeof (Elf32_External_Relr);
1374 else
1375 nentries = relr_size / sizeof (Elf64_External_Relr);
1376 for (i = 0; i < nentries; i++)
1377 {
1378 if (is_32bit_elf)
1379 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1380 else
1381 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1382 if ((entry & 1) == 0)
1383 size++;
1384 else
1385 while ((entry >>= 1) != 0)
1386 if ((entry & 1) == 1)
1387 size++;
1388 }
1389
625d49fc 1390 *relrsp = malloc (size * sizeof (**relrsp));
a7fd1186
FS
1391 if (*relrsp == NULL)
1392 {
1393 free (relrs);
1394 error (_("out of memory parsing relocs\n"));
1395 return false;
1396 }
1397
1398 size = 0;
1399 for (i = 0; i < nentries; i++)
1400 {
625d49fc 1401 const uint64_t entry_bytes = is_32bit_elf ? 4 : 8;
a7fd1186
FS
1402
1403 if (is_32bit_elf)
1404 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1405 else
1406 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1407 if ((entry & 1) == 0)
1408 {
1409 (*relrsp)[size++] = entry;
1410 base = entry + entry_bytes;
1411 }
1412 else
1413 {
1414 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1415 if ((entry & 1) != 0)
1416 (*relrsp)[size++] = addr;
1417 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1418 }
1419 }
1420
1421 *nrelrsp = size;
1422 free (relrs);
1423 return true;
1424}
1425
aca88567
NC
1426/* Returns the reloc type extracted from the reloc info field. */
1427
1428static unsigned int
625d49fc 1429get_reloc_type (Filedata * filedata, uint64_t reloc_info)
aca88567
NC
1430{
1431 if (is_32bit_elf)
1432 return ELF32_R_TYPE (reloc_info);
1433
dda8d76d 1434 switch (filedata->file_header.e_machine)
aca88567
NC
1435 {
1436 case EM_MIPS:
1437 /* Note: We assume that reloc_info has already been adjusted for us. */
1438 return ELF64_MIPS_R_TYPE (reloc_info);
1439
1440 case EM_SPARCV9:
1441 return ELF64_R_TYPE_ID (reloc_info);
1442
1443 default:
1444 return ELF64_R_TYPE (reloc_info);
1445 }
1446}
1447
1448/* Return the symbol index extracted from the reloc info field. */
1449
625d49fc
AM
1450static uint64_t
1451get_reloc_symindex (uint64_t reloc_info)
aca88567
NC
1452{
1453 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1454}
1455
015dc7e1 1456static inline bool
dda8d76d 1457uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1458{
1459 return
dda8d76d 1460 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1461 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1462 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1463 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1464 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1465}
1466
d3ba0551
AM
1467/* Display the contents of the relocation data found at the specified
1468 offset. */
ee42cf8c 1469
015dc7e1 1470static bool
26c527e6
AM
1471dump_relocations (Filedata *filedata,
1472 uint64_t rel_offset,
1473 uint64_t rel_size,
1474 Elf_Internal_Sym *symtab,
1475 uint64_t nsyms,
1476 char *strtab,
1477 uint64_t strtablen,
1478 relocation_type rel_type,
1479 bool is_dynsym)
1480{
1481 size_t i;
2cf0635d 1482 Elf_Internal_Rela * rels;
015dc7e1 1483 bool res = true;
103f02d3 1484
a7fd1186
FS
1485 if (rel_type == reltype_unknown)
1486 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1487
a7fd1186 1488 if (rel_type == reltype_rela)
4d6ed7c8 1489 {
dda8d76d 1490 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1491 return false;
4d6ed7c8 1492 }
a7fd1186 1493 else if (rel_type == reltype_rel)
4d6ed7c8 1494 {
dda8d76d 1495 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1496 return false;
252b5132 1497 }
a7fd1186
FS
1498 else if (rel_type == reltype_relr)
1499 {
625d49fc 1500 uint64_t * relrs;
a7fd1186 1501 const char *format
b8281767 1502 = is_32bit_elf ? "%08" PRIx64 "\n" : "%016" PRIx64 "\n";
a7fd1186
FS
1503
1504 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1505 &rel_size))
1506 return false;
1507
26c527e6
AM
1508 printf (ngettext (" %" PRIu64 " offset\n",
1509 " %" PRIu64 " offsets\n", rel_size),
b8281767 1510 rel_size);
a7fd1186 1511 for (i = 0; i < rel_size; i++)
625d49fc 1512 printf (format, relrs[i]);
a7fd1186
FS
1513 free (relrs);
1514 return true;
1515 }
252b5132 1516
410f7a12
L
1517 if (is_32bit_elf)
1518 {
a7fd1186 1519 if (rel_type == reltype_rela)
2c71103e
NC
1520 {
1521 if (do_wide)
1522 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1523 else
1524 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1525 }
410f7a12 1526 else
2c71103e
NC
1527 {
1528 if (do_wide)
1529 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1530 else
1531 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1532 }
410f7a12 1533 }
252b5132 1534 else
410f7a12 1535 {
a7fd1186 1536 if (rel_type == reltype_rela)
2c71103e
NC
1537 {
1538 if (do_wide)
8beeaeb7 1539 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1540 else
1541 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1542 }
410f7a12 1543 else
2c71103e
NC
1544 {
1545 if (do_wide)
8beeaeb7 1546 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1547 else
1548 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1549 }
410f7a12 1550 }
252b5132
RH
1551
1552 for (i = 0; i < rel_size; i++)
1553 {
2cf0635d 1554 const char * rtype;
625d49fc
AM
1555 uint64_t offset;
1556 uint64_t inf;
1557 uint64_t symtab_index;
1558 uint64_t type;
103f02d3 1559
b34976b6 1560 offset = rels[i].r_offset;
91d6fa6a 1561 inf = rels[i].r_info;
103f02d3 1562
dda8d76d 1563 type = get_reloc_type (filedata, inf);
91d6fa6a 1564 symtab_index = get_reloc_symindex (inf);
252b5132 1565
410f7a12
L
1566 if (is_32bit_elf)
1567 {
39dbeff8
AM
1568 printf ("%8.8lx %8.8lx ",
1569 (unsigned long) offset & 0xffffffff,
91d6fa6a 1570 (unsigned long) inf & 0xffffffff);
410f7a12
L
1571 }
1572 else
1573 {
39dbeff8 1574 printf (do_wide
b8281767
AM
1575 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
1576 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
625d49fc 1577 offset, inf);
410f7a12 1578 }
103f02d3 1579
dda8d76d 1580 switch (filedata->file_header.e_machine)
252b5132
RH
1581 {
1582 default:
1583 rtype = NULL;
1584 break;
1585
a06ea964
NC
1586 case EM_AARCH64:
1587 rtype = elf_aarch64_reloc_type (type);
1588 break;
1589
2b0337b0 1590 case EM_M32R:
252b5132 1591 case EM_CYGNUS_M32R:
9ea033b2 1592 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1593 break;
1594
1595 case EM_386:
22abe556 1596 case EM_IAMCU:
9ea033b2 1597 rtype = elf_i386_reloc_type (type);
252b5132
RH
1598 break;
1599
ba2685cc
AM
1600 case EM_68HC11:
1601 case EM_68HC12:
1602 rtype = elf_m68hc11_reloc_type (type);
1603 break;
75751cd9 1604
7b4ae824
JD
1605 case EM_S12Z:
1606 rtype = elf_s12z_reloc_type (type);
1607 break;
1608
252b5132 1609 case EM_68K:
9ea033b2 1610 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1611 break;
1612
f954747f
AM
1613 case EM_960:
1614 rtype = elf_i960_reloc_type (type);
1615 break;
1616
adde6300 1617 case EM_AVR:
2b0337b0 1618 case EM_AVR_OLD:
adde6300
AM
1619 rtype = elf_avr_reloc_type (type);
1620 break;
1621
9ea033b2
NC
1622 case EM_OLD_SPARCV9:
1623 case EM_SPARC32PLUS:
1624 case EM_SPARCV9:
252b5132 1625 case EM_SPARC:
9ea033b2 1626 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1627 break;
1628
e9f53129
AM
1629 case EM_SPU:
1630 rtype = elf_spu_reloc_type (type);
1631 break;
1632
708e2187
NC
1633 case EM_V800:
1634 rtype = v800_reloc_type (type);
1635 break;
2b0337b0 1636 case EM_V850:
252b5132 1637 case EM_CYGNUS_V850:
9ea033b2 1638 rtype = v850_reloc_type (type);
252b5132
RH
1639 break;
1640
2b0337b0 1641 case EM_D10V:
252b5132 1642 case EM_CYGNUS_D10V:
9ea033b2 1643 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1644 break;
1645
2b0337b0 1646 case EM_D30V:
252b5132 1647 case EM_CYGNUS_D30V:
9ea033b2 1648 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1649 break;
1650
d172d4ba
NC
1651 case EM_DLX:
1652 rtype = elf_dlx_reloc_type (type);
1653 break;
1654
252b5132 1655 case EM_SH:
9ea033b2 1656 rtype = elf_sh_reloc_type (type);
252b5132
RH
1657 break;
1658
2b0337b0 1659 case EM_MN10300:
252b5132 1660 case EM_CYGNUS_MN10300:
9ea033b2 1661 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1662 break;
1663
2b0337b0 1664 case EM_MN10200:
252b5132 1665 case EM_CYGNUS_MN10200:
9ea033b2 1666 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1667 break;
1668
2b0337b0 1669 case EM_FR30:
252b5132 1670 case EM_CYGNUS_FR30:
9ea033b2 1671 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1672 break;
1673
ba2685cc
AM
1674 case EM_CYGNUS_FRV:
1675 rtype = elf_frv_reloc_type (type);
1676 break;
5c70f934 1677
b8891f8d
AJ
1678 case EM_CSKY:
1679 rtype = elf_csky_reloc_type (type);
1680 break;
1681
3f8107ab
AM
1682 case EM_FT32:
1683 rtype = elf_ft32_reloc_type (type);
1684 break;
1685
252b5132 1686 case EM_MCORE:
9ea033b2 1687 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1688 break;
1689
3c3bdf30
NC
1690 case EM_MMIX:
1691 rtype = elf_mmix_reloc_type (type);
1692 break;
1693
5506d11a
AM
1694 case EM_MOXIE:
1695 rtype = elf_moxie_reloc_type (type);
1696 break;
1697
2469cfa2 1698 case EM_MSP430:
dda8d76d 1699 if (uses_msp430x_relocs (filedata))
13761a11
NC
1700 {
1701 rtype = elf_msp430x_reloc_type (type);
1702 break;
1703 }
1a0670f3 1704 /* Fall through. */
2469cfa2
NC
1705 case EM_MSP430_OLD:
1706 rtype = elf_msp430_reloc_type (type);
1707 break;
1708
35c08157
KLC
1709 case EM_NDS32:
1710 rtype = elf_nds32_reloc_type (type);
1711 break;
1712
252b5132 1713 case EM_PPC:
9ea033b2 1714 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1715 break;
1716
c833c019
AM
1717 case EM_PPC64:
1718 rtype = elf_ppc64_reloc_type (type);
1719 break;
1720
252b5132 1721 case EM_MIPS:
4fe85591 1722 case EM_MIPS_RS3_LE:
9ea033b2 1723 rtype = elf_mips_reloc_type (type);
252b5132
RH
1724 break;
1725
e23eba97
NC
1726 case EM_RISCV:
1727 rtype = elf_riscv_reloc_type (type);
1728 break;
1729
252b5132 1730 case EM_ALPHA:
9ea033b2 1731 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1732 break;
1733
1734 case EM_ARM:
9ea033b2 1735 rtype = elf_arm_reloc_type (type);
252b5132
RH
1736 break;
1737
584da044 1738 case EM_ARC:
886a2506
NC
1739 case EM_ARC_COMPACT:
1740 case EM_ARC_COMPACT2:
9ea033b2 1741 rtype = elf_arc_reloc_type (type);
252b5132
RH
1742 break;
1743
1744 case EM_PARISC:
69e617ca 1745 rtype = elf_hppa_reloc_type (type);
252b5132 1746 break;
7d466069 1747
b8720f9d
JL
1748 case EM_H8_300:
1749 case EM_H8_300H:
1750 case EM_H8S:
1751 rtype = elf_h8_reloc_type (type);
1752 break;
1753
73589c9d
CS
1754 case EM_OR1K:
1755 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1756 break;
1757
7d466069 1758 case EM_PJ:
2b0337b0 1759 case EM_PJ_OLD:
7d466069
ILT
1760 rtype = elf_pj_reloc_type (type);
1761 break;
800eeca4
JW
1762 case EM_IA_64:
1763 rtype = elf_ia64_reloc_type (type);
1764 break;
1b61cf92
HPN
1765
1766 case EM_CRIS:
1767 rtype = elf_cris_reloc_type (type);
1768 break;
535c37ff 1769
f954747f
AM
1770 case EM_860:
1771 rtype = elf_i860_reloc_type (type);
1772 break;
1773
bcedfee6 1774 case EM_X86_64:
8a9036a4 1775 case EM_L1OM:
7a9068fe 1776 case EM_K1OM:
bcedfee6
NC
1777 rtype = elf_x86_64_reloc_type (type);
1778 break;
a85d7ed0 1779
f954747f
AM
1780 case EM_S370:
1781 rtype = i370_reloc_type (type);
1782 break;
1783
53c7db4b
KH
1784 case EM_S390_OLD:
1785 case EM_S390:
1786 rtype = elf_s390_reloc_type (type);
1787 break;
93fbbb04 1788
1c0d3aa6
NC
1789 case EM_SCORE:
1790 rtype = elf_score_reloc_type (type);
1791 break;
1792
93fbbb04
GK
1793 case EM_XSTORMY16:
1794 rtype = elf_xstormy16_reloc_type (type);
1795 break;
179d3252 1796
1fe1f39c
NC
1797 case EM_CRX:
1798 rtype = elf_crx_reloc_type (type);
1799 break;
1800
179d3252
JT
1801 case EM_VAX:
1802 rtype = elf_vax_reloc_type (type);
1803 break;
1e4cf259 1804
619ed720
EB
1805 case EM_VISIUM:
1806 rtype = elf_visium_reloc_type (type);
1807 break;
1808
aca4efc7
JM
1809 case EM_BPF:
1810 rtype = elf_bpf_reloc_type (type);
1811 break;
1812
cfb8c092
NC
1813 case EM_ADAPTEVA_EPIPHANY:
1814 rtype = elf_epiphany_reloc_type (type);
1815 break;
1816
1e4cf259
NC
1817 case EM_IP2K:
1818 case EM_IP2K_OLD:
1819 rtype = elf_ip2k_reloc_type (type);
1820 break;
3b36097d
SC
1821
1822 case EM_IQ2000:
1823 rtype = elf_iq2000_reloc_type (type);
1824 break;
88da6820
NC
1825
1826 case EM_XTENSA_OLD:
1827 case EM_XTENSA:
1828 rtype = elf_xtensa_reloc_type (type);
1829 break;
a34e3ecb 1830
84e94c90
NC
1831 case EM_LATTICEMICO32:
1832 rtype = elf_lm32_reloc_type (type);
1833 break;
1834
ff7eeb89 1835 case EM_M32C_OLD:
49f58d10
JB
1836 case EM_M32C:
1837 rtype = elf_m32c_reloc_type (type);
1838 break;
1839
d031aafb
NS
1840 case EM_MT:
1841 rtype = elf_mt_reloc_type (type);
a34e3ecb 1842 break;
1d65ded4
CM
1843
1844 case EM_BLACKFIN:
1845 rtype = elf_bfin_reloc_type (type);
1846 break;
15ab5209
DB
1847
1848 case EM_CYGNUS_MEP:
1849 rtype = elf_mep_reloc_type (type);
1850 break;
60bca95a
NC
1851
1852 case EM_CR16:
1853 rtype = elf_cr16_reloc_type (type);
1854 break;
dd24e3da 1855
7ba29e2a
NC
1856 case EM_MICROBLAZE:
1857 case EM_MICROBLAZE_OLD:
1858 rtype = elf_microblaze_reloc_type (type);
1859 break;
c7927a3c 1860
99c513f6
DD
1861 case EM_RL78:
1862 rtype = elf_rl78_reloc_type (type);
1863 break;
1864
c7927a3c
NC
1865 case EM_RX:
1866 rtype = elf_rx_reloc_type (type);
1867 break;
c29aca4a 1868
a3c62988
NC
1869 case EM_METAG:
1870 rtype = elf_metag_reloc_type (type);
1871 break;
1872
40b36596
JM
1873 case EM_TI_C6000:
1874 rtype = elf_tic6x_reloc_type (type);
1875 break;
aa137e4d
NC
1876
1877 case EM_TILEGX:
1878 rtype = elf_tilegx_reloc_type (type);
1879 break;
1880
1881 case EM_TILEPRO:
1882 rtype = elf_tilepro_reloc_type (type);
1883 break;
f6c1a2d5 1884
f96bd6c2
PC
1885 case EM_WEBASSEMBLY:
1886 rtype = elf_wasm32_reloc_type (type);
1887 break;
1888
f6c1a2d5
NC
1889 case EM_XGATE:
1890 rtype = elf_xgate_reloc_type (type);
1891 break;
36591ba1
SL
1892
1893 case EM_ALTERA_NIOS2:
1894 rtype = elf_nios2_reloc_type (type);
1895 break;
2b100bb5
DD
1896
1897 case EM_TI_PRU:
1898 rtype = elf_pru_reloc_type (type);
1899 break;
fe944acf
FT
1900
1901 case EM_NFP:
1902 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1903 rtype = elf_nfp3200_reloc_type (type);
1904 else
1905 rtype = elf_nfp_reloc_type (type);
1906 break;
6655dba2
SB
1907
1908 case EM_Z80:
1909 rtype = elf_z80_reloc_type (type);
1910 break;
e9a0721f 1911
1912 case EM_LOONGARCH:
1913 rtype = elf_loongarch_reloc_type (type);
1914 break;
1915
0c857ef4
SM
1916 case EM_AMDGPU:
1917 rtype = elf_amdgpu_reloc_type (type);
1918 break;
252b5132
RH
1919 }
1920
1921 if (rtype == NULL)
39dbeff8 1922 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1923 else
5c144731 1924 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1925
dda8d76d 1926 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1927 && rtype != NULL
7ace3541 1928 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 1929 && rel_type == reltype_rela)
7ace3541
RH
1930 {
1931 switch (rels[i].r_addend)
1932 {
1933 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1934 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1935 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1936 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1937 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1938 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1939 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1940 default: rtype = NULL;
1941 }
32ec8896 1942
7ace3541
RH
1943 if (rtype)
1944 printf (" (%s)", rtype);
1945 else
1946 {
1947 putchar (' ');
26c527e6
AM
1948 printf (_("<unknown addend: %" PRIx64 ">"),
1949 rels[i].r_addend);
015dc7e1 1950 res = false;
7ace3541
RH
1951 }
1952 }
1953 else if (symtab_index)
252b5132 1954 {
af3fc3bc 1955 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1956 {
27a45f42
AS
1957 error (_(" bad symbol index: %08lx in reloc\n"),
1958 (unsigned long) symtab_index);
015dc7e1 1959 res = false;
32ec8896 1960 }
af3fc3bc 1961 else
19936277 1962 {
2cf0635d 1963 Elf_Internal_Sym * psym;
bb4d2ac2
L
1964 const char * version_string;
1965 enum versioned_symbol_info sym_info;
1966 unsigned short vna_other;
19936277 1967
af3fc3bc 1968 psym = symtab + symtab_index;
103f02d3 1969
bb4d2ac2 1970 version_string
dda8d76d 1971 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1972 strtab, strtablen,
1973 symtab_index,
1974 psym,
1975 &sym_info,
1976 &vna_other);
1977
af3fc3bc 1978 printf (" ");
171191ba 1979
d8045f23
NC
1980 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1981 {
1982 const char * name;
1983 unsigned int len;
1984 unsigned int width = is_32bit_elf ? 8 : 14;
1985
1986 /* Relocations against GNU_IFUNC symbols do not use the value
1987 of the symbol as the address to relocate against. Instead
1988 they invoke the function named by the symbol and use its
1989 result as the address for relocation.
1990
1991 To indicate this to the user, do not display the value of
1992 the symbol in the "Symbols's Value" field. Instead show
1993 its name followed by () as a hint that the symbol is
1994 invoked. */
1995
1996 if (strtab == NULL
1997 || psym->st_name == 0
1998 || psym->st_name >= strtablen)
1999 name = "??";
2000 else
2001 name = strtab + psym->st_name;
2002
2003 len = print_symbol (width, name);
bb4d2ac2
L
2004 if (version_string)
2005 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2006 version_string);
d8045f23
NC
2007 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2008 }
2009 else
2010 {
2011 print_vma (psym->st_value, LONG_HEX);
171191ba 2012
d8045f23
NC
2013 printf (is_32bit_elf ? " " : " ");
2014 }
103f02d3 2015
af3fc3bc 2016 if (psym->st_name == 0)
f1ef08cb 2017 {
2cf0635d 2018 const char * sec_name = "<null>";
f1ef08cb
AM
2019 char name_buf[40];
2020
2021 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
2022 {
b9af6379
AM
2023 if (psym->st_shndx < filedata->file_header.e_shnum
2024 && filedata->section_headers != NULL)
84714f86
AM
2025 sec_name = section_name_print (filedata,
2026 filedata->section_headers
b9e920ec 2027 + psym->st_shndx);
f1ef08cb
AM
2028 else if (psym->st_shndx == SHN_ABS)
2029 sec_name = "ABS";
2030 else if (psym->st_shndx == SHN_COMMON)
2031 sec_name = "COMMON";
dda8d76d 2032 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 2033 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 2034 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 2035 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 2036 sec_name = "SCOMMON";
dda8d76d 2037 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
2038 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
2039 sec_name = "SUNDEF";
dda8d76d
NC
2040 else if ((filedata->file_header.e_machine == EM_X86_64
2041 || filedata->file_header.e_machine == EM_L1OM
2042 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
2043 && psym->st_shndx == SHN_X86_64_LCOMMON)
2044 sec_name = "LARGE_COMMON";
dda8d76d
NC
2045 else if (filedata->file_header.e_machine == EM_IA_64
2046 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
2047 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
2048 sec_name = "ANSI_COM";
dda8d76d 2049 else if (is_ia64_vms (filedata)
148b93f2
NC
2050 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
2051 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
2052 else
2053 {
2054 sprintf (name_buf, "<section 0x%x>",
2055 (unsigned int) psym->st_shndx);
2056 sec_name = name_buf;
2057 }
2058 }
2059 print_symbol (22, sec_name);
2060 }
af3fc3bc 2061 else if (strtab == NULL)
d79b3d50 2062 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2063 else if (psym->st_name >= strtablen)
32ec8896 2064 {
27a45f42
AS
2065 error (_("<corrupt string table index: %3ld>\n"),
2066 psym->st_name);
015dc7e1 2067 res = false;
32ec8896 2068 }
af3fc3bc 2069 else
bb4d2ac2
L
2070 {
2071 print_symbol (22, strtab + psym->st_name);
2072 if (version_string)
2073 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2074 version_string);
2075 }
103f02d3 2076
a7fd1186 2077 if (rel_type == reltype_rela)
171191ba 2078 {
625d49fc 2079 uint64_t off = rels[i].r_addend;
171191ba 2080
625d49fc
AM
2081 if ((int64_t) off < 0)
2082 printf (" - %" PRIx64, -off);
171191ba 2083 else
625d49fc 2084 printf (" + %" PRIx64, off);
171191ba 2085 }
19936277 2086 }
252b5132 2087 }
a7fd1186 2088 else if (rel_type == reltype_rela)
f7a99963 2089 {
625d49fc 2090 uint64_t off = rels[i].r_addend;
e04d7088
L
2091
2092 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
625d49fc
AM
2093 if ((int64_t) off < 0)
2094 printf ("-%" PRIx64, -off);
e04d7088 2095 else
625d49fc 2096 printf ("%" PRIx64, off);
f7a99963 2097 }
252b5132 2098
dda8d76d 2099 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2100 && rtype != NULL
2101 && streq (rtype, "R_SPARC_OLO10"))
26c527e6 2102 printf (" + %" PRIx64, ELF64_R_TYPE_DATA (inf));
351b4b40 2103
252b5132 2104 putchar ('\n');
2c71103e 2105
dda8d76d 2106 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2107 {
625d49fc
AM
2108 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2109 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2110 const char * rtype2 = elf_mips_reloc_type (type2);
2111 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2112
2c71103e
NC
2113 printf (" Type2: ");
2114
2115 if (rtype2 == NULL)
39dbeff8
AM
2116 printf (_("unrecognized: %-7lx"),
2117 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2118 else
2119 printf ("%-17.17s", rtype2);
2120
18bd398b 2121 printf ("\n Type3: ");
2c71103e
NC
2122
2123 if (rtype3 == NULL)
39dbeff8
AM
2124 printf (_("unrecognized: %-7lx"),
2125 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2126 else
2127 printf ("%-17.17s", rtype3);
2128
53c7db4b 2129 putchar ('\n');
2c71103e 2130 }
252b5132
RH
2131 }
2132
c8286bd1 2133 free (rels);
32ec8896
NC
2134
2135 return res;
252b5132
RH
2136}
2137
37c18eed
SD
2138static const char *
2139get_aarch64_dynamic_type (unsigned long type)
2140{
2141 switch (type)
2142 {
2143 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2144 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2145 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2146 default:
2147 return NULL;
2148 }
2149}
2150
252b5132 2151static const char *
d3ba0551 2152get_mips_dynamic_type (unsigned long type)
252b5132
RH
2153{
2154 switch (type)
2155 {
2156 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2157 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2158 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2159 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2160 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2161 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2162 case DT_MIPS_MSYM: return "MIPS_MSYM";
2163 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2164 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2165 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2166 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2167 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2168 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2169 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2170 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2171 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2172 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2173 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2174 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2175 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2176 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2177 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2178 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2179 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2180 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2181 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2182 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2183 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2184 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2185 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2186 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2187 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2188 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2189 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2190 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2191 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2192 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2193 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2194 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2195 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2196 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2197 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2198 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2199 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2200 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2201 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2202 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2203 default:
2204 return NULL;
2205 }
2206}
2207
9a097730 2208static const char *
d3ba0551 2209get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2210{
2211 switch (type)
2212 {
2213 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2214 default:
2215 return NULL;
2216 }
103f02d3
UD
2217}
2218
7490d522
AM
2219static const char *
2220get_ppc_dynamic_type (unsigned long type)
2221{
2222 switch (type)
2223 {
a7f2871e 2224 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2225 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2226 default:
2227 return NULL;
2228 }
2229}
2230
f1cb7e17 2231static const char *
d3ba0551 2232get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2233{
2234 switch (type)
2235 {
a7f2871e
AM
2236 case DT_PPC64_GLINK: return "PPC64_GLINK";
2237 case DT_PPC64_OPD: return "PPC64_OPD";
2238 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2239 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2240 default:
2241 return NULL;
2242 }
2243}
2244
103f02d3 2245static const char *
d3ba0551 2246get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2247{
2248 switch (type)
2249 {
2250 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2251 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2252 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2253 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2254 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2255 case DT_HP_PREINIT: return "HP_PREINIT";
2256 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2257 case DT_HP_NEEDED: return "HP_NEEDED";
2258 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2259 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2260 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2261 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2262 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2263 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2264 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2265 case DT_HP_FILTERED: return "HP_FILTERED";
2266 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2267 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2268 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2269 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2270 case DT_PLT: return "PLT";
2271 case DT_PLT_SIZE: return "PLT_SIZE";
2272 case DT_DLT: return "DLT";
2273 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2274 default:
2275 return NULL;
2276 }
2277}
9a097730 2278
ecc51f48 2279static const char *
d3ba0551 2280get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2281{
2282 switch (type)
2283 {
148b93f2
NC
2284 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2285 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2286 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2287 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2288 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2289 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2290 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2291 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2292 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2293 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2294 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2295 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2296 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2297 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2298 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2299 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2300 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2301 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2302 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2303 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2304 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2305 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2306 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2307 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2308 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2309 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2310 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2311 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2312 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2313 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2314 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2315 default:
2316 return NULL;
2317 }
2318}
2319
fd85a6a1
NC
2320static const char *
2321get_solaris_section_type (unsigned long type)
2322{
2323 switch (type)
2324 {
2325 case 0x6fffffee: return "SUNW_ancillary";
2326 case 0x6fffffef: return "SUNW_capchain";
2327 case 0x6ffffff0: return "SUNW_capinfo";
2328 case 0x6ffffff1: return "SUNW_symsort";
2329 case 0x6ffffff2: return "SUNW_tlssort";
2330 case 0x6ffffff3: return "SUNW_LDYNSYM";
2331 case 0x6ffffff4: return "SUNW_dof";
2332 case 0x6ffffff5: return "SUNW_cap";
2333 case 0x6ffffff6: return "SUNW_SIGNATURE";
2334 case 0x6ffffff7: return "SUNW_ANNOTATE";
2335 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2336 case 0x6ffffff9: return "SUNW_DEBUG";
2337 case 0x6ffffffa: return "SUNW_move";
2338 case 0x6ffffffb: return "SUNW_COMDAT";
2339 case 0x6ffffffc: return "SUNW_syminfo";
2340 case 0x6ffffffd: return "SUNW_verdef";
2341 case 0x6ffffffe: return "SUNW_verneed";
2342 case 0x6fffffff: return "SUNW_versym";
2343 case 0x70000000: return "SPARC_GOTDATA";
2344 default: return NULL;
2345 }
2346}
2347
fabcb361
RH
2348static const char *
2349get_alpha_dynamic_type (unsigned long type)
2350{
2351 switch (type)
2352 {
2353 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2354 default: return NULL;
fabcb361
RH
2355 }
2356}
2357
1c0d3aa6
NC
2358static const char *
2359get_score_dynamic_type (unsigned long type)
2360{
2361 switch (type)
2362 {
2363 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2364 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2365 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2366 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2367 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2368 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2369 default: return NULL;
1c0d3aa6
NC
2370 }
2371}
2372
40b36596
JM
2373static const char *
2374get_tic6x_dynamic_type (unsigned long type)
2375{
2376 switch (type)
2377 {
2378 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2379 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2380 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2381 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2382 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2383 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2384 default: return NULL;
40b36596
JM
2385 }
2386}
1c0d3aa6 2387
36591ba1
SL
2388static const char *
2389get_nios2_dynamic_type (unsigned long type)
2390{
2391 switch (type)
2392 {
2393 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2394 default: return NULL;
36591ba1
SL
2395 }
2396}
2397
fd85a6a1
NC
2398static const char *
2399get_solaris_dynamic_type (unsigned long type)
2400{
2401 switch (type)
2402 {
2403 case 0x6000000d: return "SUNW_AUXILIARY";
2404 case 0x6000000e: return "SUNW_RTLDINF";
2405 case 0x6000000f: return "SUNW_FILTER";
2406 case 0x60000010: return "SUNW_CAP";
2407 case 0x60000011: return "SUNW_SYMTAB";
2408 case 0x60000012: return "SUNW_SYMSZ";
2409 case 0x60000013: return "SUNW_SORTENT";
2410 case 0x60000014: return "SUNW_SYMSORT";
2411 case 0x60000015: return "SUNW_SYMSORTSZ";
2412 case 0x60000016: return "SUNW_TLSSORT";
2413 case 0x60000017: return "SUNW_TLSSORTSZ";
2414 case 0x60000018: return "SUNW_CAPINFO";
2415 case 0x60000019: return "SUNW_STRPAD";
2416 case 0x6000001a: return "SUNW_CAPCHAIN";
2417 case 0x6000001b: return "SUNW_LDMACH";
2418 case 0x6000001d: return "SUNW_CAPCHAINENT";
2419 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2420 case 0x60000021: return "SUNW_PARENT";
2421 case 0x60000023: return "SUNW_ASLR";
2422 case 0x60000025: return "SUNW_RELAX";
2423 case 0x60000029: return "SUNW_NXHEAP";
2424 case 0x6000002b: return "SUNW_NXSTACK";
2425
2426 case 0x70000001: return "SPARC_REGISTER";
2427 case 0x7ffffffd: return "AUXILIARY";
2428 case 0x7ffffffe: return "USED";
2429 case 0x7fffffff: return "FILTER";
2430
15f205b1 2431 default: return NULL;
fd85a6a1
NC
2432 }
2433}
2434
8155b853
NC
2435static const char *
2436get_riscv_dynamic_type (unsigned long type)
2437{
2438 switch (type)
2439 {
2440 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2441 default:
2442 return NULL;
2443 }
2444}
2445
252b5132 2446static const char *
dda8d76d 2447get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2448{
e9e44622 2449 static char buff[64];
252b5132
RH
2450
2451 switch (type)
2452 {
2453 case DT_NULL: return "NULL";
2454 case DT_NEEDED: return "NEEDED";
2455 case DT_PLTRELSZ: return "PLTRELSZ";
2456 case DT_PLTGOT: return "PLTGOT";
2457 case DT_HASH: return "HASH";
2458 case DT_STRTAB: return "STRTAB";
2459 case DT_SYMTAB: return "SYMTAB";
2460 case DT_RELA: return "RELA";
2461 case DT_RELASZ: return "RELASZ";
2462 case DT_RELAENT: return "RELAENT";
2463 case DT_STRSZ: return "STRSZ";
2464 case DT_SYMENT: return "SYMENT";
2465 case DT_INIT: return "INIT";
2466 case DT_FINI: return "FINI";
2467 case DT_SONAME: return "SONAME";
2468 case DT_RPATH: return "RPATH";
2469 case DT_SYMBOLIC: return "SYMBOLIC";
2470 case DT_REL: return "REL";
2471 case DT_RELSZ: return "RELSZ";
2472 case DT_RELENT: return "RELENT";
dd207c13
FS
2473 case DT_RELR: return "RELR";
2474 case DT_RELRSZ: return "RELRSZ";
2475 case DT_RELRENT: return "RELRENT";
252b5132
RH
2476 case DT_PLTREL: return "PLTREL";
2477 case DT_DEBUG: return "DEBUG";
2478 case DT_TEXTREL: return "TEXTREL";
2479 case DT_JMPREL: return "JMPREL";
2480 case DT_BIND_NOW: return "BIND_NOW";
2481 case DT_INIT_ARRAY: return "INIT_ARRAY";
2482 case DT_FINI_ARRAY: return "FINI_ARRAY";
2483 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2484 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2485 case DT_RUNPATH: return "RUNPATH";
2486 case DT_FLAGS: return "FLAGS";
2d0e6f43 2487
d1133906
NC
2488 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2489 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2490 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2491
05107a46 2492 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2493 case DT_PLTPADSZ: return "PLTPADSZ";
2494 case DT_MOVEENT: return "MOVEENT";
2495 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2496 case DT_FEATURE: return "FEATURE";
252b5132
RH
2497 case DT_POSFLAG_1: return "POSFLAG_1";
2498 case DT_SYMINSZ: return "SYMINSZ";
2499 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2500
252b5132 2501 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2502 case DT_CONFIG: return "CONFIG";
2503 case DT_DEPAUDIT: return "DEPAUDIT";
2504 case DT_AUDIT: return "AUDIT";
2505 case DT_PLTPAD: return "PLTPAD";
2506 case DT_MOVETAB: return "MOVETAB";
252b5132 2507 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2508
252b5132 2509 case DT_VERSYM: return "VERSYM";
103f02d3 2510
67a4f2b7
AO
2511 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2512 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2513 case DT_RELACOUNT: return "RELACOUNT";
2514 case DT_RELCOUNT: return "RELCOUNT";
2515 case DT_FLAGS_1: return "FLAGS_1";
2516 case DT_VERDEF: return "VERDEF";
2517 case DT_VERDEFNUM: return "VERDEFNUM";
2518 case DT_VERNEED: return "VERNEED";
2519 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2520
019148e4 2521 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2522 case DT_USED: return "USED";
2523 case DT_FILTER: return "FILTER";
103f02d3 2524
047b2264
JJ
2525 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2526 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2527 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2528 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2529 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2530 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2531 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2532
252b5132
RH
2533 default:
2534 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2535 {
2cf0635d 2536 const char * result;
103f02d3 2537
dda8d76d 2538 switch (filedata->file_header.e_machine)
252b5132 2539 {
37c18eed
SD
2540 case EM_AARCH64:
2541 result = get_aarch64_dynamic_type (type);
2542 break;
252b5132 2543 case EM_MIPS:
4fe85591 2544 case EM_MIPS_RS3_LE:
252b5132
RH
2545 result = get_mips_dynamic_type (type);
2546 break;
9a097730
RH
2547 case EM_SPARCV9:
2548 result = get_sparc64_dynamic_type (type);
2549 break;
7490d522
AM
2550 case EM_PPC:
2551 result = get_ppc_dynamic_type (type);
2552 break;
f1cb7e17
AM
2553 case EM_PPC64:
2554 result = get_ppc64_dynamic_type (type);
2555 break;
ecc51f48
NC
2556 case EM_IA_64:
2557 result = get_ia64_dynamic_type (type);
2558 break;
fabcb361
RH
2559 case EM_ALPHA:
2560 result = get_alpha_dynamic_type (type);
2561 break;
1c0d3aa6
NC
2562 case EM_SCORE:
2563 result = get_score_dynamic_type (type);
2564 break;
40b36596
JM
2565 case EM_TI_C6000:
2566 result = get_tic6x_dynamic_type (type);
2567 break;
36591ba1
SL
2568 case EM_ALTERA_NIOS2:
2569 result = get_nios2_dynamic_type (type);
2570 break;
8155b853
NC
2571 case EM_RISCV:
2572 result = get_riscv_dynamic_type (type);
2573 break;
252b5132 2574 default:
dda8d76d 2575 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2576 result = get_solaris_dynamic_type (type);
2577 else
2578 result = NULL;
252b5132
RH
2579 break;
2580 }
2581
2582 if (result != NULL)
2583 return result;
2584
e9e44622 2585 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2586 }
eec8f817 2587 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2588 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2589 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2590 {
2cf0635d 2591 const char * result;
103f02d3 2592
dda8d76d 2593 switch (filedata->file_header.e_machine)
103f02d3
UD
2594 {
2595 case EM_PARISC:
2596 result = get_parisc_dynamic_type (type);
2597 break;
148b93f2
NC
2598 case EM_IA_64:
2599 result = get_ia64_dynamic_type (type);
2600 break;
103f02d3 2601 default:
dda8d76d 2602 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2603 result = get_solaris_dynamic_type (type);
2604 else
2605 result = NULL;
103f02d3
UD
2606 break;
2607 }
2608
2609 if (result != NULL)
2610 return result;
2611
e9e44622
JJ
2612 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2613 type);
103f02d3 2614 }
252b5132 2615 else
e9e44622 2616 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2617
252b5132
RH
2618 return buff;
2619 }
2620}
2621
93df3340
AM
2622static bool get_program_headers (Filedata *);
2623static bool get_dynamic_section (Filedata *);
2624
2625static void
2626locate_dynamic_section (Filedata *filedata)
2627{
26c527e6 2628 uint64_t dynamic_addr = 0;
be7d229a 2629 uint64_t dynamic_size = 0;
93df3340
AM
2630
2631 if (filedata->file_header.e_phnum != 0
2632 && get_program_headers (filedata))
2633 {
2634 Elf_Internal_Phdr *segment;
2635 unsigned int i;
2636
2637 for (i = 0, segment = filedata->program_headers;
2638 i < filedata->file_header.e_phnum;
2639 i++, segment++)
2640 {
2641 if (segment->p_type == PT_DYNAMIC)
2642 {
2643 dynamic_addr = segment->p_offset;
2644 dynamic_size = segment->p_filesz;
2645
2646 if (filedata->section_headers != NULL)
2647 {
2648 Elf_Internal_Shdr *sec;
2649
2650 sec = find_section (filedata, ".dynamic");
2651 if (sec != NULL)
2652 {
2653 if (sec->sh_size == 0
2654 || sec->sh_type == SHT_NOBITS)
2655 {
2656 dynamic_addr = 0;
2657 dynamic_size = 0;
2658 }
2659 else
2660 {
2661 dynamic_addr = sec->sh_offset;
2662 dynamic_size = sec->sh_size;
2663 }
2664 }
2665 }
2666
2667 if (dynamic_addr > filedata->file_size
2668 || (dynamic_size > filedata->file_size - dynamic_addr))
2669 {
2670 dynamic_addr = 0;
2671 dynamic_size = 0;
2672 }
2673 break;
2674 }
2675 }
2676 }
2677 filedata->dynamic_addr = dynamic_addr;
2678 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2679}
2680
2681static bool
2682is_pie (Filedata *filedata)
2683{
2684 Elf_Internal_Dyn *entry;
2685
2686 if (filedata->dynamic_size == 0)
2687 locate_dynamic_section (filedata);
2688 if (filedata->dynamic_size <= 1)
2689 return false;
2690
2691 if (!get_dynamic_section (filedata))
2692 return false;
2693
2694 for (entry = filedata->dynamic_section;
2695 entry < filedata->dynamic_section + filedata->dynamic_nent;
2696 entry++)
2697 {
2698 if (entry->d_tag == DT_FLAGS_1)
2699 {
2700 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2701 return true;
2702 break;
2703 }
2704 }
2705 return false;
2706}
2707
252b5132 2708static char *
93df3340 2709get_file_type (Filedata *filedata)
252b5132 2710{
93df3340 2711 unsigned e_type = filedata->file_header.e_type;
89246a0e 2712 static char buff[64];
252b5132
RH
2713
2714 switch (e_type)
2715 {
32ec8896
NC
2716 case ET_NONE: return _("NONE (None)");
2717 case ET_REL: return _("REL (Relocatable file)");
2718 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2719 case ET_DYN:
2720 if (is_pie (filedata))
2721 return _("DYN (Position-Independent Executable file)");
2722 else
2723 return _("DYN (Shared object file)");
32ec8896 2724 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2725
2726 default:
2727 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2728 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2729 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2730 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2731 else
e9e44622 2732 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2733 return buff;
2734 }
2735}
2736
2737static char *
d3ba0551 2738get_machine_name (unsigned e_machine)
252b5132 2739{
b34976b6 2740 static char buff[64]; /* XXX */
252b5132
RH
2741
2742 switch (e_machine)
2743 {
55e22ca8
NC
2744 /* Please keep this switch table sorted by increasing EM_ value. */
2745 /* 0 */
c45021f2
NC
2746 case EM_NONE: return _("None");
2747 case EM_M32: return "WE32100";
2748 case EM_SPARC: return "Sparc";
2749 case EM_386: return "Intel 80386";
2750 case EM_68K: return "MC68000";
2751 case EM_88K: return "MC88000";
22abe556 2752 case EM_IAMCU: return "Intel MCU";
fb70ec17 2753 case EM_860: return "Intel 80860";
c45021f2
NC
2754 case EM_MIPS: return "MIPS R3000";
2755 case EM_S370: return "IBM System/370";
55e22ca8 2756 /* 10 */
7036c0e1 2757 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2758 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2759 case EM_PARISC: return "HPPA";
55e22ca8 2760 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2761 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2762 case EM_960: return "Intel 80960";
c45021f2 2763 case EM_PPC: return "PowerPC";
55e22ca8 2764 /* 20 */
285d1771 2765 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2766 case EM_S390_OLD:
2767 case EM_S390: return "IBM S/390";
2768 case EM_SPU: return "SPU";
2769 /* 30 */
2770 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2771 case EM_FR20: return "Fujitsu FR20";
2772 case EM_RH32: return "TRW RH32";
b34976b6 2773 case EM_MCORE: return "MCORE";
55e22ca8 2774 /* 40 */
7036c0e1
AJ
2775 case EM_ARM: return "ARM";
2776 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2777 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2778 case EM_SPARCV9: return "Sparc v9";
2779 case EM_TRICORE: return "Siemens Tricore";
584da044 2780 case EM_ARC: return "ARC";
c2dcd04e
NC
2781 case EM_H8_300: return "Renesas H8/300";
2782 case EM_H8_300H: return "Renesas H8/300H";
2783 case EM_H8S: return "Renesas H8S";
2784 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2785 /* 50 */
30800947 2786 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2787 case EM_MIPS_X: return "Stanford MIPS-X";
2788 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2789 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2790 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2791 case EM_PCP: return "Siemens PCP";
2792 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2793 case EM_NDR1: return "Denso NDR1 microprocesspr";
2794 case EM_STARCORE: return "Motorola Star*Core processor";
2795 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2796 /* 60 */
7036c0e1
AJ
2797 case EM_ST100: return "STMicroelectronics ST100 processor";
2798 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2799 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2800 case EM_PDSP: return "Sony DSP processor";
2801 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2802 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2803 case EM_FX66: return "Siemens FX66 microcontroller";
2804 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2805 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2806 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2807 /* 70 */
7036c0e1
AJ
2808 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2809 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2810 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2811 case EM_SVX: return "Silicon Graphics SVx";
2812 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2813 case EM_VAX: return "Digital VAX";
1b61cf92 2814 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2815 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2816 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2817 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2818 /* 80 */
b34976b6 2819 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2820 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2821 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2822 case EM_AVR_OLD:
2823 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2824 case EM_CYGNUS_FR30:
2825 case EM_FR30: return "Fujitsu FR30";
2826 case EM_CYGNUS_D10V:
2827 case EM_D10V: return "d10v";
2828 case EM_CYGNUS_D30V:
2829 case EM_D30V: return "d30v";
2830 case EM_CYGNUS_V850:
2831 case EM_V850: return "Renesas V850";
2832 case EM_CYGNUS_M32R:
2833 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2834 case EM_CYGNUS_MN10300:
2835 case EM_MN10300: return "mn10300";
2836 /* 90 */
2837 case EM_CYGNUS_MN10200:
2838 case EM_MN10200: return "mn10200";
2839 case EM_PJ: return "picoJava";
73589c9d 2840 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2841 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2842 case EM_XTENSA_OLD:
2843 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2844 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2845 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2846 case EM_NS32K: return "National Semiconductor 32000 series";
2847 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2848 case EM_SNP1K: return "Trebia SNP 1000 processor";
2849 /* 100 */
9abca702 2850 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2851 case EM_IP2K_OLD:
2852 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2853 case EM_MAX: return "MAX Processor";
2854 case EM_CR: return "National Semiconductor CompactRISC";
2855 case EM_F2MC16: return "Fujitsu F2MC16";
2856 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2857 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2858 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2859 case EM_SEP: return "Sharp embedded microprocessor";
2860 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2861 /* 110 */
11636f9e
JM
2862 case EM_UNICORE: return "Unicore";
2863 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2864 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2865 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2866 case EM_CRX: return "National Semiconductor CRX microprocessor";
2867 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2868 case EM_C166:
d70c5fc7 2869 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2870 case EM_M16C: return "Renesas M16C series microprocessors";
2871 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2872 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2873 /* 120 */
2874 case EM_M32C: return "Renesas M32c";
2875 /* 130 */
11636f9e
JM
2876 case EM_TSK3000: return "Altium TSK3000 core";
2877 case EM_RS08: return "Freescale RS08 embedded processor";
2878 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2879 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2880 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2881 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2882 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2883 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2884 /* 140 */
11636f9e
JM
2885 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2886 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2887 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2888 case EM_TI_PRU: return "TI PRU I/O processor";
2889 /* 160 */
11636f9e
JM
2890 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2891 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2892 case EM_R32C: return "Renesas R32C series microprocessors";
2893 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2894 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2895 case EM_8051: return "Intel 8051 and variants";
2896 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2897 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2898 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2899 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2900 /* 170 */
11636f9e
JM
2901 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2902 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2903 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2904 case EM_RX: return "Renesas RX";
a3c62988 2905 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2906 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2907 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2908 case EM_CR16:
2909 case EM_MICROBLAZE:
2910 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2911 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2912 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2913 /* 180 */
2914 case EM_L1OM: return "Intel L1OM";
2915 case EM_K1OM: return "Intel K1OM";
2916 case EM_INTEL182: return "Intel (reserved)";
2917 case EM_AARCH64: return "AArch64";
2918 case EM_ARM184: return "ARM (reserved)";
2919 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2920 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2921 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2922 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2923 /* 190 */
11636f9e 2924 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2925 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2926 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2927 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2928 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2929 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2930 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2931 case EM_RL78: return "Renesas RL78";
6d913794 2932 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2933 case EM_78K0R: return "Renesas 78K0R";
2934 /* 200 */
6d913794 2935 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2936 case EM_BA1: return "Beyond BA1 CPU architecture";
2937 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2938 case EM_XCORE: return "XMOS xCORE processor family";
2939 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2940 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2941 /* 210 */
6d913794
NC
2942 case EM_KM32: return "KM211 KM32 32-bit processor";
2943 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2944 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2945 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2946 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2947 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2948 case EM_COGE: return "Cognitive Smart Memory Processor";
2949 case EM_COOL: return "Bluechip Systems CoolEngine";
2950 case EM_NORC: return "Nanoradio Optimized RISC";
2951 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2952 /* 220 */
15f205b1 2953 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2954 case EM_VISIUM: return "CDS VISIUMcore processor";
2955 case EM_FT32: return "FTDI Chip FT32";
2956 case EM_MOXIE: return "Moxie";
2957 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2958 /* 230 (all reserved) */
2959 /* 240 */
55e22ca8
NC
2960 case EM_RISCV: return "RISC-V";
2961 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2962 case EM_CEVA: return "CEVA Processor Architecture Family";
2963 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2964 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2965 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2966 case EM_IMG1: return "Imagination Technologies";
2967 /* 250 */
fe944acf 2968 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2969 case EM_VE: return "NEC Vector Engine";
2970 case EM_CSKY: return "C-SKY";
2971 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2972 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2973 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2974 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2975 case EM_65816: return "WDC 65816/65C816";
01a8c731 2976 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2977 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2978
2979 /* Large numbers... */
2980 case EM_MT: return "Morpho Techologies MT processor";
2981 case EM_ALPHA: return "Alpha";
2982 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2983 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2984 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2985 case EM_IQ2000: return "Vitesse IQ2000";
2986 case EM_M32C_OLD:
2987 case EM_NIOS32: return "Altera Nios";
2988 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2989 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2990 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2991 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2992
252b5132 2993 default:
35d9dd2f 2994 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2995 return buff;
2996 }
2997}
2998
a9522a21
AB
2999static void
3000decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
3001{
3002 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3003 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3004 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3005 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3006 architectures.
3007
3008 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3009 but also sets a specific architecture type in the e_flags field.
3010
3011 However, when decoding the flags we don't worry if we see an
3012 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3013 ARCEM architecture type. */
3014
3015 switch (e_flags & EF_ARC_MACH_MSK)
3016 {
3017 /* We only expect these to occur for EM_ARC_COMPACT2. */
3018 case EF_ARC_CPU_ARCV2EM:
3019 strcat (buf, ", ARC EM");
3020 break;
3021 case EF_ARC_CPU_ARCV2HS:
3022 strcat (buf, ", ARC HS");
3023 break;
3024
3025 /* We only expect these to occur for EM_ARC_COMPACT. */
3026 case E_ARC_MACH_ARC600:
3027 strcat (buf, ", ARC600");
3028 break;
3029 case E_ARC_MACH_ARC601:
3030 strcat (buf, ", ARC601");
3031 break;
3032 case E_ARC_MACH_ARC700:
3033 strcat (buf, ", ARC700");
3034 break;
3035
3036 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3037 new ELF with new architecture being read by an old version of
3038 readelf, or (c) An ELF built with non-GNU compiler that does not
3039 set the architecture in the e_flags. */
3040 default:
3041 if (e_machine == EM_ARC_COMPACT)
3042 strcat (buf, ", Unknown ARCompact");
3043 else
3044 strcat (buf, ", Unknown ARC");
3045 break;
3046 }
3047
3048 switch (e_flags & EF_ARC_OSABI_MSK)
3049 {
3050 case E_ARC_OSABI_ORIG:
3051 strcat (buf, ", (ABI:legacy)");
3052 break;
3053 case E_ARC_OSABI_V2:
3054 strcat (buf, ", (ABI:v2)");
3055 break;
3056 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3057 case E_ARC_OSABI_V3:
3058 strcat (buf, ", v3 no-legacy-syscalls ABI");
3059 break;
53a346d8
CZ
3060 case E_ARC_OSABI_V4:
3061 strcat (buf, ", v4 ABI");
3062 break;
a9522a21
AB
3063 default:
3064 strcat (buf, ", unrecognised ARC OSABI flag");
3065 break;
3066 }
3067}
3068
f3485b74 3069static void
d3ba0551 3070decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
3071{
3072 unsigned eabi;
015dc7e1 3073 bool unknown = false;
f3485b74
NC
3074
3075 eabi = EF_ARM_EABI_VERSION (e_flags);
3076 e_flags &= ~ EF_ARM_EABIMASK;
3077
3078 /* Handle "generic" ARM flags. */
3079 if (e_flags & EF_ARM_RELEXEC)
3080 {
3081 strcat (buf, ", relocatable executable");
3082 e_flags &= ~ EF_ARM_RELEXEC;
3083 }
76da6bbe 3084
18a20338
CL
3085 if (e_flags & EF_ARM_PIC)
3086 {
3087 strcat (buf, ", position independent");
3088 e_flags &= ~ EF_ARM_PIC;
3089 }
3090
f3485b74
NC
3091 /* Now handle EABI specific flags. */
3092 switch (eabi)
3093 {
3094 default:
2c71103e 3095 strcat (buf, ", <unrecognized EABI>");
f3485b74 3096 if (e_flags)
015dc7e1 3097 unknown = true;
f3485b74
NC
3098 break;
3099
3100 case EF_ARM_EABI_VER1:
a5bcd848 3101 strcat (buf, ", Version1 EABI");
f3485b74
NC
3102 while (e_flags)
3103 {
3104 unsigned flag;
76da6bbe 3105
f3485b74
NC
3106 /* Process flags one bit at a time. */
3107 flag = e_flags & - e_flags;
3108 e_flags &= ~ flag;
76da6bbe 3109
f3485b74
NC
3110 switch (flag)
3111 {
a5bcd848 3112 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
3113 strcat (buf, ", sorted symbol tables");
3114 break;
76da6bbe 3115
f3485b74 3116 default:
015dc7e1 3117 unknown = true;
f3485b74
NC
3118 break;
3119 }
3120 }
3121 break;
76da6bbe 3122
a5bcd848
PB
3123 case EF_ARM_EABI_VER2:
3124 strcat (buf, ", Version2 EABI");
3125 while (e_flags)
3126 {
3127 unsigned flag;
3128
3129 /* Process flags one bit at a time. */
3130 flag = e_flags & - e_flags;
3131 e_flags &= ~ flag;
3132
3133 switch (flag)
3134 {
3135 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3136 strcat (buf, ", sorted symbol tables");
3137 break;
3138
3139 case EF_ARM_DYNSYMSUSESEGIDX:
3140 strcat (buf, ", dynamic symbols use segment index");
3141 break;
3142
3143 case EF_ARM_MAPSYMSFIRST:
3144 strcat (buf, ", mapping symbols precede others");
3145 break;
3146
3147 default:
015dc7e1 3148 unknown = true;
a5bcd848
PB
3149 break;
3150 }
3151 }
3152 break;
3153
d507cf36
PB
3154 case EF_ARM_EABI_VER3:
3155 strcat (buf, ", Version3 EABI");
8cb51566
PB
3156 break;
3157
3158 case EF_ARM_EABI_VER4:
3159 strcat (buf, ", Version4 EABI");
3bfcb652
NC
3160 while (e_flags)
3161 {
3162 unsigned flag;
3163
3164 /* Process flags one bit at a time. */
3165 flag = e_flags & - e_flags;
3166 e_flags &= ~ flag;
3167
3168 switch (flag)
3169 {
3170 case EF_ARM_BE8:
3171 strcat (buf, ", BE8");
3172 break;
3173
3174 case EF_ARM_LE8:
3175 strcat (buf, ", LE8");
3176 break;
3177
3178 default:
015dc7e1 3179 unknown = true;
3bfcb652
NC
3180 break;
3181 }
3bfcb652
NC
3182 }
3183 break;
3a4a14e9
PB
3184
3185 case EF_ARM_EABI_VER5:
3186 strcat (buf, ", Version5 EABI");
d507cf36
PB
3187 while (e_flags)
3188 {
3189 unsigned flag;
3190
3191 /* Process flags one bit at a time. */
3192 flag = e_flags & - e_flags;
3193 e_flags &= ~ flag;
3194
3195 switch (flag)
3196 {
3197 case EF_ARM_BE8:
3198 strcat (buf, ", BE8");
3199 break;
3200
3201 case EF_ARM_LE8:
3202 strcat (buf, ", LE8");
3203 break;
3204
3bfcb652
NC
3205 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3206 strcat (buf, ", soft-float ABI");
3207 break;
3208
3209 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3210 strcat (buf, ", hard-float ABI");
3211 break;
3212
d507cf36 3213 default:
015dc7e1 3214 unknown = true;
d507cf36
PB
3215 break;
3216 }
3217 }
3218 break;
3219
f3485b74 3220 case EF_ARM_EABI_UNKNOWN:
a5bcd848 3221 strcat (buf, ", GNU EABI");
f3485b74
NC
3222 while (e_flags)
3223 {
3224 unsigned flag;
76da6bbe 3225
f3485b74
NC
3226 /* Process flags one bit at a time. */
3227 flag = e_flags & - e_flags;
3228 e_flags &= ~ flag;
76da6bbe 3229
f3485b74
NC
3230 switch (flag)
3231 {
a5bcd848 3232 case EF_ARM_INTERWORK:
f3485b74
NC
3233 strcat (buf, ", interworking enabled");
3234 break;
76da6bbe 3235
a5bcd848 3236 case EF_ARM_APCS_26:
f3485b74
NC
3237 strcat (buf, ", uses APCS/26");
3238 break;
76da6bbe 3239
a5bcd848 3240 case EF_ARM_APCS_FLOAT:
f3485b74
NC
3241 strcat (buf, ", uses APCS/float");
3242 break;
76da6bbe 3243
a5bcd848 3244 case EF_ARM_PIC:
f3485b74
NC
3245 strcat (buf, ", position independent");
3246 break;
76da6bbe 3247
a5bcd848 3248 case EF_ARM_ALIGN8:
f3485b74
NC
3249 strcat (buf, ", 8 bit structure alignment");
3250 break;
76da6bbe 3251
a5bcd848 3252 case EF_ARM_NEW_ABI:
f3485b74
NC
3253 strcat (buf, ", uses new ABI");
3254 break;
76da6bbe 3255
a5bcd848 3256 case EF_ARM_OLD_ABI:
f3485b74
NC
3257 strcat (buf, ", uses old ABI");
3258 break;
76da6bbe 3259
a5bcd848 3260 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
3261 strcat (buf, ", software FP");
3262 break;
76da6bbe 3263
90e01f86
ILT
3264 case EF_ARM_VFP_FLOAT:
3265 strcat (buf, ", VFP");
3266 break;
3267
fde78edd
NC
3268 case EF_ARM_MAVERICK_FLOAT:
3269 strcat (buf, ", Maverick FP");
3270 break;
3271
f3485b74 3272 default:
015dc7e1 3273 unknown = true;
f3485b74
NC
3274 break;
3275 }
3276 }
3277 }
f3485b74
NC
3278
3279 if (unknown)
2b692964 3280 strcat (buf,_(", <unknown>"));
f3485b74
NC
3281}
3282
343433df
AB
3283static void
3284decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
3285{
3286 --size; /* Leave space for null terminator. */
3287
3288 switch (e_flags & EF_AVR_MACH)
3289 {
3290 case E_AVR_MACH_AVR1:
3291 strncat (buf, ", avr:1", size);
3292 break;
3293 case E_AVR_MACH_AVR2:
3294 strncat (buf, ", avr:2", size);
3295 break;
3296 case E_AVR_MACH_AVR25:
3297 strncat (buf, ", avr:25", size);
3298 break;
3299 case E_AVR_MACH_AVR3:
3300 strncat (buf, ", avr:3", size);
3301 break;
3302 case E_AVR_MACH_AVR31:
3303 strncat (buf, ", avr:31", size);
3304 break;
3305 case E_AVR_MACH_AVR35:
3306 strncat (buf, ", avr:35", size);
3307 break;
3308 case E_AVR_MACH_AVR4:
3309 strncat (buf, ", avr:4", size);
3310 break;
3311 case E_AVR_MACH_AVR5:
3312 strncat (buf, ", avr:5", size);
3313 break;
3314 case E_AVR_MACH_AVR51:
3315 strncat (buf, ", avr:51", size);
3316 break;
3317 case E_AVR_MACH_AVR6:
3318 strncat (buf, ", avr:6", size);
3319 break;
3320 case E_AVR_MACH_AVRTINY:
3321 strncat (buf, ", avr:100", size);
3322 break;
3323 case E_AVR_MACH_XMEGA1:
3324 strncat (buf, ", avr:101", size);
3325 break;
3326 case E_AVR_MACH_XMEGA2:
3327 strncat (buf, ", avr:102", size);
3328 break;
3329 case E_AVR_MACH_XMEGA3:
3330 strncat (buf, ", avr:103", size);
3331 break;
3332 case E_AVR_MACH_XMEGA4:
3333 strncat (buf, ", avr:104", size);
3334 break;
3335 case E_AVR_MACH_XMEGA5:
3336 strncat (buf, ", avr:105", size);
3337 break;
3338 case E_AVR_MACH_XMEGA6:
3339 strncat (buf, ", avr:106", size);
3340 break;
3341 case E_AVR_MACH_XMEGA7:
3342 strncat (buf, ", avr:107", size);
3343 break;
3344 default:
3345 strncat (buf, ", avr:<unknown>", size);
3346 break;
3347 }
3348
3349 size -= strlen (buf);
3350 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3351 strncat (buf, ", link-relax", size);
3352}
3353
35c08157
KLC
3354static void
3355decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
3356{
3357 unsigned abi;
3358 unsigned arch;
3359 unsigned config;
3360 unsigned version;
015dc7e1 3361 bool has_fpu = false;
32ec8896 3362 unsigned int r = 0;
35c08157
KLC
3363
3364 static const char *ABI_STRINGS[] =
3365 {
3366 "ABI v0", /* use r5 as return register; only used in N1213HC */
3367 "ABI v1", /* use r0 as return register */
3368 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3369 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3370 "AABI",
3371 "ABI2 FP+"
35c08157
KLC
3372 };
3373 static const char *VER_STRINGS[] =
3374 {
3375 "Andes ELF V1.3 or older",
3376 "Andes ELF V1.3.1",
3377 "Andes ELF V1.4"
3378 };
3379 static const char *ARCH_STRINGS[] =
3380 {
3381 "",
3382 "Andes Star v1.0",
3383 "Andes Star v2.0",
3384 "Andes Star v3.0",
3385 "Andes Star v3.0m"
3386 };
3387
3388 abi = EF_NDS_ABI & e_flags;
3389 arch = EF_NDS_ARCH & e_flags;
3390 config = EF_NDS_INST & e_flags;
3391 version = EF_NDS32_ELF_VERSION & e_flags;
3392
3393 memset (buf, 0, size);
3394
3395 switch (abi)
3396 {
3397 case E_NDS_ABI_V0:
3398 case E_NDS_ABI_V1:
3399 case E_NDS_ABI_V2:
3400 case E_NDS_ABI_V2FP:
3401 case E_NDS_ABI_AABI:
40c7a7cb 3402 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3403 /* In case there are holes in the array. */
3404 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3405 break;
3406
3407 default:
3408 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3409 break;
3410 }
3411
3412 switch (version)
3413 {
3414 case E_NDS32_ELF_VER_1_2:
3415 case E_NDS32_ELF_VER_1_3:
3416 case E_NDS32_ELF_VER_1_4:
3417 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3418 break;
3419
3420 default:
3421 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3422 break;
3423 }
3424
3425 if (E_NDS_ABI_V0 == abi)
3426 {
3427 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3428 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3429 if (arch == E_NDS_ARCH_STAR_V1_0)
3430 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3431 return;
3432 }
3433
3434 switch (arch)
3435 {
3436 case E_NDS_ARCH_STAR_V1_0:
3437 case E_NDS_ARCH_STAR_V2_0:
3438 case E_NDS_ARCH_STAR_V3_0:
3439 case E_NDS_ARCH_STAR_V3_M:
3440 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3441 break;
3442
3443 default:
3444 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3445 /* ARCH version determines how the e_flags are interpreted.
3446 If it is unknown, we cannot proceed. */
3447 return;
3448 }
3449
3450 /* Newer ABI; Now handle architecture specific flags. */
3451 if (arch == E_NDS_ARCH_STAR_V1_0)
3452 {
3453 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3454 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3455
3456 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3457 r += snprintf (buf + r, size -r, ", MAC");
3458
3459 if (config & E_NDS32_HAS_DIV_INST)
3460 r += snprintf (buf + r, size -r, ", DIV");
3461
3462 if (config & E_NDS32_HAS_16BIT_INST)
3463 r += snprintf (buf + r, size -r, ", 16b");
3464 }
3465 else
3466 {
3467 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3468 {
3469 if (version <= E_NDS32_ELF_VER_1_3)
3470 r += snprintf (buf + r, size -r, ", [B8]");
3471 else
3472 r += snprintf (buf + r, size -r, ", EX9");
3473 }
3474
3475 if (config & E_NDS32_HAS_MAC_DX_INST)
3476 r += snprintf (buf + r, size -r, ", MAC_DX");
3477
3478 if (config & E_NDS32_HAS_DIV_DX_INST)
3479 r += snprintf (buf + r, size -r, ", DIV_DX");
3480
3481 if (config & E_NDS32_HAS_16BIT_INST)
3482 {
3483 if (version <= E_NDS32_ELF_VER_1_3)
3484 r += snprintf (buf + r, size -r, ", 16b");
3485 else
3486 r += snprintf (buf + r, size -r, ", IFC");
3487 }
3488 }
3489
3490 if (config & E_NDS32_HAS_EXT_INST)
3491 r += snprintf (buf + r, size -r, ", PERF1");
3492
3493 if (config & E_NDS32_HAS_EXT2_INST)
3494 r += snprintf (buf + r, size -r, ", PERF2");
3495
3496 if (config & E_NDS32_HAS_FPU_INST)
3497 {
015dc7e1 3498 has_fpu = true;
35c08157
KLC
3499 r += snprintf (buf + r, size -r, ", FPU_SP");
3500 }
3501
3502 if (config & E_NDS32_HAS_FPU_DP_INST)
3503 {
015dc7e1 3504 has_fpu = true;
35c08157
KLC
3505 r += snprintf (buf + r, size -r, ", FPU_DP");
3506 }
3507
3508 if (config & E_NDS32_HAS_FPU_MAC_INST)
3509 {
015dc7e1 3510 has_fpu = true;
35c08157
KLC
3511 r += snprintf (buf + r, size -r, ", FPU_MAC");
3512 }
3513
3514 if (has_fpu)
3515 {
3516 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3517 {
3518 case E_NDS32_FPU_REG_8SP_4DP:
3519 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3520 break;
3521 case E_NDS32_FPU_REG_16SP_8DP:
3522 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3523 break;
3524 case E_NDS32_FPU_REG_32SP_16DP:
3525 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3526 break;
3527 case E_NDS32_FPU_REG_32SP_32DP:
3528 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3529 break;
3530 }
3531 }
3532
3533 if (config & E_NDS32_HAS_AUDIO_INST)
3534 r += snprintf (buf + r, size -r, ", AUDIO");
3535
3536 if (config & E_NDS32_HAS_STRING_INST)
3537 r += snprintf (buf + r, size -r, ", STR");
3538
3539 if (config & E_NDS32_HAS_REDUCED_REGS)
3540 r += snprintf (buf + r, size -r, ", 16REG");
3541
3542 if (config & E_NDS32_HAS_VIDEO_INST)
3543 {
3544 if (version <= E_NDS32_ELF_VER_1_3)
3545 r += snprintf (buf + r, size -r, ", VIDEO");
3546 else
3547 r += snprintf (buf + r, size -r, ", SATURATION");
3548 }
3549
3550 if (config & E_NDS32_HAS_ENCRIPT_INST)
3551 r += snprintf (buf + r, size -r, ", ENCRP");
3552
3553 if (config & E_NDS32_HAS_L2C_INST)
3554 r += snprintf (buf + r, size -r, ", L2C");
3555}
3556
c077c580
SM
3557static void
3558decode_AMDGPU_machine_flags (Filedata *filedata, unsigned int e_flags,
3559 char *buf)
3560{
3561 unsigned char *e_ident = filedata->file_header.e_ident;
3562 unsigned char osabi = e_ident[EI_OSABI];
3563 unsigned char abiversion = e_ident[EI_ABIVERSION];
3564 unsigned int mach;
3565
3566 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
3567 it has been deprecated for a while.
3568
3569 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
3570 of writing, they use the same flags as HSA v3, so the code below uses that
3571 assumption. */
3572 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
3573 return;
3574
3575 mach = e_flags & EF_AMDGPU_MACH;
3576 switch (mach)
3577 {
3578#define AMDGPU_CASE(code, string) \
3579 case code: strcat (buf, ", " string); break;
3580 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
3581 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
3582 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
3583 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
3584 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
3585 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
3586 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
3587 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
3588 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
3589 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
3590 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
3591 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
3592 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
3593 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
3594 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
3595 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
3596 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
3597 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
3598 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
3599 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
3600 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
3601 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
3602 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
3603 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
3604 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
3605 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
3606 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
3607 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
3608 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
3609 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
3610 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
3611 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
3612 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
3613 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
3614 default:
3615 sprintf (buf, _(", <unknown AMDGPU GPU type: %#x>"), mach);
3616 break;
3617#undef AMDGPU_CASE
3618 }
3619
3620 buf += strlen (buf);
3621 e_flags &= ~EF_AMDGPU_MACH;
3622
3623 if ((osabi == ELFOSABI_AMDGPU_HSA
3624 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
3625 || osabi != ELFOSABI_AMDGPU_HSA)
3626 {
3627 /* For HSA v3 and other OS ABIs. */
3628 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
3629 {
3630 strcat (buf, ", xnack on");
3631 buf += strlen (buf);
3632 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
3633 }
3634
3635 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
3636 {
3637 strcat (buf, ", sramecc on");
3638 buf += strlen (buf);
3639 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
3640 }
3641 }
3642 else
3643 {
3644 /* For HSA v4+. */
3645 int xnack, sramecc;
3646
3647 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
3648 switch (xnack)
3649 {
3650 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
3651 break;
3652
3653 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
3654 strcat (buf, ", xnack any");
3655 break;
3656
3657 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
3658 strcat (buf, ", xnack off");
3659 break;
3660
3661 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
3662 strcat (buf, ", xnack on");
3663 break;
3664
3665 default:
3666 sprintf (buf, _(", <unknown xnack value: %#x>"), xnack);
3667 break;
3668 }
3669
3670 buf += strlen (buf);
3671 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
3672
3673 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
3674 switch (sramecc)
3675 {
3676 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
3677 break;
3678
3679 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
3680 strcat (buf, ", sramecc any");
3681 break;
3682
3683 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
3684 strcat (buf, ", sramecc off");
3685 break;
3686
3687 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
3688 strcat (buf, ", sramecc on");
3689 break;
3690
3691 default:
3692 sprintf (buf, _(", <unknown sramecc value: %#x>"), sramecc);
3693 break;
3694 }
3695
3696 buf += strlen (buf);
3697 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
3698 }
3699
3700 if (e_flags != 0)
3701 sprintf (buf, _(", unknown flags bits: %#x"), e_flags);
3702}
3703
252b5132 3704static char *
dda8d76d 3705get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3706{
b34976b6 3707 static char buf[1024];
252b5132
RH
3708
3709 buf[0] = '\0';
76da6bbe 3710
252b5132
RH
3711 if (e_flags)
3712 {
3713 switch (e_machine)
3714 {
3715 default:
3716 break;
3717
886a2506 3718 case EM_ARC_COMPACT2:
886a2506 3719 case EM_ARC_COMPACT:
a9522a21
AB
3720 decode_ARC_machine_flags (e_flags, e_machine, buf);
3721 break;
886a2506 3722
f3485b74
NC
3723 case EM_ARM:
3724 decode_ARM_machine_flags (e_flags, buf);
3725 break;
76da6bbe 3726
343433df
AB
3727 case EM_AVR:
3728 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3729 break;
3730
781303ce
MF
3731 case EM_BLACKFIN:
3732 if (e_flags & EF_BFIN_PIC)
3733 strcat (buf, ", PIC");
3734
3735 if (e_flags & EF_BFIN_FDPIC)
3736 strcat (buf, ", FDPIC");
3737
3738 if (e_flags & EF_BFIN_CODE_IN_L1)
3739 strcat (buf, ", code in L1");
3740
3741 if (e_flags & EF_BFIN_DATA_IN_L1)
3742 strcat (buf, ", data in L1");
3743
3744 break;
3745
ec2dfb42
AO
3746 case EM_CYGNUS_FRV:
3747 switch (e_flags & EF_FRV_CPU_MASK)
3748 {
3749 case EF_FRV_CPU_GENERIC:
3750 break;
3751
3752 default:
3753 strcat (buf, ", fr???");
3754 break;
57346661 3755
ec2dfb42
AO
3756 case EF_FRV_CPU_FR300:
3757 strcat (buf, ", fr300");
3758 break;
3759
3760 case EF_FRV_CPU_FR400:
3761 strcat (buf, ", fr400");
3762 break;
3763 case EF_FRV_CPU_FR405:
3764 strcat (buf, ", fr405");
3765 break;
3766
3767 case EF_FRV_CPU_FR450:
3768 strcat (buf, ", fr450");
3769 break;
3770
3771 case EF_FRV_CPU_FR500:
3772 strcat (buf, ", fr500");
3773 break;
3774 case EF_FRV_CPU_FR550:
3775 strcat (buf, ", fr550");
3776 break;
3777
3778 case EF_FRV_CPU_SIMPLE:
3779 strcat (buf, ", simple");
3780 break;
3781 case EF_FRV_CPU_TOMCAT:
3782 strcat (buf, ", tomcat");
3783 break;
3784 }
1c877e87 3785 break;
ec2dfb42 3786
53c7db4b 3787 case EM_68K:
425c6cb0 3788 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3789 strcat (buf, ", m68000");
425c6cb0 3790 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3791 strcat (buf, ", cpu32");
3792 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3793 strcat (buf, ", fido_a");
425c6cb0 3794 else
266abb8f 3795 {
2cf0635d
NC
3796 char const * isa = _("unknown");
3797 char const * mac = _("unknown mac");
3798 char const * additional = NULL;
0112cd26 3799
c694fd50 3800 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3801 {
c694fd50 3802 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3803 isa = "A";
3804 additional = ", nodiv";
3805 break;
c694fd50 3806 case EF_M68K_CF_ISA_A:
266abb8f
NS
3807 isa = "A";
3808 break;
c694fd50 3809 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3810 isa = "A+";
3811 break;
c694fd50 3812 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3813 isa = "B";
3814 additional = ", nousp";
3815 break;
c694fd50 3816 case EF_M68K_CF_ISA_B:
266abb8f
NS
3817 isa = "B";
3818 break;
f608cd77
NS
3819 case EF_M68K_CF_ISA_C:
3820 isa = "C";
3821 break;
3822 case EF_M68K_CF_ISA_C_NODIV:
3823 isa = "C";
3824 additional = ", nodiv";
3825 break;
266abb8f
NS
3826 }
3827 strcat (buf, ", cf, isa ");
3828 strcat (buf, isa);
0b2e31dc
NS
3829 if (additional)
3830 strcat (buf, additional);
c694fd50 3831 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3832 strcat (buf, ", float");
c694fd50 3833 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3834 {
3835 case 0:
3836 mac = NULL;
3837 break;
c694fd50 3838 case EF_M68K_CF_MAC:
266abb8f
NS
3839 mac = "mac";
3840 break;
c694fd50 3841 case EF_M68K_CF_EMAC:
266abb8f
NS
3842 mac = "emac";
3843 break;
f608cd77
NS
3844 case EF_M68K_CF_EMAC_B:
3845 mac = "emac_b";
3846 break;
266abb8f
NS
3847 }
3848 if (mac)
3849 {
3850 strcat (buf, ", ");
3851 strcat (buf, mac);
3852 }
266abb8f 3853 }
53c7db4b 3854 break;
33c63f9d 3855
c077c580
SM
3856 case EM_AMDGPU:
3857 decode_AMDGPU_machine_flags (filedata, e_flags, buf);
3858 break;
3859
153a2776
NC
3860 case EM_CYGNUS_MEP:
3861 switch (e_flags & EF_MEP_CPU_MASK)
3862 {
3863 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3864 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3865 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3866 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3867 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3868 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3869 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3870 }
3871
3872 switch (e_flags & EF_MEP_COP_MASK)
3873 {
3874 case EF_MEP_COP_NONE: break;
3875 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3876 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3877 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3878 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3879 default: strcat (buf, _("<unknown MeP copro type>")); break;
3880 }
3881
3882 if (e_flags & EF_MEP_LIBRARY)
3883 strcat (buf, ", Built for Library");
3884
3885 if (e_flags & EF_MEP_INDEX_MASK)
3886 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3887 e_flags & EF_MEP_INDEX_MASK);
3888
3889 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3890 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3891 e_flags & ~ EF_MEP_ALL_FLAGS);
3892 break;
3893
252b5132
RH
3894 case EM_PPC:
3895 if (e_flags & EF_PPC_EMB)
3896 strcat (buf, ", emb");
3897
3898 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3899 strcat (buf, _(", relocatable"));
252b5132
RH
3900
3901 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3902 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3903 break;
3904
ee67d69a
AM
3905 case EM_PPC64:
3906 if (e_flags & EF_PPC64_ABI)
3907 {
3908 char abi[] = ", abiv0";
3909
3910 abi[6] += e_flags & EF_PPC64_ABI;
3911 strcat (buf, abi);
3912 }
3913 break;
3914
708e2187
NC
3915 case EM_V800:
3916 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3917 strcat (buf, ", RH850 ABI");
0b4362b0 3918
708e2187
NC
3919 if (e_flags & EF_V800_850E3)
3920 strcat (buf, ", V3 architecture");
3921
3922 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3923 strcat (buf, ", FPU not used");
3924
3925 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3926 strcat (buf, ", regmode: COMMON");
3927
3928 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3929 strcat (buf, ", r4 not used");
3930
3931 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3932 strcat (buf, ", r30 not used");
3933
3934 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3935 strcat (buf, ", r5 not used");
3936
3937 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3938 strcat (buf, ", r2 not used");
3939
3940 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3941 {
3942 switch (e_flags & - e_flags)
3943 {
3944 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3945 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3946 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3947 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3948 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3949 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3950 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3951 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3952 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3953 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3954 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3955 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3956 default: break;
3957 }
3958 }
3959 break;
3960
2b0337b0 3961 case EM_V850:
252b5132
RH
3962 case EM_CYGNUS_V850:
3963 switch (e_flags & EF_V850_ARCH)
3964 {
78c8d46c
NC
3965 case E_V850E3V5_ARCH:
3966 strcat (buf, ", v850e3v5");
3967 break;
1cd986c5
NC
3968 case E_V850E2V3_ARCH:
3969 strcat (buf, ", v850e2v3");
3970 break;
3971 case E_V850E2_ARCH:
3972 strcat (buf, ", v850e2");
3973 break;
3974 case E_V850E1_ARCH:
3975 strcat (buf, ", v850e1");
8ad30312 3976 break;
252b5132
RH
3977 case E_V850E_ARCH:
3978 strcat (buf, ", v850e");
3979 break;
252b5132
RH
3980 case E_V850_ARCH:
3981 strcat (buf, ", v850");
3982 break;
3983 default:
2b692964 3984 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3985 break;
3986 }
3987 break;
3988
2b0337b0 3989 case EM_M32R:
252b5132
RH
3990 case EM_CYGNUS_M32R:
3991 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3992 strcat (buf, ", m32r");
252b5132
RH
3993 break;
3994
3995 case EM_MIPS:
4fe85591 3996 case EM_MIPS_RS3_LE:
252b5132
RH
3997 if (e_flags & EF_MIPS_NOREORDER)
3998 strcat (buf, ", noreorder");
3999
4000 if (e_flags & EF_MIPS_PIC)
4001 strcat (buf, ", pic");
4002
4003 if (e_flags & EF_MIPS_CPIC)
4004 strcat (buf, ", cpic");
4005
d1bdd336
TS
4006 if (e_flags & EF_MIPS_UCODE)
4007 strcat (buf, ", ugen_reserved");
4008
252b5132
RH
4009 if (e_flags & EF_MIPS_ABI2)
4010 strcat (buf, ", abi2");
4011
43521d43
TS
4012 if (e_flags & EF_MIPS_OPTIONS_FIRST)
4013 strcat (buf, ", odk first");
4014
a5d22d2a
TS
4015 if (e_flags & EF_MIPS_32BITMODE)
4016 strcat (buf, ", 32bitmode");
4017
ba92f887
MR
4018 if (e_flags & EF_MIPS_NAN2008)
4019 strcat (buf, ", nan2008");
4020
fef1b0b3
SE
4021 if (e_flags & EF_MIPS_FP64)
4022 strcat (buf, ", fp64");
4023
156c2f8b
NC
4024 switch ((e_flags & EF_MIPS_MACH))
4025 {
4026 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
4027 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
4028 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 4029 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
4030 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
4031 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
4032 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
4033 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 4034 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 4035 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 4036 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
4037 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
4038 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 4039 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 4040 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 4041 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 4042 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 4043 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 4044 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 4045 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 4046 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
4047 case 0:
4048 /* We simply ignore the field in this case to avoid confusion:
4049 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4050 extension. */
4051 break;
2b692964 4052 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 4053 }
43521d43
TS
4054
4055 switch ((e_flags & EF_MIPS_ABI))
4056 {
4057 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
4058 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
4059 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
4060 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
4061 case 0:
4062 /* We simply ignore the field in this case to avoid confusion:
4063 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4064 This means it is likely to be an o32 file, but not for
4065 sure. */
4066 break;
2b692964 4067 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
4068 }
4069
4070 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4071 strcat (buf, ", mdmx");
4072
4073 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4074 strcat (buf, ", mips16");
4075
df58fc94
RS
4076 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4077 strcat (buf, ", micromips");
4078
43521d43
TS
4079 switch ((e_flags & EF_MIPS_ARCH))
4080 {
4081 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
4082 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
4083 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
4084 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
4085 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
4086 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 4087 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 4088 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 4089 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 4090 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 4091 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 4092 default: strcat (buf, _(", unknown ISA")); break;
43521d43 4093 }
252b5132 4094 break;
351b4b40 4095
35c08157
KLC
4096 case EM_NDS32:
4097 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
4098 break;
4099
fe944acf
FT
4100 case EM_NFP:
4101 switch (EF_NFP_MACH (e_flags))
4102 {
4103 case E_NFP_MACH_3200:
4104 strcat (buf, ", NFP-32xx");
4105 break;
4106 case E_NFP_MACH_6000:
4107 strcat (buf, ", NFP-6xxx");
4108 break;
4109 }
4110 break;
4111
e23eba97
NC
4112 case EM_RISCV:
4113 if (e_flags & EF_RISCV_RVC)
4114 strcat (buf, ", RVC");
2922d21d 4115
7f999549
JW
4116 if (e_flags & EF_RISCV_RVE)
4117 strcat (buf, ", RVE");
4118
96462b01
S
4119 if (e_flags & EF_RISCV_TSO)
4120 strcat (buf, ", TSO");
4121
2922d21d
AW
4122 switch (e_flags & EF_RISCV_FLOAT_ABI)
4123 {
4124 case EF_RISCV_FLOAT_ABI_SOFT:
4125 strcat (buf, ", soft-float ABI");
4126 break;
4127
4128 case EF_RISCV_FLOAT_ABI_SINGLE:
4129 strcat (buf, ", single-float ABI");
4130 break;
4131
4132 case EF_RISCV_FLOAT_ABI_DOUBLE:
4133 strcat (buf, ", double-float ABI");
4134 break;
4135
4136 case EF_RISCV_FLOAT_ABI_QUAD:
4137 strcat (buf, ", quad-float ABI");
4138 break;
4139 }
e23eba97
NC
4140 break;
4141
ccde1100
AO
4142 case EM_SH:
4143 switch ((e_flags & EF_SH_MACH_MASK))
4144 {
4145 case EF_SH1: strcat (buf, ", sh1"); break;
4146 case EF_SH2: strcat (buf, ", sh2"); break;
4147 case EF_SH3: strcat (buf, ", sh3"); break;
4148 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
4149 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
4150 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
4151 case EF_SH3E: strcat (buf, ", sh3e"); break;
4152 case EF_SH4: strcat (buf, ", sh4"); break;
4153 case EF_SH5: strcat (buf, ", sh5"); break;
4154 case EF_SH2E: strcat (buf, ", sh2e"); break;
4155 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 4156 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
4157 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
4158 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 4159 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
4160 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
4161 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
4162 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
4163 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
4164 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
4165 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 4166 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
4167 }
4168
cec6a5b8
MR
4169 if (e_flags & EF_SH_PIC)
4170 strcat (buf, ", pic");
4171
4172 if (e_flags & EF_SH_FDPIC)
4173 strcat (buf, ", fdpic");
ccde1100 4174 break;
948f632f 4175
73589c9d
CS
4176 case EM_OR1K:
4177 if (e_flags & EF_OR1K_NODELAY)
4178 strcat (buf, ", no delay");
4179 break;
57346661 4180
351b4b40
RH
4181 case EM_SPARCV9:
4182 if (e_flags & EF_SPARC_32PLUS)
4183 strcat (buf, ", v8+");
4184
4185 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
4186 strcat (buf, ", ultrasparcI");
4187
4188 if (e_flags & EF_SPARC_SUN_US3)
4189 strcat (buf, ", ultrasparcIII");
351b4b40
RH
4190
4191 if (e_flags & EF_SPARC_HAL_R1)
4192 strcat (buf, ", halr1");
4193
4194 if (e_flags & EF_SPARC_LEDATA)
4195 strcat (buf, ", ledata");
4196
4197 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4198 strcat (buf, ", tso");
4199
4200 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4201 strcat (buf, ", pso");
4202
4203 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4204 strcat (buf, ", rmo");
4205 break;
7d466069 4206
103f02d3
UD
4207 case EM_PARISC:
4208 switch (e_flags & EF_PARISC_ARCH)
4209 {
4210 case EFA_PARISC_1_0:
4211 strcpy (buf, ", PA-RISC 1.0");
4212 break;
4213 case EFA_PARISC_1_1:
4214 strcpy (buf, ", PA-RISC 1.1");
4215 break;
4216 case EFA_PARISC_2_0:
4217 strcpy (buf, ", PA-RISC 2.0");
4218 break;
4219 default:
4220 break;
4221 }
4222 if (e_flags & EF_PARISC_TRAPNIL)
4223 strcat (buf, ", trapnil");
4224 if (e_flags & EF_PARISC_EXT)
4225 strcat (buf, ", ext");
4226 if (e_flags & EF_PARISC_LSB)
4227 strcat (buf, ", lsb");
4228 if (e_flags & EF_PARISC_WIDE)
4229 strcat (buf, ", wide");
4230 if (e_flags & EF_PARISC_NO_KABP)
4231 strcat (buf, ", no kabp");
4232 if (e_flags & EF_PARISC_LAZYSWAP)
4233 strcat (buf, ", lazyswap");
30800947 4234 break;
76da6bbe 4235
7d466069 4236 case EM_PJ:
2b0337b0 4237 case EM_PJ_OLD:
7d466069
ILT
4238 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4239 strcat (buf, ", new calling convention");
4240
4241 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4242 strcat (buf, ", gnu calling convention");
4243 break;
4d6ed7c8
NC
4244
4245 case EM_IA_64:
4246 if ((e_flags & EF_IA_64_ABI64))
4247 strcat (buf, ", 64-bit");
4248 else
4249 strcat (buf, ", 32-bit");
4250 if ((e_flags & EF_IA_64_REDUCEDFP))
4251 strcat (buf, ", reduced fp model");
4252 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4253 strcat (buf, ", no function descriptors, constant gp");
4254 else if ((e_flags & EF_IA_64_CONS_GP))
4255 strcat (buf, ", constant gp");
4256 if ((e_flags & EF_IA_64_ABSOLUTE))
4257 strcat (buf, ", absolute");
dda8d76d 4258 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
4259 {
4260 if ((e_flags & EF_IA_64_VMS_LINKAGES))
4261 strcat (buf, ", vms_linkages");
4262 switch ((e_flags & EF_IA_64_VMS_COMCOD))
4263 {
4264 case EF_IA_64_VMS_COMCOD_SUCCESS:
4265 break;
4266 case EF_IA_64_VMS_COMCOD_WARNING:
4267 strcat (buf, ", warning");
4268 break;
4269 case EF_IA_64_VMS_COMCOD_ERROR:
4270 strcat (buf, ", error");
4271 break;
4272 case EF_IA_64_VMS_COMCOD_ABORT:
4273 strcat (buf, ", abort");
4274 break;
4275 default:
bee0ee85
NC
4276 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
4277 e_flags & EF_IA_64_VMS_COMCOD);
4278 strcat (buf, ", <unknown>");
28f997cf
TG
4279 }
4280 }
4d6ed7c8 4281 break;
179d3252
JT
4282
4283 case EM_VAX:
4284 if ((e_flags & EF_VAX_NONPIC))
4285 strcat (buf, ", non-PIC");
4286 if ((e_flags & EF_VAX_DFLOAT))
4287 strcat (buf, ", D-Float");
4288 if ((e_flags & EF_VAX_GFLOAT))
4289 strcat (buf, ", G-Float");
4290 break;
c7927a3c 4291
619ed720
EB
4292 case EM_VISIUM:
4293 if (e_flags & EF_VISIUM_ARCH_MCM)
4294 strcat (buf, ", mcm");
4295 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4296 strcat (buf, ", mcm24");
4297 if (e_flags & EF_VISIUM_ARCH_GR6)
4298 strcat (buf, ", gr6");
4299 break;
4300
4046d87a 4301 case EM_RL78:
1740ba0c
NC
4302 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4303 {
4304 case E_FLAG_RL78_ANY_CPU: break;
4305 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
4306 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
4307 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
4308 }
856ea05c
KP
4309 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4310 strcat (buf, ", 64-bit doubles");
4046d87a 4311 break;
0b4362b0 4312
c7927a3c
NC
4313 case EM_RX:
4314 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4315 strcat (buf, ", 64-bit doubles");
4316 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 4317 strcat (buf, ", dsp");
d4cb0ea0 4318 if (e_flags & E_FLAG_RX_PID)
0b4362b0 4319 strcat (buf, ", pid");
708e2187
NC
4320 if (e_flags & E_FLAG_RX_ABI)
4321 strcat (buf, ", RX ABI");
3525236c
NC
4322 if (e_flags & E_FLAG_RX_SINSNS_SET)
4323 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
4324 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
4325 if (e_flags & E_FLAG_RX_V2)
4326 strcat (buf, ", V2");
f87673e0
YS
4327 if (e_flags & E_FLAG_RX_V3)
4328 strcat (buf, ", V3");
d4cb0ea0 4329 break;
55786da2
AK
4330
4331 case EM_S390:
4332 if (e_flags & EF_S390_HIGH_GPRS)
4333 strcat (buf, ", highgprs");
d4cb0ea0 4334 break;
40b36596
JM
4335
4336 case EM_TI_C6000:
4337 if ((e_flags & EF_C6000_REL))
4338 strcat (buf, ", relocatable module");
d4cb0ea0 4339 break;
13761a11
NC
4340
4341 case EM_MSP430:
4342 strcat (buf, _(": architecture variant: "));
4343 switch (e_flags & EF_MSP430_MACH)
4344 {
4345 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
4346 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
4347 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
4348 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
4349 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
4350 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
4351 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
4352 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
4353 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
4354 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
4355 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
4356 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
4357 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
4358 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
4359 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
4360 default:
4361 strcat (buf, _(": unknown")); break;
4362 }
4363
4364 if (e_flags & ~ EF_MSP430_MACH)
4365 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
4366 break;
4367
4368 case EM_Z80:
4369 switch (e_flags & EF_Z80_MACH_MSK)
4370 {
4371 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
4372 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
4373 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
4374 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
4375 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
4376 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 4377 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
4378 default:
4379 strcat (buf, _(", unknown")); break;
4380 }
4381 break;
e9a0721f 4382 case EM_LOONGARCH:
e9a0721f 4383 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
4384 strcat (buf, ", SOFT-FLOAT");
4385 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
4386 strcat (buf, ", SINGLE-FLOAT");
4387 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
4388 strcat (buf, ", DOUBLE-FLOAT");
4389
c4a7e6b5 4390 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
4391 strcat (buf, ", OBJ-v0");
4392 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
4393 strcat (buf, ", OBJ-v1");
4394
e9a0721f 4395 break;
252b5132
RH
4396 }
4397 }
4398
4399 return buf;
4400}
4401
252b5132 4402static const char *
dda8d76d 4403get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4404{
4405 static char buff[32];
4406
4407 switch (osabi)
4408 {
4409 case ELFOSABI_NONE: return "UNIX - System V";
4410 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4411 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4412 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4413 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4414 case ELFOSABI_AIX: return "UNIX - AIX";
4415 case ELFOSABI_IRIX: return "UNIX - IRIX";
4416 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4417 case ELFOSABI_TRU64: return "UNIX - TRU64";
4418 case ELFOSABI_MODESTO: return "Novell - Modesto";
4419 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4420 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4421 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4422 case ELFOSABI_AROS: return "AROS";
11636f9e 4423 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4424 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4425 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4426 default:
40b36596 4427 if (osabi >= 64)
dda8d76d 4428 switch (filedata->file_header.e_machine)
40b36596 4429 {
37870be8
SM
4430 case EM_AMDGPU:
4431 switch (osabi)
4432 {
4433 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4434 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4435 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4436 default:
4437 break;
4438 }
4439 break;
4440
40b36596
JM
4441 case EM_ARM:
4442 switch (osabi)
4443 {
4444 case ELFOSABI_ARM: return "ARM";
18a20338 4445 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4446 default:
4447 break;
4448 }
4449 break;
4450
4451 case EM_MSP430:
4452 case EM_MSP430_OLD:
619ed720 4453 case EM_VISIUM:
40b36596
JM
4454 switch (osabi)
4455 {
4456 case ELFOSABI_STANDALONE: return _("Standalone App");
4457 default:
4458 break;
4459 }
4460 break;
4461
4462 case EM_TI_C6000:
4463 switch (osabi)
4464 {
4465 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4466 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4467 default:
4468 break;
4469 }
4470 break;
4471
4472 default:
4473 break;
4474 }
e9e44622 4475 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4476 return buff;
4477 }
4478}
4479
a06ea964
NC
4480static const char *
4481get_aarch64_segment_type (unsigned long type)
4482{
4483 switch (type)
4484 {
32ec8896 4485 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4486 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4487 default: return NULL;
a06ea964 4488 }
a06ea964
NC
4489}
4490
b294bdf8
MM
4491static const char *
4492get_arm_segment_type (unsigned long type)
4493{
4494 switch (type)
4495 {
32ec8896
NC
4496 case PT_ARM_EXIDX: return "EXIDX";
4497 default: return NULL;
b294bdf8 4498 }
b294bdf8
MM
4499}
4500
b4cbbe8f
AK
4501static const char *
4502get_s390_segment_type (unsigned long type)
4503{
4504 switch (type)
4505 {
4506 case PT_S390_PGSTE: return "S390_PGSTE";
4507 default: return NULL;
4508 }
4509}
4510
d3ba0551
AM
4511static const char *
4512get_mips_segment_type (unsigned long type)
252b5132
RH
4513{
4514 switch (type)
4515 {
32ec8896
NC
4516 case PT_MIPS_REGINFO: return "REGINFO";
4517 case PT_MIPS_RTPROC: return "RTPROC";
4518 case PT_MIPS_OPTIONS: return "OPTIONS";
4519 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4520 default: return NULL;
252b5132 4521 }
252b5132
RH
4522}
4523
103f02d3 4524static const char *
d3ba0551 4525get_parisc_segment_type (unsigned long type)
103f02d3
UD
4526{
4527 switch (type)
4528 {
103f02d3
UD
4529 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4530 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4531 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4532 default: return NULL;
103f02d3 4533 }
103f02d3
UD
4534}
4535
4d6ed7c8 4536static const char *
d3ba0551 4537get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4538{
4539 switch (type)
4540 {
4541 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4542 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4543 default: return NULL;
4d6ed7c8 4544 }
4d6ed7c8
NC
4545}
4546
40b36596
JM
4547static const char *
4548get_tic6x_segment_type (unsigned long type)
4549{
4550 switch (type)
4551 {
32ec8896
NC
4552 case PT_C6000_PHATTR: return "C6000_PHATTR";
4553 default: return NULL;
40b36596 4554 }
40b36596
JM
4555}
4556
fbc95f1e
KC
4557static const char *
4558get_riscv_segment_type (unsigned long type)
4559{
4560 switch (type)
4561 {
4562 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4563 default: return NULL;
4564 }
4565}
4566
df3a023b
AM
4567static const char *
4568get_hpux_segment_type (unsigned long type, unsigned e_machine)
4569{
4570 if (e_machine == EM_PARISC)
4571 switch (type)
4572 {
4573 case PT_HP_TLS: return "HP_TLS";
4574 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4575 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4576 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4577 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4578 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4579 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4580 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4581 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4582 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4583 case PT_HP_PARALLEL: return "HP_PARALLEL";
4584 case PT_HP_FASTBIND: return "HP_FASTBIND";
4585 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4586 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4587 case PT_HP_STACK: return "HP_STACK";
4588 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4589 default: return NULL;
4590 }
4591
4592 if (e_machine == EM_IA_64)
4593 switch (type)
4594 {
4595 case PT_HP_TLS: return "HP_TLS";
4596 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4597 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4598 case PT_IA_64_HP_STACK: return "HP_STACK";
4599 default: return NULL;
4600 }
4601
4602 return NULL;
4603}
4604
5522f910
NC
4605static const char *
4606get_solaris_segment_type (unsigned long type)
4607{
4608 switch (type)
4609 {
4610 case 0x6464e550: return "PT_SUNW_UNWIND";
4611 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4612 case 0x6ffffff7: return "PT_LOSUNW";
4613 case 0x6ffffffa: return "PT_SUNWBSS";
4614 case 0x6ffffffb: return "PT_SUNWSTACK";
4615 case 0x6ffffffc: return "PT_SUNWDTRACE";
4616 case 0x6ffffffd: return "PT_SUNWCAP";
4617 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4618 default: return NULL;
5522f910
NC
4619 }
4620}
4621
252b5132 4622static const char *
dda8d76d 4623get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4624{
b34976b6 4625 static char buff[32];
252b5132
RH
4626
4627 switch (p_type)
4628 {
b34976b6
AM
4629 case PT_NULL: return "NULL";
4630 case PT_LOAD: return "LOAD";
252b5132 4631 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4632 case PT_INTERP: return "INTERP";
4633 case PT_NOTE: return "NOTE";
4634 case PT_SHLIB: return "SHLIB";
4635 case PT_PHDR: return "PHDR";
13ae64f3 4636 case PT_TLS: return "TLS";
32ec8896 4637 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4638 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4639 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4640 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
cf0e0a0b 4641 case PT_GNU_SFRAME: return "GNU_SFRAME";
65765700 4642
80251d41 4643 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
3eba3ef3
NC
4644 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4645 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4646 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4647
252b5132 4648 default:
df3a023b 4649 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4650 {
2cf0635d 4651 const char * result;
103f02d3 4652
dda8d76d 4653 switch (filedata->file_header.e_machine)
252b5132 4654 {
a06ea964
NC
4655 case EM_AARCH64:
4656 result = get_aarch64_segment_type (p_type);
4657 break;
b294bdf8
MM
4658 case EM_ARM:
4659 result = get_arm_segment_type (p_type);
4660 break;
252b5132 4661 case EM_MIPS:
4fe85591 4662 case EM_MIPS_RS3_LE:
252b5132
RH
4663 result = get_mips_segment_type (p_type);
4664 break;
103f02d3
UD
4665 case EM_PARISC:
4666 result = get_parisc_segment_type (p_type);
4667 break;
4d6ed7c8
NC
4668 case EM_IA_64:
4669 result = get_ia64_segment_type (p_type);
4670 break;
40b36596
JM
4671 case EM_TI_C6000:
4672 result = get_tic6x_segment_type (p_type);
4673 break;
b4cbbe8f
AK
4674 case EM_S390:
4675 case EM_S390_OLD:
4676 result = get_s390_segment_type (p_type);
4677 break;
fbc95f1e
KC
4678 case EM_RISCV:
4679 result = get_riscv_segment_type (p_type);
4680 break;
252b5132
RH
4681 default:
4682 result = NULL;
4683 break;
4684 }
103f02d3 4685
252b5132
RH
4686 if (result != NULL)
4687 return result;
103f02d3 4688
1a9ccd70 4689 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4690 }
4691 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4692 {
df3a023b 4693 const char * result = NULL;
103f02d3 4694
df3a023b 4695 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4696 {
df3a023b
AM
4697 case ELFOSABI_GNU:
4698 case ELFOSABI_FREEBSD:
4699 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4700 {
4701 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4702 result = buff;
4703 }
103f02d3 4704 break;
df3a023b
AM
4705 case ELFOSABI_HPUX:
4706 result = get_hpux_segment_type (p_type,
4707 filedata->file_header.e_machine);
4708 break;
4709 case ELFOSABI_SOLARIS:
4710 result = get_solaris_segment_type (p_type);
00428cca 4711 break;
103f02d3 4712 default:
103f02d3
UD
4713 break;
4714 }
103f02d3
UD
4715 if (result != NULL)
4716 return result;
4717
1a9ccd70 4718 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4719 }
252b5132 4720 else
e9e44622 4721 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4722
4723 return buff;
4724 }
4725}
4726
53a346d8
CZ
4727static const char *
4728get_arc_section_type_name (unsigned int sh_type)
4729{
4730 switch (sh_type)
4731 {
4732 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4733 default:
4734 break;
4735 }
4736 return NULL;
4737}
4738
252b5132 4739static const char *
d3ba0551 4740get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4741{
4742 switch (sh_type)
4743 {
b34976b6
AM
4744 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4745 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4746 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4747 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4748 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4749 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4750 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4751 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4752 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4753 case SHT_MIPS_RELD: return "MIPS_RELD";
4754 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4755 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4756 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4757 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4758 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4759 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4760 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4761 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4762 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4763 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4764 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4765 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4766 case SHT_MIPS_LINE: return "MIPS_LINE";
4767 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4768 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4769 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4770 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4771 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4772 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4773 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4774 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4775 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4776 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4777 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4778 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4779 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4780 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4781 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4782 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4783 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4784 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4785 default:
4786 break;
4787 }
4788 return NULL;
4789}
4790
103f02d3 4791static const char *
d3ba0551 4792get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4793{
4794 switch (sh_type)
4795 {
4796 case SHT_PARISC_EXT: return "PARISC_EXT";
4797 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4798 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4799 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4800 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4801 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4802 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4803 default: return NULL;
103f02d3 4804 }
103f02d3
UD
4805}
4806
4d6ed7c8 4807static const char *
dda8d76d 4808get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4809{
18bd398b 4810 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4811 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4812 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4813
4d6ed7c8
NC
4814 switch (sh_type)
4815 {
148b93f2
NC
4816 case SHT_IA_64_EXT: return "IA_64_EXT";
4817 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4818 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4819 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4820 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4821 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4822 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4823 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4824 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4825 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4826 default:
4827 break;
4828 }
4829 return NULL;
4830}
4831
d2b2c203
DJ
4832static const char *
4833get_x86_64_section_type_name (unsigned int sh_type)
4834{
4835 switch (sh_type)
4836 {
4837 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4838 default: return NULL;
d2b2c203 4839 }
d2b2c203
DJ
4840}
4841
a06ea964
NC
4842static const char *
4843get_aarch64_section_type_name (unsigned int sh_type)
4844{
4845 switch (sh_type)
4846 {
32ec8896
NC
4847 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4848 default: return NULL;
a06ea964 4849 }
a06ea964
NC
4850}
4851
40a18ebd
NC
4852static const char *
4853get_arm_section_type_name (unsigned int sh_type)
4854{
4855 switch (sh_type)
4856 {
7f6fed87
NC
4857 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4858 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4859 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4860 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4861 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4862 default: return NULL;
40a18ebd 4863 }
40a18ebd
NC
4864}
4865
40b36596
JM
4866static const char *
4867get_tic6x_section_type_name (unsigned int sh_type)
4868{
4869 switch (sh_type)
4870 {
32ec8896
NC
4871 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4872 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4873 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4874 case SHT_TI_ICODE: return "TI_ICODE";
4875 case SHT_TI_XREF: return "TI_XREF";
4876 case SHT_TI_HANDLER: return "TI_HANDLER";
4877 case SHT_TI_INITINFO: return "TI_INITINFO";
4878 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4879 default: return NULL;
40b36596 4880 }
40b36596
JM
4881}
4882
13761a11 4883static const char *
b0191216 4884get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4885{
4886 switch (sh_type)
4887 {
32ec8896
NC
4888 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4889 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4890 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4891 default: return NULL;
13761a11
NC
4892 }
4893}
4894
fe944acf
FT
4895static const char *
4896get_nfp_section_type_name (unsigned int sh_type)
4897{
4898 switch (sh_type)
4899 {
4900 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4901 case SHT_NFP_INITREG: return "NFP_INITREG";
4902 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4903 default: return NULL;
4904 }
4905}
4906
685080f2
NC
4907static const char *
4908get_v850_section_type_name (unsigned int sh_type)
4909{
4910 switch (sh_type)
4911 {
32ec8896
NC
4912 case SHT_V850_SCOMMON: return "V850 Small Common";
4913 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4914 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4915 case SHT_RENESAS_IOP: return "RENESAS IOP";
4916 case SHT_RENESAS_INFO: return "RENESAS INFO";
4917 default: return NULL;
685080f2
NC
4918 }
4919}
4920
2dc8dd17
JW
4921static const char *
4922get_riscv_section_type_name (unsigned int sh_type)
4923{
4924 switch (sh_type)
4925 {
4926 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4927 default: return NULL;
4928 }
4929}
4930
0861f561
CQ
4931static const char *
4932get_csky_section_type_name (unsigned int sh_type)
4933{
4934 switch (sh_type)
4935 {
4936 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4937 default: return NULL;
4938 }
4939}
4940
252b5132 4941static const char *
dda8d76d 4942get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4943{
b34976b6 4944 static char buff[32];
9fb71ee4 4945 const char * result;
252b5132
RH
4946
4947 switch (sh_type)
4948 {
4949 case SHT_NULL: return "NULL";
4950 case SHT_PROGBITS: return "PROGBITS";
4951 case SHT_SYMTAB: return "SYMTAB";
4952 case SHT_STRTAB: return "STRTAB";
4953 case SHT_RELA: return "RELA";
dd207c13 4954 case SHT_RELR: return "RELR";
252b5132
RH
4955 case SHT_HASH: return "HASH";
4956 case SHT_DYNAMIC: return "DYNAMIC";
4957 case SHT_NOTE: return "NOTE";
4958 case SHT_NOBITS: return "NOBITS";
4959 case SHT_REL: return "REL";
4960 case SHT_SHLIB: return "SHLIB";
4961 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4962 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4963 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4964 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4965 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4966 case SHT_GROUP: return "GROUP";
67ce483b 4967 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4968 case SHT_GNU_verdef: return "VERDEF";
4969 case SHT_GNU_verneed: return "VERNEED";
4970 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4971 case 0x6ffffff0: return "VERSYM";
4972 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4973 case 0x7ffffffd: return "AUXILIARY";
4974 case 0x7fffffff: return "FILTER";
047b2264 4975 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4976
4977 default:
4978 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4979 {
dda8d76d 4980 switch (filedata->file_header.e_machine)
252b5132 4981 {
53a346d8
CZ
4982 case EM_ARC:
4983 case EM_ARC_COMPACT:
4984 case EM_ARC_COMPACT2:
4985 result = get_arc_section_type_name (sh_type);
4986 break;
252b5132 4987 case EM_MIPS:
4fe85591 4988 case EM_MIPS_RS3_LE:
252b5132
RH
4989 result = get_mips_section_type_name (sh_type);
4990 break;
103f02d3
UD
4991 case EM_PARISC:
4992 result = get_parisc_section_type_name (sh_type);
4993 break;
4d6ed7c8 4994 case EM_IA_64:
dda8d76d 4995 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4996 break;
d2b2c203 4997 case EM_X86_64:
8a9036a4 4998 case EM_L1OM:
7a9068fe 4999 case EM_K1OM:
d2b2c203
DJ
5000 result = get_x86_64_section_type_name (sh_type);
5001 break;
a06ea964
NC
5002 case EM_AARCH64:
5003 result = get_aarch64_section_type_name (sh_type);
5004 break;
40a18ebd
NC
5005 case EM_ARM:
5006 result = get_arm_section_type_name (sh_type);
5007 break;
40b36596
JM
5008 case EM_TI_C6000:
5009 result = get_tic6x_section_type_name (sh_type);
5010 break;
13761a11 5011 case EM_MSP430:
b0191216 5012 result = get_msp430_section_type_name (sh_type);
13761a11 5013 break;
fe944acf
FT
5014 case EM_NFP:
5015 result = get_nfp_section_type_name (sh_type);
5016 break;
685080f2
NC
5017 case EM_V800:
5018 case EM_V850:
5019 case EM_CYGNUS_V850:
5020 result = get_v850_section_type_name (sh_type);
5021 break;
2dc8dd17
JW
5022 case EM_RISCV:
5023 result = get_riscv_section_type_name (sh_type);
5024 break;
0861f561
CQ
5025 case EM_CSKY:
5026 result = get_csky_section_type_name (sh_type);
5027 break;
252b5132
RH
5028 default:
5029 result = NULL;
5030 break;
5031 }
5032
5033 if (result != NULL)
5034 return result;
5035
9fb71ee4 5036 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5037 }
5038 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5039 {
dda8d76d 5040 switch (filedata->file_header.e_machine)
148b93f2
NC
5041 {
5042 case EM_IA_64:
dda8d76d 5043 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5044 break;
5045 default:
dda8d76d 5046 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5047 result = get_solaris_section_type (sh_type);
5048 else
1b4b80bf
NC
5049 {
5050 switch (sh_type)
5051 {
5052 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5053 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5054 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5055 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5056 default:
5057 result = NULL;
5058 break;
5059 }
5060 }
148b93f2
NC
5061 break;
5062 }
5063
5064 if (result != NULL)
5065 return result;
5066
9fb71ee4 5067 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5068 }
252b5132 5069 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5070 {
dda8d76d 5071 switch (filedata->file_header.e_machine)
685080f2
NC
5072 {
5073 case EM_V800:
5074 case EM_V850:
5075 case EM_CYGNUS_V850:
9fb71ee4 5076 result = get_v850_section_type_name (sh_type);
a9fb83be 5077 break;
685080f2 5078 default:
9fb71ee4 5079 result = NULL;
685080f2
NC
5080 break;
5081 }
5082
9fb71ee4
NC
5083 if (result != NULL)
5084 return result;
5085
5086 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5087 }
252b5132 5088 else
a7dbfd1c
NC
5089 /* This message is probably going to be displayed in a 15
5090 character wide field, so put the hex value first. */
5091 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5092
252b5132
RH
5093 return buff;
5094 }
5095}
5096
79bc120c
NC
5097enum long_option_values
5098{
5099 OPTION_DEBUG_DUMP = 512,
5100 OPTION_DYN_SYMS,
0f03783c 5101 OPTION_LTO_SYMS,
79bc120c
NC
5102 OPTION_DWARF_DEPTH,
5103 OPTION_DWARF_START,
5104 OPTION_DWARF_CHECK,
5105 OPTION_CTF_DUMP,
5106 OPTION_CTF_PARENT,
5107 OPTION_CTF_SYMBOLS,
5108 OPTION_CTF_STRINGS,
42b6953b 5109 OPTION_SFRAME_DUMP,
79bc120c
NC
5110 OPTION_WITH_SYMBOL_VERSIONS,
5111 OPTION_RECURSE_LIMIT,
5112 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
5113 OPTION_NO_DEMANGLING,
5114 OPTION_SYM_BASE
79bc120c 5115};
2979dc34 5116
85b1c36d 5117static struct option options[] =
252b5132 5118{
79bc120c
NC
5119 /* Note - This table is alpha-sorted on the 'val'
5120 field in order to make adding new options easier. */
5121 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5122 {"all", no_argument, 0, 'a'},
79bc120c
NC
5123 {"demangle", optional_argument, 0, 'C'},
5124 {"archive-index", no_argument, 0, 'c'},
5125 {"use-dynamic", no_argument, 0, 'D'},
5126 {"dynamic", no_argument, 0, 'd'},
b34976b6 5127 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5128 {"section-groups", no_argument, 0, 'g'},
5129 {"help", no_argument, 0, 'H'},
5130 {"file-header", no_argument, 0, 'h'},
b34976b6 5131 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5132 {"lint", no_argument, 0, 'L'},
5133 {"enable-checks", no_argument, 0, 'L'},
5134 {"program-headers", no_argument, 0, 'l'},
b34976b6 5135 {"segments", no_argument, 0, 'l'},
595cf52e 5136 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5137 {"notes", no_argument, 0, 'n'},
ca0e11aa 5138 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5139 {"string-dump", required_argument, 0, 'p'},
5140 {"relocated-dump", required_argument, 0, 'R'},
5141 {"relocs", no_argument, 0, 'r'},
5142 {"section-headers", no_argument, 0, 'S'},
5143 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5144 {"symbols", no_argument, 0, 's'},
5145 {"syms", no_argument, 0, 's'},
79bc120c
NC
5146 {"silent-truncation",no_argument, 0, 'T'},
5147 {"section-details", no_argument, 0, 't'},
b3aa80b4 5148 {"unicode", required_argument, NULL, 'U'},
09c11c86 5149 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5150 {"version-info", no_argument, 0, 'V'},
5151 {"version", no_argument, 0, 'v'},
5152 {"wide", no_argument, 0, 'W'},
b34976b6 5153 {"hex-dump", required_argument, 0, 'x'},
0e602686 5154 {"decompress", no_argument, 0, 'z'},
252b5132 5155
79bc120c
NC
5156 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5157 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5158 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5159 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5160 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5161 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5162 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5163 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5164 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5165 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5166#ifdef ENABLE_LIBCTF
d344b407 5167 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5168 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5169 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5170 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5171#endif
42b6953b 5172 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
047c3dbf 5173 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5174
b34976b6 5175 {0, no_argument, 0, 0}
252b5132
RH
5176};
5177
5178static void
2cf0635d 5179usage (FILE * stream)
252b5132 5180{
92f01d61
JM
5181 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5182 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5183 fprintf (stream, _(" Options are:\n"));
5184 fprintf (stream, _("\
5185 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5186 fprintf (stream, _("\
5187 -h --file-header Display the ELF file header\n"));
5188 fprintf (stream, _("\
5189 -l --program-headers Display the program headers\n"));
5190 fprintf (stream, _("\
5191 --segments An alias for --program-headers\n"));
5192 fprintf (stream, _("\
5193 -S --section-headers Display the sections' header\n"));
5194 fprintf (stream, _("\
5195 --sections An alias for --section-headers\n"));
5196 fprintf (stream, _("\
5197 -g --section-groups Display the section groups\n"));
5198 fprintf (stream, _("\
5199 -t --section-details Display the section details\n"));
5200 fprintf (stream, _("\
5201 -e --headers Equivalent to: -h -l -S\n"));
5202 fprintf (stream, _("\
5203 -s --syms Display the symbol table\n"));
5204 fprintf (stream, _("\
5205 --symbols An alias for --syms\n"));
5206 fprintf (stream, _("\
5207 --dyn-syms Display the dynamic symbol table\n"));
5208 fprintf (stream, _("\
5209 --lto-syms Display LTO symbol tables\n"));
5210 fprintf (stream, _("\
047c3dbf
NL
5211 --sym-base=[0|8|10|16] \n\
5212 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5213 mixed (the default), octal, decimal, hexadecimal.\n"));
5214 fprintf (stream, _("\
0d646226
AM
5215 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5216 display_demangler_styles (stream, _("\
5217 STYLE can be "));
d6249f5f
AM
5218 fprintf (stream, _("\
5219 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5220 fprintf (stream, _("\
5221 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5222 fprintf (stream, _("\
5223 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5224 fprintf (stream, _("\
5225 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5226 Display unicode characters as determined by the current locale\n\
5227 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5228 escape sequences, or treat them as invalid and display as\n\
5229 \"{hex sequences}\"\n"));
d6249f5f
AM
5230 fprintf (stream, _("\
5231 -n --notes Display the core notes (if present)\n"));
5232 fprintf (stream, _("\
5233 -r --relocs Display the relocations (if present)\n"));
5234 fprintf (stream, _("\
5235 -u --unwind Display the unwind info (if present)\n"));
5236 fprintf (stream, _("\
5237 -d --dynamic Display the dynamic section (if present)\n"));
5238 fprintf (stream, _("\
5239 -V --version-info Display the version sections (if present)\n"));
5240 fprintf (stream, _("\
5241 -A --arch-specific Display architecture specific information (if any)\n"));
5242 fprintf (stream, _("\
5243 -c --archive-index Display the symbol/file index in an archive\n"));
5244 fprintf (stream, _("\
5245 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5246 fprintf (stream, _("\
5247 -L --lint|--enable-checks\n\
5248 Display warning messages for possible problems\n"));
5249 fprintf (stream, _("\
09c11c86 5250 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5251 Dump the contents of section <number|name> as bytes\n"));
5252 fprintf (stream, _("\
09c11c86 5253 -p --string-dump=<number|name>\n\
d6249f5f
AM
5254 Dump the contents of section <number|name> as strings\n"));
5255 fprintf (stream, _("\
cf13d699 5256 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5257 Dump the relocated contents of section <number|name>\n"));
5258 fprintf (stream, _("\
5259 -z --decompress Decompress section before dumping it\n"));
5260 fprintf (stream, _("\
5261 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5262 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5263 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5264 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5265 U/=trace_info]\n\
5266 Display the contents of DWARF debug sections\n"));
5267 fprintf (stream, _("\
5268 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5269 debuginfo files\n"));
5270 fprintf (stream, _("\
5271 -P --process-links Display the contents of non-debug sections in separate\n\
5272 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5273#if DEFAULT_FOR_FOLLOW_LINKS
5274 fprintf (stream, _("\
d6249f5f
AM
5275 -wK --debug-dump=follow-links\n\
5276 Follow links to separate debug info files (default)\n"));
5277 fprintf (stream, _("\
5278 -wN --debug-dump=no-follow-links\n\
5279 Do not follow links to separate debug info files\n"));
c46b7066
NC
5280#else
5281 fprintf (stream, _("\
d6249f5f
AM
5282 -wK --debug-dump=follow-links\n\
5283 Follow links to separate debug info files\n"));
5284 fprintf (stream, _("\
5285 -wN --debug-dump=no-follow-links\n\
5286 Do not follow links to separate debug info files\n\
5287 (default)\n"));
bed566bb
NC
5288#endif
5289#if HAVE_LIBDEBUGINFOD
5290 fprintf (stream, _("\
5291 -wD --debug-dump=use-debuginfod\n\
5292 When following links, also query debuginfod servers (default)\n"));
5293 fprintf (stream, _("\
5294 -wE --debug-dump=do-not-use-debuginfod\n\
5295 When following links, do not query debuginfod servers\n"));
c46b7066 5296#endif
fd2f0033 5297 fprintf (stream, _("\
d6249f5f
AM
5298 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5299 fprintf (stream, _("\
5300 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5301#ifdef ENABLE_LIBCTF
7d9813f1 5302 fprintf (stream, _("\
d6249f5f
AM
5303 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5304 fprintf (stream, _("\
80b56fad 5305 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5306 fprintf (stream, _("\
7d9813f1 5307 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5308 Use section <number|name> as the CTF external symtab\n"));
5309 fprintf (stream, _("\
7d9813f1 5310 --ctf-strings=<number|name>\n\
d6249f5f 5311 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5312#endif
42b6953b
IB
5313 fprintf (stream, _("\
5314 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
7d9813f1 5315
252b5132 5316#ifdef SUPPORT_DISASSEMBLY
92f01d61 5317 fprintf (stream, _("\
09c11c86
NC
5318 -i --instruction-dump=<number|name>\n\
5319 Disassemble the contents of section <number|name>\n"));
252b5132 5320#endif
92f01d61 5321 fprintf (stream, _("\
d6249f5f
AM
5322 -I --histogram Display histogram of bucket list lengths\n"));
5323 fprintf (stream, _("\
5324 -W --wide Allow output width to exceed 80 characters\n"));
5325 fprintf (stream, _("\
5326 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5327 fprintf (stream, _("\
5328 @<file> Read options from <file>\n"));
5329 fprintf (stream, _("\
5330 -H --help Display this information\n"));
5331 fprintf (stream, _("\
8b53311e 5332 -v --version Display the version number of readelf\n"));
1118d252 5333
92f01d61
JM
5334 if (REPORT_BUGS_TO[0] && stream == stdout)
5335 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5336
92f01d61 5337 exit (stream == stdout ? 0 : 1);
252b5132
RH
5338}
5339
18bd398b
NC
5340/* Record the fact that the user wants the contents of section number
5341 SECTION to be displayed using the method(s) encoded as flags bits
5342 in TYPE. Note, TYPE can be zero if we are creating the array for
5343 the first time. */
5344
252b5132 5345static void
6431e409
AM
5346request_dump_bynumber (struct dump_data *dumpdata,
5347 unsigned int section, dump_type type)
252b5132 5348{
6431e409 5349 if (section >= dumpdata->num_dump_sects)
252b5132 5350 {
2cf0635d 5351 dump_type * new_dump_sects;
252b5132 5352
3f5e193b 5353 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5354 sizeof (* new_dump_sects));
252b5132
RH
5355
5356 if (new_dump_sects == NULL)
591a748a 5357 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5358 else
5359 {
6431e409 5360 if (dumpdata->dump_sects)
21b65bac
NC
5361 {
5362 /* Copy current flag settings. */
6431e409
AM
5363 memcpy (new_dump_sects, dumpdata->dump_sects,
5364 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5365
6431e409 5366 free (dumpdata->dump_sects);
21b65bac 5367 }
252b5132 5368
6431e409
AM
5369 dumpdata->dump_sects = new_dump_sects;
5370 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5371 }
5372 }
5373
6431e409
AM
5374 if (dumpdata->dump_sects)
5375 dumpdata->dump_sects[section] |= type;
252b5132
RH
5376}
5377
aef1f6d0
DJ
5378/* Request a dump by section name. */
5379
5380static void
2cf0635d 5381request_dump_byname (const char * section, dump_type type)
aef1f6d0 5382{
2cf0635d 5383 struct dump_list_entry * new_request;
aef1f6d0 5384
3f5e193b
NC
5385 new_request = (struct dump_list_entry *)
5386 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5387 if (!new_request)
591a748a 5388 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5389
5390 new_request->name = strdup (section);
5391 if (!new_request->name)
591a748a 5392 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5393
5394 new_request->type = type;
5395
5396 new_request->next = dump_sects_byname;
5397 dump_sects_byname = new_request;
5398}
5399
cf13d699 5400static inline void
6431e409 5401request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5402{
5403 int section;
5404 char * cp;
5405
015dc7e1 5406 do_dump = true;
cf13d699
NC
5407 section = strtoul (optarg, & cp, 0);
5408
5409 if (! *cp && section >= 0)
6431e409 5410 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5411 else
5412 request_dump_byname (optarg, type);
5413}
5414
252b5132 5415static void
6431e409 5416parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5417{
5418 int c;
5419
5420 if (argc < 2)
92f01d61 5421 usage (stderr);
252b5132
RH
5422
5423 while ((c = getopt_long
b3aa80b4 5424 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5425 {
252b5132
RH
5426 switch (c)
5427 {
5428 case 0:
5429 /* Long options. */
5430 break;
5431 case 'H':
92f01d61 5432 usage (stdout);
252b5132
RH
5433 break;
5434
5435 case 'a':
015dc7e1
AM
5436 do_syms = true;
5437 do_reloc = true;
5438 do_unwind = true;
5439 do_dynamic = true;
5440 do_header = true;
5441 do_sections = true;
5442 do_section_groups = true;
5443 do_segments = true;
5444 do_version = true;
5445 do_histogram = true;
5446 do_arch = true;
5447 do_notes = true;
252b5132 5448 break;
79bc120c 5449
f5842774 5450 case 'g':
015dc7e1 5451 do_section_groups = true;
f5842774 5452 break;
5477e8a0 5453 case 't':
595cf52e 5454 case 'N':
015dc7e1
AM
5455 do_sections = true;
5456 do_section_details = true;
595cf52e 5457 break;
252b5132 5458 case 'e':
015dc7e1
AM
5459 do_header = true;
5460 do_sections = true;
5461 do_segments = true;
252b5132 5462 break;
a952a375 5463 case 'A':
015dc7e1 5464 do_arch = true;
a952a375 5465 break;
252b5132 5466 case 'D':
015dc7e1 5467 do_using_dynamic = true;
252b5132
RH
5468 break;
5469 case 'r':
015dc7e1 5470 do_reloc = true;
252b5132 5471 break;
4d6ed7c8 5472 case 'u':
015dc7e1 5473 do_unwind = true;
4d6ed7c8 5474 break;
252b5132 5475 case 'h':
015dc7e1 5476 do_header = true;
252b5132
RH
5477 break;
5478 case 'l':
015dc7e1 5479 do_segments = true;
252b5132
RH
5480 break;
5481 case 's':
015dc7e1 5482 do_syms = true;
252b5132
RH
5483 break;
5484 case 'S':
015dc7e1 5485 do_sections = true;
252b5132
RH
5486 break;
5487 case 'd':
015dc7e1 5488 do_dynamic = true;
252b5132 5489 break;
a952a375 5490 case 'I':
015dc7e1 5491 do_histogram = true;
a952a375 5492 break;
779fe533 5493 case 'n':
015dc7e1 5494 do_notes = true;
779fe533 5495 break;
4145f1d5 5496 case 'c':
015dc7e1 5497 do_archive_index = true;
4145f1d5 5498 break;
1b513401 5499 case 'L':
015dc7e1 5500 do_checks = true;
1b513401 5501 break;
ca0e11aa 5502 case 'P':
015dc7e1
AM
5503 process_links = true;
5504 do_follow_links = true;
e1dbfc17 5505 dump_any_debugging = true;
ca0e11aa 5506 break;
252b5132 5507 case 'x':
6431e409 5508 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5509 break;
09c11c86 5510 case 'p':
6431e409 5511 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5512 break;
5513 case 'R':
6431e409 5514 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5515 break;
0e602686 5516 case 'z':
015dc7e1 5517 decompress_dumps = true;
0e602686 5518 break;
252b5132 5519 case 'w':
0f03783c 5520 if (optarg == NULL)
613ff48b 5521 {
015dc7e1 5522 do_debugging = true;
94585d6d
NC
5523 do_dump = true;
5524 dump_any_debugging = true;
613ff48b
CC
5525 dwarf_select_sections_all ();
5526 }
252b5132
RH
5527 else
5528 {
015dc7e1 5529 do_debugging = false;
94585d6d
NC
5530 if (dwarf_select_sections_by_letters (optarg))
5531 {
5532 do_dump = true;
5533 dump_any_debugging = true;
5534 }
252b5132
RH
5535 }
5536 break;
2979dc34 5537 case OPTION_DEBUG_DUMP:
0f03783c 5538 if (optarg == NULL)
d6249f5f 5539 {
94585d6d 5540 do_dump = true;
d6249f5f 5541 do_debugging = true;
94585d6d 5542 dump_any_debugging = true;
d6249f5f
AM
5543 dwarf_select_sections_all ();
5544 }
2979dc34
JJ
5545 else
5546 {
015dc7e1 5547 do_debugging = false;
94585d6d
NC
5548 if (dwarf_select_sections_by_names (optarg))
5549 {
5550 do_dump = true;
5551 dump_any_debugging = true;
5552 }
2979dc34
JJ
5553 }
5554 break;
fd2f0033
TT
5555 case OPTION_DWARF_DEPTH:
5556 {
5557 char *cp;
5558
5559 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5560 }
5561 break;
5562 case OPTION_DWARF_START:
5563 {
5564 char *cp;
5565
5566 dwarf_start_die = strtoul (optarg, & cp, 0);
5567 }
5568 break;
4723351a 5569 case OPTION_DWARF_CHECK:
015dc7e1 5570 dwarf_check = true;
4723351a 5571 break;
7d9813f1 5572 case OPTION_CTF_DUMP:
015dc7e1 5573 do_ctf = true;
6431e409 5574 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5575 break;
5576 case OPTION_CTF_SYMBOLS:
df16e041 5577 free (dump_ctf_symtab_name);
7d9813f1
NA
5578 dump_ctf_symtab_name = strdup (optarg);
5579 break;
5580 case OPTION_CTF_STRINGS:
df16e041 5581 free (dump_ctf_strtab_name);
7d9813f1
NA
5582 dump_ctf_strtab_name = strdup (optarg);
5583 break;
5584 case OPTION_CTF_PARENT:
df16e041 5585 free (dump_ctf_parent_name);
7d9813f1
NA
5586 dump_ctf_parent_name = strdup (optarg);
5587 break;
42b6953b
IB
5588 case OPTION_SFRAME_DUMP:
5589 do_sframe = true;
5590 /* Providing section name is optional. request_dump (), however,
5591 thrives on non NULL optarg. Handle it explicitly here. */
5592 if (optarg != NULL)
5593 request_dump (dumpdata, SFRAME_DUMP);
5594 else
5595 {
5596 do_dump = true;
5597 const char *sframe_sec_name = strdup (".sframe");
5598 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
5599 }
5600 break;
2c610e4b 5601 case OPTION_DYN_SYMS:
015dc7e1 5602 do_dyn_syms = true;
2c610e4b 5603 break;
0f03783c 5604 case OPTION_LTO_SYMS:
015dc7e1 5605 do_lto_syms = true;
0f03783c 5606 break;
252b5132
RH
5607#ifdef SUPPORT_DISASSEMBLY
5608 case 'i':
6431e409 5609 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5610 break;
252b5132
RH
5611#endif
5612 case 'v':
5613 print_version (program_name);
5614 break;
5615 case 'V':
015dc7e1 5616 do_version = true;
252b5132 5617 break;
d974e256 5618 case 'W':
015dc7e1 5619 do_wide = true;
d974e256 5620 break;
0942c7ab 5621 case 'T':
015dc7e1 5622 do_not_show_symbol_truncation = true;
0942c7ab 5623 break;
79bc120c 5624 case 'C':
015dc7e1 5625 do_demangle = true;
79bc120c
NC
5626 if (optarg != NULL)
5627 {
5628 enum demangling_styles style;
5629
5630 style = cplus_demangle_name_to_style (optarg);
5631 if (style == unknown_demangling)
5632 error (_("unknown demangling style `%s'"), optarg);
5633
5634 cplus_demangle_set_style (style);
5635 }
5636 break;
5637 case OPTION_NO_DEMANGLING:
015dc7e1 5638 do_demangle = false;
79bc120c
NC
5639 break;
5640 case OPTION_RECURSE_LIMIT:
5641 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5642 break;
5643 case OPTION_NO_RECURSE_LIMIT:
5644 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5645 break;
5646 case OPTION_WITH_SYMBOL_VERSIONS:
5647 /* Ignored for backward compatibility. */
5648 break;
b9e920ec 5649
b3aa80b4
NC
5650 case 'U':
5651 if (optarg == NULL)
5652 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5653 else if (streq (optarg, "default") || streq (optarg, "d"))
5654 unicode_display = unicode_default;
5655 else if (streq (optarg, "locale") || streq (optarg, "l"))
5656 unicode_display = unicode_locale;
5657 else if (streq (optarg, "escape") || streq (optarg, "e"))
5658 unicode_display = unicode_escape;
5659 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5660 unicode_display = unicode_invalid;
5661 else if (streq (optarg, "hex") || streq (optarg, "x"))
5662 unicode_display = unicode_hex;
5663 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5664 unicode_display = unicode_highlight;
5665 else
5666 error (_("invalid argument to -U/--unicode: %s"), optarg);
5667 break;
5668
047c3dbf
NL
5669 case OPTION_SYM_BASE:
5670 sym_base = 0;
5671 if (optarg != NULL)
5672 {
5673 sym_base = strtoul (optarg, NULL, 0);
5674 switch (sym_base)
5675 {
5676 case 0:
5677 case 8:
5678 case 10:
5679 case 16:
5680 break;
5681
5682 default:
5683 sym_base = 0;
5684 break;
5685 }
5686 }
5687 break;
5688
252b5132 5689 default:
252b5132
RH
5690 /* xgettext:c-format */
5691 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5692 /* Fall through. */
252b5132 5693 case '?':
92f01d61 5694 usage (stderr);
252b5132
RH
5695 }
5696 }
5697
4d6ed7c8 5698 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5699 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5700 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5701 && !do_section_groups && !do_archive_index
0f03783c 5702 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5703 {
5704 if (do_checks)
5705 {
015dc7e1
AM
5706 check_all = true;
5707 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5708 do_segments = do_header = do_dump = do_version = true;
5709 do_histogram = do_debugging = do_arch = do_notes = true;
5710 do_section_groups = do_archive_index = do_dyn_syms = true;
5711 do_lto_syms = true;
1b513401
NC
5712 }
5713 else
5714 usage (stderr);
5715 }
252b5132
RH
5716}
5717
5718static const char *
d3ba0551 5719get_elf_class (unsigned int elf_class)
252b5132 5720{
b34976b6 5721 static char buff[32];
103f02d3 5722
252b5132
RH
5723 switch (elf_class)
5724 {
5725 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5726 case ELFCLASS32: return "ELF32";
5727 case ELFCLASS64: return "ELF64";
ab5e7794 5728 default:
e9e44622 5729 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5730 return buff;
252b5132
RH
5731 }
5732}
5733
5734static const char *
d3ba0551 5735get_data_encoding (unsigned int encoding)
252b5132 5736{
b34976b6 5737 static char buff[32];
103f02d3 5738
252b5132
RH
5739 switch (encoding)
5740 {
5741 case ELFDATANONE: return _("none");
33c63f9d
CM
5742 case ELFDATA2LSB: return _("2's complement, little endian");
5743 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5744 default:
e9e44622 5745 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5746 return buff;
252b5132
RH
5747 }
5748}
5749
521f7268
NC
5750static bool
5751check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
5752{
5753 if (header->e_ident[EI_MAG0] == ELFMAG0
5754 && header->e_ident[EI_MAG1] == ELFMAG1
5755 && header->e_ident[EI_MAG2] == ELFMAG2
5756 && header->e_ident[EI_MAG3] == ELFMAG3)
5757 return true;
5758
5759 /* Some compilers produce object files that are not in the ELF file format.
5760 As an aid to users of readelf, try to identify these cases and suggest
5761 alternative tools.
5762
5763 FIXME: It is not clear if all four bytes are used as constant magic
5764 valus by all compilers. It may be necessary to recode this function if
5765 different tools use different length sequences. */
5766
5767 static struct
5768 {
5769 unsigned char magic[4];
5770 const char * obj_message;
5771 const char * ar_message;
5772 }
5773 known_magic[] =
5774 {
5775 { { 'B', 'C', 0xc0, 0xde },
5776 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
5777 N_("This is a LLVM bitcode file - try extracing and then using llvm-bcanalyzer\n")
5778 },
5779 { { 'g', 'o', ' ', 'o' },
5780 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
5781 NULL
5782 }
5783 };
5784 int i;
5785
5786 for (i = ARRAY_SIZE (known_magic); i--;)
5787 {
5788 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
5789 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
5790 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
5791 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
5792 {
5793 /* Some compiler's analyzer tools do not handle archives,
5794 so we provide two different kinds of error message. */
5795 if (filedata->archive_file_size > 0
5796 && known_magic[i].ar_message != NULL)
b3ea2010 5797 error ("%s", known_magic[i].ar_message);
521f7268 5798 else
b3ea2010 5799 error ("%s", known_magic[i].obj_message);
521f7268
NC
5800 return false;
5801 }
5802 }
5803
5804 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
5805 return false;
5806}
5807
dda8d76d 5808/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5809
015dc7e1 5810static bool
dda8d76d 5811process_file_header (Filedata * filedata)
252b5132 5812{
dda8d76d
NC
5813 Elf_Internal_Ehdr * header = & filedata->file_header;
5814
521f7268
NC
5815 if (! check_magic_number (filedata, header))
5816 return false;
252b5132 5817
ca0e11aa
NC
5818 if (! filedata->is_separate)
5819 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5820
252b5132
RH
5821 if (do_header)
5822 {
32ec8896 5823 unsigned i;
252b5132 5824
ca0e11aa
NC
5825 if (filedata->is_separate)
5826 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5827 else
5828 printf (_("ELF Header:\n"));
252b5132 5829 printf (_(" Magic: "));
b34976b6 5830 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5831 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5832 printf ("\n");
5833 printf (_(" Class: %s\n"),
dda8d76d 5834 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5835 printf (_(" Data: %s\n"),
dda8d76d 5836 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5837 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5838 header->e_ident[EI_VERSION],
5839 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5840 ? _(" (current)")
dda8d76d 5841 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5842 ? _(" <unknown>")
789be9f7 5843 : "")));
252b5132 5844 printf (_(" OS/ABI: %s\n"),
dda8d76d 5845 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5846 printf (_(" ABI Version: %d\n"),
dda8d76d 5847 header->e_ident[EI_ABIVERSION]);
252b5132 5848 printf (_(" Type: %s\n"),
93df3340 5849 get_file_type (filedata));
252b5132 5850 printf (_(" Machine: %s\n"),
dda8d76d 5851 get_machine_name (header->e_machine));
252b5132 5852 printf (_(" Version: 0x%lx\n"),
e8a64888 5853 header->e_version);
76da6bbe 5854
f7a99963 5855 printf (_(" Entry point address: "));
e8a64888 5856 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5857 printf (_("\n Start of program headers: "));
e8a64888 5858 print_vma (header->e_phoff, DEC);
f7a99963 5859 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5860 print_vma (header->e_shoff, DEC);
f7a99963 5861 printf (_(" (bytes into file)\n"));
76da6bbe 5862
252b5132 5863 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5864 header->e_flags,
dda8d76d 5865 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5866 printf (_(" Size of this header: %u (bytes)\n"),
5867 header->e_ehsize);
5868 printf (_(" Size of program headers: %u (bytes)\n"),
5869 header->e_phentsize);
5870 printf (_(" Number of program headers: %u"),
5871 header->e_phnum);
dda8d76d
NC
5872 if (filedata->section_headers != NULL
5873 && header->e_phnum == PN_XNUM
5874 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5875 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5876 putc ('\n', stdout);
e8a64888
AM
5877 printf (_(" Size of section headers: %u (bytes)\n"),
5878 header->e_shentsize);
5879 printf (_(" Number of section headers: %u"),
5880 header->e_shnum);
dda8d76d 5881 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5882 {
5883 header->e_shnum = filedata->section_headers[0].sh_size;
5884 printf (" (%u)", header->e_shnum);
5885 }
560f3c1c 5886 putc ('\n', stdout);
e8a64888
AM
5887 printf (_(" Section header string table index: %u"),
5888 header->e_shstrndx);
dda8d76d
NC
5889 if (filedata->section_headers != NULL
5890 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5891 {
5892 header->e_shstrndx = filedata->section_headers[0].sh_link;
5893 printf (" (%u)", header->e_shstrndx);
5894 }
5895 if (header->e_shstrndx != SHN_UNDEF
5896 && header->e_shstrndx >= header->e_shnum)
5897 {
5898 header->e_shstrndx = SHN_UNDEF;
5899 printf (_(" <corrupt: out of range>"));
5900 }
560f3c1c
AM
5901 putc ('\n', stdout);
5902 }
5903
dda8d76d 5904 if (filedata->section_headers != NULL)
560f3c1c 5905 {
dda8d76d
NC
5906 if (header->e_phnum == PN_XNUM
5907 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5908 {
5909 /* Throw away any cached read of PN_XNUM headers. */
5910 free (filedata->program_headers);
5911 filedata->program_headers = NULL;
5912 header->e_phnum = filedata->section_headers[0].sh_info;
5913 }
dda8d76d
NC
5914 if (header->e_shnum == SHN_UNDEF)
5915 header->e_shnum = filedata->section_headers[0].sh_size;
5916 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5917 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5918 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5919 header->e_shstrndx = SHN_UNDEF;
252b5132 5920 }
103f02d3 5921
015dc7e1 5922 return true;
9ea033b2
NC
5923}
5924
dda8d76d
NC
5925/* Read in the program headers from FILEDATA and store them in PHEADERS.
5926 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5927
015dc7e1 5928static bool
dda8d76d 5929get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5930{
2cf0635d
NC
5931 Elf32_External_Phdr * phdrs;
5932 Elf32_External_Phdr * external;
5933 Elf_Internal_Phdr * internal;
b34976b6 5934 unsigned int i;
dda8d76d
NC
5935 unsigned int size = filedata->file_header.e_phentsize;
5936 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5937
5938 /* PR binutils/17531: Cope with unexpected section header sizes. */
5939 if (size == 0 || num == 0)
015dc7e1 5940 return false;
e0a31db1
NC
5941 if (size < sizeof * phdrs)
5942 {
5943 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5944 return false;
e0a31db1
NC
5945 }
5946 if (size > sizeof * phdrs)
5947 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5948
dda8d76d 5949 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5950 size, num, _("program headers"));
5951 if (phdrs == NULL)
015dc7e1 5952 return false;
9ea033b2 5953
91d6fa6a 5954 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5955 i < filedata->file_header.e_phnum;
b34976b6 5956 i++, internal++, external++)
252b5132 5957 {
9ea033b2
NC
5958 internal->p_type = BYTE_GET (external->p_type);
5959 internal->p_offset = BYTE_GET (external->p_offset);
5960 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5961 internal->p_paddr = BYTE_GET (external->p_paddr);
5962 internal->p_filesz = BYTE_GET (external->p_filesz);
5963 internal->p_memsz = BYTE_GET (external->p_memsz);
5964 internal->p_flags = BYTE_GET (external->p_flags);
5965 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5966 }
5967
9ea033b2 5968 free (phdrs);
015dc7e1 5969 return true;
252b5132
RH
5970}
5971
dda8d76d
NC
5972/* Read in the program headers from FILEDATA and store them in PHEADERS.
5973 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5974
015dc7e1 5975static bool
dda8d76d 5976get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5977{
2cf0635d
NC
5978 Elf64_External_Phdr * phdrs;
5979 Elf64_External_Phdr * external;
5980 Elf_Internal_Phdr * internal;
b34976b6 5981 unsigned int i;
dda8d76d
NC
5982 unsigned int size = filedata->file_header.e_phentsize;
5983 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5984
5985 /* PR binutils/17531: Cope with unexpected section header sizes. */
5986 if (size == 0 || num == 0)
015dc7e1 5987 return false;
e0a31db1
NC
5988 if (size < sizeof * phdrs)
5989 {
5990 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5991 return false;
e0a31db1
NC
5992 }
5993 if (size > sizeof * phdrs)
5994 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5995
dda8d76d 5996 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5997 size, num, _("program headers"));
a6e9f9df 5998 if (!phdrs)
015dc7e1 5999 return false;
9ea033b2 6000
91d6fa6a 6001 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6002 i < filedata->file_header.e_phnum;
b34976b6 6003 i++, internal++, external++)
9ea033b2
NC
6004 {
6005 internal->p_type = BYTE_GET (external->p_type);
6006 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
6007 internal->p_offset = BYTE_GET (external->p_offset);
6008 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6009 internal->p_paddr = BYTE_GET (external->p_paddr);
6010 internal->p_filesz = BYTE_GET (external->p_filesz);
6011 internal->p_memsz = BYTE_GET (external->p_memsz);
6012 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
6013 }
6014
6015 free (phdrs);
015dc7e1 6016 return true;
9ea033b2 6017}
252b5132 6018
32ec8896 6019/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 6020
015dc7e1 6021static bool
dda8d76d 6022get_program_headers (Filedata * filedata)
d93f0186 6023{
2cf0635d 6024 Elf_Internal_Phdr * phdrs;
d93f0186
NC
6025
6026 /* Check cache of prior read. */
dda8d76d 6027 if (filedata->program_headers != NULL)
015dc7e1 6028 return true;
d93f0186 6029
82156ab7
NC
6030 /* Be kind to memory checkers by looking for
6031 e_phnum values which we know must be invalid. */
dda8d76d 6032 if (filedata->file_header.e_phnum
82156ab7 6033 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 6034 >= filedata->file_size)
82156ab7
NC
6035 {
6036 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 6037 filedata->file_header.e_phnum);
015dc7e1 6038 return false;
82156ab7 6039 }
d93f0186 6040
dda8d76d 6041 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 6042 sizeof (Elf_Internal_Phdr));
d93f0186
NC
6043 if (phdrs == NULL)
6044 {
8b73c356 6045 error (_("Out of memory reading %u program headers\n"),
dda8d76d 6046 filedata->file_header.e_phnum);
015dc7e1 6047 return false;
d93f0186
NC
6048 }
6049
6050 if (is_32bit_elf
dda8d76d
NC
6051 ? get_32bit_program_headers (filedata, phdrs)
6052 : get_64bit_program_headers (filedata, phdrs))
d93f0186 6053 {
dda8d76d 6054 filedata->program_headers = phdrs;
015dc7e1 6055 return true;
d93f0186
NC
6056 }
6057
6058 free (phdrs);
015dc7e1 6059 return false;
d93f0186
NC
6060}
6061
93df3340 6062/* Print program header info and locate dynamic section. */
2f62977e 6063
93df3340 6064static void
dda8d76d 6065process_program_headers (Filedata * filedata)
252b5132 6066{
2cf0635d 6067 Elf_Internal_Phdr * segment;
b34976b6 6068 unsigned int i;
1a9ccd70 6069 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6070
dda8d76d 6071 if (filedata->file_header.e_phnum == 0)
252b5132 6072 {
82f2dbf7 6073 /* PR binutils/12467. */
dda8d76d 6074 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6075 warn (_("possibly corrupt ELF header - it has a non-zero program"
6076 " header offset, but no program headers\n"));
82f2dbf7 6077 else if (do_segments)
ca0e11aa
NC
6078 {
6079 if (filedata->is_separate)
6080 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6081 filedata->file_name);
6082 else
6083 printf (_("\nThere are no program headers in this file.\n"));
6084 }
93df3340 6085 goto no_headers;
252b5132
RH
6086 }
6087
6088 if (do_segments && !do_header)
6089 {
ca0e11aa
NC
6090 if (filedata->is_separate)
6091 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6092 filedata->file_name, get_file_type (filedata));
ca0e11aa 6093 else
93df3340 6094 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6095 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6096 filedata->file_header.e_entry);
b8281767
AM
6097 printf (ngettext ("There is %d program header,"
6098 " starting at offset %" PRIu64 "\n",
6099 "There are %d program headers,"
6100 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6101 filedata->file_header.e_phnum),
6102 filedata->file_header.e_phnum,
625d49fc 6103 filedata->file_header.e_phoff);
252b5132
RH
6104 }
6105
dda8d76d 6106 if (! get_program_headers (filedata))
93df3340 6107 goto no_headers;
103f02d3 6108
252b5132
RH
6109 if (do_segments)
6110 {
dda8d76d 6111 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6112 printf (_("\nProgram Headers:\n"));
6113 else
6114 printf (_("\nProgram Headers:\n"));
76da6bbe 6115
f7a99963
NC
6116 if (is_32bit_elf)
6117 printf
6118 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6119 else if (do_wide)
6120 printf
6121 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6122 else
6123 {
6124 printf
6125 (_(" Type Offset VirtAddr PhysAddr\n"));
6126 printf
6127 (_(" FileSiz MemSiz Flags Align\n"));
6128 }
252b5132
RH
6129 }
6130
26c527e6 6131 uint64_t dynamic_addr = 0;
be7d229a 6132 uint64_t dynamic_size = 0;
dda8d76d
NC
6133 for (i = 0, segment = filedata->program_headers;
6134 i < filedata->file_header.e_phnum;
b34976b6 6135 i++, segment++)
252b5132
RH
6136 {
6137 if (do_segments)
6138 {
dda8d76d 6139 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6140
6141 if (is_32bit_elf)
6142 {
6143 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6144 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6145 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6146 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6147 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6148 printf ("%c%c%c ",
6149 (segment->p_flags & PF_R ? 'R' : ' '),
6150 (segment->p_flags & PF_W ? 'W' : ' '),
6151 (segment->p_flags & PF_X ? 'E' : ' '));
6152 printf ("%#lx", (unsigned long) segment->p_align);
6153 }
d974e256
JJ
6154 else if (do_wide)
6155 {
6156 if ((unsigned long) segment->p_offset == segment->p_offset)
6157 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6158 else
6159 {
6160 print_vma (segment->p_offset, FULL_HEX);
6161 putchar (' ');
6162 }
6163
6164 print_vma (segment->p_vaddr, FULL_HEX);
6165 putchar (' ');
6166 print_vma (segment->p_paddr, FULL_HEX);
6167 putchar (' ');
6168
6169 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6170 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6171 else
6172 {
6173 print_vma (segment->p_filesz, FULL_HEX);
6174 putchar (' ');
6175 }
6176
6177 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6178 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6179 else
6180 {
f48e6c45 6181 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6182 }
6183
6184 printf (" %c%c%c ",
6185 (segment->p_flags & PF_R ? 'R' : ' '),
6186 (segment->p_flags & PF_W ? 'W' : ' '),
6187 (segment->p_flags & PF_X ? 'E' : ' '));
6188
6189 if ((unsigned long) segment->p_align == segment->p_align)
6190 printf ("%#lx", (unsigned long) segment->p_align);
6191 else
6192 {
6193 print_vma (segment->p_align, PREFIX_HEX);
6194 }
6195 }
f7a99963
NC
6196 else
6197 {
6198 print_vma (segment->p_offset, FULL_HEX);
6199 putchar (' ');
6200 print_vma (segment->p_vaddr, FULL_HEX);
6201 putchar (' ');
6202 print_vma (segment->p_paddr, FULL_HEX);
6203 printf ("\n ");
6204 print_vma (segment->p_filesz, FULL_HEX);
6205 putchar (' ');
6206 print_vma (segment->p_memsz, FULL_HEX);
6207 printf (" %c%c%c ",
6208 (segment->p_flags & PF_R ? 'R' : ' '),
6209 (segment->p_flags & PF_W ? 'W' : ' '),
6210 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6211 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6212 }
252b5132 6213
1a9ccd70
NC
6214 putc ('\n', stdout);
6215 }
f54498b4 6216
252b5132
RH
6217 switch (segment->p_type)
6218 {
1a9ccd70 6219 case PT_LOAD:
502d895c
NC
6220#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6221 required by the ELF standard, several programs, including the Linux
6222 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6223 if (previous_load
6224 && previous_load->p_vaddr > segment->p_vaddr)
6225 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6226#endif
1a9ccd70
NC
6227 if (segment->p_memsz < segment->p_filesz)
6228 error (_("the segment's file size is larger than its memory size\n"));
6229 previous_load = segment;
6230 break;
6231
6232 case PT_PHDR:
6233 /* PR 20815 - Verify that the program header is loaded into memory. */
6234 if (i > 0 && previous_load != NULL)
6235 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6236 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6237 {
6238 unsigned int j;
6239
dda8d76d 6240 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6241 {
6242 Elf_Internal_Phdr *load = filedata->program_headers + j;
6243 if (load->p_type == PT_LOAD
6244 && load->p_offset <= segment->p_offset
6245 && (load->p_offset + load->p_filesz
6246 >= segment->p_offset + segment->p_filesz)
6247 && load->p_vaddr <= segment->p_vaddr
6248 && (load->p_vaddr + load->p_filesz
6249 >= segment->p_vaddr + segment->p_filesz))
6250 break;
6251 }
dda8d76d 6252 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6253 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6254 }
6255 break;
6256
252b5132 6257 case PT_DYNAMIC:
93df3340 6258 if (dynamic_addr)
252b5132
RH
6259 error (_("more than one dynamic segment\n"));
6260
20737c13
AM
6261 /* By default, assume that the .dynamic section is the first
6262 section in the DYNAMIC segment. */
93df3340
AM
6263 dynamic_addr = segment->p_offset;
6264 dynamic_size = segment->p_filesz;
20737c13 6265
b2d38a17
NC
6266 /* Try to locate the .dynamic section. If there is
6267 a section header table, we can easily locate it. */
dda8d76d 6268 if (filedata->section_headers != NULL)
b2d38a17 6269 {
2cf0635d 6270 Elf_Internal_Shdr * sec;
b2d38a17 6271
dda8d76d 6272 sec = find_section (filedata, ".dynamic");
89fac5e3 6273 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6274 {
93df3340
AM
6275 /* A corresponding .dynamic section is expected, but on
6276 IA-64/OpenVMS it is OK for it to be missing. */
6277 if (!is_ia64_vms (filedata))
6278 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6279 break;
6280 }
6281
42bb2e33 6282 if (sec->sh_type == SHT_NOBITS)
20737c13 6283 {
93df3340
AM
6284 dynamic_addr = 0;
6285 dynamic_size = 0;
20737c13
AM
6286 break;
6287 }
42bb2e33 6288
93df3340
AM
6289 dynamic_addr = sec->sh_offset;
6290 dynamic_size = sec->sh_size;
b2d38a17 6291
8ac10c5b
L
6292 /* The PT_DYNAMIC segment, which is used by the run-time
6293 loader, should exactly match the .dynamic section. */
6294 if (do_checks
93df3340
AM
6295 && (dynamic_addr != segment->p_offset
6296 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6297 warn (_("\
6298the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6299 }
39e224f6
MW
6300
6301 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6302 segment. Check this after matching against the section headers
6303 so we don't warn on debuginfo file (which have NOBITS .dynamic
6304 sections). */
93df3340
AM
6305 if (dynamic_addr > filedata->file_size
6306 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6307 {
6308 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6309 dynamic_addr = 0;
6310 dynamic_size = 0;
39e224f6 6311 }
252b5132
RH
6312 break;
6313
6314 case PT_INTERP:
13acb58d
AM
6315 if (segment->p_offset >= filedata->file_size
6316 || segment->p_filesz > filedata->file_size - segment->p_offset
6317 || segment->p_filesz - 1 >= (size_t) -2
63cf857e
AM
6318 || fseek64 (filedata->handle,
6319 filedata->archive_file_offset + segment->p_offset,
6320 SEEK_SET))
252b5132
RH
6321 error (_("Unable to find program interpreter name\n"));
6322 else
6323 {
13acb58d
AM
6324 size_t len = segment->p_filesz;
6325 free (filedata->program_interpreter);
6326 filedata->program_interpreter = xmalloc (len + 1);
6327 len = fread (filedata->program_interpreter, 1, len,
6328 filedata->handle);
6329 filedata->program_interpreter[len] = 0;
252b5132
RH
6330
6331 if (do_segments)
f54498b4 6332 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6333 filedata->program_interpreter);
252b5132
RH
6334 }
6335 break;
6336 }
252b5132
RH
6337 }
6338
dda8d76d
NC
6339 if (do_segments
6340 && filedata->section_headers != NULL
6341 && filedata->string_table != NULL)
252b5132
RH
6342 {
6343 printf (_("\n Section to Segment mapping:\n"));
6344 printf (_(" Segment Sections...\n"));
6345
dda8d76d 6346 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6347 {
9ad5cbcf 6348 unsigned int j;
2cf0635d 6349 Elf_Internal_Shdr * section;
252b5132 6350
dda8d76d
NC
6351 segment = filedata->program_headers + i;
6352 section = filedata->section_headers + 1;
252b5132
RH
6353
6354 printf (" %2.2d ", i);
6355
dda8d76d 6356 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6357 {
f4638467
AM
6358 if (!ELF_TBSS_SPECIAL (section, segment)
6359 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6360 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6361 }
6362
6363 putc ('\n',stdout);
6364 }
6365 }
6366
93df3340
AM
6367 filedata->dynamic_addr = dynamic_addr;
6368 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6369 return;
6370
6371 no_headers:
6372 filedata->dynamic_addr = 0;
6373 filedata->dynamic_size = 1;
252b5132
RH
6374}
6375
6376
d93f0186
NC
6377/* Find the file offset corresponding to VMA by using the program headers. */
6378
26c527e6 6379static int64_t
625d49fc 6380offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 6381{
2cf0635d 6382 Elf_Internal_Phdr * seg;
d93f0186 6383
dda8d76d 6384 if (! get_program_headers (filedata))
d93f0186
NC
6385 {
6386 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6387 return (long) vma;
6388 }
6389
dda8d76d
NC
6390 for (seg = filedata->program_headers;
6391 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6392 ++seg)
6393 {
6394 if (seg->p_type != PT_LOAD)
6395 continue;
6396
6397 if (vma >= (seg->p_vaddr & -seg->p_align)
6398 && vma + size <= seg->p_vaddr + seg->p_filesz)
6399 return vma - seg->p_vaddr + seg->p_offset;
6400 }
6401
26c527e6
AM
6402 warn (_("Virtual address %#" PRIx64
6403 " not located in any PT_LOAD segment.\n"), vma);
6404 return vma;
d93f0186
NC
6405}
6406
6407
dda8d76d
NC
6408/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6409 If PROBE is true, this is just a probe and we do not generate any error
6410 messages if the load fails. */
049b0c3a 6411
015dc7e1
AM
6412static bool
6413get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6414{
2cf0635d
NC
6415 Elf32_External_Shdr * shdrs;
6416 Elf_Internal_Shdr * internal;
dda8d76d
NC
6417 unsigned int i;
6418 unsigned int size = filedata->file_header.e_shentsize;
6419 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6420
6421 /* PR binutils/17531: Cope with unexpected section header sizes. */
6422 if (size == 0 || num == 0)
015dc7e1 6423 return false;
907b52f4
NC
6424
6425 /* The section header cannot be at the start of the file - that is
6426 where the ELF file header is located. A file with absolutely no
6427 sections in it will use a shoff of 0. */
6428 if (filedata->file_header.e_shoff == 0)
6429 return false;
6430
049b0c3a
NC
6431 if (size < sizeof * shdrs)
6432 {
6433 if (! probe)
6434 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6435 return false;
049b0c3a
NC
6436 }
6437 if (!probe && size > sizeof * shdrs)
6438 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6439
dda8d76d 6440 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6441 size, num,
6442 probe ? NULL : _("section headers"));
6443 if (shdrs == NULL)
015dc7e1 6444 return false;
252b5132 6445
dda8d76d
NC
6446 filedata->section_headers = (Elf_Internal_Shdr *)
6447 cmalloc (num, sizeof (Elf_Internal_Shdr));
6448 if (filedata->section_headers == NULL)
252b5132 6449 {
049b0c3a 6450 if (!probe)
8b73c356 6451 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6452 free (shdrs);
015dc7e1 6453 return false;
252b5132
RH
6454 }
6455
dda8d76d 6456 for (i = 0, internal = filedata->section_headers;
560f3c1c 6457 i < num;
b34976b6 6458 i++, internal++)
252b5132
RH
6459 {
6460 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6461 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6462 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6463 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6464 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6465 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6466 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6467 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6468 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6469 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6470 if (!probe && internal->sh_link > num)
6471 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6472 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6473 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6474 }
6475
6476 free (shdrs);
015dc7e1 6477 return true;
252b5132
RH
6478}
6479
dda8d76d
NC
6480/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6481
015dc7e1
AM
6482static bool
6483get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6484{
dda8d76d
NC
6485 Elf64_External_Shdr * shdrs;
6486 Elf_Internal_Shdr * internal;
6487 unsigned int i;
6488 unsigned int size = filedata->file_header.e_shentsize;
6489 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6490
6491 /* PR binutils/17531: Cope with unexpected section header sizes. */
6492 if (size == 0 || num == 0)
015dc7e1 6493 return false;
dda8d76d 6494
907b52f4
NC
6495 /* The section header cannot be at the start of the file - that is
6496 where the ELF file header is located. A file with absolutely no
6497 sections in it will use a shoff of 0. */
6498 if (filedata->file_header.e_shoff == 0)
6499 return false;
6500
049b0c3a
NC
6501 if (size < sizeof * shdrs)
6502 {
6503 if (! probe)
6504 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6505 return false;
049b0c3a 6506 }
dda8d76d 6507
049b0c3a
NC
6508 if (! probe && size > sizeof * shdrs)
6509 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6510
dda8d76d
NC
6511 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6512 filedata->file_header.e_shoff,
049b0c3a
NC
6513 size, num,
6514 probe ? NULL : _("section headers"));
6515 if (shdrs == NULL)
015dc7e1 6516 return false;
9ea033b2 6517
dda8d76d
NC
6518 filedata->section_headers = (Elf_Internal_Shdr *)
6519 cmalloc (num, sizeof (Elf_Internal_Shdr));
6520 if (filedata->section_headers == NULL)
9ea033b2 6521 {
049b0c3a 6522 if (! probe)
8b73c356 6523 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6524 free (shdrs);
015dc7e1 6525 return false;
9ea033b2
NC
6526 }
6527
dda8d76d 6528 for (i = 0, internal = filedata->section_headers;
560f3c1c 6529 i < num;
b34976b6 6530 i++, internal++)
9ea033b2
NC
6531 {
6532 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6533 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6534 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6535 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6536 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6537 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6538 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6539 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6540 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6541 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6542 if (!probe && internal->sh_link > num)
6543 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6544 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6545 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6546 }
6547
6548 free (shdrs);
015dc7e1 6549 return true;
9ea033b2
NC
6550}
6551
4de91c10
AM
6552static bool
6553get_section_headers (Filedata *filedata, bool probe)
6554{
6555 if (filedata->section_headers != NULL)
6556 return true;
6557
4de91c10
AM
6558 if (is_32bit_elf)
6559 return get_32bit_section_headers (filedata, probe);
6560 else
6561 return get_64bit_section_headers (filedata, probe);
6562}
6563
252b5132 6564static Elf_Internal_Sym *
26c527e6
AM
6565get_32bit_elf_symbols (Filedata *filedata,
6566 Elf_Internal_Shdr *section,
6567 uint64_t *num_syms_return)
252b5132 6568{
26c527e6 6569 uint64_t number = 0;
dd24e3da 6570 Elf32_External_Sym * esyms = NULL;
ba5cdace 6571 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6572 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6573 Elf_Internal_Sym * psym;
b34976b6 6574 unsigned int j;
e3d39609 6575 elf_section_list * entry;
252b5132 6576
c9c1d674
EG
6577 if (section->sh_size == 0)
6578 {
6579 if (num_syms_return != NULL)
6580 * num_syms_return = 0;
6581 return NULL;
6582 }
6583
dd24e3da 6584 /* Run some sanity checks first. */
c9c1d674 6585 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6586 {
26c527e6 6587 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 6588 printable_section_name (filedata, section),
26c527e6 6589 section->sh_entsize);
ba5cdace 6590 goto exit_point;
dd24e3da
NC
6591 }
6592
dda8d76d 6593 if (section->sh_size > filedata->file_size)
f54498b4 6594 {
26c527e6 6595 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 6596 printable_section_name (filedata, section),
26c527e6 6597 section->sh_size);
f54498b4
NC
6598 goto exit_point;
6599 }
6600
dd24e3da
NC
6601 number = section->sh_size / section->sh_entsize;
6602
6603 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6604 {
26c527e6
AM
6605 error (_("Size (%#" PRIx64 ") of section %s "
6606 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
6607 section->sh_size,
dda8d76d 6608 printable_section_name (filedata, section),
26c527e6 6609 section->sh_entsize);
ba5cdace 6610 goto exit_point;
dd24e3da
NC
6611 }
6612
dda8d76d 6613 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6614 section->sh_size, _("symbols"));
dd24e3da 6615 if (esyms == NULL)
ba5cdace 6616 goto exit_point;
252b5132 6617
e3d39609 6618 shndx = NULL;
978c4450 6619 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 6620 {
26c527e6 6621 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
6622 continue;
6623
6624 if (shndx != NULL)
6625 {
6626 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6627 free (shndx);
6628 }
6629
6630 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6631 entry->hdr->sh_offset,
6632 1, entry->hdr->sh_size,
6633 _("symbol table section indices"));
6634 if (shndx == NULL)
6635 goto exit_point;
6636
6637 /* PR17531: file: heap-buffer-overflow */
6638 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6639 {
26c527e6 6640 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 6641 printable_section_name (filedata, entry->hdr),
26c527e6
AM
6642 entry->hdr->sh_size,
6643 section->sh_size);
e3d39609 6644 goto exit_point;
c9c1d674 6645 }
e3d39609 6646 }
9ad5cbcf 6647
3f5e193b 6648 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6649
6650 if (isyms == NULL)
6651 {
26c527e6 6652 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
dd24e3da 6653 goto exit_point;
252b5132
RH
6654 }
6655
dd24e3da 6656 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6657 {
6658 psym->st_name = BYTE_GET (esyms[j].st_name);
6659 psym->st_value = BYTE_GET (esyms[j].st_value);
6660 psym->st_size = BYTE_GET (esyms[j].st_size);
6661 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6662 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6663 psym->st_shndx
6664 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6665 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6666 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6667 psym->st_info = BYTE_GET (esyms[j].st_info);
6668 psym->st_other = BYTE_GET (esyms[j].st_other);
6669 }
6670
dd24e3da 6671 exit_point:
e3d39609
NC
6672 free (shndx);
6673 free (esyms);
252b5132 6674
ba5cdace
NC
6675 if (num_syms_return != NULL)
6676 * num_syms_return = isyms == NULL ? 0 : number;
6677
252b5132
RH
6678 return isyms;
6679}
6680
9ea033b2 6681static Elf_Internal_Sym *
26c527e6
AM
6682get_64bit_elf_symbols (Filedata *filedata,
6683 Elf_Internal_Shdr *section,
6684 uint64_t *num_syms_return)
9ea033b2 6685{
26c527e6 6686 uint64_t number = 0;
ba5cdace
NC
6687 Elf64_External_Sym * esyms = NULL;
6688 Elf_External_Sym_Shndx * shndx = NULL;
6689 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6690 Elf_Internal_Sym * psym;
b34976b6 6691 unsigned int j;
e3d39609 6692 elf_section_list * entry;
9ea033b2 6693
c9c1d674
EG
6694 if (section->sh_size == 0)
6695 {
6696 if (num_syms_return != NULL)
6697 * num_syms_return = 0;
6698 return NULL;
6699 }
6700
dd24e3da 6701 /* Run some sanity checks first. */
c9c1d674 6702 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6703 {
26c527e6 6704 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 6705 printable_section_name (filedata, section),
26c527e6 6706 section->sh_entsize);
ba5cdace 6707 goto exit_point;
dd24e3da
NC
6708 }
6709
dda8d76d 6710 if (section->sh_size > filedata->file_size)
f54498b4 6711 {
26c527e6 6712 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 6713 printable_section_name (filedata, section),
26c527e6 6714 section->sh_size);
f54498b4
NC
6715 goto exit_point;
6716 }
6717
dd24e3da
NC
6718 number = section->sh_size / section->sh_entsize;
6719
6720 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6721 {
26c527e6
AM
6722 error (_("Size (%#" PRIx64 ") of section %s "
6723 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
6724 section->sh_size,
dda8d76d 6725 printable_section_name (filedata, section),
26c527e6 6726 section->sh_entsize);
ba5cdace 6727 goto exit_point;
dd24e3da
NC
6728 }
6729
dda8d76d 6730 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6731 section->sh_size, _("symbols"));
a6e9f9df 6732 if (!esyms)
ba5cdace 6733 goto exit_point;
9ea033b2 6734
e3d39609 6735 shndx = NULL;
978c4450 6736 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 6737 {
26c527e6 6738 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
6739 continue;
6740
6741 if (shndx != NULL)
6742 {
6743 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6744 free (shndx);
c9c1d674 6745 }
e3d39609
NC
6746
6747 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6748 entry->hdr->sh_offset,
6749 1, entry->hdr->sh_size,
6750 _("symbol table section indices"));
6751 if (shndx == NULL)
6752 goto exit_point;
6753
6754 /* PR17531: file: heap-buffer-overflow */
6755 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6756 {
26c527e6 6757 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 6758 printable_section_name (filedata, entry->hdr),
26c527e6
AM
6759 entry->hdr->sh_size,
6760 section->sh_size);
e3d39609
NC
6761 goto exit_point;
6762 }
6763 }
9ad5cbcf 6764
3f5e193b 6765 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6766
6767 if (isyms == NULL)
6768 {
26c527e6 6769 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
ba5cdace 6770 goto exit_point;
9ea033b2
NC
6771 }
6772
ba5cdace 6773 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6774 {
6775 psym->st_name = BYTE_GET (esyms[j].st_name);
6776 psym->st_info = BYTE_GET (esyms[j].st_info);
6777 psym->st_other = BYTE_GET (esyms[j].st_other);
6778 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6779
4fbb74a6 6780 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6781 psym->st_shndx
6782 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6783 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6784 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6785
66543521
AM
6786 psym->st_value = BYTE_GET (esyms[j].st_value);
6787 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6788 }
6789
ba5cdace 6790 exit_point:
e3d39609
NC
6791 free (shndx);
6792 free (esyms);
ba5cdace
NC
6793
6794 if (num_syms_return != NULL)
6795 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6796
6797 return isyms;
6798}
6799
4de91c10
AM
6800static Elf_Internal_Sym *
6801get_elf_symbols (Filedata *filedata,
6802 Elf_Internal_Shdr *section,
26c527e6 6803 uint64_t *num_syms_return)
4de91c10
AM
6804{
6805 if (is_32bit_elf)
6806 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6807 else
6808 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6809}
6810
d1133906 6811static const char *
625d49fc 6812get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 6813{
5477e8a0 6814 static char buff[1024];
2cf0635d 6815 char * p = buff;
32ec8896
NC
6816 unsigned int field_size = is_32bit_elf ? 8 : 16;
6817 signed int sindex;
6818 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
6819 uint64_t os_flags = 0;
6820 uint64_t proc_flags = 0;
6821 uint64_t unknown_flags = 0;
148b93f2 6822 static const struct
5477e8a0 6823 {
2cf0635d 6824 const char * str;
32ec8896 6825 unsigned int len;
5477e8a0
L
6826 }
6827 flags [] =
6828 {
cfcac11d
NC
6829 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6830 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6831 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6832 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6833 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6834 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6835 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6836 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6837 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6838 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6839 /* IA-64 specific. */
6840 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6841 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6842 /* IA-64 OpenVMS specific. */
6843 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6844 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6845 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6846 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6847 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6848 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6849 /* Generic. */
cfcac11d 6850 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6851 /* SPARC specific. */
77115a4a 6852 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6853 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6854 /* ARM specific. */
6855 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6856 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6857 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6858 /* GNU specific. */
6859 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6860 /* VLE specific. */
6861 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6862 /* GNU specific. */
6863 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6864 };
6865
6866 if (do_section_details)
6867 {
8d5ff12c
L
6868 sprintf (buff, "[%*.*lx]: ",
6869 field_size, field_size, (unsigned long) sh_flags);
6870 p += field_size + 4;
5477e8a0 6871 }
76da6bbe 6872
d1133906
NC
6873 while (sh_flags)
6874 {
625d49fc 6875 uint64_t flag;
d1133906
NC
6876
6877 flag = sh_flags & - sh_flags;
6878 sh_flags &= ~ flag;
76da6bbe 6879
5477e8a0 6880 if (do_section_details)
d1133906 6881 {
5477e8a0
L
6882 switch (flag)
6883 {
91d6fa6a
NC
6884 case SHF_WRITE: sindex = 0; break;
6885 case SHF_ALLOC: sindex = 1; break;
6886 case SHF_EXECINSTR: sindex = 2; break;
6887 case SHF_MERGE: sindex = 3; break;
6888 case SHF_STRINGS: sindex = 4; break;
6889 case SHF_INFO_LINK: sindex = 5; break;
6890 case SHF_LINK_ORDER: sindex = 6; break;
6891 case SHF_OS_NONCONFORMING: sindex = 7; break;
6892 case SHF_GROUP: sindex = 8; break;
6893 case SHF_TLS: sindex = 9; break;
18ae9cc1 6894 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6895 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6896
5477e8a0 6897 default:
91d6fa6a 6898 sindex = -1;
dda8d76d 6899 switch (filedata->file_header.e_machine)
148b93f2 6900 {
cfcac11d 6901 case EM_IA_64:
148b93f2 6902 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6903 sindex = 10;
148b93f2 6904 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6905 sindex = 11;
dda8d76d 6906 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6907 switch (flag)
6908 {
91d6fa6a
NC
6909 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6910 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6911 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6912 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6913 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6914 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6915 default: break;
6916 }
cfcac11d
NC
6917 break;
6918
caa83f8b 6919 case EM_386:
22abe556 6920 case EM_IAMCU:
caa83f8b 6921 case EM_X86_64:
7f502d6c 6922 case EM_L1OM:
7a9068fe 6923 case EM_K1OM:
cfcac11d
NC
6924 case EM_OLD_SPARCV9:
6925 case EM_SPARC32PLUS:
6926 case EM_SPARCV9:
6927 case EM_SPARC:
18ae9cc1 6928 if (flag == SHF_ORDERED)
91d6fa6a 6929 sindex = 19;
cfcac11d 6930 break;
ac4c9b04
MG
6931
6932 case EM_ARM:
6933 switch (flag)
6934 {
6935 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6936 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6937 case SHF_COMDEF: sindex = 23; break;
6938 default: break;
6939 }
6940 break;
83eef883
AFB
6941 case EM_PPC:
6942 if (flag == SHF_PPC_VLE)
6943 sindex = 25;
6944 break;
99fabbc9
JL
6945 default:
6946 break;
6947 }
ac4c9b04 6948
99fabbc9
JL
6949 switch (filedata->file_header.e_ident[EI_OSABI])
6950 {
6951 case ELFOSABI_GNU:
6952 case ELFOSABI_FREEBSD:
6953 if (flag == SHF_GNU_RETAIN)
6954 sindex = 26;
6955 /* Fall through */
6956 case ELFOSABI_NONE:
6957 if (flag == SHF_GNU_MBIND)
6958 /* We should not recognize SHF_GNU_MBIND for
6959 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6960 not set the EI_OSABI header byte. */
6961 sindex = 24;
6962 break;
cfcac11d
NC
6963 default:
6964 break;
148b93f2 6965 }
99fabbc9 6966 break;
5477e8a0
L
6967 }
6968
91d6fa6a 6969 if (sindex != -1)
5477e8a0 6970 {
8d5ff12c
L
6971 if (p != buff + field_size + 4)
6972 {
6973 if (size < (10 + 2))
bee0ee85
NC
6974 {
6975 warn (_("Internal error: not enough buffer room for section flag info"));
6976 return _("<unknown>");
6977 }
8d5ff12c
L
6978 size -= 2;
6979 *p++ = ',';
6980 *p++ = ' ';
6981 }
6982
91d6fa6a
NC
6983 size -= flags [sindex].len;
6984 p = stpcpy (p, flags [sindex].str);
5477e8a0 6985 }
3b22753a 6986 else if (flag & SHF_MASKOS)
8d5ff12c 6987 os_flags |= flag;
d1133906 6988 else if (flag & SHF_MASKPROC)
8d5ff12c 6989 proc_flags |= flag;
d1133906 6990 else
8d5ff12c 6991 unknown_flags |= flag;
5477e8a0
L
6992 }
6993 else
6994 {
6995 switch (flag)
6996 {
6997 case SHF_WRITE: *p = 'W'; break;
6998 case SHF_ALLOC: *p = 'A'; break;
6999 case SHF_EXECINSTR: *p = 'X'; break;
7000 case SHF_MERGE: *p = 'M'; break;
7001 case SHF_STRINGS: *p = 'S'; break;
7002 case SHF_INFO_LINK: *p = 'I'; break;
7003 case SHF_LINK_ORDER: *p = 'L'; break;
7004 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7005 case SHF_GROUP: *p = 'G'; break;
7006 case SHF_TLS: *p = 'T'; break;
18ae9cc1 7007 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 7008 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
7009
7010 default:
dda8d76d
NC
7011 if ((filedata->file_header.e_machine == EM_X86_64
7012 || filedata->file_header.e_machine == EM_L1OM
7013 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
7014 && flag == SHF_X86_64_LARGE)
7015 *p = 'l';
dda8d76d 7016 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 7017 && flag == SHF_ARM_PURECODE)
99fabbc9 7018 *p = 'y';
dda8d76d 7019 else if (filedata->file_header.e_machine == EM_PPC
83eef883 7020 && flag == SHF_PPC_VLE)
99fabbc9 7021 *p = 'v';
5477e8a0
L
7022 else if (flag & SHF_MASKOS)
7023 {
99fabbc9
JL
7024 switch (filedata->file_header.e_ident[EI_OSABI])
7025 {
7026 case ELFOSABI_GNU:
7027 case ELFOSABI_FREEBSD:
7028 if (flag == SHF_GNU_RETAIN)
7029 {
7030 *p = 'R';
7031 break;
7032 }
7033 /* Fall through */
7034 case ELFOSABI_NONE:
7035 if (flag == SHF_GNU_MBIND)
7036 {
7037 /* We should not recognize SHF_GNU_MBIND for
7038 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7039 not set the EI_OSABI header byte. */
7040 *p = 'D';
7041 break;
7042 }
7043 /* Fall through */
7044 default:
7045 *p = 'o';
7046 sh_flags &= ~SHF_MASKOS;
7047 break;
7048 }
5477e8a0
L
7049 }
7050 else if (flag & SHF_MASKPROC)
7051 {
7052 *p = 'p';
7053 sh_flags &= ~ SHF_MASKPROC;
7054 }
7055 else
7056 *p = 'x';
7057 break;
7058 }
7059 p++;
d1133906
NC
7060 }
7061 }
76da6bbe 7062
8d5ff12c
L
7063 if (do_section_details)
7064 {
7065 if (os_flags)
7066 {
7067 size -= 5 + field_size;
7068 if (p != buff + field_size + 4)
7069 {
7070 if (size < (2 + 1))
bee0ee85
NC
7071 {
7072 warn (_("Internal error: not enough buffer room for section flag info"));
7073 return _("<unknown>");
7074 }
8d5ff12c
L
7075 size -= 2;
7076 *p++ = ',';
7077 *p++ = ' ';
7078 }
7079 sprintf (p, "OS (%*.*lx)", field_size, field_size,
7080 (unsigned long) os_flags);
7081 p += 5 + field_size;
7082 }
7083 if (proc_flags)
7084 {
7085 size -= 7 + field_size;
7086 if (p != buff + field_size + 4)
7087 {
7088 if (size < (2 + 1))
bee0ee85
NC
7089 {
7090 warn (_("Internal error: not enough buffer room for section flag info"));
7091 return _("<unknown>");
7092 }
8d5ff12c
L
7093 size -= 2;
7094 *p++ = ',';
7095 *p++ = ' ';
7096 }
7097 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7098 (unsigned long) proc_flags);
7099 p += 7 + field_size;
7100 }
7101 if (unknown_flags)
7102 {
7103 size -= 10 + field_size;
7104 if (p != buff + field_size + 4)
7105 {
7106 if (size < (2 + 1))
bee0ee85
NC
7107 {
7108 warn (_("Internal error: not enough buffer room for section flag info"));
7109 return _("<unknown>");
7110 }
8d5ff12c
L
7111 size -= 2;
7112 *p++ = ',';
7113 *p++ = ' ';
7114 }
2b692964 7115 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
7116 (unsigned long) unknown_flags);
7117 p += 10 + field_size;
7118 }
7119 }
7120
e9e44622 7121 *p = '\0';
d1133906
NC
7122 return buff;
7123}
7124
5844b465 7125static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7126get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7127 uint64_t size)
77115a4a
L
7128{
7129 if (is_32bit_elf)
7130 {
7131 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7132
ebdf1ebf
NC
7133 if (size < sizeof (* echdr))
7134 {
7135 error (_("Compressed section is too small even for a compression header\n"));
7136 return 0;
7137 }
7138
77115a4a
L
7139 chdr->ch_type = BYTE_GET (echdr->ch_type);
7140 chdr->ch_size = BYTE_GET (echdr->ch_size);
7141 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7142 return sizeof (*echdr);
7143 }
7144 else
7145 {
7146 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7147
ebdf1ebf
NC
7148 if (size < sizeof (* echdr))
7149 {
7150 error (_("Compressed section is too small even for a compression header\n"));
7151 return 0;
7152 }
7153
77115a4a
L
7154 chdr->ch_type = BYTE_GET (echdr->ch_type);
7155 chdr->ch_size = BYTE_GET (echdr->ch_size);
7156 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7157 return sizeof (*echdr);
7158 }
7159}
7160
015dc7e1 7161static bool
dda8d76d 7162process_section_headers (Filedata * filedata)
252b5132 7163{
2cf0635d 7164 Elf_Internal_Shdr * section;
b34976b6 7165 unsigned int i;
252b5132 7166
dda8d76d 7167 if (filedata->file_header.e_shnum == 0)
252b5132 7168 {
82f2dbf7 7169 /* PR binutils/12467. */
dda8d76d 7170 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7171 {
7172 warn (_("possibly corrupt ELF file header - it has a non-zero"
7173 " section header offset, but no section headers\n"));
015dc7e1 7174 return false;
32ec8896 7175 }
82f2dbf7 7176 else if (do_sections)
252b5132
RH
7177 printf (_("\nThere are no sections in this file.\n"));
7178
015dc7e1 7179 return true;
252b5132
RH
7180 }
7181
7182 if (do_sections && !do_header)
ca0e11aa
NC
7183 {
7184 if (filedata->is_separate && process_links)
7185 printf (_("In linked file '%s': "), filedata->file_name);
7186 if (! filedata->is_separate || process_links)
7187 printf (ngettext ("There is %d section header, "
26c527e6 7188 "starting at offset %#" PRIx64 ":\n",
ca0e11aa 7189 "There are %d section headers, "
26c527e6 7190 "starting at offset %#" PRIx64 ":\n",
ca0e11aa
NC
7191 filedata->file_header.e_shnum),
7192 filedata->file_header.e_shnum,
26c527e6 7193 filedata->file_header.e_shoff);
ca0e11aa 7194 }
252b5132 7195
4de91c10
AM
7196 if (!get_section_headers (filedata, false))
7197 return false;
252b5132
RH
7198
7199 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7200 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7201 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7202 {
dda8d76d 7203 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7204
c256ffe7
JJ
7205 if (section->sh_size != 0)
7206 {
dda8d76d
NC
7207 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7208 1, section->sh_size,
7209 _("string table"));
0de14b54 7210
dda8d76d 7211 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7212 }
252b5132
RH
7213 }
7214
7215 /* Scan the sections for the dynamic symbol table
e3c8793a 7216 and dynamic string table and debug sections. */
89fac5e3 7217 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7218 switch (filedata->file_header.e_machine)
89fac5e3
RS
7219 {
7220 case EM_MIPS:
7221 case EM_MIPS_RS3_LE:
7222 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7223 FDE addresses. However, the ABI also has a semi-official ILP32
7224 variant for which the normal FDE address size rules apply.
7225
7226 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7227 section, where XX is the size of longs in bits. Unfortunately,
7228 earlier compilers provided no way of distinguishing ILP32 objects
7229 from LP64 objects, so if there's any doubt, we should assume that
7230 the official LP64 form is being used. */
dda8d76d
NC
7231 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7232 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7233 eh_addr_size = 8;
7234 break;
0f56a26a
DD
7235
7236 case EM_H8_300:
7237 case EM_H8_300H:
dda8d76d 7238 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7239 {
7240 case E_H8_MACH_H8300:
7241 case E_H8_MACH_H8300HN:
7242 case E_H8_MACH_H8300SN:
7243 case E_H8_MACH_H8300SXN:
7244 eh_addr_size = 2;
7245 break;
7246 case E_H8_MACH_H8300H:
7247 case E_H8_MACH_H8300S:
7248 case E_H8_MACH_H8300SX:
7249 eh_addr_size = 4;
7250 break;
7251 }
f4236fe4
DD
7252 break;
7253
ff7eeb89 7254 case EM_M32C_OLD:
f4236fe4 7255 case EM_M32C:
dda8d76d 7256 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7257 {
7258 case EF_M32C_CPU_M16C:
7259 eh_addr_size = 2;
7260 break;
7261 }
7262 break;
89fac5e3
RS
7263 }
7264
76ca31c0
NC
7265#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7266 do \
7267 { \
be7d229a 7268 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7269 if (section->sh_entsize != expected_entsize) \
9dd3a467 7270 { \
f493c217 7271 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7272 i, section->sh_entsize); \
f493c217 7273 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7274 expected_entsize); \
9dd3a467 7275 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7276 } \
7277 } \
08d8fa11 7278 while (0)
9dd3a467
NC
7279
7280#define CHECK_ENTSIZE(section, i, type) \
1b513401 7281 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7282 sizeof (Elf64_External_##type))
7283
dda8d76d
NC
7284 for (i = 0, section = filedata->section_headers;
7285 i < filedata->file_header.e_shnum;
b34976b6 7286 i++, section++)
252b5132 7287 {
84714f86 7288 const char *name = section_name_print (filedata, section);
252b5132 7289
1b513401
NC
7290 /* Run some sanity checks on the headers and
7291 possibly fill in some file data as well. */
7292 switch (section->sh_type)
252b5132 7293 {
1b513401 7294 case SHT_DYNSYM:
978c4450 7295 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7296 {
7297 error (_("File contains multiple dynamic symbol tables\n"));
7298 continue;
7299 }
7300
08d8fa11 7301 CHECK_ENTSIZE (section, i, Sym);
978c4450 7302 filedata->dynamic_symbols
4de91c10 7303 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7304 filedata->dynamic_symtab_section = section;
1b513401
NC
7305 break;
7306
7307 case SHT_STRTAB:
7308 if (streq (name, ".dynstr"))
252b5132 7309 {
1b513401
NC
7310 if (filedata->dynamic_strings != NULL)
7311 {
7312 error (_("File contains multiple dynamic string tables\n"));
7313 continue;
7314 }
7315
7316 filedata->dynamic_strings
7317 = (char *) get_data (NULL, filedata, section->sh_offset,
7318 1, section->sh_size, _("dynamic strings"));
7319 filedata->dynamic_strings_length
7320 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7321 filedata->dynamic_strtab_section = section;
252b5132 7322 }
1b513401
NC
7323 break;
7324
7325 case SHT_SYMTAB_SHNDX:
7326 {
7327 elf_section_list * entry = xmalloc (sizeof * entry);
7328
7329 entry->hdr = section;
7330 entry->next = filedata->symtab_shndx_list;
7331 filedata->symtab_shndx_list = entry;
7332 }
7333 break;
7334
7335 case SHT_SYMTAB:
7336 CHECK_ENTSIZE (section, i, Sym);
7337 break;
7338
7339 case SHT_GROUP:
7340 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7341 break;
252b5132 7342
1b513401
NC
7343 case SHT_REL:
7344 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7345 if (do_checks && section->sh_size == 0)
1b513401
NC
7346 warn (_("Section '%s': zero-sized relocation section\n"), name);
7347 break;
7348
7349 case SHT_RELA:
7350 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7351 if (do_checks && section->sh_size == 0)
1b513401
NC
7352 warn (_("Section '%s': zero-sized relocation section\n"), name);
7353 break;
7354
682351b9
AM
7355 case SHT_RELR:
7356 CHECK_ENTSIZE (section, i, Relr);
7357 break;
7358
1b513401
NC
7359 case SHT_NOTE:
7360 case SHT_PROGBITS:
546cb2d8
NC
7361 /* Having a zero sized section is not illegal according to the
7362 ELF standard, but it might be an indication that something
7363 is wrong. So issue a warning if we are running in lint mode. */
7364 if (do_checks && section->sh_size == 0)
1b513401
NC
7365 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7366 break;
7367
7368 default:
7369 break;
7370 }
7371
7372 if ((do_debugging || do_debug_info || do_debug_abbrevs
7373 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7374 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7375 || do_debug_str || do_debug_str_offsets || do_debug_loc
7376 || do_debug_ranges
1b513401 7377 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7378 && (startswith (name, ".debug_")
7379 || startswith (name, ".zdebug_")))
252b5132 7380 {
1b315056
CS
7381 if (name[1] == 'z')
7382 name += sizeof (".zdebug_") - 1;
7383 else
7384 name += sizeof (".debug_") - 1;
252b5132
RH
7385
7386 if (do_debugging
24d127aa
ML
7387 || (do_debug_info && startswith (name, "info"))
7388 || (do_debug_info && startswith (name, "types"))
7389 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7390 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7391 || (do_debug_lines && startswith (name, "line."))
7392 || (do_debug_pubnames && startswith (name, "pubnames"))
7393 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7394 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7395 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7396 || (do_debug_aranges && startswith (name, "aranges"))
7397 || (do_debug_ranges && startswith (name, "ranges"))
7398 || (do_debug_ranges && startswith (name, "rnglists"))
7399 || (do_debug_frames && startswith (name, "frame"))
7400 || (do_debug_macinfo && startswith (name, "macinfo"))
7401 || (do_debug_macinfo && startswith (name, "macro"))
7402 || (do_debug_str && startswith (name, "str"))
7403 || (do_debug_links && startswith (name, "sup"))
7404 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7405 || (do_debug_loc && startswith (name, "loc"))
7406 || (do_debug_loc && startswith (name, "loclists"))
7407 || (do_debug_addr && startswith (name, "addr"))
7408 || (do_debug_cu_index && startswith (name, "cu_index"))
7409 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7410 )
6431e409 7411 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7412 }
a262ae96 7413 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7414 else if ((do_debugging || do_debug_info)
24d127aa 7415 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7416 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7417 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7418 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7419 else if (do_gdb_index && (streq (name, ".gdb_index")
7420 || streq (name, ".debug_names")))
6431e409 7421 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7422 /* Trace sections for Itanium VMS. */
7423 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7424 || do_trace_aranges)
24d127aa 7425 && startswith (name, ".trace_"))
6f875884
TG
7426 {
7427 name += sizeof (".trace_") - 1;
7428
7429 if (do_debugging
7430 || (do_trace_info && streq (name, "info"))
7431 || (do_trace_abbrevs && streq (name, "abbrev"))
7432 || (do_trace_aranges && streq (name, "aranges"))
7433 )
6431e409 7434 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7435 }
dda8d76d 7436 else if ((do_debugging || do_debug_links)
24d127aa
ML
7437 && (startswith (name, ".gnu_debuglink")
7438 || startswith (name, ".gnu_debugaltlink")))
6431e409 7439 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7440 }
7441
7442 if (! do_sections)
015dc7e1 7443 return true;
252b5132 7444
ca0e11aa 7445 if (filedata->is_separate && ! process_links)
015dc7e1 7446 return true;
ca0e11aa
NC
7447
7448 if (filedata->is_separate)
7449 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7450 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7451 printf (_("\nSection Headers:\n"));
7452 else
7453 printf (_("\nSection Header:\n"));
76da6bbe 7454
f7a99963 7455 if (is_32bit_elf)
595cf52e 7456 {
5477e8a0 7457 if (do_section_details)
595cf52e
L
7458 {
7459 printf (_(" [Nr] Name\n"));
5477e8a0 7460 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7461 }
7462 else
7463 printf
7464 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7465 }
d974e256 7466 else if (do_wide)
595cf52e 7467 {
5477e8a0 7468 if (do_section_details)
595cf52e
L
7469 {
7470 printf (_(" [Nr] Name\n"));
5477e8a0 7471 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7472 }
7473 else
7474 printf
7475 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7476 }
f7a99963
NC
7477 else
7478 {
5477e8a0 7479 if (do_section_details)
595cf52e
L
7480 {
7481 printf (_(" [Nr] Name\n"));
5477e8a0
L
7482 printf (_(" Type Address Offset Link\n"));
7483 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7484 }
7485 else
7486 {
7487 printf (_(" [Nr] Name Type Address Offset\n"));
7488 printf (_(" Size EntSize Flags Link Info Align\n"));
7489 }
f7a99963 7490 }
252b5132 7491
5477e8a0
L
7492 if (do_section_details)
7493 printf (_(" Flags\n"));
7494
dda8d76d
NC
7495 for (i = 0, section = filedata->section_headers;
7496 i < filedata->file_header.e_shnum;
b34976b6 7497 i++, section++)
252b5132 7498 {
dd905818
NC
7499 /* Run some sanity checks on the section header. */
7500
7501 /* Check the sh_link field. */
7502 switch (section->sh_type)
7503 {
285e3f99
AM
7504 case SHT_REL:
7505 case SHT_RELA:
7506 if (section->sh_link == 0
7507 && (filedata->file_header.e_type == ET_EXEC
7508 || filedata->file_header.e_type == ET_DYN))
7509 /* A dynamic relocation section where all entries use a
7510 zero symbol index need not specify a symtab section. */
7511 break;
7512 /* Fall through. */
dd905818
NC
7513 case SHT_SYMTAB_SHNDX:
7514 case SHT_GROUP:
7515 case SHT_HASH:
7516 case SHT_GNU_HASH:
7517 case SHT_GNU_versym:
285e3f99 7518 if (section->sh_link == 0
dda8d76d
NC
7519 || section->sh_link >= filedata->file_header.e_shnum
7520 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7521 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7522 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7523 i, section->sh_link);
7524 break;
7525
7526 case SHT_DYNAMIC:
7527 case SHT_SYMTAB:
7528 case SHT_DYNSYM:
7529 case SHT_GNU_verneed:
7530 case SHT_GNU_verdef:
7531 case SHT_GNU_LIBLIST:
285e3f99 7532 if (section->sh_link == 0
dda8d76d
NC
7533 || section->sh_link >= filedata->file_header.e_shnum
7534 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7535 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7536 i, section->sh_link);
7537 break;
7538
7539 case SHT_INIT_ARRAY:
7540 case SHT_FINI_ARRAY:
7541 case SHT_PREINIT_ARRAY:
7542 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7543 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7544 i, section->sh_link);
7545 break;
7546
7547 default:
7548 /* FIXME: Add support for target specific section types. */
7549#if 0 /* Currently we do not check other section types as there are too
7550 many special cases. Stab sections for example have a type
7551 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7552 section. */
7553 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7554 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7555 i, section->sh_link);
7556#endif
7557 break;
7558 }
7559
7560 /* Check the sh_info field. */
7561 switch (section->sh_type)
7562 {
7563 case SHT_REL:
7564 case SHT_RELA:
285e3f99
AM
7565 if (section->sh_info == 0
7566 && (filedata->file_header.e_type == ET_EXEC
7567 || filedata->file_header.e_type == ET_DYN))
7568 /* Dynamic relocations apply to segments, so they do not
7569 need to specify the section they relocate. */
7570 break;
7571 if (section->sh_info == 0
dda8d76d
NC
7572 || section->sh_info >= filedata->file_header.e_shnum
7573 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7574 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7575 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7576 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7577 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7578 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7579 /* FIXME: Are other section types valid ? */
dda8d76d 7580 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7581 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7582 i, section->sh_info);
dd905818
NC
7583 break;
7584
7585 case SHT_DYNAMIC:
7586 case SHT_HASH:
7587 case SHT_SYMTAB_SHNDX:
7588 case SHT_INIT_ARRAY:
7589 case SHT_FINI_ARRAY:
7590 case SHT_PREINIT_ARRAY:
7591 if (section->sh_info != 0)
7592 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7593 i, section->sh_info);
7594 break;
7595
7596 case SHT_GROUP:
7597 case SHT_SYMTAB:
7598 case SHT_DYNSYM:
7599 /* A symbol index - we assume that it is valid. */
7600 break;
7601
7602 default:
7603 /* FIXME: Add support for target specific section types. */
7604 if (section->sh_type == SHT_NOBITS)
7605 /* NOBITS section headers with non-zero sh_info fields can be
7606 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7607 information. The stripped sections have their headers
7608 preserved but their types set to SHT_NOBITS. So do not check
7609 this type of section. */
dd905818
NC
7610 ;
7611 else if (section->sh_flags & SHF_INFO_LINK)
7612 {
dda8d76d 7613 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7614 warn (_("[%2u]: Expected link to another section in info field"), i);
7615 }
a91e1603
L
7616 else if (section->sh_type < SHT_LOOS
7617 && (section->sh_flags & SHF_GNU_MBIND) == 0
7618 && section->sh_info != 0)
dd905818
NC
7619 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7620 i, section->sh_info);
7621 break;
7622 }
7623
3e6b6445 7624 /* Check the sh_size field. */
dda8d76d 7625 if (section->sh_size > filedata->file_size
3e6b6445
NC
7626 && section->sh_type != SHT_NOBITS
7627 && section->sh_type != SHT_NULL
7628 && section->sh_type < SHT_LOOS)
7629 warn (_("Size of section %u is larger than the entire file!\n"), i);
7630
7bfd842d 7631 printf (" [%2u] ", i);
5477e8a0 7632 if (do_section_details)
dda8d76d 7633 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7634 else
84714f86 7635 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7636
ea52a088 7637 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7638 get_section_type_name (filedata, section->sh_type));
0b4362b0 7639
f7a99963
NC
7640 if (is_32bit_elf)
7641 {
cfcac11d
NC
7642 const char * link_too_big = NULL;
7643
f7a99963 7644 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7645
f7a99963
NC
7646 printf ( " %6.6lx %6.6lx %2.2lx",
7647 (unsigned long) section->sh_offset,
7648 (unsigned long) section->sh_size,
7649 (unsigned long) section->sh_entsize);
d1133906 7650
5477e8a0
L
7651 if (do_section_details)
7652 fputs (" ", stdout);
7653 else
dda8d76d 7654 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7655
dda8d76d 7656 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7657 {
7658 link_too_big = "";
7659 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7660 an error but it can have special values in Solaris binaries. */
dda8d76d 7661 switch (filedata->file_header.e_machine)
cfcac11d 7662 {
caa83f8b 7663 case EM_386:
22abe556 7664 case EM_IAMCU:
caa83f8b 7665 case EM_X86_64:
7f502d6c 7666 case EM_L1OM:
7a9068fe 7667 case EM_K1OM:
cfcac11d
NC
7668 case EM_OLD_SPARCV9:
7669 case EM_SPARC32PLUS:
7670 case EM_SPARCV9:
7671 case EM_SPARC:
7672 if (section->sh_link == (SHN_BEFORE & 0xffff))
7673 link_too_big = "BEFORE";
7674 else if (section->sh_link == (SHN_AFTER & 0xffff))
7675 link_too_big = "AFTER";
7676 break;
7677 default:
7678 break;
7679 }
7680 }
7681
7682 if (do_section_details)
7683 {
7684 if (link_too_big != NULL && * link_too_big)
7685 printf ("<%s> ", link_too_big);
7686 else
7687 printf ("%2u ", section->sh_link);
7688 printf ("%3u %2lu\n", section->sh_info,
7689 (unsigned long) section->sh_addralign);
7690 }
7691 else
7692 printf ("%2u %3u %2lu\n",
7693 section->sh_link,
7694 section->sh_info,
7695 (unsigned long) section->sh_addralign);
7696
7697 if (link_too_big && ! * link_too_big)
7698 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7699 i, section->sh_link);
f7a99963 7700 }
d974e256
JJ
7701 else if (do_wide)
7702 {
7703 print_vma (section->sh_addr, LONG_HEX);
7704
7705 if ((long) section->sh_offset == section->sh_offset)
7706 printf (" %6.6lx", (unsigned long) section->sh_offset);
7707 else
7708 {
7709 putchar (' ');
7710 print_vma (section->sh_offset, LONG_HEX);
7711 }
7712
7713 if ((unsigned long) section->sh_size == section->sh_size)
7714 printf (" %6.6lx", (unsigned long) section->sh_size);
7715 else
7716 {
7717 putchar (' ');
7718 print_vma (section->sh_size, LONG_HEX);
7719 }
7720
7721 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7722 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7723 else
7724 {
7725 putchar (' ');
7726 print_vma (section->sh_entsize, LONG_HEX);
7727 }
7728
5477e8a0
L
7729 if (do_section_details)
7730 fputs (" ", stdout);
7731 else
dda8d76d 7732 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7733
72de5009 7734 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7735
7736 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7737 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7738 else
7739 {
7740 print_vma (section->sh_addralign, DEC);
7741 putchar ('\n');
7742 }
7743 }
5477e8a0 7744 else if (do_section_details)
595cf52e 7745 {
55cc53e9 7746 putchar (' ');
595cf52e
L
7747 print_vma (section->sh_addr, LONG_HEX);
7748 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7749 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7750 else
7751 {
7752 printf (" ");
7753 print_vma (section->sh_offset, LONG_HEX);
7754 }
72de5009 7755 printf (" %u\n ", section->sh_link);
595cf52e 7756 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7757 putchar (' ');
595cf52e
L
7758 print_vma (section->sh_entsize, LONG_HEX);
7759
72de5009
AM
7760 printf (" %-16u %lu\n",
7761 section->sh_info,
595cf52e
L
7762 (unsigned long) section->sh_addralign);
7763 }
f7a99963
NC
7764 else
7765 {
7766 putchar (' ');
7767 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7768 if ((long) section->sh_offset == section->sh_offset)
7769 printf (" %8.8lx", (unsigned long) section->sh_offset);
7770 else
7771 {
7772 printf (" ");
7773 print_vma (section->sh_offset, LONG_HEX);
7774 }
f7a99963
NC
7775 printf ("\n ");
7776 print_vma (section->sh_size, LONG_HEX);
7777 printf (" ");
7778 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7779
dda8d76d 7780 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7781
72de5009
AM
7782 printf (" %2u %3u %lu\n",
7783 section->sh_link,
7784 section->sh_info,
f7a99963
NC
7785 (unsigned long) section->sh_addralign);
7786 }
5477e8a0
L
7787
7788 if (do_section_details)
77115a4a 7789 {
dda8d76d 7790 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7791 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7792 {
7793 /* Minimum section size is 12 bytes for 32-bit compression
7794 header + 12 bytes for compressed data header. */
7795 unsigned char buf[24];
d8024a91 7796
77115a4a 7797 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7798 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7799 sizeof (buf), _("compression header")))
7800 {
7801 Elf_Internal_Chdr chdr;
d8024a91 7802
5844b465
NC
7803 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7804 printf (_(" [<corrupt>]\n"));
77115a4a 7805 else
5844b465 7806 {
89dbeac7 7807 if (chdr.ch_type == ch_compress_zlib)
5844b465 7808 printf (" ZLIB, ");
89dbeac7 7809 else if (chdr.ch_type == ch_compress_zstd)
1369522f 7810 printf (" ZSTD, ");
5844b465
NC
7811 else
7812 printf (_(" [<unknown>: 0x%x], "),
7813 chdr.ch_type);
7814 print_vma (chdr.ch_size, LONG_HEX);
7815 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7816 }
77115a4a
L
7817 }
7818 }
7819 }
252b5132
RH
7820 }
7821
5477e8a0 7822 if (!do_section_details)
3dbcc61d 7823 {
9fb71ee4
NC
7824 /* The ordering of the letters shown here matches the ordering of the
7825 corresponding SHF_xxx values, and hence the order in which these
7826 letters will be displayed to the user. */
7827 printf (_("Key to Flags:\n\
7828 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7829 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7830 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7831 switch (filedata->file_header.e_ident[EI_OSABI])
7832 {
7833 case ELFOSABI_GNU:
7834 case ELFOSABI_FREEBSD:
7835 printf (_("R (retain), "));
7836 /* Fall through */
7837 case ELFOSABI_NONE:
7838 printf (_("D (mbind), "));
7839 break;
7840 default:
7841 break;
7842 }
dda8d76d
NC
7843 if (filedata->file_header.e_machine == EM_X86_64
7844 || filedata->file_header.e_machine == EM_L1OM
7845 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7846 printf (_("l (large), "));
dda8d76d 7847 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7848 printf (_("y (purecode), "));
dda8d76d 7849 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7850 printf (_("v (VLE), "));
9fb71ee4 7851 printf ("p (processor specific)\n");
0b4362b0 7852 }
d1133906 7853
015dc7e1 7854 return true;
252b5132
RH
7855}
7856
015dc7e1 7857static bool
28d13567 7858get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
26c527e6
AM
7859 Elf_Internal_Sym **symtab, uint64_t *nsyms,
7860 char **strtab, uint64_t *strtablen)
28d13567
AM
7861{
7862 *strtab = NULL;
7863 *strtablen = 0;
4de91c10 7864 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7865
7866 if (*symtab == NULL)
015dc7e1 7867 return false;
28d13567
AM
7868
7869 if (symsec->sh_link != 0)
7870 {
7871 Elf_Internal_Shdr *strsec;
7872
7873 if (symsec->sh_link >= filedata->file_header.e_shnum)
7874 {
7875 error (_("Bad sh_link in symbol table section\n"));
7876 free (*symtab);
7877 *symtab = NULL;
7878 *nsyms = 0;
015dc7e1 7879 return false;
28d13567
AM
7880 }
7881
7882 strsec = filedata->section_headers + symsec->sh_link;
7883
7884 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7885 1, strsec->sh_size, _("string table"));
7886 if (*strtab == NULL)
7887 {
7888 free (*symtab);
7889 *symtab = NULL;
7890 *nsyms = 0;
015dc7e1 7891 return false;
28d13567
AM
7892 }
7893 *strtablen = strsec->sh_size;
7894 }
015dc7e1 7895 return true;
28d13567
AM
7896}
7897
f5842774
L
7898static const char *
7899get_group_flags (unsigned int flags)
7900{
1449284b 7901 static char buff[128];
220453ec 7902
6d913794
NC
7903 if (flags == 0)
7904 return "";
7905 else if (flags == GRP_COMDAT)
7906 return "COMDAT ";
f5842774 7907
89246a0e
AM
7908 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7909 flags,
7910 flags & GRP_MASKOS ? _("<OS specific>") : "",
7911 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7912 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7913 ? _("<unknown>") : ""));
6d913794 7914
f5842774
L
7915 return buff;
7916}
7917
015dc7e1 7918static bool
dda8d76d 7919process_section_groups (Filedata * filedata)
f5842774 7920{
2cf0635d 7921 Elf_Internal_Shdr * section;
f5842774 7922 unsigned int i;
2cf0635d
NC
7923 struct group * group;
7924 Elf_Internal_Shdr * symtab_sec;
7925 Elf_Internal_Shdr * strtab_sec;
7926 Elf_Internal_Sym * symtab;
26c527e6 7927 uint64_t num_syms;
2cf0635d 7928 char * strtab;
c256ffe7 7929 size_t strtab_size;
d1f5c6e3
L
7930
7931 /* Don't process section groups unless needed. */
7932 if (!do_unwind && !do_section_groups)
015dc7e1 7933 return true;
f5842774 7934
dda8d76d 7935 if (filedata->file_header.e_shnum == 0)
f5842774
L
7936 {
7937 if (do_section_groups)
ca0e11aa
NC
7938 {
7939 if (filedata->is_separate)
7940 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7941 filedata->file_name);
7942 else
7943 printf (_("\nThere are no section groups in this file.\n"));
7944 }
015dc7e1 7945 return true;
f5842774
L
7946 }
7947
dda8d76d 7948 if (filedata->section_headers == NULL)
f5842774
L
7949 {
7950 error (_("Section headers are not available!\n"));
fa1908fd 7951 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7952 return false;
f5842774
L
7953 }
7954
978c4450
AM
7955 filedata->section_headers_groups
7956 = (struct group **) calloc (filedata->file_header.e_shnum,
7957 sizeof (struct group *));
e4b17d5c 7958
978c4450 7959 if (filedata->section_headers_groups == NULL)
e4b17d5c 7960 {
8b73c356 7961 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7962 filedata->file_header.e_shnum);
015dc7e1 7963 return false;
e4b17d5c
L
7964 }
7965
f5842774 7966 /* Scan the sections for the group section. */
978c4450 7967 filedata->group_count = 0;
dda8d76d
NC
7968 for (i = 0, section = filedata->section_headers;
7969 i < filedata->file_header.e_shnum;
f5842774 7970 i++, section++)
e4b17d5c 7971 if (section->sh_type == SHT_GROUP)
978c4450 7972 filedata->group_count++;
e4b17d5c 7973
978c4450 7974 if (filedata->group_count == 0)
d1f5c6e3
L
7975 {
7976 if (do_section_groups)
ca0e11aa
NC
7977 {
7978 if (filedata->is_separate)
7979 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7980 filedata->file_name);
7981 else
7982 printf (_("\nThere are no section groups in this file.\n"));
7983 }
d1f5c6e3 7984
015dc7e1 7985 return true;
d1f5c6e3
L
7986 }
7987
978c4450
AM
7988 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7989 sizeof (struct group));
e4b17d5c 7990
978c4450 7991 if (filedata->section_groups == NULL)
e4b17d5c 7992 {
26c527e6 7993 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
015dc7e1 7994 return false;
e4b17d5c
L
7995 }
7996
d1f5c6e3
L
7997 symtab_sec = NULL;
7998 strtab_sec = NULL;
7999 symtab = NULL;
ba5cdace 8000 num_syms = 0;
d1f5c6e3 8001 strtab = NULL;
c256ffe7 8002 strtab_size = 0;
ca0e11aa
NC
8003
8004 if (filedata->is_separate)
8005 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 8006
978c4450 8007 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 8008 i < filedata->file_header.e_shnum;
e4b17d5c 8009 i++, section++)
f5842774
L
8010 {
8011 if (section->sh_type == SHT_GROUP)
8012 {
dda8d76d 8013 const char * name = printable_section_name (filedata, section);
74e1a04b 8014 const char * group_name;
2cf0635d
NC
8015 unsigned char * start;
8016 unsigned char * indices;
f5842774 8017 unsigned int entry, j, size;
2cf0635d
NC
8018 Elf_Internal_Shdr * sec;
8019 Elf_Internal_Sym * sym;
f5842774
L
8020
8021 /* Get the symbol table. */
dda8d76d
NC
8022 if (section->sh_link >= filedata->file_header.e_shnum
8023 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 8024 != SHT_SYMTAB))
f5842774
L
8025 {
8026 error (_("Bad sh_link in group section `%s'\n"), name);
8027 continue;
8028 }
d1f5c6e3
L
8029
8030 if (symtab_sec != sec)
8031 {
8032 symtab_sec = sec;
9db70fc3 8033 free (symtab);
4de91c10 8034 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 8035 }
f5842774 8036
dd24e3da
NC
8037 if (symtab == NULL)
8038 {
8039 error (_("Corrupt header in group section `%s'\n"), name);
8040 continue;
8041 }
8042
ba5cdace
NC
8043 if (section->sh_info >= num_syms)
8044 {
8045 error (_("Bad sh_info in group section `%s'\n"), name);
8046 continue;
8047 }
8048
f5842774
L
8049 sym = symtab + section->sh_info;
8050
8051 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8052 {
4fbb74a6 8053 if (sym->st_shndx == 0
dda8d76d 8054 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
8055 {
8056 error (_("Bad sh_info in group section `%s'\n"), name);
8057 continue;
8058 }
ba2685cc 8059
84714f86
AM
8060 group_name = section_name_print (filedata,
8061 filedata->section_headers
b9e920ec 8062 + sym->st_shndx);
c256ffe7 8063 strtab_sec = NULL;
9db70fc3 8064 free (strtab);
f5842774 8065 strtab = NULL;
c256ffe7 8066 strtab_size = 0;
f5842774
L
8067 }
8068 else
8069 {
8070 /* Get the string table. */
dda8d76d 8071 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8072 {
8073 strtab_sec = NULL;
9db70fc3 8074 free (strtab);
c256ffe7
JJ
8075 strtab = NULL;
8076 strtab_size = 0;
8077 }
8078 else if (strtab_sec
dda8d76d 8079 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8080 {
8081 strtab_sec = sec;
9db70fc3 8082 free (strtab);
071436c6 8083
dda8d76d 8084 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8085 1, strtab_sec->sh_size,
8086 _("string table"));
c256ffe7 8087 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8088 }
c256ffe7 8089 group_name = sym->st_name < strtab_size
2b692964 8090 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8091 }
8092
c9c1d674
EG
8093 /* PR 17531: file: loop. */
8094 if (section->sh_entsize > section->sh_size)
8095 {
26c527e6
AM
8096 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8097 " which is larger than its size (%#" PRIx64 ")\n"),
dda8d76d 8098 printable_section_name (filedata, section),
26c527e6
AM
8099 section->sh_entsize,
8100 section->sh_size);
61dd8e19 8101 continue;
c9c1d674
EG
8102 }
8103
dda8d76d 8104 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8105 1, section->sh_size,
8106 _("section data"));
59245841
NC
8107 if (start == NULL)
8108 continue;
f5842774
L
8109
8110 indices = start;
8111 size = (section->sh_size / section->sh_entsize) - 1;
8112 entry = byte_get (indices, 4);
8113 indices += 4;
e4b17d5c
L
8114
8115 if (do_section_groups)
8116 {
2b692964 8117 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8118 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8119
e4b17d5c
L
8120 printf (_(" [Index] Name\n"));
8121 }
8122
8123 group->group_index = i;
8124
f5842774
L
8125 for (j = 0; j < size; j++)
8126 {
2cf0635d 8127 struct group_list * g;
e4b17d5c 8128
f5842774
L
8129 entry = byte_get (indices, 4);
8130 indices += 4;
8131
dda8d76d 8132 if (entry >= filedata->file_header.e_shnum)
391cb864 8133 {
57028622
NC
8134 static unsigned num_group_errors = 0;
8135
8136 if (num_group_errors ++ < 10)
8137 {
8138 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8139 entry, i, filedata->file_header.e_shnum - 1);
57028622 8140 if (num_group_errors == 10)
67ce483b 8141 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8142 }
391cb864
L
8143 continue;
8144 }
391cb864 8145
978c4450 8146 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8147 {
d1f5c6e3
L
8148 if (entry)
8149 {
57028622
NC
8150 static unsigned num_errs = 0;
8151
8152 if (num_errs ++ < 10)
8153 {
8154 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8155 entry, i,
978c4450 8156 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8157 if (num_errs == 10)
8158 warn (_("Further error messages about already contained group sections suppressed\n"));
8159 }
d1f5c6e3
L
8160 continue;
8161 }
8162 else
8163 {
8164 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8165 section group. We just warn it the first time
d1f5c6e3 8166 and ignore it afterwards. */
015dc7e1 8167 static bool warned = false;
d1f5c6e3
L
8168 if (!warned)
8169 {
8170 error (_("section 0 in group section [%5u]\n"),
978c4450 8171 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8172 warned = true;
d1f5c6e3
L
8173 }
8174 }
e4b17d5c
L
8175 }
8176
978c4450 8177 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8178
8179 if (do_section_groups)
8180 {
dda8d76d
NC
8181 sec = filedata->section_headers + entry;
8182 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8183 }
8184
3f5e193b 8185 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8186 g->section_index = entry;
8187 g->next = group->root;
8188 group->root = g;
f5842774
L
8189 }
8190
9db70fc3 8191 free (start);
e4b17d5c
L
8192
8193 group++;
f5842774
L
8194 }
8195 }
8196
9db70fc3
AM
8197 free (symtab);
8198 free (strtab);
015dc7e1 8199 return true;
f5842774
L
8200}
8201
28f997cf
TG
8202/* Data used to display dynamic fixups. */
8203
8204struct ia64_vms_dynfixup
8205{
625d49fc
AM
8206 uint64_t needed_ident; /* Library ident number. */
8207 uint64_t needed; /* Index in the dstrtab of the library name. */
8208 uint64_t fixup_needed; /* Index of the library. */
8209 uint64_t fixup_rela_cnt; /* Number of fixups. */
8210 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8211};
8212
8213/* Data used to display dynamic relocations. */
8214
8215struct ia64_vms_dynimgrela
8216{
625d49fc
AM
8217 uint64_t img_rela_cnt; /* Number of relocations. */
8218 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8219};
8220
8221/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8222 library). */
8223
015dc7e1 8224static bool
dda8d76d
NC
8225dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8226 struct ia64_vms_dynfixup * fixup,
8227 const char * strtab,
8228 unsigned int strtab_sz)
28f997cf 8229{
32ec8896 8230 Elf64_External_VMS_IMAGE_FIXUP * imfs;
26c527e6 8231 size_t i;
32ec8896 8232 const char * lib_name;
28f997cf 8233
978c4450
AM
8234 imfs = get_data (NULL, filedata,
8235 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8236 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8237 _("dynamic section image fixups"));
8238 if (!imfs)
015dc7e1 8239 return false;
28f997cf
TG
8240
8241 if (fixup->needed < strtab_sz)
8242 lib_name = strtab + fixup->needed;
8243 else
8244 {
26c527e6
AM
8245 warn (_("corrupt library name index of %#" PRIx64
8246 " found in dynamic entry"), fixup->needed);
28f997cf
TG
8247 lib_name = "???";
8248 }
736990c4 8249
26c527e6
AM
8250 printf (_("\nImage fixups for needed library #%" PRId64
8251 ": %s - ident: %" PRIx64 "\n"),
8252 fixup->fixup_needed, lib_name, fixup->needed_ident);
28f997cf
TG
8253 printf
8254 (_("Seg Offset Type SymVec DataType\n"));
8255
26c527e6 8256 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
28f997cf
TG
8257 {
8258 unsigned int type;
8259 const char *rtype;
8260
8261 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8262 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8263 type = BYTE_GET (imfs [i].type);
8264 rtype = elf_ia64_reloc_type (type);
8265 if (rtype == NULL)
f493c217 8266 printf ("0x%08x ", type);
28f997cf 8267 else
f493c217 8268 printf ("%-32s ", rtype);
28f997cf
TG
8269 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8270 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8271 }
8272
8273 free (imfs);
015dc7e1 8274 return true;
28f997cf
TG
8275}
8276
8277/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8278
015dc7e1 8279static bool
dda8d76d 8280dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8281{
8282 Elf64_External_VMS_IMAGE_RELA *imrs;
26c527e6 8283 size_t i;
28f997cf 8284
978c4450
AM
8285 imrs = get_data (NULL, filedata,
8286 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8287 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8288 _("dynamic section image relocations"));
28f997cf 8289 if (!imrs)
015dc7e1 8290 return false;
28f997cf
TG
8291
8292 printf (_("\nImage relocs\n"));
8293 printf
8294 (_("Seg Offset Type Addend Seg Sym Off\n"));
8295
26c527e6 8296 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
28f997cf
TG
8297 {
8298 unsigned int type;
8299 const char *rtype;
8300
8301 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8302 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8303 type = BYTE_GET (imrs [i].type);
8304 rtype = elf_ia64_reloc_type (type);
8305 if (rtype == NULL)
8306 printf ("0x%08x ", type);
8307 else
8308 printf ("%-31s ", rtype);
8309 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8310 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8311 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8312 }
8313
8314 free (imrs);
015dc7e1 8315 return true;
28f997cf
TG
8316}
8317
8318/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8319
015dc7e1 8320static bool
dda8d76d 8321process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8322{
8323 struct ia64_vms_dynfixup fixup;
8324 struct ia64_vms_dynimgrela imgrela;
8325 Elf_Internal_Dyn *entry;
625d49fc
AM
8326 uint64_t strtab_off = 0;
8327 uint64_t strtab_sz = 0;
28f997cf 8328 char *strtab = NULL;
015dc7e1 8329 bool res = true;
28f997cf
TG
8330
8331 memset (&fixup, 0, sizeof (fixup));
8332 memset (&imgrela, 0, sizeof (imgrela));
8333
8334 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8335 for (entry = filedata->dynamic_section;
8336 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8337 entry++)
8338 {
8339 switch (entry->d_tag)
8340 {
8341 case DT_IA_64_VMS_STRTAB_OFFSET:
8342 strtab_off = entry->d_un.d_val;
8343 break;
8344 case DT_STRSZ:
8345 strtab_sz = entry->d_un.d_val;
8346 if (strtab == NULL)
978c4450
AM
8347 strtab = get_data (NULL, filedata,
8348 filedata->dynamic_addr + strtab_off,
28f997cf 8349 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8350 if (strtab == NULL)
8351 strtab_sz = 0;
28f997cf
TG
8352 break;
8353
8354 case DT_IA_64_VMS_NEEDED_IDENT:
8355 fixup.needed_ident = entry->d_un.d_val;
8356 break;
8357 case DT_NEEDED:
8358 fixup.needed = entry->d_un.d_val;
8359 break;
8360 case DT_IA_64_VMS_FIXUP_NEEDED:
8361 fixup.fixup_needed = entry->d_un.d_val;
8362 break;
8363 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8364 fixup.fixup_rela_cnt = entry->d_un.d_val;
8365 break;
8366 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8367 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8368 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8369 res = false;
28f997cf 8370 break;
28f997cf
TG
8371 case DT_IA_64_VMS_IMG_RELA_CNT:
8372 imgrela.img_rela_cnt = entry->d_un.d_val;
8373 break;
8374 case DT_IA_64_VMS_IMG_RELA_OFF:
8375 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8376 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8377 res = false;
28f997cf
TG
8378 break;
8379
8380 default:
8381 break;
8382 }
8383 }
8384
9db70fc3 8385 free (strtab);
28f997cf
TG
8386
8387 return res;
8388}
8389
85b1c36d 8390static struct
566b0d53 8391{
2cf0635d 8392 const char * name;
566b0d53
L
8393 int reloc;
8394 int size;
a7fd1186 8395 relocation_type rel_type;
32ec8896
NC
8396}
8397 dynamic_relocations [] =
566b0d53 8398{
a7fd1186
FS
8399 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8400 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8401 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8402 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8403};
8404
252b5132 8405/* Process the reloc section. */
18bd398b 8406
015dc7e1 8407static bool
dda8d76d 8408process_relocs (Filedata * filedata)
252b5132 8409{
26c527e6
AM
8410 uint64_t rel_size;
8411 uint64_t rel_offset;
252b5132 8412
252b5132 8413 if (!do_reloc)
015dc7e1 8414 return true;
252b5132
RH
8415
8416 if (do_using_dynamic)
8417 {
a7fd1186 8418 relocation_type rel_type;
2cf0635d 8419 const char * name;
015dc7e1 8420 bool has_dynamic_reloc;
566b0d53 8421 unsigned int i;
0de14b54 8422
015dc7e1 8423 has_dynamic_reloc = false;
252b5132 8424
566b0d53 8425 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8426 {
a7fd1186 8427 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8428 name = dynamic_relocations [i].name;
978c4450
AM
8429 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8430 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8431
32ec8896 8432 if (rel_size)
015dc7e1 8433 has_dynamic_reloc = true;
566b0d53 8434
a7fd1186 8435 if (rel_type == reltype_unknown)
aa903cfb 8436 {
566b0d53 8437 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8438 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8439 {
8440 case DT_REL:
a7fd1186 8441 rel_type = reltype_rel;
566b0d53
L
8442 break;
8443 case DT_RELA:
a7fd1186 8444 rel_type = reltype_rela;
566b0d53
L
8445 break;
8446 }
aa903cfb 8447 }
252b5132 8448
566b0d53
L
8449 if (rel_size)
8450 {
ca0e11aa
NC
8451 if (filedata->is_separate)
8452 printf
26c527e6
AM
8453 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
8454 " contains %" PRId64 " bytes:\n"),
ca0e11aa
NC
8455 filedata->file_name, name, rel_offset, rel_size);
8456 else
8457 printf
26c527e6
AM
8458 (_("\n'%s' relocation section at offset %#" PRIx64
8459 " contains %" PRId64 " bytes:\n"),
ca0e11aa 8460 name, rel_offset, rel_size);
252b5132 8461
dda8d76d
NC
8462 dump_relocations (filedata,
8463 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8464 rel_size,
978c4450
AM
8465 filedata->dynamic_symbols,
8466 filedata->num_dynamic_syms,
8467 filedata->dynamic_strings,
8468 filedata->dynamic_strings_length,
a7fd1186 8469 rel_type, true /* is_dynamic */);
566b0d53 8470 }
252b5132 8471 }
566b0d53 8472
dda8d76d
NC
8473 if (is_ia64_vms (filedata))
8474 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8475 has_dynamic_reloc = true;
28f997cf 8476
566b0d53 8477 if (! has_dynamic_reloc)
ca0e11aa
NC
8478 {
8479 if (filedata->is_separate)
8480 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8481 filedata->file_name);
8482 else
8483 printf (_("\nThere are no dynamic relocations in this file.\n"));
8484 }
252b5132
RH
8485 }
8486 else
8487 {
2cf0635d 8488 Elf_Internal_Shdr * section;
26c527e6 8489 size_t i;
015dc7e1 8490 bool found = false;
252b5132 8491
dda8d76d
NC
8492 for (i = 0, section = filedata->section_headers;
8493 i < filedata->file_header.e_shnum;
b34976b6 8494 i++, section++)
252b5132
RH
8495 {
8496 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8497 && section->sh_type != SHT_REL
8498 && section->sh_type != SHT_RELR)
252b5132
RH
8499 continue;
8500
8501 rel_offset = section->sh_offset;
8502 rel_size = section->sh_size;
8503
8504 if (rel_size)
8505 {
a7fd1186 8506 relocation_type rel_type;
26c527e6 8507 uint64_t num_rela;
103f02d3 8508
ca0e11aa
NC
8509 if (filedata->is_separate)
8510 printf (_("\nIn linked file '%s' relocation section "),
8511 filedata->file_name);
8512 else
8513 printf (_("\nRelocation section "));
252b5132 8514
dda8d76d 8515 if (filedata->string_table == NULL)
19936277 8516 printf ("%d", section->sh_name);
252b5132 8517 else
dda8d76d 8518 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8519
d3a49aa8 8520 num_rela = rel_size / section->sh_entsize;
26c527e6
AM
8521 printf (ngettext (" at offset %#" PRIx64
8522 " contains %" PRIu64 " entry:\n",
8523 " at offset %#" PRIx64
8524 " contains %" PRId64 " entries:\n",
d3a49aa8
AM
8525 num_rela),
8526 rel_offset, num_rela);
252b5132 8527
a7fd1186
FS
8528 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8529 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8530
4fbb74a6 8531 if (section->sh_link != 0
dda8d76d 8532 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8533 {
26c527e6
AM
8534 Elf_Internal_Shdr *symsec;
8535 Elf_Internal_Sym *symtab;
8536 uint64_t nsyms;
8537 uint64_t strtablen = 0;
8538 char *strtab = NULL;
57346661 8539
dda8d76d 8540 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8541 if (symsec->sh_type != SHT_SYMTAB
8542 && symsec->sh_type != SHT_DYNSYM)
8543 continue;
8544
28d13567
AM
8545 if (!get_symtab (filedata, symsec,
8546 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8547 continue;
252b5132 8548
dda8d76d 8549 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8550 symtab, nsyms, strtab, strtablen,
a7fd1186 8551 rel_type,
bb4d2ac2 8552 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8553 free (strtab);
d79b3d50
NC
8554 free (symtab);
8555 }
8556 else
dda8d76d 8557 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8558 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8559
015dc7e1 8560 found = true;
252b5132
RH
8561 }
8562 }
8563
8564 if (! found)
45ac8f4f
NC
8565 {
8566 /* Users sometimes forget the -D option, so try to be helpful. */
8567 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8568 {
978c4450 8569 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8570 {
ca0e11aa
NC
8571 if (filedata->is_separate)
8572 printf (_("\nThere are no static relocations in linked file '%s'."),
8573 filedata->file_name);
8574 else
8575 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8576 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8577
8578 break;
8579 }
8580 }
8581 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8582 {
8583 if (filedata->is_separate)
8584 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8585 filedata->file_name);
8586 else
8587 printf (_("\nThere are no relocations in this file.\n"));
8588 }
45ac8f4f 8589 }
252b5132
RH
8590 }
8591
015dc7e1 8592 return true;
252b5132
RH
8593}
8594
4d6ed7c8
NC
8595/* An absolute address consists of a section and an offset. If the
8596 section is NULL, the offset itself is the address, otherwise, the
8597 address equals to LOAD_ADDRESS(section) + offset. */
8598
8599struct absaddr
948f632f
DA
8600{
8601 unsigned short section;
625d49fc 8602 uint64_t offset;
948f632f 8603};
4d6ed7c8 8604
948f632f
DA
8605/* Find the nearest symbol at or below ADDR. Returns the symbol
8606 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8607
4d6ed7c8 8608static void
26c527e6
AM
8609find_symbol_for_address (Filedata *filedata,
8610 Elf_Internal_Sym *symtab,
8611 uint64_t nsyms,
8612 const char *strtab,
8613 uint64_t strtab_size,
8614 struct absaddr addr,
8615 const char **symname,
8616 uint64_t *offset)
4d6ed7c8 8617{
625d49fc 8618 uint64_t dist = 0x100000;
2cf0635d 8619 Elf_Internal_Sym * sym;
948f632f
DA
8620 Elf_Internal_Sym * beg;
8621 Elf_Internal_Sym * end;
2cf0635d 8622 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8623
0b6ae522 8624 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8625 beg = symtab;
8626 end = symtab + nsyms;
0b6ae522 8627
948f632f 8628 while (beg < end)
4d6ed7c8 8629 {
625d49fc 8630 uint64_t value;
948f632f
DA
8631
8632 sym = beg + (end - beg) / 2;
0b6ae522 8633
948f632f 8634 value = sym->st_value;
0b6ae522
DJ
8635 REMOVE_ARCH_BITS (value);
8636
948f632f 8637 if (sym->st_name != 0
4d6ed7c8 8638 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8639 && addr.offset >= value
8640 && addr.offset - value < dist)
4d6ed7c8
NC
8641 {
8642 best = sym;
0b6ae522 8643 dist = addr.offset - value;
4d6ed7c8
NC
8644 if (!dist)
8645 break;
8646 }
948f632f
DA
8647
8648 if (addr.offset < value)
8649 end = sym;
8650 else
8651 beg = sym + 1;
4d6ed7c8 8652 }
1b31d05e 8653
4d6ed7c8
NC
8654 if (best)
8655 {
57346661 8656 *symname = (best->st_name >= strtab_size
2b692964 8657 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8658 *offset = dist;
8659 return;
8660 }
1b31d05e 8661
4d6ed7c8
NC
8662 *symname = NULL;
8663 *offset = addr.offset;
8664}
8665
32ec8896 8666static /* signed */ int
948f632f
DA
8667symcmp (const void *p, const void *q)
8668{
8669 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8670 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8671
8672 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8673}
8674
8675/* Process the unwind section. */
8676
8677#include "unwind-ia64.h"
8678
8679struct ia64_unw_table_entry
8680{
8681 struct absaddr start;
8682 struct absaddr end;
8683 struct absaddr info;
8684};
8685
8686struct ia64_unw_aux_info
8687{
32ec8896 8688 struct ia64_unw_table_entry * table; /* Unwind table. */
26c527e6 8689 uint64_t table_len; /* Length of unwind table. */
32ec8896 8690 unsigned char * info; /* Unwind info. */
26c527e6 8691 uint64_t info_size; /* Size of unwind info. */
625d49fc
AM
8692 uint64_t info_addr; /* Starting address of unwind info. */
8693 uint64_t seg_base; /* Starting address of segment. */
32ec8896 8694 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 8695 uint64_t nsyms; /* Number of symbols. */
32ec8896 8696 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 8697 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 8698 char * strtab; /* The string table. */
26c527e6 8699 uint64_t strtab_size; /* Size of string table. */
948f632f
DA
8700};
8701
015dc7e1 8702static bool
dda8d76d 8703dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8704{
2cf0635d 8705 struct ia64_unw_table_entry * tp;
26c527e6 8706 size_t j, nfuns;
4d6ed7c8 8707 int in_body;
015dc7e1 8708 bool res = true;
7036c0e1 8709
948f632f
DA
8710 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8711 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8712 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8713 aux->funtab[nfuns++] = aux->symtab[j];
8714 aux->nfuns = nfuns;
8715 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8716
4d6ed7c8
NC
8717 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8718 {
625d49fc
AM
8719 uint64_t stamp;
8720 uint64_t offset;
2cf0635d
NC
8721 const unsigned char * dp;
8722 const unsigned char * head;
53774b7e 8723 const unsigned char * end;
2cf0635d 8724 const char * procname;
4d6ed7c8 8725
dda8d76d 8726 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8727 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8728
8729 fputs ("\n<", stdout);
8730
8731 if (procname)
8732 {
8733 fputs (procname, stdout);
8734
8735 if (offset)
26c527e6 8736 printf ("+%" PRIx64, offset);
4d6ed7c8
NC
8737 }
8738
8739 fputs (">: [", stdout);
8740 print_vma (tp->start.offset, PREFIX_HEX);
8741 fputc ('-', stdout);
8742 print_vma (tp->end.offset, PREFIX_HEX);
26c527e6
AM
8743 printf ("], info at +0x%" PRIx64 "\n",
8744 tp->info.offset - aux->seg_base);
4d6ed7c8 8745
53774b7e
NC
8746 /* PR 17531: file: 86232b32. */
8747 if (aux->info == NULL)
8748 continue;
8749
97c0a079
AM
8750 offset = tp->info.offset;
8751 if (tp->info.section)
8752 {
8753 if (tp->info.section >= filedata->file_header.e_shnum)
8754 {
26c527e6
AM
8755 warn (_("Invalid section %u in table entry %td\n"),
8756 tp->info.section, tp - aux->table);
015dc7e1 8757 res = false;
97c0a079
AM
8758 continue;
8759 }
8760 offset += filedata->section_headers[tp->info.section].sh_addr;
8761 }
8762 offset -= aux->info_addr;
53774b7e 8763 /* PR 17531: file: 0997b4d1. */
90679903
AM
8764 if (offset >= aux->info_size
8765 || aux->info_size - offset < 8)
53774b7e 8766 {
26c527e6
AM
8767 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
8768 tp->info.offset, tp - aux->table);
015dc7e1 8769 res = false;
53774b7e
NC
8770 continue;
8771 }
8772
97c0a079 8773 head = aux->info + offset;
a4a00738 8774 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8775
86f55779 8776 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8777 (unsigned) UNW_VER (stamp),
8778 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8779 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8780 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8781 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8782
8783 if (UNW_VER (stamp) != 1)
8784 {
2b692964 8785 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8786 continue;
8787 }
8788
8789 in_body = 0;
53774b7e
NC
8790 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8791 /* PR 17531: file: 16ceda89. */
8792 if (end > aux->info + aux->info_size)
8793 end = aux->info + aux->info_size;
8794 for (dp = head + 8; dp < end;)
b4477bc8 8795 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8796 }
948f632f
DA
8797
8798 free (aux->funtab);
32ec8896
NC
8799
8800 return res;
4d6ed7c8
NC
8801}
8802
015dc7e1 8803static bool
dda8d76d
NC
8804slurp_ia64_unwind_table (Filedata * filedata,
8805 struct ia64_unw_aux_info * aux,
8806 Elf_Internal_Shdr * sec)
4d6ed7c8 8807{
26c527e6 8808 uint64_t size, nrelas, i;
2cf0635d
NC
8809 Elf_Internal_Phdr * seg;
8810 struct ia64_unw_table_entry * tep;
8811 Elf_Internal_Shdr * relsec;
8812 Elf_Internal_Rela * rela;
8813 Elf_Internal_Rela * rp;
8814 unsigned char * table;
8815 unsigned char * tp;
8816 Elf_Internal_Sym * sym;
8817 const char * relname;
4d6ed7c8 8818
53774b7e
NC
8819 aux->table_len = 0;
8820
4d6ed7c8
NC
8821 /* First, find the starting address of the segment that includes
8822 this section: */
8823
dda8d76d 8824 if (filedata->file_header.e_phnum)
4d6ed7c8 8825 {
dda8d76d 8826 if (! get_program_headers (filedata))
015dc7e1 8827 return false;
4d6ed7c8 8828
dda8d76d
NC
8829 for (seg = filedata->program_headers;
8830 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8831 ++seg)
4d6ed7c8
NC
8832 {
8833 if (seg->p_type != PT_LOAD)
8834 continue;
8835
8836 if (sec->sh_addr >= seg->p_vaddr
8837 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8838 {
8839 aux->seg_base = seg->p_vaddr;
8840 break;
8841 }
8842 }
4d6ed7c8
NC
8843 }
8844
8845 /* Second, build the unwind table from the contents of the unwind section: */
8846 size = sec->sh_size;
dda8d76d 8847 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8848 _("unwind table"));
a6e9f9df 8849 if (!table)
015dc7e1 8850 return false;
4d6ed7c8 8851
53774b7e 8852 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8853 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8854 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8855 tep = aux->table;
53774b7e
NC
8856
8857 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8858 {
8859 tep->start.section = SHN_UNDEF;
8860 tep->end.section = SHN_UNDEF;
8861 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8862 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8863 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8864 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8865 tep->start.offset += aux->seg_base;
8866 tep->end.offset += aux->seg_base;
8867 tep->info.offset += aux->seg_base;
8868 }
8869 free (table);
8870
41e92641 8871 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8872 for (relsec = filedata->section_headers;
8873 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8874 ++relsec)
8875 {
8876 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8877 || relsec->sh_info >= filedata->file_header.e_shnum
8878 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8879 continue;
8880
dda8d76d 8881 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8882 & rela, & nrelas))
53774b7e
NC
8883 {
8884 free (aux->table);
8885 aux->table = NULL;
8886 aux->table_len = 0;
015dc7e1 8887 return false;
53774b7e 8888 }
4d6ed7c8
NC
8889
8890 for (rp = rela; rp < rela + nrelas; ++rp)
8891 {
4770fb94 8892 unsigned int sym_ndx;
726bd37d
AM
8893 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8894 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8895
82b1b41b
NC
8896 /* PR 17531: file: 9fa67536. */
8897 if (relname == NULL)
8898 {
726bd37d 8899 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8900 continue;
8901 }
948f632f 8902
24d127aa 8903 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8904 {
82b1b41b 8905 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8906 continue;
8907 }
8908
89fac5e3 8909 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8910
53774b7e
NC
8911 /* PR 17531: file: 5bc8d9bf. */
8912 if (i >= aux->table_len)
8913 {
26c527e6
AM
8914 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
8915 i);
53774b7e
NC
8916 continue;
8917 }
8918
4770fb94
AM
8919 sym_ndx = get_reloc_symindex (rp->r_info);
8920 if (sym_ndx >= aux->nsyms)
8921 {
8922 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8923 sym_ndx);
8924 continue;
8925 }
8926 sym = aux->symtab + sym_ndx;
8927
53774b7e 8928 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8929 {
8930 case 0:
8931 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8932 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8933 break;
8934 case 1:
8935 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8936 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8937 break;
8938 case 2:
8939 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8940 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8941 break;
8942 default:
8943 break;
8944 }
8945 }
8946
8947 free (rela);
8948 }
8949
015dc7e1 8950 return true;
4d6ed7c8
NC
8951}
8952
015dc7e1 8953static bool
dda8d76d 8954ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8955{
2cf0635d
NC
8956 Elf_Internal_Shdr * sec;
8957 Elf_Internal_Shdr * unwsec = NULL;
26c527e6 8958 uint64_t i, unwcount = 0, unwstart = 0;
57346661 8959 struct ia64_unw_aux_info aux;
015dc7e1 8960 bool res = true;
f1467e33 8961
4d6ed7c8
NC
8962 memset (& aux, 0, sizeof (aux));
8963
dda8d76d 8964 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8965 {
28d13567 8966 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8967 {
28d13567 8968 if (aux.symtab)
4082ef84 8969 {
28d13567
AM
8970 error (_("Multiple symbol tables encountered\n"));
8971 free (aux.symtab);
8972 aux.symtab = NULL;
4082ef84 8973 free (aux.strtab);
28d13567 8974 aux.strtab = NULL;
4082ef84 8975 }
28d13567
AM
8976 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8977 &aux.strtab, &aux.strtab_size))
015dc7e1 8978 return false;
4d6ed7c8
NC
8979 }
8980 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8981 unwcount++;
8982 }
8983
8984 if (!unwcount)
8985 printf (_("\nThere are no unwind sections in this file.\n"));
8986
8987 while (unwcount-- > 0)
8988 {
84714f86 8989 const char *suffix;
579f31ac
JJ
8990 size_t len, len2;
8991
dda8d76d
NC
8992 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8993 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8994 if (sec->sh_type == SHT_IA_64_UNWIND)
8995 {
8996 unwsec = sec;
8997 break;
8998 }
4082ef84
NC
8999 /* We have already counted the number of SHT_IA64_UNWIND
9000 sections so the loop above should never fail. */
9001 assert (unwsec != NULL);
579f31ac
JJ
9002
9003 unwstart = i + 1;
9004 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9005
e4b17d5c
L
9006 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9007 {
9008 /* We need to find which section group it is in. */
4082ef84 9009 struct group_list * g;
e4b17d5c 9010
978c4450
AM
9011 if (filedata->section_headers_groups == NULL
9012 || filedata->section_headers_groups[i] == NULL)
dda8d76d 9013 i = filedata->file_header.e_shnum;
4082ef84 9014 else
e4b17d5c 9015 {
978c4450 9016 g = filedata->section_headers_groups[i]->root;
18bd398b 9017
4082ef84
NC
9018 for (; g != NULL; g = g->next)
9019 {
dda8d76d 9020 sec = filedata->section_headers + g->section_index;
e4b17d5c 9021
84714f86
AM
9022 if (section_name_valid (filedata, sec)
9023 && streq (section_name (filedata, sec),
9024 ELF_STRING_ia64_unwind_info))
4082ef84
NC
9025 break;
9026 }
9027
9028 if (g == NULL)
dda8d76d 9029 i = filedata->file_header.e_shnum;
4082ef84 9030 }
e4b17d5c 9031 }
84714f86
AM
9032 else if (section_name_valid (filedata, unwsec)
9033 && startswith (section_name (filedata, unwsec),
e9b095a5 9034 ELF_STRING_ia64_unwind_once))
579f31ac 9035 {
18bd398b 9036 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 9037 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 9038 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9039 for (i = 0, sec = filedata->section_headers;
9040 i < filedata->file_header.e_shnum;
579f31ac 9041 ++i, ++sec)
84714f86
AM
9042 if (section_name_valid (filedata, sec)
9043 && startswith (section_name (filedata, sec),
e9b095a5 9044 ELF_STRING_ia64_unwind_info_once)
84714f86 9045 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9046 break;
9047 }
9048 else
9049 {
9050 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 9051 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
9052 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9053 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9054 suffix = "";
84714f86
AM
9055 if (section_name_valid (filedata, unwsec)
9056 && startswith (section_name (filedata, unwsec),
9057 ELF_STRING_ia64_unwind))
9058 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9059 for (i = 0, sec = filedata->section_headers;
9060 i < filedata->file_header.e_shnum;
579f31ac 9061 ++i, ++sec)
84714f86
AM
9062 if (section_name_valid (filedata, sec)
9063 && startswith (section_name (filedata, sec),
9064 ELF_STRING_ia64_unwind_info)
9065 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9066 break;
9067 }
9068
dda8d76d 9069 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
9070 {
9071 printf (_("\nCould not find unwind info section for "));
9072
dda8d76d 9073 if (filedata->string_table == NULL)
579f31ac
JJ
9074 printf ("%d", unwsec->sh_name);
9075 else
dda8d76d 9076 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9077 }
9078 else
4d6ed7c8 9079 {
4d6ed7c8 9080 aux.info_addr = sec->sh_addr;
dda8d76d 9081 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9082 sec->sh_size,
9083 _("unwind info"));
59245841 9084 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9085
579f31ac 9086 printf (_("\nUnwind section "));
4d6ed7c8 9087
dda8d76d 9088 if (filedata->string_table == NULL)
579f31ac
JJ
9089 printf ("%d", unwsec->sh_name);
9090 else
dda8d76d 9091 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9092
26c527e6
AM
9093 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9094 unwsec->sh_offset,
9095 unwsec->sh_size / (3 * eh_addr_size));
4d6ed7c8 9096
dda8d76d 9097 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9098 && aux.table_len > 0)
dda8d76d 9099 dump_ia64_unwind (filedata, & aux);
579f31ac 9100
9db70fc3
AM
9101 free ((char *) aux.table);
9102 free ((char *) aux.info);
579f31ac
JJ
9103 aux.table = NULL;
9104 aux.info = NULL;
9105 }
4d6ed7c8 9106 }
4d6ed7c8 9107
9db70fc3
AM
9108 free (aux.symtab);
9109 free ((char *) aux.strtab);
32ec8896
NC
9110
9111 return res;
4d6ed7c8
NC
9112}
9113
3f5e193b 9114struct hppa_unw_table_entry
32ec8896
NC
9115{
9116 struct absaddr start;
9117 struct absaddr end;
9118 unsigned int Cannot_unwind:1; /* 0 */
9119 unsigned int Millicode:1; /* 1 */
9120 unsigned int Millicode_save_sr0:1; /* 2 */
9121 unsigned int Region_description:2; /* 3..4 */
9122 unsigned int reserved1:1; /* 5 */
9123 unsigned int Entry_SR:1; /* 6 */
9124 unsigned int Entry_FR:4; /* Number saved 7..10 */
9125 unsigned int Entry_GR:5; /* Number saved 11..15 */
9126 unsigned int Args_stored:1; /* 16 */
9127 unsigned int Variable_Frame:1; /* 17 */
9128 unsigned int Separate_Package_Body:1; /* 18 */
9129 unsigned int Frame_Extension_Millicode:1; /* 19 */
9130 unsigned int Stack_Overflow_Check:1; /* 20 */
9131 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9132 unsigned int Ada_Region:1; /* 22 */
9133 unsigned int cxx_info:1; /* 23 */
9134 unsigned int cxx_try_catch:1; /* 24 */
9135 unsigned int sched_entry_seq:1; /* 25 */
9136 unsigned int reserved2:1; /* 26 */
9137 unsigned int Save_SP:1; /* 27 */
9138 unsigned int Save_RP:1; /* 28 */
9139 unsigned int Save_MRP_in_frame:1; /* 29 */
9140 unsigned int extn_ptr_defined:1; /* 30 */
9141 unsigned int Cleanup_defined:1; /* 31 */
9142
9143 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9144 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9145 unsigned int Large_frame:1; /* 2 */
9146 unsigned int Pseudo_SP_Set:1; /* 3 */
9147 unsigned int reserved4:1; /* 4 */
9148 unsigned int Total_frame_size:27; /* 5..31 */
9149};
3f5e193b 9150
57346661 9151struct hppa_unw_aux_info
948f632f 9152{
32ec8896 9153 struct hppa_unw_table_entry * table; /* Unwind table. */
26c527e6 9154 uint64_t table_len; /* Length of unwind table. */
625d49fc 9155 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9156 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9157 uint64_t nsyms; /* Number of symbols. */
32ec8896 9158 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9159 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9160 char * strtab; /* The string table. */
26c527e6 9161 uint64_t strtab_size; /* Size of string table. */
948f632f 9162};
57346661 9163
015dc7e1 9164static bool
dda8d76d 9165dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9166{
2cf0635d 9167 struct hppa_unw_table_entry * tp;
26c527e6 9168 uint64_t j, nfuns;
015dc7e1 9169 bool res = true;
948f632f
DA
9170
9171 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9172 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9173 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9174 aux->funtab[nfuns++] = aux->symtab[j];
9175 aux->nfuns = nfuns;
9176 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9177
57346661
AM
9178 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9179 {
625d49fc 9180 uint64_t offset;
2cf0635d 9181 const char * procname;
57346661 9182
dda8d76d 9183 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9184 aux->strtab_size, tp->start, &procname,
9185 &offset);
9186
9187 fputs ("\n<", stdout);
9188
9189 if (procname)
9190 {
9191 fputs (procname, stdout);
9192
9193 if (offset)
26c527e6 9194 printf ("+%" PRIx64, offset);
57346661
AM
9195 }
9196
9197 fputs (">: [", stdout);
9198 print_vma (tp->start.offset, PREFIX_HEX);
9199 fputc ('-', stdout);
9200 print_vma (tp->end.offset, PREFIX_HEX);
9201 printf ("]\n\t");
9202
18bd398b
NC
9203#define PF(_m) if (tp->_m) printf (#_m " ");
9204#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9205 PF(Cannot_unwind);
9206 PF(Millicode);
9207 PF(Millicode_save_sr0);
18bd398b 9208 /* PV(Region_description); */
57346661
AM
9209 PF(Entry_SR);
9210 PV(Entry_FR);
9211 PV(Entry_GR);
9212 PF(Args_stored);
9213 PF(Variable_Frame);
9214 PF(Separate_Package_Body);
9215 PF(Frame_Extension_Millicode);
9216 PF(Stack_Overflow_Check);
9217 PF(Two_Instruction_SP_Increment);
9218 PF(Ada_Region);
9219 PF(cxx_info);
9220 PF(cxx_try_catch);
9221 PF(sched_entry_seq);
9222 PF(Save_SP);
9223 PF(Save_RP);
9224 PF(Save_MRP_in_frame);
9225 PF(extn_ptr_defined);
9226 PF(Cleanup_defined);
9227 PF(MPE_XL_interrupt_marker);
9228 PF(HP_UX_interrupt_marker);
9229 PF(Large_frame);
9230 PF(Pseudo_SP_Set);
9231 PV(Total_frame_size);
9232#undef PF
9233#undef PV
9234 }
9235
18bd398b 9236 printf ("\n");
948f632f
DA
9237
9238 free (aux->funtab);
32ec8896
NC
9239
9240 return res;
57346661
AM
9241}
9242
015dc7e1 9243static bool
dda8d76d
NC
9244slurp_hppa_unwind_table (Filedata * filedata,
9245 struct hppa_unw_aux_info * aux,
9246 Elf_Internal_Shdr * sec)
57346661 9247{
26c527e6 9248 uint64_t size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9249 Elf_Internal_Phdr * seg;
9250 struct hppa_unw_table_entry * tep;
9251 Elf_Internal_Shdr * relsec;
9252 Elf_Internal_Rela * rela;
9253 Elf_Internal_Rela * rp;
9254 unsigned char * table;
9255 unsigned char * tp;
9256 Elf_Internal_Sym * sym;
9257 const char * relname;
57346661 9258
57346661
AM
9259 /* First, find the starting address of the segment that includes
9260 this section. */
dda8d76d 9261 if (filedata->file_header.e_phnum)
57346661 9262 {
dda8d76d 9263 if (! get_program_headers (filedata))
015dc7e1 9264 return false;
57346661 9265
dda8d76d
NC
9266 for (seg = filedata->program_headers;
9267 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9268 ++seg)
9269 {
9270 if (seg->p_type != PT_LOAD)
9271 continue;
9272
9273 if (sec->sh_addr >= seg->p_vaddr
9274 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9275 {
9276 aux->seg_base = seg->p_vaddr;
9277 break;
9278 }
9279 }
9280 }
9281
9282 /* Second, build the unwind table from the contents of the unwind
9283 section. */
9284 size = sec->sh_size;
dda8d76d 9285 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9286 _("unwind table"));
57346661 9287 if (!table)
015dc7e1 9288 return false;
57346661 9289
1c0751b2
DA
9290 unw_ent_size = 16;
9291 nentries = size / unw_ent_size;
9292 size = unw_ent_size * nentries;
57346661 9293
e3fdc001 9294 aux->table_len = nentries;
3f5e193b
NC
9295 tep = aux->table = (struct hppa_unw_table_entry *)
9296 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9297
1c0751b2 9298 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9299 {
9300 unsigned int tmp1, tmp2;
9301
9302 tep->start.section = SHN_UNDEF;
9303 tep->end.section = SHN_UNDEF;
9304
1c0751b2
DA
9305 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9306 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9307 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9308 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9309
9310 tep->start.offset += aux->seg_base;
9311 tep->end.offset += aux->seg_base;
57346661
AM
9312
9313 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9314 tep->Millicode = (tmp1 >> 30) & 0x1;
9315 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9316 tep->Region_description = (tmp1 >> 27) & 0x3;
9317 tep->reserved1 = (tmp1 >> 26) & 0x1;
9318 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9319 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9320 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9321 tep->Args_stored = (tmp1 >> 15) & 0x1;
9322 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9323 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9324 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9325 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9326 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9327 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9328 tep->cxx_info = (tmp1 >> 8) & 0x1;
9329 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9330 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9331 tep->reserved2 = (tmp1 >> 5) & 0x1;
9332 tep->Save_SP = (tmp1 >> 4) & 0x1;
9333 tep->Save_RP = (tmp1 >> 3) & 0x1;
9334 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9335 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9336 tep->Cleanup_defined = tmp1 & 0x1;
9337
9338 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9339 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9340 tep->Large_frame = (tmp2 >> 29) & 0x1;
9341 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9342 tep->reserved4 = (tmp2 >> 27) & 0x1;
9343 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9344 }
9345 free (table);
9346
9347 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9348 for (relsec = filedata->section_headers;
9349 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9350 ++relsec)
9351 {
9352 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9353 || relsec->sh_info >= filedata->file_header.e_shnum
9354 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9355 continue;
9356
dda8d76d 9357 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9358 & rela, & nrelas))
015dc7e1 9359 return false;
57346661
AM
9360
9361 for (rp = rela; rp < rela + nrelas; ++rp)
9362 {
4770fb94 9363 unsigned int sym_ndx;
726bd37d
AM
9364 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9365 relname = elf_hppa_reloc_type (r_type);
57346661 9366
726bd37d
AM
9367 if (relname == NULL)
9368 {
9369 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9370 continue;
9371 }
9372
57346661 9373 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9374 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9375 {
726bd37d 9376 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9377 continue;
9378 }
9379
9380 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9381 if (i >= aux->table_len)
9382 {
26c527e6
AM
9383 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9384 i);
726bd37d
AM
9385 continue;
9386 }
57346661 9387
4770fb94
AM
9388 sym_ndx = get_reloc_symindex (rp->r_info);
9389 if (sym_ndx >= aux->nsyms)
9390 {
9391 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9392 sym_ndx);
9393 continue;
9394 }
9395 sym = aux->symtab + sym_ndx;
9396
43f6cd05 9397 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9398 {
9399 case 0:
9400 aux->table[i].start.section = sym->st_shndx;
1e456d54 9401 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9402 break;
9403 case 1:
9404 aux->table[i].end.section = sym->st_shndx;
1e456d54 9405 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9406 break;
9407 default:
9408 break;
9409 }
9410 }
9411
9412 free (rela);
9413 }
9414
015dc7e1 9415 return true;
57346661
AM
9416}
9417
015dc7e1 9418static bool
dda8d76d 9419hppa_process_unwind (Filedata * filedata)
57346661 9420{
57346661 9421 struct hppa_unw_aux_info aux;
2cf0635d 9422 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9423 Elf_Internal_Shdr * sec;
26c527e6 9424 size_t i;
015dc7e1 9425 bool res = true;
57346661 9426
dda8d76d 9427 if (filedata->string_table == NULL)
015dc7e1 9428 return false;
1b31d05e
NC
9429
9430 memset (& aux, 0, sizeof (aux));
57346661 9431
dda8d76d 9432 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9433 {
28d13567 9434 if (sec->sh_type == SHT_SYMTAB)
57346661 9435 {
28d13567 9436 if (aux.symtab)
4082ef84 9437 {
28d13567
AM
9438 error (_("Multiple symbol tables encountered\n"));
9439 free (aux.symtab);
9440 aux.symtab = NULL;
4082ef84 9441 free (aux.strtab);
28d13567 9442 aux.strtab = NULL;
4082ef84 9443 }
28d13567
AM
9444 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9445 &aux.strtab, &aux.strtab_size))
015dc7e1 9446 return false;
57346661 9447 }
84714f86
AM
9448 else if (section_name_valid (filedata, sec)
9449 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9450 unwsec = sec;
9451 }
9452
9453 if (!unwsec)
9454 printf (_("\nThere are no unwind sections in this file.\n"));
9455
dda8d76d 9456 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9457 {
84714f86
AM
9458 if (section_name_valid (filedata, sec)
9459 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9460 {
26c527e6 9461 uint64_t num_unwind = sec->sh_size / 16;
dda8d76d 9462
26c527e6
AM
9463 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
9464 "contains %" PRIu64 " entry:\n",
9465 "\nUnwind section '%s' at offset %#" PRIx64 " "
9466 "contains %" PRIu64 " entries:\n",
d3a49aa8 9467 num_unwind),
dda8d76d 9468 printable_section_name (filedata, sec),
26c527e6 9469 sec->sh_offset,
d3a49aa8 9470 num_unwind);
57346661 9471
dda8d76d 9472 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9473 res = false;
66b09c7e
S
9474
9475 if (res && aux.table_len > 0)
32ec8896 9476 {
dda8d76d 9477 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9478 res = false;
32ec8896 9479 }
57346661 9480
9db70fc3 9481 free ((char *) aux.table);
57346661
AM
9482 aux.table = NULL;
9483 }
9484 }
9485
9db70fc3
AM
9486 free (aux.symtab);
9487 free ((char *) aux.strtab);
32ec8896
NC
9488
9489 return res;
57346661
AM
9490}
9491
0b6ae522
DJ
9492struct arm_section
9493{
a734115a
NC
9494 unsigned char * data; /* The unwind data. */
9495 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9496 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
26c527e6 9497 uint64_t nrelas; /* The number of relocations. */
a734115a
NC
9498 unsigned int rel_type; /* REL or RELA ? */
9499 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9500};
9501
9502struct arm_unw_aux_info
9503{
dda8d76d 9504 Filedata * filedata; /* The file containing the unwind sections. */
a734115a 9505 Elf_Internal_Sym * symtab; /* The file's symbol table. */
26c527e6 9506 uint64_t nsyms; /* Number of symbols. */
948f632f 9507 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9508 uint64_t nfuns; /* Number of these symbols. */
a734115a 9509 char * strtab; /* The file's string table. */
26c527e6 9510 uint64_t strtab_size; /* Size of string table. */
0b6ae522
DJ
9511};
9512
9513static const char *
dda8d76d
NC
9514arm_print_vma_and_name (Filedata * filedata,
9515 struct arm_unw_aux_info * aux,
625d49fc 9516 uint64_t fn,
dda8d76d 9517 struct absaddr addr)
0b6ae522
DJ
9518{
9519 const char *procname;
625d49fc 9520 uint64_t sym_offset;
0b6ae522
DJ
9521
9522 if (addr.section == SHN_UNDEF)
9523 addr.offset = fn;
9524
dda8d76d 9525 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9526 aux->strtab_size, addr, &procname,
9527 &sym_offset);
9528
9529 print_vma (fn, PREFIX_HEX);
9530
9531 if (procname)
9532 {
9533 fputs (" <", stdout);
9534 fputs (procname, stdout);
9535
9536 if (sym_offset)
26c527e6 9537 printf ("+0x%" PRIx64, sym_offset);
0b6ae522
DJ
9538 fputc ('>', stdout);
9539 }
9540
9541 return procname;
9542}
9543
9544static void
9545arm_free_section (struct arm_section *arm_sec)
9546{
9db70fc3
AM
9547 free (arm_sec->data);
9548 free (arm_sec->rela);
0b6ae522
DJ
9549}
9550
a734115a
NC
9551/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9552 cached section and install SEC instead.
9553 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9554 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9555 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9556 relocation's offset in ADDR.
1b31d05e
NC
9557 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9558 into the string table of the symbol associated with the reloc. If no
9559 reloc was applied store -1 there.
9560 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9561
015dc7e1 9562static bool
dda8d76d
NC
9563get_unwind_section_word (Filedata * filedata,
9564 struct arm_unw_aux_info * aux,
1b31d05e
NC
9565 struct arm_section * arm_sec,
9566 Elf_Internal_Shdr * sec,
625d49fc 9567 uint64_t word_offset,
1b31d05e
NC
9568 unsigned int * wordp,
9569 struct absaddr * addr,
625d49fc 9570 uint64_t * sym_name)
0b6ae522
DJ
9571{
9572 Elf_Internal_Rela *rp;
9573 Elf_Internal_Sym *sym;
9574 const char * relname;
9575 unsigned int word;
015dc7e1 9576 bool wrapped;
0b6ae522 9577
e0a31db1 9578 if (sec == NULL || arm_sec == NULL)
015dc7e1 9579 return false;
e0a31db1 9580
0b6ae522
DJ
9581 addr->section = SHN_UNDEF;
9582 addr->offset = 0;
9583
1b31d05e 9584 if (sym_name != NULL)
625d49fc 9585 *sym_name = (uint64_t) -1;
1b31d05e 9586
a734115a 9587 /* If necessary, update the section cache. */
0b6ae522
DJ
9588 if (sec != arm_sec->sec)
9589 {
9590 Elf_Internal_Shdr *relsec;
9591
9592 arm_free_section (arm_sec);
9593
9594 arm_sec->sec = sec;
dda8d76d 9595 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9596 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9597 arm_sec->rela = NULL;
9598 arm_sec->nrelas = 0;
9599
dda8d76d
NC
9600 for (relsec = filedata->section_headers;
9601 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9602 ++relsec)
9603 {
dda8d76d
NC
9604 if (relsec->sh_info >= filedata->file_header.e_shnum
9605 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9606 /* PR 15745: Check the section type as well. */
9607 || (relsec->sh_type != SHT_REL
9608 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9609 continue;
9610
a734115a 9611 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9612 if (relsec->sh_type == SHT_REL)
9613 {
dda8d76d 9614 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9615 relsec->sh_size,
9616 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9617 return false;
0b6ae522 9618 }
1ae40aa4 9619 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9620 {
dda8d76d 9621 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9622 relsec->sh_size,
9623 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9624 return false;
0b6ae522 9625 }
1ae40aa4 9626 break;
0b6ae522
DJ
9627 }
9628
9629 arm_sec->next_rela = arm_sec->rela;
9630 }
9631
a734115a 9632 /* If there is no unwind data we can do nothing. */
0b6ae522 9633 if (arm_sec->data == NULL)
015dc7e1 9634 return false;
0b6ae522 9635
e0a31db1 9636 /* If the offset is invalid then fail. */
f32ba729
NC
9637 if (/* PR 21343 *//* PR 18879 */
9638 sec->sh_size < 4
625d49fc 9639 || word_offset > sec->sh_size - 4)
015dc7e1 9640 return false;
e0a31db1 9641
a734115a 9642 /* Get the word at the required offset. */
0b6ae522
DJ
9643 word = byte_get (arm_sec->data + word_offset, 4);
9644
0eff7165
NC
9645 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9646 if (arm_sec->rela == NULL)
9647 {
9648 * wordp = word;
015dc7e1 9649 return true;
0eff7165
NC
9650 }
9651
a734115a 9652 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9653 wrapped = false;
0b6ae522
DJ
9654 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9655 {
625d49fc 9656 uint64_t prelval, offset;
0b6ae522
DJ
9657
9658 if (rp->r_offset > word_offset && !wrapped)
9659 {
9660 rp = arm_sec->rela;
015dc7e1 9661 wrapped = true;
0b6ae522
DJ
9662 }
9663 if (rp->r_offset > word_offset)
9664 break;
9665
9666 if (rp->r_offset & 3)
9667 {
26c527e6
AM
9668 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
9669 rp->r_offset);
0b6ae522
DJ
9670 continue;
9671 }
9672
9673 if (rp->r_offset < word_offset)
9674 continue;
9675
74e1a04b
NC
9676 /* PR 17531: file: 027-161405-0.004 */
9677 if (aux->symtab == NULL)
9678 continue;
9679
0b6ae522
DJ
9680 if (arm_sec->rel_type == SHT_REL)
9681 {
9682 offset = word & 0x7fffffff;
9683 if (offset & 0x40000000)
625d49fc 9684 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 9685 }
a734115a 9686 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9687 offset = rp->r_addend;
a734115a 9688 else
74e1a04b
NC
9689 {
9690 error (_("Unknown section relocation type %d encountered\n"),
9691 arm_sec->rel_type);
9692 break;
9693 }
0b6ae522 9694
071436c6
NC
9695 /* PR 17531 file: 027-1241568-0.004. */
9696 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9697 {
26c527e6
AM
9698 error (_("Bad symbol index in unwind relocation "
9699 "(%" PRIu64 " > %" PRIu64 ")\n"),
9700 ELF32_R_SYM (rp->r_info), aux->nsyms);
071436c6
NC
9701 break;
9702 }
9703
9704 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9705 offset += sym->st_value;
9706 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9707
a734115a 9708 /* Check that we are processing the expected reloc type. */
dda8d76d 9709 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9710 {
9711 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9712 if (relname == NULL)
9713 {
9714 warn (_("Skipping unknown ARM relocation type: %d\n"),
9715 (int) ELF32_R_TYPE (rp->r_info));
9716 continue;
9717 }
a734115a
NC
9718
9719 if (streq (relname, "R_ARM_NONE"))
9720 continue;
0b4362b0 9721
a734115a
NC
9722 if (! streq (relname, "R_ARM_PREL31"))
9723 {
071436c6 9724 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9725 continue;
9726 }
9727 }
dda8d76d 9728 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9729 {
9730 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9731 if (relname == NULL)
9732 {
9733 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9734 (int) ELF32_R_TYPE (rp->r_info));
9735 continue;
9736 }
0b4362b0 9737
a734115a
NC
9738 if (streq (relname, "R_C6000_NONE"))
9739 continue;
9740
9741 if (! streq (relname, "R_C6000_PREL31"))
9742 {
071436c6 9743 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9744 continue;
9745 }
9746
9747 prelval >>= 1;
9748 }
9749 else
74e1a04b
NC
9750 {
9751 /* This function currently only supports ARM and TI unwinders. */
9752 warn (_("Only TI and ARM unwinders are currently supported\n"));
9753 break;
9754 }
fa197c1c 9755
625d49fc 9756 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
9757 addr->section = sym->st_shndx;
9758 addr->offset = offset;
74e1a04b 9759
1b31d05e
NC
9760 if (sym_name)
9761 * sym_name = sym->st_name;
0b6ae522
DJ
9762 break;
9763 }
9764
9765 *wordp = word;
9766 arm_sec->next_rela = rp;
9767
015dc7e1 9768 return true;
0b6ae522
DJ
9769}
9770
a734115a
NC
9771static const char *tic6x_unwind_regnames[16] =
9772{
0b4362b0
RM
9773 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9774 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9775 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9776};
fa197c1c 9777
0b6ae522 9778static void
fa197c1c 9779decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9780{
fa197c1c
PB
9781 int i;
9782
9783 for (i = 12; mask; mask >>= 1, i--)
9784 {
9785 if (mask & 1)
9786 {
9787 fputs (tic6x_unwind_regnames[i], stdout);
9788 if (mask > 1)
9789 fputs (", ", stdout);
9790 }
9791 }
9792}
0b6ae522
DJ
9793
9794#define ADVANCE \
9795 if (remaining == 0 && more_words) \
9796 { \
9797 data_offset += 4; \
dda8d76d 9798 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9799 data_offset, & word, & addr, NULL)) \
015dc7e1 9800 return false; \
0b6ae522
DJ
9801 remaining = 4; \
9802 more_words--; \
9803 } \
9804
9805#define GET_OP(OP) \
9806 ADVANCE; \
9807 if (remaining) \
9808 { \
9809 remaining--; \
9810 (OP) = word >> 24; \
9811 word <<= 8; \
9812 } \
9813 else \
9814 { \
2b692964 9815 printf (_("[Truncated opcode]\n")); \
015dc7e1 9816 return false; \
0b6ae522 9817 } \
cc5914eb 9818 printf ("0x%02x ", OP)
0b6ae522 9819
015dc7e1 9820static bool
dda8d76d
NC
9821decode_arm_unwind_bytecode (Filedata * filedata,
9822 struct arm_unw_aux_info * aux,
948f632f
DA
9823 unsigned int word,
9824 unsigned int remaining,
9825 unsigned int more_words,
625d49fc 9826 uint64_t data_offset,
948f632f
DA
9827 Elf_Internal_Shdr * data_sec,
9828 struct arm_section * data_arm_sec)
fa197c1c
PB
9829{
9830 struct absaddr addr;
015dc7e1 9831 bool res = true;
0b6ae522
DJ
9832
9833 /* Decode the unwinding instructions. */
9834 while (1)
9835 {
9836 unsigned int op, op2;
9837
9838 ADVANCE;
9839 if (remaining == 0)
9840 break;
9841 remaining--;
9842 op = word >> 24;
9843 word <<= 8;
9844
cc5914eb 9845 printf (" 0x%02x ", op);
0b6ae522
DJ
9846
9847 if ((op & 0xc0) == 0x00)
9848 {
9849 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9850
cc5914eb 9851 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9852 }
9853 else if ((op & 0xc0) == 0x40)
9854 {
9855 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9856
cc5914eb 9857 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9858 }
9859 else if ((op & 0xf0) == 0x80)
9860 {
9861 GET_OP (op2);
9862 if (op == 0x80 && op2 == 0)
9863 printf (_("Refuse to unwind"));
9864 else
9865 {
9866 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9867 bool first = true;
0b6ae522 9868 int i;
2b692964 9869
0b6ae522
DJ
9870 printf ("pop {");
9871 for (i = 0; i < 12; i++)
9872 if (mask & (1 << i))
9873 {
9874 if (first)
015dc7e1 9875 first = false;
0b6ae522
DJ
9876 else
9877 printf (", ");
9878 printf ("r%d", 4 + i);
9879 }
9880 printf ("}");
9881 }
9882 }
9883 else if ((op & 0xf0) == 0x90)
9884 {
9885 if (op == 0x9d || op == 0x9f)
9886 printf (_(" [Reserved]"));
9887 else
cc5914eb 9888 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9889 }
9890 else if ((op & 0xf0) == 0xa0)
9891 {
9892 int end = 4 + (op & 0x07);
015dc7e1 9893 bool first = true;
0b6ae522 9894 int i;
61865e30 9895
0b6ae522
DJ
9896 printf (" pop {");
9897 for (i = 4; i <= end; i++)
9898 {
9899 if (first)
015dc7e1 9900 first = false;
0b6ae522
DJ
9901 else
9902 printf (", ");
9903 printf ("r%d", i);
9904 }
9905 if (op & 0x08)
9906 {
1b31d05e 9907 if (!first)
0b6ae522
DJ
9908 printf (", ");
9909 printf ("r14");
9910 }
9911 printf ("}");
9912 }
9913 else if (op == 0xb0)
9914 printf (_(" finish"));
9915 else if (op == 0xb1)
9916 {
9917 GET_OP (op2);
9918 if (op2 == 0 || (op2 & 0xf0) != 0)
9919 printf (_("[Spare]"));
9920 else
9921 {
9922 unsigned int mask = op2 & 0x0f;
015dc7e1 9923 bool first = true;
0b6ae522 9924 int i;
61865e30 9925
0b6ae522
DJ
9926 printf ("pop {");
9927 for (i = 0; i < 12; i++)
9928 if (mask & (1 << i))
9929 {
9930 if (first)
015dc7e1 9931 first = false;
0b6ae522
DJ
9932 else
9933 printf (", ");
9934 printf ("r%d", i);
9935 }
9936 printf ("}");
9937 }
9938 }
9939 else if (op == 0xb2)
9940 {
b115cf96 9941 unsigned char buf[9];
0b6ae522 9942 unsigned int i, len;
26c527e6 9943 uint64_t offset;
61865e30 9944
b115cf96 9945 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9946 {
9947 GET_OP (buf[i]);
9948 if ((buf[i] & 0x80) == 0)
9949 break;
9950 }
4082ef84 9951 if (i == sizeof (buf))
32ec8896 9952 {
27a45f42 9953 error (_("corrupt change to vsp\n"));
015dc7e1 9954 res = false;
32ec8896 9955 }
4082ef84
NC
9956 else
9957 {
015dc7e1 9958 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9959 assert (len == i + 1);
9960 offset = offset * 4 + 0x204;
26c527e6 9961 printf ("vsp = vsp + %" PRId64, offset);
4082ef84 9962 }
0b6ae522 9963 }
61865e30 9964 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9965 {
61865e30
NC
9966 unsigned int first, last;
9967
9968 GET_OP (op2);
9969 first = op2 >> 4;
9970 last = op2 & 0x0f;
9971 if (op == 0xc8)
9972 first = first + 16;
9973 printf ("pop {D%d", first);
9974 if (last)
9975 printf ("-D%d", first + last);
9976 printf ("}");
9977 }
09854a88
TB
9978 else if (op == 0xb4)
9979 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
9980 else if (op == 0xb5)
9981 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
9982 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9983 {
9984 unsigned int count = op & 0x07;
9985
9986 printf ("pop {D8");
9987 if (count)
9988 printf ("-D%d", 8 + count);
9989 printf ("}");
9990 }
9991 else if (op >= 0xc0 && op <= 0xc5)
9992 {
9993 unsigned int count = op & 0x07;
9994
9995 printf (" pop {wR10");
9996 if (count)
9997 printf ("-wR%d", 10 + count);
9998 printf ("}");
9999 }
10000 else if (op == 0xc6)
10001 {
10002 unsigned int first, last;
10003
10004 GET_OP (op2);
10005 first = op2 >> 4;
10006 last = op2 & 0x0f;
10007 printf ("pop {wR%d", first);
10008 if (last)
10009 printf ("-wR%d", first + last);
10010 printf ("}");
10011 }
10012 else if (op == 0xc7)
10013 {
10014 GET_OP (op2);
10015 if (op2 == 0 || (op2 & 0xf0) != 0)
10016 printf (_("[Spare]"));
0b6ae522
DJ
10017 else
10018 {
61865e30 10019 unsigned int mask = op2 & 0x0f;
015dc7e1 10020 bool first = true;
61865e30
NC
10021 int i;
10022
10023 printf ("pop {");
10024 for (i = 0; i < 4; i++)
10025 if (mask & (1 << i))
10026 {
10027 if (first)
015dc7e1 10028 first = false;
61865e30
NC
10029 else
10030 printf (", ");
10031 printf ("wCGR%d", i);
10032 }
10033 printf ("}");
0b6ae522
DJ
10034 }
10035 }
61865e30 10036 else
32ec8896
NC
10037 {
10038 printf (_(" [unsupported opcode]"));
015dc7e1 10039 res = false;
32ec8896
NC
10040 }
10041
0b6ae522
DJ
10042 printf ("\n");
10043 }
32ec8896
NC
10044
10045 return res;
fa197c1c
PB
10046}
10047
015dc7e1 10048static bool
dda8d76d
NC
10049decode_tic6x_unwind_bytecode (Filedata * filedata,
10050 struct arm_unw_aux_info * aux,
948f632f
DA
10051 unsigned int word,
10052 unsigned int remaining,
10053 unsigned int more_words,
625d49fc 10054 uint64_t data_offset,
948f632f
DA
10055 Elf_Internal_Shdr * data_sec,
10056 struct arm_section * data_arm_sec)
fa197c1c
PB
10057{
10058 struct absaddr addr;
10059
10060 /* Decode the unwinding instructions. */
10061 while (1)
10062 {
10063 unsigned int op, op2;
10064
10065 ADVANCE;
10066 if (remaining == 0)
10067 break;
10068 remaining--;
10069 op = word >> 24;
10070 word <<= 8;
10071
9cf03b7e 10072 printf (" 0x%02x ", op);
fa197c1c
PB
10073
10074 if ((op & 0xc0) == 0x00)
10075 {
10076 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10077 printf (" sp = sp + %d", offset);
fa197c1c
PB
10078 }
10079 else if ((op & 0xc0) == 0x80)
10080 {
10081 GET_OP (op2);
10082 if (op == 0x80 && op2 == 0)
10083 printf (_("Refuse to unwind"));
10084 else
10085 {
10086 unsigned int mask = ((op & 0x1f) << 8) | op2;
10087 if (op & 0x20)
10088 printf ("pop compact {");
10089 else
10090 printf ("pop {");
10091
10092 decode_tic6x_unwind_regmask (mask);
10093 printf("}");
10094 }
10095 }
10096 else if ((op & 0xf0) == 0xc0)
10097 {
10098 unsigned int reg;
10099 unsigned int nregs;
10100 unsigned int i;
10101 const char *name;
a734115a
NC
10102 struct
10103 {
32ec8896
NC
10104 unsigned int offset;
10105 unsigned int reg;
fa197c1c
PB
10106 } regpos[16];
10107
10108 /* Scan entire instruction first so that GET_OP output is not
10109 interleaved with disassembly. */
10110 nregs = 0;
10111 for (i = 0; nregs < (op & 0xf); i++)
10112 {
10113 GET_OP (op2);
10114 reg = op2 >> 4;
10115 if (reg != 0xf)
10116 {
10117 regpos[nregs].offset = i * 2;
10118 regpos[nregs].reg = reg;
10119 nregs++;
10120 }
10121
10122 reg = op2 & 0xf;
10123 if (reg != 0xf)
10124 {
10125 regpos[nregs].offset = i * 2 + 1;
10126 regpos[nregs].reg = reg;
10127 nregs++;
10128 }
10129 }
10130
10131 printf (_("pop frame {"));
18344509 10132 if (nregs == 0)
fa197c1c 10133 {
18344509
NC
10134 printf (_("*corrupt* - no registers specified"));
10135 }
10136 else
10137 {
10138 reg = nregs - 1;
10139 for (i = i * 2; i > 0; i--)
fa197c1c 10140 {
18344509
NC
10141 if (regpos[reg].offset == i - 1)
10142 {
10143 name = tic6x_unwind_regnames[regpos[reg].reg];
10144 if (reg > 0)
10145 reg--;
10146 }
10147 else
10148 name = _("[pad]");
fa197c1c 10149
18344509
NC
10150 fputs (name, stdout);
10151 if (i > 1)
10152 printf (", ");
10153 }
fa197c1c
PB
10154 }
10155
10156 printf ("}");
10157 }
10158 else if (op == 0xd0)
10159 printf (" MOV FP, SP");
10160 else if (op == 0xd1)
10161 printf (" __c6xabi_pop_rts");
10162 else if (op == 0xd2)
10163 {
10164 unsigned char buf[9];
10165 unsigned int i, len;
26c527e6 10166 uint64_t offset;
a734115a 10167
fa197c1c
PB
10168 for (i = 0; i < sizeof (buf); i++)
10169 {
10170 GET_OP (buf[i]);
10171 if ((buf[i] & 0x80) == 0)
10172 break;
10173 }
0eff7165
NC
10174 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10175 if (i == sizeof (buf))
10176 {
0eff7165 10177 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10178 return false;
0eff7165 10179 }
948f632f 10180
015dc7e1 10181 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10182 assert (len == i + 1);
10183 offset = offset * 8 + 0x408;
26c527e6 10184 printf (_("sp = sp + %" PRId64), offset);
fa197c1c
PB
10185 }
10186 else if ((op & 0xf0) == 0xe0)
10187 {
10188 if ((op & 0x0f) == 7)
10189 printf (" RETURN");
10190 else
10191 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10192 }
10193 else
10194 {
10195 printf (_(" [unsupported opcode]"));
10196 }
10197 putchar ('\n');
10198 }
32ec8896 10199
015dc7e1 10200 return true;
fa197c1c
PB
10201}
10202
625d49fc
AM
10203static uint64_t
10204arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10205{
625d49fc 10206 uint64_t offset;
fa197c1c
PB
10207
10208 offset = word & 0x7fffffff;
10209 if (offset & 0x40000000)
625d49fc 10210 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10211
dda8d76d 10212 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10213 offset <<= 1;
10214
10215 return offset + where;
10216}
10217
015dc7e1 10218static bool
dda8d76d
NC
10219decode_arm_unwind (Filedata * filedata,
10220 struct arm_unw_aux_info * aux,
1b31d05e
NC
10221 unsigned int word,
10222 unsigned int remaining,
625d49fc 10223 uint64_t data_offset,
1b31d05e
NC
10224 Elf_Internal_Shdr * data_sec,
10225 struct arm_section * data_arm_sec)
fa197c1c
PB
10226{
10227 int per_index;
10228 unsigned int more_words = 0;
37e14bc3 10229 struct absaddr addr;
625d49fc 10230 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10231 bool res = true;
fa197c1c
PB
10232
10233 if (remaining == 0)
10234 {
1b31d05e
NC
10235 /* Fetch the first word.
10236 Note - when decoding an object file the address extracted
10237 here will always be 0. So we also pass in the sym_name
10238 parameter so that we can find the symbol associated with
10239 the personality routine. */
dda8d76d 10240 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10241 & word, & addr, & sym_name))
015dc7e1 10242 return false;
1b31d05e 10243
fa197c1c
PB
10244 remaining = 4;
10245 }
c93dbb25
CZ
10246 else
10247 {
10248 addr.section = SHN_UNDEF;
10249 addr.offset = 0;
10250 }
fa197c1c
PB
10251
10252 if ((word & 0x80000000) == 0)
10253 {
10254 /* Expand prel31 for personality routine. */
625d49fc 10255 uint64_t fn;
fa197c1c
PB
10256 const char *procname;
10257
dda8d76d 10258 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10259 printf (_(" Personality routine: "));
1b31d05e
NC
10260 if (fn == 0
10261 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10262 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10263 {
10264 procname = aux->strtab + sym_name;
10265 print_vma (fn, PREFIX_HEX);
10266 if (procname)
10267 {
10268 fputs (" <", stdout);
10269 fputs (procname, stdout);
10270 fputc ('>', stdout);
10271 }
10272 }
10273 else
dda8d76d 10274 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10275 fputc ('\n', stdout);
10276
10277 /* The GCC personality routines use the standard compact
10278 encoding, starting with one byte giving the number of
10279 words. */
10280 if (procname != NULL
24d127aa
ML
10281 && (startswith (procname, "__gcc_personality_v0")
10282 || startswith (procname, "__gxx_personality_v0")
10283 || startswith (procname, "__gcj_personality_v0")
10284 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10285 {
10286 remaining = 0;
10287 more_words = 1;
10288 ADVANCE;
10289 if (!remaining)
10290 {
10291 printf (_(" [Truncated data]\n"));
015dc7e1 10292 return false;
fa197c1c
PB
10293 }
10294 more_words = word >> 24;
10295 word <<= 8;
10296 remaining--;
10297 per_index = -1;
10298 }
10299 else
015dc7e1 10300 return true;
fa197c1c
PB
10301 }
10302 else
10303 {
1b31d05e 10304 /* ARM EHABI Section 6.3:
0b4362b0 10305
1b31d05e 10306 An exception-handling table entry for the compact model looks like:
0b4362b0 10307
1b31d05e
NC
10308 31 30-28 27-24 23-0
10309 -- ----- ----- ----
10310 1 0 index Data for personalityRoutine[index] */
10311
dda8d76d 10312 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10313 && (word & 0x70000000))
32ec8896
NC
10314 {
10315 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10316 res = false;
32ec8896 10317 }
1b31d05e 10318
fa197c1c 10319 per_index = (word >> 24) & 0x7f;
1b31d05e 10320 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10321 if (per_index == 0)
10322 {
10323 more_words = 0;
10324 word <<= 8;
10325 remaining--;
10326 }
10327 else if (per_index < 3)
10328 {
10329 more_words = (word >> 16) & 0xff;
10330 word <<= 16;
10331 remaining -= 2;
10332 }
10333 }
10334
dda8d76d 10335 switch (filedata->file_header.e_machine)
fa197c1c
PB
10336 {
10337 case EM_ARM:
10338 if (per_index < 3)
10339 {
dda8d76d 10340 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10341 data_offset, data_sec, data_arm_sec))
015dc7e1 10342 res = false;
fa197c1c
PB
10343 }
10344 else
1b31d05e
NC
10345 {
10346 warn (_("Unknown ARM compact model index encountered\n"));
10347 printf (_(" [reserved]\n"));
015dc7e1 10348 res = false;
1b31d05e 10349 }
fa197c1c
PB
10350 break;
10351
10352 case EM_TI_C6000:
10353 if (per_index < 3)
10354 {
dda8d76d 10355 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10356 data_offset, data_sec, data_arm_sec))
015dc7e1 10357 res = false;
fa197c1c
PB
10358 }
10359 else if (per_index < 5)
10360 {
10361 if (((word >> 17) & 0x7f) == 0x7f)
10362 printf (_(" Restore stack from frame pointer\n"));
10363 else
10364 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10365 printf (_(" Registers restored: "));
10366 if (per_index == 4)
10367 printf (" (compact) ");
10368 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10369 putchar ('\n');
10370 printf (_(" Return register: %s\n"),
10371 tic6x_unwind_regnames[word & 0xf]);
10372 }
10373 else
1b31d05e 10374 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10375 break;
10376
10377 default:
74e1a04b 10378 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10379 filedata->file_header.e_machine);
015dc7e1 10380 res = false;
fa197c1c 10381 }
0b6ae522
DJ
10382
10383 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10384
10385 return res;
0b6ae522
DJ
10386}
10387
015dc7e1 10388static bool
dda8d76d
NC
10389dump_arm_unwind (Filedata * filedata,
10390 struct arm_unw_aux_info * aux,
10391 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10392{
10393 struct arm_section exidx_arm_sec, extab_arm_sec;
10394 unsigned int i, exidx_len;
26c527e6 10395 uint64_t j, nfuns;
015dc7e1 10396 bool res = true;
0b6ae522
DJ
10397
10398 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10399 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10400 exidx_len = exidx_sec->sh_size / 8;
10401
948f632f
DA
10402 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10403 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10404 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10405 aux->funtab[nfuns++] = aux->symtab[j];
10406 aux->nfuns = nfuns;
10407 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10408
0b6ae522
DJ
10409 for (i = 0; i < exidx_len; i++)
10410 {
10411 unsigned int exidx_fn, exidx_entry;
10412 struct absaddr fn_addr, entry_addr;
625d49fc 10413 uint64_t fn;
0b6ae522
DJ
10414
10415 fputc ('\n', stdout);
10416
dda8d76d 10417 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10418 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10419 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10420 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10421 {
948f632f 10422 free (aux->funtab);
1b31d05e
NC
10423 arm_free_section (& exidx_arm_sec);
10424 arm_free_section (& extab_arm_sec);
015dc7e1 10425 return false;
0b6ae522
DJ
10426 }
10427
83c257ca
NC
10428 /* ARM EHABI, Section 5:
10429 An index table entry consists of 2 words.
10430 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10431 if (exidx_fn & 0x80000000)
32ec8896
NC
10432 {
10433 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10434 res = false;
32ec8896 10435 }
83c257ca 10436
dda8d76d 10437 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10438
dda8d76d 10439 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10440 fputs (": ", stdout);
10441
10442 if (exidx_entry == 1)
10443 {
10444 print_vma (exidx_entry, PREFIX_HEX);
10445 fputs (" [cantunwind]\n", stdout);
10446 }
10447 else if (exidx_entry & 0x80000000)
10448 {
10449 print_vma (exidx_entry, PREFIX_HEX);
10450 fputc ('\n', stdout);
dda8d76d 10451 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10452 }
10453 else
10454 {
625d49fc 10455 uint64_t table, table_offset = 0;
0b6ae522
DJ
10456 Elf_Internal_Shdr *table_sec;
10457
10458 fputs ("@", stdout);
dda8d76d 10459 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10460 print_vma (table, PREFIX_HEX);
10461 printf ("\n");
10462
10463 /* Locate the matching .ARM.extab. */
10464 if (entry_addr.section != SHN_UNDEF
dda8d76d 10465 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10466 {
dda8d76d 10467 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10468 table_offset = entry_addr.offset;
1a915552 10469 /* PR 18879 */
625d49fc 10470 if (table_offset > table_sec->sh_size)
1a915552 10471 {
26c527e6
AM
10472 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
10473 table_offset,
dda8d76d 10474 printable_section_name (filedata, table_sec));
015dc7e1 10475 res = false;
1a915552
NC
10476 continue;
10477 }
0b6ae522
DJ
10478 }
10479 else
10480 {
dda8d76d 10481 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10482 if (table_sec != NULL)
10483 table_offset = table - table_sec->sh_addr;
10484 }
32ec8896 10485
0b6ae522
DJ
10486 if (table_sec == NULL)
10487 {
26c527e6
AM
10488 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
10489 table);
015dc7e1 10490 res = false;
0b6ae522
DJ
10491 continue;
10492 }
32ec8896 10493
dda8d76d 10494 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10495 &extab_arm_sec))
015dc7e1 10496 res = false;
0b6ae522
DJ
10497 }
10498 }
10499
10500 printf ("\n");
10501
948f632f 10502 free (aux->funtab);
0b6ae522
DJ
10503 arm_free_section (&exidx_arm_sec);
10504 arm_free_section (&extab_arm_sec);
32ec8896
NC
10505
10506 return res;
0b6ae522
DJ
10507}
10508
fa197c1c 10509/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10510
015dc7e1 10511static bool
dda8d76d 10512arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10513{
10514 struct arm_unw_aux_info aux;
10515 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522 10516 Elf_Internal_Shdr *sec;
26c527e6 10517 size_t i;
fa197c1c 10518 unsigned int sec_type;
015dc7e1 10519 bool res = true;
0b6ae522 10520
dda8d76d 10521 switch (filedata->file_header.e_machine)
fa197c1c
PB
10522 {
10523 case EM_ARM:
10524 sec_type = SHT_ARM_EXIDX;
10525 break;
10526
10527 case EM_TI_C6000:
10528 sec_type = SHT_C6000_UNWIND;
10529 break;
10530
0b4362b0 10531 default:
74e1a04b 10532 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10533 filedata->file_header.e_machine);
015dc7e1 10534 return false;
fa197c1c
PB
10535 }
10536
dda8d76d 10537 if (filedata->string_table == NULL)
015dc7e1 10538 return false;
1b31d05e
NC
10539
10540 memset (& aux, 0, sizeof (aux));
dda8d76d 10541 aux.filedata = filedata;
0b6ae522 10542
dda8d76d 10543 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10544 {
28d13567 10545 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10546 {
28d13567 10547 if (aux.symtab)
74e1a04b 10548 {
28d13567
AM
10549 error (_("Multiple symbol tables encountered\n"));
10550 free (aux.symtab);
10551 aux.symtab = NULL;
74e1a04b 10552 free (aux.strtab);
28d13567 10553 aux.strtab = NULL;
74e1a04b 10554 }
28d13567
AM
10555 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10556 &aux.strtab, &aux.strtab_size))
015dc7e1 10557 return false;
0b6ae522 10558 }
fa197c1c 10559 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10560 unwsec = sec;
10561 }
10562
1b31d05e 10563 if (unwsec == NULL)
0b6ae522 10564 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10565 else
dda8d76d 10566 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10567 {
10568 if (sec->sh_type == sec_type)
10569 {
26c527e6
AM
10570 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
10571 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
10572 "contains %" PRIu64 " entry:\n",
10573 "\nUnwind section '%s' at offset %#" PRIx64 " "
10574 "contains %" PRIu64 " entries:\n",
d3a49aa8 10575 num_unwind),
dda8d76d 10576 printable_section_name (filedata, sec),
26c527e6 10577 sec->sh_offset,
d3a49aa8 10578 num_unwind);
0b6ae522 10579
dda8d76d 10580 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10581 res = false;
1b31d05e
NC
10582 }
10583 }
0b6ae522 10584
9db70fc3
AM
10585 free (aux.symtab);
10586 free ((char *) aux.strtab);
32ec8896
NC
10587
10588 return res;
0b6ae522
DJ
10589}
10590
3ecc00ec
NC
10591static bool
10592no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10593{
10594 printf (_("No processor specific unwind information to decode\n"));
10595 return true;
10596}
10597
015dc7e1 10598static bool
dda8d76d 10599process_unwind (Filedata * filedata)
57346661 10600{
2cf0635d
NC
10601 struct unwind_handler
10602 {
32ec8896 10603 unsigned int machtype;
015dc7e1 10604 bool (* handler)(Filedata *);
2cf0635d
NC
10605 } handlers[] =
10606 {
0b6ae522 10607 { EM_ARM, arm_process_unwind },
57346661
AM
10608 { EM_IA_64, ia64_process_unwind },
10609 { EM_PARISC, hppa_process_unwind },
fa197c1c 10610 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10611 { EM_386, no_processor_specific_unwind },
10612 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10613 { 0, NULL }
57346661
AM
10614 };
10615 int i;
10616
10617 if (!do_unwind)
015dc7e1 10618 return true;
57346661
AM
10619
10620 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10621 if (filedata->file_header.e_machine == handlers[i].machtype)
10622 return handlers[i].handler (filedata);
57346661 10623
1b31d05e 10624 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10625 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10626 return true;
57346661
AM
10627}
10628
37c18eed
SD
10629static void
10630dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10631{
10632 switch (entry->d_tag)
10633 {
10634 case DT_AARCH64_BTI_PLT:
1dbade74 10635 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10636 break;
10637 default:
10638 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10639 break;
10640 }
10641 putchar ('\n');
10642}
10643
252b5132 10644static void
978c4450 10645dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10646{
10647 switch (entry->d_tag)
10648 {
10649 case DT_MIPS_FLAGS:
10650 if (entry->d_un.d_val == 0)
4b68bca3 10651 printf (_("NONE"));
252b5132
RH
10652 else
10653 {
10654 static const char * opts[] =
10655 {
10656 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10657 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10658 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10659 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10660 "RLD_ORDER_SAFE"
10661 };
10662 unsigned int cnt;
015dc7e1 10663 bool first = true;
2b692964 10664
60bca95a 10665 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10666 if (entry->d_un.d_val & (1 << cnt))
10667 {
10668 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10669 first = false;
252b5132 10670 }
252b5132
RH
10671 }
10672 break;
103f02d3 10673
252b5132 10674 case DT_MIPS_IVERSION:
84714f86 10675 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10676 printf (_("Interface Version: %s"),
84714f86 10677 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10678 else
f493c217 10679 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 10680 entry->d_un.d_ptr);
252b5132 10681 break;
103f02d3 10682
252b5132
RH
10683 case DT_MIPS_TIME_STAMP:
10684 {
d5b07ef4 10685 char timebuf[128];
2cf0635d 10686 struct tm * tmp;
91d6fa6a 10687 time_t atime = entry->d_un.d_val;
82b1b41b 10688
91d6fa6a 10689 tmp = gmtime (&atime);
82b1b41b
NC
10690 /* PR 17531: file: 6accc532. */
10691 if (tmp == NULL)
10692 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10693 else
10694 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10695 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10696 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10697 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10698 }
10699 break;
103f02d3 10700
252b5132
RH
10701 case DT_MIPS_RLD_VERSION:
10702 case DT_MIPS_LOCAL_GOTNO:
10703 case DT_MIPS_CONFLICTNO:
10704 case DT_MIPS_LIBLISTNO:
10705 case DT_MIPS_SYMTABNO:
10706 case DT_MIPS_UNREFEXTNO:
10707 case DT_MIPS_HIPAGENO:
10708 case DT_MIPS_DELTA_CLASS_NO:
10709 case DT_MIPS_DELTA_INSTANCE_NO:
10710 case DT_MIPS_DELTA_RELOC_NO:
10711 case DT_MIPS_DELTA_SYM_NO:
10712 case DT_MIPS_DELTA_CLASSSYM_NO:
10713 case DT_MIPS_COMPACT_SIZE:
c69075ac 10714 print_vma (entry->d_un.d_val, DEC);
252b5132 10715 break;
103f02d3 10716
f16a9783 10717 case DT_MIPS_XHASH:
978c4450
AM
10718 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10719 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10720 /* Falls through. */
10721
103f02d3 10722 default:
4b68bca3 10723 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10724 }
4b68bca3 10725 putchar ('\n');
103f02d3
UD
10726}
10727
103f02d3 10728static void
2cf0635d 10729dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10730{
10731 switch (entry->d_tag)
10732 {
10733 case DT_HP_DLD_FLAGS:
10734 {
10735 static struct
10736 {
26c527e6 10737 unsigned int bit;
2cf0635d 10738 const char * str;
5e220199
NC
10739 }
10740 flags[] =
10741 {
10742 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10743 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10744 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10745 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10746 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10747 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10748 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10749 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10750 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10751 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10752 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10753 { DT_HP_GST, "HP_GST" },
10754 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10755 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10756 { DT_HP_NODELETE, "HP_NODELETE" },
10757 { DT_HP_GROUP, "HP_GROUP" },
10758 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10759 };
015dc7e1 10760 bool first = true;
5e220199 10761 size_t cnt;
625d49fc 10762 uint64_t val = entry->d_un.d_val;
103f02d3 10763
60bca95a 10764 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10765 if (val & flags[cnt].bit)
30800947
NC
10766 {
10767 if (! first)
10768 putchar (' ');
10769 fputs (flags[cnt].str, stdout);
015dc7e1 10770 first = false;
30800947
NC
10771 val ^= flags[cnt].bit;
10772 }
76da6bbe 10773
103f02d3 10774 if (val != 0 || first)
f7a99963
NC
10775 {
10776 if (! first)
10777 putchar (' ');
10778 print_vma (val, HEX);
10779 }
103f02d3
UD
10780 }
10781 break;
76da6bbe 10782
252b5132 10783 default:
f7a99963
NC
10784 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10785 break;
252b5132 10786 }
35b1837e 10787 putchar ('\n');
252b5132
RH
10788}
10789
28f997cf
TG
10790/* VMS vs Unix time offset and factor. */
10791
10792#define VMS_EPOCH_OFFSET 35067168000000000LL
10793#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10794#ifndef INT64_MIN
10795#define INT64_MIN (-9223372036854775807LL - 1)
10796#endif
28f997cf
TG
10797
10798/* Display a VMS time in a human readable format. */
10799
10800static void
0e3c1eeb 10801print_vms_time (int64_t vmstime)
28f997cf 10802{
dccc31de 10803 struct tm *tm = NULL;
28f997cf
TG
10804 time_t unxtime;
10805
dccc31de
AM
10806 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10807 {
10808 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10809 unxtime = vmstime;
10810 if (unxtime == vmstime)
10811 tm = gmtime (&unxtime);
10812 }
10813 if (tm != NULL)
10814 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10815 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10816 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 10817}
28f997cf 10818
ecc51f48 10819static void
2cf0635d 10820dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10821{
10822 switch (entry->d_tag)
10823 {
0de14b54 10824 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10825 /* First 3 slots reserved. */
ecc51f48
NC
10826 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10827 printf (" -- ");
10828 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10829 break;
10830
28f997cf 10831 case DT_IA_64_VMS_LINKTIME:
28f997cf 10832 print_vms_time (entry->d_un.d_val);
28f997cf
TG
10833 break;
10834
10835 case DT_IA_64_VMS_LNKFLAGS:
10836 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10837 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10838 printf (" CALL_DEBUG");
10839 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10840 printf (" NOP0BUFS");
10841 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10842 printf (" P0IMAGE");
10843 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10844 printf (" MKTHREADS");
10845 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10846 printf (" UPCALLS");
10847 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10848 printf (" IMGSTA");
10849 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10850 printf (" INITIALIZE");
10851 if (entry->d_un.d_val & VMS_LF_MAIN)
10852 printf (" MAIN");
10853 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10854 printf (" EXE_INIT");
10855 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10856 printf (" TBK_IN_IMG");
10857 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10858 printf (" DBG_IN_IMG");
10859 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10860 printf (" TBK_IN_DSF");
10861 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10862 printf (" DBG_IN_DSF");
10863 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10864 printf (" SIGNATURES");
10865 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10866 printf (" REL_SEG_OFF");
10867 break;
10868
bdf4d63a
JJ
10869 default:
10870 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10871 break;
ecc51f48 10872 }
bdf4d63a 10873 putchar ('\n');
ecc51f48
NC
10874}
10875
015dc7e1 10876static bool
dda8d76d 10877get_32bit_dynamic_section (Filedata * filedata)
252b5132 10878{
2cf0635d
NC
10879 Elf32_External_Dyn * edyn;
10880 Elf32_External_Dyn * ext;
10881 Elf_Internal_Dyn * entry;
103f02d3 10882
978c4450
AM
10883 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10884 filedata->dynamic_addr, 1,
10885 filedata->dynamic_size,
10886 _("dynamic section"));
a6e9f9df 10887 if (!edyn)
015dc7e1 10888 return false;
103f02d3 10889
071436c6
NC
10890 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10891 might not have the luxury of section headers. Look for the DT_NULL
10892 terminator to determine the number of entries. */
978c4450
AM
10893 for (ext = edyn, filedata->dynamic_nent = 0;
10894 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10895 ext++)
10896 {
978c4450 10897 filedata->dynamic_nent++;
ba2685cc
AM
10898 if (BYTE_GET (ext->d_tag) == DT_NULL)
10899 break;
10900 }
252b5132 10901
978c4450
AM
10902 filedata->dynamic_section
10903 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10904 if (filedata->dynamic_section == NULL)
252b5132 10905 {
26c527e6
AM
10906 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
10907 filedata->dynamic_nent);
9ea033b2 10908 free (edyn);
015dc7e1 10909 return false;
9ea033b2 10910 }
252b5132 10911
978c4450
AM
10912 for (ext = edyn, entry = filedata->dynamic_section;
10913 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10914 ext++, entry++)
9ea033b2 10915 {
fb514b26
AM
10916 entry->d_tag = BYTE_GET (ext->d_tag);
10917 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10918 }
10919
9ea033b2
NC
10920 free (edyn);
10921
015dc7e1 10922 return true;
9ea033b2
NC
10923}
10924
015dc7e1 10925static bool
dda8d76d 10926get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10927{
2cf0635d
NC
10928 Elf64_External_Dyn * edyn;
10929 Elf64_External_Dyn * ext;
10930 Elf_Internal_Dyn * entry;
103f02d3 10931
071436c6 10932 /* Read in the data. */
978c4450
AM
10933 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10934 filedata->dynamic_addr, 1,
10935 filedata->dynamic_size,
10936 _("dynamic section"));
a6e9f9df 10937 if (!edyn)
015dc7e1 10938 return false;
103f02d3 10939
071436c6
NC
10940 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10941 might not have the luxury of section headers. Look for the DT_NULL
10942 terminator to determine the number of entries. */
978c4450 10943 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10944 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10945 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10946 ext++)
10947 {
978c4450 10948 filedata->dynamic_nent++;
66543521 10949 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10950 break;
10951 }
252b5132 10952
978c4450
AM
10953 filedata->dynamic_section
10954 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10955 if (filedata->dynamic_section == NULL)
252b5132 10956 {
26c527e6
AM
10957 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
10958 filedata->dynamic_nent);
252b5132 10959 free (edyn);
015dc7e1 10960 return false;
252b5132
RH
10961 }
10962
071436c6 10963 /* Convert from external to internal formats. */
978c4450
AM
10964 for (ext = edyn, entry = filedata->dynamic_section;
10965 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10966 ext++, entry++)
252b5132 10967 {
66543521
AM
10968 entry->d_tag = BYTE_GET (ext->d_tag);
10969 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10970 }
10971
10972 free (edyn);
10973
015dc7e1 10974 return true;
9ea033b2
NC
10975}
10976
4de91c10
AM
10977static bool
10978get_dynamic_section (Filedata *filedata)
10979{
10980 if (filedata->dynamic_section)
10981 return true;
10982
10983 if (is_32bit_elf)
10984 return get_32bit_dynamic_section (filedata);
10985 else
10986 return get_64bit_dynamic_section (filedata);
10987}
10988
e9e44622 10989static void
625d49fc 10990print_dynamic_flags (uint64_t flags)
d1133906 10991{
015dc7e1 10992 bool first = true;
13ae64f3 10993
d1133906
NC
10994 while (flags)
10995 {
625d49fc 10996 uint64_t flag;
d1133906
NC
10997
10998 flag = flags & - flags;
10999 flags &= ~ flag;
11000
e9e44622 11001 if (first)
015dc7e1 11002 first = false;
e9e44622
JJ
11003 else
11004 putc (' ', stdout);
13ae64f3 11005
d1133906
NC
11006 switch (flag)
11007 {
e9e44622
JJ
11008 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11009 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11010 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11011 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11012 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 11013 default: fputs (_("unknown"), stdout); break;
d1133906
NC
11014 }
11015 }
e9e44622 11016 puts ("");
d1133906
NC
11017}
11018
625d49fc 11019static uint64_t *
be7d229a 11020get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
11021{
11022 unsigned char * e_data;
625d49fc 11023 uint64_t * i_data;
10ca4b04 11024
be7d229a
AM
11025 /* If size_t is smaller than uint64_t, eg because you are building
11026 on a 32-bit host, then make sure that when number is cast to
11027 size_t no information is lost. */
11028 if ((size_t) number != number
11029 || ent_size * number / ent_size != number)
10ca4b04 11030 {
be7d229a 11031 error (_("Size overflow prevents reading %" PRIu64
b8281767 11032 " elements of size %u\n"),
be7d229a 11033 number, ent_size);
10ca4b04
L
11034 return NULL;
11035 }
11036
11037 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11038 attempting to allocate memory when the read is bound to fail. */
11039 if (ent_size * number > filedata->file_size)
11040 {
b8281767 11041 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 11042 number);
10ca4b04
L
11043 return NULL;
11044 }
11045
11046 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11047 if (e_data == NULL)
11048 {
b8281767 11049 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 11050 number);
10ca4b04
L
11051 return NULL;
11052 }
11053
11054 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11055 {
b8281767 11056 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 11057 number * ent_size);
10ca4b04
L
11058 free (e_data);
11059 return NULL;
11060 }
11061
625d49fc 11062 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
11063 if (i_data == NULL)
11064 {
b8281767 11065 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 11066 number);
10ca4b04
L
11067 free (e_data);
11068 return NULL;
11069 }
11070
11071 while (number--)
11072 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11073
11074 free (e_data);
11075
11076 return i_data;
11077}
11078
26c527e6 11079static uint64_t
10ca4b04
L
11080get_num_dynamic_syms (Filedata * filedata)
11081{
26c527e6 11082 uint64_t num_of_syms = 0;
10ca4b04
L
11083
11084 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11085 return num_of_syms;
11086
978c4450 11087 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11088 {
11089 unsigned char nb[8];
11090 unsigned char nc[8];
11091 unsigned int hash_ent_size = 4;
11092
11093 if ((filedata->file_header.e_machine == EM_ALPHA
11094 || filedata->file_header.e_machine == EM_S390
11095 || filedata->file_header.e_machine == EM_S390_OLD)
11096 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11097 hash_ent_size = 8;
11098
63cf857e
AM
11099 if (fseek64 (filedata->handle,
11100 (filedata->archive_file_offset
11101 + offset_from_vma (filedata,
11102 filedata->dynamic_info[DT_HASH],
11103 sizeof nb + sizeof nc)),
11104 SEEK_SET))
10ca4b04
L
11105 {
11106 error (_("Unable to seek to start of dynamic information\n"));
11107 goto no_hash;
11108 }
11109
11110 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11111 {
11112 error (_("Failed to read in number of buckets\n"));
11113 goto no_hash;
11114 }
11115
11116 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11117 {
11118 error (_("Failed to read in number of chains\n"));
11119 goto no_hash;
11120 }
11121
978c4450
AM
11122 filedata->nbuckets = byte_get (nb, hash_ent_size);
11123 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11124
2482f306
AM
11125 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11126 {
11127 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11128 hash_ent_size);
11129 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11130 hash_ent_size);
001890e1 11131
2482f306
AM
11132 if (filedata->buckets != NULL && filedata->chains != NULL)
11133 num_of_syms = filedata->nchains;
11134 }
ceb9bf11 11135 no_hash:
10ca4b04
L
11136 if (num_of_syms == 0)
11137 {
9db70fc3
AM
11138 free (filedata->buckets);
11139 filedata->buckets = NULL;
11140 free (filedata->chains);
11141 filedata->chains = NULL;
978c4450 11142 filedata->nbuckets = 0;
10ca4b04
L
11143 }
11144 }
11145
978c4450 11146 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11147 {
11148 unsigned char nb[16];
625d49fc
AM
11149 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11150 uint64_t buckets_vma;
26c527e6 11151 uint64_t hn;
10ca4b04 11152
63cf857e
AM
11153 if (fseek64 (filedata->handle,
11154 (filedata->archive_file_offset
11155 + offset_from_vma (filedata,
11156 filedata->dynamic_info_DT_GNU_HASH,
11157 sizeof nb)),
11158 SEEK_SET))
10ca4b04
L
11159 {
11160 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11161 goto no_gnu_hash;
11162 }
11163
11164 if (fread (nb, 16, 1, filedata->handle) != 1)
11165 {
11166 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11167 goto no_gnu_hash;
11168 }
11169
978c4450
AM
11170 filedata->ngnubuckets = byte_get (nb, 4);
11171 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11172 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11173 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11174 if (is_32bit_elf)
11175 buckets_vma += bitmaskwords * 4;
11176 else
11177 buckets_vma += bitmaskwords * 8;
11178
63cf857e
AM
11179 if (fseek64 (filedata->handle,
11180 (filedata->archive_file_offset
11181 + offset_from_vma (filedata, buckets_vma, 4)),
11182 SEEK_SET))
10ca4b04
L
11183 {
11184 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11185 goto no_gnu_hash;
11186 }
11187
978c4450
AM
11188 filedata->gnubuckets
11189 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11190
978c4450 11191 if (filedata->gnubuckets == NULL)
90837ea7 11192 goto no_gnu_hash;
10ca4b04 11193
978c4450
AM
11194 for (i = 0; i < filedata->ngnubuckets; i++)
11195 if (filedata->gnubuckets[i] != 0)
10ca4b04 11196 {
978c4450 11197 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11198 goto no_gnu_hash;
10ca4b04 11199
978c4450
AM
11200 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11201 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11202 }
11203
11204 if (maxchain == 0xffffffff)
90837ea7 11205 goto no_gnu_hash;
10ca4b04 11206
978c4450 11207 maxchain -= filedata->gnusymidx;
10ca4b04 11208
63cf857e
AM
11209 if (fseek64 (filedata->handle,
11210 (filedata->archive_file_offset
11211 + offset_from_vma (filedata,
11212 buckets_vma + 4 * (filedata->ngnubuckets
11213 + maxchain),
11214 4)),
11215 SEEK_SET))
10ca4b04
L
11216 {
11217 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11218 goto no_gnu_hash;
11219 }
11220
11221 do
11222 {
11223 if (fread (nb, 4, 1, filedata->handle) != 1)
11224 {
11225 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11226 goto no_gnu_hash;
11227 }
11228
11229 if (maxchain + 1 == 0)
90837ea7 11230 goto no_gnu_hash;
10ca4b04
L
11231
11232 ++maxchain;
11233 }
11234 while ((byte_get (nb, 4) & 1) == 0);
11235
63cf857e
AM
11236 if (fseek64 (filedata->handle,
11237 (filedata->archive_file_offset
11238 + offset_from_vma (filedata, (buckets_vma
11239 + 4 * filedata->ngnubuckets),
11240 4)),
11241 SEEK_SET))
10ca4b04
L
11242 {
11243 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11244 goto no_gnu_hash;
11245 }
11246
978c4450
AM
11247 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11248 filedata->ngnuchains = maxchain;
10ca4b04 11249
978c4450 11250 if (filedata->gnuchains == NULL)
90837ea7 11251 goto no_gnu_hash;
10ca4b04 11252
978c4450 11253 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11254 {
63cf857e
AM
11255 if (fseek64 (filedata->handle,
11256 (filedata->archive_file_offset
11257 + offset_from_vma (filedata, (buckets_vma
11258 + 4 * (filedata->ngnubuckets
11259 + maxchain)), 4)),
11260 SEEK_SET))
10ca4b04
L
11261 {
11262 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11263 goto no_gnu_hash;
11264 }
11265
978c4450 11266 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11267 if (filedata->mipsxlat == NULL)
11268 goto no_gnu_hash;
10ca4b04
L
11269 }
11270
978c4450
AM
11271 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11272 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11273 {
625d49fc
AM
11274 uint64_t si = filedata->gnubuckets[hn];
11275 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11276
11277 do
11278 {
978c4450 11279 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11280 {
c31ab5a0
AM
11281 if (off < filedata->ngnuchains
11282 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11283 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11284 }
11285 else
11286 {
11287 if (si >= num_of_syms)
11288 num_of_syms = si + 1;
11289 }
11290 si++;
11291 }
978c4450
AM
11292 while (off < filedata->ngnuchains
11293 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11294 }
11295
90837ea7 11296 if (num_of_syms == 0)
10ca4b04 11297 {
90837ea7 11298 no_gnu_hash:
9db70fc3
AM
11299 free (filedata->mipsxlat);
11300 filedata->mipsxlat = NULL;
11301 free (filedata->gnuchains);
11302 filedata->gnuchains = NULL;
11303 free (filedata->gnubuckets);
11304 filedata->gnubuckets = NULL;
978c4450
AM
11305 filedata->ngnubuckets = 0;
11306 filedata->ngnuchains = 0;
10ca4b04
L
11307 }
11308 }
11309
11310 return num_of_syms;
11311}
11312
b2d38a17
NC
11313/* Parse and display the contents of the dynamic section. */
11314
015dc7e1 11315static bool
dda8d76d 11316process_dynamic_section (Filedata * filedata)
9ea033b2 11317{
2cf0635d 11318 Elf_Internal_Dyn * entry;
9ea033b2 11319
93df3340 11320 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11321 {
11322 if (do_dynamic)
ca0e11aa
NC
11323 {
11324 if (filedata->is_separate)
11325 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11326 filedata->file_name);
11327 else
11328 printf (_("\nThere is no dynamic section in this file.\n"));
11329 }
9ea033b2 11330
015dc7e1 11331 return true;
9ea033b2
NC
11332 }
11333
4de91c10
AM
11334 if (!get_dynamic_section (filedata))
11335 return false;
9ea033b2 11336
252b5132 11337 /* Find the appropriate symbol table. */
978c4450 11338 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11339 {
26c527e6 11340 uint64_t num_of_syms;
2482f306 11341
978c4450
AM
11342 for (entry = filedata->dynamic_section;
11343 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11344 ++entry)
10ca4b04 11345 if (entry->d_tag == DT_SYMTAB)
978c4450 11346 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11347 else if (entry->d_tag == DT_SYMENT)
978c4450 11348 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11349 else if (entry->d_tag == DT_HASH)
978c4450 11350 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11351 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11352 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11353 else if ((filedata->file_header.e_machine == EM_MIPS
11354 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11355 && entry->d_tag == DT_MIPS_XHASH)
11356 {
978c4450
AM
11357 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11358 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11359 }
252b5132 11360
2482f306
AM
11361 num_of_syms = get_num_dynamic_syms (filedata);
11362
11363 if (num_of_syms != 0
11364 && filedata->dynamic_symbols == NULL
11365 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11366 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11367 {
11368 Elf_Internal_Phdr *seg;
625d49fc 11369 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11370
2482f306
AM
11371 if (! get_program_headers (filedata))
11372 {
11373 error (_("Cannot interpret virtual addresses "
11374 "without program headers.\n"));
015dc7e1 11375 return false;
2482f306 11376 }
252b5132 11377
2482f306
AM
11378 for (seg = filedata->program_headers;
11379 seg < filedata->program_headers + filedata->file_header.e_phnum;
11380 ++seg)
11381 {
11382 if (seg->p_type != PT_LOAD)
11383 continue;
252b5132 11384
2482f306
AM
11385 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11386 {
11387 /* See PR 21379 for a reproducer. */
11388 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11389 return false;
2482f306 11390 }
252b5132 11391
2482f306
AM
11392 if (vma >= (seg->p_vaddr & -seg->p_align)
11393 && vma < seg->p_vaddr + seg->p_filesz)
11394 {
11395 /* Since we do not know how big the symbol table is,
11396 we default to reading in up to the end of PT_LOAD
11397 segment and processing that. This is overkill, I
11398 know, but it should work. */
11399 Elf_Internal_Shdr section;
11400 section.sh_offset = (vma - seg->p_vaddr
11401 + seg->p_offset);
11402 section.sh_size = (num_of_syms
11403 * filedata->dynamic_info[DT_SYMENT]);
11404 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11405
11406 if (do_checks
11407 && filedata->dynamic_symtab_section != NULL
11408 && ((filedata->dynamic_symtab_section->sh_offset
11409 != section.sh_offset)
11410 || (filedata->dynamic_symtab_section->sh_size
11411 != section.sh_size)
11412 || (filedata->dynamic_symtab_section->sh_entsize
11413 != section.sh_entsize)))
11414 warn (_("\
11415the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11416
2482f306
AM
11417 section.sh_name = filedata->string_table_length;
11418 filedata->dynamic_symbols
4de91c10 11419 = get_elf_symbols (filedata, &section,
2482f306
AM
11420 &filedata->num_dynamic_syms);
11421 if (filedata->dynamic_symbols == NULL
11422 || filedata->num_dynamic_syms != num_of_syms)
11423 {
11424 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11425 return false;
2482f306
AM
11426 }
11427 break;
11428 }
11429 }
11430 }
11431 }
252b5132
RH
11432
11433 /* Similarly find a string table. */
978c4450
AM
11434 if (filedata->dynamic_strings == NULL)
11435 for (entry = filedata->dynamic_section;
11436 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11437 ++entry)
11438 {
11439 if (entry->d_tag == DT_STRTAB)
978c4450 11440 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11441
10ca4b04 11442 if (entry->d_tag == DT_STRSZ)
978c4450 11443 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11444
978c4450
AM
11445 if (filedata->dynamic_info[DT_STRTAB]
11446 && filedata->dynamic_info[DT_STRSZ])
10ca4b04 11447 {
26c527e6 11448 uint64_t offset;
be7d229a 11449 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11450
11451 offset = offset_from_vma (filedata,
978c4450 11452 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11453 str_tab_len);
8ac10c5b
L
11454 if (do_checks
11455 && filedata->dynamic_strtab_section
11456 && ((filedata->dynamic_strtab_section->sh_offset
11457 != (file_ptr) offset)
11458 || (filedata->dynamic_strtab_section->sh_size
11459 != str_tab_len)))
11460 warn (_("\
11461the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11462
978c4450
AM
11463 filedata->dynamic_strings
11464 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11465 _("dynamic string table"));
11466 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11467 {
11468 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11469 break;
11470 }
e3d39609 11471
978c4450 11472 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11473 break;
11474 }
11475 }
252b5132
RH
11476
11477 /* And find the syminfo section if available. */
978c4450 11478 if (filedata->dynamic_syminfo == NULL)
252b5132 11479 {
26c527e6 11480 uint64_t syminsz = 0;
252b5132 11481
978c4450
AM
11482 for (entry = filedata->dynamic_section;
11483 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11484 ++entry)
252b5132
RH
11485 {
11486 if (entry->d_tag == DT_SYMINENT)
11487 {
11488 /* Note: these braces are necessary to avoid a syntax
11489 error from the SunOS4 C compiler. */
049b0c3a
NC
11490 /* PR binutils/17531: A corrupt file can trigger this test.
11491 So do not use an assert, instead generate an error message. */
11492 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11493 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11494 (int) entry->d_un.d_val);
252b5132
RH
11495 }
11496 else if (entry->d_tag == DT_SYMINSZ)
11497 syminsz = entry->d_un.d_val;
11498 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11499 filedata->dynamic_syminfo_offset
11500 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11501 }
11502
978c4450 11503 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11504 {
2cf0635d
NC
11505 Elf_External_Syminfo * extsyminfo;
11506 Elf_External_Syminfo * extsym;
11507 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11508
11509 /* There is a syminfo section. Read the data. */
3f5e193b 11510 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11511 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11512 1, syminsz, _("symbol information"));
a6e9f9df 11513 if (!extsyminfo)
015dc7e1 11514 return false;
252b5132 11515
978c4450 11516 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11517 {
11518 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11519 free (filedata->dynamic_syminfo);
e3d39609 11520 }
978c4450
AM
11521 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11522 if (filedata->dynamic_syminfo == NULL)
252b5132 11523 {
26c527e6
AM
11524 error (_("Out of memory allocating %" PRIu64
11525 " bytes for dynamic symbol info\n"),
11526 syminsz);
015dc7e1 11527 return false;
252b5132
RH
11528 }
11529
2482f306
AM
11530 filedata->dynamic_syminfo_nent
11531 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11532 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11533 syminfo < (filedata->dynamic_syminfo
11534 + filedata->dynamic_syminfo_nent);
86dba8ee 11535 ++syminfo, ++extsym)
252b5132 11536 {
86dba8ee
AM
11537 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11538 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11539 }
11540
11541 free (extsyminfo);
11542 }
11543 }
11544
978c4450 11545 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11546 {
f253158f 11547 if (filedata->is_separate)
26c527e6
AM
11548 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
11549 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
11550 filedata->dynamic_nent),
f253158f
NC
11551 filedata->file_name,
11552 filedata->dynamic_addr,
26c527e6 11553 filedata->dynamic_nent);
84a9f195 11554 else
02da71ee 11555 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
26c527e6
AM
11556 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
11557 filedata->dynamic_nent),
84a9f195 11558 filedata->dynamic_addr,
26c527e6 11559 filedata->dynamic_nent);
ca0e11aa 11560 }
252b5132
RH
11561 if (do_dynamic)
11562 printf (_(" Tag Type Name/Value\n"));
11563
978c4450
AM
11564 for (entry = filedata->dynamic_section;
11565 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11566 entry++)
252b5132
RH
11567 {
11568 if (do_dynamic)
f7a99963 11569 {
2cf0635d 11570 const char * dtype;
e699b9ff 11571
f7a99963
NC
11572 putchar (' ');
11573 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11574 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11575 printf (" (%s)%*s", dtype,
32ec8896 11576 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11577 }
252b5132
RH
11578
11579 switch (entry->d_tag)
11580 {
d1133906
NC
11581 case DT_FLAGS:
11582 if (do_dynamic)
e9e44622 11583 print_dynamic_flags (entry->d_un.d_val);
d1133906 11584 break;
76da6bbe 11585
252b5132
RH
11586 case DT_AUXILIARY:
11587 case DT_FILTER:
019148e4
L
11588 case DT_CONFIG:
11589 case DT_DEPAUDIT:
11590 case DT_AUDIT:
252b5132
RH
11591 if (do_dynamic)
11592 {
019148e4 11593 switch (entry->d_tag)
b34976b6 11594 {
019148e4
L
11595 case DT_AUXILIARY:
11596 printf (_("Auxiliary library"));
11597 break;
11598
11599 case DT_FILTER:
11600 printf (_("Filter library"));
11601 break;
11602
b34976b6 11603 case DT_CONFIG:
019148e4
L
11604 printf (_("Configuration file"));
11605 break;
11606
11607 case DT_DEPAUDIT:
11608 printf (_("Dependency audit library"));
11609 break;
11610
11611 case DT_AUDIT:
11612 printf (_("Audit library"));
11613 break;
11614 }
252b5132 11615
84714f86 11616 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11617 printf (": [%s]\n",
84714f86 11618 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11619 else
f7a99963
NC
11620 {
11621 printf (": ");
11622 print_vma (entry->d_un.d_val, PREFIX_HEX);
11623 putchar ('\n');
11624 }
252b5132
RH
11625 }
11626 break;
11627
dcefbbbd 11628 case DT_FEATURE:
252b5132
RH
11629 if (do_dynamic)
11630 {
11631 printf (_("Flags:"));
86f55779 11632
252b5132
RH
11633 if (entry->d_un.d_val == 0)
11634 printf (_(" None\n"));
11635 else
11636 {
26c527e6 11637 uint64_t val = entry->d_un.d_val;
86f55779 11638
252b5132
RH
11639 if (val & DTF_1_PARINIT)
11640 {
11641 printf (" PARINIT");
11642 val ^= DTF_1_PARINIT;
11643 }
dcefbbbd
L
11644 if (val & DTF_1_CONFEXP)
11645 {
11646 printf (" CONFEXP");
11647 val ^= DTF_1_CONFEXP;
11648 }
252b5132 11649 if (val != 0)
26c527e6 11650 printf (" %" PRIx64, val);
252b5132
RH
11651 puts ("");
11652 }
11653 }
11654 break;
11655
11656 case DT_POSFLAG_1:
11657 if (do_dynamic)
11658 {
11659 printf (_("Flags:"));
86f55779 11660
252b5132
RH
11661 if (entry->d_un.d_val == 0)
11662 printf (_(" None\n"));
11663 else
11664 {
26c527e6 11665 uint64_t val = entry->d_un.d_val;
86f55779 11666
252b5132
RH
11667 if (val & DF_P1_LAZYLOAD)
11668 {
11669 printf (" LAZYLOAD");
11670 val ^= DF_P1_LAZYLOAD;
11671 }
11672 if (val & DF_P1_GROUPPERM)
11673 {
11674 printf (" GROUPPERM");
11675 val ^= DF_P1_GROUPPERM;
11676 }
11677 if (val != 0)
26c527e6 11678 printf (" %" PRIx64, val);
252b5132
RH
11679 puts ("");
11680 }
11681 }
11682 break;
11683
11684 case DT_FLAGS_1:
11685 if (do_dynamic)
11686 {
11687 printf (_("Flags:"));
11688 if (entry->d_un.d_val == 0)
11689 printf (_(" None\n"));
11690 else
11691 {
26c527e6 11692 uint64_t val = entry->d_un.d_val;
86f55779 11693
252b5132
RH
11694 if (val & DF_1_NOW)
11695 {
11696 printf (" NOW");
11697 val ^= DF_1_NOW;
11698 }
11699 if (val & DF_1_GLOBAL)
11700 {
11701 printf (" GLOBAL");
11702 val ^= DF_1_GLOBAL;
11703 }
11704 if (val & DF_1_GROUP)
11705 {
11706 printf (" GROUP");
11707 val ^= DF_1_GROUP;
11708 }
11709 if (val & DF_1_NODELETE)
11710 {
11711 printf (" NODELETE");
11712 val ^= DF_1_NODELETE;
11713 }
11714 if (val & DF_1_LOADFLTR)
11715 {
11716 printf (" LOADFLTR");
11717 val ^= DF_1_LOADFLTR;
11718 }
11719 if (val & DF_1_INITFIRST)
11720 {
11721 printf (" INITFIRST");
11722 val ^= DF_1_INITFIRST;
11723 }
11724 if (val & DF_1_NOOPEN)
11725 {
11726 printf (" NOOPEN");
11727 val ^= DF_1_NOOPEN;
11728 }
11729 if (val & DF_1_ORIGIN)
11730 {
11731 printf (" ORIGIN");
11732 val ^= DF_1_ORIGIN;
11733 }
11734 if (val & DF_1_DIRECT)
11735 {
11736 printf (" DIRECT");
11737 val ^= DF_1_DIRECT;
11738 }
11739 if (val & DF_1_TRANS)
11740 {
11741 printf (" TRANS");
11742 val ^= DF_1_TRANS;
11743 }
11744 if (val & DF_1_INTERPOSE)
11745 {
11746 printf (" INTERPOSE");
11747 val ^= DF_1_INTERPOSE;
11748 }
f7db6139 11749 if (val & DF_1_NODEFLIB)
dcefbbbd 11750 {
f7db6139
L
11751 printf (" NODEFLIB");
11752 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11753 }
11754 if (val & DF_1_NODUMP)
11755 {
11756 printf (" NODUMP");
11757 val ^= DF_1_NODUMP;
11758 }
34b60028 11759 if (val & DF_1_CONFALT)
dcefbbbd 11760 {
34b60028
L
11761 printf (" CONFALT");
11762 val ^= DF_1_CONFALT;
11763 }
11764 if (val & DF_1_ENDFILTEE)
11765 {
11766 printf (" ENDFILTEE");
11767 val ^= DF_1_ENDFILTEE;
11768 }
11769 if (val & DF_1_DISPRELDNE)
11770 {
11771 printf (" DISPRELDNE");
11772 val ^= DF_1_DISPRELDNE;
11773 }
11774 if (val & DF_1_DISPRELPND)
11775 {
11776 printf (" DISPRELPND");
11777 val ^= DF_1_DISPRELPND;
11778 }
11779 if (val & DF_1_NODIRECT)
11780 {
11781 printf (" NODIRECT");
11782 val ^= DF_1_NODIRECT;
11783 }
11784 if (val & DF_1_IGNMULDEF)
11785 {
11786 printf (" IGNMULDEF");
11787 val ^= DF_1_IGNMULDEF;
11788 }
11789 if (val & DF_1_NOKSYMS)
11790 {
11791 printf (" NOKSYMS");
11792 val ^= DF_1_NOKSYMS;
11793 }
11794 if (val & DF_1_NOHDR)
11795 {
11796 printf (" NOHDR");
11797 val ^= DF_1_NOHDR;
11798 }
11799 if (val & DF_1_EDITED)
11800 {
11801 printf (" EDITED");
11802 val ^= DF_1_EDITED;
11803 }
11804 if (val & DF_1_NORELOC)
11805 {
11806 printf (" NORELOC");
11807 val ^= DF_1_NORELOC;
11808 }
11809 if (val & DF_1_SYMINTPOSE)
11810 {
11811 printf (" SYMINTPOSE");
11812 val ^= DF_1_SYMINTPOSE;
11813 }
11814 if (val & DF_1_GLOBAUDIT)
11815 {
11816 printf (" GLOBAUDIT");
11817 val ^= DF_1_GLOBAUDIT;
11818 }
11819 if (val & DF_1_SINGLETON)
11820 {
11821 printf (" SINGLETON");
11822 val ^= DF_1_SINGLETON;
dcefbbbd 11823 }
5c383f02
RO
11824 if (val & DF_1_STUB)
11825 {
11826 printf (" STUB");
11827 val ^= DF_1_STUB;
11828 }
11829 if (val & DF_1_PIE)
11830 {
11831 printf (" PIE");
11832 val ^= DF_1_PIE;
11833 }
b1202ffa
L
11834 if (val & DF_1_KMOD)
11835 {
11836 printf (" KMOD");
11837 val ^= DF_1_KMOD;
11838 }
11839 if (val & DF_1_WEAKFILTER)
11840 {
11841 printf (" WEAKFILTER");
11842 val ^= DF_1_WEAKFILTER;
11843 }
11844 if (val & DF_1_NOCOMMON)
11845 {
11846 printf (" NOCOMMON");
11847 val ^= DF_1_NOCOMMON;
11848 }
252b5132 11849 if (val != 0)
26c527e6 11850 printf (" %" PRIx64, val);
252b5132
RH
11851 puts ("");
11852 }
11853 }
11854 break;
11855
11856 case DT_PLTREL:
978c4450 11857 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11858 if (do_dynamic)
dda8d76d 11859 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11860 break;
11861
11862 case DT_NULL :
11863 case DT_NEEDED :
11864 case DT_PLTGOT :
11865 case DT_HASH :
11866 case DT_STRTAB :
11867 case DT_SYMTAB :
11868 case DT_RELA :
11869 case DT_INIT :
11870 case DT_FINI :
11871 case DT_SONAME :
11872 case DT_RPATH :
11873 case DT_SYMBOLIC:
11874 case DT_REL :
a7fd1186 11875 case DT_RELR :
252b5132
RH
11876 case DT_DEBUG :
11877 case DT_TEXTREL :
11878 case DT_JMPREL :
019148e4 11879 case DT_RUNPATH :
978c4450 11880 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11881
11882 if (do_dynamic)
11883 {
84714f86 11884 const char *name;
252b5132 11885
84714f86
AM
11886 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11887 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11888 else
d79b3d50 11889 name = NULL;
252b5132
RH
11890
11891 if (name)
11892 {
11893 switch (entry->d_tag)
11894 {
11895 case DT_NEEDED:
11896 printf (_("Shared library: [%s]"), name);
11897
13acb58d
AM
11898 if (filedata->program_interpreter
11899 && streq (name, filedata->program_interpreter))
f7a99963 11900 printf (_(" program interpreter"));
252b5132
RH
11901 break;
11902
11903 case DT_SONAME:
f7a99963 11904 printf (_("Library soname: [%s]"), name);
252b5132
RH
11905 break;
11906
11907 case DT_RPATH:
f7a99963 11908 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11909 break;
11910
019148e4
L
11911 case DT_RUNPATH:
11912 printf (_("Library runpath: [%s]"), name);
11913 break;
11914
252b5132 11915 default:
f7a99963
NC
11916 print_vma (entry->d_un.d_val, PREFIX_HEX);
11917 break;
252b5132
RH
11918 }
11919 }
11920 else
f7a99963
NC
11921 print_vma (entry->d_un.d_val, PREFIX_HEX);
11922
11923 putchar ('\n');
252b5132
RH
11924 }
11925 break;
11926
11927 case DT_PLTRELSZ:
11928 case DT_RELASZ :
11929 case DT_STRSZ :
11930 case DT_RELSZ :
11931 case DT_RELAENT :
a7fd1186
FS
11932 case DT_RELRENT :
11933 case DT_RELRSZ :
252b5132
RH
11934 case DT_SYMENT :
11935 case DT_RELENT :
978c4450 11936 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11937 /* Fall through. */
252b5132
RH
11938 case DT_PLTPADSZ:
11939 case DT_MOVEENT :
11940 case DT_MOVESZ :
04d8355a 11941 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11942 case DT_INIT_ARRAYSZ:
11943 case DT_FINI_ARRAYSZ:
047b2264
JJ
11944 case DT_GNU_CONFLICTSZ:
11945 case DT_GNU_LIBLISTSZ:
252b5132 11946 if (do_dynamic)
f7a99963
NC
11947 {
11948 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11949 printf (_(" (bytes)\n"));
f7a99963 11950 }
252b5132
RH
11951 break;
11952
11953 case DT_VERDEFNUM:
11954 case DT_VERNEEDNUM:
11955 case DT_RELACOUNT:
11956 case DT_RELCOUNT:
11957 if (do_dynamic)
f7a99963
NC
11958 {
11959 print_vma (entry->d_un.d_val, UNSIGNED);
11960 putchar ('\n');
11961 }
252b5132
RH
11962 break;
11963
11964 case DT_SYMINSZ:
11965 case DT_SYMINENT:
11966 case DT_SYMINFO:
11967 case DT_USED:
11968 case DT_INIT_ARRAY:
11969 case DT_FINI_ARRAY:
11970 if (do_dynamic)
11971 {
d79b3d50 11972 if (entry->d_tag == DT_USED
84714f86 11973 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11974 {
84714f86
AM
11975 const char *name
11976 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11977
b34976b6 11978 if (*name)
252b5132
RH
11979 {
11980 printf (_("Not needed object: [%s]\n"), name);
11981 break;
11982 }
11983 }
103f02d3 11984
f7a99963
NC
11985 print_vma (entry->d_un.d_val, PREFIX_HEX);
11986 putchar ('\n');
252b5132
RH
11987 }
11988 break;
11989
11990 case DT_BIND_NOW:
11991 /* The value of this entry is ignored. */
35b1837e
AM
11992 if (do_dynamic)
11993 putchar ('\n');
252b5132 11994 break;
103f02d3 11995
047b2264
JJ
11996 case DT_GNU_PRELINKED:
11997 if (do_dynamic)
11998 {
2cf0635d 11999 struct tm * tmp;
91d6fa6a 12000 time_t atime = entry->d_un.d_val;
047b2264 12001
91d6fa6a 12002 tmp = gmtime (&atime);
071436c6
NC
12003 /* PR 17533 file: 041-1244816-0.004. */
12004 if (tmp == NULL)
26c527e6
AM
12005 printf (_("<corrupt time val: %" PRIx64),
12006 (uint64_t) atime);
071436c6
NC
12007 else
12008 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12009 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12010 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12011
12012 }
12013 break;
12014
fdc90cb4 12015 case DT_GNU_HASH:
978c4450 12016 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
12017 if (do_dynamic)
12018 {
12019 print_vma (entry->d_un.d_val, PREFIX_HEX);
12020 putchar ('\n');
12021 }
12022 break;
12023
a5da3dee
VDM
12024 case DT_GNU_FLAGS_1:
12025 if (do_dynamic)
12026 {
12027 printf (_("Flags:"));
12028 if (entry->d_un.d_val == 0)
12029 printf (_(" None\n"));
12030 else
12031 {
26c527e6 12032 uint64_t val = entry->d_un.d_val;
a5da3dee
VDM
12033
12034 if (val & DF_GNU_1_UNIQUE)
12035 {
12036 printf (" UNIQUE");
12037 val ^= DF_GNU_1_UNIQUE;
12038 }
12039 if (val != 0)
26c527e6 12040 printf (" %" PRIx64, val);
a5da3dee
VDM
12041 puts ("");
12042 }
12043 }
12044 break;
12045
252b5132
RH
12046 default:
12047 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
12048 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12049 = entry->d_un.d_val;
252b5132
RH
12050
12051 if (do_dynamic)
12052 {
dda8d76d 12053 switch (filedata->file_header.e_machine)
252b5132 12054 {
37c18eed
SD
12055 case EM_AARCH64:
12056 dynamic_section_aarch64_val (entry);
12057 break;
252b5132 12058 case EM_MIPS:
4fe85591 12059 case EM_MIPS_RS3_LE:
978c4450 12060 dynamic_section_mips_val (filedata, entry);
252b5132 12061 break;
103f02d3 12062 case EM_PARISC:
b2d38a17 12063 dynamic_section_parisc_val (entry);
103f02d3 12064 break;
ecc51f48 12065 case EM_IA_64:
b2d38a17 12066 dynamic_section_ia64_val (entry);
ecc51f48 12067 break;
252b5132 12068 default:
f7a99963
NC
12069 print_vma (entry->d_un.d_val, PREFIX_HEX);
12070 putchar ('\n');
252b5132
RH
12071 }
12072 }
12073 break;
12074 }
12075 }
12076
015dc7e1 12077 return true;
252b5132
RH
12078}
12079
12080static char *
d3ba0551 12081get_ver_flags (unsigned int flags)
252b5132 12082{
6d4f21f6 12083 static char buff[128];
252b5132
RH
12084
12085 buff[0] = 0;
12086
12087 if (flags == 0)
12088 return _("none");
12089
12090 if (flags & VER_FLG_BASE)
7bb1ad17 12091 strcat (buff, "BASE");
252b5132
RH
12092
12093 if (flags & VER_FLG_WEAK)
12094 {
12095 if (flags & VER_FLG_BASE)
7bb1ad17 12096 strcat (buff, " | ");
252b5132 12097
7bb1ad17 12098 strcat (buff, "WEAK");
252b5132
RH
12099 }
12100
44ec90b9
RO
12101 if (flags & VER_FLG_INFO)
12102 {
12103 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12104 strcat (buff, " | ");
44ec90b9 12105
7bb1ad17 12106 strcat (buff, "INFO");
44ec90b9
RO
12107 }
12108
12109 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12110 {
12111 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12112 strcat (buff, " | ");
12113
12114 strcat (buff, _("<unknown>"));
12115 }
252b5132
RH
12116
12117 return buff;
12118}
12119
12120/* Display the contents of the version sections. */
98fb390a 12121
015dc7e1 12122static bool
dda8d76d 12123process_version_sections (Filedata * filedata)
252b5132 12124{
2cf0635d 12125 Elf_Internal_Shdr * section;
b34976b6 12126 unsigned i;
015dc7e1 12127 bool found = false;
252b5132
RH
12128
12129 if (! do_version)
015dc7e1 12130 return true;
252b5132 12131
dda8d76d
NC
12132 for (i = 0, section = filedata->section_headers;
12133 i < filedata->file_header.e_shnum;
b34976b6 12134 i++, section++)
252b5132
RH
12135 {
12136 switch (section->sh_type)
12137 {
12138 case SHT_GNU_verdef:
12139 {
2cf0635d 12140 Elf_External_Verdef * edefs;
26c527e6
AM
12141 size_t idx;
12142 size_t cnt;
2cf0635d 12143 char * endbuf;
252b5132 12144
015dc7e1 12145 found = true;
252b5132 12146
ca0e11aa
NC
12147 if (filedata->is_separate)
12148 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12149 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12150 section->sh_info),
12151 filedata->file_name,
12152 printable_section_name (filedata, section),
12153 section->sh_info);
12154 else
12155 printf (ngettext ("\nVersion definition section '%s' "
12156 "contains %u entry:\n",
12157 "\nVersion definition section '%s' "
12158 "contains %u entries:\n",
12159 section->sh_info),
12160 printable_section_name (filedata, section),
12161 section->sh_info);
047c3dbf 12162
625d49fc 12163 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12164 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12165 section->sh_offset, section->sh_link,
dda8d76d 12166 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12167
3f5e193b 12168 edefs = (Elf_External_Verdef *)
dda8d76d 12169 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12170 _("version definition section"));
a6e9f9df
AM
12171 if (!edefs)
12172 break;
59245841 12173 endbuf = (char *) edefs + section->sh_size;
252b5132 12174
1445030f 12175 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12176 {
2cf0635d
NC
12177 char * vstart;
12178 Elf_External_Verdef * edef;
b34976b6 12179 Elf_Internal_Verdef ent;
2cf0635d 12180 Elf_External_Verdaux * eaux;
b34976b6 12181 Elf_Internal_Verdaux aux;
26c527e6 12182 size_t isum;
b34976b6 12183 int j;
103f02d3 12184
252b5132 12185 vstart = ((char *) edefs) + idx;
54806181
AM
12186 if (vstart + sizeof (*edef) > endbuf)
12187 break;
252b5132
RH
12188
12189 edef = (Elf_External_Verdef *) vstart;
12190
12191 ent.vd_version = BYTE_GET (edef->vd_version);
12192 ent.vd_flags = BYTE_GET (edef->vd_flags);
12193 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12194 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12195 ent.vd_hash = BYTE_GET (edef->vd_hash);
12196 ent.vd_aux = BYTE_GET (edef->vd_aux);
12197 ent.vd_next = BYTE_GET (edef->vd_next);
12198
26c527e6 12199 printf (_(" %#06zx: Rev: %d Flags: %s"),
252b5132
RH
12200 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12201
12202 printf (_(" Index: %d Cnt: %d "),
12203 ent.vd_ndx, ent.vd_cnt);
12204
452bf675 12205 /* Check for overflow. */
1445030f 12206 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12207 break;
12208
252b5132
RH
12209 vstart += ent.vd_aux;
12210
1445030f
AM
12211 if (vstart + sizeof (*eaux) > endbuf)
12212 break;
252b5132
RH
12213 eaux = (Elf_External_Verdaux *) vstart;
12214
12215 aux.vda_name = BYTE_GET (eaux->vda_name);
12216 aux.vda_next = BYTE_GET (eaux->vda_next);
12217
84714f86 12218 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12219 printf (_("Name: %s\n"),
84714f86 12220 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12221 else
12222 printf (_("Name index: %ld\n"), aux.vda_name);
12223
12224 isum = idx + ent.vd_aux;
12225
b34976b6 12226 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12227 {
1445030f
AM
12228 if (aux.vda_next < sizeof (*eaux)
12229 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12230 {
12231 warn (_("Invalid vda_next field of %lx\n"),
12232 aux.vda_next);
12233 j = ent.vd_cnt;
12234 break;
12235 }
dd24e3da 12236 /* Check for overflow. */
7e26601c 12237 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12238 break;
12239
252b5132
RH
12240 isum += aux.vda_next;
12241 vstart += aux.vda_next;
12242
54806181
AM
12243 if (vstart + sizeof (*eaux) > endbuf)
12244 break;
1445030f 12245 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12246
12247 aux.vda_name = BYTE_GET (eaux->vda_name);
12248 aux.vda_next = BYTE_GET (eaux->vda_next);
12249
84714f86 12250 if (valid_dynamic_name (filedata, aux.vda_name))
26c527e6 12251 printf (_(" %#06zx: Parent %d: %s\n"),
978c4450 12252 isum, j,
84714f86 12253 get_dynamic_name (filedata, aux.vda_name));
252b5132 12254 else
26c527e6 12255 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
252b5132
RH
12256 isum, j, aux.vda_name);
12257 }
dd24e3da 12258
54806181
AM
12259 if (j < ent.vd_cnt)
12260 printf (_(" Version def aux past end of section\n"));
252b5132 12261
c9f02c3e
MR
12262 /* PR 17531:
12263 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12264 if (ent.vd_next < sizeof (*edef)
12265 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12266 {
12267 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12268 cnt = section->sh_info;
12269 break;
12270 }
452bf675 12271 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12272 break;
12273
252b5132
RH
12274 idx += ent.vd_next;
12275 }
dd24e3da 12276
54806181
AM
12277 if (cnt < section->sh_info)
12278 printf (_(" Version definition past end of section\n"));
252b5132
RH
12279
12280 free (edefs);
12281 }
12282 break;
103f02d3 12283
252b5132
RH
12284 case SHT_GNU_verneed:
12285 {
2cf0635d 12286 Elf_External_Verneed * eneed;
26c527e6
AM
12287 size_t idx;
12288 size_t cnt;
2cf0635d 12289 char * endbuf;
252b5132 12290
015dc7e1 12291 found = true;
252b5132 12292
ca0e11aa
NC
12293 if (filedata->is_separate)
12294 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12295 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12296 section->sh_info),
12297 filedata->file_name,
12298 printable_section_name (filedata, section),
12299 section->sh_info);
12300 else
12301 printf (ngettext ("\nVersion needs section '%s' "
12302 "contains %u entry:\n",
12303 "\nVersion needs section '%s' "
12304 "contains %u entries:\n",
12305 section->sh_info),
12306 printable_section_name (filedata, section),
12307 section->sh_info);
047c3dbf 12308
625d49fc 12309 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12310 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12311 section->sh_offset, section->sh_link,
dda8d76d 12312 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12313
dda8d76d 12314 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12315 section->sh_offset, 1,
12316 section->sh_size,
9cf03b7e 12317 _("Version Needs section"));
a6e9f9df
AM
12318 if (!eneed)
12319 break;
59245841 12320 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12321
12322 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12323 {
2cf0635d 12324 Elf_External_Verneed * entry;
b34976b6 12325 Elf_Internal_Verneed ent;
26c527e6 12326 size_t isum;
b34976b6 12327 int j;
2cf0635d 12328 char * vstart;
252b5132
RH
12329
12330 vstart = ((char *) eneed) + idx;
54806181
AM
12331 if (vstart + sizeof (*entry) > endbuf)
12332 break;
252b5132
RH
12333
12334 entry = (Elf_External_Verneed *) vstart;
12335
12336 ent.vn_version = BYTE_GET (entry->vn_version);
12337 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12338 ent.vn_file = BYTE_GET (entry->vn_file);
12339 ent.vn_aux = BYTE_GET (entry->vn_aux);
12340 ent.vn_next = BYTE_GET (entry->vn_next);
12341
26c527e6 12342 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
252b5132 12343
84714f86 12344 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12345 printf (_(" File: %s"),
84714f86 12346 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12347 else
12348 printf (_(" File: %lx"), ent.vn_file);
12349
12350 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12351
dd24e3da 12352 /* Check for overflow. */
7e26601c 12353 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12354 break;
252b5132
RH
12355 vstart += ent.vn_aux;
12356
12357 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12358 {
2cf0635d 12359 Elf_External_Vernaux * eaux;
b34976b6 12360 Elf_Internal_Vernaux aux;
252b5132 12361
54806181
AM
12362 if (vstart + sizeof (*eaux) > endbuf)
12363 break;
252b5132
RH
12364 eaux = (Elf_External_Vernaux *) vstart;
12365
12366 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12367 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12368 aux.vna_other = BYTE_GET (eaux->vna_other);
12369 aux.vna_name = BYTE_GET (eaux->vna_name);
12370 aux.vna_next = BYTE_GET (eaux->vna_next);
12371
84714f86 12372 if (valid_dynamic_name (filedata, aux.vna_name))
26c527e6 12373 printf (_(" %#06zx: Name: %s"),
84714f86 12374 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12375 else
26c527e6 12376 printf (_(" %#06zx: Name index: %lx"),
252b5132
RH
12377 isum, aux.vna_name);
12378
12379 printf (_(" Flags: %s Version: %d\n"),
12380 get_ver_flags (aux.vna_flags), aux.vna_other);
12381
1445030f
AM
12382 if (aux.vna_next < sizeof (*eaux)
12383 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12384 {
12385 warn (_("Invalid vna_next field of %lx\n"),
12386 aux.vna_next);
12387 j = ent.vn_cnt;
12388 break;
12389 }
1445030f
AM
12390 /* Check for overflow. */
12391 if (aux.vna_next > (size_t) (endbuf - vstart))
12392 break;
252b5132
RH
12393 isum += aux.vna_next;
12394 vstart += aux.vna_next;
12395 }
9cf03b7e 12396
54806181 12397 if (j < ent.vn_cnt)
f9a6a8f0 12398 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12399
1445030f
AM
12400 if (ent.vn_next < sizeof (*entry)
12401 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12402 {
452bf675 12403 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12404 cnt = section->sh_info;
12405 break;
12406 }
1445030f
AM
12407 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12408 break;
252b5132
RH
12409 idx += ent.vn_next;
12410 }
9cf03b7e 12411
54806181 12412 if (cnt < section->sh_info)
9cf03b7e 12413 warn (_("Missing Version Needs information\n"));
103f02d3 12414
252b5132
RH
12415 free (eneed);
12416 }
12417 break;
12418
12419 case SHT_GNU_versym:
12420 {
2cf0635d 12421 Elf_Internal_Shdr * link_section;
26c527e6 12422 uint64_t total;
8b73c356 12423 unsigned int cnt;
2cf0635d
NC
12424 unsigned char * edata;
12425 unsigned short * data;
12426 char * strtab;
12427 Elf_Internal_Sym * symbols;
12428 Elf_Internal_Shdr * string_sec;
26c527e6
AM
12429 uint64_t num_syms;
12430 uint64_t off;
252b5132 12431
dda8d76d 12432 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12433 break;
12434
dda8d76d 12435 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12436 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12437
dda8d76d 12438 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12439 break;
12440
015dc7e1 12441 found = true;
252b5132 12442
4de91c10 12443 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12444 if (symbols == NULL)
12445 break;
252b5132 12446
dda8d76d 12447 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12448
dda8d76d 12449 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12450 string_sec->sh_size,
12451 _("version string table"));
a6e9f9df 12452 if (!strtab)
0429c154
MS
12453 {
12454 free (symbols);
12455 break;
12456 }
252b5132 12457
ca0e11aa 12458 if (filedata->is_separate)
26c527e6
AM
12459 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
12460 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12461 total),
12462 filedata->file_name,
12463 printable_section_name (filedata, section),
26c527e6 12464 total);
ca0e11aa
NC
12465 else
12466 printf (ngettext ("\nVersion symbols section '%s' "
26c527e6 12467 "contains %" PRIu64 " entry:\n",
ca0e11aa 12468 "\nVersion symbols section '%s' "
26c527e6 12469 "contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12470 total),
12471 printable_section_name (filedata, section),
26c527e6 12472 total);
252b5132 12473
625d49fc 12474 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12475 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12476 section->sh_offset, section->sh_link,
dda8d76d 12477 printable_section_name (filedata, link_section));
252b5132 12478
dda8d76d 12479 off = offset_from_vma (filedata,
978c4450 12480 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12481 total * sizeof (short));
95099889
AM
12482 edata = (unsigned char *) get_data (NULL, filedata, off,
12483 sizeof (short), total,
12484 _("version symbol data"));
a6e9f9df
AM
12485 if (!edata)
12486 {
12487 free (strtab);
0429c154 12488 free (symbols);
a6e9f9df
AM
12489 break;
12490 }
252b5132 12491
3f5e193b 12492 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12493
12494 for (cnt = total; cnt --;)
b34976b6
AM
12495 data[cnt] = byte_get (edata + cnt * sizeof (short),
12496 sizeof (short));
252b5132
RH
12497
12498 free (edata);
12499
12500 for (cnt = 0; cnt < total; cnt += 4)
12501 {
12502 int j, nn;
ab273396
AM
12503 char *name;
12504 char *invalid = _("*invalid*");
252b5132
RH
12505
12506 printf (" %03x:", cnt);
12507
12508 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12509 switch (data[cnt + j])
252b5132
RH
12510 {
12511 case 0:
12512 fputs (_(" 0 (*local*) "), stdout);
12513 break;
12514
12515 case 1:
12516 fputs (_(" 1 (*global*) "), stdout);
12517 break;
12518
12519 default:
c244d050
NC
12520 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12521 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12522
dd24e3da 12523 /* If this index value is greater than the size of the symbols
ba5cdace 12524 array, break to avoid an out-of-bounds read. */
26c527e6 12525 if (cnt + j >= num_syms)
dd24e3da
NC
12526 {
12527 warn (_("invalid index into symbol array\n"));
12528 break;
12529 }
12530
ab273396 12531 name = NULL;
978c4450 12532 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12533 {
b34976b6 12534 Elf_Internal_Verneed ivn;
26c527e6 12535 uint64_t offset;
252b5132 12536
d93f0186 12537 offset = offset_from_vma
978c4450
AM
12538 (filedata,
12539 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12540 sizeof (Elf_External_Verneed));
252b5132 12541
b34976b6 12542 do
252b5132 12543 {
b34976b6
AM
12544 Elf_Internal_Vernaux ivna;
12545 Elf_External_Verneed evn;
12546 Elf_External_Vernaux evna;
26c527e6 12547 uint64_t a_off;
252b5132 12548
dda8d76d 12549 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12550 _("version need")) == NULL)
12551 break;
0b4362b0 12552
252b5132
RH
12553 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12554 ivn.vn_next = BYTE_GET (evn.vn_next);
12555
12556 a_off = offset + ivn.vn_aux;
12557
12558 do
12559 {
dda8d76d 12560 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12561 1, _("version need aux (2)")) == NULL)
12562 {
12563 ivna.vna_next = 0;
12564 ivna.vna_other = 0;
12565 }
12566 else
12567 {
12568 ivna.vna_next = BYTE_GET (evna.vna_next);
12569 ivna.vna_other = BYTE_GET (evna.vna_other);
12570 }
252b5132
RH
12571
12572 a_off += ivna.vna_next;
12573 }
b34976b6 12574 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12575 && ivna.vna_next != 0);
12576
b34976b6 12577 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12578 {
12579 ivna.vna_name = BYTE_GET (evna.vna_name);
12580
54806181 12581 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12582 name = invalid;
54806181
AM
12583 else
12584 name = strtab + ivna.vna_name;
252b5132
RH
12585 break;
12586 }
12587
12588 offset += ivn.vn_next;
12589 }
12590 while (ivn.vn_next);
12591 }
00d93f34 12592
ab273396 12593 if (data[cnt + j] != 0x8001
978c4450 12594 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12595 {
b34976b6
AM
12596 Elf_Internal_Verdef ivd;
12597 Elf_External_Verdef evd;
26c527e6 12598 uint64_t offset;
252b5132 12599
d93f0186 12600 offset = offset_from_vma
978c4450
AM
12601 (filedata,
12602 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12603 sizeof evd);
252b5132
RH
12604
12605 do
12606 {
dda8d76d 12607 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12608 _("version def")) == NULL)
12609 {
12610 ivd.vd_next = 0;
948f632f 12611 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12612 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12613 break;
59245841
NC
12614 }
12615 else
12616 {
12617 ivd.vd_next = BYTE_GET (evd.vd_next);
12618 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12619 }
252b5132
RH
12620
12621 offset += ivd.vd_next;
12622 }
c244d050 12623 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12624 && ivd.vd_next != 0);
12625
c244d050 12626 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12627 {
b34976b6
AM
12628 Elf_External_Verdaux evda;
12629 Elf_Internal_Verdaux ivda;
252b5132
RH
12630
12631 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12632
dda8d76d 12633 if (get_data (&evda, filedata,
59245841
NC
12634 offset - ivd.vd_next + ivd.vd_aux,
12635 sizeof (evda), 1,
12636 _("version def aux")) == NULL)
12637 break;
252b5132
RH
12638
12639 ivda.vda_name = BYTE_GET (evda.vda_name);
12640
54806181 12641 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12642 name = invalid;
12643 else if (name != NULL && name != invalid)
12644 name = _("*both*");
54806181
AM
12645 else
12646 name = strtab + ivda.vda_name;
252b5132
RH
12647 }
12648 }
ab273396
AM
12649 if (name != NULL)
12650 nn += printf ("(%s%-*s",
12651 name,
12652 12 - (int) strlen (name),
12653 ")");
252b5132
RH
12654
12655 if (nn < 18)
12656 printf ("%*c", 18 - nn, ' ');
12657 }
12658
12659 putchar ('\n');
12660 }
12661
12662 free (data);
12663 free (strtab);
12664 free (symbols);
12665 }
12666 break;
103f02d3 12667
252b5132
RH
12668 default:
12669 break;
12670 }
12671 }
12672
12673 if (! found)
ca0e11aa
NC
12674 {
12675 if (filedata->is_separate)
12676 printf (_("\nNo version information found in linked file '%s'.\n"),
12677 filedata->file_name);
12678 else
12679 printf (_("\nNo version information found in this file.\n"));
12680 }
252b5132 12681
015dc7e1 12682 return true;
252b5132
RH
12683}
12684
d1133906 12685static const char *
dda8d76d 12686get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12687{
89246a0e 12688 static char buff[64];
252b5132
RH
12689
12690 switch (binding)
12691 {
b34976b6
AM
12692 case STB_LOCAL: return "LOCAL";
12693 case STB_GLOBAL: return "GLOBAL";
12694 case STB_WEAK: return "WEAK";
252b5132
RH
12695 default:
12696 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12697 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12698 binding);
252b5132 12699 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12700 {
12701 if (binding == STB_GNU_UNIQUE
df3a023b 12702 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12703 return "UNIQUE";
12704 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12705 }
252b5132 12706 else
e9e44622 12707 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12708 return buff;
12709 }
12710}
12711
d1133906 12712static const char *
dda8d76d 12713get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12714{
89246a0e 12715 static char buff[64];
252b5132
RH
12716
12717 switch (type)
12718 {
b34976b6
AM
12719 case STT_NOTYPE: return "NOTYPE";
12720 case STT_OBJECT: return "OBJECT";
12721 case STT_FUNC: return "FUNC";
12722 case STT_SECTION: return "SECTION";
12723 case STT_FILE: return "FILE";
12724 case STT_COMMON: return "COMMON";
12725 case STT_TLS: return "TLS";
15ab5209
DB
12726 case STT_RELC: return "RELC";
12727 case STT_SRELC: return "SRELC";
252b5132
RH
12728 default:
12729 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12730 {
dda8d76d 12731 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12732 return "THUMB_FUNC";
103f02d3 12733
dda8d76d 12734 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12735 return "REGISTER";
12736
dda8d76d 12737 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12738 return "PARISC_MILLI";
12739
e9e44622 12740 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12741 }
252b5132 12742 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12743 {
dda8d76d 12744 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12745 {
12746 if (type == STT_HP_OPAQUE)
12747 return "HP_OPAQUE";
12748 if (type == STT_HP_STUB)
12749 return "HP_STUB";
12750 }
12751
8654c01f
ML
12752 if (type == STT_GNU_IFUNC
12753 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
12754 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
12755 return "IFUNC";
12756
e9e44622 12757 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12758 }
252b5132 12759 else
e9e44622 12760 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12761 return buff;
12762 }
12763}
12764
d1133906 12765static const char *
d3ba0551 12766get_symbol_visibility (unsigned int visibility)
d1133906
NC
12767{
12768 switch (visibility)
12769 {
b34976b6
AM
12770 case STV_DEFAULT: return "DEFAULT";
12771 case STV_INTERNAL: return "INTERNAL";
12772 case STV_HIDDEN: return "HIDDEN";
d1133906 12773 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12774 default:
27a45f42 12775 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12776 return _("<unknown>");
d1133906
NC
12777 }
12778}
12779
2057d69d
CZ
12780static const char *
12781get_alpha_symbol_other (unsigned int other)
9abca702 12782{
2057d69d
CZ
12783 switch (other)
12784 {
12785 case STO_ALPHA_NOPV: return "NOPV";
12786 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12787 default:
27a45f42 12788 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12789 return _("<unknown>");
9abca702 12790 }
2057d69d
CZ
12791}
12792
fd85a6a1
NC
12793static const char *
12794get_solaris_symbol_visibility (unsigned int visibility)
12795{
12796 switch (visibility)
12797 {
12798 case 4: return "EXPORTED";
12799 case 5: return "SINGLETON";
12800 case 6: return "ELIMINATE";
12801 default: return get_symbol_visibility (visibility);
12802 }
12803}
12804
2301ed1c
SN
12805static const char *
12806get_aarch64_symbol_other (unsigned int other)
12807{
12808 static char buf[32];
12809
12810 if (other & STO_AARCH64_VARIANT_PCS)
12811 {
12812 other &= ~STO_AARCH64_VARIANT_PCS;
12813 if (other == 0)
12814 return "VARIANT_PCS";
12815 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12816 return buf;
12817 }
12818 return NULL;
12819}
12820
5e2b0d47
NC
12821static const char *
12822get_mips_symbol_other (unsigned int other)
12823{
12824 switch (other)
12825 {
32ec8896
NC
12826 case STO_OPTIONAL: return "OPTIONAL";
12827 case STO_MIPS_PLT: return "MIPS PLT";
12828 case STO_MIPS_PIC: return "MIPS PIC";
12829 case STO_MICROMIPS: return "MICROMIPS";
12830 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12831 case STO_MIPS16: return "MIPS16";
12832 default: return NULL;
5e2b0d47
NC
12833 }
12834}
12835
28f997cf 12836static const char *
dda8d76d 12837get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12838{
dda8d76d 12839 if (is_ia64_vms (filedata))
28f997cf
TG
12840 {
12841 static char res[32];
12842
12843 res[0] = 0;
12844
12845 /* Function types is for images and .STB files only. */
dda8d76d 12846 switch (filedata->file_header.e_type)
28f997cf
TG
12847 {
12848 case ET_DYN:
12849 case ET_EXEC:
12850 switch (VMS_ST_FUNC_TYPE (other))
12851 {
12852 case VMS_SFT_CODE_ADDR:
12853 strcat (res, " CA");
12854 break;
12855 case VMS_SFT_SYMV_IDX:
12856 strcat (res, " VEC");
12857 break;
12858 case VMS_SFT_FD:
12859 strcat (res, " FD");
12860 break;
12861 case VMS_SFT_RESERVE:
12862 strcat (res, " RSV");
12863 break;
12864 default:
bee0ee85
NC
12865 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12866 VMS_ST_FUNC_TYPE (other));
12867 strcat (res, " <unknown>");
12868 break;
28f997cf
TG
12869 }
12870 break;
12871 default:
12872 break;
12873 }
12874 switch (VMS_ST_LINKAGE (other))
12875 {
12876 case VMS_STL_IGNORE:
12877 strcat (res, " IGN");
12878 break;
12879 case VMS_STL_RESERVE:
12880 strcat (res, " RSV");
12881 break;
12882 case VMS_STL_STD:
12883 strcat (res, " STD");
12884 break;
12885 case VMS_STL_LNK:
12886 strcat (res, " LNK");
12887 break;
12888 default:
bee0ee85
NC
12889 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12890 VMS_ST_LINKAGE (other));
12891 strcat (res, " <unknown>");
12892 break;
28f997cf
TG
12893 }
12894
12895 if (res[0] != 0)
12896 return res + 1;
12897 else
12898 return res;
12899 }
12900 return NULL;
12901}
12902
6911b7dc
AM
12903static const char *
12904get_ppc64_symbol_other (unsigned int other)
12905{
14732552
AM
12906 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12907 return NULL;
12908
12909 other >>= STO_PPC64_LOCAL_BIT;
12910 if (other <= 6)
6911b7dc 12911 {
89246a0e 12912 static char buf[64];
14732552
AM
12913 if (other >= 2)
12914 other = ppc64_decode_local_entry (other);
12915 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12916 return buf;
12917 }
12918 return NULL;
12919}
12920
8155b853
NC
12921static const char *
12922get_riscv_symbol_other (unsigned int other)
12923{
12924 static char buf[32];
12925 buf[0] = 0;
12926
12927 if (other & STO_RISCV_VARIANT_CC)
12928 {
12929 strcat (buf, _(" VARIANT_CC"));
12930 other &= ~STO_RISCV_VARIANT_CC;
12931 }
12932
12933 if (other != 0)
12934 snprintf (buf, sizeof buf, " %x", other);
12935
12936
12937 if (buf[0] != 0)
12938 return buf + 1;
12939 else
12940 return buf;
12941}
12942
5e2b0d47 12943static const char *
dda8d76d 12944get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12945{
12946 const char * result = NULL;
89246a0e 12947 static char buff [64];
5e2b0d47
NC
12948
12949 if (other == 0)
12950 return "";
12951
dda8d76d 12952 switch (filedata->file_header.e_machine)
5e2b0d47 12953 {
2057d69d
CZ
12954 case EM_ALPHA:
12955 result = get_alpha_symbol_other (other);
12956 break;
2301ed1c
SN
12957 case EM_AARCH64:
12958 result = get_aarch64_symbol_other (other);
12959 break;
5e2b0d47
NC
12960 case EM_MIPS:
12961 result = get_mips_symbol_other (other);
28f997cf
TG
12962 break;
12963 case EM_IA_64:
dda8d76d 12964 result = get_ia64_symbol_other (filedata, other);
28f997cf 12965 break;
6911b7dc
AM
12966 case EM_PPC64:
12967 result = get_ppc64_symbol_other (other);
12968 break;
8155b853
NC
12969 case EM_RISCV:
12970 result = get_riscv_symbol_other (other);
12971 break;
5e2b0d47 12972 default:
fd85a6a1 12973 result = NULL;
5e2b0d47
NC
12974 break;
12975 }
12976
12977 if (result)
12978 return result;
12979
12980 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12981 return buff;
12982}
12983
d1133906 12984static const char *
dda8d76d 12985get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12986{
b34976b6 12987 static char buff[32];
5cf1065c 12988
252b5132
RH
12989 switch (type)
12990 {
b34976b6
AM
12991 case SHN_UNDEF: return "UND";
12992 case SHN_ABS: return "ABS";
12993 case SHN_COMMON: return "COM";
252b5132 12994 default:
9ce701e2 12995 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12996 && filedata->file_header.e_machine == EM_IA_64
12997 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12998 return "ANSI_COM";
12999 else if ((filedata->file_header.e_machine == EM_X86_64
13000 || filedata->file_header.e_machine == EM_L1OM
13001 || filedata->file_header.e_machine == EM_K1OM)
13002 && type == SHN_X86_64_LCOMMON)
13003 return "LARGE_COM";
13004 else if ((type == SHN_MIPS_SCOMMON
13005 && filedata->file_header.e_machine == EM_MIPS)
13006 || (type == SHN_TIC6X_SCOMMON
13007 && filedata->file_header.e_machine == EM_TI_C6000))
13008 return "SCOM";
13009 else if (type == SHN_MIPS_SUNDEFINED
13010 && filedata->file_header.e_machine == EM_MIPS)
13011 return "SUND";
13012 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
13013 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
13014 else if (type >= SHN_LOOS && type <= SHN_HIOS)
13015 sprintf (buff, "OS [0x%04x]", type & 0xffff);
13016 else if (type >= SHN_LORESERVE)
13017 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
13018 else if (filedata->file_header.e_shnum != 0
13019 && type >= filedata->file_header.e_shnum)
13020 sprintf (buff, _("bad section index[%3d]"), type);
13021 else
13022 sprintf (buff, "%3d", type);
13023 break;
fd85a6a1
NC
13024 }
13025
10ca4b04 13026 return buff;
6bd1a22c
L
13027}
13028
bb4d2ac2 13029static const char *
26c527e6
AM
13030get_symbol_version_string (Filedata *filedata,
13031 bool is_dynsym,
13032 const char *strtab,
13033 size_t strtab_size,
13034 unsigned int si,
13035 Elf_Internal_Sym *psym,
13036 enum versioned_symbol_info *sym_info,
13037 unsigned short *vna_other)
bb4d2ac2 13038{
ab273396
AM
13039 unsigned char data[2];
13040 unsigned short vers_data;
26c527e6 13041 uint64_t offset;
7a815dd5 13042 unsigned short max_vd_ndx;
bb4d2ac2 13043
ab273396 13044 if (!is_dynsym
978c4450 13045 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 13046 return NULL;
bb4d2ac2 13047
978c4450
AM
13048 offset = offset_from_vma (filedata,
13049 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 13050 sizeof data + si * sizeof (vers_data));
bb4d2ac2 13051
dda8d76d 13052 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
13053 sizeof (data), 1, _("version data")) == NULL)
13054 return NULL;
13055
13056 vers_data = byte_get (data, 2);
bb4d2ac2 13057
1f6f5dba 13058 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 13059 return NULL;
bb4d2ac2 13060
0b8b7609 13061 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
13062 max_vd_ndx = 0;
13063
ab273396
AM
13064 /* Usually we'd only see verdef for defined symbols, and verneed for
13065 undefined symbols. However, symbols defined by the linker in
13066 .dynbss for variables copied from a shared library in order to
13067 avoid text relocations are defined yet have verneed. We could
13068 use a heuristic to detect the special case, for example, check
13069 for verneed first on symbols defined in SHT_NOBITS sections, but
13070 it is simpler and more reliable to just look for both verdef and
13071 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13072
ab273396
AM
13073 if (psym->st_shndx != SHN_UNDEF
13074 && vers_data != 0x8001
978c4450 13075 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13076 {
13077 Elf_Internal_Verdef ivd;
13078 Elf_Internal_Verdaux ivda;
13079 Elf_External_Verdaux evda;
26c527e6 13080 uint64_t off;
bb4d2ac2 13081
dda8d76d 13082 off = offset_from_vma (filedata,
978c4450 13083 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13084 sizeof (Elf_External_Verdef));
13085
13086 do
bb4d2ac2 13087 {
ab273396
AM
13088 Elf_External_Verdef evd;
13089
dda8d76d 13090 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13091 _("version def")) == NULL)
13092 {
13093 ivd.vd_ndx = 0;
13094 ivd.vd_aux = 0;
13095 ivd.vd_next = 0;
1f6f5dba 13096 ivd.vd_flags = 0;
ab273396
AM
13097 }
13098 else
bb4d2ac2 13099 {
ab273396
AM
13100 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13101 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13102 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13103 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13104 }
bb4d2ac2 13105
7a815dd5
L
13106 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13107 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13108
ab273396
AM
13109 off += ivd.vd_next;
13110 }
13111 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13112
ab273396
AM
13113 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13114 {
9abca702 13115 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13116 return NULL;
13117
ab273396
AM
13118 off -= ivd.vd_next;
13119 off += ivd.vd_aux;
bb4d2ac2 13120
dda8d76d 13121 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13122 _("version def aux")) != NULL)
13123 {
13124 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13125
ab273396 13126 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13127 return (ivda.vda_name < strtab_size
13128 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13129 }
13130 }
13131 }
bb4d2ac2 13132
978c4450 13133 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13134 {
13135 Elf_External_Verneed evn;
13136 Elf_Internal_Verneed ivn;
13137 Elf_Internal_Vernaux ivna;
bb4d2ac2 13138
dda8d76d 13139 offset = offset_from_vma (filedata,
978c4450 13140 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13141 sizeof evn);
13142 do
13143 {
26c527e6 13144 uint64_t vna_off;
bb4d2ac2 13145
dda8d76d 13146 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13147 _("version need")) == NULL)
13148 {
13149 ivna.vna_next = 0;
13150 ivna.vna_other = 0;
13151 ivna.vna_name = 0;
13152 break;
13153 }
bb4d2ac2 13154
ab273396
AM
13155 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13156 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13157
ab273396 13158 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13159
ab273396
AM
13160 do
13161 {
13162 Elf_External_Vernaux evna;
bb4d2ac2 13163
dda8d76d 13164 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13165 _("version need aux (3)")) == NULL)
bb4d2ac2 13166 {
ab273396
AM
13167 ivna.vna_next = 0;
13168 ivna.vna_other = 0;
13169 ivna.vna_name = 0;
bb4d2ac2 13170 }
bb4d2ac2 13171 else
bb4d2ac2 13172 {
ab273396
AM
13173 ivna.vna_other = BYTE_GET (evna.vna_other);
13174 ivna.vna_next = BYTE_GET (evna.vna_next);
13175 ivna.vna_name = BYTE_GET (evna.vna_name);
13176 }
bb4d2ac2 13177
ab273396
AM
13178 vna_off += ivna.vna_next;
13179 }
13180 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13181
ab273396
AM
13182 if (ivna.vna_other == vers_data)
13183 break;
bb4d2ac2 13184
ab273396
AM
13185 offset += ivn.vn_next;
13186 }
13187 while (ivn.vn_next != 0);
bb4d2ac2 13188
ab273396
AM
13189 if (ivna.vna_other == vers_data)
13190 {
13191 *sym_info = symbol_undefined;
13192 *vna_other = ivna.vna_other;
13193 return (ivna.vna_name < strtab_size
13194 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13195 }
7a815dd5
L
13196 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13197 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13198 return _("<corrupt>");
bb4d2ac2 13199 }
ab273396 13200 return NULL;
bb4d2ac2
L
13201}
13202
047c3dbf
NL
13203/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13204
13205static unsigned int
625d49fc 13206print_dynamic_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13207{
13208 switch (base)
13209 {
13210 case 8:
13211 return print_vma (vma, OCTAL_5);
13212
13213 case 10:
13214 return print_vma (vma, UNSIGNED_5);
13215
13216 case 16:
13217 return print_vma (vma, PREFIX_HEX_5);
13218
13219 case 0:
13220 default:
13221 return print_vma (vma, DEC_5);
13222 }
13223}
13224
10ca4b04 13225static void
26c527e6 13226print_dynamic_symbol (Filedata *filedata, uint64_t si,
10ca4b04
L
13227 Elf_Internal_Sym *symtab,
13228 Elf_Internal_Shdr *section,
13229 char *strtab, size_t strtab_size)
252b5132 13230{
10ca4b04
L
13231 const char *version_string;
13232 enum versioned_symbol_info sym_info;
13233 unsigned short vna_other;
23356397
NC
13234 bool is_valid;
13235 const char * sstr;
10ca4b04 13236 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13237
26c527e6 13238 printf ("%6" PRId64 ": ", si);
10ca4b04
L
13239 print_vma (psym->st_value, LONG_HEX);
13240 putchar (' ');
047c3dbf 13241 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13242 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13243 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13244 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13245 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13246 else
252b5132 13247 {
10ca4b04 13248 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13249
10ca4b04
L
13250 printf (" %-7s", get_symbol_visibility (vis));
13251 /* Check to see if any other bits in the st_other field are set.
13252 Note - displaying this information disrupts the layout of the
13253 table being generated, but for the moment this case is very rare. */
13254 if (psym->st_other ^ vis)
13255 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13256 }
10ca4b04 13257 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13258
23356397
NC
13259 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13260 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13261 && filedata->section_headers != NULL
23356397
NC
13262 && psym->st_name == 0)
13263 {
84714f86
AM
13264 is_valid
13265 = section_name_valid (filedata,
13266 filedata->section_headers + psym->st_shndx);
23356397 13267 sstr = is_valid ?
84714f86
AM
13268 section_name_print (filedata,
13269 filedata->section_headers + psym->st_shndx)
23356397
NC
13270 : _("<corrupt>");
13271 }
13272 else
13273 {
84714f86 13274 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13275 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13276 }
10ca4b04
L
13277
13278 version_string
13279 = get_symbol_version_string (filedata,
13280 (section == NULL
13281 || section->sh_type == SHT_DYNSYM),
13282 strtab, strtab_size, si,
13283 psym, &sym_info, &vna_other);
b9e920ec 13284
0942c7ab
NC
13285 int len_avail = 21;
13286 if (! do_wide && version_string != NULL)
13287 {
ddb43bab 13288 char buffer[16];
0942c7ab 13289
ddb43bab 13290 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13291
13292 if (sym_info == symbol_undefined)
13293 len_avail -= sprintf (buffer," (%d)", vna_other);
13294 else if (sym_info != symbol_hidden)
13295 len_avail -= 1;
13296 }
13297
13298 print_symbol (len_avail, sstr);
b9e920ec 13299
10ca4b04
L
13300 if (version_string)
13301 {
13302 if (sym_info == symbol_undefined)
13303 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13304 else
10ca4b04
L
13305 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13306 version_string);
13307 }
6bd1a22c 13308
10ca4b04 13309 putchar ('\n');
6bd1a22c 13310
10ca4b04
L
13311 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13312 && section != NULL
13313 && si >= section->sh_info
13314 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13315 && filedata->file_header.e_machine != EM_MIPS
13316 /* Solaris binaries have been found to violate this requirement as
13317 well. Not sure if this is a bug or an ABI requirement. */
13318 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
26c527e6 13319 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
10ca4b04
L
13320 si, printable_section_name (filedata, section), section->sh_info);
13321}
f16a9783 13322
0f03783c
NC
13323static const char *
13324get_lto_kind (unsigned int kind)
13325{
13326 switch (kind)
13327 {
13328 case 0: return "DEF";
13329 case 1: return "WEAKDEF";
13330 case 2: return "UNDEF";
13331 case 3: return "WEAKUNDEF";
13332 case 4: return "COMMON";
13333 default:
13334 break;
13335 }
13336
13337 static char buffer[30];
13338 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13339 sprintf (buffer, "<unknown: %u>", kind);
13340 return buffer;
13341}
13342
13343static const char *
13344get_lto_visibility (unsigned int visibility)
13345{
13346 switch (visibility)
13347 {
13348 case 0: return "DEFAULT";
13349 case 1: return "PROTECTED";
13350 case 2: return "INTERNAL";
13351 case 3: return "HIDDEN";
13352 default:
13353 break;
13354 }
13355
13356 static char buffer[30];
13357 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13358 sprintf (buffer, "<unknown: %u>", visibility);
13359 return buffer;
13360}
13361
13362static const char *
13363get_lto_sym_type (unsigned int sym_type)
13364{
13365 switch (sym_type)
13366 {
13367 case 0: return "UNKNOWN";
13368 case 1: return "FUNCTION";
13369 case 2: return "VARIABLE";
13370 default:
13371 break;
13372 }
13373
13374 static char buffer[30];
13375 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13376 sprintf (buffer, "<unknown: %u>", sym_type);
13377 return buffer;
13378}
13379
13380/* Display an LTO format symbol table.
13381 FIXME: The format of LTO symbol tables is not formalized.
13382 So this code could need changing in the future. */
13383
015dc7e1 13384static bool
0f03783c
NC
13385display_lto_symtab (Filedata * filedata,
13386 Elf_Internal_Shdr * section)
13387{
13388 if (section->sh_size == 0)
13389 {
ca0e11aa
NC
13390 if (filedata->is_separate)
13391 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13392 printable_section_name (filedata, section),
13393 filedata->file_name);
13394 else
13395 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13396 printable_section_name (filedata, section));
047c3dbf 13397
015dc7e1 13398 return true;
0f03783c
NC
13399 }
13400
13401 if (section->sh_size > filedata->file_size)
13402 {
26c527e6 13403 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
0f03783c 13404 printable_section_name (filedata, section),
26c527e6 13405 section->sh_size);
015dc7e1 13406 return false;
0f03783c
NC
13407 }
13408
13409 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13410 section->sh_size, 1, _("LTO symbols"));
13411 if (alloced_data == NULL)
015dc7e1 13412 return false;
0f03783c
NC
13413
13414 /* Look for extended data for the symbol table. */
13415 Elf_Internal_Shdr * ext;
13416 void * ext_data_orig = NULL;
13417 char * ext_data = NULL;
13418 char * ext_data_end = NULL;
13419 char * ext_name = NULL;
13420
13421 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13422 (section_name (filedata, section)
13423 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13424 && ext_name != NULL /* Paranoia. */
13425 && (ext = find_section (filedata, ext_name)) != NULL)
13426 {
13427 if (ext->sh_size < 3)
13428 error (_("LTO Symbol extension table '%s' is empty!\n"),
13429 printable_section_name (filedata, ext));
13430 else
13431 {
13432 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13433 ext->sh_size, 1,
13434 _("LTO ext symbol data"));
13435 if (ext_data != NULL)
13436 {
13437 ext_data_end = ext_data + ext->sh_size;
13438 if (* ext_data++ != 1)
13439 error (_("Unexpected version number in symbol extension table\n"));
13440 }
13441 }
13442 }
b9e920ec 13443
0f03783c
NC
13444 const unsigned char * data = (const unsigned char *) alloced_data;
13445 const unsigned char * end = data + section->sh_size;
13446
ca0e11aa
NC
13447 if (filedata->is_separate)
13448 printf (_("\nIn linked file '%s': "), filedata->file_name);
13449 else
13450 printf ("\n");
13451
0f03783c
NC
13452 if (ext_data_orig != NULL)
13453 {
13454 if (do_wide)
ca0e11aa 13455 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13456 printable_section_name (filedata, section),
13457 printable_section_name (filedata, ext));
13458 else
13459 {
ca0e11aa 13460 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13461 printable_section_name (filedata, section));
13462 printf (_(" and extension table '%s' contain:\n"),
13463 printable_section_name (filedata, ext));
13464 }
13465 }
13466 else
ca0e11aa 13467 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13468 printable_section_name (filedata, section));
b9e920ec 13469
0f03783c 13470 /* FIXME: Add a wide version. */
b9e920ec 13471 if (ext_data_orig != NULL)
0f03783c
NC
13472 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13473 else
13474 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13475
13476 /* FIXME: We do not handle style prefixes. */
13477
13478 while (data < end)
13479 {
13480 const unsigned char * sym_name = data;
13481 data += strnlen ((const char *) sym_name, end - data) + 1;
13482 if (data >= end)
13483 goto fail;
13484
13485 const unsigned char * comdat_key = data;
13486 data += strnlen ((const char *) comdat_key, end - data) + 1;
13487 if (data >= end)
13488 goto fail;
13489
13490 if (data + 2 + 8 + 4 > end)
13491 goto fail;
13492
13493 unsigned int kind = *data++;
13494 unsigned int visibility = *data++;
13495
928c411d 13496 uint64_t size = byte_get (data, 8);
0f03783c
NC
13497 data += 8;
13498
928c411d 13499 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13500 data += 4;
13501
13502 if (ext_data != NULL)
13503 {
13504 if (ext_data < (ext_data_end - 1))
13505 {
13506 unsigned int sym_type = * ext_data ++;
13507 unsigned int sec_kind = * ext_data ++;
13508
31e5a3a3 13509 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
13510 * comdat_key == 0 ? "-" : (char *) comdat_key,
13511 get_lto_kind (kind),
13512 get_lto_visibility (visibility),
31e5a3a3
AM
13513 size,
13514 slot,
0f03783c 13515 get_lto_sym_type (sym_type),
31e5a3a3 13516 sec_kind);
0f03783c
NC
13517 print_symbol (6, (const char *) sym_name);
13518 }
13519 else
13520 {
13521 error (_("Ran out of LTO symbol extension data\n"));
13522 ext_data = NULL;
13523 /* FIXME: return FAIL result ? */
13524 }
13525 }
13526 else
13527 {
31e5a3a3 13528 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
13529 * comdat_key == 0 ? "-" : (char *) comdat_key,
13530 get_lto_kind (kind),
13531 get_lto_visibility (visibility),
31e5a3a3
AM
13532 size,
13533 slot);
0f03783c
NC
13534 print_symbol (21, (const char *) sym_name);
13535 }
13536 putchar ('\n');
13537 }
13538
13539 if (ext_data != NULL && ext_data < ext_data_end)
13540 {
13541 error (_("Data remains in the LTO symbol extension table\n"));
13542 goto fail;
13543 }
13544
13545 free (alloced_data);
13546 free (ext_data_orig);
13547 free (ext_name);
015dc7e1 13548 return true;
b9e920ec 13549
0f03783c
NC
13550 fail:
13551 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13552 free (alloced_data);
13553 free (ext_data_orig);
13554 free (ext_name);
015dc7e1 13555 return false;
0f03783c
NC
13556}
13557
13558/* Display LTO symbol tables. */
13559
015dc7e1 13560static bool
0f03783c
NC
13561process_lto_symbol_tables (Filedata * filedata)
13562{
13563 Elf_Internal_Shdr * section;
13564 unsigned int i;
015dc7e1 13565 bool res = true;
0f03783c
NC
13566
13567 if (!do_lto_syms)
015dc7e1 13568 return true;
0f03783c
NC
13569
13570 if (filedata->section_headers == NULL)
015dc7e1 13571 return true;
0f03783c
NC
13572
13573 for (i = 0, section = filedata->section_headers;
13574 i < filedata->file_header.e_shnum;
13575 i++, section++)
84714f86
AM
13576 if (section_name_valid (filedata, section)
13577 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13578 res &= display_lto_symtab (filedata, section);
13579
b9e920ec 13580 return res;
0f03783c
NC
13581}
13582
10ca4b04 13583/* Dump the symbol table. */
0f03783c 13584
015dc7e1 13585static bool
10ca4b04
L
13586process_symbol_table (Filedata * filedata)
13587{
13588 Elf_Internal_Shdr * section;
f16a9783 13589
10ca4b04 13590 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13591 return true;
6bd1a22c 13592
978c4450 13593 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13594 && do_syms
13595 && do_using_dynamic
978c4450
AM
13596 && filedata->dynamic_strings != NULL
13597 && filedata->dynamic_symbols != NULL)
6bd1a22c 13598 {
26c527e6 13599 uint64_t si;
6bd1a22c 13600
ca0e11aa
NC
13601 if (filedata->is_separate)
13602 {
26c527e6
AM
13603 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
13604 " contains %" PRIu64 " entry:\n",
13605 "\nIn linked file '%s' the dynamic symbol table"
13606 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13607 filedata->num_dynamic_syms),
13608 filedata->file_name,
13609 filedata->num_dynamic_syms);
13610 }
13611 else
13612 {
26c527e6
AM
13613 printf (ngettext ("\nSymbol table for image contains %" PRIu64
13614 " entry:\n",
13615 "\nSymbol table for image contains %" PRIu64
13616 " entries:\n",
ca0e11aa
NC
13617 filedata->num_dynamic_syms),
13618 filedata->num_dynamic_syms);
13619 }
10ca4b04
L
13620 if (is_32bit_elf)
13621 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13622 else
13623 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13624
978c4450
AM
13625 for (si = 0; si < filedata->num_dynamic_syms; si++)
13626 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13627 filedata->dynamic_strings,
13628 filedata->dynamic_strings_length);
252b5132 13629 }
8b73c356 13630 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13631 && filedata->section_headers != NULL)
252b5132 13632 {
b34976b6 13633 unsigned int i;
252b5132 13634
dda8d76d
NC
13635 for (i = 0, section = filedata->section_headers;
13636 i < filedata->file_header.e_shnum;
252b5132
RH
13637 i++, section++)
13638 {
2cf0635d 13639 char * strtab = NULL;
26c527e6 13640 uint64_t strtab_size = 0;
2cf0635d 13641 Elf_Internal_Sym * symtab;
26c527e6 13642 uint64_t si, num_syms;
252b5132 13643
2c610e4b
L
13644 if ((section->sh_type != SHT_SYMTAB
13645 && section->sh_type != SHT_DYNSYM)
13646 || (!do_syms
13647 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13648 continue;
13649
dd24e3da
NC
13650 if (section->sh_entsize == 0)
13651 {
13652 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13653 printable_section_name (filedata, section));
dd24e3da
NC
13654 continue;
13655 }
13656
d3a49aa8 13657 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13658
13659 if (filedata->is_separate)
26c527e6
AM
13660 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
13661 " contains %" PRIu64 " entry:\n",
13662 "\nIn linked file '%s' symbol section '%s'"
13663 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13664 num_syms),
13665 filedata->file_name,
13666 printable_section_name (filedata, section),
13667 num_syms);
13668 else
26c527e6
AM
13669 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
13670 " entry:\n",
13671 "\nSymbol table '%s' contains %" PRIu64
13672 " entries:\n",
ca0e11aa
NC
13673 num_syms),
13674 printable_section_name (filedata, section),
13675 num_syms);
dd24e3da 13676
f7a99963 13677 if (is_32bit_elf)
ca47b30c 13678 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13679 else
ca47b30c 13680 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13681
4de91c10 13682 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13683 if (symtab == NULL)
13684 continue;
13685
dda8d76d 13686 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13687 {
dda8d76d
NC
13688 strtab = filedata->string_table;
13689 strtab_size = filedata->string_table_length;
c256ffe7 13690 }
dda8d76d 13691 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13692 {
2cf0635d 13693 Elf_Internal_Shdr * string_sec;
252b5132 13694
dda8d76d 13695 string_sec = filedata->section_headers + section->sh_link;
252b5132 13696
dda8d76d 13697 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13698 1, string_sec->sh_size,
13699 _("string table"));
c256ffe7 13700 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13701 }
13702
10ca4b04
L
13703 for (si = 0; si < num_syms; si++)
13704 print_dynamic_symbol (filedata, si, symtab, section,
13705 strtab, strtab_size);
252b5132
RH
13706
13707 free (symtab);
dda8d76d 13708 if (strtab != filedata->string_table)
252b5132
RH
13709 free (strtab);
13710 }
13711 }
13712 else if (do_syms)
13713 printf
13714 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13715
978c4450 13716 if (do_histogram && filedata->buckets != NULL)
252b5132 13717 {
26c527e6
AM
13718 uint64_t *lengths;
13719 uint64_t *counts;
13720 uint64_t hn;
625d49fc 13721 uint64_t si;
26c527e6
AM
13722 uint64_t maxlength = 0;
13723 uint64_t nzero_counts = 0;
13724 uint64_t nsyms = 0;
6bd6a03d 13725 char *visited;
252b5132 13726
d3a49aa8 13727 printf (ngettext ("\nHistogram for bucket list length "
26c527e6 13728 "(total of %" PRIu64 " bucket):\n",
d3a49aa8 13729 "\nHistogram for bucket list length "
26c527e6
AM
13730 "(total of %" PRIu64 " buckets):\n",
13731 filedata->nbuckets),
13732 filedata->nbuckets);
252b5132 13733
26c527e6 13734 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
252b5132
RH
13735 if (lengths == NULL)
13736 {
8b73c356 13737 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13738 goto err_out;
252b5132 13739 }
978c4450
AM
13740 visited = xcmalloc (filedata->nchains, 1);
13741 memset (visited, 0, filedata->nchains);
8b73c356
NC
13742
13743 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13744 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13745 {
978c4450 13746 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13747 {
b34976b6 13748 ++nsyms;
252b5132 13749 if (maxlength < ++lengths[hn])
b34976b6 13750 ++maxlength;
978c4450 13751 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13752 {
13753 error (_("histogram chain is corrupt\n"));
13754 break;
13755 }
13756 visited[si] = 1;
252b5132
RH
13757 }
13758 }
6bd6a03d 13759 free (visited);
252b5132 13760
26c527e6 13761 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13762 if (counts == NULL)
13763 {
b2e951ec 13764 free (lengths);
8b73c356 13765 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13766 goto err_out;
252b5132
RH
13767 }
13768
978c4450 13769 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13770 ++counts[lengths[hn]];
252b5132 13771
978c4450 13772 if (filedata->nbuckets > 0)
252b5132 13773 {
26c527e6
AM
13774 uint64_t i;
13775 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 13776 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13777 for (i = 1; i <= maxlength; ++i)
103f02d3 13778 {
66543521 13779 nzero_counts += counts[i] * i;
26c527e6 13780 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 13781 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13782 (nzero_counts * 100.0) / nsyms);
13783 }
252b5132
RH
13784 }
13785
13786 free (counts);
13787 free (lengths);
13788 }
13789
978c4450
AM
13790 free (filedata->buckets);
13791 filedata->buckets = NULL;
13792 filedata->nbuckets = 0;
13793 free (filedata->chains);
13794 filedata->chains = NULL;
252b5132 13795
978c4450 13796 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13797 {
26c527e6
AM
13798 uint64_t *lengths;
13799 uint64_t *counts;
13800 uint64_t hn;
13801 uint64_t maxlength = 0;
13802 uint64_t nzero_counts = 0;
13803 uint64_t nsyms = 0;
fdc90cb4 13804
f16a9783 13805 printf (ngettext ("\nHistogram for `%s' bucket list length "
26c527e6 13806 "(total of %" PRIu64 " bucket):\n",
f16a9783 13807 "\nHistogram for `%s' bucket list length "
26c527e6
AM
13808 "(total of %" PRIu64 " buckets):\n",
13809 filedata->ngnubuckets),
978c4450 13810 GNU_HASH_SECTION_NAME (filedata),
26c527e6 13811 filedata->ngnubuckets);
8b73c356 13812
26c527e6 13813 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
13814 if (lengths == NULL)
13815 {
8b73c356 13816 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13817 goto err_out;
fdc90cb4
JJ
13818 }
13819
fdc90cb4
JJ
13820 printf (_(" Length Number %% of total Coverage\n"));
13821
978c4450
AM
13822 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13823 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 13824 {
625d49fc 13825 uint64_t off, length = 1;
fdc90cb4 13826
978c4450 13827 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13828 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13829 off < filedata->ngnuchains
13830 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13831 ++off)
fdc90cb4
JJ
13832 ++length;
13833 lengths[hn] = length;
13834 if (length > maxlength)
13835 maxlength = length;
13836 nsyms += length;
13837 }
13838
26c527e6 13839 counts = calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13840 if (counts == NULL)
13841 {
b2e951ec 13842 free (lengths);
8b73c356 13843 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13844 goto err_out;
fdc90cb4
JJ
13845 }
13846
978c4450 13847 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13848 ++counts[lengths[hn]];
13849
978c4450 13850 if (filedata->ngnubuckets > 0)
fdc90cb4 13851 {
26c527e6
AM
13852 uint64_t j;
13853 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 13854 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13855 for (j = 1; j <= maxlength; ++j)
13856 {
13857 nzero_counts += counts[j] * j;
26c527e6 13858 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 13859 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13860 (nzero_counts * 100.0) / nsyms);
13861 }
13862 }
13863
13864 free (counts);
13865 free (lengths);
fdc90cb4 13866 }
978c4450
AM
13867 free (filedata->gnubuckets);
13868 filedata->gnubuckets = NULL;
13869 filedata->ngnubuckets = 0;
13870 free (filedata->gnuchains);
13871 filedata->gnuchains = NULL;
13872 filedata->ngnuchains = 0;
13873 free (filedata->mipsxlat);
13874 filedata->mipsxlat = NULL;
015dc7e1 13875 return true;
fd486f32
AM
13876
13877 err_out:
978c4450
AM
13878 free (filedata->gnubuckets);
13879 filedata->gnubuckets = NULL;
13880 filedata->ngnubuckets = 0;
13881 free (filedata->gnuchains);
13882 filedata->gnuchains = NULL;
13883 filedata->ngnuchains = 0;
13884 free (filedata->mipsxlat);
13885 filedata->mipsxlat = NULL;
13886 free (filedata->buckets);
13887 filedata->buckets = NULL;
13888 filedata->nbuckets = 0;
13889 free (filedata->chains);
13890 filedata->chains = NULL;
015dc7e1 13891 return false;
252b5132
RH
13892}
13893
015dc7e1 13894static bool
ca0e11aa 13895process_syminfo (Filedata * filedata)
252b5132 13896{
b4c96d0d 13897 unsigned int i;
252b5132 13898
978c4450 13899 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13900 || !do_dynamic)
13901 /* No syminfo, this is ok. */
015dc7e1 13902 return true;
252b5132
RH
13903
13904 /* There better should be a dynamic symbol section. */
978c4450 13905 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13906 return false;
252b5132 13907
ca0e11aa 13908 if (filedata->is_separate)
26c527e6
AM
13909 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
13910 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
ca0e11aa
NC
13911 filedata->dynamic_syminfo_nent),
13912 filedata->file_name,
13913 filedata->dynamic_syminfo_offset,
13914 filedata->dynamic_syminfo_nent);
13915 else
26c527e6
AM
13916 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
13917 " contains %d entry:\n",
13918 "\nDynamic info segment at offset %#" PRIx64
13919 " contains %d entries:\n",
978c4450 13920 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13921 filedata->dynamic_syminfo_offset,
13922 filedata->dynamic_syminfo_nent);
252b5132
RH
13923
13924 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13925 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13926 {
978c4450 13927 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13928
31104126 13929 printf ("%4d: ", i);
978c4450 13930 if (i >= filedata->num_dynamic_syms)
4082ef84 13931 printf (_("<corrupt index>"));
84714f86
AM
13932 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13933 print_symbol (30, get_dynamic_name (filedata,
978c4450 13934 filedata->dynamic_symbols[i].st_name));
d79b3d50 13935 else
978c4450 13936 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13937 putchar (' ');
252b5132 13938
978c4450 13939 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13940 {
13941 case SYMINFO_BT_SELF:
13942 fputs ("SELF ", stdout);
13943 break;
13944 case SYMINFO_BT_PARENT:
13945 fputs ("PARENT ", stdout);
13946 break;
13947 default:
978c4450
AM
13948 if (filedata->dynamic_syminfo[i].si_boundto > 0
13949 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13950 && valid_dynamic_name (filedata,
978c4450 13951 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13952 {
84714f86 13953 print_symbol (10, get_dynamic_name (filedata,
978c4450 13954 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13955 putchar (' ' );
13956 }
252b5132 13957 else
978c4450 13958 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13959 break;
13960 }
13961
13962 if (flags & SYMINFO_FLG_DIRECT)
13963 printf (" DIRECT");
13964 if (flags & SYMINFO_FLG_PASSTHRU)
13965 printf (" PASSTHRU");
13966 if (flags & SYMINFO_FLG_COPY)
13967 printf (" COPY");
13968 if (flags & SYMINFO_FLG_LAZYLOAD)
13969 printf (" LAZYLOAD");
13970
13971 puts ("");
13972 }
13973
015dc7e1 13974 return true;
252b5132
RH
13975}
13976
75802ccb
CE
13977/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13978 is contained by the region START .. END. The types of ADDR, START
13979 and END should all be the same. Note both ADDR + NELEM and END
13980 point to just beyond the end of the regions that are being tested. */
13981#define IN_RANGE(START,END,ADDR,NELEM) \
13982 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13983
cf13d699
NC
13984/* Check to see if the given reloc needs to be handled in a target specific
13985 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13986 FALSE.
13987
13988 If called with reloc == NULL, then this is a signal that reloc processing
13989 for the current section has finished, and any saved state should be
13990 discarded. */
09c11c86 13991
015dc7e1 13992static bool
26c527e6
AM
13993target_specific_reloc_handling (Filedata *filedata,
13994 Elf_Internal_Rela *reloc,
13995 unsigned char *start,
13996 unsigned char *end,
13997 Elf_Internal_Sym *symtab,
13998 uint64_t num_syms)
252b5132 13999{
f84ce13b 14000 unsigned int reloc_type = 0;
26c527e6 14001 uint64_t sym_index = 0;
f84ce13b
NC
14002
14003 if (reloc)
14004 {
dda8d76d 14005 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
14006 sym_index = get_reloc_symindex (reloc->r_info);
14007 }
252b5132 14008
dda8d76d 14009 switch (filedata->file_header.e_machine)
252b5132 14010 {
13761a11
NC
14011 case EM_MSP430:
14012 case EM_MSP430_OLD:
14013 {
14014 static Elf_Internal_Sym * saved_sym = NULL;
14015
f84ce13b
NC
14016 if (reloc == NULL)
14017 {
14018 saved_sym = NULL;
015dc7e1 14019 return true;
f84ce13b
NC
14020 }
14021
13761a11
NC
14022 switch (reloc_type)
14023 {
14024 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 14025 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 14026 if (uses_msp430x_relocs (filedata))
13761a11 14027 break;
1a0670f3 14028 /* Fall through. */
13761a11 14029 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 14030 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
14031 /* PR 21139. */
14032 if (sym_index >= num_syms)
26c527e6
AM
14033 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index"
14034 " %" PRIu64 "\n"), sym_index);
f84ce13b
NC
14035 else
14036 saved_sym = symtab + sym_index;
015dc7e1 14037 return true;
13761a11
NC
14038
14039 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14040 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14041 goto handle_sym_diff;
0b4362b0 14042
13761a11
NC
14043 case 5: /* R_MSP430_16_BYTE */
14044 case 9: /* R_MSP430_8 */
7d81bc93 14045 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 14046 if (uses_msp430x_relocs (filedata))
13761a11
NC
14047 break;
14048 goto handle_sym_diff;
14049
14050 case 2: /* R_MSP430_ABS16 */
14051 case 15: /* R_MSP430X_ABS16 */
7d81bc93 14052 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 14053 if (! uses_msp430x_relocs (filedata))
13761a11
NC
14054 break;
14055 goto handle_sym_diff;
0b4362b0 14056
13761a11
NC
14057 handle_sym_diff:
14058 if (saved_sym != NULL)
14059 {
625d49fc 14060 uint64_t value;
5a805384 14061 unsigned int reloc_size = 0;
7d81bc93
JL
14062 int leb_ret = 0;
14063 switch (reloc_type)
14064 {
14065 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14066 reloc_size = 4;
14067 break;
14068 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14069 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14070 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14071 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14072 &reloc_size, &leb_ret);
7d81bc93
JL
14073 break;
14074 default:
14075 reloc_size = 2;
14076 break;
14077 }
13761a11 14078
5a805384 14079 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
14080 error (_("MSP430 ULEB128 field at %#" PRIx64
14081 " contains invalid ULEB128 value\n"),
14082 reloc->r_offset);
7d81bc93 14083 else if (sym_index >= num_syms)
26c527e6
AM
14084 error (_("MSP430 reloc contains invalid symbol index "
14085 "%" PRIu64 "\n"),
f84ce13b 14086 sym_index);
03f7786e 14087 else
f84ce13b
NC
14088 {
14089 value = reloc->r_addend + (symtab[sym_index].st_value
14090 - saved_sym->st_value);
14091
b32e566b 14092 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14093 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14094 else
14095 /* PR 21137 */
26c527e6
AM
14096 error (_("MSP430 sym diff reloc contains invalid offset: "
14097 "%#" PRIx64 "\n"),
14098 reloc->r_offset);
f84ce13b 14099 }
13761a11
NC
14100
14101 saved_sym = NULL;
015dc7e1 14102 return true;
13761a11
NC
14103 }
14104 break;
14105
14106 default:
14107 if (saved_sym != NULL)
071436c6 14108 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14109 break;
14110 }
14111 break;
14112 }
14113
cf13d699
NC
14114 case EM_MN10300:
14115 case EM_CYGNUS_MN10300:
14116 {
14117 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14118
f84ce13b
NC
14119 if (reloc == NULL)
14120 {
14121 saved_sym = NULL;
015dc7e1 14122 return true;
f84ce13b
NC
14123 }
14124
cf13d699
NC
14125 switch (reloc_type)
14126 {
14127 case 34: /* R_MN10300_ALIGN */
015dc7e1 14128 return true;
cf13d699 14129 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 14130 if (sym_index >= num_syms)
26c527e6
AM
14131 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index "
14132 "%" PRIu64 "\n"),
f84ce13b
NC
14133 sym_index);
14134 else
14135 saved_sym = symtab + sym_index;
015dc7e1 14136 return true;
f84ce13b 14137
cf13d699
NC
14138 case 1: /* R_MN10300_32 */
14139 case 2: /* R_MN10300_16 */
14140 if (saved_sym != NULL)
14141 {
03f7786e 14142 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14143 uint64_t value;
252b5132 14144
f84ce13b 14145 if (sym_index >= num_syms)
26c527e6
AM
14146 error (_("MN10300 reloc contains invalid symbol index "
14147 "%" PRIu64 "\n"),
f84ce13b 14148 sym_index);
03f7786e 14149 else
f84ce13b
NC
14150 {
14151 value = reloc->r_addend + (symtab[sym_index].st_value
14152 - saved_sym->st_value);
14153
b32e566b 14154 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14155 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 14156 else
26c527e6
AM
14157 error (_("MN10300 sym diff reloc contains invalid offset:"
14158 " %#" PRIx64 "\n"),
14159 reloc->r_offset);
f84ce13b 14160 }
252b5132 14161
cf13d699 14162 saved_sym = NULL;
015dc7e1 14163 return true;
cf13d699
NC
14164 }
14165 break;
14166 default:
14167 if (saved_sym != NULL)
071436c6 14168 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14169 break;
14170 }
14171 break;
14172 }
6ff71e76
NC
14173
14174 case EM_RL78:
14175 {
625d49fc
AM
14176 static uint64_t saved_sym1 = 0;
14177 static uint64_t saved_sym2 = 0;
14178 static uint64_t value;
6ff71e76 14179
f84ce13b
NC
14180 if (reloc == NULL)
14181 {
14182 saved_sym1 = saved_sym2 = 0;
015dc7e1 14183 return true;
f84ce13b
NC
14184 }
14185
6ff71e76
NC
14186 switch (reloc_type)
14187 {
14188 case 0x80: /* R_RL78_SYM. */
14189 saved_sym1 = saved_sym2;
f84ce13b 14190 if (sym_index >= num_syms)
26c527e6
AM
14191 error (_("RL78_SYM reloc contains invalid symbol index "
14192 "%" PRIu64 "\n"), sym_index);
f84ce13b
NC
14193 else
14194 {
14195 saved_sym2 = symtab[sym_index].st_value;
14196 saved_sym2 += reloc->r_addend;
14197 }
015dc7e1 14198 return true;
6ff71e76
NC
14199
14200 case 0x83: /* R_RL78_OPsub. */
14201 value = saved_sym1 - saved_sym2;
14202 saved_sym2 = saved_sym1 = 0;
015dc7e1 14203 return true;
6ff71e76
NC
14204 break;
14205
14206 case 0x41: /* R_RL78_ABS32. */
b32e566b 14207 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14208 byte_put (start + reloc->r_offset, value, 4);
b32e566b 14209 else
26c527e6
AM
14210 error (_("RL78 sym diff reloc contains invalid offset: "
14211 "%#" PRIx64 "\n"),
14212 reloc->r_offset);
6ff71e76 14213 value = 0;
015dc7e1 14214 return true;
6ff71e76
NC
14215
14216 case 0x43: /* R_RL78_ABS16. */
b32e566b 14217 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14218 byte_put (start + reloc->r_offset, value, 2);
b32e566b 14219 else
26c527e6
AM
14220 error (_("RL78 sym diff reloc contains invalid offset: "
14221 "%#" PRIx64 "\n"),
14222 reloc->r_offset);
6ff71e76 14223 value = 0;
015dc7e1 14224 return true;
6ff71e76
NC
14225
14226 default:
14227 break;
14228 }
14229 break;
14230 }
252b5132
RH
14231 }
14232
015dc7e1 14233 return false;
252b5132
RH
14234}
14235
aca88567
NC
14236/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14237 DWARF debug sections. This is a target specific test. Note - we do not
14238 go through the whole including-target-headers-multiple-times route, (as
14239 we have already done with <elf/h8.h>) because this would become very
14240 messy and even then this function would have to contain target specific
14241 information (the names of the relocs instead of their numeric values).
14242 FIXME: This is not the correct way to solve this problem. The proper way
14243 is to have target specific reloc sizing and typing functions created by
14244 the reloc-macros.h header, in the same way that it already creates the
14245 reloc naming functions. */
14246
015dc7e1 14247static bool
dda8d76d 14248is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14249{
d347c9df 14250 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14251 switch (filedata->file_header.e_machine)
aca88567 14252 {
41e92641 14253 case EM_386:
22abe556 14254 case EM_IAMCU:
41e92641 14255 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14256 case EM_68K:
14257 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14258 case EM_860:
14259 return reloc_type == 1; /* R_860_32. */
14260 case EM_960:
14261 return reloc_type == 2; /* R_960_32. */
a06ea964 14262 case EM_AARCH64:
9282b95a
JW
14263 return (reloc_type == 258
14264 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14265 case EM_BPF:
14266 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14267 case EM_ADAPTEVA_EPIPHANY:
14268 return reloc_type == 3;
aca88567 14269 case EM_ALPHA:
137b6b5f 14270 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14271 case EM_ARC:
14272 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14273 case EM_ARC_COMPACT:
14274 case EM_ARC_COMPACT2:
14275 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14276 case EM_ARM:
14277 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14278 case EM_AVR_OLD:
aca88567
NC
14279 case EM_AVR:
14280 return reloc_type == 1;
14281 case EM_BLACKFIN:
14282 return reloc_type == 0x12; /* R_byte4_data. */
14283 case EM_CRIS:
14284 return reloc_type == 3; /* R_CRIS_32. */
14285 case EM_CR16:
14286 return reloc_type == 3; /* R_CR16_NUM32. */
14287 case EM_CRX:
14288 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14289 case EM_CSKY:
14290 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14291 case EM_CYGNUS_FRV:
14292 return reloc_type == 1;
41e92641
NC
14293 case EM_CYGNUS_D10V:
14294 case EM_D10V:
14295 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14296 case EM_CYGNUS_D30V:
14297 case EM_D30V:
14298 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14299 case EM_DLX:
14300 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14301 case EM_CYGNUS_FR30:
14302 case EM_FR30:
14303 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14304 case EM_FT32:
14305 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14306 case EM_H8S:
14307 case EM_H8_300:
14308 case EM_H8_300H:
14309 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14310 case EM_IA_64:
262cdac7
AM
14311 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14312 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14313 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14314 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14315 case EM_IP2K_OLD:
14316 case EM_IP2K:
14317 return reloc_type == 2; /* R_IP2K_32. */
14318 case EM_IQ2000:
14319 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14320 case EM_LATTICEMICO32:
14321 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14322 case EM_LOONGARCH:
14323 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14324 case EM_M32C_OLD:
aca88567
NC
14325 case EM_M32C:
14326 return reloc_type == 3; /* R_M32C_32. */
14327 case EM_M32R:
14328 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14329 case EM_68HC11:
14330 case EM_68HC12:
14331 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14332 case EM_S12Z:
2849d19f
JD
14333 return reloc_type == 7 || /* R_S12Z_EXT32 */
14334 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14335 case EM_MCORE:
14336 return reloc_type == 1; /* R_MCORE_ADDR32. */
14337 case EM_CYGNUS_MEP:
14338 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14339 case EM_METAG:
14340 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14341 case EM_MICROBLAZE:
14342 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14343 case EM_MIPS:
14344 return reloc_type == 2; /* R_MIPS_32. */
14345 case EM_MMIX:
14346 return reloc_type == 4; /* R_MMIX_32. */
14347 case EM_CYGNUS_MN10200:
14348 case EM_MN10200:
14349 return reloc_type == 1; /* R_MN10200_32. */
14350 case EM_CYGNUS_MN10300:
14351 case EM_MN10300:
14352 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14353 case EM_MOXIE:
14354 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14355 case EM_MSP430_OLD:
14356 case EM_MSP430:
13761a11 14357 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14358 case EM_MT:
14359 return reloc_type == 2; /* R_MT_32. */
35c08157 14360 case EM_NDS32:
81c5e376 14361 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14362 case EM_ALTERA_NIOS2:
36591ba1 14363 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14364 case EM_NIOS32:
14365 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14366 case EM_OR1K:
14367 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14368 case EM_PARISC:
9abca702 14369 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14370 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14371 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14372 case EM_PJ:
14373 case EM_PJ_OLD:
14374 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14375 case EM_PPC64:
14376 return reloc_type == 1; /* R_PPC64_ADDR32. */
14377 case EM_PPC:
14378 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14379 case EM_TI_PRU:
14380 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14381 case EM_RISCV:
14382 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14383 case EM_RL78:
14384 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14385 case EM_RX:
14386 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14387 case EM_S370:
14388 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14389 case EM_S390_OLD:
14390 case EM_S390:
14391 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14392 case EM_SCORE:
14393 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14394 case EM_SH:
14395 return reloc_type == 1; /* R_SH_DIR32. */
14396 case EM_SPARC32PLUS:
14397 case EM_SPARCV9:
14398 case EM_SPARC:
14399 return reloc_type == 3 /* R_SPARC_32. */
14400 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14401 case EM_SPU:
14402 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14403 case EM_TI_C6000:
14404 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14405 case EM_TILEGX:
14406 return reloc_type == 2; /* R_TILEGX_32. */
14407 case EM_TILEPRO:
14408 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14409 case EM_CYGNUS_V850:
14410 case EM_V850:
14411 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14412 case EM_V800:
14413 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14414 case EM_VAX:
14415 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14416 case EM_VISIUM:
14417 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14418 case EM_WEBASSEMBLY:
14419 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14420 case EM_X86_64:
8a9036a4 14421 case EM_L1OM:
7a9068fe 14422 case EM_K1OM:
aca88567 14423 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14424 case EM_XGATE:
14425 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14426 case EM_XSTORMY16:
14427 return reloc_type == 1; /* R_XSTROMY16_32. */
14428 case EM_XTENSA_OLD:
14429 case EM_XTENSA:
14430 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14431 case EM_Z80:
14432 return reloc_type == 6; /* R_Z80_32. */
aca88567 14433 default:
bee0ee85
NC
14434 {
14435 static unsigned int prev_warn = 0;
14436
14437 /* Avoid repeating the same warning multiple times. */
dda8d76d 14438 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14439 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14440 filedata->file_header.e_machine);
14441 prev_warn = filedata->file_header.e_machine;
015dc7e1 14442 return false;
bee0ee85 14443 }
aca88567
NC
14444 }
14445}
14446
14447/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14448 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14449
015dc7e1 14450static bool
dda8d76d 14451is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14452{
dda8d76d 14453 switch (filedata->file_header.e_machine)
d347c9df 14454 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14455 {
41e92641 14456 case EM_386:
22abe556 14457 case EM_IAMCU:
3e0873ac 14458 return reloc_type == 2; /* R_386_PC32. */
aca88567 14459 case EM_68K:
3e0873ac 14460 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14461 case EM_AARCH64:
14462 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14463 case EM_ADAPTEVA_EPIPHANY:
14464 return reloc_type == 6;
aca88567
NC
14465 case EM_ALPHA:
14466 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14467 case EM_ARC_COMPACT:
14468 case EM_ARC_COMPACT2:
14469 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14470 case EM_ARM:
3e0873ac 14471 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14472 case EM_AVR_OLD:
14473 case EM_AVR:
14474 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14475 case EM_LOONGARCH:
14476 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14477 case EM_MICROBLAZE:
14478 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14479 case EM_OR1K:
14480 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14481 case EM_PARISC:
85acf597 14482 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14483 case EM_PPC:
14484 return reloc_type == 26; /* R_PPC_REL32. */
14485 case EM_PPC64:
3e0873ac 14486 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14487 case EM_RISCV:
14488 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14489 case EM_S390_OLD:
14490 case EM_S390:
3e0873ac 14491 return reloc_type == 5; /* R_390_PC32. */
aca88567 14492 case EM_SH:
3e0873ac 14493 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14494 case EM_SPARC32PLUS:
14495 case EM_SPARCV9:
14496 case EM_SPARC:
3e0873ac 14497 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14498 case EM_SPU:
14499 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14500 case EM_TILEGX:
14501 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14502 case EM_TILEPRO:
14503 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14504 case EM_VISIUM:
14505 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14506 case EM_X86_64:
8a9036a4 14507 case EM_L1OM:
7a9068fe 14508 case EM_K1OM:
3e0873ac 14509 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14510 case EM_VAX:
14511 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14512 case EM_XTENSA_OLD:
14513 case EM_XTENSA:
14514 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14515 default:
14516 /* Do not abort or issue an error message here. Not all targets use
14517 pc-relative 32-bit relocs in their DWARF debug information and we
14518 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14519 more helpful warning message will be generated by apply_relocations
14520 anyway, so just return. */
015dc7e1 14521 return false;
aca88567
NC
14522 }
14523}
14524
14525/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14526 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14527
015dc7e1 14528static bool
dda8d76d 14529is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14530{
dda8d76d 14531 switch (filedata->file_header.e_machine)
aca88567 14532 {
a06ea964
NC
14533 case EM_AARCH64:
14534 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14535 case EM_ALPHA:
14536 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14537 case EM_IA_64:
262cdac7
AM
14538 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14539 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14540 case EM_LOONGARCH:
14541 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14542 case EM_PARISC:
14543 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14544 case EM_PPC64:
14545 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14546 case EM_RISCV:
14547 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14548 case EM_SPARC32PLUS:
14549 case EM_SPARCV9:
14550 case EM_SPARC:
714da62f
NC
14551 return reloc_type == 32 /* R_SPARC_64. */
14552 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14553 case EM_X86_64:
8a9036a4 14554 case EM_L1OM:
7a9068fe 14555 case EM_K1OM:
aca88567 14556 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14557 case EM_S390_OLD:
14558 case EM_S390:
aa137e4d
NC
14559 return reloc_type == 22; /* R_S390_64. */
14560 case EM_TILEGX:
14561 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14562 case EM_MIPS:
aa137e4d 14563 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14564 default:
015dc7e1 14565 return false;
aca88567
NC
14566 }
14567}
14568
85acf597
RH
14569/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14570 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14571
015dc7e1 14572static bool
dda8d76d 14573is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14574{
dda8d76d 14575 switch (filedata->file_header.e_machine)
85acf597 14576 {
a06ea964
NC
14577 case EM_AARCH64:
14578 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14579 case EM_ALPHA:
aa137e4d 14580 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14581 case EM_IA_64:
262cdac7
AM
14582 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14583 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14584 case EM_PARISC:
aa137e4d 14585 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14586 case EM_PPC64:
aa137e4d 14587 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14588 case EM_SPARC32PLUS:
14589 case EM_SPARCV9:
14590 case EM_SPARC:
aa137e4d 14591 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14592 case EM_X86_64:
8a9036a4 14593 case EM_L1OM:
7a9068fe 14594 case EM_K1OM:
aa137e4d 14595 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14596 case EM_S390_OLD:
14597 case EM_S390:
aa137e4d
NC
14598 return reloc_type == 23; /* R_S390_PC64. */
14599 case EM_TILEGX:
14600 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14601 default:
015dc7e1 14602 return false;
85acf597
RH
14603 }
14604}
14605
4dc3c23d
AM
14606/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14607 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14608
015dc7e1 14609static bool
dda8d76d 14610is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14611{
dda8d76d 14612 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14613 {
14614 case EM_CYGNUS_MN10200:
14615 case EM_MN10200:
14616 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14617 case EM_FT32:
14618 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14619 case EM_Z80:
14620 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14621 default:
015dc7e1 14622 return false;
4dc3c23d
AM
14623 }
14624}
14625
aca88567
NC
14626/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14627 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14628
015dc7e1 14629static bool
dda8d76d 14630is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14631{
d347c9df 14632 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14633 switch (filedata->file_header.e_machine)
4b78141a 14634 {
886a2506
NC
14635 case EM_ARC:
14636 case EM_ARC_COMPACT:
14637 case EM_ARC_COMPACT2:
14638 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14639 case EM_ADAPTEVA_EPIPHANY:
14640 return reloc_type == 5;
aca88567
NC
14641 case EM_AVR_OLD:
14642 case EM_AVR:
14643 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14644 case EM_CYGNUS_D10V:
14645 case EM_D10V:
14646 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14647 case EM_FT32:
14648 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14649 case EM_H8S:
14650 case EM_H8_300:
14651 case EM_H8_300H:
aca88567
NC
14652 return reloc_type == R_H8_DIR16;
14653 case EM_IP2K_OLD:
14654 case EM_IP2K:
14655 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14656 case EM_M32C_OLD:
f4236fe4
DD
14657 case EM_M32C:
14658 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14659 case EM_CYGNUS_MN10200:
14660 case EM_MN10200:
14661 return reloc_type == 2; /* R_MN10200_16. */
14662 case EM_CYGNUS_MN10300:
14663 case EM_MN10300:
14664 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14665 case EM_MSP430:
dda8d76d 14666 if (uses_msp430x_relocs (filedata))
13761a11 14667 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14668 /* Fall through. */
78c8d46c 14669 case EM_MSP430_OLD:
aca88567 14670 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 14671 case EM_NDS32:
81c5e376 14672 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 14673 case EM_ALTERA_NIOS2:
36591ba1 14674 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14675 case EM_NIOS32:
14676 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14677 case EM_OR1K:
14678 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14679 case EM_RISCV:
14680 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14681 case EM_TI_PRU:
14682 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14683 case EM_TI_C6000:
14684 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14685 case EM_VISIUM:
14686 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
14687 case EM_XGATE:
14688 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14689 case EM_Z80:
14690 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14691 default:
015dc7e1 14692 return false;
4b78141a
NC
14693 }
14694}
14695
39e07931
AS
14696/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14697 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14698
015dc7e1 14699static bool
39e07931
AS
14700is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14701{
14702 switch (filedata->file_header.e_machine)
14703 {
14704 case EM_RISCV:
14705 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14706 case EM_Z80:
14707 return reloc_type == 1; /* R_Z80_8. */
39e07931 14708 default:
015dc7e1 14709 return false;
39e07931
AS
14710 }
14711}
14712
14713/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14714 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14715
015dc7e1 14716static bool
39e07931
AS
14717is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14718{
14719 switch (filedata->file_header.e_machine)
14720 {
14721 case EM_RISCV:
14722 return reloc_type == 53; /* R_RISCV_SET6. */
14723 default:
015dc7e1 14724 return false;
39e07931
AS
14725 }
14726}
14727
03336641
JW
14728/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14729 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14730
015dc7e1 14731static bool
03336641
JW
14732is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14733{
14734 /* Please keep this table alpha-sorted for ease of visual lookup. */
14735 switch (filedata->file_header.e_machine)
14736 {
14737 case EM_RISCV:
14738 return reloc_type == 35; /* R_RISCV_ADD32. */
14739 default:
015dc7e1 14740 return false;
03336641
JW
14741 }
14742}
14743
14744/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14745 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14746
015dc7e1 14747static bool
03336641
JW
14748is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14749{
14750 /* Please keep this table alpha-sorted for ease of visual lookup. */
14751 switch (filedata->file_header.e_machine)
14752 {
14753 case EM_RISCV:
14754 return reloc_type == 39; /* R_RISCV_SUB32. */
14755 default:
015dc7e1 14756 return false;
03336641
JW
14757 }
14758}
14759
14760/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14761 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14762
015dc7e1 14763static bool
03336641
JW
14764is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14765{
14766 /* Please keep this table alpha-sorted for ease of visual lookup. */
14767 switch (filedata->file_header.e_machine)
14768 {
14769 case EM_RISCV:
14770 return reloc_type == 36; /* R_RISCV_ADD64. */
14771 default:
015dc7e1 14772 return false;
03336641
JW
14773 }
14774}
14775
14776/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14777 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14778
015dc7e1 14779static bool
03336641
JW
14780is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14781{
14782 /* Please keep this table alpha-sorted for ease of visual lookup. */
14783 switch (filedata->file_header.e_machine)
14784 {
14785 case EM_RISCV:
14786 return reloc_type == 40; /* R_RISCV_SUB64. */
14787 default:
015dc7e1 14788 return false;
03336641
JW
14789 }
14790}
14791
14792/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14793 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14794
015dc7e1 14795static bool
03336641
JW
14796is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14797{
14798 /* Please keep this table alpha-sorted for ease of visual lookup. */
14799 switch (filedata->file_header.e_machine)
14800 {
14801 case EM_RISCV:
14802 return reloc_type == 34; /* R_RISCV_ADD16. */
14803 default:
015dc7e1 14804 return false;
03336641
JW
14805 }
14806}
14807
14808/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14809 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14810
015dc7e1 14811static bool
03336641
JW
14812is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14813{
14814 /* Please keep this table alpha-sorted for ease of visual lookup. */
14815 switch (filedata->file_header.e_machine)
14816 {
14817 case EM_RISCV:
14818 return reloc_type == 38; /* R_RISCV_SUB16. */
14819 default:
015dc7e1 14820 return false;
03336641
JW
14821 }
14822}
14823
14824/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14825 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14826
015dc7e1 14827static bool
03336641
JW
14828is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14829{
14830 /* Please keep this table alpha-sorted for ease of visual lookup. */
14831 switch (filedata->file_header.e_machine)
14832 {
14833 case EM_RISCV:
14834 return reloc_type == 33; /* R_RISCV_ADD8. */
14835 default:
015dc7e1 14836 return false;
03336641
JW
14837 }
14838}
14839
14840/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14841 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14842
015dc7e1 14843static bool
03336641
JW
14844is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14845{
14846 /* Please keep this table alpha-sorted for ease of visual lookup. */
14847 switch (filedata->file_header.e_machine)
14848 {
14849 case EM_RISCV:
14850 return reloc_type == 37; /* R_RISCV_SUB8. */
14851 default:
015dc7e1 14852 return false;
03336641
JW
14853 }
14854}
14855
39e07931
AS
14856/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14857 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14858
015dc7e1 14859static bool
39e07931
AS
14860is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14861{
14862 switch (filedata->file_header.e_machine)
14863 {
14864 case EM_RISCV:
14865 return reloc_type == 52; /* R_RISCV_SUB6. */
14866 default:
015dc7e1 14867 return false;
39e07931
AS
14868 }
14869}
14870
2a7b2e88
JK
14871/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14872 relocation entries (possibly formerly used for SHT_GROUP sections). */
14873
015dc7e1 14874static bool
dda8d76d 14875is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14876{
dda8d76d 14877 switch (filedata->file_header.e_machine)
2a7b2e88 14878 {
cb8f3167 14879 case EM_386: /* R_386_NONE. */
d347c9df 14880 case EM_68K: /* R_68K_NONE. */
cfb8c092 14881 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14882 case EM_ALPHA: /* R_ALPHA_NONE. */
14883 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14884 case EM_ARC: /* R_ARC_NONE. */
886a2506 14885 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14886 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14887 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 14888 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14889 case EM_FT32: /* R_FT32_NONE. */
14890 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14891 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14892 case EM_L1OM: /* R_X86_64_NONE. */
14893 case EM_M32R: /* R_M32R_NONE. */
14894 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14895 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14896 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14897 case EM_NIOS32: /* R_NIOS_NONE. */
14898 case EM_OR1K: /* R_OR1K_NONE. */
14899 case EM_PARISC: /* R_PARISC_NONE. */
14900 case EM_PPC64: /* R_PPC64_NONE. */
14901 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14902 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14903 case EM_S390: /* R_390_NONE. */
14904 case EM_S390_OLD:
14905 case EM_SH: /* R_SH_NONE. */
14906 case EM_SPARC32PLUS:
14907 case EM_SPARC: /* R_SPARC_NONE. */
14908 case EM_SPARCV9:
aa137e4d
NC
14909 case EM_TILEGX: /* R_TILEGX_NONE. */
14910 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14911 case EM_TI_C6000:/* R_C6000_NONE. */
14912 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 14913 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14914 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14915 return reloc_type == 0;
d347c9df 14916
a06ea964
NC
14917 case EM_AARCH64:
14918 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14919 case EM_AVR_OLD:
14920 case EM_AVR:
14921 return (reloc_type == 0 /* R_AVR_NONE. */
14922 || reloc_type == 30 /* R_AVR_DIFF8. */
14923 || reloc_type == 31 /* R_AVR_DIFF16. */
14924 || reloc_type == 32 /* R_AVR_DIFF32. */);
14925 case EM_METAG:
14926 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 14927 case EM_NDS32:
81c5e376
AM
14928 return (reloc_type == 0 /* R_NDS32_NONE. */
14929 || reloc_type == 205 /* R_NDS32_DIFF8. */
14930 || reloc_type == 206 /* R_NDS32_DIFF16. */
14931 || reloc_type == 207 /* R_NDS32_DIFF32. */
14932 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
14933 case EM_TI_PRU:
14934 return (reloc_type == 0 /* R_PRU_NONE. */
14935 || reloc_type == 65 /* R_PRU_DIFF8. */
14936 || reloc_type == 66 /* R_PRU_DIFF16. */
14937 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14938 case EM_XTENSA_OLD:
14939 case EM_XTENSA:
4dc3c23d
AM
14940 return (reloc_type == 0 /* R_XTENSA_NONE. */
14941 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14942 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14943 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14944 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14945 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14946 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14947 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14948 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14949 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14950 }
015dc7e1 14951 return false;
2a7b2e88
JK
14952}
14953
d1c4b12b
NC
14954/* Returns TRUE if there is a relocation against
14955 section NAME at OFFSET bytes. */
14956
015dc7e1 14957bool
31e5a3a3 14958reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
14959{
14960 Elf_Internal_Rela * relocs;
14961 Elf_Internal_Rela * rp;
14962
14963 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14964 return false;
d1c4b12b
NC
14965
14966 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14967
14968 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14969 if (rp->r_offset == offset)
015dc7e1 14970 return true;
d1c4b12b 14971
015dc7e1 14972 return false;
d1c4b12b
NC
14973}
14974
cf13d699 14975/* Apply relocations to a section.
32ec8896
NC
14976 Returns TRUE upon success, FALSE otherwise.
14977 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14978 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14979 will be set to the number of relocs loaded.
14980
cf13d699 14981 Note: So far support has been added only for those relocations
32ec8896
NC
14982 which can be found in debug sections. FIXME: Add support for
14983 more relocations ? */
1b315056 14984
015dc7e1 14985static bool
be7d229a
AM
14986apply_relocations (Filedata *filedata,
14987 const Elf_Internal_Shdr *section,
14988 unsigned char *start,
14989 size_t size,
14990 void **relocs_return,
26c527e6 14991 uint64_t *num_relocs_return)
1b315056 14992{
cf13d699 14993 Elf_Internal_Shdr * relsec;
0d2a7a93 14994 unsigned char * end = start + size;
cb8f3167 14995
d1c4b12b
NC
14996 if (relocs_return != NULL)
14997 {
14998 * (Elf_Internal_Rela **) relocs_return = NULL;
14999 * num_relocs_return = 0;
15000 }
15001
dda8d76d 15002 if (filedata->file_header.e_type != ET_REL)
32ec8896 15003 /* No relocs to apply. */
015dc7e1 15004 return true;
1b315056 15005
cf13d699 15006 /* Find the reloc section associated with the section. */
dda8d76d
NC
15007 for (relsec = filedata->section_headers;
15008 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 15009 ++relsec)
252b5132 15010 {
015dc7e1 15011 bool is_rela;
26c527e6 15012 uint64_t num_relocs;
2cf0635d
NC
15013 Elf_Internal_Rela * relocs;
15014 Elf_Internal_Rela * rp;
15015 Elf_Internal_Shdr * symsec;
15016 Elf_Internal_Sym * symtab;
26c527e6 15017 uint64_t num_syms;
2cf0635d 15018 Elf_Internal_Sym * sym;
252b5132 15019
41e92641 15020 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15021 || relsec->sh_info >= filedata->file_header.e_shnum
15022 || filedata->section_headers + relsec->sh_info != section
c256ffe7 15023 || relsec->sh_size == 0
dda8d76d 15024 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 15025 continue;
428409d5 15026
a788aedd
AM
15027 symsec = filedata->section_headers + relsec->sh_link;
15028 if (symsec->sh_type != SHT_SYMTAB
15029 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 15030 return false;
a788aedd 15031
41e92641
NC
15032 is_rela = relsec->sh_type == SHT_RELA;
15033
15034 if (is_rela)
15035 {
dda8d76d 15036 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 15037 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15038 return false;
41e92641
NC
15039 }
15040 else
15041 {
dda8d76d 15042 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 15043 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15044 return false;
41e92641
NC
15045 }
15046
15047 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 15048 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 15049 is_rela = false;
428409d5 15050
4de91c10 15051 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 15052
41e92641 15053 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 15054 {
625d49fc 15055 uint64_t addend;
015dc7e1
AM
15056 unsigned int reloc_type;
15057 unsigned int reloc_size;
15058 bool reloc_inplace = false;
15059 bool reloc_subtract = false;
15060 unsigned char *rloc;
26c527e6 15061 uint64_t sym_index;
4b78141a 15062
dda8d76d 15063 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 15064
dda8d76d 15065 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 15066 continue;
dda8d76d 15067 else if (is_none_reloc (filedata, reloc_type))
98fb390a 15068 continue;
dda8d76d
NC
15069 else if (is_32bit_abs_reloc (filedata, reloc_type)
15070 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 15071 reloc_size = 4;
dda8d76d
NC
15072 else if (is_64bit_abs_reloc (filedata, reloc_type)
15073 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 15074 reloc_size = 8;
dda8d76d 15075 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15076 reloc_size = 3;
dda8d76d 15077 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15078 reloc_size = 2;
39e07931
AS
15079 else if (is_8bit_abs_reloc (filedata, reloc_type)
15080 || is_6bit_abs_reloc (filedata, reloc_type))
15081 reloc_size = 1;
03336641
JW
15082 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15083 reloc_type))
15084 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15085 {
15086 reloc_size = 4;
015dc7e1 15087 reloc_inplace = true;
03336641
JW
15088 }
15089 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15090 reloc_type))
15091 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15092 {
15093 reloc_size = 8;
015dc7e1 15094 reloc_inplace = true;
03336641
JW
15095 }
15096 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15097 reloc_type))
15098 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15099 {
15100 reloc_size = 2;
015dc7e1 15101 reloc_inplace = true;
03336641
JW
15102 }
15103 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15104 reloc_type))
15105 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15106 {
15107 reloc_size = 1;
015dc7e1 15108 reloc_inplace = true;
03336641 15109 }
39e07931
AS
15110 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
15111 reloc_type)))
15112 {
15113 reloc_size = 1;
015dc7e1 15114 reloc_inplace = true;
39e07931 15115 }
aca88567 15116 else
4b78141a 15117 {
bee0ee85 15118 static unsigned int prev_reloc = 0;
dda8d76d 15119
bee0ee85
NC
15120 if (reloc_type != prev_reloc)
15121 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15122 reloc_type, printable_section_name (filedata, section));
bee0ee85 15123 prev_reloc = reloc_type;
4b78141a
NC
15124 continue;
15125 }
103f02d3 15126
91d6fa6a 15127 rloc = start + rp->r_offset;
75802ccb 15128 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 15129 {
26c527e6
AM
15130 warn (_("skipping invalid relocation offset %#" PRIx64
15131 " in section %s\n"),
15132 rp->r_offset,
dda8d76d 15133 printable_section_name (filedata, section));
700dd8b7
L
15134 continue;
15135 }
103f02d3 15136
26c527e6 15137 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
15138 if (sym_index >= num_syms)
15139 {
26c527e6
AM
15140 warn (_("skipping invalid relocation symbol index %#" PRIx64
15141 " in section %s\n"),
dda8d76d 15142 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15143 continue;
15144 }
15145 sym = symtab + sym_index;
41e92641
NC
15146
15147 /* If the reloc has a symbol associated with it,
55f25fc3
L
15148 make sure that it is of an appropriate type.
15149
15150 Relocations against symbols without type can happen.
15151 Gcc -feliminate-dwarf2-dups may generate symbols
15152 without type for debug info.
15153
15154 Icc generates relocations against function symbols
15155 instead of local labels.
15156
15157 Relocations against object symbols can happen, eg when
15158 referencing a global array. For an example of this see
15159 the _clz.o binary in libgcc.a. */
aca88567 15160 if (sym != symtab
b8871f35 15161 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15162 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15163 {
26c527e6 15164 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
15165 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15166 printable_section_name (filedata, relsec),
26c527e6 15167 rp - relocs);
aca88567 15168 continue;
5b18a4bc 15169 }
252b5132 15170
4dc3c23d
AM
15171 addend = 0;
15172 if (is_rela)
15173 addend += rp->r_addend;
c47320c3
AM
15174 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15175 partial_inplace. */
4dc3c23d 15176 if (!is_rela
dda8d76d 15177 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15178 && reloc_type == 1)
dda8d76d
NC
15179 || ((filedata->file_header.e_machine == EM_PJ
15180 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15181 && reloc_type == 1)
dda8d76d
NC
15182 || ((filedata->file_header.e_machine == EM_D30V
15183 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15184 && reloc_type == 12)
15185 || reloc_inplace)
39e07931
AS
15186 {
15187 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15188 addend += byte_get (rloc, reloc_size) & 0x3f;
15189 else
15190 addend += byte_get (rloc, reloc_size);
15191 }
cb8f3167 15192
dda8d76d
NC
15193 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15194 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15195 {
15196 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15197 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15198 addend -= 8;
91d6fa6a 15199 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15200 reloc_size);
15201 }
39e07931
AS
15202 else if (is_6bit_abs_reloc (filedata, reloc_type)
15203 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
15204 {
15205 if (reloc_subtract)
15206 addend -= sym->st_value;
15207 else
15208 addend += sym->st_value;
15209 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15210 byte_put (rloc, addend, reloc_size);
15211 }
03336641
JW
15212 else if (reloc_subtract)
15213 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15214 else
91d6fa6a 15215 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15216 }
252b5132 15217
5b18a4bc 15218 free (symtab);
f84ce13b
NC
15219 /* Let the target specific reloc processing code know that
15220 we have finished with these relocs. */
dda8d76d 15221 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15222
15223 if (relocs_return)
15224 {
15225 * (Elf_Internal_Rela **) relocs_return = relocs;
15226 * num_relocs_return = num_relocs;
15227 }
15228 else
15229 free (relocs);
15230
5b18a4bc
NC
15231 break;
15232 }
32ec8896 15233
015dc7e1 15234 return true;
5b18a4bc 15235}
103f02d3 15236
cf13d699 15237#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15238static bool
dda8d76d 15239disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15240{
dda8d76d 15241 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15242
74e1a04b 15243 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15244
015dc7e1 15245 return true;
cf13d699
NC
15246}
15247#endif
15248
15249/* Reads in the contents of SECTION from FILE, returning a pointer
15250 to a malloc'ed buffer or NULL if something went wrong. */
15251
15252static char *
dda8d76d 15253get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15254{
be7d229a 15255 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15256
15257 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15258 {
c6b78c96 15259 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15260 printable_section_name (filedata, section));
cf13d699
NC
15261 return NULL;
15262 }
15263
dda8d76d 15264 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15265 _("section contents"));
cf13d699
NC
15266}
15267
1f5a3546 15268/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 15269
015dc7e1 15270static bool
45f5fe46
NC
15271uncompress_section_contents (bool is_zstd,
15272 unsigned char ** buffer,
15273 uint64_t uncompressed_size,
15274 uint64_t * size,
15275 uint64_t file_size)
0e602686 15276{
31e5a3a3
AM
15277 uint64_t compressed_size = *size;
15278 unsigned char *compressed_buffer = *buffer;
45f5fe46 15279 unsigned char *uncompressed_buffer = NULL;
0e602686
NC
15280 z_stream strm;
15281 int rc;
15282
45f5fe46
NC
15283 /* Similar to _bfd_section_size_insane() in the BFD library we expect an
15284 upper limit of ~10x compression. Any compression larger than that is
15285 thought to be due to fuzzing of the compression header. */
15286 if (uncompressed_size > file_size * 10)
15287 {
15288 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
15289 uncompressed_size);
15290 goto fail;
15291 }
15292
15293 uncompressed_buffer = xmalloc (uncompressed_size);
15294
1f5a3546
FS
15295 if (is_zstd)
15296 {
15297#ifdef HAVE_ZSTD
15298 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15299 compressed_buffer, compressed_size);
15300 if (ZSTD_isError (ret))
15301 goto fail;
15302#endif
15303 }
15304 else
15305 {
15306 /* It is possible the section consists of several compressed
15307 buffers concatenated together, so we uncompress in a loop. */
15308 /* PR 18313: The state field in the z_stream structure is supposed
15309 to be invisible to the user (ie us), but some compilers will
15310 still complain about it being used without initialisation. So
15311 we first zero the entire z_stream structure and then set the fields
15312 that we need. */
15313 memset (&strm, 0, sizeof strm);
15314 strm.avail_in = compressed_size;
15315 strm.next_in = (Bytef *)compressed_buffer;
15316 strm.avail_out = uncompressed_size;
15317
15318 rc = inflateInit (&strm);
15319 while (strm.avail_in > 0)
15320 {
15321 if (rc != Z_OK)
15322 break;
15323 strm.next_out = ((Bytef *)uncompressed_buffer
15324 + (uncompressed_size - strm.avail_out));
15325 rc = inflate (&strm, Z_FINISH);
15326 if (rc != Z_STREAM_END)
15327 break;
15328 rc = inflateReset (&strm);
15329 }
15330 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15331 goto fail;
15332 }
0e602686
NC
15333
15334 *buffer = uncompressed_buffer;
15335 *size = uncompressed_size;
015dc7e1 15336 return true;
0e602686
NC
15337
15338 fail:
15339 free (uncompressed_buffer);
15340 /* Indicate decompression failure. */
15341 *buffer = NULL;
015dc7e1 15342 return false;
0e602686 15343}
dd24e3da 15344
015dc7e1 15345static bool
dda8d76d 15346dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15347{
015dc7e1 15348 Elf_Internal_Shdr *relsec;
be7d229a 15349 uint64_t num_bytes;
015dc7e1
AM
15350 unsigned char *data;
15351 unsigned char *end;
15352 unsigned char *real_start;
15353 unsigned char *start;
15354 bool some_strings_shown;
cf13d699 15355
dda8d76d 15356 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15357 if (start == NULL)
c6b78c96 15358 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15359 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15360
0e602686 15361 num_bytes = section->sh_size;
cf13d699 15362
835f2fae
NC
15363 if (filedata->is_separate)
15364 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15365 printable_section_name (filedata, section),
15366 filedata->file_name);
15367 else
15368 printf (_("\nString dump of section '%s':\n"),
15369 printable_section_name (filedata, section));
cf13d699 15370
0e602686
NC
15371 if (decompress_dumps)
15372 {
31e5a3a3
AM
15373 uint64_t new_size = num_bytes;
15374 uint64_t uncompressed_size = 0;
1f5a3546 15375 bool is_zstd = false;
0e602686
NC
15376
15377 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15378 {
15379 Elf_Internal_Chdr chdr;
15380 unsigned int compression_header_size
ebdf1ebf
NC
15381 = get_compression_header (& chdr, (unsigned char *) start,
15382 num_bytes);
5844b465
NC
15383 if (compression_header_size == 0)
15384 /* An error message will have already been generated
15385 by get_compression_header. */
15386 goto error_out;
0e602686 15387
89dbeac7 15388 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
15389 ;
15390#ifdef HAVE_ZSTD
89dbeac7 15391 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
15392 is_zstd = true;
15393#endif
15394 else
0e602686 15395 {
813dabb9 15396 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15397 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15398 goto error_out;
813dabb9 15399 }
813dabb9
L
15400 uncompressed_size = chdr.ch_size;
15401 start += compression_header_size;
15402 new_size -= compression_header_size;
0e602686
NC
15403 }
15404 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15405 {
15406 /* Read the zlib header. In this case, it should be "ZLIB"
15407 followed by the uncompressed section size, 8 bytes in
15408 big-endian order. */
15409 uncompressed_size = start[4]; uncompressed_size <<= 8;
15410 uncompressed_size += start[5]; uncompressed_size <<= 8;
15411 uncompressed_size += start[6]; uncompressed_size <<= 8;
15412 uncompressed_size += start[7]; uncompressed_size <<= 8;
15413 uncompressed_size += start[8]; uncompressed_size <<= 8;
15414 uncompressed_size += start[9]; uncompressed_size <<= 8;
15415 uncompressed_size += start[10]; uncompressed_size <<= 8;
15416 uncompressed_size += start[11];
15417 start += 12;
15418 new_size -= 12;
15419 }
15420
1835f746
NC
15421 if (uncompressed_size)
15422 {
1f5a3546 15423 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 15424 &new_size, filedata->file_size))
1835f746
NC
15425 num_bytes = new_size;
15426 else
15427 {
15428 error (_("Unable to decompress section %s\n"),
dda8d76d 15429 printable_section_name (filedata, section));
f761cb13 15430 goto error_out;
1835f746
NC
15431 }
15432 }
bc303e5d
NC
15433 else
15434 start = real_start;
0e602686 15435 }
fd8008d8 15436
cf13d699
NC
15437 /* If the section being dumped has relocations against it the user might
15438 be expecting these relocations to have been applied. Check for this
15439 case and issue a warning message in order to avoid confusion.
15440 FIXME: Maybe we ought to have an option that dumps a section with
15441 relocs applied ? */
dda8d76d
NC
15442 for (relsec = filedata->section_headers;
15443 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15444 ++relsec)
15445 {
15446 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15447 || relsec->sh_info >= filedata->file_header.e_shnum
15448 || filedata->section_headers + relsec->sh_info != section
cf13d699 15449 || relsec->sh_size == 0
dda8d76d 15450 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15451 continue;
15452
15453 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15454 break;
15455 }
15456
cf13d699
NC
15457 data = start;
15458 end = start + num_bytes;
015dc7e1 15459 some_strings_shown = false;
cf13d699 15460
ba3265d0
NC
15461#ifdef HAVE_MBSTATE_T
15462 mbstate_t state;
15463 /* Initialise the multibyte conversion state. */
15464 memset (& state, 0, sizeof (state));
15465#endif
15466
015dc7e1 15467 bool continuing = false;
ba3265d0 15468
cf13d699
NC
15469 while (data < end)
15470 {
15471 while (!ISPRINT (* data))
15472 if (++ data >= end)
15473 break;
15474
15475 if (data < end)
15476 {
071436c6
NC
15477 size_t maxlen = end - data;
15478
ba3265d0
NC
15479 if (continuing)
15480 {
15481 printf (" ");
015dc7e1 15482 continuing = false;
ba3265d0
NC
15483 }
15484 else
15485 {
26c527e6 15486 printf (" [%6tx] ", data - start);
ba3265d0
NC
15487 }
15488
4082ef84
NC
15489 if (maxlen > 0)
15490 {
f3da8a96 15491 char c = 0;
ba3265d0
NC
15492
15493 while (maxlen)
15494 {
15495 c = *data++;
15496
15497 if (c == 0)
15498 break;
15499
15500 /* PR 25543: Treat new-lines as string-ending characters. */
15501 if (c == '\n')
15502 {
15503 printf ("\\n\n");
15504 if (*data != 0)
015dc7e1 15505 continuing = true;
ba3265d0
NC
15506 break;
15507 }
15508
15509 /* Do not print control characters directly as they can affect terminal
15510 settings. Such characters usually appear in the names generated
15511 by the assembler for local labels. */
15512 if (ISCNTRL (c))
15513 {
15514 printf ("^%c", c + 0x40);
15515 }
15516 else if (ISPRINT (c))
15517 {
15518 putchar (c);
15519 }
15520 else
15521 {
15522 size_t n;
15523#ifdef HAVE_MBSTATE_T
15524 wchar_t w;
15525#endif
15526 /* Let printf do the hard work of displaying multibyte characters. */
15527 printf ("%.1s", data - 1);
15528#ifdef HAVE_MBSTATE_T
15529 /* Try to find out how many bytes made up the character that was
15530 just printed. Advance the symbol pointer past the bytes that
15531 were displayed. */
15532 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15533#else
15534 n = 1;
15535#endif
15536 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15537 data += (n - 1);
15538 }
15539 }
15540
15541 if (c != '\n')
15542 putchar ('\n');
4082ef84
NC
15543 }
15544 else
15545 {
15546 printf (_("<corrupt>\n"));
15547 data = end;
15548 }
015dc7e1 15549 some_strings_shown = true;
cf13d699
NC
15550 }
15551 }
15552
15553 if (! some_strings_shown)
15554 printf (_(" No strings found in this section."));
15555
0e602686 15556 free (real_start);
cf13d699
NC
15557
15558 putchar ('\n');
015dc7e1 15559 return true;
f761cb13
AM
15560
15561error_out:
15562 free (real_start);
015dc7e1 15563 return false;
cf13d699
NC
15564}
15565
015dc7e1
AM
15566static bool
15567dump_section_as_bytes (Elf_Internal_Shdr *section,
15568 Filedata *filedata,
15569 bool relocate)
cf13d699 15570{
be7d229a
AM
15571 Elf_Internal_Shdr *relsec;
15572 size_t bytes;
15573 uint64_t section_size;
625d49fc 15574 uint64_t addr;
be7d229a
AM
15575 unsigned char *data;
15576 unsigned char *real_start;
15577 unsigned char *start;
0e602686 15578
dda8d76d 15579 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15580 if (start == NULL)
c6b78c96 15581 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15582 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15583
0e602686 15584 section_size = section->sh_size;
cf13d699 15585
835f2fae
NC
15586 if (filedata->is_separate)
15587 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15588 printable_section_name (filedata, section),
15589 filedata->file_name);
15590 else
15591 printf (_("\nHex dump of section '%s':\n"),
15592 printable_section_name (filedata, section));
cf13d699 15593
0e602686
NC
15594 if (decompress_dumps)
15595 {
31e5a3a3
AM
15596 uint64_t new_size = section_size;
15597 uint64_t uncompressed_size = 0;
1f5a3546 15598 bool is_zstd = false;
0e602686
NC
15599
15600 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15601 {
15602 Elf_Internal_Chdr chdr;
15603 unsigned int compression_header_size
ebdf1ebf 15604 = get_compression_header (& chdr, start, section_size);
0e602686 15605
5844b465
NC
15606 if (compression_header_size == 0)
15607 /* An error message will have already been generated
15608 by get_compression_header. */
15609 goto error_out;
15610
89dbeac7 15611 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
15612 ;
15613#ifdef HAVE_ZSTD
89dbeac7 15614 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
15615 is_zstd = true;
15616#endif
15617 else
0e602686 15618 {
813dabb9 15619 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15620 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15621 goto error_out;
0e602686 15622 }
813dabb9
L
15623 uncompressed_size = chdr.ch_size;
15624 start += compression_header_size;
15625 new_size -= compression_header_size;
0e602686
NC
15626 }
15627 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15628 {
15629 /* Read the zlib header. In this case, it should be "ZLIB"
15630 followed by the uncompressed section size, 8 bytes in
15631 big-endian order. */
15632 uncompressed_size = start[4]; uncompressed_size <<= 8;
15633 uncompressed_size += start[5]; uncompressed_size <<= 8;
15634 uncompressed_size += start[6]; uncompressed_size <<= 8;
15635 uncompressed_size += start[7]; uncompressed_size <<= 8;
15636 uncompressed_size += start[8]; uncompressed_size <<= 8;
15637 uncompressed_size += start[9]; uncompressed_size <<= 8;
15638 uncompressed_size += start[10]; uncompressed_size <<= 8;
15639 uncompressed_size += start[11];
15640 start += 12;
15641 new_size -= 12;
15642 }
15643
f055032e
NC
15644 if (uncompressed_size)
15645 {
1f5a3546 15646 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 15647 &new_size, filedata->file_size))
bc303e5d
NC
15648 {
15649 section_size = new_size;
15650 }
f055032e
NC
15651 else
15652 {
15653 error (_("Unable to decompress section %s\n"),
dda8d76d 15654 printable_section_name (filedata, section));
bc303e5d 15655 /* FIXME: Print the section anyway ? */
f761cb13 15656 goto error_out;
f055032e
NC
15657 }
15658 }
bc303e5d
NC
15659 else
15660 start = real_start;
0e602686 15661 }
14ae95f2 15662
cf13d699
NC
15663 if (relocate)
15664 {
dda8d76d 15665 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15666 goto error_out;
cf13d699
NC
15667 }
15668 else
15669 {
15670 /* If the section being dumped has relocations against it the user might
15671 be expecting these relocations to have been applied. Check for this
15672 case and issue a warning message in order to avoid confusion.
15673 FIXME: Maybe we ought to have an option that dumps a section with
15674 relocs applied ? */
dda8d76d
NC
15675 for (relsec = filedata->section_headers;
15676 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15677 ++relsec)
15678 {
15679 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15680 || relsec->sh_info >= filedata->file_header.e_shnum
15681 || filedata->section_headers + relsec->sh_info != section
cf13d699 15682 || relsec->sh_size == 0
dda8d76d 15683 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15684 continue;
15685
15686 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15687 break;
15688 }
15689 }
15690
15691 addr = section->sh_addr;
0e602686 15692 bytes = section_size;
cf13d699
NC
15693 data = start;
15694
15695 while (bytes)
15696 {
15697 int j;
15698 int k;
15699 int lbytes;
15700
15701 lbytes = (bytes > 16 ? 16 : bytes);
15702
26c527e6 15703 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
15704
15705 for (j = 0; j < 16; j++)
15706 {
15707 if (j < lbytes)
15708 printf ("%2.2x", data[j]);
15709 else
15710 printf (" ");
15711
15712 if ((j & 3) == 3)
15713 printf (" ");
15714 }
15715
15716 for (j = 0; j < lbytes; j++)
15717 {
15718 k = data[j];
15719 if (k >= ' ' && k < 0x7f)
15720 printf ("%c", k);
15721 else
15722 printf (".");
15723 }
15724
15725 putchar ('\n');
15726
15727 data += lbytes;
15728 addr += lbytes;
15729 bytes -= lbytes;
15730 }
15731
0e602686 15732 free (real_start);
cf13d699
NC
15733
15734 putchar ('\n');
015dc7e1 15735 return true;
f761cb13
AM
15736
15737 error_out:
15738 free (real_start);
015dc7e1 15739 return false;
cf13d699
NC
15740}
15741
094e34f2 15742#ifdef ENABLE_LIBCTF
7d9813f1
NA
15743static ctf_sect_t *
15744shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15745{
84714f86 15746 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15747 buf->cts_size = shdr->sh_size;
15748 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15749
15750 return buf;
15751}
15752
15753/* Formatting callback function passed to ctf_dump. Returns either the pointer
15754 it is passed, or a pointer to newly-allocated storage, in which case
15755 dump_ctf() will free it when it no longer needs it. */
15756
2f6ecaed
NA
15757static char *
15758dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15759 char *s, void *arg)
7d9813f1 15760{
3e50a591 15761 const char *blanks = arg;
7d9813f1
NA
15762 char *new_s;
15763
3e50a591 15764 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15765 return s;
15766 return new_s;
15767}
15768
926c9e76
NA
15769/* Dump CTF errors/warnings. */
15770static void
139633c3 15771dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15772{
15773 ctf_next_t *it = NULL;
15774 char *errtext;
15775 int is_warning;
15776 int err;
15777
15778 /* Dump accumulated errors and warnings. */
15779 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15780 {
5e9b84f7 15781 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15782 errtext);
15783 free (errtext);
15784 }
15785 if (err != ECTF_NEXT_END)
15786 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15787}
15788
2f6ecaed
NA
15789/* Dump one CTF archive member. */
15790
80b56fad
NA
15791static void
15792dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15793 size_t member)
2f6ecaed 15794{
2f6ecaed
NA
15795 const char *things[] = {"Header", "Labels", "Data objects",
15796 "Function objects", "Variables", "Types", "Strings",
15797 ""};
15798 const char **thing;
15799 size_t i;
15800
80b56fad
NA
15801 /* Don't print out the name of the default-named archive member if it appears
15802 first in the list. The name .ctf appears everywhere, even for things that
15803 aren't really archives, so printing it out is liable to be confusing; also,
15804 the common case by far is for only one archive member to exist, and hiding
15805 it in that case seems worthwhile. */
2f6ecaed 15806
80b56fad
NA
15807 if (strcmp (name, ".ctf") != 0 || member != 0)
15808 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15809
80b56fad
NA
15810 if (ctf_parent_name (ctf) != NULL)
15811 ctf_import (ctf, parent);
2f6ecaed
NA
15812
15813 for (i = 0, thing = things; *thing[0]; thing++, i++)
15814 {
15815 ctf_dump_state_t *s = NULL;
15816 char *item;
15817
15818 printf ("\n %s:\n", *thing);
15819 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15820 (void *) " ")) != NULL)
15821 {
15822 printf ("%s\n", item);
15823 free (item);
15824 }
15825
15826 if (ctf_errno (ctf))
15827 {
15828 error (_("Iteration failed: %s, %s\n"), *thing,
15829 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15830 break;
2f6ecaed
NA
15831 }
15832 }
8b37e7b6 15833
926c9e76 15834 dump_ctf_errs (ctf);
2f6ecaed
NA
15835}
15836
015dc7e1 15837static bool
7d9813f1
NA
15838dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15839{
7d9813f1
NA
15840 Elf_Internal_Shdr * symtab_sec = NULL;
15841 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15842 void * data = NULL;
15843 void * symdata = NULL;
15844 void * strdata = NULL;
80b56fad 15845 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15846 ctf_sect_t * symsectp = NULL;
15847 ctf_sect_t * strsectp = NULL;
2f6ecaed 15848 ctf_archive_t * ctfa = NULL;
139633c3 15849 ctf_dict_t * parent = NULL;
80b56fad 15850 ctf_dict_t * fp;
7d9813f1 15851
80b56fad
NA
15852 ctf_next_t *i = NULL;
15853 const char *name;
15854 size_t member = 0;
7d9813f1 15855 int err;
015dc7e1 15856 bool ret = false;
7d9813f1
NA
15857
15858 shdr_to_ctf_sect (&ctfsect, section, filedata);
15859 data = get_section_contents (section, filedata);
15860 ctfsect.cts_data = data;
15861
616febde 15862 if (!dump_ctf_symtab_name)
3d16b64e 15863 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15864
15865 if (!dump_ctf_strtab_name)
3d16b64e 15866 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15867
15868 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15869 {
15870 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15871 {
15872 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15873 goto fail;
15874 }
15875 if ((symdata = (void *) get_data (NULL, filedata,
15876 symtab_sec->sh_offset, 1,
15877 symtab_sec->sh_size,
15878 _("symbols"))) == NULL)
15879 goto fail;
15880 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15881 symsect.cts_data = symdata;
15882 }
835f2fae 15883
df16e041 15884 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15885 {
15886 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15887 {
15888 error (_("No string table section named %s\n"),
15889 dump_ctf_strtab_name);
15890 goto fail;
15891 }
15892 if ((strdata = (void *) get_data (NULL, filedata,
15893 strtab_sec->sh_offset, 1,
15894 strtab_sec->sh_size,
15895 _("strings"))) == NULL)
15896 goto fail;
15897 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15898 strsect.cts_data = strdata;
15899 }
835f2fae 15900
2f6ecaed
NA
15901 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15902 libctf papers over the difference, so we can pretend it is always an
80b56fad 15903 archive. */
7d9813f1 15904
2f6ecaed 15905 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15906 {
926c9e76 15907 dump_ctf_errs (NULL);
7d9813f1
NA
15908 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15909 goto fail;
15910 }
15911
96c61be5
NA
15912 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15913 != ELFDATA2MSB);
15914
80b56fad
NA
15915 /* Preload the parent dict, since it will need to be imported into every
15916 child in turn. */
15917 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15918 {
926c9e76 15919 dump_ctf_errs (NULL);
2f6ecaed
NA
15920 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15921 goto fail;
7d9813f1
NA
15922 }
15923
015dc7e1 15924 ret = true;
7d9813f1 15925
835f2fae
NC
15926 if (filedata->is_separate)
15927 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15928 printable_section_name (filedata, section),
15929 filedata->file_name);
15930 else
15931 printf (_("\nDump of CTF section '%s':\n"),
15932 printable_section_name (filedata, section));
7d9813f1 15933
80b56fad
NA
15934 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15935 dump_ctf_archive_member (fp, name, parent, member++);
15936 if (err != ECTF_NEXT_END)
15937 {
15938 dump_ctf_errs (NULL);
15939 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15940 ret = false;
15941 }
7d9813f1
NA
15942
15943 fail:
139633c3 15944 ctf_dict_close (parent);
2f6ecaed 15945 ctf_close (ctfa);
7d9813f1
NA
15946 free (data);
15947 free (symdata);
15948 free (strdata);
15949 return ret;
15950}
094e34f2 15951#endif
7d9813f1 15952
42b6953b
IB
15953static bool
15954dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
15955{
15956 void * data = NULL;
15957 sframe_decoder_ctx *sfd_ctx = NULL;
15958 const char *print_name = printable_section_name (filedata, section);
15959
15960 bool ret = true;
15961 size_t sf_size;
15962 int err = 0;
15963
15964 if (strcmp (print_name, "") == 0)
15965 {
15966 error (_("Section name must be provided \n"));
15967 ret = false;
15968 return ret;
15969 }
15970
15971 data = get_section_contents (section, filedata);
15972 sf_size = section->sh_size;
15973 /* Decode the contents of the section. */
15974 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
15975 if (!sfd_ctx)
15976 {
15977 ret = false;
15978 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
15979 goto fail;
15980 }
15981
15982 printf (_("Contents of the SFrame section %s:"), print_name);
15983 /* Dump the contents as text. */
15984 dump_sframe (sfd_ctx, section->sh_addr);
15985
15986 fail:
15987 free (data);
15988 return ret;
15989}
15990
015dc7e1 15991static bool
dda8d76d
NC
15992load_specific_debug_section (enum dwarf_section_display_enum debug,
15993 const Elf_Internal_Shdr * sec,
15994 void * data)
1007acb3 15995{
2cf0635d 15996 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15997 char buf [64];
dda8d76d 15998 Filedata * filedata = (Filedata *) data;
9abca702 15999
19e6b90e 16000 if (section->start != NULL)
dda8d76d
NC
16001 {
16002 /* If it is already loaded, do nothing. */
16003 if (streq (section->filename, filedata->file_name))
015dc7e1 16004 return true;
dda8d76d
NC
16005 free (section->start);
16006 }
1007acb3 16007
19e6b90e
L
16008 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16009 section->address = sec->sh_addr;
dda8d76d
NC
16010 section->filename = filedata->file_name;
16011 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
16012 sec->sh_offset, 1,
16013 sec->sh_size, buf);
59245841
NC
16014 if (section->start == NULL)
16015 section->size = 0;
16016 else
16017 {
77115a4a 16018 unsigned char *start = section->start;
31e5a3a3
AM
16019 uint64_t size = sec->sh_size;
16020 uint64_t uncompressed_size = 0;
1f5a3546 16021 bool is_zstd = false;
77115a4a
L
16022
16023 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16024 {
16025 Elf_Internal_Chdr chdr;
d8024a91
NC
16026 unsigned int compression_header_size;
16027
f53be977
L
16028 if (size < (is_32bit_elf
16029 ? sizeof (Elf32_External_Chdr)
16030 : sizeof (Elf64_External_Chdr)))
d8024a91 16031 {
55be8fd0 16032 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 16033 section->name);
015dc7e1 16034 return false;
d8024a91
NC
16035 }
16036
ebdf1ebf 16037 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
16038 if (compression_header_size == 0)
16039 /* An error message will have already been generated
16040 by get_compression_header. */
015dc7e1 16041 return false;
d8024a91 16042
89dbeac7 16043 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16044 ;
16045#ifdef HAVE_ZSTD
89dbeac7 16046 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16047 is_zstd = true;
16048#endif
16049 else
813dabb9
L
16050 {
16051 warn (_("section '%s' has unsupported compress type: %d\n"),
16052 section->name, chdr.ch_type);
015dc7e1 16053 return false;
813dabb9 16054 }
dab394de 16055 uncompressed_size = chdr.ch_size;
77115a4a
L
16056 start += compression_header_size;
16057 size -= compression_header_size;
16058 }
dab394de
L
16059 else if (size > 12 && streq ((char *) start, "ZLIB"))
16060 {
16061 /* Read the zlib header. In this case, it should be "ZLIB"
16062 followed by the uncompressed section size, 8 bytes in
16063 big-endian order. */
16064 uncompressed_size = start[4]; uncompressed_size <<= 8;
16065 uncompressed_size += start[5]; uncompressed_size <<= 8;
16066 uncompressed_size += start[6]; uncompressed_size <<= 8;
16067 uncompressed_size += start[7]; uncompressed_size <<= 8;
16068 uncompressed_size += start[8]; uncompressed_size <<= 8;
16069 uncompressed_size += start[9]; uncompressed_size <<= 8;
16070 uncompressed_size += start[10]; uncompressed_size <<= 8;
16071 uncompressed_size += start[11];
16072 start += 12;
16073 size -= 12;
16074 }
16075
1835f746 16076 if (uncompressed_size)
77115a4a 16077 {
1f5a3546 16078 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16079 &size, filedata->file_size))
1835f746
NC
16080 {
16081 /* Free the compressed buffer, update the section buffer
16082 and the section size if uncompress is successful. */
16083 free (section->start);
16084 section->start = start;
16085 }
16086 else
16087 {
16088 error (_("Unable to decompress section %s\n"),
dda8d76d 16089 printable_section_name (filedata, sec));
015dc7e1 16090 return false;
1835f746 16091 }
77115a4a 16092 }
bc303e5d 16093
77115a4a 16094 section->size = size;
59245841 16095 }
4a114e3e 16096
1b315056 16097 if (section->start == NULL)
015dc7e1 16098 return false;
1b315056 16099
19e6b90e 16100 if (debug_displays [debug].relocate)
32ec8896 16101 {
dda8d76d 16102 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 16103 & section->reloc_info, & section->num_relocs))
015dc7e1 16104 return false;
32ec8896 16105 }
d1c4b12b
NC
16106 else
16107 {
16108 section->reloc_info = NULL;
16109 section->num_relocs = 0;
16110 }
1007acb3 16111
015dc7e1 16112 return true;
1007acb3
L
16113}
16114
301a9420
AM
16115#if HAVE_LIBDEBUGINFOD
16116/* Return a hex string representation of the build-id. */
16117unsigned char *
16118get_build_id (void * data)
16119{
ca0e11aa 16120 Filedata * filedata = (Filedata *) data;
301a9420 16121 Elf_Internal_Shdr * shdr;
26c527e6 16122 size_t i;
301a9420 16123
55be8fd0
NC
16124 /* Iterate through notes to find note.gnu.build-id.
16125 FIXME: Only the first note in any note section is examined. */
301a9420
AM
16126 for (i = 0, shdr = filedata->section_headers;
16127 i < filedata->file_header.e_shnum && shdr != NULL;
16128 i++, shdr++)
16129 {
16130 if (shdr->sh_type != SHT_NOTE)
16131 continue;
16132
16133 char * next;
16134 char * end;
16135 size_t data_remaining;
16136 size_t min_notesz;
16137 Elf_External_Note * enote;
16138 Elf_Internal_Note inote;
16139
625d49fc
AM
16140 uint64_t offset = shdr->sh_offset;
16141 uint64_t align = shdr->sh_addralign;
16142 uint64_t length = shdr->sh_size;
301a9420
AM
16143
16144 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16145 if (enote == NULL)
16146 continue;
16147
16148 if (align < 4)
16149 align = 4;
16150 else if (align != 4 && align != 8)
f761cb13
AM
16151 {
16152 free (enote);
16153 continue;
16154 }
301a9420
AM
16155
16156 end = (char *) enote + length;
16157 data_remaining = end - (char *) enote;
16158
16159 if (!is_ia64_vms (filedata))
16160 {
16161 min_notesz = offsetof (Elf_External_Note, name);
16162 if (data_remaining < min_notesz)
16163 {
55be8fd0
NC
16164 warn (_("\
16165malformed note encountered in section %s whilst scanning for build-id note\n"),
16166 printable_section_name (filedata, shdr));
f761cb13 16167 free (enote);
55be8fd0 16168 continue;
301a9420
AM
16169 }
16170 data_remaining -= min_notesz;
16171
16172 inote.type = BYTE_GET (enote->type);
16173 inote.namesz = BYTE_GET (enote->namesz);
16174 inote.namedata = enote->name;
16175 inote.descsz = BYTE_GET (enote->descsz);
16176 inote.descdata = ((char *) enote
16177 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16178 inote.descpos = offset + (inote.descdata - (char *) enote);
16179 next = ((char *) enote
16180 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16181 }
16182 else
16183 {
16184 Elf64_External_VMS_Note *vms_enote;
16185
16186 /* PR binutils/15191
16187 Make sure that there is enough data to read. */
16188 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16189 if (data_remaining < min_notesz)
16190 {
55be8fd0
NC
16191 warn (_("\
16192malformed note encountered in section %s whilst scanning for build-id note\n"),
16193 printable_section_name (filedata, shdr));
f761cb13 16194 free (enote);
55be8fd0 16195 continue;
301a9420
AM
16196 }
16197 data_remaining -= min_notesz;
16198
16199 vms_enote = (Elf64_External_VMS_Note *) enote;
16200 inote.type = BYTE_GET (vms_enote->type);
16201 inote.namesz = BYTE_GET (vms_enote->namesz);
16202 inote.namedata = vms_enote->name;
16203 inote.descsz = BYTE_GET (vms_enote->descsz);
16204 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16205 inote.descpos = offset + (inote.descdata - (char *) enote);
16206 next = inote.descdata + align_power (inote.descsz, 3);
16207 }
16208
16209 /* Skip malformed notes. */
16210 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16211 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16212 || (size_t) (next - inote.descdata) < inote.descsz
16213 || ((size_t) (next - inote.descdata)
16214 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16215 {
55be8fd0
NC
16216 warn (_("\
16217malformed note encountered in section %s whilst scanning for build-id note\n"),
16218 printable_section_name (filedata, shdr));
f761cb13 16219 free (enote);
301a9420
AM
16220 continue;
16221 }
16222
16223 /* Check if this is the build-id note. If so then convert the build-id
16224 bytes to a hex string. */
16225 if (inote.namesz > 0
24d127aa 16226 && startswith (inote.namedata, "GNU")
301a9420
AM
16227 && inote.type == NT_GNU_BUILD_ID)
16228 {
26c527e6 16229 size_t j;
301a9420
AM
16230 char * build_id;
16231
16232 build_id = malloc (inote.descsz * 2 + 1);
16233 if (build_id == NULL)
f761cb13
AM
16234 {
16235 free (enote);
16236 return NULL;
16237 }
301a9420
AM
16238
16239 for (j = 0; j < inote.descsz; ++j)
16240 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16241 build_id[inote.descsz * 2] = '\0';
f761cb13 16242 free (enote);
301a9420 16243
55be8fd0 16244 return (unsigned char *) build_id;
301a9420 16245 }
f761cb13 16246 free (enote);
301a9420
AM
16247 }
16248
16249 return NULL;
16250}
16251#endif /* HAVE_LIBDEBUGINFOD */
16252
657d0d47
CC
16253/* If this is not NULL, load_debug_section will only look for sections
16254 within the list of sections given here. */
32ec8896 16255static unsigned int * section_subset = NULL;
657d0d47 16256
015dc7e1 16257bool
dda8d76d 16258load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16259{
2cf0635d
NC
16260 struct dwarf_section * section = &debug_displays [debug].section;
16261 Elf_Internal_Shdr * sec;
dda8d76d
NC
16262 Filedata * filedata = (Filedata *) data;
16263
e1dbfc17
L
16264 if (!dump_any_debugging)
16265 return false;
16266
f425ec66
NC
16267 /* Without section headers we cannot find any sections. */
16268 if (filedata->section_headers == NULL)
015dc7e1 16269 return false;
f425ec66 16270
9c1ce108
AM
16271 if (filedata->string_table == NULL
16272 && filedata->file_header.e_shstrndx != SHN_UNDEF
16273 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16274 {
16275 Elf_Internal_Shdr * strs;
16276
16277 /* Read in the string table, so that we have section names to scan. */
16278 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16279
4dff97b2 16280 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16281 {
9c1ce108
AM
16282 filedata->string_table
16283 = (char *) get_data (NULL, filedata, strs->sh_offset,
16284 1, strs->sh_size, _("string table"));
dda8d76d 16285
9c1ce108
AM
16286 filedata->string_table_length
16287 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16288 }
16289 }
d966045b
DJ
16290
16291 /* Locate the debug section. */
dda8d76d 16292 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16293 if (sec != NULL)
16294 section->name = section->uncompressed_name;
16295 else
16296 {
dda8d76d 16297 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16298 if (sec != NULL)
16299 section->name = section->compressed_name;
16300 }
16301 if (sec == NULL)
015dc7e1 16302 return false;
d966045b 16303
657d0d47
CC
16304 /* If we're loading from a subset of sections, and we've loaded
16305 a section matching this name before, it's likely that it's a
16306 different one. */
16307 if (section_subset != NULL)
16308 free_debug_section (debug);
16309
dda8d76d 16310 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16311}
16312
19e6b90e
L
16313void
16314free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16315{
2cf0635d 16316 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16317
19e6b90e
L
16318 if (section->start == NULL)
16319 return;
1007acb3 16320
19e6b90e
L
16321 free ((char *) section->start);
16322 section->start = NULL;
16323 section->address = 0;
16324 section->size = 0;
a788aedd 16325
9db70fc3
AM
16326 free (section->reloc_info);
16327 section->reloc_info = NULL;
16328 section->num_relocs = 0;
1007acb3
L
16329}
16330
015dc7e1 16331static bool
dda8d76d 16332display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16333{
84714f86
AM
16334 const char *name = (section_name_valid (filedata, section)
16335 ? section_name (filedata, section) : "");
16336 const char *print_name = printable_section_name (filedata, section);
be7d229a 16337 uint64_t length;
015dc7e1 16338 bool result = true;
3f5e193b 16339 int i;
1007acb3 16340
19e6b90e
L
16341 length = section->sh_size;
16342 if (length == 0)
1007acb3 16343 {
74e1a04b 16344 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16345 return true;
1007acb3 16346 }
5dff79d8
NC
16347 if (section->sh_type == SHT_NOBITS)
16348 {
16349 /* There is no point in dumping the contents of a debugging section
16350 which has the NOBITS type - the bits in the file will be random.
16351 This can happen when a file containing a .eh_frame section is
16352 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16353 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16354 print_name);
015dc7e1 16355 return false;
5dff79d8 16356 }
1007acb3 16357
24d127aa 16358 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16359 name = ".debug_info";
1007acb3 16360
19e6b90e
L
16361 /* See if we know how to display the contents of this section. */
16362 for (i = 0; i < max; i++)
d85bf2ba
NC
16363 {
16364 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16365 struct dwarf_section_display * display = debug_displays + i;
16366 struct dwarf_section * sec = & display->section;
d966045b 16367
d85bf2ba 16368 if (streq (sec->uncompressed_name, name)
24d127aa 16369 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16370 || streq (sec->compressed_name, name))
16371 {
015dc7e1 16372 bool secondary = (section != find_section (filedata, name));
1007acb3 16373
d85bf2ba
NC
16374 if (secondary)
16375 free_debug_section (id);
dda8d76d 16376
24d127aa 16377 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16378 sec->name = name;
16379 else if (streq (sec->uncompressed_name, name))
16380 sec->name = sec->uncompressed_name;
16381 else
16382 sec->name = sec->compressed_name;
657d0d47 16383
d85bf2ba
NC
16384 if (load_specific_debug_section (id, section, filedata))
16385 {
16386 /* If this debug section is part of a CU/TU set in a .dwp file,
16387 restrict load_debug_section to the sections in that set. */
16388 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16389
d85bf2ba 16390 result &= display->display (sec, filedata);
657d0d47 16391
d85bf2ba 16392 section_subset = NULL;
1007acb3 16393
44266f36 16394 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16395 free_debug_section (id);
16396 }
16397 break;
16398 }
16399 }
1007acb3 16400
19e6b90e 16401 if (i == max)
1007acb3 16402 {
74e1a04b 16403 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16404 result = false;
1007acb3
L
16405 }
16406
19e6b90e 16407 return result;
5b18a4bc 16408}
103f02d3 16409
aef1f6d0
DJ
16410/* Set DUMP_SECTS for all sections where dumps were requested
16411 based on section name. */
16412
16413static void
dda8d76d 16414initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16415{
2cf0635d 16416 struct dump_list_entry * cur;
aef1f6d0
DJ
16417
16418 for (cur = dump_sects_byname; cur; cur = cur->next)
16419 {
16420 unsigned int i;
015dc7e1 16421 bool any = false;
aef1f6d0 16422
dda8d76d 16423 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16424 if (section_name_valid (filedata, filedata->section_headers + i)
16425 && streq (section_name (filedata, filedata->section_headers + i),
16426 cur->name))
aef1f6d0 16427 {
6431e409 16428 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16429 any = true;
aef1f6d0
DJ
16430 }
16431
835f2fae
NC
16432 if (!any && !filedata->is_separate)
16433 warn (_("Section '%s' was not dumped because it does not exist\n"),
16434 cur->name);
aef1f6d0
DJ
16435 }
16436}
16437
015dc7e1 16438static bool
dda8d76d 16439process_section_contents (Filedata * filedata)
5b18a4bc 16440{
2cf0635d 16441 Elf_Internal_Shdr * section;
19e6b90e 16442 unsigned int i;
015dc7e1 16443 bool res = true;
103f02d3 16444
19e6b90e 16445 if (! do_dump)
015dc7e1 16446 return true;
103f02d3 16447
dda8d76d 16448 initialise_dumps_byname (filedata);
aef1f6d0 16449
dda8d76d 16450 for (i = 0, section = filedata->section_headers;
6431e409 16451 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16452 i++, section++)
16453 {
6431e409 16454 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16455
d6bfbc39
NC
16456 if (filedata->is_separate && ! process_links)
16457 dump &= DEBUG_DUMP;
047c3dbf 16458
19e6b90e 16459#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16460 if (dump & DISASS_DUMP)
16461 {
16462 if (! disassemble_section (section, filedata))
015dc7e1 16463 res = false;
dda8d76d 16464 }
19e6b90e 16465#endif
dda8d76d 16466 if (dump & HEX_DUMP)
32ec8896 16467 {
015dc7e1
AM
16468 if (! dump_section_as_bytes (section, filedata, false))
16469 res = false;
32ec8896 16470 }
103f02d3 16471
dda8d76d 16472 if (dump & RELOC_DUMP)
32ec8896 16473 {
015dc7e1
AM
16474 if (! dump_section_as_bytes (section, filedata, true))
16475 res = false;
32ec8896 16476 }
09c11c86 16477
dda8d76d 16478 if (dump & STRING_DUMP)
32ec8896 16479 {
dda8d76d 16480 if (! dump_section_as_strings (section, filedata))
015dc7e1 16481 res = false;
32ec8896 16482 }
cf13d699 16483
dda8d76d 16484 if (dump & DEBUG_DUMP)
32ec8896 16485 {
dda8d76d 16486 if (! display_debug_section (i, section, filedata))
015dc7e1 16487 res = false;
32ec8896 16488 }
7d9813f1 16489
094e34f2 16490#ifdef ENABLE_LIBCTF
7d9813f1
NA
16491 if (dump & CTF_DUMP)
16492 {
16493 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16494 res = false;
7d9813f1 16495 }
094e34f2 16496#endif
42b6953b
IB
16497 if (dump & SFRAME_DUMP)
16498 {
16499 if (! dump_section_as_sframe (section, filedata))
16500 res = false;
16501 }
5b18a4bc 16502 }
103f02d3 16503
835f2fae 16504 if (! filedata->is_separate)
0ee3043f 16505 {
835f2fae
NC
16506 /* Check to see if the user requested a
16507 dump of a section that does not exist. */
16508 for (; i < filedata->dump.num_dump_sects; i++)
16509 if (filedata->dump.dump_sects[i])
16510 {
ca0e11aa 16511 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16512 res = false;
835f2fae 16513 }
0ee3043f 16514 }
32ec8896
NC
16515
16516 return res;
5b18a4bc 16517}
103f02d3 16518
5b18a4bc 16519static void
19e6b90e 16520process_mips_fpe_exception (int mask)
5b18a4bc 16521{
19e6b90e
L
16522 if (mask)
16523 {
015dc7e1 16524 bool first = true;
32ec8896 16525
19e6b90e 16526 if (mask & OEX_FPU_INEX)
015dc7e1 16527 fputs ("INEX", stdout), first = false;
19e6b90e 16528 if (mask & OEX_FPU_UFLO)
015dc7e1 16529 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16530 if (mask & OEX_FPU_OFLO)
015dc7e1 16531 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16532 if (mask & OEX_FPU_DIV0)
015dc7e1 16533 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16534 if (mask & OEX_FPU_INVAL)
16535 printf ("%sINVAL", first ? "" : "|");
16536 }
5b18a4bc 16537 else
19e6b90e 16538 fputs ("0", stdout);
5b18a4bc 16539}
103f02d3 16540
f6f0e17b
NC
16541/* Display's the value of TAG at location P. If TAG is
16542 greater than 0 it is assumed to be an unknown tag, and
16543 a message is printed to this effect. Otherwise it is
16544 assumed that a message has already been printed.
16545
16546 If the bottom bit of TAG is set it assumed to have a
16547 string value, otherwise it is assumed to have an integer
16548 value.
16549
16550 Returns an updated P pointing to the first unread byte
16551 beyond the end of TAG's value.
16552
16553 Reads at or beyond END will not be made. */
16554
16555static unsigned char *
60abdbed 16556display_tag_value (signed int tag,
f6f0e17b
NC
16557 unsigned char * p,
16558 const unsigned char * const end)
16559{
26c527e6 16560 uint64_t val;
f6f0e17b
NC
16561
16562 if (tag > 0)
16563 printf (" Tag_unknown_%d: ", tag);
16564
16565 if (p >= end)
16566 {
4082ef84 16567 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16568 }
16569 else if (tag & 1)
16570 {
071436c6
NC
16571 /* PR 17531 file: 027-19978-0.004. */
16572 size_t maxlen = (end - p) - 1;
16573
16574 putchar ('"');
4082ef84
NC
16575 if (maxlen > 0)
16576 {
16577 print_symbol ((int) maxlen, (const char *) p);
16578 p += strnlen ((char *) p, maxlen) + 1;
16579 }
16580 else
16581 {
16582 printf (_("<corrupt string tag>"));
16583 p = (unsigned char *) end;
16584 }
071436c6 16585 printf ("\"\n");
f6f0e17b
NC
16586 }
16587 else
16588 {
cd30bcef 16589 READ_ULEB (val, p, end);
26c527e6 16590 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
16591 }
16592
4082ef84 16593 assert (p <= end);
f6f0e17b
NC
16594 return p;
16595}
16596
53a346d8
CZ
16597/* ARC ABI attributes section. */
16598
16599static unsigned char *
16600display_arc_attribute (unsigned char * p,
16601 const unsigned char * const end)
16602{
16603 unsigned int tag;
53a346d8
CZ
16604 unsigned int val;
16605
cd30bcef 16606 READ_ULEB (tag, p, end);
53a346d8
CZ
16607
16608 switch (tag)
16609 {
16610 case Tag_ARC_PCS_config:
cd30bcef 16611 READ_ULEB (val, p, end);
53a346d8
CZ
16612 printf (" Tag_ARC_PCS_config: ");
16613 switch (val)
16614 {
16615 case 0:
16616 printf (_("Absent/Non standard\n"));
16617 break;
16618 case 1:
16619 printf (_("Bare metal/mwdt\n"));
16620 break;
16621 case 2:
16622 printf (_("Bare metal/newlib\n"));
16623 break;
16624 case 3:
16625 printf (_("Linux/uclibc\n"));
16626 break;
16627 case 4:
16628 printf (_("Linux/glibc\n"));
16629 break;
16630 default:
16631 printf (_("Unknown\n"));
16632 break;
16633 }
16634 break;
16635
16636 case Tag_ARC_CPU_base:
cd30bcef 16637 READ_ULEB (val, p, end);
53a346d8
CZ
16638 printf (" Tag_ARC_CPU_base: ");
16639 switch (val)
16640 {
16641 default:
16642 case TAG_CPU_NONE:
16643 printf (_("Absent\n"));
16644 break;
16645 case TAG_CPU_ARC6xx:
16646 printf ("ARC6xx\n");
16647 break;
16648 case TAG_CPU_ARC7xx:
16649 printf ("ARC7xx\n");
16650 break;
16651 case TAG_CPU_ARCEM:
16652 printf ("ARCEM\n");
16653 break;
16654 case TAG_CPU_ARCHS:
16655 printf ("ARCHS\n");
16656 break;
16657 }
16658 break;
16659
16660 case Tag_ARC_CPU_variation:
cd30bcef 16661 READ_ULEB (val, p, end);
53a346d8
CZ
16662 printf (" Tag_ARC_CPU_variation: ");
16663 switch (val)
16664 {
16665 default:
16666 if (val > 0 && val < 16)
53a346d8 16667 printf ("Core%d\n", val);
d8cbc93b
JL
16668 else
16669 printf ("Unknown\n");
16670 break;
16671
53a346d8
CZ
16672 case 0:
16673 printf (_("Absent\n"));
16674 break;
16675 }
16676 break;
16677
16678 case Tag_ARC_CPU_name:
16679 printf (" Tag_ARC_CPU_name: ");
16680 p = display_tag_value (-1, p, end);
16681 break;
16682
16683 case Tag_ARC_ABI_rf16:
cd30bcef 16684 READ_ULEB (val, p, end);
53a346d8
CZ
16685 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16686 break;
16687
16688 case Tag_ARC_ABI_osver:
cd30bcef 16689 READ_ULEB (val, p, end);
53a346d8
CZ
16690 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16691 break;
16692
16693 case Tag_ARC_ABI_pic:
16694 case Tag_ARC_ABI_sda:
cd30bcef 16695 READ_ULEB (val, p, end);
53a346d8
CZ
16696 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16697 : " Tag_ARC_ABI_pic: ");
16698 switch (val)
16699 {
16700 case 0:
16701 printf (_("Absent\n"));
16702 break;
16703 case 1:
16704 printf ("MWDT\n");
16705 break;
16706 case 2:
16707 printf ("GNU\n");
16708 break;
16709 default:
16710 printf (_("Unknown\n"));
16711 break;
16712 }
16713 break;
16714
16715 case Tag_ARC_ABI_tls:
cd30bcef 16716 READ_ULEB (val, p, end);
53a346d8
CZ
16717 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16718 break;
16719
16720 case Tag_ARC_ABI_enumsize:
cd30bcef 16721 READ_ULEB (val, p, end);
53a346d8
CZ
16722 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16723 _("smallest"));
16724 break;
16725
16726 case Tag_ARC_ABI_exceptions:
cd30bcef 16727 READ_ULEB (val, p, end);
53a346d8
CZ
16728 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16729 : _("default"));
16730 break;
16731
16732 case Tag_ARC_ABI_double_size:
cd30bcef 16733 READ_ULEB (val, p, end);
53a346d8
CZ
16734 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16735 break;
16736
16737 case Tag_ARC_ISA_config:
16738 printf (" Tag_ARC_ISA_config: ");
16739 p = display_tag_value (-1, p, end);
16740 break;
16741
16742 case Tag_ARC_ISA_apex:
16743 printf (" Tag_ARC_ISA_apex: ");
16744 p = display_tag_value (-1, p, end);
16745 break;
16746
16747 case Tag_ARC_ISA_mpy_option:
cd30bcef 16748 READ_ULEB (val, p, end);
53a346d8
CZ
16749 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16750 break;
16751
db1e1b45 16752 case Tag_ARC_ATR_version:
cd30bcef 16753 READ_ULEB (val, p, end);
db1e1b45 16754 printf (" Tag_ARC_ATR_version: %d\n", val);
16755 break;
16756
53a346d8
CZ
16757 default:
16758 return display_tag_value (tag & 1, p, end);
16759 }
16760
16761 return p;
16762}
16763
11c1ff18
PB
16764/* ARM EABI attributes section. */
16765typedef struct
16766{
70e99720 16767 unsigned int tag;
2cf0635d 16768 const char * name;
11c1ff18 16769 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16770 unsigned int type;
288f0ba2 16771 const char *const *table;
11c1ff18
PB
16772} arm_attr_public_tag;
16773
288f0ba2 16774static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16775 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16776 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16777 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16778 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16779static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16780static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16781 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16782static const char *const arm_attr_tag_FP_arch[] =
bca38921 16783 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16784 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16785static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16786static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16787 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16788 "NEON for ARMv8.1"};
288f0ba2 16789static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16790 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16791 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16792static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16793 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16794static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16795 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16796static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16797 {"Absolute", "PC-relative", "None"};
288f0ba2 16798static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16799 {"None", "direct", "GOT-indirect"};
288f0ba2 16800static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16801 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16802static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16803static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16804 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16805static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16806static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16807static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16808 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16809static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16810 {"Unused", "small", "int", "forced to int"};
288f0ba2 16811static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16812 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16813static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16814 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16815static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16816 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16817static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16818 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16819 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16820static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16821 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16822 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16823static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16824static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16825 {"Not Allowed", "Allowed"};
288f0ba2 16826static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16827 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16828static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16829 {"Follow architecture", "Allowed"};
288f0ba2 16830static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16831 {"Not Allowed", "Allowed"};
288f0ba2 16832static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16833 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16834 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16835static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16836static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16837 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16838 "TrustZone and Virtualization Extensions"};
288f0ba2 16839static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16840 {"Not Allowed", "Allowed"};
11c1ff18 16841
288f0ba2 16842static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16843 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16844
99db83d0
AC
16845static const char * arm_attr_tag_PAC_extension[] =
16846 {"No PAC/AUT instructions",
16847 "PAC/AUT instructions permitted in the NOP space",
16848 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16849
4b535030
AC
16850static const char * arm_attr_tag_BTI_extension[] =
16851 {"BTI instructions not permitted",
16852 "BTI instructions permitted in the NOP space",
16853 "BTI instructions permitted in the NOP and in the non-NOP space"};
16854
b81ee92f
AC
16855static const char * arm_attr_tag_BTI_use[] =
16856 {"Compiled without branch target enforcement",
16857 "Compiled with branch target enforcement"};
16858
c9fed665
AC
16859static const char * arm_attr_tag_PACRET_use[] =
16860 {"Compiled without return address signing and authentication",
16861 "Compiled with return address signing and authentication"};
16862
11c1ff18
PB
16863#define LOOKUP(id, name) \
16864 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16865static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16866{
16867 {4, "CPU_raw_name", 1, NULL},
16868 {5, "CPU_name", 1, NULL},
16869 LOOKUP(6, CPU_arch),
16870 {7, "CPU_arch_profile", 0, NULL},
16871 LOOKUP(8, ARM_ISA_use),
16872 LOOKUP(9, THUMB_ISA_use),
75375b3e 16873 LOOKUP(10, FP_arch),
11c1ff18 16874 LOOKUP(11, WMMX_arch),
f5f53991
AS
16875 LOOKUP(12, Advanced_SIMD_arch),
16876 LOOKUP(13, PCS_config),
11c1ff18
PB
16877 LOOKUP(14, ABI_PCS_R9_use),
16878 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16879 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16880 LOOKUP(17, ABI_PCS_GOT_use),
16881 LOOKUP(18, ABI_PCS_wchar_t),
16882 LOOKUP(19, ABI_FP_rounding),
16883 LOOKUP(20, ABI_FP_denormal),
16884 LOOKUP(21, ABI_FP_exceptions),
16885 LOOKUP(22, ABI_FP_user_exceptions),
16886 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16887 {24, "ABI_align_needed", 0, NULL},
16888 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16889 LOOKUP(26, ABI_enum_size),
16890 LOOKUP(27, ABI_HardFP_use),
16891 LOOKUP(28, ABI_VFP_args),
16892 LOOKUP(29, ABI_WMMX_args),
16893 LOOKUP(30, ABI_optimization_goals),
16894 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16895 {32, "compatibility", 0, NULL},
f5f53991 16896 LOOKUP(34, CPU_unaligned_access),
75375b3e 16897 LOOKUP(36, FP_HP_extension),
8e79c3df 16898 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16899 LOOKUP(42, MPextension_use),
16900 LOOKUP(44, DIV_use),
15afaa63 16901 LOOKUP(46, DSP_extension),
a7ad558c 16902 LOOKUP(48, MVE_arch),
99db83d0 16903 LOOKUP(50, PAC_extension),
4b535030 16904 LOOKUP(52, BTI_extension),
b81ee92f 16905 LOOKUP(74, BTI_use),
c9fed665 16906 LOOKUP(76, PACRET_use),
f5f53991
AS
16907 {64, "nodefaults", 0, NULL},
16908 {65, "also_compatible_with", 0, NULL},
16909 LOOKUP(66, T2EE_use),
16910 {67, "conformance", 1, NULL},
16911 LOOKUP(68, Virtualization_use),
cd21e546 16912 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16913};
16914#undef LOOKUP
16915
11c1ff18 16916static unsigned char *
f6f0e17b
NC
16917display_arm_attribute (unsigned char * p,
16918 const unsigned char * const end)
11c1ff18 16919{
70e99720 16920 unsigned int tag;
70e99720 16921 unsigned int val;
2cf0635d 16922 arm_attr_public_tag * attr;
11c1ff18 16923 unsigned i;
70e99720 16924 unsigned int type;
11c1ff18 16925
cd30bcef 16926 READ_ULEB (tag, p, end);
11c1ff18 16927 attr = NULL;
2cf0635d 16928 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16929 {
16930 if (arm_attr_public_tags[i].tag == tag)
16931 {
16932 attr = &arm_attr_public_tags[i];
16933 break;
16934 }
16935 }
16936
16937 if (attr)
16938 {
16939 printf (" Tag_%s: ", attr->name);
16940 switch (attr->type)
16941 {
16942 case 0:
16943 switch (tag)
16944 {
16945 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16946 READ_ULEB (val, p, end);
11c1ff18
PB
16947 switch (val)
16948 {
2b692964
NC
16949 case 0: printf (_("None\n")); break;
16950 case 'A': printf (_("Application\n")); break;
16951 case 'R': printf (_("Realtime\n")); break;
16952 case 'M': printf (_("Microcontroller\n")); break;
16953 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16954 default: printf ("??? (%d)\n", val); break;
16955 }
16956 break;
16957
75375b3e 16958 case 24: /* Tag_align_needed. */
cd30bcef 16959 READ_ULEB (val, p, end);
75375b3e
MGD
16960 switch (val)
16961 {
2b692964
NC
16962 case 0: printf (_("None\n")); break;
16963 case 1: printf (_("8-byte\n")); break;
16964 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16965 case 3: printf ("??? 3\n"); break;
16966 default:
16967 if (val <= 12)
dd24e3da 16968 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16969 1 << val);
16970 else
16971 printf ("??? (%d)\n", val);
16972 break;
16973 }
16974 break;
16975
16976 case 25: /* Tag_align_preserved. */
cd30bcef 16977 READ_ULEB (val, p, end);
75375b3e
MGD
16978 switch (val)
16979 {
2b692964
NC
16980 case 0: printf (_("None\n")); break;
16981 case 1: printf (_("8-byte, except leaf SP\n")); break;
16982 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16983 case 3: printf ("??? 3\n"); break;
16984 default:
16985 if (val <= 12)
dd24e3da 16986 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16987 1 << val);
16988 else
16989 printf ("??? (%d)\n", val);
16990 break;
16991 }
16992 break;
16993
11c1ff18 16994 case 32: /* Tag_compatibility. */
071436c6 16995 {
cd30bcef 16996 READ_ULEB (val, p, end);
071436c6 16997 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16998 if (p < end - 1)
16999 {
17000 size_t maxlen = (end - p) - 1;
17001
17002 print_symbol ((int) maxlen, (const char *) p);
17003 p += strnlen ((char *) p, maxlen) + 1;
17004 }
17005 else
17006 {
17007 printf (_("<corrupt>"));
17008 p = (unsigned char *) end;
17009 }
071436c6 17010 putchar ('\n');
071436c6 17011 }
11c1ff18
PB
17012 break;
17013
f5f53991 17014 case 64: /* Tag_nodefaults. */
541a3cbd
NC
17015 /* PR 17531: file: 001-505008-0.01. */
17016 if (p < end)
17017 p++;
2b692964 17018 printf (_("True\n"));
f5f53991
AS
17019 break;
17020
17021 case 65: /* Tag_also_compatible_with. */
cd30bcef 17022 READ_ULEB (val, p, end);
f5f53991
AS
17023 if (val == 6 /* Tag_CPU_arch. */)
17024 {
cd30bcef 17025 READ_ULEB (val, p, end);
071436c6 17026 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
17027 printf ("??? (%d)\n", val);
17028 else
17029 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17030 }
17031 else
17032 printf ("???\n");
071436c6
NC
17033 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17034 ;
f5f53991
AS
17035 break;
17036
11c1ff18 17037 default:
bee0ee85
NC
17038 printf (_("<unknown: %d>\n"), tag);
17039 break;
11c1ff18
PB
17040 }
17041 return p;
17042
17043 case 1:
f6f0e17b 17044 return display_tag_value (-1, p, end);
11c1ff18 17045 case 2:
f6f0e17b 17046 return display_tag_value (0, p, end);
11c1ff18
PB
17047
17048 default:
17049 assert (attr->type & 0x80);
cd30bcef 17050 READ_ULEB (val, p, end);
11c1ff18
PB
17051 type = attr->type & 0x7f;
17052 if (val >= type)
17053 printf ("??? (%d)\n", val);
17054 else
17055 printf ("%s\n", attr->table[val]);
17056 return p;
17057 }
17058 }
11c1ff18 17059
f6f0e17b 17060 return display_tag_value (tag, p, end);
11c1ff18
PB
17061}
17062
104d59d1 17063static unsigned char *
60bca95a 17064display_gnu_attribute (unsigned char * p,
60abdbed 17065 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 17066 const unsigned char * const end)
104d59d1 17067{
cd30bcef 17068 unsigned int tag;
60abdbed 17069 unsigned int val;
104d59d1 17070
cd30bcef 17071 READ_ULEB (tag, p, end);
104d59d1
JM
17072
17073 /* Tag_compatibility is the only generic GNU attribute defined at
17074 present. */
17075 if (tag == 32)
17076 {
cd30bcef 17077 READ_ULEB (val, p, end);
071436c6
NC
17078
17079 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
17080 if (p == end)
17081 {
071436c6 17082 printf (_("<corrupt>\n"));
f6f0e17b
NC
17083 warn (_("corrupt vendor attribute\n"));
17084 }
17085 else
17086 {
4082ef84
NC
17087 if (p < end - 1)
17088 {
17089 size_t maxlen = (end - p) - 1;
071436c6 17090
4082ef84
NC
17091 print_symbol ((int) maxlen, (const char *) p);
17092 p += strnlen ((char *) p, maxlen) + 1;
17093 }
17094 else
17095 {
17096 printf (_("<corrupt>"));
17097 p = (unsigned char *) end;
17098 }
071436c6 17099 putchar ('\n');
f6f0e17b 17100 }
104d59d1
JM
17101 return p;
17102 }
17103
17104 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 17105 return display_proc_gnu_attribute (p, tag, end);
104d59d1 17106
f6f0e17b 17107 return display_tag_value (tag, p, end);
104d59d1
JM
17108}
17109
85f7484a
PB
17110static unsigned char *
17111display_m68k_gnu_attribute (unsigned char * p,
17112 unsigned int tag,
17113 const unsigned char * const end)
17114{
17115 unsigned int val;
17116
17117 if (tag == Tag_GNU_M68K_ABI_FP)
17118 {
17119 printf (" Tag_GNU_M68K_ABI_FP: ");
17120 if (p == end)
17121 {
17122 printf (_("<corrupt>\n"));
17123 return p;
17124 }
17125 READ_ULEB (val, p, end);
17126
17127 if (val > 3)
17128 printf ("(%#x), ", val);
17129
17130 switch (val & 3)
17131 {
17132 case 0:
17133 printf (_("unspecified hard/soft float\n"));
17134 break;
17135 case 1:
17136 printf (_("hard float\n"));
17137 break;
17138 case 2:
17139 printf (_("soft float\n"));
17140 break;
17141 }
17142 return p;
17143 }
17144
17145 return display_tag_value (tag & 1, p, end);
17146}
17147
34c8bcba 17148static unsigned char *
f6f0e17b 17149display_power_gnu_attribute (unsigned char * p,
60abdbed 17150 unsigned int tag,
f6f0e17b 17151 const unsigned char * const end)
34c8bcba 17152{
005d79fd 17153 unsigned int val;
34c8bcba
JM
17154
17155 if (tag == Tag_GNU_Power_ABI_FP)
17156 {
34c8bcba 17157 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 17158 if (p == end)
005d79fd
AM
17159 {
17160 printf (_("<corrupt>\n"));
17161 return p;
17162 }
cd30bcef 17163 READ_ULEB (val, p, end);
60bca95a 17164
005d79fd
AM
17165 if (val > 15)
17166 printf ("(%#x), ", val);
17167
17168 switch (val & 3)
34c8bcba
JM
17169 {
17170 case 0:
005d79fd 17171 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17172 break;
17173 case 1:
005d79fd 17174 printf (_("hard float, "));
34c8bcba
JM
17175 break;
17176 case 2:
005d79fd 17177 printf (_("soft float, "));
34c8bcba 17178 break;
3c7b9897 17179 case 3:
005d79fd 17180 printf (_("single-precision hard float, "));
3c7b9897 17181 break;
005d79fd
AM
17182 }
17183
17184 switch (val & 0xC)
17185 {
17186 case 0:
17187 printf (_("unspecified long double\n"));
17188 break;
17189 case 4:
17190 printf (_("128-bit IBM long double\n"));
17191 break;
17192 case 8:
17193 printf (_("64-bit long double\n"));
17194 break;
17195 case 12:
17196 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17197 break;
17198 }
17199 return p;
005d79fd 17200 }
34c8bcba 17201
c6e65352
DJ
17202 if (tag == Tag_GNU_Power_ABI_Vector)
17203 {
c6e65352 17204 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17205 if (p == end)
005d79fd
AM
17206 {
17207 printf (_("<corrupt>\n"));
17208 return p;
17209 }
cd30bcef 17210 READ_ULEB (val, p, end);
005d79fd
AM
17211
17212 if (val > 3)
17213 printf ("(%#x), ", val);
17214
17215 switch (val & 3)
c6e65352
DJ
17216 {
17217 case 0:
005d79fd 17218 printf (_("unspecified\n"));
c6e65352
DJ
17219 break;
17220 case 1:
005d79fd 17221 printf (_("generic\n"));
c6e65352
DJ
17222 break;
17223 case 2:
17224 printf ("AltiVec\n");
17225 break;
17226 case 3:
17227 printf ("SPE\n");
17228 break;
c6e65352
DJ
17229 }
17230 return p;
005d79fd 17231 }
c6e65352 17232
f82e0623
NF
17233 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17234 {
005d79fd 17235 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17236 if (p == end)
f6f0e17b 17237 {
005d79fd 17238 printf (_("<corrupt>\n"));
f6f0e17b
NC
17239 return p;
17240 }
cd30bcef 17241 READ_ULEB (val, p, end);
0b4362b0 17242
005d79fd
AM
17243 if (val > 2)
17244 printf ("(%#x), ", val);
17245
17246 switch (val & 3)
17247 {
17248 case 0:
17249 printf (_("unspecified\n"));
17250 break;
17251 case 1:
17252 printf ("r3/r4\n");
17253 break;
17254 case 2:
17255 printf (_("memory\n"));
17256 break;
17257 case 3:
17258 printf ("???\n");
17259 break;
17260 }
f82e0623
NF
17261 return p;
17262 }
17263
f6f0e17b 17264 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17265}
17266
643f7afb
AK
17267static unsigned char *
17268display_s390_gnu_attribute (unsigned char * p,
60abdbed 17269 unsigned int tag,
643f7afb
AK
17270 const unsigned char * const end)
17271{
cd30bcef 17272 unsigned int val;
643f7afb
AK
17273
17274 if (tag == Tag_GNU_S390_ABI_Vector)
17275 {
643f7afb 17276 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17277 READ_ULEB (val, p, end);
643f7afb
AK
17278
17279 switch (val)
17280 {
17281 case 0:
17282 printf (_("any\n"));
17283 break;
17284 case 1:
17285 printf (_("software\n"));
17286 break;
17287 case 2:
17288 printf (_("hardware\n"));
17289 break;
17290 default:
17291 printf ("??? (%d)\n", val);
17292 break;
17293 }
17294 return p;
17295 }
17296
17297 return display_tag_value (tag & 1, p, end);
17298}
17299
9e8c70f9 17300static void
60abdbed 17301display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17302{
17303 if (mask)
17304 {
015dc7e1 17305 bool first = true;
071436c6 17306
9e8c70f9 17307 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17308 fputs ("mul32", stdout), first = false;
9e8c70f9 17309 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17310 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17311 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17312 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17313 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17314 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17315 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17316 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17317 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17318 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17319 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17320 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17321 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17322 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17323 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17324 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17325 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17326 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17327 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17328 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17329 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17330 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17331 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17332 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17333 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17334 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17335 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17336 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17337 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17338 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17339 }
17340 else
071436c6
NC
17341 fputc ('0', stdout);
17342 fputc ('\n', stdout);
9e8c70f9
DM
17343}
17344
3d68f91c 17345static void
60abdbed 17346display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17347{
17348 if (mask)
17349 {
015dc7e1 17350 bool first = true;
071436c6 17351
3d68f91c 17352 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17353 fputs ("fjathplus", stdout), first = false;
3d68f91c 17354 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17355 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17356 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17357 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17358 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17359 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17360 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17361 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17362 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17363 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17364 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17365 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17366 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17367 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17368 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17369 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17370 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17371 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17372 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17373 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17374 }
17375 else
071436c6
NC
17376 fputc ('0', stdout);
17377 fputc ('\n', stdout);
3d68f91c
JM
17378}
17379
9e8c70f9 17380static unsigned char *
f6f0e17b 17381display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17382 unsigned int tag,
f6f0e17b 17383 const unsigned char * const end)
9e8c70f9 17384{
cd30bcef 17385 unsigned int val;
3d68f91c 17386
9e8c70f9
DM
17387 if (tag == Tag_GNU_Sparc_HWCAPS)
17388 {
cd30bcef 17389 READ_ULEB (val, p, end);
9e8c70f9 17390 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17391 display_sparc_hwcaps (val);
17392 return p;
3d68f91c
JM
17393 }
17394 if (tag == Tag_GNU_Sparc_HWCAPS2)
17395 {
cd30bcef 17396 READ_ULEB (val, p, end);
3d68f91c
JM
17397 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17398 display_sparc_hwcaps2 (val);
17399 return p;
17400 }
9e8c70f9 17401
f6f0e17b 17402 return display_tag_value (tag, p, end);
9e8c70f9
DM
17403}
17404
351cdf24 17405static void
32ec8896 17406print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17407{
17408 switch (val)
17409 {
17410 case Val_GNU_MIPS_ABI_FP_ANY:
17411 printf (_("Hard or soft float\n"));
17412 break;
17413 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17414 printf (_("Hard float (double precision)\n"));
17415 break;
17416 case Val_GNU_MIPS_ABI_FP_SINGLE:
17417 printf (_("Hard float (single precision)\n"));
17418 break;
17419 case Val_GNU_MIPS_ABI_FP_SOFT:
17420 printf (_("Soft float\n"));
17421 break;
17422 case Val_GNU_MIPS_ABI_FP_OLD_64:
17423 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17424 break;
17425 case Val_GNU_MIPS_ABI_FP_XX:
17426 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17427 break;
17428 case Val_GNU_MIPS_ABI_FP_64:
17429 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17430 break;
17431 case Val_GNU_MIPS_ABI_FP_64A:
17432 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17433 break;
3350cc01
CM
17434 case Val_GNU_MIPS_ABI_FP_NAN2008:
17435 printf (_("NaN 2008 compatibility\n"));
17436 break;
351cdf24
MF
17437 default:
17438 printf ("??? (%d)\n", val);
17439 break;
17440 }
17441}
17442
2cf19d5c 17443static unsigned char *
f6f0e17b 17444display_mips_gnu_attribute (unsigned char * p,
60abdbed 17445 unsigned int tag,
f6f0e17b 17446 const unsigned char * const end)
2cf19d5c 17447{
2cf19d5c
JM
17448 if (tag == Tag_GNU_MIPS_ABI_FP)
17449 {
32ec8896 17450 unsigned int val;
f6f0e17b 17451
2cf19d5c 17452 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17453 READ_ULEB (val, p, end);
351cdf24 17454 print_mips_fp_abi_value (val);
2cf19d5c
JM
17455 return p;
17456 }
17457
a9f58168
CF
17458 if (tag == Tag_GNU_MIPS_ABI_MSA)
17459 {
32ec8896 17460 unsigned int val;
a9f58168 17461
a9f58168 17462 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17463 READ_ULEB (val, p, end);
a9f58168
CF
17464
17465 switch (val)
17466 {
17467 case Val_GNU_MIPS_ABI_MSA_ANY:
17468 printf (_("Any MSA or not\n"));
17469 break;
17470 case Val_GNU_MIPS_ABI_MSA_128:
17471 printf (_("128-bit MSA\n"));
17472 break;
17473 default:
17474 printf ("??? (%d)\n", val);
17475 break;
17476 }
17477 return p;
17478 }
17479
f6f0e17b 17480 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17481}
17482
59e6276b 17483static unsigned char *
f6f0e17b
NC
17484display_tic6x_attribute (unsigned char * p,
17485 const unsigned char * const end)
59e6276b 17486{
60abdbed 17487 unsigned int tag;
cd30bcef 17488 unsigned int val;
59e6276b 17489
cd30bcef 17490 READ_ULEB (tag, p, end);
59e6276b
JM
17491
17492 switch (tag)
17493 {
75fa6dc1 17494 case Tag_ISA:
75fa6dc1 17495 printf (" Tag_ISA: ");
cd30bcef 17496 READ_ULEB (val, p, end);
59e6276b
JM
17497
17498 switch (val)
17499 {
75fa6dc1 17500 case C6XABI_Tag_ISA_none:
59e6276b
JM
17501 printf (_("None\n"));
17502 break;
75fa6dc1 17503 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17504 printf ("C62x\n");
17505 break;
75fa6dc1 17506 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17507 printf ("C67x\n");
17508 break;
75fa6dc1 17509 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17510 printf ("C67x+\n");
17511 break;
75fa6dc1 17512 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17513 printf ("C64x\n");
17514 break;
75fa6dc1 17515 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17516 printf ("C64x+\n");
17517 break;
75fa6dc1 17518 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17519 printf ("C674x\n");
17520 break;
17521 default:
17522 printf ("??? (%d)\n", val);
17523 break;
17524 }
17525 return p;
17526
87779176 17527 case Tag_ABI_wchar_t:
87779176 17528 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17529 READ_ULEB (val, p, end);
87779176
JM
17530 switch (val)
17531 {
17532 case 0:
17533 printf (_("Not used\n"));
17534 break;
17535 case 1:
17536 printf (_("2 bytes\n"));
17537 break;
17538 case 2:
17539 printf (_("4 bytes\n"));
17540 break;
17541 default:
17542 printf ("??? (%d)\n", val);
17543 break;
17544 }
17545 return p;
17546
17547 case Tag_ABI_stack_align_needed:
87779176 17548 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17549 READ_ULEB (val, p, end);
87779176
JM
17550 switch (val)
17551 {
17552 case 0:
17553 printf (_("8-byte\n"));
17554 break;
17555 case 1:
17556 printf (_("16-byte\n"));
17557 break;
17558 default:
17559 printf ("??? (%d)\n", val);
17560 break;
17561 }
17562 return p;
17563
17564 case Tag_ABI_stack_align_preserved:
cd30bcef 17565 READ_ULEB (val, p, end);
87779176
JM
17566 printf (" Tag_ABI_stack_align_preserved: ");
17567 switch (val)
17568 {
17569 case 0:
17570 printf (_("8-byte\n"));
17571 break;
17572 case 1:
17573 printf (_("16-byte\n"));
17574 break;
17575 default:
17576 printf ("??? (%d)\n", val);
17577 break;
17578 }
17579 return p;
17580
b5593623 17581 case Tag_ABI_DSBT:
cd30bcef 17582 READ_ULEB (val, p, end);
b5593623
JM
17583 printf (" Tag_ABI_DSBT: ");
17584 switch (val)
17585 {
17586 case 0:
17587 printf (_("DSBT addressing not used\n"));
17588 break;
17589 case 1:
17590 printf (_("DSBT addressing used\n"));
17591 break;
17592 default:
17593 printf ("??? (%d)\n", val);
17594 break;
17595 }
17596 return p;
17597
87779176 17598 case Tag_ABI_PID:
cd30bcef 17599 READ_ULEB (val, p, end);
87779176
JM
17600 printf (" Tag_ABI_PID: ");
17601 switch (val)
17602 {
17603 case 0:
17604 printf (_("Data addressing position-dependent\n"));
17605 break;
17606 case 1:
17607 printf (_("Data addressing position-independent, GOT near DP\n"));
17608 break;
17609 case 2:
17610 printf (_("Data addressing position-independent, GOT far from DP\n"));
17611 break;
17612 default:
17613 printf ("??? (%d)\n", val);
17614 break;
17615 }
17616 return p;
17617
17618 case Tag_ABI_PIC:
cd30bcef 17619 READ_ULEB (val, p, end);
87779176
JM
17620 printf (" Tag_ABI_PIC: ");
17621 switch (val)
17622 {
17623 case 0:
17624 printf (_("Code addressing position-dependent\n"));
17625 break;
17626 case 1:
17627 printf (_("Code addressing position-independent\n"));
17628 break;
17629 default:
17630 printf ("??? (%d)\n", val);
17631 break;
17632 }
17633 return p;
17634
17635 case Tag_ABI_array_object_alignment:
cd30bcef 17636 READ_ULEB (val, p, end);
87779176
JM
17637 printf (" Tag_ABI_array_object_alignment: ");
17638 switch (val)
17639 {
17640 case 0:
17641 printf (_("8-byte\n"));
17642 break;
17643 case 1:
17644 printf (_("4-byte\n"));
17645 break;
17646 case 2:
17647 printf (_("16-byte\n"));
17648 break;
17649 default:
17650 printf ("??? (%d)\n", val);
17651 break;
17652 }
17653 return p;
17654
17655 case Tag_ABI_array_object_align_expected:
cd30bcef 17656 READ_ULEB (val, p, end);
87779176
JM
17657 printf (" Tag_ABI_array_object_align_expected: ");
17658 switch (val)
17659 {
17660 case 0:
17661 printf (_("8-byte\n"));
17662 break;
17663 case 1:
17664 printf (_("4-byte\n"));
17665 break;
17666 case 2:
17667 printf (_("16-byte\n"));
17668 break;
17669 default:
17670 printf ("??? (%d)\n", val);
17671 break;
17672 }
17673 return p;
17674
3cbd1c06 17675 case Tag_ABI_compatibility:
071436c6 17676 {
cd30bcef 17677 READ_ULEB (val, p, end);
071436c6 17678 printf (" Tag_ABI_compatibility: ");
071436c6 17679 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17680 if (p < end - 1)
17681 {
17682 size_t maxlen = (end - p) - 1;
17683
17684 print_symbol ((int) maxlen, (const char *) p);
17685 p += strnlen ((char *) p, maxlen) + 1;
17686 }
17687 else
17688 {
17689 printf (_("<corrupt>"));
17690 p = (unsigned char *) end;
17691 }
071436c6 17692 putchar ('\n');
071436c6
NC
17693 return p;
17694 }
87779176
JM
17695
17696 case Tag_ABI_conformance:
071436c6 17697 {
4082ef84
NC
17698 printf (" Tag_ABI_conformance: \"");
17699 if (p < end - 1)
17700 {
17701 size_t maxlen = (end - p) - 1;
071436c6 17702
4082ef84
NC
17703 print_symbol ((int) maxlen, (const char *) p);
17704 p += strnlen ((char *) p, maxlen) + 1;
17705 }
17706 else
17707 {
17708 printf (_("<corrupt>"));
17709 p = (unsigned char *) end;
17710 }
071436c6 17711 printf ("\"\n");
071436c6
NC
17712 return p;
17713 }
59e6276b
JM
17714 }
17715
f6f0e17b
NC
17716 return display_tag_value (tag, p, end);
17717}
59e6276b 17718
f6f0e17b 17719static void
60abdbed 17720display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 17721{
26c527e6 17722 uint64_t addr = 0;
f6f0e17b
NC
17723 size_t bytes = end - p;
17724
feceaa59 17725 assert (end >= p);
f6f0e17b 17726 while (bytes)
87779176 17727 {
f6f0e17b
NC
17728 int j;
17729 int k;
17730 int lbytes = (bytes > 16 ? 16 : bytes);
17731
26c527e6 17732 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
17733
17734 for (j = 0; j < 16; j++)
17735 {
17736 if (j < lbytes)
17737 printf ("%2.2x", p[j]);
17738 else
17739 printf (" ");
17740
17741 if ((j & 3) == 3)
17742 printf (" ");
17743 }
17744
17745 for (j = 0; j < lbytes; j++)
17746 {
17747 k = p[j];
17748 if (k >= ' ' && k < 0x7f)
17749 printf ("%c", k);
17750 else
17751 printf (".");
17752 }
17753
17754 putchar ('\n');
17755
17756 p += lbytes;
17757 bytes -= lbytes;
17758 addr += lbytes;
87779176 17759 }
59e6276b 17760
f6f0e17b 17761 putchar ('\n');
59e6276b
JM
17762}
17763
13761a11 17764static unsigned char *
b0191216 17765display_msp430_attribute (unsigned char * p,
26c527e6 17766 const unsigned char * const end)
13761a11 17767{
26c527e6
AM
17768 uint64_t val;
17769 uint64_t tag;
13761a11 17770
cd30bcef 17771 READ_ULEB (tag, p, end);
0b4362b0 17772
13761a11
NC
17773 switch (tag)
17774 {
17775 case OFBA_MSPABI_Tag_ISA:
13761a11 17776 printf (" Tag_ISA: ");
cd30bcef 17777 READ_ULEB (val, p, end);
13761a11
NC
17778 switch (val)
17779 {
17780 case 0: printf (_("None\n")); break;
17781 case 1: printf (_("MSP430\n")); break;
17782 case 2: printf (_("MSP430X\n")); break;
26c527e6 17783 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17784 }
17785 break;
17786
17787 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17788 printf (" Tag_Code_Model: ");
cd30bcef 17789 READ_ULEB (val, p, end);
13761a11
NC
17790 switch (val)
17791 {
17792 case 0: printf (_("None\n")); break;
17793 case 1: printf (_("Small\n")); break;
17794 case 2: printf (_("Large\n")); break;
26c527e6 17795 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17796 }
17797 break;
17798
17799 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17800 printf (" Tag_Data_Model: ");
cd30bcef 17801 READ_ULEB (val, p, end);
13761a11
NC
17802 switch (val)
17803 {
17804 case 0: printf (_("None\n")); break;
17805 case 1: printf (_("Small\n")); break;
17806 case 2: printf (_("Large\n")); break;
17807 case 3: printf (_("Restricted Large\n")); break;
26c527e6 17808 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17809 }
17810 break;
17811
17812 default:
26c527e6 17813 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
17814
17815 if (tag & 1)
17816 {
071436c6 17817 putchar ('"');
4082ef84
NC
17818 if (p < end - 1)
17819 {
17820 size_t maxlen = (end - p) - 1;
17821
17822 print_symbol ((int) maxlen, (const char *) p);
17823 p += strnlen ((char *) p, maxlen) + 1;
17824 }
17825 else
17826 {
17827 printf (_("<corrupt>"));
17828 p = (unsigned char *) end;
17829 }
071436c6 17830 printf ("\"\n");
13761a11
NC
17831 }
17832 else
17833 {
cd30bcef 17834 READ_ULEB (val, p, end);
26c527e6 17835 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
17836 }
17837 break;
17838 }
17839
4082ef84 17840 assert (p <= end);
13761a11
NC
17841 return p;
17842}
17843
c0ea7c52
JL
17844static unsigned char *
17845display_msp430_gnu_attribute (unsigned char * p,
17846 unsigned int tag,
17847 const unsigned char * const end)
17848{
17849 if (tag == Tag_GNU_MSP430_Data_Region)
17850 {
26c527e6 17851 uint64_t val;
c0ea7c52 17852
c0ea7c52 17853 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17854 READ_ULEB (val, p, end);
c0ea7c52
JL
17855
17856 switch (val)
17857 {
17858 case Val_GNU_MSP430_Data_Region_Any:
17859 printf (_("Any Region\n"));
17860 break;
17861 case Val_GNU_MSP430_Data_Region_Lower:
17862 printf (_("Lower Region Only\n"));
17863 break;
17864 default:
26c527e6 17865 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
17866 }
17867 return p;
17868 }
17869 return display_tag_value (tag & 1, p, end);
17870}
17871
2dc8dd17
JW
17872struct riscv_attr_tag_t {
17873 const char *name;
cd30bcef 17874 unsigned int tag;
2dc8dd17
JW
17875};
17876
17877static struct riscv_attr_tag_t riscv_attr_tag[] =
17878{
17879#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17880 T(arch),
17881 T(priv_spec),
17882 T(priv_spec_minor),
17883 T(priv_spec_revision),
17884 T(unaligned_access),
17885 T(stack_align),
17886#undef T
17887};
17888
17889static unsigned char *
17890display_riscv_attribute (unsigned char *p,
17891 const unsigned char * const end)
17892{
26c527e6
AM
17893 uint64_t val;
17894 uint64_t tag;
2dc8dd17
JW
17895 struct riscv_attr_tag_t *attr = NULL;
17896 unsigned i;
17897
cd30bcef 17898 READ_ULEB (tag, p, end);
2dc8dd17
JW
17899
17900 /* Find the name of attribute. */
17901 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17902 {
17903 if (riscv_attr_tag[i].tag == tag)
17904 {
17905 attr = &riscv_attr_tag[i];
17906 break;
17907 }
17908 }
17909
17910 if (attr)
17911 printf (" %s: ", attr->name);
17912 else
17913 return display_tag_value (tag, p, end);
17914
17915 switch (tag)
17916 {
17917 case Tag_RISCV_priv_spec:
17918 case Tag_RISCV_priv_spec_minor:
17919 case Tag_RISCV_priv_spec_revision:
cd30bcef 17920 READ_ULEB (val, p, end);
26c527e6 17921 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
17922 break;
17923 case Tag_RISCV_unaligned_access:
cd30bcef 17924 READ_ULEB (val, p, end);
2dc8dd17
JW
17925 switch (val)
17926 {
17927 case 0:
17928 printf (_("No unaligned access\n"));
17929 break;
17930 case 1:
17931 printf (_("Unaligned access\n"));
17932 break;
17933 }
17934 break;
17935 case Tag_RISCV_stack_align:
cd30bcef 17936 READ_ULEB (val, p, end);
26c527e6 17937 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
17938 break;
17939 case Tag_RISCV_arch:
17940 p = display_tag_value (-1, p, end);
17941 break;
17942 default:
17943 return display_tag_value (tag, p, end);
17944 }
17945
17946 return p;
17947}
17948
0861f561
CQ
17949static unsigned char *
17950display_csky_attribute (unsigned char * p,
17951 const unsigned char * const end)
17952{
26c527e6
AM
17953 uint64_t tag;
17954 uint64_t val;
0861f561
CQ
17955 READ_ULEB (tag, p, end);
17956
17957 if (tag >= Tag_CSKY_MAX)
17958 {
17959 return display_tag_value (-1, p, end);
17960 }
17961
17962 switch (tag)
17963 {
17964 case Tag_CSKY_ARCH_NAME:
17965 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17966 return display_tag_value (-1, p, end);
17967 case Tag_CSKY_CPU_NAME:
17968 printf (" Tag_CSKY_CPU_NAME:\t\t");
17969 return display_tag_value (-1, p, end);
17970
17971 case Tag_CSKY_ISA_FLAGS:
17972 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17973 return display_tag_value (0, p, end);
17974 case Tag_CSKY_ISA_EXT_FLAGS:
17975 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17976 return display_tag_value (0, p, end);
17977
17978 case Tag_CSKY_DSP_VERSION:
17979 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17980 READ_ULEB (val, p, end);
17981 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17982 printf ("DSP Extension\n");
17983 else if (val == VAL_CSKY_DSP_VERSION_2)
17984 printf ("DSP 2.0\n");
17985 break;
17986
17987 case Tag_CSKY_VDSP_VERSION:
17988 printf (" Tag_CSKY_VDSP_VERSION:\t");
17989 READ_ULEB (val, p, end);
26c527e6 17990 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
17991 break;
17992
17993 case Tag_CSKY_FPU_VERSION:
17994 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17995 READ_ULEB (val, p, end);
17996 if (val == VAL_CSKY_FPU_VERSION_1)
17997 printf ("ABIV1 FPU Version 1\n");
17998 else if (val == VAL_CSKY_FPU_VERSION_2)
17999 printf ("FPU Version 2\n");
18000 break;
18001
18002 case Tag_CSKY_FPU_ABI:
18003 printf (" Tag_CSKY_FPU_ABI:\t\t");
18004 READ_ULEB (val, p, end);
18005 if (val == VAL_CSKY_FPU_ABI_HARD)
18006 printf ("Hard\n");
18007 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18008 printf ("SoftFP\n");
18009 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18010 printf ("Soft\n");
18011 break;
18012 case Tag_CSKY_FPU_ROUNDING:
18013 READ_ULEB (val, p, end);
f253158f
NC
18014 if (val == 1)
18015 {
18016 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18017 printf ("Needed\n");
18018 }
0861f561
CQ
18019 break;
18020 case Tag_CSKY_FPU_DENORMAL:
18021 READ_ULEB (val, p, end);
f253158f
NC
18022 if (val == 1)
18023 {
18024 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18025 printf ("Needed\n");
18026 }
0861f561
CQ
18027 break;
18028 case Tag_CSKY_FPU_Exception:
18029 READ_ULEB (val, p, end);
f253158f
NC
18030 if (val == 1)
18031 {
18032 printf (" Tag_CSKY_FPU_Exception:\t");
18033 printf ("Needed\n");
18034 }
0861f561
CQ
18035 break;
18036 case Tag_CSKY_FPU_NUMBER_MODULE:
18037 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18038 return display_tag_value (-1, p, end);
18039 case Tag_CSKY_FPU_HARDFP:
18040 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18041 READ_ULEB (val, p, end);
18042 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18043 printf (" Half");
18044 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18045 printf (" Single");
18046 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18047 printf (" Double");
18048 printf ("\n");
18049 break;
18050 default:
18051 return display_tag_value (tag, p, end);
18052 }
18053 return p;
18054}
18055
015dc7e1 18056static bool
dda8d76d 18057process_attributes (Filedata * filedata,
60bca95a 18058 const char * public_name,
104d59d1 18059 unsigned int proc_type,
f6f0e17b 18060 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 18061 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 18062{
2cf0635d 18063 Elf_Internal_Shdr * sect;
11c1ff18 18064 unsigned i;
015dc7e1 18065 bool res = true;
11c1ff18
PB
18066
18067 /* Find the section header so that we get the size. */
dda8d76d
NC
18068 for (i = 0, sect = filedata->section_headers;
18069 i < filedata->file_header.e_shnum;
11c1ff18
PB
18070 i++, sect++)
18071 {
071436c6
NC
18072 unsigned char * contents;
18073 unsigned char * p;
18074
104d59d1 18075 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
18076 continue;
18077
dda8d76d 18078 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 18079 sect->sh_size, _("attributes"));
60bca95a 18080 if (contents == NULL)
32ec8896 18081 {
015dc7e1 18082 res = false;
32ec8896
NC
18083 continue;
18084 }
60bca95a 18085
11c1ff18 18086 p = contents;
60abdbed
NC
18087 /* The first character is the version of the attributes.
18088 Currently only version 1, (aka 'A') is recognised here. */
18089 if (*p != 'A')
32ec8896
NC
18090 {
18091 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 18092 res = false;
32ec8896 18093 }
60abdbed 18094 else
11c1ff18 18095 {
625d49fc 18096 uint64_t section_len;
071436c6
NC
18097
18098 section_len = sect->sh_size - 1;
11c1ff18 18099 p++;
60bca95a 18100
071436c6 18101 while (section_len > 0)
11c1ff18 18102 {
625d49fc 18103 uint64_t attr_len;
e9847026 18104 unsigned int namelen;
015dc7e1
AM
18105 bool public_section;
18106 bool gnu_section;
11c1ff18 18107
071436c6 18108 if (section_len <= 4)
e0a31db1
NC
18109 {
18110 error (_("Tag section ends prematurely\n"));
015dc7e1 18111 res = false;
e0a31db1
NC
18112 break;
18113 }
071436c6 18114 attr_len = byte_get (p, 4);
11c1ff18 18115 p += 4;
60bca95a 18116
071436c6 18117 if (attr_len > section_len)
11c1ff18 18118 {
071436c6
NC
18119 error (_("Bad attribute length (%u > %u)\n"),
18120 (unsigned) attr_len, (unsigned) section_len);
18121 attr_len = section_len;
015dc7e1 18122 res = false;
11c1ff18 18123 }
74e1a04b 18124 /* PR 17531: file: 001-101425-0.004 */
071436c6 18125 else if (attr_len < 5)
74e1a04b 18126 {
071436c6 18127 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 18128 res = false;
74e1a04b
NC
18129 break;
18130 }
e9847026 18131
071436c6
NC
18132 section_len -= attr_len;
18133 attr_len -= 4;
18134
18135 namelen = strnlen ((char *) p, attr_len) + 1;
18136 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
18137 {
18138 error (_("Corrupt attribute section name\n"));
015dc7e1 18139 res = false;
e9847026
NC
18140 break;
18141 }
18142
071436c6
NC
18143 printf (_("Attribute Section: "));
18144 print_symbol (INT_MAX, (const char *) p);
18145 putchar ('\n');
60bca95a
NC
18146
18147 if (public_name && streq ((char *) p, public_name))
015dc7e1 18148 public_section = true;
11c1ff18 18149 else
015dc7e1 18150 public_section = false;
60bca95a
NC
18151
18152 if (streq ((char *) p, "gnu"))
015dc7e1 18153 gnu_section = true;
104d59d1 18154 else
015dc7e1 18155 gnu_section = false;
60bca95a 18156
11c1ff18 18157 p += namelen;
071436c6 18158 attr_len -= namelen;
e0a31db1 18159
071436c6 18160 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18161 {
e0a31db1 18162 int tag;
cd30bcef 18163 unsigned int val;
625d49fc 18164 uint64_t size;
071436c6 18165 unsigned char * end;
60bca95a 18166
e0a31db1 18167 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18168 if (attr_len < 6)
e0a31db1
NC
18169 {
18170 error (_("Unused bytes at end of section\n"));
015dc7e1 18171 res = false;
e0a31db1
NC
18172 section_len = 0;
18173 break;
18174 }
18175
18176 tag = *(p++);
11c1ff18 18177 size = byte_get (p, 4);
071436c6 18178 if (size > attr_len)
11c1ff18 18179 {
e9847026 18180 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18181 (unsigned) size, (unsigned) attr_len);
015dc7e1 18182 res = false;
071436c6 18183 size = attr_len;
11c1ff18 18184 }
e0a31db1
NC
18185 /* PR binutils/17531: Safe handling of corrupt files. */
18186 if (size < 6)
18187 {
18188 error (_("Bad subsection length (%u < 6)\n"),
18189 (unsigned) size);
015dc7e1 18190 res = false;
e0a31db1
NC
18191 section_len = 0;
18192 break;
18193 }
60bca95a 18194
071436c6 18195 attr_len -= size;
11c1ff18 18196 end = p + size - 1;
071436c6 18197 assert (end <= contents + sect->sh_size);
11c1ff18 18198 p += 4;
60bca95a 18199
11c1ff18
PB
18200 switch (tag)
18201 {
18202 case 1:
2b692964 18203 printf (_("File Attributes\n"));
11c1ff18
PB
18204 break;
18205 case 2:
2b692964 18206 printf (_("Section Attributes:"));
11c1ff18
PB
18207 goto do_numlist;
18208 case 3:
2b692964 18209 printf (_("Symbol Attributes:"));
1a0670f3 18210 /* Fall through. */
11c1ff18
PB
18211 do_numlist:
18212 for (;;)
18213 {
cd30bcef 18214 READ_ULEB (val, p, end);
11c1ff18
PB
18215 if (val == 0)
18216 break;
18217 printf (" %d", val);
18218 }
18219 printf ("\n");
18220 break;
18221 default:
2b692964 18222 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18223 public_section = false;
11c1ff18
PB
18224 break;
18225 }
60bca95a 18226
071436c6 18227 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18228 {
18229 while (p < end)
f6f0e17b 18230 p = display_pub_attribute (p, end);
60abdbed 18231 assert (p == end);
104d59d1 18232 }
071436c6 18233 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18234 {
18235 while (p < end)
18236 p = display_gnu_attribute (p,
f6f0e17b
NC
18237 display_proc_gnu_attribute,
18238 end);
60abdbed 18239 assert (p == end);
11c1ff18 18240 }
071436c6 18241 else if (p < end)
11c1ff18 18242 {
071436c6 18243 printf (_(" Unknown attribute:\n"));
f6f0e17b 18244 display_raw_attribute (p, end);
11c1ff18
PB
18245 p = end;
18246 }
071436c6
NC
18247 else
18248 attr_len = 0;
11c1ff18
PB
18249 }
18250 }
18251 }
d70c5fc7 18252
60bca95a 18253 free (contents);
11c1ff18 18254 }
32ec8896
NC
18255
18256 return res;
11c1ff18
PB
18257}
18258
ccb4c951
RS
18259/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18260 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18261 and return the VMA of the next entry, or -1 if there was a problem.
18262 Does not read from DATA_END or beyond. */
ccb4c951 18263
625d49fc
AM
18264static uint64_t
18265print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18266 unsigned char * data_end)
ccb4c951
RS
18267{
18268 printf (" ");
18269 print_vma (addr, LONG_HEX);
18270 printf (" ");
18271 if (addr < pltgot + 0xfff0)
18272 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18273 else
18274 printf ("%10s", "");
18275 printf (" ");
18276 if (data == NULL)
2b692964 18277 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18278 else
18279 {
625d49fc 18280 uint64_t entry;
82b1b41b 18281 unsigned char * from = data + addr - pltgot;
ccb4c951 18282
82b1b41b
NC
18283 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18284 {
18285 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18286 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18287 return (uint64_t) -1;
82b1b41b
NC
18288 }
18289 else
18290 {
18291 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18292 print_vma (entry, LONG_HEX);
18293 }
ccb4c951
RS
18294 }
18295 return addr + (is_32bit_elf ? 4 : 8);
18296}
18297
861fb55a
DJ
18298/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18299 PLTGOT. Print the Address and Initial fields of an entry at VMA
18300 ADDR and return the VMA of the next entry. */
18301
625d49fc
AM
18302static uint64_t
18303print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18304{
18305 printf (" ");
18306 print_vma (addr, LONG_HEX);
18307 printf (" ");
18308 if (data == NULL)
2b692964 18309 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18310 else
18311 {
625d49fc 18312 uint64_t entry;
861fb55a
DJ
18313
18314 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18315 print_vma (entry, LONG_HEX);
18316 }
18317 return addr + (is_32bit_elf ? 4 : 8);
18318}
18319
351cdf24
MF
18320static void
18321print_mips_ases (unsigned int mask)
18322{
18323 if (mask & AFL_ASE_DSP)
18324 fputs ("\n\tDSP ASE", stdout);
18325 if (mask & AFL_ASE_DSPR2)
18326 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18327 if (mask & AFL_ASE_DSPR3)
18328 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18329 if (mask & AFL_ASE_EVA)
18330 fputs ("\n\tEnhanced VA Scheme", stdout);
18331 if (mask & AFL_ASE_MCU)
18332 fputs ("\n\tMCU (MicroController) ASE", stdout);
18333 if (mask & AFL_ASE_MDMX)
18334 fputs ("\n\tMDMX ASE", stdout);
18335 if (mask & AFL_ASE_MIPS3D)
18336 fputs ("\n\tMIPS-3D ASE", stdout);
18337 if (mask & AFL_ASE_MT)
18338 fputs ("\n\tMT ASE", stdout);
18339 if (mask & AFL_ASE_SMARTMIPS)
18340 fputs ("\n\tSmartMIPS ASE", stdout);
18341 if (mask & AFL_ASE_VIRT)
18342 fputs ("\n\tVZ ASE", stdout);
18343 if (mask & AFL_ASE_MSA)
18344 fputs ("\n\tMSA ASE", stdout);
18345 if (mask & AFL_ASE_MIPS16)
18346 fputs ("\n\tMIPS16 ASE", stdout);
18347 if (mask & AFL_ASE_MICROMIPS)
18348 fputs ("\n\tMICROMIPS ASE", stdout);
18349 if (mask & AFL_ASE_XPA)
18350 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18351 if (mask & AFL_ASE_MIPS16E2)
18352 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18353 if (mask & AFL_ASE_CRC)
18354 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18355 if (mask & AFL_ASE_GINV)
18356 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18357 if (mask & AFL_ASE_LOONGSON_MMI)
18358 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18359 if (mask & AFL_ASE_LOONGSON_CAM)
18360 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18361 if (mask & AFL_ASE_LOONGSON_EXT)
18362 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18363 if (mask & AFL_ASE_LOONGSON_EXT2)
18364 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18365 if (mask == 0)
18366 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18367 else if ((mask & ~AFL_ASE_MASK) != 0)
18368 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18369}
18370
18371static void
18372print_mips_isa_ext (unsigned int isa_ext)
18373{
18374 switch (isa_ext)
18375 {
18376 case 0:
18377 fputs (_("None"), stdout);
18378 break;
18379 case AFL_EXT_XLR:
18380 fputs ("RMI XLR", stdout);
18381 break;
2c629856
N
18382 case AFL_EXT_OCTEON3:
18383 fputs ("Cavium Networks Octeon3", stdout);
18384 break;
351cdf24
MF
18385 case AFL_EXT_OCTEON2:
18386 fputs ("Cavium Networks Octeon2", stdout);
18387 break;
18388 case AFL_EXT_OCTEONP:
18389 fputs ("Cavium Networks OcteonP", stdout);
18390 break;
351cdf24
MF
18391 case AFL_EXT_OCTEON:
18392 fputs ("Cavium Networks Octeon", stdout);
18393 break;
18394 case AFL_EXT_5900:
18395 fputs ("Toshiba R5900", stdout);
18396 break;
18397 case AFL_EXT_4650:
18398 fputs ("MIPS R4650", stdout);
18399 break;
18400 case AFL_EXT_4010:
18401 fputs ("LSI R4010", stdout);
18402 break;
18403 case AFL_EXT_4100:
18404 fputs ("NEC VR4100", stdout);
18405 break;
18406 case AFL_EXT_3900:
18407 fputs ("Toshiba R3900", stdout);
18408 break;
18409 case AFL_EXT_10000:
18410 fputs ("MIPS R10000", stdout);
18411 break;
18412 case AFL_EXT_SB1:
18413 fputs ("Broadcom SB-1", stdout);
18414 break;
18415 case AFL_EXT_4111:
18416 fputs ("NEC VR4111/VR4181", stdout);
18417 break;
18418 case AFL_EXT_4120:
18419 fputs ("NEC VR4120", stdout);
18420 break;
18421 case AFL_EXT_5400:
18422 fputs ("NEC VR5400", stdout);
18423 break;
18424 case AFL_EXT_5500:
18425 fputs ("NEC VR5500", stdout);
18426 break;
18427 case AFL_EXT_LOONGSON_2E:
18428 fputs ("ST Microelectronics Loongson 2E", stdout);
18429 break;
18430 case AFL_EXT_LOONGSON_2F:
18431 fputs ("ST Microelectronics Loongson 2F", stdout);
18432 break;
38bf472a
MR
18433 case AFL_EXT_INTERAPTIV_MR2:
18434 fputs ("Imagination interAptiv MR2", stdout);
18435 break;
351cdf24 18436 default:
00ac7aa0 18437 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18438 }
18439}
18440
32ec8896 18441static signed int
351cdf24
MF
18442get_mips_reg_size (int reg_size)
18443{
18444 return (reg_size == AFL_REG_NONE) ? 0
18445 : (reg_size == AFL_REG_32) ? 32
18446 : (reg_size == AFL_REG_64) ? 64
18447 : (reg_size == AFL_REG_128) ? 128
18448 : -1;
18449}
18450
015dc7e1 18451static bool
dda8d76d 18452process_mips_specific (Filedata * filedata)
5b18a4bc 18453{
2cf0635d 18454 Elf_Internal_Dyn * entry;
351cdf24 18455 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18456 size_t liblist_offset = 0;
18457 size_t liblistno = 0;
18458 size_t conflictsno = 0;
18459 size_t options_offset = 0;
18460 size_t conflicts_offset = 0;
861fb55a
DJ
18461 size_t pltrelsz = 0;
18462 size_t pltrel = 0;
625d49fc
AM
18463 uint64_t pltgot = 0;
18464 uint64_t mips_pltgot = 0;
18465 uint64_t jmprel = 0;
18466 uint64_t local_gotno = 0;
18467 uint64_t gotsym = 0;
18468 uint64_t symtabno = 0;
015dc7e1 18469 bool res = true;
103f02d3 18470
dda8d76d 18471 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18472 display_mips_gnu_attribute))
015dc7e1 18473 res = false;
2cf19d5c 18474
dda8d76d 18475 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18476
18477 if (sect != NULL)
18478 {
18479 Elf_External_ABIFlags_v0 *abiflags_ext;
18480 Elf_Internal_ABIFlags_v0 abiflags_in;
18481
18482 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18483 {
18484 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18485 res = false;
32ec8896 18486 }
351cdf24
MF
18487 else
18488 {
dda8d76d 18489 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18490 sect->sh_size, _("MIPS ABI Flags section"));
18491 if (abiflags_ext)
18492 {
18493 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18494 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18495 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18496 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18497 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18498 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18499 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18500 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18501 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18502 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18503 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18504
18505 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18506 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18507 if (abiflags_in.isa_rev > 1)
18508 printf ("r%d", abiflags_in.isa_rev);
18509 printf ("\nGPR size: %d",
18510 get_mips_reg_size (abiflags_in.gpr_size));
18511 printf ("\nCPR1 size: %d",
18512 get_mips_reg_size (abiflags_in.cpr1_size));
18513 printf ("\nCPR2 size: %d",
18514 get_mips_reg_size (abiflags_in.cpr2_size));
18515 fputs ("\nFP ABI: ", stdout);
18516 print_mips_fp_abi_value (abiflags_in.fp_abi);
18517 fputs ("ISA Extension: ", stdout);
18518 print_mips_isa_ext (abiflags_in.isa_ext);
18519 fputs ("\nASEs:", stdout);
18520 print_mips_ases (abiflags_in.ases);
18521 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18522 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18523 fputc ('\n', stdout);
18524 free (abiflags_ext);
18525 }
18526 }
18527 }
18528
19e6b90e 18529 /* We have a lot of special sections. Thanks SGI! */
978c4450 18530 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18531 {
18532 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18533 sect = find_section (filedata, ".got");
bbdd9a68
MR
18534 if (sect != NULL)
18535 {
18536 unsigned char *data_end;
18537 unsigned char *data;
625d49fc 18538 uint64_t ent, end;
bbdd9a68
MR
18539 int addr_size;
18540
18541 pltgot = sect->sh_addr;
18542
18543 ent = pltgot;
18544 addr_size = (is_32bit_elf ? 4 : 8);
18545 end = pltgot + sect->sh_size;
18546
dda8d76d 18547 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18548 end - pltgot, 1,
18549 _("Global Offset Table data"));
18550 /* PR 12855: Null data is handled gracefully throughout. */
18551 data_end = data + (end - pltgot);
18552
18553 printf (_("\nStatic GOT:\n"));
18554 printf (_(" Canonical gp value: "));
18555 print_vma (ent + 0x7ff0, LONG_HEX);
18556 printf ("\n\n");
18557
18558 /* In a dynamic binary GOT[0] is reserved for the dynamic
18559 loader to store the lazy resolver pointer, however in
18560 a static binary it may well have been omitted and GOT
18561 reduced to a table of addresses.
18562 PR 21344: Check for the entry being fully available
18563 before fetching it. */
18564 if (data
18565 && data + ent - pltgot + addr_size <= data_end
18566 && byte_get (data + ent - pltgot, addr_size) == 0)
18567 {
18568 printf (_(" Reserved entries:\n"));
18569 printf (_(" %*s %10s %*s\n"),
18570 addr_size * 2, _("Address"), _("Access"),
18571 addr_size * 2, _("Value"));
18572 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18573 printf ("\n");
625d49fc 18574 if (ent == (uint64_t) -1)
bbdd9a68
MR
18575 goto sgot_print_fail;
18576
18577 /* Check for the MSB of GOT[1] being set, identifying a
18578 GNU object. This entry will be used by some runtime
18579 loaders, to store the module pointer. Otherwise this
18580 is an ordinary local entry.
18581 PR 21344: Check for the entry being fully available
18582 before fetching it. */
18583 if (data
18584 && data + ent - pltgot + addr_size <= data_end
18585 && (byte_get (data + ent - pltgot, addr_size)
18586 >> (addr_size * 8 - 1)) != 0)
18587 {
18588 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18589 printf ("\n");
625d49fc 18590 if (ent == (uint64_t) -1)
bbdd9a68
MR
18591 goto sgot_print_fail;
18592 }
18593 printf ("\n");
18594 }
18595
f17e9d8a 18596 if (data != NULL && ent < end)
bbdd9a68
MR
18597 {
18598 printf (_(" Local entries:\n"));
18599 printf (" %*s %10s %*s\n",
18600 addr_size * 2, _("Address"), _("Access"),
18601 addr_size * 2, _("Value"));
18602 while (ent < end)
18603 {
18604 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18605 printf ("\n");
625d49fc 18606 if (ent == (uint64_t) -1)
bbdd9a68
MR
18607 goto sgot_print_fail;
18608 }
18609 printf ("\n");
18610 }
18611
18612 sgot_print_fail:
9db70fc3 18613 free (data);
bbdd9a68
MR
18614 }
18615 return res;
18616 }
252b5132 18617
978c4450 18618 for (entry = filedata->dynamic_section;
071436c6 18619 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18620 (entry < filedata->dynamic_section + filedata->dynamic_nent
18621 && entry->d_tag != DT_NULL);
071436c6 18622 ++entry)
252b5132
RH
18623 switch (entry->d_tag)
18624 {
18625 case DT_MIPS_LIBLIST:
d93f0186 18626 liblist_offset
dda8d76d 18627 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18628 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18629 break;
18630 case DT_MIPS_LIBLISTNO:
18631 liblistno = entry->d_un.d_val;
18632 break;
18633 case DT_MIPS_OPTIONS:
dda8d76d 18634 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18635 break;
18636 case DT_MIPS_CONFLICT:
d93f0186 18637 conflicts_offset
dda8d76d 18638 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18639 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18640 break;
18641 case DT_MIPS_CONFLICTNO:
18642 conflictsno = entry->d_un.d_val;
18643 break;
ccb4c951 18644 case DT_PLTGOT:
861fb55a
DJ
18645 pltgot = entry->d_un.d_ptr;
18646 break;
ccb4c951
RS
18647 case DT_MIPS_LOCAL_GOTNO:
18648 local_gotno = entry->d_un.d_val;
18649 break;
18650 case DT_MIPS_GOTSYM:
18651 gotsym = entry->d_un.d_val;
18652 break;
18653 case DT_MIPS_SYMTABNO:
18654 symtabno = entry->d_un.d_val;
18655 break;
861fb55a
DJ
18656 case DT_MIPS_PLTGOT:
18657 mips_pltgot = entry->d_un.d_ptr;
18658 break;
18659 case DT_PLTREL:
18660 pltrel = entry->d_un.d_val;
18661 break;
18662 case DT_PLTRELSZ:
18663 pltrelsz = entry->d_un.d_val;
18664 break;
18665 case DT_JMPREL:
18666 jmprel = entry->d_un.d_ptr;
18667 break;
252b5132
RH
18668 default:
18669 break;
18670 }
18671
18672 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18673 {
2cf0635d 18674 Elf32_External_Lib * elib;
252b5132
RH
18675 size_t cnt;
18676
dda8d76d 18677 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18678 sizeof (Elf32_External_Lib),
18679 liblistno,
18680 _("liblist section data"));
a6e9f9df 18681 if (elib)
252b5132 18682 {
26c527e6
AM
18683 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
18684 "\nSection '.liblist' contains %zu entries:\n",
18685 liblistno),
18686 liblistno);
2b692964 18687 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18688 stdout);
18689
18690 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18691 {
a6e9f9df 18692 Elf32_Lib liblist;
91d6fa6a 18693 time_t atime;
d5b07ef4 18694 char timebuf[128];
2cf0635d 18695 struct tm * tmp;
a6e9f9df
AM
18696
18697 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18698 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18699 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18700 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18701 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18702
91d6fa6a 18703 tmp = gmtime (&atime);
e9e44622
JJ
18704 snprintf (timebuf, sizeof (timebuf),
18705 "%04u-%02u-%02uT%02u:%02u:%02u",
18706 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18707 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18708
26c527e6 18709 printf ("%3zu: ", cnt);
84714f86
AM
18710 if (valid_dynamic_name (filedata, liblist.l_name))
18711 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18712 else
2b692964 18713 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18714 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18715 liblist.l_version);
a6e9f9df
AM
18716
18717 if (liblist.l_flags == 0)
2b692964 18718 puts (_(" NONE"));
a6e9f9df
AM
18719 else
18720 {
18721 static const struct
252b5132 18722 {
2cf0635d 18723 const char * name;
a6e9f9df 18724 int bit;
252b5132 18725 }
a6e9f9df
AM
18726 l_flags_vals[] =
18727 {
18728 { " EXACT_MATCH", LL_EXACT_MATCH },
18729 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18730 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18731 { " EXPORTS", LL_EXPORTS },
18732 { " DELAY_LOAD", LL_DELAY_LOAD },
18733 { " DELTA", LL_DELTA }
18734 };
18735 int flags = liblist.l_flags;
18736 size_t fcnt;
18737
60bca95a 18738 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18739 if ((flags & l_flags_vals[fcnt].bit) != 0)
18740 {
18741 fputs (l_flags_vals[fcnt].name, stdout);
18742 flags ^= l_flags_vals[fcnt].bit;
18743 }
18744 if (flags != 0)
18745 printf (" %#x", (unsigned int) flags);
252b5132 18746
a6e9f9df
AM
18747 puts ("");
18748 }
252b5132 18749 }
252b5132 18750
a6e9f9df
AM
18751 free (elib);
18752 }
32ec8896 18753 else
015dc7e1 18754 res = false;
252b5132
RH
18755 }
18756
18757 if (options_offset != 0)
18758 {
2cf0635d 18759 Elf_External_Options * eopt;
252b5132
RH
18760 size_t offset;
18761 int cnt;
18762
18763 /* Find the section header so that we get the size. */
dda8d76d 18764 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18765 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18766 if (sect == NULL)
18767 {
18768 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18769 return false;
071436c6 18770 }
7fc0c668
NC
18771 /* PR 24243 */
18772 if (sect->sh_size < sizeof (* eopt))
18773 {
18774 error (_("The MIPS options section is too small.\n"));
015dc7e1 18775 return false;
7fc0c668 18776 }
252b5132 18777
dda8d76d 18778 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18779 sect->sh_size, _("options"));
a6e9f9df 18780 if (eopt)
252b5132 18781 {
fd17d1e6 18782 Elf_Internal_Options option;
76da6bbe 18783
a6e9f9df 18784 offset = cnt = 0;
82b1b41b 18785 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18786 {
2cf0635d 18787 Elf_External_Options * eoption;
fd17d1e6 18788 unsigned int optsize;
252b5132 18789
a6e9f9df 18790 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18791
fd17d1e6 18792 optsize = BYTE_GET (eoption->size);
76da6bbe 18793
82b1b41b 18794 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18795 if (optsize < sizeof (* eopt)
18796 || optsize > sect->sh_size - offset)
82b1b41b 18797 {
645f43a8 18798 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18799 optsize);
645f43a8 18800 free (eopt);
015dc7e1 18801 return false;
82b1b41b 18802 }
fd17d1e6 18803 offset += optsize;
a6e9f9df
AM
18804 ++cnt;
18805 }
252b5132 18806
d3a49aa8
AM
18807 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18808 "\nSection '%s' contains %d entries:\n",
18809 cnt),
dda8d76d 18810 printable_section_name (filedata, sect), cnt);
76da6bbe 18811
82b1b41b 18812 offset = 0;
a6e9f9df 18813 while (cnt-- > 0)
252b5132 18814 {
a6e9f9df 18815 size_t len;
fd17d1e6
AM
18816 Elf_External_Options * eoption;
18817
18818 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18819
18820 option.kind = BYTE_GET (eoption->kind);
18821 option.size = BYTE_GET (eoption->size);
18822 option.section = BYTE_GET (eoption->section);
18823 option.info = BYTE_GET (eoption->info);
a6e9f9df 18824
fd17d1e6 18825 switch (option.kind)
252b5132 18826 {
a6e9f9df
AM
18827 case ODK_NULL:
18828 /* This shouldn't happen. */
d0c4e780 18829 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18830 option.section, option.info);
a6e9f9df 18831 break;
2e6be59c 18832
a6e9f9df
AM
18833 case ODK_REGINFO:
18834 printf (" REGINFO ");
dda8d76d 18835 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18836 {
2cf0635d 18837 Elf32_External_RegInfo * ereg;
b34976b6 18838 Elf32_RegInfo reginfo;
a6e9f9df 18839
2e6be59c 18840 /* 32bit form. */
fd17d1e6
AM
18841 if (option.size < (sizeof (Elf_External_Options)
18842 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18843 {
18844 printf (_("<corrupt>\n"));
18845 error (_("Truncated MIPS REGINFO option\n"));
18846 cnt = 0;
18847 break;
18848 }
18849
fd17d1e6 18850 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18851
a6e9f9df
AM
18852 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18853 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18854 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18855 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18856 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18857 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18858
d0c4e780
AM
18859 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18860 reginfo.ri_gprmask, reginfo.ri_gp_value);
18861 printf (" "
18862 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18863 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18864 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18865 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18866 }
18867 else
18868 {
18869 /* 64 bit form. */
2cf0635d 18870 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18871 Elf64_Internal_RegInfo reginfo;
18872
fd17d1e6
AM
18873 if (option.size < (sizeof (Elf_External_Options)
18874 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18875 {
18876 printf (_("<corrupt>\n"));
18877 error (_("Truncated MIPS REGINFO option\n"));
18878 cnt = 0;
18879 break;
18880 }
18881
fd17d1e6 18882 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18883 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18884 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18885 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18886 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18887 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18888 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18889
d0c4e780
AM
18890 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18891 reginfo.ri_gprmask, reginfo.ri_gp_value);
18892 printf (" "
18893 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18894 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18895 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18896 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18897 }
fd17d1e6 18898 offset += option.size;
a6e9f9df 18899 continue;
2e6be59c 18900
a6e9f9df
AM
18901 case ODK_EXCEPTIONS:
18902 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18903 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18904 fputs (") fpe_max(", stdout);
fd17d1e6 18905 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18906 fputs (")", stdout);
18907
fd17d1e6 18908 if (option.info & OEX_PAGE0)
a6e9f9df 18909 fputs (" PAGE0", stdout);
fd17d1e6 18910 if (option.info & OEX_SMM)
a6e9f9df 18911 fputs (" SMM", stdout);
fd17d1e6 18912 if (option.info & OEX_FPDBUG)
a6e9f9df 18913 fputs (" FPDBUG", stdout);
fd17d1e6 18914 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18915 fputs (" DISMISS", stdout);
18916 break;
2e6be59c 18917
a6e9f9df
AM
18918 case ODK_PAD:
18919 fputs (" PAD ", stdout);
fd17d1e6 18920 if (option.info & OPAD_PREFIX)
a6e9f9df 18921 fputs (" PREFIX", stdout);
fd17d1e6 18922 if (option.info & OPAD_POSTFIX)
a6e9f9df 18923 fputs (" POSTFIX", stdout);
fd17d1e6 18924 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18925 fputs (" SYMBOL", stdout);
18926 break;
2e6be59c 18927
a6e9f9df
AM
18928 case ODK_HWPATCH:
18929 fputs (" HWPATCH ", stdout);
fd17d1e6 18930 if (option.info & OHW_R4KEOP)
a6e9f9df 18931 fputs (" R4KEOP", stdout);
fd17d1e6 18932 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18933 fputs (" R8KPFETCH", stdout);
fd17d1e6 18934 if (option.info & OHW_R5KEOP)
a6e9f9df 18935 fputs (" R5KEOP", stdout);
fd17d1e6 18936 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18937 fputs (" R5KCVTL", stdout);
18938 break;
2e6be59c 18939
a6e9f9df
AM
18940 case ODK_FILL:
18941 fputs (" FILL ", stdout);
18942 /* XXX Print content of info word? */
18943 break;
2e6be59c 18944
a6e9f9df
AM
18945 case ODK_TAGS:
18946 fputs (" TAGS ", stdout);
18947 /* XXX Print content of info word? */
18948 break;
2e6be59c 18949
a6e9f9df
AM
18950 case ODK_HWAND:
18951 fputs (" HWAND ", stdout);
fd17d1e6 18952 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18953 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18954 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18955 fputs (" R4KEOP_CLEAN", stdout);
18956 break;
2e6be59c 18957
a6e9f9df
AM
18958 case ODK_HWOR:
18959 fputs (" HWOR ", stdout);
fd17d1e6 18960 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18961 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18962 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18963 fputs (" R4KEOP_CLEAN", stdout);
18964 break;
2e6be59c 18965
a6e9f9df 18966 case ODK_GP_GROUP:
d0c4e780 18967 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18968 option.info & OGP_GROUP,
18969 (option.info & OGP_SELF) >> 16);
a6e9f9df 18970 break;
2e6be59c 18971
a6e9f9df 18972 case ODK_IDENT:
d0c4e780 18973 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18974 option.info & OGP_GROUP,
18975 (option.info & OGP_SELF) >> 16);
a6e9f9df 18976 break;
2e6be59c 18977
a6e9f9df
AM
18978 default:
18979 /* This shouldn't happen. */
d0c4e780 18980 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18981 option.kind, option.section, option.info);
a6e9f9df 18982 break;
252b5132 18983 }
a6e9f9df 18984
2cf0635d 18985 len = sizeof (* eopt);
fd17d1e6 18986 while (len < option.size)
82b1b41b 18987 {
fd17d1e6 18988 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18989
82b1b41b
NC
18990 if (ISPRINT (datum))
18991 printf ("%c", datum);
18992 else
18993 printf ("\\%03o", datum);
18994 len ++;
18995 }
a6e9f9df 18996 fputs ("\n", stdout);
82b1b41b 18997
fd17d1e6 18998 offset += option.size;
252b5132 18999 }
a6e9f9df 19000 free (eopt);
252b5132 19001 }
32ec8896 19002 else
015dc7e1 19003 res = false;
252b5132
RH
19004 }
19005
19006 if (conflicts_offset != 0 && conflictsno != 0)
19007 {
2cf0635d 19008 Elf32_Conflict * iconf;
252b5132
RH
19009 size_t cnt;
19010
978c4450 19011 if (filedata->dynamic_symbols == NULL)
252b5132 19012 {
591a748a 19013 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 19014 return false;
252b5132
RH
19015 }
19016
7296a62a
NC
19017 /* PR 21345 - print a slightly more helpful error message
19018 if we are sure that the cmalloc will fail. */
645f43a8 19019 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 19020 {
26c527e6
AM
19021 error (_("Overlarge number of conflicts detected: %zx\n"),
19022 conflictsno);
015dc7e1 19023 return false;
7296a62a
NC
19024 }
19025
3f5e193b 19026 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
19027 if (iconf == NULL)
19028 {
8b73c356 19029 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 19030 return false;
252b5132
RH
19031 }
19032
9ea033b2 19033 if (is_32bit_elf)
252b5132 19034 {
2cf0635d 19035 Elf32_External_Conflict * econf32;
a6e9f9df 19036
3f5e193b 19037 econf32 = (Elf32_External_Conflict *)
95099889
AM
19038 get_data (NULL, filedata, conflicts_offset,
19039 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 19040 if (!econf32)
5a814d6d
AM
19041 {
19042 free (iconf);
015dc7e1 19043 return false;
5a814d6d 19044 }
252b5132
RH
19045
19046 for (cnt = 0; cnt < conflictsno; ++cnt)
19047 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
19048
19049 free (econf32);
252b5132
RH
19050 }
19051 else
19052 {
2cf0635d 19053 Elf64_External_Conflict * econf64;
a6e9f9df 19054
3f5e193b 19055 econf64 = (Elf64_External_Conflict *)
95099889
AM
19056 get_data (NULL, filedata, conflicts_offset,
19057 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 19058 if (!econf64)
5a814d6d
AM
19059 {
19060 free (iconf);
015dc7e1 19061 return false;
5a814d6d 19062 }
252b5132
RH
19063
19064 for (cnt = 0; cnt < conflictsno; ++cnt)
19065 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
19066
19067 free (econf64);
252b5132
RH
19068 }
19069
26c527e6
AM
19070 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19071 "\nSection '.conflict' contains %zu entries:\n",
19072 conflictsno),
19073 conflictsno);
252b5132
RH
19074 puts (_(" Num: Index Value Name"));
19075
19076 for (cnt = 0; cnt < conflictsno; ++cnt)
19077 {
26c527e6 19078 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 19079
978c4450 19080 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 19081 printf (_("<corrupt symbol index>"));
d79b3d50 19082 else
e0a31db1
NC
19083 {
19084 Elf_Internal_Sym * psym;
19085
978c4450 19086 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
19087 print_vma (psym->st_value, FULL_HEX);
19088 putchar (' ');
84714f86
AM
19089 if (valid_dynamic_name (filedata, psym->st_name))
19090 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19091 else
19092 printf (_("<corrupt: %14ld>"), psym->st_name);
19093 }
31104126 19094 putchar ('\n');
252b5132
RH
19095 }
19096
252b5132
RH
19097 free (iconf);
19098 }
19099
ccb4c951
RS
19100 if (pltgot != 0 && local_gotno != 0)
19101 {
625d49fc 19102 uint64_t ent, local_end, global_end;
bbeee7ea 19103 size_t i, offset;
2cf0635d 19104 unsigned char * data;
82b1b41b 19105 unsigned char * data_end;
bbeee7ea 19106 int addr_size;
ccb4c951 19107
91d6fa6a 19108 ent = pltgot;
ccb4c951
RS
19109 addr_size = (is_32bit_elf ? 4 : 8);
19110 local_end = pltgot + local_gotno * addr_size;
ccb4c951 19111
74e1a04b
NC
19112 /* PR binutils/17533 file: 012-111227-0.004 */
19113 if (symtabno < gotsym)
19114 {
26c527e6
AM
19115 error (_("The GOT symbol offset (%" PRIu64
19116 ") is greater than the symbol table size (%" PRIu64 ")\n"),
19117 gotsym, symtabno);
015dc7e1 19118 return false;
74e1a04b 19119 }
82b1b41b 19120
74e1a04b 19121 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
19122 /* PR 17531: file: 54c91a34. */
19123 if (global_end < local_end)
19124 {
26c527e6 19125 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 19126 return false;
82b1b41b 19127 }
948f632f 19128
dda8d76d
NC
19129 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
19130 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
19131 global_end - pltgot, 1,
19132 _("Global Offset Table data"));
919383ac 19133 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 19134 data_end = data + (global_end - pltgot);
59245841 19135
ccb4c951
RS
19136 printf (_("\nPrimary GOT:\n"));
19137 printf (_(" Canonical gp value: "));
19138 print_vma (pltgot + 0x7ff0, LONG_HEX);
19139 printf ("\n\n");
19140
19141 printf (_(" Reserved entries:\n"));
19142 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
19143 addr_size * 2, _("Address"), _("Access"),
19144 addr_size * 2, _("Initial"));
82b1b41b 19145 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 19146 printf (_(" Lazy resolver\n"));
625d49fc 19147 if (ent == (uint64_t) -1)
82b1b41b 19148 goto got_print_fail;
75ec1fdb 19149
c4ab9505
MR
19150 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19151 This entry will be used by some runtime loaders, to store the
19152 module pointer. Otherwise this is an ordinary local entry.
19153 PR 21344: Check for the entry being fully available before
19154 fetching it. */
19155 if (data
19156 && data + ent - pltgot + addr_size <= data_end
19157 && (byte_get (data + ent - pltgot, addr_size)
19158 >> (addr_size * 8 - 1)) != 0)
19159 {
19160 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19161 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 19162 if (ent == (uint64_t) -1)
c4ab9505 19163 goto got_print_fail;
ccb4c951
RS
19164 }
19165 printf ("\n");
19166
f17e9d8a 19167 if (data != NULL && ent < local_end)
ccb4c951
RS
19168 {
19169 printf (_(" Local entries:\n"));
cc5914eb 19170 printf (" %*s %10s %*s\n",
2b692964
NC
19171 addr_size * 2, _("Address"), _("Access"),
19172 addr_size * 2, _("Initial"));
91d6fa6a 19173 while (ent < local_end)
ccb4c951 19174 {
82b1b41b 19175 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19176 printf ("\n");
625d49fc 19177 if (ent == (uint64_t) -1)
82b1b41b 19178 goto got_print_fail;
ccb4c951
RS
19179 }
19180 printf ("\n");
19181 }
19182
f17e9d8a 19183 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19184 {
19185 int sym_width;
19186
19187 printf (_(" Global entries:\n"));
cc5914eb 19188 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19189 addr_size * 2, _("Address"),
19190 _("Access"),
2b692964 19191 addr_size * 2, _("Initial"),
9cf03b7e
NC
19192 addr_size * 2, _("Sym.Val."),
19193 _("Type"),
19194 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19195 _("Ndx"), _("Name"));
0b4362b0 19196
ccb4c951 19197 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19198
ccb4c951
RS
19199 for (i = gotsym; i < symtabno; i++)
19200 {
82b1b41b 19201 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19202 printf (" ");
e0a31db1 19203
978c4450 19204 if (filedata->dynamic_symbols == NULL)
e0a31db1 19205 printf (_("<no dynamic symbols>"));
978c4450 19206 else if (i < filedata->num_dynamic_syms)
e0a31db1 19207 {
978c4450 19208 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19209
19210 print_vma (psym->st_value, LONG_HEX);
19211 printf (" %-7s %3s ",
dda8d76d
NC
19212 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19213 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19214
84714f86 19215 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19216 print_symbol (sym_width,
84714f86 19217 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19218 else
19219 printf (_("<corrupt: %14ld>"), psym->st_name);
19220 }
ccb4c951 19221 else
26c527e6
AM
19222 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
19223 i);
e0a31db1 19224
ccb4c951 19225 printf ("\n");
625d49fc 19226 if (ent == (uint64_t) -1)
82b1b41b 19227 break;
ccb4c951
RS
19228 }
19229 printf ("\n");
19230 }
19231
82b1b41b 19232 got_print_fail:
9db70fc3 19233 free (data);
ccb4c951
RS
19234 }
19235
861fb55a
DJ
19236 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19237 {
625d49fc 19238 uint64_t ent, end;
26c527e6
AM
19239 uint64_t offset, rel_offset;
19240 uint64_t count, i;
2cf0635d 19241 unsigned char * data;
861fb55a 19242 int addr_size, sym_width;
2cf0635d 19243 Elf_Internal_Rela * rels;
861fb55a 19244
dda8d76d 19245 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19246 if (pltrel == DT_RELA)
19247 {
dda8d76d 19248 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19249 return false;
861fb55a
DJ
19250 }
19251 else
19252 {
dda8d76d 19253 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19254 return false;
861fb55a
DJ
19255 }
19256
91d6fa6a 19257 ent = mips_pltgot;
861fb55a
DJ
19258 addr_size = (is_32bit_elf ? 4 : 8);
19259 end = mips_pltgot + (2 + count) * addr_size;
19260
dda8d76d
NC
19261 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19262 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19263 1, _("Procedure Linkage Table data"));
59245841 19264 if (data == NULL)
288f0ba2
AM
19265 {
19266 free (rels);
015dc7e1 19267 return false;
288f0ba2 19268 }
59245841 19269
9cf03b7e 19270 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19271 printf (_(" Reserved entries:\n"));
19272 printf (_(" %*s %*s Purpose\n"),
2b692964 19273 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19274 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19275 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19276 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19277 printf (_(" Module pointer\n"));
861fb55a
DJ
19278 printf ("\n");
19279
19280 printf (_(" Entries:\n"));
cc5914eb 19281 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19282 addr_size * 2, _("Address"),
19283 addr_size * 2, _("Initial"),
19284 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19285 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19286 for (i = 0; i < count; i++)
19287 {
26c527e6 19288 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19289
91d6fa6a 19290 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19291 printf (" ");
e0a31db1 19292
978c4450 19293 if (idx >= filedata->num_dynamic_syms)
26c527e6 19294 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 19295 else
e0a31db1 19296 {
978c4450 19297 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19298
19299 print_vma (psym->st_value, LONG_HEX);
19300 printf (" %-7s %3s ",
dda8d76d
NC
19301 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19302 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19303 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19304 print_symbol (sym_width,
84714f86 19305 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19306 else
19307 printf (_("<corrupt: %14ld>"), psym->st_name);
19308 }
861fb55a
DJ
19309 printf ("\n");
19310 }
19311 printf ("\n");
19312
9db70fc3 19313 free (data);
861fb55a
DJ
19314 free (rels);
19315 }
19316
32ec8896 19317 return res;
252b5132
RH
19318}
19319
015dc7e1 19320static bool
dda8d76d 19321process_nds32_specific (Filedata * filedata)
35c08157
KLC
19322{
19323 Elf_Internal_Shdr *sect = NULL;
19324
dda8d76d 19325 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19326 if (sect != NULL && sect->sh_size >= 4)
35c08157 19327 {
9c7b8e9b
AM
19328 unsigned char *buf;
19329 unsigned int flag;
35c08157
KLC
19330
19331 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19332 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19333 _("NDS32 elf flags section"));
35c08157 19334
9c7b8e9b 19335 if (buf == NULL)
015dc7e1 19336 return false;
32ec8896 19337
9c7b8e9b
AM
19338 flag = byte_get (buf, 4);
19339 free (buf);
19340 switch (flag & 0x3)
35c08157
KLC
19341 {
19342 case 0:
19343 printf ("(VEC_SIZE):\tNo entry.\n");
19344 break;
19345 case 1:
19346 printf ("(VEC_SIZE):\t4 bytes\n");
19347 break;
19348 case 2:
19349 printf ("(VEC_SIZE):\t16 bytes\n");
19350 break;
19351 case 3:
19352 printf ("(VEC_SIZE):\treserved\n");
19353 break;
19354 }
19355 }
19356
015dc7e1 19357 return true;
35c08157
KLC
19358}
19359
015dc7e1 19360static bool
dda8d76d 19361process_gnu_liblist (Filedata * filedata)
047b2264 19362{
2cf0635d
NC
19363 Elf_Internal_Shdr * section;
19364 Elf_Internal_Shdr * string_sec;
19365 Elf32_External_Lib * elib;
19366 char * strtab;
c256ffe7 19367 size_t strtab_size;
047b2264 19368 size_t cnt;
26c527e6 19369 uint64_t num_liblist;
047b2264 19370 unsigned i;
015dc7e1 19371 bool res = true;
047b2264
JJ
19372
19373 if (! do_arch)
015dc7e1 19374 return true;
047b2264 19375
dda8d76d
NC
19376 for (i = 0, section = filedata->section_headers;
19377 i < filedata->file_header.e_shnum;
b34976b6 19378 i++, section++)
047b2264
JJ
19379 {
19380 switch (section->sh_type)
19381 {
19382 case SHT_GNU_LIBLIST:
dda8d76d 19383 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19384 break;
19385
3f5e193b 19386 elib = (Elf32_External_Lib *)
dda8d76d 19387 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19388 _("liblist section data"));
047b2264
JJ
19389
19390 if (elib == NULL)
32ec8896 19391 {
015dc7e1 19392 res = false;
32ec8896
NC
19393 break;
19394 }
047b2264 19395
dda8d76d
NC
19396 string_sec = filedata->section_headers + section->sh_link;
19397 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19398 string_sec->sh_size,
19399 _("liblist string table"));
047b2264
JJ
19400 if (strtab == NULL
19401 || section->sh_entsize != sizeof (Elf32_External_Lib))
19402 {
19403 free (elib);
2842702f 19404 free (strtab);
015dc7e1 19405 res = false;
047b2264
JJ
19406 break;
19407 }
59245841 19408 strtab_size = string_sec->sh_size;
047b2264 19409
d3a49aa8 19410 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
19411 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
19412 " entries:\n",
19413 "\nLibrary list section '%s' contains %" PRIu64
19414 " entries:\n",
d3a49aa8 19415 num_liblist),
dda8d76d 19416 printable_section_name (filedata, section),
d3a49aa8 19417 num_liblist);
047b2264 19418
2b692964 19419 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19420
19421 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19422 ++cnt)
19423 {
19424 Elf32_Lib liblist;
91d6fa6a 19425 time_t atime;
d5b07ef4 19426 char timebuf[128];
2cf0635d 19427 struct tm * tmp;
047b2264
JJ
19428
19429 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19430 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19431 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19432 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19433 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19434
91d6fa6a 19435 tmp = gmtime (&atime);
e9e44622
JJ
19436 snprintf (timebuf, sizeof (timebuf),
19437 "%04u-%02u-%02uT%02u:%02u:%02u",
19438 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19439 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 19440
26c527e6 19441 printf ("%3zu: ", cnt);
047b2264 19442 if (do_wide)
c256ffe7 19443 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19444 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19445 else
c256ffe7 19446 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19447 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19448 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19449 liblist.l_version, liblist.l_flags);
19450 }
19451
19452 free (elib);
2842702f 19453 free (strtab);
047b2264
JJ
19454 }
19455 }
19456
32ec8896 19457 return res;
047b2264
JJ
19458}
19459
9437c45b 19460static const char *
dda8d76d 19461get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19462{
19463 static char buff[64];
103f02d3 19464
dda8d76d 19465 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19466 switch (e_type)
19467 {
57346661 19468 case NT_AUXV:
1ec5cd37 19469 return _("NT_AUXV (auxiliary vector)");
57346661 19470 case NT_PRSTATUS:
1ec5cd37 19471 return _("NT_PRSTATUS (prstatus structure)");
57346661 19472 case NT_FPREGSET:
1ec5cd37 19473 return _("NT_FPREGSET (floating point registers)");
57346661 19474 case NT_PRPSINFO:
1ec5cd37 19475 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19476 case NT_TASKSTRUCT:
1ec5cd37 19477 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19478 case NT_GDB_TDESC:
19479 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19480 case NT_PRXFPREG:
1ec5cd37 19481 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19482 case NT_PPC_VMX:
19483 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19484 case NT_PPC_VSX:
19485 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19486 case NT_PPC_TAR:
19487 return _("NT_PPC_TAR (ppc TAR register)");
19488 case NT_PPC_PPR:
19489 return _("NT_PPC_PPR (ppc PPR register)");
19490 case NT_PPC_DSCR:
19491 return _("NT_PPC_DSCR (ppc DSCR register)");
19492 case NT_PPC_EBB:
19493 return _("NT_PPC_EBB (ppc EBB registers)");
19494 case NT_PPC_PMU:
19495 return _("NT_PPC_PMU (ppc PMU registers)");
19496 case NT_PPC_TM_CGPR:
19497 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19498 case NT_PPC_TM_CFPR:
19499 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19500 case NT_PPC_TM_CVMX:
19501 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19502 case NT_PPC_TM_CVSX:
3fd21718 19503 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19504 case NT_PPC_TM_SPR:
19505 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19506 case NT_PPC_TM_CTAR:
19507 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19508 case NT_PPC_TM_CPPR:
19509 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19510 case NT_PPC_TM_CDSCR:
19511 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19512 case NT_386_TLS:
19513 return _("NT_386_TLS (x86 TLS information)");
19514 case NT_386_IOPERM:
19515 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19516 case NT_X86_XSTATE:
19517 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19518 case NT_X86_CET:
19519 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19520 case NT_S390_HIGH_GPRS:
19521 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19522 case NT_S390_TIMER:
19523 return _("NT_S390_TIMER (s390 timer register)");
19524 case NT_S390_TODCMP:
19525 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19526 case NT_S390_TODPREG:
19527 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19528 case NT_S390_CTRS:
19529 return _("NT_S390_CTRS (s390 control registers)");
19530 case NT_S390_PREFIX:
19531 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19532 case NT_S390_LAST_BREAK:
19533 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19534 case NT_S390_SYSTEM_CALL:
19535 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19536 case NT_S390_TDB:
19537 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19538 case NT_S390_VXRS_LOW:
19539 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19540 case NT_S390_VXRS_HIGH:
19541 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19542 case NT_S390_GS_CB:
19543 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19544 case NT_S390_GS_BC:
19545 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19546 case NT_ARM_VFP:
19547 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19548 case NT_ARM_TLS:
19549 return _("NT_ARM_TLS (AArch TLS registers)");
19550 case NT_ARM_HW_BREAK:
19551 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19552 case NT_ARM_HW_WATCH:
19553 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
19554 case NT_ARM_SYSTEM_CALL:
19555 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
19556 case NT_ARM_SVE:
19557 return _("NT_ARM_SVE (AArch SVE registers)");
19558 case NT_ARM_PAC_MASK:
19559 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19560 case NT_ARM_PACA_KEYS:
19561 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19562 case NT_ARM_PACG_KEYS:
19563 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19564 case NT_ARM_TAGGED_ADDR_CTRL:
19565 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
a8f175d9
LM
19566 case NT_ARM_SSVE:
19567 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
19568 case NT_ARM_ZA:
19569 return _("NT_ARM_ZA (AArch64 SME ZA register)");
3af2785c
LM
19570 case NT_ARM_PAC_ENABLED_KEYS:
19571 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19572 case NT_ARC_V2:
19573 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19574 case NT_RISCV_CSR:
19575 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19576 case NT_PSTATUS:
1ec5cd37 19577 return _("NT_PSTATUS (pstatus structure)");
57346661 19578 case NT_FPREGS:
1ec5cd37 19579 return _("NT_FPREGS (floating point registers)");
57346661 19580 case NT_PSINFO:
1ec5cd37 19581 return _("NT_PSINFO (psinfo structure)");
57346661 19582 case NT_LWPSTATUS:
1ec5cd37 19583 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19584 case NT_LWPSINFO:
1ec5cd37 19585 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19586 case NT_WIN32PSTATUS:
1ec5cd37 19587 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19588 case NT_SIGINFO:
19589 return _("NT_SIGINFO (siginfo_t data)");
19590 case NT_FILE:
19591 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19592 default:
19593 break;
19594 }
19595 else
19596 switch (e_type)
19597 {
19598 case NT_VERSION:
19599 return _("NT_VERSION (version)");
19600 case NT_ARCH:
19601 return _("NT_ARCH (architecture)");
9ef920e9 19602 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19603 return _("OPEN");
9ef920e9 19604 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19605 return _("func");
c8795e1f
NC
19606 case NT_GO_BUILDID:
19607 return _("GO BUILDID");
3ac925fc
LB
19608 case FDO_PACKAGING_METADATA:
19609 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19610 default:
19611 break;
19612 }
19613
e9e44622 19614 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19615 return buff;
779fe533
NC
19616}
19617
015dc7e1 19618static bool
9ece1fa9
TT
19619print_core_note (Elf_Internal_Note *pnote)
19620{
19621 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 19622 uint64_t count, page_size;
9ece1fa9
TT
19623 unsigned char *descdata, *filenames, *descend;
19624
19625 if (pnote->type != NT_FILE)
04ac15ab
AS
19626 {
19627 if (do_wide)
19628 printf ("\n");
015dc7e1 19629 return true;
04ac15ab 19630 }
9ece1fa9 19631
9ece1fa9
TT
19632 if (!is_32bit_elf)
19633 {
19634 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19635 /* Still "successful". */
015dc7e1 19636 return true;
9ece1fa9 19637 }
9ece1fa9
TT
19638
19639 if (pnote->descsz < 2 * addr_size)
19640 {
32ec8896 19641 error (_(" Malformed note - too short for header\n"));
015dc7e1 19642 return false;
9ece1fa9
TT
19643 }
19644
19645 descdata = (unsigned char *) pnote->descdata;
19646 descend = descdata + pnote->descsz;
19647
19648 if (descdata[pnote->descsz - 1] != '\0')
19649 {
32ec8896 19650 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19651 return false;
9ece1fa9
TT
19652 }
19653
19654 count = byte_get (descdata, addr_size);
19655 descdata += addr_size;
19656
19657 page_size = byte_get (descdata, addr_size);
19658 descdata += addr_size;
19659
625d49fc 19660 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 19661 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19662 {
32ec8896 19663 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19664 return false;
9ece1fa9
TT
19665 }
19666
19667 printf (_(" Page size: "));
19668 print_vma (page_size, DEC);
19669 printf ("\n");
19670
19671 printf (_(" %*s%*s%*s\n"),
19672 (int) (2 + 2 * addr_size), _("Start"),
19673 (int) (4 + 2 * addr_size), _("End"),
19674 (int) (4 + 2 * addr_size), _("Page Offset"));
19675 filenames = descdata + count * 3 * addr_size;
595712bb 19676 while (count-- > 0)
9ece1fa9 19677 {
625d49fc 19678 uint64_t start, end, file_ofs;
9ece1fa9
TT
19679
19680 if (filenames == descend)
19681 {
32ec8896 19682 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19683 return false;
9ece1fa9
TT
19684 }
19685
19686 start = byte_get (descdata, addr_size);
19687 descdata += addr_size;
19688 end = byte_get (descdata, addr_size);
19689 descdata += addr_size;
19690 file_ofs = byte_get (descdata, addr_size);
19691 descdata += addr_size;
19692
19693 printf (" ");
19694 print_vma (start, FULL_HEX);
19695 printf (" ");
19696 print_vma (end, FULL_HEX);
19697 printf (" ");
19698 print_vma (file_ofs, FULL_HEX);
19699 printf ("\n %s\n", filenames);
19700
19701 filenames += 1 + strlen ((char *) filenames);
19702 }
19703
015dc7e1 19704 return true;
9ece1fa9
TT
19705}
19706
1118d252
RM
19707static const char *
19708get_gnu_elf_note_type (unsigned e_type)
19709{
1449284b 19710 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19711 switch (e_type)
19712 {
19713 case NT_GNU_ABI_TAG:
19714 return _("NT_GNU_ABI_TAG (ABI version tag)");
19715 case NT_GNU_HWCAP:
19716 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19717 case NT_GNU_BUILD_ID:
19718 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19719 case NT_GNU_GOLD_VERSION:
19720 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19721 case NT_GNU_PROPERTY_TYPE_0:
19722 return _("NT_GNU_PROPERTY_TYPE_0");
19723 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19724 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19725 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19726 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19727 default:
1449284b
NC
19728 {
19729 static char buff[64];
1118d252 19730
1449284b
NC
19731 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19732 return buff;
19733 }
19734 }
1118d252
RM
19735}
19736
a9eafb08
L
19737static void
19738decode_x86_compat_isa (unsigned int bitmask)
19739{
19740 while (bitmask)
19741 {
19742 unsigned int bit = bitmask & (- bitmask);
19743
19744 bitmask &= ~ bit;
19745 switch (bit)
19746 {
19747 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19748 printf ("i486");
19749 break;
19750 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19751 printf ("586");
19752 break;
19753 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19754 printf ("686");
19755 break;
19756 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19757 printf ("SSE");
19758 break;
19759 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19760 printf ("SSE2");
19761 break;
19762 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19763 printf ("SSE3");
19764 break;
19765 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19766 printf ("SSSE3");
19767 break;
19768 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19769 printf ("SSE4_1");
19770 break;
19771 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19772 printf ("SSE4_2");
19773 break;
19774 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19775 printf ("AVX");
19776 break;
19777 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19778 printf ("AVX2");
19779 break;
19780 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19781 printf ("AVX512F");
19782 break;
19783 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19784 printf ("AVX512CD");
19785 break;
19786 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19787 printf ("AVX512ER");
19788 break;
19789 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19790 printf ("AVX512PF");
19791 break;
19792 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19793 printf ("AVX512VL");
19794 break;
19795 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19796 printf ("AVX512DQ");
19797 break;
19798 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19799 printf ("AVX512BW");
19800 break;
65b3d26e
L
19801 default:
19802 printf (_("<unknown: %x>"), bit);
19803 break;
a9eafb08
L
19804 }
19805 if (bitmask)
19806 printf (", ");
19807 }
19808}
19809
9ef920e9 19810static void
32930e4e 19811decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19812{
0a59decb 19813 if (!bitmask)
90c745dc
L
19814 {
19815 printf (_("<None>"));
19816 return;
19817 }
90c745dc 19818
9ef920e9
NC
19819 while (bitmask)
19820 {
1fc87489 19821 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19822
19823 bitmask &= ~ bit;
19824 switch (bit)
19825 {
32930e4e 19826 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19827 printf ("CMOV");
19828 break;
32930e4e 19829 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19830 printf ("SSE");
19831 break;
32930e4e 19832 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19833 printf ("SSE2");
19834 break;
32930e4e 19835 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19836 printf ("SSE3");
19837 break;
32930e4e 19838 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19839 printf ("SSSE3");
19840 break;
32930e4e 19841 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19842 printf ("SSE4_1");
19843 break;
32930e4e 19844 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19845 printf ("SSE4_2");
19846 break;
32930e4e 19847 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19848 printf ("AVX");
19849 break;
32930e4e 19850 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19851 printf ("AVX2");
19852 break;
32930e4e 19853 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19854 printf ("FMA");
19855 break;
32930e4e 19856 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19857 printf ("AVX512F");
19858 break;
32930e4e 19859 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19860 printf ("AVX512CD");
19861 break;
32930e4e 19862 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19863 printf ("AVX512ER");
19864 break;
32930e4e 19865 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19866 printf ("AVX512PF");
19867 break;
32930e4e 19868 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19869 printf ("AVX512VL");
19870 break;
32930e4e 19871 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19872 printf ("AVX512DQ");
19873 break;
32930e4e 19874 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19875 printf ("AVX512BW");
19876 break;
32930e4e 19877 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19878 printf ("AVX512_4FMAPS");
19879 break;
32930e4e 19880 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19881 printf ("AVX512_4VNNIW");
19882 break;
32930e4e 19883 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19884 printf ("AVX512_BITALG");
19885 break;
32930e4e 19886 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19887 printf ("AVX512_IFMA");
19888 break;
32930e4e 19889 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19890 printf ("AVX512_VBMI");
19891 break;
32930e4e 19892 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19893 printf ("AVX512_VBMI2");
19894 break;
32930e4e 19895 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19896 printf ("AVX512_VNNI");
19897 break;
32930e4e 19898 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19899 printf ("AVX512_BF16");
19900 break;
65b3d26e
L
19901 default:
19902 printf (_("<unknown: %x>"), bit);
19903 break;
9ef920e9
NC
19904 }
19905 if (bitmask)
19906 printf (", ");
19907 }
19908}
19909
28cdbb18
SM
19910static const char *
19911get_amdgpu_elf_note_type (unsigned int e_type)
19912{
19913 switch (e_type)
19914 {
19915 case NT_AMDGPU_METADATA:
19916 return _("NT_AMDGPU_METADATA (code object metadata)");
19917 default:
19918 {
19919 static char buf[64];
19920 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
19921 return buf;
19922 }
19923 }
19924}
19925
32930e4e
L
19926static void
19927decode_x86_isa (unsigned int bitmask)
19928{
32930e4e
L
19929 while (bitmask)
19930 {
19931 unsigned int bit = bitmask & (- bitmask);
19932
19933 bitmask &= ~ bit;
19934 switch (bit)
19935 {
b0ab0693
L
19936 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19937 printf ("x86-64-baseline");
19938 break;
32930e4e
L
19939 case GNU_PROPERTY_X86_ISA_1_V2:
19940 printf ("x86-64-v2");
19941 break;
19942 case GNU_PROPERTY_X86_ISA_1_V3:
19943 printf ("x86-64-v3");
19944 break;
19945 case GNU_PROPERTY_X86_ISA_1_V4:
19946 printf ("x86-64-v4");
19947 break;
19948 default:
19949 printf (_("<unknown: %x>"), bit);
19950 break;
19951 }
19952 if (bitmask)
19953 printf (", ");
19954 }
19955}
19956
ee2fdd6f 19957static void
a9eafb08 19958decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19959{
0a59decb 19960 if (!bitmask)
90c745dc
L
19961 {
19962 printf (_("<None>"));
19963 return;
19964 }
90c745dc 19965
ee2fdd6f
L
19966 while (bitmask)
19967 {
19968 unsigned int bit = bitmask & (- bitmask);
19969
19970 bitmask &= ~ bit;
19971 switch (bit)
19972 {
19973 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19974 printf ("IBT");
ee2fdd6f 19975 break;
48580982 19976 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19977 printf ("SHSTK");
48580982 19978 break;
279d901e
L
19979 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19980 printf ("LAM_U48");
19981 break;
19982 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19983 printf ("LAM_U57");
19984 break;
ee2fdd6f
L
19985 default:
19986 printf (_("<unknown: %x>"), bit);
19987 break;
19988 }
19989 if (bitmask)
19990 printf (", ");
19991 }
19992}
19993
a9eafb08
L
19994static void
19995decode_x86_feature_2 (unsigned int bitmask)
19996{
0a59decb 19997 if (!bitmask)
90c745dc
L
19998 {
19999 printf (_("<None>"));
20000 return;
20001 }
90c745dc 20002
a9eafb08
L
20003 while (bitmask)
20004 {
20005 unsigned int bit = bitmask & (- bitmask);
20006
20007 bitmask &= ~ bit;
20008 switch (bit)
20009 {
20010 case GNU_PROPERTY_X86_FEATURE_2_X86:
20011 printf ("x86");
20012 break;
20013 case GNU_PROPERTY_X86_FEATURE_2_X87:
20014 printf ("x87");
20015 break;
20016 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20017 printf ("MMX");
20018 break;
20019 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20020 printf ("XMM");
20021 break;
20022 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20023 printf ("YMM");
20024 break;
20025 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20026 printf ("ZMM");
20027 break;
a308b89d
L
20028 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20029 printf ("TMM");
20030 break;
32930e4e
L
20031 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20032 printf ("MASK");
20033 break;
a9eafb08
L
20034 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20035 printf ("FXSR");
20036 break;
20037 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20038 printf ("XSAVE");
20039 break;
20040 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20041 printf ("XSAVEOPT");
20042 break;
20043 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20044 printf ("XSAVEC");
20045 break;
65b3d26e
L
20046 default:
20047 printf (_("<unknown: %x>"), bit);
20048 break;
a9eafb08
L
20049 }
20050 if (bitmask)
20051 printf (", ");
20052 }
20053}
20054
cd702818
SD
20055static void
20056decode_aarch64_feature_1_and (unsigned int bitmask)
20057{
20058 while (bitmask)
20059 {
20060 unsigned int bit = bitmask & (- bitmask);
20061
20062 bitmask &= ~ bit;
20063 switch (bit)
20064 {
20065 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20066 printf ("BTI");
20067 break;
20068
20069 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20070 printf ("PAC");
20071 break;
20072
20073 default:
20074 printf (_("<unknown: %x>"), bit);
20075 break;
20076 }
20077 if (bitmask)
20078 printf (", ");
20079 }
20080}
20081
6320fd00
L
20082static void
20083decode_1_needed (unsigned int bitmask)
20084{
20085 while (bitmask)
20086 {
20087 unsigned int bit = bitmask & (- bitmask);
20088
20089 bitmask &= ~ bit;
20090 switch (bit)
20091 {
20092 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20093 printf ("indirect external access");
20094 break;
20095 default:
20096 printf (_("<unknown: %x>"), bit);
20097 break;
20098 }
20099 if (bitmask)
20100 printf (", ");
20101 }
20102}
20103
9ef920e9 20104static void
dda8d76d 20105print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
20106{
20107 unsigned char * ptr = (unsigned char *) pnote->descdata;
20108 unsigned char * ptr_end = ptr + pnote->descsz;
20109 unsigned int size = is_32bit_elf ? 4 : 8;
20110
20111 printf (_(" Properties: "));
20112
1fc87489 20113 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
20114 {
20115 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
20116 return;
20117 }
20118
6ab2c4ed 20119 while (ptr < ptr_end)
9ef920e9 20120 {
1fc87489 20121 unsigned int j;
6ab2c4ed
MC
20122 unsigned int type;
20123 unsigned int datasz;
20124
20125 if ((size_t) (ptr_end - ptr) < 8)
20126 {
20127 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
20128 break;
20129 }
20130
20131 type = byte_get (ptr, 4);
20132 datasz = byte_get (ptr + 4, 4);
9ef920e9 20133
1fc87489 20134 ptr += 8;
9ef920e9 20135
6ab2c4ed 20136 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 20137 {
1fc87489
L
20138 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
20139 type, datasz);
9ef920e9 20140 break;
1fc87489 20141 }
9ef920e9 20142
1fc87489
L
20143 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20144 {
dda8d76d
NC
20145 if (filedata->file_header.e_machine == EM_X86_64
20146 || filedata->file_header.e_machine == EM_IAMCU
20147 || filedata->file_header.e_machine == EM_386)
1fc87489 20148 {
aa7bca9b
L
20149 unsigned int bitmask;
20150
20151 if (datasz == 4)
0a59decb 20152 bitmask = byte_get (ptr, 4);
aa7bca9b
L
20153 else
20154 bitmask = 0;
20155
1fc87489
L
20156 switch (type)
20157 {
20158 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 20159 if (datasz != 4)
aa7bca9b
L
20160 printf (_("x86 ISA used: <corrupt length: %#x> "),
20161 datasz);
1fc87489 20162 else
aa7bca9b
L
20163 {
20164 printf ("x86 ISA used: ");
20165 decode_x86_isa (bitmask);
20166 }
1fc87489 20167 goto next;
9ef920e9 20168
1fc87489 20169 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20170 if (datasz != 4)
aa7bca9b
L
20171 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20172 datasz);
1fc87489 20173 else
aa7bca9b
L
20174 {
20175 printf ("x86 ISA needed: ");
20176 decode_x86_isa (bitmask);
20177 }
1fc87489 20178 goto next;
9ef920e9 20179
ee2fdd6f 20180 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20181 if (datasz != 4)
aa7bca9b
L
20182 printf (_("x86 feature: <corrupt length: %#x> "),
20183 datasz);
ee2fdd6f 20184 else
aa7bca9b
L
20185 {
20186 printf ("x86 feature: ");
a9eafb08
L
20187 decode_x86_feature_1 (bitmask);
20188 }
20189 goto next;
20190
20191 case GNU_PROPERTY_X86_FEATURE_2_USED:
20192 if (datasz != 4)
20193 printf (_("x86 feature used: <corrupt length: %#x> "),
20194 datasz);
20195 else
20196 {
20197 printf ("x86 feature used: ");
20198 decode_x86_feature_2 (bitmask);
20199 }
20200 goto next;
20201
20202 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20203 if (datasz != 4)
20204 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20205 else
20206 {
20207 printf ("x86 feature needed: ");
20208 decode_x86_feature_2 (bitmask);
20209 }
20210 goto next;
20211
20212 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20213 if (datasz != 4)
20214 printf (_("x86 ISA used: <corrupt length: %#x> "),
20215 datasz);
20216 else
20217 {
20218 printf ("x86 ISA used: ");
20219 decode_x86_compat_isa (bitmask);
20220 }
20221 goto next;
20222
20223 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20224 if (datasz != 4)
20225 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20226 datasz);
20227 else
20228 {
20229 printf ("x86 ISA needed: ");
20230 decode_x86_compat_isa (bitmask);
aa7bca9b 20231 }
ee2fdd6f
L
20232 goto next;
20233
32930e4e
L
20234 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20235 if (datasz != 4)
20236 printf (_("x86 ISA used: <corrupt length: %#x> "),
20237 datasz);
20238 else
20239 {
20240 printf ("x86 ISA used: ");
20241 decode_x86_compat_2_isa (bitmask);
20242 }
20243 goto next;
20244
20245 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20246 if (datasz != 4)
20247 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20248 datasz);
20249 else
20250 {
20251 printf ("x86 ISA needed: ");
20252 decode_x86_compat_2_isa (bitmask);
20253 }
20254 goto next;
20255
1fc87489
L
20256 default:
20257 break;
20258 }
20259 }
cd702818
SD
20260 else if (filedata->file_header.e_machine == EM_AARCH64)
20261 {
20262 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20263 {
20264 printf ("AArch64 feature: ");
20265 if (datasz != 4)
20266 printf (_("<corrupt length: %#x> "), datasz);
20267 else
20268 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20269 goto next;
20270 }
20271 }
1fc87489
L
20272 }
20273 else
20274 {
20275 switch (type)
9ef920e9 20276 {
1fc87489
L
20277 case GNU_PROPERTY_STACK_SIZE:
20278 printf (_("stack size: "));
20279 if (datasz != size)
20280 printf (_("<corrupt length: %#x> "), datasz);
20281 else
26c527e6 20282 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
20283 goto next;
20284
20285 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20286 printf ("no copy on protected ");
20287 if (datasz)
20288 printf (_("<corrupt length: %#x> "), datasz);
20289 goto next;
20290
20291 default:
5a767724
L
20292 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20293 && type <= GNU_PROPERTY_UINT32_AND_HI)
20294 || (type >= GNU_PROPERTY_UINT32_OR_LO
20295 && type <= GNU_PROPERTY_UINT32_OR_HI))
20296 {
6320fd00
L
20297 switch (type)
20298 {
20299 case GNU_PROPERTY_1_NEEDED:
20300 if (datasz != 4)
20301 printf (_("1_needed: <corrupt length: %#x> "),
20302 datasz);
20303 else
20304 {
20305 unsigned int bitmask = byte_get (ptr, 4);
20306 printf ("1_needed: ");
20307 decode_1_needed (bitmask);
20308 }
20309 goto next;
20310
20311 default:
20312 break;
20313 }
5a767724
L
20314 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20315 printf (_("UINT32_AND (%#x): "), type);
20316 else
20317 printf (_("UINT32_OR (%#x): "), type);
20318 if (datasz != 4)
20319 printf (_("<corrupt length: %#x> "), datasz);
20320 else
20321 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20322 goto next;
20323 }
9ef920e9
NC
20324 break;
20325 }
9ef920e9
NC
20326 }
20327
1fc87489
L
20328 if (type < GNU_PROPERTY_LOPROC)
20329 printf (_("<unknown type %#x data: "), type);
20330 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20331 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20332 else
20333 printf (_("<application-specific type %#x data: "), type);
20334 for (j = 0; j < datasz; ++j)
20335 printf ("%02x ", ptr[j] & 0xff);
20336 printf (">");
20337
dc1e8a47 20338 next:
9ef920e9 20339 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20340 if (ptr == ptr_end)
20341 break;
1fc87489 20342
6ab2c4ed
MC
20343 if (do_wide)
20344 printf (", ");
20345 else
20346 printf ("\n\t");
9ef920e9
NC
20347 }
20348
20349 printf ("\n");
20350}
20351
015dc7e1 20352static bool
dda8d76d 20353print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20354{
1449284b 20355 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20356 switch (pnote->type)
20357 {
20358 case NT_GNU_BUILD_ID:
20359 {
26c527e6 20360 size_t i;
664f90a3
TT
20361
20362 printf (_(" Build ID: "));
20363 for (i = 0; i < pnote->descsz; ++i)
20364 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20365 printf ("\n");
664f90a3
TT
20366 }
20367 break;
20368
20369 case NT_GNU_ABI_TAG:
20370 {
26c527e6 20371 unsigned int os, major, minor, subminor;
664f90a3
TT
20372 const char *osname;
20373
3102e897
NC
20374 /* PR 17531: file: 030-599401-0.004. */
20375 if (pnote->descsz < 16)
20376 {
20377 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20378 break;
20379 }
20380
664f90a3
TT
20381 os = byte_get ((unsigned char *) pnote->descdata, 4);
20382 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20383 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20384 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20385
20386 switch (os)
20387 {
20388 case GNU_ABI_TAG_LINUX:
20389 osname = "Linux";
20390 break;
20391 case GNU_ABI_TAG_HURD:
20392 osname = "Hurd";
20393 break;
20394 case GNU_ABI_TAG_SOLARIS:
20395 osname = "Solaris";
20396 break;
20397 case GNU_ABI_TAG_FREEBSD:
20398 osname = "FreeBSD";
20399 break;
20400 case GNU_ABI_TAG_NETBSD:
20401 osname = "NetBSD";
20402 break;
14ae95f2
RM
20403 case GNU_ABI_TAG_SYLLABLE:
20404 osname = "Syllable";
20405 break;
20406 case GNU_ABI_TAG_NACL:
20407 osname = "NaCl";
20408 break;
664f90a3
TT
20409 default:
20410 osname = "Unknown";
20411 break;
20412 }
20413
26c527e6 20414 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
20415 major, minor, subminor);
20416 }
20417 break;
926c5385
CC
20418
20419 case NT_GNU_GOLD_VERSION:
20420 {
26c527e6 20421 size_t i;
926c5385
CC
20422
20423 printf (_(" Version: "));
20424 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20425 printf ("%c", pnote->descdata[i]);
20426 printf ("\n");
20427 }
20428 break;
1449284b
NC
20429
20430 case NT_GNU_HWCAP:
20431 {
26c527e6 20432 unsigned int num_entries, mask;
1449284b
NC
20433
20434 /* Hardware capabilities information. Word 0 is the number of entries.
20435 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20436 is a series of entries, where each entry is a single byte followed
20437 by a nul terminated string. The byte gives the bit number to test
20438 if enabled in the bitmask. */
20439 printf (_(" Hardware Capabilities: "));
20440 if (pnote->descsz < 8)
20441 {
32ec8896 20442 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20443 return false;
1449284b
NC
20444 }
20445 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20446 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 20447 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
20448 /* FIXME: Add code to display the entries... */
20449 }
20450 break;
20451
9ef920e9 20452 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20453 print_gnu_property_note (filedata, pnote);
9ef920e9 20454 break;
9abca702 20455
1449284b
NC
20456 default:
20457 /* Handle unrecognised types. An error message should have already been
20458 created by get_gnu_elf_note_type(), so all that we need to do is to
20459 display the data. */
20460 {
26c527e6 20461 size_t i;
1449284b
NC
20462
20463 printf (_(" Description data: "));
20464 for (i = 0; i < pnote->descsz; ++i)
20465 printf ("%02x ", pnote->descdata[i] & 0xff);
20466 printf ("\n");
20467 }
20468 break;
664f90a3
TT
20469 }
20470
015dc7e1 20471 return true;
664f90a3
TT
20472}
20473
685080f2
NC
20474static const char *
20475get_v850_elf_note_type (enum v850_notes n_type)
20476{
20477 static char buff[64];
20478
20479 switch (n_type)
20480 {
20481 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20482 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20483 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20484 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20485 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20486 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20487 default:
20488 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20489 return buff;
20490 }
20491}
20492
015dc7e1 20493static bool
685080f2
NC
20494print_v850_note (Elf_Internal_Note * pnote)
20495{
20496 unsigned int val;
20497
20498 if (pnote->descsz != 4)
015dc7e1 20499 return false;
32ec8896 20500
685080f2
NC
20501 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20502
20503 if (val == 0)
20504 {
20505 printf (_("not set\n"));
015dc7e1 20506 return true;
685080f2
NC
20507 }
20508
20509 switch (pnote->type)
20510 {
20511 case V850_NOTE_ALIGNMENT:
20512 switch (val)
20513 {
015dc7e1
AM
20514 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20515 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20516 }
20517 break;
14ae95f2 20518
685080f2
NC
20519 case V850_NOTE_DATA_SIZE:
20520 switch (val)
20521 {
015dc7e1
AM
20522 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20523 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20524 }
20525 break;
14ae95f2 20526
685080f2
NC
20527 case V850_NOTE_FPU_INFO:
20528 switch (val)
20529 {
015dc7e1
AM
20530 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20531 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20532 }
20533 break;
14ae95f2 20534
685080f2
NC
20535 case V850_NOTE_MMU_INFO:
20536 case V850_NOTE_CACHE_INFO:
20537 case V850_NOTE_SIMD_INFO:
20538 if (val == EF_RH850_SIMD)
20539 {
20540 printf (_("yes\n"));
015dc7e1 20541 return true;
685080f2
NC
20542 }
20543 break;
20544
20545 default:
20546 /* An 'unknown note type' message will already have been displayed. */
20547 break;
20548 }
20549
20550 printf (_("unknown value: %x\n"), val);
015dc7e1 20551 return false;
685080f2
NC
20552}
20553
015dc7e1 20554static bool
c6056a74
SF
20555process_netbsd_elf_note (Elf_Internal_Note * pnote)
20556{
20557 unsigned int version;
20558
20559 switch (pnote->type)
20560 {
20561 case NT_NETBSD_IDENT:
b966f55f
AM
20562 if (pnote->descsz < 1)
20563 break;
c6056a74
SF
20564 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20565 if ((version / 10000) % 100)
b966f55f 20566 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20567 version, version / 100000000, (version / 1000000) % 100,
20568 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20569 'A' + (version / 10000) % 26);
c6056a74
SF
20570 else
20571 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20572 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20573 (version / 100) % 100);
015dc7e1 20574 return true;
c6056a74
SF
20575
20576 case NT_NETBSD_MARCH:
9abca702 20577 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20578 pnote->descdata);
015dc7e1 20579 return true;
c6056a74 20580
9abca702 20581 case NT_NETBSD_PAX:
b966f55f
AM
20582 if (pnote->descsz < 1)
20583 break;
9abca702
CZ
20584 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20585 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20586 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20587 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20588 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20589 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20590 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20591 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20592 return true;
c6056a74 20593 }
b966f55f
AM
20594
20595 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20596 pnote->descsz, pnote->type);
015dc7e1 20597 return false;
c6056a74
SF
20598}
20599
f4ddf30f 20600static const char *
dda8d76d 20601get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20602{
f4ddf30f
JB
20603 switch (e_type)
20604 {
20605 case NT_FREEBSD_THRMISC:
20606 return _("NT_THRMISC (thrmisc structure)");
20607 case NT_FREEBSD_PROCSTAT_PROC:
20608 return _("NT_PROCSTAT_PROC (proc data)");
20609 case NT_FREEBSD_PROCSTAT_FILES:
20610 return _("NT_PROCSTAT_FILES (files data)");
20611 case NT_FREEBSD_PROCSTAT_VMMAP:
20612 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20613 case NT_FREEBSD_PROCSTAT_GROUPS:
20614 return _("NT_PROCSTAT_GROUPS (groups data)");
20615 case NT_FREEBSD_PROCSTAT_UMASK:
20616 return _("NT_PROCSTAT_UMASK (umask data)");
20617 case NT_FREEBSD_PROCSTAT_RLIMIT:
20618 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20619 case NT_FREEBSD_PROCSTAT_OSREL:
20620 return _("NT_PROCSTAT_OSREL (osreldate data)");
20621 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20622 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20623 case NT_FREEBSD_PROCSTAT_AUXV:
20624 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20625 case NT_FREEBSD_PTLWPINFO:
20626 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
20627 case NT_FREEBSD_X86_SEGBASES:
20628 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 20629 }
dda8d76d 20630 return get_note_type (filedata, e_type);
f4ddf30f
JB
20631}
20632
9437c45b 20633static const char *
dda8d76d 20634get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20635{
20636 static char buff[64];
20637
540e6170
CZ
20638 switch (e_type)
20639 {
20640 case NT_NETBSDCORE_PROCINFO:
20641 /* NetBSD core "procinfo" structure. */
20642 return _("NetBSD procinfo structure");
9437c45b 20643
540e6170
CZ
20644 case NT_NETBSDCORE_AUXV:
20645 return _("NetBSD ELF auxiliary vector data");
9437c45b 20646
06d949ec
KR
20647 case NT_NETBSDCORE_LWPSTATUS:
20648 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20649
540e6170 20650 default:
06d949ec 20651 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20652 defined for NetBSD core files. If the note type is less
20653 than the start of the machine-dependent note types, we don't
20654 understand it. */
20655
20656 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20657 {
20658 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20659 return buff;
20660 }
20661 break;
9437c45b
JT
20662 }
20663
dda8d76d 20664 switch (filedata->file_header.e_machine)
9437c45b
JT
20665 {
20666 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20667 and PT_GETFPREGS == mach+2. */
20668
20669 case EM_OLD_ALPHA:
20670 case EM_ALPHA:
20671 case EM_SPARC:
20672 case EM_SPARC32PLUS:
20673 case EM_SPARCV9:
20674 switch (e_type)
20675 {
2b692964 20676 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20677 return _("PT_GETREGS (reg structure)");
2b692964 20678 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20679 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20680 default:
20681 break;
20682 }
20683 break;
20684
c0d38b0e
CZ
20685 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20686 There's also old PT___GETREGS40 == mach + 1 for old reg
20687 structure which lacks GBR. */
20688 case EM_SH:
20689 switch (e_type)
20690 {
20691 case NT_NETBSDCORE_FIRSTMACH + 1:
20692 return _("PT___GETREGS40 (old reg structure)");
20693 case NT_NETBSDCORE_FIRSTMACH + 3:
20694 return _("PT_GETREGS (reg structure)");
20695 case NT_NETBSDCORE_FIRSTMACH + 5:
20696 return _("PT_GETFPREGS (fpreg structure)");
20697 default:
20698 break;
20699 }
20700 break;
20701
9437c45b
JT
20702 /* On all other arch's, PT_GETREGS == mach+1 and
20703 PT_GETFPREGS == mach+3. */
20704 default:
20705 switch (e_type)
20706 {
2b692964 20707 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20708 return _("PT_GETREGS (reg structure)");
2b692964 20709 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20710 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20711 default:
20712 break;
20713 }
20714 }
20715
9cf03b7e 20716 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20717 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20718 return buff;
20719}
20720
98ca73af
FC
20721static const char *
20722get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20723{
20724 switch (e_type)
20725 {
20726 case NT_OPENBSD_PROCINFO:
20727 return _("OpenBSD procinfo structure");
20728 case NT_OPENBSD_AUXV:
20729 return _("OpenBSD ELF auxiliary vector data");
20730 case NT_OPENBSD_REGS:
20731 return _("OpenBSD regular registers");
20732 case NT_OPENBSD_FPREGS:
20733 return _("OpenBSD floating point registers");
20734 case NT_OPENBSD_WCOOKIE:
20735 return _("OpenBSD window cookie");
20736 }
20737
20738 return get_note_type (filedata, e_type);
20739}
20740
e263a66b
CC
20741static const char *
20742get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
20743{
20744 switch (e_type)
20745 {
20746 case QNT_DEBUG_FULLPATH:
20747 return _("QNX debug fullpath");
20748 case QNT_DEBUG_RELOC:
20749 return _("QNX debug relocation");
20750 case QNT_STACK:
20751 return _("QNX stack");
20752 case QNT_GENERATOR:
20753 return _("QNX generator");
20754 case QNT_DEFAULT_LIB:
20755 return _("QNX default library");
20756 case QNT_CORE_SYSINFO:
20757 return _("QNX core sysinfo");
20758 case QNT_CORE_INFO:
20759 return _("QNX core info");
20760 case QNT_CORE_STATUS:
20761 return _("QNX core status");
20762 case QNT_CORE_GREG:
20763 return _("QNX general registers");
20764 case QNT_CORE_FPREG:
20765 return _("QNX floating point registers");
20766 case QNT_LINK_MAP:
20767 return _("QNX link map");
20768 }
20769
20770 return get_note_type (filedata, e_type);
20771}
20772
70616151
TT
20773static const char *
20774get_stapsdt_note_type (unsigned e_type)
20775{
20776 static char buff[64];
20777
20778 switch (e_type)
20779 {
20780 case NT_STAPSDT:
20781 return _("NT_STAPSDT (SystemTap probe descriptors)");
20782
20783 default:
20784 break;
20785 }
20786
20787 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20788 return buff;
20789}
20790
015dc7e1 20791static bool
c6a9fc58
TT
20792print_stapsdt_note (Elf_Internal_Note *pnote)
20793{
3ca60c57 20794 size_t len, maxlen;
26c527e6 20795 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20796 char *data = pnote->descdata;
20797 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 20798 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
20799 char *provider, *probe, *arg_fmt;
20800
3ca60c57
NC
20801 if (pnote->descsz < (addr_size * 3))
20802 goto stapdt_note_too_small;
20803
c6a9fc58
TT
20804 pc = byte_get ((unsigned char *) data, addr_size);
20805 data += addr_size;
3ca60c57 20806
c6a9fc58
TT
20807 base_addr = byte_get ((unsigned char *) data, addr_size);
20808 data += addr_size;
3ca60c57 20809
c6a9fc58
TT
20810 semaphore = byte_get ((unsigned char *) data, addr_size);
20811 data += addr_size;
20812
3ca60c57
NC
20813 if (data >= data_end)
20814 goto stapdt_note_too_small;
20815 maxlen = data_end - data;
20816 len = strnlen (data, maxlen);
20817 if (len < maxlen)
20818 {
20819 provider = data;
20820 data += len + 1;
20821 }
20822 else
20823 goto stapdt_note_too_small;
20824
20825 if (data >= data_end)
20826 goto stapdt_note_too_small;
20827 maxlen = data_end - data;
20828 len = strnlen (data, maxlen);
20829 if (len < maxlen)
20830 {
20831 probe = data;
20832 data += len + 1;
20833 }
20834 else
20835 goto stapdt_note_too_small;
9abca702 20836
3ca60c57
NC
20837 if (data >= data_end)
20838 goto stapdt_note_too_small;
20839 maxlen = data_end - data;
20840 len = strnlen (data, maxlen);
20841 if (len < maxlen)
20842 {
20843 arg_fmt = data;
20844 data += len + 1;
20845 }
20846 else
20847 goto stapdt_note_too_small;
c6a9fc58
TT
20848
20849 printf (_(" Provider: %s\n"), provider);
20850 printf (_(" Name: %s\n"), probe);
20851 printf (_(" Location: "));
20852 print_vma (pc, FULL_HEX);
20853 printf (_(", Base: "));
20854 print_vma (base_addr, FULL_HEX);
20855 printf (_(", Semaphore: "));
20856 print_vma (semaphore, FULL_HEX);
9cf03b7e 20857 printf ("\n");
c6a9fc58
TT
20858 printf (_(" Arguments: %s\n"), arg_fmt);
20859
20860 return data == data_end;
3ca60c57
NC
20861
20862 stapdt_note_too_small:
20863 printf (_(" <corrupt - note is too small>\n"));
20864 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20865 return false;
c6a9fc58
TT
20866}
20867
e5382207
LB
20868static bool
20869print_fdo_note (Elf_Internal_Note * pnote)
20870{
20871 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20872 {
20873 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20874 return true;
20875 }
20876 return false;
20877}
20878
00e98fc7
TG
20879static const char *
20880get_ia64_vms_note_type (unsigned e_type)
20881{
20882 static char buff[64];
20883
20884 switch (e_type)
20885 {
20886 case NT_VMS_MHD:
20887 return _("NT_VMS_MHD (module header)");
20888 case NT_VMS_LNM:
20889 return _("NT_VMS_LNM (language name)");
20890 case NT_VMS_SRC:
20891 return _("NT_VMS_SRC (source files)");
20892 case NT_VMS_TITLE:
9cf03b7e 20893 return "NT_VMS_TITLE";
00e98fc7
TG
20894 case NT_VMS_EIDC:
20895 return _("NT_VMS_EIDC (consistency check)");
20896 case NT_VMS_FPMODE:
20897 return _("NT_VMS_FPMODE (FP mode)");
20898 case NT_VMS_LINKTIME:
9cf03b7e 20899 return "NT_VMS_LINKTIME";
00e98fc7
TG
20900 case NT_VMS_IMGNAM:
20901 return _("NT_VMS_IMGNAM (image name)");
20902 case NT_VMS_IMGID:
20903 return _("NT_VMS_IMGID (image id)");
20904 case NT_VMS_LINKID:
20905 return _("NT_VMS_LINKID (link id)");
20906 case NT_VMS_IMGBID:
20907 return _("NT_VMS_IMGBID (build id)");
20908 case NT_VMS_GSTNAM:
20909 return _("NT_VMS_GSTNAM (sym table name)");
20910 case NT_VMS_ORIG_DYN:
9cf03b7e 20911 return "NT_VMS_ORIG_DYN";
00e98fc7 20912 case NT_VMS_PATCHTIME:
9cf03b7e 20913 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20914 default:
20915 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20916 return buff;
20917 }
20918}
20919
015dc7e1 20920static bool
00e98fc7
TG
20921print_ia64_vms_note (Elf_Internal_Note * pnote)
20922{
26c527e6 20923 unsigned int maxlen = pnote->descsz;
8d18bf79 20924
26c527e6 20925 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
20926 goto desc_size_fail;
20927
00e98fc7
TG
20928 switch (pnote->type)
20929 {
20930 case NT_VMS_MHD:
8d18bf79
NC
20931 if (maxlen <= 36)
20932 goto desc_size_fail;
20933
26c527e6 20934 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
20935
20936 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20937 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20938 if (l + 34 < maxlen)
20939 {
20940 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20941 if (l + 35 < maxlen)
20942 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20943 else
20944 printf (_(" Module version : <missing>\n"));
20945 }
00e98fc7 20946 else
8d18bf79
NC
20947 {
20948 printf (_(" Module name : <missing>\n"));
20949 printf (_(" Module version : <missing>\n"));
20950 }
00e98fc7 20951 break;
8d18bf79 20952
00e98fc7 20953 case NT_VMS_LNM:
8d18bf79 20954 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20955 break;
8d18bf79 20956
00e98fc7 20957 case NT_VMS_FPMODE:
9cf03b7e 20958 printf (_(" Floating Point mode: "));
8d18bf79
NC
20959 if (maxlen < 8)
20960 goto desc_size_fail;
20961 /* FIXME: Generate an error if descsz > 8 ? */
20962
b8281767 20963 printf ("0x%016" PRIx64 "\n",
625d49fc 20964 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 20965 break;
8d18bf79 20966
00e98fc7
TG
20967 case NT_VMS_LINKTIME:
20968 printf (_(" Link time: "));
8d18bf79
NC
20969 if (maxlen < 8)
20970 goto desc_size_fail;
20971 /* FIXME: Generate an error if descsz > 8 ? */
20972
0e3c1eeb 20973 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20974 printf ("\n");
20975 break;
8d18bf79 20976
00e98fc7
TG
20977 case NT_VMS_PATCHTIME:
20978 printf (_(" Patch time: "));
8d18bf79
NC
20979 if (maxlen < 8)
20980 goto desc_size_fail;
20981 /* FIXME: Generate an error if descsz > 8 ? */
20982
0e3c1eeb 20983 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20984 printf ("\n");
20985 break;
8d18bf79 20986
00e98fc7 20987 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20988 if (maxlen < 34)
20989 goto desc_size_fail;
20990
00e98fc7 20991 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
20992 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
20993 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 20994 printf (_(" Last modified : "));
0e3c1eeb 20995 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 20996 printf (_("\n Link flags : "));
b8281767 20997 printf ("0x%016" PRIx64 "\n",
625d49fc 20998 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 20999 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 21000 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 21001 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 21002 break;
8d18bf79 21003
00e98fc7 21004 case NT_VMS_IMGNAM:
8d18bf79 21005 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21006 break;
8d18bf79 21007
00e98fc7 21008 case NT_VMS_GSTNAM:
8d18bf79 21009 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21010 break;
8d18bf79 21011
00e98fc7 21012 case NT_VMS_IMGID:
8d18bf79 21013 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21014 break;
8d18bf79 21015
00e98fc7 21016 case NT_VMS_LINKID:
8d18bf79 21017 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21018 break;
8d18bf79 21019
00e98fc7 21020 default:
015dc7e1 21021 return false;
00e98fc7 21022 }
8d18bf79 21023
015dc7e1 21024 return true;
8d18bf79
NC
21025
21026 desc_size_fail:
21027 printf (_(" <corrupt - data size is too small>\n"));
21028 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 21029 return false;
00e98fc7
TG
21030}
21031
fd486f32
AM
21032struct build_attr_cache {
21033 Filedata *filedata;
21034 char *strtab;
26c527e6 21035 uint64_t strtablen;
fd486f32 21036 Elf_Internal_Sym *symtab;
26c527e6 21037 uint64_t nsyms;
fd486f32
AM
21038} ba_cache;
21039
6f156d7a
NC
21040/* Find the symbol associated with a build attribute that is attached
21041 to address OFFSET. If PNAME is non-NULL then store the name of
21042 the symbol (if found) in the provided pointer, Returns NULL if a
21043 symbol could not be found. */
c799a79d 21044
6f156d7a 21045static Elf_Internal_Sym *
015dc7e1 21046get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 21047 uint64_t offset,
015dc7e1
AM
21048 bool is_open_attr,
21049 const char **pname)
9ef920e9 21050{
fd486f32
AM
21051 Elf_Internal_Sym *saved_sym = NULL;
21052 Elf_Internal_Sym *sym;
9ef920e9 21053
dda8d76d 21054 if (filedata->section_headers != NULL
fd486f32 21055 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 21056 {
c799a79d 21057 Elf_Internal_Shdr * symsec;
9ef920e9 21058
fd486f32
AM
21059 free (ba_cache.strtab);
21060 ba_cache.strtab = NULL;
21061 free (ba_cache.symtab);
21062 ba_cache.symtab = NULL;
21063
c799a79d 21064 /* Load the symbol and string sections. */
dda8d76d
NC
21065 for (symsec = filedata->section_headers;
21066 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 21067 symsec ++)
9ef920e9 21068 {
28d13567
AM
21069 if (symsec->sh_type == SHT_SYMTAB
21070 && get_symtab (filedata, symsec,
21071 &ba_cache.symtab, &ba_cache.nsyms,
21072 &ba_cache.strtab, &ba_cache.strtablen))
21073 break;
9ef920e9 21074 }
fd486f32 21075 ba_cache.filedata = filedata;
9ef920e9
NC
21076 }
21077
fd486f32 21078 if (ba_cache.symtab == NULL)
6f156d7a 21079 return NULL;
9ef920e9 21080
c799a79d 21081 /* Find a symbol whose value matches offset. */
fd486f32 21082 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
21083 if (sym->st_value == offset)
21084 {
fd486f32 21085 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
21086 /* Huh ? This should not happen. */
21087 continue;
9ef920e9 21088
fd486f32 21089 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 21090 continue;
9ef920e9 21091
9b9b1092 21092 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 21093 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
21094 if (ba_cache.strtab[sym->st_name] == '$'
21095 && ba_cache.strtab[sym->st_name + 1] != 0
21096 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
21097 continue;
21098
c799a79d
NC
21099 if (is_open_attr)
21100 {
21101 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
21102 and FILE or OBJECT symbols over NOTYPE symbols. We skip
21103 FUNC symbols entirely. */
21104 switch (ELF_ST_TYPE (sym->st_info))
21105 {
c799a79d 21106 case STT_OBJECT:
6f156d7a 21107 case STT_FILE:
c799a79d 21108 saved_sym = sym;
6f156d7a
NC
21109 if (sym->st_size)
21110 {
21111 /* If the symbol has a size associated
21112 with it then we can stop searching. */
fd486f32 21113 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 21114 }
c799a79d 21115 continue;
9ef920e9 21116
c799a79d
NC
21117 case STT_FUNC:
21118 /* Ignore function symbols. */
21119 continue;
21120
21121 default:
21122 break;
21123 }
21124
21125 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 21126 {
c799a79d
NC
21127 case STB_GLOBAL:
21128 if (saved_sym == NULL
21129 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
21130 saved_sym = sym;
21131 break;
c871dade 21132
c799a79d
NC
21133 case STB_LOCAL:
21134 if (saved_sym == NULL)
21135 saved_sym = sym;
21136 break;
21137
21138 default:
9ef920e9
NC
21139 break;
21140 }
21141 }
c799a79d
NC
21142 else
21143 {
21144 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
21145 continue;
21146
21147 saved_sym = sym;
21148 break;
21149 }
21150 }
21151
6f156d7a 21152 if (saved_sym && pname)
fd486f32 21153 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
21154
21155 return saved_sym;
c799a79d
NC
21156}
21157
d20e98ab
NC
21158/* Returns true iff addr1 and addr2 are in the same section. */
21159
015dc7e1 21160static bool
26c527e6 21161same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
21162{
21163 Elf_Internal_Shdr * a1;
21164 Elf_Internal_Shdr * a2;
21165
21166 a1 = find_section_by_address (filedata, addr1);
21167 a2 = find_section_by_address (filedata, addr2);
9abca702 21168
d20e98ab
NC
21169 return a1 == a2 && a1 != NULL;
21170}
21171
015dc7e1 21172static bool
dda8d76d
NC
21173print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21174 Filedata * filedata)
c799a79d 21175{
26c527e6
AM
21176 static uint64_t global_offset = 0;
21177 static uint64_t global_end = 0;
21178 static uint64_t func_offset = 0;
21179 static uint64_t func_end = 0;
c871dade 21180
015dc7e1
AM
21181 Elf_Internal_Sym *sym;
21182 const char *name;
26c527e6
AM
21183 uint64_t start;
21184 uint64_t end;
015dc7e1 21185 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
21186
21187 switch (pnote->descsz)
c799a79d 21188 {
6f156d7a
NC
21189 case 0:
21190 /* A zero-length description means that the range of
21191 the previous note of the same type should be used. */
c799a79d 21192 if (is_open_attr)
c871dade 21193 {
6f156d7a 21194 if (global_end > global_offset)
26c527e6
AM
21195 printf (_(" Applies to region from %#" PRIx64
21196 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 21197 else
26c527e6
AM
21198 printf (_(" Applies to region from %#" PRIx64
21199 "\n"), global_offset);
c799a79d
NC
21200 }
21201 else
21202 {
6f156d7a 21203 if (func_end > func_offset)
26c527e6
AM
21204 printf (_(" Applies to region from %#" PRIx64
21205 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 21206 else
26c527e6
AM
21207 printf (_(" Applies to region from %#" PRIx64
21208 "\n"), func_offset);
c871dade 21209 }
015dc7e1 21210 return true;
9ef920e9 21211
6f156d7a
NC
21212 case 4:
21213 start = byte_get ((unsigned char *) pnote->descdata, 4);
21214 end = 0;
21215 break;
21216
21217 case 8:
c74147bb
NC
21218 start = byte_get ((unsigned char *) pnote->descdata, 4);
21219 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21220 break;
21221
21222 case 16:
21223 start = byte_get ((unsigned char *) pnote->descdata, 8);
21224 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21225 break;
9abca702 21226
6f156d7a 21227 default:
c799a79d
NC
21228 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21229 printf (_(" <invalid descsz>"));
015dc7e1 21230 return false;
c799a79d
NC
21231 }
21232
6f156d7a
NC
21233 name = NULL;
21234 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21235 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21236 in order to avoid them being confused with the start address of the
21237 first function in the file... */
21238 if (sym == NULL && is_open_attr)
21239 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21240 & name);
6f156d7a
NC
21241
21242 if (end == 0 && sym != NULL && sym->st_size > 0)
21243 end = start + sym->st_size;
c799a79d
NC
21244
21245 if (is_open_attr)
21246 {
d20e98ab
NC
21247 /* FIXME: Need to properly allow for section alignment.
21248 16 is just the alignment used on x86_64. */
21249 if (global_end > 0
21250 && start > BFD_ALIGN (global_end, 16)
21251 /* Build notes are not guaranteed to be organised in order of
21252 increasing address, but we should find the all of the notes
21253 for one section in the same place. */
21254 && same_section (filedata, start, global_end))
26c527e6
AM
21255 warn (_("Gap in build notes detected from %#" PRIx64
21256 " to %#" PRIx64 "\n"),
6f156d7a
NC
21257 global_end + 1, start - 1);
21258
26c527e6 21259 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21260 global_offset = start;
21261
21262 if (end)
21263 {
26c527e6 21264 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21265 global_end = end;
21266 }
c799a79d
NC
21267 }
21268 else
21269 {
26c527e6 21270 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21271 func_offset = start;
21272
21273 if (end)
21274 {
26c527e6 21275 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21276 func_end = end;
21277 }
c799a79d
NC
21278 }
21279
6f156d7a
NC
21280 if (sym && name)
21281 printf (_(" (%s)"), name);
21282
21283 printf ("\n");
015dc7e1 21284 return true;
9ef920e9
NC
21285}
21286
015dc7e1 21287static bool
9ef920e9
NC
21288print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21289{
1d15e434
NC
21290 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21291 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21292 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21293 char name_type;
21294 char name_attribute;
1d15e434 21295 const char * expected_types;
9ef920e9
NC
21296 const char * name = pnote->namedata;
21297 const char * text;
88305e1b 21298 signed int left;
9ef920e9
NC
21299
21300 if (name == NULL || pnote->namesz < 2)
21301 {
21302 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21303 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21304 return false;
9ef920e9
NC
21305 }
21306
6f156d7a
NC
21307 if (do_wide)
21308 left = 28;
21309 else
21310 left = 20;
88305e1b
NC
21311
21312 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21313 if (name[0] == 'G' && name[1] == 'A')
21314 {
6f156d7a
NC
21315 if (pnote->namesz < 4)
21316 {
21317 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21318 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21319 return false;
6f156d7a
NC
21320 }
21321
88305e1b
NC
21322 printf ("GA");
21323 name += 2;
21324 left -= 2;
21325 }
21326
9ef920e9
NC
21327 switch ((name_type = * name))
21328 {
21329 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21330 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21331 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21332 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21333 printf ("%c", * name);
88305e1b 21334 left --;
9ef920e9
NC
21335 break;
21336 default:
21337 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21338 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21339 return false;
9ef920e9
NC
21340 }
21341
9ef920e9
NC
21342 ++ name;
21343 text = NULL;
21344
21345 switch ((name_attribute = * name))
21346 {
21347 case GNU_BUILD_ATTRIBUTE_VERSION:
21348 text = _("<version>");
1d15e434 21349 expected_types = string_expected;
9ef920e9
NC
21350 ++ name;
21351 break;
21352 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21353 text = _("<stack prot>");
75d7d298 21354 expected_types = "!+*";
9ef920e9
NC
21355 ++ name;
21356 break;
21357 case GNU_BUILD_ATTRIBUTE_RELRO:
21358 text = _("<relro>");
1d15e434 21359 expected_types = bool_expected;
9ef920e9
NC
21360 ++ name;
21361 break;
21362 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21363 text = _("<stack size>");
1d15e434 21364 expected_types = number_expected;
9ef920e9
NC
21365 ++ name;
21366 break;
21367 case GNU_BUILD_ATTRIBUTE_TOOL:
21368 text = _("<tool>");
1d15e434 21369 expected_types = string_expected;
9ef920e9
NC
21370 ++ name;
21371 break;
21372 case GNU_BUILD_ATTRIBUTE_ABI:
21373 text = _("<ABI>");
21374 expected_types = "$*";
21375 ++ name;
21376 break;
21377 case GNU_BUILD_ATTRIBUTE_PIC:
21378 text = _("<PIC>");
1d15e434 21379 expected_types = number_expected;
9ef920e9
NC
21380 ++ name;
21381 break;
a8be5506
NC
21382 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21383 text = _("<short enum>");
1d15e434 21384 expected_types = bool_expected;
a8be5506
NC
21385 ++ name;
21386 break;
9ef920e9
NC
21387 default:
21388 if (ISPRINT (* name))
21389 {
21390 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21391
21392 if (len > left && ! do_wide)
21393 len = left;
75d7d298 21394 printf ("%.*s:", len, name);
9ef920e9 21395 left -= len;
0dd6ae21 21396 name += len;
9ef920e9
NC
21397 }
21398 else
21399 {
3e6b6445 21400 static char tmpbuf [128];
88305e1b 21401
3e6b6445
NC
21402 error (_("unrecognised byte in name field: %d\n"), * name);
21403 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21404 text = tmpbuf;
21405 name ++;
9ef920e9
NC
21406 }
21407 expected_types = "*$!+";
21408 break;
21409 }
21410
21411 if (text)
88305e1b 21412 left -= printf ("%s", text);
9ef920e9
NC
21413
21414 if (strchr (expected_types, name_type) == NULL)
75d7d298 21415 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 21416
26c527e6 21417 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 21418 {
26c527e6
AM
21419 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
21420 pnote->namesz,
21421 name - pnote->namedata);
015dc7e1 21422 return false;
9ef920e9
NC
21423 }
21424
21425 if (left < 1 && ! do_wide)
015dc7e1 21426 return true;
9ef920e9
NC
21427
21428 switch (name_type)
21429 {
21430 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21431 {
26c527e6
AM
21432 unsigned int bytes;
21433 uint64_t val = 0;
21434 unsigned int shift = 0;
21435 char *decoded = NULL;
ddef72cd 21436
b06b2c92
NC
21437 bytes = pnote->namesz - (name - pnote->namedata);
21438 if (bytes > 0)
21439 /* The -1 is because the name field is always 0 terminated, and we
21440 want to be able to ensure that the shift in the while loop below
21441 will not overflow. */
21442 -- bytes;
21443
ddef72cd
NC
21444 if (bytes > sizeof (val))
21445 {
3e6b6445
NC
21446 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21447 bytes);
21448 bytes = sizeof (val);
ddef72cd 21449 }
3e6b6445
NC
21450 /* We do not bother to warn if bytes == 0 as this can
21451 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21452
21453 while (bytes --)
21454 {
26c527e6 21455 uint64_t byte = *name++ & 0xff;
79a964dc
NC
21456
21457 val |= byte << shift;
9ef920e9
NC
21458 shift += 8;
21459 }
21460
75d7d298 21461 switch (name_attribute)
9ef920e9 21462 {
75d7d298 21463 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21464 switch (val)
21465 {
75d7d298
NC
21466 case 0: decoded = "static"; break;
21467 case 1: decoded = "pic"; break;
21468 case 2: decoded = "PIC"; break;
21469 case 3: decoded = "pie"; break;
21470 case 4: decoded = "PIE"; break;
21471 default: break;
9ef920e9 21472 }
75d7d298
NC
21473 break;
21474 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21475 switch (val)
9ef920e9 21476 {
75d7d298
NC
21477 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21478 case 0: decoded = "off"; break;
21479 case 1: decoded = "on"; break;
21480 case 2: decoded = "all"; break;
21481 case 3: decoded = "strong"; break;
21482 case 4: decoded = "explicit"; break;
21483 default: break;
9ef920e9 21484 }
75d7d298
NC
21485 break;
21486 default:
21487 break;
9ef920e9
NC
21488 }
21489
75d7d298 21490 if (decoded != NULL)
3e6b6445
NC
21491 {
21492 print_symbol (-left, decoded);
21493 left = 0;
21494 }
21495 else if (val == 0)
21496 {
21497 printf ("0x0");
21498 left -= 3;
21499 }
9ef920e9 21500 else
75d7d298
NC
21501 {
21502 if (do_wide)
26c527e6 21503 left -= printf ("0x%" PRIx64, val);
75d7d298 21504 else
26c527e6 21505 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 21506 }
9ef920e9
NC
21507 }
21508 break;
21509 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21510 left -= print_symbol (- left, name);
21511 break;
21512 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21513 left -= print_symbol (- left, "true");
21514 break;
21515 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21516 left -= print_symbol (- left, "false");
21517 break;
21518 }
21519
21520 if (do_wide && left > 0)
21521 printf ("%-*s", left, " ");
9abca702 21522
015dc7e1 21523 return true;
9ef920e9
NC
21524}
21525
2952f10c
SM
21526/* Print the contents of PNOTE as hex. */
21527
21528static void
21529print_note_contents_hex (Elf_Internal_Note *pnote)
21530{
21531 if (pnote->descsz)
21532 {
26c527e6 21533 size_t i;
2952f10c
SM
21534
21535 printf (_(" description data: "));
21536 for (i = 0; i < pnote->descsz; i++)
21537 printf ("%02x ", pnote->descdata[i] & 0xff);
21538 if (!do_wide)
21539 printf ("\n");
21540 }
21541
21542 if (do_wide)
21543 printf ("\n");
21544}
21545
21546#if defined HAVE_MSGPACK
21547
21548static void
21549print_indents (int n)
21550{
21551 printf (" ");
21552
21553 for (int i = 0; i < n; i++)
21554 printf (" ");
21555}
21556
21557/* Print OBJ in human-readable form. */
21558
21559static void
21560dump_msgpack_obj (const msgpack_object *obj, int indent)
21561{
21562 switch (obj->type)
21563 {
21564 case MSGPACK_OBJECT_NIL:
21565 printf ("(nil)");
21566 break;
21567
21568 case MSGPACK_OBJECT_BOOLEAN:
21569 printf ("%s", obj->via.boolean ? "true" : "false");
21570 break;
21571
21572 case MSGPACK_OBJECT_POSITIVE_INTEGER:
21573 printf ("%" PRIu64, obj->via.u64);
21574 break;
21575
21576 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
21577 printf ("%" PRIi64, obj->via.i64);
21578 break;
21579
21580 case MSGPACK_OBJECT_FLOAT32:
21581 case MSGPACK_OBJECT_FLOAT64:
21582 printf ("%f", obj->via.f64);
21583 break;
21584
21585 case MSGPACK_OBJECT_STR:
21586 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
21587 break;
21588
21589 case MSGPACK_OBJECT_ARRAY:
21590 {
21591 const msgpack_object_array *array = &obj->via.array;
21592
21593 printf ("[\n");
21594 ++indent;
21595
21596 for (uint32_t i = 0; i < array->size; ++i)
21597 {
21598 const msgpack_object *item = &array->ptr[i];
21599
21600 print_indents (indent);
21601 dump_msgpack_obj (item, indent);
21602 printf (",\n");
21603 }
21604
21605 --indent;
21606 print_indents (indent);
21607 printf ("]");
21608 break;
21609 }
21610 break;
21611
21612 case MSGPACK_OBJECT_MAP:
21613 {
21614 const msgpack_object_map *map = &obj->via.map;
21615
21616 printf ("{\n");
21617 ++indent;
21618
21619 for (uint32_t i = 0; i < map->size; ++i)
21620 {
21621 const msgpack_object_kv *kv = &map->ptr[i];
21622 const msgpack_object *key = &kv->key;
21623 const msgpack_object *val = &kv->val;
21624
21625 print_indents (indent);
21626 dump_msgpack_obj (key, indent);
21627 printf (": ");
21628 dump_msgpack_obj (val, indent);
21629
21630 printf (",\n");
21631 }
21632
21633 --indent;
21634 print_indents (indent);
21635 printf ("}");
21636
21637 break;
21638 }
21639
21640 case MSGPACK_OBJECT_BIN:
21641 printf ("(bin)");
21642 break;
21643
21644 case MSGPACK_OBJECT_EXT:
21645 printf ("(ext)");
21646 break;
21647 }
21648}
21649
21650static void
21651dump_msgpack (const msgpack_unpacked *msg)
21652{
21653 print_indents (0);
21654 dump_msgpack_obj (&msg->data, 0);
21655 printf ("\n");
21656}
21657
21658#endif /* defined HAVE_MSGPACK */
21659
21660static bool
21661print_amdgpu_note (Elf_Internal_Note *pnote)
21662{
21663#if defined HAVE_MSGPACK
21664 /* If msgpack is available, decode and dump the note's content. */
21665 bool ret;
21666 msgpack_unpacked msg;
21667 msgpack_unpack_return msgpack_ret;
21668
21669 assert (pnote->type == NT_AMDGPU_METADATA);
21670
21671 msgpack_unpacked_init (&msg);
21672 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
21673 NULL);
21674
21675 switch (msgpack_ret)
21676 {
21677 case MSGPACK_UNPACK_SUCCESS:
21678 dump_msgpack (&msg);
21679 ret = true;
21680 break;
21681
21682 default:
21683 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
21684 ret = false;
21685 break;
21686 }
21687
21688 msgpack_unpacked_destroy (&msg);
21689 return ret;
21690#else
21691 /* msgpack is not available, dump contents as hex. */
21692 print_note_contents_hex (pnote);
21693 return true;
21694#endif
21695}
21696
e263a66b
CC
21697static bool
21698print_qnx_note (Elf_Internal_Note *pnote)
21699{
21700 switch (pnote->type)
21701 {
21702 case QNT_STACK:
21703 if (pnote->descsz != 12)
21704 goto desc_size_fail;
21705
21706 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
21707 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
21708 printf (_(" Stack allocated: %" PRIx32 "\n"),
21709 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
21710 printf (_(" Executable: %s\n"),
21711 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
21712 break;
21713
21714 default:
21715 print_note_contents_hex(pnote);
21716 }
21717 return true;
21718
21719desc_size_fail:
21720 printf (_(" <corrupt - data size is too small>\n"));
21721 error (_("corrupt QNX note: data size is too small\n"));
21722 return false;
21723}
21724
21725
6d118b09
NC
21726/* Note that by the ELF standard, the name field is already null byte
21727 terminated, and namesz includes the terminating null byte.
21728 I.E. the value of namesz for the name "FSF" is 4.
21729
e3c8793a 21730 If the value of namesz is zero, there is no name present. */
9ef920e9 21731
015dc7e1 21732static bool
9ef920e9 21733process_note (Elf_Internal_Note * pnote,
dda8d76d 21734 Filedata * filedata)
779fe533 21735{
2cf0635d
NC
21736 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21737 const char * nt;
9437c45b
JT
21738
21739 if (pnote->namesz == 0)
1ec5cd37
NC
21740 /* If there is no note name, then use the default set of
21741 note type strings. */
dda8d76d 21742 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21743
24d127aa 21744 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21745 /* GNU-specific object file notes. */
21746 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21747
28cdbb18
SM
21748 else if (startswith (pnote->namedata, "AMDGPU"))
21749 /* AMDGPU-specific object file notes. */
21750 nt = get_amdgpu_elf_note_type (pnote->type);
21751
24d127aa 21752 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21753 /* FreeBSD-specific core file notes. */
dda8d76d 21754 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21755
24d127aa 21756 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21757 /* NetBSD-specific core file notes. */
dda8d76d 21758 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21759
24d127aa 21760 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21761 /* NetBSD-specific core file notes. */
21762 return process_netbsd_elf_note (pnote);
21763
24d127aa 21764 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21765 /* NetBSD-specific core file notes. */
21766 return process_netbsd_elf_note (pnote);
21767
98ca73af
FC
21768 else if (startswith (pnote->namedata, "OpenBSD"))
21769 /* OpenBSD-specific core file notes. */
21770 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21771
e263a66b
CC
21772 else if (startswith (pnote->namedata, "QNX"))
21773 /* QNX-specific core file notes. */
21774 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
21775
e9b095a5 21776 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21777 {
21778 /* SPU-specific core file notes. */
21779 nt = pnote->namedata + 4;
21780 name = "SPU";
21781 }
21782
24d127aa 21783 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21784 /* VMS/ia64-specific file notes. */
21785 nt = get_ia64_vms_note_type (pnote->type);
21786
24d127aa 21787 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21788 nt = get_stapsdt_note_type (pnote->type);
21789
9437c45b 21790 else
1ec5cd37
NC
21791 /* Don't recognize this note name; just use the default set of
21792 note type strings. */
dda8d76d 21793 nt = get_note_type (filedata, pnote->type);
9437c45b 21794
1449284b 21795 printf (" ");
9ef920e9 21796
24d127aa 21797 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21798 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21799 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21800 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21801 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21802 print_gnu_build_attribute_name (pnote);
21803 else
21804 print_symbol (-20, name);
21805
21806 if (do_wide)
21807 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21808 else
21809 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21810
24d127aa 21811 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21812 return print_ia64_vms_note (pnote);
24d127aa 21813 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21814 return print_gnu_note (filedata, pnote);
24d127aa 21815 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21816 return print_stapsdt_note (pnote);
24d127aa 21817 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21818 return print_core_note (pnote);
e5382207
LB
21819 else if (startswith (pnote->namedata, "FDO"))
21820 return print_fdo_note (pnote);
24d127aa 21821 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21822 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21823 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21824 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21825 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21826 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
21827 else if (startswith (pnote->namedata, "AMDGPU")
21828 && pnote->type == NT_AMDGPU_METADATA)
21829 return print_amdgpu_note (pnote);
e263a66b
CC
21830 else if (startswith (pnote->namedata, "QNX"))
21831 return print_qnx_note (pnote);
779fe533 21832
2952f10c 21833 print_note_contents_hex (pnote);
015dc7e1 21834 return true;
1449284b 21835}
6d118b09 21836
015dc7e1 21837static bool
dda8d76d
NC
21838process_notes_at (Filedata * filedata,
21839 Elf_Internal_Shdr * section,
625d49fc
AM
21840 uint64_t offset,
21841 uint64_t length,
21842 uint64_t align)
779fe533 21843{
015dc7e1
AM
21844 Elf_External_Note *pnotes;
21845 Elf_External_Note *external;
21846 char *end;
21847 bool res = true;
103f02d3 21848
779fe533 21849 if (length <= 0)
015dc7e1 21850 return false;
103f02d3 21851
1449284b
NC
21852 if (section)
21853 {
dda8d76d 21854 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21855 if (pnotes)
32ec8896 21856 {
dda8d76d 21857 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21858 {
21859 free (pnotes);
015dc7e1 21860 return false;
f761cb13 21861 }
32ec8896 21862 }
1449284b
NC
21863 }
21864 else
82ed9683 21865 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21866 _("notes"));
4dff97b2 21867
dd24e3da 21868 if (pnotes == NULL)
015dc7e1 21869 return false;
779fe533 21870
103f02d3 21871 external = pnotes;
103f02d3 21872
ca0e11aa
NC
21873 if (filedata->is_separate)
21874 printf (_("In linked file '%s': "), filedata->file_name);
21875 else
21876 printf ("\n");
1449284b 21877 if (section)
ca0e11aa 21878 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21879 else
26c527e6
AM
21880 printf (_("Displaying notes found at file offset 0x%08" PRIx64
21881 " with length 0x%08" PRIx64 ":\n"),
21882 offset, length);
1449284b 21883
82ed9683
L
21884 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21885 specifies that notes should be aligned to 4 bytes in 32-bit
21886 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21887 we also support 4 byte alignment in 64-bit objects. If section
21888 alignment is less than 4, we treate alignment as 4 bytes. */
21889 if (align < 4)
21890 align = 4;
21891 else if (align != 4 && align != 8)
21892 {
26c527e6
AM
21893 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
21894 align);
a788aedd 21895 free (pnotes);
015dc7e1 21896 return false;
82ed9683
L
21897 }
21898
dbe15e4e 21899 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21900
c8071705
NC
21901 end = (char *) pnotes + length;
21902 while ((char *) external < end)
779fe533 21903 {
b34976b6 21904 Elf_Internal_Note inote;
15b42fb0 21905 size_t min_notesz;
4dff97b2 21906 char * next;
2cf0635d 21907 char * temp = NULL;
c8071705 21908 size_t data_remaining = end - (char *) external;
6d118b09 21909
dda8d76d 21910 if (!is_ia64_vms (filedata))
15b42fb0 21911 {
9dd3a467
NC
21912 /* PR binutils/15191
21913 Make sure that there is enough data to read. */
15b42fb0
AM
21914 min_notesz = offsetof (Elf_External_Note, name);
21915 if (data_remaining < min_notesz)
9dd3a467 21916 {
26c527e6 21917 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 21918 "not enough for a full note\n",
26c527e6 21919 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
21920 "not enough for a full note\n",
21921 data_remaining),
26c527e6 21922 data_remaining);
9dd3a467
NC
21923 break;
21924 }
5396a86e
AM
21925 data_remaining -= min_notesz;
21926
15b42fb0
AM
21927 inote.type = BYTE_GET (external->type);
21928 inote.namesz = BYTE_GET (external->namesz);
21929 inote.namedata = external->name;
21930 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21931 inote.descdata = ((char *) external
4dff97b2 21932 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21933 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21934 next = ((char *) external
4dff97b2 21935 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21936 }
00e98fc7 21937 else
15b42fb0
AM
21938 {
21939 Elf64_External_VMS_Note *vms_external;
00e98fc7 21940
9dd3a467
NC
21941 /* PR binutils/15191
21942 Make sure that there is enough data to read. */
15b42fb0
AM
21943 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21944 if (data_remaining < min_notesz)
9dd3a467 21945 {
26c527e6 21946 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 21947 "not enough for a full note\n",
26c527e6 21948 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
21949 "not enough for a full note\n",
21950 data_remaining),
26c527e6 21951 data_remaining);
9dd3a467
NC
21952 break;
21953 }
5396a86e 21954 data_remaining -= min_notesz;
3e55a963 21955
15b42fb0
AM
21956 vms_external = (Elf64_External_VMS_Note *) external;
21957 inote.type = BYTE_GET (vms_external->type);
21958 inote.namesz = BYTE_GET (vms_external->namesz);
21959 inote.namedata = vms_external->name;
21960 inote.descsz = BYTE_GET (vms_external->descsz);
21961 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21962 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21963 next = inote.descdata + align_power (inote.descsz, 3);
21964 }
21965
5396a86e
AM
21966 /* PR 17531: file: 3443835e. */
21967 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21968 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21969 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21970 || (size_t) (next - inote.descdata) < inote.descsz
21971 || ((size_t) (next - inote.descdata)
21972 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21973 {
26c527e6
AM
21974 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
21975 (char *) external - (char *) pnotes);
21976 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 21977 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21978 break;
21979 }
21980
15b42fb0 21981 external = (Elf_External_Note *) next;
dd24e3da 21982
6d118b09
NC
21983 /* Verify that name is null terminated. It appears that at least
21984 one version of Linux (RedHat 6.0) generates corefiles that don't
21985 comply with the ELF spec by failing to include the null byte in
21986 namesz. */
18344509 21987 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21988 {
5396a86e 21989 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21990 {
5396a86e
AM
21991 temp = (char *) malloc (inote.namesz + 1);
21992 if (temp == NULL)
21993 {
21994 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21995 res = false;
5396a86e
AM
21996 break;
21997 }
76da6bbe 21998
5396a86e
AM
21999 memcpy (temp, inote.namedata, inote.namesz);
22000 inote.namedata = temp;
22001 }
22002 inote.namedata[inote.namesz] = 0;
6d118b09
NC
22003 }
22004
dda8d76d 22005 if (! process_note (& inote, filedata))
015dc7e1 22006 res = false;
103f02d3 22007
9db70fc3
AM
22008 free (temp);
22009 temp = NULL;
779fe533
NC
22010 }
22011
22012 free (pnotes);
103f02d3 22013
779fe533
NC
22014 return res;
22015}
22016
015dc7e1 22017static bool
dda8d76d 22018process_corefile_note_segments (Filedata * filedata)
779fe533 22019{
015dc7e1 22020 Elf_Internal_Phdr *segment;
b34976b6 22021 unsigned int i;
015dc7e1 22022 bool res = true;
103f02d3 22023
dda8d76d 22024 if (! get_program_headers (filedata))
015dc7e1 22025 return true;
103f02d3 22026
dda8d76d
NC
22027 for (i = 0, segment = filedata->program_headers;
22028 i < filedata->file_header.e_phnum;
b34976b6 22029 i++, segment++)
779fe533
NC
22030 {
22031 if (segment->p_type == PT_NOTE)
625d49fc
AM
22032 if (! process_notes_at (filedata, NULL, segment->p_offset,
22033 segment->p_filesz, segment->p_align))
015dc7e1 22034 res = false;
779fe533 22035 }
103f02d3 22036
779fe533
NC
22037 return res;
22038}
22039
015dc7e1 22040static bool
625d49fc 22041process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
22042{
22043 Elf_External_Note * pnotes;
22044 Elf_External_Note * external;
c8071705 22045 char * end;
015dc7e1 22046 bool res = true;
685080f2
NC
22047
22048 if (length <= 0)
015dc7e1 22049 return false;
685080f2 22050
dda8d76d 22051 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
22052 _("v850 notes"));
22053 if (pnotes == NULL)
015dc7e1 22054 return false;
685080f2
NC
22055
22056 external = pnotes;
c8071705 22057 end = (char*) pnotes + length;
685080f2 22058
26c527e6
AM
22059 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22060 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22061 offset, length);
685080f2 22062
c8071705 22063 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
22064 {
22065 Elf_External_Note * next;
22066 Elf_Internal_Note inote;
22067
22068 inote.type = BYTE_GET (external->type);
22069 inote.namesz = BYTE_GET (external->namesz);
22070 inote.namedata = external->name;
22071 inote.descsz = BYTE_GET (external->descsz);
22072 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22073 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22074
c8071705
NC
22075 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22076 {
22077 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22078 inote.descdata = inote.namedata;
22079 inote.namesz = 0;
22080 }
22081
685080f2
NC
22082 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22083
c8071705 22084 if ( ((char *) next > end)
685080f2
NC
22085 || ((char *) next < (char *) pnotes))
22086 {
26c527e6
AM
22087 warn (_("corrupt descsz found in note at offset %#tx\n"),
22088 (char *) external - (char *) pnotes);
22089 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22090 inote.type, inote.namesz, inote.descsz);
22091 break;
22092 }
22093
22094 external = next;
22095
22096 /* Prevent out-of-bounds indexing. */
c8071705 22097 if ( inote.namedata + inote.namesz > end
685080f2
NC
22098 || inote.namedata + inote.namesz < inote.namedata)
22099 {
26c527e6
AM
22100 warn (_("corrupt namesz found in note at offset %#zx\n"),
22101 (char *) external - (char *) pnotes);
22102 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22103 inote.type, inote.namesz, inote.descsz);
22104 break;
22105 }
22106
22107 printf (" %s: ", get_v850_elf_note_type (inote.type));
22108
22109 if (! print_v850_note (& inote))
22110 {
015dc7e1 22111 res = false;
26c527e6 22112 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
22113 inote.namesz, inote.descsz);
22114 }
22115 }
22116
22117 free (pnotes);
22118
22119 return res;
22120}
22121
015dc7e1 22122static bool
dda8d76d 22123process_note_sections (Filedata * filedata)
1ec5cd37 22124{
015dc7e1 22125 Elf_Internal_Shdr *section;
26c527e6 22126 size_t i;
32ec8896 22127 unsigned int n = 0;
015dc7e1 22128 bool res = true;
1ec5cd37 22129
dda8d76d
NC
22130 for (i = 0, section = filedata->section_headers;
22131 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 22132 i++, section++)
685080f2
NC
22133 {
22134 if (section->sh_type == SHT_NOTE)
22135 {
625d49fc
AM
22136 if (! process_notes_at (filedata, section, section->sh_offset,
22137 section->sh_size, section->sh_addralign))
015dc7e1 22138 res = false;
685080f2
NC
22139 n++;
22140 }
22141
dda8d76d
NC
22142 if (( filedata->file_header.e_machine == EM_V800
22143 || filedata->file_header.e_machine == EM_V850
22144 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
22145 && section->sh_type == SHT_RENESAS_INFO)
22146 {
625d49fc
AM
22147 if (! process_v850_notes (filedata, section->sh_offset,
22148 section->sh_size))
015dc7e1 22149 res = false;
685080f2
NC
22150 n++;
22151 }
22152 }
df565f32
NC
22153
22154 if (n == 0)
22155 /* Try processing NOTE segments instead. */
dda8d76d 22156 return process_corefile_note_segments (filedata);
1ec5cd37
NC
22157
22158 return res;
22159}
22160
015dc7e1 22161static bool
dda8d76d 22162process_notes (Filedata * filedata)
779fe533
NC
22163{
22164 /* If we have not been asked to display the notes then do nothing. */
22165 if (! do_notes)
015dc7e1 22166 return true;
103f02d3 22167
dda8d76d
NC
22168 if (filedata->file_header.e_type != ET_CORE)
22169 return process_note_sections (filedata);
103f02d3 22170
779fe533 22171 /* No program headers means no NOTE segment. */
dda8d76d
NC
22172 if (filedata->file_header.e_phnum > 0)
22173 return process_corefile_note_segments (filedata);
779fe533 22174
ca0e11aa
NC
22175 if (filedata->is_separate)
22176 printf (_("No notes found in linked file '%s'.\n"),
22177 filedata->file_name);
22178 else
22179 printf (_("No notes found file.\n"));
22180
015dc7e1 22181 return true;
779fe533
NC
22182}
22183
60abdbed
NC
22184static unsigned char *
22185display_public_gnu_attributes (unsigned char * start,
22186 const unsigned char * const end)
22187{
22188 printf (_(" Unknown GNU attribute: %s\n"), start);
22189
22190 start += strnlen ((char *) start, end - start);
22191 display_raw_attribute (start, end);
22192
22193 return (unsigned char *) end;
22194}
22195
22196static unsigned char *
22197display_generic_attribute (unsigned char * start,
22198 unsigned int tag,
22199 const unsigned char * const end)
22200{
22201 if (tag == 0)
22202 return (unsigned char *) end;
22203
22204 return display_tag_value (tag, start, end);
22205}
22206
015dc7e1 22207static bool
dda8d76d 22208process_arch_specific (Filedata * filedata)
252b5132 22209{
a952a375 22210 if (! do_arch)
015dc7e1 22211 return true;
a952a375 22212
dda8d76d 22213 switch (filedata->file_header.e_machine)
252b5132 22214 {
53a346d8
CZ
22215 case EM_ARC:
22216 case EM_ARC_COMPACT:
22217 case EM_ARC_COMPACT2:
dda8d76d 22218 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
22219 display_arc_attribute,
22220 display_generic_attribute);
11c1ff18 22221 case EM_ARM:
dda8d76d 22222 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
22223 display_arm_attribute,
22224 display_generic_attribute);
22225
252b5132 22226 case EM_MIPS:
4fe85591 22227 case EM_MIPS_RS3_LE:
dda8d76d 22228 return process_mips_specific (filedata);
60abdbed
NC
22229
22230 case EM_MSP430:
dda8d76d 22231 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 22232 display_msp430_attribute,
c0ea7c52 22233 display_msp430_gnu_attribute);
60abdbed 22234
2dc8dd17
JW
22235 case EM_RISCV:
22236 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22237 display_riscv_attribute,
22238 display_generic_attribute);
22239
35c08157 22240 case EM_NDS32:
dda8d76d 22241 return process_nds32_specific (filedata);
60abdbed 22242
85f7484a
PB
22243 case EM_68K:
22244 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22245 display_m68k_gnu_attribute);
22246
34c8bcba 22247 case EM_PPC:
b82317dd 22248 case EM_PPC64:
dda8d76d 22249 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22250 display_power_gnu_attribute);
22251
643f7afb
AK
22252 case EM_S390:
22253 case EM_S390_OLD:
dda8d76d 22254 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22255 display_s390_gnu_attribute);
22256
9e8c70f9
DM
22257 case EM_SPARC:
22258 case EM_SPARC32PLUS:
22259 case EM_SPARCV9:
dda8d76d 22260 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22261 display_sparc_gnu_attribute);
22262
59e6276b 22263 case EM_TI_C6000:
dda8d76d 22264 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22265 display_tic6x_attribute,
22266 display_generic_attribute);
22267
0861f561
CQ
22268 case EM_CSKY:
22269 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22270 display_csky_attribute, NULL);
22271
252b5132 22272 default:
dda8d76d 22273 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22274 display_public_gnu_attributes,
22275 display_generic_attribute);
252b5132 22276 }
252b5132
RH
22277}
22278
015dc7e1 22279static bool
dda8d76d 22280get_file_header (Filedata * filedata)
252b5132 22281{
9ea033b2 22282 /* Read in the identity array. */
dda8d76d 22283 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22284 return false;
252b5132 22285
9ea033b2 22286 /* Determine how to read the rest of the header. */
dda8d76d 22287 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22288 {
1a0670f3
AM
22289 default:
22290 case ELFDATANONE:
adab8cdc
AO
22291 case ELFDATA2LSB:
22292 byte_get = byte_get_little_endian;
22293 byte_put = byte_put_little_endian;
22294 break;
22295 case ELFDATA2MSB:
22296 byte_get = byte_get_big_endian;
22297 byte_put = byte_put_big_endian;
22298 break;
9ea033b2
NC
22299 }
22300
22301 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22302 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22303
22304 /* Read in the rest of the header. */
22305 if (is_32bit_elf)
22306 {
22307 Elf32_External_Ehdr ehdr32;
252b5132 22308
dda8d76d 22309 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22310 return false;
103f02d3 22311
dda8d76d
NC
22312 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22313 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22314 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22315 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22316 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22317 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22318 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22319 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22320 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22321 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22322 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22323 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22324 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22325 }
252b5132 22326 else
9ea033b2
NC
22327 {
22328 Elf64_External_Ehdr ehdr64;
a952a375 22329
dda8d76d 22330 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22331 return false;
103f02d3 22332
dda8d76d
NC
22333 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22334 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22335 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22336 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22337 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22338 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22339 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22340 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22341 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22342 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22343 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22344 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22345 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22346 }
252b5132 22347
015dc7e1 22348 return true;
252b5132
RH
22349}
22350
13acb58d
AM
22351static void
22352free_filedata (Filedata *filedata)
22353{
22354 free (filedata->program_interpreter);
13acb58d 22355 free (filedata->program_headers);
13acb58d 22356 free (filedata->section_headers);
13acb58d 22357 free (filedata->string_table);
13acb58d 22358 free (filedata->dump.dump_sects);
13acb58d 22359 free (filedata->dynamic_strings);
13acb58d 22360 free (filedata->dynamic_symbols);
13acb58d 22361 free (filedata->dynamic_syminfo);
13acb58d 22362 free (filedata->dynamic_section);
13acb58d
AM
22363
22364 while (filedata->symtab_shndx_list != NULL)
22365 {
22366 elf_section_list *next = filedata->symtab_shndx_list->next;
22367 free (filedata->symtab_shndx_list);
22368 filedata->symtab_shndx_list = next;
22369 }
22370
22371 free (filedata->section_headers_groups);
13acb58d
AM
22372
22373 if (filedata->section_groups)
22374 {
22375 size_t i;
22376 struct group_list * g;
22377 struct group_list * next;
22378
22379 for (i = 0; i < filedata->group_count; i++)
22380 {
22381 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22382 {
22383 next = g->next;
22384 free (g);
22385 }
22386 }
22387
22388 free (filedata->section_groups);
13acb58d 22389 }
066f8fbe
AM
22390 memset (&filedata->section_headers, 0,
22391 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22392}
22393
dda8d76d
NC
22394static void
22395close_file (Filedata * filedata)
22396{
22397 if (filedata)
22398 {
22399 if (filedata->handle)
22400 fclose (filedata->handle);
22401 free (filedata);
22402 }
22403}
22404
22405void
22406close_debug_file (void * data)
22407{
13acb58d 22408 free_filedata ((Filedata *) data);
dda8d76d
NC
22409 close_file ((Filedata *) data);
22410}
22411
22412static Filedata *
015dc7e1 22413open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22414{
22415 struct stat statbuf;
22416 Filedata * filedata = NULL;
22417
22418 if (stat (pathname, & statbuf) < 0
22419 || ! S_ISREG (statbuf.st_mode))
22420 goto fail;
22421
22422 filedata = calloc (1, sizeof * filedata);
22423 if (filedata == NULL)
22424 goto fail;
22425
22426 filedata->handle = fopen (pathname, "rb");
22427 if (filedata->handle == NULL)
22428 goto fail;
22429
be7d229a 22430 filedata->file_size = statbuf.st_size;
dda8d76d 22431 filedata->file_name = pathname;
ca0e11aa 22432 filedata->is_separate = is_separate;
dda8d76d
NC
22433
22434 if (! get_file_header (filedata))
22435 goto fail;
22436
4de91c10
AM
22437 if (!get_section_headers (filedata, false))
22438 goto fail;
dda8d76d
NC
22439
22440 return filedata;
22441
22442 fail:
22443 if (filedata)
22444 {
22445 if (filedata->handle)
22446 fclose (filedata->handle);
22447 free (filedata);
22448 }
22449 return NULL;
22450}
22451
22452void *
22453open_debug_file (const char * pathname)
22454{
015dc7e1 22455 return open_file (pathname, true);
dda8d76d
NC
22456}
22457
835f2fae
NC
22458static void
22459initialise_dump_sects (Filedata * filedata)
22460{
22461 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22462 Note we do this even if cmdline_dump_sects is empty because we
22463 must make sure that the dump_sets array is zeroed out before each
22464 object file is processed. */
22465 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22466 memset (filedata->dump.dump_sects, 0,
22467 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22468
22469 if (cmdline.num_dump_sects > 0)
22470 {
22471 if (filedata->dump.num_dump_sects == 0)
22472 /* A sneaky way of allocating the dump_sects array. */
22473 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22474
22475 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22476 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22477 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22478 }
22479}
22480
94585d6d
NC
22481static bool
22482might_need_separate_debug_info (Filedata * filedata)
22483{
22484 /* Debuginfo files do not need further separate file loading. */
22485 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22486 return false;
22487
22488 /* Since do_follow_links might be enabled by default, only treat it as an
22489 indication that separate files should be loaded if setting it was a
22490 deliberate user action. */
22491 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22492 return true;
22493
22494 if (process_links || do_syms || do_unwind
22495 || dump_any_debugging || do_dump || do_debugging)
22496 return true;
22497
22498 return false;
22499}
22500
fb52b2f4
NC
22501/* Process one ELF object file according to the command line options.
22502 This file may actually be stored in an archive. The file is
32ec8896
NC
22503 positioned at the start of the ELF object. Returns TRUE if no
22504 problems were encountered, FALSE otherwise. */
fb52b2f4 22505
015dc7e1 22506static bool
dda8d76d 22507process_object (Filedata * filedata)
252b5132 22508{
015dc7e1 22509 bool have_separate_files;
252b5132 22510 unsigned int i;
015dc7e1 22511 bool res;
252b5132 22512
dda8d76d 22513 if (! get_file_header (filedata))
252b5132 22514 {
dda8d76d 22515 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22516 return false;
252b5132
RH
22517 }
22518
22519 /* Initialise per file variables. */
978c4450
AM
22520 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22521 filedata->version_info[i] = 0;
252b5132 22522
978c4450
AM
22523 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22524 filedata->dynamic_info[i] = 0;
22525 filedata->dynamic_info_DT_GNU_HASH = 0;
22526 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22527
22528 /* Process the file. */
22529 if (show_name)
dda8d76d 22530 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22531
835f2fae 22532 initialise_dump_sects (filedata);
d70c5fc7 22533
4de91c10
AM
22534 /* There may be some extensions in the first section header. Don't
22535 bomb if we can't read it. */
22536 get_section_headers (filedata, true);
22537
dda8d76d 22538 if (! process_file_header (filedata))
4de91c10
AM
22539 {
22540 res = false;
22541 goto out;
22542 }
252b5132 22543
e331b18d
AM
22544 /* Throw away the single section header read above, so that we
22545 re-read the entire set. */
22546 free (filedata->section_headers);
22547 filedata->section_headers = NULL;
22548
dda8d76d 22549 if (! process_section_headers (filedata))
2f62977e 22550 {
32ec8896 22551 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22552 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22553
2f62977e 22554 if (! do_using_dynamic)
015dc7e1 22555 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22556 }
252b5132 22557
dda8d76d 22558 if (! process_section_groups (filedata))
32ec8896 22559 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22560 do_unwind = false;
d1f5c6e3 22561
93df3340
AM
22562 process_program_headers (filedata);
22563
22564 res = process_dynamic_section (filedata);
252b5132 22565
dda8d76d 22566 if (! process_relocs (filedata))
015dc7e1 22567 res = false;
252b5132 22568
dda8d76d 22569 if (! process_unwind (filedata))
015dc7e1 22570 res = false;
4d6ed7c8 22571
dda8d76d 22572 if (! process_symbol_table (filedata))
015dc7e1 22573 res = false;
252b5132 22574
0f03783c 22575 if (! process_lto_symbol_tables (filedata))
015dc7e1 22576 res = false;
b9e920ec 22577
dda8d76d 22578 if (! process_syminfo (filedata))
015dc7e1 22579 res = false;
252b5132 22580
dda8d76d 22581 if (! process_version_sections (filedata))
015dc7e1 22582 res = false;
252b5132 22583
94585d6d 22584 if (might_need_separate_debug_info (filedata))
24841daa 22585 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22586 else
015dc7e1 22587 have_separate_files = false;
dda8d76d
NC
22588
22589 if (! process_section_contents (filedata))
015dc7e1 22590 res = false;
f5842774 22591
24841daa 22592 if (have_separate_files)
dda8d76d 22593 {
24841daa
NC
22594 separate_info * d;
22595
22596 for (d = first_separate_info; d != NULL; d = d->next)
22597 {
835f2fae
NC
22598 initialise_dump_sects (d->handle);
22599
ca0e11aa 22600 if (process_links && ! process_file_header (d->handle))
015dc7e1 22601 res = false;
ca0e11aa 22602 else if (! process_section_headers (d->handle))
015dc7e1 22603 res = false;
d6bfbc39 22604 else if (! process_section_contents (d->handle))
015dc7e1 22605 res = false;
ca0e11aa
NC
22606 else if (process_links)
22607 {
ca0e11aa 22608 if (! process_section_groups (d->handle))
015dc7e1 22609 res = false;
93df3340 22610 process_program_headers (d->handle);
ca0e11aa 22611 if (! process_dynamic_section (d->handle))
015dc7e1 22612 res = false;
ca0e11aa 22613 if (! process_relocs (d->handle))
015dc7e1 22614 res = false;
ca0e11aa 22615 if (! process_unwind (d->handle))
015dc7e1 22616 res = false;
ca0e11aa 22617 if (! process_symbol_table (d->handle))
015dc7e1 22618 res = false;
ca0e11aa 22619 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22620 res = false;
ca0e11aa 22621 if (! process_syminfo (d->handle))
015dc7e1 22622 res = false;
ca0e11aa 22623 if (! process_version_sections (d->handle))
015dc7e1 22624 res = false;
ca0e11aa 22625 if (! process_notes (d->handle))
015dc7e1 22626 res = false;
ca0e11aa 22627 }
24841daa
NC
22628 }
22629
22630 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22631 }
22632
22633 if (! process_notes (filedata))
015dc7e1 22634 res = false;
103f02d3 22635
dda8d76d 22636 if (! process_gnu_liblist (filedata))
015dc7e1 22637 res = false;
047b2264 22638
dda8d76d 22639 if (! process_arch_specific (filedata))
015dc7e1 22640 res = false;
252b5132 22641
4de91c10 22642 out:
13acb58d 22643 free_filedata (filedata);
e4b17d5c 22644
19e6b90e 22645 free_debug_memory ();
18bd398b 22646
32ec8896 22647 return res;
252b5132
RH
22648}
22649
2cf0635d 22650/* Process an ELF archive.
32ec8896
NC
22651 On entry the file is positioned just after the ARMAG string.
22652 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22653
015dc7e1
AM
22654static bool
22655process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22656{
22657 struct archive_info arch;
22658 struct archive_info nested_arch;
22659 size_t got;
015dc7e1 22660 bool ret = true;
2cf0635d 22661
015dc7e1 22662 show_name = true;
2cf0635d
NC
22663
22664 /* The ARCH structure is used to hold information about this archive. */
22665 arch.file_name = NULL;
22666 arch.file = NULL;
22667 arch.index_array = NULL;
22668 arch.sym_table = NULL;
22669 arch.longnames = NULL;
22670
22671 /* The NESTED_ARCH structure is used as a single-item cache of information
22672 about a nested archive (when members of a thin archive reside within
22673 another regular archive file). */
22674 nested_arch.file_name = NULL;
22675 nested_arch.file = NULL;
22676 nested_arch.index_array = NULL;
22677 nested_arch.sym_table = NULL;
22678 nested_arch.longnames = NULL;
22679
dda8d76d 22680 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22681 filedata->file_size, is_thin_archive,
22682 do_archive_index) != 0)
2cf0635d 22683 {
015dc7e1 22684 ret = false;
2cf0635d 22685 goto out;
4145f1d5 22686 }
fb52b2f4 22687
4145f1d5
NC
22688 if (do_archive_index)
22689 {
2cf0635d 22690 if (arch.sym_table == NULL)
1cb7d8b1
AM
22691 error (_("%s: unable to dump the index as none was found\n"),
22692 filedata->file_name);
4145f1d5
NC
22693 else
22694 {
26c527e6
AM
22695 uint64_t i, l;
22696 uint64_t current_pos;
4145f1d5 22697
26c527e6
AM
22698 printf (_("Index of archive %s: (%" PRIu64 " entries,"
22699 " %#" PRIx64 " bytes in the symbol table)\n"),
22700 filedata->file_name, arch.index_num,
1cb7d8b1 22701 arch.sym_size);
dda8d76d
NC
22702
22703 current_pos = ftell (filedata->handle);
4145f1d5 22704
2cf0635d 22705 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22706 {
1cb7d8b1
AM
22707 if (i == 0
22708 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22709 {
22710 char * member_name
22711 = get_archive_member_name_at (&arch, arch.index_array[i],
22712 &nested_arch);
2cf0635d 22713
1cb7d8b1
AM
22714 if (member_name != NULL)
22715 {
22716 char * qualified_name
22717 = make_qualified_name (&arch, &nested_arch,
22718 member_name);
2cf0635d 22719
1cb7d8b1
AM
22720 if (qualified_name != NULL)
22721 {
22722 printf (_("Contents of binary %s at offset "),
22723 qualified_name);
c2a7d3f5
NC
22724 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22725 putchar ('\n');
1cb7d8b1
AM
22726 free (qualified_name);
22727 }
fd486f32 22728 free (member_name);
4145f1d5
NC
22729 }
22730 }
2cf0635d
NC
22731
22732 if (l >= arch.sym_size)
4145f1d5 22733 {
1cb7d8b1
AM
22734 error (_("%s: end of the symbol table reached "
22735 "before the end of the index\n"),
dda8d76d 22736 filedata->file_name);
015dc7e1 22737 ret = false;
cb8f3167 22738 break;
4145f1d5 22739 }
591f7597 22740 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22741 printf ("\t%.*s\n",
22742 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22743 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22744 }
22745
67ce483b 22746 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22747 l = (l + 7) & ~ 7;
22748 else
22749 l += l & 1;
22750
2cf0635d 22751 if (l < arch.sym_size)
32ec8896 22752 {
26c527e6 22753 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
22754 "but without corresponding entries in "
22755 "the index table\n",
26c527e6 22756 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
22757 "but without corresponding entries in "
22758 "the index table\n",
22759 arch.sym_size - l),
dda8d76d 22760 filedata->file_name, arch.sym_size - l);
015dc7e1 22761 ret = false;
32ec8896 22762 }
4145f1d5 22763
63cf857e 22764 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22765 {
1cb7d8b1
AM
22766 error (_("%s: failed to seek back to start of object files "
22767 "in the archive\n"),
dda8d76d 22768 filedata->file_name);
015dc7e1 22769 ret = false;
2cf0635d 22770 goto out;
4145f1d5 22771 }
fb52b2f4 22772 }
4145f1d5
NC
22773
22774 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22775 && !do_segments && !do_header && !do_dump && !do_version
22776 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22777 && !do_section_groups && !do_dyn_syms)
2cf0635d 22778 {
015dc7e1 22779 ret = true; /* Archive index only. */
2cf0635d
NC
22780 goto out;
22781 }
fb52b2f4
NC
22782 }
22783
fb52b2f4
NC
22784 while (1)
22785 {
2cf0635d
NC
22786 char * name;
22787 size_t namelen;
22788 char * qualified_name;
22789
22790 /* Read the next archive header. */
63cf857e 22791 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22792 {
22793 error (_("%s: failed to seek to next archive header\n"),
22794 arch.file_name);
015dc7e1 22795 ret = false;
1cb7d8b1
AM
22796 break;
22797 }
dda8d76d 22798 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22799 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22800 {
22801 if (got == 0)
2cf0635d 22802 break;
28e817cc
NC
22803 /* PR 24049 - we cannot use filedata->file_name as this will
22804 have already been freed. */
22805 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22806
015dc7e1 22807 ret = false;
1cb7d8b1
AM
22808 break;
22809 }
2cf0635d 22810 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22811 {
22812 error (_("%s: did not find a valid archive header\n"),
22813 arch.file_name);
015dc7e1 22814 ret = false;
1cb7d8b1
AM
22815 break;
22816 }
2cf0635d
NC
22817
22818 arch.next_arhdr_offset += sizeof arch.arhdr;
22819
978c4450 22820 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22821
22822 name = get_archive_member_name (&arch, &nested_arch);
22823 if (name == NULL)
fb52b2f4 22824 {
28e817cc 22825 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22826 ret = false;
d989285c 22827 break;
fb52b2f4 22828 }
2cf0635d 22829 namelen = strlen (name);
fb52b2f4 22830
2cf0635d
NC
22831 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22832 if (qualified_name == NULL)
fb52b2f4 22833 {
28e817cc 22834 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22835 free (name);
015dc7e1 22836 ret = false;
d989285c 22837 break;
fb52b2f4
NC
22838 }
22839
2cf0635d 22840 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22841 {
22842 /* This is a proxy for an external member of a thin archive. */
22843 Filedata * member_filedata;
22844 char * member_file_name = adjust_relative_path
dda8d76d 22845 (filedata->file_name, name, namelen);
32ec8896 22846
fd486f32 22847 free (name);
1cb7d8b1
AM
22848 if (member_file_name == NULL)
22849 {
fd486f32 22850 free (qualified_name);
015dc7e1 22851 ret = false;
1cb7d8b1
AM
22852 break;
22853 }
2cf0635d 22854
015dc7e1 22855 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22856 if (member_filedata == NULL)
22857 {
22858 error (_("Input file '%s' is not readable.\n"), member_file_name);
22859 free (member_file_name);
fd486f32 22860 free (qualified_name);
015dc7e1 22861 ret = false;
1cb7d8b1
AM
22862 break;
22863 }
2cf0635d 22864
978c4450 22865 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22866 member_filedata->file_name = qualified_name;
2cf0635d 22867
75a2da57
AH
22868 /* The call to process_object() expects the file to be at the beginning. */
22869 rewind (member_filedata->handle);
22870
1cb7d8b1 22871 if (! process_object (member_filedata))
015dc7e1 22872 ret = false;
2cf0635d 22873
1cb7d8b1
AM
22874 close_file (member_filedata);
22875 free (member_file_name);
1cb7d8b1 22876 }
2cf0635d 22877 else if (is_thin_archive)
1cb7d8b1
AM
22878 {
22879 Filedata thin_filedata;
eb02c04d 22880
1cb7d8b1 22881 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22882
a043396b
NC
22883 /* PR 15140: Allow for corrupt thin archives. */
22884 if (nested_arch.file == NULL)
22885 {
22886 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22887 qualified_name, name);
fd486f32
AM
22888 free (qualified_name);
22889 free (name);
015dc7e1 22890 ret = false;
a043396b
NC
22891 break;
22892 }
fd486f32 22893 free (name);
a043396b 22894
1cb7d8b1 22895 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22896 filedata->archive_file_offset
22897 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22898
1cb7d8b1
AM
22899 /* The nested archive file will have been opened and setup by
22900 get_archive_member_name. */
63cf857e
AM
22901 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
22902 SEEK_SET) != 0)
1cb7d8b1
AM
22903 {
22904 error (_("%s: failed to seek to archive member.\n"),
22905 nested_arch.file_name);
fd486f32 22906 free (qualified_name);
015dc7e1 22907 ret = false;
1cb7d8b1
AM
22908 break;
22909 }
2cf0635d 22910
dda8d76d
NC
22911 thin_filedata.handle = nested_arch.file;
22912 thin_filedata.file_name = qualified_name;
9abca702 22913
1cb7d8b1 22914 if (! process_object (& thin_filedata))
015dc7e1 22915 ret = false;
1cb7d8b1 22916 }
2cf0635d 22917 else
1cb7d8b1 22918 {
fd486f32 22919 free (name);
978c4450 22920 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22921 filedata->file_name = qualified_name;
1cb7d8b1 22922 if (! process_object (filedata))
015dc7e1 22923 ret = false;
237877b8 22924 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22925 /* Stop looping with "negative" archive_file_size. */
978c4450 22926 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22927 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22928 }
fb52b2f4 22929
2cf0635d 22930 free (qualified_name);
fb52b2f4
NC
22931 }
22932
4145f1d5 22933 out:
2cf0635d
NC
22934 if (nested_arch.file != NULL)
22935 fclose (nested_arch.file);
22936 release_archive (&nested_arch);
22937 release_archive (&arch);
fb52b2f4 22938
d989285c 22939 return ret;
fb52b2f4
NC
22940}
22941
015dc7e1 22942static bool
2cf0635d 22943process_file (char * file_name)
fb52b2f4 22944{
dda8d76d 22945 Filedata * filedata = NULL;
fb52b2f4
NC
22946 struct stat statbuf;
22947 char armag[SARMAG];
015dc7e1 22948 bool ret = true;
fb52b2f4
NC
22949
22950 if (stat (file_name, &statbuf) < 0)
22951 {
f24ddbdd
NC
22952 if (errno == ENOENT)
22953 error (_("'%s': No such file\n"), file_name);
22954 else
22955 error (_("Could not locate '%s'. System error message: %s\n"),
22956 file_name, strerror (errno));
015dc7e1 22957 return false;
f24ddbdd
NC
22958 }
22959
22960 if (! S_ISREG (statbuf.st_mode))
22961 {
22962 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22963 return false;
fb52b2f4
NC
22964 }
22965
dda8d76d
NC
22966 filedata = calloc (1, sizeof * filedata);
22967 if (filedata == NULL)
22968 {
22969 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22970 return false;
dda8d76d
NC
22971 }
22972
22973 filedata->file_name = file_name;
22974 filedata->handle = fopen (file_name, "rb");
22975 if (filedata->handle == NULL)
fb52b2f4 22976 {
f24ddbdd 22977 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22978 free (filedata);
015dc7e1 22979 return false;
fb52b2f4
NC
22980 }
22981
dda8d76d 22982 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22983 {
4145f1d5 22984 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22985 fclose (filedata->handle);
22986 free (filedata);
015dc7e1 22987 return false;
fb52b2f4
NC
22988 }
22989
be7d229a 22990 filedata->file_size = statbuf.st_size;
015dc7e1 22991 filedata->is_separate = false;
f54498b4 22992
fb52b2f4 22993 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22994 {
015dc7e1
AM
22995 if (! process_archive (filedata, false))
22996 ret = false;
32ec8896 22997 }
2cf0635d 22998 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22999 {
015dc7e1
AM
23000 if ( ! process_archive (filedata, true))
23001 ret = false;
32ec8896 23002 }
fb52b2f4
NC
23003 else
23004 {
1b513401 23005 if (do_archive_index && !check_all)
4145f1d5
NC
23006 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23007 file_name);
23008
dda8d76d 23009 rewind (filedata->handle);
978c4450 23010 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 23011
dda8d76d 23012 if (! process_object (filedata))
015dc7e1 23013 ret = false;
fb52b2f4
NC
23014 }
23015
dda8d76d 23016 fclose (filedata->handle);
8fb879cd
AM
23017 free (filedata->section_headers);
23018 free (filedata->program_headers);
23019 free (filedata->string_table);
6431e409 23020 free (filedata->dump.dump_sects);
dda8d76d 23021 free (filedata);
32ec8896 23022
fd486f32 23023 free (ba_cache.strtab);
1bd6175a 23024 ba_cache.strtab = NULL;
fd486f32 23025 free (ba_cache.symtab);
1bd6175a 23026 ba_cache.symtab = NULL;
fd486f32
AM
23027 ba_cache.filedata = NULL;
23028
fb52b2f4
NC
23029 return ret;
23030}
23031
252b5132
RH
23032#ifdef SUPPORT_DISASSEMBLY
23033/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 23034 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 23035 symbols. */
252b5132
RH
23036
23037void
2cf0635d 23038print_address (unsigned int addr, FILE * outfile)
252b5132
RH
23039{
23040 fprintf (outfile,"0x%8.8x", addr);
23041}
23042
e3c8793a 23043/* Needed by the i386 disassembler. */
dda8d76d 23044
252b5132
RH
23045void
23046db_task_printsym (unsigned int addr)
23047{
23048 print_address (addr, stderr);
23049}
23050#endif
23051
23052int
2cf0635d 23053main (int argc, char ** argv)
252b5132 23054{
ff78d6d6
L
23055 int err;
23056
87b9f255 23057#ifdef HAVE_LC_MESSAGES
252b5132 23058 setlocale (LC_MESSAGES, "");
3882b010 23059#endif
3882b010 23060 setlocale (LC_CTYPE, "");
252b5132
RH
23061 bindtextdomain (PACKAGE, LOCALEDIR);
23062 textdomain (PACKAGE);
23063
869b9d07
MM
23064 expandargv (&argc, &argv);
23065
dda8d76d 23066 parse_args (& cmdline, argc, argv);
59f14fc0 23067
18bd398b 23068 if (optind < (argc - 1))
1b513401
NC
23069 /* When displaying information for more than one file,
23070 prefix the information with the file name. */
015dc7e1 23071 show_name = true;
5656ba2c
L
23072 else if (optind >= argc)
23073 {
1b513401 23074 /* Ensure that the warning is always displayed. */
015dc7e1 23075 do_checks = true;
1b513401 23076
5656ba2c
L
23077 warn (_("Nothing to do.\n"));
23078 usage (stderr);
23079 }
18bd398b 23080
015dc7e1 23081 err = false;
252b5132 23082 while (optind < argc)
32ec8896 23083 if (! process_file (argv[optind++]))
015dc7e1 23084 err = true;
252b5132 23085
9db70fc3 23086 free (cmdline.dump_sects);
252b5132 23087
7d9813f1
NA
23088 free (dump_ctf_symtab_name);
23089 free (dump_ctf_strtab_name);
23090 free (dump_ctf_parent_name);
23091
32ec8896 23092 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 23093}