]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
LoongArch: Fix dynamic reloc not generated bug in some cases.
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
a2c58332 2 Copyright (C) 1998-2022 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;
625d49fc
AM
307 uint64_t dynamic_info[DT_ENCODING];
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
3eba3ef3
NC
4643 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4644 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4645 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4646
252b5132 4647 default:
df3a023b 4648 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4649 {
2cf0635d 4650 const char * result;
103f02d3 4651
dda8d76d 4652 switch (filedata->file_header.e_machine)
252b5132 4653 {
a06ea964
NC
4654 case EM_AARCH64:
4655 result = get_aarch64_segment_type (p_type);
4656 break;
b294bdf8
MM
4657 case EM_ARM:
4658 result = get_arm_segment_type (p_type);
4659 break;
252b5132 4660 case EM_MIPS:
4fe85591 4661 case EM_MIPS_RS3_LE:
252b5132
RH
4662 result = get_mips_segment_type (p_type);
4663 break;
103f02d3
UD
4664 case EM_PARISC:
4665 result = get_parisc_segment_type (p_type);
4666 break;
4d6ed7c8
NC
4667 case EM_IA_64:
4668 result = get_ia64_segment_type (p_type);
4669 break;
40b36596
JM
4670 case EM_TI_C6000:
4671 result = get_tic6x_segment_type (p_type);
4672 break;
b4cbbe8f
AK
4673 case EM_S390:
4674 case EM_S390_OLD:
4675 result = get_s390_segment_type (p_type);
4676 break;
fbc95f1e
KC
4677 case EM_RISCV:
4678 result = get_riscv_segment_type (p_type);
4679 break;
252b5132
RH
4680 default:
4681 result = NULL;
4682 break;
4683 }
103f02d3 4684
252b5132
RH
4685 if (result != NULL)
4686 return result;
103f02d3 4687
1a9ccd70 4688 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4689 }
4690 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4691 {
df3a023b 4692 const char * result = NULL;
103f02d3 4693
df3a023b 4694 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4695 {
df3a023b
AM
4696 case ELFOSABI_GNU:
4697 case ELFOSABI_FREEBSD:
4698 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4699 {
4700 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4701 result = buff;
4702 }
103f02d3 4703 break;
df3a023b
AM
4704 case ELFOSABI_HPUX:
4705 result = get_hpux_segment_type (p_type,
4706 filedata->file_header.e_machine);
4707 break;
4708 case ELFOSABI_SOLARIS:
4709 result = get_solaris_segment_type (p_type);
00428cca 4710 break;
103f02d3 4711 default:
103f02d3
UD
4712 break;
4713 }
103f02d3
UD
4714 if (result != NULL)
4715 return result;
4716
1a9ccd70 4717 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4718 }
252b5132 4719 else
e9e44622 4720 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4721
4722 return buff;
4723 }
4724}
4725
53a346d8
CZ
4726static const char *
4727get_arc_section_type_name (unsigned int sh_type)
4728{
4729 switch (sh_type)
4730 {
4731 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4732 default:
4733 break;
4734 }
4735 return NULL;
4736}
4737
252b5132 4738static const char *
d3ba0551 4739get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4740{
4741 switch (sh_type)
4742 {
b34976b6
AM
4743 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4744 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4745 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4746 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4747 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4748 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4749 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4750 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4751 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4752 case SHT_MIPS_RELD: return "MIPS_RELD";
4753 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4754 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4755 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4756 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4757 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4758 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4759 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4760 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4761 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4762 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4763 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4764 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4765 case SHT_MIPS_LINE: return "MIPS_LINE";
4766 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4767 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4768 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4769 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4770 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4771 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4772 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4773 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4774 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4775 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4776 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4777 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4778 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4779 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4780 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4781 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4782 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4783 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4784 default:
4785 break;
4786 }
4787 return NULL;
4788}
4789
103f02d3 4790static const char *
d3ba0551 4791get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4792{
4793 switch (sh_type)
4794 {
4795 case SHT_PARISC_EXT: return "PARISC_EXT";
4796 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4797 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4798 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4799 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4800 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4801 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4802 default: return NULL;
103f02d3 4803 }
103f02d3
UD
4804}
4805
4d6ed7c8 4806static const char *
dda8d76d 4807get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4808{
18bd398b 4809 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4810 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4811 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4812
4d6ed7c8
NC
4813 switch (sh_type)
4814 {
148b93f2
NC
4815 case SHT_IA_64_EXT: return "IA_64_EXT";
4816 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4817 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4818 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4819 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4820 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4821 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4822 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4823 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4824 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4825 default:
4826 break;
4827 }
4828 return NULL;
4829}
4830
d2b2c203
DJ
4831static const char *
4832get_x86_64_section_type_name (unsigned int sh_type)
4833{
4834 switch (sh_type)
4835 {
4836 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4837 default: return NULL;
d2b2c203 4838 }
d2b2c203
DJ
4839}
4840
a06ea964
NC
4841static const char *
4842get_aarch64_section_type_name (unsigned int sh_type)
4843{
4844 switch (sh_type)
4845 {
32ec8896
NC
4846 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4847 default: return NULL;
a06ea964 4848 }
a06ea964
NC
4849}
4850
40a18ebd
NC
4851static const char *
4852get_arm_section_type_name (unsigned int sh_type)
4853{
4854 switch (sh_type)
4855 {
7f6fed87
NC
4856 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4857 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4858 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4859 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4860 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4861 default: return NULL;
40a18ebd 4862 }
40a18ebd
NC
4863}
4864
40b36596
JM
4865static const char *
4866get_tic6x_section_type_name (unsigned int sh_type)
4867{
4868 switch (sh_type)
4869 {
32ec8896
NC
4870 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4871 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4872 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4873 case SHT_TI_ICODE: return "TI_ICODE";
4874 case SHT_TI_XREF: return "TI_XREF";
4875 case SHT_TI_HANDLER: return "TI_HANDLER";
4876 case SHT_TI_INITINFO: return "TI_INITINFO";
4877 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4878 default: return NULL;
40b36596 4879 }
40b36596
JM
4880}
4881
13761a11 4882static const char *
b0191216 4883get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4884{
4885 switch (sh_type)
4886 {
32ec8896
NC
4887 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4888 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4889 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4890 default: return NULL;
13761a11
NC
4891 }
4892}
4893
fe944acf
FT
4894static const char *
4895get_nfp_section_type_name (unsigned int sh_type)
4896{
4897 switch (sh_type)
4898 {
4899 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4900 case SHT_NFP_INITREG: return "NFP_INITREG";
4901 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4902 default: return NULL;
4903 }
4904}
4905
685080f2
NC
4906static const char *
4907get_v850_section_type_name (unsigned int sh_type)
4908{
4909 switch (sh_type)
4910 {
32ec8896
NC
4911 case SHT_V850_SCOMMON: return "V850 Small Common";
4912 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4913 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4914 case SHT_RENESAS_IOP: return "RENESAS IOP";
4915 case SHT_RENESAS_INFO: return "RENESAS INFO";
4916 default: return NULL;
685080f2
NC
4917 }
4918}
4919
2dc8dd17
JW
4920static const char *
4921get_riscv_section_type_name (unsigned int sh_type)
4922{
4923 switch (sh_type)
4924 {
4925 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4926 default: return NULL;
4927 }
4928}
4929
0861f561
CQ
4930static const char *
4931get_csky_section_type_name (unsigned int sh_type)
4932{
4933 switch (sh_type)
4934 {
4935 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4936 default: return NULL;
4937 }
4938}
4939
252b5132 4940static const char *
dda8d76d 4941get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4942{
b34976b6 4943 static char buff[32];
9fb71ee4 4944 const char * result;
252b5132
RH
4945
4946 switch (sh_type)
4947 {
4948 case SHT_NULL: return "NULL";
4949 case SHT_PROGBITS: return "PROGBITS";
4950 case SHT_SYMTAB: return "SYMTAB";
4951 case SHT_STRTAB: return "STRTAB";
4952 case SHT_RELA: return "RELA";
dd207c13 4953 case SHT_RELR: return "RELR";
252b5132
RH
4954 case SHT_HASH: return "HASH";
4955 case SHT_DYNAMIC: return "DYNAMIC";
4956 case SHT_NOTE: return "NOTE";
4957 case SHT_NOBITS: return "NOBITS";
4958 case SHT_REL: return "REL";
4959 case SHT_SHLIB: return "SHLIB";
4960 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4961 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4962 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4963 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4964 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4965 case SHT_GROUP: return "GROUP";
67ce483b 4966 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4967 case SHT_GNU_verdef: return "VERDEF";
4968 case SHT_GNU_verneed: return "VERNEED";
4969 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4970 case 0x6ffffff0: return "VERSYM";
4971 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4972 case 0x7ffffffd: return "AUXILIARY";
4973 case 0x7fffffff: return "FILTER";
047b2264 4974 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4975
4976 default:
4977 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4978 {
dda8d76d 4979 switch (filedata->file_header.e_machine)
252b5132 4980 {
53a346d8
CZ
4981 case EM_ARC:
4982 case EM_ARC_COMPACT:
4983 case EM_ARC_COMPACT2:
4984 result = get_arc_section_type_name (sh_type);
4985 break;
252b5132 4986 case EM_MIPS:
4fe85591 4987 case EM_MIPS_RS3_LE:
252b5132
RH
4988 result = get_mips_section_type_name (sh_type);
4989 break;
103f02d3
UD
4990 case EM_PARISC:
4991 result = get_parisc_section_type_name (sh_type);
4992 break;
4d6ed7c8 4993 case EM_IA_64:
dda8d76d 4994 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4995 break;
d2b2c203 4996 case EM_X86_64:
8a9036a4 4997 case EM_L1OM:
7a9068fe 4998 case EM_K1OM:
d2b2c203
DJ
4999 result = get_x86_64_section_type_name (sh_type);
5000 break;
a06ea964
NC
5001 case EM_AARCH64:
5002 result = get_aarch64_section_type_name (sh_type);
5003 break;
40a18ebd
NC
5004 case EM_ARM:
5005 result = get_arm_section_type_name (sh_type);
5006 break;
40b36596
JM
5007 case EM_TI_C6000:
5008 result = get_tic6x_section_type_name (sh_type);
5009 break;
13761a11 5010 case EM_MSP430:
b0191216 5011 result = get_msp430_section_type_name (sh_type);
13761a11 5012 break;
fe944acf
FT
5013 case EM_NFP:
5014 result = get_nfp_section_type_name (sh_type);
5015 break;
685080f2
NC
5016 case EM_V800:
5017 case EM_V850:
5018 case EM_CYGNUS_V850:
5019 result = get_v850_section_type_name (sh_type);
5020 break;
2dc8dd17
JW
5021 case EM_RISCV:
5022 result = get_riscv_section_type_name (sh_type);
5023 break;
0861f561
CQ
5024 case EM_CSKY:
5025 result = get_csky_section_type_name (sh_type);
5026 break;
252b5132
RH
5027 default:
5028 result = NULL;
5029 break;
5030 }
5031
5032 if (result != NULL)
5033 return result;
5034
9fb71ee4 5035 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5036 }
5037 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5038 {
dda8d76d 5039 switch (filedata->file_header.e_machine)
148b93f2
NC
5040 {
5041 case EM_IA_64:
dda8d76d 5042 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5043 break;
5044 default:
dda8d76d 5045 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5046 result = get_solaris_section_type (sh_type);
5047 else
1b4b80bf
NC
5048 {
5049 switch (sh_type)
5050 {
5051 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5052 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5053 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5054 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5055 default:
5056 result = NULL;
5057 break;
5058 }
5059 }
148b93f2
NC
5060 break;
5061 }
5062
5063 if (result != NULL)
5064 return result;
5065
9fb71ee4 5066 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5067 }
252b5132 5068 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5069 {
dda8d76d 5070 switch (filedata->file_header.e_machine)
685080f2
NC
5071 {
5072 case EM_V800:
5073 case EM_V850:
5074 case EM_CYGNUS_V850:
9fb71ee4 5075 result = get_v850_section_type_name (sh_type);
a9fb83be 5076 break;
685080f2 5077 default:
9fb71ee4 5078 result = NULL;
685080f2
NC
5079 break;
5080 }
5081
9fb71ee4
NC
5082 if (result != NULL)
5083 return result;
5084
5085 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5086 }
252b5132 5087 else
a7dbfd1c
NC
5088 /* This message is probably going to be displayed in a 15
5089 character wide field, so put the hex value first. */
5090 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5091
252b5132
RH
5092 return buff;
5093 }
5094}
5095
79bc120c
NC
5096enum long_option_values
5097{
5098 OPTION_DEBUG_DUMP = 512,
5099 OPTION_DYN_SYMS,
0f03783c 5100 OPTION_LTO_SYMS,
79bc120c
NC
5101 OPTION_DWARF_DEPTH,
5102 OPTION_DWARF_START,
5103 OPTION_DWARF_CHECK,
5104 OPTION_CTF_DUMP,
5105 OPTION_CTF_PARENT,
5106 OPTION_CTF_SYMBOLS,
5107 OPTION_CTF_STRINGS,
42b6953b 5108 OPTION_SFRAME_DUMP,
79bc120c
NC
5109 OPTION_WITH_SYMBOL_VERSIONS,
5110 OPTION_RECURSE_LIMIT,
5111 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
5112 OPTION_NO_DEMANGLING,
5113 OPTION_SYM_BASE
79bc120c 5114};
2979dc34 5115
85b1c36d 5116static struct option options[] =
252b5132 5117{
79bc120c
NC
5118 /* Note - This table is alpha-sorted on the 'val'
5119 field in order to make adding new options easier. */
5120 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5121 {"all", no_argument, 0, 'a'},
79bc120c
NC
5122 {"demangle", optional_argument, 0, 'C'},
5123 {"archive-index", no_argument, 0, 'c'},
5124 {"use-dynamic", no_argument, 0, 'D'},
5125 {"dynamic", no_argument, 0, 'd'},
b34976b6 5126 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5127 {"section-groups", no_argument, 0, 'g'},
5128 {"help", no_argument, 0, 'H'},
5129 {"file-header", no_argument, 0, 'h'},
b34976b6 5130 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5131 {"lint", no_argument, 0, 'L'},
5132 {"enable-checks", no_argument, 0, 'L'},
5133 {"program-headers", no_argument, 0, 'l'},
b34976b6 5134 {"segments", no_argument, 0, 'l'},
595cf52e 5135 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5136 {"notes", no_argument, 0, 'n'},
ca0e11aa 5137 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5138 {"string-dump", required_argument, 0, 'p'},
5139 {"relocated-dump", required_argument, 0, 'R'},
5140 {"relocs", no_argument, 0, 'r'},
5141 {"section-headers", no_argument, 0, 'S'},
5142 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5143 {"symbols", no_argument, 0, 's'},
5144 {"syms", no_argument, 0, 's'},
79bc120c
NC
5145 {"silent-truncation",no_argument, 0, 'T'},
5146 {"section-details", no_argument, 0, 't'},
b3aa80b4 5147 {"unicode", required_argument, NULL, 'U'},
09c11c86 5148 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5149 {"version-info", no_argument, 0, 'V'},
5150 {"version", no_argument, 0, 'v'},
5151 {"wide", no_argument, 0, 'W'},
b34976b6 5152 {"hex-dump", required_argument, 0, 'x'},
0e602686 5153 {"decompress", no_argument, 0, 'z'},
252b5132 5154
79bc120c
NC
5155 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5156 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5157 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5158 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5159 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5160 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5161 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5162 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5163 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5164 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5165#ifdef ENABLE_LIBCTF
d344b407 5166 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5167 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5168 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5169 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5170#endif
42b6953b 5171 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
047c3dbf 5172 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5173
b34976b6 5174 {0, no_argument, 0, 0}
252b5132
RH
5175};
5176
5177static void
2cf0635d 5178usage (FILE * stream)
252b5132 5179{
92f01d61
JM
5180 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5181 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5182 fprintf (stream, _(" Options are:\n"));
5183 fprintf (stream, _("\
5184 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5185 fprintf (stream, _("\
5186 -h --file-header Display the ELF file header\n"));
5187 fprintf (stream, _("\
5188 -l --program-headers Display the program headers\n"));
5189 fprintf (stream, _("\
5190 --segments An alias for --program-headers\n"));
5191 fprintf (stream, _("\
5192 -S --section-headers Display the sections' header\n"));
5193 fprintf (stream, _("\
5194 --sections An alias for --section-headers\n"));
5195 fprintf (stream, _("\
5196 -g --section-groups Display the section groups\n"));
5197 fprintf (stream, _("\
5198 -t --section-details Display the section details\n"));
5199 fprintf (stream, _("\
5200 -e --headers Equivalent to: -h -l -S\n"));
5201 fprintf (stream, _("\
5202 -s --syms Display the symbol table\n"));
5203 fprintf (stream, _("\
5204 --symbols An alias for --syms\n"));
5205 fprintf (stream, _("\
5206 --dyn-syms Display the dynamic symbol table\n"));
5207 fprintf (stream, _("\
5208 --lto-syms Display LTO symbol tables\n"));
5209 fprintf (stream, _("\
047c3dbf
NL
5210 --sym-base=[0|8|10|16] \n\
5211 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5212 mixed (the default), octal, decimal, hexadecimal.\n"));
5213 fprintf (stream, _("\
0d646226
AM
5214 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5215 display_demangler_styles (stream, _("\
5216 STYLE can be "));
d6249f5f
AM
5217 fprintf (stream, _("\
5218 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5219 fprintf (stream, _("\
5220 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5221 fprintf (stream, _("\
5222 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5223 fprintf (stream, _("\
5224 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5225 Display unicode characters as determined by the current locale\n\
5226 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5227 escape sequences, or treat them as invalid and display as\n\
5228 \"{hex sequences}\"\n"));
d6249f5f
AM
5229 fprintf (stream, _("\
5230 -n --notes Display the core notes (if present)\n"));
5231 fprintf (stream, _("\
5232 -r --relocs Display the relocations (if present)\n"));
5233 fprintf (stream, _("\
5234 -u --unwind Display the unwind info (if present)\n"));
5235 fprintf (stream, _("\
5236 -d --dynamic Display the dynamic section (if present)\n"));
5237 fprintf (stream, _("\
5238 -V --version-info Display the version sections (if present)\n"));
5239 fprintf (stream, _("\
5240 -A --arch-specific Display architecture specific information (if any)\n"));
5241 fprintf (stream, _("\
5242 -c --archive-index Display the symbol/file index in an archive\n"));
5243 fprintf (stream, _("\
5244 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5245 fprintf (stream, _("\
5246 -L --lint|--enable-checks\n\
5247 Display warning messages for possible problems\n"));
5248 fprintf (stream, _("\
09c11c86 5249 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5250 Dump the contents of section <number|name> as bytes\n"));
5251 fprintf (stream, _("\
09c11c86 5252 -p --string-dump=<number|name>\n\
d6249f5f
AM
5253 Dump the contents of section <number|name> as strings\n"));
5254 fprintf (stream, _("\
cf13d699 5255 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5256 Dump the relocated contents of section <number|name>\n"));
5257 fprintf (stream, _("\
5258 -z --decompress Decompress section before dumping it\n"));
5259 fprintf (stream, _("\
5260 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5261 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5262 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5263 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5264 U/=trace_info]\n\
5265 Display the contents of DWARF debug sections\n"));
5266 fprintf (stream, _("\
5267 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5268 debuginfo files\n"));
5269 fprintf (stream, _("\
5270 -P --process-links Display the contents of non-debug sections in separate\n\
5271 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5272#if DEFAULT_FOR_FOLLOW_LINKS
5273 fprintf (stream, _("\
d6249f5f
AM
5274 -wK --debug-dump=follow-links\n\
5275 Follow links to separate debug info files (default)\n"));
5276 fprintf (stream, _("\
5277 -wN --debug-dump=no-follow-links\n\
5278 Do not follow links to separate debug info files\n"));
c46b7066
NC
5279#else
5280 fprintf (stream, _("\
d6249f5f
AM
5281 -wK --debug-dump=follow-links\n\
5282 Follow links to separate debug info files\n"));
5283 fprintf (stream, _("\
5284 -wN --debug-dump=no-follow-links\n\
5285 Do not follow links to separate debug info files\n\
5286 (default)\n"));
bed566bb
NC
5287#endif
5288#if HAVE_LIBDEBUGINFOD
5289 fprintf (stream, _("\
5290 -wD --debug-dump=use-debuginfod\n\
5291 When following links, also query debuginfod servers (default)\n"));
5292 fprintf (stream, _("\
5293 -wE --debug-dump=do-not-use-debuginfod\n\
5294 When following links, do not query debuginfod servers\n"));
c46b7066 5295#endif
fd2f0033 5296 fprintf (stream, _("\
d6249f5f
AM
5297 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5298 fprintf (stream, _("\
5299 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5300#ifdef ENABLE_LIBCTF
7d9813f1 5301 fprintf (stream, _("\
d6249f5f
AM
5302 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5303 fprintf (stream, _("\
80b56fad 5304 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5305 fprintf (stream, _("\
7d9813f1 5306 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5307 Use section <number|name> as the CTF external symtab\n"));
5308 fprintf (stream, _("\
7d9813f1 5309 --ctf-strings=<number|name>\n\
d6249f5f 5310 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5311#endif
42b6953b
IB
5312 fprintf (stream, _("\
5313 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
7d9813f1 5314
252b5132 5315#ifdef SUPPORT_DISASSEMBLY
92f01d61 5316 fprintf (stream, _("\
09c11c86
NC
5317 -i --instruction-dump=<number|name>\n\
5318 Disassemble the contents of section <number|name>\n"));
252b5132 5319#endif
92f01d61 5320 fprintf (stream, _("\
d6249f5f
AM
5321 -I --histogram Display histogram of bucket list lengths\n"));
5322 fprintf (stream, _("\
5323 -W --wide Allow output width to exceed 80 characters\n"));
5324 fprintf (stream, _("\
5325 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5326 fprintf (stream, _("\
5327 @<file> Read options from <file>\n"));
5328 fprintf (stream, _("\
5329 -H --help Display this information\n"));
5330 fprintf (stream, _("\
8b53311e 5331 -v --version Display the version number of readelf\n"));
1118d252 5332
92f01d61
JM
5333 if (REPORT_BUGS_TO[0] && stream == stdout)
5334 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5335
92f01d61 5336 exit (stream == stdout ? 0 : 1);
252b5132
RH
5337}
5338
18bd398b
NC
5339/* Record the fact that the user wants the contents of section number
5340 SECTION to be displayed using the method(s) encoded as flags bits
5341 in TYPE. Note, TYPE can be zero if we are creating the array for
5342 the first time. */
5343
252b5132 5344static void
6431e409
AM
5345request_dump_bynumber (struct dump_data *dumpdata,
5346 unsigned int section, dump_type type)
252b5132 5347{
6431e409 5348 if (section >= dumpdata->num_dump_sects)
252b5132 5349 {
2cf0635d 5350 dump_type * new_dump_sects;
252b5132 5351
3f5e193b 5352 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5353 sizeof (* new_dump_sects));
252b5132
RH
5354
5355 if (new_dump_sects == NULL)
591a748a 5356 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5357 else
5358 {
6431e409 5359 if (dumpdata->dump_sects)
21b65bac
NC
5360 {
5361 /* Copy current flag settings. */
6431e409
AM
5362 memcpy (new_dump_sects, dumpdata->dump_sects,
5363 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5364
6431e409 5365 free (dumpdata->dump_sects);
21b65bac 5366 }
252b5132 5367
6431e409
AM
5368 dumpdata->dump_sects = new_dump_sects;
5369 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5370 }
5371 }
5372
6431e409
AM
5373 if (dumpdata->dump_sects)
5374 dumpdata->dump_sects[section] |= type;
252b5132
RH
5375}
5376
aef1f6d0
DJ
5377/* Request a dump by section name. */
5378
5379static void
2cf0635d 5380request_dump_byname (const char * section, dump_type type)
aef1f6d0 5381{
2cf0635d 5382 struct dump_list_entry * new_request;
aef1f6d0 5383
3f5e193b
NC
5384 new_request = (struct dump_list_entry *)
5385 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5386 if (!new_request)
591a748a 5387 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5388
5389 new_request->name = strdup (section);
5390 if (!new_request->name)
591a748a 5391 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5392
5393 new_request->type = type;
5394
5395 new_request->next = dump_sects_byname;
5396 dump_sects_byname = new_request;
5397}
5398
cf13d699 5399static inline void
6431e409 5400request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5401{
5402 int section;
5403 char * cp;
5404
015dc7e1 5405 do_dump = true;
cf13d699
NC
5406 section = strtoul (optarg, & cp, 0);
5407
5408 if (! *cp && section >= 0)
6431e409 5409 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5410 else
5411 request_dump_byname (optarg, type);
5412}
5413
252b5132 5414static void
6431e409 5415parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5416{
5417 int c;
5418
5419 if (argc < 2)
92f01d61 5420 usage (stderr);
252b5132
RH
5421
5422 while ((c = getopt_long
b3aa80b4 5423 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5424 {
252b5132
RH
5425 switch (c)
5426 {
5427 case 0:
5428 /* Long options. */
5429 break;
5430 case 'H':
92f01d61 5431 usage (stdout);
252b5132
RH
5432 break;
5433
5434 case 'a':
015dc7e1
AM
5435 do_syms = true;
5436 do_reloc = true;
5437 do_unwind = true;
5438 do_dynamic = true;
5439 do_header = true;
5440 do_sections = true;
5441 do_section_groups = true;
5442 do_segments = true;
5443 do_version = true;
5444 do_histogram = true;
5445 do_arch = true;
5446 do_notes = true;
252b5132 5447 break;
79bc120c 5448
f5842774 5449 case 'g':
015dc7e1 5450 do_section_groups = true;
f5842774 5451 break;
5477e8a0 5452 case 't':
595cf52e 5453 case 'N':
015dc7e1
AM
5454 do_sections = true;
5455 do_section_details = true;
595cf52e 5456 break;
252b5132 5457 case 'e':
015dc7e1
AM
5458 do_header = true;
5459 do_sections = true;
5460 do_segments = true;
252b5132 5461 break;
a952a375 5462 case 'A':
015dc7e1 5463 do_arch = true;
a952a375 5464 break;
252b5132 5465 case 'D':
015dc7e1 5466 do_using_dynamic = true;
252b5132
RH
5467 break;
5468 case 'r':
015dc7e1 5469 do_reloc = true;
252b5132 5470 break;
4d6ed7c8 5471 case 'u':
015dc7e1 5472 do_unwind = true;
4d6ed7c8 5473 break;
252b5132 5474 case 'h':
015dc7e1 5475 do_header = true;
252b5132
RH
5476 break;
5477 case 'l':
015dc7e1 5478 do_segments = true;
252b5132
RH
5479 break;
5480 case 's':
015dc7e1 5481 do_syms = true;
252b5132
RH
5482 break;
5483 case 'S':
015dc7e1 5484 do_sections = true;
252b5132
RH
5485 break;
5486 case 'd':
015dc7e1 5487 do_dynamic = true;
252b5132 5488 break;
a952a375 5489 case 'I':
015dc7e1 5490 do_histogram = true;
a952a375 5491 break;
779fe533 5492 case 'n':
015dc7e1 5493 do_notes = true;
779fe533 5494 break;
4145f1d5 5495 case 'c':
015dc7e1 5496 do_archive_index = true;
4145f1d5 5497 break;
1b513401 5498 case 'L':
015dc7e1 5499 do_checks = true;
1b513401 5500 break;
ca0e11aa 5501 case 'P':
015dc7e1
AM
5502 process_links = true;
5503 do_follow_links = true;
e1dbfc17 5504 dump_any_debugging = true;
ca0e11aa 5505 break;
252b5132 5506 case 'x':
6431e409 5507 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5508 break;
09c11c86 5509 case 'p':
6431e409 5510 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5511 break;
5512 case 'R':
6431e409 5513 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5514 break;
0e602686 5515 case 'z':
015dc7e1 5516 decompress_dumps = true;
0e602686 5517 break;
252b5132 5518 case 'w':
0f03783c 5519 if (optarg == NULL)
613ff48b 5520 {
015dc7e1 5521 do_debugging = true;
94585d6d
NC
5522 do_dump = true;
5523 dump_any_debugging = true;
613ff48b
CC
5524 dwarf_select_sections_all ();
5525 }
252b5132
RH
5526 else
5527 {
015dc7e1 5528 do_debugging = false;
94585d6d
NC
5529 if (dwarf_select_sections_by_letters (optarg))
5530 {
5531 do_dump = true;
5532 dump_any_debugging = true;
5533 }
252b5132
RH
5534 }
5535 break;
2979dc34 5536 case OPTION_DEBUG_DUMP:
0f03783c 5537 if (optarg == NULL)
d6249f5f 5538 {
94585d6d 5539 do_dump = true;
d6249f5f 5540 do_debugging = true;
94585d6d 5541 dump_any_debugging = true;
d6249f5f
AM
5542 dwarf_select_sections_all ();
5543 }
2979dc34
JJ
5544 else
5545 {
015dc7e1 5546 do_debugging = false;
94585d6d
NC
5547 if (dwarf_select_sections_by_names (optarg))
5548 {
5549 do_dump = true;
5550 dump_any_debugging = true;
5551 }
2979dc34
JJ
5552 }
5553 break;
fd2f0033
TT
5554 case OPTION_DWARF_DEPTH:
5555 {
5556 char *cp;
5557
5558 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5559 }
5560 break;
5561 case OPTION_DWARF_START:
5562 {
5563 char *cp;
5564
5565 dwarf_start_die = strtoul (optarg, & cp, 0);
5566 }
5567 break;
4723351a 5568 case OPTION_DWARF_CHECK:
015dc7e1 5569 dwarf_check = true;
4723351a 5570 break;
7d9813f1 5571 case OPTION_CTF_DUMP:
015dc7e1 5572 do_ctf = true;
6431e409 5573 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5574 break;
5575 case OPTION_CTF_SYMBOLS:
df16e041 5576 free (dump_ctf_symtab_name);
7d9813f1
NA
5577 dump_ctf_symtab_name = strdup (optarg);
5578 break;
5579 case OPTION_CTF_STRINGS:
df16e041 5580 free (dump_ctf_strtab_name);
7d9813f1
NA
5581 dump_ctf_strtab_name = strdup (optarg);
5582 break;
5583 case OPTION_CTF_PARENT:
df16e041 5584 free (dump_ctf_parent_name);
7d9813f1
NA
5585 dump_ctf_parent_name = strdup (optarg);
5586 break;
42b6953b
IB
5587 case OPTION_SFRAME_DUMP:
5588 do_sframe = true;
5589 /* Providing section name is optional. request_dump (), however,
5590 thrives on non NULL optarg. Handle it explicitly here. */
5591 if (optarg != NULL)
5592 request_dump (dumpdata, SFRAME_DUMP);
5593 else
5594 {
5595 do_dump = true;
5596 const char *sframe_sec_name = strdup (".sframe");
5597 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
5598 }
5599 break;
2c610e4b 5600 case OPTION_DYN_SYMS:
015dc7e1 5601 do_dyn_syms = true;
2c610e4b 5602 break;
0f03783c 5603 case OPTION_LTO_SYMS:
015dc7e1 5604 do_lto_syms = true;
0f03783c 5605 break;
252b5132
RH
5606#ifdef SUPPORT_DISASSEMBLY
5607 case 'i':
6431e409 5608 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5609 break;
252b5132
RH
5610#endif
5611 case 'v':
5612 print_version (program_name);
5613 break;
5614 case 'V':
015dc7e1 5615 do_version = true;
252b5132 5616 break;
d974e256 5617 case 'W':
015dc7e1 5618 do_wide = true;
d974e256 5619 break;
0942c7ab 5620 case 'T':
015dc7e1 5621 do_not_show_symbol_truncation = true;
0942c7ab 5622 break;
79bc120c 5623 case 'C':
015dc7e1 5624 do_demangle = true;
79bc120c
NC
5625 if (optarg != NULL)
5626 {
5627 enum demangling_styles style;
5628
5629 style = cplus_demangle_name_to_style (optarg);
5630 if (style == unknown_demangling)
5631 error (_("unknown demangling style `%s'"), optarg);
5632
5633 cplus_demangle_set_style (style);
5634 }
5635 break;
5636 case OPTION_NO_DEMANGLING:
015dc7e1 5637 do_demangle = false;
79bc120c
NC
5638 break;
5639 case OPTION_RECURSE_LIMIT:
5640 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5641 break;
5642 case OPTION_NO_RECURSE_LIMIT:
5643 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5644 break;
5645 case OPTION_WITH_SYMBOL_VERSIONS:
5646 /* Ignored for backward compatibility. */
5647 break;
b9e920ec 5648
b3aa80b4
NC
5649 case 'U':
5650 if (optarg == NULL)
5651 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5652 else if (streq (optarg, "default") || streq (optarg, "d"))
5653 unicode_display = unicode_default;
5654 else if (streq (optarg, "locale") || streq (optarg, "l"))
5655 unicode_display = unicode_locale;
5656 else if (streq (optarg, "escape") || streq (optarg, "e"))
5657 unicode_display = unicode_escape;
5658 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5659 unicode_display = unicode_invalid;
5660 else if (streq (optarg, "hex") || streq (optarg, "x"))
5661 unicode_display = unicode_hex;
5662 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5663 unicode_display = unicode_highlight;
5664 else
5665 error (_("invalid argument to -U/--unicode: %s"), optarg);
5666 break;
5667
047c3dbf
NL
5668 case OPTION_SYM_BASE:
5669 sym_base = 0;
5670 if (optarg != NULL)
5671 {
5672 sym_base = strtoul (optarg, NULL, 0);
5673 switch (sym_base)
5674 {
5675 case 0:
5676 case 8:
5677 case 10:
5678 case 16:
5679 break;
5680
5681 default:
5682 sym_base = 0;
5683 break;
5684 }
5685 }
5686 break;
5687
252b5132 5688 default:
252b5132
RH
5689 /* xgettext:c-format */
5690 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5691 /* Fall through. */
252b5132 5692 case '?':
92f01d61 5693 usage (stderr);
252b5132
RH
5694 }
5695 }
5696
4d6ed7c8 5697 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5698 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5699 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5700 && !do_section_groups && !do_archive_index
0f03783c 5701 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5702 {
5703 if (do_checks)
5704 {
015dc7e1
AM
5705 check_all = true;
5706 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5707 do_segments = do_header = do_dump = do_version = true;
5708 do_histogram = do_debugging = do_arch = do_notes = true;
5709 do_section_groups = do_archive_index = do_dyn_syms = true;
5710 do_lto_syms = true;
1b513401
NC
5711 }
5712 else
5713 usage (stderr);
5714 }
252b5132
RH
5715}
5716
5717static const char *
d3ba0551 5718get_elf_class (unsigned int elf_class)
252b5132 5719{
b34976b6 5720 static char buff[32];
103f02d3 5721
252b5132
RH
5722 switch (elf_class)
5723 {
5724 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5725 case ELFCLASS32: return "ELF32";
5726 case ELFCLASS64: return "ELF64";
ab5e7794 5727 default:
e9e44622 5728 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5729 return buff;
252b5132
RH
5730 }
5731}
5732
5733static const char *
d3ba0551 5734get_data_encoding (unsigned int encoding)
252b5132 5735{
b34976b6 5736 static char buff[32];
103f02d3 5737
252b5132
RH
5738 switch (encoding)
5739 {
5740 case ELFDATANONE: return _("none");
33c63f9d
CM
5741 case ELFDATA2LSB: return _("2's complement, little endian");
5742 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5743 default:
e9e44622 5744 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5745 return buff;
252b5132
RH
5746 }
5747}
5748
521f7268
NC
5749static bool
5750check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
5751{
5752 if (header->e_ident[EI_MAG0] == ELFMAG0
5753 && header->e_ident[EI_MAG1] == ELFMAG1
5754 && header->e_ident[EI_MAG2] == ELFMAG2
5755 && header->e_ident[EI_MAG3] == ELFMAG3)
5756 return true;
5757
5758 /* Some compilers produce object files that are not in the ELF file format.
5759 As an aid to users of readelf, try to identify these cases and suggest
5760 alternative tools.
5761
5762 FIXME: It is not clear if all four bytes are used as constant magic
5763 valus by all compilers. It may be necessary to recode this function if
5764 different tools use different length sequences. */
5765
5766 static struct
5767 {
5768 unsigned char magic[4];
5769 const char * obj_message;
5770 const char * ar_message;
5771 }
5772 known_magic[] =
5773 {
5774 { { 'B', 'C', 0xc0, 0xde },
5775 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
5776 N_("This is a LLVM bitcode file - try extracing and then using llvm-bcanalyzer\n")
5777 },
5778 { { 'g', 'o', ' ', 'o' },
5779 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
5780 NULL
5781 }
5782 };
5783 int i;
5784
5785 for (i = ARRAY_SIZE (known_magic); i--;)
5786 {
5787 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
5788 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
5789 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
5790 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
5791 {
5792 /* Some compiler's analyzer tools do not handle archives,
5793 so we provide two different kinds of error message. */
5794 if (filedata->archive_file_size > 0
5795 && known_magic[i].ar_message != NULL)
b3ea2010 5796 error ("%s", known_magic[i].ar_message);
521f7268 5797 else
b3ea2010 5798 error ("%s", known_magic[i].obj_message);
521f7268
NC
5799 return false;
5800 }
5801 }
5802
5803 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
5804 return false;
5805}
5806
dda8d76d 5807/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5808
015dc7e1 5809static bool
dda8d76d 5810process_file_header (Filedata * filedata)
252b5132 5811{
dda8d76d
NC
5812 Elf_Internal_Ehdr * header = & filedata->file_header;
5813
521f7268
NC
5814 if (! check_magic_number (filedata, header))
5815 return false;
252b5132 5816
ca0e11aa
NC
5817 if (! filedata->is_separate)
5818 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5819
252b5132
RH
5820 if (do_header)
5821 {
32ec8896 5822 unsigned i;
252b5132 5823
ca0e11aa
NC
5824 if (filedata->is_separate)
5825 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5826 else
5827 printf (_("ELF Header:\n"));
252b5132 5828 printf (_(" Magic: "));
b34976b6 5829 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5830 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5831 printf ("\n");
5832 printf (_(" Class: %s\n"),
dda8d76d 5833 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5834 printf (_(" Data: %s\n"),
dda8d76d 5835 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5836 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5837 header->e_ident[EI_VERSION],
5838 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5839 ? _(" (current)")
dda8d76d 5840 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5841 ? _(" <unknown>")
789be9f7 5842 : "")));
252b5132 5843 printf (_(" OS/ABI: %s\n"),
dda8d76d 5844 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5845 printf (_(" ABI Version: %d\n"),
dda8d76d 5846 header->e_ident[EI_ABIVERSION]);
252b5132 5847 printf (_(" Type: %s\n"),
93df3340 5848 get_file_type (filedata));
252b5132 5849 printf (_(" Machine: %s\n"),
dda8d76d 5850 get_machine_name (header->e_machine));
252b5132 5851 printf (_(" Version: 0x%lx\n"),
e8a64888 5852 header->e_version);
76da6bbe 5853
f7a99963 5854 printf (_(" Entry point address: "));
e8a64888 5855 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5856 printf (_("\n Start of program headers: "));
e8a64888 5857 print_vma (header->e_phoff, DEC);
f7a99963 5858 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5859 print_vma (header->e_shoff, DEC);
f7a99963 5860 printf (_(" (bytes into file)\n"));
76da6bbe 5861
252b5132 5862 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5863 header->e_flags,
dda8d76d 5864 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5865 printf (_(" Size of this header: %u (bytes)\n"),
5866 header->e_ehsize);
5867 printf (_(" Size of program headers: %u (bytes)\n"),
5868 header->e_phentsize);
5869 printf (_(" Number of program headers: %u"),
5870 header->e_phnum);
dda8d76d
NC
5871 if (filedata->section_headers != NULL
5872 && header->e_phnum == PN_XNUM
5873 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5874 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5875 putc ('\n', stdout);
e8a64888
AM
5876 printf (_(" Size of section headers: %u (bytes)\n"),
5877 header->e_shentsize);
5878 printf (_(" Number of section headers: %u"),
5879 header->e_shnum);
dda8d76d 5880 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5881 {
5882 header->e_shnum = filedata->section_headers[0].sh_size;
5883 printf (" (%u)", header->e_shnum);
5884 }
560f3c1c 5885 putc ('\n', stdout);
e8a64888
AM
5886 printf (_(" Section header string table index: %u"),
5887 header->e_shstrndx);
dda8d76d
NC
5888 if (filedata->section_headers != NULL
5889 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5890 {
5891 header->e_shstrndx = filedata->section_headers[0].sh_link;
5892 printf (" (%u)", header->e_shstrndx);
5893 }
5894 if (header->e_shstrndx != SHN_UNDEF
5895 && header->e_shstrndx >= header->e_shnum)
5896 {
5897 header->e_shstrndx = SHN_UNDEF;
5898 printf (_(" <corrupt: out of range>"));
5899 }
560f3c1c
AM
5900 putc ('\n', stdout);
5901 }
5902
dda8d76d 5903 if (filedata->section_headers != NULL)
560f3c1c 5904 {
dda8d76d
NC
5905 if (header->e_phnum == PN_XNUM
5906 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5907 {
5908 /* Throw away any cached read of PN_XNUM headers. */
5909 free (filedata->program_headers);
5910 filedata->program_headers = NULL;
5911 header->e_phnum = filedata->section_headers[0].sh_info;
5912 }
dda8d76d
NC
5913 if (header->e_shnum == SHN_UNDEF)
5914 header->e_shnum = filedata->section_headers[0].sh_size;
5915 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5916 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5917 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5918 header->e_shstrndx = SHN_UNDEF;
252b5132 5919 }
103f02d3 5920
015dc7e1 5921 return true;
9ea033b2
NC
5922}
5923
dda8d76d
NC
5924/* Read in the program headers from FILEDATA and store them in PHEADERS.
5925 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5926
015dc7e1 5927static bool
dda8d76d 5928get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5929{
2cf0635d
NC
5930 Elf32_External_Phdr * phdrs;
5931 Elf32_External_Phdr * external;
5932 Elf_Internal_Phdr * internal;
b34976b6 5933 unsigned int i;
dda8d76d
NC
5934 unsigned int size = filedata->file_header.e_phentsize;
5935 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5936
5937 /* PR binutils/17531: Cope with unexpected section header sizes. */
5938 if (size == 0 || num == 0)
015dc7e1 5939 return false;
e0a31db1
NC
5940 if (size < sizeof * phdrs)
5941 {
5942 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5943 return false;
e0a31db1
NC
5944 }
5945 if (size > sizeof * phdrs)
5946 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5947
dda8d76d 5948 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5949 size, num, _("program headers"));
5950 if (phdrs == NULL)
015dc7e1 5951 return false;
9ea033b2 5952
91d6fa6a 5953 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5954 i < filedata->file_header.e_phnum;
b34976b6 5955 i++, internal++, external++)
252b5132 5956 {
9ea033b2
NC
5957 internal->p_type = BYTE_GET (external->p_type);
5958 internal->p_offset = BYTE_GET (external->p_offset);
5959 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5960 internal->p_paddr = BYTE_GET (external->p_paddr);
5961 internal->p_filesz = BYTE_GET (external->p_filesz);
5962 internal->p_memsz = BYTE_GET (external->p_memsz);
5963 internal->p_flags = BYTE_GET (external->p_flags);
5964 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5965 }
5966
9ea033b2 5967 free (phdrs);
015dc7e1 5968 return true;
252b5132
RH
5969}
5970
dda8d76d
NC
5971/* Read in the program headers from FILEDATA and store them in PHEADERS.
5972 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5973
015dc7e1 5974static bool
dda8d76d 5975get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5976{
2cf0635d
NC
5977 Elf64_External_Phdr * phdrs;
5978 Elf64_External_Phdr * external;
5979 Elf_Internal_Phdr * internal;
b34976b6 5980 unsigned int i;
dda8d76d
NC
5981 unsigned int size = filedata->file_header.e_phentsize;
5982 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5983
5984 /* PR binutils/17531: Cope with unexpected section header sizes. */
5985 if (size == 0 || num == 0)
015dc7e1 5986 return false;
e0a31db1
NC
5987 if (size < sizeof * phdrs)
5988 {
5989 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5990 return false;
e0a31db1
NC
5991 }
5992 if (size > sizeof * phdrs)
5993 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5994
dda8d76d 5995 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5996 size, num, _("program headers"));
a6e9f9df 5997 if (!phdrs)
015dc7e1 5998 return false;
9ea033b2 5999
91d6fa6a 6000 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6001 i < filedata->file_header.e_phnum;
b34976b6 6002 i++, internal++, external++)
9ea033b2
NC
6003 {
6004 internal->p_type = BYTE_GET (external->p_type);
6005 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
6006 internal->p_offset = BYTE_GET (external->p_offset);
6007 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6008 internal->p_paddr = BYTE_GET (external->p_paddr);
6009 internal->p_filesz = BYTE_GET (external->p_filesz);
6010 internal->p_memsz = BYTE_GET (external->p_memsz);
6011 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
6012 }
6013
6014 free (phdrs);
015dc7e1 6015 return true;
9ea033b2 6016}
252b5132 6017
32ec8896 6018/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 6019
015dc7e1 6020static bool
dda8d76d 6021get_program_headers (Filedata * filedata)
d93f0186 6022{
2cf0635d 6023 Elf_Internal_Phdr * phdrs;
d93f0186
NC
6024
6025 /* Check cache of prior read. */
dda8d76d 6026 if (filedata->program_headers != NULL)
015dc7e1 6027 return true;
d93f0186 6028
82156ab7
NC
6029 /* Be kind to memory checkers by looking for
6030 e_phnum values which we know must be invalid. */
dda8d76d 6031 if (filedata->file_header.e_phnum
82156ab7 6032 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 6033 >= filedata->file_size)
82156ab7
NC
6034 {
6035 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 6036 filedata->file_header.e_phnum);
015dc7e1 6037 return false;
82156ab7 6038 }
d93f0186 6039
dda8d76d 6040 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 6041 sizeof (Elf_Internal_Phdr));
d93f0186
NC
6042 if (phdrs == NULL)
6043 {
8b73c356 6044 error (_("Out of memory reading %u program headers\n"),
dda8d76d 6045 filedata->file_header.e_phnum);
015dc7e1 6046 return false;
d93f0186
NC
6047 }
6048
6049 if (is_32bit_elf
dda8d76d
NC
6050 ? get_32bit_program_headers (filedata, phdrs)
6051 : get_64bit_program_headers (filedata, phdrs))
d93f0186 6052 {
dda8d76d 6053 filedata->program_headers = phdrs;
015dc7e1 6054 return true;
d93f0186
NC
6055 }
6056
6057 free (phdrs);
015dc7e1 6058 return false;
d93f0186
NC
6059}
6060
93df3340 6061/* Print program header info and locate dynamic section. */
2f62977e 6062
93df3340 6063static void
dda8d76d 6064process_program_headers (Filedata * filedata)
252b5132 6065{
2cf0635d 6066 Elf_Internal_Phdr * segment;
b34976b6 6067 unsigned int i;
1a9ccd70 6068 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6069
dda8d76d 6070 if (filedata->file_header.e_phnum == 0)
252b5132 6071 {
82f2dbf7 6072 /* PR binutils/12467. */
dda8d76d 6073 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6074 warn (_("possibly corrupt ELF header - it has a non-zero program"
6075 " header offset, but no program headers\n"));
82f2dbf7 6076 else if (do_segments)
ca0e11aa
NC
6077 {
6078 if (filedata->is_separate)
6079 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6080 filedata->file_name);
6081 else
6082 printf (_("\nThere are no program headers in this file.\n"));
6083 }
93df3340 6084 goto no_headers;
252b5132
RH
6085 }
6086
6087 if (do_segments && !do_header)
6088 {
ca0e11aa
NC
6089 if (filedata->is_separate)
6090 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6091 filedata->file_name, get_file_type (filedata));
ca0e11aa 6092 else
93df3340 6093 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6094 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6095 filedata->file_header.e_entry);
b8281767
AM
6096 printf (ngettext ("There is %d program header,"
6097 " starting at offset %" PRIu64 "\n",
6098 "There are %d program headers,"
6099 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6100 filedata->file_header.e_phnum),
6101 filedata->file_header.e_phnum,
625d49fc 6102 filedata->file_header.e_phoff);
252b5132
RH
6103 }
6104
dda8d76d 6105 if (! get_program_headers (filedata))
93df3340 6106 goto no_headers;
103f02d3 6107
252b5132
RH
6108 if (do_segments)
6109 {
dda8d76d 6110 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6111 printf (_("\nProgram Headers:\n"));
6112 else
6113 printf (_("\nProgram Headers:\n"));
76da6bbe 6114
f7a99963
NC
6115 if (is_32bit_elf)
6116 printf
6117 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6118 else if (do_wide)
6119 printf
6120 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6121 else
6122 {
6123 printf
6124 (_(" Type Offset VirtAddr PhysAddr\n"));
6125 printf
6126 (_(" FileSiz MemSiz Flags Align\n"));
6127 }
252b5132
RH
6128 }
6129
26c527e6 6130 uint64_t dynamic_addr = 0;
be7d229a 6131 uint64_t dynamic_size = 0;
dda8d76d
NC
6132 for (i = 0, segment = filedata->program_headers;
6133 i < filedata->file_header.e_phnum;
b34976b6 6134 i++, segment++)
252b5132
RH
6135 {
6136 if (do_segments)
6137 {
dda8d76d 6138 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6139
6140 if (is_32bit_elf)
6141 {
6142 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6143 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6144 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6145 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6146 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6147 printf ("%c%c%c ",
6148 (segment->p_flags & PF_R ? 'R' : ' '),
6149 (segment->p_flags & PF_W ? 'W' : ' '),
6150 (segment->p_flags & PF_X ? 'E' : ' '));
6151 printf ("%#lx", (unsigned long) segment->p_align);
6152 }
d974e256
JJ
6153 else if (do_wide)
6154 {
6155 if ((unsigned long) segment->p_offset == segment->p_offset)
6156 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6157 else
6158 {
6159 print_vma (segment->p_offset, FULL_HEX);
6160 putchar (' ');
6161 }
6162
6163 print_vma (segment->p_vaddr, FULL_HEX);
6164 putchar (' ');
6165 print_vma (segment->p_paddr, FULL_HEX);
6166 putchar (' ');
6167
6168 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6169 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6170 else
6171 {
6172 print_vma (segment->p_filesz, FULL_HEX);
6173 putchar (' ');
6174 }
6175
6176 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6177 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6178 else
6179 {
f48e6c45 6180 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6181 }
6182
6183 printf (" %c%c%c ",
6184 (segment->p_flags & PF_R ? 'R' : ' '),
6185 (segment->p_flags & PF_W ? 'W' : ' '),
6186 (segment->p_flags & PF_X ? 'E' : ' '));
6187
6188 if ((unsigned long) segment->p_align == segment->p_align)
6189 printf ("%#lx", (unsigned long) segment->p_align);
6190 else
6191 {
6192 print_vma (segment->p_align, PREFIX_HEX);
6193 }
6194 }
f7a99963
NC
6195 else
6196 {
6197 print_vma (segment->p_offset, FULL_HEX);
6198 putchar (' ');
6199 print_vma (segment->p_vaddr, FULL_HEX);
6200 putchar (' ');
6201 print_vma (segment->p_paddr, FULL_HEX);
6202 printf ("\n ");
6203 print_vma (segment->p_filesz, FULL_HEX);
6204 putchar (' ');
6205 print_vma (segment->p_memsz, FULL_HEX);
6206 printf (" %c%c%c ",
6207 (segment->p_flags & PF_R ? 'R' : ' '),
6208 (segment->p_flags & PF_W ? 'W' : ' '),
6209 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6210 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6211 }
252b5132 6212
1a9ccd70
NC
6213 putc ('\n', stdout);
6214 }
f54498b4 6215
252b5132
RH
6216 switch (segment->p_type)
6217 {
1a9ccd70 6218 case PT_LOAD:
502d895c
NC
6219#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6220 required by the ELF standard, several programs, including the Linux
6221 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6222 if (previous_load
6223 && previous_load->p_vaddr > segment->p_vaddr)
6224 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6225#endif
1a9ccd70
NC
6226 if (segment->p_memsz < segment->p_filesz)
6227 error (_("the segment's file size is larger than its memory size\n"));
6228 previous_load = segment;
6229 break;
6230
6231 case PT_PHDR:
6232 /* PR 20815 - Verify that the program header is loaded into memory. */
6233 if (i > 0 && previous_load != NULL)
6234 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6235 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6236 {
6237 unsigned int j;
6238
dda8d76d 6239 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6240 {
6241 Elf_Internal_Phdr *load = filedata->program_headers + j;
6242 if (load->p_type == PT_LOAD
6243 && load->p_offset <= segment->p_offset
6244 && (load->p_offset + load->p_filesz
6245 >= segment->p_offset + segment->p_filesz)
6246 && load->p_vaddr <= segment->p_vaddr
6247 && (load->p_vaddr + load->p_filesz
6248 >= segment->p_vaddr + segment->p_filesz))
6249 break;
6250 }
dda8d76d 6251 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6252 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6253 }
6254 break;
6255
252b5132 6256 case PT_DYNAMIC:
93df3340 6257 if (dynamic_addr)
252b5132
RH
6258 error (_("more than one dynamic segment\n"));
6259
20737c13
AM
6260 /* By default, assume that the .dynamic section is the first
6261 section in the DYNAMIC segment. */
93df3340
AM
6262 dynamic_addr = segment->p_offset;
6263 dynamic_size = segment->p_filesz;
20737c13 6264
b2d38a17
NC
6265 /* Try to locate the .dynamic section. If there is
6266 a section header table, we can easily locate it. */
dda8d76d 6267 if (filedata->section_headers != NULL)
b2d38a17 6268 {
2cf0635d 6269 Elf_Internal_Shdr * sec;
b2d38a17 6270
dda8d76d 6271 sec = find_section (filedata, ".dynamic");
89fac5e3 6272 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6273 {
93df3340
AM
6274 /* A corresponding .dynamic section is expected, but on
6275 IA-64/OpenVMS it is OK for it to be missing. */
6276 if (!is_ia64_vms (filedata))
6277 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6278 break;
6279 }
6280
42bb2e33 6281 if (sec->sh_type == SHT_NOBITS)
20737c13 6282 {
93df3340
AM
6283 dynamic_addr = 0;
6284 dynamic_size = 0;
20737c13
AM
6285 break;
6286 }
42bb2e33 6287
93df3340
AM
6288 dynamic_addr = sec->sh_offset;
6289 dynamic_size = sec->sh_size;
b2d38a17 6290
8ac10c5b
L
6291 /* The PT_DYNAMIC segment, which is used by the run-time
6292 loader, should exactly match the .dynamic section. */
6293 if (do_checks
93df3340
AM
6294 && (dynamic_addr != segment->p_offset
6295 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6296 warn (_("\
6297the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6298 }
39e224f6
MW
6299
6300 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6301 segment. Check this after matching against the section headers
6302 so we don't warn on debuginfo file (which have NOBITS .dynamic
6303 sections). */
93df3340
AM
6304 if (dynamic_addr > filedata->file_size
6305 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6306 {
6307 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6308 dynamic_addr = 0;
6309 dynamic_size = 0;
39e224f6 6310 }
252b5132
RH
6311 break;
6312
6313 case PT_INTERP:
13acb58d
AM
6314 if (segment->p_offset >= filedata->file_size
6315 || segment->p_filesz > filedata->file_size - segment->p_offset
6316 || segment->p_filesz - 1 >= (size_t) -2
63cf857e
AM
6317 || fseek64 (filedata->handle,
6318 filedata->archive_file_offset + segment->p_offset,
6319 SEEK_SET))
252b5132
RH
6320 error (_("Unable to find program interpreter name\n"));
6321 else
6322 {
13acb58d
AM
6323 size_t len = segment->p_filesz;
6324 free (filedata->program_interpreter);
6325 filedata->program_interpreter = xmalloc (len + 1);
6326 len = fread (filedata->program_interpreter, 1, len,
6327 filedata->handle);
6328 filedata->program_interpreter[len] = 0;
252b5132
RH
6329
6330 if (do_segments)
f54498b4 6331 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6332 filedata->program_interpreter);
252b5132
RH
6333 }
6334 break;
6335 }
252b5132
RH
6336 }
6337
dda8d76d
NC
6338 if (do_segments
6339 && filedata->section_headers != NULL
6340 && filedata->string_table != NULL)
252b5132
RH
6341 {
6342 printf (_("\n Section to Segment mapping:\n"));
6343 printf (_(" Segment Sections...\n"));
6344
dda8d76d 6345 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6346 {
9ad5cbcf 6347 unsigned int j;
2cf0635d 6348 Elf_Internal_Shdr * section;
252b5132 6349
dda8d76d
NC
6350 segment = filedata->program_headers + i;
6351 section = filedata->section_headers + 1;
252b5132
RH
6352
6353 printf (" %2.2d ", i);
6354
dda8d76d 6355 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6356 {
f4638467
AM
6357 if (!ELF_TBSS_SPECIAL (section, segment)
6358 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6359 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6360 }
6361
6362 putc ('\n',stdout);
6363 }
6364 }
6365
93df3340
AM
6366 filedata->dynamic_addr = dynamic_addr;
6367 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6368 return;
6369
6370 no_headers:
6371 filedata->dynamic_addr = 0;
6372 filedata->dynamic_size = 1;
252b5132
RH
6373}
6374
6375
d93f0186
NC
6376/* Find the file offset corresponding to VMA by using the program headers. */
6377
26c527e6 6378static int64_t
625d49fc 6379offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 6380{
2cf0635d 6381 Elf_Internal_Phdr * seg;
d93f0186 6382
dda8d76d 6383 if (! get_program_headers (filedata))
d93f0186
NC
6384 {
6385 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6386 return (long) vma;
6387 }
6388
dda8d76d
NC
6389 for (seg = filedata->program_headers;
6390 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6391 ++seg)
6392 {
6393 if (seg->p_type != PT_LOAD)
6394 continue;
6395
6396 if (vma >= (seg->p_vaddr & -seg->p_align)
6397 && vma + size <= seg->p_vaddr + seg->p_filesz)
6398 return vma - seg->p_vaddr + seg->p_offset;
6399 }
6400
26c527e6
AM
6401 warn (_("Virtual address %#" PRIx64
6402 " not located in any PT_LOAD segment.\n"), vma);
6403 return vma;
d93f0186
NC
6404}
6405
6406
dda8d76d
NC
6407/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6408 If PROBE is true, this is just a probe and we do not generate any error
6409 messages if the load fails. */
049b0c3a 6410
015dc7e1
AM
6411static bool
6412get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6413{
2cf0635d
NC
6414 Elf32_External_Shdr * shdrs;
6415 Elf_Internal_Shdr * internal;
dda8d76d
NC
6416 unsigned int i;
6417 unsigned int size = filedata->file_header.e_shentsize;
6418 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6419
6420 /* PR binutils/17531: Cope with unexpected section header sizes. */
6421 if (size == 0 || num == 0)
015dc7e1 6422 return false;
907b52f4
NC
6423
6424 /* The section header cannot be at the start of the file - that is
6425 where the ELF file header is located. A file with absolutely no
6426 sections in it will use a shoff of 0. */
6427 if (filedata->file_header.e_shoff == 0)
6428 return false;
6429
049b0c3a
NC
6430 if (size < sizeof * shdrs)
6431 {
6432 if (! probe)
6433 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6434 return false;
049b0c3a
NC
6435 }
6436 if (!probe && size > sizeof * shdrs)
6437 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6438
dda8d76d 6439 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6440 size, num,
6441 probe ? NULL : _("section headers"));
6442 if (shdrs == NULL)
015dc7e1 6443 return false;
252b5132 6444
dda8d76d
NC
6445 filedata->section_headers = (Elf_Internal_Shdr *)
6446 cmalloc (num, sizeof (Elf_Internal_Shdr));
6447 if (filedata->section_headers == NULL)
252b5132 6448 {
049b0c3a 6449 if (!probe)
8b73c356 6450 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6451 free (shdrs);
015dc7e1 6452 return false;
252b5132
RH
6453 }
6454
dda8d76d 6455 for (i = 0, internal = filedata->section_headers;
560f3c1c 6456 i < num;
b34976b6 6457 i++, internal++)
252b5132
RH
6458 {
6459 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6460 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6461 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6462 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6463 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6464 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6465 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6466 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6467 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6468 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6469 if (!probe && internal->sh_link > num)
6470 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6471 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6472 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6473 }
6474
6475 free (shdrs);
015dc7e1 6476 return true;
252b5132
RH
6477}
6478
dda8d76d
NC
6479/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6480
015dc7e1
AM
6481static bool
6482get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6483{
dda8d76d
NC
6484 Elf64_External_Shdr * shdrs;
6485 Elf_Internal_Shdr * internal;
6486 unsigned int i;
6487 unsigned int size = filedata->file_header.e_shentsize;
6488 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6489
6490 /* PR binutils/17531: Cope with unexpected section header sizes. */
6491 if (size == 0 || num == 0)
015dc7e1 6492 return false;
dda8d76d 6493
907b52f4
NC
6494 /* The section header cannot be at the start of the file - that is
6495 where the ELF file header is located. A file with absolutely no
6496 sections in it will use a shoff of 0. */
6497 if (filedata->file_header.e_shoff == 0)
6498 return false;
6499
049b0c3a
NC
6500 if (size < sizeof * shdrs)
6501 {
6502 if (! probe)
6503 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6504 return false;
049b0c3a 6505 }
dda8d76d 6506
049b0c3a
NC
6507 if (! probe && size > sizeof * shdrs)
6508 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6509
dda8d76d
NC
6510 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6511 filedata->file_header.e_shoff,
049b0c3a
NC
6512 size, num,
6513 probe ? NULL : _("section headers"));
6514 if (shdrs == NULL)
015dc7e1 6515 return false;
9ea033b2 6516
dda8d76d
NC
6517 filedata->section_headers = (Elf_Internal_Shdr *)
6518 cmalloc (num, sizeof (Elf_Internal_Shdr));
6519 if (filedata->section_headers == NULL)
9ea033b2 6520 {
049b0c3a 6521 if (! probe)
8b73c356 6522 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6523 free (shdrs);
015dc7e1 6524 return false;
9ea033b2
NC
6525 }
6526
dda8d76d 6527 for (i = 0, internal = filedata->section_headers;
560f3c1c 6528 i < num;
b34976b6 6529 i++, internal++)
9ea033b2
NC
6530 {
6531 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6532 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6533 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6534 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6535 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6536 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6537 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6538 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6539 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6540 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6541 if (!probe && internal->sh_link > num)
6542 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6543 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6544 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6545 }
6546
6547 free (shdrs);
015dc7e1 6548 return true;
9ea033b2
NC
6549}
6550
4de91c10
AM
6551static bool
6552get_section_headers (Filedata *filedata, bool probe)
6553{
6554 if (filedata->section_headers != NULL)
6555 return true;
6556
4de91c10
AM
6557 if (is_32bit_elf)
6558 return get_32bit_section_headers (filedata, probe);
6559 else
6560 return get_64bit_section_headers (filedata, probe);
6561}
6562
252b5132 6563static Elf_Internal_Sym *
26c527e6
AM
6564get_32bit_elf_symbols (Filedata *filedata,
6565 Elf_Internal_Shdr *section,
6566 uint64_t *num_syms_return)
252b5132 6567{
26c527e6 6568 uint64_t number = 0;
dd24e3da 6569 Elf32_External_Sym * esyms = NULL;
ba5cdace 6570 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6571 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6572 Elf_Internal_Sym * psym;
b34976b6 6573 unsigned int j;
e3d39609 6574 elf_section_list * entry;
252b5132 6575
c9c1d674
EG
6576 if (section->sh_size == 0)
6577 {
6578 if (num_syms_return != NULL)
6579 * num_syms_return = 0;
6580 return NULL;
6581 }
6582
dd24e3da 6583 /* Run some sanity checks first. */
c9c1d674 6584 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6585 {
26c527e6 6586 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 6587 printable_section_name (filedata, section),
26c527e6 6588 section->sh_entsize);
ba5cdace 6589 goto exit_point;
dd24e3da
NC
6590 }
6591
dda8d76d 6592 if (section->sh_size > filedata->file_size)
f54498b4 6593 {
26c527e6 6594 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 6595 printable_section_name (filedata, section),
26c527e6 6596 section->sh_size);
f54498b4
NC
6597 goto exit_point;
6598 }
6599
dd24e3da
NC
6600 number = section->sh_size / section->sh_entsize;
6601
6602 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6603 {
26c527e6
AM
6604 error (_("Size (%#" PRIx64 ") of section %s "
6605 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
6606 section->sh_size,
dda8d76d 6607 printable_section_name (filedata, section),
26c527e6 6608 section->sh_entsize);
ba5cdace 6609 goto exit_point;
dd24e3da
NC
6610 }
6611
dda8d76d 6612 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6613 section->sh_size, _("symbols"));
dd24e3da 6614 if (esyms == NULL)
ba5cdace 6615 goto exit_point;
252b5132 6616
e3d39609 6617 shndx = NULL;
978c4450 6618 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 6619 {
26c527e6 6620 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
6621 continue;
6622
6623 if (shndx != NULL)
6624 {
6625 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6626 free (shndx);
6627 }
6628
6629 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6630 entry->hdr->sh_offset,
6631 1, entry->hdr->sh_size,
6632 _("symbol table section indices"));
6633 if (shndx == NULL)
6634 goto exit_point;
6635
6636 /* PR17531: file: heap-buffer-overflow */
6637 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6638 {
26c527e6 6639 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 6640 printable_section_name (filedata, entry->hdr),
26c527e6
AM
6641 entry->hdr->sh_size,
6642 section->sh_size);
e3d39609 6643 goto exit_point;
c9c1d674 6644 }
e3d39609 6645 }
9ad5cbcf 6646
3f5e193b 6647 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6648
6649 if (isyms == NULL)
6650 {
26c527e6 6651 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
dd24e3da 6652 goto exit_point;
252b5132
RH
6653 }
6654
dd24e3da 6655 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6656 {
6657 psym->st_name = BYTE_GET (esyms[j].st_name);
6658 psym->st_value = BYTE_GET (esyms[j].st_value);
6659 psym->st_size = BYTE_GET (esyms[j].st_size);
6660 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6661 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6662 psym->st_shndx
6663 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6664 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6665 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6666 psym->st_info = BYTE_GET (esyms[j].st_info);
6667 psym->st_other = BYTE_GET (esyms[j].st_other);
6668 }
6669
dd24e3da 6670 exit_point:
e3d39609
NC
6671 free (shndx);
6672 free (esyms);
252b5132 6673
ba5cdace
NC
6674 if (num_syms_return != NULL)
6675 * num_syms_return = isyms == NULL ? 0 : number;
6676
252b5132
RH
6677 return isyms;
6678}
6679
9ea033b2 6680static Elf_Internal_Sym *
26c527e6
AM
6681get_64bit_elf_symbols (Filedata *filedata,
6682 Elf_Internal_Shdr *section,
6683 uint64_t *num_syms_return)
9ea033b2 6684{
26c527e6 6685 uint64_t number = 0;
ba5cdace
NC
6686 Elf64_External_Sym * esyms = NULL;
6687 Elf_External_Sym_Shndx * shndx = NULL;
6688 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6689 Elf_Internal_Sym * psym;
b34976b6 6690 unsigned int j;
e3d39609 6691 elf_section_list * entry;
9ea033b2 6692
c9c1d674
EG
6693 if (section->sh_size == 0)
6694 {
6695 if (num_syms_return != NULL)
6696 * num_syms_return = 0;
6697 return NULL;
6698 }
6699
dd24e3da 6700 /* Run some sanity checks first. */
c9c1d674 6701 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6702 {
26c527e6 6703 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 6704 printable_section_name (filedata, section),
26c527e6 6705 section->sh_entsize);
ba5cdace 6706 goto exit_point;
dd24e3da
NC
6707 }
6708
dda8d76d 6709 if (section->sh_size > filedata->file_size)
f54498b4 6710 {
26c527e6 6711 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 6712 printable_section_name (filedata, section),
26c527e6 6713 section->sh_size);
f54498b4
NC
6714 goto exit_point;
6715 }
6716
dd24e3da
NC
6717 number = section->sh_size / section->sh_entsize;
6718
6719 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6720 {
26c527e6
AM
6721 error (_("Size (%#" PRIx64 ") of section %s "
6722 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
6723 section->sh_size,
dda8d76d 6724 printable_section_name (filedata, section),
26c527e6 6725 section->sh_entsize);
ba5cdace 6726 goto exit_point;
dd24e3da
NC
6727 }
6728
dda8d76d 6729 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6730 section->sh_size, _("symbols"));
a6e9f9df 6731 if (!esyms)
ba5cdace 6732 goto exit_point;
9ea033b2 6733
e3d39609 6734 shndx = NULL;
978c4450 6735 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 6736 {
26c527e6 6737 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
6738 continue;
6739
6740 if (shndx != NULL)
6741 {
6742 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6743 free (shndx);
c9c1d674 6744 }
e3d39609
NC
6745
6746 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6747 entry->hdr->sh_offset,
6748 1, entry->hdr->sh_size,
6749 _("symbol table section indices"));
6750 if (shndx == NULL)
6751 goto exit_point;
6752
6753 /* PR17531: file: heap-buffer-overflow */
6754 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6755 {
26c527e6 6756 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 6757 printable_section_name (filedata, entry->hdr),
26c527e6
AM
6758 entry->hdr->sh_size,
6759 section->sh_size);
e3d39609
NC
6760 goto exit_point;
6761 }
6762 }
9ad5cbcf 6763
3f5e193b 6764 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6765
6766 if (isyms == NULL)
6767 {
26c527e6 6768 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
ba5cdace 6769 goto exit_point;
9ea033b2
NC
6770 }
6771
ba5cdace 6772 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6773 {
6774 psym->st_name = BYTE_GET (esyms[j].st_name);
6775 psym->st_info = BYTE_GET (esyms[j].st_info);
6776 psym->st_other = BYTE_GET (esyms[j].st_other);
6777 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6778
4fbb74a6 6779 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6780 psym->st_shndx
6781 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6782 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6783 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6784
66543521
AM
6785 psym->st_value = BYTE_GET (esyms[j].st_value);
6786 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6787 }
6788
ba5cdace 6789 exit_point:
e3d39609
NC
6790 free (shndx);
6791 free (esyms);
ba5cdace
NC
6792
6793 if (num_syms_return != NULL)
6794 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6795
6796 return isyms;
6797}
6798
4de91c10
AM
6799static Elf_Internal_Sym *
6800get_elf_symbols (Filedata *filedata,
6801 Elf_Internal_Shdr *section,
26c527e6 6802 uint64_t *num_syms_return)
4de91c10
AM
6803{
6804 if (is_32bit_elf)
6805 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6806 else
6807 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6808}
6809
d1133906 6810static const char *
625d49fc 6811get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 6812{
5477e8a0 6813 static char buff[1024];
2cf0635d 6814 char * p = buff;
32ec8896
NC
6815 unsigned int field_size = is_32bit_elf ? 8 : 16;
6816 signed int sindex;
6817 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
6818 uint64_t os_flags = 0;
6819 uint64_t proc_flags = 0;
6820 uint64_t unknown_flags = 0;
148b93f2 6821 static const struct
5477e8a0 6822 {
2cf0635d 6823 const char * str;
32ec8896 6824 unsigned int len;
5477e8a0
L
6825 }
6826 flags [] =
6827 {
cfcac11d
NC
6828 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6829 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6830 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6831 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6832 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6833 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6834 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6835 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6836 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6837 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6838 /* IA-64 specific. */
6839 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6840 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6841 /* IA-64 OpenVMS specific. */
6842 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6843 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6844 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6845 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6846 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6847 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6848 /* Generic. */
cfcac11d 6849 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6850 /* SPARC specific. */
77115a4a 6851 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6852 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6853 /* ARM specific. */
6854 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6855 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6856 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6857 /* GNU specific. */
6858 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6859 /* VLE specific. */
6860 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6861 /* GNU specific. */
6862 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6863 };
6864
6865 if (do_section_details)
6866 {
8d5ff12c
L
6867 sprintf (buff, "[%*.*lx]: ",
6868 field_size, field_size, (unsigned long) sh_flags);
6869 p += field_size + 4;
5477e8a0 6870 }
76da6bbe 6871
d1133906
NC
6872 while (sh_flags)
6873 {
625d49fc 6874 uint64_t flag;
d1133906
NC
6875
6876 flag = sh_flags & - sh_flags;
6877 sh_flags &= ~ flag;
76da6bbe 6878
5477e8a0 6879 if (do_section_details)
d1133906 6880 {
5477e8a0
L
6881 switch (flag)
6882 {
91d6fa6a
NC
6883 case SHF_WRITE: sindex = 0; break;
6884 case SHF_ALLOC: sindex = 1; break;
6885 case SHF_EXECINSTR: sindex = 2; break;
6886 case SHF_MERGE: sindex = 3; break;
6887 case SHF_STRINGS: sindex = 4; break;
6888 case SHF_INFO_LINK: sindex = 5; break;
6889 case SHF_LINK_ORDER: sindex = 6; break;
6890 case SHF_OS_NONCONFORMING: sindex = 7; break;
6891 case SHF_GROUP: sindex = 8; break;
6892 case SHF_TLS: sindex = 9; break;
18ae9cc1 6893 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6894 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6895
5477e8a0 6896 default:
91d6fa6a 6897 sindex = -1;
dda8d76d 6898 switch (filedata->file_header.e_machine)
148b93f2 6899 {
cfcac11d 6900 case EM_IA_64:
148b93f2 6901 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6902 sindex = 10;
148b93f2 6903 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6904 sindex = 11;
dda8d76d 6905 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6906 switch (flag)
6907 {
91d6fa6a
NC
6908 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6909 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6910 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6911 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6912 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6913 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6914 default: break;
6915 }
cfcac11d
NC
6916 break;
6917
caa83f8b 6918 case EM_386:
22abe556 6919 case EM_IAMCU:
caa83f8b 6920 case EM_X86_64:
7f502d6c 6921 case EM_L1OM:
7a9068fe 6922 case EM_K1OM:
cfcac11d
NC
6923 case EM_OLD_SPARCV9:
6924 case EM_SPARC32PLUS:
6925 case EM_SPARCV9:
6926 case EM_SPARC:
18ae9cc1 6927 if (flag == SHF_ORDERED)
91d6fa6a 6928 sindex = 19;
cfcac11d 6929 break;
ac4c9b04
MG
6930
6931 case EM_ARM:
6932 switch (flag)
6933 {
6934 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6935 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6936 case SHF_COMDEF: sindex = 23; break;
6937 default: break;
6938 }
6939 break;
83eef883
AFB
6940 case EM_PPC:
6941 if (flag == SHF_PPC_VLE)
6942 sindex = 25;
6943 break;
99fabbc9
JL
6944 default:
6945 break;
6946 }
ac4c9b04 6947
99fabbc9
JL
6948 switch (filedata->file_header.e_ident[EI_OSABI])
6949 {
6950 case ELFOSABI_GNU:
6951 case ELFOSABI_FREEBSD:
6952 if (flag == SHF_GNU_RETAIN)
6953 sindex = 26;
6954 /* Fall through */
6955 case ELFOSABI_NONE:
6956 if (flag == SHF_GNU_MBIND)
6957 /* We should not recognize SHF_GNU_MBIND for
6958 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6959 not set the EI_OSABI header byte. */
6960 sindex = 24;
6961 break;
cfcac11d
NC
6962 default:
6963 break;
148b93f2 6964 }
99fabbc9 6965 break;
5477e8a0
L
6966 }
6967
91d6fa6a 6968 if (sindex != -1)
5477e8a0 6969 {
8d5ff12c
L
6970 if (p != buff + field_size + 4)
6971 {
6972 if (size < (10 + 2))
bee0ee85
NC
6973 {
6974 warn (_("Internal error: not enough buffer room for section flag info"));
6975 return _("<unknown>");
6976 }
8d5ff12c
L
6977 size -= 2;
6978 *p++ = ',';
6979 *p++ = ' ';
6980 }
6981
91d6fa6a
NC
6982 size -= flags [sindex].len;
6983 p = stpcpy (p, flags [sindex].str);
5477e8a0 6984 }
3b22753a 6985 else if (flag & SHF_MASKOS)
8d5ff12c 6986 os_flags |= flag;
d1133906 6987 else if (flag & SHF_MASKPROC)
8d5ff12c 6988 proc_flags |= flag;
d1133906 6989 else
8d5ff12c 6990 unknown_flags |= flag;
5477e8a0
L
6991 }
6992 else
6993 {
6994 switch (flag)
6995 {
6996 case SHF_WRITE: *p = 'W'; break;
6997 case SHF_ALLOC: *p = 'A'; break;
6998 case SHF_EXECINSTR: *p = 'X'; break;
6999 case SHF_MERGE: *p = 'M'; break;
7000 case SHF_STRINGS: *p = 'S'; break;
7001 case SHF_INFO_LINK: *p = 'I'; break;
7002 case SHF_LINK_ORDER: *p = 'L'; break;
7003 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7004 case SHF_GROUP: *p = 'G'; break;
7005 case SHF_TLS: *p = 'T'; break;
18ae9cc1 7006 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 7007 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
7008
7009 default:
dda8d76d
NC
7010 if ((filedata->file_header.e_machine == EM_X86_64
7011 || filedata->file_header.e_machine == EM_L1OM
7012 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
7013 && flag == SHF_X86_64_LARGE)
7014 *p = 'l';
dda8d76d 7015 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 7016 && flag == SHF_ARM_PURECODE)
99fabbc9 7017 *p = 'y';
dda8d76d 7018 else if (filedata->file_header.e_machine == EM_PPC
83eef883 7019 && flag == SHF_PPC_VLE)
99fabbc9 7020 *p = 'v';
5477e8a0
L
7021 else if (flag & SHF_MASKOS)
7022 {
99fabbc9
JL
7023 switch (filedata->file_header.e_ident[EI_OSABI])
7024 {
7025 case ELFOSABI_GNU:
7026 case ELFOSABI_FREEBSD:
7027 if (flag == SHF_GNU_RETAIN)
7028 {
7029 *p = 'R';
7030 break;
7031 }
7032 /* Fall through */
7033 case ELFOSABI_NONE:
7034 if (flag == SHF_GNU_MBIND)
7035 {
7036 /* We should not recognize SHF_GNU_MBIND for
7037 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7038 not set the EI_OSABI header byte. */
7039 *p = 'D';
7040 break;
7041 }
7042 /* Fall through */
7043 default:
7044 *p = 'o';
7045 sh_flags &= ~SHF_MASKOS;
7046 break;
7047 }
5477e8a0
L
7048 }
7049 else if (flag & SHF_MASKPROC)
7050 {
7051 *p = 'p';
7052 sh_flags &= ~ SHF_MASKPROC;
7053 }
7054 else
7055 *p = 'x';
7056 break;
7057 }
7058 p++;
d1133906
NC
7059 }
7060 }
76da6bbe 7061
8d5ff12c
L
7062 if (do_section_details)
7063 {
7064 if (os_flags)
7065 {
7066 size -= 5 + field_size;
7067 if (p != buff + field_size + 4)
7068 {
7069 if (size < (2 + 1))
bee0ee85
NC
7070 {
7071 warn (_("Internal error: not enough buffer room for section flag info"));
7072 return _("<unknown>");
7073 }
8d5ff12c
L
7074 size -= 2;
7075 *p++ = ',';
7076 *p++ = ' ';
7077 }
7078 sprintf (p, "OS (%*.*lx)", field_size, field_size,
7079 (unsigned long) os_flags);
7080 p += 5 + field_size;
7081 }
7082 if (proc_flags)
7083 {
7084 size -= 7 + field_size;
7085 if (p != buff + field_size + 4)
7086 {
7087 if (size < (2 + 1))
bee0ee85
NC
7088 {
7089 warn (_("Internal error: not enough buffer room for section flag info"));
7090 return _("<unknown>");
7091 }
8d5ff12c
L
7092 size -= 2;
7093 *p++ = ',';
7094 *p++ = ' ';
7095 }
7096 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7097 (unsigned long) proc_flags);
7098 p += 7 + field_size;
7099 }
7100 if (unknown_flags)
7101 {
7102 size -= 10 + field_size;
7103 if (p != buff + field_size + 4)
7104 {
7105 if (size < (2 + 1))
bee0ee85
NC
7106 {
7107 warn (_("Internal error: not enough buffer room for section flag info"));
7108 return _("<unknown>");
7109 }
8d5ff12c
L
7110 size -= 2;
7111 *p++ = ',';
7112 *p++ = ' ';
7113 }
2b692964 7114 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
7115 (unsigned long) unknown_flags);
7116 p += 10 + field_size;
7117 }
7118 }
7119
e9e44622 7120 *p = '\0';
d1133906
NC
7121 return buff;
7122}
7123
5844b465 7124static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7125get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7126 uint64_t size)
77115a4a
L
7127{
7128 if (is_32bit_elf)
7129 {
7130 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7131
ebdf1ebf
NC
7132 if (size < sizeof (* echdr))
7133 {
7134 error (_("Compressed section is too small even for a compression header\n"));
7135 return 0;
7136 }
7137
77115a4a
L
7138 chdr->ch_type = BYTE_GET (echdr->ch_type);
7139 chdr->ch_size = BYTE_GET (echdr->ch_size);
7140 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7141 return sizeof (*echdr);
7142 }
7143 else
7144 {
7145 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7146
ebdf1ebf
NC
7147 if (size < sizeof (* echdr))
7148 {
7149 error (_("Compressed section is too small even for a compression header\n"));
7150 return 0;
7151 }
7152
77115a4a
L
7153 chdr->ch_type = BYTE_GET (echdr->ch_type);
7154 chdr->ch_size = BYTE_GET (echdr->ch_size);
7155 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7156 return sizeof (*echdr);
7157 }
7158}
7159
015dc7e1 7160static bool
dda8d76d 7161process_section_headers (Filedata * filedata)
252b5132 7162{
2cf0635d 7163 Elf_Internal_Shdr * section;
b34976b6 7164 unsigned int i;
252b5132 7165
dda8d76d 7166 if (filedata->file_header.e_shnum == 0)
252b5132 7167 {
82f2dbf7 7168 /* PR binutils/12467. */
dda8d76d 7169 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7170 {
7171 warn (_("possibly corrupt ELF file header - it has a non-zero"
7172 " section header offset, but no section headers\n"));
015dc7e1 7173 return false;
32ec8896 7174 }
82f2dbf7 7175 else if (do_sections)
252b5132
RH
7176 printf (_("\nThere are no sections in this file.\n"));
7177
015dc7e1 7178 return true;
252b5132
RH
7179 }
7180
7181 if (do_sections && !do_header)
ca0e11aa
NC
7182 {
7183 if (filedata->is_separate && process_links)
7184 printf (_("In linked file '%s': "), filedata->file_name);
7185 if (! filedata->is_separate || process_links)
7186 printf (ngettext ("There is %d section header, "
26c527e6 7187 "starting at offset %#" PRIx64 ":\n",
ca0e11aa 7188 "There are %d section headers, "
26c527e6 7189 "starting at offset %#" PRIx64 ":\n",
ca0e11aa
NC
7190 filedata->file_header.e_shnum),
7191 filedata->file_header.e_shnum,
26c527e6 7192 filedata->file_header.e_shoff);
ca0e11aa 7193 }
252b5132 7194
4de91c10
AM
7195 if (!get_section_headers (filedata, false))
7196 return false;
252b5132
RH
7197
7198 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7199 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7200 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7201 {
dda8d76d 7202 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7203
c256ffe7
JJ
7204 if (section->sh_size != 0)
7205 {
dda8d76d
NC
7206 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7207 1, section->sh_size,
7208 _("string table"));
0de14b54 7209
dda8d76d 7210 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7211 }
252b5132
RH
7212 }
7213
7214 /* Scan the sections for the dynamic symbol table
e3c8793a 7215 and dynamic string table and debug sections. */
89fac5e3 7216 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7217 switch (filedata->file_header.e_machine)
89fac5e3
RS
7218 {
7219 case EM_MIPS:
7220 case EM_MIPS_RS3_LE:
7221 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7222 FDE addresses. However, the ABI also has a semi-official ILP32
7223 variant for which the normal FDE address size rules apply.
7224
7225 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7226 section, where XX is the size of longs in bits. Unfortunately,
7227 earlier compilers provided no way of distinguishing ILP32 objects
7228 from LP64 objects, so if there's any doubt, we should assume that
7229 the official LP64 form is being used. */
dda8d76d
NC
7230 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7231 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7232 eh_addr_size = 8;
7233 break;
0f56a26a
DD
7234
7235 case EM_H8_300:
7236 case EM_H8_300H:
dda8d76d 7237 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7238 {
7239 case E_H8_MACH_H8300:
7240 case E_H8_MACH_H8300HN:
7241 case E_H8_MACH_H8300SN:
7242 case E_H8_MACH_H8300SXN:
7243 eh_addr_size = 2;
7244 break;
7245 case E_H8_MACH_H8300H:
7246 case E_H8_MACH_H8300S:
7247 case E_H8_MACH_H8300SX:
7248 eh_addr_size = 4;
7249 break;
7250 }
f4236fe4
DD
7251 break;
7252
ff7eeb89 7253 case EM_M32C_OLD:
f4236fe4 7254 case EM_M32C:
dda8d76d 7255 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7256 {
7257 case EF_M32C_CPU_M16C:
7258 eh_addr_size = 2;
7259 break;
7260 }
7261 break;
89fac5e3
RS
7262 }
7263
76ca31c0
NC
7264#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7265 do \
7266 { \
be7d229a 7267 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7268 if (section->sh_entsize != expected_entsize) \
9dd3a467 7269 { \
f493c217 7270 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7271 i, section->sh_entsize); \
f493c217 7272 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7273 expected_entsize); \
9dd3a467 7274 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7275 } \
7276 } \
08d8fa11 7277 while (0)
9dd3a467
NC
7278
7279#define CHECK_ENTSIZE(section, i, type) \
1b513401 7280 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7281 sizeof (Elf64_External_##type))
7282
dda8d76d
NC
7283 for (i = 0, section = filedata->section_headers;
7284 i < filedata->file_header.e_shnum;
b34976b6 7285 i++, section++)
252b5132 7286 {
84714f86 7287 const char *name = section_name_print (filedata, section);
252b5132 7288
1b513401
NC
7289 /* Run some sanity checks on the headers and
7290 possibly fill in some file data as well. */
7291 switch (section->sh_type)
252b5132 7292 {
1b513401 7293 case SHT_DYNSYM:
978c4450 7294 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7295 {
7296 error (_("File contains multiple dynamic symbol tables\n"));
7297 continue;
7298 }
7299
08d8fa11 7300 CHECK_ENTSIZE (section, i, Sym);
978c4450 7301 filedata->dynamic_symbols
4de91c10 7302 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7303 filedata->dynamic_symtab_section = section;
1b513401
NC
7304 break;
7305
7306 case SHT_STRTAB:
7307 if (streq (name, ".dynstr"))
252b5132 7308 {
1b513401
NC
7309 if (filedata->dynamic_strings != NULL)
7310 {
7311 error (_("File contains multiple dynamic string tables\n"));
7312 continue;
7313 }
7314
7315 filedata->dynamic_strings
7316 = (char *) get_data (NULL, filedata, section->sh_offset,
7317 1, section->sh_size, _("dynamic strings"));
7318 filedata->dynamic_strings_length
7319 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7320 filedata->dynamic_strtab_section = section;
252b5132 7321 }
1b513401
NC
7322 break;
7323
7324 case SHT_SYMTAB_SHNDX:
7325 {
7326 elf_section_list * entry = xmalloc (sizeof * entry);
7327
7328 entry->hdr = section;
7329 entry->next = filedata->symtab_shndx_list;
7330 filedata->symtab_shndx_list = entry;
7331 }
7332 break;
7333
7334 case SHT_SYMTAB:
7335 CHECK_ENTSIZE (section, i, Sym);
7336 break;
7337
7338 case SHT_GROUP:
7339 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7340 break;
252b5132 7341
1b513401
NC
7342 case SHT_REL:
7343 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7344 if (do_checks && section->sh_size == 0)
1b513401
NC
7345 warn (_("Section '%s': zero-sized relocation section\n"), name);
7346 break;
7347
7348 case SHT_RELA:
7349 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7350 if (do_checks && section->sh_size == 0)
1b513401
NC
7351 warn (_("Section '%s': zero-sized relocation section\n"), name);
7352 break;
7353
682351b9
AM
7354 case SHT_RELR:
7355 CHECK_ENTSIZE (section, i, Relr);
7356 break;
7357
1b513401
NC
7358 case SHT_NOTE:
7359 case SHT_PROGBITS:
546cb2d8
NC
7360 /* Having a zero sized section is not illegal according to the
7361 ELF standard, but it might be an indication that something
7362 is wrong. So issue a warning if we are running in lint mode. */
7363 if (do_checks && section->sh_size == 0)
1b513401
NC
7364 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7365 break;
7366
7367 default:
7368 break;
7369 }
7370
7371 if ((do_debugging || do_debug_info || do_debug_abbrevs
7372 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7373 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7374 || do_debug_str || do_debug_str_offsets || do_debug_loc
7375 || do_debug_ranges
1b513401 7376 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7377 && (startswith (name, ".debug_")
7378 || startswith (name, ".zdebug_")))
252b5132 7379 {
1b315056
CS
7380 if (name[1] == 'z')
7381 name += sizeof (".zdebug_") - 1;
7382 else
7383 name += sizeof (".debug_") - 1;
252b5132
RH
7384
7385 if (do_debugging
24d127aa
ML
7386 || (do_debug_info && startswith (name, "info"))
7387 || (do_debug_info && startswith (name, "types"))
7388 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7389 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7390 || (do_debug_lines && startswith (name, "line."))
7391 || (do_debug_pubnames && startswith (name, "pubnames"))
7392 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7393 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7394 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7395 || (do_debug_aranges && startswith (name, "aranges"))
7396 || (do_debug_ranges && startswith (name, "ranges"))
7397 || (do_debug_ranges && startswith (name, "rnglists"))
7398 || (do_debug_frames && startswith (name, "frame"))
7399 || (do_debug_macinfo && startswith (name, "macinfo"))
7400 || (do_debug_macinfo && startswith (name, "macro"))
7401 || (do_debug_str && startswith (name, "str"))
7402 || (do_debug_links && startswith (name, "sup"))
7403 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7404 || (do_debug_loc && startswith (name, "loc"))
7405 || (do_debug_loc && startswith (name, "loclists"))
7406 || (do_debug_addr && startswith (name, "addr"))
7407 || (do_debug_cu_index && startswith (name, "cu_index"))
7408 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7409 )
6431e409 7410 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7411 }
a262ae96 7412 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7413 else if ((do_debugging || do_debug_info)
24d127aa 7414 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7415 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7416 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7417 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7418 else if (do_gdb_index && (streq (name, ".gdb_index")
7419 || streq (name, ".debug_names")))
6431e409 7420 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7421 /* Trace sections for Itanium VMS. */
7422 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7423 || do_trace_aranges)
24d127aa 7424 && startswith (name, ".trace_"))
6f875884
TG
7425 {
7426 name += sizeof (".trace_") - 1;
7427
7428 if (do_debugging
7429 || (do_trace_info && streq (name, "info"))
7430 || (do_trace_abbrevs && streq (name, "abbrev"))
7431 || (do_trace_aranges && streq (name, "aranges"))
7432 )
6431e409 7433 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7434 }
dda8d76d 7435 else if ((do_debugging || do_debug_links)
24d127aa
ML
7436 && (startswith (name, ".gnu_debuglink")
7437 || startswith (name, ".gnu_debugaltlink")))
6431e409 7438 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7439 }
7440
7441 if (! do_sections)
015dc7e1 7442 return true;
252b5132 7443
ca0e11aa 7444 if (filedata->is_separate && ! process_links)
015dc7e1 7445 return true;
ca0e11aa
NC
7446
7447 if (filedata->is_separate)
7448 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7449 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7450 printf (_("\nSection Headers:\n"));
7451 else
7452 printf (_("\nSection Header:\n"));
76da6bbe 7453
f7a99963 7454 if (is_32bit_elf)
595cf52e 7455 {
5477e8a0 7456 if (do_section_details)
595cf52e
L
7457 {
7458 printf (_(" [Nr] Name\n"));
5477e8a0 7459 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7460 }
7461 else
7462 printf
7463 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7464 }
d974e256 7465 else if (do_wide)
595cf52e 7466 {
5477e8a0 7467 if (do_section_details)
595cf52e
L
7468 {
7469 printf (_(" [Nr] Name\n"));
5477e8a0 7470 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7471 }
7472 else
7473 printf
7474 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7475 }
f7a99963
NC
7476 else
7477 {
5477e8a0 7478 if (do_section_details)
595cf52e
L
7479 {
7480 printf (_(" [Nr] Name\n"));
5477e8a0
L
7481 printf (_(" Type Address Offset Link\n"));
7482 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7483 }
7484 else
7485 {
7486 printf (_(" [Nr] Name Type Address Offset\n"));
7487 printf (_(" Size EntSize Flags Link Info Align\n"));
7488 }
f7a99963 7489 }
252b5132 7490
5477e8a0
L
7491 if (do_section_details)
7492 printf (_(" Flags\n"));
7493
dda8d76d
NC
7494 for (i = 0, section = filedata->section_headers;
7495 i < filedata->file_header.e_shnum;
b34976b6 7496 i++, section++)
252b5132 7497 {
dd905818
NC
7498 /* Run some sanity checks on the section header. */
7499
7500 /* Check the sh_link field. */
7501 switch (section->sh_type)
7502 {
285e3f99
AM
7503 case SHT_REL:
7504 case SHT_RELA:
7505 if (section->sh_link == 0
7506 && (filedata->file_header.e_type == ET_EXEC
7507 || filedata->file_header.e_type == ET_DYN))
7508 /* A dynamic relocation section where all entries use a
7509 zero symbol index need not specify a symtab section. */
7510 break;
7511 /* Fall through. */
dd905818
NC
7512 case SHT_SYMTAB_SHNDX:
7513 case SHT_GROUP:
7514 case SHT_HASH:
7515 case SHT_GNU_HASH:
7516 case SHT_GNU_versym:
285e3f99 7517 if (section->sh_link == 0
dda8d76d
NC
7518 || section->sh_link >= filedata->file_header.e_shnum
7519 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7520 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7521 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7522 i, section->sh_link);
7523 break;
7524
7525 case SHT_DYNAMIC:
7526 case SHT_SYMTAB:
7527 case SHT_DYNSYM:
7528 case SHT_GNU_verneed:
7529 case SHT_GNU_verdef:
7530 case SHT_GNU_LIBLIST:
285e3f99 7531 if (section->sh_link == 0
dda8d76d
NC
7532 || section->sh_link >= filedata->file_header.e_shnum
7533 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7534 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7535 i, section->sh_link);
7536 break;
7537
7538 case SHT_INIT_ARRAY:
7539 case SHT_FINI_ARRAY:
7540 case SHT_PREINIT_ARRAY:
7541 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7542 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7543 i, section->sh_link);
7544 break;
7545
7546 default:
7547 /* FIXME: Add support for target specific section types. */
7548#if 0 /* Currently we do not check other section types as there are too
7549 many special cases. Stab sections for example have a type
7550 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7551 section. */
7552 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7553 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7554 i, section->sh_link);
7555#endif
7556 break;
7557 }
7558
7559 /* Check the sh_info field. */
7560 switch (section->sh_type)
7561 {
7562 case SHT_REL:
7563 case SHT_RELA:
285e3f99
AM
7564 if (section->sh_info == 0
7565 && (filedata->file_header.e_type == ET_EXEC
7566 || filedata->file_header.e_type == ET_DYN))
7567 /* Dynamic relocations apply to segments, so they do not
7568 need to specify the section they relocate. */
7569 break;
7570 if (section->sh_info == 0
dda8d76d
NC
7571 || section->sh_info >= filedata->file_header.e_shnum
7572 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7573 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7574 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7575 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7576 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7577 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7578 /* FIXME: Are other section types valid ? */
dda8d76d 7579 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7580 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7581 i, section->sh_info);
dd905818
NC
7582 break;
7583
7584 case SHT_DYNAMIC:
7585 case SHT_HASH:
7586 case SHT_SYMTAB_SHNDX:
7587 case SHT_INIT_ARRAY:
7588 case SHT_FINI_ARRAY:
7589 case SHT_PREINIT_ARRAY:
7590 if (section->sh_info != 0)
7591 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7592 i, section->sh_info);
7593 break;
7594
7595 case SHT_GROUP:
7596 case SHT_SYMTAB:
7597 case SHT_DYNSYM:
7598 /* A symbol index - we assume that it is valid. */
7599 break;
7600
7601 default:
7602 /* FIXME: Add support for target specific section types. */
7603 if (section->sh_type == SHT_NOBITS)
7604 /* NOBITS section headers with non-zero sh_info fields can be
7605 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7606 information. The stripped sections have their headers
7607 preserved but their types set to SHT_NOBITS. So do not check
7608 this type of section. */
dd905818
NC
7609 ;
7610 else if (section->sh_flags & SHF_INFO_LINK)
7611 {
dda8d76d 7612 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7613 warn (_("[%2u]: Expected link to another section in info field"), i);
7614 }
a91e1603
L
7615 else if (section->sh_type < SHT_LOOS
7616 && (section->sh_flags & SHF_GNU_MBIND) == 0
7617 && section->sh_info != 0)
dd905818
NC
7618 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7619 i, section->sh_info);
7620 break;
7621 }
7622
3e6b6445 7623 /* Check the sh_size field. */
dda8d76d 7624 if (section->sh_size > filedata->file_size
3e6b6445
NC
7625 && section->sh_type != SHT_NOBITS
7626 && section->sh_type != SHT_NULL
7627 && section->sh_type < SHT_LOOS)
7628 warn (_("Size of section %u is larger than the entire file!\n"), i);
7629
7bfd842d 7630 printf (" [%2u] ", i);
5477e8a0 7631 if (do_section_details)
dda8d76d 7632 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7633 else
84714f86 7634 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7635
ea52a088 7636 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7637 get_section_type_name (filedata, section->sh_type));
0b4362b0 7638
f7a99963
NC
7639 if (is_32bit_elf)
7640 {
cfcac11d
NC
7641 const char * link_too_big = NULL;
7642
f7a99963 7643 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7644
f7a99963
NC
7645 printf ( " %6.6lx %6.6lx %2.2lx",
7646 (unsigned long) section->sh_offset,
7647 (unsigned long) section->sh_size,
7648 (unsigned long) section->sh_entsize);
d1133906 7649
5477e8a0
L
7650 if (do_section_details)
7651 fputs (" ", stdout);
7652 else
dda8d76d 7653 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7654
dda8d76d 7655 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7656 {
7657 link_too_big = "";
7658 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7659 an error but it can have special values in Solaris binaries. */
dda8d76d 7660 switch (filedata->file_header.e_machine)
cfcac11d 7661 {
caa83f8b 7662 case EM_386:
22abe556 7663 case EM_IAMCU:
caa83f8b 7664 case EM_X86_64:
7f502d6c 7665 case EM_L1OM:
7a9068fe 7666 case EM_K1OM:
cfcac11d
NC
7667 case EM_OLD_SPARCV9:
7668 case EM_SPARC32PLUS:
7669 case EM_SPARCV9:
7670 case EM_SPARC:
7671 if (section->sh_link == (SHN_BEFORE & 0xffff))
7672 link_too_big = "BEFORE";
7673 else if (section->sh_link == (SHN_AFTER & 0xffff))
7674 link_too_big = "AFTER";
7675 break;
7676 default:
7677 break;
7678 }
7679 }
7680
7681 if (do_section_details)
7682 {
7683 if (link_too_big != NULL && * link_too_big)
7684 printf ("<%s> ", link_too_big);
7685 else
7686 printf ("%2u ", section->sh_link);
7687 printf ("%3u %2lu\n", section->sh_info,
7688 (unsigned long) section->sh_addralign);
7689 }
7690 else
7691 printf ("%2u %3u %2lu\n",
7692 section->sh_link,
7693 section->sh_info,
7694 (unsigned long) section->sh_addralign);
7695
7696 if (link_too_big && ! * link_too_big)
7697 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7698 i, section->sh_link);
f7a99963 7699 }
d974e256
JJ
7700 else if (do_wide)
7701 {
7702 print_vma (section->sh_addr, LONG_HEX);
7703
7704 if ((long) section->sh_offset == section->sh_offset)
7705 printf (" %6.6lx", (unsigned long) section->sh_offset);
7706 else
7707 {
7708 putchar (' ');
7709 print_vma (section->sh_offset, LONG_HEX);
7710 }
7711
7712 if ((unsigned long) section->sh_size == section->sh_size)
7713 printf (" %6.6lx", (unsigned long) section->sh_size);
7714 else
7715 {
7716 putchar (' ');
7717 print_vma (section->sh_size, LONG_HEX);
7718 }
7719
7720 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7721 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7722 else
7723 {
7724 putchar (' ');
7725 print_vma (section->sh_entsize, LONG_HEX);
7726 }
7727
5477e8a0
L
7728 if (do_section_details)
7729 fputs (" ", stdout);
7730 else
dda8d76d 7731 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7732
72de5009 7733 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7734
7735 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7736 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7737 else
7738 {
7739 print_vma (section->sh_addralign, DEC);
7740 putchar ('\n');
7741 }
7742 }
5477e8a0 7743 else if (do_section_details)
595cf52e 7744 {
55cc53e9 7745 putchar (' ');
595cf52e
L
7746 print_vma (section->sh_addr, LONG_HEX);
7747 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7748 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7749 else
7750 {
7751 printf (" ");
7752 print_vma (section->sh_offset, LONG_HEX);
7753 }
72de5009 7754 printf (" %u\n ", section->sh_link);
595cf52e 7755 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7756 putchar (' ');
595cf52e
L
7757 print_vma (section->sh_entsize, LONG_HEX);
7758
72de5009
AM
7759 printf (" %-16u %lu\n",
7760 section->sh_info,
595cf52e
L
7761 (unsigned long) section->sh_addralign);
7762 }
f7a99963
NC
7763 else
7764 {
7765 putchar (' ');
7766 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7767 if ((long) section->sh_offset == section->sh_offset)
7768 printf (" %8.8lx", (unsigned long) section->sh_offset);
7769 else
7770 {
7771 printf (" ");
7772 print_vma (section->sh_offset, LONG_HEX);
7773 }
f7a99963
NC
7774 printf ("\n ");
7775 print_vma (section->sh_size, LONG_HEX);
7776 printf (" ");
7777 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7778
dda8d76d 7779 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7780
72de5009
AM
7781 printf (" %2u %3u %lu\n",
7782 section->sh_link,
7783 section->sh_info,
f7a99963
NC
7784 (unsigned long) section->sh_addralign);
7785 }
5477e8a0
L
7786
7787 if (do_section_details)
77115a4a 7788 {
dda8d76d 7789 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7790 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7791 {
7792 /* Minimum section size is 12 bytes for 32-bit compression
7793 header + 12 bytes for compressed data header. */
7794 unsigned char buf[24];
d8024a91 7795
77115a4a 7796 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7797 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7798 sizeof (buf), _("compression header")))
7799 {
7800 Elf_Internal_Chdr chdr;
d8024a91 7801
5844b465
NC
7802 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7803 printf (_(" [<corrupt>]\n"));
77115a4a 7804 else
5844b465
NC
7805 {
7806 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7807 printf (" ZLIB, ");
1369522f
CC
7808 else if (chdr.ch_type == ELFCOMPRESS_ZSTD)
7809 printf (" ZSTD, ");
5844b465
NC
7810 else
7811 printf (_(" [<unknown>: 0x%x], "),
7812 chdr.ch_type);
7813 print_vma (chdr.ch_size, LONG_HEX);
7814 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7815 }
77115a4a
L
7816 }
7817 }
7818 }
252b5132
RH
7819 }
7820
5477e8a0 7821 if (!do_section_details)
3dbcc61d 7822 {
9fb71ee4
NC
7823 /* The ordering of the letters shown here matches the ordering of the
7824 corresponding SHF_xxx values, and hence the order in which these
7825 letters will be displayed to the user. */
7826 printf (_("Key to Flags:\n\
7827 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7828 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7829 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7830 switch (filedata->file_header.e_ident[EI_OSABI])
7831 {
7832 case ELFOSABI_GNU:
7833 case ELFOSABI_FREEBSD:
7834 printf (_("R (retain), "));
7835 /* Fall through */
7836 case ELFOSABI_NONE:
7837 printf (_("D (mbind), "));
7838 break;
7839 default:
7840 break;
7841 }
dda8d76d
NC
7842 if (filedata->file_header.e_machine == EM_X86_64
7843 || filedata->file_header.e_machine == EM_L1OM
7844 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7845 printf (_("l (large), "));
dda8d76d 7846 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7847 printf (_("y (purecode), "));
dda8d76d 7848 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7849 printf (_("v (VLE), "));
9fb71ee4 7850 printf ("p (processor specific)\n");
0b4362b0 7851 }
d1133906 7852
015dc7e1 7853 return true;
252b5132
RH
7854}
7855
015dc7e1 7856static bool
28d13567 7857get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
26c527e6
AM
7858 Elf_Internal_Sym **symtab, uint64_t *nsyms,
7859 char **strtab, uint64_t *strtablen)
28d13567
AM
7860{
7861 *strtab = NULL;
7862 *strtablen = 0;
4de91c10 7863 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7864
7865 if (*symtab == NULL)
015dc7e1 7866 return false;
28d13567
AM
7867
7868 if (symsec->sh_link != 0)
7869 {
7870 Elf_Internal_Shdr *strsec;
7871
7872 if (symsec->sh_link >= filedata->file_header.e_shnum)
7873 {
7874 error (_("Bad sh_link in symbol table section\n"));
7875 free (*symtab);
7876 *symtab = NULL;
7877 *nsyms = 0;
015dc7e1 7878 return false;
28d13567
AM
7879 }
7880
7881 strsec = filedata->section_headers + symsec->sh_link;
7882
7883 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7884 1, strsec->sh_size, _("string table"));
7885 if (*strtab == NULL)
7886 {
7887 free (*symtab);
7888 *symtab = NULL;
7889 *nsyms = 0;
015dc7e1 7890 return false;
28d13567
AM
7891 }
7892 *strtablen = strsec->sh_size;
7893 }
015dc7e1 7894 return true;
28d13567
AM
7895}
7896
f5842774
L
7897static const char *
7898get_group_flags (unsigned int flags)
7899{
1449284b 7900 static char buff[128];
220453ec 7901
6d913794
NC
7902 if (flags == 0)
7903 return "";
7904 else if (flags == GRP_COMDAT)
7905 return "COMDAT ";
f5842774 7906
89246a0e
AM
7907 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7908 flags,
7909 flags & GRP_MASKOS ? _("<OS specific>") : "",
7910 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7911 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7912 ? _("<unknown>") : ""));
6d913794 7913
f5842774
L
7914 return buff;
7915}
7916
015dc7e1 7917static bool
dda8d76d 7918process_section_groups (Filedata * filedata)
f5842774 7919{
2cf0635d 7920 Elf_Internal_Shdr * section;
f5842774 7921 unsigned int i;
2cf0635d
NC
7922 struct group * group;
7923 Elf_Internal_Shdr * symtab_sec;
7924 Elf_Internal_Shdr * strtab_sec;
7925 Elf_Internal_Sym * symtab;
26c527e6 7926 uint64_t num_syms;
2cf0635d 7927 char * strtab;
c256ffe7 7928 size_t strtab_size;
d1f5c6e3
L
7929
7930 /* Don't process section groups unless needed. */
7931 if (!do_unwind && !do_section_groups)
015dc7e1 7932 return true;
f5842774 7933
dda8d76d 7934 if (filedata->file_header.e_shnum == 0)
f5842774
L
7935 {
7936 if (do_section_groups)
ca0e11aa
NC
7937 {
7938 if (filedata->is_separate)
7939 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7940 filedata->file_name);
7941 else
7942 printf (_("\nThere are no section groups in this file.\n"));
7943 }
015dc7e1 7944 return true;
f5842774
L
7945 }
7946
dda8d76d 7947 if (filedata->section_headers == NULL)
f5842774
L
7948 {
7949 error (_("Section headers are not available!\n"));
fa1908fd 7950 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7951 return false;
f5842774
L
7952 }
7953
978c4450
AM
7954 filedata->section_headers_groups
7955 = (struct group **) calloc (filedata->file_header.e_shnum,
7956 sizeof (struct group *));
e4b17d5c 7957
978c4450 7958 if (filedata->section_headers_groups == NULL)
e4b17d5c 7959 {
8b73c356 7960 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7961 filedata->file_header.e_shnum);
015dc7e1 7962 return false;
e4b17d5c
L
7963 }
7964
f5842774 7965 /* Scan the sections for the group section. */
978c4450 7966 filedata->group_count = 0;
dda8d76d
NC
7967 for (i = 0, section = filedata->section_headers;
7968 i < filedata->file_header.e_shnum;
f5842774 7969 i++, section++)
e4b17d5c 7970 if (section->sh_type == SHT_GROUP)
978c4450 7971 filedata->group_count++;
e4b17d5c 7972
978c4450 7973 if (filedata->group_count == 0)
d1f5c6e3
L
7974 {
7975 if (do_section_groups)
ca0e11aa
NC
7976 {
7977 if (filedata->is_separate)
7978 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7979 filedata->file_name);
7980 else
7981 printf (_("\nThere are no section groups in this file.\n"));
7982 }
d1f5c6e3 7983
015dc7e1 7984 return true;
d1f5c6e3
L
7985 }
7986
978c4450
AM
7987 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7988 sizeof (struct group));
e4b17d5c 7989
978c4450 7990 if (filedata->section_groups == NULL)
e4b17d5c 7991 {
26c527e6 7992 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
015dc7e1 7993 return false;
e4b17d5c
L
7994 }
7995
d1f5c6e3
L
7996 symtab_sec = NULL;
7997 strtab_sec = NULL;
7998 symtab = NULL;
ba5cdace 7999 num_syms = 0;
d1f5c6e3 8000 strtab = NULL;
c256ffe7 8001 strtab_size = 0;
ca0e11aa
NC
8002
8003 if (filedata->is_separate)
8004 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 8005
978c4450 8006 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 8007 i < filedata->file_header.e_shnum;
e4b17d5c 8008 i++, section++)
f5842774
L
8009 {
8010 if (section->sh_type == SHT_GROUP)
8011 {
dda8d76d 8012 const char * name = printable_section_name (filedata, section);
74e1a04b 8013 const char * group_name;
2cf0635d
NC
8014 unsigned char * start;
8015 unsigned char * indices;
f5842774 8016 unsigned int entry, j, size;
2cf0635d
NC
8017 Elf_Internal_Shdr * sec;
8018 Elf_Internal_Sym * sym;
f5842774
L
8019
8020 /* Get the symbol table. */
dda8d76d
NC
8021 if (section->sh_link >= filedata->file_header.e_shnum
8022 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 8023 != SHT_SYMTAB))
f5842774
L
8024 {
8025 error (_("Bad sh_link in group section `%s'\n"), name);
8026 continue;
8027 }
d1f5c6e3
L
8028
8029 if (symtab_sec != sec)
8030 {
8031 symtab_sec = sec;
9db70fc3 8032 free (symtab);
4de91c10 8033 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 8034 }
f5842774 8035
dd24e3da
NC
8036 if (symtab == NULL)
8037 {
8038 error (_("Corrupt header in group section `%s'\n"), name);
8039 continue;
8040 }
8041
ba5cdace
NC
8042 if (section->sh_info >= num_syms)
8043 {
8044 error (_("Bad sh_info in group section `%s'\n"), name);
8045 continue;
8046 }
8047
f5842774
L
8048 sym = symtab + section->sh_info;
8049
8050 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8051 {
4fbb74a6 8052 if (sym->st_shndx == 0
dda8d76d 8053 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
8054 {
8055 error (_("Bad sh_info in group section `%s'\n"), name);
8056 continue;
8057 }
ba2685cc 8058
84714f86
AM
8059 group_name = section_name_print (filedata,
8060 filedata->section_headers
b9e920ec 8061 + sym->st_shndx);
c256ffe7 8062 strtab_sec = NULL;
9db70fc3 8063 free (strtab);
f5842774 8064 strtab = NULL;
c256ffe7 8065 strtab_size = 0;
f5842774
L
8066 }
8067 else
8068 {
8069 /* Get the string table. */
dda8d76d 8070 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8071 {
8072 strtab_sec = NULL;
9db70fc3 8073 free (strtab);
c256ffe7
JJ
8074 strtab = NULL;
8075 strtab_size = 0;
8076 }
8077 else if (strtab_sec
dda8d76d 8078 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8079 {
8080 strtab_sec = sec;
9db70fc3 8081 free (strtab);
071436c6 8082
dda8d76d 8083 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8084 1, strtab_sec->sh_size,
8085 _("string table"));
c256ffe7 8086 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8087 }
c256ffe7 8088 group_name = sym->st_name < strtab_size
2b692964 8089 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8090 }
8091
c9c1d674
EG
8092 /* PR 17531: file: loop. */
8093 if (section->sh_entsize > section->sh_size)
8094 {
26c527e6
AM
8095 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8096 " which is larger than its size (%#" PRIx64 ")\n"),
dda8d76d 8097 printable_section_name (filedata, section),
26c527e6
AM
8098 section->sh_entsize,
8099 section->sh_size);
61dd8e19 8100 continue;
c9c1d674
EG
8101 }
8102
dda8d76d 8103 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8104 1, section->sh_size,
8105 _("section data"));
59245841
NC
8106 if (start == NULL)
8107 continue;
f5842774
L
8108
8109 indices = start;
8110 size = (section->sh_size / section->sh_entsize) - 1;
8111 entry = byte_get (indices, 4);
8112 indices += 4;
e4b17d5c
L
8113
8114 if (do_section_groups)
8115 {
2b692964 8116 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8117 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8118
e4b17d5c
L
8119 printf (_(" [Index] Name\n"));
8120 }
8121
8122 group->group_index = i;
8123
f5842774
L
8124 for (j = 0; j < size; j++)
8125 {
2cf0635d 8126 struct group_list * g;
e4b17d5c 8127
f5842774
L
8128 entry = byte_get (indices, 4);
8129 indices += 4;
8130
dda8d76d 8131 if (entry >= filedata->file_header.e_shnum)
391cb864 8132 {
57028622
NC
8133 static unsigned num_group_errors = 0;
8134
8135 if (num_group_errors ++ < 10)
8136 {
8137 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8138 entry, i, filedata->file_header.e_shnum - 1);
57028622 8139 if (num_group_errors == 10)
67ce483b 8140 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8141 }
391cb864
L
8142 continue;
8143 }
391cb864 8144
978c4450 8145 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8146 {
d1f5c6e3
L
8147 if (entry)
8148 {
57028622
NC
8149 static unsigned num_errs = 0;
8150
8151 if (num_errs ++ < 10)
8152 {
8153 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8154 entry, i,
978c4450 8155 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8156 if (num_errs == 10)
8157 warn (_("Further error messages about already contained group sections suppressed\n"));
8158 }
d1f5c6e3
L
8159 continue;
8160 }
8161 else
8162 {
8163 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8164 section group. We just warn it the first time
d1f5c6e3 8165 and ignore it afterwards. */
015dc7e1 8166 static bool warned = false;
d1f5c6e3
L
8167 if (!warned)
8168 {
8169 error (_("section 0 in group section [%5u]\n"),
978c4450 8170 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8171 warned = true;
d1f5c6e3
L
8172 }
8173 }
e4b17d5c
L
8174 }
8175
978c4450 8176 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8177
8178 if (do_section_groups)
8179 {
dda8d76d
NC
8180 sec = filedata->section_headers + entry;
8181 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8182 }
8183
3f5e193b 8184 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8185 g->section_index = entry;
8186 g->next = group->root;
8187 group->root = g;
f5842774
L
8188 }
8189
9db70fc3 8190 free (start);
e4b17d5c
L
8191
8192 group++;
f5842774
L
8193 }
8194 }
8195
9db70fc3
AM
8196 free (symtab);
8197 free (strtab);
015dc7e1 8198 return true;
f5842774
L
8199}
8200
28f997cf
TG
8201/* Data used to display dynamic fixups. */
8202
8203struct ia64_vms_dynfixup
8204{
625d49fc
AM
8205 uint64_t needed_ident; /* Library ident number. */
8206 uint64_t needed; /* Index in the dstrtab of the library name. */
8207 uint64_t fixup_needed; /* Index of the library. */
8208 uint64_t fixup_rela_cnt; /* Number of fixups. */
8209 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8210};
8211
8212/* Data used to display dynamic relocations. */
8213
8214struct ia64_vms_dynimgrela
8215{
625d49fc
AM
8216 uint64_t img_rela_cnt; /* Number of relocations. */
8217 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8218};
8219
8220/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8221 library). */
8222
015dc7e1 8223static bool
dda8d76d
NC
8224dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8225 struct ia64_vms_dynfixup * fixup,
8226 const char * strtab,
8227 unsigned int strtab_sz)
28f997cf 8228{
32ec8896 8229 Elf64_External_VMS_IMAGE_FIXUP * imfs;
26c527e6 8230 size_t i;
32ec8896 8231 const char * lib_name;
28f997cf 8232
978c4450
AM
8233 imfs = get_data (NULL, filedata,
8234 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8235 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8236 _("dynamic section image fixups"));
8237 if (!imfs)
015dc7e1 8238 return false;
28f997cf
TG
8239
8240 if (fixup->needed < strtab_sz)
8241 lib_name = strtab + fixup->needed;
8242 else
8243 {
26c527e6
AM
8244 warn (_("corrupt library name index of %#" PRIx64
8245 " found in dynamic entry"), fixup->needed);
28f997cf
TG
8246 lib_name = "???";
8247 }
736990c4 8248
26c527e6
AM
8249 printf (_("\nImage fixups for needed library #%" PRId64
8250 ": %s - ident: %" PRIx64 "\n"),
8251 fixup->fixup_needed, lib_name, fixup->needed_ident);
28f997cf
TG
8252 printf
8253 (_("Seg Offset Type SymVec DataType\n"));
8254
26c527e6 8255 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
28f997cf
TG
8256 {
8257 unsigned int type;
8258 const char *rtype;
8259
8260 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8261 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8262 type = BYTE_GET (imfs [i].type);
8263 rtype = elf_ia64_reloc_type (type);
8264 if (rtype == NULL)
f493c217 8265 printf ("0x%08x ", type);
28f997cf 8266 else
f493c217 8267 printf ("%-32s ", rtype);
28f997cf
TG
8268 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8269 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8270 }
8271
8272 free (imfs);
015dc7e1 8273 return true;
28f997cf
TG
8274}
8275
8276/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8277
015dc7e1 8278static bool
dda8d76d 8279dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8280{
8281 Elf64_External_VMS_IMAGE_RELA *imrs;
26c527e6 8282 size_t i;
28f997cf 8283
978c4450
AM
8284 imrs = get_data (NULL, filedata,
8285 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8286 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8287 _("dynamic section image relocations"));
28f997cf 8288 if (!imrs)
015dc7e1 8289 return false;
28f997cf
TG
8290
8291 printf (_("\nImage relocs\n"));
8292 printf
8293 (_("Seg Offset Type Addend Seg Sym Off\n"));
8294
26c527e6 8295 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
28f997cf
TG
8296 {
8297 unsigned int type;
8298 const char *rtype;
8299
8300 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8301 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8302 type = BYTE_GET (imrs [i].type);
8303 rtype = elf_ia64_reloc_type (type);
8304 if (rtype == NULL)
8305 printf ("0x%08x ", type);
8306 else
8307 printf ("%-31s ", rtype);
8308 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8309 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8310 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8311 }
8312
8313 free (imrs);
015dc7e1 8314 return true;
28f997cf
TG
8315}
8316
8317/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8318
015dc7e1 8319static bool
dda8d76d 8320process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8321{
8322 struct ia64_vms_dynfixup fixup;
8323 struct ia64_vms_dynimgrela imgrela;
8324 Elf_Internal_Dyn *entry;
625d49fc
AM
8325 uint64_t strtab_off = 0;
8326 uint64_t strtab_sz = 0;
28f997cf 8327 char *strtab = NULL;
015dc7e1 8328 bool res = true;
28f997cf
TG
8329
8330 memset (&fixup, 0, sizeof (fixup));
8331 memset (&imgrela, 0, sizeof (imgrela));
8332
8333 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8334 for (entry = filedata->dynamic_section;
8335 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8336 entry++)
8337 {
8338 switch (entry->d_tag)
8339 {
8340 case DT_IA_64_VMS_STRTAB_OFFSET:
8341 strtab_off = entry->d_un.d_val;
8342 break;
8343 case DT_STRSZ:
8344 strtab_sz = entry->d_un.d_val;
8345 if (strtab == NULL)
978c4450
AM
8346 strtab = get_data (NULL, filedata,
8347 filedata->dynamic_addr + strtab_off,
28f997cf 8348 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8349 if (strtab == NULL)
8350 strtab_sz = 0;
28f997cf
TG
8351 break;
8352
8353 case DT_IA_64_VMS_NEEDED_IDENT:
8354 fixup.needed_ident = entry->d_un.d_val;
8355 break;
8356 case DT_NEEDED:
8357 fixup.needed = entry->d_un.d_val;
8358 break;
8359 case DT_IA_64_VMS_FIXUP_NEEDED:
8360 fixup.fixup_needed = entry->d_un.d_val;
8361 break;
8362 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8363 fixup.fixup_rela_cnt = entry->d_un.d_val;
8364 break;
8365 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8366 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8367 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8368 res = false;
28f997cf 8369 break;
28f997cf
TG
8370 case DT_IA_64_VMS_IMG_RELA_CNT:
8371 imgrela.img_rela_cnt = entry->d_un.d_val;
8372 break;
8373 case DT_IA_64_VMS_IMG_RELA_OFF:
8374 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8375 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8376 res = false;
28f997cf
TG
8377 break;
8378
8379 default:
8380 break;
8381 }
8382 }
8383
9db70fc3 8384 free (strtab);
28f997cf
TG
8385
8386 return res;
8387}
8388
85b1c36d 8389static struct
566b0d53 8390{
2cf0635d 8391 const char * name;
566b0d53
L
8392 int reloc;
8393 int size;
a7fd1186 8394 relocation_type rel_type;
32ec8896
NC
8395}
8396 dynamic_relocations [] =
566b0d53 8397{
a7fd1186
FS
8398 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8399 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8400 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8401 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8402};
8403
252b5132 8404/* Process the reloc section. */
18bd398b 8405
015dc7e1 8406static bool
dda8d76d 8407process_relocs (Filedata * filedata)
252b5132 8408{
26c527e6
AM
8409 uint64_t rel_size;
8410 uint64_t rel_offset;
252b5132 8411
252b5132 8412 if (!do_reloc)
015dc7e1 8413 return true;
252b5132
RH
8414
8415 if (do_using_dynamic)
8416 {
a7fd1186 8417 relocation_type rel_type;
2cf0635d 8418 const char * name;
015dc7e1 8419 bool has_dynamic_reloc;
566b0d53 8420 unsigned int i;
0de14b54 8421
015dc7e1 8422 has_dynamic_reloc = false;
252b5132 8423
566b0d53 8424 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8425 {
a7fd1186 8426 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8427 name = dynamic_relocations [i].name;
978c4450
AM
8428 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8429 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8430
32ec8896 8431 if (rel_size)
015dc7e1 8432 has_dynamic_reloc = true;
566b0d53 8433
a7fd1186 8434 if (rel_type == reltype_unknown)
aa903cfb 8435 {
566b0d53 8436 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8437 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8438 {
8439 case DT_REL:
a7fd1186 8440 rel_type = reltype_rel;
566b0d53
L
8441 break;
8442 case DT_RELA:
a7fd1186 8443 rel_type = reltype_rela;
566b0d53
L
8444 break;
8445 }
aa903cfb 8446 }
252b5132 8447
566b0d53
L
8448 if (rel_size)
8449 {
ca0e11aa
NC
8450 if (filedata->is_separate)
8451 printf
26c527e6
AM
8452 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
8453 " contains %" PRId64 " bytes:\n"),
ca0e11aa
NC
8454 filedata->file_name, name, rel_offset, rel_size);
8455 else
8456 printf
26c527e6
AM
8457 (_("\n'%s' relocation section at offset %#" PRIx64
8458 " contains %" PRId64 " bytes:\n"),
ca0e11aa 8459 name, rel_offset, rel_size);
252b5132 8460
dda8d76d
NC
8461 dump_relocations (filedata,
8462 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8463 rel_size,
978c4450
AM
8464 filedata->dynamic_symbols,
8465 filedata->num_dynamic_syms,
8466 filedata->dynamic_strings,
8467 filedata->dynamic_strings_length,
a7fd1186 8468 rel_type, true /* is_dynamic */);
566b0d53 8469 }
252b5132 8470 }
566b0d53 8471
dda8d76d
NC
8472 if (is_ia64_vms (filedata))
8473 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8474 has_dynamic_reloc = true;
28f997cf 8475
566b0d53 8476 if (! has_dynamic_reloc)
ca0e11aa
NC
8477 {
8478 if (filedata->is_separate)
8479 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8480 filedata->file_name);
8481 else
8482 printf (_("\nThere are no dynamic relocations in this file.\n"));
8483 }
252b5132
RH
8484 }
8485 else
8486 {
2cf0635d 8487 Elf_Internal_Shdr * section;
26c527e6 8488 size_t i;
015dc7e1 8489 bool found = false;
252b5132 8490
dda8d76d
NC
8491 for (i = 0, section = filedata->section_headers;
8492 i < filedata->file_header.e_shnum;
b34976b6 8493 i++, section++)
252b5132
RH
8494 {
8495 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8496 && section->sh_type != SHT_REL
8497 && section->sh_type != SHT_RELR)
252b5132
RH
8498 continue;
8499
8500 rel_offset = section->sh_offset;
8501 rel_size = section->sh_size;
8502
8503 if (rel_size)
8504 {
a7fd1186 8505 relocation_type rel_type;
26c527e6 8506 uint64_t num_rela;
103f02d3 8507
ca0e11aa
NC
8508 if (filedata->is_separate)
8509 printf (_("\nIn linked file '%s' relocation section "),
8510 filedata->file_name);
8511 else
8512 printf (_("\nRelocation section "));
252b5132 8513
dda8d76d 8514 if (filedata->string_table == NULL)
19936277 8515 printf ("%d", section->sh_name);
252b5132 8516 else
dda8d76d 8517 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8518
d3a49aa8 8519 num_rela = rel_size / section->sh_entsize;
26c527e6
AM
8520 printf (ngettext (" at offset %#" PRIx64
8521 " contains %" PRIu64 " entry:\n",
8522 " at offset %#" PRIx64
8523 " contains %" PRId64 " entries:\n",
d3a49aa8
AM
8524 num_rela),
8525 rel_offset, num_rela);
252b5132 8526
a7fd1186
FS
8527 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8528 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8529
4fbb74a6 8530 if (section->sh_link != 0
dda8d76d 8531 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8532 {
26c527e6
AM
8533 Elf_Internal_Shdr *symsec;
8534 Elf_Internal_Sym *symtab;
8535 uint64_t nsyms;
8536 uint64_t strtablen = 0;
8537 char *strtab = NULL;
57346661 8538
dda8d76d 8539 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8540 if (symsec->sh_type != SHT_SYMTAB
8541 && symsec->sh_type != SHT_DYNSYM)
8542 continue;
8543
28d13567
AM
8544 if (!get_symtab (filedata, symsec,
8545 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8546 continue;
252b5132 8547
dda8d76d 8548 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8549 symtab, nsyms, strtab, strtablen,
a7fd1186 8550 rel_type,
bb4d2ac2 8551 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8552 free (strtab);
d79b3d50
NC
8553 free (symtab);
8554 }
8555 else
dda8d76d 8556 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8557 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8558
015dc7e1 8559 found = true;
252b5132
RH
8560 }
8561 }
8562
8563 if (! found)
45ac8f4f
NC
8564 {
8565 /* Users sometimes forget the -D option, so try to be helpful. */
8566 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8567 {
978c4450 8568 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8569 {
ca0e11aa
NC
8570 if (filedata->is_separate)
8571 printf (_("\nThere are no static relocations in linked file '%s'."),
8572 filedata->file_name);
8573 else
8574 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8575 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8576
8577 break;
8578 }
8579 }
8580 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8581 {
8582 if (filedata->is_separate)
8583 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8584 filedata->file_name);
8585 else
8586 printf (_("\nThere are no relocations in this file.\n"));
8587 }
45ac8f4f 8588 }
252b5132
RH
8589 }
8590
015dc7e1 8591 return true;
252b5132
RH
8592}
8593
4d6ed7c8
NC
8594/* An absolute address consists of a section and an offset. If the
8595 section is NULL, the offset itself is the address, otherwise, the
8596 address equals to LOAD_ADDRESS(section) + offset. */
8597
8598struct absaddr
948f632f
DA
8599{
8600 unsigned short section;
625d49fc 8601 uint64_t offset;
948f632f 8602};
4d6ed7c8 8603
948f632f
DA
8604/* Find the nearest symbol at or below ADDR. Returns the symbol
8605 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8606
4d6ed7c8 8607static void
26c527e6
AM
8608find_symbol_for_address (Filedata *filedata,
8609 Elf_Internal_Sym *symtab,
8610 uint64_t nsyms,
8611 const char *strtab,
8612 uint64_t strtab_size,
8613 struct absaddr addr,
8614 const char **symname,
8615 uint64_t *offset)
4d6ed7c8 8616{
625d49fc 8617 uint64_t dist = 0x100000;
2cf0635d 8618 Elf_Internal_Sym * sym;
948f632f
DA
8619 Elf_Internal_Sym * beg;
8620 Elf_Internal_Sym * end;
2cf0635d 8621 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8622
0b6ae522 8623 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8624 beg = symtab;
8625 end = symtab + nsyms;
0b6ae522 8626
948f632f 8627 while (beg < end)
4d6ed7c8 8628 {
625d49fc 8629 uint64_t value;
948f632f
DA
8630
8631 sym = beg + (end - beg) / 2;
0b6ae522 8632
948f632f 8633 value = sym->st_value;
0b6ae522
DJ
8634 REMOVE_ARCH_BITS (value);
8635
948f632f 8636 if (sym->st_name != 0
4d6ed7c8 8637 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8638 && addr.offset >= value
8639 && addr.offset - value < dist)
4d6ed7c8
NC
8640 {
8641 best = sym;
0b6ae522 8642 dist = addr.offset - value;
4d6ed7c8
NC
8643 if (!dist)
8644 break;
8645 }
948f632f
DA
8646
8647 if (addr.offset < value)
8648 end = sym;
8649 else
8650 beg = sym + 1;
4d6ed7c8 8651 }
1b31d05e 8652
4d6ed7c8
NC
8653 if (best)
8654 {
57346661 8655 *symname = (best->st_name >= strtab_size
2b692964 8656 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8657 *offset = dist;
8658 return;
8659 }
1b31d05e 8660
4d6ed7c8
NC
8661 *symname = NULL;
8662 *offset = addr.offset;
8663}
8664
32ec8896 8665static /* signed */ int
948f632f
DA
8666symcmp (const void *p, const void *q)
8667{
8668 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8669 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8670
8671 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8672}
8673
8674/* Process the unwind section. */
8675
8676#include "unwind-ia64.h"
8677
8678struct ia64_unw_table_entry
8679{
8680 struct absaddr start;
8681 struct absaddr end;
8682 struct absaddr info;
8683};
8684
8685struct ia64_unw_aux_info
8686{
32ec8896 8687 struct ia64_unw_table_entry * table; /* Unwind table. */
26c527e6 8688 uint64_t table_len; /* Length of unwind table. */
32ec8896 8689 unsigned char * info; /* Unwind info. */
26c527e6 8690 uint64_t info_size; /* Size of unwind info. */
625d49fc
AM
8691 uint64_t info_addr; /* Starting address of unwind info. */
8692 uint64_t seg_base; /* Starting address of segment. */
32ec8896 8693 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 8694 uint64_t nsyms; /* Number of symbols. */
32ec8896 8695 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 8696 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 8697 char * strtab; /* The string table. */
26c527e6 8698 uint64_t strtab_size; /* Size of string table. */
948f632f
DA
8699};
8700
015dc7e1 8701static bool
dda8d76d 8702dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8703{
2cf0635d 8704 struct ia64_unw_table_entry * tp;
26c527e6 8705 size_t j, nfuns;
4d6ed7c8 8706 int in_body;
015dc7e1 8707 bool res = true;
7036c0e1 8708
948f632f
DA
8709 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8710 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8711 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8712 aux->funtab[nfuns++] = aux->symtab[j];
8713 aux->nfuns = nfuns;
8714 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8715
4d6ed7c8
NC
8716 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8717 {
625d49fc
AM
8718 uint64_t stamp;
8719 uint64_t offset;
2cf0635d
NC
8720 const unsigned char * dp;
8721 const unsigned char * head;
53774b7e 8722 const unsigned char * end;
2cf0635d 8723 const char * procname;
4d6ed7c8 8724
dda8d76d 8725 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8726 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8727
8728 fputs ("\n<", stdout);
8729
8730 if (procname)
8731 {
8732 fputs (procname, stdout);
8733
8734 if (offset)
26c527e6 8735 printf ("+%" PRIx64, offset);
4d6ed7c8
NC
8736 }
8737
8738 fputs (">: [", stdout);
8739 print_vma (tp->start.offset, PREFIX_HEX);
8740 fputc ('-', stdout);
8741 print_vma (tp->end.offset, PREFIX_HEX);
26c527e6
AM
8742 printf ("], info at +0x%" PRIx64 "\n",
8743 tp->info.offset - aux->seg_base);
4d6ed7c8 8744
53774b7e
NC
8745 /* PR 17531: file: 86232b32. */
8746 if (aux->info == NULL)
8747 continue;
8748
97c0a079
AM
8749 offset = tp->info.offset;
8750 if (tp->info.section)
8751 {
8752 if (tp->info.section >= filedata->file_header.e_shnum)
8753 {
26c527e6
AM
8754 warn (_("Invalid section %u in table entry %td\n"),
8755 tp->info.section, tp - aux->table);
015dc7e1 8756 res = false;
97c0a079
AM
8757 continue;
8758 }
8759 offset += filedata->section_headers[tp->info.section].sh_addr;
8760 }
8761 offset -= aux->info_addr;
53774b7e 8762 /* PR 17531: file: 0997b4d1. */
90679903
AM
8763 if (offset >= aux->info_size
8764 || aux->info_size - offset < 8)
53774b7e 8765 {
26c527e6
AM
8766 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
8767 tp->info.offset, tp - aux->table);
015dc7e1 8768 res = false;
53774b7e
NC
8769 continue;
8770 }
8771
97c0a079 8772 head = aux->info + offset;
a4a00738 8773 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8774
86f55779 8775 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8776 (unsigned) UNW_VER (stamp),
8777 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8778 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8779 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8780 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8781
8782 if (UNW_VER (stamp) != 1)
8783 {
2b692964 8784 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8785 continue;
8786 }
8787
8788 in_body = 0;
53774b7e
NC
8789 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8790 /* PR 17531: file: 16ceda89. */
8791 if (end > aux->info + aux->info_size)
8792 end = aux->info + aux->info_size;
8793 for (dp = head + 8; dp < end;)
b4477bc8 8794 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8795 }
948f632f
DA
8796
8797 free (aux->funtab);
32ec8896
NC
8798
8799 return res;
4d6ed7c8
NC
8800}
8801
015dc7e1 8802static bool
dda8d76d
NC
8803slurp_ia64_unwind_table (Filedata * filedata,
8804 struct ia64_unw_aux_info * aux,
8805 Elf_Internal_Shdr * sec)
4d6ed7c8 8806{
26c527e6 8807 uint64_t size, nrelas, i;
2cf0635d
NC
8808 Elf_Internal_Phdr * seg;
8809 struct ia64_unw_table_entry * tep;
8810 Elf_Internal_Shdr * relsec;
8811 Elf_Internal_Rela * rela;
8812 Elf_Internal_Rela * rp;
8813 unsigned char * table;
8814 unsigned char * tp;
8815 Elf_Internal_Sym * sym;
8816 const char * relname;
4d6ed7c8 8817
53774b7e
NC
8818 aux->table_len = 0;
8819
4d6ed7c8
NC
8820 /* First, find the starting address of the segment that includes
8821 this section: */
8822
dda8d76d 8823 if (filedata->file_header.e_phnum)
4d6ed7c8 8824 {
dda8d76d 8825 if (! get_program_headers (filedata))
015dc7e1 8826 return false;
4d6ed7c8 8827
dda8d76d
NC
8828 for (seg = filedata->program_headers;
8829 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8830 ++seg)
4d6ed7c8
NC
8831 {
8832 if (seg->p_type != PT_LOAD)
8833 continue;
8834
8835 if (sec->sh_addr >= seg->p_vaddr
8836 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8837 {
8838 aux->seg_base = seg->p_vaddr;
8839 break;
8840 }
8841 }
4d6ed7c8
NC
8842 }
8843
8844 /* Second, build the unwind table from the contents of the unwind section: */
8845 size = sec->sh_size;
dda8d76d 8846 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8847 _("unwind table"));
a6e9f9df 8848 if (!table)
015dc7e1 8849 return false;
4d6ed7c8 8850
53774b7e 8851 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8852 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8853 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8854 tep = aux->table;
53774b7e
NC
8855
8856 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8857 {
8858 tep->start.section = SHN_UNDEF;
8859 tep->end.section = SHN_UNDEF;
8860 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8861 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8862 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8863 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8864 tep->start.offset += aux->seg_base;
8865 tep->end.offset += aux->seg_base;
8866 tep->info.offset += aux->seg_base;
8867 }
8868 free (table);
8869
41e92641 8870 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8871 for (relsec = filedata->section_headers;
8872 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8873 ++relsec)
8874 {
8875 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8876 || relsec->sh_info >= filedata->file_header.e_shnum
8877 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8878 continue;
8879
dda8d76d 8880 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8881 & rela, & nrelas))
53774b7e
NC
8882 {
8883 free (aux->table);
8884 aux->table = NULL;
8885 aux->table_len = 0;
015dc7e1 8886 return false;
53774b7e 8887 }
4d6ed7c8
NC
8888
8889 for (rp = rela; rp < rela + nrelas; ++rp)
8890 {
4770fb94 8891 unsigned int sym_ndx;
726bd37d
AM
8892 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8893 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8894
82b1b41b
NC
8895 /* PR 17531: file: 9fa67536. */
8896 if (relname == NULL)
8897 {
726bd37d 8898 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8899 continue;
8900 }
948f632f 8901
24d127aa 8902 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8903 {
82b1b41b 8904 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8905 continue;
8906 }
8907
89fac5e3 8908 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8909
53774b7e
NC
8910 /* PR 17531: file: 5bc8d9bf. */
8911 if (i >= aux->table_len)
8912 {
26c527e6
AM
8913 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
8914 i);
53774b7e
NC
8915 continue;
8916 }
8917
4770fb94
AM
8918 sym_ndx = get_reloc_symindex (rp->r_info);
8919 if (sym_ndx >= aux->nsyms)
8920 {
8921 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8922 sym_ndx);
8923 continue;
8924 }
8925 sym = aux->symtab + sym_ndx;
8926
53774b7e 8927 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8928 {
8929 case 0:
8930 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8931 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8932 break;
8933 case 1:
8934 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8935 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8936 break;
8937 case 2:
8938 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8939 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8940 break;
8941 default:
8942 break;
8943 }
8944 }
8945
8946 free (rela);
8947 }
8948
015dc7e1 8949 return true;
4d6ed7c8
NC
8950}
8951
015dc7e1 8952static bool
dda8d76d 8953ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8954{
2cf0635d
NC
8955 Elf_Internal_Shdr * sec;
8956 Elf_Internal_Shdr * unwsec = NULL;
26c527e6 8957 uint64_t i, unwcount = 0, unwstart = 0;
57346661 8958 struct ia64_unw_aux_info aux;
015dc7e1 8959 bool res = true;
f1467e33 8960
4d6ed7c8
NC
8961 memset (& aux, 0, sizeof (aux));
8962
dda8d76d 8963 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8964 {
28d13567 8965 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8966 {
28d13567 8967 if (aux.symtab)
4082ef84 8968 {
28d13567
AM
8969 error (_("Multiple symbol tables encountered\n"));
8970 free (aux.symtab);
8971 aux.symtab = NULL;
4082ef84 8972 free (aux.strtab);
28d13567 8973 aux.strtab = NULL;
4082ef84 8974 }
28d13567
AM
8975 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8976 &aux.strtab, &aux.strtab_size))
015dc7e1 8977 return false;
4d6ed7c8
NC
8978 }
8979 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8980 unwcount++;
8981 }
8982
8983 if (!unwcount)
8984 printf (_("\nThere are no unwind sections in this file.\n"));
8985
8986 while (unwcount-- > 0)
8987 {
84714f86 8988 const char *suffix;
579f31ac
JJ
8989 size_t len, len2;
8990
dda8d76d
NC
8991 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8992 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8993 if (sec->sh_type == SHT_IA_64_UNWIND)
8994 {
8995 unwsec = sec;
8996 break;
8997 }
4082ef84
NC
8998 /* We have already counted the number of SHT_IA64_UNWIND
8999 sections so the loop above should never fail. */
9000 assert (unwsec != NULL);
579f31ac
JJ
9001
9002 unwstart = i + 1;
9003 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9004
e4b17d5c
L
9005 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9006 {
9007 /* We need to find which section group it is in. */
4082ef84 9008 struct group_list * g;
e4b17d5c 9009
978c4450
AM
9010 if (filedata->section_headers_groups == NULL
9011 || filedata->section_headers_groups[i] == NULL)
dda8d76d 9012 i = filedata->file_header.e_shnum;
4082ef84 9013 else
e4b17d5c 9014 {
978c4450 9015 g = filedata->section_headers_groups[i]->root;
18bd398b 9016
4082ef84
NC
9017 for (; g != NULL; g = g->next)
9018 {
dda8d76d 9019 sec = filedata->section_headers + g->section_index;
e4b17d5c 9020
84714f86
AM
9021 if (section_name_valid (filedata, sec)
9022 && streq (section_name (filedata, sec),
9023 ELF_STRING_ia64_unwind_info))
4082ef84
NC
9024 break;
9025 }
9026
9027 if (g == NULL)
dda8d76d 9028 i = filedata->file_header.e_shnum;
4082ef84 9029 }
e4b17d5c 9030 }
84714f86
AM
9031 else if (section_name_valid (filedata, unwsec)
9032 && startswith (section_name (filedata, unwsec),
e9b095a5 9033 ELF_STRING_ia64_unwind_once))
579f31ac 9034 {
18bd398b 9035 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 9036 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 9037 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9038 for (i = 0, sec = filedata->section_headers;
9039 i < filedata->file_header.e_shnum;
579f31ac 9040 ++i, ++sec)
84714f86
AM
9041 if (section_name_valid (filedata, sec)
9042 && startswith (section_name (filedata, sec),
e9b095a5 9043 ELF_STRING_ia64_unwind_info_once)
84714f86 9044 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9045 break;
9046 }
9047 else
9048 {
9049 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 9050 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
9051 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9052 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9053 suffix = "";
84714f86
AM
9054 if (section_name_valid (filedata, unwsec)
9055 && startswith (section_name (filedata, unwsec),
9056 ELF_STRING_ia64_unwind))
9057 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9058 for (i = 0, sec = filedata->section_headers;
9059 i < filedata->file_header.e_shnum;
579f31ac 9060 ++i, ++sec)
84714f86
AM
9061 if (section_name_valid (filedata, sec)
9062 && startswith (section_name (filedata, sec),
9063 ELF_STRING_ia64_unwind_info)
9064 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9065 break;
9066 }
9067
dda8d76d 9068 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
9069 {
9070 printf (_("\nCould not find unwind info section for "));
9071
dda8d76d 9072 if (filedata->string_table == NULL)
579f31ac
JJ
9073 printf ("%d", unwsec->sh_name);
9074 else
dda8d76d 9075 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9076 }
9077 else
4d6ed7c8 9078 {
4d6ed7c8 9079 aux.info_addr = sec->sh_addr;
dda8d76d 9080 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9081 sec->sh_size,
9082 _("unwind info"));
59245841 9083 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9084
579f31ac 9085 printf (_("\nUnwind section "));
4d6ed7c8 9086
dda8d76d 9087 if (filedata->string_table == NULL)
579f31ac
JJ
9088 printf ("%d", unwsec->sh_name);
9089 else
dda8d76d 9090 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9091
26c527e6
AM
9092 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9093 unwsec->sh_offset,
9094 unwsec->sh_size / (3 * eh_addr_size));
4d6ed7c8 9095
dda8d76d 9096 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9097 && aux.table_len > 0)
dda8d76d 9098 dump_ia64_unwind (filedata, & aux);
579f31ac 9099
9db70fc3
AM
9100 free ((char *) aux.table);
9101 free ((char *) aux.info);
579f31ac
JJ
9102 aux.table = NULL;
9103 aux.info = NULL;
9104 }
4d6ed7c8 9105 }
4d6ed7c8 9106
9db70fc3
AM
9107 free (aux.symtab);
9108 free ((char *) aux.strtab);
32ec8896
NC
9109
9110 return res;
4d6ed7c8
NC
9111}
9112
3f5e193b 9113struct hppa_unw_table_entry
32ec8896
NC
9114{
9115 struct absaddr start;
9116 struct absaddr end;
9117 unsigned int Cannot_unwind:1; /* 0 */
9118 unsigned int Millicode:1; /* 1 */
9119 unsigned int Millicode_save_sr0:1; /* 2 */
9120 unsigned int Region_description:2; /* 3..4 */
9121 unsigned int reserved1:1; /* 5 */
9122 unsigned int Entry_SR:1; /* 6 */
9123 unsigned int Entry_FR:4; /* Number saved 7..10 */
9124 unsigned int Entry_GR:5; /* Number saved 11..15 */
9125 unsigned int Args_stored:1; /* 16 */
9126 unsigned int Variable_Frame:1; /* 17 */
9127 unsigned int Separate_Package_Body:1; /* 18 */
9128 unsigned int Frame_Extension_Millicode:1; /* 19 */
9129 unsigned int Stack_Overflow_Check:1; /* 20 */
9130 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9131 unsigned int Ada_Region:1; /* 22 */
9132 unsigned int cxx_info:1; /* 23 */
9133 unsigned int cxx_try_catch:1; /* 24 */
9134 unsigned int sched_entry_seq:1; /* 25 */
9135 unsigned int reserved2:1; /* 26 */
9136 unsigned int Save_SP:1; /* 27 */
9137 unsigned int Save_RP:1; /* 28 */
9138 unsigned int Save_MRP_in_frame:1; /* 29 */
9139 unsigned int extn_ptr_defined:1; /* 30 */
9140 unsigned int Cleanup_defined:1; /* 31 */
9141
9142 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9143 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9144 unsigned int Large_frame:1; /* 2 */
9145 unsigned int Pseudo_SP_Set:1; /* 3 */
9146 unsigned int reserved4:1; /* 4 */
9147 unsigned int Total_frame_size:27; /* 5..31 */
9148};
3f5e193b 9149
57346661 9150struct hppa_unw_aux_info
948f632f 9151{
32ec8896 9152 struct hppa_unw_table_entry * table; /* Unwind table. */
26c527e6 9153 uint64_t table_len; /* Length of unwind table. */
625d49fc 9154 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9155 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9156 uint64_t nsyms; /* Number of symbols. */
32ec8896 9157 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9158 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9159 char * strtab; /* The string table. */
26c527e6 9160 uint64_t strtab_size; /* Size of string table. */
948f632f 9161};
57346661 9162
015dc7e1 9163static bool
dda8d76d 9164dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9165{
2cf0635d 9166 struct hppa_unw_table_entry * tp;
26c527e6 9167 uint64_t j, nfuns;
015dc7e1 9168 bool res = true;
948f632f
DA
9169
9170 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9171 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9172 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9173 aux->funtab[nfuns++] = aux->symtab[j];
9174 aux->nfuns = nfuns;
9175 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9176
57346661
AM
9177 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9178 {
625d49fc 9179 uint64_t offset;
2cf0635d 9180 const char * procname;
57346661 9181
dda8d76d 9182 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9183 aux->strtab_size, tp->start, &procname,
9184 &offset);
9185
9186 fputs ("\n<", stdout);
9187
9188 if (procname)
9189 {
9190 fputs (procname, stdout);
9191
9192 if (offset)
26c527e6 9193 printf ("+%" PRIx64, offset);
57346661
AM
9194 }
9195
9196 fputs (">: [", stdout);
9197 print_vma (tp->start.offset, PREFIX_HEX);
9198 fputc ('-', stdout);
9199 print_vma (tp->end.offset, PREFIX_HEX);
9200 printf ("]\n\t");
9201
18bd398b
NC
9202#define PF(_m) if (tp->_m) printf (#_m " ");
9203#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9204 PF(Cannot_unwind);
9205 PF(Millicode);
9206 PF(Millicode_save_sr0);
18bd398b 9207 /* PV(Region_description); */
57346661
AM
9208 PF(Entry_SR);
9209 PV(Entry_FR);
9210 PV(Entry_GR);
9211 PF(Args_stored);
9212 PF(Variable_Frame);
9213 PF(Separate_Package_Body);
9214 PF(Frame_Extension_Millicode);
9215 PF(Stack_Overflow_Check);
9216 PF(Two_Instruction_SP_Increment);
9217 PF(Ada_Region);
9218 PF(cxx_info);
9219 PF(cxx_try_catch);
9220 PF(sched_entry_seq);
9221 PF(Save_SP);
9222 PF(Save_RP);
9223 PF(Save_MRP_in_frame);
9224 PF(extn_ptr_defined);
9225 PF(Cleanup_defined);
9226 PF(MPE_XL_interrupt_marker);
9227 PF(HP_UX_interrupt_marker);
9228 PF(Large_frame);
9229 PF(Pseudo_SP_Set);
9230 PV(Total_frame_size);
9231#undef PF
9232#undef PV
9233 }
9234
18bd398b 9235 printf ("\n");
948f632f
DA
9236
9237 free (aux->funtab);
32ec8896
NC
9238
9239 return res;
57346661
AM
9240}
9241
015dc7e1 9242static bool
dda8d76d
NC
9243slurp_hppa_unwind_table (Filedata * filedata,
9244 struct hppa_unw_aux_info * aux,
9245 Elf_Internal_Shdr * sec)
57346661 9246{
26c527e6 9247 uint64_t size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9248 Elf_Internal_Phdr * seg;
9249 struct hppa_unw_table_entry * tep;
9250 Elf_Internal_Shdr * relsec;
9251 Elf_Internal_Rela * rela;
9252 Elf_Internal_Rela * rp;
9253 unsigned char * table;
9254 unsigned char * tp;
9255 Elf_Internal_Sym * sym;
9256 const char * relname;
57346661 9257
57346661
AM
9258 /* First, find the starting address of the segment that includes
9259 this section. */
dda8d76d 9260 if (filedata->file_header.e_phnum)
57346661 9261 {
dda8d76d 9262 if (! get_program_headers (filedata))
015dc7e1 9263 return false;
57346661 9264
dda8d76d
NC
9265 for (seg = filedata->program_headers;
9266 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9267 ++seg)
9268 {
9269 if (seg->p_type != PT_LOAD)
9270 continue;
9271
9272 if (sec->sh_addr >= seg->p_vaddr
9273 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9274 {
9275 aux->seg_base = seg->p_vaddr;
9276 break;
9277 }
9278 }
9279 }
9280
9281 /* Second, build the unwind table from the contents of the unwind
9282 section. */
9283 size = sec->sh_size;
dda8d76d 9284 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9285 _("unwind table"));
57346661 9286 if (!table)
015dc7e1 9287 return false;
57346661 9288
1c0751b2
DA
9289 unw_ent_size = 16;
9290 nentries = size / unw_ent_size;
9291 size = unw_ent_size * nentries;
57346661 9292
e3fdc001 9293 aux->table_len = nentries;
3f5e193b
NC
9294 tep = aux->table = (struct hppa_unw_table_entry *)
9295 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9296
1c0751b2 9297 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9298 {
9299 unsigned int tmp1, tmp2;
9300
9301 tep->start.section = SHN_UNDEF;
9302 tep->end.section = SHN_UNDEF;
9303
1c0751b2
DA
9304 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9305 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9306 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9307 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9308
9309 tep->start.offset += aux->seg_base;
9310 tep->end.offset += aux->seg_base;
57346661
AM
9311
9312 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9313 tep->Millicode = (tmp1 >> 30) & 0x1;
9314 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9315 tep->Region_description = (tmp1 >> 27) & 0x3;
9316 tep->reserved1 = (tmp1 >> 26) & 0x1;
9317 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9318 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9319 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9320 tep->Args_stored = (tmp1 >> 15) & 0x1;
9321 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9322 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9323 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9324 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9325 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9326 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9327 tep->cxx_info = (tmp1 >> 8) & 0x1;
9328 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9329 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9330 tep->reserved2 = (tmp1 >> 5) & 0x1;
9331 tep->Save_SP = (tmp1 >> 4) & 0x1;
9332 tep->Save_RP = (tmp1 >> 3) & 0x1;
9333 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9334 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9335 tep->Cleanup_defined = tmp1 & 0x1;
9336
9337 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9338 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9339 tep->Large_frame = (tmp2 >> 29) & 0x1;
9340 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9341 tep->reserved4 = (tmp2 >> 27) & 0x1;
9342 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9343 }
9344 free (table);
9345
9346 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9347 for (relsec = filedata->section_headers;
9348 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9349 ++relsec)
9350 {
9351 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9352 || relsec->sh_info >= filedata->file_header.e_shnum
9353 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9354 continue;
9355
dda8d76d 9356 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9357 & rela, & nrelas))
015dc7e1 9358 return false;
57346661
AM
9359
9360 for (rp = rela; rp < rela + nrelas; ++rp)
9361 {
4770fb94 9362 unsigned int sym_ndx;
726bd37d
AM
9363 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9364 relname = elf_hppa_reloc_type (r_type);
57346661 9365
726bd37d
AM
9366 if (relname == NULL)
9367 {
9368 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9369 continue;
9370 }
9371
57346661 9372 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9373 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9374 {
726bd37d 9375 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9376 continue;
9377 }
9378
9379 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9380 if (i >= aux->table_len)
9381 {
26c527e6
AM
9382 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9383 i);
726bd37d
AM
9384 continue;
9385 }
57346661 9386
4770fb94
AM
9387 sym_ndx = get_reloc_symindex (rp->r_info);
9388 if (sym_ndx >= aux->nsyms)
9389 {
9390 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9391 sym_ndx);
9392 continue;
9393 }
9394 sym = aux->symtab + sym_ndx;
9395
43f6cd05 9396 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9397 {
9398 case 0:
9399 aux->table[i].start.section = sym->st_shndx;
1e456d54 9400 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9401 break;
9402 case 1:
9403 aux->table[i].end.section = sym->st_shndx;
1e456d54 9404 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9405 break;
9406 default:
9407 break;
9408 }
9409 }
9410
9411 free (rela);
9412 }
9413
015dc7e1 9414 return true;
57346661
AM
9415}
9416
015dc7e1 9417static bool
dda8d76d 9418hppa_process_unwind (Filedata * filedata)
57346661 9419{
57346661 9420 struct hppa_unw_aux_info aux;
2cf0635d 9421 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9422 Elf_Internal_Shdr * sec;
26c527e6 9423 size_t i;
015dc7e1 9424 bool res = true;
57346661 9425
dda8d76d 9426 if (filedata->string_table == NULL)
015dc7e1 9427 return false;
1b31d05e
NC
9428
9429 memset (& aux, 0, sizeof (aux));
57346661 9430
dda8d76d 9431 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9432 {
28d13567 9433 if (sec->sh_type == SHT_SYMTAB)
57346661 9434 {
28d13567 9435 if (aux.symtab)
4082ef84 9436 {
28d13567
AM
9437 error (_("Multiple symbol tables encountered\n"));
9438 free (aux.symtab);
9439 aux.symtab = NULL;
4082ef84 9440 free (aux.strtab);
28d13567 9441 aux.strtab = NULL;
4082ef84 9442 }
28d13567
AM
9443 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9444 &aux.strtab, &aux.strtab_size))
015dc7e1 9445 return false;
57346661 9446 }
84714f86
AM
9447 else if (section_name_valid (filedata, sec)
9448 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9449 unwsec = sec;
9450 }
9451
9452 if (!unwsec)
9453 printf (_("\nThere are no unwind sections in this file.\n"));
9454
dda8d76d 9455 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9456 {
84714f86
AM
9457 if (section_name_valid (filedata, sec)
9458 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9459 {
26c527e6 9460 uint64_t num_unwind = sec->sh_size / 16;
dda8d76d 9461
26c527e6
AM
9462 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
9463 "contains %" PRIu64 " entry:\n",
9464 "\nUnwind section '%s' at offset %#" PRIx64 " "
9465 "contains %" PRIu64 " entries:\n",
d3a49aa8 9466 num_unwind),
dda8d76d 9467 printable_section_name (filedata, sec),
26c527e6 9468 sec->sh_offset,
d3a49aa8 9469 num_unwind);
57346661 9470
dda8d76d 9471 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9472 res = false;
66b09c7e
S
9473
9474 if (res && aux.table_len > 0)
32ec8896 9475 {
dda8d76d 9476 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9477 res = false;
32ec8896 9478 }
57346661 9479
9db70fc3 9480 free ((char *) aux.table);
57346661
AM
9481 aux.table = NULL;
9482 }
9483 }
9484
9db70fc3
AM
9485 free (aux.symtab);
9486 free ((char *) aux.strtab);
32ec8896
NC
9487
9488 return res;
57346661
AM
9489}
9490
0b6ae522
DJ
9491struct arm_section
9492{
a734115a
NC
9493 unsigned char * data; /* The unwind data. */
9494 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9495 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
26c527e6 9496 uint64_t nrelas; /* The number of relocations. */
a734115a
NC
9497 unsigned int rel_type; /* REL or RELA ? */
9498 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9499};
9500
9501struct arm_unw_aux_info
9502{
dda8d76d 9503 Filedata * filedata; /* The file containing the unwind sections. */
a734115a 9504 Elf_Internal_Sym * symtab; /* The file's symbol table. */
26c527e6 9505 uint64_t nsyms; /* Number of symbols. */
948f632f 9506 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9507 uint64_t nfuns; /* Number of these symbols. */
a734115a 9508 char * strtab; /* The file's string table. */
26c527e6 9509 uint64_t strtab_size; /* Size of string table. */
0b6ae522
DJ
9510};
9511
9512static const char *
dda8d76d
NC
9513arm_print_vma_and_name (Filedata * filedata,
9514 struct arm_unw_aux_info * aux,
625d49fc 9515 uint64_t fn,
dda8d76d 9516 struct absaddr addr)
0b6ae522
DJ
9517{
9518 const char *procname;
625d49fc 9519 uint64_t sym_offset;
0b6ae522
DJ
9520
9521 if (addr.section == SHN_UNDEF)
9522 addr.offset = fn;
9523
dda8d76d 9524 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9525 aux->strtab_size, addr, &procname,
9526 &sym_offset);
9527
9528 print_vma (fn, PREFIX_HEX);
9529
9530 if (procname)
9531 {
9532 fputs (" <", stdout);
9533 fputs (procname, stdout);
9534
9535 if (sym_offset)
26c527e6 9536 printf ("+0x%" PRIx64, sym_offset);
0b6ae522
DJ
9537 fputc ('>', stdout);
9538 }
9539
9540 return procname;
9541}
9542
9543static void
9544arm_free_section (struct arm_section *arm_sec)
9545{
9db70fc3
AM
9546 free (arm_sec->data);
9547 free (arm_sec->rela);
0b6ae522
DJ
9548}
9549
a734115a
NC
9550/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9551 cached section and install SEC instead.
9552 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9553 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9554 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9555 relocation's offset in ADDR.
1b31d05e
NC
9556 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9557 into the string table of the symbol associated with the reloc. If no
9558 reloc was applied store -1 there.
9559 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9560
015dc7e1 9561static bool
dda8d76d
NC
9562get_unwind_section_word (Filedata * filedata,
9563 struct arm_unw_aux_info * aux,
1b31d05e
NC
9564 struct arm_section * arm_sec,
9565 Elf_Internal_Shdr * sec,
625d49fc 9566 uint64_t word_offset,
1b31d05e
NC
9567 unsigned int * wordp,
9568 struct absaddr * addr,
625d49fc 9569 uint64_t * sym_name)
0b6ae522
DJ
9570{
9571 Elf_Internal_Rela *rp;
9572 Elf_Internal_Sym *sym;
9573 const char * relname;
9574 unsigned int word;
015dc7e1 9575 bool wrapped;
0b6ae522 9576
e0a31db1 9577 if (sec == NULL || arm_sec == NULL)
015dc7e1 9578 return false;
e0a31db1 9579
0b6ae522
DJ
9580 addr->section = SHN_UNDEF;
9581 addr->offset = 0;
9582
1b31d05e 9583 if (sym_name != NULL)
625d49fc 9584 *sym_name = (uint64_t) -1;
1b31d05e 9585
a734115a 9586 /* If necessary, update the section cache. */
0b6ae522
DJ
9587 if (sec != arm_sec->sec)
9588 {
9589 Elf_Internal_Shdr *relsec;
9590
9591 arm_free_section (arm_sec);
9592
9593 arm_sec->sec = sec;
dda8d76d 9594 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9595 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9596 arm_sec->rela = NULL;
9597 arm_sec->nrelas = 0;
9598
dda8d76d
NC
9599 for (relsec = filedata->section_headers;
9600 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9601 ++relsec)
9602 {
dda8d76d
NC
9603 if (relsec->sh_info >= filedata->file_header.e_shnum
9604 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9605 /* PR 15745: Check the section type as well. */
9606 || (relsec->sh_type != SHT_REL
9607 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9608 continue;
9609
a734115a 9610 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9611 if (relsec->sh_type == SHT_REL)
9612 {
dda8d76d 9613 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9614 relsec->sh_size,
9615 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9616 return false;
0b6ae522 9617 }
1ae40aa4 9618 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9619 {
dda8d76d 9620 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9621 relsec->sh_size,
9622 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9623 return false;
0b6ae522 9624 }
1ae40aa4 9625 break;
0b6ae522
DJ
9626 }
9627
9628 arm_sec->next_rela = arm_sec->rela;
9629 }
9630
a734115a 9631 /* If there is no unwind data we can do nothing. */
0b6ae522 9632 if (arm_sec->data == NULL)
015dc7e1 9633 return false;
0b6ae522 9634
e0a31db1 9635 /* If the offset is invalid then fail. */
f32ba729
NC
9636 if (/* PR 21343 *//* PR 18879 */
9637 sec->sh_size < 4
625d49fc 9638 || word_offset > sec->sh_size - 4)
015dc7e1 9639 return false;
e0a31db1 9640
a734115a 9641 /* Get the word at the required offset. */
0b6ae522
DJ
9642 word = byte_get (arm_sec->data + word_offset, 4);
9643
0eff7165
NC
9644 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9645 if (arm_sec->rela == NULL)
9646 {
9647 * wordp = word;
015dc7e1 9648 return true;
0eff7165
NC
9649 }
9650
a734115a 9651 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9652 wrapped = false;
0b6ae522
DJ
9653 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9654 {
625d49fc 9655 uint64_t prelval, offset;
0b6ae522
DJ
9656
9657 if (rp->r_offset > word_offset && !wrapped)
9658 {
9659 rp = arm_sec->rela;
015dc7e1 9660 wrapped = true;
0b6ae522
DJ
9661 }
9662 if (rp->r_offset > word_offset)
9663 break;
9664
9665 if (rp->r_offset & 3)
9666 {
26c527e6
AM
9667 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
9668 rp->r_offset);
0b6ae522
DJ
9669 continue;
9670 }
9671
9672 if (rp->r_offset < word_offset)
9673 continue;
9674
74e1a04b
NC
9675 /* PR 17531: file: 027-161405-0.004 */
9676 if (aux->symtab == NULL)
9677 continue;
9678
0b6ae522
DJ
9679 if (arm_sec->rel_type == SHT_REL)
9680 {
9681 offset = word & 0x7fffffff;
9682 if (offset & 0x40000000)
625d49fc 9683 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 9684 }
a734115a 9685 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9686 offset = rp->r_addend;
a734115a 9687 else
74e1a04b
NC
9688 {
9689 error (_("Unknown section relocation type %d encountered\n"),
9690 arm_sec->rel_type);
9691 break;
9692 }
0b6ae522 9693
071436c6
NC
9694 /* PR 17531 file: 027-1241568-0.004. */
9695 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9696 {
26c527e6
AM
9697 error (_("Bad symbol index in unwind relocation "
9698 "(%" PRIu64 " > %" PRIu64 ")\n"),
9699 ELF32_R_SYM (rp->r_info), aux->nsyms);
071436c6
NC
9700 break;
9701 }
9702
9703 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9704 offset += sym->st_value;
9705 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9706
a734115a 9707 /* Check that we are processing the expected reloc type. */
dda8d76d 9708 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9709 {
9710 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9711 if (relname == NULL)
9712 {
9713 warn (_("Skipping unknown ARM relocation type: %d\n"),
9714 (int) ELF32_R_TYPE (rp->r_info));
9715 continue;
9716 }
a734115a
NC
9717
9718 if (streq (relname, "R_ARM_NONE"))
9719 continue;
0b4362b0 9720
a734115a
NC
9721 if (! streq (relname, "R_ARM_PREL31"))
9722 {
071436c6 9723 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9724 continue;
9725 }
9726 }
dda8d76d 9727 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9728 {
9729 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9730 if (relname == NULL)
9731 {
9732 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9733 (int) ELF32_R_TYPE (rp->r_info));
9734 continue;
9735 }
0b4362b0 9736
a734115a
NC
9737 if (streq (relname, "R_C6000_NONE"))
9738 continue;
9739
9740 if (! streq (relname, "R_C6000_PREL31"))
9741 {
071436c6 9742 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9743 continue;
9744 }
9745
9746 prelval >>= 1;
9747 }
9748 else
74e1a04b
NC
9749 {
9750 /* This function currently only supports ARM and TI unwinders. */
9751 warn (_("Only TI and ARM unwinders are currently supported\n"));
9752 break;
9753 }
fa197c1c 9754
625d49fc 9755 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
9756 addr->section = sym->st_shndx;
9757 addr->offset = offset;
74e1a04b 9758
1b31d05e
NC
9759 if (sym_name)
9760 * sym_name = sym->st_name;
0b6ae522
DJ
9761 break;
9762 }
9763
9764 *wordp = word;
9765 arm_sec->next_rela = rp;
9766
015dc7e1 9767 return true;
0b6ae522
DJ
9768}
9769
a734115a
NC
9770static const char *tic6x_unwind_regnames[16] =
9771{
0b4362b0
RM
9772 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9773 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9774 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9775};
fa197c1c 9776
0b6ae522 9777static void
fa197c1c 9778decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9779{
fa197c1c
PB
9780 int i;
9781
9782 for (i = 12; mask; mask >>= 1, i--)
9783 {
9784 if (mask & 1)
9785 {
9786 fputs (tic6x_unwind_regnames[i], stdout);
9787 if (mask > 1)
9788 fputs (", ", stdout);
9789 }
9790 }
9791}
0b6ae522
DJ
9792
9793#define ADVANCE \
9794 if (remaining == 0 && more_words) \
9795 { \
9796 data_offset += 4; \
dda8d76d 9797 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9798 data_offset, & word, & addr, NULL)) \
015dc7e1 9799 return false; \
0b6ae522
DJ
9800 remaining = 4; \
9801 more_words--; \
9802 } \
9803
9804#define GET_OP(OP) \
9805 ADVANCE; \
9806 if (remaining) \
9807 { \
9808 remaining--; \
9809 (OP) = word >> 24; \
9810 word <<= 8; \
9811 } \
9812 else \
9813 { \
2b692964 9814 printf (_("[Truncated opcode]\n")); \
015dc7e1 9815 return false; \
0b6ae522 9816 } \
cc5914eb 9817 printf ("0x%02x ", OP)
0b6ae522 9818
015dc7e1 9819static bool
dda8d76d
NC
9820decode_arm_unwind_bytecode (Filedata * filedata,
9821 struct arm_unw_aux_info * aux,
948f632f
DA
9822 unsigned int word,
9823 unsigned int remaining,
9824 unsigned int more_words,
625d49fc 9825 uint64_t data_offset,
948f632f
DA
9826 Elf_Internal_Shdr * data_sec,
9827 struct arm_section * data_arm_sec)
fa197c1c
PB
9828{
9829 struct absaddr addr;
015dc7e1 9830 bool res = true;
0b6ae522
DJ
9831
9832 /* Decode the unwinding instructions. */
9833 while (1)
9834 {
9835 unsigned int op, op2;
9836
9837 ADVANCE;
9838 if (remaining == 0)
9839 break;
9840 remaining--;
9841 op = word >> 24;
9842 word <<= 8;
9843
cc5914eb 9844 printf (" 0x%02x ", op);
0b6ae522
DJ
9845
9846 if ((op & 0xc0) == 0x00)
9847 {
9848 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9849
cc5914eb 9850 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9851 }
9852 else if ((op & 0xc0) == 0x40)
9853 {
9854 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9855
cc5914eb 9856 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9857 }
9858 else if ((op & 0xf0) == 0x80)
9859 {
9860 GET_OP (op2);
9861 if (op == 0x80 && op2 == 0)
9862 printf (_("Refuse to unwind"));
9863 else
9864 {
9865 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9866 bool first = true;
0b6ae522 9867 int i;
2b692964 9868
0b6ae522
DJ
9869 printf ("pop {");
9870 for (i = 0; i < 12; i++)
9871 if (mask & (1 << i))
9872 {
9873 if (first)
015dc7e1 9874 first = false;
0b6ae522
DJ
9875 else
9876 printf (", ");
9877 printf ("r%d", 4 + i);
9878 }
9879 printf ("}");
9880 }
9881 }
9882 else if ((op & 0xf0) == 0x90)
9883 {
9884 if (op == 0x9d || op == 0x9f)
9885 printf (_(" [Reserved]"));
9886 else
cc5914eb 9887 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9888 }
9889 else if ((op & 0xf0) == 0xa0)
9890 {
9891 int end = 4 + (op & 0x07);
015dc7e1 9892 bool first = true;
0b6ae522 9893 int i;
61865e30 9894
0b6ae522
DJ
9895 printf (" pop {");
9896 for (i = 4; i <= end; i++)
9897 {
9898 if (first)
015dc7e1 9899 first = false;
0b6ae522
DJ
9900 else
9901 printf (", ");
9902 printf ("r%d", i);
9903 }
9904 if (op & 0x08)
9905 {
1b31d05e 9906 if (!first)
0b6ae522
DJ
9907 printf (", ");
9908 printf ("r14");
9909 }
9910 printf ("}");
9911 }
9912 else if (op == 0xb0)
9913 printf (_(" finish"));
9914 else if (op == 0xb1)
9915 {
9916 GET_OP (op2);
9917 if (op2 == 0 || (op2 & 0xf0) != 0)
9918 printf (_("[Spare]"));
9919 else
9920 {
9921 unsigned int mask = op2 & 0x0f;
015dc7e1 9922 bool first = true;
0b6ae522 9923 int i;
61865e30 9924
0b6ae522
DJ
9925 printf ("pop {");
9926 for (i = 0; i < 12; i++)
9927 if (mask & (1 << i))
9928 {
9929 if (first)
015dc7e1 9930 first = false;
0b6ae522
DJ
9931 else
9932 printf (", ");
9933 printf ("r%d", i);
9934 }
9935 printf ("}");
9936 }
9937 }
9938 else if (op == 0xb2)
9939 {
b115cf96 9940 unsigned char buf[9];
0b6ae522 9941 unsigned int i, len;
26c527e6 9942 uint64_t offset;
61865e30 9943
b115cf96 9944 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9945 {
9946 GET_OP (buf[i]);
9947 if ((buf[i] & 0x80) == 0)
9948 break;
9949 }
4082ef84 9950 if (i == sizeof (buf))
32ec8896 9951 {
27a45f42 9952 error (_("corrupt change to vsp\n"));
015dc7e1 9953 res = false;
32ec8896 9954 }
4082ef84
NC
9955 else
9956 {
015dc7e1 9957 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9958 assert (len == i + 1);
9959 offset = offset * 4 + 0x204;
26c527e6 9960 printf ("vsp = vsp + %" PRId64, offset);
4082ef84 9961 }
0b6ae522 9962 }
61865e30 9963 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9964 {
61865e30
NC
9965 unsigned int first, last;
9966
9967 GET_OP (op2);
9968 first = op2 >> 4;
9969 last = op2 & 0x0f;
9970 if (op == 0xc8)
9971 first = first + 16;
9972 printf ("pop {D%d", first);
9973 if (last)
9974 printf ("-D%d", first + last);
9975 printf ("}");
9976 }
09854a88
TB
9977 else if (op == 0xb4)
9978 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
9979 else if (op == 0xb5)
9980 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
9981 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9982 {
9983 unsigned int count = op & 0x07;
9984
9985 printf ("pop {D8");
9986 if (count)
9987 printf ("-D%d", 8 + count);
9988 printf ("}");
9989 }
9990 else if (op >= 0xc0 && op <= 0xc5)
9991 {
9992 unsigned int count = op & 0x07;
9993
9994 printf (" pop {wR10");
9995 if (count)
9996 printf ("-wR%d", 10 + count);
9997 printf ("}");
9998 }
9999 else if (op == 0xc6)
10000 {
10001 unsigned int first, last;
10002
10003 GET_OP (op2);
10004 first = op2 >> 4;
10005 last = op2 & 0x0f;
10006 printf ("pop {wR%d", first);
10007 if (last)
10008 printf ("-wR%d", first + last);
10009 printf ("}");
10010 }
10011 else if (op == 0xc7)
10012 {
10013 GET_OP (op2);
10014 if (op2 == 0 || (op2 & 0xf0) != 0)
10015 printf (_("[Spare]"));
0b6ae522
DJ
10016 else
10017 {
61865e30 10018 unsigned int mask = op2 & 0x0f;
015dc7e1 10019 bool first = true;
61865e30
NC
10020 int i;
10021
10022 printf ("pop {");
10023 for (i = 0; i < 4; i++)
10024 if (mask & (1 << i))
10025 {
10026 if (first)
015dc7e1 10027 first = false;
61865e30
NC
10028 else
10029 printf (", ");
10030 printf ("wCGR%d", i);
10031 }
10032 printf ("}");
0b6ae522
DJ
10033 }
10034 }
61865e30 10035 else
32ec8896
NC
10036 {
10037 printf (_(" [unsupported opcode]"));
015dc7e1 10038 res = false;
32ec8896
NC
10039 }
10040
0b6ae522
DJ
10041 printf ("\n");
10042 }
32ec8896
NC
10043
10044 return res;
fa197c1c
PB
10045}
10046
015dc7e1 10047static bool
dda8d76d
NC
10048decode_tic6x_unwind_bytecode (Filedata * filedata,
10049 struct arm_unw_aux_info * aux,
948f632f
DA
10050 unsigned int word,
10051 unsigned int remaining,
10052 unsigned int more_words,
625d49fc 10053 uint64_t data_offset,
948f632f
DA
10054 Elf_Internal_Shdr * data_sec,
10055 struct arm_section * data_arm_sec)
fa197c1c
PB
10056{
10057 struct absaddr addr;
10058
10059 /* Decode the unwinding instructions. */
10060 while (1)
10061 {
10062 unsigned int op, op2;
10063
10064 ADVANCE;
10065 if (remaining == 0)
10066 break;
10067 remaining--;
10068 op = word >> 24;
10069 word <<= 8;
10070
9cf03b7e 10071 printf (" 0x%02x ", op);
fa197c1c
PB
10072
10073 if ((op & 0xc0) == 0x00)
10074 {
10075 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10076 printf (" sp = sp + %d", offset);
fa197c1c
PB
10077 }
10078 else if ((op & 0xc0) == 0x80)
10079 {
10080 GET_OP (op2);
10081 if (op == 0x80 && op2 == 0)
10082 printf (_("Refuse to unwind"));
10083 else
10084 {
10085 unsigned int mask = ((op & 0x1f) << 8) | op2;
10086 if (op & 0x20)
10087 printf ("pop compact {");
10088 else
10089 printf ("pop {");
10090
10091 decode_tic6x_unwind_regmask (mask);
10092 printf("}");
10093 }
10094 }
10095 else if ((op & 0xf0) == 0xc0)
10096 {
10097 unsigned int reg;
10098 unsigned int nregs;
10099 unsigned int i;
10100 const char *name;
a734115a
NC
10101 struct
10102 {
32ec8896
NC
10103 unsigned int offset;
10104 unsigned int reg;
fa197c1c
PB
10105 } regpos[16];
10106
10107 /* Scan entire instruction first so that GET_OP output is not
10108 interleaved with disassembly. */
10109 nregs = 0;
10110 for (i = 0; nregs < (op & 0xf); i++)
10111 {
10112 GET_OP (op2);
10113 reg = op2 >> 4;
10114 if (reg != 0xf)
10115 {
10116 regpos[nregs].offset = i * 2;
10117 regpos[nregs].reg = reg;
10118 nregs++;
10119 }
10120
10121 reg = op2 & 0xf;
10122 if (reg != 0xf)
10123 {
10124 regpos[nregs].offset = i * 2 + 1;
10125 regpos[nregs].reg = reg;
10126 nregs++;
10127 }
10128 }
10129
10130 printf (_("pop frame {"));
18344509 10131 if (nregs == 0)
fa197c1c 10132 {
18344509
NC
10133 printf (_("*corrupt* - no registers specified"));
10134 }
10135 else
10136 {
10137 reg = nregs - 1;
10138 for (i = i * 2; i > 0; i--)
fa197c1c 10139 {
18344509
NC
10140 if (regpos[reg].offset == i - 1)
10141 {
10142 name = tic6x_unwind_regnames[regpos[reg].reg];
10143 if (reg > 0)
10144 reg--;
10145 }
10146 else
10147 name = _("[pad]");
fa197c1c 10148
18344509
NC
10149 fputs (name, stdout);
10150 if (i > 1)
10151 printf (", ");
10152 }
fa197c1c
PB
10153 }
10154
10155 printf ("}");
10156 }
10157 else if (op == 0xd0)
10158 printf (" MOV FP, SP");
10159 else if (op == 0xd1)
10160 printf (" __c6xabi_pop_rts");
10161 else if (op == 0xd2)
10162 {
10163 unsigned char buf[9];
10164 unsigned int i, len;
26c527e6 10165 uint64_t offset;
a734115a 10166
fa197c1c
PB
10167 for (i = 0; i < sizeof (buf); i++)
10168 {
10169 GET_OP (buf[i]);
10170 if ((buf[i] & 0x80) == 0)
10171 break;
10172 }
0eff7165
NC
10173 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10174 if (i == sizeof (buf))
10175 {
0eff7165 10176 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10177 return false;
0eff7165 10178 }
948f632f 10179
015dc7e1 10180 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10181 assert (len == i + 1);
10182 offset = offset * 8 + 0x408;
26c527e6 10183 printf (_("sp = sp + %" PRId64), offset);
fa197c1c
PB
10184 }
10185 else if ((op & 0xf0) == 0xe0)
10186 {
10187 if ((op & 0x0f) == 7)
10188 printf (" RETURN");
10189 else
10190 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10191 }
10192 else
10193 {
10194 printf (_(" [unsupported opcode]"));
10195 }
10196 putchar ('\n');
10197 }
32ec8896 10198
015dc7e1 10199 return true;
fa197c1c
PB
10200}
10201
625d49fc
AM
10202static uint64_t
10203arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10204{
625d49fc 10205 uint64_t offset;
fa197c1c
PB
10206
10207 offset = word & 0x7fffffff;
10208 if (offset & 0x40000000)
625d49fc 10209 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10210
dda8d76d 10211 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10212 offset <<= 1;
10213
10214 return offset + where;
10215}
10216
015dc7e1 10217static bool
dda8d76d
NC
10218decode_arm_unwind (Filedata * filedata,
10219 struct arm_unw_aux_info * aux,
1b31d05e
NC
10220 unsigned int word,
10221 unsigned int remaining,
625d49fc 10222 uint64_t data_offset,
1b31d05e
NC
10223 Elf_Internal_Shdr * data_sec,
10224 struct arm_section * data_arm_sec)
fa197c1c
PB
10225{
10226 int per_index;
10227 unsigned int more_words = 0;
37e14bc3 10228 struct absaddr addr;
625d49fc 10229 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10230 bool res = true;
fa197c1c
PB
10231
10232 if (remaining == 0)
10233 {
1b31d05e
NC
10234 /* Fetch the first word.
10235 Note - when decoding an object file the address extracted
10236 here will always be 0. So we also pass in the sym_name
10237 parameter so that we can find the symbol associated with
10238 the personality routine. */
dda8d76d 10239 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10240 & word, & addr, & sym_name))
015dc7e1 10241 return false;
1b31d05e 10242
fa197c1c
PB
10243 remaining = 4;
10244 }
c93dbb25
CZ
10245 else
10246 {
10247 addr.section = SHN_UNDEF;
10248 addr.offset = 0;
10249 }
fa197c1c
PB
10250
10251 if ((word & 0x80000000) == 0)
10252 {
10253 /* Expand prel31 for personality routine. */
625d49fc 10254 uint64_t fn;
fa197c1c
PB
10255 const char *procname;
10256
dda8d76d 10257 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10258 printf (_(" Personality routine: "));
1b31d05e
NC
10259 if (fn == 0
10260 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10261 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10262 {
10263 procname = aux->strtab + sym_name;
10264 print_vma (fn, PREFIX_HEX);
10265 if (procname)
10266 {
10267 fputs (" <", stdout);
10268 fputs (procname, stdout);
10269 fputc ('>', stdout);
10270 }
10271 }
10272 else
dda8d76d 10273 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10274 fputc ('\n', stdout);
10275
10276 /* The GCC personality routines use the standard compact
10277 encoding, starting with one byte giving the number of
10278 words. */
10279 if (procname != NULL
24d127aa
ML
10280 && (startswith (procname, "__gcc_personality_v0")
10281 || startswith (procname, "__gxx_personality_v0")
10282 || startswith (procname, "__gcj_personality_v0")
10283 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10284 {
10285 remaining = 0;
10286 more_words = 1;
10287 ADVANCE;
10288 if (!remaining)
10289 {
10290 printf (_(" [Truncated data]\n"));
015dc7e1 10291 return false;
fa197c1c
PB
10292 }
10293 more_words = word >> 24;
10294 word <<= 8;
10295 remaining--;
10296 per_index = -1;
10297 }
10298 else
015dc7e1 10299 return true;
fa197c1c
PB
10300 }
10301 else
10302 {
1b31d05e 10303 /* ARM EHABI Section 6.3:
0b4362b0 10304
1b31d05e 10305 An exception-handling table entry for the compact model looks like:
0b4362b0 10306
1b31d05e
NC
10307 31 30-28 27-24 23-0
10308 -- ----- ----- ----
10309 1 0 index Data for personalityRoutine[index] */
10310
dda8d76d 10311 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10312 && (word & 0x70000000))
32ec8896
NC
10313 {
10314 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10315 res = false;
32ec8896 10316 }
1b31d05e 10317
fa197c1c 10318 per_index = (word >> 24) & 0x7f;
1b31d05e 10319 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10320 if (per_index == 0)
10321 {
10322 more_words = 0;
10323 word <<= 8;
10324 remaining--;
10325 }
10326 else if (per_index < 3)
10327 {
10328 more_words = (word >> 16) & 0xff;
10329 word <<= 16;
10330 remaining -= 2;
10331 }
10332 }
10333
dda8d76d 10334 switch (filedata->file_header.e_machine)
fa197c1c
PB
10335 {
10336 case EM_ARM:
10337 if (per_index < 3)
10338 {
dda8d76d 10339 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10340 data_offset, data_sec, data_arm_sec))
015dc7e1 10341 res = false;
fa197c1c
PB
10342 }
10343 else
1b31d05e
NC
10344 {
10345 warn (_("Unknown ARM compact model index encountered\n"));
10346 printf (_(" [reserved]\n"));
015dc7e1 10347 res = false;
1b31d05e 10348 }
fa197c1c
PB
10349 break;
10350
10351 case EM_TI_C6000:
10352 if (per_index < 3)
10353 {
dda8d76d 10354 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10355 data_offset, data_sec, data_arm_sec))
015dc7e1 10356 res = false;
fa197c1c
PB
10357 }
10358 else if (per_index < 5)
10359 {
10360 if (((word >> 17) & 0x7f) == 0x7f)
10361 printf (_(" Restore stack from frame pointer\n"));
10362 else
10363 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10364 printf (_(" Registers restored: "));
10365 if (per_index == 4)
10366 printf (" (compact) ");
10367 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10368 putchar ('\n');
10369 printf (_(" Return register: %s\n"),
10370 tic6x_unwind_regnames[word & 0xf]);
10371 }
10372 else
1b31d05e 10373 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10374 break;
10375
10376 default:
74e1a04b 10377 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10378 filedata->file_header.e_machine);
015dc7e1 10379 res = false;
fa197c1c 10380 }
0b6ae522
DJ
10381
10382 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10383
10384 return res;
0b6ae522
DJ
10385}
10386
015dc7e1 10387static bool
dda8d76d
NC
10388dump_arm_unwind (Filedata * filedata,
10389 struct arm_unw_aux_info * aux,
10390 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10391{
10392 struct arm_section exidx_arm_sec, extab_arm_sec;
10393 unsigned int i, exidx_len;
26c527e6 10394 uint64_t j, nfuns;
015dc7e1 10395 bool res = true;
0b6ae522
DJ
10396
10397 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10398 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10399 exidx_len = exidx_sec->sh_size / 8;
10400
948f632f
DA
10401 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10402 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10403 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10404 aux->funtab[nfuns++] = aux->symtab[j];
10405 aux->nfuns = nfuns;
10406 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10407
0b6ae522
DJ
10408 for (i = 0; i < exidx_len; i++)
10409 {
10410 unsigned int exidx_fn, exidx_entry;
10411 struct absaddr fn_addr, entry_addr;
625d49fc 10412 uint64_t fn;
0b6ae522
DJ
10413
10414 fputc ('\n', stdout);
10415
dda8d76d 10416 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10417 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10418 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10419 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10420 {
948f632f 10421 free (aux->funtab);
1b31d05e
NC
10422 arm_free_section (& exidx_arm_sec);
10423 arm_free_section (& extab_arm_sec);
015dc7e1 10424 return false;
0b6ae522
DJ
10425 }
10426
83c257ca
NC
10427 /* ARM EHABI, Section 5:
10428 An index table entry consists of 2 words.
10429 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10430 if (exidx_fn & 0x80000000)
32ec8896
NC
10431 {
10432 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10433 res = false;
32ec8896 10434 }
83c257ca 10435
dda8d76d 10436 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10437
dda8d76d 10438 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10439 fputs (": ", stdout);
10440
10441 if (exidx_entry == 1)
10442 {
10443 print_vma (exidx_entry, PREFIX_HEX);
10444 fputs (" [cantunwind]\n", stdout);
10445 }
10446 else if (exidx_entry & 0x80000000)
10447 {
10448 print_vma (exidx_entry, PREFIX_HEX);
10449 fputc ('\n', stdout);
dda8d76d 10450 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10451 }
10452 else
10453 {
625d49fc 10454 uint64_t table, table_offset = 0;
0b6ae522
DJ
10455 Elf_Internal_Shdr *table_sec;
10456
10457 fputs ("@", stdout);
dda8d76d 10458 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10459 print_vma (table, PREFIX_HEX);
10460 printf ("\n");
10461
10462 /* Locate the matching .ARM.extab. */
10463 if (entry_addr.section != SHN_UNDEF
dda8d76d 10464 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10465 {
dda8d76d 10466 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10467 table_offset = entry_addr.offset;
1a915552 10468 /* PR 18879 */
625d49fc 10469 if (table_offset > table_sec->sh_size)
1a915552 10470 {
26c527e6
AM
10471 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
10472 table_offset,
dda8d76d 10473 printable_section_name (filedata, table_sec));
015dc7e1 10474 res = false;
1a915552
NC
10475 continue;
10476 }
0b6ae522
DJ
10477 }
10478 else
10479 {
dda8d76d 10480 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10481 if (table_sec != NULL)
10482 table_offset = table - table_sec->sh_addr;
10483 }
32ec8896 10484
0b6ae522
DJ
10485 if (table_sec == NULL)
10486 {
26c527e6
AM
10487 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
10488 table);
015dc7e1 10489 res = false;
0b6ae522
DJ
10490 continue;
10491 }
32ec8896 10492
dda8d76d 10493 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10494 &extab_arm_sec))
015dc7e1 10495 res = false;
0b6ae522
DJ
10496 }
10497 }
10498
10499 printf ("\n");
10500
948f632f 10501 free (aux->funtab);
0b6ae522
DJ
10502 arm_free_section (&exidx_arm_sec);
10503 arm_free_section (&extab_arm_sec);
32ec8896
NC
10504
10505 return res;
0b6ae522
DJ
10506}
10507
fa197c1c 10508/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10509
015dc7e1 10510static bool
dda8d76d 10511arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10512{
10513 struct arm_unw_aux_info aux;
10514 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522 10515 Elf_Internal_Shdr *sec;
26c527e6 10516 size_t i;
fa197c1c 10517 unsigned int sec_type;
015dc7e1 10518 bool res = true;
0b6ae522 10519
dda8d76d 10520 switch (filedata->file_header.e_machine)
fa197c1c
PB
10521 {
10522 case EM_ARM:
10523 sec_type = SHT_ARM_EXIDX;
10524 break;
10525
10526 case EM_TI_C6000:
10527 sec_type = SHT_C6000_UNWIND;
10528 break;
10529
0b4362b0 10530 default:
74e1a04b 10531 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10532 filedata->file_header.e_machine);
015dc7e1 10533 return false;
fa197c1c
PB
10534 }
10535
dda8d76d 10536 if (filedata->string_table == NULL)
015dc7e1 10537 return false;
1b31d05e
NC
10538
10539 memset (& aux, 0, sizeof (aux));
dda8d76d 10540 aux.filedata = filedata;
0b6ae522 10541
dda8d76d 10542 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10543 {
28d13567 10544 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10545 {
28d13567 10546 if (aux.symtab)
74e1a04b 10547 {
28d13567
AM
10548 error (_("Multiple symbol tables encountered\n"));
10549 free (aux.symtab);
10550 aux.symtab = NULL;
74e1a04b 10551 free (aux.strtab);
28d13567 10552 aux.strtab = NULL;
74e1a04b 10553 }
28d13567
AM
10554 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10555 &aux.strtab, &aux.strtab_size))
015dc7e1 10556 return false;
0b6ae522 10557 }
fa197c1c 10558 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10559 unwsec = sec;
10560 }
10561
1b31d05e 10562 if (unwsec == NULL)
0b6ae522 10563 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10564 else
dda8d76d 10565 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10566 {
10567 if (sec->sh_type == sec_type)
10568 {
26c527e6
AM
10569 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
10570 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
10571 "contains %" PRIu64 " entry:\n",
10572 "\nUnwind section '%s' at offset %#" PRIx64 " "
10573 "contains %" PRIu64 " entries:\n",
d3a49aa8 10574 num_unwind),
dda8d76d 10575 printable_section_name (filedata, sec),
26c527e6 10576 sec->sh_offset,
d3a49aa8 10577 num_unwind);
0b6ae522 10578
dda8d76d 10579 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10580 res = false;
1b31d05e
NC
10581 }
10582 }
0b6ae522 10583
9db70fc3
AM
10584 free (aux.symtab);
10585 free ((char *) aux.strtab);
32ec8896
NC
10586
10587 return res;
0b6ae522
DJ
10588}
10589
3ecc00ec
NC
10590static bool
10591no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10592{
10593 printf (_("No processor specific unwind information to decode\n"));
10594 return true;
10595}
10596
015dc7e1 10597static bool
dda8d76d 10598process_unwind (Filedata * filedata)
57346661 10599{
2cf0635d
NC
10600 struct unwind_handler
10601 {
32ec8896 10602 unsigned int machtype;
015dc7e1 10603 bool (* handler)(Filedata *);
2cf0635d
NC
10604 } handlers[] =
10605 {
0b6ae522 10606 { EM_ARM, arm_process_unwind },
57346661
AM
10607 { EM_IA_64, ia64_process_unwind },
10608 { EM_PARISC, hppa_process_unwind },
fa197c1c 10609 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10610 { EM_386, no_processor_specific_unwind },
10611 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10612 { 0, NULL }
57346661
AM
10613 };
10614 int i;
10615
10616 if (!do_unwind)
015dc7e1 10617 return true;
57346661
AM
10618
10619 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10620 if (filedata->file_header.e_machine == handlers[i].machtype)
10621 return handlers[i].handler (filedata);
57346661 10622
1b31d05e 10623 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10624 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10625 return true;
57346661
AM
10626}
10627
37c18eed
SD
10628static void
10629dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10630{
10631 switch (entry->d_tag)
10632 {
10633 case DT_AARCH64_BTI_PLT:
1dbade74 10634 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10635 break;
10636 default:
10637 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10638 break;
10639 }
10640 putchar ('\n');
10641}
10642
252b5132 10643static void
978c4450 10644dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10645{
10646 switch (entry->d_tag)
10647 {
10648 case DT_MIPS_FLAGS:
10649 if (entry->d_un.d_val == 0)
4b68bca3 10650 printf (_("NONE"));
252b5132
RH
10651 else
10652 {
10653 static const char * opts[] =
10654 {
10655 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10656 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10657 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10658 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10659 "RLD_ORDER_SAFE"
10660 };
10661 unsigned int cnt;
015dc7e1 10662 bool first = true;
2b692964 10663
60bca95a 10664 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10665 if (entry->d_un.d_val & (1 << cnt))
10666 {
10667 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10668 first = false;
252b5132 10669 }
252b5132
RH
10670 }
10671 break;
103f02d3 10672
252b5132 10673 case DT_MIPS_IVERSION:
84714f86 10674 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10675 printf (_("Interface Version: %s"),
84714f86 10676 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10677 else
f493c217 10678 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 10679 entry->d_un.d_ptr);
252b5132 10680 break;
103f02d3 10681
252b5132
RH
10682 case DT_MIPS_TIME_STAMP:
10683 {
d5b07ef4 10684 char timebuf[128];
2cf0635d 10685 struct tm * tmp;
91d6fa6a 10686 time_t atime = entry->d_un.d_val;
82b1b41b 10687
91d6fa6a 10688 tmp = gmtime (&atime);
82b1b41b
NC
10689 /* PR 17531: file: 6accc532. */
10690 if (tmp == NULL)
10691 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10692 else
10693 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10694 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10695 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10696 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10697 }
10698 break;
103f02d3 10699
252b5132
RH
10700 case DT_MIPS_RLD_VERSION:
10701 case DT_MIPS_LOCAL_GOTNO:
10702 case DT_MIPS_CONFLICTNO:
10703 case DT_MIPS_LIBLISTNO:
10704 case DT_MIPS_SYMTABNO:
10705 case DT_MIPS_UNREFEXTNO:
10706 case DT_MIPS_HIPAGENO:
10707 case DT_MIPS_DELTA_CLASS_NO:
10708 case DT_MIPS_DELTA_INSTANCE_NO:
10709 case DT_MIPS_DELTA_RELOC_NO:
10710 case DT_MIPS_DELTA_SYM_NO:
10711 case DT_MIPS_DELTA_CLASSSYM_NO:
10712 case DT_MIPS_COMPACT_SIZE:
c69075ac 10713 print_vma (entry->d_un.d_val, DEC);
252b5132 10714 break;
103f02d3 10715
f16a9783 10716 case DT_MIPS_XHASH:
978c4450
AM
10717 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10718 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10719 /* Falls through. */
10720
103f02d3 10721 default:
4b68bca3 10722 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10723 }
4b68bca3 10724 putchar ('\n');
103f02d3
UD
10725}
10726
103f02d3 10727static void
2cf0635d 10728dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10729{
10730 switch (entry->d_tag)
10731 {
10732 case DT_HP_DLD_FLAGS:
10733 {
10734 static struct
10735 {
26c527e6 10736 unsigned int bit;
2cf0635d 10737 const char * str;
5e220199
NC
10738 }
10739 flags[] =
10740 {
10741 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10742 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10743 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10744 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10745 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10746 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10747 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10748 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10749 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10750 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10751 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10752 { DT_HP_GST, "HP_GST" },
10753 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10754 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10755 { DT_HP_NODELETE, "HP_NODELETE" },
10756 { DT_HP_GROUP, "HP_GROUP" },
10757 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10758 };
015dc7e1 10759 bool first = true;
5e220199 10760 size_t cnt;
625d49fc 10761 uint64_t val = entry->d_un.d_val;
103f02d3 10762
60bca95a 10763 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10764 if (val & flags[cnt].bit)
30800947
NC
10765 {
10766 if (! first)
10767 putchar (' ');
10768 fputs (flags[cnt].str, stdout);
015dc7e1 10769 first = false;
30800947
NC
10770 val ^= flags[cnt].bit;
10771 }
76da6bbe 10772
103f02d3 10773 if (val != 0 || first)
f7a99963
NC
10774 {
10775 if (! first)
10776 putchar (' ');
10777 print_vma (val, HEX);
10778 }
103f02d3
UD
10779 }
10780 break;
76da6bbe 10781
252b5132 10782 default:
f7a99963
NC
10783 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10784 break;
252b5132 10785 }
35b1837e 10786 putchar ('\n');
252b5132
RH
10787}
10788
28f997cf
TG
10789/* VMS vs Unix time offset and factor. */
10790
10791#define VMS_EPOCH_OFFSET 35067168000000000LL
10792#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10793#ifndef INT64_MIN
10794#define INT64_MIN (-9223372036854775807LL - 1)
10795#endif
28f997cf
TG
10796
10797/* Display a VMS time in a human readable format. */
10798
10799static void
0e3c1eeb 10800print_vms_time (int64_t vmstime)
28f997cf 10801{
dccc31de 10802 struct tm *tm = NULL;
28f997cf
TG
10803 time_t unxtime;
10804
dccc31de
AM
10805 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10806 {
10807 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10808 unxtime = vmstime;
10809 if (unxtime == vmstime)
10810 tm = gmtime (&unxtime);
10811 }
10812 if (tm != NULL)
10813 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10814 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10815 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 10816}
28f997cf 10817
ecc51f48 10818static void
2cf0635d 10819dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10820{
10821 switch (entry->d_tag)
10822 {
0de14b54 10823 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10824 /* First 3 slots reserved. */
ecc51f48
NC
10825 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10826 printf (" -- ");
10827 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10828 break;
10829
28f997cf 10830 case DT_IA_64_VMS_LINKTIME:
28f997cf 10831 print_vms_time (entry->d_un.d_val);
28f997cf
TG
10832 break;
10833
10834 case DT_IA_64_VMS_LNKFLAGS:
10835 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10836 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10837 printf (" CALL_DEBUG");
10838 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10839 printf (" NOP0BUFS");
10840 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10841 printf (" P0IMAGE");
10842 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10843 printf (" MKTHREADS");
10844 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10845 printf (" UPCALLS");
10846 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10847 printf (" IMGSTA");
10848 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10849 printf (" INITIALIZE");
10850 if (entry->d_un.d_val & VMS_LF_MAIN)
10851 printf (" MAIN");
10852 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10853 printf (" EXE_INIT");
10854 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10855 printf (" TBK_IN_IMG");
10856 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10857 printf (" DBG_IN_IMG");
10858 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10859 printf (" TBK_IN_DSF");
10860 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10861 printf (" DBG_IN_DSF");
10862 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10863 printf (" SIGNATURES");
10864 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10865 printf (" REL_SEG_OFF");
10866 break;
10867
bdf4d63a
JJ
10868 default:
10869 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10870 break;
ecc51f48 10871 }
bdf4d63a 10872 putchar ('\n');
ecc51f48
NC
10873}
10874
015dc7e1 10875static bool
dda8d76d 10876get_32bit_dynamic_section (Filedata * filedata)
252b5132 10877{
2cf0635d
NC
10878 Elf32_External_Dyn * edyn;
10879 Elf32_External_Dyn * ext;
10880 Elf_Internal_Dyn * entry;
103f02d3 10881
978c4450
AM
10882 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10883 filedata->dynamic_addr, 1,
10884 filedata->dynamic_size,
10885 _("dynamic section"));
a6e9f9df 10886 if (!edyn)
015dc7e1 10887 return false;
103f02d3 10888
071436c6
NC
10889 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10890 might not have the luxury of section headers. Look for the DT_NULL
10891 terminator to determine the number of entries. */
978c4450
AM
10892 for (ext = edyn, filedata->dynamic_nent = 0;
10893 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10894 ext++)
10895 {
978c4450 10896 filedata->dynamic_nent++;
ba2685cc
AM
10897 if (BYTE_GET (ext->d_tag) == DT_NULL)
10898 break;
10899 }
252b5132 10900
978c4450
AM
10901 filedata->dynamic_section
10902 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10903 if (filedata->dynamic_section == NULL)
252b5132 10904 {
26c527e6
AM
10905 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
10906 filedata->dynamic_nent);
9ea033b2 10907 free (edyn);
015dc7e1 10908 return false;
9ea033b2 10909 }
252b5132 10910
978c4450
AM
10911 for (ext = edyn, entry = filedata->dynamic_section;
10912 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10913 ext++, entry++)
9ea033b2 10914 {
fb514b26
AM
10915 entry->d_tag = BYTE_GET (ext->d_tag);
10916 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10917 }
10918
9ea033b2
NC
10919 free (edyn);
10920
015dc7e1 10921 return true;
9ea033b2
NC
10922}
10923
015dc7e1 10924static bool
dda8d76d 10925get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10926{
2cf0635d
NC
10927 Elf64_External_Dyn * edyn;
10928 Elf64_External_Dyn * ext;
10929 Elf_Internal_Dyn * entry;
103f02d3 10930
071436c6 10931 /* Read in the data. */
978c4450
AM
10932 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10933 filedata->dynamic_addr, 1,
10934 filedata->dynamic_size,
10935 _("dynamic section"));
a6e9f9df 10936 if (!edyn)
015dc7e1 10937 return false;
103f02d3 10938
071436c6
NC
10939 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10940 might not have the luxury of section headers. Look for the DT_NULL
10941 terminator to determine the number of entries. */
978c4450 10942 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10943 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10944 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10945 ext++)
10946 {
978c4450 10947 filedata->dynamic_nent++;
66543521 10948 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10949 break;
10950 }
252b5132 10951
978c4450
AM
10952 filedata->dynamic_section
10953 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10954 if (filedata->dynamic_section == NULL)
252b5132 10955 {
26c527e6
AM
10956 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
10957 filedata->dynamic_nent);
252b5132 10958 free (edyn);
015dc7e1 10959 return false;
252b5132
RH
10960 }
10961
071436c6 10962 /* Convert from external to internal formats. */
978c4450
AM
10963 for (ext = edyn, entry = filedata->dynamic_section;
10964 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10965 ext++, entry++)
252b5132 10966 {
66543521
AM
10967 entry->d_tag = BYTE_GET (ext->d_tag);
10968 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10969 }
10970
10971 free (edyn);
10972
015dc7e1 10973 return true;
9ea033b2
NC
10974}
10975
4de91c10
AM
10976static bool
10977get_dynamic_section (Filedata *filedata)
10978{
10979 if (filedata->dynamic_section)
10980 return true;
10981
10982 if (is_32bit_elf)
10983 return get_32bit_dynamic_section (filedata);
10984 else
10985 return get_64bit_dynamic_section (filedata);
10986}
10987
e9e44622 10988static void
625d49fc 10989print_dynamic_flags (uint64_t flags)
d1133906 10990{
015dc7e1 10991 bool first = true;
13ae64f3 10992
d1133906
NC
10993 while (flags)
10994 {
625d49fc 10995 uint64_t flag;
d1133906
NC
10996
10997 flag = flags & - flags;
10998 flags &= ~ flag;
10999
e9e44622 11000 if (first)
015dc7e1 11001 first = false;
e9e44622
JJ
11002 else
11003 putc (' ', stdout);
13ae64f3 11004
d1133906
NC
11005 switch (flag)
11006 {
e9e44622
JJ
11007 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11008 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11009 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11010 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11011 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 11012 default: fputs (_("unknown"), stdout); break;
d1133906
NC
11013 }
11014 }
e9e44622 11015 puts ("");
d1133906
NC
11016}
11017
625d49fc 11018static uint64_t *
be7d229a 11019get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
11020{
11021 unsigned char * e_data;
625d49fc 11022 uint64_t * i_data;
10ca4b04 11023
be7d229a
AM
11024 /* If size_t is smaller than uint64_t, eg because you are building
11025 on a 32-bit host, then make sure that when number is cast to
11026 size_t no information is lost. */
11027 if ((size_t) number != number
11028 || ent_size * number / ent_size != number)
10ca4b04 11029 {
be7d229a 11030 error (_("Size overflow prevents reading %" PRIu64
b8281767 11031 " elements of size %u\n"),
be7d229a 11032 number, ent_size);
10ca4b04
L
11033 return NULL;
11034 }
11035
11036 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11037 attempting to allocate memory when the read is bound to fail. */
11038 if (ent_size * number > filedata->file_size)
11039 {
b8281767 11040 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 11041 number);
10ca4b04
L
11042 return NULL;
11043 }
11044
11045 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11046 if (e_data == NULL)
11047 {
b8281767 11048 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 11049 number);
10ca4b04
L
11050 return NULL;
11051 }
11052
11053 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11054 {
b8281767 11055 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 11056 number * ent_size);
10ca4b04
L
11057 free (e_data);
11058 return NULL;
11059 }
11060
625d49fc 11061 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
11062 if (i_data == NULL)
11063 {
b8281767 11064 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 11065 number);
10ca4b04
L
11066 free (e_data);
11067 return NULL;
11068 }
11069
11070 while (number--)
11071 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11072
11073 free (e_data);
11074
11075 return i_data;
11076}
11077
26c527e6 11078static uint64_t
10ca4b04
L
11079get_num_dynamic_syms (Filedata * filedata)
11080{
26c527e6 11081 uint64_t num_of_syms = 0;
10ca4b04
L
11082
11083 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11084 return num_of_syms;
11085
978c4450 11086 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11087 {
11088 unsigned char nb[8];
11089 unsigned char nc[8];
11090 unsigned int hash_ent_size = 4;
11091
11092 if ((filedata->file_header.e_machine == EM_ALPHA
11093 || filedata->file_header.e_machine == EM_S390
11094 || filedata->file_header.e_machine == EM_S390_OLD)
11095 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11096 hash_ent_size = 8;
11097
63cf857e
AM
11098 if (fseek64 (filedata->handle,
11099 (filedata->archive_file_offset
11100 + offset_from_vma (filedata,
11101 filedata->dynamic_info[DT_HASH],
11102 sizeof nb + sizeof nc)),
11103 SEEK_SET))
10ca4b04
L
11104 {
11105 error (_("Unable to seek to start of dynamic information\n"));
11106 goto no_hash;
11107 }
11108
11109 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11110 {
11111 error (_("Failed to read in number of buckets\n"));
11112 goto no_hash;
11113 }
11114
11115 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11116 {
11117 error (_("Failed to read in number of chains\n"));
11118 goto no_hash;
11119 }
11120
978c4450
AM
11121 filedata->nbuckets = byte_get (nb, hash_ent_size);
11122 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11123
2482f306
AM
11124 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11125 {
11126 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11127 hash_ent_size);
11128 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11129 hash_ent_size);
001890e1 11130
2482f306
AM
11131 if (filedata->buckets != NULL && filedata->chains != NULL)
11132 num_of_syms = filedata->nchains;
11133 }
ceb9bf11 11134 no_hash:
10ca4b04
L
11135 if (num_of_syms == 0)
11136 {
9db70fc3
AM
11137 free (filedata->buckets);
11138 filedata->buckets = NULL;
11139 free (filedata->chains);
11140 filedata->chains = NULL;
978c4450 11141 filedata->nbuckets = 0;
10ca4b04
L
11142 }
11143 }
11144
978c4450 11145 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11146 {
11147 unsigned char nb[16];
625d49fc
AM
11148 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11149 uint64_t buckets_vma;
26c527e6 11150 uint64_t hn;
10ca4b04 11151
63cf857e
AM
11152 if (fseek64 (filedata->handle,
11153 (filedata->archive_file_offset
11154 + offset_from_vma (filedata,
11155 filedata->dynamic_info_DT_GNU_HASH,
11156 sizeof nb)),
11157 SEEK_SET))
10ca4b04
L
11158 {
11159 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11160 goto no_gnu_hash;
11161 }
11162
11163 if (fread (nb, 16, 1, filedata->handle) != 1)
11164 {
11165 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11166 goto no_gnu_hash;
11167 }
11168
978c4450
AM
11169 filedata->ngnubuckets = byte_get (nb, 4);
11170 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11171 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11172 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11173 if (is_32bit_elf)
11174 buckets_vma += bitmaskwords * 4;
11175 else
11176 buckets_vma += bitmaskwords * 8;
11177
63cf857e
AM
11178 if (fseek64 (filedata->handle,
11179 (filedata->archive_file_offset
11180 + offset_from_vma (filedata, buckets_vma, 4)),
11181 SEEK_SET))
10ca4b04
L
11182 {
11183 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11184 goto no_gnu_hash;
11185 }
11186
978c4450
AM
11187 filedata->gnubuckets
11188 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11189
978c4450 11190 if (filedata->gnubuckets == NULL)
90837ea7 11191 goto no_gnu_hash;
10ca4b04 11192
978c4450
AM
11193 for (i = 0; i < filedata->ngnubuckets; i++)
11194 if (filedata->gnubuckets[i] != 0)
10ca4b04 11195 {
978c4450 11196 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11197 goto no_gnu_hash;
10ca4b04 11198
978c4450
AM
11199 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11200 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11201 }
11202
11203 if (maxchain == 0xffffffff)
90837ea7 11204 goto no_gnu_hash;
10ca4b04 11205
978c4450 11206 maxchain -= filedata->gnusymidx;
10ca4b04 11207
63cf857e
AM
11208 if (fseek64 (filedata->handle,
11209 (filedata->archive_file_offset
11210 + offset_from_vma (filedata,
11211 buckets_vma + 4 * (filedata->ngnubuckets
11212 + maxchain),
11213 4)),
11214 SEEK_SET))
10ca4b04
L
11215 {
11216 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11217 goto no_gnu_hash;
11218 }
11219
11220 do
11221 {
11222 if (fread (nb, 4, 1, filedata->handle) != 1)
11223 {
11224 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11225 goto no_gnu_hash;
11226 }
11227
11228 if (maxchain + 1 == 0)
90837ea7 11229 goto no_gnu_hash;
10ca4b04
L
11230
11231 ++maxchain;
11232 }
11233 while ((byte_get (nb, 4) & 1) == 0);
11234
63cf857e
AM
11235 if (fseek64 (filedata->handle,
11236 (filedata->archive_file_offset
11237 + offset_from_vma (filedata, (buckets_vma
11238 + 4 * filedata->ngnubuckets),
11239 4)),
11240 SEEK_SET))
10ca4b04
L
11241 {
11242 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11243 goto no_gnu_hash;
11244 }
11245
978c4450
AM
11246 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11247 filedata->ngnuchains = maxchain;
10ca4b04 11248
978c4450 11249 if (filedata->gnuchains == NULL)
90837ea7 11250 goto no_gnu_hash;
10ca4b04 11251
978c4450 11252 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11253 {
63cf857e
AM
11254 if (fseek64 (filedata->handle,
11255 (filedata->archive_file_offset
11256 + offset_from_vma (filedata, (buckets_vma
11257 + 4 * (filedata->ngnubuckets
11258 + maxchain)), 4)),
11259 SEEK_SET))
10ca4b04
L
11260 {
11261 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11262 goto no_gnu_hash;
11263 }
11264
978c4450 11265 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11266 if (filedata->mipsxlat == NULL)
11267 goto no_gnu_hash;
10ca4b04
L
11268 }
11269
978c4450
AM
11270 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11271 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11272 {
625d49fc
AM
11273 uint64_t si = filedata->gnubuckets[hn];
11274 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11275
11276 do
11277 {
978c4450 11278 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11279 {
c31ab5a0
AM
11280 if (off < filedata->ngnuchains
11281 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11282 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11283 }
11284 else
11285 {
11286 if (si >= num_of_syms)
11287 num_of_syms = si + 1;
11288 }
11289 si++;
11290 }
978c4450
AM
11291 while (off < filedata->ngnuchains
11292 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11293 }
11294
90837ea7 11295 if (num_of_syms == 0)
10ca4b04 11296 {
90837ea7 11297 no_gnu_hash:
9db70fc3
AM
11298 free (filedata->mipsxlat);
11299 filedata->mipsxlat = NULL;
11300 free (filedata->gnuchains);
11301 filedata->gnuchains = NULL;
11302 free (filedata->gnubuckets);
11303 filedata->gnubuckets = NULL;
978c4450
AM
11304 filedata->ngnubuckets = 0;
11305 filedata->ngnuchains = 0;
10ca4b04
L
11306 }
11307 }
11308
11309 return num_of_syms;
11310}
11311
b2d38a17
NC
11312/* Parse and display the contents of the dynamic section. */
11313
015dc7e1 11314static bool
dda8d76d 11315process_dynamic_section (Filedata * filedata)
9ea033b2 11316{
2cf0635d 11317 Elf_Internal_Dyn * entry;
9ea033b2 11318
93df3340 11319 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11320 {
11321 if (do_dynamic)
ca0e11aa
NC
11322 {
11323 if (filedata->is_separate)
11324 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11325 filedata->file_name);
11326 else
11327 printf (_("\nThere is no dynamic section in this file.\n"));
11328 }
9ea033b2 11329
015dc7e1 11330 return true;
9ea033b2
NC
11331 }
11332
4de91c10
AM
11333 if (!get_dynamic_section (filedata))
11334 return false;
9ea033b2 11335
252b5132 11336 /* Find the appropriate symbol table. */
978c4450 11337 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11338 {
26c527e6 11339 uint64_t num_of_syms;
2482f306 11340
978c4450
AM
11341 for (entry = filedata->dynamic_section;
11342 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11343 ++entry)
10ca4b04 11344 if (entry->d_tag == DT_SYMTAB)
978c4450 11345 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11346 else if (entry->d_tag == DT_SYMENT)
978c4450 11347 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11348 else if (entry->d_tag == DT_HASH)
978c4450 11349 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11350 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11351 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11352 else if ((filedata->file_header.e_machine == EM_MIPS
11353 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11354 && entry->d_tag == DT_MIPS_XHASH)
11355 {
978c4450
AM
11356 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11357 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11358 }
252b5132 11359
2482f306
AM
11360 num_of_syms = get_num_dynamic_syms (filedata);
11361
11362 if (num_of_syms != 0
11363 && filedata->dynamic_symbols == NULL
11364 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11365 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11366 {
11367 Elf_Internal_Phdr *seg;
625d49fc 11368 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11369
2482f306
AM
11370 if (! get_program_headers (filedata))
11371 {
11372 error (_("Cannot interpret virtual addresses "
11373 "without program headers.\n"));
015dc7e1 11374 return false;
2482f306 11375 }
252b5132 11376
2482f306
AM
11377 for (seg = filedata->program_headers;
11378 seg < filedata->program_headers + filedata->file_header.e_phnum;
11379 ++seg)
11380 {
11381 if (seg->p_type != PT_LOAD)
11382 continue;
252b5132 11383
2482f306
AM
11384 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11385 {
11386 /* See PR 21379 for a reproducer. */
11387 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11388 return false;
2482f306 11389 }
252b5132 11390
2482f306
AM
11391 if (vma >= (seg->p_vaddr & -seg->p_align)
11392 && vma < seg->p_vaddr + seg->p_filesz)
11393 {
11394 /* Since we do not know how big the symbol table is,
11395 we default to reading in up to the end of PT_LOAD
11396 segment and processing that. This is overkill, I
11397 know, but it should work. */
11398 Elf_Internal_Shdr section;
11399 section.sh_offset = (vma - seg->p_vaddr
11400 + seg->p_offset);
11401 section.sh_size = (num_of_syms
11402 * filedata->dynamic_info[DT_SYMENT]);
11403 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11404
11405 if (do_checks
11406 && filedata->dynamic_symtab_section != NULL
11407 && ((filedata->dynamic_symtab_section->sh_offset
11408 != section.sh_offset)
11409 || (filedata->dynamic_symtab_section->sh_size
11410 != section.sh_size)
11411 || (filedata->dynamic_symtab_section->sh_entsize
11412 != section.sh_entsize)))
11413 warn (_("\
11414the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11415
2482f306
AM
11416 section.sh_name = filedata->string_table_length;
11417 filedata->dynamic_symbols
4de91c10 11418 = get_elf_symbols (filedata, &section,
2482f306
AM
11419 &filedata->num_dynamic_syms);
11420 if (filedata->dynamic_symbols == NULL
11421 || filedata->num_dynamic_syms != num_of_syms)
11422 {
11423 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11424 return false;
2482f306
AM
11425 }
11426 break;
11427 }
11428 }
11429 }
11430 }
252b5132
RH
11431
11432 /* Similarly find a string table. */
978c4450
AM
11433 if (filedata->dynamic_strings == NULL)
11434 for (entry = filedata->dynamic_section;
11435 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11436 ++entry)
11437 {
11438 if (entry->d_tag == DT_STRTAB)
978c4450 11439 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11440
10ca4b04 11441 if (entry->d_tag == DT_STRSZ)
978c4450 11442 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11443
978c4450
AM
11444 if (filedata->dynamic_info[DT_STRTAB]
11445 && filedata->dynamic_info[DT_STRSZ])
10ca4b04 11446 {
26c527e6 11447 uint64_t offset;
be7d229a 11448 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11449
11450 offset = offset_from_vma (filedata,
978c4450 11451 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11452 str_tab_len);
8ac10c5b
L
11453 if (do_checks
11454 && filedata->dynamic_strtab_section
11455 && ((filedata->dynamic_strtab_section->sh_offset
11456 != (file_ptr) offset)
11457 || (filedata->dynamic_strtab_section->sh_size
11458 != str_tab_len)))
11459 warn (_("\
11460the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11461
978c4450
AM
11462 filedata->dynamic_strings
11463 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11464 _("dynamic string table"));
11465 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11466 {
11467 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11468 break;
11469 }
e3d39609 11470
978c4450 11471 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11472 break;
11473 }
11474 }
252b5132
RH
11475
11476 /* And find the syminfo section if available. */
978c4450 11477 if (filedata->dynamic_syminfo == NULL)
252b5132 11478 {
26c527e6 11479 uint64_t syminsz = 0;
252b5132 11480
978c4450
AM
11481 for (entry = filedata->dynamic_section;
11482 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11483 ++entry)
252b5132
RH
11484 {
11485 if (entry->d_tag == DT_SYMINENT)
11486 {
11487 /* Note: these braces are necessary to avoid a syntax
11488 error from the SunOS4 C compiler. */
049b0c3a
NC
11489 /* PR binutils/17531: A corrupt file can trigger this test.
11490 So do not use an assert, instead generate an error message. */
11491 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11492 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11493 (int) entry->d_un.d_val);
252b5132
RH
11494 }
11495 else if (entry->d_tag == DT_SYMINSZ)
11496 syminsz = entry->d_un.d_val;
11497 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11498 filedata->dynamic_syminfo_offset
11499 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11500 }
11501
978c4450 11502 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11503 {
2cf0635d
NC
11504 Elf_External_Syminfo * extsyminfo;
11505 Elf_External_Syminfo * extsym;
11506 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11507
11508 /* There is a syminfo section. Read the data. */
3f5e193b 11509 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11510 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11511 1, syminsz, _("symbol information"));
a6e9f9df 11512 if (!extsyminfo)
015dc7e1 11513 return false;
252b5132 11514
978c4450 11515 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11516 {
11517 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11518 free (filedata->dynamic_syminfo);
e3d39609 11519 }
978c4450
AM
11520 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11521 if (filedata->dynamic_syminfo == NULL)
252b5132 11522 {
26c527e6
AM
11523 error (_("Out of memory allocating %" PRIu64
11524 " bytes for dynamic symbol info\n"),
11525 syminsz);
015dc7e1 11526 return false;
252b5132
RH
11527 }
11528
2482f306
AM
11529 filedata->dynamic_syminfo_nent
11530 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11531 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11532 syminfo < (filedata->dynamic_syminfo
11533 + filedata->dynamic_syminfo_nent);
86dba8ee 11534 ++syminfo, ++extsym)
252b5132 11535 {
86dba8ee
AM
11536 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11537 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11538 }
11539
11540 free (extsyminfo);
11541 }
11542 }
11543
978c4450 11544 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11545 {
f253158f 11546 if (filedata->is_separate)
26c527e6
AM
11547 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
11548 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
11549 filedata->dynamic_nent),
f253158f
NC
11550 filedata->file_name,
11551 filedata->dynamic_addr,
26c527e6 11552 filedata->dynamic_nent);
84a9f195 11553 else
26c527e6
AM
11554 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRId64 " entry:\n",
11555 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
11556 filedata->dynamic_nent),
84a9f195 11557 filedata->dynamic_addr,
26c527e6 11558 filedata->dynamic_nent);
ca0e11aa 11559 }
252b5132
RH
11560 if (do_dynamic)
11561 printf (_(" Tag Type Name/Value\n"));
11562
978c4450
AM
11563 for (entry = filedata->dynamic_section;
11564 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11565 entry++)
252b5132
RH
11566 {
11567 if (do_dynamic)
f7a99963 11568 {
2cf0635d 11569 const char * dtype;
e699b9ff 11570
f7a99963
NC
11571 putchar (' ');
11572 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11573 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11574 printf (" (%s)%*s", dtype,
32ec8896 11575 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11576 }
252b5132
RH
11577
11578 switch (entry->d_tag)
11579 {
d1133906
NC
11580 case DT_FLAGS:
11581 if (do_dynamic)
e9e44622 11582 print_dynamic_flags (entry->d_un.d_val);
d1133906 11583 break;
76da6bbe 11584
252b5132
RH
11585 case DT_AUXILIARY:
11586 case DT_FILTER:
019148e4
L
11587 case DT_CONFIG:
11588 case DT_DEPAUDIT:
11589 case DT_AUDIT:
252b5132
RH
11590 if (do_dynamic)
11591 {
019148e4 11592 switch (entry->d_tag)
b34976b6 11593 {
019148e4
L
11594 case DT_AUXILIARY:
11595 printf (_("Auxiliary library"));
11596 break;
11597
11598 case DT_FILTER:
11599 printf (_("Filter library"));
11600 break;
11601
b34976b6 11602 case DT_CONFIG:
019148e4
L
11603 printf (_("Configuration file"));
11604 break;
11605
11606 case DT_DEPAUDIT:
11607 printf (_("Dependency audit library"));
11608 break;
11609
11610 case DT_AUDIT:
11611 printf (_("Audit library"));
11612 break;
11613 }
252b5132 11614
84714f86 11615 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11616 printf (": [%s]\n",
84714f86 11617 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11618 else
f7a99963
NC
11619 {
11620 printf (": ");
11621 print_vma (entry->d_un.d_val, PREFIX_HEX);
11622 putchar ('\n');
11623 }
252b5132
RH
11624 }
11625 break;
11626
dcefbbbd 11627 case DT_FEATURE:
252b5132
RH
11628 if (do_dynamic)
11629 {
11630 printf (_("Flags:"));
86f55779 11631
252b5132
RH
11632 if (entry->d_un.d_val == 0)
11633 printf (_(" None\n"));
11634 else
11635 {
26c527e6 11636 uint64_t val = entry->d_un.d_val;
86f55779 11637
252b5132
RH
11638 if (val & DTF_1_PARINIT)
11639 {
11640 printf (" PARINIT");
11641 val ^= DTF_1_PARINIT;
11642 }
dcefbbbd
L
11643 if (val & DTF_1_CONFEXP)
11644 {
11645 printf (" CONFEXP");
11646 val ^= DTF_1_CONFEXP;
11647 }
252b5132 11648 if (val != 0)
26c527e6 11649 printf (" %" PRIx64, val);
252b5132
RH
11650 puts ("");
11651 }
11652 }
11653 break;
11654
11655 case DT_POSFLAG_1:
11656 if (do_dynamic)
11657 {
11658 printf (_("Flags:"));
86f55779 11659
252b5132
RH
11660 if (entry->d_un.d_val == 0)
11661 printf (_(" None\n"));
11662 else
11663 {
26c527e6 11664 uint64_t val = entry->d_un.d_val;
86f55779 11665
252b5132
RH
11666 if (val & DF_P1_LAZYLOAD)
11667 {
11668 printf (" LAZYLOAD");
11669 val ^= DF_P1_LAZYLOAD;
11670 }
11671 if (val & DF_P1_GROUPPERM)
11672 {
11673 printf (" GROUPPERM");
11674 val ^= DF_P1_GROUPPERM;
11675 }
11676 if (val != 0)
26c527e6 11677 printf (" %" PRIx64, val);
252b5132
RH
11678 puts ("");
11679 }
11680 }
11681 break;
11682
11683 case DT_FLAGS_1:
11684 if (do_dynamic)
11685 {
11686 printf (_("Flags:"));
11687 if (entry->d_un.d_val == 0)
11688 printf (_(" None\n"));
11689 else
11690 {
26c527e6 11691 uint64_t val = entry->d_un.d_val;
86f55779 11692
252b5132
RH
11693 if (val & DF_1_NOW)
11694 {
11695 printf (" NOW");
11696 val ^= DF_1_NOW;
11697 }
11698 if (val & DF_1_GLOBAL)
11699 {
11700 printf (" GLOBAL");
11701 val ^= DF_1_GLOBAL;
11702 }
11703 if (val & DF_1_GROUP)
11704 {
11705 printf (" GROUP");
11706 val ^= DF_1_GROUP;
11707 }
11708 if (val & DF_1_NODELETE)
11709 {
11710 printf (" NODELETE");
11711 val ^= DF_1_NODELETE;
11712 }
11713 if (val & DF_1_LOADFLTR)
11714 {
11715 printf (" LOADFLTR");
11716 val ^= DF_1_LOADFLTR;
11717 }
11718 if (val & DF_1_INITFIRST)
11719 {
11720 printf (" INITFIRST");
11721 val ^= DF_1_INITFIRST;
11722 }
11723 if (val & DF_1_NOOPEN)
11724 {
11725 printf (" NOOPEN");
11726 val ^= DF_1_NOOPEN;
11727 }
11728 if (val & DF_1_ORIGIN)
11729 {
11730 printf (" ORIGIN");
11731 val ^= DF_1_ORIGIN;
11732 }
11733 if (val & DF_1_DIRECT)
11734 {
11735 printf (" DIRECT");
11736 val ^= DF_1_DIRECT;
11737 }
11738 if (val & DF_1_TRANS)
11739 {
11740 printf (" TRANS");
11741 val ^= DF_1_TRANS;
11742 }
11743 if (val & DF_1_INTERPOSE)
11744 {
11745 printf (" INTERPOSE");
11746 val ^= DF_1_INTERPOSE;
11747 }
f7db6139 11748 if (val & DF_1_NODEFLIB)
dcefbbbd 11749 {
f7db6139
L
11750 printf (" NODEFLIB");
11751 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11752 }
11753 if (val & DF_1_NODUMP)
11754 {
11755 printf (" NODUMP");
11756 val ^= DF_1_NODUMP;
11757 }
34b60028 11758 if (val & DF_1_CONFALT)
dcefbbbd 11759 {
34b60028
L
11760 printf (" CONFALT");
11761 val ^= DF_1_CONFALT;
11762 }
11763 if (val & DF_1_ENDFILTEE)
11764 {
11765 printf (" ENDFILTEE");
11766 val ^= DF_1_ENDFILTEE;
11767 }
11768 if (val & DF_1_DISPRELDNE)
11769 {
11770 printf (" DISPRELDNE");
11771 val ^= DF_1_DISPRELDNE;
11772 }
11773 if (val & DF_1_DISPRELPND)
11774 {
11775 printf (" DISPRELPND");
11776 val ^= DF_1_DISPRELPND;
11777 }
11778 if (val & DF_1_NODIRECT)
11779 {
11780 printf (" NODIRECT");
11781 val ^= DF_1_NODIRECT;
11782 }
11783 if (val & DF_1_IGNMULDEF)
11784 {
11785 printf (" IGNMULDEF");
11786 val ^= DF_1_IGNMULDEF;
11787 }
11788 if (val & DF_1_NOKSYMS)
11789 {
11790 printf (" NOKSYMS");
11791 val ^= DF_1_NOKSYMS;
11792 }
11793 if (val & DF_1_NOHDR)
11794 {
11795 printf (" NOHDR");
11796 val ^= DF_1_NOHDR;
11797 }
11798 if (val & DF_1_EDITED)
11799 {
11800 printf (" EDITED");
11801 val ^= DF_1_EDITED;
11802 }
11803 if (val & DF_1_NORELOC)
11804 {
11805 printf (" NORELOC");
11806 val ^= DF_1_NORELOC;
11807 }
11808 if (val & DF_1_SYMINTPOSE)
11809 {
11810 printf (" SYMINTPOSE");
11811 val ^= DF_1_SYMINTPOSE;
11812 }
11813 if (val & DF_1_GLOBAUDIT)
11814 {
11815 printf (" GLOBAUDIT");
11816 val ^= DF_1_GLOBAUDIT;
11817 }
11818 if (val & DF_1_SINGLETON)
11819 {
11820 printf (" SINGLETON");
11821 val ^= DF_1_SINGLETON;
dcefbbbd 11822 }
5c383f02
RO
11823 if (val & DF_1_STUB)
11824 {
11825 printf (" STUB");
11826 val ^= DF_1_STUB;
11827 }
11828 if (val & DF_1_PIE)
11829 {
11830 printf (" PIE");
11831 val ^= DF_1_PIE;
11832 }
b1202ffa
L
11833 if (val & DF_1_KMOD)
11834 {
11835 printf (" KMOD");
11836 val ^= DF_1_KMOD;
11837 }
11838 if (val & DF_1_WEAKFILTER)
11839 {
11840 printf (" WEAKFILTER");
11841 val ^= DF_1_WEAKFILTER;
11842 }
11843 if (val & DF_1_NOCOMMON)
11844 {
11845 printf (" NOCOMMON");
11846 val ^= DF_1_NOCOMMON;
11847 }
252b5132 11848 if (val != 0)
26c527e6 11849 printf (" %" PRIx64, val);
252b5132
RH
11850 puts ("");
11851 }
11852 }
11853 break;
11854
11855 case DT_PLTREL:
978c4450 11856 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11857 if (do_dynamic)
dda8d76d 11858 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11859 break;
11860
11861 case DT_NULL :
11862 case DT_NEEDED :
11863 case DT_PLTGOT :
11864 case DT_HASH :
11865 case DT_STRTAB :
11866 case DT_SYMTAB :
11867 case DT_RELA :
11868 case DT_INIT :
11869 case DT_FINI :
11870 case DT_SONAME :
11871 case DT_RPATH :
11872 case DT_SYMBOLIC:
11873 case DT_REL :
a7fd1186 11874 case DT_RELR :
252b5132
RH
11875 case DT_DEBUG :
11876 case DT_TEXTREL :
11877 case DT_JMPREL :
019148e4 11878 case DT_RUNPATH :
978c4450 11879 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11880
11881 if (do_dynamic)
11882 {
84714f86 11883 const char *name;
252b5132 11884
84714f86
AM
11885 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11886 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11887 else
d79b3d50 11888 name = NULL;
252b5132
RH
11889
11890 if (name)
11891 {
11892 switch (entry->d_tag)
11893 {
11894 case DT_NEEDED:
11895 printf (_("Shared library: [%s]"), name);
11896
13acb58d
AM
11897 if (filedata->program_interpreter
11898 && streq (name, filedata->program_interpreter))
f7a99963 11899 printf (_(" program interpreter"));
252b5132
RH
11900 break;
11901
11902 case DT_SONAME:
f7a99963 11903 printf (_("Library soname: [%s]"), name);
252b5132
RH
11904 break;
11905
11906 case DT_RPATH:
f7a99963 11907 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11908 break;
11909
019148e4
L
11910 case DT_RUNPATH:
11911 printf (_("Library runpath: [%s]"), name);
11912 break;
11913
252b5132 11914 default:
f7a99963
NC
11915 print_vma (entry->d_un.d_val, PREFIX_HEX);
11916 break;
252b5132
RH
11917 }
11918 }
11919 else
f7a99963
NC
11920 print_vma (entry->d_un.d_val, PREFIX_HEX);
11921
11922 putchar ('\n');
252b5132
RH
11923 }
11924 break;
11925
11926 case DT_PLTRELSZ:
11927 case DT_RELASZ :
11928 case DT_STRSZ :
11929 case DT_RELSZ :
11930 case DT_RELAENT :
a7fd1186
FS
11931 case DT_RELRENT :
11932 case DT_RELRSZ :
252b5132
RH
11933 case DT_SYMENT :
11934 case DT_RELENT :
978c4450 11935 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11936 /* Fall through. */
252b5132
RH
11937 case DT_PLTPADSZ:
11938 case DT_MOVEENT :
11939 case DT_MOVESZ :
04d8355a 11940 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11941 case DT_INIT_ARRAYSZ:
11942 case DT_FINI_ARRAYSZ:
047b2264
JJ
11943 case DT_GNU_CONFLICTSZ:
11944 case DT_GNU_LIBLISTSZ:
252b5132 11945 if (do_dynamic)
f7a99963
NC
11946 {
11947 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11948 printf (_(" (bytes)\n"));
f7a99963 11949 }
252b5132
RH
11950 break;
11951
11952 case DT_VERDEFNUM:
11953 case DT_VERNEEDNUM:
11954 case DT_RELACOUNT:
11955 case DT_RELCOUNT:
11956 if (do_dynamic)
f7a99963
NC
11957 {
11958 print_vma (entry->d_un.d_val, UNSIGNED);
11959 putchar ('\n');
11960 }
252b5132
RH
11961 break;
11962
11963 case DT_SYMINSZ:
11964 case DT_SYMINENT:
11965 case DT_SYMINFO:
11966 case DT_USED:
11967 case DT_INIT_ARRAY:
11968 case DT_FINI_ARRAY:
11969 if (do_dynamic)
11970 {
d79b3d50 11971 if (entry->d_tag == DT_USED
84714f86 11972 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11973 {
84714f86
AM
11974 const char *name
11975 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11976
b34976b6 11977 if (*name)
252b5132
RH
11978 {
11979 printf (_("Not needed object: [%s]\n"), name);
11980 break;
11981 }
11982 }
103f02d3 11983
f7a99963
NC
11984 print_vma (entry->d_un.d_val, PREFIX_HEX);
11985 putchar ('\n');
252b5132
RH
11986 }
11987 break;
11988
11989 case DT_BIND_NOW:
11990 /* The value of this entry is ignored. */
35b1837e
AM
11991 if (do_dynamic)
11992 putchar ('\n');
252b5132 11993 break;
103f02d3 11994
047b2264
JJ
11995 case DT_GNU_PRELINKED:
11996 if (do_dynamic)
11997 {
2cf0635d 11998 struct tm * tmp;
91d6fa6a 11999 time_t atime = entry->d_un.d_val;
047b2264 12000
91d6fa6a 12001 tmp = gmtime (&atime);
071436c6
NC
12002 /* PR 17533 file: 041-1244816-0.004. */
12003 if (tmp == NULL)
26c527e6
AM
12004 printf (_("<corrupt time val: %" PRIx64),
12005 (uint64_t) atime);
071436c6
NC
12006 else
12007 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12008 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12009 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12010
12011 }
12012 break;
12013
fdc90cb4 12014 case DT_GNU_HASH:
978c4450 12015 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
12016 if (do_dynamic)
12017 {
12018 print_vma (entry->d_un.d_val, PREFIX_HEX);
12019 putchar ('\n');
12020 }
12021 break;
12022
a5da3dee
VDM
12023 case DT_GNU_FLAGS_1:
12024 if (do_dynamic)
12025 {
12026 printf (_("Flags:"));
12027 if (entry->d_un.d_val == 0)
12028 printf (_(" None\n"));
12029 else
12030 {
26c527e6 12031 uint64_t val = entry->d_un.d_val;
a5da3dee
VDM
12032
12033 if (val & DF_GNU_1_UNIQUE)
12034 {
12035 printf (" UNIQUE");
12036 val ^= DF_GNU_1_UNIQUE;
12037 }
12038 if (val != 0)
26c527e6 12039 printf (" %" PRIx64, val);
a5da3dee
VDM
12040 puts ("");
12041 }
12042 }
12043 break;
12044
252b5132
RH
12045 default:
12046 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
12047 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12048 = entry->d_un.d_val;
252b5132
RH
12049
12050 if (do_dynamic)
12051 {
dda8d76d 12052 switch (filedata->file_header.e_machine)
252b5132 12053 {
37c18eed
SD
12054 case EM_AARCH64:
12055 dynamic_section_aarch64_val (entry);
12056 break;
252b5132 12057 case EM_MIPS:
4fe85591 12058 case EM_MIPS_RS3_LE:
978c4450 12059 dynamic_section_mips_val (filedata, entry);
252b5132 12060 break;
103f02d3 12061 case EM_PARISC:
b2d38a17 12062 dynamic_section_parisc_val (entry);
103f02d3 12063 break;
ecc51f48 12064 case EM_IA_64:
b2d38a17 12065 dynamic_section_ia64_val (entry);
ecc51f48 12066 break;
252b5132 12067 default:
f7a99963
NC
12068 print_vma (entry->d_un.d_val, PREFIX_HEX);
12069 putchar ('\n');
252b5132
RH
12070 }
12071 }
12072 break;
12073 }
12074 }
12075
015dc7e1 12076 return true;
252b5132
RH
12077}
12078
12079static char *
d3ba0551 12080get_ver_flags (unsigned int flags)
252b5132 12081{
6d4f21f6 12082 static char buff[128];
252b5132
RH
12083
12084 buff[0] = 0;
12085
12086 if (flags == 0)
12087 return _("none");
12088
12089 if (flags & VER_FLG_BASE)
7bb1ad17 12090 strcat (buff, "BASE");
252b5132
RH
12091
12092 if (flags & VER_FLG_WEAK)
12093 {
12094 if (flags & VER_FLG_BASE)
7bb1ad17 12095 strcat (buff, " | ");
252b5132 12096
7bb1ad17 12097 strcat (buff, "WEAK");
252b5132
RH
12098 }
12099
44ec90b9
RO
12100 if (flags & VER_FLG_INFO)
12101 {
12102 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12103 strcat (buff, " | ");
44ec90b9 12104
7bb1ad17 12105 strcat (buff, "INFO");
44ec90b9
RO
12106 }
12107
12108 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12109 {
12110 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12111 strcat (buff, " | ");
12112
12113 strcat (buff, _("<unknown>"));
12114 }
252b5132
RH
12115
12116 return buff;
12117}
12118
12119/* Display the contents of the version sections. */
98fb390a 12120
015dc7e1 12121static bool
dda8d76d 12122process_version_sections (Filedata * filedata)
252b5132 12123{
2cf0635d 12124 Elf_Internal_Shdr * section;
b34976b6 12125 unsigned i;
015dc7e1 12126 bool found = false;
252b5132
RH
12127
12128 if (! do_version)
015dc7e1 12129 return true;
252b5132 12130
dda8d76d
NC
12131 for (i = 0, section = filedata->section_headers;
12132 i < filedata->file_header.e_shnum;
b34976b6 12133 i++, section++)
252b5132
RH
12134 {
12135 switch (section->sh_type)
12136 {
12137 case SHT_GNU_verdef:
12138 {
2cf0635d 12139 Elf_External_Verdef * edefs;
26c527e6
AM
12140 size_t idx;
12141 size_t cnt;
2cf0635d 12142 char * endbuf;
252b5132 12143
015dc7e1 12144 found = true;
252b5132 12145
ca0e11aa
NC
12146 if (filedata->is_separate)
12147 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12148 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12149 section->sh_info),
12150 filedata->file_name,
12151 printable_section_name (filedata, section),
12152 section->sh_info);
12153 else
12154 printf (ngettext ("\nVersion definition section '%s' "
12155 "contains %u entry:\n",
12156 "\nVersion definition section '%s' "
12157 "contains %u entries:\n",
12158 section->sh_info),
12159 printable_section_name (filedata, section),
12160 section->sh_info);
047c3dbf 12161
625d49fc 12162 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12163 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12164 section->sh_offset, section->sh_link,
dda8d76d 12165 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12166
3f5e193b 12167 edefs = (Elf_External_Verdef *)
dda8d76d 12168 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12169 _("version definition section"));
a6e9f9df
AM
12170 if (!edefs)
12171 break;
59245841 12172 endbuf = (char *) edefs + section->sh_size;
252b5132 12173
1445030f 12174 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12175 {
2cf0635d
NC
12176 char * vstart;
12177 Elf_External_Verdef * edef;
b34976b6 12178 Elf_Internal_Verdef ent;
2cf0635d 12179 Elf_External_Verdaux * eaux;
b34976b6 12180 Elf_Internal_Verdaux aux;
26c527e6 12181 size_t isum;
b34976b6 12182 int j;
103f02d3 12183
252b5132 12184 vstart = ((char *) edefs) + idx;
54806181
AM
12185 if (vstart + sizeof (*edef) > endbuf)
12186 break;
252b5132
RH
12187
12188 edef = (Elf_External_Verdef *) vstart;
12189
12190 ent.vd_version = BYTE_GET (edef->vd_version);
12191 ent.vd_flags = BYTE_GET (edef->vd_flags);
12192 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12193 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12194 ent.vd_hash = BYTE_GET (edef->vd_hash);
12195 ent.vd_aux = BYTE_GET (edef->vd_aux);
12196 ent.vd_next = BYTE_GET (edef->vd_next);
12197
26c527e6 12198 printf (_(" %#06zx: Rev: %d Flags: %s"),
252b5132
RH
12199 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12200
12201 printf (_(" Index: %d Cnt: %d "),
12202 ent.vd_ndx, ent.vd_cnt);
12203
452bf675 12204 /* Check for overflow. */
1445030f 12205 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12206 break;
12207
252b5132
RH
12208 vstart += ent.vd_aux;
12209
1445030f
AM
12210 if (vstart + sizeof (*eaux) > endbuf)
12211 break;
252b5132
RH
12212 eaux = (Elf_External_Verdaux *) vstart;
12213
12214 aux.vda_name = BYTE_GET (eaux->vda_name);
12215 aux.vda_next = BYTE_GET (eaux->vda_next);
12216
84714f86 12217 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12218 printf (_("Name: %s\n"),
84714f86 12219 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12220 else
12221 printf (_("Name index: %ld\n"), aux.vda_name);
12222
12223 isum = idx + ent.vd_aux;
12224
b34976b6 12225 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12226 {
1445030f
AM
12227 if (aux.vda_next < sizeof (*eaux)
12228 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12229 {
12230 warn (_("Invalid vda_next field of %lx\n"),
12231 aux.vda_next);
12232 j = ent.vd_cnt;
12233 break;
12234 }
dd24e3da 12235 /* Check for overflow. */
7e26601c 12236 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12237 break;
12238
252b5132
RH
12239 isum += aux.vda_next;
12240 vstart += aux.vda_next;
12241
54806181
AM
12242 if (vstart + sizeof (*eaux) > endbuf)
12243 break;
1445030f 12244 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12245
12246 aux.vda_name = BYTE_GET (eaux->vda_name);
12247 aux.vda_next = BYTE_GET (eaux->vda_next);
12248
84714f86 12249 if (valid_dynamic_name (filedata, aux.vda_name))
26c527e6 12250 printf (_(" %#06zx: Parent %d: %s\n"),
978c4450 12251 isum, j,
84714f86 12252 get_dynamic_name (filedata, aux.vda_name));
252b5132 12253 else
26c527e6 12254 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
252b5132
RH
12255 isum, j, aux.vda_name);
12256 }
dd24e3da 12257
54806181
AM
12258 if (j < ent.vd_cnt)
12259 printf (_(" Version def aux past end of section\n"));
252b5132 12260
c9f02c3e
MR
12261 /* PR 17531:
12262 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12263 if (ent.vd_next < sizeof (*edef)
12264 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12265 {
12266 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12267 cnt = section->sh_info;
12268 break;
12269 }
452bf675 12270 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12271 break;
12272
252b5132
RH
12273 idx += ent.vd_next;
12274 }
dd24e3da 12275
54806181
AM
12276 if (cnt < section->sh_info)
12277 printf (_(" Version definition past end of section\n"));
252b5132
RH
12278
12279 free (edefs);
12280 }
12281 break;
103f02d3 12282
252b5132
RH
12283 case SHT_GNU_verneed:
12284 {
2cf0635d 12285 Elf_External_Verneed * eneed;
26c527e6
AM
12286 size_t idx;
12287 size_t cnt;
2cf0635d 12288 char * endbuf;
252b5132 12289
015dc7e1 12290 found = true;
252b5132 12291
ca0e11aa
NC
12292 if (filedata->is_separate)
12293 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12294 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12295 section->sh_info),
12296 filedata->file_name,
12297 printable_section_name (filedata, section),
12298 section->sh_info);
12299 else
12300 printf (ngettext ("\nVersion needs section '%s' "
12301 "contains %u entry:\n",
12302 "\nVersion needs section '%s' "
12303 "contains %u entries:\n",
12304 section->sh_info),
12305 printable_section_name (filedata, section),
12306 section->sh_info);
047c3dbf 12307
625d49fc 12308 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12309 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12310 section->sh_offset, section->sh_link,
dda8d76d 12311 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12312
dda8d76d 12313 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12314 section->sh_offset, 1,
12315 section->sh_size,
9cf03b7e 12316 _("Version Needs section"));
a6e9f9df
AM
12317 if (!eneed)
12318 break;
59245841 12319 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12320
12321 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12322 {
2cf0635d 12323 Elf_External_Verneed * entry;
b34976b6 12324 Elf_Internal_Verneed ent;
26c527e6 12325 size_t isum;
b34976b6 12326 int j;
2cf0635d 12327 char * vstart;
252b5132
RH
12328
12329 vstart = ((char *) eneed) + idx;
54806181
AM
12330 if (vstart + sizeof (*entry) > endbuf)
12331 break;
252b5132
RH
12332
12333 entry = (Elf_External_Verneed *) vstart;
12334
12335 ent.vn_version = BYTE_GET (entry->vn_version);
12336 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12337 ent.vn_file = BYTE_GET (entry->vn_file);
12338 ent.vn_aux = BYTE_GET (entry->vn_aux);
12339 ent.vn_next = BYTE_GET (entry->vn_next);
12340
26c527e6 12341 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
252b5132 12342
84714f86 12343 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12344 printf (_(" File: %s"),
84714f86 12345 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12346 else
12347 printf (_(" File: %lx"), ent.vn_file);
12348
12349 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12350
dd24e3da 12351 /* Check for overflow. */
7e26601c 12352 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12353 break;
252b5132
RH
12354 vstart += ent.vn_aux;
12355
12356 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12357 {
2cf0635d 12358 Elf_External_Vernaux * eaux;
b34976b6 12359 Elf_Internal_Vernaux aux;
252b5132 12360
54806181
AM
12361 if (vstart + sizeof (*eaux) > endbuf)
12362 break;
252b5132
RH
12363 eaux = (Elf_External_Vernaux *) vstart;
12364
12365 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12366 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12367 aux.vna_other = BYTE_GET (eaux->vna_other);
12368 aux.vna_name = BYTE_GET (eaux->vna_name);
12369 aux.vna_next = BYTE_GET (eaux->vna_next);
12370
84714f86 12371 if (valid_dynamic_name (filedata, aux.vna_name))
26c527e6 12372 printf (_(" %#06zx: Name: %s"),
84714f86 12373 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12374 else
26c527e6 12375 printf (_(" %#06zx: Name index: %lx"),
252b5132
RH
12376 isum, aux.vna_name);
12377
12378 printf (_(" Flags: %s Version: %d\n"),
12379 get_ver_flags (aux.vna_flags), aux.vna_other);
12380
1445030f
AM
12381 if (aux.vna_next < sizeof (*eaux)
12382 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12383 {
12384 warn (_("Invalid vna_next field of %lx\n"),
12385 aux.vna_next);
12386 j = ent.vn_cnt;
12387 break;
12388 }
1445030f
AM
12389 /* Check for overflow. */
12390 if (aux.vna_next > (size_t) (endbuf - vstart))
12391 break;
252b5132
RH
12392 isum += aux.vna_next;
12393 vstart += aux.vna_next;
12394 }
9cf03b7e 12395
54806181 12396 if (j < ent.vn_cnt)
f9a6a8f0 12397 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12398
1445030f
AM
12399 if (ent.vn_next < sizeof (*entry)
12400 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12401 {
452bf675 12402 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12403 cnt = section->sh_info;
12404 break;
12405 }
1445030f
AM
12406 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12407 break;
252b5132
RH
12408 idx += ent.vn_next;
12409 }
9cf03b7e 12410
54806181 12411 if (cnt < section->sh_info)
9cf03b7e 12412 warn (_("Missing Version Needs information\n"));
103f02d3 12413
252b5132
RH
12414 free (eneed);
12415 }
12416 break;
12417
12418 case SHT_GNU_versym:
12419 {
2cf0635d 12420 Elf_Internal_Shdr * link_section;
26c527e6 12421 uint64_t total;
8b73c356 12422 unsigned int cnt;
2cf0635d
NC
12423 unsigned char * edata;
12424 unsigned short * data;
12425 char * strtab;
12426 Elf_Internal_Sym * symbols;
12427 Elf_Internal_Shdr * string_sec;
26c527e6
AM
12428 uint64_t num_syms;
12429 uint64_t off;
252b5132 12430
dda8d76d 12431 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12432 break;
12433
dda8d76d 12434 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12435 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12436
dda8d76d 12437 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12438 break;
12439
015dc7e1 12440 found = true;
252b5132 12441
4de91c10 12442 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12443 if (symbols == NULL)
12444 break;
252b5132 12445
dda8d76d 12446 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12447
dda8d76d 12448 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12449 string_sec->sh_size,
12450 _("version string table"));
a6e9f9df 12451 if (!strtab)
0429c154
MS
12452 {
12453 free (symbols);
12454 break;
12455 }
252b5132 12456
ca0e11aa 12457 if (filedata->is_separate)
26c527e6
AM
12458 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
12459 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12460 total),
12461 filedata->file_name,
12462 printable_section_name (filedata, section),
26c527e6 12463 total);
ca0e11aa
NC
12464 else
12465 printf (ngettext ("\nVersion symbols section '%s' "
26c527e6 12466 "contains %" PRIu64 " entry:\n",
ca0e11aa 12467 "\nVersion symbols section '%s' "
26c527e6 12468 "contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12469 total),
12470 printable_section_name (filedata, section),
26c527e6 12471 total);
252b5132 12472
625d49fc 12473 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12474 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12475 section->sh_offset, section->sh_link,
dda8d76d 12476 printable_section_name (filedata, link_section));
252b5132 12477
dda8d76d 12478 off = offset_from_vma (filedata,
978c4450 12479 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12480 total * sizeof (short));
95099889
AM
12481 edata = (unsigned char *) get_data (NULL, filedata, off,
12482 sizeof (short), total,
12483 _("version symbol data"));
a6e9f9df
AM
12484 if (!edata)
12485 {
12486 free (strtab);
0429c154 12487 free (symbols);
a6e9f9df
AM
12488 break;
12489 }
252b5132 12490
3f5e193b 12491 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12492
12493 for (cnt = total; cnt --;)
b34976b6
AM
12494 data[cnt] = byte_get (edata + cnt * sizeof (short),
12495 sizeof (short));
252b5132
RH
12496
12497 free (edata);
12498
12499 for (cnt = 0; cnt < total; cnt += 4)
12500 {
12501 int j, nn;
ab273396
AM
12502 char *name;
12503 char *invalid = _("*invalid*");
252b5132
RH
12504
12505 printf (" %03x:", cnt);
12506
12507 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12508 switch (data[cnt + j])
252b5132
RH
12509 {
12510 case 0:
12511 fputs (_(" 0 (*local*) "), stdout);
12512 break;
12513
12514 case 1:
12515 fputs (_(" 1 (*global*) "), stdout);
12516 break;
12517
12518 default:
c244d050
NC
12519 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12520 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12521
dd24e3da 12522 /* If this index value is greater than the size of the symbols
ba5cdace 12523 array, break to avoid an out-of-bounds read. */
26c527e6 12524 if (cnt + j >= num_syms)
dd24e3da
NC
12525 {
12526 warn (_("invalid index into symbol array\n"));
12527 break;
12528 }
12529
ab273396 12530 name = NULL;
978c4450 12531 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12532 {
b34976b6 12533 Elf_Internal_Verneed ivn;
26c527e6 12534 uint64_t offset;
252b5132 12535
d93f0186 12536 offset = offset_from_vma
978c4450
AM
12537 (filedata,
12538 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12539 sizeof (Elf_External_Verneed));
252b5132 12540
b34976b6 12541 do
252b5132 12542 {
b34976b6
AM
12543 Elf_Internal_Vernaux ivna;
12544 Elf_External_Verneed evn;
12545 Elf_External_Vernaux evna;
26c527e6 12546 uint64_t a_off;
252b5132 12547
dda8d76d 12548 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12549 _("version need")) == NULL)
12550 break;
0b4362b0 12551
252b5132
RH
12552 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12553 ivn.vn_next = BYTE_GET (evn.vn_next);
12554
12555 a_off = offset + ivn.vn_aux;
12556
12557 do
12558 {
dda8d76d 12559 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12560 1, _("version need aux (2)")) == NULL)
12561 {
12562 ivna.vna_next = 0;
12563 ivna.vna_other = 0;
12564 }
12565 else
12566 {
12567 ivna.vna_next = BYTE_GET (evna.vna_next);
12568 ivna.vna_other = BYTE_GET (evna.vna_other);
12569 }
252b5132
RH
12570
12571 a_off += ivna.vna_next;
12572 }
b34976b6 12573 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12574 && ivna.vna_next != 0);
12575
b34976b6 12576 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12577 {
12578 ivna.vna_name = BYTE_GET (evna.vna_name);
12579
54806181 12580 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12581 name = invalid;
54806181
AM
12582 else
12583 name = strtab + ivna.vna_name;
252b5132
RH
12584 break;
12585 }
12586
12587 offset += ivn.vn_next;
12588 }
12589 while (ivn.vn_next);
12590 }
00d93f34 12591
ab273396 12592 if (data[cnt + j] != 0x8001
978c4450 12593 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12594 {
b34976b6
AM
12595 Elf_Internal_Verdef ivd;
12596 Elf_External_Verdef evd;
26c527e6 12597 uint64_t offset;
252b5132 12598
d93f0186 12599 offset = offset_from_vma
978c4450
AM
12600 (filedata,
12601 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12602 sizeof evd);
252b5132
RH
12603
12604 do
12605 {
dda8d76d 12606 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12607 _("version def")) == NULL)
12608 {
12609 ivd.vd_next = 0;
948f632f 12610 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12611 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12612 break;
59245841
NC
12613 }
12614 else
12615 {
12616 ivd.vd_next = BYTE_GET (evd.vd_next);
12617 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12618 }
252b5132
RH
12619
12620 offset += ivd.vd_next;
12621 }
c244d050 12622 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12623 && ivd.vd_next != 0);
12624
c244d050 12625 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12626 {
b34976b6
AM
12627 Elf_External_Verdaux evda;
12628 Elf_Internal_Verdaux ivda;
252b5132
RH
12629
12630 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12631
dda8d76d 12632 if (get_data (&evda, filedata,
59245841
NC
12633 offset - ivd.vd_next + ivd.vd_aux,
12634 sizeof (evda), 1,
12635 _("version def aux")) == NULL)
12636 break;
252b5132
RH
12637
12638 ivda.vda_name = BYTE_GET (evda.vda_name);
12639
54806181 12640 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12641 name = invalid;
12642 else if (name != NULL && name != invalid)
12643 name = _("*both*");
54806181
AM
12644 else
12645 name = strtab + ivda.vda_name;
252b5132
RH
12646 }
12647 }
ab273396
AM
12648 if (name != NULL)
12649 nn += printf ("(%s%-*s",
12650 name,
12651 12 - (int) strlen (name),
12652 ")");
252b5132
RH
12653
12654 if (nn < 18)
12655 printf ("%*c", 18 - nn, ' ');
12656 }
12657
12658 putchar ('\n');
12659 }
12660
12661 free (data);
12662 free (strtab);
12663 free (symbols);
12664 }
12665 break;
103f02d3 12666
252b5132
RH
12667 default:
12668 break;
12669 }
12670 }
12671
12672 if (! found)
ca0e11aa
NC
12673 {
12674 if (filedata->is_separate)
12675 printf (_("\nNo version information found in linked file '%s'.\n"),
12676 filedata->file_name);
12677 else
12678 printf (_("\nNo version information found in this file.\n"));
12679 }
252b5132 12680
015dc7e1 12681 return true;
252b5132
RH
12682}
12683
d1133906 12684static const char *
dda8d76d 12685get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12686{
89246a0e 12687 static char buff[64];
252b5132
RH
12688
12689 switch (binding)
12690 {
b34976b6
AM
12691 case STB_LOCAL: return "LOCAL";
12692 case STB_GLOBAL: return "GLOBAL";
12693 case STB_WEAK: return "WEAK";
252b5132
RH
12694 default:
12695 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12696 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12697 binding);
252b5132 12698 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12699 {
12700 if (binding == STB_GNU_UNIQUE
df3a023b 12701 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12702 return "UNIQUE";
12703 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12704 }
252b5132 12705 else
e9e44622 12706 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12707 return buff;
12708 }
12709}
12710
d1133906 12711static const char *
dda8d76d 12712get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12713{
89246a0e 12714 static char buff[64];
252b5132
RH
12715
12716 switch (type)
12717 {
b34976b6
AM
12718 case STT_NOTYPE: return "NOTYPE";
12719 case STT_OBJECT: return "OBJECT";
12720 case STT_FUNC: return "FUNC";
12721 case STT_SECTION: return "SECTION";
12722 case STT_FILE: return "FILE";
12723 case STT_COMMON: return "COMMON";
12724 case STT_TLS: return "TLS";
15ab5209
DB
12725 case STT_RELC: return "RELC";
12726 case STT_SRELC: return "SRELC";
252b5132
RH
12727 default:
12728 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12729 {
dda8d76d 12730 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12731 return "THUMB_FUNC";
103f02d3 12732
dda8d76d 12733 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12734 return "REGISTER";
12735
dda8d76d 12736 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12737 return "PARISC_MILLI";
12738
e9e44622 12739 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12740 }
252b5132 12741 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12742 {
dda8d76d 12743 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12744 {
12745 if (type == STT_HP_OPAQUE)
12746 return "HP_OPAQUE";
12747 if (type == STT_HP_STUB)
12748 return "HP_STUB";
12749 }
12750
8654c01f
ML
12751 if (type == STT_GNU_IFUNC
12752 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
12753 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
12754 return "IFUNC";
12755
e9e44622 12756 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12757 }
252b5132 12758 else
e9e44622 12759 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12760 return buff;
12761 }
12762}
12763
d1133906 12764static const char *
d3ba0551 12765get_symbol_visibility (unsigned int visibility)
d1133906
NC
12766{
12767 switch (visibility)
12768 {
b34976b6
AM
12769 case STV_DEFAULT: return "DEFAULT";
12770 case STV_INTERNAL: return "INTERNAL";
12771 case STV_HIDDEN: return "HIDDEN";
d1133906 12772 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12773 default:
27a45f42 12774 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12775 return _("<unknown>");
d1133906
NC
12776 }
12777}
12778
2057d69d
CZ
12779static const char *
12780get_alpha_symbol_other (unsigned int other)
9abca702 12781{
2057d69d
CZ
12782 switch (other)
12783 {
12784 case STO_ALPHA_NOPV: return "NOPV";
12785 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12786 default:
27a45f42 12787 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12788 return _("<unknown>");
9abca702 12789 }
2057d69d
CZ
12790}
12791
fd85a6a1
NC
12792static const char *
12793get_solaris_symbol_visibility (unsigned int visibility)
12794{
12795 switch (visibility)
12796 {
12797 case 4: return "EXPORTED";
12798 case 5: return "SINGLETON";
12799 case 6: return "ELIMINATE";
12800 default: return get_symbol_visibility (visibility);
12801 }
12802}
12803
2301ed1c
SN
12804static const char *
12805get_aarch64_symbol_other (unsigned int other)
12806{
12807 static char buf[32];
12808
12809 if (other & STO_AARCH64_VARIANT_PCS)
12810 {
12811 other &= ~STO_AARCH64_VARIANT_PCS;
12812 if (other == 0)
12813 return "VARIANT_PCS";
12814 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12815 return buf;
12816 }
12817 return NULL;
12818}
12819
5e2b0d47
NC
12820static const char *
12821get_mips_symbol_other (unsigned int other)
12822{
12823 switch (other)
12824 {
32ec8896
NC
12825 case STO_OPTIONAL: return "OPTIONAL";
12826 case STO_MIPS_PLT: return "MIPS PLT";
12827 case STO_MIPS_PIC: return "MIPS PIC";
12828 case STO_MICROMIPS: return "MICROMIPS";
12829 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12830 case STO_MIPS16: return "MIPS16";
12831 default: return NULL;
5e2b0d47
NC
12832 }
12833}
12834
28f997cf 12835static const char *
dda8d76d 12836get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12837{
dda8d76d 12838 if (is_ia64_vms (filedata))
28f997cf
TG
12839 {
12840 static char res[32];
12841
12842 res[0] = 0;
12843
12844 /* Function types is for images and .STB files only. */
dda8d76d 12845 switch (filedata->file_header.e_type)
28f997cf
TG
12846 {
12847 case ET_DYN:
12848 case ET_EXEC:
12849 switch (VMS_ST_FUNC_TYPE (other))
12850 {
12851 case VMS_SFT_CODE_ADDR:
12852 strcat (res, " CA");
12853 break;
12854 case VMS_SFT_SYMV_IDX:
12855 strcat (res, " VEC");
12856 break;
12857 case VMS_SFT_FD:
12858 strcat (res, " FD");
12859 break;
12860 case VMS_SFT_RESERVE:
12861 strcat (res, " RSV");
12862 break;
12863 default:
bee0ee85
NC
12864 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12865 VMS_ST_FUNC_TYPE (other));
12866 strcat (res, " <unknown>");
12867 break;
28f997cf
TG
12868 }
12869 break;
12870 default:
12871 break;
12872 }
12873 switch (VMS_ST_LINKAGE (other))
12874 {
12875 case VMS_STL_IGNORE:
12876 strcat (res, " IGN");
12877 break;
12878 case VMS_STL_RESERVE:
12879 strcat (res, " RSV");
12880 break;
12881 case VMS_STL_STD:
12882 strcat (res, " STD");
12883 break;
12884 case VMS_STL_LNK:
12885 strcat (res, " LNK");
12886 break;
12887 default:
bee0ee85
NC
12888 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12889 VMS_ST_LINKAGE (other));
12890 strcat (res, " <unknown>");
12891 break;
28f997cf
TG
12892 }
12893
12894 if (res[0] != 0)
12895 return res + 1;
12896 else
12897 return res;
12898 }
12899 return NULL;
12900}
12901
6911b7dc
AM
12902static const char *
12903get_ppc64_symbol_other (unsigned int other)
12904{
14732552
AM
12905 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12906 return NULL;
12907
12908 other >>= STO_PPC64_LOCAL_BIT;
12909 if (other <= 6)
6911b7dc 12910 {
89246a0e 12911 static char buf[64];
14732552
AM
12912 if (other >= 2)
12913 other = ppc64_decode_local_entry (other);
12914 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12915 return buf;
12916 }
12917 return NULL;
12918}
12919
8155b853
NC
12920static const char *
12921get_riscv_symbol_other (unsigned int other)
12922{
12923 static char buf[32];
12924 buf[0] = 0;
12925
12926 if (other & STO_RISCV_VARIANT_CC)
12927 {
12928 strcat (buf, _(" VARIANT_CC"));
12929 other &= ~STO_RISCV_VARIANT_CC;
12930 }
12931
12932 if (other != 0)
12933 snprintf (buf, sizeof buf, " %x", other);
12934
12935
12936 if (buf[0] != 0)
12937 return buf + 1;
12938 else
12939 return buf;
12940}
12941
5e2b0d47 12942static const char *
dda8d76d 12943get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12944{
12945 const char * result = NULL;
89246a0e 12946 static char buff [64];
5e2b0d47
NC
12947
12948 if (other == 0)
12949 return "";
12950
dda8d76d 12951 switch (filedata->file_header.e_machine)
5e2b0d47 12952 {
2057d69d
CZ
12953 case EM_ALPHA:
12954 result = get_alpha_symbol_other (other);
12955 break;
2301ed1c
SN
12956 case EM_AARCH64:
12957 result = get_aarch64_symbol_other (other);
12958 break;
5e2b0d47
NC
12959 case EM_MIPS:
12960 result = get_mips_symbol_other (other);
28f997cf
TG
12961 break;
12962 case EM_IA_64:
dda8d76d 12963 result = get_ia64_symbol_other (filedata, other);
28f997cf 12964 break;
6911b7dc
AM
12965 case EM_PPC64:
12966 result = get_ppc64_symbol_other (other);
12967 break;
8155b853
NC
12968 case EM_RISCV:
12969 result = get_riscv_symbol_other (other);
12970 break;
5e2b0d47 12971 default:
fd85a6a1 12972 result = NULL;
5e2b0d47
NC
12973 break;
12974 }
12975
12976 if (result)
12977 return result;
12978
12979 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12980 return buff;
12981}
12982
d1133906 12983static const char *
dda8d76d 12984get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12985{
b34976b6 12986 static char buff[32];
5cf1065c 12987
252b5132
RH
12988 switch (type)
12989 {
b34976b6
AM
12990 case SHN_UNDEF: return "UND";
12991 case SHN_ABS: return "ABS";
12992 case SHN_COMMON: return "COM";
252b5132 12993 default:
9ce701e2 12994 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12995 && filedata->file_header.e_machine == EM_IA_64
12996 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12997 return "ANSI_COM";
12998 else if ((filedata->file_header.e_machine == EM_X86_64
12999 || filedata->file_header.e_machine == EM_L1OM
13000 || filedata->file_header.e_machine == EM_K1OM)
13001 && type == SHN_X86_64_LCOMMON)
13002 return "LARGE_COM";
13003 else if ((type == SHN_MIPS_SCOMMON
13004 && filedata->file_header.e_machine == EM_MIPS)
13005 || (type == SHN_TIC6X_SCOMMON
13006 && filedata->file_header.e_machine == EM_TI_C6000))
13007 return "SCOM";
13008 else if (type == SHN_MIPS_SUNDEFINED
13009 && filedata->file_header.e_machine == EM_MIPS)
13010 return "SUND";
13011 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
13012 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
13013 else if (type >= SHN_LOOS && type <= SHN_HIOS)
13014 sprintf (buff, "OS [0x%04x]", type & 0xffff);
13015 else if (type >= SHN_LORESERVE)
13016 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
13017 else if (filedata->file_header.e_shnum != 0
13018 && type >= filedata->file_header.e_shnum)
13019 sprintf (buff, _("bad section index[%3d]"), type);
13020 else
13021 sprintf (buff, "%3d", type);
13022 break;
fd85a6a1
NC
13023 }
13024
10ca4b04 13025 return buff;
6bd1a22c
L
13026}
13027
bb4d2ac2 13028static const char *
26c527e6
AM
13029get_symbol_version_string (Filedata *filedata,
13030 bool is_dynsym,
13031 const char *strtab,
13032 size_t strtab_size,
13033 unsigned int si,
13034 Elf_Internal_Sym *psym,
13035 enum versioned_symbol_info *sym_info,
13036 unsigned short *vna_other)
bb4d2ac2 13037{
ab273396
AM
13038 unsigned char data[2];
13039 unsigned short vers_data;
26c527e6 13040 uint64_t offset;
7a815dd5 13041 unsigned short max_vd_ndx;
bb4d2ac2 13042
ab273396 13043 if (!is_dynsym
978c4450 13044 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 13045 return NULL;
bb4d2ac2 13046
978c4450
AM
13047 offset = offset_from_vma (filedata,
13048 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 13049 sizeof data + si * sizeof (vers_data));
bb4d2ac2 13050
dda8d76d 13051 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
13052 sizeof (data), 1, _("version data")) == NULL)
13053 return NULL;
13054
13055 vers_data = byte_get (data, 2);
bb4d2ac2 13056
1f6f5dba 13057 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 13058 return NULL;
bb4d2ac2 13059
0b8b7609 13060 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
13061 max_vd_ndx = 0;
13062
ab273396
AM
13063 /* Usually we'd only see verdef for defined symbols, and verneed for
13064 undefined symbols. However, symbols defined by the linker in
13065 .dynbss for variables copied from a shared library in order to
13066 avoid text relocations are defined yet have verneed. We could
13067 use a heuristic to detect the special case, for example, check
13068 for verneed first on symbols defined in SHT_NOBITS sections, but
13069 it is simpler and more reliable to just look for both verdef and
13070 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13071
ab273396
AM
13072 if (psym->st_shndx != SHN_UNDEF
13073 && vers_data != 0x8001
978c4450 13074 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13075 {
13076 Elf_Internal_Verdef ivd;
13077 Elf_Internal_Verdaux ivda;
13078 Elf_External_Verdaux evda;
26c527e6 13079 uint64_t off;
bb4d2ac2 13080
dda8d76d 13081 off = offset_from_vma (filedata,
978c4450 13082 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13083 sizeof (Elf_External_Verdef));
13084
13085 do
bb4d2ac2 13086 {
ab273396
AM
13087 Elf_External_Verdef evd;
13088
dda8d76d 13089 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13090 _("version def")) == NULL)
13091 {
13092 ivd.vd_ndx = 0;
13093 ivd.vd_aux = 0;
13094 ivd.vd_next = 0;
1f6f5dba 13095 ivd.vd_flags = 0;
ab273396
AM
13096 }
13097 else
bb4d2ac2 13098 {
ab273396
AM
13099 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13100 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13101 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13102 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13103 }
bb4d2ac2 13104
7a815dd5
L
13105 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13106 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13107
ab273396
AM
13108 off += ivd.vd_next;
13109 }
13110 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13111
ab273396
AM
13112 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13113 {
9abca702 13114 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13115 return NULL;
13116
ab273396
AM
13117 off -= ivd.vd_next;
13118 off += ivd.vd_aux;
bb4d2ac2 13119
dda8d76d 13120 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13121 _("version def aux")) != NULL)
13122 {
13123 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13124
ab273396 13125 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13126 return (ivda.vda_name < strtab_size
13127 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13128 }
13129 }
13130 }
bb4d2ac2 13131
978c4450 13132 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13133 {
13134 Elf_External_Verneed evn;
13135 Elf_Internal_Verneed ivn;
13136 Elf_Internal_Vernaux ivna;
bb4d2ac2 13137
dda8d76d 13138 offset = offset_from_vma (filedata,
978c4450 13139 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13140 sizeof evn);
13141 do
13142 {
26c527e6 13143 uint64_t vna_off;
bb4d2ac2 13144
dda8d76d 13145 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13146 _("version need")) == NULL)
13147 {
13148 ivna.vna_next = 0;
13149 ivna.vna_other = 0;
13150 ivna.vna_name = 0;
13151 break;
13152 }
bb4d2ac2 13153
ab273396
AM
13154 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13155 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13156
ab273396 13157 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13158
ab273396
AM
13159 do
13160 {
13161 Elf_External_Vernaux evna;
bb4d2ac2 13162
dda8d76d 13163 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13164 _("version need aux (3)")) == NULL)
bb4d2ac2 13165 {
ab273396
AM
13166 ivna.vna_next = 0;
13167 ivna.vna_other = 0;
13168 ivna.vna_name = 0;
bb4d2ac2 13169 }
bb4d2ac2 13170 else
bb4d2ac2 13171 {
ab273396
AM
13172 ivna.vna_other = BYTE_GET (evna.vna_other);
13173 ivna.vna_next = BYTE_GET (evna.vna_next);
13174 ivna.vna_name = BYTE_GET (evna.vna_name);
13175 }
bb4d2ac2 13176
ab273396
AM
13177 vna_off += ivna.vna_next;
13178 }
13179 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13180
ab273396
AM
13181 if (ivna.vna_other == vers_data)
13182 break;
bb4d2ac2 13183
ab273396
AM
13184 offset += ivn.vn_next;
13185 }
13186 while (ivn.vn_next != 0);
bb4d2ac2 13187
ab273396
AM
13188 if (ivna.vna_other == vers_data)
13189 {
13190 *sym_info = symbol_undefined;
13191 *vna_other = ivna.vna_other;
13192 return (ivna.vna_name < strtab_size
13193 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13194 }
7a815dd5
L
13195 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13196 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13197 return _("<corrupt>");
bb4d2ac2 13198 }
ab273396 13199 return NULL;
bb4d2ac2
L
13200}
13201
047c3dbf
NL
13202/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13203
13204static unsigned int
625d49fc 13205print_dynamic_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13206{
13207 switch (base)
13208 {
13209 case 8:
13210 return print_vma (vma, OCTAL_5);
13211
13212 case 10:
13213 return print_vma (vma, UNSIGNED_5);
13214
13215 case 16:
13216 return print_vma (vma, PREFIX_HEX_5);
13217
13218 case 0:
13219 default:
13220 return print_vma (vma, DEC_5);
13221 }
13222}
13223
10ca4b04 13224static void
26c527e6 13225print_dynamic_symbol (Filedata *filedata, uint64_t si,
10ca4b04
L
13226 Elf_Internal_Sym *symtab,
13227 Elf_Internal_Shdr *section,
13228 char *strtab, size_t strtab_size)
252b5132 13229{
10ca4b04
L
13230 const char *version_string;
13231 enum versioned_symbol_info sym_info;
13232 unsigned short vna_other;
23356397
NC
13233 bool is_valid;
13234 const char * sstr;
10ca4b04 13235 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13236
26c527e6 13237 printf ("%6" PRId64 ": ", si);
10ca4b04
L
13238 print_vma (psym->st_value, LONG_HEX);
13239 putchar (' ');
047c3dbf 13240 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13241 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13242 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13243 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13244 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13245 else
252b5132 13246 {
10ca4b04 13247 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13248
10ca4b04
L
13249 printf (" %-7s", get_symbol_visibility (vis));
13250 /* Check to see if any other bits in the st_other field are set.
13251 Note - displaying this information disrupts the layout of the
13252 table being generated, but for the moment this case is very rare. */
13253 if (psym->st_other ^ vis)
13254 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13255 }
10ca4b04 13256 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13257
23356397
NC
13258 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13259 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13260 && filedata->section_headers != NULL
23356397
NC
13261 && psym->st_name == 0)
13262 {
84714f86
AM
13263 is_valid
13264 = section_name_valid (filedata,
13265 filedata->section_headers + psym->st_shndx);
23356397 13266 sstr = is_valid ?
84714f86
AM
13267 section_name_print (filedata,
13268 filedata->section_headers + psym->st_shndx)
23356397
NC
13269 : _("<corrupt>");
13270 }
13271 else
13272 {
84714f86 13273 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13274 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13275 }
10ca4b04
L
13276
13277 version_string
13278 = get_symbol_version_string (filedata,
13279 (section == NULL
13280 || section->sh_type == SHT_DYNSYM),
13281 strtab, strtab_size, si,
13282 psym, &sym_info, &vna_other);
b9e920ec 13283
0942c7ab
NC
13284 int len_avail = 21;
13285 if (! do_wide && version_string != NULL)
13286 {
ddb43bab 13287 char buffer[16];
0942c7ab 13288
ddb43bab 13289 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13290
13291 if (sym_info == symbol_undefined)
13292 len_avail -= sprintf (buffer," (%d)", vna_other);
13293 else if (sym_info != symbol_hidden)
13294 len_avail -= 1;
13295 }
13296
13297 print_symbol (len_avail, sstr);
b9e920ec 13298
10ca4b04
L
13299 if (version_string)
13300 {
13301 if (sym_info == symbol_undefined)
13302 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13303 else
10ca4b04
L
13304 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13305 version_string);
13306 }
6bd1a22c 13307
10ca4b04 13308 putchar ('\n');
6bd1a22c 13309
10ca4b04
L
13310 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13311 && section != NULL
13312 && si >= section->sh_info
13313 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13314 && filedata->file_header.e_machine != EM_MIPS
13315 /* Solaris binaries have been found to violate this requirement as
13316 well. Not sure if this is a bug or an ABI requirement. */
13317 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
26c527e6 13318 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
10ca4b04
L
13319 si, printable_section_name (filedata, section), section->sh_info);
13320}
f16a9783 13321
0f03783c
NC
13322static const char *
13323get_lto_kind (unsigned int kind)
13324{
13325 switch (kind)
13326 {
13327 case 0: return "DEF";
13328 case 1: return "WEAKDEF";
13329 case 2: return "UNDEF";
13330 case 3: return "WEAKUNDEF";
13331 case 4: return "COMMON";
13332 default:
13333 break;
13334 }
13335
13336 static char buffer[30];
13337 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13338 sprintf (buffer, "<unknown: %u>", kind);
13339 return buffer;
13340}
13341
13342static const char *
13343get_lto_visibility (unsigned int visibility)
13344{
13345 switch (visibility)
13346 {
13347 case 0: return "DEFAULT";
13348 case 1: return "PROTECTED";
13349 case 2: return "INTERNAL";
13350 case 3: return "HIDDEN";
13351 default:
13352 break;
13353 }
13354
13355 static char buffer[30];
13356 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13357 sprintf (buffer, "<unknown: %u>", visibility);
13358 return buffer;
13359}
13360
13361static const char *
13362get_lto_sym_type (unsigned int sym_type)
13363{
13364 switch (sym_type)
13365 {
13366 case 0: return "UNKNOWN";
13367 case 1: return "FUNCTION";
13368 case 2: return "VARIABLE";
13369 default:
13370 break;
13371 }
13372
13373 static char buffer[30];
13374 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13375 sprintf (buffer, "<unknown: %u>", sym_type);
13376 return buffer;
13377}
13378
13379/* Display an LTO format symbol table.
13380 FIXME: The format of LTO symbol tables is not formalized.
13381 So this code could need changing in the future. */
13382
015dc7e1 13383static bool
0f03783c
NC
13384display_lto_symtab (Filedata * filedata,
13385 Elf_Internal_Shdr * section)
13386{
13387 if (section->sh_size == 0)
13388 {
ca0e11aa
NC
13389 if (filedata->is_separate)
13390 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13391 printable_section_name (filedata, section),
13392 filedata->file_name);
13393 else
13394 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13395 printable_section_name (filedata, section));
047c3dbf 13396
015dc7e1 13397 return true;
0f03783c
NC
13398 }
13399
13400 if (section->sh_size > filedata->file_size)
13401 {
26c527e6 13402 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
0f03783c 13403 printable_section_name (filedata, section),
26c527e6 13404 section->sh_size);
015dc7e1 13405 return false;
0f03783c
NC
13406 }
13407
13408 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13409 section->sh_size, 1, _("LTO symbols"));
13410 if (alloced_data == NULL)
015dc7e1 13411 return false;
0f03783c
NC
13412
13413 /* Look for extended data for the symbol table. */
13414 Elf_Internal_Shdr * ext;
13415 void * ext_data_orig = NULL;
13416 char * ext_data = NULL;
13417 char * ext_data_end = NULL;
13418 char * ext_name = NULL;
13419
13420 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13421 (section_name (filedata, section)
13422 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13423 && ext_name != NULL /* Paranoia. */
13424 && (ext = find_section (filedata, ext_name)) != NULL)
13425 {
13426 if (ext->sh_size < 3)
13427 error (_("LTO Symbol extension table '%s' is empty!\n"),
13428 printable_section_name (filedata, ext));
13429 else
13430 {
13431 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13432 ext->sh_size, 1,
13433 _("LTO ext symbol data"));
13434 if (ext_data != NULL)
13435 {
13436 ext_data_end = ext_data + ext->sh_size;
13437 if (* ext_data++ != 1)
13438 error (_("Unexpected version number in symbol extension table\n"));
13439 }
13440 }
13441 }
b9e920ec 13442
0f03783c
NC
13443 const unsigned char * data = (const unsigned char *) alloced_data;
13444 const unsigned char * end = data + section->sh_size;
13445
ca0e11aa
NC
13446 if (filedata->is_separate)
13447 printf (_("\nIn linked file '%s': "), filedata->file_name);
13448 else
13449 printf ("\n");
13450
0f03783c
NC
13451 if (ext_data_orig != NULL)
13452 {
13453 if (do_wide)
ca0e11aa 13454 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13455 printable_section_name (filedata, section),
13456 printable_section_name (filedata, ext));
13457 else
13458 {
ca0e11aa 13459 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13460 printable_section_name (filedata, section));
13461 printf (_(" and extension table '%s' contain:\n"),
13462 printable_section_name (filedata, ext));
13463 }
13464 }
13465 else
ca0e11aa 13466 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13467 printable_section_name (filedata, section));
b9e920ec 13468
0f03783c 13469 /* FIXME: Add a wide version. */
b9e920ec 13470 if (ext_data_orig != NULL)
0f03783c
NC
13471 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13472 else
13473 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13474
13475 /* FIXME: We do not handle style prefixes. */
13476
13477 while (data < end)
13478 {
13479 const unsigned char * sym_name = data;
13480 data += strnlen ((const char *) sym_name, end - data) + 1;
13481 if (data >= end)
13482 goto fail;
13483
13484 const unsigned char * comdat_key = data;
13485 data += strnlen ((const char *) comdat_key, end - data) + 1;
13486 if (data >= end)
13487 goto fail;
13488
13489 if (data + 2 + 8 + 4 > end)
13490 goto fail;
13491
13492 unsigned int kind = *data++;
13493 unsigned int visibility = *data++;
13494
928c411d 13495 uint64_t size = byte_get (data, 8);
0f03783c
NC
13496 data += 8;
13497
928c411d 13498 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13499 data += 4;
13500
13501 if (ext_data != NULL)
13502 {
13503 if (ext_data < (ext_data_end - 1))
13504 {
13505 unsigned int sym_type = * ext_data ++;
13506 unsigned int sec_kind = * ext_data ++;
13507
31e5a3a3 13508 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
13509 * comdat_key == 0 ? "-" : (char *) comdat_key,
13510 get_lto_kind (kind),
13511 get_lto_visibility (visibility),
31e5a3a3
AM
13512 size,
13513 slot,
0f03783c 13514 get_lto_sym_type (sym_type),
31e5a3a3 13515 sec_kind);
0f03783c
NC
13516 print_symbol (6, (const char *) sym_name);
13517 }
13518 else
13519 {
13520 error (_("Ran out of LTO symbol extension data\n"));
13521 ext_data = NULL;
13522 /* FIXME: return FAIL result ? */
13523 }
13524 }
13525 else
13526 {
31e5a3a3 13527 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
13528 * comdat_key == 0 ? "-" : (char *) comdat_key,
13529 get_lto_kind (kind),
13530 get_lto_visibility (visibility),
31e5a3a3
AM
13531 size,
13532 slot);
0f03783c
NC
13533 print_symbol (21, (const char *) sym_name);
13534 }
13535 putchar ('\n');
13536 }
13537
13538 if (ext_data != NULL && ext_data < ext_data_end)
13539 {
13540 error (_("Data remains in the LTO symbol extension table\n"));
13541 goto fail;
13542 }
13543
13544 free (alloced_data);
13545 free (ext_data_orig);
13546 free (ext_name);
015dc7e1 13547 return true;
b9e920ec 13548
0f03783c
NC
13549 fail:
13550 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13551 free (alloced_data);
13552 free (ext_data_orig);
13553 free (ext_name);
015dc7e1 13554 return false;
0f03783c
NC
13555}
13556
13557/* Display LTO symbol tables. */
13558
015dc7e1 13559static bool
0f03783c
NC
13560process_lto_symbol_tables (Filedata * filedata)
13561{
13562 Elf_Internal_Shdr * section;
13563 unsigned int i;
015dc7e1 13564 bool res = true;
0f03783c
NC
13565
13566 if (!do_lto_syms)
015dc7e1 13567 return true;
0f03783c
NC
13568
13569 if (filedata->section_headers == NULL)
015dc7e1 13570 return true;
0f03783c
NC
13571
13572 for (i = 0, section = filedata->section_headers;
13573 i < filedata->file_header.e_shnum;
13574 i++, section++)
84714f86
AM
13575 if (section_name_valid (filedata, section)
13576 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13577 res &= display_lto_symtab (filedata, section);
13578
b9e920ec 13579 return res;
0f03783c
NC
13580}
13581
10ca4b04 13582/* Dump the symbol table. */
0f03783c 13583
015dc7e1 13584static bool
10ca4b04
L
13585process_symbol_table (Filedata * filedata)
13586{
13587 Elf_Internal_Shdr * section;
f16a9783 13588
10ca4b04 13589 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13590 return true;
6bd1a22c 13591
978c4450 13592 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13593 && do_syms
13594 && do_using_dynamic
978c4450
AM
13595 && filedata->dynamic_strings != NULL
13596 && filedata->dynamic_symbols != NULL)
6bd1a22c 13597 {
26c527e6 13598 uint64_t si;
6bd1a22c 13599
ca0e11aa
NC
13600 if (filedata->is_separate)
13601 {
26c527e6
AM
13602 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
13603 " contains %" PRIu64 " entry:\n",
13604 "\nIn linked file '%s' the dynamic symbol table"
13605 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13606 filedata->num_dynamic_syms),
13607 filedata->file_name,
13608 filedata->num_dynamic_syms);
13609 }
13610 else
13611 {
26c527e6
AM
13612 printf (ngettext ("\nSymbol table for image contains %" PRIu64
13613 " entry:\n",
13614 "\nSymbol table for image contains %" PRIu64
13615 " entries:\n",
ca0e11aa
NC
13616 filedata->num_dynamic_syms),
13617 filedata->num_dynamic_syms);
13618 }
10ca4b04
L
13619 if (is_32bit_elf)
13620 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13621 else
13622 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13623
978c4450
AM
13624 for (si = 0; si < filedata->num_dynamic_syms; si++)
13625 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13626 filedata->dynamic_strings,
13627 filedata->dynamic_strings_length);
252b5132 13628 }
8b73c356 13629 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13630 && filedata->section_headers != NULL)
252b5132 13631 {
b34976b6 13632 unsigned int i;
252b5132 13633
dda8d76d
NC
13634 for (i = 0, section = filedata->section_headers;
13635 i < filedata->file_header.e_shnum;
252b5132
RH
13636 i++, section++)
13637 {
2cf0635d 13638 char * strtab = NULL;
26c527e6 13639 uint64_t strtab_size = 0;
2cf0635d 13640 Elf_Internal_Sym * symtab;
26c527e6 13641 uint64_t si, num_syms;
252b5132 13642
2c610e4b
L
13643 if ((section->sh_type != SHT_SYMTAB
13644 && section->sh_type != SHT_DYNSYM)
13645 || (!do_syms
13646 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13647 continue;
13648
dd24e3da
NC
13649 if (section->sh_entsize == 0)
13650 {
13651 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13652 printable_section_name (filedata, section));
dd24e3da
NC
13653 continue;
13654 }
13655
d3a49aa8 13656 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13657
13658 if (filedata->is_separate)
26c527e6
AM
13659 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
13660 " contains %" PRIu64 " entry:\n",
13661 "\nIn linked file '%s' symbol section '%s'"
13662 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13663 num_syms),
13664 filedata->file_name,
13665 printable_section_name (filedata, section),
13666 num_syms);
13667 else
26c527e6
AM
13668 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
13669 " entry:\n",
13670 "\nSymbol table '%s' contains %" PRIu64
13671 " entries:\n",
ca0e11aa
NC
13672 num_syms),
13673 printable_section_name (filedata, section),
13674 num_syms);
dd24e3da 13675
f7a99963 13676 if (is_32bit_elf)
ca47b30c 13677 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13678 else
ca47b30c 13679 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13680
4de91c10 13681 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13682 if (symtab == NULL)
13683 continue;
13684
dda8d76d 13685 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13686 {
dda8d76d
NC
13687 strtab = filedata->string_table;
13688 strtab_size = filedata->string_table_length;
c256ffe7 13689 }
dda8d76d 13690 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13691 {
2cf0635d 13692 Elf_Internal_Shdr * string_sec;
252b5132 13693
dda8d76d 13694 string_sec = filedata->section_headers + section->sh_link;
252b5132 13695
dda8d76d 13696 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13697 1, string_sec->sh_size,
13698 _("string table"));
c256ffe7 13699 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13700 }
13701
10ca4b04
L
13702 for (si = 0; si < num_syms; si++)
13703 print_dynamic_symbol (filedata, si, symtab, section,
13704 strtab, strtab_size);
252b5132
RH
13705
13706 free (symtab);
dda8d76d 13707 if (strtab != filedata->string_table)
252b5132
RH
13708 free (strtab);
13709 }
13710 }
13711 else if (do_syms)
13712 printf
13713 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13714
978c4450 13715 if (do_histogram && filedata->buckets != NULL)
252b5132 13716 {
26c527e6
AM
13717 uint64_t *lengths;
13718 uint64_t *counts;
13719 uint64_t hn;
625d49fc 13720 uint64_t si;
26c527e6
AM
13721 uint64_t maxlength = 0;
13722 uint64_t nzero_counts = 0;
13723 uint64_t nsyms = 0;
6bd6a03d 13724 char *visited;
252b5132 13725
d3a49aa8 13726 printf (ngettext ("\nHistogram for bucket list length "
26c527e6 13727 "(total of %" PRIu64 " bucket):\n",
d3a49aa8 13728 "\nHistogram for bucket list length "
26c527e6
AM
13729 "(total of %" PRIu64 " buckets):\n",
13730 filedata->nbuckets),
13731 filedata->nbuckets);
252b5132 13732
26c527e6 13733 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
252b5132
RH
13734 if (lengths == NULL)
13735 {
8b73c356 13736 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13737 goto err_out;
252b5132 13738 }
978c4450
AM
13739 visited = xcmalloc (filedata->nchains, 1);
13740 memset (visited, 0, filedata->nchains);
8b73c356
NC
13741
13742 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13743 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13744 {
978c4450 13745 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13746 {
b34976b6 13747 ++nsyms;
252b5132 13748 if (maxlength < ++lengths[hn])
b34976b6 13749 ++maxlength;
978c4450 13750 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13751 {
13752 error (_("histogram chain is corrupt\n"));
13753 break;
13754 }
13755 visited[si] = 1;
252b5132
RH
13756 }
13757 }
6bd6a03d 13758 free (visited);
252b5132 13759
26c527e6 13760 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13761 if (counts == NULL)
13762 {
b2e951ec 13763 free (lengths);
8b73c356 13764 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13765 goto err_out;
252b5132
RH
13766 }
13767
978c4450 13768 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13769 ++counts[lengths[hn]];
252b5132 13770
978c4450 13771 if (filedata->nbuckets > 0)
252b5132 13772 {
26c527e6
AM
13773 uint64_t i;
13774 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 13775 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13776 for (i = 1; i <= maxlength; ++i)
103f02d3 13777 {
66543521 13778 nzero_counts += counts[i] * i;
26c527e6 13779 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 13780 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13781 (nzero_counts * 100.0) / nsyms);
13782 }
252b5132
RH
13783 }
13784
13785 free (counts);
13786 free (lengths);
13787 }
13788
978c4450
AM
13789 free (filedata->buckets);
13790 filedata->buckets = NULL;
13791 filedata->nbuckets = 0;
13792 free (filedata->chains);
13793 filedata->chains = NULL;
252b5132 13794
978c4450 13795 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13796 {
26c527e6
AM
13797 uint64_t *lengths;
13798 uint64_t *counts;
13799 uint64_t hn;
13800 uint64_t maxlength = 0;
13801 uint64_t nzero_counts = 0;
13802 uint64_t nsyms = 0;
fdc90cb4 13803
f16a9783 13804 printf (ngettext ("\nHistogram for `%s' bucket list length "
26c527e6 13805 "(total of %" PRIu64 " bucket):\n",
f16a9783 13806 "\nHistogram for `%s' bucket list length "
26c527e6
AM
13807 "(total of %" PRIu64 " buckets):\n",
13808 filedata->ngnubuckets),
978c4450 13809 GNU_HASH_SECTION_NAME (filedata),
26c527e6 13810 filedata->ngnubuckets);
8b73c356 13811
26c527e6 13812 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
13813 if (lengths == NULL)
13814 {
8b73c356 13815 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13816 goto err_out;
fdc90cb4
JJ
13817 }
13818
fdc90cb4
JJ
13819 printf (_(" Length Number %% of total Coverage\n"));
13820
978c4450
AM
13821 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13822 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 13823 {
625d49fc 13824 uint64_t off, length = 1;
fdc90cb4 13825
978c4450 13826 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13827 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13828 off < filedata->ngnuchains
13829 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13830 ++off)
fdc90cb4
JJ
13831 ++length;
13832 lengths[hn] = length;
13833 if (length > maxlength)
13834 maxlength = length;
13835 nsyms += length;
13836 }
13837
26c527e6 13838 counts = calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13839 if (counts == NULL)
13840 {
b2e951ec 13841 free (lengths);
8b73c356 13842 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13843 goto err_out;
fdc90cb4
JJ
13844 }
13845
978c4450 13846 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13847 ++counts[lengths[hn]];
13848
978c4450 13849 if (filedata->ngnubuckets > 0)
fdc90cb4 13850 {
26c527e6
AM
13851 uint64_t j;
13852 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 13853 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13854 for (j = 1; j <= maxlength; ++j)
13855 {
13856 nzero_counts += counts[j] * j;
26c527e6 13857 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 13858 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13859 (nzero_counts * 100.0) / nsyms);
13860 }
13861 }
13862
13863 free (counts);
13864 free (lengths);
fdc90cb4 13865 }
978c4450
AM
13866 free (filedata->gnubuckets);
13867 filedata->gnubuckets = NULL;
13868 filedata->ngnubuckets = 0;
13869 free (filedata->gnuchains);
13870 filedata->gnuchains = NULL;
13871 filedata->ngnuchains = 0;
13872 free (filedata->mipsxlat);
13873 filedata->mipsxlat = NULL;
015dc7e1 13874 return true;
fd486f32
AM
13875
13876 err_out:
978c4450
AM
13877 free (filedata->gnubuckets);
13878 filedata->gnubuckets = NULL;
13879 filedata->ngnubuckets = 0;
13880 free (filedata->gnuchains);
13881 filedata->gnuchains = NULL;
13882 filedata->ngnuchains = 0;
13883 free (filedata->mipsxlat);
13884 filedata->mipsxlat = NULL;
13885 free (filedata->buckets);
13886 filedata->buckets = NULL;
13887 filedata->nbuckets = 0;
13888 free (filedata->chains);
13889 filedata->chains = NULL;
015dc7e1 13890 return false;
252b5132
RH
13891}
13892
015dc7e1 13893static bool
ca0e11aa 13894process_syminfo (Filedata * filedata)
252b5132 13895{
b4c96d0d 13896 unsigned int i;
252b5132 13897
978c4450 13898 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13899 || !do_dynamic)
13900 /* No syminfo, this is ok. */
015dc7e1 13901 return true;
252b5132
RH
13902
13903 /* There better should be a dynamic symbol section. */
978c4450 13904 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13905 return false;
252b5132 13906
ca0e11aa 13907 if (filedata->is_separate)
26c527e6
AM
13908 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
13909 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
ca0e11aa
NC
13910 filedata->dynamic_syminfo_nent),
13911 filedata->file_name,
13912 filedata->dynamic_syminfo_offset,
13913 filedata->dynamic_syminfo_nent);
13914 else
26c527e6
AM
13915 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
13916 " contains %d entry:\n",
13917 "\nDynamic info segment at offset %#" PRIx64
13918 " contains %d entries:\n",
978c4450 13919 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13920 filedata->dynamic_syminfo_offset,
13921 filedata->dynamic_syminfo_nent);
252b5132
RH
13922
13923 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13924 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13925 {
978c4450 13926 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13927
31104126 13928 printf ("%4d: ", i);
978c4450 13929 if (i >= filedata->num_dynamic_syms)
4082ef84 13930 printf (_("<corrupt index>"));
84714f86
AM
13931 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13932 print_symbol (30, get_dynamic_name (filedata,
978c4450 13933 filedata->dynamic_symbols[i].st_name));
d79b3d50 13934 else
978c4450 13935 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13936 putchar (' ');
252b5132 13937
978c4450 13938 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13939 {
13940 case SYMINFO_BT_SELF:
13941 fputs ("SELF ", stdout);
13942 break;
13943 case SYMINFO_BT_PARENT:
13944 fputs ("PARENT ", stdout);
13945 break;
13946 default:
978c4450
AM
13947 if (filedata->dynamic_syminfo[i].si_boundto > 0
13948 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13949 && valid_dynamic_name (filedata,
978c4450 13950 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13951 {
84714f86 13952 print_symbol (10, get_dynamic_name (filedata,
978c4450 13953 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13954 putchar (' ' );
13955 }
252b5132 13956 else
978c4450 13957 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13958 break;
13959 }
13960
13961 if (flags & SYMINFO_FLG_DIRECT)
13962 printf (" DIRECT");
13963 if (flags & SYMINFO_FLG_PASSTHRU)
13964 printf (" PASSTHRU");
13965 if (flags & SYMINFO_FLG_COPY)
13966 printf (" COPY");
13967 if (flags & SYMINFO_FLG_LAZYLOAD)
13968 printf (" LAZYLOAD");
13969
13970 puts ("");
13971 }
13972
015dc7e1 13973 return true;
252b5132
RH
13974}
13975
75802ccb
CE
13976/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13977 is contained by the region START .. END. The types of ADDR, START
13978 and END should all be the same. Note both ADDR + NELEM and END
13979 point to just beyond the end of the regions that are being tested. */
13980#define IN_RANGE(START,END,ADDR,NELEM) \
13981 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13982
cf13d699
NC
13983/* Check to see if the given reloc needs to be handled in a target specific
13984 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13985 FALSE.
13986
13987 If called with reloc == NULL, then this is a signal that reloc processing
13988 for the current section has finished, and any saved state should be
13989 discarded. */
09c11c86 13990
015dc7e1 13991static bool
26c527e6
AM
13992target_specific_reloc_handling (Filedata *filedata,
13993 Elf_Internal_Rela *reloc,
13994 unsigned char *start,
13995 unsigned char *end,
13996 Elf_Internal_Sym *symtab,
13997 uint64_t num_syms)
252b5132 13998{
f84ce13b 13999 unsigned int reloc_type = 0;
26c527e6 14000 uint64_t sym_index = 0;
f84ce13b
NC
14001
14002 if (reloc)
14003 {
dda8d76d 14004 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
14005 sym_index = get_reloc_symindex (reloc->r_info);
14006 }
252b5132 14007
dda8d76d 14008 switch (filedata->file_header.e_machine)
252b5132 14009 {
13761a11
NC
14010 case EM_MSP430:
14011 case EM_MSP430_OLD:
14012 {
14013 static Elf_Internal_Sym * saved_sym = NULL;
14014
f84ce13b
NC
14015 if (reloc == NULL)
14016 {
14017 saved_sym = NULL;
015dc7e1 14018 return true;
f84ce13b
NC
14019 }
14020
13761a11
NC
14021 switch (reloc_type)
14022 {
14023 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 14024 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 14025 if (uses_msp430x_relocs (filedata))
13761a11 14026 break;
1a0670f3 14027 /* Fall through. */
13761a11 14028 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 14029 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
14030 /* PR 21139. */
14031 if (sym_index >= num_syms)
26c527e6
AM
14032 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index"
14033 " %" PRIu64 "\n"), sym_index);
f84ce13b
NC
14034 else
14035 saved_sym = symtab + sym_index;
015dc7e1 14036 return true;
13761a11
NC
14037
14038 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14039 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14040 goto handle_sym_diff;
0b4362b0 14041
13761a11
NC
14042 case 5: /* R_MSP430_16_BYTE */
14043 case 9: /* R_MSP430_8 */
7d81bc93 14044 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 14045 if (uses_msp430x_relocs (filedata))
13761a11
NC
14046 break;
14047 goto handle_sym_diff;
14048
14049 case 2: /* R_MSP430_ABS16 */
14050 case 15: /* R_MSP430X_ABS16 */
7d81bc93 14051 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 14052 if (! uses_msp430x_relocs (filedata))
13761a11
NC
14053 break;
14054 goto handle_sym_diff;
0b4362b0 14055
13761a11
NC
14056 handle_sym_diff:
14057 if (saved_sym != NULL)
14058 {
625d49fc 14059 uint64_t value;
5a805384 14060 unsigned int reloc_size = 0;
7d81bc93
JL
14061 int leb_ret = 0;
14062 switch (reloc_type)
14063 {
14064 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14065 reloc_size = 4;
14066 break;
14067 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14068 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14069 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14070 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14071 &reloc_size, &leb_ret);
7d81bc93
JL
14072 break;
14073 default:
14074 reloc_size = 2;
14075 break;
14076 }
13761a11 14077
5a805384 14078 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
14079 error (_("MSP430 ULEB128 field at %#" PRIx64
14080 " contains invalid ULEB128 value\n"),
14081 reloc->r_offset);
7d81bc93 14082 else if (sym_index >= num_syms)
26c527e6
AM
14083 error (_("MSP430 reloc contains invalid symbol index "
14084 "%" PRIu64 "\n"),
f84ce13b 14085 sym_index);
03f7786e 14086 else
f84ce13b
NC
14087 {
14088 value = reloc->r_addend + (symtab[sym_index].st_value
14089 - saved_sym->st_value);
14090
b32e566b 14091 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14092 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14093 else
14094 /* PR 21137 */
26c527e6
AM
14095 error (_("MSP430 sym diff reloc contains invalid offset: "
14096 "%#" PRIx64 "\n"),
14097 reloc->r_offset);
f84ce13b 14098 }
13761a11
NC
14099
14100 saved_sym = NULL;
015dc7e1 14101 return true;
13761a11
NC
14102 }
14103 break;
14104
14105 default:
14106 if (saved_sym != NULL)
071436c6 14107 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14108 break;
14109 }
14110 break;
14111 }
14112
cf13d699
NC
14113 case EM_MN10300:
14114 case EM_CYGNUS_MN10300:
14115 {
14116 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14117
f84ce13b
NC
14118 if (reloc == NULL)
14119 {
14120 saved_sym = NULL;
015dc7e1 14121 return true;
f84ce13b
NC
14122 }
14123
cf13d699
NC
14124 switch (reloc_type)
14125 {
14126 case 34: /* R_MN10300_ALIGN */
015dc7e1 14127 return true;
cf13d699 14128 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 14129 if (sym_index >= num_syms)
26c527e6
AM
14130 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index "
14131 "%" PRIu64 "\n"),
f84ce13b
NC
14132 sym_index);
14133 else
14134 saved_sym = symtab + sym_index;
015dc7e1 14135 return true;
f84ce13b 14136
cf13d699
NC
14137 case 1: /* R_MN10300_32 */
14138 case 2: /* R_MN10300_16 */
14139 if (saved_sym != NULL)
14140 {
03f7786e 14141 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14142 uint64_t value;
252b5132 14143
f84ce13b 14144 if (sym_index >= num_syms)
26c527e6
AM
14145 error (_("MN10300 reloc contains invalid symbol index "
14146 "%" PRIu64 "\n"),
f84ce13b 14147 sym_index);
03f7786e 14148 else
f84ce13b
NC
14149 {
14150 value = reloc->r_addend + (symtab[sym_index].st_value
14151 - saved_sym->st_value);
14152
b32e566b 14153 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14154 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 14155 else
26c527e6
AM
14156 error (_("MN10300 sym diff reloc contains invalid offset:"
14157 " %#" PRIx64 "\n"),
14158 reloc->r_offset);
f84ce13b 14159 }
252b5132 14160
cf13d699 14161 saved_sym = NULL;
015dc7e1 14162 return true;
cf13d699
NC
14163 }
14164 break;
14165 default:
14166 if (saved_sym != NULL)
071436c6 14167 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14168 break;
14169 }
14170 break;
14171 }
6ff71e76
NC
14172
14173 case EM_RL78:
14174 {
625d49fc
AM
14175 static uint64_t saved_sym1 = 0;
14176 static uint64_t saved_sym2 = 0;
14177 static uint64_t value;
6ff71e76 14178
f84ce13b
NC
14179 if (reloc == NULL)
14180 {
14181 saved_sym1 = saved_sym2 = 0;
015dc7e1 14182 return true;
f84ce13b
NC
14183 }
14184
6ff71e76
NC
14185 switch (reloc_type)
14186 {
14187 case 0x80: /* R_RL78_SYM. */
14188 saved_sym1 = saved_sym2;
f84ce13b 14189 if (sym_index >= num_syms)
26c527e6
AM
14190 error (_("RL78_SYM reloc contains invalid symbol index "
14191 "%" PRIu64 "\n"), sym_index);
f84ce13b
NC
14192 else
14193 {
14194 saved_sym2 = symtab[sym_index].st_value;
14195 saved_sym2 += reloc->r_addend;
14196 }
015dc7e1 14197 return true;
6ff71e76
NC
14198
14199 case 0x83: /* R_RL78_OPsub. */
14200 value = saved_sym1 - saved_sym2;
14201 saved_sym2 = saved_sym1 = 0;
015dc7e1 14202 return true;
6ff71e76
NC
14203 break;
14204
14205 case 0x41: /* R_RL78_ABS32. */
b32e566b 14206 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14207 byte_put (start + reloc->r_offset, value, 4);
b32e566b 14208 else
26c527e6
AM
14209 error (_("RL78 sym diff reloc contains invalid offset: "
14210 "%#" PRIx64 "\n"),
14211 reloc->r_offset);
6ff71e76 14212 value = 0;
015dc7e1 14213 return true;
6ff71e76
NC
14214
14215 case 0x43: /* R_RL78_ABS16. */
b32e566b 14216 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14217 byte_put (start + reloc->r_offset, value, 2);
b32e566b 14218 else
26c527e6
AM
14219 error (_("RL78 sym diff reloc contains invalid offset: "
14220 "%#" PRIx64 "\n"),
14221 reloc->r_offset);
6ff71e76 14222 value = 0;
015dc7e1 14223 return true;
6ff71e76
NC
14224
14225 default:
14226 break;
14227 }
14228 break;
14229 }
252b5132
RH
14230 }
14231
015dc7e1 14232 return false;
252b5132
RH
14233}
14234
aca88567
NC
14235/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14236 DWARF debug sections. This is a target specific test. Note - we do not
14237 go through the whole including-target-headers-multiple-times route, (as
14238 we have already done with <elf/h8.h>) because this would become very
14239 messy and even then this function would have to contain target specific
14240 information (the names of the relocs instead of their numeric values).
14241 FIXME: This is not the correct way to solve this problem. The proper way
14242 is to have target specific reloc sizing and typing functions created by
14243 the reloc-macros.h header, in the same way that it already creates the
14244 reloc naming functions. */
14245
015dc7e1 14246static bool
dda8d76d 14247is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14248{
d347c9df 14249 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14250 switch (filedata->file_header.e_machine)
aca88567 14251 {
41e92641 14252 case EM_386:
22abe556 14253 case EM_IAMCU:
41e92641 14254 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14255 case EM_68K:
14256 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14257 case EM_860:
14258 return reloc_type == 1; /* R_860_32. */
14259 case EM_960:
14260 return reloc_type == 2; /* R_960_32. */
a06ea964 14261 case EM_AARCH64:
9282b95a
JW
14262 return (reloc_type == 258
14263 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14264 case EM_BPF:
14265 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14266 case EM_ADAPTEVA_EPIPHANY:
14267 return reloc_type == 3;
aca88567 14268 case EM_ALPHA:
137b6b5f 14269 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14270 case EM_ARC:
14271 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14272 case EM_ARC_COMPACT:
14273 case EM_ARC_COMPACT2:
14274 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14275 case EM_ARM:
14276 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14277 case EM_AVR_OLD:
aca88567
NC
14278 case EM_AVR:
14279 return reloc_type == 1;
14280 case EM_BLACKFIN:
14281 return reloc_type == 0x12; /* R_byte4_data. */
14282 case EM_CRIS:
14283 return reloc_type == 3; /* R_CRIS_32. */
14284 case EM_CR16:
14285 return reloc_type == 3; /* R_CR16_NUM32. */
14286 case EM_CRX:
14287 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14288 case EM_CSKY:
14289 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14290 case EM_CYGNUS_FRV:
14291 return reloc_type == 1;
41e92641
NC
14292 case EM_CYGNUS_D10V:
14293 case EM_D10V:
14294 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14295 case EM_CYGNUS_D30V:
14296 case EM_D30V:
14297 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14298 case EM_DLX:
14299 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14300 case EM_CYGNUS_FR30:
14301 case EM_FR30:
14302 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14303 case EM_FT32:
14304 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14305 case EM_H8S:
14306 case EM_H8_300:
14307 case EM_H8_300H:
14308 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14309 case EM_IA_64:
262cdac7
AM
14310 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14311 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14312 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14313 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14314 case EM_IP2K_OLD:
14315 case EM_IP2K:
14316 return reloc_type == 2; /* R_IP2K_32. */
14317 case EM_IQ2000:
14318 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14319 case EM_LATTICEMICO32:
14320 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14321 case EM_LOONGARCH:
14322 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14323 case EM_M32C_OLD:
aca88567
NC
14324 case EM_M32C:
14325 return reloc_type == 3; /* R_M32C_32. */
14326 case EM_M32R:
14327 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14328 case EM_68HC11:
14329 case EM_68HC12:
14330 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14331 case EM_S12Z:
2849d19f
JD
14332 return reloc_type == 7 || /* R_S12Z_EXT32 */
14333 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14334 case EM_MCORE:
14335 return reloc_type == 1; /* R_MCORE_ADDR32. */
14336 case EM_CYGNUS_MEP:
14337 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14338 case EM_METAG:
14339 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14340 case EM_MICROBLAZE:
14341 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14342 case EM_MIPS:
14343 return reloc_type == 2; /* R_MIPS_32. */
14344 case EM_MMIX:
14345 return reloc_type == 4; /* R_MMIX_32. */
14346 case EM_CYGNUS_MN10200:
14347 case EM_MN10200:
14348 return reloc_type == 1; /* R_MN10200_32. */
14349 case EM_CYGNUS_MN10300:
14350 case EM_MN10300:
14351 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14352 case EM_MOXIE:
14353 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14354 case EM_MSP430_OLD:
14355 case EM_MSP430:
13761a11 14356 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14357 case EM_MT:
14358 return reloc_type == 2; /* R_MT_32. */
35c08157 14359 case EM_NDS32:
81c5e376 14360 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14361 case EM_ALTERA_NIOS2:
36591ba1 14362 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14363 case EM_NIOS32:
14364 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14365 case EM_OR1K:
14366 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14367 case EM_PARISC:
9abca702 14368 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14369 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14370 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14371 case EM_PJ:
14372 case EM_PJ_OLD:
14373 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14374 case EM_PPC64:
14375 return reloc_type == 1; /* R_PPC64_ADDR32. */
14376 case EM_PPC:
14377 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14378 case EM_TI_PRU:
14379 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14380 case EM_RISCV:
14381 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14382 case EM_RL78:
14383 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14384 case EM_RX:
14385 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14386 case EM_S370:
14387 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14388 case EM_S390_OLD:
14389 case EM_S390:
14390 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14391 case EM_SCORE:
14392 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14393 case EM_SH:
14394 return reloc_type == 1; /* R_SH_DIR32. */
14395 case EM_SPARC32PLUS:
14396 case EM_SPARCV9:
14397 case EM_SPARC:
14398 return reloc_type == 3 /* R_SPARC_32. */
14399 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14400 case EM_SPU:
14401 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14402 case EM_TI_C6000:
14403 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14404 case EM_TILEGX:
14405 return reloc_type == 2; /* R_TILEGX_32. */
14406 case EM_TILEPRO:
14407 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14408 case EM_CYGNUS_V850:
14409 case EM_V850:
14410 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14411 case EM_V800:
14412 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14413 case EM_VAX:
14414 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14415 case EM_VISIUM:
14416 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14417 case EM_WEBASSEMBLY:
14418 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14419 case EM_X86_64:
8a9036a4 14420 case EM_L1OM:
7a9068fe 14421 case EM_K1OM:
aca88567 14422 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14423 case EM_XGATE:
14424 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14425 case EM_XSTORMY16:
14426 return reloc_type == 1; /* R_XSTROMY16_32. */
14427 case EM_XTENSA_OLD:
14428 case EM_XTENSA:
14429 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14430 case EM_Z80:
14431 return reloc_type == 6; /* R_Z80_32. */
aca88567 14432 default:
bee0ee85
NC
14433 {
14434 static unsigned int prev_warn = 0;
14435
14436 /* Avoid repeating the same warning multiple times. */
dda8d76d 14437 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14438 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14439 filedata->file_header.e_machine);
14440 prev_warn = filedata->file_header.e_machine;
015dc7e1 14441 return false;
bee0ee85 14442 }
aca88567
NC
14443 }
14444}
14445
14446/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14447 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14448
015dc7e1 14449static bool
dda8d76d 14450is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14451{
dda8d76d 14452 switch (filedata->file_header.e_machine)
d347c9df 14453 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14454 {
41e92641 14455 case EM_386:
22abe556 14456 case EM_IAMCU:
3e0873ac 14457 return reloc_type == 2; /* R_386_PC32. */
aca88567 14458 case EM_68K:
3e0873ac 14459 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14460 case EM_AARCH64:
14461 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14462 case EM_ADAPTEVA_EPIPHANY:
14463 return reloc_type == 6;
aca88567
NC
14464 case EM_ALPHA:
14465 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14466 case EM_ARC_COMPACT:
14467 case EM_ARC_COMPACT2:
14468 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14469 case EM_ARM:
3e0873ac 14470 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14471 case EM_AVR_OLD:
14472 case EM_AVR:
14473 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14474 case EM_LOONGARCH:
14475 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14476 case EM_MICROBLAZE:
14477 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14478 case EM_OR1K:
14479 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14480 case EM_PARISC:
85acf597 14481 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14482 case EM_PPC:
14483 return reloc_type == 26; /* R_PPC_REL32. */
14484 case EM_PPC64:
3e0873ac 14485 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14486 case EM_RISCV:
14487 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14488 case EM_S390_OLD:
14489 case EM_S390:
3e0873ac 14490 return reloc_type == 5; /* R_390_PC32. */
aca88567 14491 case EM_SH:
3e0873ac 14492 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14493 case EM_SPARC32PLUS:
14494 case EM_SPARCV9:
14495 case EM_SPARC:
3e0873ac 14496 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14497 case EM_SPU:
14498 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14499 case EM_TILEGX:
14500 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14501 case EM_TILEPRO:
14502 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14503 case EM_VISIUM:
14504 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14505 case EM_X86_64:
8a9036a4 14506 case EM_L1OM:
7a9068fe 14507 case EM_K1OM:
3e0873ac 14508 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14509 case EM_VAX:
14510 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14511 case EM_XTENSA_OLD:
14512 case EM_XTENSA:
14513 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14514 default:
14515 /* Do not abort or issue an error message here. Not all targets use
14516 pc-relative 32-bit relocs in their DWARF debug information and we
14517 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14518 more helpful warning message will be generated by apply_relocations
14519 anyway, so just return. */
015dc7e1 14520 return false;
aca88567
NC
14521 }
14522}
14523
14524/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14525 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14526
015dc7e1 14527static bool
dda8d76d 14528is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14529{
dda8d76d 14530 switch (filedata->file_header.e_machine)
aca88567 14531 {
a06ea964
NC
14532 case EM_AARCH64:
14533 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14534 case EM_ALPHA:
14535 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14536 case EM_IA_64:
262cdac7
AM
14537 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14538 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14539 case EM_LOONGARCH:
14540 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14541 case EM_PARISC:
14542 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14543 case EM_PPC64:
14544 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14545 case EM_RISCV:
14546 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14547 case EM_SPARC32PLUS:
14548 case EM_SPARCV9:
14549 case EM_SPARC:
714da62f
NC
14550 return reloc_type == 32 /* R_SPARC_64. */
14551 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14552 case EM_X86_64:
8a9036a4 14553 case EM_L1OM:
7a9068fe 14554 case EM_K1OM:
aca88567 14555 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14556 case EM_S390_OLD:
14557 case EM_S390:
aa137e4d
NC
14558 return reloc_type == 22; /* R_S390_64. */
14559 case EM_TILEGX:
14560 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14561 case EM_MIPS:
aa137e4d 14562 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14563 default:
015dc7e1 14564 return false;
aca88567
NC
14565 }
14566}
14567
85acf597
RH
14568/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14569 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14570
015dc7e1 14571static bool
dda8d76d 14572is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14573{
dda8d76d 14574 switch (filedata->file_header.e_machine)
85acf597 14575 {
a06ea964
NC
14576 case EM_AARCH64:
14577 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14578 case EM_ALPHA:
aa137e4d 14579 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14580 case EM_IA_64:
262cdac7
AM
14581 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14582 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14583 case EM_PARISC:
aa137e4d 14584 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14585 case EM_PPC64:
aa137e4d 14586 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14587 case EM_SPARC32PLUS:
14588 case EM_SPARCV9:
14589 case EM_SPARC:
aa137e4d 14590 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14591 case EM_X86_64:
8a9036a4 14592 case EM_L1OM:
7a9068fe 14593 case EM_K1OM:
aa137e4d 14594 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14595 case EM_S390_OLD:
14596 case EM_S390:
aa137e4d
NC
14597 return reloc_type == 23; /* R_S390_PC64. */
14598 case EM_TILEGX:
14599 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14600 default:
015dc7e1 14601 return false;
85acf597
RH
14602 }
14603}
14604
4dc3c23d
AM
14605/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14606 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14607
015dc7e1 14608static bool
dda8d76d 14609is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14610{
dda8d76d 14611 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14612 {
14613 case EM_CYGNUS_MN10200:
14614 case EM_MN10200:
14615 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14616 case EM_FT32:
14617 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14618 case EM_Z80:
14619 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14620 default:
015dc7e1 14621 return false;
4dc3c23d
AM
14622 }
14623}
14624
aca88567
NC
14625/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14626 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14627
015dc7e1 14628static bool
dda8d76d 14629is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14630{
d347c9df 14631 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14632 switch (filedata->file_header.e_machine)
4b78141a 14633 {
886a2506
NC
14634 case EM_ARC:
14635 case EM_ARC_COMPACT:
14636 case EM_ARC_COMPACT2:
14637 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14638 case EM_ADAPTEVA_EPIPHANY:
14639 return reloc_type == 5;
aca88567
NC
14640 case EM_AVR_OLD:
14641 case EM_AVR:
14642 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14643 case EM_CYGNUS_D10V:
14644 case EM_D10V:
14645 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14646 case EM_FT32:
14647 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14648 case EM_H8S:
14649 case EM_H8_300:
14650 case EM_H8_300H:
aca88567
NC
14651 return reloc_type == R_H8_DIR16;
14652 case EM_IP2K_OLD:
14653 case EM_IP2K:
14654 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14655 case EM_M32C_OLD:
f4236fe4
DD
14656 case EM_M32C:
14657 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14658 case EM_CYGNUS_MN10200:
14659 case EM_MN10200:
14660 return reloc_type == 2; /* R_MN10200_16. */
14661 case EM_CYGNUS_MN10300:
14662 case EM_MN10300:
14663 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14664 case EM_MSP430:
dda8d76d 14665 if (uses_msp430x_relocs (filedata))
13761a11 14666 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14667 /* Fall through. */
78c8d46c 14668 case EM_MSP430_OLD:
aca88567 14669 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 14670 case EM_NDS32:
81c5e376 14671 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 14672 case EM_ALTERA_NIOS2:
36591ba1 14673 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14674 case EM_NIOS32:
14675 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14676 case EM_OR1K:
14677 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14678 case EM_RISCV:
14679 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14680 case EM_TI_PRU:
14681 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14682 case EM_TI_C6000:
14683 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14684 case EM_VISIUM:
14685 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
14686 case EM_XGATE:
14687 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14688 case EM_Z80:
14689 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14690 default:
015dc7e1 14691 return false;
4b78141a
NC
14692 }
14693}
14694
39e07931
AS
14695/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14696 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14697
015dc7e1 14698static bool
39e07931
AS
14699is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14700{
14701 switch (filedata->file_header.e_machine)
14702 {
14703 case EM_RISCV:
14704 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14705 case EM_Z80:
14706 return reloc_type == 1; /* R_Z80_8. */
39e07931 14707 default:
015dc7e1 14708 return false;
39e07931
AS
14709 }
14710}
14711
14712/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14713 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14714
015dc7e1 14715static bool
39e07931
AS
14716is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14717{
14718 switch (filedata->file_header.e_machine)
14719 {
14720 case EM_RISCV:
14721 return reloc_type == 53; /* R_RISCV_SET6. */
14722 default:
015dc7e1 14723 return false;
39e07931
AS
14724 }
14725}
14726
03336641
JW
14727/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14728 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14729
015dc7e1 14730static bool
03336641
JW
14731is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14732{
14733 /* Please keep this table alpha-sorted for ease of visual lookup. */
14734 switch (filedata->file_header.e_machine)
14735 {
14736 case EM_RISCV:
14737 return reloc_type == 35; /* R_RISCV_ADD32. */
14738 default:
015dc7e1 14739 return false;
03336641
JW
14740 }
14741}
14742
14743/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14744 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14745
015dc7e1 14746static bool
03336641
JW
14747is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14748{
14749 /* Please keep this table alpha-sorted for ease of visual lookup. */
14750 switch (filedata->file_header.e_machine)
14751 {
14752 case EM_RISCV:
14753 return reloc_type == 39; /* R_RISCV_SUB32. */
14754 default:
015dc7e1 14755 return false;
03336641
JW
14756 }
14757}
14758
14759/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14760 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14761
015dc7e1 14762static bool
03336641
JW
14763is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14764{
14765 /* Please keep this table alpha-sorted for ease of visual lookup. */
14766 switch (filedata->file_header.e_machine)
14767 {
14768 case EM_RISCV:
14769 return reloc_type == 36; /* R_RISCV_ADD64. */
14770 default:
015dc7e1 14771 return false;
03336641
JW
14772 }
14773}
14774
14775/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14776 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14777
015dc7e1 14778static bool
03336641
JW
14779is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14780{
14781 /* Please keep this table alpha-sorted for ease of visual lookup. */
14782 switch (filedata->file_header.e_machine)
14783 {
14784 case EM_RISCV:
14785 return reloc_type == 40; /* R_RISCV_SUB64. */
14786 default:
015dc7e1 14787 return false;
03336641
JW
14788 }
14789}
14790
14791/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14792 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14793
015dc7e1 14794static bool
03336641
JW
14795is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14796{
14797 /* Please keep this table alpha-sorted for ease of visual lookup. */
14798 switch (filedata->file_header.e_machine)
14799 {
14800 case EM_RISCV:
14801 return reloc_type == 34; /* R_RISCV_ADD16. */
14802 default:
015dc7e1 14803 return false;
03336641
JW
14804 }
14805}
14806
14807/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14808 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14809
015dc7e1 14810static bool
03336641
JW
14811is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14812{
14813 /* Please keep this table alpha-sorted for ease of visual lookup. */
14814 switch (filedata->file_header.e_machine)
14815 {
14816 case EM_RISCV:
14817 return reloc_type == 38; /* R_RISCV_SUB16. */
14818 default:
015dc7e1 14819 return false;
03336641
JW
14820 }
14821}
14822
14823/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14824 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14825
015dc7e1 14826static bool
03336641
JW
14827is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14828{
14829 /* Please keep this table alpha-sorted for ease of visual lookup. */
14830 switch (filedata->file_header.e_machine)
14831 {
14832 case EM_RISCV:
14833 return reloc_type == 33; /* R_RISCV_ADD8. */
14834 default:
015dc7e1 14835 return false;
03336641
JW
14836 }
14837}
14838
14839/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14840 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14841
015dc7e1 14842static bool
03336641
JW
14843is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14844{
14845 /* Please keep this table alpha-sorted for ease of visual lookup. */
14846 switch (filedata->file_header.e_machine)
14847 {
14848 case EM_RISCV:
14849 return reloc_type == 37; /* R_RISCV_SUB8. */
14850 default:
015dc7e1 14851 return false;
03336641
JW
14852 }
14853}
14854
39e07931
AS
14855/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14856 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14857
015dc7e1 14858static bool
39e07931
AS
14859is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14860{
14861 switch (filedata->file_header.e_machine)
14862 {
14863 case EM_RISCV:
14864 return reloc_type == 52; /* R_RISCV_SUB6. */
14865 default:
015dc7e1 14866 return false;
39e07931
AS
14867 }
14868}
14869
2a7b2e88
JK
14870/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14871 relocation entries (possibly formerly used for SHT_GROUP sections). */
14872
015dc7e1 14873static bool
dda8d76d 14874is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14875{
dda8d76d 14876 switch (filedata->file_header.e_machine)
2a7b2e88 14877 {
cb8f3167 14878 case EM_386: /* R_386_NONE. */
d347c9df 14879 case EM_68K: /* R_68K_NONE. */
cfb8c092 14880 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14881 case EM_ALPHA: /* R_ALPHA_NONE. */
14882 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14883 case EM_ARC: /* R_ARC_NONE. */
886a2506 14884 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14885 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14886 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 14887 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14888 case EM_FT32: /* R_FT32_NONE. */
14889 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14890 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14891 case EM_L1OM: /* R_X86_64_NONE. */
14892 case EM_M32R: /* R_M32R_NONE. */
14893 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14894 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14895 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14896 case EM_NIOS32: /* R_NIOS_NONE. */
14897 case EM_OR1K: /* R_OR1K_NONE. */
14898 case EM_PARISC: /* R_PARISC_NONE. */
14899 case EM_PPC64: /* R_PPC64_NONE. */
14900 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14901 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14902 case EM_S390: /* R_390_NONE. */
14903 case EM_S390_OLD:
14904 case EM_SH: /* R_SH_NONE. */
14905 case EM_SPARC32PLUS:
14906 case EM_SPARC: /* R_SPARC_NONE. */
14907 case EM_SPARCV9:
aa137e4d
NC
14908 case EM_TILEGX: /* R_TILEGX_NONE. */
14909 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14910 case EM_TI_C6000:/* R_C6000_NONE. */
14911 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 14912 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14913 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14914 return reloc_type == 0;
d347c9df 14915
a06ea964
NC
14916 case EM_AARCH64:
14917 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14918 case EM_AVR_OLD:
14919 case EM_AVR:
14920 return (reloc_type == 0 /* R_AVR_NONE. */
14921 || reloc_type == 30 /* R_AVR_DIFF8. */
14922 || reloc_type == 31 /* R_AVR_DIFF16. */
14923 || reloc_type == 32 /* R_AVR_DIFF32. */);
14924 case EM_METAG:
14925 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 14926 case EM_NDS32:
81c5e376
AM
14927 return (reloc_type == 0 /* R_NDS32_NONE. */
14928 || reloc_type == 205 /* R_NDS32_DIFF8. */
14929 || reloc_type == 206 /* R_NDS32_DIFF16. */
14930 || reloc_type == 207 /* R_NDS32_DIFF32. */
14931 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
14932 case EM_TI_PRU:
14933 return (reloc_type == 0 /* R_PRU_NONE. */
14934 || reloc_type == 65 /* R_PRU_DIFF8. */
14935 || reloc_type == 66 /* R_PRU_DIFF16. */
14936 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14937 case EM_XTENSA_OLD:
14938 case EM_XTENSA:
4dc3c23d
AM
14939 return (reloc_type == 0 /* R_XTENSA_NONE. */
14940 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14941 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14942 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14943 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14944 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14945 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14946 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14947 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14948 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14949 }
015dc7e1 14950 return false;
2a7b2e88
JK
14951}
14952
d1c4b12b
NC
14953/* Returns TRUE if there is a relocation against
14954 section NAME at OFFSET bytes. */
14955
015dc7e1 14956bool
31e5a3a3 14957reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
14958{
14959 Elf_Internal_Rela * relocs;
14960 Elf_Internal_Rela * rp;
14961
14962 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14963 return false;
d1c4b12b
NC
14964
14965 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14966
14967 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14968 if (rp->r_offset == offset)
015dc7e1 14969 return true;
d1c4b12b 14970
015dc7e1 14971 return false;
d1c4b12b
NC
14972}
14973
cf13d699 14974/* Apply relocations to a section.
32ec8896
NC
14975 Returns TRUE upon success, FALSE otherwise.
14976 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14977 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14978 will be set to the number of relocs loaded.
14979
cf13d699 14980 Note: So far support has been added only for those relocations
32ec8896
NC
14981 which can be found in debug sections. FIXME: Add support for
14982 more relocations ? */
1b315056 14983
015dc7e1 14984static bool
be7d229a
AM
14985apply_relocations (Filedata *filedata,
14986 const Elf_Internal_Shdr *section,
14987 unsigned char *start,
14988 size_t size,
14989 void **relocs_return,
26c527e6 14990 uint64_t *num_relocs_return)
1b315056 14991{
cf13d699 14992 Elf_Internal_Shdr * relsec;
0d2a7a93 14993 unsigned char * end = start + size;
cb8f3167 14994
d1c4b12b
NC
14995 if (relocs_return != NULL)
14996 {
14997 * (Elf_Internal_Rela **) relocs_return = NULL;
14998 * num_relocs_return = 0;
14999 }
15000
dda8d76d 15001 if (filedata->file_header.e_type != ET_REL)
32ec8896 15002 /* No relocs to apply. */
015dc7e1 15003 return true;
1b315056 15004
cf13d699 15005 /* Find the reloc section associated with the section. */
dda8d76d
NC
15006 for (relsec = filedata->section_headers;
15007 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 15008 ++relsec)
252b5132 15009 {
015dc7e1 15010 bool is_rela;
26c527e6 15011 uint64_t num_relocs;
2cf0635d
NC
15012 Elf_Internal_Rela * relocs;
15013 Elf_Internal_Rela * rp;
15014 Elf_Internal_Shdr * symsec;
15015 Elf_Internal_Sym * symtab;
26c527e6 15016 uint64_t num_syms;
2cf0635d 15017 Elf_Internal_Sym * sym;
252b5132 15018
41e92641 15019 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15020 || relsec->sh_info >= filedata->file_header.e_shnum
15021 || filedata->section_headers + relsec->sh_info != section
c256ffe7 15022 || relsec->sh_size == 0
dda8d76d 15023 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 15024 continue;
428409d5 15025
a788aedd
AM
15026 symsec = filedata->section_headers + relsec->sh_link;
15027 if (symsec->sh_type != SHT_SYMTAB
15028 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 15029 return false;
a788aedd 15030
41e92641
NC
15031 is_rela = relsec->sh_type == SHT_RELA;
15032
15033 if (is_rela)
15034 {
dda8d76d 15035 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 15036 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15037 return false;
41e92641
NC
15038 }
15039 else
15040 {
dda8d76d 15041 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 15042 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15043 return false;
41e92641
NC
15044 }
15045
15046 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 15047 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 15048 is_rela = false;
428409d5 15049
4de91c10 15050 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 15051
41e92641 15052 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 15053 {
625d49fc 15054 uint64_t addend;
015dc7e1
AM
15055 unsigned int reloc_type;
15056 unsigned int reloc_size;
15057 bool reloc_inplace = false;
15058 bool reloc_subtract = false;
15059 unsigned char *rloc;
26c527e6 15060 uint64_t sym_index;
4b78141a 15061
dda8d76d 15062 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 15063
dda8d76d 15064 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 15065 continue;
dda8d76d 15066 else if (is_none_reloc (filedata, reloc_type))
98fb390a 15067 continue;
dda8d76d
NC
15068 else if (is_32bit_abs_reloc (filedata, reloc_type)
15069 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 15070 reloc_size = 4;
dda8d76d
NC
15071 else if (is_64bit_abs_reloc (filedata, reloc_type)
15072 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 15073 reloc_size = 8;
dda8d76d 15074 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15075 reloc_size = 3;
dda8d76d 15076 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15077 reloc_size = 2;
39e07931
AS
15078 else if (is_8bit_abs_reloc (filedata, reloc_type)
15079 || is_6bit_abs_reloc (filedata, reloc_type))
15080 reloc_size = 1;
03336641
JW
15081 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15082 reloc_type))
15083 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15084 {
15085 reloc_size = 4;
015dc7e1 15086 reloc_inplace = true;
03336641
JW
15087 }
15088 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15089 reloc_type))
15090 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15091 {
15092 reloc_size = 8;
015dc7e1 15093 reloc_inplace = true;
03336641
JW
15094 }
15095 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15096 reloc_type))
15097 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15098 {
15099 reloc_size = 2;
015dc7e1 15100 reloc_inplace = true;
03336641
JW
15101 }
15102 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15103 reloc_type))
15104 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15105 {
15106 reloc_size = 1;
015dc7e1 15107 reloc_inplace = true;
03336641 15108 }
39e07931
AS
15109 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
15110 reloc_type)))
15111 {
15112 reloc_size = 1;
015dc7e1 15113 reloc_inplace = true;
39e07931 15114 }
aca88567 15115 else
4b78141a 15116 {
bee0ee85 15117 static unsigned int prev_reloc = 0;
dda8d76d 15118
bee0ee85
NC
15119 if (reloc_type != prev_reloc)
15120 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15121 reloc_type, printable_section_name (filedata, section));
bee0ee85 15122 prev_reloc = reloc_type;
4b78141a
NC
15123 continue;
15124 }
103f02d3 15125
91d6fa6a 15126 rloc = start + rp->r_offset;
75802ccb 15127 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 15128 {
26c527e6
AM
15129 warn (_("skipping invalid relocation offset %#" PRIx64
15130 " in section %s\n"),
15131 rp->r_offset,
dda8d76d 15132 printable_section_name (filedata, section));
700dd8b7
L
15133 continue;
15134 }
103f02d3 15135
26c527e6 15136 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
15137 if (sym_index >= num_syms)
15138 {
26c527e6
AM
15139 warn (_("skipping invalid relocation symbol index %#" PRIx64
15140 " in section %s\n"),
dda8d76d 15141 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15142 continue;
15143 }
15144 sym = symtab + sym_index;
41e92641
NC
15145
15146 /* If the reloc has a symbol associated with it,
55f25fc3
L
15147 make sure that it is of an appropriate type.
15148
15149 Relocations against symbols without type can happen.
15150 Gcc -feliminate-dwarf2-dups may generate symbols
15151 without type for debug info.
15152
15153 Icc generates relocations against function symbols
15154 instead of local labels.
15155
15156 Relocations against object symbols can happen, eg when
15157 referencing a global array. For an example of this see
15158 the _clz.o binary in libgcc.a. */
aca88567 15159 if (sym != symtab
b8871f35 15160 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15161 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15162 {
26c527e6 15163 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
15164 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15165 printable_section_name (filedata, relsec),
26c527e6 15166 rp - relocs);
aca88567 15167 continue;
5b18a4bc 15168 }
252b5132 15169
4dc3c23d
AM
15170 addend = 0;
15171 if (is_rela)
15172 addend += rp->r_addend;
c47320c3
AM
15173 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15174 partial_inplace. */
4dc3c23d 15175 if (!is_rela
dda8d76d 15176 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15177 && reloc_type == 1)
dda8d76d
NC
15178 || ((filedata->file_header.e_machine == EM_PJ
15179 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15180 && reloc_type == 1)
dda8d76d
NC
15181 || ((filedata->file_header.e_machine == EM_D30V
15182 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15183 && reloc_type == 12)
15184 || reloc_inplace)
39e07931
AS
15185 {
15186 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15187 addend += byte_get (rloc, reloc_size) & 0x3f;
15188 else
15189 addend += byte_get (rloc, reloc_size);
15190 }
cb8f3167 15191
dda8d76d
NC
15192 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15193 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15194 {
15195 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15196 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15197 addend -= 8;
91d6fa6a 15198 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15199 reloc_size);
15200 }
39e07931
AS
15201 else if (is_6bit_abs_reloc (filedata, reloc_type)
15202 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
15203 {
15204 if (reloc_subtract)
15205 addend -= sym->st_value;
15206 else
15207 addend += sym->st_value;
15208 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15209 byte_put (rloc, addend, reloc_size);
15210 }
03336641
JW
15211 else if (reloc_subtract)
15212 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15213 else
91d6fa6a 15214 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15215 }
252b5132 15216
5b18a4bc 15217 free (symtab);
f84ce13b
NC
15218 /* Let the target specific reloc processing code know that
15219 we have finished with these relocs. */
dda8d76d 15220 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15221
15222 if (relocs_return)
15223 {
15224 * (Elf_Internal_Rela **) relocs_return = relocs;
15225 * num_relocs_return = num_relocs;
15226 }
15227 else
15228 free (relocs);
15229
5b18a4bc
NC
15230 break;
15231 }
32ec8896 15232
015dc7e1 15233 return true;
5b18a4bc 15234}
103f02d3 15235
cf13d699 15236#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15237static bool
dda8d76d 15238disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15239{
dda8d76d 15240 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15241
74e1a04b 15242 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15243
015dc7e1 15244 return true;
cf13d699
NC
15245}
15246#endif
15247
15248/* Reads in the contents of SECTION from FILE, returning a pointer
15249 to a malloc'ed buffer or NULL if something went wrong. */
15250
15251static char *
dda8d76d 15252get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15253{
be7d229a 15254 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15255
15256 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15257 {
c6b78c96 15258 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15259 printable_section_name (filedata, section));
cf13d699
NC
15260 return NULL;
15261 }
15262
dda8d76d 15263 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15264 _("section contents"));
cf13d699
NC
15265}
15266
1f5a3546 15267/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 15268
015dc7e1 15269static bool
1f5a3546
FS
15270uncompress_section_contents (bool is_zstd, unsigned char **buffer,
15271 uint64_t uncompressed_size, uint64_t *size)
0e602686 15272{
31e5a3a3
AM
15273 uint64_t compressed_size = *size;
15274 unsigned char *compressed_buffer = *buffer;
1f5a3546 15275 unsigned char *uncompressed_buffer = xmalloc (uncompressed_size);
0e602686
NC
15276 z_stream strm;
15277 int rc;
15278
1f5a3546
FS
15279 if (is_zstd)
15280 {
15281#ifdef HAVE_ZSTD
15282 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15283 compressed_buffer, compressed_size);
15284 if (ZSTD_isError (ret))
15285 goto fail;
15286#endif
15287 }
15288 else
15289 {
15290 /* It is possible the section consists of several compressed
15291 buffers concatenated together, so we uncompress in a loop. */
15292 /* PR 18313: The state field in the z_stream structure is supposed
15293 to be invisible to the user (ie us), but some compilers will
15294 still complain about it being used without initialisation. So
15295 we first zero the entire z_stream structure and then set the fields
15296 that we need. */
15297 memset (&strm, 0, sizeof strm);
15298 strm.avail_in = compressed_size;
15299 strm.next_in = (Bytef *)compressed_buffer;
15300 strm.avail_out = uncompressed_size;
15301
15302 rc = inflateInit (&strm);
15303 while (strm.avail_in > 0)
15304 {
15305 if (rc != Z_OK)
15306 break;
15307 strm.next_out = ((Bytef *)uncompressed_buffer
15308 + (uncompressed_size - strm.avail_out));
15309 rc = inflate (&strm, Z_FINISH);
15310 if (rc != Z_STREAM_END)
15311 break;
15312 rc = inflateReset (&strm);
15313 }
15314 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15315 goto fail;
15316 }
0e602686
NC
15317
15318 *buffer = uncompressed_buffer;
15319 *size = uncompressed_size;
015dc7e1 15320 return true;
0e602686
NC
15321
15322 fail:
15323 free (uncompressed_buffer);
15324 /* Indicate decompression failure. */
15325 *buffer = NULL;
015dc7e1 15326 return false;
0e602686 15327}
dd24e3da 15328
015dc7e1 15329static bool
dda8d76d 15330dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15331{
015dc7e1 15332 Elf_Internal_Shdr *relsec;
be7d229a 15333 uint64_t num_bytes;
015dc7e1
AM
15334 unsigned char *data;
15335 unsigned char *end;
15336 unsigned char *real_start;
15337 unsigned char *start;
15338 bool some_strings_shown;
cf13d699 15339
dda8d76d 15340 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15341 if (start == NULL)
c6b78c96 15342 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15343 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15344
0e602686 15345 num_bytes = section->sh_size;
cf13d699 15346
835f2fae
NC
15347 if (filedata->is_separate)
15348 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15349 printable_section_name (filedata, section),
15350 filedata->file_name);
15351 else
15352 printf (_("\nString dump of section '%s':\n"),
15353 printable_section_name (filedata, section));
cf13d699 15354
0e602686
NC
15355 if (decompress_dumps)
15356 {
31e5a3a3
AM
15357 uint64_t new_size = num_bytes;
15358 uint64_t uncompressed_size = 0;
1f5a3546 15359 bool is_zstd = false;
0e602686
NC
15360
15361 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15362 {
15363 Elf_Internal_Chdr chdr;
15364 unsigned int compression_header_size
ebdf1ebf
NC
15365 = get_compression_header (& chdr, (unsigned char *) start,
15366 num_bytes);
5844b465
NC
15367 if (compression_header_size == 0)
15368 /* An error message will have already been generated
15369 by get_compression_header. */
15370 goto error_out;
0e602686 15371
1f5a3546
FS
15372 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
15373 ;
15374#ifdef HAVE_ZSTD
15375 else if (chdr.ch_type == ELFCOMPRESS_ZSTD)
15376 is_zstd = true;
15377#endif
15378 else
0e602686 15379 {
813dabb9 15380 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15381 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15382 goto error_out;
813dabb9 15383 }
813dabb9
L
15384 uncompressed_size = chdr.ch_size;
15385 start += compression_header_size;
15386 new_size -= compression_header_size;
0e602686
NC
15387 }
15388 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15389 {
15390 /* Read the zlib header. In this case, it should be "ZLIB"
15391 followed by the uncompressed section size, 8 bytes in
15392 big-endian order. */
15393 uncompressed_size = start[4]; uncompressed_size <<= 8;
15394 uncompressed_size += start[5]; uncompressed_size <<= 8;
15395 uncompressed_size += start[6]; uncompressed_size <<= 8;
15396 uncompressed_size += start[7]; uncompressed_size <<= 8;
15397 uncompressed_size += start[8]; uncompressed_size <<= 8;
15398 uncompressed_size += start[9]; uncompressed_size <<= 8;
15399 uncompressed_size += start[10]; uncompressed_size <<= 8;
15400 uncompressed_size += start[11];
15401 start += 12;
15402 new_size -= 12;
15403 }
15404
1835f746
NC
15405 if (uncompressed_size)
15406 {
1f5a3546
FS
15407 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
15408 &new_size))
1835f746
NC
15409 num_bytes = new_size;
15410 else
15411 {
15412 error (_("Unable to decompress section %s\n"),
dda8d76d 15413 printable_section_name (filedata, section));
f761cb13 15414 goto error_out;
1835f746
NC
15415 }
15416 }
bc303e5d
NC
15417 else
15418 start = real_start;
0e602686 15419 }
fd8008d8 15420
cf13d699
NC
15421 /* If the section being dumped has relocations against it the user might
15422 be expecting these relocations to have been applied. Check for this
15423 case and issue a warning message in order to avoid confusion.
15424 FIXME: Maybe we ought to have an option that dumps a section with
15425 relocs applied ? */
dda8d76d
NC
15426 for (relsec = filedata->section_headers;
15427 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15428 ++relsec)
15429 {
15430 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15431 || relsec->sh_info >= filedata->file_header.e_shnum
15432 || filedata->section_headers + relsec->sh_info != section
cf13d699 15433 || relsec->sh_size == 0
dda8d76d 15434 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15435 continue;
15436
15437 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15438 break;
15439 }
15440
cf13d699
NC
15441 data = start;
15442 end = start + num_bytes;
015dc7e1 15443 some_strings_shown = false;
cf13d699 15444
ba3265d0
NC
15445#ifdef HAVE_MBSTATE_T
15446 mbstate_t state;
15447 /* Initialise the multibyte conversion state. */
15448 memset (& state, 0, sizeof (state));
15449#endif
15450
015dc7e1 15451 bool continuing = false;
ba3265d0 15452
cf13d699
NC
15453 while (data < end)
15454 {
15455 while (!ISPRINT (* data))
15456 if (++ data >= end)
15457 break;
15458
15459 if (data < end)
15460 {
071436c6
NC
15461 size_t maxlen = end - data;
15462
ba3265d0
NC
15463 if (continuing)
15464 {
15465 printf (" ");
015dc7e1 15466 continuing = false;
ba3265d0
NC
15467 }
15468 else
15469 {
26c527e6 15470 printf (" [%6tx] ", data - start);
ba3265d0
NC
15471 }
15472
4082ef84
NC
15473 if (maxlen > 0)
15474 {
f3da8a96 15475 char c = 0;
ba3265d0
NC
15476
15477 while (maxlen)
15478 {
15479 c = *data++;
15480
15481 if (c == 0)
15482 break;
15483
15484 /* PR 25543: Treat new-lines as string-ending characters. */
15485 if (c == '\n')
15486 {
15487 printf ("\\n\n");
15488 if (*data != 0)
015dc7e1 15489 continuing = true;
ba3265d0
NC
15490 break;
15491 }
15492
15493 /* Do not print control characters directly as they can affect terminal
15494 settings. Such characters usually appear in the names generated
15495 by the assembler for local labels. */
15496 if (ISCNTRL (c))
15497 {
15498 printf ("^%c", c + 0x40);
15499 }
15500 else if (ISPRINT (c))
15501 {
15502 putchar (c);
15503 }
15504 else
15505 {
15506 size_t n;
15507#ifdef HAVE_MBSTATE_T
15508 wchar_t w;
15509#endif
15510 /* Let printf do the hard work of displaying multibyte characters. */
15511 printf ("%.1s", data - 1);
15512#ifdef HAVE_MBSTATE_T
15513 /* Try to find out how many bytes made up the character that was
15514 just printed. Advance the symbol pointer past the bytes that
15515 were displayed. */
15516 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15517#else
15518 n = 1;
15519#endif
15520 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15521 data += (n - 1);
15522 }
15523 }
15524
15525 if (c != '\n')
15526 putchar ('\n');
4082ef84
NC
15527 }
15528 else
15529 {
15530 printf (_("<corrupt>\n"));
15531 data = end;
15532 }
015dc7e1 15533 some_strings_shown = true;
cf13d699
NC
15534 }
15535 }
15536
15537 if (! some_strings_shown)
15538 printf (_(" No strings found in this section."));
15539
0e602686 15540 free (real_start);
cf13d699
NC
15541
15542 putchar ('\n');
015dc7e1 15543 return true;
f761cb13
AM
15544
15545error_out:
15546 free (real_start);
015dc7e1 15547 return false;
cf13d699
NC
15548}
15549
015dc7e1
AM
15550static bool
15551dump_section_as_bytes (Elf_Internal_Shdr *section,
15552 Filedata *filedata,
15553 bool relocate)
cf13d699 15554{
be7d229a
AM
15555 Elf_Internal_Shdr *relsec;
15556 size_t bytes;
15557 uint64_t section_size;
625d49fc 15558 uint64_t addr;
be7d229a
AM
15559 unsigned char *data;
15560 unsigned char *real_start;
15561 unsigned char *start;
0e602686 15562
dda8d76d 15563 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15564 if (start == NULL)
c6b78c96 15565 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15566 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15567
0e602686 15568 section_size = section->sh_size;
cf13d699 15569
835f2fae
NC
15570 if (filedata->is_separate)
15571 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15572 printable_section_name (filedata, section),
15573 filedata->file_name);
15574 else
15575 printf (_("\nHex dump of section '%s':\n"),
15576 printable_section_name (filedata, section));
cf13d699 15577
0e602686
NC
15578 if (decompress_dumps)
15579 {
31e5a3a3
AM
15580 uint64_t new_size = section_size;
15581 uint64_t uncompressed_size = 0;
1f5a3546 15582 bool is_zstd = false;
0e602686
NC
15583
15584 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15585 {
15586 Elf_Internal_Chdr chdr;
15587 unsigned int compression_header_size
ebdf1ebf 15588 = get_compression_header (& chdr, start, section_size);
0e602686 15589
5844b465
NC
15590 if (compression_header_size == 0)
15591 /* An error message will have already been generated
15592 by get_compression_header. */
15593 goto error_out;
15594
1f5a3546
FS
15595 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
15596 ;
15597#ifdef HAVE_ZSTD
15598 else if (chdr.ch_type == ELFCOMPRESS_ZSTD)
15599 is_zstd = true;
15600#endif
15601 else
0e602686 15602 {
813dabb9 15603 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15604 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15605 goto error_out;
0e602686 15606 }
813dabb9
L
15607 uncompressed_size = chdr.ch_size;
15608 start += compression_header_size;
15609 new_size -= compression_header_size;
0e602686
NC
15610 }
15611 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15612 {
15613 /* Read the zlib header. In this case, it should be "ZLIB"
15614 followed by the uncompressed section size, 8 bytes in
15615 big-endian order. */
15616 uncompressed_size = start[4]; uncompressed_size <<= 8;
15617 uncompressed_size += start[5]; uncompressed_size <<= 8;
15618 uncompressed_size += start[6]; uncompressed_size <<= 8;
15619 uncompressed_size += start[7]; uncompressed_size <<= 8;
15620 uncompressed_size += start[8]; uncompressed_size <<= 8;
15621 uncompressed_size += start[9]; uncompressed_size <<= 8;
15622 uncompressed_size += start[10]; uncompressed_size <<= 8;
15623 uncompressed_size += start[11];
15624 start += 12;
15625 new_size -= 12;
15626 }
15627
f055032e
NC
15628 if (uncompressed_size)
15629 {
1f5a3546
FS
15630 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
15631 &new_size))
bc303e5d
NC
15632 {
15633 section_size = new_size;
15634 }
f055032e
NC
15635 else
15636 {
15637 error (_("Unable to decompress section %s\n"),
dda8d76d 15638 printable_section_name (filedata, section));
bc303e5d 15639 /* FIXME: Print the section anyway ? */
f761cb13 15640 goto error_out;
f055032e
NC
15641 }
15642 }
bc303e5d
NC
15643 else
15644 start = real_start;
0e602686 15645 }
14ae95f2 15646
cf13d699
NC
15647 if (relocate)
15648 {
dda8d76d 15649 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15650 goto error_out;
cf13d699
NC
15651 }
15652 else
15653 {
15654 /* If the section being dumped has relocations against it the user might
15655 be expecting these relocations to have been applied. Check for this
15656 case and issue a warning message in order to avoid confusion.
15657 FIXME: Maybe we ought to have an option that dumps a section with
15658 relocs applied ? */
dda8d76d
NC
15659 for (relsec = filedata->section_headers;
15660 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15661 ++relsec)
15662 {
15663 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15664 || relsec->sh_info >= filedata->file_header.e_shnum
15665 || filedata->section_headers + relsec->sh_info != section
cf13d699 15666 || relsec->sh_size == 0
dda8d76d 15667 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15668 continue;
15669
15670 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15671 break;
15672 }
15673 }
15674
15675 addr = section->sh_addr;
0e602686 15676 bytes = section_size;
cf13d699
NC
15677 data = start;
15678
15679 while (bytes)
15680 {
15681 int j;
15682 int k;
15683 int lbytes;
15684
15685 lbytes = (bytes > 16 ? 16 : bytes);
15686
26c527e6 15687 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
15688
15689 for (j = 0; j < 16; j++)
15690 {
15691 if (j < lbytes)
15692 printf ("%2.2x", data[j]);
15693 else
15694 printf (" ");
15695
15696 if ((j & 3) == 3)
15697 printf (" ");
15698 }
15699
15700 for (j = 0; j < lbytes; j++)
15701 {
15702 k = data[j];
15703 if (k >= ' ' && k < 0x7f)
15704 printf ("%c", k);
15705 else
15706 printf (".");
15707 }
15708
15709 putchar ('\n');
15710
15711 data += lbytes;
15712 addr += lbytes;
15713 bytes -= lbytes;
15714 }
15715
0e602686 15716 free (real_start);
cf13d699
NC
15717
15718 putchar ('\n');
015dc7e1 15719 return true;
f761cb13
AM
15720
15721 error_out:
15722 free (real_start);
015dc7e1 15723 return false;
cf13d699
NC
15724}
15725
094e34f2 15726#ifdef ENABLE_LIBCTF
7d9813f1
NA
15727static ctf_sect_t *
15728shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15729{
84714f86 15730 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15731 buf->cts_size = shdr->sh_size;
15732 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15733
15734 return buf;
15735}
15736
15737/* Formatting callback function passed to ctf_dump. Returns either the pointer
15738 it is passed, or a pointer to newly-allocated storage, in which case
15739 dump_ctf() will free it when it no longer needs it. */
15740
2f6ecaed
NA
15741static char *
15742dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15743 char *s, void *arg)
7d9813f1 15744{
3e50a591 15745 const char *blanks = arg;
7d9813f1
NA
15746 char *new_s;
15747
3e50a591 15748 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15749 return s;
15750 return new_s;
15751}
15752
926c9e76
NA
15753/* Dump CTF errors/warnings. */
15754static void
139633c3 15755dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15756{
15757 ctf_next_t *it = NULL;
15758 char *errtext;
15759 int is_warning;
15760 int err;
15761
15762 /* Dump accumulated errors and warnings. */
15763 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15764 {
5e9b84f7 15765 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15766 errtext);
15767 free (errtext);
15768 }
15769 if (err != ECTF_NEXT_END)
15770 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15771}
15772
2f6ecaed
NA
15773/* Dump one CTF archive member. */
15774
80b56fad
NA
15775static void
15776dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15777 size_t member)
2f6ecaed 15778{
2f6ecaed
NA
15779 const char *things[] = {"Header", "Labels", "Data objects",
15780 "Function objects", "Variables", "Types", "Strings",
15781 ""};
15782 const char **thing;
15783 size_t i;
15784
80b56fad
NA
15785 /* Don't print out the name of the default-named archive member if it appears
15786 first in the list. The name .ctf appears everywhere, even for things that
15787 aren't really archives, so printing it out is liable to be confusing; also,
15788 the common case by far is for only one archive member to exist, and hiding
15789 it in that case seems worthwhile. */
2f6ecaed 15790
80b56fad
NA
15791 if (strcmp (name, ".ctf") != 0 || member != 0)
15792 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15793
80b56fad
NA
15794 if (ctf_parent_name (ctf) != NULL)
15795 ctf_import (ctf, parent);
2f6ecaed
NA
15796
15797 for (i = 0, thing = things; *thing[0]; thing++, i++)
15798 {
15799 ctf_dump_state_t *s = NULL;
15800 char *item;
15801
15802 printf ("\n %s:\n", *thing);
15803 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15804 (void *) " ")) != NULL)
15805 {
15806 printf ("%s\n", item);
15807 free (item);
15808 }
15809
15810 if (ctf_errno (ctf))
15811 {
15812 error (_("Iteration failed: %s, %s\n"), *thing,
15813 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15814 break;
2f6ecaed
NA
15815 }
15816 }
8b37e7b6 15817
926c9e76 15818 dump_ctf_errs (ctf);
2f6ecaed
NA
15819}
15820
015dc7e1 15821static bool
7d9813f1
NA
15822dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15823{
7d9813f1
NA
15824 Elf_Internal_Shdr * symtab_sec = NULL;
15825 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15826 void * data = NULL;
15827 void * symdata = NULL;
15828 void * strdata = NULL;
80b56fad 15829 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15830 ctf_sect_t * symsectp = NULL;
15831 ctf_sect_t * strsectp = NULL;
2f6ecaed 15832 ctf_archive_t * ctfa = NULL;
139633c3 15833 ctf_dict_t * parent = NULL;
80b56fad 15834 ctf_dict_t * fp;
7d9813f1 15835
80b56fad
NA
15836 ctf_next_t *i = NULL;
15837 const char *name;
15838 size_t member = 0;
7d9813f1 15839 int err;
015dc7e1 15840 bool ret = false;
7d9813f1
NA
15841
15842 shdr_to_ctf_sect (&ctfsect, section, filedata);
15843 data = get_section_contents (section, filedata);
15844 ctfsect.cts_data = data;
15845
616febde 15846 if (!dump_ctf_symtab_name)
3d16b64e 15847 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15848
15849 if (!dump_ctf_strtab_name)
3d16b64e 15850 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15851
15852 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15853 {
15854 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15855 {
15856 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15857 goto fail;
15858 }
15859 if ((symdata = (void *) get_data (NULL, filedata,
15860 symtab_sec->sh_offset, 1,
15861 symtab_sec->sh_size,
15862 _("symbols"))) == NULL)
15863 goto fail;
15864 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15865 symsect.cts_data = symdata;
15866 }
835f2fae 15867
df16e041 15868 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15869 {
15870 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15871 {
15872 error (_("No string table section named %s\n"),
15873 dump_ctf_strtab_name);
15874 goto fail;
15875 }
15876 if ((strdata = (void *) get_data (NULL, filedata,
15877 strtab_sec->sh_offset, 1,
15878 strtab_sec->sh_size,
15879 _("strings"))) == NULL)
15880 goto fail;
15881 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15882 strsect.cts_data = strdata;
15883 }
835f2fae 15884
2f6ecaed
NA
15885 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15886 libctf papers over the difference, so we can pretend it is always an
80b56fad 15887 archive. */
7d9813f1 15888
2f6ecaed 15889 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15890 {
926c9e76 15891 dump_ctf_errs (NULL);
7d9813f1
NA
15892 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15893 goto fail;
15894 }
15895
96c61be5
NA
15896 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15897 != ELFDATA2MSB);
15898
80b56fad
NA
15899 /* Preload the parent dict, since it will need to be imported into every
15900 child in turn. */
15901 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15902 {
926c9e76 15903 dump_ctf_errs (NULL);
2f6ecaed
NA
15904 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15905 goto fail;
7d9813f1
NA
15906 }
15907
015dc7e1 15908 ret = true;
7d9813f1 15909
835f2fae
NC
15910 if (filedata->is_separate)
15911 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15912 printable_section_name (filedata, section),
15913 filedata->file_name);
15914 else
15915 printf (_("\nDump of CTF section '%s':\n"),
15916 printable_section_name (filedata, section));
7d9813f1 15917
80b56fad
NA
15918 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15919 dump_ctf_archive_member (fp, name, parent, member++);
15920 if (err != ECTF_NEXT_END)
15921 {
15922 dump_ctf_errs (NULL);
15923 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15924 ret = false;
15925 }
7d9813f1
NA
15926
15927 fail:
139633c3 15928 ctf_dict_close (parent);
2f6ecaed 15929 ctf_close (ctfa);
7d9813f1
NA
15930 free (data);
15931 free (symdata);
15932 free (strdata);
15933 return ret;
15934}
094e34f2 15935#endif
7d9813f1 15936
42b6953b
IB
15937static bool
15938dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
15939{
15940 void * data = NULL;
15941 sframe_decoder_ctx *sfd_ctx = NULL;
15942 const char *print_name = printable_section_name (filedata, section);
15943
15944 bool ret = true;
15945 size_t sf_size;
15946 int err = 0;
15947
15948 if (strcmp (print_name, "") == 0)
15949 {
15950 error (_("Section name must be provided \n"));
15951 ret = false;
15952 return ret;
15953 }
15954
15955 data = get_section_contents (section, filedata);
15956 sf_size = section->sh_size;
15957 /* Decode the contents of the section. */
15958 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
15959 if (!sfd_ctx)
15960 {
15961 ret = false;
15962 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
15963 goto fail;
15964 }
15965
15966 printf (_("Contents of the SFrame section %s:"), print_name);
15967 /* Dump the contents as text. */
15968 dump_sframe (sfd_ctx, section->sh_addr);
15969
15970 fail:
15971 free (data);
15972 return ret;
15973}
15974
015dc7e1 15975static bool
dda8d76d
NC
15976load_specific_debug_section (enum dwarf_section_display_enum debug,
15977 const Elf_Internal_Shdr * sec,
15978 void * data)
1007acb3 15979{
2cf0635d 15980 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15981 char buf [64];
dda8d76d 15982 Filedata * filedata = (Filedata *) data;
9abca702 15983
19e6b90e 15984 if (section->start != NULL)
dda8d76d
NC
15985 {
15986 /* If it is already loaded, do nothing. */
15987 if (streq (section->filename, filedata->file_name))
015dc7e1 15988 return true;
dda8d76d
NC
15989 free (section->start);
15990 }
1007acb3 15991
19e6b90e
L
15992 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15993 section->address = sec->sh_addr;
dda8d76d
NC
15994 section->filename = filedata->file_name;
15995 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15996 sec->sh_offset, 1,
15997 sec->sh_size, buf);
59245841
NC
15998 if (section->start == NULL)
15999 section->size = 0;
16000 else
16001 {
77115a4a 16002 unsigned char *start = section->start;
31e5a3a3
AM
16003 uint64_t size = sec->sh_size;
16004 uint64_t uncompressed_size = 0;
1f5a3546 16005 bool is_zstd = false;
77115a4a
L
16006
16007 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16008 {
16009 Elf_Internal_Chdr chdr;
d8024a91
NC
16010 unsigned int compression_header_size;
16011
f53be977
L
16012 if (size < (is_32bit_elf
16013 ? sizeof (Elf32_External_Chdr)
16014 : sizeof (Elf64_External_Chdr)))
d8024a91 16015 {
55be8fd0 16016 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 16017 section->name);
015dc7e1 16018 return false;
d8024a91
NC
16019 }
16020
ebdf1ebf 16021 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
16022 if (compression_header_size == 0)
16023 /* An error message will have already been generated
16024 by get_compression_header. */
015dc7e1 16025 return false;
d8024a91 16026
1f5a3546
FS
16027 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
16028 ;
16029#ifdef HAVE_ZSTD
16030 else if (chdr.ch_type == ELFCOMPRESS_ZSTD)
16031 is_zstd = true;
16032#endif
16033 else
813dabb9
L
16034 {
16035 warn (_("section '%s' has unsupported compress type: %d\n"),
16036 section->name, chdr.ch_type);
015dc7e1 16037 return false;
813dabb9 16038 }
dab394de 16039 uncompressed_size = chdr.ch_size;
77115a4a
L
16040 start += compression_header_size;
16041 size -= compression_header_size;
16042 }
dab394de
L
16043 else if (size > 12 && streq ((char *) start, "ZLIB"))
16044 {
16045 /* Read the zlib header. In this case, it should be "ZLIB"
16046 followed by the uncompressed section size, 8 bytes in
16047 big-endian order. */
16048 uncompressed_size = start[4]; uncompressed_size <<= 8;
16049 uncompressed_size += start[5]; uncompressed_size <<= 8;
16050 uncompressed_size += start[6]; uncompressed_size <<= 8;
16051 uncompressed_size += start[7]; uncompressed_size <<= 8;
16052 uncompressed_size += start[8]; uncompressed_size <<= 8;
16053 uncompressed_size += start[9]; uncompressed_size <<= 8;
16054 uncompressed_size += start[10]; uncompressed_size <<= 8;
16055 uncompressed_size += start[11];
16056 start += 12;
16057 size -= 12;
16058 }
16059
1835f746 16060 if (uncompressed_size)
77115a4a 16061 {
1f5a3546 16062 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
1835f746
NC
16063 &size))
16064 {
16065 /* Free the compressed buffer, update the section buffer
16066 and the section size if uncompress is successful. */
16067 free (section->start);
16068 section->start = start;
16069 }
16070 else
16071 {
16072 error (_("Unable to decompress section %s\n"),
dda8d76d 16073 printable_section_name (filedata, sec));
015dc7e1 16074 return false;
1835f746 16075 }
77115a4a 16076 }
bc303e5d 16077
77115a4a 16078 section->size = size;
59245841 16079 }
4a114e3e 16080
1b315056 16081 if (section->start == NULL)
015dc7e1 16082 return false;
1b315056 16083
19e6b90e 16084 if (debug_displays [debug].relocate)
32ec8896 16085 {
dda8d76d 16086 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 16087 & section->reloc_info, & section->num_relocs))
015dc7e1 16088 return false;
32ec8896 16089 }
d1c4b12b
NC
16090 else
16091 {
16092 section->reloc_info = NULL;
16093 section->num_relocs = 0;
16094 }
1007acb3 16095
015dc7e1 16096 return true;
1007acb3
L
16097}
16098
301a9420
AM
16099#if HAVE_LIBDEBUGINFOD
16100/* Return a hex string representation of the build-id. */
16101unsigned char *
16102get_build_id (void * data)
16103{
ca0e11aa 16104 Filedata * filedata = (Filedata *) data;
301a9420 16105 Elf_Internal_Shdr * shdr;
26c527e6 16106 size_t i;
301a9420 16107
55be8fd0
NC
16108 /* Iterate through notes to find note.gnu.build-id.
16109 FIXME: Only the first note in any note section is examined. */
301a9420
AM
16110 for (i = 0, shdr = filedata->section_headers;
16111 i < filedata->file_header.e_shnum && shdr != NULL;
16112 i++, shdr++)
16113 {
16114 if (shdr->sh_type != SHT_NOTE)
16115 continue;
16116
16117 char * next;
16118 char * end;
16119 size_t data_remaining;
16120 size_t min_notesz;
16121 Elf_External_Note * enote;
16122 Elf_Internal_Note inote;
16123
625d49fc
AM
16124 uint64_t offset = shdr->sh_offset;
16125 uint64_t align = shdr->sh_addralign;
16126 uint64_t length = shdr->sh_size;
301a9420
AM
16127
16128 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16129 if (enote == NULL)
16130 continue;
16131
16132 if (align < 4)
16133 align = 4;
16134 else if (align != 4 && align != 8)
f761cb13
AM
16135 {
16136 free (enote);
16137 continue;
16138 }
301a9420
AM
16139
16140 end = (char *) enote + length;
16141 data_remaining = end - (char *) enote;
16142
16143 if (!is_ia64_vms (filedata))
16144 {
16145 min_notesz = offsetof (Elf_External_Note, name);
16146 if (data_remaining < min_notesz)
16147 {
55be8fd0
NC
16148 warn (_("\
16149malformed note encountered in section %s whilst scanning for build-id note\n"),
16150 printable_section_name (filedata, shdr));
f761cb13 16151 free (enote);
55be8fd0 16152 continue;
301a9420
AM
16153 }
16154 data_remaining -= min_notesz;
16155
16156 inote.type = BYTE_GET (enote->type);
16157 inote.namesz = BYTE_GET (enote->namesz);
16158 inote.namedata = enote->name;
16159 inote.descsz = BYTE_GET (enote->descsz);
16160 inote.descdata = ((char *) enote
16161 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16162 inote.descpos = offset + (inote.descdata - (char *) enote);
16163 next = ((char *) enote
16164 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16165 }
16166 else
16167 {
16168 Elf64_External_VMS_Note *vms_enote;
16169
16170 /* PR binutils/15191
16171 Make sure that there is enough data to read. */
16172 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16173 if (data_remaining < min_notesz)
16174 {
55be8fd0
NC
16175 warn (_("\
16176malformed note encountered in section %s whilst scanning for build-id note\n"),
16177 printable_section_name (filedata, shdr));
f761cb13 16178 free (enote);
55be8fd0 16179 continue;
301a9420
AM
16180 }
16181 data_remaining -= min_notesz;
16182
16183 vms_enote = (Elf64_External_VMS_Note *) enote;
16184 inote.type = BYTE_GET (vms_enote->type);
16185 inote.namesz = BYTE_GET (vms_enote->namesz);
16186 inote.namedata = vms_enote->name;
16187 inote.descsz = BYTE_GET (vms_enote->descsz);
16188 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16189 inote.descpos = offset + (inote.descdata - (char *) enote);
16190 next = inote.descdata + align_power (inote.descsz, 3);
16191 }
16192
16193 /* Skip malformed notes. */
16194 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16195 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16196 || (size_t) (next - inote.descdata) < inote.descsz
16197 || ((size_t) (next - inote.descdata)
16198 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16199 {
55be8fd0
NC
16200 warn (_("\
16201malformed note encountered in section %s whilst scanning for build-id note\n"),
16202 printable_section_name (filedata, shdr));
f761cb13 16203 free (enote);
301a9420
AM
16204 continue;
16205 }
16206
16207 /* Check if this is the build-id note. If so then convert the build-id
16208 bytes to a hex string. */
16209 if (inote.namesz > 0
24d127aa 16210 && startswith (inote.namedata, "GNU")
301a9420
AM
16211 && inote.type == NT_GNU_BUILD_ID)
16212 {
26c527e6 16213 size_t j;
301a9420
AM
16214 char * build_id;
16215
16216 build_id = malloc (inote.descsz * 2 + 1);
16217 if (build_id == NULL)
f761cb13
AM
16218 {
16219 free (enote);
16220 return NULL;
16221 }
301a9420
AM
16222
16223 for (j = 0; j < inote.descsz; ++j)
16224 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16225 build_id[inote.descsz * 2] = '\0';
f761cb13 16226 free (enote);
301a9420 16227
55be8fd0 16228 return (unsigned char *) build_id;
301a9420 16229 }
f761cb13 16230 free (enote);
301a9420
AM
16231 }
16232
16233 return NULL;
16234}
16235#endif /* HAVE_LIBDEBUGINFOD */
16236
657d0d47
CC
16237/* If this is not NULL, load_debug_section will only look for sections
16238 within the list of sections given here. */
32ec8896 16239static unsigned int * section_subset = NULL;
657d0d47 16240
015dc7e1 16241bool
dda8d76d 16242load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16243{
2cf0635d
NC
16244 struct dwarf_section * section = &debug_displays [debug].section;
16245 Elf_Internal_Shdr * sec;
dda8d76d
NC
16246 Filedata * filedata = (Filedata *) data;
16247
e1dbfc17
L
16248 if (!dump_any_debugging)
16249 return false;
16250
f425ec66
NC
16251 /* Without section headers we cannot find any sections. */
16252 if (filedata->section_headers == NULL)
015dc7e1 16253 return false;
f425ec66 16254
9c1ce108
AM
16255 if (filedata->string_table == NULL
16256 && filedata->file_header.e_shstrndx != SHN_UNDEF
16257 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16258 {
16259 Elf_Internal_Shdr * strs;
16260
16261 /* Read in the string table, so that we have section names to scan. */
16262 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16263
4dff97b2 16264 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16265 {
9c1ce108
AM
16266 filedata->string_table
16267 = (char *) get_data (NULL, filedata, strs->sh_offset,
16268 1, strs->sh_size, _("string table"));
dda8d76d 16269
9c1ce108
AM
16270 filedata->string_table_length
16271 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16272 }
16273 }
d966045b
DJ
16274
16275 /* Locate the debug section. */
dda8d76d 16276 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16277 if (sec != NULL)
16278 section->name = section->uncompressed_name;
16279 else
16280 {
dda8d76d 16281 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16282 if (sec != NULL)
16283 section->name = section->compressed_name;
16284 }
16285 if (sec == NULL)
015dc7e1 16286 return false;
d966045b 16287
657d0d47
CC
16288 /* If we're loading from a subset of sections, and we've loaded
16289 a section matching this name before, it's likely that it's a
16290 different one. */
16291 if (section_subset != NULL)
16292 free_debug_section (debug);
16293
dda8d76d 16294 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16295}
16296
19e6b90e
L
16297void
16298free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16299{
2cf0635d 16300 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16301
19e6b90e
L
16302 if (section->start == NULL)
16303 return;
1007acb3 16304
19e6b90e
L
16305 free ((char *) section->start);
16306 section->start = NULL;
16307 section->address = 0;
16308 section->size = 0;
a788aedd 16309
9db70fc3
AM
16310 free (section->reloc_info);
16311 section->reloc_info = NULL;
16312 section->num_relocs = 0;
1007acb3
L
16313}
16314
015dc7e1 16315static bool
dda8d76d 16316display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16317{
84714f86
AM
16318 const char *name = (section_name_valid (filedata, section)
16319 ? section_name (filedata, section) : "");
16320 const char *print_name = printable_section_name (filedata, section);
be7d229a 16321 uint64_t length;
015dc7e1 16322 bool result = true;
3f5e193b 16323 int i;
1007acb3 16324
19e6b90e
L
16325 length = section->sh_size;
16326 if (length == 0)
1007acb3 16327 {
74e1a04b 16328 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16329 return true;
1007acb3 16330 }
5dff79d8
NC
16331 if (section->sh_type == SHT_NOBITS)
16332 {
16333 /* There is no point in dumping the contents of a debugging section
16334 which has the NOBITS type - the bits in the file will be random.
16335 This can happen when a file containing a .eh_frame section is
16336 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16337 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16338 print_name);
015dc7e1 16339 return false;
5dff79d8 16340 }
1007acb3 16341
24d127aa 16342 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16343 name = ".debug_info";
1007acb3 16344
19e6b90e
L
16345 /* See if we know how to display the contents of this section. */
16346 for (i = 0; i < max; i++)
d85bf2ba
NC
16347 {
16348 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16349 struct dwarf_section_display * display = debug_displays + i;
16350 struct dwarf_section * sec = & display->section;
d966045b 16351
d85bf2ba 16352 if (streq (sec->uncompressed_name, name)
24d127aa 16353 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16354 || streq (sec->compressed_name, name))
16355 {
015dc7e1 16356 bool secondary = (section != find_section (filedata, name));
1007acb3 16357
d85bf2ba
NC
16358 if (secondary)
16359 free_debug_section (id);
dda8d76d 16360
24d127aa 16361 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16362 sec->name = name;
16363 else if (streq (sec->uncompressed_name, name))
16364 sec->name = sec->uncompressed_name;
16365 else
16366 sec->name = sec->compressed_name;
657d0d47 16367
d85bf2ba
NC
16368 if (load_specific_debug_section (id, section, filedata))
16369 {
16370 /* If this debug section is part of a CU/TU set in a .dwp file,
16371 restrict load_debug_section to the sections in that set. */
16372 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16373
d85bf2ba 16374 result &= display->display (sec, filedata);
657d0d47 16375
d85bf2ba 16376 section_subset = NULL;
1007acb3 16377
44266f36 16378 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16379 free_debug_section (id);
16380 }
16381 break;
16382 }
16383 }
1007acb3 16384
19e6b90e 16385 if (i == max)
1007acb3 16386 {
74e1a04b 16387 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16388 result = false;
1007acb3
L
16389 }
16390
19e6b90e 16391 return result;
5b18a4bc 16392}
103f02d3 16393
aef1f6d0
DJ
16394/* Set DUMP_SECTS for all sections where dumps were requested
16395 based on section name. */
16396
16397static void
dda8d76d 16398initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16399{
2cf0635d 16400 struct dump_list_entry * cur;
aef1f6d0
DJ
16401
16402 for (cur = dump_sects_byname; cur; cur = cur->next)
16403 {
16404 unsigned int i;
015dc7e1 16405 bool any = false;
aef1f6d0 16406
dda8d76d 16407 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16408 if (section_name_valid (filedata, filedata->section_headers + i)
16409 && streq (section_name (filedata, filedata->section_headers + i),
16410 cur->name))
aef1f6d0 16411 {
6431e409 16412 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16413 any = true;
aef1f6d0
DJ
16414 }
16415
835f2fae
NC
16416 if (!any && !filedata->is_separate)
16417 warn (_("Section '%s' was not dumped because it does not exist\n"),
16418 cur->name);
aef1f6d0
DJ
16419 }
16420}
16421
015dc7e1 16422static bool
dda8d76d 16423process_section_contents (Filedata * filedata)
5b18a4bc 16424{
2cf0635d 16425 Elf_Internal_Shdr * section;
19e6b90e 16426 unsigned int i;
015dc7e1 16427 bool res = true;
103f02d3 16428
19e6b90e 16429 if (! do_dump)
015dc7e1 16430 return true;
103f02d3 16431
dda8d76d 16432 initialise_dumps_byname (filedata);
aef1f6d0 16433
dda8d76d 16434 for (i = 0, section = filedata->section_headers;
6431e409 16435 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16436 i++, section++)
16437 {
6431e409 16438 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16439
d6bfbc39
NC
16440 if (filedata->is_separate && ! process_links)
16441 dump &= DEBUG_DUMP;
047c3dbf 16442
19e6b90e 16443#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16444 if (dump & DISASS_DUMP)
16445 {
16446 if (! disassemble_section (section, filedata))
015dc7e1 16447 res = false;
dda8d76d 16448 }
19e6b90e 16449#endif
dda8d76d 16450 if (dump & HEX_DUMP)
32ec8896 16451 {
015dc7e1
AM
16452 if (! dump_section_as_bytes (section, filedata, false))
16453 res = false;
32ec8896 16454 }
103f02d3 16455
dda8d76d 16456 if (dump & RELOC_DUMP)
32ec8896 16457 {
015dc7e1
AM
16458 if (! dump_section_as_bytes (section, filedata, true))
16459 res = false;
32ec8896 16460 }
09c11c86 16461
dda8d76d 16462 if (dump & STRING_DUMP)
32ec8896 16463 {
dda8d76d 16464 if (! dump_section_as_strings (section, filedata))
015dc7e1 16465 res = false;
32ec8896 16466 }
cf13d699 16467
dda8d76d 16468 if (dump & DEBUG_DUMP)
32ec8896 16469 {
dda8d76d 16470 if (! display_debug_section (i, section, filedata))
015dc7e1 16471 res = false;
32ec8896 16472 }
7d9813f1 16473
094e34f2 16474#ifdef ENABLE_LIBCTF
7d9813f1
NA
16475 if (dump & CTF_DUMP)
16476 {
16477 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16478 res = false;
7d9813f1 16479 }
094e34f2 16480#endif
42b6953b
IB
16481 if (dump & SFRAME_DUMP)
16482 {
16483 if (! dump_section_as_sframe (section, filedata))
16484 res = false;
16485 }
5b18a4bc 16486 }
103f02d3 16487
835f2fae 16488 if (! filedata->is_separate)
0ee3043f 16489 {
835f2fae
NC
16490 /* Check to see if the user requested a
16491 dump of a section that does not exist. */
16492 for (; i < filedata->dump.num_dump_sects; i++)
16493 if (filedata->dump.dump_sects[i])
16494 {
ca0e11aa 16495 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16496 res = false;
835f2fae 16497 }
0ee3043f 16498 }
32ec8896
NC
16499
16500 return res;
5b18a4bc 16501}
103f02d3 16502
5b18a4bc 16503static void
19e6b90e 16504process_mips_fpe_exception (int mask)
5b18a4bc 16505{
19e6b90e
L
16506 if (mask)
16507 {
015dc7e1 16508 bool first = true;
32ec8896 16509
19e6b90e 16510 if (mask & OEX_FPU_INEX)
015dc7e1 16511 fputs ("INEX", stdout), first = false;
19e6b90e 16512 if (mask & OEX_FPU_UFLO)
015dc7e1 16513 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16514 if (mask & OEX_FPU_OFLO)
015dc7e1 16515 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16516 if (mask & OEX_FPU_DIV0)
015dc7e1 16517 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16518 if (mask & OEX_FPU_INVAL)
16519 printf ("%sINVAL", first ? "" : "|");
16520 }
5b18a4bc 16521 else
19e6b90e 16522 fputs ("0", stdout);
5b18a4bc 16523}
103f02d3 16524
f6f0e17b
NC
16525/* Display's the value of TAG at location P. If TAG is
16526 greater than 0 it is assumed to be an unknown tag, and
16527 a message is printed to this effect. Otherwise it is
16528 assumed that a message has already been printed.
16529
16530 If the bottom bit of TAG is set it assumed to have a
16531 string value, otherwise it is assumed to have an integer
16532 value.
16533
16534 Returns an updated P pointing to the first unread byte
16535 beyond the end of TAG's value.
16536
16537 Reads at or beyond END will not be made. */
16538
16539static unsigned char *
60abdbed 16540display_tag_value (signed int tag,
f6f0e17b
NC
16541 unsigned char * p,
16542 const unsigned char * const end)
16543{
26c527e6 16544 uint64_t val;
f6f0e17b
NC
16545
16546 if (tag > 0)
16547 printf (" Tag_unknown_%d: ", tag);
16548
16549 if (p >= end)
16550 {
4082ef84 16551 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16552 }
16553 else if (tag & 1)
16554 {
071436c6
NC
16555 /* PR 17531 file: 027-19978-0.004. */
16556 size_t maxlen = (end - p) - 1;
16557
16558 putchar ('"');
4082ef84
NC
16559 if (maxlen > 0)
16560 {
16561 print_symbol ((int) maxlen, (const char *) p);
16562 p += strnlen ((char *) p, maxlen) + 1;
16563 }
16564 else
16565 {
16566 printf (_("<corrupt string tag>"));
16567 p = (unsigned char *) end;
16568 }
071436c6 16569 printf ("\"\n");
f6f0e17b
NC
16570 }
16571 else
16572 {
cd30bcef 16573 READ_ULEB (val, p, end);
26c527e6 16574 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
16575 }
16576
4082ef84 16577 assert (p <= end);
f6f0e17b
NC
16578 return p;
16579}
16580
53a346d8
CZ
16581/* ARC ABI attributes section. */
16582
16583static unsigned char *
16584display_arc_attribute (unsigned char * p,
16585 const unsigned char * const end)
16586{
16587 unsigned int tag;
53a346d8
CZ
16588 unsigned int val;
16589
cd30bcef 16590 READ_ULEB (tag, p, end);
53a346d8
CZ
16591
16592 switch (tag)
16593 {
16594 case Tag_ARC_PCS_config:
cd30bcef 16595 READ_ULEB (val, p, end);
53a346d8
CZ
16596 printf (" Tag_ARC_PCS_config: ");
16597 switch (val)
16598 {
16599 case 0:
16600 printf (_("Absent/Non standard\n"));
16601 break;
16602 case 1:
16603 printf (_("Bare metal/mwdt\n"));
16604 break;
16605 case 2:
16606 printf (_("Bare metal/newlib\n"));
16607 break;
16608 case 3:
16609 printf (_("Linux/uclibc\n"));
16610 break;
16611 case 4:
16612 printf (_("Linux/glibc\n"));
16613 break;
16614 default:
16615 printf (_("Unknown\n"));
16616 break;
16617 }
16618 break;
16619
16620 case Tag_ARC_CPU_base:
cd30bcef 16621 READ_ULEB (val, p, end);
53a346d8
CZ
16622 printf (" Tag_ARC_CPU_base: ");
16623 switch (val)
16624 {
16625 default:
16626 case TAG_CPU_NONE:
16627 printf (_("Absent\n"));
16628 break;
16629 case TAG_CPU_ARC6xx:
16630 printf ("ARC6xx\n");
16631 break;
16632 case TAG_CPU_ARC7xx:
16633 printf ("ARC7xx\n");
16634 break;
16635 case TAG_CPU_ARCEM:
16636 printf ("ARCEM\n");
16637 break;
16638 case TAG_CPU_ARCHS:
16639 printf ("ARCHS\n");
16640 break;
16641 }
16642 break;
16643
16644 case Tag_ARC_CPU_variation:
cd30bcef 16645 READ_ULEB (val, p, end);
53a346d8
CZ
16646 printf (" Tag_ARC_CPU_variation: ");
16647 switch (val)
16648 {
16649 default:
16650 if (val > 0 && val < 16)
53a346d8 16651 printf ("Core%d\n", val);
d8cbc93b
JL
16652 else
16653 printf ("Unknown\n");
16654 break;
16655
53a346d8
CZ
16656 case 0:
16657 printf (_("Absent\n"));
16658 break;
16659 }
16660 break;
16661
16662 case Tag_ARC_CPU_name:
16663 printf (" Tag_ARC_CPU_name: ");
16664 p = display_tag_value (-1, p, end);
16665 break;
16666
16667 case Tag_ARC_ABI_rf16:
cd30bcef 16668 READ_ULEB (val, p, end);
53a346d8
CZ
16669 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16670 break;
16671
16672 case Tag_ARC_ABI_osver:
cd30bcef 16673 READ_ULEB (val, p, end);
53a346d8
CZ
16674 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16675 break;
16676
16677 case Tag_ARC_ABI_pic:
16678 case Tag_ARC_ABI_sda:
cd30bcef 16679 READ_ULEB (val, p, end);
53a346d8
CZ
16680 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16681 : " Tag_ARC_ABI_pic: ");
16682 switch (val)
16683 {
16684 case 0:
16685 printf (_("Absent\n"));
16686 break;
16687 case 1:
16688 printf ("MWDT\n");
16689 break;
16690 case 2:
16691 printf ("GNU\n");
16692 break;
16693 default:
16694 printf (_("Unknown\n"));
16695 break;
16696 }
16697 break;
16698
16699 case Tag_ARC_ABI_tls:
cd30bcef 16700 READ_ULEB (val, p, end);
53a346d8
CZ
16701 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16702 break;
16703
16704 case Tag_ARC_ABI_enumsize:
cd30bcef 16705 READ_ULEB (val, p, end);
53a346d8
CZ
16706 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16707 _("smallest"));
16708 break;
16709
16710 case Tag_ARC_ABI_exceptions:
cd30bcef 16711 READ_ULEB (val, p, end);
53a346d8
CZ
16712 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16713 : _("default"));
16714 break;
16715
16716 case Tag_ARC_ABI_double_size:
cd30bcef 16717 READ_ULEB (val, p, end);
53a346d8
CZ
16718 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16719 break;
16720
16721 case Tag_ARC_ISA_config:
16722 printf (" Tag_ARC_ISA_config: ");
16723 p = display_tag_value (-1, p, end);
16724 break;
16725
16726 case Tag_ARC_ISA_apex:
16727 printf (" Tag_ARC_ISA_apex: ");
16728 p = display_tag_value (-1, p, end);
16729 break;
16730
16731 case Tag_ARC_ISA_mpy_option:
cd30bcef 16732 READ_ULEB (val, p, end);
53a346d8
CZ
16733 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16734 break;
16735
db1e1b45 16736 case Tag_ARC_ATR_version:
cd30bcef 16737 READ_ULEB (val, p, end);
db1e1b45 16738 printf (" Tag_ARC_ATR_version: %d\n", val);
16739 break;
16740
53a346d8
CZ
16741 default:
16742 return display_tag_value (tag & 1, p, end);
16743 }
16744
16745 return p;
16746}
16747
11c1ff18
PB
16748/* ARM EABI attributes section. */
16749typedef struct
16750{
70e99720 16751 unsigned int tag;
2cf0635d 16752 const char * name;
11c1ff18 16753 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16754 unsigned int type;
288f0ba2 16755 const char *const *table;
11c1ff18
PB
16756} arm_attr_public_tag;
16757
288f0ba2 16758static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16759 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16760 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16761 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16762 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16763static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16764static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16765 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16766static const char *const arm_attr_tag_FP_arch[] =
bca38921 16767 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16768 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16769static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16770static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16771 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16772 "NEON for ARMv8.1"};
288f0ba2 16773static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16774 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16775 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16776static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16777 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16778static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16779 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16780static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16781 {"Absolute", "PC-relative", "None"};
288f0ba2 16782static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16783 {"None", "direct", "GOT-indirect"};
288f0ba2 16784static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16785 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16786static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16787static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16788 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16789static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16790static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16791static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16792 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16793static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16794 {"Unused", "small", "int", "forced to int"};
288f0ba2 16795static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16796 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16797static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16798 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16799static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16800 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16801static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16802 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16803 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16804static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16805 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16806 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16807static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16808static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16809 {"Not Allowed", "Allowed"};
288f0ba2 16810static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16811 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16812static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16813 {"Follow architecture", "Allowed"};
288f0ba2 16814static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16815 {"Not Allowed", "Allowed"};
288f0ba2 16816static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16817 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16818 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16819static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16820static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16821 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16822 "TrustZone and Virtualization Extensions"};
288f0ba2 16823static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16824 {"Not Allowed", "Allowed"};
11c1ff18 16825
288f0ba2 16826static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16827 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16828
99db83d0
AC
16829static const char * arm_attr_tag_PAC_extension[] =
16830 {"No PAC/AUT instructions",
16831 "PAC/AUT instructions permitted in the NOP space",
16832 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16833
4b535030
AC
16834static const char * arm_attr_tag_BTI_extension[] =
16835 {"BTI instructions not permitted",
16836 "BTI instructions permitted in the NOP space",
16837 "BTI instructions permitted in the NOP and in the non-NOP space"};
16838
b81ee92f
AC
16839static const char * arm_attr_tag_BTI_use[] =
16840 {"Compiled without branch target enforcement",
16841 "Compiled with branch target enforcement"};
16842
c9fed665
AC
16843static const char * arm_attr_tag_PACRET_use[] =
16844 {"Compiled without return address signing and authentication",
16845 "Compiled with return address signing and authentication"};
16846
11c1ff18
PB
16847#define LOOKUP(id, name) \
16848 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16849static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16850{
16851 {4, "CPU_raw_name", 1, NULL},
16852 {5, "CPU_name", 1, NULL},
16853 LOOKUP(6, CPU_arch),
16854 {7, "CPU_arch_profile", 0, NULL},
16855 LOOKUP(8, ARM_ISA_use),
16856 LOOKUP(9, THUMB_ISA_use),
75375b3e 16857 LOOKUP(10, FP_arch),
11c1ff18 16858 LOOKUP(11, WMMX_arch),
f5f53991
AS
16859 LOOKUP(12, Advanced_SIMD_arch),
16860 LOOKUP(13, PCS_config),
11c1ff18
PB
16861 LOOKUP(14, ABI_PCS_R9_use),
16862 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16863 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16864 LOOKUP(17, ABI_PCS_GOT_use),
16865 LOOKUP(18, ABI_PCS_wchar_t),
16866 LOOKUP(19, ABI_FP_rounding),
16867 LOOKUP(20, ABI_FP_denormal),
16868 LOOKUP(21, ABI_FP_exceptions),
16869 LOOKUP(22, ABI_FP_user_exceptions),
16870 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16871 {24, "ABI_align_needed", 0, NULL},
16872 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16873 LOOKUP(26, ABI_enum_size),
16874 LOOKUP(27, ABI_HardFP_use),
16875 LOOKUP(28, ABI_VFP_args),
16876 LOOKUP(29, ABI_WMMX_args),
16877 LOOKUP(30, ABI_optimization_goals),
16878 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16879 {32, "compatibility", 0, NULL},
f5f53991 16880 LOOKUP(34, CPU_unaligned_access),
75375b3e 16881 LOOKUP(36, FP_HP_extension),
8e79c3df 16882 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16883 LOOKUP(42, MPextension_use),
16884 LOOKUP(44, DIV_use),
15afaa63 16885 LOOKUP(46, DSP_extension),
a7ad558c 16886 LOOKUP(48, MVE_arch),
99db83d0 16887 LOOKUP(50, PAC_extension),
4b535030 16888 LOOKUP(52, BTI_extension),
b81ee92f 16889 LOOKUP(74, BTI_use),
c9fed665 16890 LOOKUP(76, PACRET_use),
f5f53991
AS
16891 {64, "nodefaults", 0, NULL},
16892 {65, "also_compatible_with", 0, NULL},
16893 LOOKUP(66, T2EE_use),
16894 {67, "conformance", 1, NULL},
16895 LOOKUP(68, Virtualization_use),
cd21e546 16896 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16897};
16898#undef LOOKUP
16899
11c1ff18 16900static unsigned char *
f6f0e17b
NC
16901display_arm_attribute (unsigned char * p,
16902 const unsigned char * const end)
11c1ff18 16903{
70e99720 16904 unsigned int tag;
70e99720 16905 unsigned int val;
2cf0635d 16906 arm_attr_public_tag * attr;
11c1ff18 16907 unsigned i;
70e99720 16908 unsigned int type;
11c1ff18 16909
cd30bcef 16910 READ_ULEB (tag, p, end);
11c1ff18 16911 attr = NULL;
2cf0635d 16912 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16913 {
16914 if (arm_attr_public_tags[i].tag == tag)
16915 {
16916 attr = &arm_attr_public_tags[i];
16917 break;
16918 }
16919 }
16920
16921 if (attr)
16922 {
16923 printf (" Tag_%s: ", attr->name);
16924 switch (attr->type)
16925 {
16926 case 0:
16927 switch (tag)
16928 {
16929 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16930 READ_ULEB (val, p, end);
11c1ff18
PB
16931 switch (val)
16932 {
2b692964
NC
16933 case 0: printf (_("None\n")); break;
16934 case 'A': printf (_("Application\n")); break;
16935 case 'R': printf (_("Realtime\n")); break;
16936 case 'M': printf (_("Microcontroller\n")); break;
16937 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16938 default: printf ("??? (%d)\n", val); break;
16939 }
16940 break;
16941
75375b3e 16942 case 24: /* Tag_align_needed. */
cd30bcef 16943 READ_ULEB (val, p, end);
75375b3e
MGD
16944 switch (val)
16945 {
2b692964
NC
16946 case 0: printf (_("None\n")); break;
16947 case 1: printf (_("8-byte\n")); break;
16948 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16949 case 3: printf ("??? 3\n"); break;
16950 default:
16951 if (val <= 12)
dd24e3da 16952 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16953 1 << val);
16954 else
16955 printf ("??? (%d)\n", val);
16956 break;
16957 }
16958 break;
16959
16960 case 25: /* Tag_align_preserved. */
cd30bcef 16961 READ_ULEB (val, p, end);
75375b3e
MGD
16962 switch (val)
16963 {
2b692964
NC
16964 case 0: printf (_("None\n")); break;
16965 case 1: printf (_("8-byte, except leaf SP\n")); break;
16966 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16967 case 3: printf ("??? 3\n"); break;
16968 default:
16969 if (val <= 12)
dd24e3da 16970 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16971 1 << val);
16972 else
16973 printf ("??? (%d)\n", val);
16974 break;
16975 }
16976 break;
16977
11c1ff18 16978 case 32: /* Tag_compatibility. */
071436c6 16979 {
cd30bcef 16980 READ_ULEB (val, p, end);
071436c6 16981 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16982 if (p < end - 1)
16983 {
16984 size_t maxlen = (end - p) - 1;
16985
16986 print_symbol ((int) maxlen, (const char *) p);
16987 p += strnlen ((char *) p, maxlen) + 1;
16988 }
16989 else
16990 {
16991 printf (_("<corrupt>"));
16992 p = (unsigned char *) end;
16993 }
071436c6 16994 putchar ('\n');
071436c6 16995 }
11c1ff18
PB
16996 break;
16997
f5f53991 16998 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16999 /* PR 17531: file: 001-505008-0.01. */
17000 if (p < end)
17001 p++;
2b692964 17002 printf (_("True\n"));
f5f53991
AS
17003 break;
17004
17005 case 65: /* Tag_also_compatible_with. */
cd30bcef 17006 READ_ULEB (val, p, end);
f5f53991
AS
17007 if (val == 6 /* Tag_CPU_arch. */)
17008 {
cd30bcef 17009 READ_ULEB (val, p, end);
071436c6 17010 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
17011 printf ("??? (%d)\n", val);
17012 else
17013 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17014 }
17015 else
17016 printf ("???\n");
071436c6
NC
17017 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17018 ;
f5f53991
AS
17019 break;
17020
11c1ff18 17021 default:
bee0ee85
NC
17022 printf (_("<unknown: %d>\n"), tag);
17023 break;
11c1ff18
PB
17024 }
17025 return p;
17026
17027 case 1:
f6f0e17b 17028 return display_tag_value (-1, p, end);
11c1ff18 17029 case 2:
f6f0e17b 17030 return display_tag_value (0, p, end);
11c1ff18
PB
17031
17032 default:
17033 assert (attr->type & 0x80);
cd30bcef 17034 READ_ULEB (val, p, end);
11c1ff18
PB
17035 type = attr->type & 0x7f;
17036 if (val >= type)
17037 printf ("??? (%d)\n", val);
17038 else
17039 printf ("%s\n", attr->table[val]);
17040 return p;
17041 }
17042 }
11c1ff18 17043
f6f0e17b 17044 return display_tag_value (tag, p, end);
11c1ff18
PB
17045}
17046
104d59d1 17047static unsigned char *
60bca95a 17048display_gnu_attribute (unsigned char * p,
60abdbed 17049 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 17050 const unsigned char * const end)
104d59d1 17051{
cd30bcef 17052 unsigned int tag;
60abdbed 17053 unsigned int val;
104d59d1 17054
cd30bcef 17055 READ_ULEB (tag, p, end);
104d59d1
JM
17056
17057 /* Tag_compatibility is the only generic GNU attribute defined at
17058 present. */
17059 if (tag == 32)
17060 {
cd30bcef 17061 READ_ULEB (val, p, end);
071436c6
NC
17062
17063 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
17064 if (p == end)
17065 {
071436c6 17066 printf (_("<corrupt>\n"));
f6f0e17b
NC
17067 warn (_("corrupt vendor attribute\n"));
17068 }
17069 else
17070 {
4082ef84
NC
17071 if (p < end - 1)
17072 {
17073 size_t maxlen = (end - p) - 1;
071436c6 17074
4082ef84
NC
17075 print_symbol ((int) maxlen, (const char *) p);
17076 p += strnlen ((char *) p, maxlen) + 1;
17077 }
17078 else
17079 {
17080 printf (_("<corrupt>"));
17081 p = (unsigned char *) end;
17082 }
071436c6 17083 putchar ('\n');
f6f0e17b 17084 }
104d59d1
JM
17085 return p;
17086 }
17087
17088 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 17089 return display_proc_gnu_attribute (p, tag, end);
104d59d1 17090
f6f0e17b 17091 return display_tag_value (tag, p, end);
104d59d1
JM
17092}
17093
85f7484a
PB
17094static unsigned char *
17095display_m68k_gnu_attribute (unsigned char * p,
17096 unsigned int tag,
17097 const unsigned char * const end)
17098{
17099 unsigned int val;
17100
17101 if (tag == Tag_GNU_M68K_ABI_FP)
17102 {
17103 printf (" Tag_GNU_M68K_ABI_FP: ");
17104 if (p == end)
17105 {
17106 printf (_("<corrupt>\n"));
17107 return p;
17108 }
17109 READ_ULEB (val, p, end);
17110
17111 if (val > 3)
17112 printf ("(%#x), ", val);
17113
17114 switch (val & 3)
17115 {
17116 case 0:
17117 printf (_("unspecified hard/soft float\n"));
17118 break;
17119 case 1:
17120 printf (_("hard float\n"));
17121 break;
17122 case 2:
17123 printf (_("soft float\n"));
17124 break;
17125 }
17126 return p;
17127 }
17128
17129 return display_tag_value (tag & 1, p, end);
17130}
17131
34c8bcba 17132static unsigned char *
f6f0e17b 17133display_power_gnu_attribute (unsigned char * p,
60abdbed 17134 unsigned int tag,
f6f0e17b 17135 const unsigned char * const end)
34c8bcba 17136{
005d79fd 17137 unsigned int val;
34c8bcba
JM
17138
17139 if (tag == Tag_GNU_Power_ABI_FP)
17140 {
34c8bcba 17141 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 17142 if (p == end)
005d79fd
AM
17143 {
17144 printf (_("<corrupt>\n"));
17145 return p;
17146 }
cd30bcef 17147 READ_ULEB (val, p, end);
60bca95a 17148
005d79fd
AM
17149 if (val > 15)
17150 printf ("(%#x), ", val);
17151
17152 switch (val & 3)
34c8bcba
JM
17153 {
17154 case 0:
005d79fd 17155 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17156 break;
17157 case 1:
005d79fd 17158 printf (_("hard float, "));
34c8bcba
JM
17159 break;
17160 case 2:
005d79fd 17161 printf (_("soft float, "));
34c8bcba 17162 break;
3c7b9897 17163 case 3:
005d79fd 17164 printf (_("single-precision hard float, "));
3c7b9897 17165 break;
005d79fd
AM
17166 }
17167
17168 switch (val & 0xC)
17169 {
17170 case 0:
17171 printf (_("unspecified long double\n"));
17172 break;
17173 case 4:
17174 printf (_("128-bit IBM long double\n"));
17175 break;
17176 case 8:
17177 printf (_("64-bit long double\n"));
17178 break;
17179 case 12:
17180 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17181 break;
17182 }
17183 return p;
005d79fd 17184 }
34c8bcba 17185
c6e65352
DJ
17186 if (tag == Tag_GNU_Power_ABI_Vector)
17187 {
c6e65352 17188 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17189 if (p == end)
005d79fd
AM
17190 {
17191 printf (_("<corrupt>\n"));
17192 return p;
17193 }
cd30bcef 17194 READ_ULEB (val, p, end);
005d79fd
AM
17195
17196 if (val > 3)
17197 printf ("(%#x), ", val);
17198
17199 switch (val & 3)
c6e65352
DJ
17200 {
17201 case 0:
005d79fd 17202 printf (_("unspecified\n"));
c6e65352
DJ
17203 break;
17204 case 1:
005d79fd 17205 printf (_("generic\n"));
c6e65352
DJ
17206 break;
17207 case 2:
17208 printf ("AltiVec\n");
17209 break;
17210 case 3:
17211 printf ("SPE\n");
17212 break;
c6e65352
DJ
17213 }
17214 return p;
005d79fd 17215 }
c6e65352 17216
f82e0623
NF
17217 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17218 {
005d79fd 17219 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17220 if (p == end)
f6f0e17b 17221 {
005d79fd 17222 printf (_("<corrupt>\n"));
f6f0e17b
NC
17223 return p;
17224 }
cd30bcef 17225 READ_ULEB (val, p, end);
0b4362b0 17226
005d79fd
AM
17227 if (val > 2)
17228 printf ("(%#x), ", val);
17229
17230 switch (val & 3)
17231 {
17232 case 0:
17233 printf (_("unspecified\n"));
17234 break;
17235 case 1:
17236 printf ("r3/r4\n");
17237 break;
17238 case 2:
17239 printf (_("memory\n"));
17240 break;
17241 case 3:
17242 printf ("???\n");
17243 break;
17244 }
f82e0623
NF
17245 return p;
17246 }
17247
f6f0e17b 17248 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17249}
17250
643f7afb
AK
17251static unsigned char *
17252display_s390_gnu_attribute (unsigned char * p,
60abdbed 17253 unsigned int tag,
643f7afb
AK
17254 const unsigned char * const end)
17255{
cd30bcef 17256 unsigned int val;
643f7afb
AK
17257
17258 if (tag == Tag_GNU_S390_ABI_Vector)
17259 {
643f7afb 17260 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17261 READ_ULEB (val, p, end);
643f7afb
AK
17262
17263 switch (val)
17264 {
17265 case 0:
17266 printf (_("any\n"));
17267 break;
17268 case 1:
17269 printf (_("software\n"));
17270 break;
17271 case 2:
17272 printf (_("hardware\n"));
17273 break;
17274 default:
17275 printf ("??? (%d)\n", val);
17276 break;
17277 }
17278 return p;
17279 }
17280
17281 return display_tag_value (tag & 1, p, end);
17282}
17283
9e8c70f9 17284static void
60abdbed 17285display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17286{
17287 if (mask)
17288 {
015dc7e1 17289 bool first = true;
071436c6 17290
9e8c70f9 17291 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17292 fputs ("mul32", stdout), first = false;
9e8c70f9 17293 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17294 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17295 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17296 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17297 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17298 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17299 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17300 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17301 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17302 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17303 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17304 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17305 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17306 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17307 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17308 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17309 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17310 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17311 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17312 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17313 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17314 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17315 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17316 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17317 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17318 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17319 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17320 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17321 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17322 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17323 }
17324 else
071436c6
NC
17325 fputc ('0', stdout);
17326 fputc ('\n', stdout);
9e8c70f9
DM
17327}
17328
3d68f91c 17329static void
60abdbed 17330display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17331{
17332 if (mask)
17333 {
015dc7e1 17334 bool first = true;
071436c6 17335
3d68f91c 17336 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17337 fputs ("fjathplus", stdout), first = false;
3d68f91c 17338 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17339 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17340 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17341 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17342 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17343 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17344 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17345 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17346 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17347 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17348 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17349 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17350 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17351 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17352 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17353 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17354 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17355 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17356 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17357 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17358 }
17359 else
071436c6
NC
17360 fputc ('0', stdout);
17361 fputc ('\n', stdout);
3d68f91c
JM
17362}
17363
9e8c70f9 17364static unsigned char *
f6f0e17b 17365display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17366 unsigned int tag,
f6f0e17b 17367 const unsigned char * const end)
9e8c70f9 17368{
cd30bcef 17369 unsigned int val;
3d68f91c 17370
9e8c70f9
DM
17371 if (tag == Tag_GNU_Sparc_HWCAPS)
17372 {
cd30bcef 17373 READ_ULEB (val, p, end);
9e8c70f9 17374 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17375 display_sparc_hwcaps (val);
17376 return p;
3d68f91c
JM
17377 }
17378 if (tag == Tag_GNU_Sparc_HWCAPS2)
17379 {
cd30bcef 17380 READ_ULEB (val, p, end);
3d68f91c
JM
17381 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17382 display_sparc_hwcaps2 (val);
17383 return p;
17384 }
9e8c70f9 17385
f6f0e17b 17386 return display_tag_value (tag, p, end);
9e8c70f9
DM
17387}
17388
351cdf24 17389static void
32ec8896 17390print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17391{
17392 switch (val)
17393 {
17394 case Val_GNU_MIPS_ABI_FP_ANY:
17395 printf (_("Hard or soft float\n"));
17396 break;
17397 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17398 printf (_("Hard float (double precision)\n"));
17399 break;
17400 case Val_GNU_MIPS_ABI_FP_SINGLE:
17401 printf (_("Hard float (single precision)\n"));
17402 break;
17403 case Val_GNU_MIPS_ABI_FP_SOFT:
17404 printf (_("Soft float\n"));
17405 break;
17406 case Val_GNU_MIPS_ABI_FP_OLD_64:
17407 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17408 break;
17409 case Val_GNU_MIPS_ABI_FP_XX:
17410 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17411 break;
17412 case Val_GNU_MIPS_ABI_FP_64:
17413 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17414 break;
17415 case Val_GNU_MIPS_ABI_FP_64A:
17416 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17417 break;
3350cc01
CM
17418 case Val_GNU_MIPS_ABI_FP_NAN2008:
17419 printf (_("NaN 2008 compatibility\n"));
17420 break;
351cdf24
MF
17421 default:
17422 printf ("??? (%d)\n", val);
17423 break;
17424 }
17425}
17426
2cf19d5c 17427static unsigned char *
f6f0e17b 17428display_mips_gnu_attribute (unsigned char * p,
60abdbed 17429 unsigned int tag,
f6f0e17b 17430 const unsigned char * const end)
2cf19d5c 17431{
2cf19d5c
JM
17432 if (tag == Tag_GNU_MIPS_ABI_FP)
17433 {
32ec8896 17434 unsigned int val;
f6f0e17b 17435
2cf19d5c 17436 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17437 READ_ULEB (val, p, end);
351cdf24 17438 print_mips_fp_abi_value (val);
2cf19d5c
JM
17439 return p;
17440 }
17441
a9f58168
CF
17442 if (tag == Tag_GNU_MIPS_ABI_MSA)
17443 {
32ec8896 17444 unsigned int val;
a9f58168 17445
a9f58168 17446 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17447 READ_ULEB (val, p, end);
a9f58168
CF
17448
17449 switch (val)
17450 {
17451 case Val_GNU_MIPS_ABI_MSA_ANY:
17452 printf (_("Any MSA or not\n"));
17453 break;
17454 case Val_GNU_MIPS_ABI_MSA_128:
17455 printf (_("128-bit MSA\n"));
17456 break;
17457 default:
17458 printf ("??? (%d)\n", val);
17459 break;
17460 }
17461 return p;
17462 }
17463
f6f0e17b 17464 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17465}
17466
59e6276b 17467static unsigned char *
f6f0e17b
NC
17468display_tic6x_attribute (unsigned char * p,
17469 const unsigned char * const end)
59e6276b 17470{
60abdbed 17471 unsigned int tag;
cd30bcef 17472 unsigned int val;
59e6276b 17473
cd30bcef 17474 READ_ULEB (tag, p, end);
59e6276b
JM
17475
17476 switch (tag)
17477 {
75fa6dc1 17478 case Tag_ISA:
75fa6dc1 17479 printf (" Tag_ISA: ");
cd30bcef 17480 READ_ULEB (val, p, end);
59e6276b
JM
17481
17482 switch (val)
17483 {
75fa6dc1 17484 case C6XABI_Tag_ISA_none:
59e6276b
JM
17485 printf (_("None\n"));
17486 break;
75fa6dc1 17487 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17488 printf ("C62x\n");
17489 break;
75fa6dc1 17490 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17491 printf ("C67x\n");
17492 break;
75fa6dc1 17493 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17494 printf ("C67x+\n");
17495 break;
75fa6dc1 17496 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17497 printf ("C64x\n");
17498 break;
75fa6dc1 17499 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17500 printf ("C64x+\n");
17501 break;
75fa6dc1 17502 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17503 printf ("C674x\n");
17504 break;
17505 default:
17506 printf ("??? (%d)\n", val);
17507 break;
17508 }
17509 return p;
17510
87779176 17511 case Tag_ABI_wchar_t:
87779176 17512 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17513 READ_ULEB (val, p, end);
87779176
JM
17514 switch (val)
17515 {
17516 case 0:
17517 printf (_("Not used\n"));
17518 break;
17519 case 1:
17520 printf (_("2 bytes\n"));
17521 break;
17522 case 2:
17523 printf (_("4 bytes\n"));
17524 break;
17525 default:
17526 printf ("??? (%d)\n", val);
17527 break;
17528 }
17529 return p;
17530
17531 case Tag_ABI_stack_align_needed:
87779176 17532 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17533 READ_ULEB (val, p, end);
87779176
JM
17534 switch (val)
17535 {
17536 case 0:
17537 printf (_("8-byte\n"));
17538 break;
17539 case 1:
17540 printf (_("16-byte\n"));
17541 break;
17542 default:
17543 printf ("??? (%d)\n", val);
17544 break;
17545 }
17546 return p;
17547
17548 case Tag_ABI_stack_align_preserved:
cd30bcef 17549 READ_ULEB (val, p, end);
87779176
JM
17550 printf (" Tag_ABI_stack_align_preserved: ");
17551 switch (val)
17552 {
17553 case 0:
17554 printf (_("8-byte\n"));
17555 break;
17556 case 1:
17557 printf (_("16-byte\n"));
17558 break;
17559 default:
17560 printf ("??? (%d)\n", val);
17561 break;
17562 }
17563 return p;
17564
b5593623 17565 case Tag_ABI_DSBT:
cd30bcef 17566 READ_ULEB (val, p, end);
b5593623
JM
17567 printf (" Tag_ABI_DSBT: ");
17568 switch (val)
17569 {
17570 case 0:
17571 printf (_("DSBT addressing not used\n"));
17572 break;
17573 case 1:
17574 printf (_("DSBT addressing used\n"));
17575 break;
17576 default:
17577 printf ("??? (%d)\n", val);
17578 break;
17579 }
17580 return p;
17581
87779176 17582 case Tag_ABI_PID:
cd30bcef 17583 READ_ULEB (val, p, end);
87779176
JM
17584 printf (" Tag_ABI_PID: ");
17585 switch (val)
17586 {
17587 case 0:
17588 printf (_("Data addressing position-dependent\n"));
17589 break;
17590 case 1:
17591 printf (_("Data addressing position-independent, GOT near DP\n"));
17592 break;
17593 case 2:
17594 printf (_("Data addressing position-independent, GOT far from DP\n"));
17595 break;
17596 default:
17597 printf ("??? (%d)\n", val);
17598 break;
17599 }
17600 return p;
17601
17602 case Tag_ABI_PIC:
cd30bcef 17603 READ_ULEB (val, p, end);
87779176
JM
17604 printf (" Tag_ABI_PIC: ");
17605 switch (val)
17606 {
17607 case 0:
17608 printf (_("Code addressing position-dependent\n"));
17609 break;
17610 case 1:
17611 printf (_("Code addressing position-independent\n"));
17612 break;
17613 default:
17614 printf ("??? (%d)\n", val);
17615 break;
17616 }
17617 return p;
17618
17619 case Tag_ABI_array_object_alignment:
cd30bcef 17620 READ_ULEB (val, p, end);
87779176
JM
17621 printf (" Tag_ABI_array_object_alignment: ");
17622 switch (val)
17623 {
17624 case 0:
17625 printf (_("8-byte\n"));
17626 break;
17627 case 1:
17628 printf (_("4-byte\n"));
17629 break;
17630 case 2:
17631 printf (_("16-byte\n"));
17632 break;
17633 default:
17634 printf ("??? (%d)\n", val);
17635 break;
17636 }
17637 return p;
17638
17639 case Tag_ABI_array_object_align_expected:
cd30bcef 17640 READ_ULEB (val, p, end);
87779176
JM
17641 printf (" Tag_ABI_array_object_align_expected: ");
17642 switch (val)
17643 {
17644 case 0:
17645 printf (_("8-byte\n"));
17646 break;
17647 case 1:
17648 printf (_("4-byte\n"));
17649 break;
17650 case 2:
17651 printf (_("16-byte\n"));
17652 break;
17653 default:
17654 printf ("??? (%d)\n", val);
17655 break;
17656 }
17657 return p;
17658
3cbd1c06 17659 case Tag_ABI_compatibility:
071436c6 17660 {
cd30bcef 17661 READ_ULEB (val, p, end);
071436c6 17662 printf (" Tag_ABI_compatibility: ");
071436c6 17663 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17664 if (p < end - 1)
17665 {
17666 size_t maxlen = (end - p) - 1;
17667
17668 print_symbol ((int) maxlen, (const char *) p);
17669 p += strnlen ((char *) p, maxlen) + 1;
17670 }
17671 else
17672 {
17673 printf (_("<corrupt>"));
17674 p = (unsigned char *) end;
17675 }
071436c6 17676 putchar ('\n');
071436c6
NC
17677 return p;
17678 }
87779176
JM
17679
17680 case Tag_ABI_conformance:
071436c6 17681 {
4082ef84
NC
17682 printf (" Tag_ABI_conformance: \"");
17683 if (p < end - 1)
17684 {
17685 size_t maxlen = (end - p) - 1;
071436c6 17686
4082ef84
NC
17687 print_symbol ((int) maxlen, (const char *) p);
17688 p += strnlen ((char *) p, maxlen) + 1;
17689 }
17690 else
17691 {
17692 printf (_("<corrupt>"));
17693 p = (unsigned char *) end;
17694 }
071436c6 17695 printf ("\"\n");
071436c6
NC
17696 return p;
17697 }
59e6276b
JM
17698 }
17699
f6f0e17b
NC
17700 return display_tag_value (tag, p, end);
17701}
59e6276b 17702
f6f0e17b 17703static void
60abdbed 17704display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 17705{
26c527e6 17706 uint64_t addr = 0;
f6f0e17b
NC
17707 size_t bytes = end - p;
17708
feceaa59 17709 assert (end >= p);
f6f0e17b 17710 while (bytes)
87779176 17711 {
f6f0e17b
NC
17712 int j;
17713 int k;
17714 int lbytes = (bytes > 16 ? 16 : bytes);
17715
26c527e6 17716 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
17717
17718 for (j = 0; j < 16; j++)
17719 {
17720 if (j < lbytes)
17721 printf ("%2.2x", p[j]);
17722 else
17723 printf (" ");
17724
17725 if ((j & 3) == 3)
17726 printf (" ");
17727 }
17728
17729 for (j = 0; j < lbytes; j++)
17730 {
17731 k = p[j];
17732 if (k >= ' ' && k < 0x7f)
17733 printf ("%c", k);
17734 else
17735 printf (".");
17736 }
17737
17738 putchar ('\n');
17739
17740 p += lbytes;
17741 bytes -= lbytes;
17742 addr += lbytes;
87779176 17743 }
59e6276b 17744
f6f0e17b 17745 putchar ('\n');
59e6276b
JM
17746}
17747
13761a11 17748static unsigned char *
b0191216 17749display_msp430_attribute (unsigned char * p,
26c527e6 17750 const unsigned char * const end)
13761a11 17751{
26c527e6
AM
17752 uint64_t val;
17753 uint64_t tag;
13761a11 17754
cd30bcef 17755 READ_ULEB (tag, p, end);
0b4362b0 17756
13761a11
NC
17757 switch (tag)
17758 {
17759 case OFBA_MSPABI_Tag_ISA:
13761a11 17760 printf (" Tag_ISA: ");
cd30bcef 17761 READ_ULEB (val, p, end);
13761a11
NC
17762 switch (val)
17763 {
17764 case 0: printf (_("None\n")); break;
17765 case 1: printf (_("MSP430\n")); break;
17766 case 2: printf (_("MSP430X\n")); break;
26c527e6 17767 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17768 }
17769 break;
17770
17771 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17772 printf (" Tag_Code_Model: ");
cd30bcef 17773 READ_ULEB (val, p, end);
13761a11
NC
17774 switch (val)
17775 {
17776 case 0: printf (_("None\n")); break;
17777 case 1: printf (_("Small\n")); break;
17778 case 2: printf (_("Large\n")); break;
26c527e6 17779 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17780 }
17781 break;
17782
17783 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17784 printf (" Tag_Data_Model: ");
cd30bcef 17785 READ_ULEB (val, p, end);
13761a11
NC
17786 switch (val)
17787 {
17788 case 0: printf (_("None\n")); break;
17789 case 1: printf (_("Small\n")); break;
17790 case 2: printf (_("Large\n")); break;
17791 case 3: printf (_("Restricted Large\n")); break;
26c527e6 17792 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
17793 }
17794 break;
17795
17796 default:
26c527e6 17797 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
17798
17799 if (tag & 1)
17800 {
071436c6 17801 putchar ('"');
4082ef84
NC
17802 if (p < end - 1)
17803 {
17804 size_t maxlen = (end - p) - 1;
17805
17806 print_symbol ((int) maxlen, (const char *) p);
17807 p += strnlen ((char *) p, maxlen) + 1;
17808 }
17809 else
17810 {
17811 printf (_("<corrupt>"));
17812 p = (unsigned char *) end;
17813 }
071436c6 17814 printf ("\"\n");
13761a11
NC
17815 }
17816 else
17817 {
cd30bcef 17818 READ_ULEB (val, p, end);
26c527e6 17819 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
17820 }
17821 break;
17822 }
17823
4082ef84 17824 assert (p <= end);
13761a11
NC
17825 return p;
17826}
17827
c0ea7c52
JL
17828static unsigned char *
17829display_msp430_gnu_attribute (unsigned char * p,
17830 unsigned int tag,
17831 const unsigned char * const end)
17832{
17833 if (tag == Tag_GNU_MSP430_Data_Region)
17834 {
26c527e6 17835 uint64_t val;
c0ea7c52 17836
c0ea7c52 17837 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17838 READ_ULEB (val, p, end);
c0ea7c52
JL
17839
17840 switch (val)
17841 {
17842 case Val_GNU_MSP430_Data_Region_Any:
17843 printf (_("Any Region\n"));
17844 break;
17845 case Val_GNU_MSP430_Data_Region_Lower:
17846 printf (_("Lower Region Only\n"));
17847 break;
17848 default:
26c527e6 17849 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
17850 }
17851 return p;
17852 }
17853 return display_tag_value (tag & 1, p, end);
17854}
17855
2dc8dd17
JW
17856struct riscv_attr_tag_t {
17857 const char *name;
cd30bcef 17858 unsigned int tag;
2dc8dd17
JW
17859};
17860
17861static struct riscv_attr_tag_t riscv_attr_tag[] =
17862{
17863#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17864 T(arch),
17865 T(priv_spec),
17866 T(priv_spec_minor),
17867 T(priv_spec_revision),
17868 T(unaligned_access),
17869 T(stack_align),
17870#undef T
17871};
17872
17873static unsigned char *
17874display_riscv_attribute (unsigned char *p,
17875 const unsigned char * const end)
17876{
26c527e6
AM
17877 uint64_t val;
17878 uint64_t tag;
2dc8dd17
JW
17879 struct riscv_attr_tag_t *attr = NULL;
17880 unsigned i;
17881
cd30bcef 17882 READ_ULEB (tag, p, end);
2dc8dd17
JW
17883
17884 /* Find the name of attribute. */
17885 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17886 {
17887 if (riscv_attr_tag[i].tag == tag)
17888 {
17889 attr = &riscv_attr_tag[i];
17890 break;
17891 }
17892 }
17893
17894 if (attr)
17895 printf (" %s: ", attr->name);
17896 else
17897 return display_tag_value (tag, p, end);
17898
17899 switch (tag)
17900 {
17901 case Tag_RISCV_priv_spec:
17902 case Tag_RISCV_priv_spec_minor:
17903 case Tag_RISCV_priv_spec_revision:
cd30bcef 17904 READ_ULEB (val, p, end);
26c527e6 17905 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
17906 break;
17907 case Tag_RISCV_unaligned_access:
cd30bcef 17908 READ_ULEB (val, p, end);
2dc8dd17
JW
17909 switch (val)
17910 {
17911 case 0:
17912 printf (_("No unaligned access\n"));
17913 break;
17914 case 1:
17915 printf (_("Unaligned access\n"));
17916 break;
17917 }
17918 break;
17919 case Tag_RISCV_stack_align:
cd30bcef 17920 READ_ULEB (val, p, end);
26c527e6 17921 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
17922 break;
17923 case Tag_RISCV_arch:
17924 p = display_tag_value (-1, p, end);
17925 break;
17926 default:
17927 return display_tag_value (tag, p, end);
17928 }
17929
17930 return p;
17931}
17932
0861f561
CQ
17933static unsigned char *
17934display_csky_attribute (unsigned char * p,
17935 const unsigned char * const end)
17936{
26c527e6
AM
17937 uint64_t tag;
17938 uint64_t val;
0861f561
CQ
17939 READ_ULEB (tag, p, end);
17940
17941 if (tag >= Tag_CSKY_MAX)
17942 {
17943 return display_tag_value (-1, p, end);
17944 }
17945
17946 switch (tag)
17947 {
17948 case Tag_CSKY_ARCH_NAME:
17949 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17950 return display_tag_value (-1, p, end);
17951 case Tag_CSKY_CPU_NAME:
17952 printf (" Tag_CSKY_CPU_NAME:\t\t");
17953 return display_tag_value (-1, p, end);
17954
17955 case Tag_CSKY_ISA_FLAGS:
17956 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17957 return display_tag_value (0, p, end);
17958 case Tag_CSKY_ISA_EXT_FLAGS:
17959 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17960 return display_tag_value (0, p, end);
17961
17962 case Tag_CSKY_DSP_VERSION:
17963 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17964 READ_ULEB (val, p, end);
17965 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17966 printf ("DSP Extension\n");
17967 else if (val == VAL_CSKY_DSP_VERSION_2)
17968 printf ("DSP 2.0\n");
17969 break;
17970
17971 case Tag_CSKY_VDSP_VERSION:
17972 printf (" Tag_CSKY_VDSP_VERSION:\t");
17973 READ_ULEB (val, p, end);
26c527e6 17974 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
17975 break;
17976
17977 case Tag_CSKY_FPU_VERSION:
17978 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17979 READ_ULEB (val, p, end);
17980 if (val == VAL_CSKY_FPU_VERSION_1)
17981 printf ("ABIV1 FPU Version 1\n");
17982 else if (val == VAL_CSKY_FPU_VERSION_2)
17983 printf ("FPU Version 2\n");
17984 break;
17985
17986 case Tag_CSKY_FPU_ABI:
17987 printf (" Tag_CSKY_FPU_ABI:\t\t");
17988 READ_ULEB (val, p, end);
17989 if (val == VAL_CSKY_FPU_ABI_HARD)
17990 printf ("Hard\n");
17991 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17992 printf ("SoftFP\n");
17993 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17994 printf ("Soft\n");
17995 break;
17996 case Tag_CSKY_FPU_ROUNDING:
17997 READ_ULEB (val, p, end);
f253158f
NC
17998 if (val == 1)
17999 {
18000 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18001 printf ("Needed\n");
18002 }
0861f561
CQ
18003 break;
18004 case Tag_CSKY_FPU_DENORMAL:
18005 READ_ULEB (val, p, end);
f253158f
NC
18006 if (val == 1)
18007 {
18008 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18009 printf ("Needed\n");
18010 }
0861f561
CQ
18011 break;
18012 case Tag_CSKY_FPU_Exception:
18013 READ_ULEB (val, p, end);
f253158f
NC
18014 if (val == 1)
18015 {
18016 printf (" Tag_CSKY_FPU_Exception:\t");
18017 printf ("Needed\n");
18018 }
0861f561
CQ
18019 break;
18020 case Tag_CSKY_FPU_NUMBER_MODULE:
18021 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18022 return display_tag_value (-1, p, end);
18023 case Tag_CSKY_FPU_HARDFP:
18024 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18025 READ_ULEB (val, p, end);
18026 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18027 printf (" Half");
18028 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18029 printf (" Single");
18030 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18031 printf (" Double");
18032 printf ("\n");
18033 break;
18034 default:
18035 return display_tag_value (tag, p, end);
18036 }
18037 return p;
18038}
18039
015dc7e1 18040static bool
dda8d76d 18041process_attributes (Filedata * filedata,
60bca95a 18042 const char * public_name,
104d59d1 18043 unsigned int proc_type,
f6f0e17b 18044 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 18045 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 18046{
2cf0635d 18047 Elf_Internal_Shdr * sect;
11c1ff18 18048 unsigned i;
015dc7e1 18049 bool res = true;
11c1ff18
PB
18050
18051 /* Find the section header so that we get the size. */
dda8d76d
NC
18052 for (i = 0, sect = filedata->section_headers;
18053 i < filedata->file_header.e_shnum;
11c1ff18
PB
18054 i++, sect++)
18055 {
071436c6
NC
18056 unsigned char * contents;
18057 unsigned char * p;
18058
104d59d1 18059 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
18060 continue;
18061
dda8d76d 18062 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 18063 sect->sh_size, _("attributes"));
60bca95a 18064 if (contents == NULL)
32ec8896 18065 {
015dc7e1 18066 res = false;
32ec8896
NC
18067 continue;
18068 }
60bca95a 18069
11c1ff18 18070 p = contents;
60abdbed
NC
18071 /* The first character is the version of the attributes.
18072 Currently only version 1, (aka 'A') is recognised here. */
18073 if (*p != 'A')
32ec8896
NC
18074 {
18075 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 18076 res = false;
32ec8896 18077 }
60abdbed 18078 else
11c1ff18 18079 {
625d49fc 18080 uint64_t section_len;
071436c6
NC
18081
18082 section_len = sect->sh_size - 1;
11c1ff18 18083 p++;
60bca95a 18084
071436c6 18085 while (section_len > 0)
11c1ff18 18086 {
625d49fc 18087 uint64_t attr_len;
e9847026 18088 unsigned int namelen;
015dc7e1
AM
18089 bool public_section;
18090 bool gnu_section;
11c1ff18 18091
071436c6 18092 if (section_len <= 4)
e0a31db1
NC
18093 {
18094 error (_("Tag section ends prematurely\n"));
015dc7e1 18095 res = false;
e0a31db1
NC
18096 break;
18097 }
071436c6 18098 attr_len = byte_get (p, 4);
11c1ff18 18099 p += 4;
60bca95a 18100
071436c6 18101 if (attr_len > section_len)
11c1ff18 18102 {
071436c6
NC
18103 error (_("Bad attribute length (%u > %u)\n"),
18104 (unsigned) attr_len, (unsigned) section_len);
18105 attr_len = section_len;
015dc7e1 18106 res = false;
11c1ff18 18107 }
74e1a04b 18108 /* PR 17531: file: 001-101425-0.004 */
071436c6 18109 else if (attr_len < 5)
74e1a04b 18110 {
071436c6 18111 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 18112 res = false;
74e1a04b
NC
18113 break;
18114 }
e9847026 18115
071436c6
NC
18116 section_len -= attr_len;
18117 attr_len -= 4;
18118
18119 namelen = strnlen ((char *) p, attr_len) + 1;
18120 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
18121 {
18122 error (_("Corrupt attribute section name\n"));
015dc7e1 18123 res = false;
e9847026
NC
18124 break;
18125 }
18126
071436c6
NC
18127 printf (_("Attribute Section: "));
18128 print_symbol (INT_MAX, (const char *) p);
18129 putchar ('\n');
60bca95a
NC
18130
18131 if (public_name && streq ((char *) p, public_name))
015dc7e1 18132 public_section = true;
11c1ff18 18133 else
015dc7e1 18134 public_section = false;
60bca95a
NC
18135
18136 if (streq ((char *) p, "gnu"))
015dc7e1 18137 gnu_section = true;
104d59d1 18138 else
015dc7e1 18139 gnu_section = false;
60bca95a 18140
11c1ff18 18141 p += namelen;
071436c6 18142 attr_len -= namelen;
e0a31db1 18143
071436c6 18144 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18145 {
e0a31db1 18146 int tag;
cd30bcef 18147 unsigned int val;
625d49fc 18148 uint64_t size;
071436c6 18149 unsigned char * end;
60bca95a 18150
e0a31db1 18151 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18152 if (attr_len < 6)
e0a31db1
NC
18153 {
18154 error (_("Unused bytes at end of section\n"));
015dc7e1 18155 res = false;
e0a31db1
NC
18156 section_len = 0;
18157 break;
18158 }
18159
18160 tag = *(p++);
11c1ff18 18161 size = byte_get (p, 4);
071436c6 18162 if (size > attr_len)
11c1ff18 18163 {
e9847026 18164 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18165 (unsigned) size, (unsigned) attr_len);
015dc7e1 18166 res = false;
071436c6 18167 size = attr_len;
11c1ff18 18168 }
e0a31db1
NC
18169 /* PR binutils/17531: Safe handling of corrupt files. */
18170 if (size < 6)
18171 {
18172 error (_("Bad subsection length (%u < 6)\n"),
18173 (unsigned) size);
015dc7e1 18174 res = false;
e0a31db1
NC
18175 section_len = 0;
18176 break;
18177 }
60bca95a 18178
071436c6 18179 attr_len -= size;
11c1ff18 18180 end = p + size - 1;
071436c6 18181 assert (end <= contents + sect->sh_size);
11c1ff18 18182 p += 4;
60bca95a 18183
11c1ff18
PB
18184 switch (tag)
18185 {
18186 case 1:
2b692964 18187 printf (_("File Attributes\n"));
11c1ff18
PB
18188 break;
18189 case 2:
2b692964 18190 printf (_("Section Attributes:"));
11c1ff18
PB
18191 goto do_numlist;
18192 case 3:
2b692964 18193 printf (_("Symbol Attributes:"));
1a0670f3 18194 /* Fall through. */
11c1ff18
PB
18195 do_numlist:
18196 for (;;)
18197 {
cd30bcef 18198 READ_ULEB (val, p, end);
11c1ff18
PB
18199 if (val == 0)
18200 break;
18201 printf (" %d", val);
18202 }
18203 printf ("\n");
18204 break;
18205 default:
2b692964 18206 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18207 public_section = false;
11c1ff18
PB
18208 break;
18209 }
60bca95a 18210
071436c6 18211 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18212 {
18213 while (p < end)
f6f0e17b 18214 p = display_pub_attribute (p, end);
60abdbed 18215 assert (p == end);
104d59d1 18216 }
071436c6 18217 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18218 {
18219 while (p < end)
18220 p = display_gnu_attribute (p,
f6f0e17b
NC
18221 display_proc_gnu_attribute,
18222 end);
60abdbed 18223 assert (p == end);
11c1ff18 18224 }
071436c6 18225 else if (p < end)
11c1ff18 18226 {
071436c6 18227 printf (_(" Unknown attribute:\n"));
f6f0e17b 18228 display_raw_attribute (p, end);
11c1ff18
PB
18229 p = end;
18230 }
071436c6
NC
18231 else
18232 attr_len = 0;
11c1ff18
PB
18233 }
18234 }
18235 }
d70c5fc7 18236
60bca95a 18237 free (contents);
11c1ff18 18238 }
32ec8896
NC
18239
18240 return res;
11c1ff18
PB
18241}
18242
ccb4c951
RS
18243/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18244 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18245 and return the VMA of the next entry, or -1 if there was a problem.
18246 Does not read from DATA_END or beyond. */
ccb4c951 18247
625d49fc
AM
18248static uint64_t
18249print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18250 unsigned char * data_end)
ccb4c951
RS
18251{
18252 printf (" ");
18253 print_vma (addr, LONG_HEX);
18254 printf (" ");
18255 if (addr < pltgot + 0xfff0)
18256 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18257 else
18258 printf ("%10s", "");
18259 printf (" ");
18260 if (data == NULL)
2b692964 18261 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18262 else
18263 {
625d49fc 18264 uint64_t entry;
82b1b41b 18265 unsigned char * from = data + addr - pltgot;
ccb4c951 18266
82b1b41b
NC
18267 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18268 {
18269 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18270 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18271 return (uint64_t) -1;
82b1b41b
NC
18272 }
18273 else
18274 {
18275 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18276 print_vma (entry, LONG_HEX);
18277 }
ccb4c951
RS
18278 }
18279 return addr + (is_32bit_elf ? 4 : 8);
18280}
18281
861fb55a
DJ
18282/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18283 PLTGOT. Print the Address and Initial fields of an entry at VMA
18284 ADDR and return the VMA of the next entry. */
18285
625d49fc
AM
18286static uint64_t
18287print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18288{
18289 printf (" ");
18290 print_vma (addr, LONG_HEX);
18291 printf (" ");
18292 if (data == NULL)
2b692964 18293 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18294 else
18295 {
625d49fc 18296 uint64_t entry;
861fb55a
DJ
18297
18298 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18299 print_vma (entry, LONG_HEX);
18300 }
18301 return addr + (is_32bit_elf ? 4 : 8);
18302}
18303
351cdf24
MF
18304static void
18305print_mips_ases (unsigned int mask)
18306{
18307 if (mask & AFL_ASE_DSP)
18308 fputs ("\n\tDSP ASE", stdout);
18309 if (mask & AFL_ASE_DSPR2)
18310 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18311 if (mask & AFL_ASE_DSPR3)
18312 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18313 if (mask & AFL_ASE_EVA)
18314 fputs ("\n\tEnhanced VA Scheme", stdout);
18315 if (mask & AFL_ASE_MCU)
18316 fputs ("\n\tMCU (MicroController) ASE", stdout);
18317 if (mask & AFL_ASE_MDMX)
18318 fputs ("\n\tMDMX ASE", stdout);
18319 if (mask & AFL_ASE_MIPS3D)
18320 fputs ("\n\tMIPS-3D ASE", stdout);
18321 if (mask & AFL_ASE_MT)
18322 fputs ("\n\tMT ASE", stdout);
18323 if (mask & AFL_ASE_SMARTMIPS)
18324 fputs ("\n\tSmartMIPS ASE", stdout);
18325 if (mask & AFL_ASE_VIRT)
18326 fputs ("\n\tVZ ASE", stdout);
18327 if (mask & AFL_ASE_MSA)
18328 fputs ("\n\tMSA ASE", stdout);
18329 if (mask & AFL_ASE_MIPS16)
18330 fputs ("\n\tMIPS16 ASE", stdout);
18331 if (mask & AFL_ASE_MICROMIPS)
18332 fputs ("\n\tMICROMIPS ASE", stdout);
18333 if (mask & AFL_ASE_XPA)
18334 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18335 if (mask & AFL_ASE_MIPS16E2)
18336 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18337 if (mask & AFL_ASE_CRC)
18338 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18339 if (mask & AFL_ASE_GINV)
18340 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18341 if (mask & AFL_ASE_LOONGSON_MMI)
18342 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18343 if (mask & AFL_ASE_LOONGSON_CAM)
18344 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18345 if (mask & AFL_ASE_LOONGSON_EXT)
18346 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18347 if (mask & AFL_ASE_LOONGSON_EXT2)
18348 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18349 if (mask == 0)
18350 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18351 else if ((mask & ~AFL_ASE_MASK) != 0)
18352 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18353}
18354
18355static void
18356print_mips_isa_ext (unsigned int isa_ext)
18357{
18358 switch (isa_ext)
18359 {
18360 case 0:
18361 fputs (_("None"), stdout);
18362 break;
18363 case AFL_EXT_XLR:
18364 fputs ("RMI XLR", stdout);
18365 break;
2c629856
N
18366 case AFL_EXT_OCTEON3:
18367 fputs ("Cavium Networks Octeon3", stdout);
18368 break;
351cdf24
MF
18369 case AFL_EXT_OCTEON2:
18370 fputs ("Cavium Networks Octeon2", stdout);
18371 break;
18372 case AFL_EXT_OCTEONP:
18373 fputs ("Cavium Networks OcteonP", stdout);
18374 break;
351cdf24
MF
18375 case AFL_EXT_OCTEON:
18376 fputs ("Cavium Networks Octeon", stdout);
18377 break;
18378 case AFL_EXT_5900:
18379 fputs ("Toshiba R5900", stdout);
18380 break;
18381 case AFL_EXT_4650:
18382 fputs ("MIPS R4650", stdout);
18383 break;
18384 case AFL_EXT_4010:
18385 fputs ("LSI R4010", stdout);
18386 break;
18387 case AFL_EXT_4100:
18388 fputs ("NEC VR4100", stdout);
18389 break;
18390 case AFL_EXT_3900:
18391 fputs ("Toshiba R3900", stdout);
18392 break;
18393 case AFL_EXT_10000:
18394 fputs ("MIPS R10000", stdout);
18395 break;
18396 case AFL_EXT_SB1:
18397 fputs ("Broadcom SB-1", stdout);
18398 break;
18399 case AFL_EXT_4111:
18400 fputs ("NEC VR4111/VR4181", stdout);
18401 break;
18402 case AFL_EXT_4120:
18403 fputs ("NEC VR4120", stdout);
18404 break;
18405 case AFL_EXT_5400:
18406 fputs ("NEC VR5400", stdout);
18407 break;
18408 case AFL_EXT_5500:
18409 fputs ("NEC VR5500", stdout);
18410 break;
18411 case AFL_EXT_LOONGSON_2E:
18412 fputs ("ST Microelectronics Loongson 2E", stdout);
18413 break;
18414 case AFL_EXT_LOONGSON_2F:
18415 fputs ("ST Microelectronics Loongson 2F", stdout);
18416 break;
38bf472a
MR
18417 case AFL_EXT_INTERAPTIV_MR2:
18418 fputs ("Imagination interAptiv MR2", stdout);
18419 break;
351cdf24 18420 default:
00ac7aa0 18421 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18422 }
18423}
18424
32ec8896 18425static signed int
351cdf24
MF
18426get_mips_reg_size (int reg_size)
18427{
18428 return (reg_size == AFL_REG_NONE) ? 0
18429 : (reg_size == AFL_REG_32) ? 32
18430 : (reg_size == AFL_REG_64) ? 64
18431 : (reg_size == AFL_REG_128) ? 128
18432 : -1;
18433}
18434
015dc7e1 18435static bool
dda8d76d 18436process_mips_specific (Filedata * filedata)
5b18a4bc 18437{
2cf0635d 18438 Elf_Internal_Dyn * entry;
351cdf24 18439 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18440 size_t liblist_offset = 0;
18441 size_t liblistno = 0;
18442 size_t conflictsno = 0;
18443 size_t options_offset = 0;
18444 size_t conflicts_offset = 0;
861fb55a
DJ
18445 size_t pltrelsz = 0;
18446 size_t pltrel = 0;
625d49fc
AM
18447 uint64_t pltgot = 0;
18448 uint64_t mips_pltgot = 0;
18449 uint64_t jmprel = 0;
18450 uint64_t local_gotno = 0;
18451 uint64_t gotsym = 0;
18452 uint64_t symtabno = 0;
015dc7e1 18453 bool res = true;
103f02d3 18454
dda8d76d 18455 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18456 display_mips_gnu_attribute))
015dc7e1 18457 res = false;
2cf19d5c 18458
dda8d76d 18459 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18460
18461 if (sect != NULL)
18462 {
18463 Elf_External_ABIFlags_v0 *abiflags_ext;
18464 Elf_Internal_ABIFlags_v0 abiflags_in;
18465
18466 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18467 {
18468 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18469 res = false;
32ec8896 18470 }
351cdf24
MF
18471 else
18472 {
dda8d76d 18473 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18474 sect->sh_size, _("MIPS ABI Flags section"));
18475 if (abiflags_ext)
18476 {
18477 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18478 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18479 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18480 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18481 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18482 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18483 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18484 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18485 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18486 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18487 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18488
18489 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18490 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18491 if (abiflags_in.isa_rev > 1)
18492 printf ("r%d", abiflags_in.isa_rev);
18493 printf ("\nGPR size: %d",
18494 get_mips_reg_size (abiflags_in.gpr_size));
18495 printf ("\nCPR1 size: %d",
18496 get_mips_reg_size (abiflags_in.cpr1_size));
18497 printf ("\nCPR2 size: %d",
18498 get_mips_reg_size (abiflags_in.cpr2_size));
18499 fputs ("\nFP ABI: ", stdout);
18500 print_mips_fp_abi_value (abiflags_in.fp_abi);
18501 fputs ("ISA Extension: ", stdout);
18502 print_mips_isa_ext (abiflags_in.isa_ext);
18503 fputs ("\nASEs:", stdout);
18504 print_mips_ases (abiflags_in.ases);
18505 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18506 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18507 fputc ('\n', stdout);
18508 free (abiflags_ext);
18509 }
18510 }
18511 }
18512
19e6b90e 18513 /* We have a lot of special sections. Thanks SGI! */
978c4450 18514 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18515 {
18516 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18517 sect = find_section (filedata, ".got");
bbdd9a68
MR
18518 if (sect != NULL)
18519 {
18520 unsigned char *data_end;
18521 unsigned char *data;
625d49fc 18522 uint64_t ent, end;
bbdd9a68
MR
18523 int addr_size;
18524
18525 pltgot = sect->sh_addr;
18526
18527 ent = pltgot;
18528 addr_size = (is_32bit_elf ? 4 : 8);
18529 end = pltgot + sect->sh_size;
18530
dda8d76d 18531 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18532 end - pltgot, 1,
18533 _("Global Offset Table data"));
18534 /* PR 12855: Null data is handled gracefully throughout. */
18535 data_end = data + (end - pltgot);
18536
18537 printf (_("\nStatic GOT:\n"));
18538 printf (_(" Canonical gp value: "));
18539 print_vma (ent + 0x7ff0, LONG_HEX);
18540 printf ("\n\n");
18541
18542 /* In a dynamic binary GOT[0] is reserved for the dynamic
18543 loader to store the lazy resolver pointer, however in
18544 a static binary it may well have been omitted and GOT
18545 reduced to a table of addresses.
18546 PR 21344: Check for the entry being fully available
18547 before fetching it. */
18548 if (data
18549 && data + ent - pltgot + addr_size <= data_end
18550 && byte_get (data + ent - pltgot, addr_size) == 0)
18551 {
18552 printf (_(" Reserved entries:\n"));
18553 printf (_(" %*s %10s %*s\n"),
18554 addr_size * 2, _("Address"), _("Access"),
18555 addr_size * 2, _("Value"));
18556 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18557 printf ("\n");
625d49fc 18558 if (ent == (uint64_t) -1)
bbdd9a68
MR
18559 goto sgot_print_fail;
18560
18561 /* Check for the MSB of GOT[1] being set, identifying a
18562 GNU object. This entry will be used by some runtime
18563 loaders, to store the module pointer. Otherwise this
18564 is an ordinary local entry.
18565 PR 21344: Check for the entry being fully available
18566 before fetching it. */
18567 if (data
18568 && data + ent - pltgot + addr_size <= data_end
18569 && (byte_get (data + ent - pltgot, addr_size)
18570 >> (addr_size * 8 - 1)) != 0)
18571 {
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 printf ("\n");
18578 }
18579
f17e9d8a 18580 if (data != NULL && ent < end)
bbdd9a68
MR
18581 {
18582 printf (_(" Local entries:\n"));
18583 printf (" %*s %10s %*s\n",
18584 addr_size * 2, _("Address"), _("Access"),
18585 addr_size * 2, _("Value"));
18586 while (ent < end)
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
18596 sgot_print_fail:
9db70fc3 18597 free (data);
bbdd9a68
MR
18598 }
18599 return res;
18600 }
252b5132 18601
978c4450 18602 for (entry = filedata->dynamic_section;
071436c6 18603 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18604 (entry < filedata->dynamic_section + filedata->dynamic_nent
18605 && entry->d_tag != DT_NULL);
071436c6 18606 ++entry)
252b5132
RH
18607 switch (entry->d_tag)
18608 {
18609 case DT_MIPS_LIBLIST:
d93f0186 18610 liblist_offset
dda8d76d 18611 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18612 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18613 break;
18614 case DT_MIPS_LIBLISTNO:
18615 liblistno = entry->d_un.d_val;
18616 break;
18617 case DT_MIPS_OPTIONS:
dda8d76d 18618 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18619 break;
18620 case DT_MIPS_CONFLICT:
d93f0186 18621 conflicts_offset
dda8d76d 18622 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18623 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18624 break;
18625 case DT_MIPS_CONFLICTNO:
18626 conflictsno = entry->d_un.d_val;
18627 break;
ccb4c951 18628 case DT_PLTGOT:
861fb55a
DJ
18629 pltgot = entry->d_un.d_ptr;
18630 break;
ccb4c951
RS
18631 case DT_MIPS_LOCAL_GOTNO:
18632 local_gotno = entry->d_un.d_val;
18633 break;
18634 case DT_MIPS_GOTSYM:
18635 gotsym = entry->d_un.d_val;
18636 break;
18637 case DT_MIPS_SYMTABNO:
18638 symtabno = entry->d_un.d_val;
18639 break;
861fb55a
DJ
18640 case DT_MIPS_PLTGOT:
18641 mips_pltgot = entry->d_un.d_ptr;
18642 break;
18643 case DT_PLTREL:
18644 pltrel = entry->d_un.d_val;
18645 break;
18646 case DT_PLTRELSZ:
18647 pltrelsz = entry->d_un.d_val;
18648 break;
18649 case DT_JMPREL:
18650 jmprel = entry->d_un.d_ptr;
18651 break;
252b5132
RH
18652 default:
18653 break;
18654 }
18655
18656 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18657 {
2cf0635d 18658 Elf32_External_Lib * elib;
252b5132
RH
18659 size_t cnt;
18660
dda8d76d 18661 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18662 sizeof (Elf32_External_Lib),
18663 liblistno,
18664 _("liblist section data"));
a6e9f9df 18665 if (elib)
252b5132 18666 {
26c527e6
AM
18667 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
18668 "\nSection '.liblist' contains %zu entries:\n",
18669 liblistno),
18670 liblistno);
2b692964 18671 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18672 stdout);
18673
18674 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18675 {
a6e9f9df 18676 Elf32_Lib liblist;
91d6fa6a 18677 time_t atime;
d5b07ef4 18678 char timebuf[128];
2cf0635d 18679 struct tm * tmp;
a6e9f9df
AM
18680
18681 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18682 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18683 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18684 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18685 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18686
91d6fa6a 18687 tmp = gmtime (&atime);
e9e44622
JJ
18688 snprintf (timebuf, sizeof (timebuf),
18689 "%04u-%02u-%02uT%02u:%02u:%02u",
18690 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18691 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18692
26c527e6 18693 printf ("%3zu: ", cnt);
84714f86
AM
18694 if (valid_dynamic_name (filedata, liblist.l_name))
18695 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18696 else
2b692964 18697 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18698 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18699 liblist.l_version);
a6e9f9df
AM
18700
18701 if (liblist.l_flags == 0)
2b692964 18702 puts (_(" NONE"));
a6e9f9df
AM
18703 else
18704 {
18705 static const struct
252b5132 18706 {
2cf0635d 18707 const char * name;
a6e9f9df 18708 int bit;
252b5132 18709 }
a6e9f9df
AM
18710 l_flags_vals[] =
18711 {
18712 { " EXACT_MATCH", LL_EXACT_MATCH },
18713 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18714 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18715 { " EXPORTS", LL_EXPORTS },
18716 { " DELAY_LOAD", LL_DELAY_LOAD },
18717 { " DELTA", LL_DELTA }
18718 };
18719 int flags = liblist.l_flags;
18720 size_t fcnt;
18721
60bca95a 18722 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18723 if ((flags & l_flags_vals[fcnt].bit) != 0)
18724 {
18725 fputs (l_flags_vals[fcnt].name, stdout);
18726 flags ^= l_flags_vals[fcnt].bit;
18727 }
18728 if (flags != 0)
18729 printf (" %#x", (unsigned int) flags);
252b5132 18730
a6e9f9df
AM
18731 puts ("");
18732 }
252b5132 18733 }
252b5132 18734
a6e9f9df
AM
18735 free (elib);
18736 }
32ec8896 18737 else
015dc7e1 18738 res = false;
252b5132
RH
18739 }
18740
18741 if (options_offset != 0)
18742 {
2cf0635d 18743 Elf_External_Options * eopt;
252b5132
RH
18744 size_t offset;
18745 int cnt;
18746
18747 /* Find the section header so that we get the size. */
dda8d76d 18748 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18749 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18750 if (sect == NULL)
18751 {
18752 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18753 return false;
071436c6 18754 }
7fc0c668
NC
18755 /* PR 24243 */
18756 if (sect->sh_size < sizeof (* eopt))
18757 {
18758 error (_("The MIPS options section is too small.\n"));
015dc7e1 18759 return false;
7fc0c668 18760 }
252b5132 18761
dda8d76d 18762 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18763 sect->sh_size, _("options"));
a6e9f9df 18764 if (eopt)
252b5132 18765 {
fd17d1e6 18766 Elf_Internal_Options option;
76da6bbe 18767
a6e9f9df 18768 offset = cnt = 0;
82b1b41b 18769 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18770 {
2cf0635d 18771 Elf_External_Options * eoption;
fd17d1e6 18772 unsigned int optsize;
252b5132 18773
a6e9f9df 18774 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18775
fd17d1e6 18776 optsize = BYTE_GET (eoption->size);
76da6bbe 18777
82b1b41b 18778 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18779 if (optsize < sizeof (* eopt)
18780 || optsize > sect->sh_size - offset)
82b1b41b 18781 {
645f43a8 18782 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18783 optsize);
645f43a8 18784 free (eopt);
015dc7e1 18785 return false;
82b1b41b 18786 }
fd17d1e6 18787 offset += optsize;
a6e9f9df
AM
18788 ++cnt;
18789 }
252b5132 18790
d3a49aa8
AM
18791 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18792 "\nSection '%s' contains %d entries:\n",
18793 cnt),
dda8d76d 18794 printable_section_name (filedata, sect), cnt);
76da6bbe 18795
82b1b41b 18796 offset = 0;
a6e9f9df 18797 while (cnt-- > 0)
252b5132 18798 {
a6e9f9df 18799 size_t len;
fd17d1e6
AM
18800 Elf_External_Options * eoption;
18801
18802 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18803
18804 option.kind = BYTE_GET (eoption->kind);
18805 option.size = BYTE_GET (eoption->size);
18806 option.section = BYTE_GET (eoption->section);
18807 option.info = BYTE_GET (eoption->info);
a6e9f9df 18808
fd17d1e6 18809 switch (option.kind)
252b5132 18810 {
a6e9f9df
AM
18811 case ODK_NULL:
18812 /* This shouldn't happen. */
d0c4e780 18813 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18814 option.section, option.info);
a6e9f9df 18815 break;
2e6be59c 18816
a6e9f9df
AM
18817 case ODK_REGINFO:
18818 printf (" REGINFO ");
dda8d76d 18819 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18820 {
2cf0635d 18821 Elf32_External_RegInfo * ereg;
b34976b6 18822 Elf32_RegInfo reginfo;
a6e9f9df 18823
2e6be59c 18824 /* 32bit form. */
fd17d1e6
AM
18825 if (option.size < (sizeof (Elf_External_Options)
18826 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18827 {
18828 printf (_("<corrupt>\n"));
18829 error (_("Truncated MIPS REGINFO option\n"));
18830 cnt = 0;
18831 break;
18832 }
18833
fd17d1e6 18834 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18835
a6e9f9df
AM
18836 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18837 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18838 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18839 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18840 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18841 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18842
d0c4e780
AM
18843 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18844 reginfo.ri_gprmask, reginfo.ri_gp_value);
18845 printf (" "
18846 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18847 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18848 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18849 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18850 }
18851 else
18852 {
18853 /* 64 bit form. */
2cf0635d 18854 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18855 Elf64_Internal_RegInfo reginfo;
18856
fd17d1e6
AM
18857 if (option.size < (sizeof (Elf_External_Options)
18858 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18859 {
18860 printf (_("<corrupt>\n"));
18861 error (_("Truncated MIPS REGINFO option\n"));
18862 cnt = 0;
18863 break;
18864 }
18865
fd17d1e6 18866 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18867 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18868 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18869 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18870 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18871 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18872 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18873
d0c4e780
AM
18874 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18875 reginfo.ri_gprmask, reginfo.ri_gp_value);
18876 printf (" "
18877 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18878 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18879 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18880 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18881 }
fd17d1e6 18882 offset += option.size;
a6e9f9df 18883 continue;
2e6be59c 18884
a6e9f9df
AM
18885 case ODK_EXCEPTIONS:
18886 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18887 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18888 fputs (") fpe_max(", stdout);
fd17d1e6 18889 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18890 fputs (")", stdout);
18891
fd17d1e6 18892 if (option.info & OEX_PAGE0)
a6e9f9df 18893 fputs (" PAGE0", stdout);
fd17d1e6 18894 if (option.info & OEX_SMM)
a6e9f9df 18895 fputs (" SMM", stdout);
fd17d1e6 18896 if (option.info & OEX_FPDBUG)
a6e9f9df 18897 fputs (" FPDBUG", stdout);
fd17d1e6 18898 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18899 fputs (" DISMISS", stdout);
18900 break;
2e6be59c 18901
a6e9f9df
AM
18902 case ODK_PAD:
18903 fputs (" PAD ", stdout);
fd17d1e6 18904 if (option.info & OPAD_PREFIX)
a6e9f9df 18905 fputs (" PREFIX", stdout);
fd17d1e6 18906 if (option.info & OPAD_POSTFIX)
a6e9f9df 18907 fputs (" POSTFIX", stdout);
fd17d1e6 18908 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18909 fputs (" SYMBOL", stdout);
18910 break;
2e6be59c 18911
a6e9f9df
AM
18912 case ODK_HWPATCH:
18913 fputs (" HWPATCH ", stdout);
fd17d1e6 18914 if (option.info & OHW_R4KEOP)
a6e9f9df 18915 fputs (" R4KEOP", stdout);
fd17d1e6 18916 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18917 fputs (" R8KPFETCH", stdout);
fd17d1e6 18918 if (option.info & OHW_R5KEOP)
a6e9f9df 18919 fputs (" R5KEOP", stdout);
fd17d1e6 18920 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18921 fputs (" R5KCVTL", stdout);
18922 break;
2e6be59c 18923
a6e9f9df
AM
18924 case ODK_FILL:
18925 fputs (" FILL ", stdout);
18926 /* XXX Print content of info word? */
18927 break;
2e6be59c 18928
a6e9f9df
AM
18929 case ODK_TAGS:
18930 fputs (" TAGS ", stdout);
18931 /* XXX Print content of info word? */
18932 break;
2e6be59c 18933
a6e9f9df
AM
18934 case ODK_HWAND:
18935 fputs (" HWAND ", stdout);
fd17d1e6 18936 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18937 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18938 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18939 fputs (" R4KEOP_CLEAN", stdout);
18940 break;
2e6be59c 18941
a6e9f9df
AM
18942 case ODK_HWOR:
18943 fputs (" HWOR ", stdout);
fd17d1e6 18944 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18945 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18946 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18947 fputs (" R4KEOP_CLEAN", stdout);
18948 break;
2e6be59c 18949
a6e9f9df 18950 case ODK_GP_GROUP:
d0c4e780 18951 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18952 option.info & OGP_GROUP,
18953 (option.info & OGP_SELF) >> 16);
a6e9f9df 18954 break;
2e6be59c 18955
a6e9f9df 18956 case ODK_IDENT:
d0c4e780 18957 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18958 option.info & OGP_GROUP,
18959 (option.info & OGP_SELF) >> 16);
a6e9f9df 18960 break;
2e6be59c 18961
a6e9f9df
AM
18962 default:
18963 /* This shouldn't happen. */
d0c4e780 18964 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18965 option.kind, option.section, option.info);
a6e9f9df 18966 break;
252b5132 18967 }
a6e9f9df 18968
2cf0635d 18969 len = sizeof (* eopt);
fd17d1e6 18970 while (len < option.size)
82b1b41b 18971 {
fd17d1e6 18972 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18973
82b1b41b
NC
18974 if (ISPRINT (datum))
18975 printf ("%c", datum);
18976 else
18977 printf ("\\%03o", datum);
18978 len ++;
18979 }
a6e9f9df 18980 fputs ("\n", stdout);
82b1b41b 18981
fd17d1e6 18982 offset += option.size;
252b5132 18983 }
a6e9f9df 18984 free (eopt);
252b5132 18985 }
32ec8896 18986 else
015dc7e1 18987 res = false;
252b5132
RH
18988 }
18989
18990 if (conflicts_offset != 0 && conflictsno != 0)
18991 {
2cf0635d 18992 Elf32_Conflict * iconf;
252b5132
RH
18993 size_t cnt;
18994
978c4450 18995 if (filedata->dynamic_symbols == NULL)
252b5132 18996 {
591a748a 18997 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18998 return false;
252b5132
RH
18999 }
19000
7296a62a
NC
19001 /* PR 21345 - print a slightly more helpful error message
19002 if we are sure that the cmalloc will fail. */
645f43a8 19003 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 19004 {
26c527e6
AM
19005 error (_("Overlarge number of conflicts detected: %zx\n"),
19006 conflictsno);
015dc7e1 19007 return false;
7296a62a
NC
19008 }
19009
3f5e193b 19010 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
19011 if (iconf == NULL)
19012 {
8b73c356 19013 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 19014 return false;
252b5132
RH
19015 }
19016
9ea033b2 19017 if (is_32bit_elf)
252b5132 19018 {
2cf0635d 19019 Elf32_External_Conflict * econf32;
a6e9f9df 19020
3f5e193b 19021 econf32 = (Elf32_External_Conflict *)
95099889
AM
19022 get_data (NULL, filedata, conflicts_offset,
19023 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 19024 if (!econf32)
5a814d6d
AM
19025 {
19026 free (iconf);
015dc7e1 19027 return false;
5a814d6d 19028 }
252b5132
RH
19029
19030 for (cnt = 0; cnt < conflictsno; ++cnt)
19031 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
19032
19033 free (econf32);
252b5132
RH
19034 }
19035 else
19036 {
2cf0635d 19037 Elf64_External_Conflict * econf64;
a6e9f9df 19038
3f5e193b 19039 econf64 = (Elf64_External_Conflict *)
95099889
AM
19040 get_data (NULL, filedata, conflicts_offset,
19041 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 19042 if (!econf64)
5a814d6d
AM
19043 {
19044 free (iconf);
015dc7e1 19045 return false;
5a814d6d 19046 }
252b5132
RH
19047
19048 for (cnt = 0; cnt < conflictsno; ++cnt)
19049 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
19050
19051 free (econf64);
252b5132
RH
19052 }
19053
26c527e6
AM
19054 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19055 "\nSection '.conflict' contains %zu entries:\n",
19056 conflictsno),
19057 conflictsno);
252b5132
RH
19058 puts (_(" Num: Index Value Name"));
19059
19060 for (cnt = 0; cnt < conflictsno; ++cnt)
19061 {
26c527e6 19062 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 19063
978c4450 19064 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 19065 printf (_("<corrupt symbol index>"));
d79b3d50 19066 else
e0a31db1
NC
19067 {
19068 Elf_Internal_Sym * psym;
19069
978c4450 19070 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
19071 print_vma (psym->st_value, FULL_HEX);
19072 putchar (' ');
84714f86
AM
19073 if (valid_dynamic_name (filedata, psym->st_name))
19074 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19075 else
19076 printf (_("<corrupt: %14ld>"), psym->st_name);
19077 }
31104126 19078 putchar ('\n');
252b5132
RH
19079 }
19080
252b5132
RH
19081 free (iconf);
19082 }
19083
ccb4c951
RS
19084 if (pltgot != 0 && local_gotno != 0)
19085 {
625d49fc 19086 uint64_t ent, local_end, global_end;
bbeee7ea 19087 size_t i, offset;
2cf0635d 19088 unsigned char * data;
82b1b41b 19089 unsigned char * data_end;
bbeee7ea 19090 int addr_size;
ccb4c951 19091
91d6fa6a 19092 ent = pltgot;
ccb4c951
RS
19093 addr_size = (is_32bit_elf ? 4 : 8);
19094 local_end = pltgot + local_gotno * addr_size;
ccb4c951 19095
74e1a04b
NC
19096 /* PR binutils/17533 file: 012-111227-0.004 */
19097 if (symtabno < gotsym)
19098 {
26c527e6
AM
19099 error (_("The GOT symbol offset (%" PRIu64
19100 ") is greater than the symbol table size (%" PRIu64 ")\n"),
19101 gotsym, symtabno);
015dc7e1 19102 return false;
74e1a04b 19103 }
82b1b41b 19104
74e1a04b 19105 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
19106 /* PR 17531: file: 54c91a34. */
19107 if (global_end < local_end)
19108 {
26c527e6 19109 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 19110 return false;
82b1b41b 19111 }
948f632f 19112
dda8d76d
NC
19113 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
19114 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
19115 global_end - pltgot, 1,
19116 _("Global Offset Table data"));
919383ac 19117 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 19118 data_end = data + (global_end - pltgot);
59245841 19119
ccb4c951
RS
19120 printf (_("\nPrimary GOT:\n"));
19121 printf (_(" Canonical gp value: "));
19122 print_vma (pltgot + 0x7ff0, LONG_HEX);
19123 printf ("\n\n");
19124
19125 printf (_(" Reserved entries:\n"));
19126 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
19127 addr_size * 2, _("Address"), _("Access"),
19128 addr_size * 2, _("Initial"));
82b1b41b 19129 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 19130 printf (_(" Lazy resolver\n"));
625d49fc 19131 if (ent == (uint64_t) -1)
82b1b41b 19132 goto got_print_fail;
75ec1fdb 19133
c4ab9505
MR
19134 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19135 This entry will be used by some runtime loaders, to store the
19136 module pointer. Otherwise this is an ordinary local entry.
19137 PR 21344: Check for the entry being fully available before
19138 fetching it. */
19139 if (data
19140 && data + ent - pltgot + addr_size <= data_end
19141 && (byte_get (data + ent - pltgot, addr_size)
19142 >> (addr_size * 8 - 1)) != 0)
19143 {
19144 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19145 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 19146 if (ent == (uint64_t) -1)
c4ab9505 19147 goto got_print_fail;
ccb4c951
RS
19148 }
19149 printf ("\n");
19150
f17e9d8a 19151 if (data != NULL && ent < local_end)
ccb4c951
RS
19152 {
19153 printf (_(" Local entries:\n"));
cc5914eb 19154 printf (" %*s %10s %*s\n",
2b692964
NC
19155 addr_size * 2, _("Address"), _("Access"),
19156 addr_size * 2, _("Initial"));
91d6fa6a 19157 while (ent < local_end)
ccb4c951 19158 {
82b1b41b 19159 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19160 printf ("\n");
625d49fc 19161 if (ent == (uint64_t) -1)
82b1b41b 19162 goto got_print_fail;
ccb4c951
RS
19163 }
19164 printf ("\n");
19165 }
19166
f17e9d8a 19167 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19168 {
19169 int sym_width;
19170
19171 printf (_(" Global entries:\n"));
cc5914eb 19172 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19173 addr_size * 2, _("Address"),
19174 _("Access"),
2b692964 19175 addr_size * 2, _("Initial"),
9cf03b7e
NC
19176 addr_size * 2, _("Sym.Val."),
19177 _("Type"),
19178 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19179 _("Ndx"), _("Name"));
0b4362b0 19180
ccb4c951 19181 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19182
ccb4c951
RS
19183 for (i = gotsym; i < symtabno; i++)
19184 {
82b1b41b 19185 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19186 printf (" ");
e0a31db1 19187
978c4450 19188 if (filedata->dynamic_symbols == NULL)
e0a31db1 19189 printf (_("<no dynamic symbols>"));
978c4450 19190 else if (i < filedata->num_dynamic_syms)
e0a31db1 19191 {
978c4450 19192 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19193
19194 print_vma (psym->st_value, LONG_HEX);
19195 printf (" %-7s %3s ",
dda8d76d
NC
19196 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19197 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19198
84714f86 19199 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19200 print_symbol (sym_width,
84714f86 19201 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19202 else
19203 printf (_("<corrupt: %14ld>"), psym->st_name);
19204 }
ccb4c951 19205 else
26c527e6
AM
19206 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
19207 i);
e0a31db1 19208
ccb4c951 19209 printf ("\n");
625d49fc 19210 if (ent == (uint64_t) -1)
82b1b41b 19211 break;
ccb4c951
RS
19212 }
19213 printf ("\n");
19214 }
19215
82b1b41b 19216 got_print_fail:
9db70fc3 19217 free (data);
ccb4c951
RS
19218 }
19219
861fb55a
DJ
19220 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19221 {
625d49fc 19222 uint64_t ent, end;
26c527e6
AM
19223 uint64_t offset, rel_offset;
19224 uint64_t count, i;
2cf0635d 19225 unsigned char * data;
861fb55a 19226 int addr_size, sym_width;
2cf0635d 19227 Elf_Internal_Rela * rels;
861fb55a 19228
dda8d76d 19229 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19230 if (pltrel == DT_RELA)
19231 {
dda8d76d 19232 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19233 return false;
861fb55a
DJ
19234 }
19235 else
19236 {
dda8d76d 19237 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19238 return false;
861fb55a
DJ
19239 }
19240
91d6fa6a 19241 ent = mips_pltgot;
861fb55a
DJ
19242 addr_size = (is_32bit_elf ? 4 : 8);
19243 end = mips_pltgot + (2 + count) * addr_size;
19244
dda8d76d
NC
19245 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19246 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19247 1, _("Procedure Linkage Table data"));
59245841 19248 if (data == NULL)
288f0ba2
AM
19249 {
19250 free (rels);
015dc7e1 19251 return false;
288f0ba2 19252 }
59245841 19253
9cf03b7e 19254 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19255 printf (_(" Reserved entries:\n"));
19256 printf (_(" %*s %*s Purpose\n"),
2b692964 19257 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19258 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19259 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19260 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19261 printf (_(" Module pointer\n"));
861fb55a
DJ
19262 printf ("\n");
19263
19264 printf (_(" Entries:\n"));
cc5914eb 19265 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19266 addr_size * 2, _("Address"),
19267 addr_size * 2, _("Initial"),
19268 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19269 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19270 for (i = 0; i < count; i++)
19271 {
26c527e6 19272 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19273
91d6fa6a 19274 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19275 printf (" ");
e0a31db1 19276
978c4450 19277 if (idx >= filedata->num_dynamic_syms)
26c527e6 19278 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 19279 else
e0a31db1 19280 {
978c4450 19281 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19282
19283 print_vma (psym->st_value, LONG_HEX);
19284 printf (" %-7s %3s ",
dda8d76d
NC
19285 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19286 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19287 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19288 print_symbol (sym_width,
84714f86 19289 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19290 else
19291 printf (_("<corrupt: %14ld>"), psym->st_name);
19292 }
861fb55a
DJ
19293 printf ("\n");
19294 }
19295 printf ("\n");
19296
9db70fc3 19297 free (data);
861fb55a
DJ
19298 free (rels);
19299 }
19300
32ec8896 19301 return res;
252b5132
RH
19302}
19303
015dc7e1 19304static bool
dda8d76d 19305process_nds32_specific (Filedata * filedata)
35c08157
KLC
19306{
19307 Elf_Internal_Shdr *sect = NULL;
19308
dda8d76d 19309 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19310 if (sect != NULL && sect->sh_size >= 4)
35c08157 19311 {
9c7b8e9b
AM
19312 unsigned char *buf;
19313 unsigned int flag;
35c08157
KLC
19314
19315 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19316 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19317 _("NDS32 elf flags section"));
35c08157 19318
9c7b8e9b 19319 if (buf == NULL)
015dc7e1 19320 return false;
32ec8896 19321
9c7b8e9b
AM
19322 flag = byte_get (buf, 4);
19323 free (buf);
19324 switch (flag & 0x3)
35c08157
KLC
19325 {
19326 case 0:
19327 printf ("(VEC_SIZE):\tNo entry.\n");
19328 break;
19329 case 1:
19330 printf ("(VEC_SIZE):\t4 bytes\n");
19331 break;
19332 case 2:
19333 printf ("(VEC_SIZE):\t16 bytes\n");
19334 break;
19335 case 3:
19336 printf ("(VEC_SIZE):\treserved\n");
19337 break;
19338 }
19339 }
19340
015dc7e1 19341 return true;
35c08157
KLC
19342}
19343
015dc7e1 19344static bool
dda8d76d 19345process_gnu_liblist (Filedata * filedata)
047b2264 19346{
2cf0635d
NC
19347 Elf_Internal_Shdr * section;
19348 Elf_Internal_Shdr * string_sec;
19349 Elf32_External_Lib * elib;
19350 char * strtab;
c256ffe7 19351 size_t strtab_size;
047b2264 19352 size_t cnt;
26c527e6 19353 uint64_t num_liblist;
047b2264 19354 unsigned i;
015dc7e1 19355 bool res = true;
047b2264
JJ
19356
19357 if (! do_arch)
015dc7e1 19358 return true;
047b2264 19359
dda8d76d
NC
19360 for (i = 0, section = filedata->section_headers;
19361 i < filedata->file_header.e_shnum;
b34976b6 19362 i++, section++)
047b2264
JJ
19363 {
19364 switch (section->sh_type)
19365 {
19366 case SHT_GNU_LIBLIST:
dda8d76d 19367 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19368 break;
19369
3f5e193b 19370 elib = (Elf32_External_Lib *)
dda8d76d 19371 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19372 _("liblist section data"));
047b2264
JJ
19373
19374 if (elib == NULL)
32ec8896 19375 {
015dc7e1 19376 res = false;
32ec8896
NC
19377 break;
19378 }
047b2264 19379
dda8d76d
NC
19380 string_sec = filedata->section_headers + section->sh_link;
19381 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19382 string_sec->sh_size,
19383 _("liblist string table"));
047b2264
JJ
19384 if (strtab == NULL
19385 || section->sh_entsize != sizeof (Elf32_External_Lib))
19386 {
19387 free (elib);
2842702f 19388 free (strtab);
015dc7e1 19389 res = false;
047b2264
JJ
19390 break;
19391 }
59245841 19392 strtab_size = string_sec->sh_size;
047b2264 19393
d3a49aa8 19394 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
19395 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
19396 " entries:\n",
19397 "\nLibrary list section '%s' contains %" PRIu64
19398 " entries:\n",
d3a49aa8 19399 num_liblist),
dda8d76d 19400 printable_section_name (filedata, section),
d3a49aa8 19401 num_liblist);
047b2264 19402
2b692964 19403 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19404
19405 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19406 ++cnt)
19407 {
19408 Elf32_Lib liblist;
91d6fa6a 19409 time_t atime;
d5b07ef4 19410 char timebuf[128];
2cf0635d 19411 struct tm * tmp;
047b2264
JJ
19412
19413 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19414 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19415 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19416 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19417 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19418
91d6fa6a 19419 tmp = gmtime (&atime);
e9e44622
JJ
19420 snprintf (timebuf, sizeof (timebuf),
19421 "%04u-%02u-%02uT%02u:%02u:%02u",
19422 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19423 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 19424
26c527e6 19425 printf ("%3zu: ", cnt);
047b2264 19426 if (do_wide)
c256ffe7 19427 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19428 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19429 else
c256ffe7 19430 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19431 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19432 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19433 liblist.l_version, liblist.l_flags);
19434 }
19435
19436 free (elib);
2842702f 19437 free (strtab);
047b2264
JJ
19438 }
19439 }
19440
32ec8896 19441 return res;
047b2264
JJ
19442}
19443
9437c45b 19444static const char *
dda8d76d 19445get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19446{
19447 static char buff[64];
103f02d3 19448
dda8d76d 19449 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19450 switch (e_type)
19451 {
57346661 19452 case NT_AUXV:
1ec5cd37 19453 return _("NT_AUXV (auxiliary vector)");
57346661 19454 case NT_PRSTATUS:
1ec5cd37 19455 return _("NT_PRSTATUS (prstatus structure)");
57346661 19456 case NT_FPREGSET:
1ec5cd37 19457 return _("NT_FPREGSET (floating point registers)");
57346661 19458 case NT_PRPSINFO:
1ec5cd37 19459 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19460 case NT_TASKSTRUCT:
1ec5cd37 19461 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19462 case NT_GDB_TDESC:
19463 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19464 case NT_PRXFPREG:
1ec5cd37 19465 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19466 case NT_PPC_VMX:
19467 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19468 case NT_PPC_VSX:
19469 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19470 case NT_PPC_TAR:
19471 return _("NT_PPC_TAR (ppc TAR register)");
19472 case NT_PPC_PPR:
19473 return _("NT_PPC_PPR (ppc PPR register)");
19474 case NT_PPC_DSCR:
19475 return _("NT_PPC_DSCR (ppc DSCR register)");
19476 case NT_PPC_EBB:
19477 return _("NT_PPC_EBB (ppc EBB registers)");
19478 case NT_PPC_PMU:
19479 return _("NT_PPC_PMU (ppc PMU registers)");
19480 case NT_PPC_TM_CGPR:
19481 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19482 case NT_PPC_TM_CFPR:
19483 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19484 case NT_PPC_TM_CVMX:
19485 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19486 case NT_PPC_TM_CVSX:
3fd21718 19487 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19488 case NT_PPC_TM_SPR:
19489 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19490 case NT_PPC_TM_CTAR:
19491 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19492 case NT_PPC_TM_CPPR:
19493 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19494 case NT_PPC_TM_CDSCR:
19495 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19496 case NT_386_TLS:
19497 return _("NT_386_TLS (x86 TLS information)");
19498 case NT_386_IOPERM:
19499 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19500 case NT_X86_XSTATE:
19501 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19502 case NT_X86_CET:
19503 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19504 case NT_S390_HIGH_GPRS:
19505 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19506 case NT_S390_TIMER:
19507 return _("NT_S390_TIMER (s390 timer register)");
19508 case NT_S390_TODCMP:
19509 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19510 case NT_S390_TODPREG:
19511 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19512 case NT_S390_CTRS:
19513 return _("NT_S390_CTRS (s390 control registers)");
19514 case NT_S390_PREFIX:
19515 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19516 case NT_S390_LAST_BREAK:
19517 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19518 case NT_S390_SYSTEM_CALL:
19519 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19520 case NT_S390_TDB:
19521 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19522 case NT_S390_VXRS_LOW:
19523 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19524 case NT_S390_VXRS_HIGH:
19525 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19526 case NT_S390_GS_CB:
19527 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19528 case NT_S390_GS_BC:
19529 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19530 case NT_ARM_VFP:
19531 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19532 case NT_ARM_TLS:
19533 return _("NT_ARM_TLS (AArch TLS registers)");
19534 case NT_ARM_HW_BREAK:
19535 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19536 case NT_ARM_HW_WATCH:
19537 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
19538 case NT_ARM_SYSTEM_CALL:
19539 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
19540 case NT_ARM_SVE:
19541 return _("NT_ARM_SVE (AArch SVE registers)");
19542 case NT_ARM_PAC_MASK:
19543 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19544 case NT_ARM_PACA_KEYS:
19545 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19546 case NT_ARM_PACG_KEYS:
19547 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19548 case NT_ARM_TAGGED_ADDR_CTRL:
19549 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
19550 case NT_ARM_PAC_ENABLED_KEYS:
19551 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19552 case NT_ARC_V2:
19553 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19554 case NT_RISCV_CSR:
19555 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19556 case NT_PSTATUS:
1ec5cd37 19557 return _("NT_PSTATUS (pstatus structure)");
57346661 19558 case NT_FPREGS:
1ec5cd37 19559 return _("NT_FPREGS (floating point registers)");
57346661 19560 case NT_PSINFO:
1ec5cd37 19561 return _("NT_PSINFO (psinfo structure)");
57346661 19562 case NT_LWPSTATUS:
1ec5cd37 19563 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19564 case NT_LWPSINFO:
1ec5cd37 19565 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19566 case NT_WIN32PSTATUS:
1ec5cd37 19567 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19568 case NT_SIGINFO:
19569 return _("NT_SIGINFO (siginfo_t data)");
19570 case NT_FILE:
19571 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19572 default:
19573 break;
19574 }
19575 else
19576 switch (e_type)
19577 {
19578 case NT_VERSION:
19579 return _("NT_VERSION (version)");
19580 case NT_ARCH:
19581 return _("NT_ARCH (architecture)");
9ef920e9 19582 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19583 return _("OPEN");
9ef920e9 19584 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19585 return _("func");
c8795e1f
NC
19586 case NT_GO_BUILDID:
19587 return _("GO BUILDID");
3ac925fc
LB
19588 case FDO_PACKAGING_METADATA:
19589 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19590 default:
19591 break;
19592 }
19593
e9e44622 19594 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19595 return buff;
779fe533
NC
19596}
19597
015dc7e1 19598static bool
9ece1fa9
TT
19599print_core_note (Elf_Internal_Note *pnote)
19600{
19601 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 19602 uint64_t count, page_size;
9ece1fa9
TT
19603 unsigned char *descdata, *filenames, *descend;
19604
19605 if (pnote->type != NT_FILE)
04ac15ab
AS
19606 {
19607 if (do_wide)
19608 printf ("\n");
015dc7e1 19609 return true;
04ac15ab 19610 }
9ece1fa9 19611
9ece1fa9
TT
19612 if (!is_32bit_elf)
19613 {
19614 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19615 /* Still "successful". */
015dc7e1 19616 return true;
9ece1fa9 19617 }
9ece1fa9
TT
19618
19619 if (pnote->descsz < 2 * addr_size)
19620 {
32ec8896 19621 error (_(" Malformed note - too short for header\n"));
015dc7e1 19622 return false;
9ece1fa9
TT
19623 }
19624
19625 descdata = (unsigned char *) pnote->descdata;
19626 descend = descdata + pnote->descsz;
19627
19628 if (descdata[pnote->descsz - 1] != '\0')
19629 {
32ec8896 19630 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19631 return false;
9ece1fa9
TT
19632 }
19633
19634 count = byte_get (descdata, addr_size);
19635 descdata += addr_size;
19636
19637 page_size = byte_get (descdata, addr_size);
19638 descdata += addr_size;
19639
625d49fc 19640 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 19641 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19642 {
32ec8896 19643 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19644 return false;
9ece1fa9
TT
19645 }
19646
19647 printf (_(" Page size: "));
19648 print_vma (page_size, DEC);
19649 printf ("\n");
19650
19651 printf (_(" %*s%*s%*s\n"),
19652 (int) (2 + 2 * addr_size), _("Start"),
19653 (int) (4 + 2 * addr_size), _("End"),
19654 (int) (4 + 2 * addr_size), _("Page Offset"));
19655 filenames = descdata + count * 3 * addr_size;
595712bb 19656 while (count-- > 0)
9ece1fa9 19657 {
625d49fc 19658 uint64_t start, end, file_ofs;
9ece1fa9
TT
19659
19660 if (filenames == descend)
19661 {
32ec8896 19662 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19663 return false;
9ece1fa9
TT
19664 }
19665
19666 start = byte_get (descdata, addr_size);
19667 descdata += addr_size;
19668 end = byte_get (descdata, addr_size);
19669 descdata += addr_size;
19670 file_ofs = byte_get (descdata, addr_size);
19671 descdata += addr_size;
19672
19673 printf (" ");
19674 print_vma (start, FULL_HEX);
19675 printf (" ");
19676 print_vma (end, FULL_HEX);
19677 printf (" ");
19678 print_vma (file_ofs, FULL_HEX);
19679 printf ("\n %s\n", filenames);
19680
19681 filenames += 1 + strlen ((char *) filenames);
19682 }
19683
015dc7e1 19684 return true;
9ece1fa9
TT
19685}
19686
1118d252
RM
19687static const char *
19688get_gnu_elf_note_type (unsigned e_type)
19689{
1449284b 19690 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19691 switch (e_type)
19692 {
19693 case NT_GNU_ABI_TAG:
19694 return _("NT_GNU_ABI_TAG (ABI version tag)");
19695 case NT_GNU_HWCAP:
19696 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19697 case NT_GNU_BUILD_ID:
19698 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19699 case NT_GNU_GOLD_VERSION:
19700 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19701 case NT_GNU_PROPERTY_TYPE_0:
19702 return _("NT_GNU_PROPERTY_TYPE_0");
19703 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19704 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19705 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19706 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19707 default:
1449284b
NC
19708 {
19709 static char buff[64];
1118d252 19710
1449284b
NC
19711 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19712 return buff;
19713 }
19714 }
1118d252
RM
19715}
19716
a9eafb08
L
19717static void
19718decode_x86_compat_isa (unsigned int bitmask)
19719{
19720 while (bitmask)
19721 {
19722 unsigned int bit = bitmask & (- bitmask);
19723
19724 bitmask &= ~ bit;
19725 switch (bit)
19726 {
19727 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19728 printf ("i486");
19729 break;
19730 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19731 printf ("586");
19732 break;
19733 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19734 printf ("686");
19735 break;
19736 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19737 printf ("SSE");
19738 break;
19739 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19740 printf ("SSE2");
19741 break;
19742 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19743 printf ("SSE3");
19744 break;
19745 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19746 printf ("SSSE3");
19747 break;
19748 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19749 printf ("SSE4_1");
19750 break;
19751 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19752 printf ("SSE4_2");
19753 break;
19754 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19755 printf ("AVX");
19756 break;
19757 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19758 printf ("AVX2");
19759 break;
19760 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19761 printf ("AVX512F");
19762 break;
19763 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19764 printf ("AVX512CD");
19765 break;
19766 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19767 printf ("AVX512ER");
19768 break;
19769 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19770 printf ("AVX512PF");
19771 break;
19772 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19773 printf ("AVX512VL");
19774 break;
19775 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19776 printf ("AVX512DQ");
19777 break;
19778 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19779 printf ("AVX512BW");
19780 break;
65b3d26e
L
19781 default:
19782 printf (_("<unknown: %x>"), bit);
19783 break;
a9eafb08
L
19784 }
19785 if (bitmask)
19786 printf (", ");
19787 }
19788}
19789
9ef920e9 19790static void
32930e4e 19791decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19792{
0a59decb 19793 if (!bitmask)
90c745dc
L
19794 {
19795 printf (_("<None>"));
19796 return;
19797 }
90c745dc 19798
9ef920e9
NC
19799 while (bitmask)
19800 {
1fc87489 19801 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19802
19803 bitmask &= ~ bit;
19804 switch (bit)
19805 {
32930e4e 19806 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19807 printf ("CMOV");
19808 break;
32930e4e 19809 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19810 printf ("SSE");
19811 break;
32930e4e 19812 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19813 printf ("SSE2");
19814 break;
32930e4e 19815 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19816 printf ("SSE3");
19817 break;
32930e4e 19818 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19819 printf ("SSSE3");
19820 break;
32930e4e 19821 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19822 printf ("SSE4_1");
19823 break;
32930e4e 19824 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19825 printf ("SSE4_2");
19826 break;
32930e4e 19827 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19828 printf ("AVX");
19829 break;
32930e4e 19830 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19831 printf ("AVX2");
19832 break;
32930e4e 19833 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19834 printf ("FMA");
19835 break;
32930e4e 19836 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19837 printf ("AVX512F");
19838 break;
32930e4e 19839 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19840 printf ("AVX512CD");
19841 break;
32930e4e 19842 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19843 printf ("AVX512ER");
19844 break;
32930e4e 19845 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19846 printf ("AVX512PF");
19847 break;
32930e4e 19848 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19849 printf ("AVX512VL");
19850 break;
32930e4e 19851 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19852 printf ("AVX512DQ");
19853 break;
32930e4e 19854 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19855 printf ("AVX512BW");
19856 break;
32930e4e 19857 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19858 printf ("AVX512_4FMAPS");
19859 break;
32930e4e 19860 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19861 printf ("AVX512_4VNNIW");
19862 break;
32930e4e 19863 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19864 printf ("AVX512_BITALG");
19865 break;
32930e4e 19866 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19867 printf ("AVX512_IFMA");
19868 break;
32930e4e 19869 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19870 printf ("AVX512_VBMI");
19871 break;
32930e4e 19872 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19873 printf ("AVX512_VBMI2");
19874 break;
32930e4e 19875 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19876 printf ("AVX512_VNNI");
19877 break;
32930e4e 19878 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19879 printf ("AVX512_BF16");
19880 break;
65b3d26e
L
19881 default:
19882 printf (_("<unknown: %x>"), bit);
19883 break;
9ef920e9
NC
19884 }
19885 if (bitmask)
19886 printf (", ");
19887 }
19888}
19889
28cdbb18
SM
19890static const char *
19891get_amdgpu_elf_note_type (unsigned int e_type)
19892{
19893 switch (e_type)
19894 {
19895 case NT_AMDGPU_METADATA:
19896 return _("NT_AMDGPU_METADATA (code object metadata)");
19897 default:
19898 {
19899 static char buf[64];
19900 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
19901 return buf;
19902 }
19903 }
19904}
19905
32930e4e
L
19906static void
19907decode_x86_isa (unsigned int bitmask)
19908{
32930e4e
L
19909 while (bitmask)
19910 {
19911 unsigned int bit = bitmask & (- bitmask);
19912
19913 bitmask &= ~ bit;
19914 switch (bit)
19915 {
b0ab0693
L
19916 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19917 printf ("x86-64-baseline");
19918 break;
32930e4e
L
19919 case GNU_PROPERTY_X86_ISA_1_V2:
19920 printf ("x86-64-v2");
19921 break;
19922 case GNU_PROPERTY_X86_ISA_1_V3:
19923 printf ("x86-64-v3");
19924 break;
19925 case GNU_PROPERTY_X86_ISA_1_V4:
19926 printf ("x86-64-v4");
19927 break;
19928 default:
19929 printf (_("<unknown: %x>"), bit);
19930 break;
19931 }
19932 if (bitmask)
19933 printf (", ");
19934 }
19935}
19936
ee2fdd6f 19937static void
a9eafb08 19938decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19939{
0a59decb 19940 if (!bitmask)
90c745dc
L
19941 {
19942 printf (_("<None>"));
19943 return;
19944 }
90c745dc 19945
ee2fdd6f
L
19946 while (bitmask)
19947 {
19948 unsigned int bit = bitmask & (- bitmask);
19949
19950 bitmask &= ~ bit;
19951 switch (bit)
19952 {
19953 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19954 printf ("IBT");
ee2fdd6f 19955 break;
48580982 19956 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19957 printf ("SHSTK");
48580982 19958 break;
279d901e
L
19959 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19960 printf ("LAM_U48");
19961 break;
19962 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19963 printf ("LAM_U57");
19964 break;
ee2fdd6f
L
19965 default:
19966 printf (_("<unknown: %x>"), bit);
19967 break;
19968 }
19969 if (bitmask)
19970 printf (", ");
19971 }
19972}
19973
a9eafb08
L
19974static void
19975decode_x86_feature_2 (unsigned int bitmask)
19976{
0a59decb 19977 if (!bitmask)
90c745dc
L
19978 {
19979 printf (_("<None>"));
19980 return;
19981 }
90c745dc 19982
a9eafb08
L
19983 while (bitmask)
19984 {
19985 unsigned int bit = bitmask & (- bitmask);
19986
19987 bitmask &= ~ bit;
19988 switch (bit)
19989 {
19990 case GNU_PROPERTY_X86_FEATURE_2_X86:
19991 printf ("x86");
19992 break;
19993 case GNU_PROPERTY_X86_FEATURE_2_X87:
19994 printf ("x87");
19995 break;
19996 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19997 printf ("MMX");
19998 break;
19999 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20000 printf ("XMM");
20001 break;
20002 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20003 printf ("YMM");
20004 break;
20005 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20006 printf ("ZMM");
20007 break;
a308b89d
L
20008 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20009 printf ("TMM");
20010 break;
32930e4e
L
20011 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20012 printf ("MASK");
20013 break;
a9eafb08
L
20014 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20015 printf ("FXSR");
20016 break;
20017 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20018 printf ("XSAVE");
20019 break;
20020 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20021 printf ("XSAVEOPT");
20022 break;
20023 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20024 printf ("XSAVEC");
20025 break;
65b3d26e
L
20026 default:
20027 printf (_("<unknown: %x>"), bit);
20028 break;
a9eafb08
L
20029 }
20030 if (bitmask)
20031 printf (", ");
20032 }
20033}
20034
cd702818
SD
20035static void
20036decode_aarch64_feature_1_and (unsigned int bitmask)
20037{
20038 while (bitmask)
20039 {
20040 unsigned int bit = bitmask & (- bitmask);
20041
20042 bitmask &= ~ bit;
20043 switch (bit)
20044 {
20045 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20046 printf ("BTI");
20047 break;
20048
20049 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20050 printf ("PAC");
20051 break;
20052
20053 default:
20054 printf (_("<unknown: %x>"), bit);
20055 break;
20056 }
20057 if (bitmask)
20058 printf (", ");
20059 }
20060}
20061
6320fd00
L
20062static void
20063decode_1_needed (unsigned int bitmask)
20064{
20065 while (bitmask)
20066 {
20067 unsigned int bit = bitmask & (- bitmask);
20068
20069 bitmask &= ~ bit;
20070 switch (bit)
20071 {
20072 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20073 printf ("indirect external access");
20074 break;
20075 default:
20076 printf (_("<unknown: %x>"), bit);
20077 break;
20078 }
20079 if (bitmask)
20080 printf (", ");
20081 }
20082}
20083
9ef920e9 20084static void
dda8d76d 20085print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
20086{
20087 unsigned char * ptr = (unsigned char *) pnote->descdata;
20088 unsigned char * ptr_end = ptr + pnote->descsz;
20089 unsigned int size = is_32bit_elf ? 4 : 8;
20090
20091 printf (_(" Properties: "));
20092
1fc87489 20093 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
20094 {
20095 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
20096 return;
20097 }
20098
6ab2c4ed 20099 while (ptr < ptr_end)
9ef920e9 20100 {
1fc87489 20101 unsigned int j;
6ab2c4ed
MC
20102 unsigned int type;
20103 unsigned int datasz;
20104
20105 if ((size_t) (ptr_end - ptr) < 8)
20106 {
20107 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
20108 break;
20109 }
20110
20111 type = byte_get (ptr, 4);
20112 datasz = byte_get (ptr + 4, 4);
9ef920e9 20113
1fc87489 20114 ptr += 8;
9ef920e9 20115
6ab2c4ed 20116 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 20117 {
1fc87489
L
20118 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
20119 type, datasz);
9ef920e9 20120 break;
1fc87489 20121 }
9ef920e9 20122
1fc87489
L
20123 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20124 {
dda8d76d
NC
20125 if (filedata->file_header.e_machine == EM_X86_64
20126 || filedata->file_header.e_machine == EM_IAMCU
20127 || filedata->file_header.e_machine == EM_386)
1fc87489 20128 {
aa7bca9b
L
20129 unsigned int bitmask;
20130
20131 if (datasz == 4)
0a59decb 20132 bitmask = byte_get (ptr, 4);
aa7bca9b
L
20133 else
20134 bitmask = 0;
20135
1fc87489
L
20136 switch (type)
20137 {
20138 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 20139 if (datasz != 4)
aa7bca9b
L
20140 printf (_("x86 ISA used: <corrupt length: %#x> "),
20141 datasz);
1fc87489 20142 else
aa7bca9b
L
20143 {
20144 printf ("x86 ISA used: ");
20145 decode_x86_isa (bitmask);
20146 }
1fc87489 20147 goto next;
9ef920e9 20148
1fc87489 20149 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20150 if (datasz != 4)
aa7bca9b
L
20151 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20152 datasz);
1fc87489 20153 else
aa7bca9b
L
20154 {
20155 printf ("x86 ISA needed: ");
20156 decode_x86_isa (bitmask);
20157 }
1fc87489 20158 goto next;
9ef920e9 20159
ee2fdd6f 20160 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20161 if (datasz != 4)
aa7bca9b
L
20162 printf (_("x86 feature: <corrupt length: %#x> "),
20163 datasz);
ee2fdd6f 20164 else
aa7bca9b
L
20165 {
20166 printf ("x86 feature: ");
a9eafb08
L
20167 decode_x86_feature_1 (bitmask);
20168 }
20169 goto next;
20170
20171 case GNU_PROPERTY_X86_FEATURE_2_USED:
20172 if (datasz != 4)
20173 printf (_("x86 feature used: <corrupt length: %#x> "),
20174 datasz);
20175 else
20176 {
20177 printf ("x86 feature used: ");
20178 decode_x86_feature_2 (bitmask);
20179 }
20180 goto next;
20181
20182 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20183 if (datasz != 4)
20184 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20185 else
20186 {
20187 printf ("x86 feature needed: ");
20188 decode_x86_feature_2 (bitmask);
20189 }
20190 goto next;
20191
20192 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20193 if (datasz != 4)
20194 printf (_("x86 ISA used: <corrupt length: %#x> "),
20195 datasz);
20196 else
20197 {
20198 printf ("x86 ISA used: ");
20199 decode_x86_compat_isa (bitmask);
20200 }
20201 goto next;
20202
20203 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20204 if (datasz != 4)
20205 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20206 datasz);
20207 else
20208 {
20209 printf ("x86 ISA needed: ");
20210 decode_x86_compat_isa (bitmask);
aa7bca9b 20211 }
ee2fdd6f
L
20212 goto next;
20213
32930e4e
L
20214 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20215 if (datasz != 4)
20216 printf (_("x86 ISA used: <corrupt length: %#x> "),
20217 datasz);
20218 else
20219 {
20220 printf ("x86 ISA used: ");
20221 decode_x86_compat_2_isa (bitmask);
20222 }
20223 goto next;
20224
20225 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20226 if (datasz != 4)
20227 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20228 datasz);
20229 else
20230 {
20231 printf ("x86 ISA needed: ");
20232 decode_x86_compat_2_isa (bitmask);
20233 }
20234 goto next;
20235
1fc87489
L
20236 default:
20237 break;
20238 }
20239 }
cd702818
SD
20240 else if (filedata->file_header.e_machine == EM_AARCH64)
20241 {
20242 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20243 {
20244 printf ("AArch64 feature: ");
20245 if (datasz != 4)
20246 printf (_("<corrupt length: %#x> "), datasz);
20247 else
20248 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20249 goto next;
20250 }
20251 }
1fc87489
L
20252 }
20253 else
20254 {
20255 switch (type)
9ef920e9 20256 {
1fc87489
L
20257 case GNU_PROPERTY_STACK_SIZE:
20258 printf (_("stack size: "));
20259 if (datasz != size)
20260 printf (_("<corrupt length: %#x> "), datasz);
20261 else
26c527e6 20262 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
20263 goto next;
20264
20265 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20266 printf ("no copy on protected ");
20267 if (datasz)
20268 printf (_("<corrupt length: %#x> "), datasz);
20269 goto next;
20270
20271 default:
5a767724
L
20272 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20273 && type <= GNU_PROPERTY_UINT32_AND_HI)
20274 || (type >= GNU_PROPERTY_UINT32_OR_LO
20275 && type <= GNU_PROPERTY_UINT32_OR_HI))
20276 {
6320fd00
L
20277 switch (type)
20278 {
20279 case GNU_PROPERTY_1_NEEDED:
20280 if (datasz != 4)
20281 printf (_("1_needed: <corrupt length: %#x> "),
20282 datasz);
20283 else
20284 {
20285 unsigned int bitmask = byte_get (ptr, 4);
20286 printf ("1_needed: ");
20287 decode_1_needed (bitmask);
20288 }
20289 goto next;
20290
20291 default:
20292 break;
20293 }
5a767724
L
20294 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20295 printf (_("UINT32_AND (%#x): "), type);
20296 else
20297 printf (_("UINT32_OR (%#x): "), type);
20298 if (datasz != 4)
20299 printf (_("<corrupt length: %#x> "), datasz);
20300 else
20301 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20302 goto next;
20303 }
9ef920e9
NC
20304 break;
20305 }
9ef920e9
NC
20306 }
20307
1fc87489
L
20308 if (type < GNU_PROPERTY_LOPROC)
20309 printf (_("<unknown type %#x data: "), type);
20310 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20311 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20312 else
20313 printf (_("<application-specific type %#x data: "), type);
20314 for (j = 0; j < datasz; ++j)
20315 printf ("%02x ", ptr[j] & 0xff);
20316 printf (">");
20317
dc1e8a47 20318 next:
9ef920e9 20319 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20320 if (ptr == ptr_end)
20321 break;
1fc87489 20322
6ab2c4ed
MC
20323 if (do_wide)
20324 printf (", ");
20325 else
20326 printf ("\n\t");
9ef920e9
NC
20327 }
20328
20329 printf ("\n");
20330}
20331
015dc7e1 20332static bool
dda8d76d 20333print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20334{
1449284b 20335 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20336 switch (pnote->type)
20337 {
20338 case NT_GNU_BUILD_ID:
20339 {
26c527e6 20340 size_t i;
664f90a3
TT
20341
20342 printf (_(" Build ID: "));
20343 for (i = 0; i < pnote->descsz; ++i)
20344 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20345 printf ("\n");
664f90a3
TT
20346 }
20347 break;
20348
20349 case NT_GNU_ABI_TAG:
20350 {
26c527e6 20351 unsigned int os, major, minor, subminor;
664f90a3
TT
20352 const char *osname;
20353
3102e897
NC
20354 /* PR 17531: file: 030-599401-0.004. */
20355 if (pnote->descsz < 16)
20356 {
20357 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20358 break;
20359 }
20360
664f90a3
TT
20361 os = byte_get ((unsigned char *) pnote->descdata, 4);
20362 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20363 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20364 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20365
20366 switch (os)
20367 {
20368 case GNU_ABI_TAG_LINUX:
20369 osname = "Linux";
20370 break;
20371 case GNU_ABI_TAG_HURD:
20372 osname = "Hurd";
20373 break;
20374 case GNU_ABI_TAG_SOLARIS:
20375 osname = "Solaris";
20376 break;
20377 case GNU_ABI_TAG_FREEBSD:
20378 osname = "FreeBSD";
20379 break;
20380 case GNU_ABI_TAG_NETBSD:
20381 osname = "NetBSD";
20382 break;
14ae95f2
RM
20383 case GNU_ABI_TAG_SYLLABLE:
20384 osname = "Syllable";
20385 break;
20386 case GNU_ABI_TAG_NACL:
20387 osname = "NaCl";
20388 break;
664f90a3
TT
20389 default:
20390 osname = "Unknown";
20391 break;
20392 }
20393
26c527e6 20394 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
20395 major, minor, subminor);
20396 }
20397 break;
926c5385
CC
20398
20399 case NT_GNU_GOLD_VERSION:
20400 {
26c527e6 20401 size_t i;
926c5385
CC
20402
20403 printf (_(" Version: "));
20404 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20405 printf ("%c", pnote->descdata[i]);
20406 printf ("\n");
20407 }
20408 break;
1449284b
NC
20409
20410 case NT_GNU_HWCAP:
20411 {
26c527e6 20412 unsigned int num_entries, mask;
1449284b
NC
20413
20414 /* Hardware capabilities information. Word 0 is the number of entries.
20415 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20416 is a series of entries, where each entry is a single byte followed
20417 by a nul terminated string. The byte gives the bit number to test
20418 if enabled in the bitmask. */
20419 printf (_(" Hardware Capabilities: "));
20420 if (pnote->descsz < 8)
20421 {
32ec8896 20422 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20423 return false;
1449284b
NC
20424 }
20425 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20426 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 20427 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
20428 /* FIXME: Add code to display the entries... */
20429 }
20430 break;
20431
9ef920e9 20432 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20433 print_gnu_property_note (filedata, pnote);
9ef920e9 20434 break;
9abca702 20435
1449284b
NC
20436 default:
20437 /* Handle unrecognised types. An error message should have already been
20438 created by get_gnu_elf_note_type(), so all that we need to do is to
20439 display the data. */
20440 {
26c527e6 20441 size_t i;
1449284b
NC
20442
20443 printf (_(" Description data: "));
20444 for (i = 0; i < pnote->descsz; ++i)
20445 printf ("%02x ", pnote->descdata[i] & 0xff);
20446 printf ("\n");
20447 }
20448 break;
664f90a3
TT
20449 }
20450
015dc7e1 20451 return true;
664f90a3
TT
20452}
20453
685080f2
NC
20454static const char *
20455get_v850_elf_note_type (enum v850_notes n_type)
20456{
20457 static char buff[64];
20458
20459 switch (n_type)
20460 {
20461 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20462 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20463 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20464 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20465 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20466 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20467 default:
20468 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20469 return buff;
20470 }
20471}
20472
015dc7e1 20473static bool
685080f2
NC
20474print_v850_note (Elf_Internal_Note * pnote)
20475{
20476 unsigned int val;
20477
20478 if (pnote->descsz != 4)
015dc7e1 20479 return false;
32ec8896 20480
685080f2
NC
20481 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20482
20483 if (val == 0)
20484 {
20485 printf (_("not set\n"));
015dc7e1 20486 return true;
685080f2
NC
20487 }
20488
20489 switch (pnote->type)
20490 {
20491 case V850_NOTE_ALIGNMENT:
20492 switch (val)
20493 {
015dc7e1
AM
20494 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20495 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20496 }
20497 break;
14ae95f2 20498
685080f2
NC
20499 case V850_NOTE_DATA_SIZE:
20500 switch (val)
20501 {
015dc7e1
AM
20502 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20503 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20504 }
20505 break;
14ae95f2 20506
685080f2
NC
20507 case V850_NOTE_FPU_INFO:
20508 switch (val)
20509 {
015dc7e1
AM
20510 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20511 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20512 }
20513 break;
14ae95f2 20514
685080f2
NC
20515 case V850_NOTE_MMU_INFO:
20516 case V850_NOTE_CACHE_INFO:
20517 case V850_NOTE_SIMD_INFO:
20518 if (val == EF_RH850_SIMD)
20519 {
20520 printf (_("yes\n"));
015dc7e1 20521 return true;
685080f2
NC
20522 }
20523 break;
20524
20525 default:
20526 /* An 'unknown note type' message will already have been displayed. */
20527 break;
20528 }
20529
20530 printf (_("unknown value: %x\n"), val);
015dc7e1 20531 return false;
685080f2
NC
20532}
20533
015dc7e1 20534static bool
c6056a74
SF
20535process_netbsd_elf_note (Elf_Internal_Note * pnote)
20536{
20537 unsigned int version;
20538
20539 switch (pnote->type)
20540 {
20541 case NT_NETBSD_IDENT:
b966f55f
AM
20542 if (pnote->descsz < 1)
20543 break;
c6056a74
SF
20544 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20545 if ((version / 10000) % 100)
b966f55f 20546 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20547 version, version / 100000000, (version / 1000000) % 100,
20548 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20549 'A' + (version / 10000) % 26);
c6056a74
SF
20550 else
20551 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20552 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20553 (version / 100) % 100);
015dc7e1 20554 return true;
c6056a74
SF
20555
20556 case NT_NETBSD_MARCH:
9abca702 20557 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20558 pnote->descdata);
015dc7e1 20559 return true;
c6056a74 20560
9abca702 20561 case NT_NETBSD_PAX:
b966f55f
AM
20562 if (pnote->descsz < 1)
20563 break;
9abca702
CZ
20564 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20565 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20566 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20567 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20568 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20569 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20570 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20571 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20572 return true;
c6056a74 20573 }
b966f55f
AM
20574
20575 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20576 pnote->descsz, pnote->type);
015dc7e1 20577 return false;
c6056a74
SF
20578}
20579
f4ddf30f 20580static const char *
dda8d76d 20581get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20582{
f4ddf30f
JB
20583 switch (e_type)
20584 {
20585 case NT_FREEBSD_THRMISC:
20586 return _("NT_THRMISC (thrmisc structure)");
20587 case NT_FREEBSD_PROCSTAT_PROC:
20588 return _("NT_PROCSTAT_PROC (proc data)");
20589 case NT_FREEBSD_PROCSTAT_FILES:
20590 return _("NT_PROCSTAT_FILES (files data)");
20591 case NT_FREEBSD_PROCSTAT_VMMAP:
20592 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20593 case NT_FREEBSD_PROCSTAT_GROUPS:
20594 return _("NT_PROCSTAT_GROUPS (groups data)");
20595 case NT_FREEBSD_PROCSTAT_UMASK:
20596 return _("NT_PROCSTAT_UMASK (umask data)");
20597 case NT_FREEBSD_PROCSTAT_RLIMIT:
20598 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20599 case NT_FREEBSD_PROCSTAT_OSREL:
20600 return _("NT_PROCSTAT_OSREL (osreldate data)");
20601 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20602 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20603 case NT_FREEBSD_PROCSTAT_AUXV:
20604 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20605 case NT_FREEBSD_PTLWPINFO:
20606 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
20607 case NT_FREEBSD_X86_SEGBASES:
20608 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 20609 }
dda8d76d 20610 return get_note_type (filedata, e_type);
f4ddf30f
JB
20611}
20612
9437c45b 20613static const char *
dda8d76d 20614get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20615{
20616 static char buff[64];
20617
540e6170
CZ
20618 switch (e_type)
20619 {
20620 case NT_NETBSDCORE_PROCINFO:
20621 /* NetBSD core "procinfo" structure. */
20622 return _("NetBSD procinfo structure");
9437c45b 20623
540e6170
CZ
20624 case NT_NETBSDCORE_AUXV:
20625 return _("NetBSD ELF auxiliary vector data");
9437c45b 20626
06d949ec
KR
20627 case NT_NETBSDCORE_LWPSTATUS:
20628 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20629
540e6170 20630 default:
06d949ec 20631 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20632 defined for NetBSD core files. If the note type is less
20633 than the start of the machine-dependent note types, we don't
20634 understand it. */
20635
20636 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20637 {
20638 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20639 return buff;
20640 }
20641 break;
9437c45b
JT
20642 }
20643
dda8d76d 20644 switch (filedata->file_header.e_machine)
9437c45b
JT
20645 {
20646 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20647 and PT_GETFPREGS == mach+2. */
20648
20649 case EM_OLD_ALPHA:
20650 case EM_ALPHA:
20651 case EM_SPARC:
20652 case EM_SPARC32PLUS:
20653 case EM_SPARCV9:
20654 switch (e_type)
20655 {
2b692964 20656 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20657 return _("PT_GETREGS (reg structure)");
2b692964 20658 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20659 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20660 default:
20661 break;
20662 }
20663 break;
20664
c0d38b0e
CZ
20665 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20666 There's also old PT___GETREGS40 == mach + 1 for old reg
20667 structure which lacks GBR. */
20668 case EM_SH:
20669 switch (e_type)
20670 {
20671 case NT_NETBSDCORE_FIRSTMACH + 1:
20672 return _("PT___GETREGS40 (old reg structure)");
20673 case NT_NETBSDCORE_FIRSTMACH + 3:
20674 return _("PT_GETREGS (reg structure)");
20675 case NT_NETBSDCORE_FIRSTMACH + 5:
20676 return _("PT_GETFPREGS (fpreg structure)");
20677 default:
20678 break;
20679 }
20680 break;
20681
9437c45b
JT
20682 /* On all other arch's, PT_GETREGS == mach+1 and
20683 PT_GETFPREGS == mach+3. */
20684 default:
20685 switch (e_type)
20686 {
2b692964 20687 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20688 return _("PT_GETREGS (reg structure)");
2b692964 20689 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20690 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20691 default:
20692 break;
20693 }
20694 }
20695
9cf03b7e 20696 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20697 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20698 return buff;
20699}
20700
98ca73af
FC
20701static const char *
20702get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20703{
20704 switch (e_type)
20705 {
20706 case NT_OPENBSD_PROCINFO:
20707 return _("OpenBSD procinfo structure");
20708 case NT_OPENBSD_AUXV:
20709 return _("OpenBSD ELF auxiliary vector data");
20710 case NT_OPENBSD_REGS:
20711 return _("OpenBSD regular registers");
20712 case NT_OPENBSD_FPREGS:
20713 return _("OpenBSD floating point registers");
20714 case NT_OPENBSD_WCOOKIE:
20715 return _("OpenBSD window cookie");
20716 }
20717
20718 return get_note_type (filedata, e_type);
20719}
20720
70616151
TT
20721static const char *
20722get_stapsdt_note_type (unsigned e_type)
20723{
20724 static char buff[64];
20725
20726 switch (e_type)
20727 {
20728 case NT_STAPSDT:
20729 return _("NT_STAPSDT (SystemTap probe descriptors)");
20730
20731 default:
20732 break;
20733 }
20734
20735 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20736 return buff;
20737}
20738
015dc7e1 20739static bool
c6a9fc58
TT
20740print_stapsdt_note (Elf_Internal_Note *pnote)
20741{
3ca60c57 20742 size_t len, maxlen;
26c527e6 20743 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20744 char *data = pnote->descdata;
20745 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 20746 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
20747 char *provider, *probe, *arg_fmt;
20748
3ca60c57
NC
20749 if (pnote->descsz < (addr_size * 3))
20750 goto stapdt_note_too_small;
20751
c6a9fc58
TT
20752 pc = byte_get ((unsigned char *) data, addr_size);
20753 data += addr_size;
3ca60c57 20754
c6a9fc58
TT
20755 base_addr = byte_get ((unsigned char *) data, addr_size);
20756 data += addr_size;
3ca60c57 20757
c6a9fc58
TT
20758 semaphore = byte_get ((unsigned char *) data, addr_size);
20759 data += addr_size;
20760
3ca60c57
NC
20761 if (data >= data_end)
20762 goto stapdt_note_too_small;
20763 maxlen = data_end - data;
20764 len = strnlen (data, maxlen);
20765 if (len < maxlen)
20766 {
20767 provider = data;
20768 data += len + 1;
20769 }
20770 else
20771 goto stapdt_note_too_small;
20772
20773 if (data >= data_end)
20774 goto stapdt_note_too_small;
20775 maxlen = data_end - data;
20776 len = strnlen (data, maxlen);
20777 if (len < maxlen)
20778 {
20779 probe = data;
20780 data += len + 1;
20781 }
20782 else
20783 goto stapdt_note_too_small;
9abca702 20784
3ca60c57
NC
20785 if (data >= data_end)
20786 goto stapdt_note_too_small;
20787 maxlen = data_end - data;
20788 len = strnlen (data, maxlen);
20789 if (len < maxlen)
20790 {
20791 arg_fmt = data;
20792 data += len + 1;
20793 }
20794 else
20795 goto stapdt_note_too_small;
c6a9fc58
TT
20796
20797 printf (_(" Provider: %s\n"), provider);
20798 printf (_(" Name: %s\n"), probe);
20799 printf (_(" Location: "));
20800 print_vma (pc, FULL_HEX);
20801 printf (_(", Base: "));
20802 print_vma (base_addr, FULL_HEX);
20803 printf (_(", Semaphore: "));
20804 print_vma (semaphore, FULL_HEX);
9cf03b7e 20805 printf ("\n");
c6a9fc58
TT
20806 printf (_(" Arguments: %s\n"), arg_fmt);
20807
20808 return data == data_end;
3ca60c57
NC
20809
20810 stapdt_note_too_small:
20811 printf (_(" <corrupt - note is too small>\n"));
20812 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20813 return false;
c6a9fc58
TT
20814}
20815
e5382207
LB
20816static bool
20817print_fdo_note (Elf_Internal_Note * pnote)
20818{
20819 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20820 {
20821 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20822 return true;
20823 }
20824 return false;
20825}
20826
00e98fc7
TG
20827static const char *
20828get_ia64_vms_note_type (unsigned e_type)
20829{
20830 static char buff[64];
20831
20832 switch (e_type)
20833 {
20834 case NT_VMS_MHD:
20835 return _("NT_VMS_MHD (module header)");
20836 case NT_VMS_LNM:
20837 return _("NT_VMS_LNM (language name)");
20838 case NT_VMS_SRC:
20839 return _("NT_VMS_SRC (source files)");
20840 case NT_VMS_TITLE:
9cf03b7e 20841 return "NT_VMS_TITLE";
00e98fc7
TG
20842 case NT_VMS_EIDC:
20843 return _("NT_VMS_EIDC (consistency check)");
20844 case NT_VMS_FPMODE:
20845 return _("NT_VMS_FPMODE (FP mode)");
20846 case NT_VMS_LINKTIME:
9cf03b7e 20847 return "NT_VMS_LINKTIME";
00e98fc7
TG
20848 case NT_VMS_IMGNAM:
20849 return _("NT_VMS_IMGNAM (image name)");
20850 case NT_VMS_IMGID:
20851 return _("NT_VMS_IMGID (image id)");
20852 case NT_VMS_LINKID:
20853 return _("NT_VMS_LINKID (link id)");
20854 case NT_VMS_IMGBID:
20855 return _("NT_VMS_IMGBID (build id)");
20856 case NT_VMS_GSTNAM:
20857 return _("NT_VMS_GSTNAM (sym table name)");
20858 case NT_VMS_ORIG_DYN:
9cf03b7e 20859 return "NT_VMS_ORIG_DYN";
00e98fc7 20860 case NT_VMS_PATCHTIME:
9cf03b7e 20861 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20862 default:
20863 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20864 return buff;
20865 }
20866}
20867
015dc7e1 20868static bool
00e98fc7
TG
20869print_ia64_vms_note (Elf_Internal_Note * pnote)
20870{
26c527e6 20871 unsigned int maxlen = pnote->descsz;
8d18bf79 20872
26c527e6 20873 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
20874 goto desc_size_fail;
20875
00e98fc7
TG
20876 switch (pnote->type)
20877 {
20878 case NT_VMS_MHD:
8d18bf79
NC
20879 if (maxlen <= 36)
20880 goto desc_size_fail;
20881
26c527e6 20882 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
20883
20884 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20885 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20886 if (l + 34 < maxlen)
20887 {
20888 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20889 if (l + 35 < maxlen)
20890 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20891 else
20892 printf (_(" Module version : <missing>\n"));
20893 }
00e98fc7 20894 else
8d18bf79
NC
20895 {
20896 printf (_(" Module name : <missing>\n"));
20897 printf (_(" Module version : <missing>\n"));
20898 }
00e98fc7 20899 break;
8d18bf79 20900
00e98fc7 20901 case NT_VMS_LNM:
8d18bf79 20902 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20903 break;
8d18bf79 20904
00e98fc7 20905 case NT_VMS_FPMODE:
9cf03b7e 20906 printf (_(" Floating Point mode: "));
8d18bf79
NC
20907 if (maxlen < 8)
20908 goto desc_size_fail;
20909 /* FIXME: Generate an error if descsz > 8 ? */
20910
b8281767 20911 printf ("0x%016" PRIx64 "\n",
625d49fc 20912 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 20913 break;
8d18bf79 20914
00e98fc7
TG
20915 case NT_VMS_LINKTIME:
20916 printf (_(" Link time: "));
8d18bf79
NC
20917 if (maxlen < 8)
20918 goto desc_size_fail;
20919 /* FIXME: Generate an error if descsz > 8 ? */
20920
0e3c1eeb 20921 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20922 printf ("\n");
20923 break;
8d18bf79 20924
00e98fc7
TG
20925 case NT_VMS_PATCHTIME:
20926 printf (_(" Patch time: "));
8d18bf79
NC
20927 if (maxlen < 8)
20928 goto desc_size_fail;
20929 /* FIXME: Generate an error if descsz > 8 ? */
20930
0e3c1eeb 20931 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20932 printf ("\n");
20933 break;
8d18bf79 20934
00e98fc7 20935 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20936 if (maxlen < 34)
20937 goto desc_size_fail;
20938
00e98fc7 20939 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
20940 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
20941 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 20942 printf (_(" Last modified : "));
0e3c1eeb 20943 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 20944 printf (_("\n Link flags : "));
b8281767 20945 printf ("0x%016" PRIx64 "\n",
625d49fc 20946 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 20947 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 20948 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 20949 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 20950 break;
8d18bf79 20951
00e98fc7 20952 case NT_VMS_IMGNAM:
8d18bf79 20953 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20954 break;
8d18bf79 20955
00e98fc7 20956 case NT_VMS_GSTNAM:
8d18bf79 20957 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20958 break;
8d18bf79 20959
00e98fc7 20960 case NT_VMS_IMGID:
8d18bf79 20961 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20962 break;
8d18bf79 20963
00e98fc7 20964 case NT_VMS_LINKID:
8d18bf79 20965 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20966 break;
8d18bf79 20967
00e98fc7 20968 default:
015dc7e1 20969 return false;
00e98fc7 20970 }
8d18bf79 20971
015dc7e1 20972 return true;
8d18bf79
NC
20973
20974 desc_size_fail:
20975 printf (_(" <corrupt - data size is too small>\n"));
20976 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20977 return false;
00e98fc7
TG
20978}
20979
fd486f32
AM
20980struct build_attr_cache {
20981 Filedata *filedata;
20982 char *strtab;
26c527e6 20983 uint64_t strtablen;
fd486f32 20984 Elf_Internal_Sym *symtab;
26c527e6 20985 uint64_t nsyms;
fd486f32
AM
20986} ba_cache;
20987
6f156d7a
NC
20988/* Find the symbol associated with a build attribute that is attached
20989 to address OFFSET. If PNAME is non-NULL then store the name of
20990 the symbol (if found) in the provided pointer, Returns NULL if a
20991 symbol could not be found. */
c799a79d 20992
6f156d7a 20993static Elf_Internal_Sym *
015dc7e1 20994get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 20995 uint64_t offset,
015dc7e1
AM
20996 bool is_open_attr,
20997 const char **pname)
9ef920e9 20998{
fd486f32
AM
20999 Elf_Internal_Sym *saved_sym = NULL;
21000 Elf_Internal_Sym *sym;
9ef920e9 21001
dda8d76d 21002 if (filedata->section_headers != NULL
fd486f32 21003 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 21004 {
c799a79d 21005 Elf_Internal_Shdr * symsec;
9ef920e9 21006
fd486f32
AM
21007 free (ba_cache.strtab);
21008 ba_cache.strtab = NULL;
21009 free (ba_cache.symtab);
21010 ba_cache.symtab = NULL;
21011
c799a79d 21012 /* Load the symbol and string sections. */
dda8d76d
NC
21013 for (symsec = filedata->section_headers;
21014 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 21015 symsec ++)
9ef920e9 21016 {
28d13567
AM
21017 if (symsec->sh_type == SHT_SYMTAB
21018 && get_symtab (filedata, symsec,
21019 &ba_cache.symtab, &ba_cache.nsyms,
21020 &ba_cache.strtab, &ba_cache.strtablen))
21021 break;
9ef920e9 21022 }
fd486f32 21023 ba_cache.filedata = filedata;
9ef920e9
NC
21024 }
21025
fd486f32 21026 if (ba_cache.symtab == NULL)
6f156d7a 21027 return NULL;
9ef920e9 21028
c799a79d 21029 /* Find a symbol whose value matches offset. */
fd486f32 21030 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
21031 if (sym->st_value == offset)
21032 {
fd486f32 21033 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
21034 /* Huh ? This should not happen. */
21035 continue;
9ef920e9 21036
fd486f32 21037 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 21038 continue;
9ef920e9 21039
9b9b1092 21040 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 21041 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
21042 if (ba_cache.strtab[sym->st_name] == '$'
21043 && ba_cache.strtab[sym->st_name + 1] != 0
21044 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
21045 continue;
21046
c799a79d
NC
21047 if (is_open_attr)
21048 {
21049 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
21050 and FILE or OBJECT symbols over NOTYPE symbols. We skip
21051 FUNC symbols entirely. */
21052 switch (ELF_ST_TYPE (sym->st_info))
21053 {
c799a79d 21054 case STT_OBJECT:
6f156d7a 21055 case STT_FILE:
c799a79d 21056 saved_sym = sym;
6f156d7a
NC
21057 if (sym->st_size)
21058 {
21059 /* If the symbol has a size associated
21060 with it then we can stop searching. */
fd486f32 21061 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 21062 }
c799a79d 21063 continue;
9ef920e9 21064
c799a79d
NC
21065 case STT_FUNC:
21066 /* Ignore function symbols. */
21067 continue;
21068
21069 default:
21070 break;
21071 }
21072
21073 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 21074 {
c799a79d
NC
21075 case STB_GLOBAL:
21076 if (saved_sym == NULL
21077 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
21078 saved_sym = sym;
21079 break;
c871dade 21080
c799a79d
NC
21081 case STB_LOCAL:
21082 if (saved_sym == NULL)
21083 saved_sym = sym;
21084 break;
21085
21086 default:
9ef920e9
NC
21087 break;
21088 }
21089 }
c799a79d
NC
21090 else
21091 {
21092 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
21093 continue;
21094
21095 saved_sym = sym;
21096 break;
21097 }
21098 }
21099
6f156d7a 21100 if (saved_sym && pname)
fd486f32 21101 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
21102
21103 return saved_sym;
c799a79d
NC
21104}
21105
d20e98ab
NC
21106/* Returns true iff addr1 and addr2 are in the same section. */
21107
015dc7e1 21108static bool
26c527e6 21109same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
21110{
21111 Elf_Internal_Shdr * a1;
21112 Elf_Internal_Shdr * a2;
21113
21114 a1 = find_section_by_address (filedata, addr1);
21115 a2 = find_section_by_address (filedata, addr2);
9abca702 21116
d20e98ab
NC
21117 return a1 == a2 && a1 != NULL;
21118}
21119
015dc7e1 21120static bool
dda8d76d
NC
21121print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21122 Filedata * filedata)
c799a79d 21123{
26c527e6
AM
21124 static uint64_t global_offset = 0;
21125 static uint64_t global_end = 0;
21126 static uint64_t func_offset = 0;
21127 static uint64_t func_end = 0;
c871dade 21128
015dc7e1
AM
21129 Elf_Internal_Sym *sym;
21130 const char *name;
26c527e6
AM
21131 uint64_t start;
21132 uint64_t end;
015dc7e1 21133 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
21134
21135 switch (pnote->descsz)
c799a79d 21136 {
6f156d7a
NC
21137 case 0:
21138 /* A zero-length description means that the range of
21139 the previous note of the same type should be used. */
c799a79d 21140 if (is_open_attr)
c871dade 21141 {
6f156d7a 21142 if (global_end > global_offset)
26c527e6
AM
21143 printf (_(" Applies to region from %#" PRIx64
21144 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 21145 else
26c527e6
AM
21146 printf (_(" Applies to region from %#" PRIx64
21147 "\n"), global_offset);
c799a79d
NC
21148 }
21149 else
21150 {
6f156d7a 21151 if (func_end > func_offset)
26c527e6
AM
21152 printf (_(" Applies to region from %#" PRIx64
21153 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 21154 else
26c527e6
AM
21155 printf (_(" Applies to region from %#" PRIx64
21156 "\n"), func_offset);
c871dade 21157 }
015dc7e1 21158 return true;
9ef920e9 21159
6f156d7a
NC
21160 case 4:
21161 start = byte_get ((unsigned char *) pnote->descdata, 4);
21162 end = 0;
21163 break;
21164
21165 case 8:
c74147bb
NC
21166 start = byte_get ((unsigned char *) pnote->descdata, 4);
21167 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21168 break;
21169
21170 case 16:
21171 start = byte_get ((unsigned char *) pnote->descdata, 8);
21172 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21173 break;
9abca702 21174
6f156d7a 21175 default:
c799a79d
NC
21176 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21177 printf (_(" <invalid descsz>"));
015dc7e1 21178 return false;
c799a79d
NC
21179 }
21180
6f156d7a
NC
21181 name = NULL;
21182 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21183 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21184 in order to avoid them being confused with the start address of the
21185 first function in the file... */
21186 if (sym == NULL && is_open_attr)
21187 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21188 & name);
6f156d7a
NC
21189
21190 if (end == 0 && sym != NULL && sym->st_size > 0)
21191 end = start + sym->st_size;
c799a79d
NC
21192
21193 if (is_open_attr)
21194 {
d20e98ab
NC
21195 /* FIXME: Need to properly allow for section alignment.
21196 16 is just the alignment used on x86_64. */
21197 if (global_end > 0
21198 && start > BFD_ALIGN (global_end, 16)
21199 /* Build notes are not guaranteed to be organised in order of
21200 increasing address, but we should find the all of the notes
21201 for one section in the same place. */
21202 && same_section (filedata, start, global_end))
26c527e6
AM
21203 warn (_("Gap in build notes detected from %#" PRIx64
21204 " to %#" PRIx64 "\n"),
6f156d7a
NC
21205 global_end + 1, start - 1);
21206
26c527e6 21207 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21208 global_offset = start;
21209
21210 if (end)
21211 {
26c527e6 21212 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21213 global_end = end;
21214 }
c799a79d
NC
21215 }
21216 else
21217 {
26c527e6 21218 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21219 func_offset = start;
21220
21221 if (end)
21222 {
26c527e6 21223 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21224 func_end = end;
21225 }
c799a79d
NC
21226 }
21227
6f156d7a
NC
21228 if (sym && name)
21229 printf (_(" (%s)"), name);
21230
21231 printf ("\n");
015dc7e1 21232 return true;
9ef920e9
NC
21233}
21234
015dc7e1 21235static bool
9ef920e9
NC
21236print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21237{
1d15e434
NC
21238 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21239 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21240 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21241 char name_type;
21242 char name_attribute;
1d15e434 21243 const char * expected_types;
9ef920e9
NC
21244 const char * name = pnote->namedata;
21245 const char * text;
88305e1b 21246 signed int left;
9ef920e9
NC
21247
21248 if (name == NULL || pnote->namesz < 2)
21249 {
21250 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21251 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21252 return false;
9ef920e9
NC
21253 }
21254
6f156d7a
NC
21255 if (do_wide)
21256 left = 28;
21257 else
21258 left = 20;
88305e1b
NC
21259
21260 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21261 if (name[0] == 'G' && name[1] == 'A')
21262 {
6f156d7a
NC
21263 if (pnote->namesz < 4)
21264 {
21265 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21266 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21267 return false;
6f156d7a
NC
21268 }
21269
88305e1b
NC
21270 printf ("GA");
21271 name += 2;
21272 left -= 2;
21273 }
21274
9ef920e9
NC
21275 switch ((name_type = * name))
21276 {
21277 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21278 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21279 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21280 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21281 printf ("%c", * name);
88305e1b 21282 left --;
9ef920e9
NC
21283 break;
21284 default:
21285 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21286 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21287 return false;
9ef920e9
NC
21288 }
21289
9ef920e9
NC
21290 ++ name;
21291 text = NULL;
21292
21293 switch ((name_attribute = * name))
21294 {
21295 case GNU_BUILD_ATTRIBUTE_VERSION:
21296 text = _("<version>");
1d15e434 21297 expected_types = string_expected;
9ef920e9
NC
21298 ++ name;
21299 break;
21300 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21301 text = _("<stack prot>");
75d7d298 21302 expected_types = "!+*";
9ef920e9
NC
21303 ++ name;
21304 break;
21305 case GNU_BUILD_ATTRIBUTE_RELRO:
21306 text = _("<relro>");
1d15e434 21307 expected_types = bool_expected;
9ef920e9
NC
21308 ++ name;
21309 break;
21310 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21311 text = _("<stack size>");
1d15e434 21312 expected_types = number_expected;
9ef920e9
NC
21313 ++ name;
21314 break;
21315 case GNU_BUILD_ATTRIBUTE_TOOL:
21316 text = _("<tool>");
1d15e434 21317 expected_types = string_expected;
9ef920e9
NC
21318 ++ name;
21319 break;
21320 case GNU_BUILD_ATTRIBUTE_ABI:
21321 text = _("<ABI>");
21322 expected_types = "$*";
21323 ++ name;
21324 break;
21325 case GNU_BUILD_ATTRIBUTE_PIC:
21326 text = _("<PIC>");
1d15e434 21327 expected_types = number_expected;
9ef920e9
NC
21328 ++ name;
21329 break;
a8be5506
NC
21330 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21331 text = _("<short enum>");
1d15e434 21332 expected_types = bool_expected;
a8be5506
NC
21333 ++ name;
21334 break;
9ef920e9
NC
21335 default:
21336 if (ISPRINT (* name))
21337 {
21338 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21339
21340 if (len > left && ! do_wide)
21341 len = left;
75d7d298 21342 printf ("%.*s:", len, name);
9ef920e9 21343 left -= len;
0dd6ae21 21344 name += len;
9ef920e9
NC
21345 }
21346 else
21347 {
3e6b6445 21348 static char tmpbuf [128];
88305e1b 21349
3e6b6445
NC
21350 error (_("unrecognised byte in name field: %d\n"), * name);
21351 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21352 text = tmpbuf;
21353 name ++;
9ef920e9
NC
21354 }
21355 expected_types = "*$!+";
21356 break;
21357 }
21358
21359 if (text)
88305e1b 21360 left -= printf ("%s", text);
9ef920e9
NC
21361
21362 if (strchr (expected_types, name_type) == NULL)
75d7d298 21363 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 21364
26c527e6 21365 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 21366 {
26c527e6
AM
21367 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
21368 pnote->namesz,
21369 name - pnote->namedata);
015dc7e1 21370 return false;
9ef920e9
NC
21371 }
21372
21373 if (left < 1 && ! do_wide)
015dc7e1 21374 return true;
9ef920e9
NC
21375
21376 switch (name_type)
21377 {
21378 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21379 {
26c527e6
AM
21380 unsigned int bytes;
21381 uint64_t val = 0;
21382 unsigned int shift = 0;
21383 char *decoded = NULL;
ddef72cd 21384
b06b2c92
NC
21385 bytes = pnote->namesz - (name - pnote->namedata);
21386 if (bytes > 0)
21387 /* The -1 is because the name field is always 0 terminated, and we
21388 want to be able to ensure that the shift in the while loop below
21389 will not overflow. */
21390 -- bytes;
21391
ddef72cd
NC
21392 if (bytes > sizeof (val))
21393 {
3e6b6445
NC
21394 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21395 bytes);
21396 bytes = sizeof (val);
ddef72cd 21397 }
3e6b6445
NC
21398 /* We do not bother to warn if bytes == 0 as this can
21399 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21400
21401 while (bytes --)
21402 {
26c527e6 21403 uint64_t byte = *name++ & 0xff;
79a964dc
NC
21404
21405 val |= byte << shift;
9ef920e9
NC
21406 shift += 8;
21407 }
21408
75d7d298 21409 switch (name_attribute)
9ef920e9 21410 {
75d7d298 21411 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21412 switch (val)
21413 {
75d7d298
NC
21414 case 0: decoded = "static"; break;
21415 case 1: decoded = "pic"; break;
21416 case 2: decoded = "PIC"; break;
21417 case 3: decoded = "pie"; break;
21418 case 4: decoded = "PIE"; break;
21419 default: break;
9ef920e9 21420 }
75d7d298
NC
21421 break;
21422 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21423 switch (val)
9ef920e9 21424 {
75d7d298
NC
21425 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21426 case 0: decoded = "off"; break;
21427 case 1: decoded = "on"; break;
21428 case 2: decoded = "all"; break;
21429 case 3: decoded = "strong"; break;
21430 case 4: decoded = "explicit"; break;
21431 default: break;
9ef920e9 21432 }
75d7d298
NC
21433 break;
21434 default:
21435 break;
9ef920e9
NC
21436 }
21437
75d7d298 21438 if (decoded != NULL)
3e6b6445
NC
21439 {
21440 print_symbol (-left, decoded);
21441 left = 0;
21442 }
21443 else if (val == 0)
21444 {
21445 printf ("0x0");
21446 left -= 3;
21447 }
9ef920e9 21448 else
75d7d298
NC
21449 {
21450 if (do_wide)
26c527e6 21451 left -= printf ("0x%" PRIx64, val);
75d7d298 21452 else
26c527e6 21453 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 21454 }
9ef920e9
NC
21455 }
21456 break;
21457 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21458 left -= print_symbol (- left, name);
21459 break;
21460 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21461 left -= print_symbol (- left, "true");
21462 break;
21463 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21464 left -= print_symbol (- left, "false");
21465 break;
21466 }
21467
21468 if (do_wide && left > 0)
21469 printf ("%-*s", left, " ");
9abca702 21470
015dc7e1 21471 return true;
9ef920e9
NC
21472}
21473
2952f10c
SM
21474/* Print the contents of PNOTE as hex. */
21475
21476static void
21477print_note_contents_hex (Elf_Internal_Note *pnote)
21478{
21479 if (pnote->descsz)
21480 {
26c527e6 21481 size_t i;
2952f10c
SM
21482
21483 printf (_(" description data: "));
21484 for (i = 0; i < pnote->descsz; i++)
21485 printf ("%02x ", pnote->descdata[i] & 0xff);
21486 if (!do_wide)
21487 printf ("\n");
21488 }
21489
21490 if (do_wide)
21491 printf ("\n");
21492}
21493
21494#if defined HAVE_MSGPACK
21495
21496static void
21497print_indents (int n)
21498{
21499 printf (" ");
21500
21501 for (int i = 0; i < n; i++)
21502 printf (" ");
21503}
21504
21505/* Print OBJ in human-readable form. */
21506
21507static void
21508dump_msgpack_obj (const msgpack_object *obj, int indent)
21509{
21510 switch (obj->type)
21511 {
21512 case MSGPACK_OBJECT_NIL:
21513 printf ("(nil)");
21514 break;
21515
21516 case MSGPACK_OBJECT_BOOLEAN:
21517 printf ("%s", obj->via.boolean ? "true" : "false");
21518 break;
21519
21520 case MSGPACK_OBJECT_POSITIVE_INTEGER:
21521 printf ("%" PRIu64, obj->via.u64);
21522 break;
21523
21524 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
21525 printf ("%" PRIi64, obj->via.i64);
21526 break;
21527
21528 case MSGPACK_OBJECT_FLOAT32:
21529 case MSGPACK_OBJECT_FLOAT64:
21530 printf ("%f", obj->via.f64);
21531 break;
21532
21533 case MSGPACK_OBJECT_STR:
21534 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
21535 break;
21536
21537 case MSGPACK_OBJECT_ARRAY:
21538 {
21539 const msgpack_object_array *array = &obj->via.array;
21540
21541 printf ("[\n");
21542 ++indent;
21543
21544 for (uint32_t i = 0; i < array->size; ++i)
21545 {
21546 const msgpack_object *item = &array->ptr[i];
21547
21548 print_indents (indent);
21549 dump_msgpack_obj (item, indent);
21550 printf (",\n");
21551 }
21552
21553 --indent;
21554 print_indents (indent);
21555 printf ("]");
21556 break;
21557 }
21558 break;
21559
21560 case MSGPACK_OBJECT_MAP:
21561 {
21562 const msgpack_object_map *map = &obj->via.map;
21563
21564 printf ("{\n");
21565 ++indent;
21566
21567 for (uint32_t i = 0; i < map->size; ++i)
21568 {
21569 const msgpack_object_kv *kv = &map->ptr[i];
21570 const msgpack_object *key = &kv->key;
21571 const msgpack_object *val = &kv->val;
21572
21573 print_indents (indent);
21574 dump_msgpack_obj (key, indent);
21575 printf (": ");
21576 dump_msgpack_obj (val, indent);
21577
21578 printf (",\n");
21579 }
21580
21581 --indent;
21582 print_indents (indent);
21583 printf ("}");
21584
21585 break;
21586 }
21587
21588 case MSGPACK_OBJECT_BIN:
21589 printf ("(bin)");
21590 break;
21591
21592 case MSGPACK_OBJECT_EXT:
21593 printf ("(ext)");
21594 break;
21595 }
21596}
21597
21598static void
21599dump_msgpack (const msgpack_unpacked *msg)
21600{
21601 print_indents (0);
21602 dump_msgpack_obj (&msg->data, 0);
21603 printf ("\n");
21604}
21605
21606#endif /* defined HAVE_MSGPACK */
21607
21608static bool
21609print_amdgpu_note (Elf_Internal_Note *pnote)
21610{
21611#if defined HAVE_MSGPACK
21612 /* If msgpack is available, decode and dump the note's content. */
21613 bool ret;
21614 msgpack_unpacked msg;
21615 msgpack_unpack_return msgpack_ret;
21616
21617 assert (pnote->type == NT_AMDGPU_METADATA);
21618
21619 msgpack_unpacked_init (&msg);
21620 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
21621 NULL);
21622
21623 switch (msgpack_ret)
21624 {
21625 case MSGPACK_UNPACK_SUCCESS:
21626 dump_msgpack (&msg);
21627 ret = true;
21628 break;
21629
21630 default:
21631 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
21632 ret = false;
21633 break;
21634 }
21635
21636 msgpack_unpacked_destroy (&msg);
21637 return ret;
21638#else
21639 /* msgpack is not available, dump contents as hex. */
21640 print_note_contents_hex (pnote);
21641 return true;
21642#endif
21643}
21644
6d118b09
NC
21645/* Note that by the ELF standard, the name field is already null byte
21646 terminated, and namesz includes the terminating null byte.
21647 I.E. the value of namesz for the name "FSF" is 4.
21648
e3c8793a 21649 If the value of namesz is zero, there is no name present. */
9ef920e9 21650
015dc7e1 21651static bool
9ef920e9 21652process_note (Elf_Internal_Note * pnote,
dda8d76d 21653 Filedata * filedata)
779fe533 21654{
2cf0635d
NC
21655 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21656 const char * nt;
9437c45b
JT
21657
21658 if (pnote->namesz == 0)
1ec5cd37
NC
21659 /* If there is no note name, then use the default set of
21660 note type strings. */
dda8d76d 21661 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21662
24d127aa 21663 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21664 /* GNU-specific object file notes. */
21665 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21666
28cdbb18
SM
21667 else if (startswith (pnote->namedata, "AMDGPU"))
21668 /* AMDGPU-specific object file notes. */
21669 nt = get_amdgpu_elf_note_type (pnote->type);
21670
24d127aa 21671 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21672 /* FreeBSD-specific core file notes. */
dda8d76d 21673 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21674
24d127aa 21675 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21676 /* NetBSD-specific core file notes. */
dda8d76d 21677 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21678
24d127aa 21679 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21680 /* NetBSD-specific core file notes. */
21681 return process_netbsd_elf_note (pnote);
21682
24d127aa 21683 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21684 /* NetBSD-specific core file notes. */
21685 return process_netbsd_elf_note (pnote);
21686
98ca73af
FC
21687 else if (startswith (pnote->namedata, "OpenBSD"))
21688 /* OpenBSD-specific core file notes. */
21689 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21690
e9b095a5 21691 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21692 {
21693 /* SPU-specific core file notes. */
21694 nt = pnote->namedata + 4;
21695 name = "SPU";
21696 }
21697
24d127aa 21698 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21699 /* VMS/ia64-specific file notes. */
21700 nt = get_ia64_vms_note_type (pnote->type);
21701
24d127aa 21702 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21703 nt = get_stapsdt_note_type (pnote->type);
21704
9437c45b 21705 else
1ec5cd37
NC
21706 /* Don't recognize this note name; just use the default set of
21707 note type strings. */
dda8d76d 21708 nt = get_note_type (filedata, pnote->type);
9437c45b 21709
1449284b 21710 printf (" ");
9ef920e9 21711
24d127aa 21712 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21713 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21714 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21715 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21716 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21717 print_gnu_build_attribute_name (pnote);
21718 else
21719 print_symbol (-20, name);
21720
21721 if (do_wide)
21722 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21723 else
21724 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21725
24d127aa 21726 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21727 return print_ia64_vms_note (pnote);
24d127aa 21728 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21729 return print_gnu_note (filedata, pnote);
24d127aa 21730 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21731 return print_stapsdt_note (pnote);
24d127aa 21732 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21733 return print_core_note (pnote);
e5382207
LB
21734 else if (startswith (pnote->namedata, "FDO"))
21735 return print_fdo_note (pnote);
24d127aa 21736 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21737 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21738 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21739 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21740 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21741 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
21742 else if (startswith (pnote->namedata, "AMDGPU")
21743 && pnote->type == NT_AMDGPU_METADATA)
21744 return print_amdgpu_note (pnote);
779fe533 21745
2952f10c 21746 print_note_contents_hex (pnote);
015dc7e1 21747 return true;
1449284b 21748}
6d118b09 21749
015dc7e1 21750static bool
dda8d76d
NC
21751process_notes_at (Filedata * filedata,
21752 Elf_Internal_Shdr * section,
625d49fc
AM
21753 uint64_t offset,
21754 uint64_t length,
21755 uint64_t align)
779fe533 21756{
015dc7e1
AM
21757 Elf_External_Note *pnotes;
21758 Elf_External_Note *external;
21759 char *end;
21760 bool res = true;
103f02d3 21761
779fe533 21762 if (length <= 0)
015dc7e1 21763 return false;
103f02d3 21764
1449284b
NC
21765 if (section)
21766 {
dda8d76d 21767 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21768 if (pnotes)
32ec8896 21769 {
dda8d76d 21770 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21771 {
21772 free (pnotes);
015dc7e1 21773 return false;
f761cb13 21774 }
32ec8896 21775 }
1449284b
NC
21776 }
21777 else
82ed9683 21778 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21779 _("notes"));
4dff97b2 21780
dd24e3da 21781 if (pnotes == NULL)
015dc7e1 21782 return false;
779fe533 21783
103f02d3 21784 external = pnotes;
103f02d3 21785
ca0e11aa
NC
21786 if (filedata->is_separate)
21787 printf (_("In linked file '%s': "), filedata->file_name);
21788 else
21789 printf ("\n");
1449284b 21790 if (section)
ca0e11aa 21791 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21792 else
26c527e6
AM
21793 printf (_("Displaying notes found at file offset 0x%08" PRIx64
21794 " with length 0x%08" PRIx64 ":\n"),
21795 offset, length);
1449284b 21796
82ed9683
L
21797 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21798 specifies that notes should be aligned to 4 bytes in 32-bit
21799 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21800 we also support 4 byte alignment in 64-bit objects. If section
21801 alignment is less than 4, we treate alignment as 4 bytes. */
21802 if (align < 4)
21803 align = 4;
21804 else if (align != 4 && align != 8)
21805 {
26c527e6
AM
21806 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
21807 align);
a788aedd 21808 free (pnotes);
015dc7e1 21809 return false;
82ed9683
L
21810 }
21811
dbe15e4e 21812 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21813
c8071705
NC
21814 end = (char *) pnotes + length;
21815 while ((char *) external < end)
779fe533 21816 {
b34976b6 21817 Elf_Internal_Note inote;
15b42fb0 21818 size_t min_notesz;
4dff97b2 21819 char * next;
2cf0635d 21820 char * temp = NULL;
c8071705 21821 size_t data_remaining = end - (char *) external;
6d118b09 21822
dda8d76d 21823 if (!is_ia64_vms (filedata))
15b42fb0 21824 {
9dd3a467
NC
21825 /* PR binutils/15191
21826 Make sure that there is enough data to read. */
15b42fb0
AM
21827 min_notesz = offsetof (Elf_External_Note, name);
21828 if (data_remaining < min_notesz)
9dd3a467 21829 {
26c527e6 21830 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 21831 "not enough for a full note\n",
26c527e6 21832 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
21833 "not enough for a full note\n",
21834 data_remaining),
26c527e6 21835 data_remaining);
9dd3a467
NC
21836 break;
21837 }
5396a86e
AM
21838 data_remaining -= min_notesz;
21839
15b42fb0
AM
21840 inote.type = BYTE_GET (external->type);
21841 inote.namesz = BYTE_GET (external->namesz);
21842 inote.namedata = external->name;
21843 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21844 inote.descdata = ((char *) external
4dff97b2 21845 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21846 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21847 next = ((char *) external
4dff97b2 21848 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21849 }
00e98fc7 21850 else
15b42fb0
AM
21851 {
21852 Elf64_External_VMS_Note *vms_external;
00e98fc7 21853
9dd3a467
NC
21854 /* PR binutils/15191
21855 Make sure that there is enough data to read. */
15b42fb0
AM
21856 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21857 if (data_remaining < min_notesz)
9dd3a467 21858 {
26c527e6 21859 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 21860 "not enough for a full note\n",
26c527e6 21861 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
21862 "not enough for a full note\n",
21863 data_remaining),
26c527e6 21864 data_remaining);
9dd3a467
NC
21865 break;
21866 }
5396a86e 21867 data_remaining -= min_notesz;
3e55a963 21868
15b42fb0
AM
21869 vms_external = (Elf64_External_VMS_Note *) external;
21870 inote.type = BYTE_GET (vms_external->type);
21871 inote.namesz = BYTE_GET (vms_external->namesz);
21872 inote.namedata = vms_external->name;
21873 inote.descsz = BYTE_GET (vms_external->descsz);
21874 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21875 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21876 next = inote.descdata + align_power (inote.descsz, 3);
21877 }
21878
5396a86e
AM
21879 /* PR 17531: file: 3443835e. */
21880 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21881 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21882 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21883 || (size_t) (next - inote.descdata) < inote.descsz
21884 || ((size_t) (next - inote.descdata)
21885 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21886 {
26c527e6
AM
21887 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
21888 (char *) external - (char *) pnotes);
21889 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 21890 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21891 break;
21892 }
21893
15b42fb0 21894 external = (Elf_External_Note *) next;
dd24e3da 21895
6d118b09
NC
21896 /* Verify that name is null terminated. It appears that at least
21897 one version of Linux (RedHat 6.0) generates corefiles that don't
21898 comply with the ELF spec by failing to include the null byte in
21899 namesz. */
18344509 21900 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21901 {
5396a86e 21902 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21903 {
5396a86e
AM
21904 temp = (char *) malloc (inote.namesz + 1);
21905 if (temp == NULL)
21906 {
21907 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21908 res = false;
5396a86e
AM
21909 break;
21910 }
76da6bbe 21911
5396a86e
AM
21912 memcpy (temp, inote.namedata, inote.namesz);
21913 inote.namedata = temp;
21914 }
21915 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21916 }
21917
dda8d76d 21918 if (! process_note (& inote, filedata))
015dc7e1 21919 res = false;
103f02d3 21920
9db70fc3
AM
21921 free (temp);
21922 temp = NULL;
779fe533
NC
21923 }
21924
21925 free (pnotes);
103f02d3 21926
779fe533
NC
21927 return res;
21928}
21929
015dc7e1 21930static bool
dda8d76d 21931process_corefile_note_segments (Filedata * filedata)
779fe533 21932{
015dc7e1 21933 Elf_Internal_Phdr *segment;
b34976b6 21934 unsigned int i;
015dc7e1 21935 bool res = true;
103f02d3 21936
dda8d76d 21937 if (! get_program_headers (filedata))
015dc7e1 21938 return true;
103f02d3 21939
dda8d76d
NC
21940 for (i = 0, segment = filedata->program_headers;
21941 i < filedata->file_header.e_phnum;
b34976b6 21942 i++, segment++)
779fe533
NC
21943 {
21944 if (segment->p_type == PT_NOTE)
625d49fc
AM
21945 if (! process_notes_at (filedata, NULL, segment->p_offset,
21946 segment->p_filesz, segment->p_align))
015dc7e1 21947 res = false;
779fe533 21948 }
103f02d3 21949
779fe533
NC
21950 return res;
21951}
21952
015dc7e1 21953static bool
625d49fc 21954process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
21955{
21956 Elf_External_Note * pnotes;
21957 Elf_External_Note * external;
c8071705 21958 char * end;
015dc7e1 21959 bool res = true;
685080f2
NC
21960
21961 if (length <= 0)
015dc7e1 21962 return false;
685080f2 21963
dda8d76d 21964 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21965 _("v850 notes"));
21966 if (pnotes == NULL)
015dc7e1 21967 return false;
685080f2
NC
21968
21969 external = pnotes;
c8071705 21970 end = (char*) pnotes + length;
685080f2 21971
26c527e6
AM
21972 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
21973 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
21974 offset, length);
685080f2 21975
c8071705 21976 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21977 {
21978 Elf_External_Note * next;
21979 Elf_Internal_Note inote;
21980
21981 inote.type = BYTE_GET (external->type);
21982 inote.namesz = BYTE_GET (external->namesz);
21983 inote.namedata = external->name;
21984 inote.descsz = BYTE_GET (external->descsz);
21985 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21986 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21987
c8071705
NC
21988 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21989 {
21990 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21991 inote.descdata = inote.namedata;
21992 inote.namesz = 0;
21993 }
21994
685080f2
NC
21995 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21996
c8071705 21997 if ( ((char *) next > end)
685080f2
NC
21998 || ((char *) next < (char *) pnotes))
21999 {
26c527e6
AM
22000 warn (_("corrupt descsz found in note at offset %#tx\n"),
22001 (char *) external - (char *) pnotes);
22002 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22003 inote.type, inote.namesz, inote.descsz);
22004 break;
22005 }
22006
22007 external = next;
22008
22009 /* Prevent out-of-bounds indexing. */
c8071705 22010 if ( inote.namedata + inote.namesz > end
685080f2
NC
22011 || inote.namedata + inote.namesz < inote.namedata)
22012 {
26c527e6
AM
22013 warn (_("corrupt namesz found in note at offset %#zx\n"),
22014 (char *) external - (char *) pnotes);
22015 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22016 inote.type, inote.namesz, inote.descsz);
22017 break;
22018 }
22019
22020 printf (" %s: ", get_v850_elf_note_type (inote.type));
22021
22022 if (! print_v850_note (& inote))
22023 {
015dc7e1 22024 res = false;
26c527e6 22025 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
22026 inote.namesz, inote.descsz);
22027 }
22028 }
22029
22030 free (pnotes);
22031
22032 return res;
22033}
22034
015dc7e1 22035static bool
dda8d76d 22036process_note_sections (Filedata * filedata)
1ec5cd37 22037{
015dc7e1 22038 Elf_Internal_Shdr *section;
26c527e6 22039 size_t i;
32ec8896 22040 unsigned int n = 0;
015dc7e1 22041 bool res = true;
1ec5cd37 22042
dda8d76d
NC
22043 for (i = 0, section = filedata->section_headers;
22044 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 22045 i++, section++)
685080f2
NC
22046 {
22047 if (section->sh_type == SHT_NOTE)
22048 {
625d49fc
AM
22049 if (! process_notes_at (filedata, section, section->sh_offset,
22050 section->sh_size, section->sh_addralign))
015dc7e1 22051 res = false;
685080f2
NC
22052 n++;
22053 }
22054
dda8d76d
NC
22055 if (( filedata->file_header.e_machine == EM_V800
22056 || filedata->file_header.e_machine == EM_V850
22057 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
22058 && section->sh_type == SHT_RENESAS_INFO)
22059 {
625d49fc
AM
22060 if (! process_v850_notes (filedata, section->sh_offset,
22061 section->sh_size))
015dc7e1 22062 res = false;
685080f2
NC
22063 n++;
22064 }
22065 }
df565f32
NC
22066
22067 if (n == 0)
22068 /* Try processing NOTE segments instead. */
dda8d76d 22069 return process_corefile_note_segments (filedata);
1ec5cd37
NC
22070
22071 return res;
22072}
22073
015dc7e1 22074static bool
dda8d76d 22075process_notes (Filedata * filedata)
779fe533
NC
22076{
22077 /* If we have not been asked to display the notes then do nothing. */
22078 if (! do_notes)
015dc7e1 22079 return true;
103f02d3 22080
dda8d76d
NC
22081 if (filedata->file_header.e_type != ET_CORE)
22082 return process_note_sections (filedata);
103f02d3 22083
779fe533 22084 /* No program headers means no NOTE segment. */
dda8d76d
NC
22085 if (filedata->file_header.e_phnum > 0)
22086 return process_corefile_note_segments (filedata);
779fe533 22087
ca0e11aa
NC
22088 if (filedata->is_separate)
22089 printf (_("No notes found in linked file '%s'.\n"),
22090 filedata->file_name);
22091 else
22092 printf (_("No notes found file.\n"));
22093
015dc7e1 22094 return true;
779fe533
NC
22095}
22096
60abdbed
NC
22097static unsigned char *
22098display_public_gnu_attributes (unsigned char * start,
22099 const unsigned char * const end)
22100{
22101 printf (_(" Unknown GNU attribute: %s\n"), start);
22102
22103 start += strnlen ((char *) start, end - start);
22104 display_raw_attribute (start, end);
22105
22106 return (unsigned char *) end;
22107}
22108
22109static unsigned char *
22110display_generic_attribute (unsigned char * start,
22111 unsigned int tag,
22112 const unsigned char * const end)
22113{
22114 if (tag == 0)
22115 return (unsigned char *) end;
22116
22117 return display_tag_value (tag, start, end);
22118}
22119
015dc7e1 22120static bool
dda8d76d 22121process_arch_specific (Filedata * filedata)
252b5132 22122{
a952a375 22123 if (! do_arch)
015dc7e1 22124 return true;
a952a375 22125
dda8d76d 22126 switch (filedata->file_header.e_machine)
252b5132 22127 {
53a346d8
CZ
22128 case EM_ARC:
22129 case EM_ARC_COMPACT:
22130 case EM_ARC_COMPACT2:
dda8d76d 22131 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
22132 display_arc_attribute,
22133 display_generic_attribute);
11c1ff18 22134 case EM_ARM:
dda8d76d 22135 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
22136 display_arm_attribute,
22137 display_generic_attribute);
22138
252b5132 22139 case EM_MIPS:
4fe85591 22140 case EM_MIPS_RS3_LE:
dda8d76d 22141 return process_mips_specific (filedata);
60abdbed
NC
22142
22143 case EM_MSP430:
dda8d76d 22144 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 22145 display_msp430_attribute,
c0ea7c52 22146 display_msp430_gnu_attribute);
60abdbed 22147
2dc8dd17
JW
22148 case EM_RISCV:
22149 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22150 display_riscv_attribute,
22151 display_generic_attribute);
22152
35c08157 22153 case EM_NDS32:
dda8d76d 22154 return process_nds32_specific (filedata);
60abdbed 22155
85f7484a
PB
22156 case EM_68K:
22157 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22158 display_m68k_gnu_attribute);
22159
34c8bcba 22160 case EM_PPC:
b82317dd 22161 case EM_PPC64:
dda8d76d 22162 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22163 display_power_gnu_attribute);
22164
643f7afb
AK
22165 case EM_S390:
22166 case EM_S390_OLD:
dda8d76d 22167 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22168 display_s390_gnu_attribute);
22169
9e8c70f9
DM
22170 case EM_SPARC:
22171 case EM_SPARC32PLUS:
22172 case EM_SPARCV9:
dda8d76d 22173 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22174 display_sparc_gnu_attribute);
22175
59e6276b 22176 case EM_TI_C6000:
dda8d76d 22177 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22178 display_tic6x_attribute,
22179 display_generic_attribute);
22180
0861f561
CQ
22181 case EM_CSKY:
22182 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22183 display_csky_attribute, NULL);
22184
252b5132 22185 default:
dda8d76d 22186 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22187 display_public_gnu_attributes,
22188 display_generic_attribute);
252b5132 22189 }
252b5132
RH
22190}
22191
015dc7e1 22192static bool
dda8d76d 22193get_file_header (Filedata * filedata)
252b5132 22194{
9ea033b2 22195 /* Read in the identity array. */
dda8d76d 22196 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22197 return false;
252b5132 22198
9ea033b2 22199 /* Determine how to read the rest of the header. */
dda8d76d 22200 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22201 {
1a0670f3
AM
22202 default:
22203 case ELFDATANONE:
adab8cdc
AO
22204 case ELFDATA2LSB:
22205 byte_get = byte_get_little_endian;
22206 byte_put = byte_put_little_endian;
22207 break;
22208 case ELFDATA2MSB:
22209 byte_get = byte_get_big_endian;
22210 byte_put = byte_put_big_endian;
22211 break;
9ea033b2
NC
22212 }
22213
22214 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22215 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22216
22217 /* Read in the rest of the header. */
22218 if (is_32bit_elf)
22219 {
22220 Elf32_External_Ehdr ehdr32;
252b5132 22221
dda8d76d 22222 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22223 return false;
103f02d3 22224
dda8d76d
NC
22225 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22226 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22227 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22228 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22229 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22230 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22231 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22232 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22233 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22234 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22235 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22236 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22237 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22238 }
252b5132 22239 else
9ea033b2
NC
22240 {
22241 Elf64_External_Ehdr ehdr64;
a952a375 22242
dda8d76d 22243 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22244 return false;
103f02d3 22245
dda8d76d
NC
22246 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22247 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22248 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22249 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22250 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22251 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22252 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22253 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22254 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22255 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22256 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22257 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22258 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22259 }
252b5132 22260
015dc7e1 22261 return true;
252b5132
RH
22262}
22263
13acb58d
AM
22264static void
22265free_filedata (Filedata *filedata)
22266{
22267 free (filedata->program_interpreter);
13acb58d 22268 free (filedata->program_headers);
13acb58d 22269 free (filedata->section_headers);
13acb58d 22270 free (filedata->string_table);
13acb58d 22271 free (filedata->dump.dump_sects);
13acb58d 22272 free (filedata->dynamic_strings);
13acb58d 22273 free (filedata->dynamic_symbols);
13acb58d 22274 free (filedata->dynamic_syminfo);
13acb58d 22275 free (filedata->dynamic_section);
13acb58d
AM
22276
22277 while (filedata->symtab_shndx_list != NULL)
22278 {
22279 elf_section_list *next = filedata->symtab_shndx_list->next;
22280 free (filedata->symtab_shndx_list);
22281 filedata->symtab_shndx_list = next;
22282 }
22283
22284 free (filedata->section_headers_groups);
13acb58d
AM
22285
22286 if (filedata->section_groups)
22287 {
22288 size_t i;
22289 struct group_list * g;
22290 struct group_list * next;
22291
22292 for (i = 0; i < filedata->group_count; i++)
22293 {
22294 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22295 {
22296 next = g->next;
22297 free (g);
22298 }
22299 }
22300
22301 free (filedata->section_groups);
13acb58d 22302 }
066f8fbe
AM
22303 memset (&filedata->section_headers, 0,
22304 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22305}
22306
dda8d76d
NC
22307static void
22308close_file (Filedata * filedata)
22309{
22310 if (filedata)
22311 {
22312 if (filedata->handle)
22313 fclose (filedata->handle);
22314 free (filedata);
22315 }
22316}
22317
22318void
22319close_debug_file (void * data)
22320{
13acb58d 22321 free_filedata ((Filedata *) data);
dda8d76d
NC
22322 close_file ((Filedata *) data);
22323}
22324
22325static Filedata *
015dc7e1 22326open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22327{
22328 struct stat statbuf;
22329 Filedata * filedata = NULL;
22330
22331 if (stat (pathname, & statbuf) < 0
22332 || ! S_ISREG (statbuf.st_mode))
22333 goto fail;
22334
22335 filedata = calloc (1, sizeof * filedata);
22336 if (filedata == NULL)
22337 goto fail;
22338
22339 filedata->handle = fopen (pathname, "rb");
22340 if (filedata->handle == NULL)
22341 goto fail;
22342
be7d229a 22343 filedata->file_size = statbuf.st_size;
dda8d76d 22344 filedata->file_name = pathname;
ca0e11aa 22345 filedata->is_separate = is_separate;
dda8d76d
NC
22346
22347 if (! get_file_header (filedata))
22348 goto fail;
22349
4de91c10
AM
22350 if (!get_section_headers (filedata, false))
22351 goto fail;
dda8d76d
NC
22352
22353 return filedata;
22354
22355 fail:
22356 if (filedata)
22357 {
22358 if (filedata->handle)
22359 fclose (filedata->handle);
22360 free (filedata);
22361 }
22362 return NULL;
22363}
22364
22365void *
22366open_debug_file (const char * pathname)
22367{
015dc7e1 22368 return open_file (pathname, true);
dda8d76d
NC
22369}
22370
835f2fae
NC
22371static void
22372initialise_dump_sects (Filedata * filedata)
22373{
22374 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22375 Note we do this even if cmdline_dump_sects is empty because we
22376 must make sure that the dump_sets array is zeroed out before each
22377 object file is processed. */
22378 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22379 memset (filedata->dump.dump_sects, 0,
22380 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22381
22382 if (cmdline.num_dump_sects > 0)
22383 {
22384 if (filedata->dump.num_dump_sects == 0)
22385 /* A sneaky way of allocating the dump_sects array. */
22386 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22387
22388 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22389 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22390 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22391 }
22392}
22393
94585d6d
NC
22394static bool
22395might_need_separate_debug_info (Filedata * filedata)
22396{
22397 /* Debuginfo files do not need further separate file loading. */
22398 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22399 return false;
22400
22401 /* Since do_follow_links might be enabled by default, only treat it as an
22402 indication that separate files should be loaded if setting it was a
22403 deliberate user action. */
22404 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22405 return true;
22406
22407 if (process_links || do_syms || do_unwind
22408 || dump_any_debugging || do_dump || do_debugging)
22409 return true;
22410
22411 return false;
22412}
22413
fb52b2f4
NC
22414/* Process one ELF object file according to the command line options.
22415 This file may actually be stored in an archive. The file is
32ec8896
NC
22416 positioned at the start of the ELF object. Returns TRUE if no
22417 problems were encountered, FALSE otherwise. */
fb52b2f4 22418
015dc7e1 22419static bool
dda8d76d 22420process_object (Filedata * filedata)
252b5132 22421{
015dc7e1 22422 bool have_separate_files;
252b5132 22423 unsigned int i;
015dc7e1 22424 bool res;
252b5132 22425
dda8d76d 22426 if (! get_file_header (filedata))
252b5132 22427 {
dda8d76d 22428 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22429 return false;
252b5132
RH
22430 }
22431
22432 /* Initialise per file variables. */
978c4450
AM
22433 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22434 filedata->version_info[i] = 0;
252b5132 22435
978c4450
AM
22436 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22437 filedata->dynamic_info[i] = 0;
22438 filedata->dynamic_info_DT_GNU_HASH = 0;
22439 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22440
22441 /* Process the file. */
22442 if (show_name)
dda8d76d 22443 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22444
835f2fae 22445 initialise_dump_sects (filedata);
d70c5fc7 22446
4de91c10
AM
22447 /* There may be some extensions in the first section header. Don't
22448 bomb if we can't read it. */
22449 get_section_headers (filedata, true);
22450
dda8d76d 22451 if (! process_file_header (filedata))
4de91c10
AM
22452 {
22453 res = false;
22454 goto out;
22455 }
252b5132 22456
e331b18d
AM
22457 /* Throw away the single section header read above, so that we
22458 re-read the entire set. */
22459 free (filedata->section_headers);
22460 filedata->section_headers = NULL;
22461
dda8d76d 22462 if (! process_section_headers (filedata))
2f62977e 22463 {
32ec8896 22464 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22465 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22466
2f62977e 22467 if (! do_using_dynamic)
015dc7e1 22468 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22469 }
252b5132 22470
dda8d76d 22471 if (! process_section_groups (filedata))
32ec8896 22472 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22473 do_unwind = false;
d1f5c6e3 22474
93df3340
AM
22475 process_program_headers (filedata);
22476
22477 res = process_dynamic_section (filedata);
252b5132 22478
dda8d76d 22479 if (! process_relocs (filedata))
015dc7e1 22480 res = false;
252b5132 22481
dda8d76d 22482 if (! process_unwind (filedata))
015dc7e1 22483 res = false;
4d6ed7c8 22484
dda8d76d 22485 if (! process_symbol_table (filedata))
015dc7e1 22486 res = false;
252b5132 22487
0f03783c 22488 if (! process_lto_symbol_tables (filedata))
015dc7e1 22489 res = false;
b9e920ec 22490
dda8d76d 22491 if (! process_syminfo (filedata))
015dc7e1 22492 res = false;
252b5132 22493
dda8d76d 22494 if (! process_version_sections (filedata))
015dc7e1 22495 res = false;
252b5132 22496
94585d6d 22497 if (might_need_separate_debug_info (filedata))
24841daa 22498 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22499 else
015dc7e1 22500 have_separate_files = false;
dda8d76d
NC
22501
22502 if (! process_section_contents (filedata))
015dc7e1 22503 res = false;
f5842774 22504
24841daa 22505 if (have_separate_files)
dda8d76d 22506 {
24841daa
NC
22507 separate_info * d;
22508
22509 for (d = first_separate_info; d != NULL; d = d->next)
22510 {
835f2fae
NC
22511 initialise_dump_sects (d->handle);
22512
ca0e11aa 22513 if (process_links && ! process_file_header (d->handle))
015dc7e1 22514 res = false;
ca0e11aa 22515 else if (! process_section_headers (d->handle))
015dc7e1 22516 res = false;
d6bfbc39 22517 else if (! process_section_contents (d->handle))
015dc7e1 22518 res = false;
ca0e11aa
NC
22519 else if (process_links)
22520 {
ca0e11aa 22521 if (! process_section_groups (d->handle))
015dc7e1 22522 res = false;
93df3340 22523 process_program_headers (d->handle);
ca0e11aa 22524 if (! process_dynamic_section (d->handle))
015dc7e1 22525 res = false;
ca0e11aa 22526 if (! process_relocs (d->handle))
015dc7e1 22527 res = false;
ca0e11aa 22528 if (! process_unwind (d->handle))
015dc7e1 22529 res = false;
ca0e11aa 22530 if (! process_symbol_table (d->handle))
015dc7e1 22531 res = false;
ca0e11aa 22532 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22533 res = false;
ca0e11aa 22534 if (! process_syminfo (d->handle))
015dc7e1 22535 res = false;
ca0e11aa 22536 if (! process_version_sections (d->handle))
015dc7e1 22537 res = false;
ca0e11aa 22538 if (! process_notes (d->handle))
015dc7e1 22539 res = false;
ca0e11aa 22540 }
24841daa
NC
22541 }
22542
22543 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22544 }
22545
22546 if (! process_notes (filedata))
015dc7e1 22547 res = false;
103f02d3 22548
dda8d76d 22549 if (! process_gnu_liblist (filedata))
015dc7e1 22550 res = false;
047b2264 22551
dda8d76d 22552 if (! process_arch_specific (filedata))
015dc7e1 22553 res = false;
252b5132 22554
4de91c10 22555 out:
13acb58d 22556 free_filedata (filedata);
e4b17d5c 22557
19e6b90e 22558 free_debug_memory ();
18bd398b 22559
32ec8896 22560 return res;
252b5132
RH
22561}
22562
2cf0635d 22563/* Process an ELF archive.
32ec8896
NC
22564 On entry the file is positioned just after the ARMAG string.
22565 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22566
015dc7e1
AM
22567static bool
22568process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22569{
22570 struct archive_info arch;
22571 struct archive_info nested_arch;
22572 size_t got;
015dc7e1 22573 bool ret = true;
2cf0635d 22574
015dc7e1 22575 show_name = true;
2cf0635d
NC
22576
22577 /* The ARCH structure is used to hold information about this archive. */
22578 arch.file_name = NULL;
22579 arch.file = NULL;
22580 arch.index_array = NULL;
22581 arch.sym_table = NULL;
22582 arch.longnames = NULL;
22583
22584 /* The NESTED_ARCH structure is used as a single-item cache of information
22585 about a nested archive (when members of a thin archive reside within
22586 another regular archive file). */
22587 nested_arch.file_name = NULL;
22588 nested_arch.file = NULL;
22589 nested_arch.index_array = NULL;
22590 nested_arch.sym_table = NULL;
22591 nested_arch.longnames = NULL;
22592
dda8d76d 22593 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22594 filedata->file_size, is_thin_archive,
22595 do_archive_index) != 0)
2cf0635d 22596 {
015dc7e1 22597 ret = false;
2cf0635d 22598 goto out;
4145f1d5 22599 }
fb52b2f4 22600
4145f1d5
NC
22601 if (do_archive_index)
22602 {
2cf0635d 22603 if (arch.sym_table == NULL)
1cb7d8b1
AM
22604 error (_("%s: unable to dump the index as none was found\n"),
22605 filedata->file_name);
4145f1d5
NC
22606 else
22607 {
26c527e6
AM
22608 uint64_t i, l;
22609 uint64_t current_pos;
4145f1d5 22610
26c527e6
AM
22611 printf (_("Index of archive %s: (%" PRIu64 " entries,"
22612 " %#" PRIx64 " bytes in the symbol table)\n"),
22613 filedata->file_name, arch.index_num,
1cb7d8b1 22614 arch.sym_size);
dda8d76d
NC
22615
22616 current_pos = ftell (filedata->handle);
4145f1d5 22617
2cf0635d 22618 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22619 {
1cb7d8b1
AM
22620 if (i == 0
22621 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22622 {
22623 char * member_name
22624 = get_archive_member_name_at (&arch, arch.index_array[i],
22625 &nested_arch);
2cf0635d 22626
1cb7d8b1
AM
22627 if (member_name != NULL)
22628 {
22629 char * qualified_name
22630 = make_qualified_name (&arch, &nested_arch,
22631 member_name);
2cf0635d 22632
1cb7d8b1
AM
22633 if (qualified_name != NULL)
22634 {
22635 printf (_("Contents of binary %s at offset "),
22636 qualified_name);
c2a7d3f5
NC
22637 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22638 putchar ('\n');
1cb7d8b1
AM
22639 free (qualified_name);
22640 }
fd486f32 22641 free (member_name);
4145f1d5
NC
22642 }
22643 }
2cf0635d
NC
22644
22645 if (l >= arch.sym_size)
4145f1d5 22646 {
1cb7d8b1
AM
22647 error (_("%s: end of the symbol table reached "
22648 "before the end of the index\n"),
dda8d76d 22649 filedata->file_name);
015dc7e1 22650 ret = false;
cb8f3167 22651 break;
4145f1d5 22652 }
591f7597 22653 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22654 printf ("\t%.*s\n",
22655 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22656 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22657 }
22658
67ce483b 22659 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22660 l = (l + 7) & ~ 7;
22661 else
22662 l += l & 1;
22663
2cf0635d 22664 if (l < arch.sym_size)
32ec8896 22665 {
26c527e6 22666 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
22667 "but without corresponding entries in "
22668 "the index table\n",
26c527e6 22669 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
22670 "but without corresponding entries in "
22671 "the index table\n",
22672 arch.sym_size - l),
dda8d76d 22673 filedata->file_name, arch.sym_size - l);
015dc7e1 22674 ret = false;
32ec8896 22675 }
4145f1d5 22676
63cf857e 22677 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22678 {
1cb7d8b1
AM
22679 error (_("%s: failed to seek back to start of object files "
22680 "in the archive\n"),
dda8d76d 22681 filedata->file_name);
015dc7e1 22682 ret = false;
2cf0635d 22683 goto out;
4145f1d5 22684 }
fb52b2f4 22685 }
4145f1d5
NC
22686
22687 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22688 && !do_segments && !do_header && !do_dump && !do_version
22689 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22690 && !do_section_groups && !do_dyn_syms)
2cf0635d 22691 {
015dc7e1 22692 ret = true; /* Archive index only. */
2cf0635d
NC
22693 goto out;
22694 }
fb52b2f4
NC
22695 }
22696
fb52b2f4
NC
22697 while (1)
22698 {
2cf0635d
NC
22699 char * name;
22700 size_t namelen;
22701 char * qualified_name;
22702
22703 /* Read the next archive header. */
63cf857e 22704 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22705 {
22706 error (_("%s: failed to seek to next archive header\n"),
22707 arch.file_name);
015dc7e1 22708 ret = false;
1cb7d8b1
AM
22709 break;
22710 }
dda8d76d 22711 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22712 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22713 {
22714 if (got == 0)
2cf0635d 22715 break;
28e817cc
NC
22716 /* PR 24049 - we cannot use filedata->file_name as this will
22717 have already been freed. */
22718 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22719
015dc7e1 22720 ret = false;
1cb7d8b1
AM
22721 break;
22722 }
2cf0635d 22723 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22724 {
22725 error (_("%s: did not find a valid archive header\n"),
22726 arch.file_name);
015dc7e1 22727 ret = false;
1cb7d8b1
AM
22728 break;
22729 }
2cf0635d
NC
22730
22731 arch.next_arhdr_offset += sizeof arch.arhdr;
22732
978c4450 22733 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22734
22735 name = get_archive_member_name (&arch, &nested_arch);
22736 if (name == NULL)
fb52b2f4 22737 {
28e817cc 22738 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22739 ret = false;
d989285c 22740 break;
fb52b2f4 22741 }
2cf0635d 22742 namelen = strlen (name);
fb52b2f4 22743
2cf0635d
NC
22744 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22745 if (qualified_name == NULL)
fb52b2f4 22746 {
28e817cc 22747 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22748 free (name);
015dc7e1 22749 ret = false;
d989285c 22750 break;
fb52b2f4
NC
22751 }
22752
2cf0635d 22753 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22754 {
22755 /* This is a proxy for an external member of a thin archive. */
22756 Filedata * member_filedata;
22757 char * member_file_name = adjust_relative_path
dda8d76d 22758 (filedata->file_name, name, namelen);
32ec8896 22759
fd486f32 22760 free (name);
1cb7d8b1
AM
22761 if (member_file_name == NULL)
22762 {
fd486f32 22763 free (qualified_name);
015dc7e1 22764 ret = false;
1cb7d8b1
AM
22765 break;
22766 }
2cf0635d 22767
015dc7e1 22768 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22769 if (member_filedata == NULL)
22770 {
22771 error (_("Input file '%s' is not readable.\n"), member_file_name);
22772 free (member_file_name);
fd486f32 22773 free (qualified_name);
015dc7e1 22774 ret = false;
1cb7d8b1
AM
22775 break;
22776 }
2cf0635d 22777
978c4450 22778 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22779 member_filedata->file_name = qualified_name;
2cf0635d 22780
75a2da57
AH
22781 /* The call to process_object() expects the file to be at the beginning. */
22782 rewind (member_filedata->handle);
22783
1cb7d8b1 22784 if (! process_object (member_filedata))
015dc7e1 22785 ret = false;
2cf0635d 22786
1cb7d8b1
AM
22787 close_file (member_filedata);
22788 free (member_file_name);
1cb7d8b1 22789 }
2cf0635d 22790 else if (is_thin_archive)
1cb7d8b1
AM
22791 {
22792 Filedata thin_filedata;
eb02c04d 22793
1cb7d8b1 22794 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22795
a043396b
NC
22796 /* PR 15140: Allow for corrupt thin archives. */
22797 if (nested_arch.file == NULL)
22798 {
22799 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22800 qualified_name, name);
fd486f32
AM
22801 free (qualified_name);
22802 free (name);
015dc7e1 22803 ret = false;
a043396b
NC
22804 break;
22805 }
fd486f32 22806 free (name);
a043396b 22807
1cb7d8b1 22808 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22809 filedata->archive_file_offset
22810 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22811
1cb7d8b1
AM
22812 /* The nested archive file will have been opened and setup by
22813 get_archive_member_name. */
63cf857e
AM
22814 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
22815 SEEK_SET) != 0)
1cb7d8b1
AM
22816 {
22817 error (_("%s: failed to seek to archive member.\n"),
22818 nested_arch.file_name);
fd486f32 22819 free (qualified_name);
015dc7e1 22820 ret = false;
1cb7d8b1
AM
22821 break;
22822 }
2cf0635d 22823
dda8d76d
NC
22824 thin_filedata.handle = nested_arch.file;
22825 thin_filedata.file_name = qualified_name;
9abca702 22826
1cb7d8b1 22827 if (! process_object (& thin_filedata))
015dc7e1 22828 ret = false;
1cb7d8b1 22829 }
2cf0635d 22830 else
1cb7d8b1 22831 {
fd486f32 22832 free (name);
978c4450 22833 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22834 filedata->file_name = qualified_name;
1cb7d8b1 22835 if (! process_object (filedata))
015dc7e1 22836 ret = false;
237877b8 22837 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22838 /* Stop looping with "negative" archive_file_size. */
978c4450 22839 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22840 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22841 }
fb52b2f4 22842
2cf0635d 22843 free (qualified_name);
fb52b2f4
NC
22844 }
22845
4145f1d5 22846 out:
2cf0635d
NC
22847 if (nested_arch.file != NULL)
22848 fclose (nested_arch.file);
22849 release_archive (&nested_arch);
22850 release_archive (&arch);
fb52b2f4 22851
d989285c 22852 return ret;
fb52b2f4
NC
22853}
22854
015dc7e1 22855static bool
2cf0635d 22856process_file (char * file_name)
fb52b2f4 22857{
dda8d76d 22858 Filedata * filedata = NULL;
fb52b2f4
NC
22859 struct stat statbuf;
22860 char armag[SARMAG];
015dc7e1 22861 bool ret = true;
fb52b2f4
NC
22862
22863 if (stat (file_name, &statbuf) < 0)
22864 {
f24ddbdd
NC
22865 if (errno == ENOENT)
22866 error (_("'%s': No such file\n"), file_name);
22867 else
22868 error (_("Could not locate '%s'. System error message: %s\n"),
22869 file_name, strerror (errno));
015dc7e1 22870 return false;
f24ddbdd
NC
22871 }
22872
22873 if (! S_ISREG (statbuf.st_mode))
22874 {
22875 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22876 return false;
fb52b2f4
NC
22877 }
22878
dda8d76d
NC
22879 filedata = calloc (1, sizeof * filedata);
22880 if (filedata == NULL)
22881 {
22882 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22883 return false;
dda8d76d
NC
22884 }
22885
22886 filedata->file_name = file_name;
22887 filedata->handle = fopen (file_name, "rb");
22888 if (filedata->handle == NULL)
fb52b2f4 22889 {
f24ddbdd 22890 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22891 free (filedata);
015dc7e1 22892 return false;
fb52b2f4
NC
22893 }
22894
dda8d76d 22895 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22896 {
4145f1d5 22897 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22898 fclose (filedata->handle);
22899 free (filedata);
015dc7e1 22900 return false;
fb52b2f4
NC
22901 }
22902
be7d229a 22903 filedata->file_size = statbuf.st_size;
015dc7e1 22904 filedata->is_separate = false;
f54498b4 22905
fb52b2f4 22906 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22907 {
015dc7e1
AM
22908 if (! process_archive (filedata, false))
22909 ret = false;
32ec8896 22910 }
2cf0635d 22911 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22912 {
015dc7e1
AM
22913 if ( ! process_archive (filedata, true))
22914 ret = false;
32ec8896 22915 }
fb52b2f4
NC
22916 else
22917 {
1b513401 22918 if (do_archive_index && !check_all)
4145f1d5
NC
22919 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22920 file_name);
22921
dda8d76d 22922 rewind (filedata->handle);
978c4450 22923 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22924
dda8d76d 22925 if (! process_object (filedata))
015dc7e1 22926 ret = false;
fb52b2f4
NC
22927 }
22928
dda8d76d 22929 fclose (filedata->handle);
8fb879cd
AM
22930 free (filedata->section_headers);
22931 free (filedata->program_headers);
22932 free (filedata->string_table);
6431e409 22933 free (filedata->dump.dump_sects);
dda8d76d 22934 free (filedata);
32ec8896 22935
fd486f32 22936 free (ba_cache.strtab);
1bd6175a 22937 ba_cache.strtab = NULL;
fd486f32 22938 free (ba_cache.symtab);
1bd6175a 22939 ba_cache.symtab = NULL;
fd486f32
AM
22940 ba_cache.filedata = NULL;
22941
fb52b2f4
NC
22942 return ret;
22943}
22944
252b5132
RH
22945#ifdef SUPPORT_DISASSEMBLY
22946/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22947 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22948 symbols. */
252b5132
RH
22949
22950void
2cf0635d 22951print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22952{
22953 fprintf (outfile,"0x%8.8x", addr);
22954}
22955
e3c8793a 22956/* Needed by the i386 disassembler. */
dda8d76d 22957
252b5132
RH
22958void
22959db_task_printsym (unsigned int addr)
22960{
22961 print_address (addr, stderr);
22962}
22963#endif
22964
22965int
2cf0635d 22966main (int argc, char ** argv)
252b5132 22967{
ff78d6d6
L
22968 int err;
22969
87b9f255 22970#ifdef HAVE_LC_MESSAGES
252b5132 22971 setlocale (LC_MESSAGES, "");
3882b010 22972#endif
3882b010 22973 setlocale (LC_CTYPE, "");
252b5132
RH
22974 bindtextdomain (PACKAGE, LOCALEDIR);
22975 textdomain (PACKAGE);
22976
869b9d07
MM
22977 expandargv (&argc, &argv);
22978
dda8d76d 22979 parse_args (& cmdline, argc, argv);
59f14fc0 22980
18bd398b 22981 if (optind < (argc - 1))
1b513401
NC
22982 /* When displaying information for more than one file,
22983 prefix the information with the file name. */
015dc7e1 22984 show_name = true;
5656ba2c
L
22985 else if (optind >= argc)
22986 {
1b513401 22987 /* Ensure that the warning is always displayed. */
015dc7e1 22988 do_checks = true;
1b513401 22989
5656ba2c
L
22990 warn (_("Nothing to do.\n"));
22991 usage (stderr);
22992 }
18bd398b 22993
015dc7e1 22994 err = false;
252b5132 22995 while (optind < argc)
32ec8896 22996 if (! process_file (argv[optind++]))
015dc7e1 22997 err = true;
252b5132 22998
9db70fc3 22999 free (cmdline.dump_sects);
252b5132 23000
7d9813f1
NA
23001 free (dump_ctf_symtab_name);
23002 free (dump_ctf_strtab_name);
23003 free (dump_ctf_parent_name);
23004
32ec8896 23005 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 23006}