]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Default getpkt 'forever' parameter to 'false'
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
d87bef3a 2 Copyright (C) 1998-2023 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056 46#include <zlib.h>
1f5a3546
FS
47#ifdef HAVE_ZSTD
48#include <zstd.h>
49#endif
7bfd842d 50#include <wchar.h>
252b5132 51
2952f10c
SM
52#if defined HAVE_MSGPACK
53#include <msgpack.h>
54#endif
55
19936277 56/* Define BFD64 here, even if our default architecture is 32 bit ELF
625d49fc 57 as this will allow us to read in and parse 64bit and 32bit ELF files. */
19936277 58#define BFD64
a952a375 59
3db64b00
AM
60#include "bfd.h"
61#include "bucomm.h"
3284fe0c 62#include "elfcomm.h"
0d646226 63#include "demanguse.h"
19e6b90e 64#include "dwarf.h"
7d9813f1 65#include "ctf-api.h"
42b6953b 66#include "sframe-api.h"
79bc120c 67#include "demangle.h"
252b5132
RH
68
69#include "elf/common.h"
70#include "elf/external.h"
71#include "elf/internal.h"
252b5132 72
4b78141a
NC
73
74/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
75 we can obtain the H8 reloc numbers. We need these for the
76 get_reloc_size() function. We include h8.h again after defining
77 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
78
79#include "elf/h8.h"
80#undef _ELF_H8_H
81
82/* Undo the effects of #including reloc-macros.h. */
83
84#undef START_RELOC_NUMBERS
85#undef RELOC_NUMBER
86#undef FAKE_RELOC
87#undef EMPTY_RELOC
88#undef END_RELOC_NUMBERS
89#undef _RELOC_MACROS_H
90
252b5132
RH
91/* The following headers use the elf/reloc-macros.h file to
92 automatically generate relocation recognition functions
93 such as elf_mips_reloc_type() */
94
95#define RELOC_MACROS_GEN_FUNC
96
a06ea964 97#include "elf/aarch64.h"
252b5132 98#include "elf/alpha.h"
c077c580 99#include "elf/amdgpu.h"
3b16e843 100#include "elf/arc.h"
252b5132 101#include "elf/arm.h"
3b16e843 102#include "elf/avr.h"
1d65ded4 103#include "elf/bfin.h"
60bca95a 104#include "elf/cr16.h"
3b16e843 105#include "elf/cris.h"
1c0d3aa6 106#include "elf/crx.h"
b8891f8d 107#include "elf/csky.h"
252b5132
RH
108#include "elf/d10v.h"
109#include "elf/d30v.h"
d172d4ba 110#include "elf/dlx.h"
aca4efc7 111#include "elf/bpf.h"
cfb8c092 112#include "elf/epiphany.h"
252b5132 113#include "elf/fr30.h"
5c70f934 114#include "elf/frv.h"
3f8107ab 115#include "elf/ft32.h"
3b16e843
NC
116#include "elf/h8.h"
117#include "elf/hppa.h"
118#include "elf/i386.h"
f954747f
AM
119#include "elf/i370.h"
120#include "elf/i860.h"
121#include "elf/i960.h"
3b16e843 122#include "elf/ia64.h"
1e4cf259 123#include "elf/ip2k.h"
6e712424 124#include "elf/kvx.h"
84e94c90 125#include "elf/lm32.h"
1c0d3aa6 126#include "elf/iq2000.h"
49f58d10 127#include "elf/m32c.h"
3b16e843
NC
128#include "elf/m32r.h"
129#include "elf/m68k.h"
75751cd9 130#include "elf/m68hc11.h"
7b4ae824 131#include "elf/s12z.h"
252b5132 132#include "elf/mcore.h"
15ab5209 133#include "elf/mep.h"
a3c62988 134#include "elf/metag.h"
7ba29e2a 135#include "elf/microblaze.h"
3b16e843 136#include "elf/mips.h"
3c3bdf30 137#include "elf/mmix.h"
3b16e843
NC
138#include "elf/mn10200.h"
139#include "elf/mn10300.h"
5506d11a 140#include "elf/moxie.h"
4970f871 141#include "elf/mt.h"
2469cfa2 142#include "elf/msp430.h"
35c08157 143#include "elf/nds32.h"
fe944acf 144#include "elf/nfp.h"
13761a11 145#include "elf/nios2.h"
73589c9d 146#include "elf/or1k.h"
7d466069 147#include "elf/pj.h"
3b16e843 148#include "elf/ppc.h"
c833c019 149#include "elf/ppc64.h"
2b100bb5 150#include "elf/pru.h"
03336641 151#include "elf/riscv.h"
99c513f6 152#include "elf/rl78.h"
c7927a3c 153#include "elf/rx.h"
a85d7ed0 154#include "elf/s390.h"
1c0d3aa6 155#include "elf/score.h"
3b16e843
NC
156#include "elf/sh.h"
157#include "elf/sparc.h"
e9f53129 158#include "elf/spu.h"
40b36596 159#include "elf/tic6x.h"
aa137e4d
NC
160#include "elf/tilegx.h"
161#include "elf/tilepro.h"
3b16e843 162#include "elf/v850.h"
179d3252 163#include "elf/vax.h"
619ed720 164#include "elf/visium.h"
f96bd6c2 165#include "elf/wasm32.h"
3b16e843 166#include "elf/x86-64.h"
f6c1a2d5 167#include "elf/xgate.h"
93fbbb04 168#include "elf/xstormy16.h"
88da6820 169#include "elf/xtensa.h"
6655dba2 170#include "elf/z80.h"
e9a0721f 171#include "elf/loongarch.h"
b5c37946 172#include "elf/bpf.h"
252b5132 173
252b5132 174#include "getopt.h"
566b0d53 175#include "libiberty.h"
09c11c86 176#include "safe-ctype.h"
2cf0635d 177#include "filenames.h"
252b5132 178
15b42fb0
AM
179#ifndef offsetof
180#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
181#endif
182
6a40cf0c
NC
183typedef struct elf_section_list
184{
dda8d76d
NC
185 Elf_Internal_Shdr * hdr;
186 struct elf_section_list * next;
6a40cf0c
NC
187} elf_section_list;
188
dda8d76d
NC
189/* Flag bits indicating particular types of dump. */
190#define HEX_DUMP (1 << 0) /* The -x command line switch. */
191#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
192#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
193#define STRING_DUMP (1 << 3) /* The -p command line switch. */
194#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 195#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
42b6953b 196#define SFRAME_DUMP (1 << 6) /* The --sframe command line switch. */
dda8d76d
NC
197
198typedef unsigned char dump_type;
199
200/* A linked list of the section names for which dumps were requested. */
201struct dump_list_entry
202{
203 char * name;
204 dump_type type;
205 struct dump_list_entry * next;
206};
207
6431e409
AM
208/* A dynamic array of flags indicating for which sections a dump
209 has been requested via command line switches. */
1b513401
NC
210struct dump_data
211{
6431e409
AM
212 dump_type * dump_sects;
213 unsigned int num_dump_sects;
214};
215
216static struct dump_data cmdline;
217
218static struct dump_list_entry * dump_sects_byname;
219
2cf0635d 220char * program_name = "readelf";
dda8d76d 221
015dc7e1
AM
222static bool show_name = false;
223static bool do_dynamic = false;
224static bool do_syms = false;
225static bool do_dyn_syms = false;
226static bool do_lto_syms = false;
227static bool do_reloc = false;
228static bool do_sections = false;
229static bool do_section_groups = false;
230static bool do_section_details = false;
231static bool do_segments = false;
232static bool do_unwind = false;
233static bool do_using_dynamic = false;
234static bool do_header = false;
235static bool do_dump = false;
236static bool do_version = false;
237static bool do_histogram = false;
238static bool do_debugging = false;
239static bool do_ctf = false;
42b6953b 240static bool do_sframe = false;
015dc7e1
AM
241static bool do_arch = false;
242static bool do_notes = false;
243static bool do_archive_index = false;
244static bool check_all = false;
245static bool is_32bit_elf = false;
246static bool decompress_dumps = false;
247static bool do_not_show_symbol_truncation = false;
248static bool do_demangle = false; /* Pretty print C++ symbol names. */
249static bool process_links = false;
e1dbfc17 250static bool dump_any_debugging = false;
79bc120c 251static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 252static int sym_base = 0;
252b5132 253
7d9813f1
NA
254static char *dump_ctf_parent_name;
255static char *dump_ctf_symtab_name;
256static char *dump_ctf_strtab_name;
257
e4b17d5c
L
258struct group_list
259{
dda8d76d
NC
260 struct group_list * next;
261 unsigned int section_index;
e4b17d5c
L
262};
263
264struct group
265{
dda8d76d
NC
266 struct group_list * root;
267 unsigned int group_index;
e4b17d5c
L
268};
269
978c4450
AM
270typedef struct filedata
271{
272 const char * file_name;
015dc7e1 273 bool is_separate;
978c4450 274 FILE * handle;
be7d229a 275 uint64_t file_size;
978c4450 276 Elf_Internal_Ehdr file_header;
26c527e6
AM
277 uint64_t archive_file_offset;
278 uint64_t archive_file_size;
066f8fbe 279 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
280 Elf_Internal_Shdr * section_headers;
281 Elf_Internal_Phdr * program_headers;
282 char * string_table;
26c527e6
AM
283 uint64_t string_table_length;
284 uint64_t dynamic_addr;
be7d229a 285 uint64_t dynamic_size;
26c527e6 286 uint64_t dynamic_nent;
978c4450 287 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 288 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450 289 char * dynamic_strings;
26c527e6 290 uint64_t dynamic_strings_length;
8ac10c5b 291 Elf_Internal_Shdr * dynamic_symtab_section;
26c527e6 292 uint64_t num_dynamic_syms;
978c4450 293 Elf_Internal_Sym * dynamic_symbols;
26c527e6 294 uint64_t version_info[16];
978c4450
AM
295 unsigned int dynamic_syminfo_nent;
296 Elf_Internal_Syminfo * dynamic_syminfo;
26c527e6 297 uint64_t dynamic_syminfo_offset;
be7d229a
AM
298 uint64_t nbuckets;
299 uint64_t nchains;
625d49fc
AM
300 uint64_t * buckets;
301 uint64_t * chains;
be7d229a
AM
302 uint64_t ngnubuckets;
303 uint64_t ngnuchains;
625d49fc
AM
304 uint64_t * gnubuckets;
305 uint64_t * gnuchains;
306 uint64_t * mipsxlat;
307 uint64_t gnusymidx;
13acb58d 308 char * program_interpreter;
bc227f4c 309 uint64_t dynamic_info[DT_RELRENT + 1];
625d49fc
AM
310 uint64_t dynamic_info_DT_GNU_HASH;
311 uint64_t dynamic_info_DT_MIPS_XHASH;
978c4450
AM
312 elf_section_list * symtab_shndx_list;
313 size_t group_count;
314 struct group * section_groups;
315 struct group ** section_headers_groups;
316 /* A dynamic array of flags indicating for which sections a dump of
317 some kind has been requested. It is reset on a per-object file
318 basis and then initialised from the cmdline_dump_sects array,
319 the results of interpreting the -w switch, and the
320 dump_sects_byname list. */
321 struct dump_data dump;
322} Filedata;
aef1f6d0 323
c256ffe7 324/* How to print a vma value. */
843dd992
NC
325typedef enum print_mode
326{
327 HEX,
047c3dbf 328 HEX_5,
843dd992
NC
329 DEC,
330 DEC_5,
331 UNSIGNED,
047c3dbf 332 UNSIGNED_5,
843dd992 333 PREFIX_HEX,
047c3dbf 334 PREFIX_HEX_5,
843dd992 335 FULL_HEX,
047c3dbf
NL
336 LONG_HEX,
337 OCTAL,
338 OCTAL_5
843dd992
NC
339}
340print_mode;
341
b3aa80b4
NC
342typedef enum unicode_display_type
343{
344 unicode_default = 0,
345 unicode_locale,
346 unicode_escape,
347 unicode_hex,
348 unicode_highlight,
349 unicode_invalid
350} unicode_display_type;
351
352static unicode_display_type unicode_display = unicode_default;
353
a7fd1186
FS
354typedef enum
355{
356 reltype_unknown,
357 reltype_rel,
358 reltype_rela,
359 reltype_relr
360} relocation_type;
361
bb4d2ac2
L
362/* Versioned symbol info. */
363enum versioned_symbol_info
364{
365 symbol_undefined,
366 symbol_hidden,
367 symbol_public
368};
369
63cf857e
AM
370static int
371fseek64 (FILE *stream, int64_t offset, int whence)
372{
373#if defined (HAVE_FSEEKO64)
374 off64_t o = offset;
375 if (o != offset)
376 {
377 errno = EINVAL;
378 return -1;
379 }
380 return fseeko64 (stream, o, whence);
381#elif defined (HAVE_FSEEKO)
382 off_t o = offset;
383 if (o != offset)
384 {
385 errno = EINVAL;
386 return -1;
387 }
388 return fseeko (stream, o, whence);
389#else
390 long o = offset;
391 if (o != offset)
392 {
393 errno = EINVAL;
394 return -1;
395 }
396 return fseek (stream, o, whence);
397#endif
398}
399
32ec8896 400static const char * get_symbol_version_string
26c527e6 401 (Filedata *, bool, const char *, size_t, unsigned,
32ec8896 402 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 403
9c19a809
NC
404#define UNKNOWN -1
405
84714f86
AM
406static inline const char *
407section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
408{
409 return filedata->string_table + hdr->sh_name;
410}
b9e920ec 411
84714f86
AM
412static inline bool
413section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
414{
415 return (hdr != NULL
416 && filedata->string_table != NULL
417 && hdr->sh_name < filedata->string_table_length);
418}
b9e920ec 419
84714f86
AM
420static inline const char *
421section_name_print (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
422{
423 if (hdr == NULL)
424 return _("<none>");
425 if (filedata->string_table == NULL)
426 return _("<no-strings>");
427 if (hdr->sh_name >= filedata->string_table_length)
428 return _("<corrupt>");
429 return section_name (filedata, hdr);
430}
252b5132 431
ee42cf8c 432#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 433
84714f86
AM
434static inline bool
435valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
436{
437 return strtab != NULL && offset < strtab_size;
438}
439
440static inline bool
441valid_dynamic_name (const Filedata *filedata, uint64_t offset)
442{
443 return valid_symbol_name (filedata->dynamic_strings,
444 filedata->dynamic_strings_length, offset);
445}
446
d79b3d50
NC
447/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
448 already been called and verified that the string exists. */
84714f86
AM
449static inline const char *
450get_dynamic_name (const Filedata *filedata, size_t offset)
451{
452 return filedata->dynamic_strings + offset;
453}
18bd398b 454
61865e30
NC
455#define REMOVE_ARCH_BITS(ADDR) \
456 do \
457 { \
dda8d76d 458 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
459 (ADDR) &= ~1; \
460 } \
461 while (0)
f16a9783
MS
462
463/* Get the correct GNU hash section name. */
978c4450
AM
464#define GNU_HASH_SECTION_NAME(filedata) \
465 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 466\f
dda8d76d
NC
467/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
468 OFFSET + the offset of the current archive member, if we are examining an
469 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
470 allocate a buffer using malloc and fill that. In either case return the
471 pointer to the start of the retrieved data or NULL if something went wrong.
472 If something does go wrong and REASON is not NULL then emit an error
473 message using REASON as part of the context. */
59245841 474
c256ffe7 475static void *
be7d229a
AM
476get_data (void *var,
477 Filedata *filedata,
26c527e6 478 uint64_t offset,
be7d229a
AM
479 uint64_t size,
480 uint64_t nmemb,
481 const char *reason)
a6e9f9df 482{
2cf0635d 483 void * mvar;
be7d229a 484 uint64_t amt = size * nmemb;
a6e9f9df 485
c256ffe7 486 if (size == 0 || nmemb == 0)
a6e9f9df
AM
487 return NULL;
488
be7d229a
AM
489 /* If size_t is smaller than uint64_t, eg because you are building
490 on a 32-bit host, then make sure that when the sizes are cast to
491 size_t no information is lost. */
7c1c1904
AM
492 if ((size_t) size != size
493 || (size_t) nmemb != nmemb
be7d229a
AM
494 || (size_t) amt != amt
495 || amt / size != nmemb
496 || (size_t) amt + 1 == 0)
57028622
NC
497 {
498 if (reason)
b8281767
AM
499 error (_("Size overflow prevents reading %" PRIu64
500 " elements of size %" PRIu64 " for %s\n"),
be7d229a 501 nmemb, size, reason);
57028622
NC
502 return NULL;
503 }
504
c22b42ce 505 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 506 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
507 if (filedata->archive_file_offset > filedata->file_size
508 || offset > filedata->file_size - filedata->archive_file_offset
509 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 510 {
049b0c3a 511 if (reason)
b8281767 512 error (_("Reading %" PRIu64 " bytes extends past end of file for %s\n"),
be7d229a 513 amt, reason);
a6e9f9df
AM
514 return NULL;
515 }
516
63cf857e
AM
517 if (fseek64 (filedata->handle, filedata->archive_file_offset + offset,
518 SEEK_SET))
071436c6
NC
519 {
520 if (reason)
26c527e6 521 error (_("Unable to seek to %#" PRIx64 " for %s\n"),
978c4450 522 filedata->archive_file_offset + offset, reason);
071436c6
NC
523 return NULL;
524 }
525
a6e9f9df
AM
526 mvar = var;
527 if (mvar == NULL)
528 {
7c1c1904
AM
529 /* + 1 so that we can '\0' terminate invalid string table sections. */
530 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
531
532 if (mvar == NULL)
533 {
049b0c3a 534 if (reason)
b8281767 535 error (_("Out of memory allocating %" PRIu64 " bytes for %s\n"),
be7d229a 536 amt, reason);
a6e9f9df
AM
537 return NULL;
538 }
c256ffe7 539
c9c1d674 540 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
541 }
542
dda8d76d 543 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 544 {
049b0c3a 545 if (reason)
b8281767 546 error (_("Unable to read in %" PRIu64 " bytes of %s\n"),
be7d229a 547 amt, reason);
a6e9f9df
AM
548 if (mvar != var)
549 free (mvar);
550 return NULL;
551 }
552
553 return mvar;
554}
555
32ec8896
NC
556/* Print a VMA value in the MODE specified.
557 Returns the number of characters displayed. */
cb8f3167 558
32ec8896 559static unsigned int
625d49fc 560print_vma (uint64_t vma, print_mode mode)
66543521 561{
32ec8896 562 unsigned int nc = 0;
66543521 563
14a91970 564 switch (mode)
66543521 565 {
14a91970
AM
566 case FULL_HEX:
567 nc = printf ("0x");
1a0670f3 568 /* Fall through. */
14a91970 569 case LONG_HEX:
f493c217 570 if (!is_32bit_elf)
625d49fc
AM
571 return nc + printf ("%16.16" PRIx64, vma);
572 return nc + printf ("%8.8" PRIx64, vma);
b19aac67 573
14a91970
AM
574 case DEC_5:
575 if (vma <= 99999)
625d49fc 576 return printf ("%5" PRId64, vma);
1a0670f3 577 /* Fall through. */
14a91970
AM
578 case PREFIX_HEX:
579 nc = printf ("0x");
1a0670f3 580 /* Fall through. */
14a91970 581 case HEX:
625d49fc 582 return nc + printf ("%" PRIx64, vma);
b19aac67 583
047c3dbf
NL
584 case PREFIX_HEX_5:
585 nc = printf ("0x");
586 /* Fall through. */
587 case HEX_5:
625d49fc 588 return nc + printf ("%05" PRIx64, vma);
047c3dbf 589
14a91970 590 case DEC:
625d49fc 591 return printf ("%" PRId64, vma);
b19aac67 592
14a91970 593 case UNSIGNED:
625d49fc 594 return printf ("%" PRIu64, vma);
32ec8896 595
047c3dbf 596 case UNSIGNED_5:
625d49fc 597 return printf ("%5" PRIu64, vma);
047c3dbf
NL
598
599 case OCTAL:
625d49fc 600 return printf ("%" PRIo64, vma);
047c3dbf
NL
601
602 case OCTAL_5:
625d49fc 603 return printf ("%5" PRIo64, vma);
047c3dbf 604
32ec8896
NC
605 default:
606 /* FIXME: Report unrecognised mode ? */
607 return 0;
f7a99963 608 }
f7a99963
NC
609}
610
047c3dbf 611
7bfd842d 612/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 613 multibye characters (assuming the host environment supports them).
31104126 614
7bfd842d
NC
615 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
616
0942c7ab
NC
617 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
618 abs(WIDTH) - 5 characters followed by "[...]".
619
7bfd842d
NC
620 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
621 padding as necessary.
171191ba
NC
622
623 Returns the number of emitted characters. */
624
625static unsigned int
0942c7ab 626print_symbol (signed int width, const char * symbol)
31104126 627{
015dc7e1
AM
628 bool extra_padding = false;
629 bool do_dots = false;
32ec8896 630 signed int num_printed = 0;
3bfcb652 631#ifdef HAVE_MBSTATE_T
7bfd842d 632 mbstate_t state;
3bfcb652 633#endif
32ec8896 634 unsigned int width_remaining;
79bc120c 635 const void * alloced_symbol = NULL;
961c521f 636
7bfd842d 637 if (width < 0)
961c521f 638 {
88305e1b 639 /* Keep the width positive. This helps the code below. */
961c521f 640 width = - width;
015dc7e1 641 extra_padding = true;
0b4362b0 642 }
56d8f8a9
NC
643 else if (width == 0)
644 return 0;
961c521f 645
7bfd842d
NC
646 if (do_wide)
647 /* Set the remaining width to a very large value.
648 This simplifies the code below. */
649 width_remaining = INT_MAX;
650 else
0942c7ab
NC
651 {
652 width_remaining = width;
653 if (! do_not_show_symbol_truncation
654 && (int) strlen (symbol) > width)
655 {
656 width_remaining -= 5;
657 if ((int) width_remaining < 0)
658 width_remaining = 0;
015dc7e1 659 do_dots = true;
0942c7ab
NC
660 }
661 }
cb8f3167 662
3bfcb652 663#ifdef HAVE_MBSTATE_T
7bfd842d
NC
664 /* Initialise the multibyte conversion state. */
665 memset (& state, 0, sizeof (state));
3bfcb652 666#endif
961c521f 667
79bc120c
NC
668 if (do_demangle && *symbol)
669 {
670 const char * res = cplus_demangle (symbol, demangle_flags);
671
672 if (res != NULL)
673 alloced_symbol = symbol = res;
674 }
675
7bfd842d
NC
676 while (width_remaining)
677 {
678 size_t n;
7bfd842d 679 const char c = *symbol++;
961c521f 680
7bfd842d 681 if (c == 0)
961c521f
NC
682 break;
683
b3aa80b4
NC
684 if (ISPRINT (c))
685 {
686 putchar (c);
687 width_remaining --;
688 num_printed ++;
689 }
690 else if (ISCNTRL (c))
961c521f 691 {
b3aa80b4
NC
692 /* Do not print control characters directly as they can affect terminal
693 settings. Such characters usually appear in the names generated
694 by the assembler for local labels. */
695
7bfd842d 696 if (width_remaining < 2)
961c521f
NC
697 break;
698
7bfd842d
NC
699 printf ("^%c", c + 0x40);
700 width_remaining -= 2;
171191ba 701 num_printed += 2;
961c521f 702 }
b3aa80b4 703 else if (c == 0x7f)
7bfd842d 704 {
b3aa80b4
NC
705 if (width_remaining < 5)
706 break;
707 printf ("<DEL>");
708 width_remaining -= 5;
709 num_printed += 5;
710 }
711 else if (unicode_display != unicode_locale
712 && unicode_display != unicode_default)
713 {
714 /* Display unicode characters as something else. */
715 unsigned char bytes[4];
716 bool is_utf8;
795588ae 717 unsigned int nbytes;
b3aa80b4
NC
718
719 bytes[0] = c;
720
721 if (bytes[0] < 0xc0)
722 {
723 nbytes = 1;
724 is_utf8 = false;
725 }
726 else
727 {
728 bytes[1] = *symbol++;
729
730 if ((bytes[1] & 0xc0) != 0x80)
731 {
732 is_utf8 = false;
733 /* Do not consume this character. It may only
734 be the first byte in the sequence that was
735 corrupt. */
736 --symbol;
737 nbytes = 1;
738 }
739 else if ((bytes[0] & 0x20) == 0)
740 {
741 is_utf8 = true;
742 nbytes = 2;
743 }
744 else
745 {
746 bytes[2] = *symbol++;
747
748 if ((bytes[2] & 0xc0) != 0x80)
749 {
750 is_utf8 = false;
751 symbol -= 2;
752 nbytes = 1;
753 }
754 else if ((bytes[0] & 0x10) == 0)
755 {
756 is_utf8 = true;
757 nbytes = 3;
758 }
759 else
760 {
761 bytes[3] = *symbol++;
762
763 nbytes = 4;
764
765 if ((bytes[3] & 0xc0) != 0x80)
766 {
767 is_utf8 = false;
768 symbol -= 3;
769 nbytes = 1;
770 }
771 else
772 is_utf8 = true;
773 }
774 }
775 }
776
777 if (unicode_display == unicode_invalid)
778 is_utf8 = false;
779
780 if (unicode_display == unicode_hex || ! is_utf8)
781 {
795588ae 782 unsigned int i;
b3aa80b4
NC
783
784 if (width_remaining < (nbytes * 2) + 2)
785 break;
786
787 putchar (is_utf8 ? '<' : '{');
788 printf ("0x");
789 for (i = 0; i < nbytes; i++)
790 printf ("%02x", bytes[i]);
791 putchar (is_utf8 ? '>' : '}');
792 }
793 else
794 {
795 if (unicode_display == unicode_highlight && isatty (1))
796 printf ("\x1B[31;47m"); /* Red. */
797
798 switch (nbytes)
799 {
800 case 2:
801 if (width_remaining < 6)
802 break;
803 printf ("\\u%02x%02x",
804 (bytes[0] & 0x1c) >> 2,
805 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
806 break;
807 case 3:
808 if (width_remaining < 6)
809 break;
810 printf ("\\u%02x%02x",
811 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
812 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
813 break;
814 case 4:
815 if (width_remaining < 8)
816 break;
817 printf ("\\u%02x%02x%02x",
818 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
819 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
820 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
821
822 break;
823 default:
824 /* URG. */
825 break;
826 }
827
828 if (unicode_display == unicode_highlight && isatty (1))
829 printf ("\033[0m"); /* Default colour. */
830 }
831
832 if (bytes[nbytes - 1] == 0)
833 break;
7bfd842d 834 }
961c521f
NC
835 else
836 {
3bfcb652
NC
837#ifdef HAVE_MBSTATE_T
838 wchar_t w;
839#endif
7bfd842d
NC
840 /* Let printf do the hard work of displaying multibyte characters. */
841 printf ("%.1s", symbol - 1);
842 width_remaining --;
843 num_printed ++;
844
3bfcb652 845#ifdef HAVE_MBSTATE_T
7bfd842d
NC
846 /* Try to find out how many bytes made up the character that was
847 just printed. Advance the symbol pointer past the bytes that
848 were displayed. */
849 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
850#else
851 n = 1;
852#endif
7bfd842d
NC
853 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
854 symbol += (n - 1);
961c521f 855 }
961c521f 856 }
171191ba 857
0942c7ab
NC
858 if (do_dots)
859 num_printed += printf ("[...]");
860
7bfd842d 861 if (extra_padding && num_printed < width)
171191ba
NC
862 {
863 /* Fill in the remaining spaces. */
7bfd842d
NC
864 printf ("%-*s", width - num_printed, " ");
865 num_printed = width;
171191ba
NC
866 }
867
79bc120c 868 free ((void *) alloced_symbol);
171191ba 869 return num_printed;
31104126
NC
870}
871
1449284b 872/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
873 the given section's name. Like print_symbol, except that it does not try
874 to print multibyte characters, it just interprets them as hex values. */
875
876static const char *
dda8d76d 877printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 878{
ca0e11aa 879#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 880 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
84714f86 881 const char * name = section_name_print (filedata, sec);
74e1a04b
NC
882 char * buf = sec_name_buf;
883 char c;
884 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
885
886 while ((c = * name ++) != 0)
887 {
888 if (ISCNTRL (c))
889 {
890 if (remaining < 2)
891 break;
948f632f 892
74e1a04b
NC
893 * buf ++ = '^';
894 * buf ++ = c + 0x40;
895 remaining -= 2;
896 }
897 else if (ISPRINT (c))
898 {
899 * buf ++ = c;
900 remaining -= 1;
901 }
902 else
903 {
904 static char hex[17] = "0123456789ABCDEF";
905
906 if (remaining < 4)
907 break;
908 * buf ++ = '<';
909 * buf ++ = hex[(c & 0xf0) >> 4];
910 * buf ++ = hex[c & 0x0f];
911 * buf ++ = '>';
912 remaining -= 4;
913 }
914
915 if (remaining == 0)
916 break;
917 }
918
919 * buf = 0;
920 return sec_name_buf;
921}
922
923static const char *
26c527e6 924printable_section_name_from_index (Filedata *filedata, size_t ndx)
74e1a04b 925{
dda8d76d 926 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
927 return _("<corrupt>");
928
dda8d76d 929 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
930}
931
89fac5e3
RS
932/* Return a pointer to section NAME, or NULL if no such section exists. */
933
934static Elf_Internal_Shdr *
dda8d76d 935find_section (Filedata * filedata, const char * name)
89fac5e3
RS
936{
937 unsigned int i;
938
68807c3c
NC
939 if (filedata->section_headers == NULL)
940 return NULL;
dda8d76d
NC
941
942 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
943 if (section_name_valid (filedata, filedata->section_headers + i)
944 && streq (section_name (filedata, filedata->section_headers + i),
945 name))
dda8d76d 946 return filedata->section_headers + i;
89fac5e3
RS
947
948 return NULL;
949}
950
0b6ae522
DJ
951/* Return a pointer to a section containing ADDR, or NULL if no such
952 section exists. */
953
954static Elf_Internal_Shdr *
625d49fc 955find_section_by_address (Filedata * filedata, uint64_t addr)
0b6ae522
DJ
956{
957 unsigned int i;
958
68807c3c
NC
959 if (filedata->section_headers == NULL)
960 return NULL;
961
dda8d76d 962 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 963 {
dda8d76d
NC
964 Elf_Internal_Shdr *sec = filedata->section_headers + i;
965
0b6ae522
DJ
966 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
967 return sec;
968 }
969
970 return NULL;
971}
972
071436c6 973static Elf_Internal_Shdr *
dda8d76d 974find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
975{
976 unsigned int i;
977
68807c3c
NC
978 if (filedata->section_headers == NULL)
979 return NULL;
980
dda8d76d 981 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 982 {
dda8d76d
NC
983 Elf_Internal_Shdr *sec = filedata->section_headers + i;
984
071436c6
NC
985 if (sec->sh_type == type)
986 return sec;
987 }
988
989 return NULL;
990}
991
657d0d47
CC
992/* Return a pointer to section NAME, or NULL if no such section exists,
993 restricted to the list of sections given in SET. */
994
995static Elf_Internal_Shdr *
dda8d76d 996find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
997{
998 unsigned int i;
999
68807c3c
NC
1000 if (filedata->section_headers == NULL)
1001 return NULL;
1002
657d0d47
CC
1003 if (set != NULL)
1004 {
1005 while ((i = *set++) > 0)
b814a36d
NC
1006 {
1007 /* See PR 21156 for a reproducer. */
dda8d76d 1008 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
1009 continue; /* FIXME: Should we issue an error message ? */
1010
84714f86
AM
1011 if (section_name_valid (filedata, filedata->section_headers + i)
1012 && streq (section_name (filedata, filedata->section_headers + i),
1013 name))
dda8d76d 1014 return filedata->section_headers + i;
b814a36d 1015 }
657d0d47
CC
1016 }
1017
dda8d76d 1018 return find_section (filedata, name);
657d0d47
CC
1019}
1020
32ec8896 1021/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
1022 This OS has so many departures from the ELF standard that we test it at
1023 many places. */
1024
015dc7e1 1025static inline bool
dda8d76d 1026is_ia64_vms (Filedata * filedata)
28f997cf 1027{
dda8d76d
NC
1028 return filedata->file_header.e_machine == EM_IA_64
1029 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
1030}
1031
bcedfee6 1032/* Guess the relocation size commonly used by the specific machines. */
252b5132 1033
015dc7e1 1034static bool
2dc4cec1 1035guess_is_rela (unsigned int e_machine)
252b5132 1036{
9c19a809 1037 switch (e_machine)
252b5132
RH
1038 {
1039 /* Targets that use REL relocations. */
252b5132 1040 case EM_386:
22abe556 1041 case EM_IAMCU:
f954747f 1042 case EM_960:
e9f53129 1043 case EM_ARM:
2b0337b0 1044 case EM_D10V:
252b5132 1045 case EM_CYGNUS_D10V:
e9f53129 1046 case EM_DLX:
252b5132 1047 case EM_MIPS:
4fe85591 1048 case EM_MIPS_RS3_LE:
e9f53129 1049 case EM_CYGNUS_M32R:
1c0d3aa6 1050 case EM_SCORE:
f6c1a2d5 1051 case EM_XGATE:
fe944acf 1052 case EM_NFP:
aca4efc7 1053 case EM_BPF:
015dc7e1 1054 return false;
103f02d3 1055
252b5132
RH
1056 /* Targets that use RELA relocations. */
1057 case EM_68K:
f954747f 1058 case EM_860:
a06ea964 1059 case EM_AARCH64:
cfb8c092 1060 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1061 case EM_ALPHA:
1062 case EM_ALTERA_NIOS2:
886a2506
NC
1063 case EM_ARC:
1064 case EM_ARC_COMPACT:
1065 case EM_ARC_COMPACT2:
b5c37946
SJ
1066 case EM_ARC_COMPACT3:
1067 case EM_ARC_COMPACT3_64:
e9f53129
AM
1068 case EM_AVR:
1069 case EM_AVR_OLD:
1070 case EM_BLACKFIN:
60bca95a 1071 case EM_CR16:
e9f53129
AM
1072 case EM_CRIS:
1073 case EM_CRX:
b8891f8d 1074 case EM_CSKY:
2b0337b0 1075 case EM_D30V:
252b5132 1076 case EM_CYGNUS_D30V:
2b0337b0 1077 case EM_FR30:
3f8107ab 1078 case EM_FT32:
252b5132 1079 case EM_CYGNUS_FR30:
5c70f934 1080 case EM_CYGNUS_FRV:
e9f53129
AM
1081 case EM_H8S:
1082 case EM_H8_300:
1083 case EM_H8_300H:
800eeca4 1084 case EM_IA_64:
1e4cf259
NC
1085 case EM_IP2K:
1086 case EM_IP2K_OLD:
3b36097d 1087 case EM_IQ2000:
6e712424 1088 case EM_KVX:
84e94c90 1089 case EM_LATTICEMICO32:
ff7eeb89 1090 case EM_M32C_OLD:
49f58d10 1091 case EM_M32C:
e9f53129
AM
1092 case EM_M32R:
1093 case EM_MCORE:
15ab5209 1094 case EM_CYGNUS_MEP:
a3c62988 1095 case EM_METAG:
e9f53129
AM
1096 case EM_MMIX:
1097 case EM_MN10200:
1098 case EM_CYGNUS_MN10200:
1099 case EM_MN10300:
1100 case EM_CYGNUS_MN10300:
5506d11a 1101 case EM_MOXIE:
e9f53129
AM
1102 case EM_MSP430:
1103 case EM_MSP430_OLD:
d031aafb 1104 case EM_MT:
35c08157 1105 case EM_NDS32:
64fd6348 1106 case EM_NIOS32:
73589c9d 1107 case EM_OR1K:
e9f53129
AM
1108 case EM_PPC64:
1109 case EM_PPC:
2b100bb5 1110 case EM_TI_PRU:
e23eba97 1111 case EM_RISCV:
99c513f6 1112 case EM_RL78:
c7927a3c 1113 case EM_RX:
e9f53129
AM
1114 case EM_S390:
1115 case EM_S390_OLD:
1116 case EM_SH:
1117 case EM_SPARC:
1118 case EM_SPARC32PLUS:
1119 case EM_SPARCV9:
1120 case EM_SPU:
40b36596 1121 case EM_TI_C6000:
aa137e4d
NC
1122 case EM_TILEGX:
1123 case EM_TILEPRO:
708e2187 1124 case EM_V800:
e9f53129
AM
1125 case EM_V850:
1126 case EM_CYGNUS_V850:
1127 case EM_VAX:
619ed720 1128 case EM_VISIUM:
e9f53129 1129 case EM_X86_64:
8a9036a4 1130 case EM_L1OM:
7a9068fe 1131 case EM_K1OM:
e9f53129
AM
1132 case EM_XSTORMY16:
1133 case EM_XTENSA:
1134 case EM_XTENSA_OLD:
7ba29e2a
NC
1135 case EM_MICROBLAZE:
1136 case EM_MICROBLAZE_OLD:
f96bd6c2 1137 case EM_WEBASSEMBLY:
015dc7e1 1138 return true;
103f02d3 1139
e9f53129
AM
1140 case EM_68HC05:
1141 case EM_68HC08:
1142 case EM_68HC11:
1143 case EM_68HC16:
1144 case EM_FX66:
1145 case EM_ME16:
d1133906 1146 case EM_MMA:
d1133906
NC
1147 case EM_NCPU:
1148 case EM_NDR1:
e9f53129 1149 case EM_PCP:
d1133906 1150 case EM_ST100:
e9f53129 1151 case EM_ST19:
d1133906 1152 case EM_ST7:
e9f53129
AM
1153 case EM_ST9PLUS:
1154 case EM_STARCORE:
d1133906 1155 case EM_SVX:
e9f53129 1156 case EM_TINYJ:
9c19a809
NC
1157 default:
1158 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1159 return false;
9c19a809
NC
1160 }
1161}
252b5132 1162
dda8d76d 1163/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1164 Returns TRUE upon success, FALSE otherwise. If successful then a
1165 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1166 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1167 responsibility to free the allocated buffer. */
1168
015dc7e1 1169static bool
26c527e6
AM
1170slurp_rela_relocs (Filedata *filedata,
1171 uint64_t rel_offset,
1172 uint64_t rel_size,
1173 Elf_Internal_Rela **relasp,
1174 uint64_t *nrelasp)
9c19a809 1175{
2cf0635d 1176 Elf_Internal_Rela * relas;
26c527e6 1177 uint64_t nrelas;
4d6ed7c8 1178 unsigned int i;
252b5132 1179
4d6ed7c8
NC
1180 if (is_32bit_elf)
1181 {
2cf0635d 1182 Elf32_External_Rela * erelas;
103f02d3 1183
dda8d76d 1184 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1185 rel_size, _("32-bit relocation data"));
a6e9f9df 1186 if (!erelas)
015dc7e1 1187 return false;
252b5132 1188
4d6ed7c8 1189 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1190
3f5e193b
NC
1191 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1192 sizeof (Elf_Internal_Rela));
103f02d3 1193
4d6ed7c8
NC
1194 if (relas == NULL)
1195 {
c256ffe7 1196 free (erelas);
591a748a 1197 error (_("out of memory parsing relocs\n"));
015dc7e1 1198 return false;
4d6ed7c8 1199 }
103f02d3 1200
4d6ed7c8
NC
1201 for (i = 0; i < nrelas; i++)
1202 {
1203 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1204 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1205 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1206 }
103f02d3 1207
4d6ed7c8
NC
1208 free (erelas);
1209 }
1210 else
1211 {
2cf0635d 1212 Elf64_External_Rela * erelas;
103f02d3 1213
dda8d76d 1214 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1215 rel_size, _("64-bit relocation data"));
a6e9f9df 1216 if (!erelas)
015dc7e1 1217 return false;
4d6ed7c8
NC
1218
1219 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1220
3f5e193b
NC
1221 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1222 sizeof (Elf_Internal_Rela));
103f02d3 1223
4d6ed7c8
NC
1224 if (relas == NULL)
1225 {
c256ffe7 1226 free (erelas);
591a748a 1227 error (_("out of memory parsing relocs\n"));
015dc7e1 1228 return false;
9c19a809 1229 }
4d6ed7c8
NC
1230
1231 for (i = 0; i < nrelas; i++)
9c19a809 1232 {
66543521
AM
1233 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1234 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1235 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a 1236
dda8d76d
NC
1237 if (filedata->file_header.e_machine == EM_MIPS
1238 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1239 {
1240 /* In little-endian objects, r_info isn't really a
1241 64-bit little-endian value: it has a 32-bit
1242 little-endian symbol index followed by four
1243 individual byte fields. Reorder INFO
1244 accordingly. */
625d49fc 1245 uint64_t inf = relas[i].r_info;
91d6fa6a
NC
1246 inf = (((inf & 0xffffffff) << 32)
1247 | ((inf >> 56) & 0xff)
1248 | ((inf >> 40) & 0xff00)
1249 | ((inf >> 24) & 0xff0000)
1250 | ((inf >> 8) & 0xff000000));
1251 relas[i].r_info = inf;
861fb55a 1252 }
4d6ed7c8 1253 }
103f02d3 1254
4d6ed7c8
NC
1255 free (erelas);
1256 }
32ec8896 1257
4d6ed7c8
NC
1258 *relasp = relas;
1259 *nrelasp = nrelas;
015dc7e1 1260 return true;
4d6ed7c8 1261}
103f02d3 1262
dda8d76d 1263/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1264 Returns TRUE upon success, FALSE otherwise. If successful then a
1265 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1266 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1267 responsibility to free the allocated buffer. */
1268
015dc7e1 1269static bool
26c527e6
AM
1270slurp_rel_relocs (Filedata *filedata,
1271 uint64_t rel_offset,
1272 uint64_t rel_size,
1273 Elf_Internal_Rela **relsp,
1274 uint64_t *nrelsp)
4d6ed7c8 1275{
2cf0635d 1276 Elf_Internal_Rela * rels;
26c527e6 1277 uint64_t nrels;
4d6ed7c8 1278 unsigned int i;
103f02d3 1279
4d6ed7c8
NC
1280 if (is_32bit_elf)
1281 {
2cf0635d 1282 Elf32_External_Rel * erels;
103f02d3 1283
dda8d76d 1284 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1285 rel_size, _("32-bit relocation data"));
a6e9f9df 1286 if (!erels)
015dc7e1 1287 return false;
103f02d3 1288
4d6ed7c8 1289 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1290
3f5e193b 1291 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1292
4d6ed7c8
NC
1293 if (rels == NULL)
1294 {
c256ffe7 1295 free (erels);
591a748a 1296 error (_("out of memory parsing relocs\n"));
015dc7e1 1297 return false;
4d6ed7c8
NC
1298 }
1299
1300 for (i = 0; i < nrels; i++)
1301 {
1302 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1303 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1304 rels[i].r_addend = 0;
9ea033b2 1305 }
4d6ed7c8
NC
1306
1307 free (erels);
9c19a809
NC
1308 }
1309 else
1310 {
2cf0635d 1311 Elf64_External_Rel * erels;
9ea033b2 1312
dda8d76d 1313 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1314 rel_size, _("64-bit relocation data"));
a6e9f9df 1315 if (!erels)
015dc7e1 1316 return false;
103f02d3 1317
4d6ed7c8 1318 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1319
3f5e193b 1320 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1321
4d6ed7c8 1322 if (rels == NULL)
9c19a809 1323 {
c256ffe7 1324 free (erels);
591a748a 1325 error (_("out of memory parsing relocs\n"));
015dc7e1 1326 return false;
4d6ed7c8 1327 }
103f02d3 1328
4d6ed7c8
NC
1329 for (i = 0; i < nrels; i++)
1330 {
66543521
AM
1331 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1332 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1333 rels[i].r_addend = 0;
861fb55a 1334
dda8d76d
NC
1335 if (filedata->file_header.e_machine == EM_MIPS
1336 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1337 {
1338 /* In little-endian objects, r_info isn't really a
1339 64-bit little-endian value: it has a 32-bit
1340 little-endian symbol index followed by four
1341 individual byte fields. Reorder INFO
1342 accordingly. */
625d49fc 1343 uint64_t inf = rels[i].r_info;
91d6fa6a
NC
1344 inf = (((inf & 0xffffffff) << 32)
1345 | ((inf >> 56) & 0xff)
1346 | ((inf >> 40) & 0xff00)
1347 | ((inf >> 24) & 0xff0000)
1348 | ((inf >> 8) & 0xff000000));
1349 rels[i].r_info = inf;
861fb55a 1350 }
4d6ed7c8 1351 }
103f02d3 1352
4d6ed7c8
NC
1353 free (erels);
1354 }
32ec8896 1355
4d6ed7c8
NC
1356 *relsp = rels;
1357 *nrelsp = nrels;
015dc7e1 1358 return true;
4d6ed7c8 1359}
103f02d3 1360
a7fd1186 1361static bool
26c527e6
AM
1362slurp_relr_relocs (Filedata *filedata,
1363 uint64_t relr_offset,
1364 uint64_t relr_size,
1365 uint64_t **relrsp,
1366 uint64_t *nrelrsp)
a7fd1186
FS
1367{
1368 void *relrs;
1369 size_t size = 0, nentries, i;
625d49fc 1370 uint64_t base = 0, addr, entry;
a7fd1186
FS
1371
1372 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1373 _("RELR relocation data"));
1374 if (!relrs)
1375 return false;
1376
1377 if (is_32bit_elf)
1378 nentries = relr_size / sizeof (Elf32_External_Relr);
1379 else
1380 nentries = relr_size / sizeof (Elf64_External_Relr);
1381 for (i = 0; i < nentries; i++)
1382 {
1383 if (is_32bit_elf)
1384 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1385 else
1386 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1387 if ((entry & 1) == 0)
1388 size++;
1389 else
1390 while ((entry >>= 1) != 0)
1391 if ((entry & 1) == 1)
1392 size++;
1393 }
1394
625d49fc 1395 *relrsp = malloc (size * sizeof (**relrsp));
a7fd1186
FS
1396 if (*relrsp == NULL)
1397 {
1398 free (relrs);
1399 error (_("out of memory parsing relocs\n"));
1400 return false;
1401 }
1402
1403 size = 0;
1404 for (i = 0; i < nentries; i++)
1405 {
625d49fc 1406 const uint64_t entry_bytes = is_32bit_elf ? 4 : 8;
a7fd1186
FS
1407
1408 if (is_32bit_elf)
1409 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1410 else
1411 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1412 if ((entry & 1) == 0)
1413 {
1414 (*relrsp)[size++] = entry;
1415 base = entry + entry_bytes;
1416 }
1417 else
1418 {
1419 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1420 if ((entry & 1) != 0)
1421 (*relrsp)[size++] = addr;
1422 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1423 }
1424 }
1425
1426 *nrelrsp = size;
1427 free (relrs);
1428 return true;
1429}
1430
aca88567
NC
1431/* Returns the reloc type extracted from the reloc info field. */
1432
1433static unsigned int
625d49fc 1434get_reloc_type (Filedata * filedata, uint64_t reloc_info)
aca88567
NC
1435{
1436 if (is_32bit_elf)
1437 return ELF32_R_TYPE (reloc_info);
1438
dda8d76d 1439 switch (filedata->file_header.e_machine)
aca88567
NC
1440 {
1441 case EM_MIPS:
1442 /* Note: We assume that reloc_info has already been adjusted for us. */
1443 return ELF64_MIPS_R_TYPE (reloc_info);
1444
1445 case EM_SPARCV9:
1446 return ELF64_R_TYPE_ID (reloc_info);
1447
1448 default:
1449 return ELF64_R_TYPE (reloc_info);
1450 }
1451}
1452
1453/* Return the symbol index extracted from the reloc info field. */
1454
625d49fc
AM
1455static uint64_t
1456get_reloc_symindex (uint64_t reloc_info)
aca88567
NC
1457{
1458 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1459}
1460
015dc7e1 1461static inline bool
dda8d76d 1462uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1463{
1464 return
dda8d76d 1465 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1466 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1467 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1468 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1469 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1470}
1471
d3ba0551
AM
1472/* Display the contents of the relocation data found at the specified
1473 offset. */
ee42cf8c 1474
015dc7e1 1475static bool
26c527e6
AM
1476dump_relocations (Filedata *filedata,
1477 uint64_t rel_offset,
1478 uint64_t rel_size,
1479 Elf_Internal_Sym *symtab,
1480 uint64_t nsyms,
1481 char *strtab,
1482 uint64_t strtablen,
1483 relocation_type rel_type,
1484 bool is_dynsym)
1485{
1486 size_t i;
2cf0635d 1487 Elf_Internal_Rela * rels;
015dc7e1 1488 bool res = true;
103f02d3 1489
a7fd1186
FS
1490 if (rel_type == reltype_unknown)
1491 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1492
a7fd1186 1493 if (rel_type == reltype_rela)
4d6ed7c8 1494 {
dda8d76d 1495 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1496 return false;
4d6ed7c8 1497 }
a7fd1186 1498 else if (rel_type == reltype_rel)
4d6ed7c8 1499 {
dda8d76d 1500 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1501 return false;
252b5132 1502 }
a7fd1186
FS
1503 else if (rel_type == reltype_relr)
1504 {
625d49fc 1505 uint64_t * relrs;
a7fd1186 1506 const char *format
b8281767 1507 = is_32bit_elf ? "%08" PRIx64 "\n" : "%016" PRIx64 "\n";
a7fd1186
FS
1508
1509 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1510 &rel_size))
1511 return false;
1512
26c527e6
AM
1513 printf (ngettext (" %" PRIu64 " offset\n",
1514 " %" PRIu64 " offsets\n", rel_size),
b8281767 1515 rel_size);
a7fd1186 1516 for (i = 0; i < rel_size; i++)
625d49fc 1517 printf (format, relrs[i]);
a7fd1186
FS
1518 free (relrs);
1519 return true;
1520 }
252b5132 1521
410f7a12
L
1522 if (is_32bit_elf)
1523 {
a7fd1186 1524 if (rel_type == reltype_rela)
2c71103e
NC
1525 {
1526 if (do_wide)
1527 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1528 else
1529 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1530 }
410f7a12 1531 else
2c71103e
NC
1532 {
1533 if (do_wide)
1534 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1535 else
1536 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1537 }
410f7a12 1538 }
252b5132 1539 else
410f7a12 1540 {
a7fd1186 1541 if (rel_type == reltype_rela)
2c71103e
NC
1542 {
1543 if (do_wide)
8beeaeb7 1544 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1545 else
1546 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1547 }
410f7a12 1548 else
2c71103e
NC
1549 {
1550 if (do_wide)
8beeaeb7 1551 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1552 else
1553 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1554 }
410f7a12 1555 }
252b5132
RH
1556
1557 for (i = 0; i < rel_size; i++)
1558 {
2cf0635d 1559 const char * rtype;
625d49fc
AM
1560 uint64_t offset;
1561 uint64_t inf;
1562 uint64_t symtab_index;
1563 uint64_t type;
103f02d3 1564
b34976b6 1565 offset = rels[i].r_offset;
91d6fa6a 1566 inf = rels[i].r_info;
103f02d3 1567
dda8d76d 1568 type = get_reloc_type (filedata, inf);
91d6fa6a 1569 symtab_index = get_reloc_symindex (inf);
252b5132 1570
410f7a12
L
1571 if (is_32bit_elf)
1572 {
39dbeff8
AM
1573 printf ("%8.8lx %8.8lx ",
1574 (unsigned long) offset & 0xffffffff,
91d6fa6a 1575 (unsigned long) inf & 0xffffffff);
410f7a12
L
1576 }
1577 else
1578 {
39dbeff8 1579 printf (do_wide
b8281767
AM
1580 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
1581 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
625d49fc 1582 offset, inf);
410f7a12 1583 }
103f02d3 1584
dda8d76d 1585 switch (filedata->file_header.e_machine)
252b5132
RH
1586 {
1587 default:
1588 rtype = NULL;
1589 break;
1590
a06ea964
NC
1591 case EM_AARCH64:
1592 rtype = elf_aarch64_reloc_type (type);
1593 break;
1594
2b0337b0 1595 case EM_M32R:
252b5132 1596 case EM_CYGNUS_M32R:
9ea033b2 1597 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1598 break;
1599
1600 case EM_386:
22abe556 1601 case EM_IAMCU:
9ea033b2 1602 rtype = elf_i386_reloc_type (type);
252b5132
RH
1603 break;
1604
ba2685cc
AM
1605 case EM_68HC11:
1606 case EM_68HC12:
1607 rtype = elf_m68hc11_reloc_type (type);
1608 break;
75751cd9 1609
7b4ae824
JD
1610 case EM_S12Z:
1611 rtype = elf_s12z_reloc_type (type);
1612 break;
1613
252b5132 1614 case EM_68K:
9ea033b2 1615 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1616 break;
1617
f954747f
AM
1618 case EM_960:
1619 rtype = elf_i960_reloc_type (type);
1620 break;
1621
adde6300 1622 case EM_AVR:
2b0337b0 1623 case EM_AVR_OLD:
adde6300
AM
1624 rtype = elf_avr_reloc_type (type);
1625 break;
1626
9ea033b2
NC
1627 case EM_OLD_SPARCV9:
1628 case EM_SPARC32PLUS:
1629 case EM_SPARCV9:
252b5132 1630 case EM_SPARC:
9ea033b2 1631 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1632 break;
1633
e9f53129
AM
1634 case EM_SPU:
1635 rtype = elf_spu_reloc_type (type);
1636 break;
1637
708e2187
NC
1638 case EM_V800:
1639 rtype = v800_reloc_type (type);
1640 break;
2b0337b0 1641 case EM_V850:
252b5132 1642 case EM_CYGNUS_V850:
9ea033b2 1643 rtype = v850_reloc_type (type);
252b5132
RH
1644 break;
1645
2b0337b0 1646 case EM_D10V:
252b5132 1647 case EM_CYGNUS_D10V:
9ea033b2 1648 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1649 break;
1650
2b0337b0 1651 case EM_D30V:
252b5132 1652 case EM_CYGNUS_D30V:
9ea033b2 1653 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1654 break;
1655
d172d4ba
NC
1656 case EM_DLX:
1657 rtype = elf_dlx_reloc_type (type);
1658 break;
1659
252b5132 1660 case EM_SH:
9ea033b2 1661 rtype = elf_sh_reloc_type (type);
252b5132
RH
1662 break;
1663
2b0337b0 1664 case EM_MN10300:
252b5132 1665 case EM_CYGNUS_MN10300:
9ea033b2 1666 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1667 break;
1668
2b0337b0 1669 case EM_MN10200:
252b5132 1670 case EM_CYGNUS_MN10200:
9ea033b2 1671 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1672 break;
1673
2b0337b0 1674 case EM_FR30:
252b5132 1675 case EM_CYGNUS_FR30:
9ea033b2 1676 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1677 break;
1678
ba2685cc
AM
1679 case EM_CYGNUS_FRV:
1680 rtype = elf_frv_reloc_type (type);
1681 break;
5c70f934 1682
b8891f8d
AJ
1683 case EM_CSKY:
1684 rtype = elf_csky_reloc_type (type);
1685 break;
1686
3f8107ab
AM
1687 case EM_FT32:
1688 rtype = elf_ft32_reloc_type (type);
1689 break;
1690
252b5132 1691 case EM_MCORE:
9ea033b2 1692 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1693 break;
1694
3c3bdf30
NC
1695 case EM_MMIX:
1696 rtype = elf_mmix_reloc_type (type);
1697 break;
1698
5506d11a
AM
1699 case EM_MOXIE:
1700 rtype = elf_moxie_reloc_type (type);
1701 break;
1702
2469cfa2 1703 case EM_MSP430:
dda8d76d 1704 if (uses_msp430x_relocs (filedata))
13761a11
NC
1705 {
1706 rtype = elf_msp430x_reloc_type (type);
1707 break;
1708 }
1a0670f3 1709 /* Fall through. */
2469cfa2
NC
1710 case EM_MSP430_OLD:
1711 rtype = elf_msp430_reloc_type (type);
1712 break;
1713
35c08157
KLC
1714 case EM_NDS32:
1715 rtype = elf_nds32_reloc_type (type);
1716 break;
1717
252b5132 1718 case EM_PPC:
9ea033b2 1719 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1720 break;
1721
c833c019
AM
1722 case EM_PPC64:
1723 rtype = elf_ppc64_reloc_type (type);
1724 break;
1725
252b5132 1726 case EM_MIPS:
4fe85591 1727 case EM_MIPS_RS3_LE:
9ea033b2 1728 rtype = elf_mips_reloc_type (type);
252b5132
RH
1729 break;
1730
e23eba97
NC
1731 case EM_RISCV:
1732 rtype = elf_riscv_reloc_type (type);
1733 break;
1734
252b5132 1735 case EM_ALPHA:
9ea033b2 1736 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1737 break;
1738
1739 case EM_ARM:
9ea033b2 1740 rtype = elf_arm_reloc_type (type);
252b5132
RH
1741 break;
1742
584da044 1743 case EM_ARC:
886a2506
NC
1744 case EM_ARC_COMPACT:
1745 case EM_ARC_COMPACT2:
b5c37946
SJ
1746 case EM_ARC_COMPACT3:
1747 case EM_ARC_COMPACT3_64:
9ea033b2 1748 rtype = elf_arc_reloc_type (type);
252b5132
RH
1749 break;
1750
1751 case EM_PARISC:
69e617ca 1752 rtype = elf_hppa_reloc_type (type);
252b5132 1753 break;
7d466069 1754
b8720f9d
JL
1755 case EM_H8_300:
1756 case EM_H8_300H:
1757 case EM_H8S:
1758 rtype = elf_h8_reloc_type (type);
1759 break;
1760
73589c9d
CS
1761 case EM_OR1K:
1762 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1763 break;
1764
7d466069 1765 case EM_PJ:
2b0337b0 1766 case EM_PJ_OLD:
7d466069
ILT
1767 rtype = elf_pj_reloc_type (type);
1768 break;
800eeca4
JW
1769 case EM_IA_64:
1770 rtype = elf_ia64_reloc_type (type);
1771 break;
1b61cf92 1772
6e712424
PI
1773 case EM_KVX:
1774 rtype = elf_kvx_reloc_type (type);
1775 break;
1776
1b61cf92
HPN
1777 case EM_CRIS:
1778 rtype = elf_cris_reloc_type (type);
1779 break;
535c37ff 1780
f954747f
AM
1781 case EM_860:
1782 rtype = elf_i860_reloc_type (type);
1783 break;
1784
bcedfee6 1785 case EM_X86_64:
8a9036a4 1786 case EM_L1OM:
7a9068fe 1787 case EM_K1OM:
bcedfee6
NC
1788 rtype = elf_x86_64_reloc_type (type);
1789 break;
a85d7ed0 1790
f954747f
AM
1791 case EM_S370:
1792 rtype = i370_reloc_type (type);
1793 break;
1794
53c7db4b
KH
1795 case EM_S390_OLD:
1796 case EM_S390:
1797 rtype = elf_s390_reloc_type (type);
1798 break;
93fbbb04 1799
1c0d3aa6
NC
1800 case EM_SCORE:
1801 rtype = elf_score_reloc_type (type);
1802 break;
1803
93fbbb04
GK
1804 case EM_XSTORMY16:
1805 rtype = elf_xstormy16_reloc_type (type);
1806 break;
179d3252 1807
1fe1f39c
NC
1808 case EM_CRX:
1809 rtype = elf_crx_reloc_type (type);
1810 break;
1811
179d3252
JT
1812 case EM_VAX:
1813 rtype = elf_vax_reloc_type (type);
1814 break;
1e4cf259 1815
619ed720
EB
1816 case EM_VISIUM:
1817 rtype = elf_visium_reloc_type (type);
1818 break;
1819
aca4efc7
JM
1820 case EM_BPF:
1821 rtype = elf_bpf_reloc_type (type);
1822 break;
1823
cfb8c092
NC
1824 case EM_ADAPTEVA_EPIPHANY:
1825 rtype = elf_epiphany_reloc_type (type);
1826 break;
1827
1e4cf259
NC
1828 case EM_IP2K:
1829 case EM_IP2K_OLD:
1830 rtype = elf_ip2k_reloc_type (type);
1831 break;
3b36097d
SC
1832
1833 case EM_IQ2000:
1834 rtype = elf_iq2000_reloc_type (type);
1835 break;
88da6820
NC
1836
1837 case EM_XTENSA_OLD:
1838 case EM_XTENSA:
1839 rtype = elf_xtensa_reloc_type (type);
1840 break;
a34e3ecb 1841
84e94c90
NC
1842 case EM_LATTICEMICO32:
1843 rtype = elf_lm32_reloc_type (type);
1844 break;
1845
ff7eeb89 1846 case EM_M32C_OLD:
49f58d10
JB
1847 case EM_M32C:
1848 rtype = elf_m32c_reloc_type (type);
1849 break;
1850
d031aafb
NS
1851 case EM_MT:
1852 rtype = elf_mt_reloc_type (type);
a34e3ecb 1853 break;
1d65ded4
CM
1854
1855 case EM_BLACKFIN:
1856 rtype = elf_bfin_reloc_type (type);
1857 break;
15ab5209
DB
1858
1859 case EM_CYGNUS_MEP:
1860 rtype = elf_mep_reloc_type (type);
1861 break;
60bca95a
NC
1862
1863 case EM_CR16:
1864 rtype = elf_cr16_reloc_type (type);
1865 break;
dd24e3da 1866
7ba29e2a
NC
1867 case EM_MICROBLAZE:
1868 case EM_MICROBLAZE_OLD:
1869 rtype = elf_microblaze_reloc_type (type);
1870 break;
c7927a3c 1871
99c513f6
DD
1872 case EM_RL78:
1873 rtype = elf_rl78_reloc_type (type);
1874 break;
1875
c7927a3c
NC
1876 case EM_RX:
1877 rtype = elf_rx_reloc_type (type);
1878 break;
c29aca4a 1879
a3c62988
NC
1880 case EM_METAG:
1881 rtype = elf_metag_reloc_type (type);
1882 break;
1883
40b36596
JM
1884 case EM_TI_C6000:
1885 rtype = elf_tic6x_reloc_type (type);
1886 break;
aa137e4d
NC
1887
1888 case EM_TILEGX:
1889 rtype = elf_tilegx_reloc_type (type);
1890 break;
1891
1892 case EM_TILEPRO:
1893 rtype = elf_tilepro_reloc_type (type);
1894 break;
f6c1a2d5 1895
f96bd6c2
PC
1896 case EM_WEBASSEMBLY:
1897 rtype = elf_wasm32_reloc_type (type);
1898 break;
1899
f6c1a2d5
NC
1900 case EM_XGATE:
1901 rtype = elf_xgate_reloc_type (type);
1902 break;
36591ba1
SL
1903
1904 case EM_ALTERA_NIOS2:
1905 rtype = elf_nios2_reloc_type (type);
1906 break;
2b100bb5
DD
1907
1908 case EM_TI_PRU:
1909 rtype = elf_pru_reloc_type (type);
1910 break;
fe944acf
FT
1911
1912 case EM_NFP:
1913 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1914 rtype = elf_nfp3200_reloc_type (type);
1915 else
1916 rtype = elf_nfp_reloc_type (type);
1917 break;
6655dba2
SB
1918
1919 case EM_Z80:
1920 rtype = elf_z80_reloc_type (type);
1921 break;
e9a0721f 1922
1923 case EM_LOONGARCH:
1924 rtype = elf_loongarch_reloc_type (type);
1925 break;
1926
0c857ef4
SM
1927 case EM_AMDGPU:
1928 rtype = elf_amdgpu_reloc_type (type);
1929 break;
252b5132
RH
1930 }
1931
1932 if (rtype == NULL)
39dbeff8 1933 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1934 else
5c144731 1935 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1936
dda8d76d 1937 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1938 && rtype != NULL
7ace3541 1939 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 1940 && rel_type == reltype_rela)
7ace3541
RH
1941 {
1942 switch (rels[i].r_addend)
1943 {
1944 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1945 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1946 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1947 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1948 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1949 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1950 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1951 default: rtype = NULL;
1952 }
32ec8896 1953
7ace3541
RH
1954 if (rtype)
1955 printf (" (%s)", rtype);
1956 else
1957 {
1958 putchar (' ');
26c527e6
AM
1959 printf (_("<unknown addend: %" PRIx64 ">"),
1960 rels[i].r_addend);
015dc7e1 1961 res = false;
7ace3541
RH
1962 }
1963 }
1964 else if (symtab_index)
252b5132 1965 {
af3fc3bc 1966 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1967 {
27a45f42
AS
1968 error (_(" bad symbol index: %08lx in reloc\n"),
1969 (unsigned long) symtab_index);
015dc7e1 1970 res = false;
32ec8896 1971 }
af3fc3bc 1972 else
19936277 1973 {
2cf0635d 1974 Elf_Internal_Sym * psym;
bb4d2ac2
L
1975 const char * version_string;
1976 enum versioned_symbol_info sym_info;
1977 unsigned short vna_other;
19936277 1978
af3fc3bc 1979 psym = symtab + symtab_index;
103f02d3 1980
bb4d2ac2 1981 version_string
dda8d76d 1982 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1983 strtab, strtablen,
1984 symtab_index,
1985 psym,
1986 &sym_info,
1987 &vna_other);
1988
af3fc3bc 1989 printf (" ");
171191ba 1990
d8045f23
NC
1991 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1992 {
1993 const char * name;
1994 unsigned int len;
1995 unsigned int width = is_32bit_elf ? 8 : 14;
1996
1997 /* Relocations against GNU_IFUNC symbols do not use the value
1998 of the symbol as the address to relocate against. Instead
1999 they invoke the function named by the symbol and use its
2000 result as the address for relocation.
2001
2002 To indicate this to the user, do not display the value of
2003 the symbol in the "Symbols's Value" field. Instead show
2004 its name followed by () as a hint that the symbol is
2005 invoked. */
2006
2007 if (strtab == NULL
2008 || psym->st_name == 0
2009 || psym->st_name >= strtablen)
2010 name = "??";
2011 else
2012 name = strtab + psym->st_name;
2013
2014 len = print_symbol (width, name);
bb4d2ac2
L
2015 if (version_string)
2016 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2017 version_string);
d8045f23
NC
2018 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2019 }
2020 else
2021 {
2022 print_vma (psym->st_value, LONG_HEX);
171191ba 2023
d8045f23
NC
2024 printf (is_32bit_elf ? " " : " ");
2025 }
103f02d3 2026
af3fc3bc 2027 if (psym->st_name == 0)
f1ef08cb 2028 {
2cf0635d 2029 const char * sec_name = "<null>";
f1ef08cb
AM
2030 char name_buf[40];
2031
2032 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
2033 {
b9af6379
AM
2034 if (psym->st_shndx < filedata->file_header.e_shnum
2035 && filedata->section_headers != NULL)
84714f86
AM
2036 sec_name = section_name_print (filedata,
2037 filedata->section_headers
b9e920ec 2038 + psym->st_shndx);
f1ef08cb
AM
2039 else if (psym->st_shndx == SHN_ABS)
2040 sec_name = "ABS";
2041 else if (psym->st_shndx == SHN_COMMON)
2042 sec_name = "COMMON";
dda8d76d 2043 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 2044 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 2045 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 2046 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 2047 sec_name = "SCOMMON";
dda8d76d 2048 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
2049 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
2050 sec_name = "SUNDEF";
dda8d76d
NC
2051 else if ((filedata->file_header.e_machine == EM_X86_64
2052 || filedata->file_header.e_machine == EM_L1OM
2053 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
2054 && psym->st_shndx == SHN_X86_64_LCOMMON)
2055 sec_name = "LARGE_COMMON";
dda8d76d
NC
2056 else if (filedata->file_header.e_machine == EM_IA_64
2057 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
2058 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
2059 sec_name = "ANSI_COM";
dda8d76d 2060 else if (is_ia64_vms (filedata)
148b93f2
NC
2061 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
2062 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
2063 else
2064 {
2065 sprintf (name_buf, "<section 0x%x>",
2066 (unsigned int) psym->st_shndx);
2067 sec_name = name_buf;
2068 }
2069 }
2070 print_symbol (22, sec_name);
2071 }
af3fc3bc 2072 else if (strtab == NULL)
d79b3d50 2073 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2074 else if (psym->st_name >= strtablen)
32ec8896 2075 {
27a45f42
AS
2076 error (_("<corrupt string table index: %3ld>\n"),
2077 psym->st_name);
015dc7e1 2078 res = false;
32ec8896 2079 }
af3fc3bc 2080 else
bb4d2ac2
L
2081 {
2082 print_symbol (22, strtab + psym->st_name);
2083 if (version_string)
2084 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2085 version_string);
2086 }
103f02d3 2087
a7fd1186 2088 if (rel_type == reltype_rela)
171191ba 2089 {
625d49fc 2090 uint64_t off = rels[i].r_addend;
171191ba 2091
625d49fc
AM
2092 if ((int64_t) off < 0)
2093 printf (" - %" PRIx64, -off);
171191ba 2094 else
625d49fc 2095 printf (" + %" PRIx64, off);
171191ba 2096 }
19936277 2097 }
252b5132 2098 }
a7fd1186 2099 else if (rel_type == reltype_rela)
f7a99963 2100 {
625d49fc 2101 uint64_t off = rels[i].r_addend;
e04d7088
L
2102
2103 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
625d49fc
AM
2104 if ((int64_t) off < 0)
2105 printf ("-%" PRIx64, -off);
e04d7088 2106 else
625d49fc 2107 printf ("%" PRIx64, off);
f7a99963 2108 }
252b5132 2109
dda8d76d 2110 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2111 && rtype != NULL
2112 && streq (rtype, "R_SPARC_OLO10"))
26c527e6 2113 printf (" + %" PRIx64, ELF64_R_TYPE_DATA (inf));
351b4b40 2114
252b5132 2115 putchar ('\n');
2c71103e 2116
dda8d76d 2117 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2118 {
625d49fc
AM
2119 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2120 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2121 const char * rtype2 = elf_mips_reloc_type (type2);
2122 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2123
2c71103e
NC
2124 printf (" Type2: ");
2125
2126 if (rtype2 == NULL)
39dbeff8
AM
2127 printf (_("unrecognized: %-7lx"),
2128 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2129 else
2130 printf ("%-17.17s", rtype2);
2131
18bd398b 2132 printf ("\n Type3: ");
2c71103e
NC
2133
2134 if (rtype3 == NULL)
39dbeff8
AM
2135 printf (_("unrecognized: %-7lx"),
2136 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2137 else
2138 printf ("%-17.17s", rtype3);
2139
53c7db4b 2140 putchar ('\n');
2c71103e 2141 }
252b5132
RH
2142 }
2143
c8286bd1 2144 free (rels);
32ec8896
NC
2145
2146 return res;
252b5132
RH
2147}
2148
37c18eed
SD
2149static const char *
2150get_aarch64_dynamic_type (unsigned long type)
2151{
2152 switch (type)
2153 {
2154 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2155 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2156 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2157 default:
2158 return NULL;
2159 }
2160}
2161
252b5132 2162static const char *
d3ba0551 2163get_mips_dynamic_type (unsigned long type)
252b5132
RH
2164{
2165 switch (type)
2166 {
2167 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2168 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2169 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2170 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2171 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2172 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2173 case DT_MIPS_MSYM: return "MIPS_MSYM";
2174 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2175 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2176 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2177 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2178 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2179 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2180 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2181 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2182 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2183 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2184 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2185 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2186 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2187 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2188 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2189 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2190 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2191 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2192 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2193 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2194 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2195 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2196 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2197 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2198 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2199 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2200 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2201 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2202 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2203 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2204 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2205 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2206 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2207 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2208 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2209 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2210 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2211 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2212 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2213 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2214 default:
2215 return NULL;
2216 }
2217}
2218
9a097730 2219static const char *
d3ba0551 2220get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2221{
2222 switch (type)
2223 {
2224 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2225 default:
2226 return NULL;
2227 }
103f02d3
UD
2228}
2229
7490d522
AM
2230static const char *
2231get_ppc_dynamic_type (unsigned long type)
2232{
2233 switch (type)
2234 {
a7f2871e 2235 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2236 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2237 default:
2238 return NULL;
2239 }
2240}
2241
f1cb7e17 2242static const char *
d3ba0551 2243get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2244{
2245 switch (type)
2246 {
a7f2871e
AM
2247 case DT_PPC64_GLINK: return "PPC64_GLINK";
2248 case DT_PPC64_OPD: return "PPC64_OPD";
2249 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2250 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2251 default:
2252 return NULL;
2253 }
2254}
2255
103f02d3 2256static const char *
d3ba0551 2257get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2258{
2259 switch (type)
2260 {
2261 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2262 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2263 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2264 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2265 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2266 case DT_HP_PREINIT: return "HP_PREINIT";
2267 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2268 case DT_HP_NEEDED: return "HP_NEEDED";
2269 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2270 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2271 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2272 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2273 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2274 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2275 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2276 case DT_HP_FILTERED: return "HP_FILTERED";
2277 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2278 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2279 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2280 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2281 case DT_PLT: return "PLT";
2282 case DT_PLT_SIZE: return "PLT_SIZE";
2283 case DT_DLT: return "DLT";
2284 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2285 default:
2286 return NULL;
2287 }
2288}
9a097730 2289
ecc51f48 2290static const char *
d3ba0551 2291get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2292{
2293 switch (type)
2294 {
148b93f2
NC
2295 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2296 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2297 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2298 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2299 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2300 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2301 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2302 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2303 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2304 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2305 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2306 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2307 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2308 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2309 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2310 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2311 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2312 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2313 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2314 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2315 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2316 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2317 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2318 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2319 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2320 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2321 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2322 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2323 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2324 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2325 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2326 default:
2327 return NULL;
2328 }
2329}
2330
fd85a6a1
NC
2331static const char *
2332get_solaris_section_type (unsigned long type)
2333{
2334 switch (type)
2335 {
2336 case 0x6fffffee: return "SUNW_ancillary";
2337 case 0x6fffffef: return "SUNW_capchain";
2338 case 0x6ffffff0: return "SUNW_capinfo";
2339 case 0x6ffffff1: return "SUNW_symsort";
2340 case 0x6ffffff2: return "SUNW_tlssort";
2341 case 0x6ffffff3: return "SUNW_LDYNSYM";
2342 case 0x6ffffff4: return "SUNW_dof";
2343 case 0x6ffffff5: return "SUNW_cap";
2344 case 0x6ffffff6: return "SUNW_SIGNATURE";
2345 case 0x6ffffff7: return "SUNW_ANNOTATE";
2346 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2347 case 0x6ffffff9: return "SUNW_DEBUG";
2348 case 0x6ffffffa: return "SUNW_move";
2349 case 0x6ffffffb: return "SUNW_COMDAT";
2350 case 0x6ffffffc: return "SUNW_syminfo";
2351 case 0x6ffffffd: return "SUNW_verdef";
2352 case 0x6ffffffe: return "SUNW_verneed";
2353 case 0x6fffffff: return "SUNW_versym";
2354 case 0x70000000: return "SPARC_GOTDATA";
2355 default: return NULL;
2356 }
2357}
2358
fabcb361
RH
2359static const char *
2360get_alpha_dynamic_type (unsigned long type)
2361{
2362 switch (type)
2363 {
2364 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2365 default: return NULL;
fabcb361
RH
2366 }
2367}
2368
1c0d3aa6
NC
2369static const char *
2370get_score_dynamic_type (unsigned long type)
2371{
2372 switch (type)
2373 {
2374 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2375 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2376 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2377 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2378 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2379 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2380 default: return NULL;
1c0d3aa6
NC
2381 }
2382}
2383
40b36596
JM
2384static const char *
2385get_tic6x_dynamic_type (unsigned long type)
2386{
2387 switch (type)
2388 {
2389 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2390 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2391 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2392 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2393 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2394 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2395 default: return NULL;
40b36596
JM
2396 }
2397}
1c0d3aa6 2398
36591ba1
SL
2399static const char *
2400get_nios2_dynamic_type (unsigned long type)
2401{
2402 switch (type)
2403 {
2404 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2405 default: return NULL;
36591ba1
SL
2406 }
2407}
2408
fd85a6a1
NC
2409static const char *
2410get_solaris_dynamic_type (unsigned long type)
2411{
2412 switch (type)
2413 {
2414 case 0x6000000d: return "SUNW_AUXILIARY";
2415 case 0x6000000e: return "SUNW_RTLDINF";
2416 case 0x6000000f: return "SUNW_FILTER";
2417 case 0x60000010: return "SUNW_CAP";
2418 case 0x60000011: return "SUNW_SYMTAB";
2419 case 0x60000012: return "SUNW_SYMSZ";
2420 case 0x60000013: return "SUNW_SORTENT";
2421 case 0x60000014: return "SUNW_SYMSORT";
2422 case 0x60000015: return "SUNW_SYMSORTSZ";
2423 case 0x60000016: return "SUNW_TLSSORT";
2424 case 0x60000017: return "SUNW_TLSSORTSZ";
2425 case 0x60000018: return "SUNW_CAPINFO";
2426 case 0x60000019: return "SUNW_STRPAD";
2427 case 0x6000001a: return "SUNW_CAPCHAIN";
2428 case 0x6000001b: return "SUNW_LDMACH";
2429 case 0x6000001d: return "SUNW_CAPCHAINENT";
2430 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2431 case 0x60000021: return "SUNW_PARENT";
2432 case 0x60000023: return "SUNW_ASLR";
2433 case 0x60000025: return "SUNW_RELAX";
2434 case 0x60000029: return "SUNW_NXHEAP";
2435 case 0x6000002b: return "SUNW_NXSTACK";
2436
2437 case 0x70000001: return "SPARC_REGISTER";
2438 case 0x7ffffffd: return "AUXILIARY";
2439 case 0x7ffffffe: return "USED";
2440 case 0x7fffffff: return "FILTER";
2441
15f205b1 2442 default: return NULL;
fd85a6a1
NC
2443 }
2444}
2445
8155b853
NC
2446static const char *
2447get_riscv_dynamic_type (unsigned long type)
2448{
2449 switch (type)
2450 {
2451 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2452 default:
2453 return NULL;
2454 }
2455}
2456
252b5132 2457static const char *
dda8d76d 2458get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2459{
e9e44622 2460 static char buff[64];
252b5132
RH
2461
2462 switch (type)
2463 {
2464 case DT_NULL: return "NULL";
2465 case DT_NEEDED: return "NEEDED";
2466 case DT_PLTRELSZ: return "PLTRELSZ";
2467 case DT_PLTGOT: return "PLTGOT";
2468 case DT_HASH: return "HASH";
2469 case DT_STRTAB: return "STRTAB";
2470 case DT_SYMTAB: return "SYMTAB";
2471 case DT_RELA: return "RELA";
2472 case DT_RELASZ: return "RELASZ";
2473 case DT_RELAENT: return "RELAENT";
2474 case DT_STRSZ: return "STRSZ";
2475 case DT_SYMENT: return "SYMENT";
2476 case DT_INIT: return "INIT";
2477 case DT_FINI: return "FINI";
2478 case DT_SONAME: return "SONAME";
2479 case DT_RPATH: return "RPATH";
2480 case DT_SYMBOLIC: return "SYMBOLIC";
2481 case DT_REL: return "REL";
2482 case DT_RELSZ: return "RELSZ";
2483 case DT_RELENT: return "RELENT";
dd207c13
FS
2484 case DT_RELR: return "RELR";
2485 case DT_RELRSZ: return "RELRSZ";
2486 case DT_RELRENT: return "RELRENT";
252b5132
RH
2487 case DT_PLTREL: return "PLTREL";
2488 case DT_DEBUG: return "DEBUG";
2489 case DT_TEXTREL: return "TEXTREL";
2490 case DT_JMPREL: return "JMPREL";
2491 case DT_BIND_NOW: return "BIND_NOW";
2492 case DT_INIT_ARRAY: return "INIT_ARRAY";
2493 case DT_FINI_ARRAY: return "FINI_ARRAY";
2494 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2495 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2496 case DT_RUNPATH: return "RUNPATH";
2497 case DT_FLAGS: return "FLAGS";
2d0e6f43 2498
d1133906
NC
2499 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2500 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2501 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2502
05107a46 2503 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2504 case DT_PLTPADSZ: return "PLTPADSZ";
2505 case DT_MOVEENT: return "MOVEENT";
2506 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2507 case DT_FEATURE: return "FEATURE";
252b5132
RH
2508 case DT_POSFLAG_1: return "POSFLAG_1";
2509 case DT_SYMINSZ: return "SYMINSZ";
2510 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2511
252b5132 2512 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2513 case DT_CONFIG: return "CONFIG";
2514 case DT_DEPAUDIT: return "DEPAUDIT";
2515 case DT_AUDIT: return "AUDIT";
2516 case DT_PLTPAD: return "PLTPAD";
2517 case DT_MOVETAB: return "MOVETAB";
252b5132 2518 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2519
252b5132 2520 case DT_VERSYM: return "VERSYM";
103f02d3 2521
67a4f2b7
AO
2522 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2523 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2524 case DT_RELACOUNT: return "RELACOUNT";
2525 case DT_RELCOUNT: return "RELCOUNT";
2526 case DT_FLAGS_1: return "FLAGS_1";
2527 case DT_VERDEF: return "VERDEF";
2528 case DT_VERDEFNUM: return "VERDEFNUM";
2529 case DT_VERNEED: return "VERNEED";
2530 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2531
019148e4 2532 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2533 case DT_USED: return "USED";
2534 case DT_FILTER: return "FILTER";
103f02d3 2535
047b2264
JJ
2536 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2537 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2538 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2539 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2540 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2541 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2542 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2543
252b5132
RH
2544 default:
2545 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2546 {
2cf0635d 2547 const char * result;
103f02d3 2548
dda8d76d 2549 switch (filedata->file_header.e_machine)
252b5132 2550 {
37c18eed
SD
2551 case EM_AARCH64:
2552 result = get_aarch64_dynamic_type (type);
2553 break;
252b5132 2554 case EM_MIPS:
4fe85591 2555 case EM_MIPS_RS3_LE:
252b5132
RH
2556 result = get_mips_dynamic_type (type);
2557 break;
9a097730
RH
2558 case EM_SPARCV9:
2559 result = get_sparc64_dynamic_type (type);
2560 break;
7490d522
AM
2561 case EM_PPC:
2562 result = get_ppc_dynamic_type (type);
2563 break;
f1cb7e17
AM
2564 case EM_PPC64:
2565 result = get_ppc64_dynamic_type (type);
2566 break;
ecc51f48
NC
2567 case EM_IA_64:
2568 result = get_ia64_dynamic_type (type);
2569 break;
fabcb361
RH
2570 case EM_ALPHA:
2571 result = get_alpha_dynamic_type (type);
2572 break;
1c0d3aa6
NC
2573 case EM_SCORE:
2574 result = get_score_dynamic_type (type);
2575 break;
40b36596
JM
2576 case EM_TI_C6000:
2577 result = get_tic6x_dynamic_type (type);
2578 break;
36591ba1
SL
2579 case EM_ALTERA_NIOS2:
2580 result = get_nios2_dynamic_type (type);
2581 break;
8155b853
NC
2582 case EM_RISCV:
2583 result = get_riscv_dynamic_type (type);
2584 break;
252b5132 2585 default:
dda8d76d 2586 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2587 result = get_solaris_dynamic_type (type);
2588 else
2589 result = NULL;
252b5132
RH
2590 break;
2591 }
2592
2593 if (result != NULL)
2594 return result;
2595
e9e44622 2596 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2597 }
eec8f817 2598 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2599 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2600 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2601 {
2cf0635d 2602 const char * result;
103f02d3 2603
dda8d76d 2604 switch (filedata->file_header.e_machine)
103f02d3
UD
2605 {
2606 case EM_PARISC:
2607 result = get_parisc_dynamic_type (type);
2608 break;
148b93f2
NC
2609 case EM_IA_64:
2610 result = get_ia64_dynamic_type (type);
2611 break;
103f02d3 2612 default:
dda8d76d 2613 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2614 result = get_solaris_dynamic_type (type);
2615 else
2616 result = NULL;
103f02d3
UD
2617 break;
2618 }
2619
2620 if (result != NULL)
2621 return result;
2622
e9e44622
JJ
2623 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2624 type);
103f02d3 2625 }
252b5132 2626 else
e9e44622 2627 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2628
252b5132
RH
2629 return buff;
2630 }
2631}
2632
93df3340
AM
2633static bool get_program_headers (Filedata *);
2634static bool get_dynamic_section (Filedata *);
2635
2636static void
2637locate_dynamic_section (Filedata *filedata)
2638{
26c527e6 2639 uint64_t dynamic_addr = 0;
be7d229a 2640 uint64_t dynamic_size = 0;
93df3340
AM
2641
2642 if (filedata->file_header.e_phnum != 0
2643 && get_program_headers (filedata))
2644 {
2645 Elf_Internal_Phdr *segment;
2646 unsigned int i;
2647
2648 for (i = 0, segment = filedata->program_headers;
2649 i < filedata->file_header.e_phnum;
2650 i++, segment++)
2651 {
2652 if (segment->p_type == PT_DYNAMIC)
2653 {
2654 dynamic_addr = segment->p_offset;
2655 dynamic_size = segment->p_filesz;
2656
2657 if (filedata->section_headers != NULL)
2658 {
2659 Elf_Internal_Shdr *sec;
2660
2661 sec = find_section (filedata, ".dynamic");
2662 if (sec != NULL)
2663 {
2664 if (sec->sh_size == 0
2665 || sec->sh_type == SHT_NOBITS)
2666 {
2667 dynamic_addr = 0;
2668 dynamic_size = 0;
2669 }
2670 else
2671 {
2672 dynamic_addr = sec->sh_offset;
2673 dynamic_size = sec->sh_size;
2674 }
2675 }
2676 }
2677
2678 if (dynamic_addr > filedata->file_size
2679 || (dynamic_size > filedata->file_size - dynamic_addr))
2680 {
2681 dynamic_addr = 0;
2682 dynamic_size = 0;
2683 }
2684 break;
2685 }
2686 }
2687 }
2688 filedata->dynamic_addr = dynamic_addr;
2689 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2690}
2691
2692static bool
2693is_pie (Filedata *filedata)
2694{
2695 Elf_Internal_Dyn *entry;
2696
2697 if (filedata->dynamic_size == 0)
2698 locate_dynamic_section (filedata);
2699 if (filedata->dynamic_size <= 1)
2700 return false;
2701
2702 if (!get_dynamic_section (filedata))
2703 return false;
2704
2705 for (entry = filedata->dynamic_section;
2706 entry < filedata->dynamic_section + filedata->dynamic_nent;
2707 entry++)
2708 {
2709 if (entry->d_tag == DT_FLAGS_1)
2710 {
2711 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2712 return true;
2713 break;
2714 }
2715 }
2716 return false;
2717}
2718
252b5132 2719static char *
93df3340 2720get_file_type (Filedata *filedata)
252b5132 2721{
93df3340 2722 unsigned e_type = filedata->file_header.e_type;
89246a0e 2723 static char buff[64];
252b5132
RH
2724
2725 switch (e_type)
2726 {
32ec8896
NC
2727 case ET_NONE: return _("NONE (None)");
2728 case ET_REL: return _("REL (Relocatable file)");
2729 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2730 case ET_DYN:
2731 if (is_pie (filedata))
2732 return _("DYN (Position-Independent Executable file)");
2733 else
2734 return _("DYN (Shared object file)");
32ec8896 2735 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2736
2737 default:
2738 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2739 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2740 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2741 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2742 else
e9e44622 2743 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2744 return buff;
2745 }
2746}
2747
2748static char *
d3ba0551 2749get_machine_name (unsigned e_machine)
252b5132 2750{
b34976b6 2751 static char buff[64]; /* XXX */
252b5132
RH
2752
2753 switch (e_machine)
2754 {
55e22ca8
NC
2755 /* Please keep this switch table sorted by increasing EM_ value. */
2756 /* 0 */
c45021f2
NC
2757 case EM_NONE: return _("None");
2758 case EM_M32: return "WE32100";
2759 case EM_SPARC: return "Sparc";
2760 case EM_386: return "Intel 80386";
2761 case EM_68K: return "MC68000";
2762 case EM_88K: return "MC88000";
22abe556 2763 case EM_IAMCU: return "Intel MCU";
fb70ec17 2764 case EM_860: return "Intel 80860";
c45021f2
NC
2765 case EM_MIPS: return "MIPS R3000";
2766 case EM_S370: return "IBM System/370";
55e22ca8 2767 /* 10 */
7036c0e1 2768 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2769 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2770 case EM_PARISC: return "HPPA";
55e22ca8 2771 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2772 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2773 case EM_960: return "Intel 80960";
c45021f2 2774 case EM_PPC: return "PowerPC";
55e22ca8 2775 /* 20 */
285d1771 2776 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2777 case EM_S390_OLD:
2778 case EM_S390: return "IBM S/390";
2779 case EM_SPU: return "SPU";
2780 /* 30 */
2781 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2782 case EM_FR20: return "Fujitsu FR20";
2783 case EM_RH32: return "TRW RH32";
b34976b6 2784 case EM_MCORE: return "MCORE";
55e22ca8 2785 /* 40 */
7036c0e1
AJ
2786 case EM_ARM: return "ARM";
2787 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2788 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2789 case EM_SPARCV9: return "Sparc v9";
2790 case EM_TRICORE: return "Siemens Tricore";
584da044 2791 case EM_ARC: return "ARC";
c2dcd04e
NC
2792 case EM_H8_300: return "Renesas H8/300";
2793 case EM_H8_300H: return "Renesas H8/300H";
2794 case EM_H8S: return "Renesas H8S";
2795 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2796 /* 50 */
30800947 2797 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2798 case EM_MIPS_X: return "Stanford MIPS-X";
2799 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2800 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2801 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2802 case EM_PCP: return "Siemens PCP";
2803 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2804 case EM_NDR1: return "Denso NDR1 microprocesspr";
2805 case EM_STARCORE: return "Motorola Star*Core processor";
2806 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2807 /* 60 */
7036c0e1
AJ
2808 case EM_ST100: return "STMicroelectronics ST100 processor";
2809 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2810 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2811 case EM_PDSP: return "Sony DSP processor";
2812 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2813 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2814 case EM_FX66: return "Siemens FX66 microcontroller";
2815 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2816 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2817 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2818 /* 70 */
7036c0e1
AJ
2819 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2820 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2821 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2822 case EM_SVX: return "Silicon Graphics SVx";
2823 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2824 case EM_VAX: return "Digital VAX";
1b61cf92 2825 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2826 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2827 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2828 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2829 /* 80 */
b34976b6 2830 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2831 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2832 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2833 case EM_AVR_OLD:
2834 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2835 case EM_CYGNUS_FR30:
2836 case EM_FR30: return "Fujitsu FR30";
2837 case EM_CYGNUS_D10V:
2838 case EM_D10V: return "d10v";
2839 case EM_CYGNUS_D30V:
2840 case EM_D30V: return "d30v";
2841 case EM_CYGNUS_V850:
2842 case EM_V850: return "Renesas V850";
2843 case EM_CYGNUS_M32R:
2844 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2845 case EM_CYGNUS_MN10300:
2846 case EM_MN10300: return "mn10300";
2847 /* 90 */
2848 case EM_CYGNUS_MN10200:
2849 case EM_MN10200: return "mn10200";
2850 case EM_PJ: return "picoJava";
73589c9d 2851 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2852 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2853 case EM_XTENSA_OLD:
2854 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2855 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2856 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2857 case EM_NS32K: return "National Semiconductor 32000 series";
2858 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2859 case EM_SNP1K: return "Trebia SNP 1000 processor";
2860 /* 100 */
9abca702 2861 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2862 case EM_IP2K_OLD:
2863 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2864 case EM_MAX: return "MAX Processor";
2865 case EM_CR: return "National Semiconductor CompactRISC";
2866 case EM_F2MC16: return "Fujitsu F2MC16";
2867 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2868 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2869 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2870 case EM_SEP: return "Sharp embedded microprocessor";
2871 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2872 /* 110 */
11636f9e
JM
2873 case EM_UNICORE: return "Unicore";
2874 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2875 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2876 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2877 case EM_CRX: return "National Semiconductor CRX microprocessor";
2878 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2879 case EM_C166:
d70c5fc7 2880 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2881 case EM_M16C: return "Renesas M16C series microprocessors";
2882 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2883 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2884 /* 120 */
2885 case EM_M32C: return "Renesas M32c";
2886 /* 130 */
11636f9e
JM
2887 case EM_TSK3000: return "Altium TSK3000 core";
2888 case EM_RS08: return "Freescale RS08 embedded processor";
2889 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2890 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2891 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2892 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2893 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2894 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2895 /* 140 */
11636f9e
JM
2896 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2897 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2898 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2899 case EM_TI_PRU: return "TI PRU I/O processor";
2900 /* 160 */
11636f9e
JM
2901 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2902 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2903 case EM_R32C: return "Renesas R32C series microprocessors";
2904 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2905 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2906 case EM_8051: return "Intel 8051 and variants";
2907 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2908 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2909 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2910 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2911 /* 170 */
11636f9e
JM
2912 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2913 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2914 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2915 case EM_RX: return "Renesas RX";
a3c62988 2916 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2917 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2918 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2919 case EM_CR16:
2920 case EM_MICROBLAZE:
2921 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2922 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2923 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2924 /* 180 */
2925 case EM_L1OM: return "Intel L1OM";
2926 case EM_K1OM: return "Intel K1OM";
2927 case EM_INTEL182: return "Intel (reserved)";
2928 case EM_AARCH64: return "AArch64";
2929 case EM_ARM184: return "ARM (reserved)";
2930 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2931 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2932 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2933 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2934 /* 190 */
11636f9e 2935 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2936 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2937 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2938 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2939 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2940 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2941 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2942 case EM_RL78: return "Renesas RL78";
6d913794 2943 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2944 case EM_78K0R: return "Renesas 78K0R";
2945 /* 200 */
6d913794 2946 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2947 case EM_BA1: return "Beyond BA1 CPU architecture";
2948 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2949 case EM_XCORE: return "XMOS xCORE processor family";
2950 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2951 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2952 /* 210 */
6d913794
NC
2953 case EM_KM32: return "KM211 KM32 32-bit processor";
2954 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2955 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2956 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2957 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2958 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2959 case EM_COGE: return "Cognitive Smart Memory Processor";
2960 case EM_COOL: return "Bluechip Systems CoolEngine";
2961 case EM_NORC: return "Nanoradio Optimized RISC";
2962 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2963 /* 220 */
15f205b1 2964 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2965 case EM_VISIUM: return "CDS VISIUMcore processor";
2966 case EM_FT32: return "FTDI Chip FT32";
2967 case EM_MOXIE: return "Moxie";
2968 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2969 /* 230 (all reserved) */
2970 /* 240 */
55e22ca8
NC
2971 case EM_RISCV: return "RISC-V";
2972 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2973 case EM_CEVA: return "CEVA Processor Architecture Family";
2974 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2975 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2976 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2977 case EM_IMG1: return "Imagination Technologies";
2978 /* 250 */
fe944acf 2979 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2980 case EM_VE: return "NEC Vector Engine";
2981 case EM_CSKY: return "C-SKY";
b5c37946 2982 case EM_ARC_COMPACT3_64: return "Synopsys ARCv3 64-bit processor";
4cf2ad72 2983 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
b5c37946 2984 case EM_ARC_COMPACT3: return "Synopsys ARCv3 32-bit processor";
4cf2ad72
CC
2985 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2986 case EM_65816: return "WDC 65816/65C816";
01a8c731 2987 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2988 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2989
2990 /* Large numbers... */
2991 case EM_MT: return "Morpho Techologies MT processor";
2992 case EM_ALPHA: return "Alpha";
2993 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2994 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2995 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2996 case EM_IQ2000: return "Vitesse IQ2000";
2997 case EM_M32C_OLD:
2998 case EM_NIOS32: return "Altera Nios";
2999 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
3000 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3001 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 3002 case EM_S12Z: return "Freescale S12Z";
55e22ca8 3003
252b5132 3004 default:
35d9dd2f 3005 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
3006 return buff;
3007 }
3008}
3009
f8c4789c
AM
3010static char *
3011decode_ARC_machine_flags (char *out, unsigned e_flags, unsigned e_machine)
a9522a21
AB
3012{
3013 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3014 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3015 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3016 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3017 architectures.
3018
3019 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3020 but also sets a specific architecture type in the e_flags field.
3021
3022 However, when decoding the flags we don't worry if we see an
3023 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3024 ARCEM architecture type. */
3025
3026 switch (e_flags & EF_ARC_MACH_MSK)
3027 {
3028 /* We only expect these to occur for EM_ARC_COMPACT2. */
3029 case EF_ARC_CPU_ARCV2EM:
f8c4789c 3030 out = stpcpy (out, ", ARC EM");
a9522a21
AB
3031 break;
3032 case EF_ARC_CPU_ARCV2HS:
f8c4789c 3033 out = stpcpy (out, ", ARC HS");
a9522a21
AB
3034 break;
3035
3036 /* We only expect these to occur for EM_ARC_COMPACT. */
3037 case E_ARC_MACH_ARC600:
f8c4789c 3038 out = stpcpy (out, ", ARC600");
a9522a21
AB
3039 break;
3040 case E_ARC_MACH_ARC601:
f8c4789c 3041 out = stpcpy (out, ", ARC601");
a9522a21
AB
3042 break;
3043 case E_ARC_MACH_ARC700:
f8c4789c 3044 out = stpcpy (out, ", ARC700");
a9522a21
AB
3045 break;
3046
3047 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3048 new ELF with new architecture being read by an old version of
3049 readelf, or (c) An ELF built with non-GNU compiler that does not
3050 set the architecture in the e_flags. */
3051 default:
3052 if (e_machine == EM_ARC_COMPACT)
f8c4789c 3053 out = stpcpy (out, ", Unknown ARCompact");
a9522a21 3054 else
f8c4789c 3055 out = stpcpy (out, ", Unknown ARC");
a9522a21
AB
3056 break;
3057 }
3058
3059 switch (e_flags & EF_ARC_OSABI_MSK)
3060 {
3061 case E_ARC_OSABI_ORIG:
f8c4789c 3062 out = stpcpy (out, ", (ABI:legacy)");
a9522a21
AB
3063 break;
3064 case E_ARC_OSABI_V2:
f8c4789c 3065 out = stpcpy (out, ", (ABI:v2)");
a9522a21
AB
3066 break;
3067 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3068 case E_ARC_OSABI_V3:
f8c4789c 3069 out = stpcpy (out, ", v3 no-legacy-syscalls ABI");
a9522a21 3070 break;
53a346d8 3071 case E_ARC_OSABI_V4:
f8c4789c 3072 out = stpcpy (out, ", v4 ABI");
53a346d8 3073 break;
a9522a21 3074 default:
f8c4789c 3075 out = stpcpy (out, ", unrecognised ARC OSABI flag");
a9522a21
AB
3076 break;
3077 }
f8c4789c 3078 return out;
a9522a21
AB
3079}
3080
f8c4789c
AM
3081static char *
3082decode_ARM_machine_flags (char *out, unsigned e_flags)
f3485b74
NC
3083{
3084 unsigned eabi;
015dc7e1 3085 bool unknown = false;
f3485b74
NC
3086
3087 eabi = EF_ARM_EABI_VERSION (e_flags);
3088 e_flags &= ~ EF_ARM_EABIMASK;
3089
3090 /* Handle "generic" ARM flags. */
3091 if (e_flags & EF_ARM_RELEXEC)
3092 {
f8c4789c 3093 out = stpcpy (out, ", relocatable executable");
f3485b74
NC
3094 e_flags &= ~ EF_ARM_RELEXEC;
3095 }
76da6bbe 3096
18a20338
CL
3097 if (e_flags & EF_ARM_PIC)
3098 {
f8c4789c 3099 out = stpcpy (out, ", position independent");
18a20338
CL
3100 e_flags &= ~ EF_ARM_PIC;
3101 }
3102
f3485b74
NC
3103 /* Now handle EABI specific flags. */
3104 switch (eabi)
3105 {
3106 default:
f8c4789c 3107 out = stpcpy (out, ", <unrecognized EABI>");
f3485b74 3108 if (e_flags)
015dc7e1 3109 unknown = true;
f3485b74
NC
3110 break;
3111
3112 case EF_ARM_EABI_VER1:
f8c4789c 3113 out = stpcpy (out, ", Version1 EABI");
f3485b74
NC
3114 while (e_flags)
3115 {
3116 unsigned flag;
76da6bbe 3117
f3485b74
NC
3118 /* Process flags one bit at a time. */
3119 flag = e_flags & - e_flags;
3120 e_flags &= ~ flag;
76da6bbe 3121
f3485b74
NC
3122 switch (flag)
3123 {
a5bcd848 3124 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3125 out = stpcpy (out, ", sorted symbol tables");
f3485b74 3126 break;
76da6bbe 3127
f3485b74 3128 default:
015dc7e1 3129 unknown = true;
f3485b74
NC
3130 break;
3131 }
3132 }
3133 break;
76da6bbe 3134
a5bcd848 3135 case EF_ARM_EABI_VER2:
f8c4789c 3136 out = stpcpy (out, ", Version2 EABI");
a5bcd848
PB
3137 while (e_flags)
3138 {
3139 unsigned flag;
3140
3141 /* Process flags one bit at a time. */
3142 flag = e_flags & - e_flags;
3143 e_flags &= ~ flag;
3144
3145 switch (flag)
3146 {
3147 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3148 out = stpcpy (out, ", sorted symbol tables");
a5bcd848
PB
3149 break;
3150
3151 case EF_ARM_DYNSYMSUSESEGIDX:
f8c4789c 3152 out = stpcpy (out, ", dynamic symbols use segment index");
a5bcd848
PB
3153 break;
3154
3155 case EF_ARM_MAPSYMSFIRST:
f8c4789c 3156 out = stpcpy (out, ", mapping symbols precede others");
a5bcd848
PB
3157 break;
3158
3159 default:
015dc7e1 3160 unknown = true;
a5bcd848
PB
3161 break;
3162 }
3163 }
3164 break;
3165
d507cf36 3166 case EF_ARM_EABI_VER3:
f8c4789c 3167 out = stpcpy (out, ", Version3 EABI");
8cb51566
PB
3168 break;
3169
3170 case EF_ARM_EABI_VER4:
f8c4789c 3171 out = stpcpy (out, ", Version4 EABI");
3bfcb652
NC
3172 while (e_flags)
3173 {
3174 unsigned flag;
3175
3176 /* Process flags one bit at a time. */
3177 flag = e_flags & - e_flags;
3178 e_flags &= ~ flag;
3179
3180 switch (flag)
3181 {
3182 case EF_ARM_BE8:
f8c4789c 3183 out = stpcpy (out, ", BE8");
3bfcb652
NC
3184 break;
3185
3186 case EF_ARM_LE8:
f8c4789c 3187 out = stpcpy (out, ", LE8");
3bfcb652
NC
3188 break;
3189
3190 default:
015dc7e1 3191 unknown = true;
3bfcb652
NC
3192 break;
3193 }
3bfcb652
NC
3194 }
3195 break;
3a4a14e9
PB
3196
3197 case EF_ARM_EABI_VER5:
f8c4789c 3198 out = stpcpy (out, ", Version5 EABI");
d507cf36
PB
3199 while (e_flags)
3200 {
3201 unsigned flag;
3202
3203 /* Process flags one bit at a time. */
3204 flag = e_flags & - e_flags;
3205 e_flags &= ~ flag;
3206
3207 switch (flag)
3208 {
3209 case EF_ARM_BE8:
f8c4789c 3210 out = stpcpy (out, ", BE8");
d507cf36
PB
3211 break;
3212
3213 case EF_ARM_LE8:
f8c4789c 3214 out = stpcpy (out, ", LE8");
d507cf36
PB
3215 break;
3216
3bfcb652 3217 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
f8c4789c 3218 out = stpcpy (out, ", soft-float ABI");
3bfcb652
NC
3219 break;
3220
3221 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
f8c4789c 3222 out = stpcpy (out, ", hard-float ABI");
3bfcb652
NC
3223 break;
3224
d507cf36 3225 default:
015dc7e1 3226 unknown = true;
d507cf36
PB
3227 break;
3228 }
3229 }
3230 break;
3231
f3485b74 3232 case EF_ARM_EABI_UNKNOWN:
f8c4789c 3233 out = stpcpy (out, ", GNU EABI");
f3485b74
NC
3234 while (e_flags)
3235 {
3236 unsigned flag;
76da6bbe 3237
f3485b74
NC
3238 /* Process flags one bit at a time. */
3239 flag = e_flags & - e_flags;
3240 e_flags &= ~ flag;
76da6bbe 3241
f3485b74
NC
3242 switch (flag)
3243 {
a5bcd848 3244 case EF_ARM_INTERWORK:
f8c4789c 3245 out = stpcpy (out, ", interworking enabled");
f3485b74 3246 break;
76da6bbe 3247
a5bcd848 3248 case EF_ARM_APCS_26:
f8c4789c 3249 out = stpcpy (out, ", uses APCS/26");
f3485b74 3250 break;
76da6bbe 3251
a5bcd848 3252 case EF_ARM_APCS_FLOAT:
f8c4789c 3253 out = stpcpy (out, ", uses APCS/float");
f3485b74 3254 break;
76da6bbe 3255
a5bcd848 3256 case EF_ARM_PIC:
f8c4789c 3257 out = stpcpy (out, ", position independent");
f3485b74 3258 break;
76da6bbe 3259
a5bcd848 3260 case EF_ARM_ALIGN8:
f8c4789c 3261 out = stpcpy (out, ", 8 bit structure alignment");
f3485b74 3262 break;
76da6bbe 3263
a5bcd848 3264 case EF_ARM_NEW_ABI:
f8c4789c 3265 out = stpcpy (out, ", uses new ABI");
f3485b74 3266 break;
76da6bbe 3267
a5bcd848 3268 case EF_ARM_OLD_ABI:
f8c4789c 3269 out = stpcpy (out, ", uses old ABI");
f3485b74 3270 break;
76da6bbe 3271
a5bcd848 3272 case EF_ARM_SOFT_FLOAT:
f8c4789c 3273 out = stpcpy (out, ", software FP");
f3485b74 3274 break;
76da6bbe 3275
90e01f86 3276 case EF_ARM_VFP_FLOAT:
f8c4789c 3277 out = stpcpy (out, ", VFP");
90e01f86
ILT
3278 break;
3279
fde78edd 3280 case EF_ARM_MAVERICK_FLOAT:
f8c4789c 3281 out = stpcpy (out, ", Maverick FP");
fde78edd
NC
3282 break;
3283
f3485b74 3284 default:
015dc7e1 3285 unknown = true;
f3485b74
NC
3286 break;
3287 }
3288 }
3289 }
f3485b74
NC
3290
3291 if (unknown)
f8c4789c
AM
3292 out = stpcpy (out,_(", <unknown>"));
3293 return out;
f3485b74
NC
3294}
3295
f8c4789c
AM
3296static char *
3297decode_AVR_machine_flags (char *out, unsigned e_flags)
343433df 3298{
343433df
AB
3299 switch (e_flags & EF_AVR_MACH)
3300 {
3301 case E_AVR_MACH_AVR1:
f8c4789c 3302 out = stpcpy (out, ", avr:1");
343433df
AB
3303 break;
3304 case E_AVR_MACH_AVR2:
f8c4789c 3305 out = stpcpy (out, ", avr:2");
343433df
AB
3306 break;
3307 case E_AVR_MACH_AVR25:
f8c4789c 3308 out = stpcpy (out, ", avr:25");
343433df
AB
3309 break;
3310 case E_AVR_MACH_AVR3:
f8c4789c 3311 out = stpcpy (out, ", avr:3");
343433df
AB
3312 break;
3313 case E_AVR_MACH_AVR31:
f8c4789c 3314 out = stpcpy (out, ", avr:31");
343433df
AB
3315 break;
3316 case E_AVR_MACH_AVR35:
f8c4789c 3317 out = stpcpy (out, ", avr:35");
343433df
AB
3318 break;
3319 case E_AVR_MACH_AVR4:
f8c4789c 3320 out = stpcpy (out, ", avr:4");
343433df
AB
3321 break;
3322 case E_AVR_MACH_AVR5:
f8c4789c 3323 out = stpcpy (out, ", avr:5");
343433df
AB
3324 break;
3325 case E_AVR_MACH_AVR51:
f8c4789c 3326 out = stpcpy (out, ", avr:51");
343433df
AB
3327 break;
3328 case E_AVR_MACH_AVR6:
f8c4789c 3329 out = stpcpy (out, ", avr:6");
343433df
AB
3330 break;
3331 case E_AVR_MACH_AVRTINY:
f8c4789c 3332 out = stpcpy (out, ", avr:100");
343433df
AB
3333 break;
3334 case E_AVR_MACH_XMEGA1:
f8c4789c 3335 out = stpcpy (out, ", avr:101");
343433df
AB
3336 break;
3337 case E_AVR_MACH_XMEGA2:
f8c4789c 3338 out = stpcpy (out, ", avr:102");
343433df
AB
3339 break;
3340 case E_AVR_MACH_XMEGA3:
f8c4789c 3341 out = stpcpy (out, ", avr:103");
343433df
AB
3342 break;
3343 case E_AVR_MACH_XMEGA4:
f8c4789c 3344 out = stpcpy (out, ", avr:104");
343433df
AB
3345 break;
3346 case E_AVR_MACH_XMEGA5:
f8c4789c 3347 out = stpcpy (out, ", avr:105");
343433df
AB
3348 break;
3349 case E_AVR_MACH_XMEGA6:
f8c4789c 3350 out = stpcpy (out, ", avr:106");
343433df
AB
3351 break;
3352 case E_AVR_MACH_XMEGA7:
f8c4789c 3353 out = stpcpy (out, ", avr:107");
343433df
AB
3354 break;
3355 default:
f8c4789c 3356 out = stpcpy (out, ", avr:<unknown>");
343433df
AB
3357 break;
3358 }
3359
343433df 3360 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
f8c4789c
AM
3361 out = stpcpy (out, ", link-relax");
3362 return out;
343433df
AB
3363}
3364
f8c4789c
AM
3365static char *
3366decode_BLACKFIN_machine_flags (char *out, unsigned e_flags)
3367{
3368 if (e_flags & EF_BFIN_PIC)
3369 out = stpcpy (out, ", PIC");
3370
3371 if (e_flags & EF_BFIN_FDPIC)
3372 out = stpcpy (out, ", FDPIC");
3373
3374 if (e_flags & EF_BFIN_CODE_IN_L1)
3375 out = stpcpy (out, ", code in L1");
3376
3377 if (e_flags & EF_BFIN_DATA_IN_L1)
3378 out = stpcpy (out, ", data in L1");
3379 return out;
3380}
3381
3382static char *
3383decode_FRV_machine_flags (char *out, unsigned e_flags)
3384{
3385 switch (e_flags & EF_FRV_CPU_MASK)
3386 {
3387 case EF_FRV_CPU_GENERIC:
3388 break;
3389
3390 default:
3391 out = stpcpy (out, ", fr???");
3392 break;
3393
3394 case EF_FRV_CPU_FR300:
3395 out = stpcpy (out, ", fr300");
3396 break;
3397
3398 case EF_FRV_CPU_FR400:
3399 out = stpcpy (out, ", fr400");
3400 break;
3401 case EF_FRV_CPU_FR405:
3402 out = stpcpy (out, ", fr405");
3403 break;
3404
3405 case EF_FRV_CPU_FR450:
3406 out = stpcpy (out, ", fr450");
3407 break;
3408
3409 case EF_FRV_CPU_FR500:
3410 out = stpcpy (out, ", fr500");
3411 break;
3412 case EF_FRV_CPU_FR550:
3413 out = stpcpy (out, ", fr550");
3414 break;
3415
3416 case EF_FRV_CPU_SIMPLE:
3417 out = stpcpy (out, ", simple");
3418 break;
3419 case EF_FRV_CPU_TOMCAT:
3420 out = stpcpy (out, ", tomcat");
3421 break;
3422 }
3423 return out;
3424}
3425
3426static char *
3427decode_IA64_machine_flags (char *out, unsigned e_flags, Filedata *filedata)
3428{
3429 if ((e_flags & EF_IA_64_ABI64))
3430 out = stpcpy (out, ", 64-bit");
3431 else
3432 out = stpcpy (out, ", 32-bit");
3433 if ((e_flags & EF_IA_64_REDUCEDFP))
3434 out = stpcpy (out, ", reduced fp model");
3435 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3436 out = stpcpy (out, ", no function descriptors, constant gp");
3437 else if ((e_flags & EF_IA_64_CONS_GP))
3438 out = stpcpy (out, ", constant gp");
3439 if ((e_flags & EF_IA_64_ABSOLUTE))
3440 out = stpcpy (out, ", absolute");
3441 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3442 {
3443 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3444 out = stpcpy (out, ", vms_linkages");
3445 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3446 {
3447 case EF_IA_64_VMS_COMCOD_SUCCESS:
3448 break;
3449 case EF_IA_64_VMS_COMCOD_WARNING:
3450 out = stpcpy (out, ", warning");
3451 break;
3452 case EF_IA_64_VMS_COMCOD_ERROR:
3453 out = stpcpy (out, ", error");
3454 break;
3455 case EF_IA_64_VMS_COMCOD_ABORT:
3456 out = stpcpy (out, ", abort");
3457 break;
3458 default:
3459 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3460 e_flags & EF_IA_64_VMS_COMCOD);
3461 out = stpcpy (out, ", <unknown>");
3462 }
3463 }
3464 return out;
3465}
3466
3467static char *
3468decode_LOONGARCH_machine_flags (char *out, unsigned int e_flags)
3469{
3470 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
3471 out = stpcpy (out, ", SOFT-FLOAT");
3472 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
3473 out = stpcpy (out, ", SINGLE-FLOAT");
3474 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
3475 out = stpcpy (out, ", DOUBLE-FLOAT");
3476
3477 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
3478 out = stpcpy (out, ", OBJ-v0");
3479 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
3480 out = stpcpy (out, ", OBJ-v1");
3481 return out;
3482}
3483
3484static char *
3485decode_M68K_machine_flags (char *out, unsigned int e_flags)
3486{
3487 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
3488 out = stpcpy (out, ", m68000");
3489 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3490 out = stpcpy (out, ", cpu32");
3491 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3492 out = stpcpy (out, ", fido_a");
3493 else
3494 {
3495 char const *isa = _("unknown");
3496 char const *mac = _("unknown mac");
3497 char const *additional = NULL;
3498
3499 switch (e_flags & EF_M68K_CF_ISA_MASK)
3500 {
3501 case EF_M68K_CF_ISA_A_NODIV:
3502 isa = "A";
3503 additional = ", nodiv";
3504 break;
3505 case EF_M68K_CF_ISA_A:
3506 isa = "A";
3507 break;
3508 case EF_M68K_CF_ISA_A_PLUS:
3509 isa = "A+";
3510 break;
3511 case EF_M68K_CF_ISA_B_NOUSP:
3512 isa = "B";
3513 additional = ", nousp";
3514 break;
3515 case EF_M68K_CF_ISA_B:
3516 isa = "B";
3517 break;
3518 case EF_M68K_CF_ISA_C:
3519 isa = "C";
3520 break;
3521 case EF_M68K_CF_ISA_C_NODIV:
3522 isa = "C";
3523 additional = ", nodiv";
3524 break;
3525 }
3526 out = stpcpy (out, ", cf, isa ");
3527 out = stpcpy (out, isa);
3528 if (additional)
3529 out = stpcpy (out, additional);
3530 if (e_flags & EF_M68K_CF_FLOAT)
3531 out = stpcpy (out, ", float");
3532 switch (e_flags & EF_M68K_CF_MAC_MASK)
3533 {
3534 case 0:
3535 mac = NULL;
3536 break;
3537 case EF_M68K_CF_MAC:
3538 mac = "mac";
3539 break;
3540 case EF_M68K_CF_EMAC:
3541 mac = "emac";
3542 break;
3543 case EF_M68K_CF_EMAC_B:
3544 mac = "emac_b";
3545 break;
3546 }
3547 if (mac)
3548 {
3549 out = stpcpy (out, ", ");
3550 out = stpcpy (out, mac);
3551 }
3552 }
3553 return out;
3554}
3555
3556static char *
3557decode_MeP_machine_flags (char *out, unsigned int e_flags)
3558{
3559 switch (e_flags & EF_MEP_CPU_MASK)
3560 {
3561 case EF_MEP_CPU_MEP:
3562 out = stpcpy (out, ", generic MeP");
3563 break;
3564 case EF_MEP_CPU_C2:
3565 out = stpcpy (out, ", MeP C2");
3566 break;
3567 case EF_MEP_CPU_C3:
3568 out = stpcpy (out, ", MeP C3");
3569 break;
3570 case EF_MEP_CPU_C4:
3571 out = stpcpy (out, ", MeP C4");
3572 break;
3573 case EF_MEP_CPU_C5:
3574 out = stpcpy (out, ", MeP C5");
3575 break;
3576 case EF_MEP_CPU_H1:
3577 out = stpcpy (out, ", MeP H1");
3578 break;
3579 default:
3580 out = stpcpy (out, _(", <unknown MeP cpu type>"));
3581 break;
3582 }
3583
3584 switch (e_flags & EF_MEP_COP_MASK)
3585 {
3586 case EF_MEP_COP_NONE:
3587 break;
3588 case EF_MEP_COP_AVC:
3589 out = stpcpy (out, ", AVC coprocessor");
3590 break;
3591 case EF_MEP_COP_AVC2:
3592 out = stpcpy (out, ", AVC2 coprocessor");
3593 break;
3594 case EF_MEP_COP_FMAX:
3595 out = stpcpy (out, ", FMAX coprocessor");
3596 break;
3597 case EF_MEP_COP_IVC2:
3598 out = stpcpy (out, ", IVC2 coprocessor");
3599 break;
3600 default:
3601 out = stpcpy (out, _("<unknown MeP copro type>"));
3602 break;
3603 }
3604
3605 if (e_flags & EF_MEP_LIBRARY)
3606 out = stpcpy (out, ", Built for Library");
3607
3608 if (e_flags & EF_MEP_INDEX_MASK)
3609 out += sprintf (out, ", Configuration Index: %#x",
3610 e_flags & EF_MEP_INDEX_MASK);
3611
3612 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3613 out += sprintf (out, _(", unknown flags bits: %#x"),
3614 e_flags & ~ EF_MEP_ALL_FLAGS);
3615 return out;
3616}
3617
3618static char *
3619decode_MIPS_machine_flags (char *out, unsigned int e_flags)
3620{
3621 if (e_flags & EF_MIPS_NOREORDER)
3622 out = stpcpy (out, ", noreorder");
3623
3624 if (e_flags & EF_MIPS_PIC)
3625 out = stpcpy (out, ", pic");
3626
3627 if (e_flags & EF_MIPS_CPIC)
3628 out = stpcpy (out, ", cpic");
3629
3630 if (e_flags & EF_MIPS_UCODE)
3631 out = stpcpy (out, ", ugen_reserved");
3632
3633 if (e_flags & EF_MIPS_ABI2)
3634 out = stpcpy (out, ", abi2");
3635
3636 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3637 out = stpcpy (out, ", odk first");
3638
3639 if (e_flags & EF_MIPS_32BITMODE)
3640 out = stpcpy (out, ", 32bitmode");
3641
3642 if (e_flags & EF_MIPS_NAN2008)
3643 out = stpcpy (out, ", nan2008");
3644
3645 if (e_flags & EF_MIPS_FP64)
3646 out = stpcpy (out, ", fp64");
3647
3648 switch ((e_flags & EF_MIPS_MACH))
3649 {
3650 case E_MIPS_MACH_3900:
3651 out = stpcpy (out, ", 3900");
3652 break;
3653 case E_MIPS_MACH_4010:
3654 out = stpcpy (out, ", 4010");
3655 break;
3656 case E_MIPS_MACH_4100:
3657 out = stpcpy (out, ", 4100");
3658 break;
3659 case E_MIPS_MACH_4111:
3660 out = stpcpy (out, ", 4111");
3661 break;
3662 case E_MIPS_MACH_4120:
3663 out = stpcpy (out, ", 4120");
3664 break;
3665 case E_MIPS_MACH_4650:
3666 out = stpcpy (out, ", 4650");
3667 break;
3668 case E_MIPS_MACH_5400:
3669 out = stpcpy (out, ", 5400");
3670 break;
3671 case E_MIPS_MACH_5500:
3672 out = stpcpy (out, ", 5500");
3673 break;
3674 case E_MIPS_MACH_5900:
3675 out = stpcpy (out, ", 5900");
3676 break;
3677 case E_MIPS_MACH_SB1:
3678 out = stpcpy (out, ", sb1");
3679 break;
3680 case E_MIPS_MACH_9000:
3681 out = stpcpy (out, ", 9000");
3682 break;
3683 case E_MIPS_MACH_LS2E:
3684 out = stpcpy (out, ", loongson-2e");
3685 break;
3686 case E_MIPS_MACH_LS2F:
3687 out = stpcpy (out, ", loongson-2f");
3688 break;
3689 case E_MIPS_MACH_GS464:
3690 out = stpcpy (out, ", gs464");
3691 break;
3692 case E_MIPS_MACH_GS464E:
3693 out = stpcpy (out, ", gs464e");
3694 break;
3695 case E_MIPS_MACH_GS264E:
3696 out = stpcpy (out, ", gs264e");
3697 break;
3698 case E_MIPS_MACH_OCTEON:
3699 out = stpcpy (out, ", octeon");
3700 break;
3701 case E_MIPS_MACH_OCTEON2:
3702 out = stpcpy (out, ", octeon2");
3703 break;
3704 case E_MIPS_MACH_OCTEON3:
3705 out = stpcpy (out, ", octeon3");
3706 break;
3707 case E_MIPS_MACH_XLR:
3708 out = stpcpy (out, ", xlr");
3709 break;
3710 case E_MIPS_MACH_IAMR2:
3711 out = stpcpy (out, ", interaptiv-mr2");
3712 break;
3713 case E_MIPS_MACH_ALLEGREX:
3714 out = stpcpy (out, ", allegrex");
3715 break;
3716 case 0:
3717 /* We simply ignore the field in this case to avoid confusion:
3718 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3719 extension. */
3720 break;
3721 default:
3722 out = stpcpy (out, _(", unknown CPU"));
3723 break;
3724 }
3725
3726 switch ((e_flags & EF_MIPS_ABI))
3727 {
3728 case E_MIPS_ABI_O32:
3729 out = stpcpy (out, ", o32");
3730 break;
3731 case E_MIPS_ABI_O64:
3732 out = stpcpy (out, ", o64");
3733 break;
3734 case E_MIPS_ABI_EABI32:
3735 out = stpcpy (out, ", eabi32");
3736 break;
3737 case E_MIPS_ABI_EABI64:
3738 out = stpcpy (out, ", eabi64");
3739 break;
3740 case 0:
3741 /* We simply ignore the field in this case to avoid confusion:
3742 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3743 This means it is likely to be an o32 file, but not for
3744 sure. */
3745 break;
3746 default:
3747 out = stpcpy (out, _(", unknown ABI"));
3748 break;
3749 }
3750
3751 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3752 out = stpcpy (out, ", mdmx");
3753
3754 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3755 out = stpcpy (out, ", mips16");
3756
3757 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3758 out = stpcpy (out, ", micromips");
3759
3760 switch ((e_flags & EF_MIPS_ARCH))
3761 {
3762 case E_MIPS_ARCH_1:
3763 out = stpcpy (out, ", mips1");
3764 break;
3765 case E_MIPS_ARCH_2:
3766 out = stpcpy (out, ", mips2");
3767 break;
3768 case E_MIPS_ARCH_3:
3769 out = stpcpy (out, ", mips3");
3770 break;
3771 case E_MIPS_ARCH_4:
3772 out = stpcpy (out, ", mips4");
3773 break;
3774 case E_MIPS_ARCH_5:
3775 out = stpcpy (out, ", mips5");
3776 break;
3777 case E_MIPS_ARCH_32:
3778 out = stpcpy (out, ", mips32");
3779 break;
3780 case E_MIPS_ARCH_32R2:
3781 out = stpcpy (out, ", mips32r2");
3782 break;
3783 case E_MIPS_ARCH_32R6:
3784 out = stpcpy (out, ", mips32r6");
3785 break;
3786 case E_MIPS_ARCH_64:
3787 out = stpcpy (out, ", mips64");
3788 break;
3789 case E_MIPS_ARCH_64R2:
3790 out = stpcpy (out, ", mips64r2");
3791 break;
3792 case E_MIPS_ARCH_64R6:
3793 out = stpcpy (out, ", mips64r6");
3794 break;
3795 default:
3796 out = stpcpy (out, _(", unknown ISA"));
3797 break;
3798 }
3799 return out;
3800}
3801
3802static char *
3803decode_MSP430_machine_flags (char *out, unsigned e_flags)
3804{
3805 out = stpcpy (out, _(": architecture variant: "));
3806 switch (e_flags & EF_MSP430_MACH)
3807 {
3808 case E_MSP430_MACH_MSP430x11:
3809 out = stpcpy (out, "MSP430x11");
3810 break;
3811 case E_MSP430_MACH_MSP430x11x1:
3812 out = stpcpy (out, "MSP430x11x1 ");
3813 break;
3814 case E_MSP430_MACH_MSP430x12:
3815 out = stpcpy (out, "MSP430x12");
3816 break;
3817 case E_MSP430_MACH_MSP430x13:
3818 out = stpcpy (out, "MSP430x13");
3819 break;
3820 case E_MSP430_MACH_MSP430x14:
3821 out = stpcpy (out, "MSP430x14");
3822 break;
3823 case E_MSP430_MACH_MSP430x15:
3824 out = stpcpy (out, "MSP430x15");
3825 break;
3826 case E_MSP430_MACH_MSP430x16:
3827 out = stpcpy (out, "MSP430x16");
3828 break;
3829 case E_MSP430_MACH_MSP430x31:
3830 out = stpcpy (out, "MSP430x31");
3831 break;
3832 case E_MSP430_MACH_MSP430x32:
3833 out = stpcpy (out, "MSP430x32");
3834 break;
3835 case E_MSP430_MACH_MSP430x33:
3836 out = stpcpy (out, "MSP430x33");
3837 break;
3838 case E_MSP430_MACH_MSP430x41:
3839 out = stpcpy (out, "MSP430x41");
3840 break;
3841 case E_MSP430_MACH_MSP430x42:
3842 out = stpcpy (out, "MSP430x42");
3843 break;
3844 case E_MSP430_MACH_MSP430x43:
3845 out = stpcpy (out, "MSP430x43");
3846 break;
3847 case E_MSP430_MACH_MSP430x44:
3848 out = stpcpy (out, "MSP430x44");
3849 break;
3850 case E_MSP430_MACH_MSP430X :
3851 out = stpcpy (out, "MSP430X");
3852 break;
3853 default:
3854 out = stpcpy (out, _(": unknown"));
3855 break;
3856 }
3857
3858 if (e_flags & ~ EF_MSP430_MACH)
3859 out = stpcpy (out, _(": unknown extra flag bits also present"));
3860 return out;
3861}
3862
3863static char *
3864decode_NDS32_machine_flags (char *out, unsigned e_flags)
35c08157
KLC
3865{
3866 unsigned abi;
3867 unsigned arch;
3868 unsigned config;
3869 unsigned version;
015dc7e1 3870 bool has_fpu = false;
35c08157
KLC
3871
3872 static const char *ABI_STRINGS[] =
3873 {
3874 "ABI v0", /* use r5 as return register; only used in N1213HC */
3875 "ABI v1", /* use r0 as return register */
3876 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3877 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3878 "AABI",
3879 "ABI2 FP+"
35c08157
KLC
3880 };
3881 static const char *VER_STRINGS[] =
3882 {
3883 "Andes ELF V1.3 or older",
3884 "Andes ELF V1.3.1",
3885 "Andes ELF V1.4"
3886 };
3887 static const char *ARCH_STRINGS[] =
3888 {
3889 "",
3890 "Andes Star v1.0",
3891 "Andes Star v2.0",
3892 "Andes Star v3.0",
3893 "Andes Star v3.0m"
3894 };
3895
3896 abi = EF_NDS_ABI & e_flags;
3897 arch = EF_NDS_ARCH & e_flags;
3898 config = EF_NDS_INST & e_flags;
3899 version = EF_NDS32_ELF_VERSION & e_flags;
3900
35c08157
KLC
3901 switch (abi)
3902 {
3903 case E_NDS_ABI_V0:
3904 case E_NDS_ABI_V1:
3905 case E_NDS_ABI_V2:
3906 case E_NDS_ABI_V2FP:
3907 case E_NDS_ABI_AABI:
40c7a7cb 3908 case E_NDS_ABI_V2FP_PLUS:
35c08157 3909 /* In case there are holes in the array. */
f8c4789c 3910 out += sprintf (out, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
35c08157
KLC
3911 break;
3912
3913 default:
f8c4789c 3914 out = stpcpy (out, ", <unrecognized ABI>");
35c08157
KLC
3915 break;
3916 }
3917
3918 switch (version)
3919 {
3920 case E_NDS32_ELF_VER_1_2:
3921 case E_NDS32_ELF_VER_1_3:
3922 case E_NDS32_ELF_VER_1_4:
f8c4789c 3923 out += sprintf (out, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
35c08157
KLC
3924 break;
3925
3926 default:
f8c4789c 3927 out = stpcpy (out, ", <unrecognized ELF version number>");
35c08157
KLC
3928 break;
3929 }
3930
3931 if (E_NDS_ABI_V0 == abi)
3932 {
3933 /* OLD ABI; only used in N1213HC, has performance extension 1. */
f8c4789c 3934 out = stpcpy (out, ", Andes Star v1.0, N1213HC, MAC, PERF1");
35c08157 3935 if (arch == E_NDS_ARCH_STAR_V1_0)
f8c4789c
AM
3936 out = stpcpy (out, ", 16b"); /* has 16-bit instructions */
3937 return out;
35c08157
KLC
3938 }
3939
3940 switch (arch)
3941 {
3942 case E_NDS_ARCH_STAR_V1_0:
3943 case E_NDS_ARCH_STAR_V2_0:
3944 case E_NDS_ARCH_STAR_V3_0:
3945 case E_NDS_ARCH_STAR_V3_M:
f8c4789c 3946 out += sprintf (out, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
35c08157
KLC
3947 break;
3948
3949 default:
f8c4789c 3950 out = stpcpy (out, ", <unrecognized architecture>");
35c08157
KLC
3951 /* ARCH version determines how the e_flags are interpreted.
3952 If it is unknown, we cannot proceed. */
f8c4789c 3953 return out;
35c08157
KLC
3954 }
3955
3956 /* Newer ABI; Now handle architecture specific flags. */
3957 if (arch == E_NDS_ARCH_STAR_V1_0)
3958 {
3959 if (config & E_NDS32_HAS_MFUSR_PC_INST)
f8c4789c 3960 out = stpcpy (out, ", MFUSR_PC");
35c08157
KLC
3961
3962 if (!(config & E_NDS32_HAS_NO_MAC_INST))
f8c4789c 3963 out = stpcpy (out, ", MAC");
35c08157
KLC
3964
3965 if (config & E_NDS32_HAS_DIV_INST)
f8c4789c 3966 out = stpcpy (out, ", DIV");
35c08157
KLC
3967
3968 if (config & E_NDS32_HAS_16BIT_INST)
f8c4789c 3969 out = stpcpy (out, ", 16b");
35c08157
KLC
3970 }
3971 else
3972 {
3973 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3974 {
3975 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 3976 out = stpcpy (out, ", [B8]");
35c08157 3977 else
f8c4789c 3978 out = stpcpy (out, ", EX9");
35c08157
KLC
3979 }
3980
3981 if (config & E_NDS32_HAS_MAC_DX_INST)
f8c4789c 3982 out = stpcpy (out, ", MAC_DX");
35c08157
KLC
3983
3984 if (config & E_NDS32_HAS_DIV_DX_INST)
f8c4789c 3985 out = stpcpy (out, ", DIV_DX");
35c08157
KLC
3986
3987 if (config & E_NDS32_HAS_16BIT_INST)
3988 {
3989 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 3990 out = stpcpy (out, ", 16b");
35c08157 3991 else
f8c4789c 3992 out = stpcpy (out, ", IFC");
35c08157
KLC
3993 }
3994 }
3995
3996 if (config & E_NDS32_HAS_EXT_INST)
f8c4789c 3997 out = stpcpy (out, ", PERF1");
35c08157
KLC
3998
3999 if (config & E_NDS32_HAS_EXT2_INST)
f8c4789c 4000 out = stpcpy (out, ", PERF2");
35c08157
KLC
4001
4002 if (config & E_NDS32_HAS_FPU_INST)
4003 {
015dc7e1 4004 has_fpu = true;
f8c4789c 4005 out = stpcpy (out, ", FPU_SP");
35c08157
KLC
4006 }
4007
4008 if (config & E_NDS32_HAS_FPU_DP_INST)
4009 {
015dc7e1 4010 has_fpu = true;
f8c4789c 4011 out = stpcpy (out, ", FPU_DP");
35c08157
KLC
4012 }
4013
4014 if (config & E_NDS32_HAS_FPU_MAC_INST)
4015 {
015dc7e1 4016 has_fpu = true;
f8c4789c 4017 out = stpcpy (out, ", FPU_MAC");
35c08157
KLC
4018 }
4019
4020 if (has_fpu)
4021 {
4022 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
4023 {
4024 case E_NDS32_FPU_REG_8SP_4DP:
f8c4789c 4025 out = stpcpy (out, ", FPU_REG:8/4");
35c08157
KLC
4026 break;
4027 case E_NDS32_FPU_REG_16SP_8DP:
f8c4789c 4028 out = stpcpy (out, ", FPU_REG:16/8");
35c08157
KLC
4029 break;
4030 case E_NDS32_FPU_REG_32SP_16DP:
f8c4789c 4031 out = stpcpy (out, ", FPU_REG:32/16");
35c08157
KLC
4032 break;
4033 case E_NDS32_FPU_REG_32SP_32DP:
f8c4789c 4034 out = stpcpy (out, ", FPU_REG:32/32");
35c08157
KLC
4035 break;
4036 }
4037 }
4038
4039 if (config & E_NDS32_HAS_AUDIO_INST)
f8c4789c 4040 out = stpcpy (out, ", AUDIO");
35c08157
KLC
4041
4042 if (config & E_NDS32_HAS_STRING_INST)
f8c4789c 4043 out = stpcpy (out, ", STR");
35c08157
KLC
4044
4045 if (config & E_NDS32_HAS_REDUCED_REGS)
f8c4789c 4046 out = stpcpy (out, ", 16REG");
35c08157
KLC
4047
4048 if (config & E_NDS32_HAS_VIDEO_INST)
4049 {
4050 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4051 out = stpcpy (out, ", VIDEO");
35c08157 4052 else
f8c4789c 4053 out = stpcpy (out, ", SATURATION");
35c08157
KLC
4054 }
4055
4056 if (config & E_NDS32_HAS_ENCRIPT_INST)
f8c4789c 4057 out = stpcpy (out, ", ENCRP");
35c08157
KLC
4058
4059 if (config & E_NDS32_HAS_L2C_INST)
f8c4789c
AM
4060 out = stpcpy (out, ", L2C");
4061
4062 return out;
35c08157
KLC
4063}
4064
f8c4789c
AM
4065static char *
4066decode_PARISC_machine_flags (char *out, unsigned e_flags)
4067{
4068 switch (e_flags & EF_PARISC_ARCH)
4069 {
4070 case EFA_PARISC_1_0:
4071 out = stpcpy (out, ", PA-RISC 1.0");
4072 break;
4073 case EFA_PARISC_1_1:
4074 out = stpcpy (out, ", PA-RISC 1.1");
4075 break;
4076 case EFA_PARISC_2_0:
4077 out = stpcpy (out, ", PA-RISC 2.0");
4078 break;
4079 default:
4080 break;
4081 }
4082 if (e_flags & EF_PARISC_TRAPNIL)
4083 out = stpcpy (out, ", trapnil");
4084 if (e_flags & EF_PARISC_EXT)
4085 out = stpcpy (out, ", ext");
4086 if (e_flags & EF_PARISC_LSB)
4087 out = stpcpy (out, ", lsb");
4088 if (e_flags & EF_PARISC_WIDE)
4089 out = stpcpy (out, ", wide");
4090 if (e_flags & EF_PARISC_NO_KABP)
4091 out = stpcpy (out, ", no kabp");
4092 if (e_flags & EF_PARISC_LAZYSWAP)
4093 out = stpcpy (out, ", lazyswap");
4094 return out;
4095}
4096
4097static char *
4098decode_RISCV_machine_flags (char *out, unsigned e_flags)
4099{
4100 if (e_flags & EF_RISCV_RVC)
4101 out = stpcpy (out, ", RVC");
4102
4103 if (e_flags & EF_RISCV_RVE)
4104 out = stpcpy (out, ", RVE");
4105
4106 if (e_flags & EF_RISCV_TSO)
4107 out = stpcpy (out, ", TSO");
4108
4109 switch (e_flags & EF_RISCV_FLOAT_ABI)
4110 {
4111 case EF_RISCV_FLOAT_ABI_SOFT:
4112 out = stpcpy (out, ", soft-float ABI");
4113 break;
4114
4115 case EF_RISCV_FLOAT_ABI_SINGLE:
4116 out = stpcpy (out, ", single-float ABI");
4117 break;
4118
4119 case EF_RISCV_FLOAT_ABI_DOUBLE:
4120 out = stpcpy (out, ", double-float ABI");
4121 break;
4122
4123 case EF_RISCV_FLOAT_ABI_QUAD:
4124 out = stpcpy (out, ", quad-float ABI");
4125 break;
4126 }
4127 return out;
4128}
4129
4130static char *
4131decode_RL78_machine_flags (char *out, unsigned e_flags)
4132{
4133 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4134 {
4135 case E_FLAG_RL78_ANY_CPU:
4136 break;
4137 case E_FLAG_RL78_G10:
4138 out = stpcpy (out, ", G10");
4139 break;
4140 case E_FLAG_RL78_G13:
4141 out = stpcpy (out, ", G13");
4142 break;
4143 case E_FLAG_RL78_G14:
4144 out = stpcpy (out, ", G14");
4145 break;
4146 }
4147 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4148 out = stpcpy (out, ", 64-bit doubles");
4149 return out;
4150}
4151
4152static char *
4153decode_RX_machine_flags (char *out, unsigned e_flags)
4154{
4155 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4156 out = stpcpy (out, ", 64-bit doubles");
4157 if (e_flags & E_FLAG_RX_DSP)
4158 out = stpcpy (out, ", dsp");
4159 if (e_flags & E_FLAG_RX_PID)
4160 out = stpcpy (out, ", pid");
4161 if (e_flags & E_FLAG_RX_ABI)
4162 out = stpcpy (out, ", RX ABI");
4163 if (e_flags & E_FLAG_RX_SINSNS_SET)
4164 out = stpcpy (out, (e_flags & E_FLAG_RX_SINSNS_YES
4165 ? ", uses String instructions"
4166 : ", bans String instructions"));
4167 if (e_flags & E_FLAG_RX_V2)
4168 out = stpcpy (out, ", V2");
4169 if (e_flags & E_FLAG_RX_V3)
4170 out = stpcpy (out, ", V3");
4171 return out;
4172}
4173
4174static char *
4175decode_SH_machine_flags (char *out, unsigned e_flags)
4176{
4177 switch ((e_flags & EF_SH_MACH_MASK))
4178 {
4179 case EF_SH1:
4180 out = stpcpy (out, ", sh1");
4181 break;
4182 case EF_SH2:
4183 out = stpcpy (out, ", sh2");
4184 break;
4185 case EF_SH3:
4186 out = stpcpy (out, ", sh3");
4187 break;
4188 case EF_SH_DSP:
4189 out = stpcpy (out, ", sh-dsp");
4190 break;
4191 case EF_SH3_DSP:
4192 out = stpcpy (out, ", sh3-dsp");
4193 break;
4194 case EF_SH4AL_DSP:
4195 out = stpcpy (out, ", sh4al-dsp");
4196 break;
4197 case EF_SH3E:
4198 out = stpcpy (out, ", sh3e");
4199 break;
4200 case EF_SH4:
4201 out = stpcpy (out, ", sh4");
4202 break;
4203 case EF_SH5:
4204 out = stpcpy (out, ", sh5");
4205 break;
4206 case EF_SH2E:
4207 out = stpcpy (out, ", sh2e");
4208 break;
4209 case EF_SH4A:
4210 out = stpcpy (out, ", sh4a");
4211 break;
4212 case EF_SH2A:
4213 out = stpcpy (out, ", sh2a");
4214 break;
4215 case EF_SH4_NOFPU:
4216 out = stpcpy (out, ", sh4-nofpu");
4217 break;
4218 case EF_SH4A_NOFPU:
4219 out = stpcpy (out, ", sh4a-nofpu");
4220 break;
4221 case EF_SH2A_NOFPU:
4222 out = stpcpy (out, ", sh2a-nofpu");
4223 break;
4224 case EF_SH3_NOMMU:
4225 out = stpcpy (out, ", sh3-nommu");
4226 break;
4227 case EF_SH4_NOMMU_NOFPU:
4228 out = stpcpy (out, ", sh4-nommu-nofpu");
4229 break;
4230 case EF_SH2A_SH4_NOFPU:
4231 out = stpcpy (out, ", sh2a-nofpu-or-sh4-nommu-nofpu");
4232 break;
4233 case EF_SH2A_SH3_NOFPU:
4234 out = stpcpy (out, ", sh2a-nofpu-or-sh3-nommu");
4235 break;
4236 case EF_SH2A_SH4:
4237 out = stpcpy (out, ", sh2a-or-sh4");
4238 break;
4239 case EF_SH2A_SH3E:
4240 out = stpcpy (out, ", sh2a-or-sh3e");
4241 break;
4242 default:
4243 out = stpcpy (out, _(", unknown ISA"));
4244 break;
4245 }
4246
4247 if (e_flags & EF_SH_PIC)
4248 out = stpcpy (out, ", pic");
4249
4250 if (e_flags & EF_SH_FDPIC)
4251 out = stpcpy (out, ", fdpic");
4252 return out;
4253}
4254
4255static char *
4256decode_SPARC_machine_flags (char *out, unsigned e_flags)
4257{
4258 if (e_flags & EF_SPARC_32PLUS)
4259 out = stpcpy (out, ", v8+");
4260
4261 if (e_flags & EF_SPARC_SUN_US1)
4262 out = stpcpy (out, ", ultrasparcI");
4263
4264 if (e_flags & EF_SPARC_SUN_US3)
4265 out = stpcpy (out, ", ultrasparcIII");
4266
4267 if (e_flags & EF_SPARC_HAL_R1)
4268 out = stpcpy (out, ", halr1");
4269
4270 if (e_flags & EF_SPARC_LEDATA)
4271 out = stpcpy (out, ", ledata");
4272
4273 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4274 out = stpcpy (out, ", tso");
4275
4276 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4277 out = stpcpy (out, ", pso");
4278
4279 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4280 out = stpcpy (out, ", rmo");
4281 return out;
4282}
4283
4284static char *
4285decode_V800_machine_flags (char *out, unsigned int e_flags)
4286{
4287 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
4288 out = stpcpy (out, ", RH850 ABI");
4289
4290 if (e_flags & EF_V800_850E3)
4291 out = stpcpy (out, ", V3 architecture");
4292
4293 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
4294 out = stpcpy (out, ", FPU not used");
4295
4296 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
4297 out = stpcpy (out, ", regmode: COMMON");
4298
4299 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
4300 out = stpcpy (out, ", r4 not used");
4301
4302 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
4303 out = stpcpy (out, ", r30 not used");
4304
4305 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
4306 out = stpcpy (out, ", r5 not used");
4307
4308 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
4309 out = stpcpy (out, ", r2 not used");
4310
4311 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
4312 {
4313 switch (e_flags & - e_flags)
4314 {
4315 case EF_RH850_FPU_DOUBLE:
4316 out = stpcpy (out, ", double precision FPU");
4317 break;
4318 case EF_RH850_FPU_SINGLE:
4319 out = stpcpy (out, ", single precision FPU");
4320 break;
4321 case EF_RH850_REGMODE22:
4322 out = stpcpy (out, ", regmode:22");
4323 break;
4324 case EF_RH850_REGMODE32:
4325 out = stpcpy (out, ", regmode:23");
4326 break;
4327 case EF_RH850_GP_FIX:
4328 out = stpcpy (out, ", r4 fixed");
4329 break;
4330 case EF_RH850_GP_NOFIX:
4331 out = stpcpy (out, ", r4 free");
4332 break;
4333 case EF_RH850_EP_FIX:
4334 out = stpcpy (out, ", r30 fixed");
4335 break;
4336 case EF_RH850_EP_NOFIX:
4337 out = stpcpy (out, ", r30 free");
4338 break;
4339 case EF_RH850_TP_FIX:
4340 out = stpcpy (out, ", r5 fixed");
4341 break;
4342 case EF_RH850_TP_NOFIX:
4343 out = stpcpy (out, ", r5 free");
4344 break;
4345 case EF_RH850_REG2_RESERVE:
4346 out = stpcpy (out, ", r2 fixed");
4347 break;
4348 case EF_RH850_REG2_NORESERVE:
4349 out = stpcpy (out, ", r2 free");
4350 break;
4351 default:
4352 break;
4353 }
4354 }
4355 return out;
4356}
4357
4358static char *
4359decode_V850_machine_flags (char *out, unsigned int e_flags)
4360{
4361 switch (e_flags & EF_V850_ARCH)
4362 {
4363 case E_V850E3V5_ARCH:
4364 out = stpcpy (out, ", v850e3v5");
4365 break;
4366 case E_V850E2V3_ARCH:
4367 out = stpcpy (out, ", v850e2v3");
4368 break;
4369 case E_V850E2_ARCH:
4370 out = stpcpy (out, ", v850e2");
4371 break;
4372 case E_V850E1_ARCH:
4373 out = stpcpy (out, ", v850e1");
4374 break;
4375 case E_V850E_ARCH:
4376 out = stpcpy (out, ", v850e");
4377 break;
4378 case E_V850_ARCH:
4379 out = stpcpy (out, ", v850");
4380 break;
4381 default:
4382 out = stpcpy (out, _(", unknown v850 architecture variant"));
4383 break;
4384 }
4385 return out;
4386}
4387
4388static char *
4389decode_Z80_machine_flags (char *out, unsigned int e_flags)
4390{
4391 switch (e_flags & EF_Z80_MACH_MSK)
4392 {
4393 case EF_Z80_MACH_Z80:
4394 out = stpcpy (out, ", Z80");
4395 break;
4396 case EF_Z80_MACH_Z180:
4397 out = stpcpy (out, ", Z180");
4398 break;
4399 case EF_Z80_MACH_R800:
4400 out = stpcpy (out, ", R800");
4401 break;
4402 case EF_Z80_MACH_EZ80_Z80:
4403 out = stpcpy (out, ", EZ80");
4404 break;
4405 case EF_Z80_MACH_EZ80_ADL:
4406 out = stpcpy (out, ", EZ80, ADL");
4407 break;
4408 case EF_Z80_MACH_GBZ80:
4409 out = stpcpy (out, ", GBZ80");
4410 break;
4411 case EF_Z80_MACH_Z80N:
4412 out = stpcpy (out, ", Z80N");
4413 break;
4414 default:
4415 out = stpcpy (out, _(", unknown"));
4416 break;
4417 }
4418 return out;
4419}
4420
4421static char *
4422decode_AMDGPU_machine_flags (char *out, unsigned int e_flags, Filedata *filedata)
c077c580
SM
4423{
4424 unsigned char *e_ident = filedata->file_header.e_ident;
4425 unsigned char osabi = e_ident[EI_OSABI];
4426 unsigned char abiversion = e_ident[EI_ABIVERSION];
4427 unsigned int mach;
4428
4429 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
4430 it has been deprecated for a while.
4431
4432 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
4433 of writing, they use the same flags as HSA v3, so the code below uses that
4434 assumption. */
4435 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
f8c4789c 4436 return out;
c077c580
SM
4437
4438 mach = e_flags & EF_AMDGPU_MACH;
4439 switch (mach)
4440 {
4441#define AMDGPU_CASE(code, string) \
f8c4789c 4442 case code: out = stpcpy (out, ", " string); break;
c077c580
SM
4443 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
4444 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
4445 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
4446 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
4447 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
4448 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
4449 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
4450 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
4451 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
4452 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
4453 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
4454 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
4455 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
4456 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
4457 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
4458 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
4459 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
4460 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
4461 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
4462 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
4463 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
4464 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
4465 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
4466 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
4467 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
4468 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
4469 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
4470 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
4471 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
4472 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
4473 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
4474 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
4475 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
4476 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
4477 default:
f8c4789c 4478 out += sprintf (out, _(", <unknown AMDGPU GPU type: %#x>"), mach);
c077c580
SM
4479 break;
4480#undef AMDGPU_CASE
4481 }
4482
c077c580
SM
4483 e_flags &= ~EF_AMDGPU_MACH;
4484
4485 if ((osabi == ELFOSABI_AMDGPU_HSA
4486 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
4487 || osabi != ELFOSABI_AMDGPU_HSA)
4488 {
4489 /* For HSA v3 and other OS ABIs. */
4490 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
4491 {
f8c4789c 4492 out = stpcpy (out, ", xnack on");
c077c580
SM
4493 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
4494 }
4495
4496 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
4497 {
f8c4789c 4498 out = stpcpy (out, ", sramecc on");
c077c580
SM
4499 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
4500 }
4501 }
4502 else
4503 {
4504 /* For HSA v4+. */
4505 int xnack, sramecc;
4506
4507 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
4508 switch (xnack)
4509 {
4510 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
4511 break;
4512
4513 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
f8c4789c 4514 out = stpcpy (out, ", xnack any");
c077c580
SM
4515 break;
4516
4517 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
f8c4789c 4518 out = stpcpy (out, ", xnack off");
c077c580
SM
4519 break;
4520
4521 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
f8c4789c 4522 out = stpcpy (out, ", xnack on");
c077c580
SM
4523 break;
4524
4525 default:
f8c4789c 4526 out += sprintf (out, _(", <unknown xnack value: %#x>"), xnack);
c077c580
SM
4527 break;
4528 }
4529
c077c580
SM
4530 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
4531
4532 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
4533 switch (sramecc)
4534 {
4535 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
4536 break;
4537
4538 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
f8c4789c 4539 out = stpcpy (out, ", sramecc any");
c077c580
SM
4540 break;
4541
4542 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
f8c4789c 4543 out = stpcpy (out, ", sramecc off");
c077c580
SM
4544 break;
4545
4546 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
f8c4789c 4547 out = stpcpy (out, ", sramecc on");
c077c580
SM
4548 break;
4549
4550 default:
f8c4789c 4551 out += sprintf (out, _(", <unknown sramecc value: %#x>"), sramecc);
c077c580
SM
4552 break;
4553 }
4554
c077c580
SM
4555 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
4556 }
4557
4558 if (e_flags != 0)
f8c4789c
AM
4559 out += sprintf (out, _(", unknown flags bits: %#x"), e_flags);
4560 return out;
c077c580
SM
4561}
4562
252b5132 4563static char *
dda8d76d 4564get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 4565{
b34976b6 4566 static char buf[1024];
f8c4789c 4567 char *out = buf;
252b5132
RH
4568
4569 buf[0] = '\0';
76da6bbe 4570
252b5132
RH
4571 if (e_flags)
4572 {
4573 switch (e_machine)
4574 {
4575 default:
4576 break;
4577
b5c37946 4578 case EM_ARC_COMPACT3:
f8c4789c 4579 out = stpcpy (out, ", HS5x");
b5c37946
SJ
4580 break;
4581
4582 case EM_ARC_COMPACT3_64:
f8c4789c 4583 out = stpcpy (out, ", HS6x");
b5c37946
SJ
4584 break;
4585
886a2506 4586 case EM_ARC_COMPACT2:
886a2506 4587 case EM_ARC_COMPACT:
f8c4789c
AM
4588 out = decode_ARC_machine_flags (out, e_flags, e_machine);
4589 break;
886a2506 4590
f3485b74 4591 case EM_ARM:
f8c4789c 4592 out = decode_ARM_machine_flags (out, e_flags);
f3485b74 4593 break;
76da6bbe 4594
f8c4789c
AM
4595 case EM_AVR:
4596 out = decode_AVR_machine_flags (out, e_flags);
4597 break;
343433df 4598
781303ce 4599 case EM_BLACKFIN:
f8c4789c 4600 out = decode_BLACKFIN_machine_flags (out, e_flags);
781303ce
MF
4601 break;
4602
ec2dfb42 4603 case EM_CYGNUS_FRV:
f8c4789c 4604 out = decode_FRV_machine_flags (out, e_flags);
1c877e87 4605 break;
ec2dfb42 4606
53c7db4b 4607 case EM_68K:
f8c4789c 4608 out = decode_M68K_machine_flags (out, e_flags);
53c7db4b 4609 break;
33c63f9d 4610
c077c580 4611 case EM_AMDGPU:
f8c4789c 4612 out = decode_AMDGPU_machine_flags (out, e_flags, filedata);
c077c580
SM
4613 break;
4614
153a2776 4615 case EM_CYGNUS_MEP:
f8c4789c 4616 out = decode_MeP_machine_flags (out, e_flags);
153a2776
NC
4617 break;
4618
252b5132
RH
4619 case EM_PPC:
4620 if (e_flags & EF_PPC_EMB)
f8c4789c 4621 out = stpcpy (out, ", emb");
252b5132
RH
4622
4623 if (e_flags & EF_PPC_RELOCATABLE)
f8c4789c 4624 out = stpcpy (out, _(", relocatable"));
252b5132
RH
4625
4626 if (e_flags & EF_PPC_RELOCATABLE_LIB)
f8c4789c 4627 out = stpcpy (out, _(", relocatable-lib"));
252b5132
RH
4628 break;
4629
ee67d69a
AM
4630 case EM_PPC64:
4631 if (e_flags & EF_PPC64_ABI)
f8c4789c 4632 out += sprintf (out, ", abiv%d", e_flags & EF_PPC64_ABI);
ee67d69a
AM
4633 break;
4634
708e2187 4635 case EM_V800:
f8c4789c 4636 out = decode_V800_machine_flags (out, e_flags);
708e2187
NC
4637 break;
4638
2b0337b0 4639 case EM_V850:
252b5132 4640 case EM_CYGNUS_V850:
f8c4789c 4641 out = decode_V850_machine_flags (out, e_flags);
252b5132
RH
4642 break;
4643
2b0337b0 4644 case EM_M32R:
252b5132
RH
4645 case EM_CYGNUS_M32R:
4646 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
f8c4789c 4647 out = stpcpy (out, ", m32r");
252b5132
RH
4648 break;
4649
4650 case EM_MIPS:
4fe85591 4651 case EM_MIPS_RS3_LE:
f8c4789c 4652 out = decode_MIPS_machine_flags (out, e_flags);
252b5132 4653 break;
351b4b40 4654
35c08157 4655 case EM_NDS32:
f8c4789c 4656 out = decode_NDS32_machine_flags (out, e_flags);
35c08157
KLC
4657 break;
4658
fe944acf
FT
4659 case EM_NFP:
4660 switch (EF_NFP_MACH (e_flags))
4661 {
4662 case E_NFP_MACH_3200:
f8c4789c 4663 out = stpcpy (out, ", NFP-32xx");
fe944acf
FT
4664 break;
4665 case E_NFP_MACH_6000:
f8c4789c 4666 out = stpcpy (out, ", NFP-6xxx");
fe944acf
FT
4667 break;
4668 }
4669 break;
4670
e23eba97 4671 case EM_RISCV:
f8c4789c 4672 out = decode_RISCV_machine_flags (out, e_flags);
e23eba97
NC
4673 break;
4674
ccde1100 4675 case EM_SH:
f8c4789c 4676 out = decode_SH_machine_flags (out, e_flags);
ccde1100 4677 break;
948f632f 4678
f8c4789c
AM
4679 case EM_OR1K:
4680 if (e_flags & EF_OR1K_NODELAY)
4681 out = stpcpy (out, ", no delay");
4682 break;
57346661 4683
f8c4789c
AM
4684 case EM_BPF:
4685 out += sprintf (out, ", CPU Version: %u", e_flags & EF_BPF_CPUVER);
4686 break;
b5c37946 4687
351b4b40 4688 case EM_SPARCV9:
f8c4789c 4689 out = decode_SPARC_machine_flags (out, e_flags);
351b4b40 4690 break;
7d466069 4691
103f02d3 4692 case EM_PARISC:
f8c4789c 4693 out = decode_PARISC_machine_flags (out, e_flags);
30800947 4694 break;
76da6bbe 4695
7d466069 4696 case EM_PJ:
2b0337b0 4697 case EM_PJ_OLD:
7d466069 4698 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
f8c4789c 4699 out = stpcpy (out, ", new calling convention");
7d466069
ILT
4700
4701 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
f8c4789c 4702 out = stpcpy (out, ", gnu calling convention");
7d466069 4703 break;
4d6ed7c8
NC
4704
4705 case EM_IA_64:
f8c4789c 4706 out = decode_IA64_machine_flags (out, e_flags, filedata);
4d6ed7c8 4707 break;
179d3252
JT
4708
4709 case EM_VAX:
4710 if ((e_flags & EF_VAX_NONPIC))
f8c4789c 4711 out = stpcpy (out, ", non-PIC");
179d3252 4712 if ((e_flags & EF_VAX_DFLOAT))
f8c4789c 4713 out = stpcpy (out, ", D-Float");
179d3252 4714 if ((e_flags & EF_VAX_GFLOAT))
f8c4789c 4715 out = stpcpy (out, ", G-Float");
179d3252 4716 break;
c7927a3c 4717
f8c4789c 4718 case EM_VISIUM:
619ed720 4719 if (e_flags & EF_VISIUM_ARCH_MCM)
f8c4789c 4720 out = stpcpy (out, ", mcm");
619ed720 4721 else if (e_flags & EF_VISIUM_ARCH_MCM24)
f8c4789c 4722 out = stpcpy (out, ", mcm24");
619ed720 4723 if (e_flags & EF_VISIUM_ARCH_GR6)
f8c4789c 4724 out = stpcpy (out, ", gr6");
619ed720
EB
4725 break;
4726
4046d87a 4727 case EM_RL78:
f8c4789c 4728 out = decode_RL78_machine_flags (out, e_flags);
4046d87a 4729 break;
0b4362b0 4730
c7927a3c 4731 case EM_RX:
f8c4789c 4732 out = decode_RX_machine_flags (out, e_flags);
d4cb0ea0 4733 break;
55786da2
AK
4734
4735 case EM_S390:
4736 if (e_flags & EF_S390_HIGH_GPRS)
f8c4789c 4737 out = stpcpy (out, ", highgprs");
d4cb0ea0 4738 break;
40b36596
JM
4739
4740 case EM_TI_C6000:
4741 if ((e_flags & EF_C6000_REL))
f8c4789c 4742 out = stpcpy (out, ", relocatable module");
d4cb0ea0 4743 break;
13761a11 4744
6e712424
PI
4745 case EM_KVX:
4746 if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_1)
4747 strcat (buf, ", Kalray VLIW kv3-1");
4748 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_2)
4749 strcat (buf, ", Kalray VLIW kv3-2");
4750 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV4_1)
4751 strcat (buf, ", Kalray VLIW kv4-1");
4752 else
4753 strcat (buf, ", unknown KVX MPPA");
4754 break;
4755
13761a11 4756 case EM_MSP430:
f8c4789c 4757 out = decode_MSP430_machine_flags (out, e_flags);
6655dba2
SB
4758 break;
4759
4760 case EM_Z80:
f8c4789c 4761 out = decode_Z80_machine_flags (out, e_flags);
6655dba2 4762 break;
c4a7e6b5 4763
f8c4789c
AM
4764 case EM_LOONGARCH:
4765 out = decode_LOONGARCH_machine_flags (out, e_flags);
e9a0721f 4766 break;
252b5132
RH
4767 }
4768 }
4769
4770 return buf;
4771}
4772
252b5132 4773static const char *
dda8d76d 4774get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4775{
4776 static char buff[32];
4777
4778 switch (osabi)
4779 {
4780 case ELFOSABI_NONE: return "UNIX - System V";
4781 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4782 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4783 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4784 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4785 case ELFOSABI_AIX: return "UNIX - AIX";
4786 case ELFOSABI_IRIX: return "UNIX - IRIX";
4787 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4788 case ELFOSABI_TRU64: return "UNIX - TRU64";
4789 case ELFOSABI_MODESTO: return "Novell - Modesto";
4790 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4791 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4792 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4793 case ELFOSABI_AROS: return "AROS";
11636f9e 4794 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4795 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4796 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4797 default:
40b36596 4798 if (osabi >= 64)
dda8d76d 4799 switch (filedata->file_header.e_machine)
40b36596 4800 {
37870be8
SM
4801 case EM_AMDGPU:
4802 switch (osabi)
4803 {
4804 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4805 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4806 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4807 default:
4808 break;
4809 }
4810 break;
4811
40b36596
JM
4812 case EM_ARM:
4813 switch (osabi)
4814 {
4815 case ELFOSABI_ARM: return "ARM";
18a20338 4816 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4817 default:
4818 break;
4819 }
4820 break;
4821
4822 case EM_MSP430:
4823 case EM_MSP430_OLD:
619ed720 4824 case EM_VISIUM:
40b36596
JM
4825 switch (osabi)
4826 {
4827 case ELFOSABI_STANDALONE: return _("Standalone App");
4828 default:
4829 break;
4830 }
4831 break;
4832
4833 case EM_TI_C6000:
4834 switch (osabi)
4835 {
4836 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4837 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4838 default:
4839 break;
4840 }
4841 break;
4842
4843 default:
4844 break;
4845 }
e9e44622 4846 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4847 return buff;
4848 }
4849}
4850
a06ea964
NC
4851static const char *
4852get_aarch64_segment_type (unsigned long type)
4853{
4854 switch (type)
4855 {
32ec8896 4856 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4857 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4858 default: return NULL;
a06ea964 4859 }
a06ea964
NC
4860}
4861
b294bdf8
MM
4862static const char *
4863get_arm_segment_type (unsigned long type)
4864{
4865 switch (type)
4866 {
32ec8896
NC
4867 case PT_ARM_EXIDX: return "EXIDX";
4868 default: return NULL;
b294bdf8 4869 }
b294bdf8
MM
4870}
4871
b4cbbe8f
AK
4872static const char *
4873get_s390_segment_type (unsigned long type)
4874{
4875 switch (type)
4876 {
4877 case PT_S390_PGSTE: return "S390_PGSTE";
4878 default: return NULL;
4879 }
4880}
4881
d3ba0551
AM
4882static const char *
4883get_mips_segment_type (unsigned long type)
252b5132
RH
4884{
4885 switch (type)
4886 {
32ec8896
NC
4887 case PT_MIPS_REGINFO: return "REGINFO";
4888 case PT_MIPS_RTPROC: return "RTPROC";
4889 case PT_MIPS_OPTIONS: return "OPTIONS";
4890 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4891 default: return NULL;
252b5132 4892 }
252b5132
RH
4893}
4894
103f02d3 4895static const char *
d3ba0551 4896get_parisc_segment_type (unsigned long type)
103f02d3
UD
4897{
4898 switch (type)
4899 {
103f02d3
UD
4900 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4901 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4902 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4903 default: return NULL;
103f02d3 4904 }
103f02d3
UD
4905}
4906
4d6ed7c8 4907static const char *
d3ba0551 4908get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4909{
4910 switch (type)
4911 {
4912 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4913 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4914 default: return NULL;
4d6ed7c8 4915 }
4d6ed7c8
NC
4916}
4917
40b36596
JM
4918static const char *
4919get_tic6x_segment_type (unsigned long type)
4920{
4921 switch (type)
4922 {
32ec8896
NC
4923 case PT_C6000_PHATTR: return "C6000_PHATTR";
4924 default: return NULL;
40b36596 4925 }
40b36596
JM
4926}
4927
fbc95f1e
KC
4928static const char *
4929get_riscv_segment_type (unsigned long type)
4930{
4931 switch (type)
4932 {
4933 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4934 default: return NULL;
4935 }
4936}
4937
df3a023b
AM
4938static const char *
4939get_hpux_segment_type (unsigned long type, unsigned e_machine)
4940{
4941 if (e_machine == EM_PARISC)
4942 switch (type)
4943 {
4944 case PT_HP_TLS: return "HP_TLS";
4945 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4946 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4947 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4948 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4949 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4950 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4951 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4952 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4953 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4954 case PT_HP_PARALLEL: return "HP_PARALLEL";
4955 case PT_HP_FASTBIND: return "HP_FASTBIND";
4956 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4957 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4958 case PT_HP_STACK: return "HP_STACK";
4959 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4960 default: return NULL;
4961 }
4962
4963 if (e_machine == EM_IA_64)
4964 switch (type)
4965 {
4966 case PT_HP_TLS: return "HP_TLS";
4967 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4968 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4969 case PT_IA_64_HP_STACK: return "HP_STACK";
4970 default: return NULL;
4971 }
4972
4973 return NULL;
4974}
4975
5522f910
NC
4976static const char *
4977get_solaris_segment_type (unsigned long type)
4978{
4979 switch (type)
4980 {
4981 case 0x6464e550: return "PT_SUNW_UNWIND";
4982 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4983 case 0x6ffffff7: return "PT_LOSUNW";
4984 case 0x6ffffffa: return "PT_SUNWBSS";
4985 case 0x6ffffffb: return "PT_SUNWSTACK";
4986 case 0x6ffffffc: return "PT_SUNWDTRACE";
4987 case 0x6ffffffd: return "PT_SUNWCAP";
4988 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4989 default: return NULL;
5522f910
NC
4990 }
4991}
4992
252b5132 4993static const char *
dda8d76d 4994get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4995{
b34976b6 4996 static char buff[32];
252b5132
RH
4997
4998 switch (p_type)
4999 {
b34976b6
AM
5000 case PT_NULL: return "NULL";
5001 case PT_LOAD: return "LOAD";
252b5132 5002 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
5003 case PT_INTERP: return "INTERP";
5004 case PT_NOTE: return "NOTE";
5005 case PT_SHLIB: return "SHLIB";
5006 case PT_PHDR: return "PHDR";
13ae64f3 5007 case PT_TLS: return "TLS";
32ec8896 5008 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 5009 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 5010 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 5011 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
cf0e0a0b 5012 case PT_GNU_SFRAME: return "GNU_SFRAME";
65765700 5013
80251d41 5014 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
3eba3ef3
NC
5015 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
5016 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
5017 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 5018
252b5132 5019 default:
df3a023b 5020 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 5021 {
2cf0635d 5022 const char * result;
103f02d3 5023
dda8d76d 5024 switch (filedata->file_header.e_machine)
252b5132 5025 {
a06ea964
NC
5026 case EM_AARCH64:
5027 result = get_aarch64_segment_type (p_type);
5028 break;
b294bdf8
MM
5029 case EM_ARM:
5030 result = get_arm_segment_type (p_type);
5031 break;
252b5132 5032 case EM_MIPS:
4fe85591 5033 case EM_MIPS_RS3_LE:
252b5132
RH
5034 result = get_mips_segment_type (p_type);
5035 break;
103f02d3
UD
5036 case EM_PARISC:
5037 result = get_parisc_segment_type (p_type);
5038 break;
4d6ed7c8
NC
5039 case EM_IA_64:
5040 result = get_ia64_segment_type (p_type);
5041 break;
40b36596
JM
5042 case EM_TI_C6000:
5043 result = get_tic6x_segment_type (p_type);
5044 break;
b4cbbe8f
AK
5045 case EM_S390:
5046 case EM_S390_OLD:
5047 result = get_s390_segment_type (p_type);
5048 break;
fbc95f1e
KC
5049 case EM_RISCV:
5050 result = get_riscv_segment_type (p_type);
5051 break;
252b5132
RH
5052 default:
5053 result = NULL;
5054 break;
5055 }
103f02d3 5056
252b5132
RH
5057 if (result != NULL)
5058 return result;
103f02d3 5059
1a9ccd70 5060 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
5061 }
5062 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 5063 {
df3a023b 5064 const char * result = NULL;
103f02d3 5065
df3a023b 5066 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 5067 {
df3a023b
AM
5068 case ELFOSABI_GNU:
5069 case ELFOSABI_FREEBSD:
5070 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
5071 {
5072 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
5073 result = buff;
5074 }
103f02d3 5075 break;
df3a023b
AM
5076 case ELFOSABI_HPUX:
5077 result = get_hpux_segment_type (p_type,
5078 filedata->file_header.e_machine);
5079 break;
5080 case ELFOSABI_SOLARIS:
5081 result = get_solaris_segment_type (p_type);
00428cca 5082 break;
103f02d3 5083 default:
103f02d3
UD
5084 break;
5085 }
103f02d3
UD
5086 if (result != NULL)
5087 return result;
5088
1a9ccd70 5089 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 5090 }
252b5132 5091 else
e9e44622 5092 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
5093
5094 return buff;
5095 }
5096}
5097
53a346d8
CZ
5098static const char *
5099get_arc_section_type_name (unsigned int sh_type)
5100{
5101 switch (sh_type)
5102 {
5103 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
5104 default:
5105 break;
5106 }
5107 return NULL;
5108}
5109
252b5132 5110static const char *
d3ba0551 5111get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
5112{
5113 switch (sh_type)
5114 {
b34976b6
AM
5115 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
5116 case SHT_MIPS_MSYM: return "MIPS_MSYM";
5117 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
5118 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
5119 case SHT_MIPS_UCODE: return "MIPS_UCODE";
5120 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
5121 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
5122 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
5123 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
5124 case SHT_MIPS_RELD: return "MIPS_RELD";
5125 case SHT_MIPS_IFACE: return "MIPS_IFACE";
5126 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
5127 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
5128 case SHT_MIPS_SHDR: return "MIPS_SHDR";
5129 case SHT_MIPS_FDESC: return "MIPS_FDESC";
5130 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
5131 case SHT_MIPS_DENSE: return "MIPS_DENSE";
5132 case SHT_MIPS_PDESC: return "MIPS_PDESC";
5133 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
5134 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
5135 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
5136 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
5137 case SHT_MIPS_LINE: return "MIPS_LINE";
5138 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
5139 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
5140 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
5141 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
5142 case SHT_MIPS_DWARF: return "MIPS_DWARF";
5143 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
5144 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
5145 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
5146 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
5147 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
5148 case SHT_MIPS_XLATE: return "MIPS_XLATE";
5149 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
5150 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
5151 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
5152 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 5153 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 5154 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 5155 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
5156 default:
5157 break;
5158 }
5159 return NULL;
5160}
5161
103f02d3 5162static const char *
d3ba0551 5163get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
5164{
5165 switch (sh_type)
5166 {
5167 case SHT_PARISC_EXT: return "PARISC_EXT";
5168 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
5169 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
5170 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
5171 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
5172 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 5173 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 5174 default: return NULL;
103f02d3 5175 }
103f02d3
UD
5176}
5177
4d6ed7c8 5178static const char *
dda8d76d 5179get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 5180{
18bd398b 5181 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 5182 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 5183 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 5184
4d6ed7c8
NC
5185 switch (sh_type)
5186 {
148b93f2
NC
5187 case SHT_IA_64_EXT: return "IA_64_EXT";
5188 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
5189 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
5190 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
5191 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
5192 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
5193 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
5194 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
5195 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
5196 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
5197 default:
5198 break;
5199 }
5200 return NULL;
5201}
5202
d2b2c203
DJ
5203static const char *
5204get_x86_64_section_type_name (unsigned int sh_type)
5205{
5206 switch (sh_type)
5207 {
5208 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 5209 default: return NULL;
d2b2c203 5210 }
d2b2c203
DJ
5211}
5212
a06ea964
NC
5213static const char *
5214get_aarch64_section_type_name (unsigned int sh_type)
5215{
5216 switch (sh_type)
5217 {
32ec8896
NC
5218 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
5219 default: return NULL;
a06ea964 5220 }
a06ea964
NC
5221}
5222
40a18ebd
NC
5223static const char *
5224get_arm_section_type_name (unsigned int sh_type)
5225{
5226 switch (sh_type)
5227 {
7f6fed87
NC
5228 case SHT_ARM_EXIDX: return "ARM_EXIDX";
5229 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
5230 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
5231 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
5232 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 5233 default: return NULL;
40a18ebd 5234 }
40a18ebd
NC
5235}
5236
40b36596
JM
5237static const char *
5238get_tic6x_section_type_name (unsigned int sh_type)
5239{
5240 switch (sh_type)
5241 {
32ec8896
NC
5242 case SHT_C6000_UNWIND: return "C6000_UNWIND";
5243 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
5244 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
5245 case SHT_TI_ICODE: return "TI_ICODE";
5246 case SHT_TI_XREF: return "TI_XREF";
5247 case SHT_TI_HANDLER: return "TI_HANDLER";
5248 case SHT_TI_INITINFO: return "TI_INITINFO";
5249 case SHT_TI_PHATTRS: return "TI_PHATTRS";
5250 default: return NULL;
40b36596 5251 }
40b36596
JM
5252}
5253
13761a11 5254static const char *
b0191216 5255get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
5256{
5257 switch (sh_type)
5258 {
32ec8896
NC
5259 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
5260 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
5261 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
5262 default: return NULL;
13761a11
NC
5263 }
5264}
5265
fe944acf
FT
5266static const char *
5267get_nfp_section_type_name (unsigned int sh_type)
5268{
5269 switch (sh_type)
5270 {
5271 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
5272 case SHT_NFP_INITREG: return "NFP_INITREG";
5273 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
5274 default: return NULL;
5275 }
5276}
5277
685080f2
NC
5278static const char *
5279get_v850_section_type_name (unsigned int sh_type)
5280{
5281 switch (sh_type)
5282 {
32ec8896
NC
5283 case SHT_V850_SCOMMON: return "V850 Small Common";
5284 case SHT_V850_TCOMMON: return "V850 Tiny Common";
5285 case SHT_V850_ZCOMMON: return "V850 Zero Common";
5286 case SHT_RENESAS_IOP: return "RENESAS IOP";
5287 case SHT_RENESAS_INFO: return "RENESAS INFO";
5288 default: return NULL;
685080f2
NC
5289 }
5290}
5291
2dc8dd17
JW
5292static const char *
5293get_riscv_section_type_name (unsigned int sh_type)
5294{
5295 switch (sh_type)
5296 {
5297 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5298 default: return NULL;
5299 }
5300}
5301
0861f561
CQ
5302static const char *
5303get_csky_section_type_name (unsigned int sh_type)
5304{
5305 switch (sh_type)
5306 {
5307 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
5308 default: return NULL;
5309 }
5310}
5311
252b5132 5312static const char *
dda8d76d 5313get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 5314{
b34976b6 5315 static char buff[32];
9fb71ee4 5316 const char * result;
252b5132
RH
5317
5318 switch (sh_type)
5319 {
5320 case SHT_NULL: return "NULL";
5321 case SHT_PROGBITS: return "PROGBITS";
5322 case SHT_SYMTAB: return "SYMTAB";
5323 case SHT_STRTAB: return "STRTAB";
5324 case SHT_RELA: return "RELA";
dd207c13 5325 case SHT_RELR: return "RELR";
252b5132
RH
5326 case SHT_HASH: return "HASH";
5327 case SHT_DYNAMIC: return "DYNAMIC";
5328 case SHT_NOTE: return "NOTE";
5329 case SHT_NOBITS: return "NOBITS";
5330 case SHT_REL: return "REL";
5331 case SHT_SHLIB: return "SHLIB";
5332 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
5333 case SHT_INIT_ARRAY: return "INIT_ARRAY";
5334 case SHT_FINI_ARRAY: return "FINI_ARRAY";
5335 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 5336 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 5337 case SHT_GROUP: return "GROUP";
67ce483b 5338 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
5339 case SHT_GNU_verdef: return "VERDEF";
5340 case SHT_GNU_verneed: return "VERNEED";
5341 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
5342 case 0x6ffffff0: return "VERSYM";
5343 case 0x6ffffffc: return "VERDEF";
252b5132
RH
5344 case 0x7ffffffd: return "AUXILIARY";
5345 case 0x7fffffff: return "FILTER";
047b2264 5346 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
5347
5348 default:
5349 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
5350 {
dda8d76d 5351 switch (filedata->file_header.e_machine)
252b5132 5352 {
53a346d8
CZ
5353 case EM_ARC:
5354 case EM_ARC_COMPACT:
5355 case EM_ARC_COMPACT2:
b5c37946
SJ
5356 case EM_ARC_COMPACT3:
5357 case EM_ARC_COMPACT3_64:
53a346d8
CZ
5358 result = get_arc_section_type_name (sh_type);
5359 break;
252b5132 5360 case EM_MIPS:
4fe85591 5361 case EM_MIPS_RS3_LE:
252b5132
RH
5362 result = get_mips_section_type_name (sh_type);
5363 break;
103f02d3
UD
5364 case EM_PARISC:
5365 result = get_parisc_section_type_name (sh_type);
5366 break;
4d6ed7c8 5367 case EM_IA_64:
dda8d76d 5368 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 5369 break;
d2b2c203 5370 case EM_X86_64:
8a9036a4 5371 case EM_L1OM:
7a9068fe 5372 case EM_K1OM:
d2b2c203
DJ
5373 result = get_x86_64_section_type_name (sh_type);
5374 break;
a06ea964
NC
5375 case EM_AARCH64:
5376 result = get_aarch64_section_type_name (sh_type);
5377 break;
40a18ebd
NC
5378 case EM_ARM:
5379 result = get_arm_section_type_name (sh_type);
5380 break;
40b36596
JM
5381 case EM_TI_C6000:
5382 result = get_tic6x_section_type_name (sh_type);
5383 break;
13761a11 5384 case EM_MSP430:
b0191216 5385 result = get_msp430_section_type_name (sh_type);
13761a11 5386 break;
fe944acf
FT
5387 case EM_NFP:
5388 result = get_nfp_section_type_name (sh_type);
5389 break;
685080f2
NC
5390 case EM_V800:
5391 case EM_V850:
5392 case EM_CYGNUS_V850:
5393 result = get_v850_section_type_name (sh_type);
5394 break;
2dc8dd17
JW
5395 case EM_RISCV:
5396 result = get_riscv_section_type_name (sh_type);
5397 break;
0861f561
CQ
5398 case EM_CSKY:
5399 result = get_csky_section_type_name (sh_type);
5400 break;
252b5132
RH
5401 default:
5402 result = NULL;
5403 break;
5404 }
5405
5406 if (result != NULL)
5407 return result;
5408
9fb71ee4 5409 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5410 }
5411 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5412 {
dda8d76d 5413 switch (filedata->file_header.e_machine)
148b93f2
NC
5414 {
5415 case EM_IA_64:
dda8d76d 5416 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5417 break;
5418 default:
dda8d76d 5419 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5420 result = get_solaris_section_type (sh_type);
5421 else
1b4b80bf
NC
5422 {
5423 switch (sh_type)
5424 {
5425 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5426 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5427 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5428 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5429 default:
5430 result = NULL;
5431 break;
5432 }
5433 }
148b93f2
NC
5434 break;
5435 }
5436
5437 if (result != NULL)
5438 return result;
5439
9fb71ee4 5440 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5441 }
252b5132 5442 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5443 {
dda8d76d 5444 switch (filedata->file_header.e_machine)
685080f2
NC
5445 {
5446 case EM_V800:
5447 case EM_V850:
5448 case EM_CYGNUS_V850:
9fb71ee4 5449 result = get_v850_section_type_name (sh_type);
a9fb83be 5450 break;
685080f2 5451 default:
9fb71ee4 5452 result = NULL;
685080f2
NC
5453 break;
5454 }
5455
9fb71ee4
NC
5456 if (result != NULL)
5457 return result;
5458
5459 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5460 }
252b5132 5461 else
a7dbfd1c
NC
5462 /* This message is probably going to be displayed in a 15
5463 character wide field, so put the hex value first. */
5464 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5465
252b5132
RH
5466 return buff;
5467 }
5468}
5469
79bc120c
NC
5470enum long_option_values
5471{
5472 OPTION_DEBUG_DUMP = 512,
5473 OPTION_DYN_SYMS,
0f03783c 5474 OPTION_LTO_SYMS,
79bc120c
NC
5475 OPTION_DWARF_DEPTH,
5476 OPTION_DWARF_START,
5477 OPTION_DWARF_CHECK,
5478 OPTION_CTF_DUMP,
5479 OPTION_CTF_PARENT,
5480 OPTION_CTF_SYMBOLS,
5481 OPTION_CTF_STRINGS,
42b6953b 5482 OPTION_SFRAME_DUMP,
79bc120c
NC
5483 OPTION_WITH_SYMBOL_VERSIONS,
5484 OPTION_RECURSE_LIMIT,
5485 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
5486 OPTION_NO_DEMANGLING,
5487 OPTION_SYM_BASE
79bc120c 5488};
2979dc34 5489
85b1c36d 5490static struct option options[] =
252b5132 5491{
79bc120c
NC
5492 /* Note - This table is alpha-sorted on the 'val'
5493 field in order to make adding new options easier. */
5494 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5495 {"all", no_argument, 0, 'a'},
79bc120c
NC
5496 {"demangle", optional_argument, 0, 'C'},
5497 {"archive-index", no_argument, 0, 'c'},
5498 {"use-dynamic", no_argument, 0, 'D'},
5499 {"dynamic", no_argument, 0, 'd'},
b34976b6 5500 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5501 {"section-groups", no_argument, 0, 'g'},
5502 {"help", no_argument, 0, 'H'},
5503 {"file-header", no_argument, 0, 'h'},
b34976b6 5504 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5505 {"lint", no_argument, 0, 'L'},
5506 {"enable-checks", no_argument, 0, 'L'},
5507 {"program-headers", no_argument, 0, 'l'},
b34976b6 5508 {"segments", no_argument, 0, 'l'},
595cf52e 5509 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5510 {"notes", no_argument, 0, 'n'},
ca0e11aa 5511 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5512 {"string-dump", required_argument, 0, 'p'},
5513 {"relocated-dump", required_argument, 0, 'R'},
5514 {"relocs", no_argument, 0, 'r'},
5515 {"section-headers", no_argument, 0, 'S'},
5516 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5517 {"symbols", no_argument, 0, 's'},
5518 {"syms", no_argument, 0, 's'},
79bc120c
NC
5519 {"silent-truncation",no_argument, 0, 'T'},
5520 {"section-details", no_argument, 0, 't'},
b3aa80b4 5521 {"unicode", required_argument, NULL, 'U'},
09c11c86 5522 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5523 {"version-info", no_argument, 0, 'V'},
5524 {"version", no_argument, 0, 'v'},
5525 {"wide", no_argument, 0, 'W'},
b34976b6 5526 {"hex-dump", required_argument, 0, 'x'},
0e602686 5527 {"decompress", no_argument, 0, 'z'},
252b5132 5528
79bc120c
NC
5529 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5530 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5531 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5532 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5533 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5534 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5535 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5536 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5537 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5538 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5539#ifdef ENABLE_LIBCTF
d344b407 5540 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5541 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5542 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5543 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5544#endif
42b6953b 5545 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
047c3dbf 5546 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5547
b34976b6 5548 {0, no_argument, 0, 0}
252b5132
RH
5549};
5550
5551static void
2cf0635d 5552usage (FILE * stream)
252b5132 5553{
92f01d61
JM
5554 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5555 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5556 fprintf (stream, _(" Options are:\n"));
5557 fprintf (stream, _("\
5558 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5559 fprintf (stream, _("\
5560 -h --file-header Display the ELF file header\n"));
5561 fprintf (stream, _("\
5562 -l --program-headers Display the program headers\n"));
5563 fprintf (stream, _("\
5564 --segments An alias for --program-headers\n"));
5565 fprintf (stream, _("\
5566 -S --section-headers Display the sections' header\n"));
5567 fprintf (stream, _("\
5568 --sections An alias for --section-headers\n"));
5569 fprintf (stream, _("\
5570 -g --section-groups Display the section groups\n"));
5571 fprintf (stream, _("\
5572 -t --section-details Display the section details\n"));
5573 fprintf (stream, _("\
5574 -e --headers Equivalent to: -h -l -S\n"));
5575 fprintf (stream, _("\
5576 -s --syms Display the symbol table\n"));
5577 fprintf (stream, _("\
5578 --symbols An alias for --syms\n"));
5579 fprintf (stream, _("\
5580 --dyn-syms Display the dynamic symbol table\n"));
5581 fprintf (stream, _("\
5582 --lto-syms Display LTO symbol tables\n"));
5583 fprintf (stream, _("\
047c3dbf
NL
5584 --sym-base=[0|8|10|16] \n\
5585 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5586 mixed (the default), octal, decimal, hexadecimal.\n"));
5587 fprintf (stream, _("\
0d646226
AM
5588 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5589 display_demangler_styles (stream, _("\
5590 STYLE can be "));
d6249f5f
AM
5591 fprintf (stream, _("\
5592 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5593 fprintf (stream, _("\
5594 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5595 fprintf (stream, _("\
5596 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5597 fprintf (stream, _("\
5598 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5599 Display unicode characters as determined by the current locale\n\
5600 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5601 escape sequences, or treat them as invalid and display as\n\
5602 \"{hex sequences}\"\n"));
d6249f5f
AM
5603 fprintf (stream, _("\
5604 -n --notes Display the core notes (if present)\n"));
5605 fprintf (stream, _("\
5606 -r --relocs Display the relocations (if present)\n"));
5607 fprintf (stream, _("\
5608 -u --unwind Display the unwind info (if present)\n"));
5609 fprintf (stream, _("\
5610 -d --dynamic Display the dynamic section (if present)\n"));
5611 fprintf (stream, _("\
5612 -V --version-info Display the version sections (if present)\n"));
5613 fprintf (stream, _("\
5614 -A --arch-specific Display architecture specific information (if any)\n"));
5615 fprintf (stream, _("\
5616 -c --archive-index Display the symbol/file index in an archive\n"));
5617 fprintf (stream, _("\
5618 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5619 fprintf (stream, _("\
5620 -L --lint|--enable-checks\n\
5621 Display warning messages for possible problems\n"));
5622 fprintf (stream, _("\
09c11c86 5623 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5624 Dump the contents of section <number|name> as bytes\n"));
5625 fprintf (stream, _("\
09c11c86 5626 -p --string-dump=<number|name>\n\
d6249f5f
AM
5627 Dump the contents of section <number|name> as strings\n"));
5628 fprintf (stream, _("\
cf13d699 5629 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5630 Dump the relocated contents of section <number|name>\n"));
5631 fprintf (stream, _("\
5632 -z --decompress Decompress section before dumping it\n"));
5633 fprintf (stream, _("\
5634 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5635 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5636 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5637 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5638 U/=trace_info]\n\
5639 Display the contents of DWARF debug sections\n"));
5640 fprintf (stream, _("\
5641 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5642 debuginfo files\n"));
5643 fprintf (stream, _("\
5644 -P --process-links Display the contents of non-debug sections in separate\n\
5645 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5646#if DEFAULT_FOR_FOLLOW_LINKS
5647 fprintf (stream, _("\
d6249f5f
AM
5648 -wK --debug-dump=follow-links\n\
5649 Follow links to separate debug info files (default)\n"));
5650 fprintf (stream, _("\
5651 -wN --debug-dump=no-follow-links\n\
5652 Do not follow links to separate debug info files\n"));
c46b7066
NC
5653#else
5654 fprintf (stream, _("\
d6249f5f
AM
5655 -wK --debug-dump=follow-links\n\
5656 Follow links to separate debug info files\n"));
5657 fprintf (stream, _("\
5658 -wN --debug-dump=no-follow-links\n\
5659 Do not follow links to separate debug info files\n\
5660 (default)\n"));
bed566bb
NC
5661#endif
5662#if HAVE_LIBDEBUGINFOD
5663 fprintf (stream, _("\
5664 -wD --debug-dump=use-debuginfod\n\
5665 When following links, also query debuginfod servers (default)\n"));
5666 fprintf (stream, _("\
5667 -wE --debug-dump=do-not-use-debuginfod\n\
5668 When following links, do not query debuginfod servers\n"));
c46b7066 5669#endif
fd2f0033 5670 fprintf (stream, _("\
d6249f5f
AM
5671 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5672 fprintf (stream, _("\
5673 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5674#ifdef ENABLE_LIBCTF
7d9813f1 5675 fprintf (stream, _("\
d6249f5f
AM
5676 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5677 fprintf (stream, _("\
80b56fad 5678 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5679 fprintf (stream, _("\
7d9813f1 5680 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5681 Use section <number|name> as the CTF external symtab\n"));
5682 fprintf (stream, _("\
7d9813f1 5683 --ctf-strings=<number|name>\n\
d6249f5f 5684 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5685#endif
42b6953b
IB
5686 fprintf (stream, _("\
5687 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
7d9813f1 5688
252b5132 5689#ifdef SUPPORT_DISASSEMBLY
92f01d61 5690 fprintf (stream, _("\
09c11c86
NC
5691 -i --instruction-dump=<number|name>\n\
5692 Disassemble the contents of section <number|name>\n"));
252b5132 5693#endif
92f01d61 5694 fprintf (stream, _("\
d6249f5f
AM
5695 -I --histogram Display histogram of bucket list lengths\n"));
5696 fprintf (stream, _("\
5697 -W --wide Allow output width to exceed 80 characters\n"));
5698 fprintf (stream, _("\
5699 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5700 fprintf (stream, _("\
5701 @<file> Read options from <file>\n"));
5702 fprintf (stream, _("\
5703 -H --help Display this information\n"));
5704 fprintf (stream, _("\
8b53311e 5705 -v --version Display the version number of readelf\n"));
1118d252 5706
92f01d61
JM
5707 if (REPORT_BUGS_TO[0] && stream == stdout)
5708 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5709
92f01d61 5710 exit (stream == stdout ? 0 : 1);
252b5132
RH
5711}
5712
18bd398b
NC
5713/* Record the fact that the user wants the contents of section number
5714 SECTION to be displayed using the method(s) encoded as flags bits
5715 in TYPE. Note, TYPE can be zero if we are creating the array for
5716 the first time. */
5717
252b5132 5718static void
6431e409
AM
5719request_dump_bynumber (struct dump_data *dumpdata,
5720 unsigned int section, dump_type type)
252b5132 5721{
6431e409 5722 if (section >= dumpdata->num_dump_sects)
252b5132 5723 {
2cf0635d 5724 dump_type * new_dump_sects;
252b5132 5725
3f5e193b 5726 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5727 sizeof (* new_dump_sects));
252b5132
RH
5728
5729 if (new_dump_sects == NULL)
591a748a 5730 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5731 else
5732 {
6431e409 5733 if (dumpdata->dump_sects)
21b65bac
NC
5734 {
5735 /* Copy current flag settings. */
6431e409
AM
5736 memcpy (new_dump_sects, dumpdata->dump_sects,
5737 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5738
6431e409 5739 free (dumpdata->dump_sects);
21b65bac 5740 }
252b5132 5741
6431e409
AM
5742 dumpdata->dump_sects = new_dump_sects;
5743 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5744 }
5745 }
5746
6431e409
AM
5747 if (dumpdata->dump_sects)
5748 dumpdata->dump_sects[section] |= type;
252b5132
RH
5749}
5750
aef1f6d0
DJ
5751/* Request a dump by section name. */
5752
5753static void
2cf0635d 5754request_dump_byname (const char * section, dump_type type)
aef1f6d0 5755{
2cf0635d 5756 struct dump_list_entry * new_request;
aef1f6d0 5757
3f5e193b
NC
5758 new_request = (struct dump_list_entry *)
5759 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5760 if (!new_request)
591a748a 5761 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5762
5763 new_request->name = strdup (section);
5764 if (!new_request->name)
591a748a 5765 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5766
5767 new_request->type = type;
5768
5769 new_request->next = dump_sects_byname;
5770 dump_sects_byname = new_request;
5771}
5772
cf13d699 5773static inline void
6431e409 5774request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5775{
5776 int section;
5777 char * cp;
5778
015dc7e1 5779 do_dump = true;
cf13d699
NC
5780 section = strtoul (optarg, & cp, 0);
5781
5782 if (! *cp && section >= 0)
6431e409 5783 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5784 else
5785 request_dump_byname (optarg, type);
5786}
5787
252b5132 5788static void
6431e409 5789parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5790{
5791 int c;
5792
5793 if (argc < 2)
92f01d61 5794 usage (stderr);
252b5132
RH
5795
5796 while ((c = getopt_long
b3aa80b4 5797 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5798 {
252b5132
RH
5799 switch (c)
5800 {
5801 case 0:
5802 /* Long options. */
5803 break;
5804 case 'H':
92f01d61 5805 usage (stdout);
252b5132
RH
5806 break;
5807
5808 case 'a':
015dc7e1
AM
5809 do_syms = true;
5810 do_reloc = true;
5811 do_unwind = true;
5812 do_dynamic = true;
5813 do_header = true;
5814 do_sections = true;
5815 do_section_groups = true;
5816 do_segments = true;
5817 do_version = true;
5818 do_histogram = true;
5819 do_arch = true;
5820 do_notes = true;
252b5132 5821 break;
79bc120c 5822
f5842774 5823 case 'g':
015dc7e1 5824 do_section_groups = true;
f5842774 5825 break;
5477e8a0 5826 case 't':
595cf52e 5827 case 'N':
015dc7e1
AM
5828 do_sections = true;
5829 do_section_details = true;
595cf52e 5830 break;
252b5132 5831 case 'e':
015dc7e1
AM
5832 do_header = true;
5833 do_sections = true;
5834 do_segments = true;
252b5132 5835 break;
a952a375 5836 case 'A':
015dc7e1 5837 do_arch = true;
a952a375 5838 break;
252b5132 5839 case 'D':
015dc7e1 5840 do_using_dynamic = true;
252b5132
RH
5841 break;
5842 case 'r':
015dc7e1 5843 do_reloc = true;
252b5132 5844 break;
4d6ed7c8 5845 case 'u':
015dc7e1 5846 do_unwind = true;
4d6ed7c8 5847 break;
252b5132 5848 case 'h':
015dc7e1 5849 do_header = true;
252b5132
RH
5850 break;
5851 case 'l':
015dc7e1 5852 do_segments = true;
252b5132
RH
5853 break;
5854 case 's':
015dc7e1 5855 do_syms = true;
252b5132
RH
5856 break;
5857 case 'S':
015dc7e1 5858 do_sections = true;
252b5132
RH
5859 break;
5860 case 'd':
015dc7e1 5861 do_dynamic = true;
252b5132 5862 break;
a952a375 5863 case 'I':
015dc7e1 5864 do_histogram = true;
a952a375 5865 break;
779fe533 5866 case 'n':
015dc7e1 5867 do_notes = true;
779fe533 5868 break;
4145f1d5 5869 case 'c':
015dc7e1 5870 do_archive_index = true;
4145f1d5 5871 break;
1b513401 5872 case 'L':
015dc7e1 5873 do_checks = true;
1b513401 5874 break;
ca0e11aa 5875 case 'P':
015dc7e1
AM
5876 process_links = true;
5877 do_follow_links = true;
e1dbfc17 5878 dump_any_debugging = true;
ca0e11aa 5879 break;
252b5132 5880 case 'x':
6431e409 5881 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5882 break;
09c11c86 5883 case 'p':
6431e409 5884 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5885 break;
5886 case 'R':
6431e409 5887 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5888 break;
0e602686 5889 case 'z':
015dc7e1 5890 decompress_dumps = true;
0e602686 5891 break;
252b5132 5892 case 'w':
0f03783c 5893 if (optarg == NULL)
613ff48b 5894 {
015dc7e1 5895 do_debugging = true;
94585d6d
NC
5896 do_dump = true;
5897 dump_any_debugging = true;
613ff48b
CC
5898 dwarf_select_sections_all ();
5899 }
252b5132
RH
5900 else
5901 {
015dc7e1 5902 do_debugging = false;
94585d6d
NC
5903 if (dwarf_select_sections_by_letters (optarg))
5904 {
5905 do_dump = true;
5906 dump_any_debugging = true;
5907 }
252b5132
RH
5908 }
5909 break;
2979dc34 5910 case OPTION_DEBUG_DUMP:
0f03783c 5911 if (optarg == NULL)
d6249f5f 5912 {
94585d6d 5913 do_dump = true;
d6249f5f 5914 do_debugging = true;
94585d6d 5915 dump_any_debugging = true;
d6249f5f
AM
5916 dwarf_select_sections_all ();
5917 }
2979dc34
JJ
5918 else
5919 {
015dc7e1 5920 do_debugging = false;
94585d6d
NC
5921 if (dwarf_select_sections_by_names (optarg))
5922 {
5923 do_dump = true;
5924 dump_any_debugging = true;
5925 }
2979dc34
JJ
5926 }
5927 break;
fd2f0033
TT
5928 case OPTION_DWARF_DEPTH:
5929 {
5930 char *cp;
5931
5932 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5933 }
5934 break;
5935 case OPTION_DWARF_START:
5936 {
5937 char *cp;
5938
5939 dwarf_start_die = strtoul (optarg, & cp, 0);
5940 }
5941 break;
4723351a 5942 case OPTION_DWARF_CHECK:
015dc7e1 5943 dwarf_check = true;
4723351a 5944 break;
7d9813f1 5945 case OPTION_CTF_DUMP:
015dc7e1 5946 do_ctf = true;
6431e409 5947 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5948 break;
5949 case OPTION_CTF_SYMBOLS:
df16e041 5950 free (dump_ctf_symtab_name);
7d9813f1
NA
5951 dump_ctf_symtab_name = strdup (optarg);
5952 break;
5953 case OPTION_CTF_STRINGS:
df16e041 5954 free (dump_ctf_strtab_name);
7d9813f1
NA
5955 dump_ctf_strtab_name = strdup (optarg);
5956 break;
5957 case OPTION_CTF_PARENT:
df16e041 5958 free (dump_ctf_parent_name);
7d9813f1
NA
5959 dump_ctf_parent_name = strdup (optarg);
5960 break;
42b6953b
IB
5961 case OPTION_SFRAME_DUMP:
5962 do_sframe = true;
5963 /* Providing section name is optional. request_dump (), however,
5964 thrives on non NULL optarg. Handle it explicitly here. */
5965 if (optarg != NULL)
5966 request_dump (dumpdata, SFRAME_DUMP);
5967 else
5968 {
5969 do_dump = true;
5970 const char *sframe_sec_name = strdup (".sframe");
5971 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
5972 }
5973 break;
2c610e4b 5974 case OPTION_DYN_SYMS:
015dc7e1 5975 do_dyn_syms = true;
2c610e4b 5976 break;
0f03783c 5977 case OPTION_LTO_SYMS:
015dc7e1 5978 do_lto_syms = true;
0f03783c 5979 break;
252b5132
RH
5980#ifdef SUPPORT_DISASSEMBLY
5981 case 'i':
6431e409 5982 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5983 break;
252b5132
RH
5984#endif
5985 case 'v':
5986 print_version (program_name);
5987 break;
5988 case 'V':
015dc7e1 5989 do_version = true;
252b5132 5990 break;
d974e256 5991 case 'W':
015dc7e1 5992 do_wide = true;
d974e256 5993 break;
0942c7ab 5994 case 'T':
015dc7e1 5995 do_not_show_symbol_truncation = true;
0942c7ab 5996 break;
79bc120c 5997 case 'C':
015dc7e1 5998 do_demangle = true;
79bc120c
NC
5999 if (optarg != NULL)
6000 {
6001 enum demangling_styles style;
6002
6003 style = cplus_demangle_name_to_style (optarg);
6004 if (style == unknown_demangling)
6005 error (_("unknown demangling style `%s'"), optarg);
6006
6007 cplus_demangle_set_style (style);
6008 }
6009 break;
6010 case OPTION_NO_DEMANGLING:
015dc7e1 6011 do_demangle = false;
79bc120c
NC
6012 break;
6013 case OPTION_RECURSE_LIMIT:
6014 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
6015 break;
6016 case OPTION_NO_RECURSE_LIMIT:
6017 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
6018 break;
6019 case OPTION_WITH_SYMBOL_VERSIONS:
6020 /* Ignored for backward compatibility. */
6021 break;
b9e920ec 6022
b3aa80b4
NC
6023 case 'U':
6024 if (optarg == NULL)
6025 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
6026 else if (streq (optarg, "default") || streq (optarg, "d"))
6027 unicode_display = unicode_default;
6028 else if (streq (optarg, "locale") || streq (optarg, "l"))
6029 unicode_display = unicode_locale;
6030 else if (streq (optarg, "escape") || streq (optarg, "e"))
6031 unicode_display = unicode_escape;
6032 else if (streq (optarg, "invalid") || streq (optarg, "i"))
6033 unicode_display = unicode_invalid;
6034 else if (streq (optarg, "hex") || streq (optarg, "x"))
6035 unicode_display = unicode_hex;
6036 else if (streq (optarg, "highlight") || streq (optarg, "h"))
6037 unicode_display = unicode_highlight;
6038 else
6039 error (_("invalid argument to -U/--unicode: %s"), optarg);
6040 break;
6041
047c3dbf
NL
6042 case OPTION_SYM_BASE:
6043 sym_base = 0;
6044 if (optarg != NULL)
6045 {
6046 sym_base = strtoul (optarg, NULL, 0);
6047 switch (sym_base)
6048 {
6049 case 0:
6050 case 8:
6051 case 10:
6052 case 16:
6053 break;
6054
6055 default:
6056 sym_base = 0;
6057 break;
6058 }
6059 }
6060 break;
6061
252b5132 6062 default:
252b5132
RH
6063 /* xgettext:c-format */
6064 error (_("Invalid option '-%c'\n"), c);
1a0670f3 6065 /* Fall through. */
252b5132 6066 case '?':
92f01d61 6067 usage (stderr);
252b5132
RH
6068 }
6069 }
6070
4d6ed7c8 6071 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 6072 && !do_segments && !do_header && !do_dump && !do_version
f5842774 6073 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 6074 && !do_section_groups && !do_archive_index
0f03783c 6075 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
6076 {
6077 if (do_checks)
6078 {
015dc7e1
AM
6079 check_all = true;
6080 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
6081 do_segments = do_header = do_dump = do_version = true;
6082 do_histogram = do_debugging = do_arch = do_notes = true;
6083 do_section_groups = do_archive_index = do_dyn_syms = true;
6084 do_lto_syms = true;
1b513401
NC
6085 }
6086 else
6087 usage (stderr);
6088 }
252b5132
RH
6089}
6090
6091static const char *
d3ba0551 6092get_elf_class (unsigned int elf_class)
252b5132 6093{
b34976b6 6094 static char buff[32];
103f02d3 6095
252b5132
RH
6096 switch (elf_class)
6097 {
6098 case ELFCLASSNONE: return _("none");
e3c8793a
NC
6099 case ELFCLASS32: return "ELF32";
6100 case ELFCLASS64: return "ELF64";
ab5e7794 6101 default:
e9e44622 6102 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 6103 return buff;
252b5132
RH
6104 }
6105}
6106
6107static const char *
d3ba0551 6108get_data_encoding (unsigned int encoding)
252b5132 6109{
b34976b6 6110 static char buff[32];
103f02d3 6111
252b5132
RH
6112 switch (encoding)
6113 {
6114 case ELFDATANONE: return _("none");
33c63f9d
CM
6115 case ELFDATA2LSB: return _("2's complement, little endian");
6116 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 6117 default:
e9e44622 6118 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 6119 return buff;
252b5132
RH
6120 }
6121}
6122
521f7268
NC
6123static bool
6124check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
6125{
6126 if (header->e_ident[EI_MAG0] == ELFMAG0
6127 && header->e_ident[EI_MAG1] == ELFMAG1
6128 && header->e_ident[EI_MAG2] == ELFMAG2
6129 && header->e_ident[EI_MAG3] == ELFMAG3)
6130 return true;
6131
6132 /* Some compilers produce object files that are not in the ELF file format.
6133 As an aid to users of readelf, try to identify these cases and suggest
6134 alternative tools.
6135
6136 FIXME: It is not clear if all four bytes are used as constant magic
6137 valus by all compilers. It may be necessary to recode this function if
6138 different tools use different length sequences. */
6139
6140 static struct
6141 {
6142 unsigned char magic[4];
6143 const char * obj_message;
6144 const char * ar_message;
6145 }
6146 known_magic[] =
6147 {
6148 { { 'B', 'C', 0xc0, 0xde },
6149 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
6150 N_("This is a LLVM bitcode file - try extracing and then using llvm-bcanalyzer\n")
6151 },
6152 { { 'g', 'o', ' ', 'o' },
6153 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
6154 NULL
6155 }
6156 };
6157 int i;
6158
6159 for (i = ARRAY_SIZE (known_magic); i--;)
6160 {
6161 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
6162 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
6163 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
6164 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
6165 {
6166 /* Some compiler's analyzer tools do not handle archives,
6167 so we provide two different kinds of error message. */
6168 if (filedata->archive_file_size > 0
6169 && known_magic[i].ar_message != NULL)
b3ea2010 6170 error ("%s", known_magic[i].ar_message);
521f7268 6171 else
b3ea2010 6172 error ("%s", known_magic[i].obj_message);
521f7268
NC
6173 return false;
6174 }
6175 }
6176
6177 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
6178 return false;
6179}
6180
dda8d76d 6181/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 6182
015dc7e1 6183static bool
dda8d76d 6184process_file_header (Filedata * filedata)
252b5132 6185{
dda8d76d
NC
6186 Elf_Internal_Ehdr * header = & filedata->file_header;
6187
521f7268
NC
6188 if (! check_magic_number (filedata, header))
6189 return false;
252b5132 6190
ca0e11aa
NC
6191 if (! filedata->is_separate)
6192 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 6193
252b5132
RH
6194 if (do_header)
6195 {
32ec8896 6196 unsigned i;
252b5132 6197
ca0e11aa
NC
6198 if (filedata->is_separate)
6199 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
6200 else
6201 printf (_("ELF Header:\n"));
252b5132 6202 printf (_(" Magic: "));
b34976b6 6203 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 6204 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
6205 printf ("\n");
6206 printf (_(" Class: %s\n"),
dda8d76d 6207 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 6208 printf (_(" Data: %s\n"),
dda8d76d 6209 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 6210 printf (_(" Version: %d%s\n"),
dda8d76d
NC
6211 header->e_ident[EI_VERSION],
6212 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 6213 ? _(" (current)")
dda8d76d 6214 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 6215 ? _(" <unknown>")
789be9f7 6216 : "")));
252b5132 6217 printf (_(" OS/ABI: %s\n"),
dda8d76d 6218 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 6219 printf (_(" ABI Version: %d\n"),
dda8d76d 6220 header->e_ident[EI_ABIVERSION]);
252b5132 6221 printf (_(" Type: %s\n"),
93df3340 6222 get_file_type (filedata));
252b5132 6223 printf (_(" Machine: %s\n"),
dda8d76d 6224 get_machine_name (header->e_machine));
252b5132 6225 printf (_(" Version: 0x%lx\n"),
e8a64888 6226 header->e_version);
76da6bbe 6227
f7a99963 6228 printf (_(" Entry point address: "));
e8a64888 6229 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 6230 printf (_("\n Start of program headers: "));
e8a64888 6231 print_vma (header->e_phoff, DEC);
f7a99963 6232 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 6233 print_vma (header->e_shoff, DEC);
f7a99963 6234 printf (_(" (bytes into file)\n"));
76da6bbe 6235
252b5132 6236 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 6237 header->e_flags,
dda8d76d 6238 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
6239 printf (_(" Size of this header: %u (bytes)\n"),
6240 header->e_ehsize);
6241 printf (_(" Size of program headers: %u (bytes)\n"),
6242 header->e_phentsize);
6243 printf (_(" Number of program headers: %u"),
6244 header->e_phnum);
dda8d76d
NC
6245 if (filedata->section_headers != NULL
6246 && header->e_phnum == PN_XNUM
6247 && filedata->section_headers[0].sh_info != 0)
2969c3b3 6248 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 6249 putc ('\n', stdout);
e8a64888
AM
6250 printf (_(" Size of section headers: %u (bytes)\n"),
6251 header->e_shentsize);
6252 printf (_(" Number of section headers: %u"),
6253 header->e_shnum);
dda8d76d 6254 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
6255 {
6256 header->e_shnum = filedata->section_headers[0].sh_size;
6257 printf (" (%u)", header->e_shnum);
6258 }
560f3c1c 6259 putc ('\n', stdout);
e8a64888
AM
6260 printf (_(" Section header string table index: %u"),
6261 header->e_shstrndx);
dda8d76d
NC
6262 if (filedata->section_headers != NULL
6263 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
6264 {
6265 header->e_shstrndx = filedata->section_headers[0].sh_link;
6266 printf (" (%u)", header->e_shstrndx);
6267 }
6268 if (header->e_shstrndx != SHN_UNDEF
6269 && header->e_shstrndx >= header->e_shnum)
6270 {
6271 header->e_shstrndx = SHN_UNDEF;
6272 printf (_(" <corrupt: out of range>"));
6273 }
560f3c1c
AM
6274 putc ('\n', stdout);
6275 }
6276
dda8d76d 6277 if (filedata->section_headers != NULL)
560f3c1c 6278 {
dda8d76d
NC
6279 if (header->e_phnum == PN_XNUM
6280 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
6281 {
6282 /* Throw away any cached read of PN_XNUM headers. */
6283 free (filedata->program_headers);
6284 filedata->program_headers = NULL;
6285 header->e_phnum = filedata->section_headers[0].sh_info;
6286 }
dda8d76d
NC
6287 if (header->e_shnum == SHN_UNDEF)
6288 header->e_shnum = filedata->section_headers[0].sh_size;
6289 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
6290 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 6291 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 6292 header->e_shstrndx = SHN_UNDEF;
252b5132 6293 }
103f02d3 6294
015dc7e1 6295 return true;
9ea033b2
NC
6296}
6297
dda8d76d
NC
6298/* Read in the program headers from FILEDATA and store them in PHEADERS.
6299 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
6300
015dc7e1 6301static bool
dda8d76d 6302get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6303{
2cf0635d
NC
6304 Elf32_External_Phdr * phdrs;
6305 Elf32_External_Phdr * external;
6306 Elf_Internal_Phdr * internal;
b34976b6 6307 unsigned int i;
dda8d76d
NC
6308 unsigned int size = filedata->file_header.e_phentsize;
6309 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6310
6311 /* PR binutils/17531: Cope with unexpected section header sizes. */
6312 if (size == 0 || num == 0)
015dc7e1 6313 return false;
e0a31db1
NC
6314 if (size < sizeof * phdrs)
6315 {
6316 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6317 return false;
e0a31db1
NC
6318 }
6319 if (size > sizeof * phdrs)
6320 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6321
dda8d76d 6322 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
6323 size, num, _("program headers"));
6324 if (phdrs == NULL)
015dc7e1 6325 return false;
9ea033b2 6326
91d6fa6a 6327 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6328 i < filedata->file_header.e_phnum;
b34976b6 6329 i++, internal++, external++)
252b5132 6330 {
9ea033b2
NC
6331 internal->p_type = BYTE_GET (external->p_type);
6332 internal->p_offset = BYTE_GET (external->p_offset);
6333 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6334 internal->p_paddr = BYTE_GET (external->p_paddr);
6335 internal->p_filesz = BYTE_GET (external->p_filesz);
6336 internal->p_memsz = BYTE_GET (external->p_memsz);
6337 internal->p_flags = BYTE_GET (external->p_flags);
6338 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
6339 }
6340
9ea033b2 6341 free (phdrs);
015dc7e1 6342 return true;
252b5132
RH
6343}
6344
dda8d76d
NC
6345/* Read in the program headers from FILEDATA and store them in PHEADERS.
6346 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
6347
015dc7e1 6348static bool
dda8d76d 6349get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6350{
2cf0635d
NC
6351 Elf64_External_Phdr * phdrs;
6352 Elf64_External_Phdr * external;
6353 Elf_Internal_Phdr * internal;
b34976b6 6354 unsigned int i;
dda8d76d
NC
6355 unsigned int size = filedata->file_header.e_phentsize;
6356 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6357
6358 /* PR binutils/17531: Cope with unexpected section header sizes. */
6359 if (size == 0 || num == 0)
015dc7e1 6360 return false;
e0a31db1
NC
6361 if (size < sizeof * phdrs)
6362 {
6363 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6364 return false;
e0a31db1
NC
6365 }
6366 if (size > sizeof * phdrs)
6367 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6368
dda8d76d 6369 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 6370 size, num, _("program headers"));
a6e9f9df 6371 if (!phdrs)
015dc7e1 6372 return false;
9ea033b2 6373
91d6fa6a 6374 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6375 i < filedata->file_header.e_phnum;
b34976b6 6376 i++, internal++, external++)
9ea033b2
NC
6377 {
6378 internal->p_type = BYTE_GET (external->p_type);
6379 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
6380 internal->p_offset = BYTE_GET (external->p_offset);
6381 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6382 internal->p_paddr = BYTE_GET (external->p_paddr);
6383 internal->p_filesz = BYTE_GET (external->p_filesz);
6384 internal->p_memsz = BYTE_GET (external->p_memsz);
6385 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
6386 }
6387
6388 free (phdrs);
015dc7e1 6389 return true;
9ea033b2 6390}
252b5132 6391
32ec8896 6392/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 6393
015dc7e1 6394static bool
dda8d76d 6395get_program_headers (Filedata * filedata)
d93f0186 6396{
2cf0635d 6397 Elf_Internal_Phdr * phdrs;
d93f0186
NC
6398
6399 /* Check cache of prior read. */
dda8d76d 6400 if (filedata->program_headers != NULL)
015dc7e1 6401 return true;
d93f0186 6402
82156ab7
NC
6403 /* Be kind to memory checkers by looking for
6404 e_phnum values which we know must be invalid. */
dda8d76d 6405 if (filedata->file_header.e_phnum
82156ab7 6406 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 6407 >= filedata->file_size)
82156ab7
NC
6408 {
6409 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 6410 filedata->file_header.e_phnum);
015dc7e1 6411 return false;
82156ab7 6412 }
d93f0186 6413
dda8d76d 6414 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 6415 sizeof (Elf_Internal_Phdr));
d93f0186
NC
6416 if (phdrs == NULL)
6417 {
8b73c356 6418 error (_("Out of memory reading %u program headers\n"),
dda8d76d 6419 filedata->file_header.e_phnum);
015dc7e1 6420 return false;
d93f0186
NC
6421 }
6422
6423 if (is_32bit_elf
dda8d76d
NC
6424 ? get_32bit_program_headers (filedata, phdrs)
6425 : get_64bit_program_headers (filedata, phdrs))
d93f0186 6426 {
dda8d76d 6427 filedata->program_headers = phdrs;
015dc7e1 6428 return true;
d93f0186
NC
6429 }
6430
6431 free (phdrs);
015dc7e1 6432 return false;
d93f0186
NC
6433}
6434
93df3340 6435/* Print program header info and locate dynamic section. */
2f62977e 6436
93df3340 6437static void
dda8d76d 6438process_program_headers (Filedata * filedata)
252b5132 6439{
2cf0635d 6440 Elf_Internal_Phdr * segment;
b34976b6 6441 unsigned int i;
1a9ccd70 6442 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6443
dda8d76d 6444 if (filedata->file_header.e_phnum == 0)
252b5132 6445 {
82f2dbf7 6446 /* PR binutils/12467. */
dda8d76d 6447 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6448 warn (_("possibly corrupt ELF header - it has a non-zero program"
6449 " header offset, but no program headers\n"));
82f2dbf7 6450 else if (do_segments)
ca0e11aa
NC
6451 {
6452 if (filedata->is_separate)
6453 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6454 filedata->file_name);
6455 else
6456 printf (_("\nThere are no program headers in this file.\n"));
6457 }
93df3340 6458 goto no_headers;
252b5132
RH
6459 }
6460
6461 if (do_segments && !do_header)
6462 {
ca0e11aa
NC
6463 if (filedata->is_separate)
6464 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6465 filedata->file_name, get_file_type (filedata));
ca0e11aa 6466 else
93df3340 6467 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6468 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6469 filedata->file_header.e_entry);
b8281767
AM
6470 printf (ngettext ("There is %d program header,"
6471 " starting at offset %" PRIu64 "\n",
6472 "There are %d program headers,"
6473 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6474 filedata->file_header.e_phnum),
6475 filedata->file_header.e_phnum,
625d49fc 6476 filedata->file_header.e_phoff);
252b5132
RH
6477 }
6478
dda8d76d 6479 if (! get_program_headers (filedata))
93df3340 6480 goto no_headers;
103f02d3 6481
252b5132
RH
6482 if (do_segments)
6483 {
dda8d76d 6484 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6485 printf (_("\nProgram Headers:\n"));
6486 else
6487 printf (_("\nProgram Headers:\n"));
76da6bbe 6488
f7a99963
NC
6489 if (is_32bit_elf)
6490 printf
6491 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6492 else if (do_wide)
6493 printf
6494 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6495 else
6496 {
6497 printf
6498 (_(" Type Offset VirtAddr PhysAddr\n"));
6499 printf
6500 (_(" FileSiz MemSiz Flags Align\n"));
6501 }
252b5132
RH
6502 }
6503
26c527e6 6504 uint64_t dynamic_addr = 0;
be7d229a 6505 uint64_t dynamic_size = 0;
dda8d76d
NC
6506 for (i = 0, segment = filedata->program_headers;
6507 i < filedata->file_header.e_phnum;
b34976b6 6508 i++, segment++)
252b5132
RH
6509 {
6510 if (do_segments)
6511 {
dda8d76d 6512 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6513
6514 if (is_32bit_elf)
6515 {
6516 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6517 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6518 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6519 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6520 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6521 printf ("%c%c%c ",
6522 (segment->p_flags & PF_R ? 'R' : ' '),
6523 (segment->p_flags & PF_W ? 'W' : ' '),
6524 (segment->p_flags & PF_X ? 'E' : ' '));
6525 printf ("%#lx", (unsigned long) segment->p_align);
6526 }
d974e256
JJ
6527 else if (do_wide)
6528 {
6529 if ((unsigned long) segment->p_offset == segment->p_offset)
6530 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6531 else
6532 {
6533 print_vma (segment->p_offset, FULL_HEX);
6534 putchar (' ');
6535 }
6536
6537 print_vma (segment->p_vaddr, FULL_HEX);
6538 putchar (' ');
6539 print_vma (segment->p_paddr, FULL_HEX);
6540 putchar (' ');
6541
6542 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6543 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6544 else
6545 {
6546 print_vma (segment->p_filesz, FULL_HEX);
6547 putchar (' ');
6548 }
6549
6550 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6551 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6552 else
6553 {
f48e6c45 6554 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6555 }
6556
6557 printf (" %c%c%c ",
6558 (segment->p_flags & PF_R ? 'R' : ' '),
6559 (segment->p_flags & PF_W ? 'W' : ' '),
6560 (segment->p_flags & PF_X ? 'E' : ' '));
6561
6562 if ((unsigned long) segment->p_align == segment->p_align)
6563 printf ("%#lx", (unsigned long) segment->p_align);
6564 else
6565 {
6566 print_vma (segment->p_align, PREFIX_HEX);
6567 }
6568 }
f7a99963
NC
6569 else
6570 {
6571 print_vma (segment->p_offset, FULL_HEX);
6572 putchar (' ');
6573 print_vma (segment->p_vaddr, FULL_HEX);
6574 putchar (' ');
6575 print_vma (segment->p_paddr, FULL_HEX);
6576 printf ("\n ");
6577 print_vma (segment->p_filesz, FULL_HEX);
6578 putchar (' ');
6579 print_vma (segment->p_memsz, FULL_HEX);
6580 printf (" %c%c%c ",
6581 (segment->p_flags & PF_R ? 'R' : ' '),
6582 (segment->p_flags & PF_W ? 'W' : ' '),
6583 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6584 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6585 }
252b5132 6586
1a9ccd70
NC
6587 putc ('\n', stdout);
6588 }
f54498b4 6589
252b5132
RH
6590 switch (segment->p_type)
6591 {
1a9ccd70 6592 case PT_LOAD:
502d895c
NC
6593#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6594 required by the ELF standard, several programs, including the Linux
6595 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6596 if (previous_load
6597 && previous_load->p_vaddr > segment->p_vaddr)
6598 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6599#endif
1a9ccd70
NC
6600 if (segment->p_memsz < segment->p_filesz)
6601 error (_("the segment's file size is larger than its memory size\n"));
6602 previous_load = segment;
6603 break;
6604
6605 case PT_PHDR:
6606 /* PR 20815 - Verify that the program header is loaded into memory. */
6607 if (i > 0 && previous_load != NULL)
6608 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6609 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6610 {
6611 unsigned int j;
6612
dda8d76d 6613 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6614 {
6615 Elf_Internal_Phdr *load = filedata->program_headers + j;
6616 if (load->p_type == PT_LOAD
6617 && load->p_offset <= segment->p_offset
6618 && (load->p_offset + load->p_filesz
6619 >= segment->p_offset + segment->p_filesz)
6620 && load->p_vaddr <= segment->p_vaddr
6621 && (load->p_vaddr + load->p_filesz
6622 >= segment->p_vaddr + segment->p_filesz))
6623 break;
6624 }
dda8d76d 6625 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6626 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6627 }
6628 break;
6629
252b5132 6630 case PT_DYNAMIC:
93df3340 6631 if (dynamic_addr)
252b5132
RH
6632 error (_("more than one dynamic segment\n"));
6633
20737c13
AM
6634 /* By default, assume that the .dynamic section is the first
6635 section in the DYNAMIC segment. */
93df3340
AM
6636 dynamic_addr = segment->p_offset;
6637 dynamic_size = segment->p_filesz;
20737c13 6638
b2d38a17
NC
6639 /* Try to locate the .dynamic section. If there is
6640 a section header table, we can easily locate it. */
dda8d76d 6641 if (filedata->section_headers != NULL)
b2d38a17 6642 {
2cf0635d 6643 Elf_Internal_Shdr * sec;
b2d38a17 6644
dda8d76d 6645 sec = find_section (filedata, ".dynamic");
89fac5e3 6646 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6647 {
93df3340
AM
6648 /* A corresponding .dynamic section is expected, but on
6649 IA-64/OpenVMS it is OK for it to be missing. */
6650 if (!is_ia64_vms (filedata))
6651 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6652 break;
6653 }
6654
42bb2e33 6655 if (sec->sh_type == SHT_NOBITS)
20737c13 6656 {
93df3340
AM
6657 dynamic_addr = 0;
6658 dynamic_size = 0;
20737c13
AM
6659 break;
6660 }
42bb2e33 6661
93df3340
AM
6662 dynamic_addr = sec->sh_offset;
6663 dynamic_size = sec->sh_size;
b2d38a17 6664
8ac10c5b
L
6665 /* The PT_DYNAMIC segment, which is used by the run-time
6666 loader, should exactly match the .dynamic section. */
6667 if (do_checks
93df3340
AM
6668 && (dynamic_addr != segment->p_offset
6669 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6670 warn (_("\
6671the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6672 }
39e224f6
MW
6673
6674 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6675 segment. Check this after matching against the section headers
6676 so we don't warn on debuginfo file (which have NOBITS .dynamic
6677 sections). */
93df3340
AM
6678 if (dynamic_addr > filedata->file_size
6679 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6680 {
6681 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6682 dynamic_addr = 0;
6683 dynamic_size = 0;
39e224f6 6684 }
252b5132
RH
6685 break;
6686
6687 case PT_INTERP:
13acb58d
AM
6688 if (segment->p_offset >= filedata->file_size
6689 || segment->p_filesz > filedata->file_size - segment->p_offset
6690 || segment->p_filesz - 1 >= (size_t) -2
63cf857e
AM
6691 || fseek64 (filedata->handle,
6692 filedata->archive_file_offset + segment->p_offset,
6693 SEEK_SET))
252b5132
RH
6694 error (_("Unable to find program interpreter name\n"));
6695 else
6696 {
13acb58d
AM
6697 size_t len = segment->p_filesz;
6698 free (filedata->program_interpreter);
6699 filedata->program_interpreter = xmalloc (len + 1);
6700 len = fread (filedata->program_interpreter, 1, len,
6701 filedata->handle);
6702 filedata->program_interpreter[len] = 0;
252b5132
RH
6703
6704 if (do_segments)
f54498b4 6705 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6706 filedata->program_interpreter);
252b5132
RH
6707 }
6708 break;
6709 }
252b5132
RH
6710 }
6711
dda8d76d
NC
6712 if (do_segments
6713 && filedata->section_headers != NULL
6714 && filedata->string_table != NULL)
252b5132
RH
6715 {
6716 printf (_("\n Section to Segment mapping:\n"));
6717 printf (_(" Segment Sections...\n"));
6718
dda8d76d 6719 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6720 {
9ad5cbcf 6721 unsigned int j;
2cf0635d 6722 Elf_Internal_Shdr * section;
252b5132 6723
dda8d76d
NC
6724 segment = filedata->program_headers + i;
6725 section = filedata->section_headers + 1;
252b5132
RH
6726
6727 printf (" %2.2d ", i);
6728
dda8d76d 6729 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6730 {
f4638467
AM
6731 if (!ELF_TBSS_SPECIAL (section, segment)
6732 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6733 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6734 }
6735
6736 putc ('\n',stdout);
6737 }
6738 }
6739
93df3340
AM
6740 filedata->dynamic_addr = dynamic_addr;
6741 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6742 return;
6743
6744 no_headers:
6745 filedata->dynamic_addr = 0;
6746 filedata->dynamic_size = 1;
252b5132
RH
6747}
6748
6749
d93f0186
NC
6750/* Find the file offset corresponding to VMA by using the program headers. */
6751
26c527e6 6752static int64_t
625d49fc 6753offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 6754{
2cf0635d 6755 Elf_Internal_Phdr * seg;
d93f0186 6756
dda8d76d 6757 if (! get_program_headers (filedata))
d93f0186
NC
6758 {
6759 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6760 return (long) vma;
6761 }
6762
dda8d76d
NC
6763 for (seg = filedata->program_headers;
6764 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6765 ++seg)
6766 {
6767 if (seg->p_type != PT_LOAD)
6768 continue;
6769
6770 if (vma >= (seg->p_vaddr & -seg->p_align)
6771 && vma + size <= seg->p_vaddr + seg->p_filesz)
6772 return vma - seg->p_vaddr + seg->p_offset;
6773 }
6774
26c527e6
AM
6775 warn (_("Virtual address %#" PRIx64
6776 " not located in any PT_LOAD segment.\n"), vma);
6777 return vma;
d93f0186
NC
6778}
6779
6780
dda8d76d
NC
6781/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6782 If PROBE is true, this is just a probe and we do not generate any error
6783 messages if the load fails. */
049b0c3a 6784
015dc7e1
AM
6785static bool
6786get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6787{
2cf0635d
NC
6788 Elf32_External_Shdr * shdrs;
6789 Elf_Internal_Shdr * internal;
dda8d76d
NC
6790 unsigned int i;
6791 unsigned int size = filedata->file_header.e_shentsize;
6792 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6793
6794 /* PR binutils/17531: Cope with unexpected section header sizes. */
6795 if (size == 0 || num == 0)
015dc7e1 6796 return false;
907b52f4
NC
6797
6798 /* The section header cannot be at the start of the file - that is
6799 where the ELF file header is located. A file with absolutely no
6800 sections in it will use a shoff of 0. */
6801 if (filedata->file_header.e_shoff == 0)
6802 return false;
6803
049b0c3a
NC
6804 if (size < sizeof * shdrs)
6805 {
6806 if (! probe)
6807 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6808 return false;
049b0c3a
NC
6809 }
6810 if (!probe && size > sizeof * shdrs)
6811 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6812
dda8d76d 6813 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6814 size, num,
6815 probe ? NULL : _("section headers"));
6816 if (shdrs == NULL)
015dc7e1 6817 return false;
252b5132 6818
dda8d76d
NC
6819 filedata->section_headers = (Elf_Internal_Shdr *)
6820 cmalloc (num, sizeof (Elf_Internal_Shdr));
6821 if (filedata->section_headers == NULL)
252b5132 6822 {
049b0c3a 6823 if (!probe)
8b73c356 6824 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6825 free (shdrs);
015dc7e1 6826 return false;
252b5132
RH
6827 }
6828
dda8d76d 6829 for (i = 0, internal = filedata->section_headers;
560f3c1c 6830 i < num;
b34976b6 6831 i++, internal++)
252b5132
RH
6832 {
6833 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6834 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6835 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6836 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6837 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6838 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6839 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6840 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6841 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6842 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6843 if (!probe && internal->sh_link > num)
6844 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6845 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6846 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6847 }
6848
6849 free (shdrs);
015dc7e1 6850 return true;
252b5132
RH
6851}
6852
dda8d76d
NC
6853/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6854
015dc7e1
AM
6855static bool
6856get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6857{
dda8d76d
NC
6858 Elf64_External_Shdr * shdrs;
6859 Elf_Internal_Shdr * internal;
6860 unsigned int i;
6861 unsigned int size = filedata->file_header.e_shentsize;
6862 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6863
6864 /* PR binutils/17531: Cope with unexpected section header sizes. */
6865 if (size == 0 || num == 0)
015dc7e1 6866 return false;
dda8d76d 6867
907b52f4
NC
6868 /* The section header cannot be at the start of the file - that is
6869 where the ELF file header is located. A file with absolutely no
6870 sections in it will use a shoff of 0. */
6871 if (filedata->file_header.e_shoff == 0)
6872 return false;
6873
049b0c3a
NC
6874 if (size < sizeof * shdrs)
6875 {
6876 if (! probe)
6877 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6878 return false;
049b0c3a 6879 }
dda8d76d 6880
049b0c3a
NC
6881 if (! probe && size > sizeof * shdrs)
6882 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6883
dda8d76d
NC
6884 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6885 filedata->file_header.e_shoff,
049b0c3a
NC
6886 size, num,
6887 probe ? NULL : _("section headers"));
6888 if (shdrs == NULL)
015dc7e1 6889 return false;
9ea033b2 6890
dda8d76d
NC
6891 filedata->section_headers = (Elf_Internal_Shdr *)
6892 cmalloc (num, sizeof (Elf_Internal_Shdr));
6893 if (filedata->section_headers == NULL)
9ea033b2 6894 {
049b0c3a 6895 if (! probe)
8b73c356 6896 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6897 free (shdrs);
015dc7e1 6898 return false;
9ea033b2
NC
6899 }
6900
dda8d76d 6901 for (i = 0, internal = filedata->section_headers;
560f3c1c 6902 i < num;
b34976b6 6903 i++, internal++)
9ea033b2
NC
6904 {
6905 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6906 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6907 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6908 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6909 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6910 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6911 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6912 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6913 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6914 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6915 if (!probe && internal->sh_link > num)
6916 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6917 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6918 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6919 }
6920
6921 free (shdrs);
015dc7e1 6922 return true;
9ea033b2
NC
6923}
6924
4de91c10
AM
6925static bool
6926get_section_headers (Filedata *filedata, bool probe)
6927{
6928 if (filedata->section_headers != NULL)
6929 return true;
6930
4de91c10
AM
6931 if (is_32bit_elf)
6932 return get_32bit_section_headers (filedata, probe);
6933 else
6934 return get_64bit_section_headers (filedata, probe);
6935}
6936
252b5132 6937static Elf_Internal_Sym *
26c527e6
AM
6938get_32bit_elf_symbols (Filedata *filedata,
6939 Elf_Internal_Shdr *section,
6940 uint64_t *num_syms_return)
252b5132 6941{
26c527e6 6942 uint64_t number = 0;
dd24e3da 6943 Elf32_External_Sym * esyms = NULL;
ba5cdace 6944 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6945 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6946 Elf_Internal_Sym * psym;
b34976b6 6947 unsigned int j;
e3d39609 6948 elf_section_list * entry;
252b5132 6949
c9c1d674
EG
6950 if (section->sh_size == 0)
6951 {
6952 if (num_syms_return != NULL)
6953 * num_syms_return = 0;
6954 return NULL;
6955 }
6956
dd24e3da 6957 /* Run some sanity checks first. */
c9c1d674 6958 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6959 {
26c527e6 6960 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 6961 printable_section_name (filedata, section),
26c527e6 6962 section->sh_entsize);
ba5cdace 6963 goto exit_point;
dd24e3da
NC
6964 }
6965
dda8d76d 6966 if (section->sh_size > filedata->file_size)
f54498b4 6967 {
26c527e6 6968 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 6969 printable_section_name (filedata, section),
26c527e6 6970 section->sh_size);
f54498b4
NC
6971 goto exit_point;
6972 }
6973
dd24e3da
NC
6974 number = section->sh_size / section->sh_entsize;
6975
6976 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6977 {
26c527e6
AM
6978 error (_("Size (%#" PRIx64 ") of section %s "
6979 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
6980 section->sh_size,
dda8d76d 6981 printable_section_name (filedata, section),
26c527e6 6982 section->sh_entsize);
ba5cdace 6983 goto exit_point;
dd24e3da
NC
6984 }
6985
dda8d76d 6986 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6987 section->sh_size, _("symbols"));
dd24e3da 6988 if (esyms == NULL)
ba5cdace 6989 goto exit_point;
252b5132 6990
e3d39609 6991 shndx = NULL;
978c4450 6992 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 6993 {
26c527e6 6994 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
6995 continue;
6996
6997 if (shndx != NULL)
6998 {
6999 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7000 free (shndx);
7001 }
7002
7003 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7004 entry->hdr->sh_offset,
7005 1, entry->hdr->sh_size,
7006 _("symbol table section indices"));
7007 if (shndx == NULL)
7008 goto exit_point;
7009
7010 /* PR17531: file: heap-buffer-overflow */
7011 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7012 {
26c527e6 7013 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7014 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7015 entry->hdr->sh_size,
7016 section->sh_size);
e3d39609 7017 goto exit_point;
c9c1d674 7018 }
e3d39609 7019 }
9ad5cbcf 7020
3f5e193b 7021 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
7022
7023 if (isyms == NULL)
7024 {
26c527e6 7025 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
dd24e3da 7026 goto exit_point;
252b5132
RH
7027 }
7028
dd24e3da 7029 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
7030 {
7031 psym->st_name = BYTE_GET (esyms[j].st_name);
7032 psym->st_value = BYTE_GET (esyms[j].st_value);
7033 psym->st_size = BYTE_GET (esyms[j].st_size);
7034 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 7035 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7036 psym->st_shndx
7037 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7038 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7039 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
7040 psym->st_info = BYTE_GET (esyms[j].st_info);
7041 psym->st_other = BYTE_GET (esyms[j].st_other);
7042 }
7043
dd24e3da 7044 exit_point:
e3d39609
NC
7045 free (shndx);
7046 free (esyms);
252b5132 7047
ba5cdace
NC
7048 if (num_syms_return != NULL)
7049 * num_syms_return = isyms == NULL ? 0 : number;
7050
252b5132
RH
7051 return isyms;
7052}
7053
9ea033b2 7054static Elf_Internal_Sym *
26c527e6
AM
7055get_64bit_elf_symbols (Filedata *filedata,
7056 Elf_Internal_Shdr *section,
7057 uint64_t *num_syms_return)
9ea033b2 7058{
26c527e6 7059 uint64_t number = 0;
ba5cdace
NC
7060 Elf64_External_Sym * esyms = NULL;
7061 Elf_External_Sym_Shndx * shndx = NULL;
7062 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7063 Elf_Internal_Sym * psym;
b34976b6 7064 unsigned int j;
e3d39609 7065 elf_section_list * entry;
9ea033b2 7066
c9c1d674
EG
7067 if (section->sh_size == 0)
7068 {
7069 if (num_syms_return != NULL)
7070 * num_syms_return = 0;
7071 return NULL;
7072 }
7073
dd24e3da 7074 /* Run some sanity checks first. */
c9c1d674 7075 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7076 {
26c527e6 7077 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7078 printable_section_name (filedata, section),
26c527e6 7079 section->sh_entsize);
ba5cdace 7080 goto exit_point;
dd24e3da
NC
7081 }
7082
dda8d76d 7083 if (section->sh_size > filedata->file_size)
f54498b4 7084 {
26c527e6 7085 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7086 printable_section_name (filedata, section),
26c527e6 7087 section->sh_size);
f54498b4
NC
7088 goto exit_point;
7089 }
7090
dd24e3da
NC
7091 number = section->sh_size / section->sh_entsize;
7092
7093 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
7094 {
26c527e6
AM
7095 error (_("Size (%#" PRIx64 ") of section %s "
7096 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7097 section->sh_size,
dda8d76d 7098 printable_section_name (filedata, section),
26c527e6 7099 section->sh_entsize);
ba5cdace 7100 goto exit_point;
dd24e3da
NC
7101 }
7102
dda8d76d 7103 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7104 section->sh_size, _("symbols"));
a6e9f9df 7105 if (!esyms)
ba5cdace 7106 goto exit_point;
9ea033b2 7107
e3d39609 7108 shndx = NULL;
978c4450 7109 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7110 {
26c527e6 7111 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7112 continue;
7113
7114 if (shndx != NULL)
7115 {
7116 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7117 free (shndx);
c9c1d674 7118 }
e3d39609
NC
7119
7120 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7121 entry->hdr->sh_offset,
7122 1, entry->hdr->sh_size,
7123 _("symbol table section indices"));
7124 if (shndx == NULL)
7125 goto exit_point;
7126
7127 /* PR17531: file: heap-buffer-overflow */
7128 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7129 {
26c527e6 7130 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7131 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7132 entry->hdr->sh_size,
7133 section->sh_size);
e3d39609
NC
7134 goto exit_point;
7135 }
7136 }
9ad5cbcf 7137
3f5e193b 7138 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
7139
7140 if (isyms == NULL)
7141 {
26c527e6 7142 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
ba5cdace 7143 goto exit_point;
9ea033b2
NC
7144 }
7145
ba5cdace 7146 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
7147 {
7148 psym->st_name = BYTE_GET (esyms[j].st_name);
7149 psym->st_info = BYTE_GET (esyms[j].st_info);
7150 psym->st_other = BYTE_GET (esyms[j].st_other);
7151 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 7152
4fbb74a6 7153 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7154 psym->st_shndx
7155 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7156 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7157 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 7158
66543521
AM
7159 psym->st_value = BYTE_GET (esyms[j].st_value);
7160 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
7161 }
7162
ba5cdace 7163 exit_point:
e3d39609
NC
7164 free (shndx);
7165 free (esyms);
ba5cdace
NC
7166
7167 if (num_syms_return != NULL)
7168 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
7169
7170 return isyms;
7171}
7172
4de91c10
AM
7173static Elf_Internal_Sym *
7174get_elf_symbols (Filedata *filedata,
7175 Elf_Internal_Shdr *section,
26c527e6 7176 uint64_t *num_syms_return)
4de91c10
AM
7177{
7178 if (is_32bit_elf)
7179 return get_32bit_elf_symbols (filedata, section, num_syms_return);
7180 else
7181 return get_64bit_elf_symbols (filedata, section, num_syms_return);
7182}
7183
d1133906 7184static const char *
625d49fc 7185get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 7186{
5477e8a0 7187 static char buff[1024];
2cf0635d 7188 char * p = buff;
32ec8896
NC
7189 unsigned int field_size = is_32bit_elf ? 8 : 16;
7190 signed int sindex;
7191 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
7192 uint64_t os_flags = 0;
7193 uint64_t proc_flags = 0;
7194 uint64_t unknown_flags = 0;
148b93f2 7195 static const struct
5477e8a0 7196 {
2cf0635d 7197 const char * str;
32ec8896 7198 unsigned int len;
5477e8a0
L
7199 }
7200 flags [] =
7201 {
cfcac11d
NC
7202 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
7203 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
7204 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
7205 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
7206 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
7207 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
7208 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
7209 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
7210 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
7211 /* 9 */ { STRING_COMMA_LEN ("TLS") },
7212 /* IA-64 specific. */
7213 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
7214 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
7215 /* IA-64 OpenVMS specific. */
7216 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
7217 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
7218 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
7219 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
7220 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
7221 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 7222 /* Generic. */
cfcac11d 7223 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 7224 /* SPARC specific. */
77115a4a 7225 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
7226 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
7227 /* ARM specific. */
7228 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 7229 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
7230 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
7231 /* GNU specific. */
7232 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
7233 /* VLE specific. */
7234 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
7235 /* GNU specific. */
7236 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
7237 };
7238
7239 if (do_section_details)
f8c4789c
AM
7240 p += sprintf (p, "[%*.*lx]: ",
7241 field_size, field_size, (unsigned long) sh_flags);
76da6bbe 7242
d1133906
NC
7243 while (sh_flags)
7244 {
625d49fc 7245 uint64_t flag;
d1133906
NC
7246
7247 flag = sh_flags & - sh_flags;
7248 sh_flags &= ~ flag;
76da6bbe 7249
5477e8a0 7250 if (do_section_details)
d1133906 7251 {
5477e8a0
L
7252 switch (flag)
7253 {
91d6fa6a
NC
7254 case SHF_WRITE: sindex = 0; break;
7255 case SHF_ALLOC: sindex = 1; break;
7256 case SHF_EXECINSTR: sindex = 2; break;
7257 case SHF_MERGE: sindex = 3; break;
7258 case SHF_STRINGS: sindex = 4; break;
7259 case SHF_INFO_LINK: sindex = 5; break;
7260 case SHF_LINK_ORDER: sindex = 6; break;
7261 case SHF_OS_NONCONFORMING: sindex = 7; break;
7262 case SHF_GROUP: sindex = 8; break;
7263 case SHF_TLS: sindex = 9; break;
18ae9cc1 7264 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 7265 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 7266
5477e8a0 7267 default:
91d6fa6a 7268 sindex = -1;
dda8d76d 7269 switch (filedata->file_header.e_machine)
148b93f2 7270 {
cfcac11d 7271 case EM_IA_64:
148b93f2 7272 if (flag == SHF_IA_64_SHORT)
91d6fa6a 7273 sindex = 10;
148b93f2 7274 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 7275 sindex = 11;
dda8d76d 7276 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
7277 switch (flag)
7278 {
91d6fa6a
NC
7279 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
7280 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
7281 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
7282 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
7283 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
7284 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
7285 default: break;
7286 }
cfcac11d
NC
7287 break;
7288
caa83f8b 7289 case EM_386:
22abe556 7290 case EM_IAMCU:
caa83f8b 7291 case EM_X86_64:
7f502d6c 7292 case EM_L1OM:
7a9068fe 7293 case EM_K1OM:
cfcac11d
NC
7294 case EM_OLD_SPARCV9:
7295 case EM_SPARC32PLUS:
7296 case EM_SPARCV9:
7297 case EM_SPARC:
18ae9cc1 7298 if (flag == SHF_ORDERED)
91d6fa6a 7299 sindex = 19;
cfcac11d 7300 break;
ac4c9b04
MG
7301
7302 case EM_ARM:
7303 switch (flag)
7304 {
7305 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 7306 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
7307 case SHF_COMDEF: sindex = 23; break;
7308 default: break;
7309 }
7310 break;
83eef883
AFB
7311 case EM_PPC:
7312 if (flag == SHF_PPC_VLE)
7313 sindex = 25;
7314 break;
99fabbc9
JL
7315 default:
7316 break;
7317 }
ac4c9b04 7318
99fabbc9
JL
7319 switch (filedata->file_header.e_ident[EI_OSABI])
7320 {
7321 case ELFOSABI_GNU:
7322 case ELFOSABI_FREEBSD:
7323 if (flag == SHF_GNU_RETAIN)
7324 sindex = 26;
7325 /* Fall through */
7326 case ELFOSABI_NONE:
7327 if (flag == SHF_GNU_MBIND)
7328 /* We should not recognize SHF_GNU_MBIND for
7329 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7330 not set the EI_OSABI header byte. */
7331 sindex = 24;
7332 break;
cfcac11d
NC
7333 default:
7334 break;
148b93f2 7335 }
99fabbc9 7336 break;
5477e8a0
L
7337 }
7338
91d6fa6a 7339 if (sindex != -1)
5477e8a0 7340 {
8d5ff12c
L
7341 if (p != buff + field_size + 4)
7342 {
7343 if (size < (10 + 2))
bee0ee85
NC
7344 {
7345 warn (_("Internal error: not enough buffer room for section flag info"));
7346 return _("<unknown>");
7347 }
8d5ff12c
L
7348 size -= 2;
7349 *p++ = ',';
7350 *p++ = ' ';
7351 }
7352
91d6fa6a
NC
7353 size -= flags [sindex].len;
7354 p = stpcpy (p, flags [sindex].str);
5477e8a0 7355 }
3b22753a 7356 else if (flag & SHF_MASKOS)
8d5ff12c 7357 os_flags |= flag;
d1133906 7358 else if (flag & SHF_MASKPROC)
8d5ff12c 7359 proc_flags |= flag;
d1133906 7360 else
8d5ff12c 7361 unknown_flags |= flag;
5477e8a0
L
7362 }
7363 else
7364 {
7365 switch (flag)
7366 {
7367 case SHF_WRITE: *p = 'W'; break;
7368 case SHF_ALLOC: *p = 'A'; break;
7369 case SHF_EXECINSTR: *p = 'X'; break;
7370 case SHF_MERGE: *p = 'M'; break;
7371 case SHF_STRINGS: *p = 'S'; break;
7372 case SHF_INFO_LINK: *p = 'I'; break;
7373 case SHF_LINK_ORDER: *p = 'L'; break;
7374 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7375 case SHF_GROUP: *p = 'G'; break;
7376 case SHF_TLS: *p = 'T'; break;
18ae9cc1 7377 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 7378 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
7379
7380 default:
dda8d76d
NC
7381 if ((filedata->file_header.e_machine == EM_X86_64
7382 || filedata->file_header.e_machine == EM_L1OM
7383 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
7384 && flag == SHF_X86_64_LARGE)
7385 *p = 'l';
dda8d76d 7386 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 7387 && flag == SHF_ARM_PURECODE)
99fabbc9 7388 *p = 'y';
dda8d76d 7389 else if (filedata->file_header.e_machine == EM_PPC
83eef883 7390 && flag == SHF_PPC_VLE)
99fabbc9 7391 *p = 'v';
5477e8a0
L
7392 else if (flag & SHF_MASKOS)
7393 {
99fabbc9
JL
7394 switch (filedata->file_header.e_ident[EI_OSABI])
7395 {
7396 case ELFOSABI_GNU:
7397 case ELFOSABI_FREEBSD:
7398 if (flag == SHF_GNU_RETAIN)
7399 {
7400 *p = 'R';
7401 break;
7402 }
7403 /* Fall through */
7404 case ELFOSABI_NONE:
7405 if (flag == SHF_GNU_MBIND)
7406 {
7407 /* We should not recognize SHF_GNU_MBIND for
7408 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7409 not set the EI_OSABI header byte. */
7410 *p = 'D';
7411 break;
7412 }
7413 /* Fall through */
7414 default:
7415 *p = 'o';
7416 sh_flags &= ~SHF_MASKOS;
7417 break;
7418 }
5477e8a0
L
7419 }
7420 else if (flag & SHF_MASKPROC)
7421 {
7422 *p = 'p';
7423 sh_flags &= ~ SHF_MASKPROC;
7424 }
7425 else
7426 *p = 'x';
7427 break;
7428 }
7429 p++;
d1133906
NC
7430 }
7431 }
76da6bbe 7432
8d5ff12c
L
7433 if (do_section_details)
7434 {
7435 if (os_flags)
7436 {
8d5ff12c
L
7437 if (p != buff + field_size + 4)
7438 {
f8c4789c 7439 if (size < 2 + 5 + field_size + 1)
bee0ee85
NC
7440 {
7441 warn (_("Internal error: not enough buffer room for section flag info"));
7442 return _("<unknown>");
7443 }
8d5ff12c
L
7444 size -= 2;
7445 *p++ = ',';
7446 *p++ = ' ';
7447 }
f8c4789c
AM
7448 size -= 5 + field_size;
7449 p += sprintf (p, "OS (%*.*lx)", field_size, field_size,
7450 (unsigned long) os_flags);
8d5ff12c
L
7451 }
7452 if (proc_flags)
7453 {
8d5ff12c
L
7454 if (p != buff + field_size + 4)
7455 {
f8c4789c 7456 if (size < 2 + 7 + field_size + 1)
bee0ee85
NC
7457 {
7458 warn (_("Internal error: not enough buffer room for section flag info"));
7459 return _("<unknown>");
7460 }
8d5ff12c
L
7461 size -= 2;
7462 *p++ = ',';
7463 *p++ = ' ';
7464 }
f8c4789c
AM
7465 size -= 7 + field_size;
7466 p += sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7467 (unsigned long) proc_flags);
8d5ff12c
L
7468 }
7469 if (unknown_flags)
7470 {
8d5ff12c
L
7471 if (p != buff + field_size + 4)
7472 {
f8c4789c 7473 if (size < 2 + 10 + field_size + 1)
bee0ee85
NC
7474 {
7475 warn (_("Internal error: not enough buffer room for section flag info"));
7476 return _("<unknown>");
7477 }
8d5ff12c
L
7478 size -= 2;
7479 *p++ = ',';
7480 *p++ = ' ';
7481 }
f8c4789c
AM
7482 size -= 10 + field_size;
7483 p += sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
7484 (unsigned long) unknown_flags);
8d5ff12c
L
7485 }
7486 }
7487
e9e44622 7488 *p = '\0';
d1133906
NC
7489 return buff;
7490}
7491
5844b465 7492static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7493get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7494 uint64_t size)
77115a4a
L
7495{
7496 if (is_32bit_elf)
7497 {
7498 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7499
ebdf1ebf
NC
7500 if (size < sizeof (* echdr))
7501 {
7502 error (_("Compressed section is too small even for a compression header\n"));
7503 return 0;
7504 }
7505
77115a4a
L
7506 chdr->ch_type = BYTE_GET (echdr->ch_type);
7507 chdr->ch_size = BYTE_GET (echdr->ch_size);
7508 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7509 return sizeof (*echdr);
7510 }
7511 else
7512 {
7513 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7514
ebdf1ebf
NC
7515 if (size < sizeof (* echdr))
7516 {
7517 error (_("Compressed section is too small even for a compression header\n"));
7518 return 0;
7519 }
7520
77115a4a
L
7521 chdr->ch_type = BYTE_GET (echdr->ch_type);
7522 chdr->ch_size = BYTE_GET (echdr->ch_size);
7523 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7524 return sizeof (*echdr);
7525 }
7526}
7527
015dc7e1 7528static bool
dda8d76d 7529process_section_headers (Filedata * filedata)
252b5132 7530{
2cf0635d 7531 Elf_Internal_Shdr * section;
b34976b6 7532 unsigned int i;
252b5132 7533
dda8d76d 7534 if (filedata->file_header.e_shnum == 0)
252b5132 7535 {
82f2dbf7 7536 /* PR binutils/12467. */
dda8d76d 7537 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7538 {
7539 warn (_("possibly corrupt ELF file header - it has a non-zero"
7540 " section header offset, but no section headers\n"));
015dc7e1 7541 return false;
32ec8896 7542 }
82f2dbf7 7543 else if (do_sections)
252b5132
RH
7544 printf (_("\nThere are no sections in this file.\n"));
7545
015dc7e1 7546 return true;
252b5132
RH
7547 }
7548
7549 if (do_sections && !do_header)
ca0e11aa
NC
7550 {
7551 if (filedata->is_separate && process_links)
7552 printf (_("In linked file '%s': "), filedata->file_name);
7553 if (! filedata->is_separate || process_links)
7554 printf (ngettext ("There is %d section header, "
26c527e6 7555 "starting at offset %#" PRIx64 ":\n",
ca0e11aa 7556 "There are %d section headers, "
26c527e6 7557 "starting at offset %#" PRIx64 ":\n",
ca0e11aa
NC
7558 filedata->file_header.e_shnum),
7559 filedata->file_header.e_shnum,
26c527e6 7560 filedata->file_header.e_shoff);
ca0e11aa 7561 }
252b5132 7562
4de91c10
AM
7563 if (!get_section_headers (filedata, false))
7564 return false;
252b5132
RH
7565
7566 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7567 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7568 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7569 {
dda8d76d 7570 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7571
c256ffe7
JJ
7572 if (section->sh_size != 0)
7573 {
dda8d76d
NC
7574 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7575 1, section->sh_size,
7576 _("string table"));
0de14b54 7577
dda8d76d 7578 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7579 }
252b5132
RH
7580 }
7581
7582 /* Scan the sections for the dynamic symbol table
e3c8793a 7583 and dynamic string table and debug sections. */
89fac5e3 7584 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7585 switch (filedata->file_header.e_machine)
89fac5e3
RS
7586 {
7587 case EM_MIPS:
7588 case EM_MIPS_RS3_LE:
7589 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7590 FDE addresses. However, the ABI also has a semi-official ILP32
7591 variant for which the normal FDE address size rules apply.
7592
7593 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7594 section, where XX is the size of longs in bits. Unfortunately,
7595 earlier compilers provided no way of distinguishing ILP32 objects
7596 from LP64 objects, so if there's any doubt, we should assume that
7597 the official LP64 form is being used. */
dda8d76d
NC
7598 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7599 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7600 eh_addr_size = 8;
7601 break;
0f56a26a
DD
7602
7603 case EM_H8_300:
7604 case EM_H8_300H:
dda8d76d 7605 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7606 {
7607 case E_H8_MACH_H8300:
7608 case E_H8_MACH_H8300HN:
7609 case E_H8_MACH_H8300SN:
7610 case E_H8_MACH_H8300SXN:
7611 eh_addr_size = 2;
7612 break;
7613 case E_H8_MACH_H8300H:
7614 case E_H8_MACH_H8300S:
7615 case E_H8_MACH_H8300SX:
7616 eh_addr_size = 4;
7617 break;
7618 }
f4236fe4
DD
7619 break;
7620
ff7eeb89 7621 case EM_M32C_OLD:
f4236fe4 7622 case EM_M32C:
dda8d76d 7623 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7624 {
7625 case EF_M32C_CPU_M16C:
7626 eh_addr_size = 2;
7627 break;
7628 }
7629 break;
89fac5e3
RS
7630 }
7631
76ca31c0
NC
7632#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7633 do \
7634 { \
be7d229a 7635 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7636 if (section->sh_entsize != expected_entsize) \
9dd3a467 7637 { \
f493c217 7638 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7639 i, section->sh_entsize); \
f493c217 7640 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7641 expected_entsize); \
9dd3a467 7642 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7643 } \
7644 } \
08d8fa11 7645 while (0)
9dd3a467
NC
7646
7647#define CHECK_ENTSIZE(section, i, type) \
1b513401 7648 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7649 sizeof (Elf64_External_##type))
7650
dda8d76d
NC
7651 for (i = 0, section = filedata->section_headers;
7652 i < filedata->file_header.e_shnum;
b34976b6 7653 i++, section++)
252b5132 7654 {
84714f86 7655 const char *name = section_name_print (filedata, section);
252b5132 7656
1b513401
NC
7657 /* Run some sanity checks on the headers and
7658 possibly fill in some file data as well. */
7659 switch (section->sh_type)
252b5132 7660 {
1b513401 7661 case SHT_DYNSYM:
978c4450 7662 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7663 {
7664 error (_("File contains multiple dynamic symbol tables\n"));
7665 continue;
7666 }
7667
08d8fa11 7668 CHECK_ENTSIZE (section, i, Sym);
978c4450 7669 filedata->dynamic_symbols
4de91c10 7670 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7671 filedata->dynamic_symtab_section = section;
1b513401
NC
7672 break;
7673
7674 case SHT_STRTAB:
7675 if (streq (name, ".dynstr"))
252b5132 7676 {
1b513401
NC
7677 if (filedata->dynamic_strings != NULL)
7678 {
7679 error (_("File contains multiple dynamic string tables\n"));
7680 continue;
7681 }
7682
7683 filedata->dynamic_strings
7684 = (char *) get_data (NULL, filedata, section->sh_offset,
7685 1, section->sh_size, _("dynamic strings"));
7686 filedata->dynamic_strings_length
7687 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7688 filedata->dynamic_strtab_section = section;
252b5132 7689 }
1b513401
NC
7690 break;
7691
7692 case SHT_SYMTAB_SHNDX:
7693 {
7694 elf_section_list * entry = xmalloc (sizeof * entry);
7695
7696 entry->hdr = section;
7697 entry->next = filedata->symtab_shndx_list;
7698 filedata->symtab_shndx_list = entry;
7699 }
7700 break;
7701
7702 case SHT_SYMTAB:
7703 CHECK_ENTSIZE (section, i, Sym);
7704 break;
7705
7706 case SHT_GROUP:
7707 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7708 break;
252b5132 7709
1b513401
NC
7710 case SHT_REL:
7711 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7712 if (do_checks && section->sh_size == 0)
1b513401
NC
7713 warn (_("Section '%s': zero-sized relocation section\n"), name);
7714 break;
7715
7716 case SHT_RELA:
7717 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7718 if (do_checks && section->sh_size == 0)
1b513401
NC
7719 warn (_("Section '%s': zero-sized relocation section\n"), name);
7720 break;
7721
682351b9
AM
7722 case SHT_RELR:
7723 CHECK_ENTSIZE (section, i, Relr);
7724 break;
7725
1b513401
NC
7726 case SHT_NOTE:
7727 case SHT_PROGBITS:
546cb2d8
NC
7728 /* Having a zero sized section is not illegal according to the
7729 ELF standard, but it might be an indication that something
7730 is wrong. So issue a warning if we are running in lint mode. */
7731 if (do_checks && section->sh_size == 0)
1b513401
NC
7732 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7733 break;
7734
7735 default:
7736 break;
7737 }
7738
7739 if ((do_debugging || do_debug_info || do_debug_abbrevs
7740 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7741 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7742 || do_debug_str || do_debug_str_offsets || do_debug_loc
7743 || do_debug_ranges
1b513401 7744 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7745 && (startswith (name, ".debug_")
7746 || startswith (name, ".zdebug_")))
252b5132 7747 {
1b315056
CS
7748 if (name[1] == 'z')
7749 name += sizeof (".zdebug_") - 1;
7750 else
7751 name += sizeof (".debug_") - 1;
252b5132
RH
7752
7753 if (do_debugging
24d127aa
ML
7754 || (do_debug_info && startswith (name, "info"))
7755 || (do_debug_info && startswith (name, "types"))
7756 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7757 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7758 || (do_debug_lines && startswith (name, "line."))
7759 || (do_debug_pubnames && startswith (name, "pubnames"))
7760 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7761 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7762 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7763 || (do_debug_aranges && startswith (name, "aranges"))
7764 || (do_debug_ranges && startswith (name, "ranges"))
7765 || (do_debug_ranges && startswith (name, "rnglists"))
7766 || (do_debug_frames && startswith (name, "frame"))
7767 || (do_debug_macinfo && startswith (name, "macinfo"))
7768 || (do_debug_macinfo && startswith (name, "macro"))
7769 || (do_debug_str && startswith (name, "str"))
7770 || (do_debug_links && startswith (name, "sup"))
7771 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7772 || (do_debug_loc && startswith (name, "loc"))
7773 || (do_debug_loc && startswith (name, "loclists"))
7774 || (do_debug_addr && startswith (name, "addr"))
7775 || (do_debug_cu_index && startswith (name, "cu_index"))
7776 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7777 )
6431e409 7778 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7779 }
a262ae96 7780 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7781 else if ((do_debugging || do_debug_info)
24d127aa 7782 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7783 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7784 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7785 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7786 else if (do_gdb_index && (streq (name, ".gdb_index")
7787 || streq (name, ".debug_names")))
6431e409 7788 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7789 /* Trace sections for Itanium VMS. */
7790 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7791 || do_trace_aranges)
24d127aa 7792 && startswith (name, ".trace_"))
6f875884
TG
7793 {
7794 name += sizeof (".trace_") - 1;
7795
7796 if (do_debugging
7797 || (do_trace_info && streq (name, "info"))
7798 || (do_trace_abbrevs && streq (name, "abbrev"))
7799 || (do_trace_aranges && streq (name, "aranges"))
7800 )
6431e409 7801 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7802 }
dda8d76d 7803 else if ((do_debugging || do_debug_links)
24d127aa
ML
7804 && (startswith (name, ".gnu_debuglink")
7805 || startswith (name, ".gnu_debugaltlink")))
6431e409 7806 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7807 }
7808
7809 if (! do_sections)
015dc7e1 7810 return true;
252b5132 7811
ca0e11aa 7812 if (filedata->is_separate && ! process_links)
015dc7e1 7813 return true;
ca0e11aa
NC
7814
7815 if (filedata->is_separate)
7816 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7817 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7818 printf (_("\nSection Headers:\n"));
7819 else
7820 printf (_("\nSection Header:\n"));
76da6bbe 7821
f7a99963 7822 if (is_32bit_elf)
595cf52e 7823 {
5477e8a0 7824 if (do_section_details)
595cf52e
L
7825 {
7826 printf (_(" [Nr] Name\n"));
5477e8a0 7827 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7828 }
7829 else
7830 printf
7831 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7832 }
d974e256 7833 else if (do_wide)
595cf52e 7834 {
5477e8a0 7835 if (do_section_details)
595cf52e
L
7836 {
7837 printf (_(" [Nr] Name\n"));
5477e8a0 7838 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7839 }
7840 else
7841 printf
7842 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7843 }
f7a99963
NC
7844 else
7845 {
5477e8a0 7846 if (do_section_details)
595cf52e
L
7847 {
7848 printf (_(" [Nr] Name\n"));
5477e8a0
L
7849 printf (_(" Type Address Offset Link\n"));
7850 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7851 }
7852 else
7853 {
7854 printf (_(" [Nr] Name Type Address Offset\n"));
7855 printf (_(" Size EntSize Flags Link Info Align\n"));
7856 }
f7a99963 7857 }
252b5132 7858
5477e8a0
L
7859 if (do_section_details)
7860 printf (_(" Flags\n"));
7861
dda8d76d
NC
7862 for (i = 0, section = filedata->section_headers;
7863 i < filedata->file_header.e_shnum;
b34976b6 7864 i++, section++)
252b5132 7865 {
dd905818
NC
7866 /* Run some sanity checks on the section header. */
7867
7868 /* Check the sh_link field. */
7869 switch (section->sh_type)
7870 {
285e3f99
AM
7871 case SHT_REL:
7872 case SHT_RELA:
7873 if (section->sh_link == 0
7874 && (filedata->file_header.e_type == ET_EXEC
7875 || filedata->file_header.e_type == ET_DYN))
7876 /* A dynamic relocation section where all entries use a
7877 zero symbol index need not specify a symtab section. */
7878 break;
7879 /* Fall through. */
dd905818
NC
7880 case SHT_SYMTAB_SHNDX:
7881 case SHT_GROUP:
7882 case SHT_HASH:
7883 case SHT_GNU_HASH:
7884 case SHT_GNU_versym:
285e3f99 7885 if (section->sh_link == 0
dda8d76d
NC
7886 || section->sh_link >= filedata->file_header.e_shnum
7887 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7888 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7889 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7890 i, section->sh_link);
7891 break;
7892
7893 case SHT_DYNAMIC:
7894 case SHT_SYMTAB:
7895 case SHT_DYNSYM:
7896 case SHT_GNU_verneed:
7897 case SHT_GNU_verdef:
7898 case SHT_GNU_LIBLIST:
285e3f99 7899 if (section->sh_link == 0
dda8d76d
NC
7900 || section->sh_link >= filedata->file_header.e_shnum
7901 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7902 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7903 i, section->sh_link);
7904 break;
7905
7906 case SHT_INIT_ARRAY:
7907 case SHT_FINI_ARRAY:
7908 case SHT_PREINIT_ARRAY:
7909 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7910 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7911 i, section->sh_link);
7912 break;
7913
7914 default:
7915 /* FIXME: Add support for target specific section types. */
7916#if 0 /* Currently we do not check other section types as there are too
7917 many special cases. Stab sections for example have a type
7918 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7919 section. */
7920 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7921 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7922 i, section->sh_link);
7923#endif
7924 break;
7925 }
7926
7927 /* Check the sh_info field. */
7928 switch (section->sh_type)
7929 {
7930 case SHT_REL:
7931 case SHT_RELA:
285e3f99
AM
7932 if (section->sh_info == 0
7933 && (filedata->file_header.e_type == ET_EXEC
7934 || filedata->file_header.e_type == ET_DYN))
7935 /* Dynamic relocations apply to segments, so they do not
7936 need to specify the section they relocate. */
7937 break;
7938 if (section->sh_info == 0
dda8d76d
NC
7939 || section->sh_info >= filedata->file_header.e_shnum
7940 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7941 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7942 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7943 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7944 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7945 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7946 /* FIXME: Are other section types valid ? */
dda8d76d 7947 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7948 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7949 i, section->sh_info);
dd905818
NC
7950 break;
7951
7952 case SHT_DYNAMIC:
7953 case SHT_HASH:
7954 case SHT_SYMTAB_SHNDX:
7955 case SHT_INIT_ARRAY:
7956 case SHT_FINI_ARRAY:
7957 case SHT_PREINIT_ARRAY:
7958 if (section->sh_info != 0)
7959 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7960 i, section->sh_info);
7961 break;
7962
7963 case SHT_GROUP:
7964 case SHT_SYMTAB:
7965 case SHT_DYNSYM:
7966 /* A symbol index - we assume that it is valid. */
7967 break;
7968
7969 default:
7970 /* FIXME: Add support for target specific section types. */
7971 if (section->sh_type == SHT_NOBITS)
7972 /* NOBITS section headers with non-zero sh_info fields can be
7973 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7974 information. The stripped sections have their headers
7975 preserved but their types set to SHT_NOBITS. So do not check
7976 this type of section. */
dd905818
NC
7977 ;
7978 else if (section->sh_flags & SHF_INFO_LINK)
7979 {
dda8d76d 7980 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7981 warn (_("[%2u]: Expected link to another section in info field"), i);
7982 }
a91e1603
L
7983 else if (section->sh_type < SHT_LOOS
7984 && (section->sh_flags & SHF_GNU_MBIND) == 0
7985 && section->sh_info != 0)
dd905818
NC
7986 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7987 i, section->sh_info);
7988 break;
7989 }
7990
3e6b6445 7991 /* Check the sh_size field. */
dda8d76d 7992 if (section->sh_size > filedata->file_size
3e6b6445
NC
7993 && section->sh_type != SHT_NOBITS
7994 && section->sh_type != SHT_NULL
7995 && section->sh_type < SHT_LOOS)
7996 warn (_("Size of section %u is larger than the entire file!\n"), i);
7997
7bfd842d 7998 printf (" [%2u] ", i);
5477e8a0 7999 if (do_section_details)
dda8d76d 8000 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 8001 else
84714f86 8002 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 8003
ea52a088 8004 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 8005 get_section_type_name (filedata, section->sh_type));
0b4362b0 8006
f7a99963
NC
8007 if (is_32bit_elf)
8008 {
cfcac11d
NC
8009 const char * link_too_big = NULL;
8010
f7a99963 8011 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 8012
f7a99963
NC
8013 printf ( " %6.6lx %6.6lx %2.2lx",
8014 (unsigned long) section->sh_offset,
8015 (unsigned long) section->sh_size,
8016 (unsigned long) section->sh_entsize);
d1133906 8017
5477e8a0
L
8018 if (do_section_details)
8019 fputs (" ", stdout);
8020 else
dda8d76d 8021 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8022
dda8d76d 8023 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
8024 {
8025 link_too_big = "";
8026 /* The sh_link value is out of range. Normally this indicates
caa83f8b 8027 an error but it can have special values in Solaris binaries. */
dda8d76d 8028 switch (filedata->file_header.e_machine)
cfcac11d 8029 {
caa83f8b 8030 case EM_386:
22abe556 8031 case EM_IAMCU:
caa83f8b 8032 case EM_X86_64:
7f502d6c 8033 case EM_L1OM:
7a9068fe 8034 case EM_K1OM:
cfcac11d
NC
8035 case EM_OLD_SPARCV9:
8036 case EM_SPARC32PLUS:
8037 case EM_SPARCV9:
8038 case EM_SPARC:
8039 if (section->sh_link == (SHN_BEFORE & 0xffff))
8040 link_too_big = "BEFORE";
8041 else if (section->sh_link == (SHN_AFTER & 0xffff))
8042 link_too_big = "AFTER";
8043 break;
8044 default:
8045 break;
8046 }
8047 }
8048
8049 if (do_section_details)
8050 {
8051 if (link_too_big != NULL && * link_too_big)
8052 printf ("<%s> ", link_too_big);
8053 else
8054 printf ("%2u ", section->sh_link);
8055 printf ("%3u %2lu\n", section->sh_info,
8056 (unsigned long) section->sh_addralign);
8057 }
8058 else
8059 printf ("%2u %3u %2lu\n",
8060 section->sh_link,
8061 section->sh_info,
8062 (unsigned long) section->sh_addralign);
8063
8064 if (link_too_big && ! * link_too_big)
8065 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
8066 i, section->sh_link);
f7a99963 8067 }
d974e256
JJ
8068 else if (do_wide)
8069 {
8070 print_vma (section->sh_addr, LONG_HEX);
8071
8072 if ((long) section->sh_offset == section->sh_offset)
8073 printf (" %6.6lx", (unsigned long) section->sh_offset);
8074 else
8075 {
8076 putchar (' ');
8077 print_vma (section->sh_offset, LONG_HEX);
8078 }
8079
8080 if ((unsigned long) section->sh_size == section->sh_size)
8081 printf (" %6.6lx", (unsigned long) section->sh_size);
8082 else
8083 {
8084 putchar (' ');
8085 print_vma (section->sh_size, LONG_HEX);
8086 }
8087
8088 if ((unsigned long) section->sh_entsize == section->sh_entsize)
8089 printf (" %2.2lx", (unsigned long) section->sh_entsize);
8090 else
8091 {
8092 putchar (' ');
8093 print_vma (section->sh_entsize, LONG_HEX);
8094 }
8095
5477e8a0
L
8096 if (do_section_details)
8097 fputs (" ", stdout);
8098 else
dda8d76d 8099 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 8100
72de5009 8101 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
8102
8103 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 8104 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
8105 else
8106 {
8107 print_vma (section->sh_addralign, DEC);
8108 putchar ('\n');
8109 }
8110 }
5477e8a0 8111 else if (do_section_details)
595cf52e 8112 {
55cc53e9 8113 putchar (' ');
595cf52e
L
8114 print_vma (section->sh_addr, LONG_HEX);
8115 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 8116 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
8117 else
8118 {
8119 printf (" ");
8120 print_vma (section->sh_offset, LONG_HEX);
8121 }
72de5009 8122 printf (" %u\n ", section->sh_link);
595cf52e 8123 print_vma (section->sh_size, LONG_HEX);
5477e8a0 8124 putchar (' ');
595cf52e
L
8125 print_vma (section->sh_entsize, LONG_HEX);
8126
72de5009
AM
8127 printf (" %-16u %lu\n",
8128 section->sh_info,
595cf52e
L
8129 (unsigned long) section->sh_addralign);
8130 }
f7a99963
NC
8131 else
8132 {
8133 putchar (' ');
8134 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
8135 if ((long) section->sh_offset == section->sh_offset)
8136 printf (" %8.8lx", (unsigned long) section->sh_offset);
8137 else
8138 {
8139 printf (" ");
8140 print_vma (section->sh_offset, LONG_HEX);
8141 }
f7a99963
NC
8142 printf ("\n ");
8143 print_vma (section->sh_size, LONG_HEX);
8144 printf (" ");
8145 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 8146
dda8d76d 8147 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8148
72de5009
AM
8149 printf (" %2u %3u %lu\n",
8150 section->sh_link,
8151 section->sh_info,
f7a99963
NC
8152 (unsigned long) section->sh_addralign);
8153 }
5477e8a0
L
8154
8155 if (do_section_details)
77115a4a 8156 {
dda8d76d 8157 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
8158 if ((section->sh_flags & SHF_COMPRESSED) != 0)
8159 {
8160 /* Minimum section size is 12 bytes for 32-bit compression
8161 header + 12 bytes for compressed data header. */
8162 unsigned char buf[24];
d8024a91 8163
77115a4a 8164 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 8165 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
8166 sizeof (buf), _("compression header")))
8167 {
8168 Elf_Internal_Chdr chdr;
d8024a91 8169
5844b465
NC
8170 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
8171 printf (_(" [<corrupt>]\n"));
77115a4a 8172 else
5844b465 8173 {
89dbeac7 8174 if (chdr.ch_type == ch_compress_zlib)
5844b465 8175 printf (" ZLIB, ");
89dbeac7 8176 else if (chdr.ch_type == ch_compress_zstd)
1369522f 8177 printf (" ZSTD, ");
5844b465
NC
8178 else
8179 printf (_(" [<unknown>: 0x%x], "),
8180 chdr.ch_type);
8181 print_vma (chdr.ch_size, LONG_HEX);
8182 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
8183 }
77115a4a
L
8184 }
8185 }
8186 }
252b5132
RH
8187 }
8188
5477e8a0 8189 if (!do_section_details)
3dbcc61d 8190 {
9fb71ee4
NC
8191 /* The ordering of the letters shown here matches the ordering of the
8192 corresponding SHF_xxx values, and hence the order in which these
8193 letters will be displayed to the user. */
8194 printf (_("Key to Flags:\n\
8195 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
8196 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 8197 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
8198 switch (filedata->file_header.e_ident[EI_OSABI])
8199 {
8200 case ELFOSABI_GNU:
8201 case ELFOSABI_FREEBSD:
8202 printf (_("R (retain), "));
8203 /* Fall through */
8204 case ELFOSABI_NONE:
8205 printf (_("D (mbind), "));
8206 break;
8207 default:
8208 break;
8209 }
dda8d76d
NC
8210 if (filedata->file_header.e_machine == EM_X86_64
8211 || filedata->file_header.e_machine == EM_L1OM
8212 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 8213 printf (_("l (large), "));
dda8d76d 8214 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 8215 printf (_("y (purecode), "));
dda8d76d 8216 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 8217 printf (_("v (VLE), "));
9fb71ee4 8218 printf ("p (processor specific)\n");
0b4362b0 8219 }
d1133906 8220
015dc7e1 8221 return true;
252b5132
RH
8222}
8223
015dc7e1 8224static bool
28d13567 8225get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
26c527e6
AM
8226 Elf_Internal_Sym **symtab, uint64_t *nsyms,
8227 char **strtab, uint64_t *strtablen)
28d13567
AM
8228{
8229 *strtab = NULL;
8230 *strtablen = 0;
4de91c10 8231 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
8232
8233 if (*symtab == NULL)
015dc7e1 8234 return false;
28d13567
AM
8235
8236 if (symsec->sh_link != 0)
8237 {
8238 Elf_Internal_Shdr *strsec;
8239
8240 if (symsec->sh_link >= filedata->file_header.e_shnum)
8241 {
8242 error (_("Bad sh_link in symbol table section\n"));
8243 free (*symtab);
8244 *symtab = NULL;
8245 *nsyms = 0;
015dc7e1 8246 return false;
28d13567
AM
8247 }
8248
8249 strsec = filedata->section_headers + symsec->sh_link;
8250
8251 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
8252 1, strsec->sh_size, _("string table"));
8253 if (*strtab == NULL)
8254 {
8255 free (*symtab);
8256 *symtab = NULL;
8257 *nsyms = 0;
015dc7e1 8258 return false;
28d13567
AM
8259 }
8260 *strtablen = strsec->sh_size;
8261 }
015dc7e1 8262 return true;
28d13567
AM
8263}
8264
f5842774
L
8265static const char *
8266get_group_flags (unsigned int flags)
8267{
1449284b 8268 static char buff[128];
220453ec 8269
6d913794
NC
8270 if (flags == 0)
8271 return "";
8272 else if (flags == GRP_COMDAT)
8273 return "COMDAT ";
f5842774 8274
89246a0e
AM
8275 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
8276 flags,
8277 flags & GRP_MASKOS ? _("<OS specific>") : "",
8278 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
8279 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
8280 ? _("<unknown>") : ""));
6d913794 8281
f5842774
L
8282 return buff;
8283}
8284
015dc7e1 8285static bool
dda8d76d 8286process_section_groups (Filedata * filedata)
f5842774 8287{
2cf0635d 8288 Elf_Internal_Shdr * section;
f5842774 8289 unsigned int i;
2cf0635d
NC
8290 struct group * group;
8291 Elf_Internal_Shdr * symtab_sec;
8292 Elf_Internal_Shdr * strtab_sec;
8293 Elf_Internal_Sym * symtab;
26c527e6 8294 uint64_t num_syms;
2cf0635d 8295 char * strtab;
c256ffe7 8296 size_t strtab_size;
d1f5c6e3
L
8297
8298 /* Don't process section groups unless needed. */
8299 if (!do_unwind && !do_section_groups)
015dc7e1 8300 return true;
f5842774 8301
dda8d76d 8302 if (filedata->file_header.e_shnum == 0)
f5842774
L
8303 {
8304 if (do_section_groups)
ca0e11aa
NC
8305 {
8306 if (filedata->is_separate)
8307 printf (_("\nThere are no sections group in linked file '%s'.\n"),
8308 filedata->file_name);
8309 else
8310 printf (_("\nThere are no section groups in this file.\n"));
8311 }
015dc7e1 8312 return true;
f5842774
L
8313 }
8314
dda8d76d 8315 if (filedata->section_headers == NULL)
f5842774
L
8316 {
8317 error (_("Section headers are not available!\n"));
fa1908fd 8318 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 8319 return false;
f5842774
L
8320 }
8321
978c4450
AM
8322 filedata->section_headers_groups
8323 = (struct group **) calloc (filedata->file_header.e_shnum,
8324 sizeof (struct group *));
e4b17d5c 8325
978c4450 8326 if (filedata->section_headers_groups == NULL)
e4b17d5c 8327 {
8b73c356 8328 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 8329 filedata->file_header.e_shnum);
015dc7e1 8330 return false;
e4b17d5c
L
8331 }
8332
f5842774 8333 /* Scan the sections for the group section. */
978c4450 8334 filedata->group_count = 0;
dda8d76d
NC
8335 for (i = 0, section = filedata->section_headers;
8336 i < filedata->file_header.e_shnum;
f5842774 8337 i++, section++)
e4b17d5c 8338 if (section->sh_type == SHT_GROUP)
978c4450 8339 filedata->group_count++;
e4b17d5c 8340
978c4450 8341 if (filedata->group_count == 0)
d1f5c6e3
L
8342 {
8343 if (do_section_groups)
ca0e11aa
NC
8344 {
8345 if (filedata->is_separate)
8346 printf (_("\nThere are no section groups in linked file '%s'.\n"),
8347 filedata->file_name);
8348 else
8349 printf (_("\nThere are no section groups in this file.\n"));
8350 }
d1f5c6e3 8351
015dc7e1 8352 return true;
d1f5c6e3
L
8353 }
8354
978c4450
AM
8355 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8356 sizeof (struct group));
e4b17d5c 8357
978c4450 8358 if (filedata->section_groups == NULL)
e4b17d5c 8359 {
26c527e6 8360 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
015dc7e1 8361 return false;
e4b17d5c
L
8362 }
8363
d1f5c6e3
L
8364 symtab_sec = NULL;
8365 strtab_sec = NULL;
8366 symtab = NULL;
ba5cdace 8367 num_syms = 0;
d1f5c6e3 8368 strtab = NULL;
c256ffe7 8369 strtab_size = 0;
ca0e11aa
NC
8370
8371 if (filedata->is_separate)
8372 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 8373
978c4450 8374 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 8375 i < filedata->file_header.e_shnum;
e4b17d5c 8376 i++, section++)
f5842774
L
8377 {
8378 if (section->sh_type == SHT_GROUP)
8379 {
dda8d76d 8380 const char * name = printable_section_name (filedata, section);
74e1a04b 8381 const char * group_name;
2cf0635d
NC
8382 unsigned char * start;
8383 unsigned char * indices;
f5842774 8384 unsigned int entry, j, size;
2cf0635d
NC
8385 Elf_Internal_Shdr * sec;
8386 Elf_Internal_Sym * sym;
f5842774
L
8387
8388 /* Get the symbol table. */
dda8d76d
NC
8389 if (section->sh_link >= filedata->file_header.e_shnum
8390 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 8391 != SHT_SYMTAB))
f5842774
L
8392 {
8393 error (_("Bad sh_link in group section `%s'\n"), name);
8394 continue;
8395 }
d1f5c6e3
L
8396
8397 if (symtab_sec != sec)
8398 {
8399 symtab_sec = sec;
9db70fc3 8400 free (symtab);
4de91c10 8401 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 8402 }
f5842774 8403
dd24e3da
NC
8404 if (symtab == NULL)
8405 {
8406 error (_("Corrupt header in group section `%s'\n"), name);
8407 continue;
8408 }
8409
ba5cdace
NC
8410 if (section->sh_info >= num_syms)
8411 {
8412 error (_("Bad sh_info in group section `%s'\n"), name);
8413 continue;
8414 }
8415
f5842774
L
8416 sym = symtab + section->sh_info;
8417
8418 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8419 {
4fbb74a6 8420 if (sym->st_shndx == 0
dda8d76d 8421 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
8422 {
8423 error (_("Bad sh_info in group section `%s'\n"), name);
8424 continue;
8425 }
ba2685cc 8426
84714f86
AM
8427 group_name = section_name_print (filedata,
8428 filedata->section_headers
b9e920ec 8429 + sym->st_shndx);
c256ffe7 8430 strtab_sec = NULL;
9db70fc3 8431 free (strtab);
f5842774 8432 strtab = NULL;
c256ffe7 8433 strtab_size = 0;
f5842774
L
8434 }
8435 else
8436 {
8437 /* Get the string table. */
dda8d76d 8438 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8439 {
8440 strtab_sec = NULL;
9db70fc3 8441 free (strtab);
c256ffe7
JJ
8442 strtab = NULL;
8443 strtab_size = 0;
8444 }
8445 else if (strtab_sec
dda8d76d 8446 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8447 {
8448 strtab_sec = sec;
9db70fc3 8449 free (strtab);
071436c6 8450
dda8d76d 8451 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8452 1, strtab_sec->sh_size,
8453 _("string table"));
c256ffe7 8454 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8455 }
c256ffe7 8456 group_name = sym->st_name < strtab_size
2b692964 8457 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8458 }
8459
c9c1d674
EG
8460 /* PR 17531: file: loop. */
8461 if (section->sh_entsize > section->sh_size)
8462 {
26c527e6
AM
8463 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8464 " which is larger than its size (%#" PRIx64 ")\n"),
dda8d76d 8465 printable_section_name (filedata, section),
26c527e6
AM
8466 section->sh_entsize,
8467 section->sh_size);
61dd8e19 8468 continue;
c9c1d674
EG
8469 }
8470
dda8d76d 8471 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8472 1, section->sh_size,
8473 _("section data"));
59245841
NC
8474 if (start == NULL)
8475 continue;
f5842774
L
8476
8477 indices = start;
8478 size = (section->sh_size / section->sh_entsize) - 1;
8479 entry = byte_get (indices, 4);
8480 indices += 4;
e4b17d5c
L
8481
8482 if (do_section_groups)
8483 {
2b692964 8484 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8485 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8486
e4b17d5c
L
8487 printf (_(" [Index] Name\n"));
8488 }
8489
8490 group->group_index = i;
8491
f5842774
L
8492 for (j = 0; j < size; j++)
8493 {
2cf0635d 8494 struct group_list * g;
e4b17d5c 8495
f5842774
L
8496 entry = byte_get (indices, 4);
8497 indices += 4;
8498
dda8d76d 8499 if (entry >= filedata->file_header.e_shnum)
391cb864 8500 {
57028622
NC
8501 static unsigned num_group_errors = 0;
8502
8503 if (num_group_errors ++ < 10)
8504 {
8505 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8506 entry, i, filedata->file_header.e_shnum - 1);
57028622 8507 if (num_group_errors == 10)
67ce483b 8508 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8509 }
391cb864
L
8510 continue;
8511 }
391cb864 8512
978c4450 8513 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8514 {
d1f5c6e3
L
8515 if (entry)
8516 {
57028622
NC
8517 static unsigned num_errs = 0;
8518
8519 if (num_errs ++ < 10)
8520 {
8521 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8522 entry, i,
978c4450 8523 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8524 if (num_errs == 10)
8525 warn (_("Further error messages about already contained group sections suppressed\n"));
8526 }
d1f5c6e3
L
8527 continue;
8528 }
8529 else
8530 {
8531 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8532 section group. We just warn it the first time
d1f5c6e3 8533 and ignore it afterwards. */
015dc7e1 8534 static bool warned = false;
d1f5c6e3
L
8535 if (!warned)
8536 {
8537 error (_("section 0 in group section [%5u]\n"),
978c4450 8538 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8539 warned = true;
d1f5c6e3
L
8540 }
8541 }
e4b17d5c
L
8542 }
8543
978c4450 8544 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8545
8546 if (do_section_groups)
8547 {
dda8d76d
NC
8548 sec = filedata->section_headers + entry;
8549 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8550 }
8551
3f5e193b 8552 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8553 g->section_index = entry;
8554 g->next = group->root;
8555 group->root = g;
f5842774
L
8556 }
8557
9db70fc3 8558 free (start);
e4b17d5c
L
8559
8560 group++;
f5842774
L
8561 }
8562 }
8563
9db70fc3
AM
8564 free (symtab);
8565 free (strtab);
015dc7e1 8566 return true;
f5842774
L
8567}
8568
28f997cf
TG
8569/* Data used to display dynamic fixups. */
8570
8571struct ia64_vms_dynfixup
8572{
625d49fc
AM
8573 uint64_t needed_ident; /* Library ident number. */
8574 uint64_t needed; /* Index in the dstrtab of the library name. */
8575 uint64_t fixup_needed; /* Index of the library. */
8576 uint64_t fixup_rela_cnt; /* Number of fixups. */
8577 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8578};
8579
8580/* Data used to display dynamic relocations. */
8581
8582struct ia64_vms_dynimgrela
8583{
625d49fc
AM
8584 uint64_t img_rela_cnt; /* Number of relocations. */
8585 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8586};
8587
8588/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8589 library). */
8590
015dc7e1 8591static bool
dda8d76d
NC
8592dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8593 struct ia64_vms_dynfixup * fixup,
8594 const char * strtab,
8595 unsigned int strtab_sz)
28f997cf 8596{
32ec8896 8597 Elf64_External_VMS_IMAGE_FIXUP * imfs;
26c527e6 8598 size_t i;
32ec8896 8599 const char * lib_name;
28f997cf 8600
978c4450
AM
8601 imfs = get_data (NULL, filedata,
8602 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8603 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8604 _("dynamic section image fixups"));
8605 if (!imfs)
015dc7e1 8606 return false;
28f997cf
TG
8607
8608 if (fixup->needed < strtab_sz)
8609 lib_name = strtab + fixup->needed;
8610 else
8611 {
26c527e6
AM
8612 warn (_("corrupt library name index of %#" PRIx64
8613 " found in dynamic entry"), fixup->needed);
28f997cf
TG
8614 lib_name = "???";
8615 }
736990c4 8616
26c527e6
AM
8617 printf (_("\nImage fixups for needed library #%" PRId64
8618 ": %s - ident: %" PRIx64 "\n"),
8619 fixup->fixup_needed, lib_name, fixup->needed_ident);
28f997cf
TG
8620 printf
8621 (_("Seg Offset Type SymVec DataType\n"));
8622
26c527e6 8623 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
28f997cf
TG
8624 {
8625 unsigned int type;
8626 const char *rtype;
8627
8628 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8629 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8630 type = BYTE_GET (imfs [i].type);
8631 rtype = elf_ia64_reloc_type (type);
8632 if (rtype == NULL)
f493c217 8633 printf ("0x%08x ", type);
28f997cf 8634 else
f493c217 8635 printf ("%-32s ", rtype);
28f997cf
TG
8636 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8637 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8638 }
8639
8640 free (imfs);
015dc7e1 8641 return true;
28f997cf
TG
8642}
8643
8644/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8645
015dc7e1 8646static bool
dda8d76d 8647dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8648{
8649 Elf64_External_VMS_IMAGE_RELA *imrs;
26c527e6 8650 size_t i;
28f997cf 8651
978c4450
AM
8652 imrs = get_data (NULL, filedata,
8653 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8654 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8655 _("dynamic section image relocations"));
28f997cf 8656 if (!imrs)
015dc7e1 8657 return false;
28f997cf
TG
8658
8659 printf (_("\nImage relocs\n"));
8660 printf
8661 (_("Seg Offset Type Addend Seg Sym Off\n"));
8662
26c527e6 8663 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
28f997cf
TG
8664 {
8665 unsigned int type;
8666 const char *rtype;
8667
8668 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8669 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8670 type = BYTE_GET (imrs [i].type);
8671 rtype = elf_ia64_reloc_type (type);
8672 if (rtype == NULL)
8673 printf ("0x%08x ", type);
8674 else
8675 printf ("%-31s ", rtype);
8676 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8677 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8678 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8679 }
8680
8681 free (imrs);
015dc7e1 8682 return true;
28f997cf
TG
8683}
8684
8685/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8686
015dc7e1 8687static bool
dda8d76d 8688process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8689{
8690 struct ia64_vms_dynfixup fixup;
8691 struct ia64_vms_dynimgrela imgrela;
8692 Elf_Internal_Dyn *entry;
625d49fc
AM
8693 uint64_t strtab_off = 0;
8694 uint64_t strtab_sz = 0;
28f997cf 8695 char *strtab = NULL;
015dc7e1 8696 bool res = true;
28f997cf
TG
8697
8698 memset (&fixup, 0, sizeof (fixup));
8699 memset (&imgrela, 0, sizeof (imgrela));
8700
8701 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8702 for (entry = filedata->dynamic_section;
8703 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8704 entry++)
8705 {
8706 switch (entry->d_tag)
8707 {
8708 case DT_IA_64_VMS_STRTAB_OFFSET:
8709 strtab_off = entry->d_un.d_val;
8710 break;
8711 case DT_STRSZ:
8712 strtab_sz = entry->d_un.d_val;
8713 if (strtab == NULL)
978c4450
AM
8714 strtab = get_data (NULL, filedata,
8715 filedata->dynamic_addr + strtab_off,
28f997cf 8716 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8717 if (strtab == NULL)
8718 strtab_sz = 0;
28f997cf
TG
8719 break;
8720
8721 case DT_IA_64_VMS_NEEDED_IDENT:
8722 fixup.needed_ident = entry->d_un.d_val;
8723 break;
8724 case DT_NEEDED:
8725 fixup.needed = entry->d_un.d_val;
8726 break;
8727 case DT_IA_64_VMS_FIXUP_NEEDED:
8728 fixup.fixup_needed = entry->d_un.d_val;
8729 break;
8730 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8731 fixup.fixup_rela_cnt = entry->d_un.d_val;
8732 break;
8733 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8734 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8735 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8736 res = false;
28f997cf 8737 break;
28f997cf
TG
8738 case DT_IA_64_VMS_IMG_RELA_CNT:
8739 imgrela.img_rela_cnt = entry->d_un.d_val;
8740 break;
8741 case DT_IA_64_VMS_IMG_RELA_OFF:
8742 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8743 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8744 res = false;
28f997cf
TG
8745 break;
8746
8747 default:
8748 break;
8749 }
8750 }
8751
9db70fc3 8752 free (strtab);
28f997cf
TG
8753
8754 return res;
8755}
8756
85b1c36d 8757static struct
566b0d53 8758{
2cf0635d 8759 const char * name;
566b0d53
L
8760 int reloc;
8761 int size;
a7fd1186 8762 relocation_type rel_type;
32ec8896
NC
8763}
8764 dynamic_relocations [] =
566b0d53 8765{
a7fd1186
FS
8766 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8767 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8768 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8769 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8770};
8771
252b5132 8772/* Process the reloc section. */
18bd398b 8773
015dc7e1 8774static bool
dda8d76d 8775process_relocs (Filedata * filedata)
252b5132 8776{
26c527e6
AM
8777 uint64_t rel_size;
8778 uint64_t rel_offset;
252b5132 8779
252b5132 8780 if (!do_reloc)
015dc7e1 8781 return true;
252b5132
RH
8782
8783 if (do_using_dynamic)
8784 {
a7fd1186 8785 relocation_type rel_type;
2cf0635d 8786 const char * name;
015dc7e1 8787 bool has_dynamic_reloc;
566b0d53 8788 unsigned int i;
0de14b54 8789
015dc7e1 8790 has_dynamic_reloc = false;
252b5132 8791
566b0d53 8792 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8793 {
a7fd1186 8794 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8795 name = dynamic_relocations [i].name;
978c4450
AM
8796 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8797 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8798
32ec8896 8799 if (rel_size)
015dc7e1 8800 has_dynamic_reloc = true;
566b0d53 8801
a7fd1186 8802 if (rel_type == reltype_unknown)
aa903cfb 8803 {
566b0d53 8804 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8805 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8806 {
8807 case DT_REL:
a7fd1186 8808 rel_type = reltype_rel;
566b0d53
L
8809 break;
8810 case DT_RELA:
a7fd1186 8811 rel_type = reltype_rela;
566b0d53
L
8812 break;
8813 }
aa903cfb 8814 }
252b5132 8815
566b0d53
L
8816 if (rel_size)
8817 {
ca0e11aa
NC
8818 if (filedata->is_separate)
8819 printf
26c527e6
AM
8820 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
8821 " contains %" PRId64 " bytes:\n"),
ca0e11aa
NC
8822 filedata->file_name, name, rel_offset, rel_size);
8823 else
8824 printf
26c527e6
AM
8825 (_("\n'%s' relocation section at offset %#" PRIx64
8826 " contains %" PRId64 " bytes:\n"),
ca0e11aa 8827 name, rel_offset, rel_size);
252b5132 8828
dda8d76d
NC
8829 dump_relocations (filedata,
8830 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8831 rel_size,
978c4450
AM
8832 filedata->dynamic_symbols,
8833 filedata->num_dynamic_syms,
8834 filedata->dynamic_strings,
8835 filedata->dynamic_strings_length,
a7fd1186 8836 rel_type, true /* is_dynamic */);
566b0d53 8837 }
252b5132 8838 }
566b0d53 8839
dda8d76d
NC
8840 if (is_ia64_vms (filedata))
8841 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8842 has_dynamic_reloc = true;
28f997cf 8843
566b0d53 8844 if (! has_dynamic_reloc)
ca0e11aa
NC
8845 {
8846 if (filedata->is_separate)
8847 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8848 filedata->file_name);
8849 else
8850 printf (_("\nThere are no dynamic relocations in this file.\n"));
8851 }
252b5132
RH
8852 }
8853 else
8854 {
2cf0635d 8855 Elf_Internal_Shdr * section;
26c527e6 8856 size_t i;
015dc7e1 8857 bool found = false;
252b5132 8858
dda8d76d
NC
8859 for (i = 0, section = filedata->section_headers;
8860 i < filedata->file_header.e_shnum;
b34976b6 8861 i++, section++)
252b5132
RH
8862 {
8863 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8864 && section->sh_type != SHT_REL
8865 && section->sh_type != SHT_RELR)
252b5132
RH
8866 continue;
8867
8868 rel_offset = section->sh_offset;
8869 rel_size = section->sh_size;
8870
8871 if (rel_size)
8872 {
a7fd1186 8873 relocation_type rel_type;
26c527e6 8874 uint64_t num_rela;
103f02d3 8875
ca0e11aa
NC
8876 if (filedata->is_separate)
8877 printf (_("\nIn linked file '%s' relocation section "),
8878 filedata->file_name);
8879 else
8880 printf (_("\nRelocation section "));
252b5132 8881
dda8d76d 8882 if (filedata->string_table == NULL)
19936277 8883 printf ("%d", section->sh_name);
252b5132 8884 else
dda8d76d 8885 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8886
d3a49aa8 8887 num_rela = rel_size / section->sh_entsize;
26c527e6
AM
8888 printf (ngettext (" at offset %#" PRIx64
8889 " contains %" PRIu64 " entry:\n",
8890 " at offset %#" PRIx64
8891 " contains %" PRId64 " entries:\n",
d3a49aa8
AM
8892 num_rela),
8893 rel_offset, num_rela);
252b5132 8894
a7fd1186
FS
8895 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8896 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8897
4fbb74a6 8898 if (section->sh_link != 0
dda8d76d 8899 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8900 {
26c527e6
AM
8901 Elf_Internal_Shdr *symsec;
8902 Elf_Internal_Sym *symtab;
8903 uint64_t nsyms;
8904 uint64_t strtablen = 0;
8905 char *strtab = NULL;
57346661 8906
dda8d76d 8907 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8908 if (symsec->sh_type != SHT_SYMTAB
8909 && symsec->sh_type != SHT_DYNSYM)
8910 continue;
8911
28d13567
AM
8912 if (!get_symtab (filedata, symsec,
8913 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8914 continue;
252b5132 8915
dda8d76d 8916 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8917 symtab, nsyms, strtab, strtablen,
a7fd1186 8918 rel_type,
bb4d2ac2 8919 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8920 free (strtab);
d79b3d50
NC
8921 free (symtab);
8922 }
8923 else
dda8d76d 8924 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8925 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8926
015dc7e1 8927 found = true;
252b5132
RH
8928 }
8929 }
8930
8931 if (! found)
45ac8f4f
NC
8932 {
8933 /* Users sometimes forget the -D option, so try to be helpful. */
8934 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8935 {
978c4450 8936 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8937 {
ca0e11aa
NC
8938 if (filedata->is_separate)
8939 printf (_("\nThere are no static relocations in linked file '%s'."),
8940 filedata->file_name);
8941 else
8942 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8943 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8944
8945 break;
8946 }
8947 }
8948 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8949 {
8950 if (filedata->is_separate)
8951 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8952 filedata->file_name);
8953 else
8954 printf (_("\nThere are no relocations in this file.\n"));
8955 }
45ac8f4f 8956 }
252b5132
RH
8957 }
8958
015dc7e1 8959 return true;
252b5132
RH
8960}
8961
4d6ed7c8
NC
8962/* An absolute address consists of a section and an offset. If the
8963 section is NULL, the offset itself is the address, otherwise, the
8964 address equals to LOAD_ADDRESS(section) + offset. */
8965
8966struct absaddr
948f632f
DA
8967{
8968 unsigned short section;
625d49fc 8969 uint64_t offset;
948f632f 8970};
4d6ed7c8 8971
948f632f
DA
8972/* Find the nearest symbol at or below ADDR. Returns the symbol
8973 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8974
4d6ed7c8 8975static void
26c527e6
AM
8976find_symbol_for_address (Filedata *filedata,
8977 Elf_Internal_Sym *symtab,
8978 uint64_t nsyms,
8979 const char *strtab,
8980 uint64_t strtab_size,
8981 struct absaddr addr,
8982 const char **symname,
8983 uint64_t *offset)
4d6ed7c8 8984{
625d49fc 8985 uint64_t dist = 0x100000;
2cf0635d 8986 Elf_Internal_Sym * sym;
948f632f
DA
8987 Elf_Internal_Sym * beg;
8988 Elf_Internal_Sym * end;
2cf0635d 8989 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8990
0b6ae522 8991 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8992 beg = symtab;
8993 end = symtab + nsyms;
0b6ae522 8994
948f632f 8995 while (beg < end)
4d6ed7c8 8996 {
625d49fc 8997 uint64_t value;
948f632f
DA
8998
8999 sym = beg + (end - beg) / 2;
0b6ae522 9000
948f632f 9001 value = sym->st_value;
0b6ae522
DJ
9002 REMOVE_ARCH_BITS (value);
9003
948f632f 9004 if (sym->st_name != 0
4d6ed7c8 9005 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
9006 && addr.offset >= value
9007 && addr.offset - value < dist)
4d6ed7c8
NC
9008 {
9009 best = sym;
0b6ae522 9010 dist = addr.offset - value;
4d6ed7c8
NC
9011 if (!dist)
9012 break;
9013 }
948f632f
DA
9014
9015 if (addr.offset < value)
9016 end = sym;
9017 else
9018 beg = sym + 1;
4d6ed7c8 9019 }
1b31d05e 9020
4d6ed7c8
NC
9021 if (best)
9022 {
57346661 9023 *symname = (best->st_name >= strtab_size
2b692964 9024 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
9025 *offset = dist;
9026 return;
9027 }
1b31d05e 9028
4d6ed7c8
NC
9029 *symname = NULL;
9030 *offset = addr.offset;
9031}
9032
32ec8896 9033static /* signed */ int
948f632f
DA
9034symcmp (const void *p, const void *q)
9035{
9036 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
9037 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
9038
9039 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
9040}
9041
9042/* Process the unwind section. */
9043
9044#include "unwind-ia64.h"
9045
9046struct ia64_unw_table_entry
9047{
9048 struct absaddr start;
9049 struct absaddr end;
9050 struct absaddr info;
9051};
9052
9053struct ia64_unw_aux_info
9054{
32ec8896 9055 struct ia64_unw_table_entry * table; /* Unwind table. */
26c527e6 9056 uint64_t table_len; /* Length of unwind table. */
32ec8896 9057 unsigned char * info; /* Unwind info. */
26c527e6 9058 uint64_t info_size; /* Size of unwind info. */
625d49fc
AM
9059 uint64_t info_addr; /* Starting address of unwind info. */
9060 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9061 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9062 uint64_t nsyms; /* Number of symbols. */
32ec8896 9063 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9064 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9065 char * strtab; /* The string table. */
26c527e6 9066 uint64_t strtab_size; /* Size of string table. */
948f632f
DA
9067};
9068
015dc7e1 9069static bool
dda8d76d 9070dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 9071{
2cf0635d 9072 struct ia64_unw_table_entry * tp;
26c527e6 9073 size_t j, nfuns;
4d6ed7c8 9074 int in_body;
015dc7e1 9075 bool res = true;
7036c0e1 9076
948f632f
DA
9077 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9078 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9079 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9080 aux->funtab[nfuns++] = aux->symtab[j];
9081 aux->nfuns = nfuns;
9082 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9083
4d6ed7c8
NC
9084 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9085 {
625d49fc
AM
9086 uint64_t stamp;
9087 uint64_t offset;
2cf0635d
NC
9088 const unsigned char * dp;
9089 const unsigned char * head;
53774b7e 9090 const unsigned char * end;
2cf0635d 9091 const char * procname;
4d6ed7c8 9092
dda8d76d 9093 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 9094 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
9095
9096 fputs ("\n<", stdout);
9097
9098 if (procname)
9099 {
9100 fputs (procname, stdout);
9101
9102 if (offset)
26c527e6 9103 printf ("+%" PRIx64, offset);
4d6ed7c8
NC
9104 }
9105
9106 fputs (">: [", stdout);
9107 print_vma (tp->start.offset, PREFIX_HEX);
9108 fputc ('-', stdout);
9109 print_vma (tp->end.offset, PREFIX_HEX);
26c527e6
AM
9110 printf ("], info at +0x%" PRIx64 "\n",
9111 tp->info.offset - aux->seg_base);
4d6ed7c8 9112
53774b7e
NC
9113 /* PR 17531: file: 86232b32. */
9114 if (aux->info == NULL)
9115 continue;
9116
97c0a079
AM
9117 offset = tp->info.offset;
9118 if (tp->info.section)
9119 {
9120 if (tp->info.section >= filedata->file_header.e_shnum)
9121 {
26c527e6
AM
9122 warn (_("Invalid section %u in table entry %td\n"),
9123 tp->info.section, tp - aux->table);
015dc7e1 9124 res = false;
97c0a079
AM
9125 continue;
9126 }
9127 offset += filedata->section_headers[tp->info.section].sh_addr;
9128 }
9129 offset -= aux->info_addr;
53774b7e 9130 /* PR 17531: file: 0997b4d1. */
90679903
AM
9131 if (offset >= aux->info_size
9132 || aux->info_size - offset < 8)
53774b7e 9133 {
26c527e6
AM
9134 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
9135 tp->info.offset, tp - aux->table);
015dc7e1 9136 res = false;
53774b7e
NC
9137 continue;
9138 }
9139
97c0a079 9140 head = aux->info + offset;
a4a00738 9141 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 9142
86f55779 9143 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
9144 (unsigned) UNW_VER (stamp),
9145 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
9146 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
9147 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 9148 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
9149
9150 if (UNW_VER (stamp) != 1)
9151 {
2b692964 9152 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
9153 continue;
9154 }
9155
9156 in_body = 0;
53774b7e
NC
9157 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
9158 /* PR 17531: file: 16ceda89. */
9159 if (end > aux->info + aux->info_size)
9160 end = aux->info + aux->info_size;
9161 for (dp = head + 8; dp < end;)
b4477bc8 9162 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 9163 }
948f632f
DA
9164
9165 free (aux->funtab);
32ec8896
NC
9166
9167 return res;
4d6ed7c8
NC
9168}
9169
015dc7e1 9170static bool
dda8d76d
NC
9171slurp_ia64_unwind_table (Filedata * filedata,
9172 struct ia64_unw_aux_info * aux,
9173 Elf_Internal_Shdr * sec)
4d6ed7c8 9174{
26c527e6 9175 uint64_t size, nrelas, i;
2cf0635d
NC
9176 Elf_Internal_Phdr * seg;
9177 struct ia64_unw_table_entry * tep;
9178 Elf_Internal_Shdr * relsec;
9179 Elf_Internal_Rela * rela;
9180 Elf_Internal_Rela * rp;
9181 unsigned char * table;
9182 unsigned char * tp;
9183 Elf_Internal_Sym * sym;
9184 const char * relname;
4d6ed7c8 9185
53774b7e
NC
9186 aux->table_len = 0;
9187
4d6ed7c8
NC
9188 /* First, find the starting address of the segment that includes
9189 this section: */
9190
dda8d76d 9191 if (filedata->file_header.e_phnum)
4d6ed7c8 9192 {
dda8d76d 9193 if (! get_program_headers (filedata))
015dc7e1 9194 return false;
4d6ed7c8 9195
dda8d76d
NC
9196 for (seg = filedata->program_headers;
9197 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 9198 ++seg)
4d6ed7c8
NC
9199 {
9200 if (seg->p_type != PT_LOAD)
9201 continue;
9202
9203 if (sec->sh_addr >= seg->p_vaddr
9204 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9205 {
9206 aux->seg_base = seg->p_vaddr;
9207 break;
9208 }
9209 }
4d6ed7c8
NC
9210 }
9211
9212 /* Second, build the unwind table from the contents of the unwind section: */
9213 size = sec->sh_size;
dda8d76d 9214 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9215 _("unwind table"));
a6e9f9df 9216 if (!table)
015dc7e1 9217 return false;
4d6ed7c8 9218
53774b7e 9219 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 9220 aux->table = (struct ia64_unw_table_entry *)
53774b7e 9221 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 9222 tep = aux->table;
53774b7e
NC
9223
9224 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
9225 {
9226 tep->start.section = SHN_UNDEF;
9227 tep->end.section = SHN_UNDEF;
9228 tep->info.section = SHN_UNDEF;
c6a0c689
AM
9229 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9230 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9231 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
9232 tep->start.offset += aux->seg_base;
9233 tep->end.offset += aux->seg_base;
9234 tep->info.offset += aux->seg_base;
9235 }
9236 free (table);
9237
41e92641 9238 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
9239 for (relsec = filedata->section_headers;
9240 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
9241 ++relsec)
9242 {
9243 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9244 || relsec->sh_info >= filedata->file_header.e_shnum
9245 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
9246 continue;
9247
dda8d76d 9248 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 9249 & rela, & nrelas))
53774b7e
NC
9250 {
9251 free (aux->table);
9252 aux->table = NULL;
9253 aux->table_len = 0;
015dc7e1 9254 return false;
53774b7e 9255 }
4d6ed7c8
NC
9256
9257 for (rp = rela; rp < rela + nrelas; ++rp)
9258 {
4770fb94 9259 unsigned int sym_ndx;
726bd37d
AM
9260 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9261 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 9262
82b1b41b
NC
9263 /* PR 17531: file: 9fa67536. */
9264 if (relname == NULL)
9265 {
726bd37d 9266 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
9267 continue;
9268 }
948f632f 9269
24d127aa 9270 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 9271 {
82b1b41b 9272 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
9273 continue;
9274 }
9275
89fac5e3 9276 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 9277
53774b7e
NC
9278 /* PR 17531: file: 5bc8d9bf. */
9279 if (i >= aux->table_len)
9280 {
26c527e6
AM
9281 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9282 i);
53774b7e
NC
9283 continue;
9284 }
9285
4770fb94
AM
9286 sym_ndx = get_reloc_symindex (rp->r_info);
9287 if (sym_ndx >= aux->nsyms)
9288 {
9289 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9290 sym_ndx);
9291 continue;
9292 }
9293 sym = aux->symtab + sym_ndx;
9294
53774b7e 9295 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
9296 {
9297 case 0:
9298 aux->table[i].start.section = sym->st_shndx;
e466bc6e 9299 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9300 break;
9301 case 1:
9302 aux->table[i].end.section = sym->st_shndx;
e466bc6e 9303 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9304 break;
9305 case 2:
9306 aux->table[i].info.section = sym->st_shndx;
e466bc6e 9307 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9308 break;
9309 default:
9310 break;
9311 }
9312 }
9313
9314 free (rela);
9315 }
9316
015dc7e1 9317 return true;
4d6ed7c8
NC
9318}
9319
015dc7e1 9320static bool
dda8d76d 9321ia64_process_unwind (Filedata * filedata)
4d6ed7c8 9322{
2cf0635d
NC
9323 Elf_Internal_Shdr * sec;
9324 Elf_Internal_Shdr * unwsec = NULL;
26c527e6 9325 uint64_t i, unwcount = 0, unwstart = 0;
57346661 9326 struct ia64_unw_aux_info aux;
015dc7e1 9327 bool res = true;
f1467e33 9328
4d6ed7c8
NC
9329 memset (& aux, 0, sizeof (aux));
9330
dda8d76d 9331 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 9332 {
28d13567 9333 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 9334 {
28d13567 9335 if (aux.symtab)
4082ef84 9336 {
28d13567
AM
9337 error (_("Multiple symbol tables encountered\n"));
9338 free (aux.symtab);
9339 aux.symtab = NULL;
4082ef84 9340 free (aux.strtab);
28d13567 9341 aux.strtab = NULL;
4082ef84 9342 }
28d13567
AM
9343 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9344 &aux.strtab, &aux.strtab_size))
015dc7e1 9345 return false;
4d6ed7c8
NC
9346 }
9347 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
9348 unwcount++;
9349 }
9350
9351 if (!unwcount)
9352 printf (_("\nThere are no unwind sections in this file.\n"));
9353
9354 while (unwcount-- > 0)
9355 {
84714f86 9356 const char *suffix;
579f31ac
JJ
9357 size_t len, len2;
9358
dda8d76d
NC
9359 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
9360 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
9361 if (sec->sh_type == SHT_IA_64_UNWIND)
9362 {
9363 unwsec = sec;
9364 break;
9365 }
4082ef84
NC
9366 /* We have already counted the number of SHT_IA64_UNWIND
9367 sections so the loop above should never fail. */
9368 assert (unwsec != NULL);
579f31ac
JJ
9369
9370 unwstart = i + 1;
9371 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9372
e4b17d5c
L
9373 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9374 {
9375 /* We need to find which section group it is in. */
4082ef84 9376 struct group_list * g;
e4b17d5c 9377
978c4450
AM
9378 if (filedata->section_headers_groups == NULL
9379 || filedata->section_headers_groups[i] == NULL)
dda8d76d 9380 i = filedata->file_header.e_shnum;
4082ef84 9381 else
e4b17d5c 9382 {
978c4450 9383 g = filedata->section_headers_groups[i]->root;
18bd398b 9384
4082ef84
NC
9385 for (; g != NULL; g = g->next)
9386 {
dda8d76d 9387 sec = filedata->section_headers + g->section_index;
e4b17d5c 9388
84714f86
AM
9389 if (section_name_valid (filedata, sec)
9390 && streq (section_name (filedata, sec),
9391 ELF_STRING_ia64_unwind_info))
4082ef84
NC
9392 break;
9393 }
9394
9395 if (g == NULL)
dda8d76d 9396 i = filedata->file_header.e_shnum;
4082ef84 9397 }
e4b17d5c 9398 }
84714f86
AM
9399 else if (section_name_valid (filedata, unwsec)
9400 && startswith (section_name (filedata, unwsec),
e9b095a5 9401 ELF_STRING_ia64_unwind_once))
579f31ac 9402 {
18bd398b 9403 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 9404 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 9405 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9406 for (i = 0, sec = filedata->section_headers;
9407 i < filedata->file_header.e_shnum;
579f31ac 9408 ++i, ++sec)
84714f86
AM
9409 if (section_name_valid (filedata, sec)
9410 && startswith (section_name (filedata, sec),
e9b095a5 9411 ELF_STRING_ia64_unwind_info_once)
84714f86 9412 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9413 break;
9414 }
9415 else
9416 {
9417 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 9418 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
9419 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9420 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9421 suffix = "";
84714f86
AM
9422 if (section_name_valid (filedata, unwsec)
9423 && startswith (section_name (filedata, unwsec),
9424 ELF_STRING_ia64_unwind))
9425 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9426 for (i = 0, sec = filedata->section_headers;
9427 i < filedata->file_header.e_shnum;
579f31ac 9428 ++i, ++sec)
84714f86
AM
9429 if (section_name_valid (filedata, sec)
9430 && startswith (section_name (filedata, sec),
9431 ELF_STRING_ia64_unwind_info)
9432 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9433 break;
9434 }
9435
dda8d76d 9436 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
9437 {
9438 printf (_("\nCould not find unwind info section for "));
9439
dda8d76d 9440 if (filedata->string_table == NULL)
579f31ac
JJ
9441 printf ("%d", unwsec->sh_name);
9442 else
dda8d76d 9443 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9444 }
9445 else
4d6ed7c8 9446 {
4d6ed7c8 9447 aux.info_addr = sec->sh_addr;
dda8d76d 9448 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9449 sec->sh_size,
9450 _("unwind info"));
59245841 9451 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9452
579f31ac 9453 printf (_("\nUnwind section "));
4d6ed7c8 9454
dda8d76d 9455 if (filedata->string_table == NULL)
579f31ac
JJ
9456 printf ("%d", unwsec->sh_name);
9457 else
dda8d76d 9458 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9459
26c527e6
AM
9460 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9461 unwsec->sh_offset,
9462 unwsec->sh_size / (3 * eh_addr_size));
4d6ed7c8 9463
dda8d76d 9464 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9465 && aux.table_len > 0)
dda8d76d 9466 dump_ia64_unwind (filedata, & aux);
579f31ac 9467
9db70fc3
AM
9468 free ((char *) aux.table);
9469 free ((char *) aux.info);
579f31ac
JJ
9470 aux.table = NULL;
9471 aux.info = NULL;
9472 }
4d6ed7c8 9473 }
4d6ed7c8 9474
9db70fc3
AM
9475 free (aux.symtab);
9476 free ((char *) aux.strtab);
32ec8896
NC
9477
9478 return res;
4d6ed7c8
NC
9479}
9480
3f5e193b 9481struct hppa_unw_table_entry
32ec8896
NC
9482{
9483 struct absaddr start;
9484 struct absaddr end;
9485 unsigned int Cannot_unwind:1; /* 0 */
9486 unsigned int Millicode:1; /* 1 */
9487 unsigned int Millicode_save_sr0:1; /* 2 */
9488 unsigned int Region_description:2; /* 3..4 */
9489 unsigned int reserved1:1; /* 5 */
9490 unsigned int Entry_SR:1; /* 6 */
9491 unsigned int Entry_FR:4; /* Number saved 7..10 */
9492 unsigned int Entry_GR:5; /* Number saved 11..15 */
9493 unsigned int Args_stored:1; /* 16 */
9494 unsigned int Variable_Frame:1; /* 17 */
9495 unsigned int Separate_Package_Body:1; /* 18 */
9496 unsigned int Frame_Extension_Millicode:1; /* 19 */
9497 unsigned int Stack_Overflow_Check:1; /* 20 */
9498 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9499 unsigned int Ada_Region:1; /* 22 */
9500 unsigned int cxx_info:1; /* 23 */
9501 unsigned int cxx_try_catch:1; /* 24 */
9502 unsigned int sched_entry_seq:1; /* 25 */
9503 unsigned int reserved2:1; /* 26 */
9504 unsigned int Save_SP:1; /* 27 */
9505 unsigned int Save_RP:1; /* 28 */
9506 unsigned int Save_MRP_in_frame:1; /* 29 */
9507 unsigned int extn_ptr_defined:1; /* 30 */
9508 unsigned int Cleanup_defined:1; /* 31 */
9509
9510 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9511 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9512 unsigned int Large_frame:1; /* 2 */
9513 unsigned int Pseudo_SP_Set:1; /* 3 */
9514 unsigned int reserved4:1; /* 4 */
9515 unsigned int Total_frame_size:27; /* 5..31 */
9516};
3f5e193b 9517
57346661 9518struct hppa_unw_aux_info
948f632f 9519{
32ec8896 9520 struct hppa_unw_table_entry * table; /* Unwind table. */
26c527e6 9521 uint64_t table_len; /* Length of unwind table. */
625d49fc 9522 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9523 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9524 uint64_t nsyms; /* Number of symbols. */
32ec8896 9525 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9526 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9527 char * strtab; /* The string table. */
26c527e6 9528 uint64_t strtab_size; /* Size of string table. */
948f632f 9529};
57346661 9530
015dc7e1 9531static bool
dda8d76d 9532dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9533{
2cf0635d 9534 struct hppa_unw_table_entry * tp;
26c527e6 9535 uint64_t j, nfuns;
015dc7e1 9536 bool res = true;
948f632f
DA
9537
9538 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9539 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9540 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9541 aux->funtab[nfuns++] = aux->symtab[j];
9542 aux->nfuns = nfuns;
9543 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9544
57346661
AM
9545 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9546 {
625d49fc 9547 uint64_t offset;
2cf0635d 9548 const char * procname;
57346661 9549
dda8d76d 9550 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9551 aux->strtab_size, tp->start, &procname,
9552 &offset);
9553
9554 fputs ("\n<", stdout);
9555
9556 if (procname)
9557 {
9558 fputs (procname, stdout);
9559
9560 if (offset)
26c527e6 9561 printf ("+%" PRIx64, offset);
57346661
AM
9562 }
9563
9564 fputs (">: [", stdout);
9565 print_vma (tp->start.offset, PREFIX_HEX);
9566 fputc ('-', stdout);
9567 print_vma (tp->end.offset, PREFIX_HEX);
9568 printf ("]\n\t");
9569
18bd398b
NC
9570#define PF(_m) if (tp->_m) printf (#_m " ");
9571#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9572 PF(Cannot_unwind);
9573 PF(Millicode);
9574 PF(Millicode_save_sr0);
18bd398b 9575 /* PV(Region_description); */
57346661
AM
9576 PF(Entry_SR);
9577 PV(Entry_FR);
9578 PV(Entry_GR);
9579 PF(Args_stored);
9580 PF(Variable_Frame);
9581 PF(Separate_Package_Body);
9582 PF(Frame_Extension_Millicode);
9583 PF(Stack_Overflow_Check);
9584 PF(Two_Instruction_SP_Increment);
9585 PF(Ada_Region);
9586 PF(cxx_info);
9587 PF(cxx_try_catch);
9588 PF(sched_entry_seq);
9589 PF(Save_SP);
9590 PF(Save_RP);
9591 PF(Save_MRP_in_frame);
9592 PF(extn_ptr_defined);
9593 PF(Cleanup_defined);
9594 PF(MPE_XL_interrupt_marker);
9595 PF(HP_UX_interrupt_marker);
9596 PF(Large_frame);
9597 PF(Pseudo_SP_Set);
9598 PV(Total_frame_size);
9599#undef PF
9600#undef PV
9601 }
9602
18bd398b 9603 printf ("\n");
948f632f
DA
9604
9605 free (aux->funtab);
32ec8896
NC
9606
9607 return res;
57346661
AM
9608}
9609
015dc7e1 9610static bool
dda8d76d
NC
9611slurp_hppa_unwind_table (Filedata * filedata,
9612 struct hppa_unw_aux_info * aux,
9613 Elf_Internal_Shdr * sec)
57346661 9614{
26c527e6 9615 uint64_t size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9616 Elf_Internal_Phdr * seg;
9617 struct hppa_unw_table_entry * tep;
9618 Elf_Internal_Shdr * relsec;
9619 Elf_Internal_Rela * rela;
9620 Elf_Internal_Rela * rp;
9621 unsigned char * table;
9622 unsigned char * tp;
9623 Elf_Internal_Sym * sym;
9624 const char * relname;
57346661 9625
57346661
AM
9626 /* First, find the starting address of the segment that includes
9627 this section. */
dda8d76d 9628 if (filedata->file_header.e_phnum)
57346661 9629 {
dda8d76d 9630 if (! get_program_headers (filedata))
015dc7e1 9631 return false;
57346661 9632
dda8d76d
NC
9633 for (seg = filedata->program_headers;
9634 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9635 ++seg)
9636 {
9637 if (seg->p_type != PT_LOAD)
9638 continue;
9639
9640 if (sec->sh_addr >= seg->p_vaddr
9641 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9642 {
9643 aux->seg_base = seg->p_vaddr;
9644 break;
9645 }
9646 }
9647 }
9648
9649 /* Second, build the unwind table from the contents of the unwind
9650 section. */
9651 size = sec->sh_size;
dda8d76d 9652 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9653 _("unwind table"));
57346661 9654 if (!table)
015dc7e1 9655 return false;
57346661 9656
1c0751b2
DA
9657 unw_ent_size = 16;
9658 nentries = size / unw_ent_size;
9659 size = unw_ent_size * nentries;
57346661 9660
e3fdc001 9661 aux->table_len = nentries;
3f5e193b
NC
9662 tep = aux->table = (struct hppa_unw_table_entry *)
9663 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9664
1c0751b2 9665 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9666 {
9667 unsigned int tmp1, tmp2;
9668
9669 tep->start.section = SHN_UNDEF;
9670 tep->end.section = SHN_UNDEF;
9671
1c0751b2
DA
9672 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9673 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9674 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9675 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9676
9677 tep->start.offset += aux->seg_base;
9678 tep->end.offset += aux->seg_base;
57346661
AM
9679
9680 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9681 tep->Millicode = (tmp1 >> 30) & 0x1;
9682 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9683 tep->Region_description = (tmp1 >> 27) & 0x3;
9684 tep->reserved1 = (tmp1 >> 26) & 0x1;
9685 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9686 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9687 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9688 tep->Args_stored = (tmp1 >> 15) & 0x1;
9689 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9690 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9691 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9692 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9693 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9694 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9695 tep->cxx_info = (tmp1 >> 8) & 0x1;
9696 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9697 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9698 tep->reserved2 = (tmp1 >> 5) & 0x1;
9699 tep->Save_SP = (tmp1 >> 4) & 0x1;
9700 tep->Save_RP = (tmp1 >> 3) & 0x1;
9701 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9702 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9703 tep->Cleanup_defined = tmp1 & 0x1;
9704
9705 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9706 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9707 tep->Large_frame = (tmp2 >> 29) & 0x1;
9708 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9709 tep->reserved4 = (tmp2 >> 27) & 0x1;
9710 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9711 }
9712 free (table);
9713
9714 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9715 for (relsec = filedata->section_headers;
9716 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9717 ++relsec)
9718 {
9719 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9720 || relsec->sh_info >= filedata->file_header.e_shnum
9721 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9722 continue;
9723
dda8d76d 9724 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9725 & rela, & nrelas))
015dc7e1 9726 return false;
57346661
AM
9727
9728 for (rp = rela; rp < rela + nrelas; ++rp)
9729 {
4770fb94 9730 unsigned int sym_ndx;
726bd37d
AM
9731 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9732 relname = elf_hppa_reloc_type (r_type);
57346661 9733
726bd37d
AM
9734 if (relname == NULL)
9735 {
9736 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9737 continue;
9738 }
9739
57346661 9740 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9741 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9742 {
726bd37d 9743 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9744 continue;
9745 }
9746
9747 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9748 if (i >= aux->table_len)
9749 {
26c527e6
AM
9750 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9751 i);
726bd37d
AM
9752 continue;
9753 }
57346661 9754
4770fb94
AM
9755 sym_ndx = get_reloc_symindex (rp->r_info);
9756 if (sym_ndx >= aux->nsyms)
9757 {
9758 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9759 sym_ndx);
9760 continue;
9761 }
9762 sym = aux->symtab + sym_ndx;
9763
43f6cd05 9764 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9765 {
9766 case 0:
9767 aux->table[i].start.section = sym->st_shndx;
1e456d54 9768 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9769 break;
9770 case 1:
9771 aux->table[i].end.section = sym->st_shndx;
1e456d54 9772 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9773 break;
9774 default:
9775 break;
9776 }
9777 }
9778
9779 free (rela);
9780 }
9781
015dc7e1 9782 return true;
57346661
AM
9783}
9784
015dc7e1 9785static bool
dda8d76d 9786hppa_process_unwind (Filedata * filedata)
57346661 9787{
57346661 9788 struct hppa_unw_aux_info aux;
2cf0635d 9789 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9790 Elf_Internal_Shdr * sec;
26c527e6 9791 size_t i;
015dc7e1 9792 bool res = true;
57346661 9793
dda8d76d 9794 if (filedata->string_table == NULL)
015dc7e1 9795 return false;
1b31d05e
NC
9796
9797 memset (& aux, 0, sizeof (aux));
57346661 9798
dda8d76d 9799 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9800 {
28d13567 9801 if (sec->sh_type == SHT_SYMTAB)
57346661 9802 {
28d13567 9803 if (aux.symtab)
4082ef84 9804 {
28d13567
AM
9805 error (_("Multiple symbol tables encountered\n"));
9806 free (aux.symtab);
9807 aux.symtab = NULL;
4082ef84 9808 free (aux.strtab);
28d13567 9809 aux.strtab = NULL;
4082ef84 9810 }
28d13567
AM
9811 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9812 &aux.strtab, &aux.strtab_size))
015dc7e1 9813 return false;
57346661 9814 }
84714f86
AM
9815 else if (section_name_valid (filedata, sec)
9816 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9817 unwsec = sec;
9818 }
9819
9820 if (!unwsec)
9821 printf (_("\nThere are no unwind sections in this file.\n"));
9822
dda8d76d 9823 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9824 {
84714f86
AM
9825 if (section_name_valid (filedata, sec)
9826 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9827 {
26c527e6 9828 uint64_t num_unwind = sec->sh_size / 16;
dda8d76d 9829
26c527e6
AM
9830 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
9831 "contains %" PRIu64 " entry:\n",
9832 "\nUnwind section '%s' at offset %#" PRIx64 " "
9833 "contains %" PRIu64 " entries:\n",
d3a49aa8 9834 num_unwind),
dda8d76d 9835 printable_section_name (filedata, sec),
26c527e6 9836 sec->sh_offset,
d3a49aa8 9837 num_unwind);
57346661 9838
dda8d76d 9839 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9840 res = false;
66b09c7e
S
9841
9842 if (res && aux.table_len > 0)
32ec8896 9843 {
dda8d76d 9844 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9845 res = false;
32ec8896 9846 }
57346661 9847
9db70fc3 9848 free ((char *) aux.table);
57346661
AM
9849 aux.table = NULL;
9850 }
9851 }
9852
9db70fc3
AM
9853 free (aux.symtab);
9854 free ((char *) aux.strtab);
32ec8896
NC
9855
9856 return res;
57346661
AM
9857}
9858
0b6ae522
DJ
9859struct arm_section
9860{
a734115a
NC
9861 unsigned char * data; /* The unwind data. */
9862 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9863 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
26c527e6 9864 uint64_t nrelas; /* The number of relocations. */
a734115a
NC
9865 unsigned int rel_type; /* REL or RELA ? */
9866 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9867};
9868
9869struct arm_unw_aux_info
9870{
dda8d76d 9871 Filedata * filedata; /* The file containing the unwind sections. */
a734115a 9872 Elf_Internal_Sym * symtab; /* The file's symbol table. */
26c527e6 9873 uint64_t nsyms; /* Number of symbols. */
948f632f 9874 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9875 uint64_t nfuns; /* Number of these symbols. */
a734115a 9876 char * strtab; /* The file's string table. */
26c527e6 9877 uint64_t strtab_size; /* Size of string table. */
0b6ae522
DJ
9878};
9879
9880static const char *
dda8d76d
NC
9881arm_print_vma_and_name (Filedata * filedata,
9882 struct arm_unw_aux_info * aux,
625d49fc 9883 uint64_t fn,
dda8d76d 9884 struct absaddr addr)
0b6ae522
DJ
9885{
9886 const char *procname;
625d49fc 9887 uint64_t sym_offset;
0b6ae522
DJ
9888
9889 if (addr.section == SHN_UNDEF)
9890 addr.offset = fn;
9891
dda8d76d 9892 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9893 aux->strtab_size, addr, &procname,
9894 &sym_offset);
9895
9896 print_vma (fn, PREFIX_HEX);
9897
9898 if (procname)
9899 {
9900 fputs (" <", stdout);
9901 fputs (procname, stdout);
9902
9903 if (sym_offset)
26c527e6 9904 printf ("+0x%" PRIx64, sym_offset);
0b6ae522
DJ
9905 fputc ('>', stdout);
9906 }
9907
9908 return procname;
9909}
9910
9911static void
9912arm_free_section (struct arm_section *arm_sec)
9913{
9db70fc3
AM
9914 free (arm_sec->data);
9915 free (arm_sec->rela);
0b6ae522
DJ
9916}
9917
a734115a
NC
9918/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9919 cached section and install SEC instead.
9920 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9921 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9922 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9923 relocation's offset in ADDR.
1b31d05e
NC
9924 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9925 into the string table of the symbol associated with the reloc. If no
9926 reloc was applied store -1 there.
9927 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9928
015dc7e1 9929static bool
dda8d76d
NC
9930get_unwind_section_word (Filedata * filedata,
9931 struct arm_unw_aux_info * aux,
1b31d05e
NC
9932 struct arm_section * arm_sec,
9933 Elf_Internal_Shdr * sec,
625d49fc 9934 uint64_t word_offset,
1b31d05e
NC
9935 unsigned int * wordp,
9936 struct absaddr * addr,
625d49fc 9937 uint64_t * sym_name)
0b6ae522
DJ
9938{
9939 Elf_Internal_Rela *rp;
9940 Elf_Internal_Sym *sym;
9941 const char * relname;
9942 unsigned int word;
015dc7e1 9943 bool wrapped;
0b6ae522 9944
e0a31db1 9945 if (sec == NULL || arm_sec == NULL)
015dc7e1 9946 return false;
e0a31db1 9947
0b6ae522
DJ
9948 addr->section = SHN_UNDEF;
9949 addr->offset = 0;
9950
1b31d05e 9951 if (sym_name != NULL)
625d49fc 9952 *sym_name = (uint64_t) -1;
1b31d05e 9953
a734115a 9954 /* If necessary, update the section cache. */
0b6ae522
DJ
9955 if (sec != arm_sec->sec)
9956 {
9957 Elf_Internal_Shdr *relsec;
9958
9959 arm_free_section (arm_sec);
9960
9961 arm_sec->sec = sec;
dda8d76d 9962 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9963 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9964 arm_sec->rela = NULL;
9965 arm_sec->nrelas = 0;
9966
dda8d76d
NC
9967 for (relsec = filedata->section_headers;
9968 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9969 ++relsec)
9970 {
dda8d76d
NC
9971 if (relsec->sh_info >= filedata->file_header.e_shnum
9972 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9973 /* PR 15745: Check the section type as well. */
9974 || (relsec->sh_type != SHT_REL
9975 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9976 continue;
9977
a734115a 9978 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9979 if (relsec->sh_type == SHT_REL)
9980 {
dda8d76d 9981 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9982 relsec->sh_size,
9983 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9984 return false;
0b6ae522 9985 }
1ae40aa4 9986 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9987 {
dda8d76d 9988 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9989 relsec->sh_size,
9990 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9991 return false;
0b6ae522 9992 }
1ae40aa4 9993 break;
0b6ae522
DJ
9994 }
9995
9996 arm_sec->next_rela = arm_sec->rela;
9997 }
9998
a734115a 9999 /* If there is no unwind data we can do nothing. */
0b6ae522 10000 if (arm_sec->data == NULL)
015dc7e1 10001 return false;
0b6ae522 10002
e0a31db1 10003 /* If the offset is invalid then fail. */
f32ba729
NC
10004 if (/* PR 21343 *//* PR 18879 */
10005 sec->sh_size < 4
625d49fc 10006 || word_offset > sec->sh_size - 4)
015dc7e1 10007 return false;
e0a31db1 10008
a734115a 10009 /* Get the word at the required offset. */
0b6ae522
DJ
10010 word = byte_get (arm_sec->data + word_offset, 4);
10011
0eff7165
NC
10012 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
10013 if (arm_sec->rela == NULL)
10014 {
10015 * wordp = word;
015dc7e1 10016 return true;
0eff7165
NC
10017 }
10018
a734115a 10019 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 10020 wrapped = false;
0b6ae522
DJ
10021 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
10022 {
625d49fc 10023 uint64_t prelval, offset;
0b6ae522
DJ
10024
10025 if (rp->r_offset > word_offset && !wrapped)
10026 {
10027 rp = arm_sec->rela;
015dc7e1 10028 wrapped = true;
0b6ae522
DJ
10029 }
10030 if (rp->r_offset > word_offset)
10031 break;
10032
10033 if (rp->r_offset & 3)
10034 {
26c527e6
AM
10035 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
10036 rp->r_offset);
0b6ae522
DJ
10037 continue;
10038 }
10039
10040 if (rp->r_offset < word_offset)
10041 continue;
10042
74e1a04b
NC
10043 /* PR 17531: file: 027-161405-0.004 */
10044 if (aux->symtab == NULL)
10045 continue;
10046
0b6ae522
DJ
10047 if (arm_sec->rel_type == SHT_REL)
10048 {
10049 offset = word & 0x7fffffff;
10050 if (offset & 0x40000000)
625d49fc 10051 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 10052 }
a734115a 10053 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 10054 offset = rp->r_addend;
a734115a 10055 else
74e1a04b
NC
10056 {
10057 error (_("Unknown section relocation type %d encountered\n"),
10058 arm_sec->rel_type);
10059 break;
10060 }
0b6ae522 10061
071436c6
NC
10062 /* PR 17531 file: 027-1241568-0.004. */
10063 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
10064 {
26c527e6
AM
10065 error (_("Bad symbol index in unwind relocation "
10066 "(%" PRIu64 " > %" PRIu64 ")\n"),
10067 ELF32_R_SYM (rp->r_info), aux->nsyms);
071436c6
NC
10068 break;
10069 }
10070
10071 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
10072 offset += sym->st_value;
10073 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
10074
a734115a 10075 /* Check that we are processing the expected reloc type. */
dda8d76d 10076 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
10077 {
10078 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10079 if (relname == NULL)
10080 {
10081 warn (_("Skipping unknown ARM relocation type: %d\n"),
10082 (int) ELF32_R_TYPE (rp->r_info));
10083 continue;
10084 }
a734115a
NC
10085
10086 if (streq (relname, "R_ARM_NONE"))
10087 continue;
0b4362b0 10088
a734115a
NC
10089 if (! streq (relname, "R_ARM_PREL31"))
10090 {
071436c6 10091 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
10092 continue;
10093 }
10094 }
dda8d76d 10095 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
10096 {
10097 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10098 if (relname == NULL)
10099 {
10100 warn (_("Skipping unknown C6000 relocation type: %d\n"),
10101 (int) ELF32_R_TYPE (rp->r_info));
10102 continue;
10103 }
0b4362b0 10104
a734115a
NC
10105 if (streq (relname, "R_C6000_NONE"))
10106 continue;
10107
10108 if (! streq (relname, "R_C6000_PREL31"))
10109 {
071436c6 10110 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
10111 continue;
10112 }
10113
10114 prelval >>= 1;
10115 }
10116 else
74e1a04b
NC
10117 {
10118 /* This function currently only supports ARM and TI unwinders. */
10119 warn (_("Only TI and ARM unwinders are currently supported\n"));
10120 break;
10121 }
fa197c1c 10122
625d49fc 10123 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
10124 addr->section = sym->st_shndx;
10125 addr->offset = offset;
74e1a04b 10126
1b31d05e
NC
10127 if (sym_name)
10128 * sym_name = sym->st_name;
0b6ae522
DJ
10129 break;
10130 }
10131
10132 *wordp = word;
10133 arm_sec->next_rela = rp;
10134
015dc7e1 10135 return true;
0b6ae522
DJ
10136}
10137
a734115a
NC
10138static const char *tic6x_unwind_regnames[16] =
10139{
0b4362b0
RM
10140 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
10141 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
10142 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
10143};
fa197c1c 10144
0b6ae522 10145static void
fa197c1c 10146decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 10147{
fa197c1c
PB
10148 int i;
10149
10150 for (i = 12; mask; mask >>= 1, i--)
10151 {
10152 if (mask & 1)
10153 {
10154 fputs (tic6x_unwind_regnames[i], stdout);
10155 if (mask > 1)
10156 fputs (", ", stdout);
10157 }
10158 }
10159}
0b6ae522
DJ
10160
10161#define ADVANCE \
10162 if (remaining == 0 && more_words) \
10163 { \
10164 data_offset += 4; \
dda8d76d 10165 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 10166 data_offset, & word, & addr, NULL)) \
015dc7e1 10167 return false; \
0b6ae522
DJ
10168 remaining = 4; \
10169 more_words--; \
10170 } \
10171
10172#define GET_OP(OP) \
10173 ADVANCE; \
10174 if (remaining) \
10175 { \
10176 remaining--; \
10177 (OP) = word >> 24; \
10178 word <<= 8; \
10179 } \
10180 else \
10181 { \
2b692964 10182 printf (_("[Truncated opcode]\n")); \
015dc7e1 10183 return false; \
0b6ae522 10184 } \
cc5914eb 10185 printf ("0x%02x ", OP)
0b6ae522 10186
015dc7e1 10187static bool
dda8d76d
NC
10188decode_arm_unwind_bytecode (Filedata * filedata,
10189 struct arm_unw_aux_info * aux,
948f632f
DA
10190 unsigned int word,
10191 unsigned int remaining,
10192 unsigned int more_words,
625d49fc 10193 uint64_t data_offset,
948f632f
DA
10194 Elf_Internal_Shdr * data_sec,
10195 struct arm_section * data_arm_sec)
fa197c1c
PB
10196{
10197 struct absaddr addr;
015dc7e1 10198 bool res = true;
0b6ae522
DJ
10199
10200 /* Decode the unwinding instructions. */
10201 while (1)
10202 {
10203 unsigned int op, op2;
10204
10205 ADVANCE;
10206 if (remaining == 0)
10207 break;
10208 remaining--;
10209 op = word >> 24;
10210 word <<= 8;
10211
cc5914eb 10212 printf (" 0x%02x ", op);
0b6ae522
DJ
10213
10214 if ((op & 0xc0) == 0x00)
10215 {
10216 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10217
cc5914eb 10218 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
10219 }
10220 else if ((op & 0xc0) == 0x40)
10221 {
10222 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10223
cc5914eb 10224 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
10225 }
10226 else if ((op & 0xf0) == 0x80)
10227 {
10228 GET_OP (op2);
10229 if (op == 0x80 && op2 == 0)
10230 printf (_("Refuse to unwind"));
10231 else
10232 {
10233 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 10234 bool first = true;
0b6ae522 10235 int i;
2b692964 10236
0b6ae522
DJ
10237 printf ("pop {");
10238 for (i = 0; i < 12; i++)
10239 if (mask & (1 << i))
10240 {
10241 if (first)
015dc7e1 10242 first = false;
0b6ae522
DJ
10243 else
10244 printf (", ");
10245 printf ("r%d", 4 + i);
10246 }
10247 printf ("}");
10248 }
10249 }
10250 else if ((op & 0xf0) == 0x90)
10251 {
10252 if (op == 0x9d || op == 0x9f)
10253 printf (_(" [Reserved]"));
10254 else
cc5914eb 10255 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
10256 }
10257 else if ((op & 0xf0) == 0xa0)
10258 {
10259 int end = 4 + (op & 0x07);
015dc7e1 10260 bool first = true;
0b6ae522 10261 int i;
61865e30 10262
0b6ae522
DJ
10263 printf (" pop {");
10264 for (i = 4; i <= end; i++)
10265 {
10266 if (first)
015dc7e1 10267 first = false;
0b6ae522
DJ
10268 else
10269 printf (", ");
10270 printf ("r%d", i);
10271 }
10272 if (op & 0x08)
10273 {
1b31d05e 10274 if (!first)
0b6ae522
DJ
10275 printf (", ");
10276 printf ("r14");
10277 }
10278 printf ("}");
10279 }
10280 else if (op == 0xb0)
10281 printf (_(" finish"));
10282 else if (op == 0xb1)
10283 {
10284 GET_OP (op2);
10285 if (op2 == 0 || (op2 & 0xf0) != 0)
10286 printf (_("[Spare]"));
10287 else
10288 {
10289 unsigned int mask = op2 & 0x0f;
015dc7e1 10290 bool first = true;
0b6ae522 10291 int i;
61865e30 10292
0b6ae522
DJ
10293 printf ("pop {");
10294 for (i = 0; i < 12; i++)
10295 if (mask & (1 << i))
10296 {
10297 if (first)
015dc7e1 10298 first = false;
0b6ae522
DJ
10299 else
10300 printf (", ");
10301 printf ("r%d", i);
10302 }
10303 printf ("}");
10304 }
10305 }
10306 else if (op == 0xb2)
10307 {
b115cf96 10308 unsigned char buf[9];
0b6ae522 10309 unsigned int i, len;
26c527e6 10310 uint64_t offset;
61865e30 10311
b115cf96 10312 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
10313 {
10314 GET_OP (buf[i]);
10315 if ((buf[i] & 0x80) == 0)
10316 break;
10317 }
4082ef84 10318 if (i == sizeof (buf))
32ec8896 10319 {
27a45f42 10320 error (_("corrupt change to vsp\n"));
015dc7e1 10321 res = false;
32ec8896 10322 }
4082ef84
NC
10323 else
10324 {
015dc7e1 10325 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
10326 assert (len == i + 1);
10327 offset = offset * 4 + 0x204;
26c527e6 10328 printf ("vsp = vsp + %" PRId64, offset);
4082ef84 10329 }
0b6ae522 10330 }
61865e30 10331 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 10332 {
61865e30
NC
10333 unsigned int first, last;
10334
10335 GET_OP (op2);
10336 first = op2 >> 4;
10337 last = op2 & 0x0f;
10338 if (op == 0xc8)
10339 first = first + 16;
10340 printf ("pop {D%d", first);
10341 if (last)
10342 printf ("-D%d", first + last);
10343 printf ("}");
10344 }
09854a88
TB
10345 else if (op == 0xb4)
10346 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
10347 else if (op == 0xb5)
10348 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
10349 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
10350 {
10351 unsigned int count = op & 0x07;
10352
10353 printf ("pop {D8");
10354 if (count)
10355 printf ("-D%d", 8 + count);
10356 printf ("}");
10357 }
10358 else if (op >= 0xc0 && op <= 0xc5)
10359 {
10360 unsigned int count = op & 0x07;
10361
10362 printf (" pop {wR10");
10363 if (count)
10364 printf ("-wR%d", 10 + count);
10365 printf ("}");
10366 }
10367 else if (op == 0xc6)
10368 {
10369 unsigned int first, last;
10370
10371 GET_OP (op2);
10372 first = op2 >> 4;
10373 last = op2 & 0x0f;
10374 printf ("pop {wR%d", first);
10375 if (last)
10376 printf ("-wR%d", first + last);
10377 printf ("}");
10378 }
10379 else if (op == 0xc7)
10380 {
10381 GET_OP (op2);
10382 if (op2 == 0 || (op2 & 0xf0) != 0)
10383 printf (_("[Spare]"));
0b6ae522
DJ
10384 else
10385 {
61865e30 10386 unsigned int mask = op2 & 0x0f;
015dc7e1 10387 bool first = true;
61865e30
NC
10388 int i;
10389
10390 printf ("pop {");
10391 for (i = 0; i < 4; i++)
10392 if (mask & (1 << i))
10393 {
10394 if (first)
015dc7e1 10395 first = false;
61865e30
NC
10396 else
10397 printf (", ");
10398 printf ("wCGR%d", i);
10399 }
10400 printf ("}");
0b6ae522
DJ
10401 }
10402 }
61865e30 10403 else
32ec8896
NC
10404 {
10405 printf (_(" [unsupported opcode]"));
015dc7e1 10406 res = false;
32ec8896
NC
10407 }
10408
0b6ae522
DJ
10409 printf ("\n");
10410 }
32ec8896
NC
10411
10412 return res;
fa197c1c
PB
10413}
10414
015dc7e1 10415static bool
dda8d76d
NC
10416decode_tic6x_unwind_bytecode (Filedata * filedata,
10417 struct arm_unw_aux_info * aux,
948f632f
DA
10418 unsigned int word,
10419 unsigned int remaining,
10420 unsigned int more_words,
625d49fc 10421 uint64_t data_offset,
948f632f
DA
10422 Elf_Internal_Shdr * data_sec,
10423 struct arm_section * data_arm_sec)
fa197c1c
PB
10424{
10425 struct absaddr addr;
10426
10427 /* Decode the unwinding instructions. */
10428 while (1)
10429 {
10430 unsigned int op, op2;
10431
10432 ADVANCE;
10433 if (remaining == 0)
10434 break;
10435 remaining--;
10436 op = word >> 24;
10437 word <<= 8;
10438
9cf03b7e 10439 printf (" 0x%02x ", op);
fa197c1c
PB
10440
10441 if ((op & 0xc0) == 0x00)
10442 {
10443 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10444 printf (" sp = sp + %d", offset);
fa197c1c
PB
10445 }
10446 else if ((op & 0xc0) == 0x80)
10447 {
10448 GET_OP (op2);
10449 if (op == 0x80 && op2 == 0)
10450 printf (_("Refuse to unwind"));
10451 else
10452 {
10453 unsigned int mask = ((op & 0x1f) << 8) | op2;
10454 if (op & 0x20)
10455 printf ("pop compact {");
10456 else
10457 printf ("pop {");
10458
10459 decode_tic6x_unwind_regmask (mask);
10460 printf("}");
10461 }
10462 }
10463 else if ((op & 0xf0) == 0xc0)
10464 {
10465 unsigned int reg;
10466 unsigned int nregs;
10467 unsigned int i;
10468 const char *name;
a734115a
NC
10469 struct
10470 {
32ec8896
NC
10471 unsigned int offset;
10472 unsigned int reg;
fa197c1c
PB
10473 } regpos[16];
10474
10475 /* Scan entire instruction first so that GET_OP output is not
10476 interleaved with disassembly. */
10477 nregs = 0;
10478 for (i = 0; nregs < (op & 0xf); i++)
10479 {
10480 GET_OP (op2);
10481 reg = op2 >> 4;
10482 if (reg != 0xf)
10483 {
10484 regpos[nregs].offset = i * 2;
10485 regpos[nregs].reg = reg;
10486 nregs++;
10487 }
10488
10489 reg = op2 & 0xf;
10490 if (reg != 0xf)
10491 {
10492 regpos[nregs].offset = i * 2 + 1;
10493 regpos[nregs].reg = reg;
10494 nregs++;
10495 }
10496 }
10497
10498 printf (_("pop frame {"));
18344509 10499 if (nregs == 0)
fa197c1c 10500 {
18344509
NC
10501 printf (_("*corrupt* - no registers specified"));
10502 }
10503 else
10504 {
10505 reg = nregs - 1;
10506 for (i = i * 2; i > 0; i--)
fa197c1c 10507 {
18344509
NC
10508 if (regpos[reg].offset == i - 1)
10509 {
10510 name = tic6x_unwind_regnames[regpos[reg].reg];
10511 if (reg > 0)
10512 reg--;
10513 }
10514 else
10515 name = _("[pad]");
fa197c1c 10516
18344509
NC
10517 fputs (name, stdout);
10518 if (i > 1)
10519 printf (", ");
10520 }
fa197c1c
PB
10521 }
10522
10523 printf ("}");
10524 }
10525 else if (op == 0xd0)
10526 printf (" MOV FP, SP");
10527 else if (op == 0xd1)
10528 printf (" __c6xabi_pop_rts");
10529 else if (op == 0xd2)
10530 {
10531 unsigned char buf[9];
10532 unsigned int i, len;
26c527e6 10533 uint64_t offset;
a734115a 10534
fa197c1c
PB
10535 for (i = 0; i < sizeof (buf); i++)
10536 {
10537 GET_OP (buf[i]);
10538 if ((buf[i] & 0x80) == 0)
10539 break;
10540 }
0eff7165
NC
10541 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10542 if (i == sizeof (buf))
10543 {
0eff7165 10544 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10545 return false;
0eff7165 10546 }
948f632f 10547
015dc7e1 10548 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10549 assert (len == i + 1);
10550 offset = offset * 8 + 0x408;
26c527e6 10551 printf (_("sp = sp + %" PRId64), offset);
fa197c1c
PB
10552 }
10553 else if ((op & 0xf0) == 0xe0)
10554 {
10555 if ((op & 0x0f) == 7)
10556 printf (" RETURN");
10557 else
10558 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10559 }
10560 else
10561 {
10562 printf (_(" [unsupported opcode]"));
10563 }
10564 putchar ('\n');
10565 }
32ec8896 10566
015dc7e1 10567 return true;
fa197c1c
PB
10568}
10569
625d49fc
AM
10570static uint64_t
10571arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10572{
625d49fc 10573 uint64_t offset;
fa197c1c
PB
10574
10575 offset = word & 0x7fffffff;
10576 if (offset & 0x40000000)
625d49fc 10577 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10578
dda8d76d 10579 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10580 offset <<= 1;
10581
10582 return offset + where;
10583}
10584
015dc7e1 10585static bool
dda8d76d
NC
10586decode_arm_unwind (Filedata * filedata,
10587 struct arm_unw_aux_info * aux,
1b31d05e
NC
10588 unsigned int word,
10589 unsigned int remaining,
625d49fc 10590 uint64_t data_offset,
1b31d05e
NC
10591 Elf_Internal_Shdr * data_sec,
10592 struct arm_section * data_arm_sec)
fa197c1c
PB
10593{
10594 int per_index;
10595 unsigned int more_words = 0;
37e14bc3 10596 struct absaddr addr;
625d49fc 10597 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10598 bool res = true;
fa197c1c
PB
10599
10600 if (remaining == 0)
10601 {
1b31d05e
NC
10602 /* Fetch the first word.
10603 Note - when decoding an object file the address extracted
10604 here will always be 0. So we also pass in the sym_name
10605 parameter so that we can find the symbol associated with
10606 the personality routine. */
dda8d76d 10607 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10608 & word, & addr, & sym_name))
015dc7e1 10609 return false;
1b31d05e 10610
fa197c1c
PB
10611 remaining = 4;
10612 }
c93dbb25
CZ
10613 else
10614 {
10615 addr.section = SHN_UNDEF;
10616 addr.offset = 0;
10617 }
fa197c1c
PB
10618
10619 if ((word & 0x80000000) == 0)
10620 {
10621 /* Expand prel31 for personality routine. */
625d49fc 10622 uint64_t fn;
fa197c1c
PB
10623 const char *procname;
10624
dda8d76d 10625 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10626 printf (_(" Personality routine: "));
1b31d05e
NC
10627 if (fn == 0
10628 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10629 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10630 {
10631 procname = aux->strtab + sym_name;
10632 print_vma (fn, PREFIX_HEX);
10633 if (procname)
10634 {
10635 fputs (" <", stdout);
10636 fputs (procname, stdout);
10637 fputc ('>', stdout);
10638 }
10639 }
10640 else
dda8d76d 10641 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10642 fputc ('\n', stdout);
10643
10644 /* The GCC personality routines use the standard compact
10645 encoding, starting with one byte giving the number of
10646 words. */
10647 if (procname != NULL
24d127aa
ML
10648 && (startswith (procname, "__gcc_personality_v0")
10649 || startswith (procname, "__gxx_personality_v0")
10650 || startswith (procname, "__gcj_personality_v0")
10651 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10652 {
10653 remaining = 0;
10654 more_words = 1;
10655 ADVANCE;
10656 if (!remaining)
10657 {
10658 printf (_(" [Truncated data]\n"));
015dc7e1 10659 return false;
fa197c1c
PB
10660 }
10661 more_words = word >> 24;
10662 word <<= 8;
10663 remaining--;
10664 per_index = -1;
10665 }
10666 else
015dc7e1 10667 return true;
fa197c1c
PB
10668 }
10669 else
10670 {
1b31d05e 10671 /* ARM EHABI Section 6.3:
0b4362b0 10672
1b31d05e 10673 An exception-handling table entry for the compact model looks like:
0b4362b0 10674
1b31d05e
NC
10675 31 30-28 27-24 23-0
10676 -- ----- ----- ----
10677 1 0 index Data for personalityRoutine[index] */
10678
dda8d76d 10679 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10680 && (word & 0x70000000))
32ec8896
NC
10681 {
10682 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10683 res = false;
32ec8896 10684 }
1b31d05e 10685
fa197c1c 10686 per_index = (word >> 24) & 0x7f;
1b31d05e 10687 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10688 if (per_index == 0)
10689 {
10690 more_words = 0;
10691 word <<= 8;
10692 remaining--;
10693 }
10694 else if (per_index < 3)
10695 {
10696 more_words = (word >> 16) & 0xff;
10697 word <<= 16;
10698 remaining -= 2;
10699 }
10700 }
10701
dda8d76d 10702 switch (filedata->file_header.e_machine)
fa197c1c
PB
10703 {
10704 case EM_ARM:
10705 if (per_index < 3)
10706 {
dda8d76d 10707 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10708 data_offset, data_sec, data_arm_sec))
015dc7e1 10709 res = false;
fa197c1c
PB
10710 }
10711 else
1b31d05e
NC
10712 {
10713 warn (_("Unknown ARM compact model index encountered\n"));
10714 printf (_(" [reserved]\n"));
015dc7e1 10715 res = false;
1b31d05e 10716 }
fa197c1c
PB
10717 break;
10718
10719 case EM_TI_C6000:
10720 if (per_index < 3)
10721 {
dda8d76d 10722 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10723 data_offset, data_sec, data_arm_sec))
015dc7e1 10724 res = false;
fa197c1c
PB
10725 }
10726 else if (per_index < 5)
10727 {
10728 if (((word >> 17) & 0x7f) == 0x7f)
10729 printf (_(" Restore stack from frame pointer\n"));
10730 else
10731 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10732 printf (_(" Registers restored: "));
10733 if (per_index == 4)
10734 printf (" (compact) ");
10735 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10736 putchar ('\n');
10737 printf (_(" Return register: %s\n"),
10738 tic6x_unwind_regnames[word & 0xf]);
10739 }
10740 else
1b31d05e 10741 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10742 break;
10743
10744 default:
74e1a04b 10745 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10746 filedata->file_header.e_machine);
015dc7e1 10747 res = false;
fa197c1c 10748 }
0b6ae522
DJ
10749
10750 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10751
10752 return res;
0b6ae522
DJ
10753}
10754
015dc7e1 10755static bool
dda8d76d
NC
10756dump_arm_unwind (Filedata * filedata,
10757 struct arm_unw_aux_info * aux,
10758 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10759{
10760 struct arm_section exidx_arm_sec, extab_arm_sec;
10761 unsigned int i, exidx_len;
26c527e6 10762 uint64_t j, nfuns;
015dc7e1 10763 bool res = true;
0b6ae522
DJ
10764
10765 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10766 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10767 exidx_len = exidx_sec->sh_size / 8;
10768
948f632f
DA
10769 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10770 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10771 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10772 aux->funtab[nfuns++] = aux->symtab[j];
10773 aux->nfuns = nfuns;
10774 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10775
0b6ae522
DJ
10776 for (i = 0; i < exidx_len; i++)
10777 {
10778 unsigned int exidx_fn, exidx_entry;
10779 struct absaddr fn_addr, entry_addr;
625d49fc 10780 uint64_t fn;
0b6ae522
DJ
10781
10782 fputc ('\n', stdout);
10783
dda8d76d 10784 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10785 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10786 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10787 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10788 {
948f632f 10789 free (aux->funtab);
1b31d05e
NC
10790 arm_free_section (& exidx_arm_sec);
10791 arm_free_section (& extab_arm_sec);
015dc7e1 10792 return false;
0b6ae522
DJ
10793 }
10794
83c257ca
NC
10795 /* ARM EHABI, Section 5:
10796 An index table entry consists of 2 words.
10797 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10798 if (exidx_fn & 0x80000000)
32ec8896
NC
10799 {
10800 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10801 res = false;
32ec8896 10802 }
83c257ca 10803
dda8d76d 10804 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10805
dda8d76d 10806 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10807 fputs (": ", stdout);
10808
10809 if (exidx_entry == 1)
10810 {
10811 print_vma (exidx_entry, PREFIX_HEX);
10812 fputs (" [cantunwind]\n", stdout);
10813 }
10814 else if (exidx_entry & 0x80000000)
10815 {
10816 print_vma (exidx_entry, PREFIX_HEX);
10817 fputc ('\n', stdout);
dda8d76d 10818 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10819 }
10820 else
10821 {
625d49fc 10822 uint64_t table, table_offset = 0;
0b6ae522
DJ
10823 Elf_Internal_Shdr *table_sec;
10824
10825 fputs ("@", stdout);
dda8d76d 10826 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10827 print_vma (table, PREFIX_HEX);
10828 printf ("\n");
10829
10830 /* Locate the matching .ARM.extab. */
10831 if (entry_addr.section != SHN_UNDEF
dda8d76d 10832 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10833 {
dda8d76d 10834 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10835 table_offset = entry_addr.offset;
1a915552 10836 /* PR 18879 */
625d49fc 10837 if (table_offset > table_sec->sh_size)
1a915552 10838 {
26c527e6
AM
10839 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
10840 table_offset,
dda8d76d 10841 printable_section_name (filedata, table_sec));
015dc7e1 10842 res = false;
1a915552
NC
10843 continue;
10844 }
0b6ae522
DJ
10845 }
10846 else
10847 {
dda8d76d 10848 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10849 if (table_sec != NULL)
10850 table_offset = table - table_sec->sh_addr;
10851 }
32ec8896 10852
0b6ae522
DJ
10853 if (table_sec == NULL)
10854 {
26c527e6
AM
10855 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
10856 table);
015dc7e1 10857 res = false;
0b6ae522
DJ
10858 continue;
10859 }
32ec8896 10860
dda8d76d 10861 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10862 &extab_arm_sec))
015dc7e1 10863 res = false;
0b6ae522
DJ
10864 }
10865 }
10866
10867 printf ("\n");
10868
948f632f 10869 free (aux->funtab);
0b6ae522
DJ
10870 arm_free_section (&exidx_arm_sec);
10871 arm_free_section (&extab_arm_sec);
32ec8896
NC
10872
10873 return res;
0b6ae522
DJ
10874}
10875
fa197c1c 10876/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10877
015dc7e1 10878static bool
dda8d76d 10879arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10880{
10881 struct arm_unw_aux_info aux;
10882 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522 10883 Elf_Internal_Shdr *sec;
26c527e6 10884 size_t i;
fa197c1c 10885 unsigned int sec_type;
015dc7e1 10886 bool res = true;
0b6ae522 10887
dda8d76d 10888 switch (filedata->file_header.e_machine)
fa197c1c
PB
10889 {
10890 case EM_ARM:
10891 sec_type = SHT_ARM_EXIDX;
10892 break;
10893
10894 case EM_TI_C6000:
10895 sec_type = SHT_C6000_UNWIND;
10896 break;
10897
0b4362b0 10898 default:
74e1a04b 10899 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10900 filedata->file_header.e_machine);
015dc7e1 10901 return false;
fa197c1c
PB
10902 }
10903
dda8d76d 10904 if (filedata->string_table == NULL)
015dc7e1 10905 return false;
1b31d05e
NC
10906
10907 memset (& aux, 0, sizeof (aux));
dda8d76d 10908 aux.filedata = filedata;
0b6ae522 10909
dda8d76d 10910 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10911 {
28d13567 10912 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10913 {
28d13567 10914 if (aux.symtab)
74e1a04b 10915 {
28d13567
AM
10916 error (_("Multiple symbol tables encountered\n"));
10917 free (aux.symtab);
10918 aux.symtab = NULL;
74e1a04b 10919 free (aux.strtab);
28d13567 10920 aux.strtab = NULL;
74e1a04b 10921 }
28d13567
AM
10922 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10923 &aux.strtab, &aux.strtab_size))
015dc7e1 10924 return false;
0b6ae522 10925 }
fa197c1c 10926 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10927 unwsec = sec;
10928 }
10929
1b31d05e 10930 if (unwsec == NULL)
0b6ae522 10931 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10932 else
dda8d76d 10933 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10934 {
10935 if (sec->sh_type == sec_type)
10936 {
26c527e6
AM
10937 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
10938 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
10939 "contains %" PRIu64 " entry:\n",
10940 "\nUnwind section '%s' at offset %#" PRIx64 " "
10941 "contains %" PRIu64 " entries:\n",
d3a49aa8 10942 num_unwind),
dda8d76d 10943 printable_section_name (filedata, sec),
26c527e6 10944 sec->sh_offset,
d3a49aa8 10945 num_unwind);
0b6ae522 10946
dda8d76d 10947 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10948 res = false;
1b31d05e
NC
10949 }
10950 }
0b6ae522 10951
9db70fc3
AM
10952 free (aux.symtab);
10953 free ((char *) aux.strtab);
32ec8896
NC
10954
10955 return res;
0b6ae522
DJ
10956}
10957
3ecc00ec
NC
10958static bool
10959no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10960{
10961 printf (_("No processor specific unwind information to decode\n"));
10962 return true;
10963}
10964
015dc7e1 10965static bool
dda8d76d 10966process_unwind (Filedata * filedata)
57346661 10967{
2cf0635d
NC
10968 struct unwind_handler
10969 {
32ec8896 10970 unsigned int machtype;
015dc7e1 10971 bool (* handler)(Filedata *);
2cf0635d
NC
10972 } handlers[] =
10973 {
0b6ae522 10974 { EM_ARM, arm_process_unwind },
57346661
AM
10975 { EM_IA_64, ia64_process_unwind },
10976 { EM_PARISC, hppa_process_unwind },
fa197c1c 10977 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10978 { EM_386, no_processor_specific_unwind },
10979 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10980 { 0, NULL }
57346661
AM
10981 };
10982 int i;
10983
10984 if (!do_unwind)
015dc7e1 10985 return true;
57346661
AM
10986
10987 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10988 if (filedata->file_header.e_machine == handlers[i].machtype)
10989 return handlers[i].handler (filedata);
57346661 10990
1b31d05e 10991 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10992 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10993 return true;
57346661
AM
10994}
10995
37c18eed
SD
10996static void
10997dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10998{
10999 switch (entry->d_tag)
11000 {
11001 case DT_AARCH64_BTI_PLT:
1dbade74 11002 case DT_AARCH64_PAC_PLT:
37c18eed
SD
11003 break;
11004 default:
11005 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11006 break;
11007 }
11008 putchar ('\n');
11009}
11010
252b5132 11011static void
978c4450 11012dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
11013{
11014 switch (entry->d_tag)
11015 {
11016 case DT_MIPS_FLAGS:
11017 if (entry->d_un.d_val == 0)
4b68bca3 11018 printf (_("NONE"));
252b5132
RH
11019 else
11020 {
11021 static const char * opts[] =
11022 {
11023 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
11024 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
11025 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
11026 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
11027 "RLD_ORDER_SAFE"
11028 };
11029 unsigned int cnt;
015dc7e1 11030 bool first = true;
2b692964 11031
60bca95a 11032 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
11033 if (entry->d_un.d_val & (1 << cnt))
11034 {
11035 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 11036 first = false;
252b5132 11037 }
252b5132
RH
11038 }
11039 break;
103f02d3 11040
252b5132 11041 case DT_MIPS_IVERSION:
84714f86 11042 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11043 printf (_("Interface Version: %s"),
84714f86 11044 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11045 else
f493c217 11046 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 11047 entry->d_un.d_ptr);
252b5132 11048 break;
103f02d3 11049
252b5132
RH
11050 case DT_MIPS_TIME_STAMP:
11051 {
d5b07ef4 11052 char timebuf[128];
2cf0635d 11053 struct tm * tmp;
91d6fa6a 11054 time_t atime = entry->d_un.d_val;
82b1b41b 11055
91d6fa6a 11056 tmp = gmtime (&atime);
82b1b41b
NC
11057 /* PR 17531: file: 6accc532. */
11058 if (tmp == NULL)
11059 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
11060 else
11061 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
11062 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11063 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 11064 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
11065 }
11066 break;
103f02d3 11067
252b5132
RH
11068 case DT_MIPS_RLD_VERSION:
11069 case DT_MIPS_LOCAL_GOTNO:
11070 case DT_MIPS_CONFLICTNO:
11071 case DT_MIPS_LIBLISTNO:
11072 case DT_MIPS_SYMTABNO:
11073 case DT_MIPS_UNREFEXTNO:
11074 case DT_MIPS_HIPAGENO:
11075 case DT_MIPS_DELTA_CLASS_NO:
11076 case DT_MIPS_DELTA_INSTANCE_NO:
11077 case DT_MIPS_DELTA_RELOC_NO:
11078 case DT_MIPS_DELTA_SYM_NO:
11079 case DT_MIPS_DELTA_CLASSSYM_NO:
11080 case DT_MIPS_COMPACT_SIZE:
c69075ac 11081 print_vma (entry->d_un.d_val, DEC);
252b5132 11082 break;
103f02d3 11083
f16a9783 11084 case DT_MIPS_XHASH:
978c4450
AM
11085 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11086 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
11087 /* Falls through. */
11088
103f02d3 11089 default:
4b68bca3 11090 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 11091 }
4b68bca3 11092 putchar ('\n');
103f02d3
UD
11093}
11094
103f02d3 11095static void
2cf0635d 11096dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
11097{
11098 switch (entry->d_tag)
11099 {
11100 case DT_HP_DLD_FLAGS:
11101 {
11102 static struct
11103 {
26c527e6 11104 unsigned int bit;
2cf0635d 11105 const char * str;
5e220199
NC
11106 }
11107 flags[] =
11108 {
11109 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
11110 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
11111 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
11112 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
11113 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
11114 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
11115 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
11116 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
11117 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
11118 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
11119 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
11120 { DT_HP_GST, "HP_GST" },
11121 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
11122 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
11123 { DT_HP_NODELETE, "HP_NODELETE" },
11124 { DT_HP_GROUP, "HP_GROUP" },
11125 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 11126 };
015dc7e1 11127 bool first = true;
5e220199 11128 size_t cnt;
625d49fc 11129 uint64_t val = entry->d_un.d_val;
103f02d3 11130
60bca95a 11131 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 11132 if (val & flags[cnt].bit)
30800947
NC
11133 {
11134 if (! first)
11135 putchar (' ');
11136 fputs (flags[cnt].str, stdout);
015dc7e1 11137 first = false;
30800947
NC
11138 val ^= flags[cnt].bit;
11139 }
76da6bbe 11140
103f02d3 11141 if (val != 0 || first)
f7a99963
NC
11142 {
11143 if (! first)
11144 putchar (' ');
11145 print_vma (val, HEX);
11146 }
103f02d3
UD
11147 }
11148 break;
76da6bbe 11149
252b5132 11150 default:
f7a99963
NC
11151 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11152 break;
252b5132 11153 }
35b1837e 11154 putchar ('\n');
252b5132
RH
11155}
11156
28f997cf
TG
11157/* VMS vs Unix time offset and factor. */
11158
11159#define VMS_EPOCH_OFFSET 35067168000000000LL
11160#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
11161#ifndef INT64_MIN
11162#define INT64_MIN (-9223372036854775807LL - 1)
11163#endif
28f997cf
TG
11164
11165/* Display a VMS time in a human readable format. */
11166
11167static void
0e3c1eeb 11168print_vms_time (int64_t vmstime)
28f997cf 11169{
dccc31de 11170 struct tm *tm = NULL;
28f997cf
TG
11171 time_t unxtime;
11172
dccc31de
AM
11173 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
11174 {
11175 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
11176 unxtime = vmstime;
11177 if (unxtime == vmstime)
11178 tm = gmtime (&unxtime);
11179 }
11180 if (tm != NULL)
11181 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
11182 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
11183 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 11184}
28f997cf 11185
ecc51f48 11186static void
2cf0635d 11187dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
11188{
11189 switch (entry->d_tag)
11190 {
0de14b54 11191 case DT_IA_64_PLT_RESERVE:
bdf4d63a 11192 /* First 3 slots reserved. */
ecc51f48
NC
11193 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11194 printf (" -- ");
11195 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
11196 break;
11197
28f997cf 11198 case DT_IA_64_VMS_LINKTIME:
28f997cf 11199 print_vms_time (entry->d_un.d_val);
28f997cf
TG
11200 break;
11201
11202 case DT_IA_64_VMS_LNKFLAGS:
11203 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11204 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
11205 printf (" CALL_DEBUG");
11206 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
11207 printf (" NOP0BUFS");
11208 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
11209 printf (" P0IMAGE");
11210 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
11211 printf (" MKTHREADS");
11212 if (entry->d_un.d_val & VMS_LF_UPCALLS)
11213 printf (" UPCALLS");
11214 if (entry->d_un.d_val & VMS_LF_IMGSTA)
11215 printf (" IMGSTA");
11216 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
11217 printf (" INITIALIZE");
11218 if (entry->d_un.d_val & VMS_LF_MAIN)
11219 printf (" MAIN");
11220 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
11221 printf (" EXE_INIT");
11222 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
11223 printf (" TBK_IN_IMG");
11224 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
11225 printf (" DBG_IN_IMG");
11226 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
11227 printf (" TBK_IN_DSF");
11228 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
11229 printf (" DBG_IN_DSF");
11230 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
11231 printf (" SIGNATURES");
11232 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
11233 printf (" REL_SEG_OFF");
11234 break;
11235
bdf4d63a
JJ
11236 default:
11237 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11238 break;
ecc51f48 11239 }
bdf4d63a 11240 putchar ('\n');
ecc51f48
NC
11241}
11242
015dc7e1 11243static bool
dda8d76d 11244get_32bit_dynamic_section (Filedata * filedata)
252b5132 11245{
2cf0635d
NC
11246 Elf32_External_Dyn * edyn;
11247 Elf32_External_Dyn * ext;
11248 Elf_Internal_Dyn * entry;
103f02d3 11249
978c4450
AM
11250 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
11251 filedata->dynamic_addr, 1,
11252 filedata->dynamic_size,
11253 _("dynamic section"));
a6e9f9df 11254 if (!edyn)
015dc7e1 11255 return false;
103f02d3 11256
071436c6
NC
11257 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11258 might not have the luxury of section headers. Look for the DT_NULL
11259 terminator to determine the number of entries. */
978c4450
AM
11260 for (ext = edyn, filedata->dynamic_nent = 0;
11261 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11262 ext++)
11263 {
978c4450 11264 filedata->dynamic_nent++;
ba2685cc
AM
11265 if (BYTE_GET (ext->d_tag) == DT_NULL)
11266 break;
11267 }
252b5132 11268
978c4450
AM
11269 filedata->dynamic_section
11270 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11271 if (filedata->dynamic_section == NULL)
252b5132 11272 {
26c527e6
AM
11273 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11274 filedata->dynamic_nent);
9ea033b2 11275 free (edyn);
015dc7e1 11276 return false;
9ea033b2 11277 }
252b5132 11278
978c4450
AM
11279 for (ext = edyn, entry = filedata->dynamic_section;
11280 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11281 ext++, entry++)
9ea033b2 11282 {
fb514b26
AM
11283 entry->d_tag = BYTE_GET (ext->d_tag);
11284 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11285 }
11286
9ea033b2
NC
11287 free (edyn);
11288
015dc7e1 11289 return true;
9ea033b2
NC
11290}
11291
015dc7e1 11292static bool
dda8d76d 11293get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 11294{
2cf0635d
NC
11295 Elf64_External_Dyn * edyn;
11296 Elf64_External_Dyn * ext;
11297 Elf_Internal_Dyn * entry;
103f02d3 11298
071436c6 11299 /* Read in the data. */
978c4450
AM
11300 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
11301 filedata->dynamic_addr, 1,
11302 filedata->dynamic_size,
11303 _("dynamic section"));
a6e9f9df 11304 if (!edyn)
015dc7e1 11305 return false;
103f02d3 11306
071436c6
NC
11307 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11308 might not have the luxury of section headers. Look for the DT_NULL
11309 terminator to determine the number of entries. */
978c4450 11310 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 11311 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 11312 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11313 ext++)
11314 {
978c4450 11315 filedata->dynamic_nent++;
66543521 11316 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
11317 break;
11318 }
252b5132 11319
978c4450
AM
11320 filedata->dynamic_section
11321 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11322 if (filedata->dynamic_section == NULL)
252b5132 11323 {
26c527e6
AM
11324 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11325 filedata->dynamic_nent);
252b5132 11326 free (edyn);
015dc7e1 11327 return false;
252b5132
RH
11328 }
11329
071436c6 11330 /* Convert from external to internal formats. */
978c4450
AM
11331 for (ext = edyn, entry = filedata->dynamic_section;
11332 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11333 ext++, entry++)
252b5132 11334 {
66543521
AM
11335 entry->d_tag = BYTE_GET (ext->d_tag);
11336 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11337 }
11338
11339 free (edyn);
11340
015dc7e1 11341 return true;
9ea033b2
NC
11342}
11343
4de91c10
AM
11344static bool
11345get_dynamic_section (Filedata *filedata)
11346{
11347 if (filedata->dynamic_section)
11348 return true;
11349
11350 if (is_32bit_elf)
11351 return get_32bit_dynamic_section (filedata);
11352 else
11353 return get_64bit_dynamic_section (filedata);
11354}
11355
e9e44622 11356static void
625d49fc 11357print_dynamic_flags (uint64_t flags)
d1133906 11358{
015dc7e1 11359 bool first = true;
13ae64f3 11360
d1133906
NC
11361 while (flags)
11362 {
625d49fc 11363 uint64_t flag;
d1133906
NC
11364
11365 flag = flags & - flags;
11366 flags &= ~ flag;
11367
e9e44622 11368 if (first)
015dc7e1 11369 first = false;
e9e44622
JJ
11370 else
11371 putc (' ', stdout);
13ae64f3 11372
d1133906
NC
11373 switch (flag)
11374 {
e9e44622
JJ
11375 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11376 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11377 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11378 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11379 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 11380 default: fputs (_("unknown"), stdout); break;
d1133906
NC
11381 }
11382 }
e9e44622 11383 puts ("");
d1133906
NC
11384}
11385
625d49fc 11386static uint64_t *
be7d229a 11387get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
11388{
11389 unsigned char * e_data;
625d49fc 11390 uint64_t * i_data;
10ca4b04 11391
be7d229a
AM
11392 /* If size_t is smaller than uint64_t, eg because you are building
11393 on a 32-bit host, then make sure that when number is cast to
11394 size_t no information is lost. */
11395 if ((size_t) number != number
11396 || ent_size * number / ent_size != number)
10ca4b04 11397 {
be7d229a 11398 error (_("Size overflow prevents reading %" PRIu64
b8281767 11399 " elements of size %u\n"),
be7d229a 11400 number, ent_size);
10ca4b04
L
11401 return NULL;
11402 }
11403
11404 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11405 attempting to allocate memory when the read is bound to fail. */
11406 if (ent_size * number > filedata->file_size)
11407 {
b8281767 11408 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 11409 number);
10ca4b04
L
11410 return NULL;
11411 }
11412
11413 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11414 if (e_data == NULL)
11415 {
b8281767 11416 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 11417 number);
10ca4b04
L
11418 return NULL;
11419 }
11420
11421 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11422 {
b8281767 11423 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 11424 number * ent_size);
10ca4b04
L
11425 free (e_data);
11426 return NULL;
11427 }
11428
625d49fc 11429 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
11430 if (i_data == NULL)
11431 {
b8281767 11432 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 11433 number);
10ca4b04
L
11434 free (e_data);
11435 return NULL;
11436 }
11437
11438 while (number--)
11439 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11440
11441 free (e_data);
11442
11443 return i_data;
11444}
11445
26c527e6 11446static uint64_t
10ca4b04
L
11447get_num_dynamic_syms (Filedata * filedata)
11448{
26c527e6 11449 uint64_t num_of_syms = 0;
10ca4b04
L
11450
11451 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11452 return num_of_syms;
11453
978c4450 11454 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11455 {
11456 unsigned char nb[8];
11457 unsigned char nc[8];
11458 unsigned int hash_ent_size = 4;
11459
11460 if ((filedata->file_header.e_machine == EM_ALPHA
11461 || filedata->file_header.e_machine == EM_S390
11462 || filedata->file_header.e_machine == EM_S390_OLD)
11463 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11464 hash_ent_size = 8;
11465
63cf857e
AM
11466 if (fseek64 (filedata->handle,
11467 (filedata->archive_file_offset
11468 + offset_from_vma (filedata,
11469 filedata->dynamic_info[DT_HASH],
11470 sizeof nb + sizeof nc)),
11471 SEEK_SET))
10ca4b04
L
11472 {
11473 error (_("Unable to seek to start of dynamic information\n"));
11474 goto no_hash;
11475 }
11476
11477 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11478 {
11479 error (_("Failed to read in number of buckets\n"));
11480 goto no_hash;
11481 }
11482
11483 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11484 {
11485 error (_("Failed to read in number of chains\n"));
11486 goto no_hash;
11487 }
11488
978c4450
AM
11489 filedata->nbuckets = byte_get (nb, hash_ent_size);
11490 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11491
2482f306
AM
11492 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11493 {
11494 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11495 hash_ent_size);
11496 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11497 hash_ent_size);
001890e1 11498
2482f306
AM
11499 if (filedata->buckets != NULL && filedata->chains != NULL)
11500 num_of_syms = filedata->nchains;
11501 }
ceb9bf11 11502 no_hash:
10ca4b04
L
11503 if (num_of_syms == 0)
11504 {
9db70fc3
AM
11505 free (filedata->buckets);
11506 filedata->buckets = NULL;
11507 free (filedata->chains);
11508 filedata->chains = NULL;
978c4450 11509 filedata->nbuckets = 0;
10ca4b04
L
11510 }
11511 }
11512
978c4450 11513 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11514 {
11515 unsigned char nb[16];
625d49fc
AM
11516 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11517 uint64_t buckets_vma;
26c527e6 11518 uint64_t hn;
10ca4b04 11519
63cf857e
AM
11520 if (fseek64 (filedata->handle,
11521 (filedata->archive_file_offset
11522 + offset_from_vma (filedata,
11523 filedata->dynamic_info_DT_GNU_HASH,
11524 sizeof nb)),
11525 SEEK_SET))
10ca4b04
L
11526 {
11527 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11528 goto no_gnu_hash;
11529 }
11530
11531 if (fread (nb, 16, 1, filedata->handle) != 1)
11532 {
11533 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11534 goto no_gnu_hash;
11535 }
11536
978c4450
AM
11537 filedata->ngnubuckets = byte_get (nb, 4);
11538 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11539 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11540 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11541 if (is_32bit_elf)
11542 buckets_vma += bitmaskwords * 4;
11543 else
11544 buckets_vma += bitmaskwords * 8;
11545
63cf857e
AM
11546 if (fseek64 (filedata->handle,
11547 (filedata->archive_file_offset
11548 + offset_from_vma (filedata, buckets_vma, 4)),
11549 SEEK_SET))
10ca4b04
L
11550 {
11551 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11552 goto no_gnu_hash;
11553 }
11554
978c4450
AM
11555 filedata->gnubuckets
11556 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11557
978c4450 11558 if (filedata->gnubuckets == NULL)
90837ea7 11559 goto no_gnu_hash;
10ca4b04 11560
978c4450
AM
11561 for (i = 0; i < filedata->ngnubuckets; i++)
11562 if (filedata->gnubuckets[i] != 0)
10ca4b04 11563 {
978c4450 11564 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11565 goto no_gnu_hash;
10ca4b04 11566
978c4450
AM
11567 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11568 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11569 }
11570
11571 if (maxchain == 0xffffffff)
90837ea7 11572 goto no_gnu_hash;
10ca4b04 11573
978c4450 11574 maxchain -= filedata->gnusymidx;
10ca4b04 11575
63cf857e
AM
11576 if (fseek64 (filedata->handle,
11577 (filedata->archive_file_offset
11578 + offset_from_vma (filedata,
11579 buckets_vma + 4 * (filedata->ngnubuckets
11580 + maxchain),
11581 4)),
11582 SEEK_SET))
10ca4b04
L
11583 {
11584 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11585 goto no_gnu_hash;
11586 }
11587
11588 do
11589 {
11590 if (fread (nb, 4, 1, filedata->handle) != 1)
11591 {
11592 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11593 goto no_gnu_hash;
11594 }
11595
11596 if (maxchain + 1 == 0)
90837ea7 11597 goto no_gnu_hash;
10ca4b04
L
11598
11599 ++maxchain;
11600 }
11601 while ((byte_get (nb, 4) & 1) == 0);
11602
63cf857e
AM
11603 if (fseek64 (filedata->handle,
11604 (filedata->archive_file_offset
11605 + offset_from_vma (filedata, (buckets_vma
11606 + 4 * filedata->ngnubuckets),
11607 4)),
11608 SEEK_SET))
10ca4b04
L
11609 {
11610 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11611 goto no_gnu_hash;
11612 }
11613
978c4450
AM
11614 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11615 filedata->ngnuchains = maxchain;
10ca4b04 11616
978c4450 11617 if (filedata->gnuchains == NULL)
90837ea7 11618 goto no_gnu_hash;
10ca4b04 11619
978c4450 11620 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11621 {
63cf857e
AM
11622 if (fseek64 (filedata->handle,
11623 (filedata->archive_file_offset
11624 + offset_from_vma (filedata, (buckets_vma
11625 + 4 * (filedata->ngnubuckets
11626 + maxchain)), 4)),
11627 SEEK_SET))
10ca4b04
L
11628 {
11629 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11630 goto no_gnu_hash;
11631 }
11632
978c4450 11633 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11634 if (filedata->mipsxlat == NULL)
11635 goto no_gnu_hash;
10ca4b04
L
11636 }
11637
978c4450
AM
11638 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11639 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11640 {
625d49fc
AM
11641 uint64_t si = filedata->gnubuckets[hn];
11642 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11643
11644 do
11645 {
978c4450 11646 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11647 {
c31ab5a0
AM
11648 if (off < filedata->ngnuchains
11649 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11650 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11651 }
11652 else
11653 {
11654 if (si >= num_of_syms)
11655 num_of_syms = si + 1;
11656 }
11657 si++;
11658 }
978c4450
AM
11659 while (off < filedata->ngnuchains
11660 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11661 }
11662
90837ea7 11663 if (num_of_syms == 0)
10ca4b04 11664 {
90837ea7 11665 no_gnu_hash:
9db70fc3
AM
11666 free (filedata->mipsxlat);
11667 filedata->mipsxlat = NULL;
11668 free (filedata->gnuchains);
11669 filedata->gnuchains = NULL;
11670 free (filedata->gnubuckets);
11671 filedata->gnubuckets = NULL;
978c4450
AM
11672 filedata->ngnubuckets = 0;
11673 filedata->ngnuchains = 0;
10ca4b04
L
11674 }
11675 }
11676
11677 return num_of_syms;
11678}
11679
b2d38a17
NC
11680/* Parse and display the contents of the dynamic section. */
11681
015dc7e1 11682static bool
dda8d76d 11683process_dynamic_section (Filedata * filedata)
9ea033b2 11684{
2cf0635d 11685 Elf_Internal_Dyn * entry;
9ea033b2 11686
93df3340 11687 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11688 {
11689 if (do_dynamic)
ca0e11aa
NC
11690 {
11691 if (filedata->is_separate)
11692 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11693 filedata->file_name);
11694 else
11695 printf (_("\nThere is no dynamic section in this file.\n"));
11696 }
9ea033b2 11697
015dc7e1 11698 return true;
9ea033b2
NC
11699 }
11700
4de91c10
AM
11701 if (!get_dynamic_section (filedata))
11702 return false;
9ea033b2 11703
252b5132 11704 /* Find the appropriate symbol table. */
978c4450 11705 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11706 {
26c527e6 11707 uint64_t num_of_syms;
2482f306 11708
978c4450
AM
11709 for (entry = filedata->dynamic_section;
11710 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11711 ++entry)
10ca4b04 11712 if (entry->d_tag == DT_SYMTAB)
978c4450 11713 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11714 else if (entry->d_tag == DT_SYMENT)
978c4450 11715 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11716 else if (entry->d_tag == DT_HASH)
978c4450 11717 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11718 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11719 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11720 else if ((filedata->file_header.e_machine == EM_MIPS
11721 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11722 && entry->d_tag == DT_MIPS_XHASH)
11723 {
978c4450
AM
11724 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11725 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11726 }
252b5132 11727
2482f306
AM
11728 num_of_syms = get_num_dynamic_syms (filedata);
11729
11730 if (num_of_syms != 0
11731 && filedata->dynamic_symbols == NULL
11732 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11733 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11734 {
11735 Elf_Internal_Phdr *seg;
625d49fc 11736 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11737
2482f306
AM
11738 if (! get_program_headers (filedata))
11739 {
11740 error (_("Cannot interpret virtual addresses "
11741 "without program headers.\n"));
015dc7e1 11742 return false;
2482f306 11743 }
252b5132 11744
2482f306
AM
11745 for (seg = filedata->program_headers;
11746 seg < filedata->program_headers + filedata->file_header.e_phnum;
11747 ++seg)
11748 {
11749 if (seg->p_type != PT_LOAD)
11750 continue;
252b5132 11751
2482f306
AM
11752 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11753 {
11754 /* See PR 21379 for a reproducer. */
11755 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11756 return false;
2482f306 11757 }
252b5132 11758
2482f306
AM
11759 if (vma >= (seg->p_vaddr & -seg->p_align)
11760 && vma < seg->p_vaddr + seg->p_filesz)
11761 {
11762 /* Since we do not know how big the symbol table is,
11763 we default to reading in up to the end of PT_LOAD
11764 segment and processing that. This is overkill, I
11765 know, but it should work. */
11766 Elf_Internal_Shdr section;
11767 section.sh_offset = (vma - seg->p_vaddr
11768 + seg->p_offset);
11769 section.sh_size = (num_of_syms
11770 * filedata->dynamic_info[DT_SYMENT]);
11771 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11772
11773 if (do_checks
11774 && filedata->dynamic_symtab_section != NULL
11775 && ((filedata->dynamic_symtab_section->sh_offset
11776 != section.sh_offset)
11777 || (filedata->dynamic_symtab_section->sh_size
11778 != section.sh_size)
11779 || (filedata->dynamic_symtab_section->sh_entsize
11780 != section.sh_entsize)))
11781 warn (_("\
11782the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11783
2482f306
AM
11784 section.sh_name = filedata->string_table_length;
11785 filedata->dynamic_symbols
4de91c10 11786 = get_elf_symbols (filedata, &section,
2482f306
AM
11787 &filedata->num_dynamic_syms);
11788 if (filedata->dynamic_symbols == NULL
11789 || filedata->num_dynamic_syms != num_of_syms)
11790 {
11791 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11792 return false;
2482f306
AM
11793 }
11794 break;
11795 }
11796 }
11797 }
11798 }
252b5132
RH
11799
11800 /* Similarly find a string table. */
978c4450
AM
11801 if (filedata->dynamic_strings == NULL)
11802 for (entry = filedata->dynamic_section;
11803 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11804 ++entry)
11805 {
11806 if (entry->d_tag == DT_STRTAB)
978c4450 11807 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11808
10ca4b04 11809 if (entry->d_tag == DT_STRSZ)
978c4450 11810 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11811
978c4450
AM
11812 if (filedata->dynamic_info[DT_STRTAB]
11813 && filedata->dynamic_info[DT_STRSZ])
10ca4b04 11814 {
26c527e6 11815 uint64_t offset;
be7d229a 11816 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11817
11818 offset = offset_from_vma (filedata,
978c4450 11819 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11820 str_tab_len);
8ac10c5b
L
11821 if (do_checks
11822 && filedata->dynamic_strtab_section
11823 && ((filedata->dynamic_strtab_section->sh_offset
11824 != (file_ptr) offset)
11825 || (filedata->dynamic_strtab_section->sh_size
11826 != str_tab_len)))
11827 warn (_("\
11828the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11829
978c4450
AM
11830 filedata->dynamic_strings
11831 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11832 _("dynamic string table"));
11833 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11834 {
11835 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11836 break;
11837 }
e3d39609 11838
978c4450 11839 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11840 break;
11841 }
11842 }
252b5132
RH
11843
11844 /* And find the syminfo section if available. */
978c4450 11845 if (filedata->dynamic_syminfo == NULL)
252b5132 11846 {
26c527e6 11847 uint64_t syminsz = 0;
252b5132 11848
978c4450
AM
11849 for (entry = filedata->dynamic_section;
11850 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11851 ++entry)
252b5132
RH
11852 {
11853 if (entry->d_tag == DT_SYMINENT)
11854 {
11855 /* Note: these braces are necessary to avoid a syntax
11856 error from the SunOS4 C compiler. */
049b0c3a
NC
11857 /* PR binutils/17531: A corrupt file can trigger this test.
11858 So do not use an assert, instead generate an error message. */
11859 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11860 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11861 (int) entry->d_un.d_val);
252b5132
RH
11862 }
11863 else if (entry->d_tag == DT_SYMINSZ)
11864 syminsz = entry->d_un.d_val;
11865 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11866 filedata->dynamic_syminfo_offset
11867 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11868 }
11869
978c4450 11870 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11871 {
2cf0635d
NC
11872 Elf_External_Syminfo * extsyminfo;
11873 Elf_External_Syminfo * extsym;
11874 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11875
11876 /* There is a syminfo section. Read the data. */
3f5e193b 11877 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11878 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11879 1, syminsz, _("symbol information"));
a6e9f9df 11880 if (!extsyminfo)
015dc7e1 11881 return false;
252b5132 11882
978c4450 11883 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11884 {
11885 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11886 free (filedata->dynamic_syminfo);
e3d39609 11887 }
978c4450
AM
11888 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11889 if (filedata->dynamic_syminfo == NULL)
252b5132 11890 {
26c527e6
AM
11891 error (_("Out of memory allocating %" PRIu64
11892 " bytes for dynamic symbol info\n"),
11893 syminsz);
015dc7e1 11894 return false;
252b5132
RH
11895 }
11896
2482f306
AM
11897 filedata->dynamic_syminfo_nent
11898 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11899 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11900 syminfo < (filedata->dynamic_syminfo
11901 + filedata->dynamic_syminfo_nent);
86dba8ee 11902 ++syminfo, ++extsym)
252b5132 11903 {
86dba8ee
AM
11904 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11905 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11906 }
11907
11908 free (extsyminfo);
11909 }
11910 }
11911
978c4450 11912 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11913 {
f253158f 11914 if (filedata->is_separate)
26c527e6
AM
11915 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
11916 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
11917 filedata->dynamic_nent),
f253158f
NC
11918 filedata->file_name,
11919 filedata->dynamic_addr,
26c527e6 11920 filedata->dynamic_nent);
84a9f195 11921 else
02da71ee 11922 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
26c527e6
AM
11923 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
11924 filedata->dynamic_nent),
84a9f195 11925 filedata->dynamic_addr,
26c527e6 11926 filedata->dynamic_nent);
ca0e11aa 11927 }
252b5132
RH
11928 if (do_dynamic)
11929 printf (_(" Tag Type Name/Value\n"));
11930
978c4450
AM
11931 for (entry = filedata->dynamic_section;
11932 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11933 entry++)
252b5132
RH
11934 {
11935 if (do_dynamic)
f7a99963 11936 {
2cf0635d 11937 const char * dtype;
e699b9ff 11938
f7a99963
NC
11939 putchar (' ');
11940 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11941 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11942 printf (" (%s)%*s", dtype,
32ec8896 11943 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11944 }
252b5132
RH
11945
11946 switch (entry->d_tag)
11947 {
d1133906
NC
11948 case DT_FLAGS:
11949 if (do_dynamic)
e9e44622 11950 print_dynamic_flags (entry->d_un.d_val);
d1133906 11951 break;
76da6bbe 11952
252b5132
RH
11953 case DT_AUXILIARY:
11954 case DT_FILTER:
019148e4
L
11955 case DT_CONFIG:
11956 case DT_DEPAUDIT:
11957 case DT_AUDIT:
252b5132
RH
11958 if (do_dynamic)
11959 {
019148e4 11960 switch (entry->d_tag)
b34976b6 11961 {
019148e4
L
11962 case DT_AUXILIARY:
11963 printf (_("Auxiliary library"));
11964 break;
11965
11966 case DT_FILTER:
11967 printf (_("Filter library"));
11968 break;
11969
b34976b6 11970 case DT_CONFIG:
019148e4
L
11971 printf (_("Configuration file"));
11972 break;
11973
11974 case DT_DEPAUDIT:
11975 printf (_("Dependency audit library"));
11976 break;
11977
11978 case DT_AUDIT:
11979 printf (_("Audit library"));
11980 break;
11981 }
252b5132 11982
84714f86 11983 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11984 printf (": [%s]\n",
84714f86 11985 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11986 else
f7a99963
NC
11987 {
11988 printf (": ");
11989 print_vma (entry->d_un.d_val, PREFIX_HEX);
11990 putchar ('\n');
11991 }
252b5132
RH
11992 }
11993 break;
11994
dcefbbbd 11995 case DT_FEATURE:
252b5132
RH
11996 if (do_dynamic)
11997 {
11998 printf (_("Flags:"));
86f55779 11999
252b5132
RH
12000 if (entry->d_un.d_val == 0)
12001 printf (_(" None\n"));
12002 else
12003 {
26c527e6 12004 uint64_t val = entry->d_un.d_val;
86f55779 12005
252b5132
RH
12006 if (val & DTF_1_PARINIT)
12007 {
12008 printf (" PARINIT");
12009 val ^= DTF_1_PARINIT;
12010 }
dcefbbbd
L
12011 if (val & DTF_1_CONFEXP)
12012 {
12013 printf (" CONFEXP");
12014 val ^= DTF_1_CONFEXP;
12015 }
252b5132 12016 if (val != 0)
26c527e6 12017 printf (" %" PRIx64, val);
252b5132
RH
12018 puts ("");
12019 }
12020 }
12021 break;
12022
12023 case DT_POSFLAG_1:
12024 if (do_dynamic)
12025 {
12026 printf (_("Flags:"));
86f55779 12027
252b5132
RH
12028 if (entry->d_un.d_val == 0)
12029 printf (_(" None\n"));
12030 else
12031 {
26c527e6 12032 uint64_t val = entry->d_un.d_val;
86f55779 12033
252b5132
RH
12034 if (val & DF_P1_LAZYLOAD)
12035 {
12036 printf (" LAZYLOAD");
12037 val ^= DF_P1_LAZYLOAD;
12038 }
12039 if (val & DF_P1_GROUPPERM)
12040 {
12041 printf (" GROUPPERM");
12042 val ^= DF_P1_GROUPPERM;
12043 }
12044 if (val != 0)
26c527e6 12045 printf (" %" PRIx64, val);
252b5132
RH
12046 puts ("");
12047 }
12048 }
12049 break;
12050
12051 case DT_FLAGS_1:
12052 if (do_dynamic)
12053 {
12054 printf (_("Flags:"));
12055 if (entry->d_un.d_val == 0)
12056 printf (_(" None\n"));
12057 else
12058 {
26c527e6 12059 uint64_t val = entry->d_un.d_val;
86f55779 12060
252b5132
RH
12061 if (val & DF_1_NOW)
12062 {
12063 printf (" NOW");
12064 val ^= DF_1_NOW;
12065 }
12066 if (val & DF_1_GLOBAL)
12067 {
12068 printf (" GLOBAL");
12069 val ^= DF_1_GLOBAL;
12070 }
12071 if (val & DF_1_GROUP)
12072 {
12073 printf (" GROUP");
12074 val ^= DF_1_GROUP;
12075 }
12076 if (val & DF_1_NODELETE)
12077 {
12078 printf (" NODELETE");
12079 val ^= DF_1_NODELETE;
12080 }
12081 if (val & DF_1_LOADFLTR)
12082 {
12083 printf (" LOADFLTR");
12084 val ^= DF_1_LOADFLTR;
12085 }
12086 if (val & DF_1_INITFIRST)
12087 {
12088 printf (" INITFIRST");
12089 val ^= DF_1_INITFIRST;
12090 }
12091 if (val & DF_1_NOOPEN)
12092 {
12093 printf (" NOOPEN");
12094 val ^= DF_1_NOOPEN;
12095 }
12096 if (val & DF_1_ORIGIN)
12097 {
12098 printf (" ORIGIN");
12099 val ^= DF_1_ORIGIN;
12100 }
12101 if (val & DF_1_DIRECT)
12102 {
12103 printf (" DIRECT");
12104 val ^= DF_1_DIRECT;
12105 }
12106 if (val & DF_1_TRANS)
12107 {
12108 printf (" TRANS");
12109 val ^= DF_1_TRANS;
12110 }
12111 if (val & DF_1_INTERPOSE)
12112 {
12113 printf (" INTERPOSE");
12114 val ^= DF_1_INTERPOSE;
12115 }
f7db6139 12116 if (val & DF_1_NODEFLIB)
dcefbbbd 12117 {
f7db6139
L
12118 printf (" NODEFLIB");
12119 val ^= DF_1_NODEFLIB;
dcefbbbd
L
12120 }
12121 if (val & DF_1_NODUMP)
12122 {
12123 printf (" NODUMP");
12124 val ^= DF_1_NODUMP;
12125 }
34b60028 12126 if (val & DF_1_CONFALT)
dcefbbbd 12127 {
34b60028
L
12128 printf (" CONFALT");
12129 val ^= DF_1_CONFALT;
12130 }
12131 if (val & DF_1_ENDFILTEE)
12132 {
12133 printf (" ENDFILTEE");
12134 val ^= DF_1_ENDFILTEE;
12135 }
12136 if (val & DF_1_DISPRELDNE)
12137 {
12138 printf (" DISPRELDNE");
12139 val ^= DF_1_DISPRELDNE;
12140 }
12141 if (val & DF_1_DISPRELPND)
12142 {
12143 printf (" DISPRELPND");
12144 val ^= DF_1_DISPRELPND;
12145 }
12146 if (val & DF_1_NODIRECT)
12147 {
12148 printf (" NODIRECT");
12149 val ^= DF_1_NODIRECT;
12150 }
12151 if (val & DF_1_IGNMULDEF)
12152 {
12153 printf (" IGNMULDEF");
12154 val ^= DF_1_IGNMULDEF;
12155 }
12156 if (val & DF_1_NOKSYMS)
12157 {
12158 printf (" NOKSYMS");
12159 val ^= DF_1_NOKSYMS;
12160 }
12161 if (val & DF_1_NOHDR)
12162 {
12163 printf (" NOHDR");
12164 val ^= DF_1_NOHDR;
12165 }
12166 if (val & DF_1_EDITED)
12167 {
12168 printf (" EDITED");
12169 val ^= DF_1_EDITED;
12170 }
12171 if (val & DF_1_NORELOC)
12172 {
12173 printf (" NORELOC");
12174 val ^= DF_1_NORELOC;
12175 }
12176 if (val & DF_1_SYMINTPOSE)
12177 {
12178 printf (" SYMINTPOSE");
12179 val ^= DF_1_SYMINTPOSE;
12180 }
12181 if (val & DF_1_GLOBAUDIT)
12182 {
12183 printf (" GLOBAUDIT");
12184 val ^= DF_1_GLOBAUDIT;
12185 }
12186 if (val & DF_1_SINGLETON)
12187 {
12188 printf (" SINGLETON");
12189 val ^= DF_1_SINGLETON;
dcefbbbd 12190 }
5c383f02
RO
12191 if (val & DF_1_STUB)
12192 {
12193 printf (" STUB");
12194 val ^= DF_1_STUB;
12195 }
12196 if (val & DF_1_PIE)
12197 {
12198 printf (" PIE");
12199 val ^= DF_1_PIE;
12200 }
b1202ffa
L
12201 if (val & DF_1_KMOD)
12202 {
12203 printf (" KMOD");
12204 val ^= DF_1_KMOD;
12205 }
12206 if (val & DF_1_WEAKFILTER)
12207 {
12208 printf (" WEAKFILTER");
12209 val ^= DF_1_WEAKFILTER;
12210 }
12211 if (val & DF_1_NOCOMMON)
12212 {
12213 printf (" NOCOMMON");
12214 val ^= DF_1_NOCOMMON;
12215 }
252b5132 12216 if (val != 0)
26c527e6 12217 printf (" %" PRIx64, val);
252b5132
RH
12218 puts ("");
12219 }
12220 }
12221 break;
12222
12223 case DT_PLTREL:
978c4450 12224 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 12225 if (do_dynamic)
dda8d76d 12226 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
12227 break;
12228
12229 case DT_NULL :
12230 case DT_NEEDED :
12231 case DT_PLTGOT :
12232 case DT_HASH :
12233 case DT_STRTAB :
12234 case DT_SYMTAB :
12235 case DT_RELA :
12236 case DT_INIT :
12237 case DT_FINI :
12238 case DT_SONAME :
12239 case DT_RPATH :
12240 case DT_SYMBOLIC:
12241 case DT_REL :
a7fd1186 12242 case DT_RELR :
252b5132
RH
12243 case DT_DEBUG :
12244 case DT_TEXTREL :
12245 case DT_JMPREL :
019148e4 12246 case DT_RUNPATH :
978c4450 12247 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
12248
12249 if (do_dynamic)
12250 {
84714f86 12251 const char *name;
252b5132 12252
84714f86
AM
12253 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12254 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12255 else
d79b3d50 12256 name = NULL;
252b5132
RH
12257
12258 if (name)
12259 {
12260 switch (entry->d_tag)
12261 {
12262 case DT_NEEDED:
12263 printf (_("Shared library: [%s]"), name);
12264
13acb58d
AM
12265 if (filedata->program_interpreter
12266 && streq (name, filedata->program_interpreter))
f7a99963 12267 printf (_(" program interpreter"));
252b5132
RH
12268 break;
12269
12270 case DT_SONAME:
f7a99963 12271 printf (_("Library soname: [%s]"), name);
252b5132
RH
12272 break;
12273
12274 case DT_RPATH:
f7a99963 12275 printf (_("Library rpath: [%s]"), name);
252b5132
RH
12276 break;
12277
019148e4
L
12278 case DT_RUNPATH:
12279 printf (_("Library runpath: [%s]"), name);
12280 break;
12281
252b5132 12282 default:
f7a99963
NC
12283 print_vma (entry->d_un.d_val, PREFIX_HEX);
12284 break;
252b5132
RH
12285 }
12286 }
12287 else
f7a99963
NC
12288 print_vma (entry->d_un.d_val, PREFIX_HEX);
12289
12290 putchar ('\n');
252b5132
RH
12291 }
12292 break;
12293
12294 case DT_PLTRELSZ:
12295 case DT_RELASZ :
12296 case DT_STRSZ :
12297 case DT_RELSZ :
12298 case DT_RELAENT :
a7fd1186
FS
12299 case DT_RELRENT :
12300 case DT_RELRSZ :
252b5132
RH
12301 case DT_SYMENT :
12302 case DT_RELENT :
978c4450 12303 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 12304 /* Fall through. */
252b5132
RH
12305 case DT_PLTPADSZ:
12306 case DT_MOVEENT :
12307 case DT_MOVESZ :
04d8355a 12308 case DT_PREINIT_ARRAYSZ:
252b5132
RH
12309 case DT_INIT_ARRAYSZ:
12310 case DT_FINI_ARRAYSZ:
047b2264
JJ
12311 case DT_GNU_CONFLICTSZ:
12312 case DT_GNU_LIBLISTSZ:
252b5132 12313 if (do_dynamic)
f7a99963
NC
12314 {
12315 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 12316 printf (_(" (bytes)\n"));
f7a99963 12317 }
252b5132
RH
12318 break;
12319
12320 case DT_VERDEFNUM:
12321 case DT_VERNEEDNUM:
12322 case DT_RELACOUNT:
12323 case DT_RELCOUNT:
12324 if (do_dynamic)
f7a99963
NC
12325 {
12326 print_vma (entry->d_un.d_val, UNSIGNED);
12327 putchar ('\n');
12328 }
252b5132
RH
12329 break;
12330
12331 case DT_SYMINSZ:
12332 case DT_SYMINENT:
12333 case DT_SYMINFO:
12334 case DT_USED:
12335 case DT_INIT_ARRAY:
12336 case DT_FINI_ARRAY:
12337 if (do_dynamic)
12338 {
d79b3d50 12339 if (entry->d_tag == DT_USED
84714f86 12340 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 12341 {
84714f86
AM
12342 const char *name
12343 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12344
b34976b6 12345 if (*name)
252b5132
RH
12346 {
12347 printf (_("Not needed object: [%s]\n"), name);
12348 break;
12349 }
12350 }
103f02d3 12351
f7a99963
NC
12352 print_vma (entry->d_un.d_val, PREFIX_HEX);
12353 putchar ('\n');
252b5132
RH
12354 }
12355 break;
12356
12357 case DT_BIND_NOW:
12358 /* The value of this entry is ignored. */
35b1837e
AM
12359 if (do_dynamic)
12360 putchar ('\n');
252b5132 12361 break;
103f02d3 12362
047b2264
JJ
12363 case DT_GNU_PRELINKED:
12364 if (do_dynamic)
12365 {
2cf0635d 12366 struct tm * tmp;
91d6fa6a 12367 time_t atime = entry->d_un.d_val;
047b2264 12368
91d6fa6a 12369 tmp = gmtime (&atime);
071436c6
NC
12370 /* PR 17533 file: 041-1244816-0.004. */
12371 if (tmp == NULL)
26c527e6
AM
12372 printf (_("<corrupt time val: %" PRIx64),
12373 (uint64_t) atime);
071436c6
NC
12374 else
12375 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12376 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12377 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12378
12379 }
12380 break;
12381
fdc90cb4 12382 case DT_GNU_HASH:
978c4450 12383 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
12384 if (do_dynamic)
12385 {
12386 print_vma (entry->d_un.d_val, PREFIX_HEX);
12387 putchar ('\n');
12388 }
12389 break;
12390
a5da3dee
VDM
12391 case DT_GNU_FLAGS_1:
12392 if (do_dynamic)
12393 {
12394 printf (_("Flags:"));
12395 if (entry->d_un.d_val == 0)
12396 printf (_(" None\n"));
12397 else
12398 {
26c527e6 12399 uint64_t val = entry->d_un.d_val;
a5da3dee
VDM
12400
12401 if (val & DF_GNU_1_UNIQUE)
12402 {
12403 printf (" UNIQUE");
12404 val ^= DF_GNU_1_UNIQUE;
12405 }
12406 if (val != 0)
26c527e6 12407 printf (" %" PRIx64, val);
a5da3dee
VDM
12408 puts ("");
12409 }
12410 }
12411 break;
12412
252b5132
RH
12413 default:
12414 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
12415 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12416 = entry->d_un.d_val;
252b5132
RH
12417
12418 if (do_dynamic)
12419 {
dda8d76d 12420 switch (filedata->file_header.e_machine)
252b5132 12421 {
37c18eed
SD
12422 case EM_AARCH64:
12423 dynamic_section_aarch64_val (entry);
12424 break;
252b5132 12425 case EM_MIPS:
4fe85591 12426 case EM_MIPS_RS3_LE:
978c4450 12427 dynamic_section_mips_val (filedata, entry);
252b5132 12428 break;
103f02d3 12429 case EM_PARISC:
b2d38a17 12430 dynamic_section_parisc_val (entry);
103f02d3 12431 break;
ecc51f48 12432 case EM_IA_64:
b2d38a17 12433 dynamic_section_ia64_val (entry);
ecc51f48 12434 break;
252b5132 12435 default:
f7a99963
NC
12436 print_vma (entry->d_un.d_val, PREFIX_HEX);
12437 putchar ('\n');
252b5132
RH
12438 }
12439 }
12440 break;
12441 }
12442 }
12443
015dc7e1 12444 return true;
252b5132
RH
12445}
12446
12447static char *
d3ba0551 12448get_ver_flags (unsigned int flags)
252b5132 12449{
6d4f21f6 12450 static char buff[128];
252b5132
RH
12451
12452 buff[0] = 0;
12453
12454 if (flags == 0)
12455 return _("none");
12456
12457 if (flags & VER_FLG_BASE)
7bb1ad17 12458 strcat (buff, "BASE");
252b5132
RH
12459
12460 if (flags & VER_FLG_WEAK)
12461 {
12462 if (flags & VER_FLG_BASE)
7bb1ad17 12463 strcat (buff, " | ");
252b5132 12464
7bb1ad17 12465 strcat (buff, "WEAK");
252b5132
RH
12466 }
12467
44ec90b9
RO
12468 if (flags & VER_FLG_INFO)
12469 {
12470 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12471 strcat (buff, " | ");
44ec90b9 12472
7bb1ad17 12473 strcat (buff, "INFO");
44ec90b9
RO
12474 }
12475
12476 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12477 {
12478 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12479 strcat (buff, " | ");
12480
12481 strcat (buff, _("<unknown>"));
12482 }
252b5132
RH
12483
12484 return buff;
12485}
12486
12487/* Display the contents of the version sections. */
98fb390a 12488
015dc7e1 12489static bool
dda8d76d 12490process_version_sections (Filedata * filedata)
252b5132 12491{
2cf0635d 12492 Elf_Internal_Shdr * section;
b34976b6 12493 unsigned i;
015dc7e1 12494 bool found = false;
252b5132
RH
12495
12496 if (! do_version)
015dc7e1 12497 return true;
252b5132 12498
dda8d76d
NC
12499 for (i = 0, section = filedata->section_headers;
12500 i < filedata->file_header.e_shnum;
b34976b6 12501 i++, section++)
252b5132
RH
12502 {
12503 switch (section->sh_type)
12504 {
12505 case SHT_GNU_verdef:
12506 {
2cf0635d 12507 Elf_External_Verdef * edefs;
26c527e6
AM
12508 size_t idx;
12509 size_t cnt;
2cf0635d 12510 char * endbuf;
252b5132 12511
015dc7e1 12512 found = true;
252b5132 12513
ca0e11aa
NC
12514 if (filedata->is_separate)
12515 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12516 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12517 section->sh_info),
12518 filedata->file_name,
12519 printable_section_name (filedata, section),
12520 section->sh_info);
12521 else
12522 printf (ngettext ("\nVersion definition section '%s' "
12523 "contains %u entry:\n",
12524 "\nVersion definition section '%s' "
12525 "contains %u entries:\n",
12526 section->sh_info),
12527 printable_section_name (filedata, section),
12528 section->sh_info);
047c3dbf 12529
625d49fc 12530 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12531 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12532 section->sh_offset, section->sh_link,
dda8d76d 12533 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12534
3f5e193b 12535 edefs = (Elf_External_Verdef *)
dda8d76d 12536 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12537 _("version definition section"));
a6e9f9df
AM
12538 if (!edefs)
12539 break;
59245841 12540 endbuf = (char *) edefs + section->sh_size;
252b5132 12541
1445030f 12542 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12543 {
2cf0635d
NC
12544 char * vstart;
12545 Elf_External_Verdef * edef;
b34976b6 12546 Elf_Internal_Verdef ent;
2cf0635d 12547 Elf_External_Verdaux * eaux;
b34976b6 12548 Elf_Internal_Verdaux aux;
26c527e6 12549 size_t isum;
b34976b6 12550 int j;
103f02d3 12551
252b5132 12552 vstart = ((char *) edefs) + idx;
54806181
AM
12553 if (vstart + sizeof (*edef) > endbuf)
12554 break;
252b5132
RH
12555
12556 edef = (Elf_External_Verdef *) vstart;
12557
12558 ent.vd_version = BYTE_GET (edef->vd_version);
12559 ent.vd_flags = BYTE_GET (edef->vd_flags);
12560 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12561 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12562 ent.vd_hash = BYTE_GET (edef->vd_hash);
12563 ent.vd_aux = BYTE_GET (edef->vd_aux);
12564 ent.vd_next = BYTE_GET (edef->vd_next);
12565
26c527e6 12566 printf (_(" %#06zx: Rev: %d Flags: %s"),
252b5132
RH
12567 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12568
12569 printf (_(" Index: %d Cnt: %d "),
12570 ent.vd_ndx, ent.vd_cnt);
12571
452bf675 12572 /* Check for overflow. */
1445030f 12573 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12574 break;
12575
252b5132
RH
12576 vstart += ent.vd_aux;
12577
1445030f
AM
12578 if (vstart + sizeof (*eaux) > endbuf)
12579 break;
252b5132
RH
12580 eaux = (Elf_External_Verdaux *) vstart;
12581
12582 aux.vda_name = BYTE_GET (eaux->vda_name);
12583 aux.vda_next = BYTE_GET (eaux->vda_next);
12584
84714f86 12585 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12586 printf (_("Name: %s\n"),
84714f86 12587 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12588 else
12589 printf (_("Name index: %ld\n"), aux.vda_name);
12590
12591 isum = idx + ent.vd_aux;
12592
b34976b6 12593 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12594 {
1445030f
AM
12595 if (aux.vda_next < sizeof (*eaux)
12596 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12597 {
12598 warn (_("Invalid vda_next field of %lx\n"),
12599 aux.vda_next);
12600 j = ent.vd_cnt;
12601 break;
12602 }
dd24e3da 12603 /* Check for overflow. */
7e26601c 12604 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12605 break;
12606
252b5132
RH
12607 isum += aux.vda_next;
12608 vstart += aux.vda_next;
12609
54806181
AM
12610 if (vstart + sizeof (*eaux) > endbuf)
12611 break;
1445030f 12612 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12613
12614 aux.vda_name = BYTE_GET (eaux->vda_name);
12615 aux.vda_next = BYTE_GET (eaux->vda_next);
12616
84714f86 12617 if (valid_dynamic_name (filedata, aux.vda_name))
26c527e6 12618 printf (_(" %#06zx: Parent %d: %s\n"),
978c4450 12619 isum, j,
84714f86 12620 get_dynamic_name (filedata, aux.vda_name));
252b5132 12621 else
26c527e6 12622 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
252b5132
RH
12623 isum, j, aux.vda_name);
12624 }
dd24e3da 12625
54806181
AM
12626 if (j < ent.vd_cnt)
12627 printf (_(" Version def aux past end of section\n"));
252b5132 12628
c9f02c3e
MR
12629 /* PR 17531:
12630 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12631 if (ent.vd_next < sizeof (*edef)
12632 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12633 {
12634 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12635 cnt = section->sh_info;
12636 break;
12637 }
452bf675 12638 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12639 break;
12640
252b5132
RH
12641 idx += ent.vd_next;
12642 }
dd24e3da 12643
54806181
AM
12644 if (cnt < section->sh_info)
12645 printf (_(" Version definition past end of section\n"));
252b5132
RH
12646
12647 free (edefs);
12648 }
12649 break;
103f02d3 12650
252b5132
RH
12651 case SHT_GNU_verneed:
12652 {
2cf0635d 12653 Elf_External_Verneed * eneed;
26c527e6
AM
12654 size_t idx;
12655 size_t cnt;
2cf0635d 12656 char * endbuf;
252b5132 12657
015dc7e1 12658 found = true;
252b5132 12659
ca0e11aa
NC
12660 if (filedata->is_separate)
12661 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12662 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12663 section->sh_info),
12664 filedata->file_name,
12665 printable_section_name (filedata, section),
12666 section->sh_info);
12667 else
12668 printf (ngettext ("\nVersion needs section '%s' "
12669 "contains %u entry:\n",
12670 "\nVersion needs section '%s' "
12671 "contains %u entries:\n",
12672 section->sh_info),
12673 printable_section_name (filedata, section),
12674 section->sh_info);
047c3dbf 12675
625d49fc 12676 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12677 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12678 section->sh_offset, section->sh_link,
dda8d76d 12679 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12680
dda8d76d 12681 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12682 section->sh_offset, 1,
12683 section->sh_size,
9cf03b7e 12684 _("Version Needs section"));
a6e9f9df
AM
12685 if (!eneed)
12686 break;
59245841 12687 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12688
12689 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12690 {
2cf0635d 12691 Elf_External_Verneed * entry;
b34976b6 12692 Elf_Internal_Verneed ent;
26c527e6 12693 size_t isum;
b34976b6 12694 int j;
2cf0635d 12695 char * vstart;
252b5132
RH
12696
12697 vstart = ((char *) eneed) + idx;
54806181
AM
12698 if (vstart + sizeof (*entry) > endbuf)
12699 break;
252b5132
RH
12700
12701 entry = (Elf_External_Verneed *) vstart;
12702
12703 ent.vn_version = BYTE_GET (entry->vn_version);
12704 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12705 ent.vn_file = BYTE_GET (entry->vn_file);
12706 ent.vn_aux = BYTE_GET (entry->vn_aux);
12707 ent.vn_next = BYTE_GET (entry->vn_next);
12708
26c527e6 12709 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
252b5132 12710
84714f86 12711 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12712 printf (_(" File: %s"),
84714f86 12713 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12714 else
12715 printf (_(" File: %lx"), ent.vn_file);
12716
12717 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12718
dd24e3da 12719 /* Check for overflow. */
7e26601c 12720 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12721 break;
252b5132
RH
12722 vstart += ent.vn_aux;
12723
12724 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12725 {
2cf0635d 12726 Elf_External_Vernaux * eaux;
b34976b6 12727 Elf_Internal_Vernaux aux;
252b5132 12728
54806181
AM
12729 if (vstart + sizeof (*eaux) > endbuf)
12730 break;
252b5132
RH
12731 eaux = (Elf_External_Vernaux *) vstart;
12732
12733 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12734 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12735 aux.vna_other = BYTE_GET (eaux->vna_other);
12736 aux.vna_name = BYTE_GET (eaux->vna_name);
12737 aux.vna_next = BYTE_GET (eaux->vna_next);
12738
84714f86 12739 if (valid_dynamic_name (filedata, aux.vna_name))
26c527e6 12740 printf (_(" %#06zx: Name: %s"),
84714f86 12741 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12742 else
26c527e6 12743 printf (_(" %#06zx: Name index: %lx"),
252b5132
RH
12744 isum, aux.vna_name);
12745
12746 printf (_(" Flags: %s Version: %d\n"),
12747 get_ver_flags (aux.vna_flags), aux.vna_other);
12748
1445030f
AM
12749 if (aux.vna_next < sizeof (*eaux)
12750 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12751 {
12752 warn (_("Invalid vna_next field of %lx\n"),
12753 aux.vna_next);
12754 j = ent.vn_cnt;
12755 break;
12756 }
1445030f
AM
12757 /* Check for overflow. */
12758 if (aux.vna_next > (size_t) (endbuf - vstart))
12759 break;
252b5132
RH
12760 isum += aux.vna_next;
12761 vstart += aux.vna_next;
12762 }
9cf03b7e 12763
54806181 12764 if (j < ent.vn_cnt)
f9a6a8f0 12765 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12766
1445030f
AM
12767 if (ent.vn_next < sizeof (*entry)
12768 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12769 {
452bf675 12770 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12771 cnt = section->sh_info;
12772 break;
12773 }
1445030f
AM
12774 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12775 break;
252b5132
RH
12776 idx += ent.vn_next;
12777 }
9cf03b7e 12778
54806181 12779 if (cnt < section->sh_info)
9cf03b7e 12780 warn (_("Missing Version Needs information\n"));
103f02d3 12781
252b5132
RH
12782 free (eneed);
12783 }
12784 break;
12785
12786 case SHT_GNU_versym:
12787 {
2cf0635d 12788 Elf_Internal_Shdr * link_section;
26c527e6 12789 uint64_t total;
8b73c356 12790 unsigned int cnt;
2cf0635d
NC
12791 unsigned char * edata;
12792 unsigned short * data;
12793 char * strtab;
12794 Elf_Internal_Sym * symbols;
12795 Elf_Internal_Shdr * string_sec;
26c527e6
AM
12796 uint64_t num_syms;
12797 uint64_t off;
252b5132 12798
dda8d76d 12799 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12800 break;
12801
dda8d76d 12802 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12803 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12804
dda8d76d 12805 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12806 break;
12807
015dc7e1 12808 found = true;
252b5132 12809
4de91c10 12810 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12811 if (symbols == NULL)
12812 break;
252b5132 12813
dda8d76d 12814 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12815
dda8d76d 12816 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12817 string_sec->sh_size,
12818 _("version string table"));
a6e9f9df 12819 if (!strtab)
0429c154
MS
12820 {
12821 free (symbols);
12822 break;
12823 }
252b5132 12824
ca0e11aa 12825 if (filedata->is_separate)
26c527e6
AM
12826 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
12827 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12828 total),
12829 filedata->file_name,
12830 printable_section_name (filedata, section),
26c527e6 12831 total);
ca0e11aa
NC
12832 else
12833 printf (ngettext ("\nVersion symbols section '%s' "
26c527e6 12834 "contains %" PRIu64 " entry:\n",
ca0e11aa 12835 "\nVersion symbols section '%s' "
26c527e6 12836 "contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12837 total),
12838 printable_section_name (filedata, section),
26c527e6 12839 total);
252b5132 12840
625d49fc 12841 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12842 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12843 section->sh_offset, section->sh_link,
dda8d76d 12844 printable_section_name (filedata, link_section));
252b5132 12845
dda8d76d 12846 off = offset_from_vma (filedata,
978c4450 12847 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12848 total * sizeof (short));
95099889
AM
12849 edata = (unsigned char *) get_data (NULL, filedata, off,
12850 sizeof (short), total,
12851 _("version symbol data"));
a6e9f9df
AM
12852 if (!edata)
12853 {
12854 free (strtab);
0429c154 12855 free (symbols);
a6e9f9df
AM
12856 break;
12857 }
252b5132 12858
3f5e193b 12859 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12860
12861 for (cnt = total; cnt --;)
b34976b6
AM
12862 data[cnt] = byte_get (edata + cnt * sizeof (short),
12863 sizeof (short));
252b5132
RH
12864
12865 free (edata);
12866
12867 for (cnt = 0; cnt < total; cnt += 4)
12868 {
12869 int j, nn;
ab273396
AM
12870 char *name;
12871 char *invalid = _("*invalid*");
252b5132
RH
12872
12873 printf (" %03x:", cnt);
12874
12875 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12876 switch (data[cnt + j])
252b5132
RH
12877 {
12878 case 0:
12879 fputs (_(" 0 (*local*) "), stdout);
12880 break;
12881
12882 case 1:
12883 fputs (_(" 1 (*global*) "), stdout);
12884 break;
12885
12886 default:
c244d050
NC
12887 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12888 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12889
dd24e3da 12890 /* If this index value is greater than the size of the symbols
ba5cdace 12891 array, break to avoid an out-of-bounds read. */
26c527e6 12892 if (cnt + j >= num_syms)
dd24e3da
NC
12893 {
12894 warn (_("invalid index into symbol array\n"));
12895 break;
12896 }
12897
ab273396 12898 name = NULL;
978c4450 12899 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12900 {
b34976b6 12901 Elf_Internal_Verneed ivn;
26c527e6 12902 uint64_t offset;
252b5132 12903
d93f0186 12904 offset = offset_from_vma
978c4450
AM
12905 (filedata,
12906 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12907 sizeof (Elf_External_Verneed));
252b5132 12908
b34976b6 12909 do
252b5132 12910 {
b34976b6
AM
12911 Elf_Internal_Vernaux ivna;
12912 Elf_External_Verneed evn;
12913 Elf_External_Vernaux evna;
26c527e6 12914 uint64_t a_off;
252b5132 12915
dda8d76d 12916 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12917 _("version need")) == NULL)
12918 break;
0b4362b0 12919
252b5132
RH
12920 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12921 ivn.vn_next = BYTE_GET (evn.vn_next);
12922
12923 a_off = offset + ivn.vn_aux;
12924
12925 do
12926 {
dda8d76d 12927 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12928 1, _("version need aux (2)")) == NULL)
12929 {
12930 ivna.vna_next = 0;
12931 ivna.vna_other = 0;
12932 }
12933 else
12934 {
12935 ivna.vna_next = BYTE_GET (evna.vna_next);
12936 ivna.vna_other = BYTE_GET (evna.vna_other);
12937 }
252b5132
RH
12938
12939 a_off += ivna.vna_next;
12940 }
b34976b6 12941 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12942 && ivna.vna_next != 0);
12943
b34976b6 12944 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12945 {
12946 ivna.vna_name = BYTE_GET (evna.vna_name);
12947
54806181 12948 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12949 name = invalid;
54806181
AM
12950 else
12951 name = strtab + ivna.vna_name;
252b5132
RH
12952 break;
12953 }
12954
12955 offset += ivn.vn_next;
12956 }
12957 while (ivn.vn_next);
12958 }
00d93f34 12959
ab273396 12960 if (data[cnt + j] != 0x8001
978c4450 12961 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12962 {
b34976b6
AM
12963 Elf_Internal_Verdef ivd;
12964 Elf_External_Verdef evd;
26c527e6 12965 uint64_t offset;
252b5132 12966
d93f0186 12967 offset = offset_from_vma
978c4450
AM
12968 (filedata,
12969 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12970 sizeof evd);
252b5132
RH
12971
12972 do
12973 {
dda8d76d 12974 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12975 _("version def")) == NULL)
12976 {
12977 ivd.vd_next = 0;
948f632f 12978 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12979 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12980 break;
59245841
NC
12981 }
12982 else
12983 {
12984 ivd.vd_next = BYTE_GET (evd.vd_next);
12985 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12986 }
252b5132
RH
12987
12988 offset += ivd.vd_next;
12989 }
c244d050 12990 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12991 && ivd.vd_next != 0);
12992
c244d050 12993 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12994 {
b34976b6
AM
12995 Elf_External_Verdaux evda;
12996 Elf_Internal_Verdaux ivda;
252b5132
RH
12997
12998 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12999
dda8d76d 13000 if (get_data (&evda, filedata,
59245841
NC
13001 offset - ivd.vd_next + ivd.vd_aux,
13002 sizeof (evda), 1,
13003 _("version def aux")) == NULL)
13004 break;
252b5132
RH
13005
13006 ivda.vda_name = BYTE_GET (evda.vda_name);
13007
54806181 13008 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
13009 name = invalid;
13010 else if (name != NULL && name != invalid)
13011 name = _("*both*");
54806181
AM
13012 else
13013 name = strtab + ivda.vda_name;
252b5132
RH
13014 }
13015 }
ab273396
AM
13016 if (name != NULL)
13017 nn += printf ("(%s%-*s",
13018 name,
13019 12 - (int) strlen (name),
13020 ")");
252b5132
RH
13021
13022 if (nn < 18)
13023 printf ("%*c", 18 - nn, ' ');
13024 }
13025
13026 putchar ('\n');
13027 }
13028
13029 free (data);
13030 free (strtab);
13031 free (symbols);
13032 }
13033 break;
103f02d3 13034
252b5132
RH
13035 default:
13036 break;
13037 }
13038 }
13039
13040 if (! found)
ca0e11aa
NC
13041 {
13042 if (filedata->is_separate)
13043 printf (_("\nNo version information found in linked file '%s'.\n"),
13044 filedata->file_name);
13045 else
13046 printf (_("\nNo version information found in this file.\n"));
13047 }
252b5132 13048
015dc7e1 13049 return true;
252b5132
RH
13050}
13051
d1133906 13052static const char *
dda8d76d 13053get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 13054{
89246a0e 13055 static char buff[64];
252b5132
RH
13056
13057 switch (binding)
13058 {
b34976b6
AM
13059 case STB_LOCAL: return "LOCAL";
13060 case STB_GLOBAL: return "GLOBAL";
13061 case STB_WEAK: return "WEAK";
252b5132
RH
13062 default:
13063 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
13064 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
13065 binding);
252b5132 13066 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
13067 {
13068 if (binding == STB_GNU_UNIQUE
df3a023b 13069 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
13070 return "UNIQUE";
13071 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
13072 }
252b5132 13073 else
e9e44622 13074 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
13075 return buff;
13076 }
13077}
13078
d1133906 13079static const char *
dda8d76d 13080get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 13081{
89246a0e 13082 static char buff[64];
252b5132
RH
13083
13084 switch (type)
13085 {
b34976b6
AM
13086 case STT_NOTYPE: return "NOTYPE";
13087 case STT_OBJECT: return "OBJECT";
13088 case STT_FUNC: return "FUNC";
13089 case STT_SECTION: return "SECTION";
13090 case STT_FILE: return "FILE";
13091 case STT_COMMON: return "COMMON";
13092 case STT_TLS: return "TLS";
15ab5209
DB
13093 case STT_RELC: return "RELC";
13094 case STT_SRELC: return "SRELC";
252b5132
RH
13095 default:
13096 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 13097 {
dda8d76d 13098 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 13099 return "THUMB_FUNC";
103f02d3 13100
dda8d76d 13101 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
13102 return "REGISTER";
13103
dda8d76d 13104 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
13105 return "PARISC_MILLI";
13106
e9e44622 13107 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 13108 }
252b5132 13109 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 13110 {
dda8d76d 13111 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
13112 {
13113 if (type == STT_HP_OPAQUE)
13114 return "HP_OPAQUE";
13115 if (type == STT_HP_STUB)
13116 return "HP_STUB";
13117 }
13118
8654c01f
ML
13119 if (type == STT_GNU_IFUNC
13120 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
13121 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
13122 return "IFUNC";
13123
e9e44622 13124 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 13125 }
252b5132 13126 else
e9e44622 13127 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
13128 return buff;
13129 }
13130}
13131
d1133906 13132static const char *
d3ba0551 13133get_symbol_visibility (unsigned int visibility)
d1133906
NC
13134{
13135 switch (visibility)
13136 {
b34976b6
AM
13137 case STV_DEFAULT: return "DEFAULT";
13138 case STV_INTERNAL: return "INTERNAL";
13139 case STV_HIDDEN: return "HIDDEN";
d1133906 13140 case STV_PROTECTED: return "PROTECTED";
bee0ee85 13141 default:
27a45f42 13142 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 13143 return _("<unknown>");
d1133906
NC
13144 }
13145}
13146
2057d69d
CZ
13147static const char *
13148get_alpha_symbol_other (unsigned int other)
9abca702 13149{
2057d69d
CZ
13150 switch (other)
13151 {
13152 case STO_ALPHA_NOPV: return "NOPV";
13153 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
13154 default:
27a45f42 13155 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 13156 return _("<unknown>");
9abca702 13157 }
2057d69d
CZ
13158}
13159
fd85a6a1
NC
13160static const char *
13161get_solaris_symbol_visibility (unsigned int visibility)
13162{
13163 switch (visibility)
13164 {
13165 case 4: return "EXPORTED";
13166 case 5: return "SINGLETON";
13167 case 6: return "ELIMINATE";
13168 default: return get_symbol_visibility (visibility);
13169 }
13170}
13171
2301ed1c
SN
13172static const char *
13173get_aarch64_symbol_other (unsigned int other)
13174{
13175 static char buf[32];
13176
13177 if (other & STO_AARCH64_VARIANT_PCS)
13178 {
13179 other &= ~STO_AARCH64_VARIANT_PCS;
13180 if (other == 0)
13181 return "VARIANT_PCS";
13182 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
13183 return buf;
13184 }
13185 return NULL;
13186}
13187
5e2b0d47
NC
13188static const char *
13189get_mips_symbol_other (unsigned int other)
13190{
13191 switch (other)
13192 {
32ec8896
NC
13193 case STO_OPTIONAL: return "OPTIONAL";
13194 case STO_MIPS_PLT: return "MIPS PLT";
13195 case STO_MIPS_PIC: return "MIPS PIC";
13196 case STO_MICROMIPS: return "MICROMIPS";
13197 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
13198 case STO_MIPS16: return "MIPS16";
13199 default: return NULL;
5e2b0d47
NC
13200 }
13201}
13202
28f997cf 13203static const char *
dda8d76d 13204get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 13205{
dda8d76d 13206 if (is_ia64_vms (filedata))
28f997cf
TG
13207 {
13208 static char res[32];
13209
13210 res[0] = 0;
13211
13212 /* Function types is for images and .STB files only. */
dda8d76d 13213 switch (filedata->file_header.e_type)
28f997cf
TG
13214 {
13215 case ET_DYN:
13216 case ET_EXEC:
13217 switch (VMS_ST_FUNC_TYPE (other))
13218 {
13219 case VMS_SFT_CODE_ADDR:
13220 strcat (res, " CA");
13221 break;
13222 case VMS_SFT_SYMV_IDX:
13223 strcat (res, " VEC");
13224 break;
13225 case VMS_SFT_FD:
13226 strcat (res, " FD");
13227 break;
13228 case VMS_SFT_RESERVE:
13229 strcat (res, " RSV");
13230 break;
13231 default:
bee0ee85
NC
13232 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
13233 VMS_ST_FUNC_TYPE (other));
13234 strcat (res, " <unknown>");
13235 break;
28f997cf
TG
13236 }
13237 break;
13238 default:
13239 break;
13240 }
13241 switch (VMS_ST_LINKAGE (other))
13242 {
13243 case VMS_STL_IGNORE:
13244 strcat (res, " IGN");
13245 break;
13246 case VMS_STL_RESERVE:
13247 strcat (res, " RSV");
13248 break;
13249 case VMS_STL_STD:
13250 strcat (res, " STD");
13251 break;
13252 case VMS_STL_LNK:
13253 strcat (res, " LNK");
13254 break;
13255 default:
bee0ee85
NC
13256 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
13257 VMS_ST_LINKAGE (other));
13258 strcat (res, " <unknown>");
13259 break;
28f997cf
TG
13260 }
13261
13262 if (res[0] != 0)
13263 return res + 1;
13264 else
13265 return res;
13266 }
13267 return NULL;
13268}
13269
6911b7dc
AM
13270static const char *
13271get_ppc64_symbol_other (unsigned int other)
13272{
14732552
AM
13273 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
13274 return NULL;
13275
13276 other >>= STO_PPC64_LOCAL_BIT;
13277 if (other <= 6)
6911b7dc 13278 {
89246a0e 13279 static char buf[64];
14732552
AM
13280 if (other >= 2)
13281 other = ppc64_decode_local_entry (other);
13282 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
13283 return buf;
13284 }
13285 return NULL;
13286}
13287
8155b853
NC
13288static const char *
13289get_riscv_symbol_other (unsigned int other)
13290{
13291 static char buf[32];
13292 buf[0] = 0;
13293
13294 if (other & STO_RISCV_VARIANT_CC)
13295 {
13296 strcat (buf, _(" VARIANT_CC"));
13297 other &= ~STO_RISCV_VARIANT_CC;
13298 }
13299
13300 if (other != 0)
13301 snprintf (buf, sizeof buf, " %x", other);
13302
13303
13304 if (buf[0] != 0)
13305 return buf + 1;
13306 else
13307 return buf;
13308}
13309
5e2b0d47 13310static const char *
dda8d76d 13311get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
13312{
13313 const char * result = NULL;
89246a0e 13314 static char buff [64];
5e2b0d47
NC
13315
13316 if (other == 0)
13317 return "";
13318
dda8d76d 13319 switch (filedata->file_header.e_machine)
5e2b0d47 13320 {
2057d69d
CZ
13321 case EM_ALPHA:
13322 result = get_alpha_symbol_other (other);
13323 break;
2301ed1c
SN
13324 case EM_AARCH64:
13325 result = get_aarch64_symbol_other (other);
13326 break;
5e2b0d47
NC
13327 case EM_MIPS:
13328 result = get_mips_symbol_other (other);
28f997cf
TG
13329 break;
13330 case EM_IA_64:
dda8d76d 13331 result = get_ia64_symbol_other (filedata, other);
28f997cf 13332 break;
6911b7dc
AM
13333 case EM_PPC64:
13334 result = get_ppc64_symbol_other (other);
13335 break;
8155b853
NC
13336 case EM_RISCV:
13337 result = get_riscv_symbol_other (other);
13338 break;
5e2b0d47 13339 default:
fd85a6a1 13340 result = NULL;
5e2b0d47
NC
13341 break;
13342 }
13343
13344 if (result)
13345 return result;
13346
13347 snprintf (buff, sizeof buff, _("<other>: %x"), other);
13348 return buff;
13349}
13350
d1133906 13351static const char *
dda8d76d 13352get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 13353{
b34976b6 13354 static char buff[32];
5cf1065c 13355
252b5132
RH
13356 switch (type)
13357 {
b34976b6
AM
13358 case SHN_UNDEF: return "UND";
13359 case SHN_ABS: return "ABS";
13360 case SHN_COMMON: return "COM";
252b5132 13361 default:
9ce701e2 13362 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
13363 && filedata->file_header.e_machine == EM_IA_64
13364 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
13365 return "ANSI_COM";
13366 else if ((filedata->file_header.e_machine == EM_X86_64
13367 || filedata->file_header.e_machine == EM_L1OM
13368 || filedata->file_header.e_machine == EM_K1OM)
13369 && type == SHN_X86_64_LCOMMON)
13370 return "LARGE_COM";
13371 else if ((type == SHN_MIPS_SCOMMON
13372 && filedata->file_header.e_machine == EM_MIPS)
13373 || (type == SHN_TIC6X_SCOMMON
13374 && filedata->file_header.e_machine == EM_TI_C6000))
13375 return "SCOM";
13376 else if (type == SHN_MIPS_SUNDEFINED
13377 && filedata->file_header.e_machine == EM_MIPS)
13378 return "SUND";
13379 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
13380 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
13381 else if (type >= SHN_LOOS && type <= SHN_HIOS)
13382 sprintf (buff, "OS [0x%04x]", type & 0xffff);
13383 else if (type >= SHN_LORESERVE)
13384 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
13385 else if (filedata->file_header.e_shnum != 0
13386 && type >= filedata->file_header.e_shnum)
13387 sprintf (buff, _("bad section index[%3d]"), type);
13388 else
13389 sprintf (buff, "%3d", type);
13390 break;
fd85a6a1
NC
13391 }
13392
10ca4b04 13393 return buff;
6bd1a22c
L
13394}
13395
bb4d2ac2 13396static const char *
26c527e6
AM
13397get_symbol_version_string (Filedata *filedata,
13398 bool is_dynsym,
13399 const char *strtab,
13400 size_t strtab_size,
13401 unsigned int si,
13402 Elf_Internal_Sym *psym,
13403 enum versioned_symbol_info *sym_info,
13404 unsigned short *vna_other)
bb4d2ac2 13405{
ab273396
AM
13406 unsigned char data[2];
13407 unsigned short vers_data;
26c527e6 13408 uint64_t offset;
7a815dd5 13409 unsigned short max_vd_ndx;
bb4d2ac2 13410
ab273396 13411 if (!is_dynsym
978c4450 13412 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 13413 return NULL;
bb4d2ac2 13414
978c4450
AM
13415 offset = offset_from_vma (filedata,
13416 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 13417 sizeof data + si * sizeof (vers_data));
bb4d2ac2 13418
dda8d76d 13419 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
13420 sizeof (data), 1, _("version data")) == NULL)
13421 return NULL;
13422
13423 vers_data = byte_get (data, 2);
bb4d2ac2 13424
1f6f5dba 13425 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 13426 return NULL;
bb4d2ac2 13427
0b8b7609 13428 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
13429 max_vd_ndx = 0;
13430
ab273396
AM
13431 /* Usually we'd only see verdef for defined symbols, and verneed for
13432 undefined symbols. However, symbols defined by the linker in
13433 .dynbss for variables copied from a shared library in order to
13434 avoid text relocations are defined yet have verneed. We could
13435 use a heuristic to detect the special case, for example, check
13436 for verneed first on symbols defined in SHT_NOBITS sections, but
13437 it is simpler and more reliable to just look for both verdef and
13438 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13439
ab273396
AM
13440 if (psym->st_shndx != SHN_UNDEF
13441 && vers_data != 0x8001
978c4450 13442 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13443 {
13444 Elf_Internal_Verdef ivd;
13445 Elf_Internal_Verdaux ivda;
13446 Elf_External_Verdaux evda;
26c527e6 13447 uint64_t off;
bb4d2ac2 13448
dda8d76d 13449 off = offset_from_vma (filedata,
978c4450 13450 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13451 sizeof (Elf_External_Verdef));
13452
13453 do
bb4d2ac2 13454 {
ab273396
AM
13455 Elf_External_Verdef evd;
13456
dda8d76d 13457 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13458 _("version def")) == NULL)
13459 {
13460 ivd.vd_ndx = 0;
13461 ivd.vd_aux = 0;
13462 ivd.vd_next = 0;
1f6f5dba 13463 ivd.vd_flags = 0;
ab273396
AM
13464 }
13465 else
bb4d2ac2 13466 {
ab273396
AM
13467 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13468 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13469 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13470 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13471 }
bb4d2ac2 13472
7a815dd5
L
13473 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13474 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13475
ab273396
AM
13476 off += ivd.vd_next;
13477 }
13478 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13479
ab273396
AM
13480 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13481 {
9abca702 13482 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13483 return NULL;
13484
ab273396
AM
13485 off -= ivd.vd_next;
13486 off += ivd.vd_aux;
bb4d2ac2 13487
dda8d76d 13488 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13489 _("version def aux")) != NULL)
13490 {
13491 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13492
ab273396 13493 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13494 return (ivda.vda_name < strtab_size
13495 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13496 }
13497 }
13498 }
bb4d2ac2 13499
978c4450 13500 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13501 {
13502 Elf_External_Verneed evn;
13503 Elf_Internal_Verneed ivn;
13504 Elf_Internal_Vernaux ivna;
bb4d2ac2 13505
dda8d76d 13506 offset = offset_from_vma (filedata,
978c4450 13507 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13508 sizeof evn);
13509 do
13510 {
26c527e6 13511 uint64_t vna_off;
bb4d2ac2 13512
dda8d76d 13513 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13514 _("version need")) == NULL)
13515 {
13516 ivna.vna_next = 0;
13517 ivna.vna_other = 0;
13518 ivna.vna_name = 0;
13519 break;
13520 }
bb4d2ac2 13521
ab273396
AM
13522 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13523 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13524
ab273396 13525 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13526
ab273396
AM
13527 do
13528 {
13529 Elf_External_Vernaux evna;
bb4d2ac2 13530
dda8d76d 13531 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13532 _("version need aux (3)")) == NULL)
bb4d2ac2 13533 {
ab273396
AM
13534 ivna.vna_next = 0;
13535 ivna.vna_other = 0;
13536 ivna.vna_name = 0;
bb4d2ac2 13537 }
bb4d2ac2 13538 else
bb4d2ac2 13539 {
ab273396
AM
13540 ivna.vna_other = BYTE_GET (evna.vna_other);
13541 ivna.vna_next = BYTE_GET (evna.vna_next);
13542 ivna.vna_name = BYTE_GET (evna.vna_name);
13543 }
bb4d2ac2 13544
ab273396
AM
13545 vna_off += ivna.vna_next;
13546 }
13547 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13548
ab273396
AM
13549 if (ivna.vna_other == vers_data)
13550 break;
bb4d2ac2 13551
ab273396
AM
13552 offset += ivn.vn_next;
13553 }
13554 while (ivn.vn_next != 0);
bb4d2ac2 13555
ab273396
AM
13556 if (ivna.vna_other == vers_data)
13557 {
13558 *sym_info = symbol_undefined;
13559 *vna_other = ivna.vna_other;
13560 return (ivna.vna_name < strtab_size
13561 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13562 }
7a815dd5
L
13563 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13564 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13565 return _("<corrupt>");
bb4d2ac2 13566 }
ab273396 13567 return NULL;
bb4d2ac2
L
13568}
13569
047c3dbf
NL
13570/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13571
13572static unsigned int
625d49fc 13573print_dynamic_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13574{
13575 switch (base)
13576 {
13577 case 8:
13578 return print_vma (vma, OCTAL_5);
13579
13580 case 10:
13581 return print_vma (vma, UNSIGNED_5);
13582
13583 case 16:
13584 return print_vma (vma, PREFIX_HEX_5);
13585
13586 case 0:
13587 default:
13588 return print_vma (vma, DEC_5);
13589 }
13590}
13591
10ca4b04 13592static void
26c527e6 13593print_dynamic_symbol (Filedata *filedata, uint64_t si,
10ca4b04
L
13594 Elf_Internal_Sym *symtab,
13595 Elf_Internal_Shdr *section,
13596 char *strtab, size_t strtab_size)
252b5132 13597{
10ca4b04
L
13598 const char *version_string;
13599 enum versioned_symbol_info sym_info;
13600 unsigned short vna_other;
23356397
NC
13601 bool is_valid;
13602 const char * sstr;
10ca4b04 13603 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13604
26c527e6 13605 printf ("%6" PRId64 ": ", si);
10ca4b04
L
13606 print_vma (psym->st_value, LONG_HEX);
13607 putchar (' ');
047c3dbf 13608 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13609 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13610 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13611 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13612 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13613 else
252b5132 13614 {
10ca4b04 13615 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13616
10ca4b04
L
13617 printf (" %-7s", get_symbol_visibility (vis));
13618 /* Check to see if any other bits in the st_other field are set.
13619 Note - displaying this information disrupts the layout of the
13620 table being generated, but for the moment this case is very rare. */
13621 if (psym->st_other ^ vis)
13622 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13623 }
10ca4b04 13624 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13625
23356397
NC
13626 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13627 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13628 && filedata->section_headers != NULL
23356397
NC
13629 && psym->st_name == 0)
13630 {
84714f86
AM
13631 is_valid
13632 = section_name_valid (filedata,
13633 filedata->section_headers + psym->st_shndx);
23356397 13634 sstr = is_valid ?
84714f86
AM
13635 section_name_print (filedata,
13636 filedata->section_headers + psym->st_shndx)
23356397
NC
13637 : _("<corrupt>");
13638 }
13639 else
13640 {
84714f86 13641 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13642 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13643 }
10ca4b04
L
13644
13645 version_string
13646 = get_symbol_version_string (filedata,
13647 (section == NULL
13648 || section->sh_type == SHT_DYNSYM),
13649 strtab, strtab_size, si,
13650 psym, &sym_info, &vna_other);
b9e920ec 13651
0942c7ab
NC
13652 int len_avail = 21;
13653 if (! do_wide && version_string != NULL)
13654 {
ddb43bab 13655 char buffer[16];
0942c7ab 13656
ddb43bab 13657 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13658
13659 if (sym_info == symbol_undefined)
13660 len_avail -= sprintf (buffer," (%d)", vna_other);
13661 else if (sym_info != symbol_hidden)
13662 len_avail -= 1;
13663 }
13664
13665 print_symbol (len_avail, sstr);
b9e920ec 13666
10ca4b04
L
13667 if (version_string)
13668 {
13669 if (sym_info == symbol_undefined)
13670 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13671 else
10ca4b04
L
13672 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13673 version_string);
13674 }
6bd1a22c 13675
10ca4b04 13676 putchar ('\n');
6bd1a22c 13677
10ca4b04
L
13678 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13679 && section != NULL
13680 && si >= section->sh_info
13681 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13682 && filedata->file_header.e_machine != EM_MIPS
13683 /* Solaris binaries have been found to violate this requirement as
13684 well. Not sure if this is a bug or an ABI requirement. */
13685 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
26c527e6 13686 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
10ca4b04
L
13687 si, printable_section_name (filedata, section), section->sh_info);
13688}
f16a9783 13689
0f03783c
NC
13690static const char *
13691get_lto_kind (unsigned int kind)
13692{
13693 switch (kind)
13694 {
13695 case 0: return "DEF";
13696 case 1: return "WEAKDEF";
13697 case 2: return "UNDEF";
13698 case 3: return "WEAKUNDEF";
13699 case 4: return "COMMON";
13700 default:
13701 break;
13702 }
13703
13704 static char buffer[30];
13705 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13706 sprintf (buffer, "<unknown: %u>", kind);
13707 return buffer;
13708}
13709
13710static const char *
13711get_lto_visibility (unsigned int visibility)
13712{
13713 switch (visibility)
13714 {
13715 case 0: return "DEFAULT";
13716 case 1: return "PROTECTED";
13717 case 2: return "INTERNAL";
13718 case 3: return "HIDDEN";
13719 default:
13720 break;
13721 }
13722
13723 static char buffer[30];
13724 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13725 sprintf (buffer, "<unknown: %u>", visibility);
13726 return buffer;
13727}
13728
13729static const char *
13730get_lto_sym_type (unsigned int sym_type)
13731{
13732 switch (sym_type)
13733 {
13734 case 0: return "UNKNOWN";
13735 case 1: return "FUNCTION";
13736 case 2: return "VARIABLE";
13737 default:
13738 break;
13739 }
13740
13741 static char buffer[30];
13742 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13743 sprintf (buffer, "<unknown: %u>", sym_type);
13744 return buffer;
13745}
13746
13747/* Display an LTO format symbol table.
13748 FIXME: The format of LTO symbol tables is not formalized.
13749 So this code could need changing in the future. */
13750
015dc7e1 13751static bool
0f03783c
NC
13752display_lto_symtab (Filedata * filedata,
13753 Elf_Internal_Shdr * section)
13754{
13755 if (section->sh_size == 0)
13756 {
ca0e11aa
NC
13757 if (filedata->is_separate)
13758 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13759 printable_section_name (filedata, section),
13760 filedata->file_name);
13761 else
13762 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13763 printable_section_name (filedata, section));
047c3dbf 13764
015dc7e1 13765 return true;
0f03783c
NC
13766 }
13767
13768 if (section->sh_size > filedata->file_size)
13769 {
26c527e6 13770 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
0f03783c 13771 printable_section_name (filedata, section),
26c527e6 13772 section->sh_size);
015dc7e1 13773 return false;
0f03783c
NC
13774 }
13775
13776 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13777 section->sh_size, 1, _("LTO symbols"));
13778 if (alloced_data == NULL)
015dc7e1 13779 return false;
0f03783c
NC
13780
13781 /* Look for extended data for the symbol table. */
13782 Elf_Internal_Shdr * ext;
13783 void * ext_data_orig = NULL;
13784 char * ext_data = NULL;
13785 char * ext_data_end = NULL;
13786 char * ext_name = NULL;
13787
13788 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13789 (section_name (filedata, section)
13790 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13791 && ext_name != NULL /* Paranoia. */
13792 && (ext = find_section (filedata, ext_name)) != NULL)
13793 {
13794 if (ext->sh_size < 3)
13795 error (_("LTO Symbol extension table '%s' is empty!\n"),
13796 printable_section_name (filedata, ext));
13797 else
13798 {
13799 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13800 ext->sh_size, 1,
13801 _("LTO ext symbol data"));
13802 if (ext_data != NULL)
13803 {
13804 ext_data_end = ext_data + ext->sh_size;
13805 if (* ext_data++ != 1)
13806 error (_("Unexpected version number in symbol extension table\n"));
13807 }
13808 }
13809 }
b9e920ec 13810
0f03783c
NC
13811 const unsigned char * data = (const unsigned char *) alloced_data;
13812 const unsigned char * end = data + section->sh_size;
13813
ca0e11aa
NC
13814 if (filedata->is_separate)
13815 printf (_("\nIn linked file '%s': "), filedata->file_name);
13816 else
13817 printf ("\n");
13818
0f03783c
NC
13819 if (ext_data_orig != NULL)
13820 {
13821 if (do_wide)
ca0e11aa 13822 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13823 printable_section_name (filedata, section),
13824 printable_section_name (filedata, ext));
13825 else
13826 {
ca0e11aa 13827 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13828 printable_section_name (filedata, section));
13829 printf (_(" and extension table '%s' contain:\n"),
13830 printable_section_name (filedata, ext));
13831 }
13832 }
13833 else
ca0e11aa 13834 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13835 printable_section_name (filedata, section));
b9e920ec 13836
0f03783c 13837 /* FIXME: Add a wide version. */
b9e920ec 13838 if (ext_data_orig != NULL)
0f03783c
NC
13839 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13840 else
13841 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13842
13843 /* FIXME: We do not handle style prefixes. */
13844
13845 while (data < end)
13846 {
13847 const unsigned char * sym_name = data;
13848 data += strnlen ((const char *) sym_name, end - data) + 1;
13849 if (data >= end)
13850 goto fail;
13851
13852 const unsigned char * comdat_key = data;
13853 data += strnlen ((const char *) comdat_key, end - data) + 1;
13854 if (data >= end)
13855 goto fail;
13856
13857 if (data + 2 + 8 + 4 > end)
13858 goto fail;
13859
13860 unsigned int kind = *data++;
13861 unsigned int visibility = *data++;
13862
928c411d 13863 uint64_t size = byte_get (data, 8);
0f03783c
NC
13864 data += 8;
13865
928c411d 13866 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13867 data += 4;
13868
13869 if (ext_data != NULL)
13870 {
13871 if (ext_data < (ext_data_end - 1))
13872 {
13873 unsigned int sym_type = * ext_data ++;
13874 unsigned int sec_kind = * ext_data ++;
13875
31e5a3a3 13876 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
13877 * comdat_key == 0 ? "-" : (char *) comdat_key,
13878 get_lto_kind (kind),
13879 get_lto_visibility (visibility),
31e5a3a3
AM
13880 size,
13881 slot,
0f03783c 13882 get_lto_sym_type (sym_type),
31e5a3a3 13883 sec_kind);
0f03783c
NC
13884 print_symbol (6, (const char *) sym_name);
13885 }
13886 else
13887 {
13888 error (_("Ran out of LTO symbol extension data\n"));
13889 ext_data = NULL;
13890 /* FIXME: return FAIL result ? */
13891 }
13892 }
13893 else
13894 {
31e5a3a3 13895 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
13896 * comdat_key == 0 ? "-" : (char *) comdat_key,
13897 get_lto_kind (kind),
13898 get_lto_visibility (visibility),
31e5a3a3
AM
13899 size,
13900 slot);
0f03783c
NC
13901 print_symbol (21, (const char *) sym_name);
13902 }
13903 putchar ('\n');
13904 }
13905
13906 if (ext_data != NULL && ext_data < ext_data_end)
13907 {
13908 error (_("Data remains in the LTO symbol extension table\n"));
13909 goto fail;
13910 }
13911
13912 free (alloced_data);
13913 free (ext_data_orig);
13914 free (ext_name);
015dc7e1 13915 return true;
b9e920ec 13916
0f03783c
NC
13917 fail:
13918 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13919 free (alloced_data);
13920 free (ext_data_orig);
13921 free (ext_name);
015dc7e1 13922 return false;
0f03783c
NC
13923}
13924
13925/* Display LTO symbol tables. */
13926
015dc7e1 13927static bool
0f03783c
NC
13928process_lto_symbol_tables (Filedata * filedata)
13929{
13930 Elf_Internal_Shdr * section;
13931 unsigned int i;
015dc7e1 13932 bool res = true;
0f03783c
NC
13933
13934 if (!do_lto_syms)
015dc7e1 13935 return true;
0f03783c
NC
13936
13937 if (filedata->section_headers == NULL)
015dc7e1 13938 return true;
0f03783c
NC
13939
13940 for (i = 0, section = filedata->section_headers;
13941 i < filedata->file_header.e_shnum;
13942 i++, section++)
84714f86
AM
13943 if (section_name_valid (filedata, section)
13944 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13945 res &= display_lto_symtab (filedata, section);
13946
b9e920ec 13947 return res;
0f03783c
NC
13948}
13949
10ca4b04 13950/* Dump the symbol table. */
0f03783c 13951
015dc7e1 13952static bool
10ca4b04
L
13953process_symbol_table (Filedata * filedata)
13954{
13955 Elf_Internal_Shdr * section;
f16a9783 13956
10ca4b04 13957 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13958 return true;
6bd1a22c 13959
978c4450 13960 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13961 && do_syms
13962 && do_using_dynamic
978c4450
AM
13963 && filedata->dynamic_strings != NULL
13964 && filedata->dynamic_symbols != NULL)
6bd1a22c 13965 {
26c527e6 13966 uint64_t si;
6bd1a22c 13967
ca0e11aa
NC
13968 if (filedata->is_separate)
13969 {
26c527e6
AM
13970 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
13971 " contains %" PRIu64 " entry:\n",
13972 "\nIn linked file '%s' the dynamic symbol table"
13973 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13974 filedata->num_dynamic_syms),
13975 filedata->file_name,
13976 filedata->num_dynamic_syms);
13977 }
13978 else
13979 {
26c527e6
AM
13980 printf (ngettext ("\nSymbol table for image contains %" PRIu64
13981 " entry:\n",
13982 "\nSymbol table for image contains %" PRIu64
13983 " entries:\n",
ca0e11aa
NC
13984 filedata->num_dynamic_syms),
13985 filedata->num_dynamic_syms);
13986 }
10ca4b04
L
13987 if (is_32bit_elf)
13988 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13989 else
13990 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13991
978c4450
AM
13992 for (si = 0; si < filedata->num_dynamic_syms; si++)
13993 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13994 filedata->dynamic_strings,
13995 filedata->dynamic_strings_length);
252b5132 13996 }
8b73c356 13997 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13998 && filedata->section_headers != NULL)
252b5132 13999 {
b34976b6 14000 unsigned int i;
252b5132 14001
dda8d76d
NC
14002 for (i = 0, section = filedata->section_headers;
14003 i < filedata->file_header.e_shnum;
252b5132
RH
14004 i++, section++)
14005 {
2cf0635d 14006 char * strtab = NULL;
26c527e6 14007 uint64_t strtab_size = 0;
2cf0635d 14008 Elf_Internal_Sym * symtab;
26c527e6 14009 uint64_t si, num_syms;
252b5132 14010
2c610e4b
L
14011 if ((section->sh_type != SHT_SYMTAB
14012 && section->sh_type != SHT_DYNSYM)
14013 || (!do_syms
14014 && section->sh_type == SHT_SYMTAB))
252b5132
RH
14015 continue;
14016
dd24e3da
NC
14017 if (section->sh_entsize == 0)
14018 {
14019 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 14020 printable_section_name (filedata, section));
dd24e3da
NC
14021 continue;
14022 }
14023
d3a49aa8 14024 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
14025
14026 if (filedata->is_separate)
26c527e6
AM
14027 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
14028 " contains %" PRIu64 " entry:\n",
14029 "\nIn linked file '%s' symbol section '%s'"
14030 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
14031 num_syms),
14032 filedata->file_name,
14033 printable_section_name (filedata, section),
14034 num_syms);
14035 else
26c527e6
AM
14036 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
14037 " entry:\n",
14038 "\nSymbol table '%s' contains %" PRIu64
14039 " entries:\n",
ca0e11aa
NC
14040 num_syms),
14041 printable_section_name (filedata, section),
14042 num_syms);
dd24e3da 14043
f7a99963 14044 if (is_32bit_elf)
ca47b30c 14045 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 14046 else
ca47b30c 14047 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 14048
4de91c10 14049 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
14050 if (symtab == NULL)
14051 continue;
14052
dda8d76d 14053 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 14054 {
dda8d76d
NC
14055 strtab = filedata->string_table;
14056 strtab_size = filedata->string_table_length;
c256ffe7 14057 }
dda8d76d 14058 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 14059 {
2cf0635d 14060 Elf_Internal_Shdr * string_sec;
252b5132 14061
dda8d76d 14062 string_sec = filedata->section_headers + section->sh_link;
252b5132 14063
dda8d76d 14064 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
14065 1, string_sec->sh_size,
14066 _("string table"));
c256ffe7 14067 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
14068 }
14069
10ca4b04
L
14070 for (si = 0; si < num_syms; si++)
14071 print_dynamic_symbol (filedata, si, symtab, section,
14072 strtab, strtab_size);
252b5132
RH
14073
14074 free (symtab);
dda8d76d 14075 if (strtab != filedata->string_table)
252b5132
RH
14076 free (strtab);
14077 }
14078 }
14079 else if (do_syms)
14080 printf
14081 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
14082
978c4450 14083 if (do_histogram && filedata->buckets != NULL)
252b5132 14084 {
26c527e6
AM
14085 uint64_t *lengths;
14086 uint64_t *counts;
14087 uint64_t hn;
625d49fc 14088 uint64_t si;
26c527e6
AM
14089 uint64_t maxlength = 0;
14090 uint64_t nzero_counts = 0;
14091 uint64_t nsyms = 0;
6bd6a03d 14092 char *visited;
252b5132 14093
d3a49aa8 14094 printf (ngettext ("\nHistogram for bucket list length "
26c527e6 14095 "(total of %" PRIu64 " bucket):\n",
d3a49aa8 14096 "\nHistogram for bucket list length "
26c527e6
AM
14097 "(total of %" PRIu64 " buckets):\n",
14098 filedata->nbuckets),
14099 filedata->nbuckets);
252b5132 14100
26c527e6 14101 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
252b5132
RH
14102 if (lengths == NULL)
14103 {
8b73c356 14104 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 14105 goto err_out;
252b5132 14106 }
978c4450
AM
14107 visited = xcmalloc (filedata->nchains, 1);
14108 memset (visited, 0, filedata->nchains);
8b73c356
NC
14109
14110 printf (_(" Length Number %% of total Coverage\n"));
978c4450 14111 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 14112 {
978c4450 14113 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 14114 {
b34976b6 14115 ++nsyms;
252b5132 14116 if (maxlength < ++lengths[hn])
b34976b6 14117 ++maxlength;
978c4450 14118 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
14119 {
14120 error (_("histogram chain is corrupt\n"));
14121 break;
14122 }
14123 visited[si] = 1;
252b5132
RH
14124 }
14125 }
6bd6a03d 14126 free (visited);
252b5132 14127
26c527e6 14128 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
14129 if (counts == NULL)
14130 {
b2e951ec 14131 free (lengths);
8b73c356 14132 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 14133 goto err_out;
252b5132
RH
14134 }
14135
978c4450 14136 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 14137 ++counts[lengths[hn]];
252b5132 14138
978c4450 14139 if (filedata->nbuckets > 0)
252b5132 14140 {
26c527e6
AM
14141 uint64_t i;
14142 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14143 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 14144 for (i = 1; i <= maxlength; ++i)
103f02d3 14145 {
66543521 14146 nzero_counts += counts[i] * i;
26c527e6 14147 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14148 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
14149 (nzero_counts * 100.0) / nsyms);
14150 }
252b5132
RH
14151 }
14152
14153 free (counts);
14154 free (lengths);
14155 }
14156
978c4450
AM
14157 free (filedata->buckets);
14158 filedata->buckets = NULL;
14159 filedata->nbuckets = 0;
14160 free (filedata->chains);
14161 filedata->chains = NULL;
252b5132 14162
978c4450 14163 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 14164 {
26c527e6
AM
14165 uint64_t *lengths;
14166 uint64_t *counts;
14167 uint64_t hn;
14168 uint64_t maxlength = 0;
14169 uint64_t nzero_counts = 0;
14170 uint64_t nsyms = 0;
fdc90cb4 14171
f16a9783 14172 printf (ngettext ("\nHistogram for `%s' bucket list length "
26c527e6 14173 "(total of %" PRIu64 " bucket):\n",
f16a9783 14174 "\nHistogram for `%s' bucket list length "
26c527e6
AM
14175 "(total of %" PRIu64 " buckets):\n",
14176 filedata->ngnubuckets),
978c4450 14177 GNU_HASH_SECTION_NAME (filedata),
26c527e6 14178 filedata->ngnubuckets);
8b73c356 14179
26c527e6 14180 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
14181 if (lengths == NULL)
14182 {
8b73c356 14183 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 14184 goto err_out;
fdc90cb4
JJ
14185 }
14186
fdc90cb4
JJ
14187 printf (_(" Length Number %% of total Coverage\n"));
14188
978c4450
AM
14189 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14190 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 14191 {
625d49fc 14192 uint64_t off, length = 1;
fdc90cb4 14193
978c4450 14194 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 14195 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
14196 off < filedata->ngnuchains
14197 && (filedata->gnuchains[off] & 1) == 0;
071436c6 14198 ++off)
fdc90cb4
JJ
14199 ++length;
14200 lengths[hn] = length;
14201 if (length > maxlength)
14202 maxlength = length;
14203 nsyms += length;
14204 }
14205
26c527e6 14206 counts = calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
14207 if (counts == NULL)
14208 {
b2e951ec 14209 free (lengths);
8b73c356 14210 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 14211 goto err_out;
fdc90cb4
JJ
14212 }
14213
978c4450 14214 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
14215 ++counts[lengths[hn]];
14216
978c4450 14217 if (filedata->ngnubuckets > 0)
fdc90cb4 14218 {
26c527e6
AM
14219 uint64_t j;
14220 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14221 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
14222 for (j = 1; j <= maxlength; ++j)
14223 {
14224 nzero_counts += counts[j] * j;
26c527e6 14225 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14226 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
14227 (nzero_counts * 100.0) / nsyms);
14228 }
14229 }
14230
14231 free (counts);
14232 free (lengths);
fdc90cb4 14233 }
978c4450
AM
14234 free (filedata->gnubuckets);
14235 filedata->gnubuckets = NULL;
14236 filedata->ngnubuckets = 0;
14237 free (filedata->gnuchains);
14238 filedata->gnuchains = NULL;
14239 filedata->ngnuchains = 0;
14240 free (filedata->mipsxlat);
14241 filedata->mipsxlat = NULL;
015dc7e1 14242 return true;
fd486f32
AM
14243
14244 err_out:
978c4450
AM
14245 free (filedata->gnubuckets);
14246 filedata->gnubuckets = NULL;
14247 filedata->ngnubuckets = 0;
14248 free (filedata->gnuchains);
14249 filedata->gnuchains = NULL;
14250 filedata->ngnuchains = 0;
14251 free (filedata->mipsxlat);
14252 filedata->mipsxlat = NULL;
14253 free (filedata->buckets);
14254 filedata->buckets = NULL;
14255 filedata->nbuckets = 0;
14256 free (filedata->chains);
14257 filedata->chains = NULL;
015dc7e1 14258 return false;
252b5132
RH
14259}
14260
015dc7e1 14261static bool
ca0e11aa 14262process_syminfo (Filedata * filedata)
252b5132 14263{
b4c96d0d 14264 unsigned int i;
252b5132 14265
978c4450 14266 if (filedata->dynamic_syminfo == NULL
252b5132
RH
14267 || !do_dynamic)
14268 /* No syminfo, this is ok. */
015dc7e1 14269 return true;
252b5132
RH
14270
14271 /* There better should be a dynamic symbol section. */
978c4450 14272 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 14273 return false;
252b5132 14274
ca0e11aa 14275 if (filedata->is_separate)
26c527e6
AM
14276 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
14277 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
ca0e11aa
NC
14278 filedata->dynamic_syminfo_nent),
14279 filedata->file_name,
14280 filedata->dynamic_syminfo_offset,
14281 filedata->dynamic_syminfo_nent);
14282 else
26c527e6
AM
14283 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
14284 " contains %d entry:\n",
14285 "\nDynamic info segment at offset %#" PRIx64
14286 " contains %d entries:\n",
978c4450 14287 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
14288 filedata->dynamic_syminfo_offset,
14289 filedata->dynamic_syminfo_nent);
252b5132
RH
14290
14291 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 14292 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 14293 {
978c4450 14294 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 14295
31104126 14296 printf ("%4d: ", i);
978c4450 14297 if (i >= filedata->num_dynamic_syms)
4082ef84 14298 printf (_("<corrupt index>"));
84714f86
AM
14299 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
14300 print_symbol (30, get_dynamic_name (filedata,
978c4450 14301 filedata->dynamic_symbols[i].st_name));
d79b3d50 14302 else
978c4450 14303 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 14304 putchar (' ');
252b5132 14305
978c4450 14306 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
14307 {
14308 case SYMINFO_BT_SELF:
14309 fputs ("SELF ", stdout);
14310 break;
14311 case SYMINFO_BT_PARENT:
14312 fputs ("PARENT ", stdout);
14313 break;
14314 default:
978c4450
AM
14315 if (filedata->dynamic_syminfo[i].si_boundto > 0
14316 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 14317 && valid_dynamic_name (filedata,
978c4450 14318 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 14319 {
84714f86 14320 print_symbol (10, get_dynamic_name (filedata,
978c4450 14321 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
14322 putchar (' ' );
14323 }
252b5132 14324 else
978c4450 14325 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
14326 break;
14327 }
14328
14329 if (flags & SYMINFO_FLG_DIRECT)
14330 printf (" DIRECT");
14331 if (flags & SYMINFO_FLG_PASSTHRU)
14332 printf (" PASSTHRU");
14333 if (flags & SYMINFO_FLG_COPY)
14334 printf (" COPY");
14335 if (flags & SYMINFO_FLG_LAZYLOAD)
14336 printf (" LAZYLOAD");
14337
14338 puts ("");
14339 }
14340
015dc7e1 14341 return true;
252b5132
RH
14342}
14343
75802ccb
CE
14344/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
14345 is contained by the region START .. END. The types of ADDR, START
14346 and END should all be the same. Note both ADDR + NELEM and END
14347 point to just beyond the end of the regions that are being tested. */
14348#define IN_RANGE(START,END,ADDR,NELEM) \
14349 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 14350
cf13d699
NC
14351/* Check to see if the given reloc needs to be handled in a target specific
14352 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
14353 FALSE.
14354
14355 If called with reloc == NULL, then this is a signal that reloc processing
14356 for the current section has finished, and any saved state should be
14357 discarded. */
09c11c86 14358
015dc7e1 14359static bool
26c527e6
AM
14360target_specific_reloc_handling (Filedata *filedata,
14361 Elf_Internal_Rela *reloc,
14362 unsigned char *start,
14363 unsigned char *end,
14364 Elf_Internal_Sym *symtab,
14365 uint64_t num_syms)
252b5132 14366{
f84ce13b 14367 unsigned int reloc_type = 0;
26c527e6 14368 uint64_t sym_index = 0;
f84ce13b
NC
14369
14370 if (reloc)
14371 {
dda8d76d 14372 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
14373 sym_index = get_reloc_symindex (reloc->r_info);
14374 }
252b5132 14375
dda8d76d 14376 switch (filedata->file_header.e_machine)
252b5132 14377 {
76244462 14378 case EM_LOONGARCH:
14379 {
14380 switch (reloc_type)
14381 {
14382 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
14383 at assembly time. */
14384 case 107: /* R_LARCH_ADD_ULEB128. */
14385 case 108: /* R_LARCH_SUB_ULEB128. */
14386 {
d3f34076 14387 uint64_t value = 0;
76244462 14388 unsigned int reloc_size = 0;
14389 int leb_ret = 0;
14390
89c70cd3
AM
14391 if (reloc->r_offset < (size_t) (end - start))
14392 value = read_leb128 (start + reloc->r_offset, end, false,
14393 &reloc_size, &leb_ret);
76244462 14394 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14395 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
14396 "ULEB128 value\n"),
14397 (long) reloc->r_offset);
14398
74a965d8
AM
14399 else if (sym_index >= num_syms)
14400 error (_("%s reloc contains invalid symbol index "
14401 "%" PRIu64 "\n"),
14402 (reloc_type == 107
14403 ? "R_LARCH_ADD_ULEB128"
14404 : "R_LARCH_SUB_ULEB128"),
14405 sym_index);
14406 else
76244462 14407 {
74a965d8
AM
14408 if (reloc_type == 107)
14409 value += reloc->r_addend + symtab[sym_index].st_value;
14410 else
14411 value -= reloc->r_addend + symtab[sym_index].st_value;
14412
14413 /* Write uleb128 value to p. */
14414 bfd_byte *p = start + reloc->r_offset;
14415 do
14416 {
14417 bfd_byte c = value & 0x7f;
14418 value >>= 7;
14419 if (--reloc_size != 0)
14420 c |= 0x80;
14421 *p++ = c;
14422 }
14423 while (reloc_size);
76244462 14424 }
76244462 14425
14426 return true;
14427 }
14428 }
14429 break;
14430 }
14431
13761a11
NC
14432 case EM_MSP430:
14433 case EM_MSP430_OLD:
14434 {
14435 static Elf_Internal_Sym * saved_sym = NULL;
14436
f84ce13b
NC
14437 if (reloc == NULL)
14438 {
14439 saved_sym = NULL;
015dc7e1 14440 return true;
f84ce13b
NC
14441 }
14442
13761a11
NC
14443 switch (reloc_type)
14444 {
14445 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 14446 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 14447 if (uses_msp430x_relocs (filedata))
13761a11 14448 break;
1a0670f3 14449 /* Fall through. */
13761a11 14450 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 14451 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
14452 /* PR 21139. */
14453 if (sym_index >= num_syms)
74a965d8
AM
14454 error (_("%s reloc contains invalid symbol index "
14455 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
f84ce13b
NC
14456 else
14457 saved_sym = symtab + sym_index;
015dc7e1 14458 return true;
13761a11
NC
14459
14460 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14461 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14462 goto handle_sym_diff;
0b4362b0 14463
13761a11
NC
14464 case 5: /* R_MSP430_16_BYTE */
14465 case 9: /* R_MSP430_8 */
7d81bc93 14466 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 14467 if (uses_msp430x_relocs (filedata))
13761a11
NC
14468 break;
14469 goto handle_sym_diff;
14470
14471 case 2: /* R_MSP430_ABS16 */
14472 case 15: /* R_MSP430X_ABS16 */
7d81bc93 14473 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 14474 if (! uses_msp430x_relocs (filedata))
13761a11
NC
14475 break;
14476 goto handle_sym_diff;
0b4362b0 14477
13761a11
NC
14478 handle_sym_diff:
14479 if (saved_sym != NULL)
14480 {
625d49fc 14481 uint64_t value;
5a805384 14482 unsigned int reloc_size = 0;
7d81bc93
JL
14483 int leb_ret = 0;
14484 switch (reloc_type)
14485 {
14486 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14487 reloc_size = 4;
14488 break;
14489 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14490 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14491 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14492 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14493 &reloc_size, &leb_ret);
7d81bc93
JL
14494 break;
14495 default:
14496 reloc_size = 2;
14497 break;
14498 }
13761a11 14499
5a805384 14500 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
14501 error (_("MSP430 ULEB128 field at %#" PRIx64
14502 " contains invalid ULEB128 value\n"),
14503 reloc->r_offset);
7d81bc93 14504 else if (sym_index >= num_syms)
74a965d8
AM
14505 error (_("%s reloc contains invalid symbol index "
14506 "%" PRIu64 "\n"), "MSP430", sym_index);
03f7786e 14507 else
f84ce13b
NC
14508 {
14509 value = reloc->r_addend + (symtab[sym_index].st_value
14510 - saved_sym->st_value);
14511
b32e566b 14512 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14513 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14514 else
14515 /* PR 21137 */
26c527e6
AM
14516 error (_("MSP430 sym diff reloc contains invalid offset: "
14517 "%#" PRIx64 "\n"),
14518 reloc->r_offset);
f84ce13b 14519 }
13761a11
NC
14520
14521 saved_sym = NULL;
015dc7e1 14522 return true;
13761a11
NC
14523 }
14524 break;
14525
14526 default:
14527 if (saved_sym != NULL)
071436c6 14528 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14529 break;
14530 }
14531 break;
14532 }
14533
cf13d699
NC
14534 case EM_MN10300:
14535 case EM_CYGNUS_MN10300:
14536 {
14537 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14538
f84ce13b
NC
14539 if (reloc == NULL)
14540 {
14541 saved_sym = NULL;
015dc7e1 14542 return true;
f84ce13b
NC
14543 }
14544
cf13d699
NC
14545 switch (reloc_type)
14546 {
14547 case 34: /* R_MN10300_ALIGN */
015dc7e1 14548 return true;
cf13d699 14549 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 14550 if (sym_index >= num_syms)
74a965d8
AM
14551 error (_("%s reloc contains invalid symbol index "
14552 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
f84ce13b
NC
14553 else
14554 saved_sym = symtab + sym_index;
015dc7e1 14555 return true;
f84ce13b 14556
cf13d699
NC
14557 case 1: /* R_MN10300_32 */
14558 case 2: /* R_MN10300_16 */
14559 if (saved_sym != NULL)
14560 {
03f7786e 14561 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14562 uint64_t value;
252b5132 14563
f84ce13b 14564 if (sym_index >= num_syms)
74a965d8
AM
14565 error (_("%s reloc contains invalid symbol index "
14566 "%" PRIu64 "\n"), "MN10300", sym_index);
03f7786e 14567 else
f84ce13b
NC
14568 {
14569 value = reloc->r_addend + (symtab[sym_index].st_value
14570 - saved_sym->st_value);
14571
b32e566b 14572 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14573 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 14574 else
26c527e6
AM
14575 error (_("MN10300 sym diff reloc contains invalid offset:"
14576 " %#" PRIx64 "\n"),
14577 reloc->r_offset);
f84ce13b 14578 }
252b5132 14579
cf13d699 14580 saved_sym = NULL;
015dc7e1 14581 return true;
cf13d699
NC
14582 }
14583 break;
14584 default:
14585 if (saved_sym != NULL)
071436c6 14586 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14587 break;
14588 }
14589 break;
14590 }
6ff71e76
NC
14591
14592 case EM_RL78:
14593 {
625d49fc
AM
14594 static uint64_t saved_sym1 = 0;
14595 static uint64_t saved_sym2 = 0;
14596 static uint64_t value;
6ff71e76 14597
f84ce13b
NC
14598 if (reloc == NULL)
14599 {
14600 saved_sym1 = saved_sym2 = 0;
015dc7e1 14601 return true;
f84ce13b
NC
14602 }
14603
6ff71e76
NC
14604 switch (reloc_type)
14605 {
14606 case 0x80: /* R_RL78_SYM. */
14607 saved_sym1 = saved_sym2;
f84ce13b 14608 if (sym_index >= num_syms)
74a965d8
AM
14609 error (_("%s reloc contains invalid symbol index "
14610 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
f84ce13b
NC
14611 else
14612 {
14613 saved_sym2 = symtab[sym_index].st_value;
14614 saved_sym2 += reloc->r_addend;
14615 }
015dc7e1 14616 return true;
6ff71e76
NC
14617
14618 case 0x83: /* R_RL78_OPsub. */
14619 value = saved_sym1 - saved_sym2;
14620 saved_sym2 = saved_sym1 = 0;
015dc7e1 14621 return true;
6ff71e76
NC
14622 break;
14623
14624 case 0x41: /* R_RL78_ABS32. */
b32e566b 14625 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14626 byte_put (start + reloc->r_offset, value, 4);
b32e566b 14627 else
26c527e6
AM
14628 error (_("RL78 sym diff reloc contains invalid offset: "
14629 "%#" PRIx64 "\n"),
14630 reloc->r_offset);
6ff71e76 14631 value = 0;
015dc7e1 14632 return true;
6ff71e76
NC
14633
14634 case 0x43: /* R_RL78_ABS16. */
b32e566b 14635 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14636 byte_put (start + reloc->r_offset, value, 2);
b32e566b 14637 else
26c527e6
AM
14638 error (_("RL78 sym diff reloc contains invalid offset: "
14639 "%#" PRIx64 "\n"),
14640 reloc->r_offset);
6ff71e76 14641 value = 0;
015dc7e1 14642 return true;
6ff71e76
NC
14643
14644 default:
14645 break;
14646 }
14647 break;
14648 }
252b5132
RH
14649 }
14650
015dc7e1 14651 return false;
252b5132
RH
14652}
14653
aca88567
NC
14654/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14655 DWARF debug sections. This is a target specific test. Note - we do not
14656 go through the whole including-target-headers-multiple-times route, (as
14657 we have already done with <elf/h8.h>) because this would become very
14658 messy and even then this function would have to contain target specific
14659 information (the names of the relocs instead of their numeric values).
14660 FIXME: This is not the correct way to solve this problem. The proper way
14661 is to have target specific reloc sizing and typing functions created by
14662 the reloc-macros.h header, in the same way that it already creates the
14663 reloc naming functions. */
14664
015dc7e1 14665static bool
dda8d76d 14666is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14667{
d347c9df 14668 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14669 switch (filedata->file_header.e_machine)
aca88567 14670 {
41e92641 14671 case EM_386:
22abe556 14672 case EM_IAMCU:
41e92641 14673 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14674 case EM_68K:
14675 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14676 case EM_860:
14677 return reloc_type == 1; /* R_860_32. */
14678 case EM_960:
14679 return reloc_type == 2; /* R_960_32. */
a06ea964 14680 case EM_AARCH64:
9282b95a
JW
14681 return (reloc_type == 258
14682 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14683 case EM_BPF:
14684 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14685 case EM_ADAPTEVA_EPIPHANY:
14686 return reloc_type == 3;
aca88567 14687 case EM_ALPHA:
137b6b5f 14688 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14689 case EM_ARC:
14690 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14691 case EM_ARC_COMPACT:
14692 case EM_ARC_COMPACT2:
b5c37946
SJ
14693 case EM_ARC_COMPACT3:
14694 case EM_ARC_COMPACT3_64:
886a2506 14695 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14696 case EM_ARM:
14697 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14698 case EM_AVR_OLD:
aca88567
NC
14699 case EM_AVR:
14700 return reloc_type == 1;
14701 case EM_BLACKFIN:
14702 return reloc_type == 0x12; /* R_byte4_data. */
14703 case EM_CRIS:
14704 return reloc_type == 3; /* R_CRIS_32. */
14705 case EM_CR16:
14706 return reloc_type == 3; /* R_CR16_NUM32. */
14707 case EM_CRX:
14708 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14709 case EM_CSKY:
14710 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14711 case EM_CYGNUS_FRV:
14712 return reloc_type == 1;
41e92641
NC
14713 case EM_CYGNUS_D10V:
14714 case EM_D10V:
14715 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14716 case EM_CYGNUS_D30V:
14717 case EM_D30V:
14718 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14719 case EM_DLX:
14720 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14721 case EM_CYGNUS_FR30:
14722 case EM_FR30:
14723 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14724 case EM_FT32:
14725 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14726 case EM_H8S:
14727 case EM_H8_300:
14728 case EM_H8_300H:
14729 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14730 case EM_IA_64:
262cdac7
AM
14731 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14732 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14733 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14734 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14735 case EM_IP2K_OLD:
14736 case EM_IP2K:
14737 return reloc_type == 2; /* R_IP2K_32. */
14738 case EM_IQ2000:
14739 return reloc_type == 2; /* R_IQ2000_32. */
6e712424
PI
14740 case EM_KVX:
14741 return reloc_type == 2; /* R_KVX_32. */
84e94c90
NC
14742 case EM_LATTICEMICO32:
14743 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14744 case EM_LOONGARCH:
14745 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14746 case EM_M32C_OLD:
aca88567
NC
14747 case EM_M32C:
14748 return reloc_type == 3; /* R_M32C_32. */
14749 case EM_M32R:
14750 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14751 case EM_68HC11:
14752 case EM_68HC12:
14753 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14754 case EM_S12Z:
2849d19f
JD
14755 return reloc_type == 7 || /* R_S12Z_EXT32 */
14756 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14757 case EM_MCORE:
14758 return reloc_type == 1; /* R_MCORE_ADDR32. */
14759 case EM_CYGNUS_MEP:
14760 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14761 case EM_METAG:
14762 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14763 case EM_MICROBLAZE:
14764 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14765 case EM_MIPS:
14766 return reloc_type == 2; /* R_MIPS_32. */
14767 case EM_MMIX:
14768 return reloc_type == 4; /* R_MMIX_32. */
14769 case EM_CYGNUS_MN10200:
14770 case EM_MN10200:
14771 return reloc_type == 1; /* R_MN10200_32. */
14772 case EM_CYGNUS_MN10300:
14773 case EM_MN10300:
14774 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14775 case EM_MOXIE:
14776 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14777 case EM_MSP430_OLD:
14778 case EM_MSP430:
13761a11 14779 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14780 case EM_MT:
14781 return reloc_type == 2; /* R_MT_32. */
35c08157 14782 case EM_NDS32:
81c5e376 14783 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14784 case EM_ALTERA_NIOS2:
36591ba1 14785 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14786 case EM_NIOS32:
14787 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14788 case EM_OR1K:
14789 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14790 case EM_PARISC:
9abca702 14791 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14792 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14793 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14794 case EM_PJ:
14795 case EM_PJ_OLD:
14796 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14797 case EM_PPC64:
14798 return reloc_type == 1; /* R_PPC64_ADDR32. */
14799 case EM_PPC:
14800 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14801 case EM_TI_PRU:
14802 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14803 case EM_RISCV:
14804 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14805 case EM_RL78:
14806 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14807 case EM_RX:
14808 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14809 case EM_S370:
14810 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14811 case EM_S390_OLD:
14812 case EM_S390:
14813 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14814 case EM_SCORE:
14815 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14816 case EM_SH:
14817 return reloc_type == 1; /* R_SH_DIR32. */
14818 case EM_SPARC32PLUS:
14819 case EM_SPARCV9:
14820 case EM_SPARC:
14821 return reloc_type == 3 /* R_SPARC_32. */
14822 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14823 case EM_SPU:
14824 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14825 case EM_TI_C6000:
14826 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14827 case EM_TILEGX:
14828 return reloc_type == 2; /* R_TILEGX_32. */
14829 case EM_TILEPRO:
14830 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14831 case EM_CYGNUS_V850:
14832 case EM_V850:
14833 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14834 case EM_V800:
14835 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14836 case EM_VAX:
14837 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14838 case EM_VISIUM:
14839 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14840 case EM_WEBASSEMBLY:
14841 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14842 case EM_X86_64:
8a9036a4 14843 case EM_L1OM:
7a9068fe 14844 case EM_K1OM:
aca88567 14845 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14846 case EM_XGATE:
14847 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14848 case EM_XSTORMY16:
14849 return reloc_type == 1; /* R_XSTROMY16_32. */
14850 case EM_XTENSA_OLD:
14851 case EM_XTENSA:
14852 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14853 case EM_Z80:
14854 return reloc_type == 6; /* R_Z80_32. */
aca88567 14855 default:
bee0ee85
NC
14856 {
14857 static unsigned int prev_warn = 0;
14858
14859 /* Avoid repeating the same warning multiple times. */
dda8d76d 14860 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14861 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14862 filedata->file_header.e_machine);
14863 prev_warn = filedata->file_header.e_machine;
015dc7e1 14864 return false;
bee0ee85 14865 }
aca88567
NC
14866 }
14867}
14868
14869/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14870 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14871
015dc7e1 14872static bool
dda8d76d 14873is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14874{
dda8d76d 14875 switch (filedata->file_header.e_machine)
d347c9df 14876 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14877 {
41e92641 14878 case EM_386:
22abe556 14879 case EM_IAMCU:
3e0873ac 14880 return reloc_type == 2; /* R_386_PC32. */
aca88567 14881 case EM_68K:
3e0873ac 14882 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14883 case EM_AARCH64:
14884 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14885 case EM_ADAPTEVA_EPIPHANY:
14886 return reloc_type == 6;
aca88567
NC
14887 case EM_ALPHA:
14888 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14889 case EM_ARC_COMPACT:
14890 case EM_ARC_COMPACT2:
b5c37946
SJ
14891 case EM_ARC_COMPACT3:
14892 case EM_ARC_COMPACT3_64:
726c18e1 14893 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14894 case EM_ARM:
3e0873ac 14895 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14896 case EM_AVR_OLD:
14897 case EM_AVR:
14898 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14899 case EM_LOONGARCH:
14900 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14901 case EM_MICROBLAZE:
14902 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14903 case EM_OR1K:
14904 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14905 case EM_PARISC:
85acf597 14906 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14907 case EM_PPC:
14908 return reloc_type == 26; /* R_PPC_REL32. */
14909 case EM_PPC64:
3e0873ac 14910 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14911 case EM_RISCV:
14912 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14913 case EM_S390_OLD:
14914 case EM_S390:
3e0873ac 14915 return reloc_type == 5; /* R_390_PC32. */
aca88567 14916 case EM_SH:
3e0873ac 14917 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14918 case EM_SPARC32PLUS:
14919 case EM_SPARCV9:
14920 case EM_SPARC:
3e0873ac 14921 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14922 case EM_SPU:
14923 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14924 case EM_TILEGX:
14925 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14926 case EM_TILEPRO:
14927 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14928 case EM_VISIUM:
14929 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14930 case EM_X86_64:
8a9036a4 14931 case EM_L1OM:
7a9068fe 14932 case EM_K1OM:
3e0873ac 14933 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14934 case EM_VAX:
14935 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14936 case EM_XTENSA_OLD:
14937 case EM_XTENSA:
14938 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
6e712424
PI
14939 case EM_KVX:
14940 return reloc_type == 7; /* R_KVX_32_PCREL */
aca88567
NC
14941 default:
14942 /* Do not abort or issue an error message here. Not all targets use
14943 pc-relative 32-bit relocs in their DWARF debug information and we
14944 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14945 more helpful warning message will be generated by apply_relocations
14946 anyway, so just return. */
015dc7e1 14947 return false;
aca88567
NC
14948 }
14949}
14950
14951/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14952 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14953
015dc7e1 14954static bool
dda8d76d 14955is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14956{
dda8d76d 14957 switch (filedata->file_header.e_machine)
aca88567 14958 {
a06ea964
NC
14959 case EM_AARCH64:
14960 return reloc_type == 257; /* R_AARCH64_ABS64. */
b5c37946
SJ
14961 case EM_ARC_COMPACT3_64:
14962 return reloc_type == 5; /* R_ARC_64. */
aca88567
NC
14963 case EM_ALPHA:
14964 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14965 case EM_IA_64:
262cdac7
AM
14966 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14967 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14968 case EM_LOONGARCH:
14969 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14970 case EM_PARISC:
14971 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14972 case EM_PPC64:
14973 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14974 case EM_RISCV:
14975 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14976 case EM_SPARC32PLUS:
14977 case EM_SPARCV9:
14978 case EM_SPARC:
714da62f
NC
14979 return reloc_type == 32 /* R_SPARC_64. */
14980 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14981 case EM_X86_64:
8a9036a4 14982 case EM_L1OM:
7a9068fe 14983 case EM_K1OM:
aca88567 14984 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14985 case EM_S390_OLD:
14986 case EM_S390:
aa137e4d
NC
14987 return reloc_type == 22; /* R_S390_64. */
14988 case EM_TILEGX:
14989 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14990 case EM_MIPS:
aa137e4d 14991 return reloc_type == 18; /* R_MIPS_64. */
6e712424
PI
14992 case EM_KVX:
14993 return reloc_type == 3; /* R_KVX_64 */
aca88567 14994 default:
015dc7e1 14995 return false;
aca88567
NC
14996 }
14997}
14998
85acf597
RH
14999/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
15000 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
15001
015dc7e1 15002static bool
dda8d76d 15003is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 15004{
dda8d76d 15005 switch (filedata->file_header.e_machine)
85acf597 15006 {
a06ea964
NC
15007 case EM_AARCH64:
15008 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 15009 case EM_ALPHA:
aa137e4d 15010 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 15011 case EM_IA_64:
262cdac7
AM
15012 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
15013 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 15014 case EM_PARISC:
aa137e4d 15015 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 15016 case EM_PPC64:
aa137e4d 15017 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
15018 case EM_SPARC32PLUS:
15019 case EM_SPARCV9:
15020 case EM_SPARC:
aa137e4d 15021 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 15022 case EM_X86_64:
8a9036a4 15023 case EM_L1OM:
7a9068fe 15024 case EM_K1OM:
aa137e4d 15025 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
15026 case EM_S390_OLD:
15027 case EM_S390:
aa137e4d
NC
15028 return reloc_type == 23; /* R_S390_PC64. */
15029 case EM_TILEGX:
15030 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 15031 default:
015dc7e1 15032 return false;
85acf597
RH
15033 }
15034}
15035
4dc3c23d
AM
15036/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15037 a 24-bit absolute RELA relocation used in DWARF debug sections. */
15038
015dc7e1 15039static bool
dda8d76d 15040is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 15041{
dda8d76d 15042 switch (filedata->file_header.e_machine)
4dc3c23d
AM
15043 {
15044 case EM_CYGNUS_MN10200:
15045 case EM_MN10200:
15046 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
15047 case EM_FT32:
15048 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
15049 case EM_Z80:
15050 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 15051 default:
015dc7e1 15052 return false;
4dc3c23d
AM
15053 }
15054}
15055
aca88567
NC
15056/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15057 a 16-bit absolute RELA relocation used in DWARF debug sections. */
15058
015dc7e1 15059static bool
dda8d76d 15060is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 15061{
d347c9df 15062 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 15063 switch (filedata->file_header.e_machine)
4b78141a 15064 {
886a2506
NC
15065 case EM_ARC:
15066 case EM_ARC_COMPACT:
15067 case EM_ARC_COMPACT2:
b5c37946
SJ
15068 case EM_ARC_COMPACT3:
15069 case EM_ARC_COMPACT3_64:
886a2506 15070 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
15071 case EM_ADAPTEVA_EPIPHANY:
15072 return reloc_type == 5;
aca88567
NC
15073 case EM_AVR_OLD:
15074 case EM_AVR:
15075 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
15076 case EM_CYGNUS_D10V:
15077 case EM_D10V:
15078 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
15079 case EM_FT32:
15080 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
15081 case EM_H8S:
15082 case EM_H8_300:
15083 case EM_H8_300H:
aca88567
NC
15084 return reloc_type == R_H8_DIR16;
15085 case EM_IP2K_OLD:
15086 case EM_IP2K:
15087 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 15088 case EM_M32C_OLD:
f4236fe4
DD
15089 case EM_M32C:
15090 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
15091 case EM_CYGNUS_MN10200:
15092 case EM_MN10200:
15093 return reloc_type == 2; /* R_MN10200_16. */
15094 case EM_CYGNUS_MN10300:
15095 case EM_MN10300:
15096 return reloc_type == 2; /* R_MN10300_16. */
6e712424
PI
15097 case EM_KVX:
15098 return reloc_type == 1; /* R_KVX_16 */
aca88567 15099 case EM_MSP430:
dda8d76d 15100 if (uses_msp430x_relocs (filedata))
13761a11 15101 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 15102 /* Fall through. */
78c8d46c 15103 case EM_MSP430_OLD:
aca88567 15104 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 15105 case EM_NDS32:
81c5e376 15106 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 15107 case EM_ALTERA_NIOS2:
36591ba1 15108 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
15109 case EM_NIOS32:
15110 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
15111 case EM_OR1K:
15112 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
15113 case EM_RISCV:
15114 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
15115 case EM_TI_PRU:
15116 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
15117 case EM_TI_C6000:
15118 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
15119 case EM_VISIUM:
15120 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
15121 case EM_XGATE:
15122 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
15123 case EM_Z80:
15124 return reloc_type == 4; /* R_Z80_16. */
4b78141a 15125 default:
015dc7e1 15126 return false;
4b78141a
NC
15127 }
15128}
15129
39e07931
AS
15130/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15131 a 8-bit absolute RELA relocation used in DWARF debug sections. */
15132
015dc7e1 15133static bool
39e07931
AS
15134is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15135{
15136 switch (filedata->file_header.e_machine)
15137 {
15138 case EM_RISCV:
15139 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
15140 case EM_Z80:
15141 return reloc_type == 1; /* R_Z80_8. */
39e07931 15142 default:
015dc7e1 15143 return false;
39e07931
AS
15144 }
15145}
15146
15147/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15148 a 6-bit absolute RELA relocation used in DWARF debug sections. */
15149
015dc7e1 15150static bool
39e07931
AS
15151is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15152{
15153 switch (filedata->file_header.e_machine)
15154 {
15155 case EM_RISCV:
15156 return reloc_type == 53; /* R_RISCV_SET6. */
15157 default:
015dc7e1 15158 return false;
39e07931
AS
15159 }
15160}
15161
03336641
JW
15162/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15163 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
15164
015dc7e1 15165static bool
03336641
JW
15166is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15167{
15168 /* Please keep this table alpha-sorted for ease of visual lookup. */
15169 switch (filedata->file_header.e_machine)
15170 {
76244462 15171 case EM_LOONGARCH:
15172 return reloc_type == 50; /* R_LARCH_ADD32. */
03336641
JW
15173 case EM_RISCV:
15174 return reloc_type == 35; /* R_RISCV_ADD32. */
15175 default:
015dc7e1 15176 return false;
03336641
JW
15177 }
15178}
15179
15180/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15181 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
15182
015dc7e1 15183static bool
03336641
JW
15184is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15185{
15186 /* Please keep this table alpha-sorted for ease of visual lookup. */
15187 switch (filedata->file_header.e_machine)
15188 {
76244462 15189 case EM_LOONGARCH:
15190 return reloc_type == 55; /* R_LARCH_SUB32. */
03336641
JW
15191 case EM_RISCV:
15192 return reloc_type == 39; /* R_RISCV_SUB32. */
15193 default:
015dc7e1 15194 return false;
03336641
JW
15195 }
15196}
15197
15198/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15199 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
15200
015dc7e1 15201static bool
03336641
JW
15202is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15203{
15204 /* Please keep this table alpha-sorted for ease of visual lookup. */
15205 switch (filedata->file_header.e_machine)
15206 {
76244462 15207 case EM_LOONGARCH:
15208 return reloc_type == 51; /* R_LARCH_ADD64. */
03336641
JW
15209 case EM_RISCV:
15210 return reloc_type == 36; /* R_RISCV_ADD64. */
15211 default:
015dc7e1 15212 return false;
03336641
JW
15213 }
15214}
15215
15216/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15217 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
15218
015dc7e1 15219static bool
03336641
JW
15220is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15221{
15222 /* Please keep this table alpha-sorted for ease of visual lookup. */
15223 switch (filedata->file_header.e_machine)
15224 {
76244462 15225 case EM_LOONGARCH:
15226 return reloc_type == 56; /* R_LARCH_SUB64. */
03336641
JW
15227 case EM_RISCV:
15228 return reloc_type == 40; /* R_RISCV_SUB64. */
15229 default:
015dc7e1 15230 return false;
03336641
JW
15231 }
15232}
15233
15234/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15235 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
15236
015dc7e1 15237static bool
03336641
JW
15238is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15239{
15240 /* Please keep this table alpha-sorted for ease of visual lookup. */
15241 switch (filedata->file_header.e_machine)
15242 {
76244462 15243 case EM_LOONGARCH:
15244 return reloc_type == 48; /* R_LARCH_ADD16. */
03336641
JW
15245 case EM_RISCV:
15246 return reloc_type == 34; /* R_RISCV_ADD16. */
15247 default:
015dc7e1 15248 return false;
03336641
JW
15249 }
15250}
15251
15252/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15253 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
15254
015dc7e1 15255static bool
03336641
JW
15256is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15257{
15258 /* Please keep this table alpha-sorted for ease of visual lookup. */
15259 switch (filedata->file_header.e_machine)
15260 {
76244462 15261 case EM_LOONGARCH:
15262 return reloc_type == 53; /* R_LARCH_SUB16. */
03336641
JW
15263 case EM_RISCV:
15264 return reloc_type == 38; /* R_RISCV_SUB16. */
15265 default:
015dc7e1 15266 return false;
03336641
JW
15267 }
15268}
15269
15270/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15271 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
15272
015dc7e1 15273static bool
03336641
JW
15274is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15275{
15276 /* Please keep this table alpha-sorted for ease of visual lookup. */
15277 switch (filedata->file_header.e_machine)
15278 {
76244462 15279 case EM_LOONGARCH:
15280 return reloc_type == 47; /* R_LARCH_ADD8. */
03336641
JW
15281 case EM_RISCV:
15282 return reloc_type == 33; /* R_RISCV_ADD8. */
15283 default:
015dc7e1 15284 return false;
03336641
JW
15285 }
15286}
15287
15288/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15289 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
15290
015dc7e1 15291static bool
03336641
JW
15292is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15293{
15294 /* Please keep this table alpha-sorted for ease of visual lookup. */
15295 switch (filedata->file_header.e_machine)
15296 {
76244462 15297 case EM_LOONGARCH:
15298 return reloc_type == 52; /* R_LARCH_SUB8. */
03336641
JW
15299 case EM_RISCV:
15300 return reloc_type == 37; /* R_RISCV_SUB8. */
15301 default:
015dc7e1 15302 return false;
03336641
JW
15303 }
15304}
15305
76244462 15306/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15307 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
15308
15309static bool
15310is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15311{
15312 switch (filedata->file_header.e_machine)
15313 {
15314 case EM_LOONGARCH:
15315 return reloc_type == 105; /* R_LARCH_ADD6. */
15316 default:
15317 return false;
15318 }
15319}
15320
39e07931
AS
15321/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15322 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
15323
015dc7e1 15324static bool
39e07931
AS
15325is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15326{
15327 switch (filedata->file_header.e_machine)
15328 {
76244462 15329 case EM_LOONGARCH:
15330 return reloc_type == 106; /* R_LARCH_SUB6. */
39e07931
AS
15331 case EM_RISCV:
15332 return reloc_type == 52; /* R_RISCV_SUB6. */
15333 default:
015dc7e1 15334 return false;
39e07931
AS
15335 }
15336}
15337
2a7b2e88
JK
15338/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
15339 relocation entries (possibly formerly used for SHT_GROUP sections). */
15340
015dc7e1 15341static bool
dda8d76d 15342is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 15343{
dda8d76d 15344 switch (filedata->file_header.e_machine)
2a7b2e88 15345 {
cb8f3167 15346 case EM_386: /* R_386_NONE. */
d347c9df 15347 case EM_68K: /* R_68K_NONE. */
cfb8c092 15348 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
15349 case EM_ALPHA: /* R_ALPHA_NONE. */
15350 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 15351 case EM_ARC: /* R_ARC_NONE. */
886a2506 15352 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 15353 case EM_ARC_COMPACT: /* R_ARC_NONE. */
b5c37946
SJ
15354 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
15355 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
cb8f3167 15356 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 15357 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
15358 case EM_FT32: /* R_FT32_NONE. */
15359 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 15360 case EM_K1OM: /* R_X86_64_NONE. */
6e712424 15361 case EM_KVX: /* R_KVX_NONE. */
d347c9df
PS
15362 case EM_L1OM: /* R_X86_64_NONE. */
15363 case EM_M32R: /* R_M32R_NONE. */
15364 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 15365 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 15366 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
15367 case EM_NIOS32: /* R_NIOS_NONE. */
15368 case EM_OR1K: /* R_OR1K_NONE. */
15369 case EM_PARISC: /* R_PARISC_NONE. */
15370 case EM_PPC64: /* R_PPC64_NONE. */
15371 case EM_PPC: /* R_PPC_NONE. */
e23eba97 15372 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
15373 case EM_S390: /* R_390_NONE. */
15374 case EM_S390_OLD:
15375 case EM_SH: /* R_SH_NONE. */
15376 case EM_SPARC32PLUS:
15377 case EM_SPARC: /* R_SPARC_NONE. */
15378 case EM_SPARCV9:
aa137e4d
NC
15379 case EM_TILEGX: /* R_TILEGX_NONE. */
15380 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
15381 case EM_TI_C6000:/* R_C6000_NONE. */
15382 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 15383 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 15384 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 15385 return reloc_type == 0;
d347c9df 15386
a06ea964
NC
15387 case EM_AARCH64:
15388 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
15389 case EM_AVR_OLD:
15390 case EM_AVR:
15391 return (reloc_type == 0 /* R_AVR_NONE. */
15392 || reloc_type == 30 /* R_AVR_DIFF8. */
15393 || reloc_type == 31 /* R_AVR_DIFF16. */
15394 || reloc_type == 32 /* R_AVR_DIFF32. */);
15395 case EM_METAG:
15396 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 15397 case EM_NDS32:
81c5e376
AM
15398 return (reloc_type == 0 /* R_NDS32_NONE. */
15399 || reloc_type == 205 /* R_NDS32_DIFF8. */
15400 || reloc_type == 206 /* R_NDS32_DIFF16. */
15401 || reloc_type == 207 /* R_NDS32_DIFF32. */
15402 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
15403 case EM_TI_PRU:
15404 return (reloc_type == 0 /* R_PRU_NONE. */
15405 || reloc_type == 65 /* R_PRU_DIFF8. */
15406 || reloc_type == 66 /* R_PRU_DIFF16. */
15407 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
15408 case EM_XTENSA_OLD:
15409 case EM_XTENSA:
4dc3c23d
AM
15410 return (reloc_type == 0 /* R_XTENSA_NONE. */
15411 || reloc_type == 17 /* R_XTENSA_DIFF8. */
15412 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
15413 || reloc_type == 19 /* R_XTENSA_DIFF32. */
15414 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
15415 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
15416 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
15417 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
15418 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
15419 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 15420 }
015dc7e1 15421 return false;
2a7b2e88
JK
15422}
15423
d1c4b12b
NC
15424/* Returns TRUE if there is a relocation against
15425 section NAME at OFFSET bytes. */
15426
015dc7e1 15427bool
31e5a3a3 15428reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
15429{
15430 Elf_Internal_Rela * relocs;
15431 Elf_Internal_Rela * rp;
15432
15433 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 15434 return false;
d1c4b12b
NC
15435
15436 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
15437
15438 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
15439 if (rp->r_offset == offset)
015dc7e1 15440 return true;
d1c4b12b 15441
015dc7e1 15442 return false;
d1c4b12b
NC
15443}
15444
cf13d699 15445/* Apply relocations to a section.
32ec8896
NC
15446 Returns TRUE upon success, FALSE otherwise.
15447 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
15448 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
15449 will be set to the number of relocs loaded.
15450
cf13d699 15451 Note: So far support has been added only for those relocations
32ec8896
NC
15452 which can be found in debug sections. FIXME: Add support for
15453 more relocations ? */
1b315056 15454
015dc7e1 15455static bool
be7d229a
AM
15456apply_relocations (Filedata *filedata,
15457 const Elf_Internal_Shdr *section,
15458 unsigned char *start,
15459 size_t size,
15460 void **relocs_return,
26c527e6 15461 uint64_t *num_relocs_return)
1b315056 15462{
cf13d699 15463 Elf_Internal_Shdr * relsec;
0d2a7a93 15464 unsigned char * end = start + size;
cb8f3167 15465
d1c4b12b
NC
15466 if (relocs_return != NULL)
15467 {
15468 * (Elf_Internal_Rela **) relocs_return = NULL;
15469 * num_relocs_return = 0;
15470 }
15471
dda8d76d 15472 if (filedata->file_header.e_type != ET_REL)
32ec8896 15473 /* No relocs to apply. */
015dc7e1 15474 return true;
1b315056 15475
cf13d699 15476 /* Find the reloc section associated with the section. */
dda8d76d
NC
15477 for (relsec = filedata->section_headers;
15478 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 15479 ++relsec)
252b5132 15480 {
015dc7e1 15481 bool is_rela;
26c527e6 15482 uint64_t num_relocs;
2cf0635d
NC
15483 Elf_Internal_Rela * relocs;
15484 Elf_Internal_Rela * rp;
15485 Elf_Internal_Shdr * symsec;
15486 Elf_Internal_Sym * symtab;
26c527e6 15487 uint64_t num_syms;
2cf0635d 15488 Elf_Internal_Sym * sym;
252b5132 15489
41e92641 15490 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15491 || relsec->sh_info >= filedata->file_header.e_shnum
15492 || filedata->section_headers + relsec->sh_info != section
c256ffe7 15493 || relsec->sh_size == 0
dda8d76d 15494 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 15495 continue;
428409d5 15496
a788aedd
AM
15497 symsec = filedata->section_headers + relsec->sh_link;
15498 if (symsec->sh_type != SHT_SYMTAB
15499 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 15500 return false;
a788aedd 15501
41e92641
NC
15502 is_rela = relsec->sh_type == SHT_RELA;
15503
15504 if (is_rela)
15505 {
dda8d76d 15506 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 15507 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15508 return false;
41e92641
NC
15509 }
15510 else
15511 {
dda8d76d 15512 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 15513 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15514 return false;
41e92641
NC
15515 }
15516
15517 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 15518 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 15519 is_rela = false;
428409d5 15520
4de91c10 15521 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 15522
41e92641 15523 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 15524 {
625d49fc 15525 uint64_t addend;
015dc7e1
AM
15526 unsigned int reloc_type;
15527 unsigned int reloc_size;
15528 bool reloc_inplace = false;
15529 bool reloc_subtract = false;
15530 unsigned char *rloc;
26c527e6 15531 uint64_t sym_index;
4b78141a 15532
dda8d76d 15533 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 15534
dda8d76d 15535 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 15536 continue;
dda8d76d 15537 else if (is_none_reloc (filedata, reloc_type))
98fb390a 15538 continue;
dda8d76d
NC
15539 else if (is_32bit_abs_reloc (filedata, reloc_type)
15540 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 15541 reloc_size = 4;
dda8d76d
NC
15542 else if (is_64bit_abs_reloc (filedata, reloc_type)
15543 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 15544 reloc_size = 8;
dda8d76d 15545 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15546 reloc_size = 3;
dda8d76d 15547 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15548 reloc_size = 2;
39e07931
AS
15549 else if (is_8bit_abs_reloc (filedata, reloc_type)
15550 || is_6bit_abs_reloc (filedata, reloc_type))
15551 reloc_size = 1;
03336641
JW
15552 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15553 reloc_type))
15554 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15555 {
15556 reloc_size = 4;
015dc7e1 15557 reloc_inplace = true;
03336641
JW
15558 }
15559 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15560 reloc_type))
15561 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15562 {
15563 reloc_size = 8;
015dc7e1 15564 reloc_inplace = true;
03336641
JW
15565 }
15566 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15567 reloc_type))
15568 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15569 {
15570 reloc_size = 2;
015dc7e1 15571 reloc_inplace = true;
03336641
JW
15572 }
15573 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15574 reloc_type))
15575 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15576 {
15577 reloc_size = 1;
015dc7e1 15578 reloc_inplace = true;
03336641 15579 }
39e07931 15580 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
76244462 15581 reloc_type))
15582 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15583 {
15584 reloc_size = 1;
015dc7e1 15585 reloc_inplace = true;
39e07931 15586 }
aca88567 15587 else
4b78141a 15588 {
bee0ee85 15589 static unsigned int prev_reloc = 0;
dda8d76d 15590
bee0ee85
NC
15591 if (reloc_type != prev_reloc)
15592 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15593 reloc_type, printable_section_name (filedata, section));
bee0ee85 15594 prev_reloc = reloc_type;
4b78141a
NC
15595 continue;
15596 }
103f02d3 15597
91d6fa6a 15598 rloc = start + rp->r_offset;
75802ccb 15599 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 15600 {
26c527e6
AM
15601 warn (_("skipping invalid relocation offset %#" PRIx64
15602 " in section %s\n"),
15603 rp->r_offset,
dda8d76d 15604 printable_section_name (filedata, section));
700dd8b7
L
15605 continue;
15606 }
103f02d3 15607
26c527e6 15608 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
15609 if (sym_index >= num_syms)
15610 {
26c527e6
AM
15611 warn (_("skipping invalid relocation symbol index %#" PRIx64
15612 " in section %s\n"),
dda8d76d 15613 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15614 continue;
15615 }
15616 sym = symtab + sym_index;
41e92641
NC
15617
15618 /* If the reloc has a symbol associated with it,
55f25fc3
L
15619 make sure that it is of an appropriate type.
15620
15621 Relocations against symbols without type can happen.
15622 Gcc -feliminate-dwarf2-dups may generate symbols
15623 without type for debug info.
15624
15625 Icc generates relocations against function symbols
15626 instead of local labels.
15627
15628 Relocations against object symbols can happen, eg when
15629 referencing a global array. For an example of this see
15630 the _clz.o binary in libgcc.a. */
aca88567 15631 if (sym != symtab
b8871f35 15632 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15633 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15634 {
26c527e6 15635 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
15636 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15637 printable_section_name (filedata, relsec),
26c527e6 15638 rp - relocs);
aca88567 15639 continue;
5b18a4bc 15640 }
252b5132 15641
4dc3c23d
AM
15642 addend = 0;
15643 if (is_rela)
15644 addend += rp->r_addend;
c47320c3
AM
15645 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15646 partial_inplace. */
4dc3c23d 15647 if (!is_rela
dda8d76d 15648 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15649 && reloc_type == 1)
dda8d76d
NC
15650 || ((filedata->file_header.e_machine == EM_PJ
15651 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15652 && reloc_type == 1)
dda8d76d
NC
15653 || ((filedata->file_header.e_machine == EM_D30V
15654 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15655 && reloc_type == 12)
15656 || reloc_inplace)
39e07931
AS
15657 {
15658 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15659 addend += byte_get (rloc, reloc_size) & 0x3f;
15660 else
15661 addend += byte_get (rloc, reloc_size);
15662 }
cb8f3167 15663
dda8d76d
NC
15664 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15665 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15666 {
15667 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15668 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15669 addend -= 8;
91d6fa6a 15670 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15671 reloc_size);
15672 }
39e07931 15673 else if (is_6bit_abs_reloc (filedata, reloc_type)
76244462 15674 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
15675 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15676 {
15677 if (reloc_subtract)
15678 addend -= sym->st_value;
15679 else
15680 addend += sym->st_value;
15681 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15682 byte_put (rloc, addend, reloc_size);
15683 }
03336641
JW
15684 else if (reloc_subtract)
15685 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15686 else
91d6fa6a 15687 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15688 }
252b5132 15689
5b18a4bc 15690 free (symtab);
f84ce13b
NC
15691 /* Let the target specific reloc processing code know that
15692 we have finished with these relocs. */
dda8d76d 15693 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15694
15695 if (relocs_return)
15696 {
15697 * (Elf_Internal_Rela **) relocs_return = relocs;
15698 * num_relocs_return = num_relocs;
15699 }
15700 else
15701 free (relocs);
15702
5b18a4bc
NC
15703 break;
15704 }
32ec8896 15705
015dc7e1 15706 return true;
5b18a4bc 15707}
103f02d3 15708
cf13d699 15709#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15710static bool
dda8d76d 15711disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15712{
dda8d76d 15713 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15714
74e1a04b 15715 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15716
015dc7e1 15717 return true;
cf13d699
NC
15718}
15719#endif
15720
15721/* Reads in the contents of SECTION from FILE, returning a pointer
15722 to a malloc'ed buffer or NULL if something went wrong. */
15723
15724static char *
dda8d76d 15725get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15726{
be7d229a 15727 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15728
15729 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15730 {
c6b78c96 15731 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15732 printable_section_name (filedata, section));
cf13d699
NC
15733 return NULL;
15734 }
15735
dda8d76d 15736 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15737 _("section contents"));
cf13d699
NC
15738}
15739
1f5a3546 15740/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 15741
015dc7e1 15742static bool
45f5fe46
NC
15743uncompress_section_contents (bool is_zstd,
15744 unsigned char ** buffer,
15745 uint64_t uncompressed_size,
15746 uint64_t * size,
15747 uint64_t file_size)
0e602686 15748{
31e5a3a3
AM
15749 uint64_t compressed_size = *size;
15750 unsigned char *compressed_buffer = *buffer;
45f5fe46 15751 unsigned char *uncompressed_buffer = NULL;
0e602686
NC
15752 z_stream strm;
15753 int rc;
15754
45f5fe46
NC
15755 /* Similar to _bfd_section_size_insane() in the BFD library we expect an
15756 upper limit of ~10x compression. Any compression larger than that is
15757 thought to be due to fuzzing of the compression header. */
15758 if (uncompressed_size > file_size * 10)
15759 {
15760 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
15761 uncompressed_size);
15762 goto fail;
15763 }
15764
15765 uncompressed_buffer = xmalloc (uncompressed_size);
15766
1f5a3546
FS
15767 if (is_zstd)
15768 {
15769#ifdef HAVE_ZSTD
15770 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15771 compressed_buffer, compressed_size);
15772 if (ZSTD_isError (ret))
15773 goto fail;
15774#endif
15775 }
15776 else
15777 {
15778 /* It is possible the section consists of several compressed
15779 buffers concatenated together, so we uncompress in a loop. */
15780 /* PR 18313: The state field in the z_stream structure is supposed
15781 to be invisible to the user (ie us), but some compilers will
15782 still complain about it being used without initialisation. So
15783 we first zero the entire z_stream structure and then set the fields
15784 that we need. */
15785 memset (&strm, 0, sizeof strm);
15786 strm.avail_in = compressed_size;
15787 strm.next_in = (Bytef *)compressed_buffer;
15788 strm.avail_out = uncompressed_size;
15789
15790 rc = inflateInit (&strm);
15791 while (strm.avail_in > 0)
15792 {
15793 if (rc != Z_OK)
15794 break;
15795 strm.next_out = ((Bytef *)uncompressed_buffer
15796 + (uncompressed_size - strm.avail_out));
15797 rc = inflate (&strm, Z_FINISH);
15798 if (rc != Z_STREAM_END)
15799 break;
15800 rc = inflateReset (&strm);
15801 }
15802 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15803 goto fail;
15804 }
0e602686
NC
15805
15806 *buffer = uncompressed_buffer;
15807 *size = uncompressed_size;
015dc7e1 15808 return true;
0e602686
NC
15809
15810 fail:
15811 free (uncompressed_buffer);
15812 /* Indicate decompression failure. */
15813 *buffer = NULL;
015dc7e1 15814 return false;
0e602686 15815}
dd24e3da 15816
015dc7e1 15817static bool
dda8d76d 15818dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15819{
015dc7e1 15820 Elf_Internal_Shdr *relsec;
be7d229a 15821 uint64_t num_bytes;
015dc7e1
AM
15822 unsigned char *data;
15823 unsigned char *end;
15824 unsigned char *real_start;
15825 unsigned char *start;
15826 bool some_strings_shown;
cf13d699 15827
dda8d76d 15828 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15829 if (start == NULL)
c6b78c96 15830 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15831 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15832
0e602686 15833 num_bytes = section->sh_size;
cf13d699 15834
835f2fae
NC
15835 if (filedata->is_separate)
15836 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15837 printable_section_name (filedata, section),
15838 filedata->file_name);
15839 else
15840 printf (_("\nString dump of section '%s':\n"),
15841 printable_section_name (filedata, section));
cf13d699 15842
0e602686
NC
15843 if (decompress_dumps)
15844 {
31e5a3a3
AM
15845 uint64_t new_size = num_bytes;
15846 uint64_t uncompressed_size = 0;
1f5a3546 15847 bool is_zstd = false;
0e602686
NC
15848
15849 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15850 {
15851 Elf_Internal_Chdr chdr;
15852 unsigned int compression_header_size
ebdf1ebf
NC
15853 = get_compression_header (& chdr, (unsigned char *) start,
15854 num_bytes);
5844b465
NC
15855 if (compression_header_size == 0)
15856 /* An error message will have already been generated
15857 by get_compression_header. */
15858 goto error_out;
0e602686 15859
89dbeac7 15860 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
15861 ;
15862#ifdef HAVE_ZSTD
89dbeac7 15863 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
15864 is_zstd = true;
15865#endif
15866 else
0e602686 15867 {
813dabb9 15868 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15869 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15870 goto error_out;
813dabb9 15871 }
813dabb9
L
15872 uncompressed_size = chdr.ch_size;
15873 start += compression_header_size;
15874 new_size -= compression_header_size;
0e602686
NC
15875 }
15876 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15877 {
15878 /* Read the zlib header. In this case, it should be "ZLIB"
15879 followed by the uncompressed section size, 8 bytes in
15880 big-endian order. */
15881 uncompressed_size = start[4]; uncompressed_size <<= 8;
15882 uncompressed_size += start[5]; uncompressed_size <<= 8;
15883 uncompressed_size += start[6]; uncompressed_size <<= 8;
15884 uncompressed_size += start[7]; uncompressed_size <<= 8;
15885 uncompressed_size += start[8]; uncompressed_size <<= 8;
15886 uncompressed_size += start[9]; uncompressed_size <<= 8;
15887 uncompressed_size += start[10]; uncompressed_size <<= 8;
15888 uncompressed_size += start[11];
15889 start += 12;
15890 new_size -= 12;
15891 }
15892
1835f746
NC
15893 if (uncompressed_size)
15894 {
1f5a3546 15895 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 15896 &new_size, filedata->file_size))
1835f746
NC
15897 num_bytes = new_size;
15898 else
15899 {
15900 error (_("Unable to decompress section %s\n"),
dda8d76d 15901 printable_section_name (filedata, section));
f761cb13 15902 goto error_out;
1835f746
NC
15903 }
15904 }
bc303e5d
NC
15905 else
15906 start = real_start;
0e602686 15907 }
fd8008d8 15908
cf13d699
NC
15909 /* If the section being dumped has relocations against it the user might
15910 be expecting these relocations to have been applied. Check for this
15911 case and issue a warning message in order to avoid confusion.
15912 FIXME: Maybe we ought to have an option that dumps a section with
15913 relocs applied ? */
dda8d76d
NC
15914 for (relsec = filedata->section_headers;
15915 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15916 ++relsec)
15917 {
15918 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15919 || relsec->sh_info >= filedata->file_header.e_shnum
15920 || filedata->section_headers + relsec->sh_info != section
cf13d699 15921 || relsec->sh_size == 0
dda8d76d 15922 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15923 continue;
15924
15925 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15926 break;
15927 }
15928
cf13d699
NC
15929 data = start;
15930 end = start + num_bytes;
015dc7e1 15931 some_strings_shown = false;
cf13d699 15932
ba3265d0
NC
15933#ifdef HAVE_MBSTATE_T
15934 mbstate_t state;
15935 /* Initialise the multibyte conversion state. */
15936 memset (& state, 0, sizeof (state));
15937#endif
15938
015dc7e1 15939 bool continuing = false;
ba3265d0 15940
cf13d699
NC
15941 while (data < end)
15942 {
15943 while (!ISPRINT (* data))
15944 if (++ data >= end)
15945 break;
15946
15947 if (data < end)
15948 {
071436c6
NC
15949 size_t maxlen = end - data;
15950
ba3265d0
NC
15951 if (continuing)
15952 {
15953 printf (" ");
015dc7e1 15954 continuing = false;
ba3265d0
NC
15955 }
15956 else
15957 {
26c527e6 15958 printf (" [%6tx] ", data - start);
ba3265d0
NC
15959 }
15960
4082ef84
NC
15961 if (maxlen > 0)
15962 {
f3da8a96 15963 char c = 0;
ba3265d0
NC
15964
15965 while (maxlen)
15966 {
15967 c = *data++;
15968
15969 if (c == 0)
15970 break;
15971
15972 /* PR 25543: Treat new-lines as string-ending characters. */
15973 if (c == '\n')
15974 {
15975 printf ("\\n\n");
15976 if (*data != 0)
015dc7e1 15977 continuing = true;
ba3265d0
NC
15978 break;
15979 }
15980
15981 /* Do not print control characters directly as they can affect terminal
15982 settings. Such characters usually appear in the names generated
15983 by the assembler for local labels. */
15984 if (ISCNTRL (c))
15985 {
15986 printf ("^%c", c + 0x40);
15987 }
15988 else if (ISPRINT (c))
15989 {
15990 putchar (c);
15991 }
15992 else
15993 {
15994 size_t n;
15995#ifdef HAVE_MBSTATE_T
15996 wchar_t w;
15997#endif
15998 /* Let printf do the hard work of displaying multibyte characters. */
15999 printf ("%.1s", data - 1);
16000#ifdef HAVE_MBSTATE_T
16001 /* Try to find out how many bytes made up the character that was
16002 just printed. Advance the symbol pointer past the bytes that
16003 were displayed. */
16004 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
16005#else
16006 n = 1;
16007#endif
16008 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
16009 data += (n - 1);
16010 }
16011 }
16012
16013 if (c != '\n')
16014 putchar ('\n');
4082ef84
NC
16015 }
16016 else
16017 {
16018 printf (_("<corrupt>\n"));
16019 data = end;
16020 }
015dc7e1 16021 some_strings_shown = true;
cf13d699
NC
16022 }
16023 }
16024
16025 if (! some_strings_shown)
16026 printf (_(" No strings found in this section."));
16027
0e602686 16028 free (real_start);
cf13d699
NC
16029
16030 putchar ('\n');
015dc7e1 16031 return true;
f761cb13
AM
16032
16033error_out:
16034 free (real_start);
015dc7e1 16035 return false;
cf13d699
NC
16036}
16037
015dc7e1
AM
16038static bool
16039dump_section_as_bytes (Elf_Internal_Shdr *section,
16040 Filedata *filedata,
16041 bool relocate)
cf13d699 16042{
be7d229a
AM
16043 Elf_Internal_Shdr *relsec;
16044 size_t bytes;
16045 uint64_t section_size;
625d49fc 16046 uint64_t addr;
be7d229a
AM
16047 unsigned char *data;
16048 unsigned char *real_start;
16049 unsigned char *start;
0e602686 16050
dda8d76d 16051 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 16052 if (start == NULL)
c6b78c96 16053 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 16054 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 16055
0e602686 16056 section_size = section->sh_size;
cf13d699 16057
835f2fae
NC
16058 if (filedata->is_separate)
16059 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
16060 printable_section_name (filedata, section),
16061 filedata->file_name);
16062 else
16063 printf (_("\nHex dump of section '%s':\n"),
16064 printable_section_name (filedata, section));
cf13d699 16065
0e602686
NC
16066 if (decompress_dumps)
16067 {
31e5a3a3
AM
16068 uint64_t new_size = section_size;
16069 uint64_t uncompressed_size = 0;
1f5a3546 16070 bool is_zstd = false;
0e602686
NC
16071
16072 if ((section->sh_flags & SHF_COMPRESSED) != 0)
16073 {
16074 Elf_Internal_Chdr chdr;
16075 unsigned int compression_header_size
ebdf1ebf 16076 = get_compression_header (& chdr, start, section_size);
0e602686 16077
5844b465
NC
16078 if (compression_header_size == 0)
16079 /* An error message will have already been generated
16080 by get_compression_header. */
16081 goto error_out;
16082
89dbeac7 16083 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16084 ;
16085#ifdef HAVE_ZSTD
89dbeac7 16086 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16087 is_zstd = true;
16088#endif
16089 else
0e602686 16090 {
813dabb9 16091 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 16092 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 16093 goto error_out;
0e602686 16094 }
813dabb9
L
16095 uncompressed_size = chdr.ch_size;
16096 start += compression_header_size;
16097 new_size -= compression_header_size;
0e602686
NC
16098 }
16099 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16100 {
16101 /* Read the zlib header. In this case, it should be "ZLIB"
16102 followed by the uncompressed section size, 8 bytes in
16103 big-endian order. */
16104 uncompressed_size = start[4]; uncompressed_size <<= 8;
16105 uncompressed_size += start[5]; uncompressed_size <<= 8;
16106 uncompressed_size += start[6]; uncompressed_size <<= 8;
16107 uncompressed_size += start[7]; uncompressed_size <<= 8;
16108 uncompressed_size += start[8]; uncompressed_size <<= 8;
16109 uncompressed_size += start[9]; uncompressed_size <<= 8;
16110 uncompressed_size += start[10]; uncompressed_size <<= 8;
16111 uncompressed_size += start[11];
16112 start += 12;
16113 new_size -= 12;
16114 }
16115
f055032e
NC
16116 if (uncompressed_size)
16117 {
1f5a3546 16118 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16119 &new_size, filedata->file_size))
bc303e5d
NC
16120 {
16121 section_size = new_size;
16122 }
f055032e
NC
16123 else
16124 {
16125 error (_("Unable to decompress section %s\n"),
dda8d76d 16126 printable_section_name (filedata, section));
bc303e5d 16127 /* FIXME: Print the section anyway ? */
f761cb13 16128 goto error_out;
f055032e
NC
16129 }
16130 }
bc303e5d
NC
16131 else
16132 start = real_start;
0e602686 16133 }
14ae95f2 16134
cf13d699
NC
16135 if (relocate)
16136 {
dda8d76d 16137 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 16138 goto error_out;
cf13d699
NC
16139 }
16140 else
16141 {
16142 /* If the section being dumped has relocations against it the user might
16143 be expecting these relocations to have been applied. Check for this
16144 case and issue a warning message in order to avoid confusion.
16145 FIXME: Maybe we ought to have an option that dumps a section with
16146 relocs applied ? */
dda8d76d
NC
16147 for (relsec = filedata->section_headers;
16148 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
16149 ++relsec)
16150 {
16151 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
16152 || relsec->sh_info >= filedata->file_header.e_shnum
16153 || filedata->section_headers + relsec->sh_info != section
cf13d699 16154 || relsec->sh_size == 0
dda8d76d 16155 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
16156 continue;
16157
16158 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16159 break;
16160 }
16161 }
16162
16163 addr = section->sh_addr;
0e602686 16164 bytes = section_size;
cf13d699
NC
16165 data = start;
16166
16167 while (bytes)
16168 {
16169 int j;
16170 int k;
16171 int lbytes;
16172
16173 lbytes = (bytes > 16 ? 16 : bytes);
16174
26c527e6 16175 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
16176
16177 for (j = 0; j < 16; j++)
16178 {
16179 if (j < lbytes)
16180 printf ("%2.2x", data[j]);
16181 else
16182 printf (" ");
16183
16184 if ((j & 3) == 3)
16185 printf (" ");
16186 }
16187
16188 for (j = 0; j < lbytes; j++)
16189 {
16190 k = data[j];
16191 if (k >= ' ' && k < 0x7f)
16192 printf ("%c", k);
16193 else
16194 printf (".");
16195 }
16196
16197 putchar ('\n');
16198
16199 data += lbytes;
16200 addr += lbytes;
16201 bytes -= lbytes;
16202 }
16203
0e602686 16204 free (real_start);
cf13d699
NC
16205
16206 putchar ('\n');
015dc7e1 16207 return true;
f761cb13
AM
16208
16209 error_out:
16210 free (real_start);
015dc7e1 16211 return false;
cf13d699
NC
16212}
16213
094e34f2 16214#ifdef ENABLE_LIBCTF
7d9813f1
NA
16215static ctf_sect_t *
16216shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
16217{
84714f86 16218 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
16219 buf->cts_size = shdr->sh_size;
16220 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
16221
16222 return buf;
16223}
16224
16225/* Formatting callback function passed to ctf_dump. Returns either the pointer
16226 it is passed, or a pointer to newly-allocated storage, in which case
16227 dump_ctf() will free it when it no longer needs it. */
16228
2f6ecaed
NA
16229static char *
16230dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
16231 char *s, void *arg)
7d9813f1 16232{
3e50a591 16233 const char *blanks = arg;
7d9813f1
NA
16234 char *new_s;
16235
3e50a591 16236 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
16237 return s;
16238 return new_s;
16239}
16240
926c9e76
NA
16241/* Dump CTF errors/warnings. */
16242static void
139633c3 16243dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
16244{
16245 ctf_next_t *it = NULL;
16246 char *errtext;
16247 int is_warning;
16248 int err;
16249
16250 /* Dump accumulated errors and warnings. */
16251 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
16252 {
5e9b84f7 16253 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
16254 errtext);
16255 free (errtext);
16256 }
16257 if (err != ECTF_NEXT_END)
16258 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
16259}
16260
2f6ecaed
NA
16261/* Dump one CTF archive member. */
16262
80b56fad
NA
16263static void
16264dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
16265 size_t member)
2f6ecaed 16266{
2f6ecaed
NA
16267 const char *things[] = {"Header", "Labels", "Data objects",
16268 "Function objects", "Variables", "Types", "Strings",
16269 ""};
16270 const char **thing;
16271 size_t i;
16272
80b56fad
NA
16273 /* Don't print out the name of the default-named archive member if it appears
16274 first in the list. The name .ctf appears everywhere, even for things that
16275 aren't really archives, so printing it out is liable to be confusing; also,
16276 the common case by far is for only one archive member to exist, and hiding
16277 it in that case seems worthwhile. */
2f6ecaed 16278
80b56fad
NA
16279 if (strcmp (name, ".ctf") != 0 || member != 0)
16280 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 16281
80b56fad
NA
16282 if (ctf_parent_name (ctf) != NULL)
16283 ctf_import (ctf, parent);
2f6ecaed
NA
16284
16285 for (i = 0, thing = things; *thing[0]; thing++, i++)
16286 {
16287 ctf_dump_state_t *s = NULL;
16288 char *item;
16289
16290 printf ("\n %s:\n", *thing);
16291 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
16292 (void *) " ")) != NULL)
16293 {
16294 printf ("%s\n", item);
16295 free (item);
16296 }
16297
16298 if (ctf_errno (ctf))
16299 {
16300 error (_("Iteration failed: %s, %s\n"), *thing,
16301 ctf_errmsg (ctf_errno (ctf)));
80b56fad 16302 break;
2f6ecaed
NA
16303 }
16304 }
8b37e7b6 16305
926c9e76 16306 dump_ctf_errs (ctf);
2f6ecaed
NA
16307}
16308
015dc7e1 16309static bool
7d9813f1
NA
16310dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
16311{
7d9813f1
NA
16312 Elf_Internal_Shdr * symtab_sec = NULL;
16313 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
16314 void * data = NULL;
16315 void * symdata = NULL;
16316 void * strdata = NULL;
80b56fad 16317 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
16318 ctf_sect_t * symsectp = NULL;
16319 ctf_sect_t * strsectp = NULL;
2f6ecaed 16320 ctf_archive_t * ctfa = NULL;
139633c3 16321 ctf_dict_t * parent = NULL;
80b56fad 16322 ctf_dict_t * fp;
7d9813f1 16323
80b56fad
NA
16324 ctf_next_t *i = NULL;
16325 const char *name;
16326 size_t member = 0;
7d9813f1 16327 int err;
015dc7e1 16328 bool ret = false;
7d9813f1
NA
16329
16330 shdr_to_ctf_sect (&ctfsect, section, filedata);
16331 data = get_section_contents (section, filedata);
16332 ctfsect.cts_data = data;
16333
616febde 16334 if (!dump_ctf_symtab_name)
3d16b64e 16335 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
16336
16337 if (!dump_ctf_strtab_name)
3d16b64e 16338 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
16339
16340 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
16341 {
16342 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
16343 {
16344 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
16345 goto fail;
16346 }
16347 if ((symdata = (void *) get_data (NULL, filedata,
16348 symtab_sec->sh_offset, 1,
16349 symtab_sec->sh_size,
16350 _("symbols"))) == NULL)
16351 goto fail;
16352 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
16353 symsect.cts_data = symdata;
16354 }
835f2fae 16355
df16e041 16356 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
16357 {
16358 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
16359 {
16360 error (_("No string table section named %s\n"),
16361 dump_ctf_strtab_name);
16362 goto fail;
16363 }
16364 if ((strdata = (void *) get_data (NULL, filedata,
16365 strtab_sec->sh_offset, 1,
16366 strtab_sec->sh_size,
16367 _("strings"))) == NULL)
16368 goto fail;
16369 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
16370 strsect.cts_data = strdata;
16371 }
835f2fae 16372
2f6ecaed
NA
16373 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
16374 libctf papers over the difference, so we can pretend it is always an
80b56fad 16375 archive. */
7d9813f1 16376
2f6ecaed 16377 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 16378 {
926c9e76 16379 dump_ctf_errs (NULL);
7d9813f1
NA
16380 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16381 goto fail;
16382 }
16383
96c61be5
NA
16384 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
16385 != ELFDATA2MSB);
16386
80b56fad
NA
16387 /* Preload the parent dict, since it will need to be imported into every
16388 child in turn. */
16389 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 16390 {
926c9e76 16391 dump_ctf_errs (NULL);
2f6ecaed
NA
16392 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16393 goto fail;
7d9813f1
NA
16394 }
16395
015dc7e1 16396 ret = true;
7d9813f1 16397
835f2fae
NC
16398 if (filedata->is_separate)
16399 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
16400 printable_section_name (filedata, section),
16401 filedata->file_name);
16402 else
16403 printf (_("\nDump of CTF section '%s':\n"),
16404 printable_section_name (filedata, section));
7d9813f1 16405
80b56fad
NA
16406 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
16407 dump_ctf_archive_member (fp, name, parent, member++);
16408 if (err != ECTF_NEXT_END)
16409 {
16410 dump_ctf_errs (NULL);
16411 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
16412 ret = false;
16413 }
7d9813f1
NA
16414
16415 fail:
139633c3 16416 ctf_dict_close (parent);
2f6ecaed 16417 ctf_close (ctfa);
7d9813f1
NA
16418 free (data);
16419 free (symdata);
16420 free (strdata);
16421 return ret;
16422}
094e34f2 16423#endif
7d9813f1 16424
42b6953b
IB
16425static bool
16426dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
16427{
16428 void * data = NULL;
16429 sframe_decoder_ctx *sfd_ctx = NULL;
16430 const char *print_name = printable_section_name (filedata, section);
16431
16432 bool ret = true;
16433 size_t sf_size;
16434 int err = 0;
16435
16436 if (strcmp (print_name, "") == 0)
16437 {
16438 error (_("Section name must be provided \n"));
16439 ret = false;
16440 return ret;
16441 }
16442
16443 data = get_section_contents (section, filedata);
16444 sf_size = section->sh_size;
16445 /* Decode the contents of the section. */
16446 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
16447 if (!sfd_ctx)
16448 {
16449 ret = false;
16450 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
16451 goto fail;
16452 }
16453
16454 printf (_("Contents of the SFrame section %s:"), print_name);
16455 /* Dump the contents as text. */
16456 dump_sframe (sfd_ctx, section->sh_addr);
16457
16458 fail:
16459 free (data);
16460 return ret;
16461}
16462
015dc7e1 16463static bool
dda8d76d
NC
16464load_specific_debug_section (enum dwarf_section_display_enum debug,
16465 const Elf_Internal_Shdr * sec,
16466 void * data)
1007acb3 16467{
2cf0635d 16468 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 16469 char buf [64];
dda8d76d 16470 Filedata * filedata = (Filedata *) data;
9abca702 16471
19e6b90e 16472 if (section->start != NULL)
dda8d76d
NC
16473 {
16474 /* If it is already loaded, do nothing. */
16475 if (streq (section->filename, filedata->file_name))
015dc7e1 16476 return true;
dda8d76d
NC
16477 free (section->start);
16478 }
1007acb3 16479
19e6b90e
L
16480 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16481 section->address = sec->sh_addr;
dda8d76d
NC
16482 section->filename = filedata->file_name;
16483 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
16484 sec->sh_offset, 1,
16485 sec->sh_size, buf);
59245841
NC
16486 if (section->start == NULL)
16487 section->size = 0;
16488 else
16489 {
77115a4a 16490 unsigned char *start = section->start;
31e5a3a3
AM
16491 uint64_t size = sec->sh_size;
16492 uint64_t uncompressed_size = 0;
1f5a3546 16493 bool is_zstd = false;
77115a4a
L
16494
16495 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16496 {
16497 Elf_Internal_Chdr chdr;
d8024a91
NC
16498 unsigned int compression_header_size;
16499
f53be977
L
16500 if (size < (is_32bit_elf
16501 ? sizeof (Elf32_External_Chdr)
16502 : sizeof (Elf64_External_Chdr)))
d8024a91 16503 {
55be8fd0 16504 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 16505 section->name);
015dc7e1 16506 return false;
d8024a91
NC
16507 }
16508
ebdf1ebf 16509 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
16510 if (compression_header_size == 0)
16511 /* An error message will have already been generated
16512 by get_compression_header. */
015dc7e1 16513 return false;
d8024a91 16514
89dbeac7 16515 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16516 ;
16517#ifdef HAVE_ZSTD
89dbeac7 16518 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16519 is_zstd = true;
16520#endif
16521 else
813dabb9
L
16522 {
16523 warn (_("section '%s' has unsupported compress type: %d\n"),
16524 section->name, chdr.ch_type);
015dc7e1 16525 return false;
813dabb9 16526 }
dab394de 16527 uncompressed_size = chdr.ch_size;
77115a4a
L
16528 start += compression_header_size;
16529 size -= compression_header_size;
16530 }
dab394de
L
16531 else if (size > 12 && streq ((char *) start, "ZLIB"))
16532 {
16533 /* Read the zlib header. In this case, it should be "ZLIB"
16534 followed by the uncompressed section size, 8 bytes in
16535 big-endian order. */
16536 uncompressed_size = start[4]; uncompressed_size <<= 8;
16537 uncompressed_size += start[5]; uncompressed_size <<= 8;
16538 uncompressed_size += start[6]; uncompressed_size <<= 8;
16539 uncompressed_size += start[7]; uncompressed_size <<= 8;
16540 uncompressed_size += start[8]; uncompressed_size <<= 8;
16541 uncompressed_size += start[9]; uncompressed_size <<= 8;
16542 uncompressed_size += start[10]; uncompressed_size <<= 8;
16543 uncompressed_size += start[11];
16544 start += 12;
16545 size -= 12;
16546 }
16547
1835f746 16548 if (uncompressed_size)
77115a4a 16549 {
1f5a3546 16550 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16551 &size, filedata->file_size))
1835f746
NC
16552 {
16553 /* Free the compressed buffer, update the section buffer
16554 and the section size if uncompress is successful. */
16555 free (section->start);
16556 section->start = start;
16557 }
16558 else
16559 {
16560 error (_("Unable to decompress section %s\n"),
dda8d76d 16561 printable_section_name (filedata, sec));
015dc7e1 16562 return false;
1835f746 16563 }
77115a4a 16564 }
bc303e5d 16565
77115a4a 16566 section->size = size;
59245841 16567 }
4a114e3e 16568
1b315056 16569 if (section->start == NULL)
015dc7e1 16570 return false;
1b315056 16571
19e6b90e 16572 if (debug_displays [debug].relocate)
32ec8896 16573 {
dda8d76d 16574 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 16575 & section->reloc_info, & section->num_relocs))
015dc7e1 16576 return false;
32ec8896 16577 }
d1c4b12b
NC
16578 else
16579 {
16580 section->reloc_info = NULL;
16581 section->num_relocs = 0;
16582 }
1007acb3 16583
015dc7e1 16584 return true;
1007acb3
L
16585}
16586
301a9420
AM
16587#if HAVE_LIBDEBUGINFOD
16588/* Return a hex string representation of the build-id. */
16589unsigned char *
16590get_build_id (void * data)
16591{
ca0e11aa 16592 Filedata * filedata = (Filedata *) data;
301a9420 16593 Elf_Internal_Shdr * shdr;
26c527e6 16594 size_t i;
301a9420 16595
55be8fd0
NC
16596 /* Iterate through notes to find note.gnu.build-id.
16597 FIXME: Only the first note in any note section is examined. */
301a9420
AM
16598 for (i = 0, shdr = filedata->section_headers;
16599 i < filedata->file_header.e_shnum && shdr != NULL;
16600 i++, shdr++)
16601 {
16602 if (shdr->sh_type != SHT_NOTE)
16603 continue;
16604
16605 char * next;
16606 char * end;
16607 size_t data_remaining;
16608 size_t min_notesz;
16609 Elf_External_Note * enote;
16610 Elf_Internal_Note inote;
16611
625d49fc
AM
16612 uint64_t offset = shdr->sh_offset;
16613 uint64_t align = shdr->sh_addralign;
16614 uint64_t length = shdr->sh_size;
301a9420
AM
16615
16616 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16617 if (enote == NULL)
16618 continue;
16619
16620 if (align < 4)
16621 align = 4;
16622 else if (align != 4 && align != 8)
f761cb13
AM
16623 {
16624 free (enote);
16625 continue;
16626 }
301a9420
AM
16627
16628 end = (char *) enote + length;
16629 data_remaining = end - (char *) enote;
16630
16631 if (!is_ia64_vms (filedata))
16632 {
16633 min_notesz = offsetof (Elf_External_Note, name);
16634 if (data_remaining < min_notesz)
16635 {
55be8fd0
NC
16636 warn (_("\
16637malformed note encountered in section %s whilst scanning for build-id note\n"),
16638 printable_section_name (filedata, shdr));
f761cb13 16639 free (enote);
55be8fd0 16640 continue;
301a9420
AM
16641 }
16642 data_remaining -= min_notesz;
16643
16644 inote.type = BYTE_GET (enote->type);
16645 inote.namesz = BYTE_GET (enote->namesz);
16646 inote.namedata = enote->name;
16647 inote.descsz = BYTE_GET (enote->descsz);
16648 inote.descdata = ((char *) enote
16649 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16650 inote.descpos = offset + (inote.descdata - (char *) enote);
16651 next = ((char *) enote
16652 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16653 }
16654 else
16655 {
16656 Elf64_External_VMS_Note *vms_enote;
16657
16658 /* PR binutils/15191
16659 Make sure that there is enough data to read. */
16660 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16661 if (data_remaining < min_notesz)
16662 {
55be8fd0
NC
16663 warn (_("\
16664malformed note encountered in section %s whilst scanning for build-id note\n"),
16665 printable_section_name (filedata, shdr));
f761cb13 16666 free (enote);
55be8fd0 16667 continue;
301a9420
AM
16668 }
16669 data_remaining -= min_notesz;
16670
16671 vms_enote = (Elf64_External_VMS_Note *) enote;
16672 inote.type = BYTE_GET (vms_enote->type);
16673 inote.namesz = BYTE_GET (vms_enote->namesz);
16674 inote.namedata = vms_enote->name;
16675 inote.descsz = BYTE_GET (vms_enote->descsz);
16676 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16677 inote.descpos = offset + (inote.descdata - (char *) enote);
16678 next = inote.descdata + align_power (inote.descsz, 3);
16679 }
16680
16681 /* Skip malformed notes. */
16682 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16683 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16684 || (size_t) (next - inote.descdata) < inote.descsz
16685 || ((size_t) (next - inote.descdata)
16686 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16687 {
55be8fd0
NC
16688 warn (_("\
16689malformed note encountered in section %s whilst scanning for build-id note\n"),
16690 printable_section_name (filedata, shdr));
f761cb13 16691 free (enote);
301a9420
AM
16692 continue;
16693 }
16694
16695 /* Check if this is the build-id note. If so then convert the build-id
16696 bytes to a hex string. */
16697 if (inote.namesz > 0
24d127aa 16698 && startswith (inote.namedata, "GNU")
301a9420
AM
16699 && inote.type == NT_GNU_BUILD_ID)
16700 {
26c527e6 16701 size_t j;
301a9420
AM
16702 char * build_id;
16703
16704 build_id = malloc (inote.descsz * 2 + 1);
16705 if (build_id == NULL)
f761cb13
AM
16706 {
16707 free (enote);
16708 return NULL;
16709 }
301a9420
AM
16710
16711 for (j = 0; j < inote.descsz; ++j)
16712 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16713 build_id[inote.descsz * 2] = '\0';
f761cb13 16714 free (enote);
301a9420 16715
55be8fd0 16716 return (unsigned char *) build_id;
301a9420 16717 }
f761cb13 16718 free (enote);
301a9420
AM
16719 }
16720
16721 return NULL;
16722}
16723#endif /* HAVE_LIBDEBUGINFOD */
16724
657d0d47
CC
16725/* If this is not NULL, load_debug_section will only look for sections
16726 within the list of sections given here. */
32ec8896 16727static unsigned int * section_subset = NULL;
657d0d47 16728
015dc7e1 16729bool
dda8d76d 16730load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16731{
2cf0635d
NC
16732 struct dwarf_section * section = &debug_displays [debug].section;
16733 Elf_Internal_Shdr * sec;
dda8d76d
NC
16734 Filedata * filedata = (Filedata *) data;
16735
e1dbfc17
L
16736 if (!dump_any_debugging)
16737 return false;
16738
f425ec66
NC
16739 /* Without section headers we cannot find any sections. */
16740 if (filedata->section_headers == NULL)
015dc7e1 16741 return false;
f425ec66 16742
9c1ce108
AM
16743 if (filedata->string_table == NULL
16744 && filedata->file_header.e_shstrndx != SHN_UNDEF
16745 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16746 {
16747 Elf_Internal_Shdr * strs;
16748
16749 /* Read in the string table, so that we have section names to scan. */
16750 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16751
4dff97b2 16752 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16753 {
9c1ce108
AM
16754 filedata->string_table
16755 = (char *) get_data (NULL, filedata, strs->sh_offset,
16756 1, strs->sh_size, _("string table"));
dda8d76d 16757
9c1ce108
AM
16758 filedata->string_table_length
16759 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16760 }
16761 }
d966045b
DJ
16762
16763 /* Locate the debug section. */
dda8d76d 16764 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16765 if (sec != NULL)
16766 section->name = section->uncompressed_name;
16767 else
16768 {
dda8d76d 16769 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16770 if (sec != NULL)
16771 section->name = section->compressed_name;
16772 }
16773 if (sec == NULL)
015dc7e1 16774 return false;
d966045b 16775
657d0d47
CC
16776 /* If we're loading from a subset of sections, and we've loaded
16777 a section matching this name before, it's likely that it's a
16778 different one. */
16779 if (section_subset != NULL)
16780 free_debug_section (debug);
16781
dda8d76d 16782 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16783}
16784
19e6b90e
L
16785void
16786free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16787{
2cf0635d 16788 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16789
19e6b90e
L
16790 if (section->start == NULL)
16791 return;
1007acb3 16792
19e6b90e
L
16793 free ((char *) section->start);
16794 section->start = NULL;
16795 section->address = 0;
16796 section->size = 0;
a788aedd 16797
9db70fc3
AM
16798 free (section->reloc_info);
16799 section->reloc_info = NULL;
16800 section->num_relocs = 0;
1007acb3
L
16801}
16802
015dc7e1 16803static bool
dda8d76d 16804display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16805{
84714f86
AM
16806 const char *name = (section_name_valid (filedata, section)
16807 ? section_name (filedata, section) : "");
16808 const char *print_name = printable_section_name (filedata, section);
be7d229a 16809 uint64_t length;
015dc7e1 16810 bool result = true;
3f5e193b 16811 int i;
1007acb3 16812
19e6b90e
L
16813 length = section->sh_size;
16814 if (length == 0)
1007acb3 16815 {
74e1a04b 16816 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16817 return true;
1007acb3 16818 }
5dff79d8
NC
16819 if (section->sh_type == SHT_NOBITS)
16820 {
16821 /* There is no point in dumping the contents of a debugging section
16822 which has the NOBITS type - the bits in the file will be random.
16823 This can happen when a file containing a .eh_frame section is
16824 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16825 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16826 print_name);
015dc7e1 16827 return false;
5dff79d8 16828 }
1007acb3 16829
24d127aa 16830 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16831 name = ".debug_info";
1007acb3 16832
19e6b90e
L
16833 /* See if we know how to display the contents of this section. */
16834 for (i = 0; i < max; i++)
d85bf2ba
NC
16835 {
16836 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16837 struct dwarf_section_display * display = debug_displays + i;
16838 struct dwarf_section * sec = & display->section;
d966045b 16839
d85bf2ba 16840 if (streq (sec->uncompressed_name, name)
24d127aa 16841 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16842 || streq (sec->compressed_name, name))
16843 {
015dc7e1 16844 bool secondary = (section != find_section (filedata, name));
1007acb3 16845
d85bf2ba
NC
16846 if (secondary)
16847 free_debug_section (id);
dda8d76d 16848
24d127aa 16849 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16850 sec->name = name;
16851 else if (streq (sec->uncompressed_name, name))
16852 sec->name = sec->uncompressed_name;
16853 else
16854 sec->name = sec->compressed_name;
657d0d47 16855
d85bf2ba
NC
16856 if (load_specific_debug_section (id, section, filedata))
16857 {
16858 /* If this debug section is part of a CU/TU set in a .dwp file,
16859 restrict load_debug_section to the sections in that set. */
16860 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16861
d85bf2ba 16862 result &= display->display (sec, filedata);
657d0d47 16863
d85bf2ba 16864 section_subset = NULL;
1007acb3 16865
44266f36 16866 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16867 free_debug_section (id);
16868 }
16869 break;
16870 }
16871 }
1007acb3 16872
19e6b90e 16873 if (i == max)
1007acb3 16874 {
74e1a04b 16875 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16876 result = false;
1007acb3
L
16877 }
16878
19e6b90e 16879 return result;
5b18a4bc 16880}
103f02d3 16881
aef1f6d0
DJ
16882/* Set DUMP_SECTS for all sections where dumps were requested
16883 based on section name. */
16884
16885static void
dda8d76d 16886initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16887{
2cf0635d 16888 struct dump_list_entry * cur;
aef1f6d0
DJ
16889
16890 for (cur = dump_sects_byname; cur; cur = cur->next)
16891 {
16892 unsigned int i;
015dc7e1 16893 bool any = false;
aef1f6d0 16894
dda8d76d 16895 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16896 if (section_name_valid (filedata, filedata->section_headers + i)
16897 && streq (section_name (filedata, filedata->section_headers + i),
16898 cur->name))
aef1f6d0 16899 {
6431e409 16900 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16901 any = true;
aef1f6d0
DJ
16902 }
16903
835f2fae
NC
16904 if (!any && !filedata->is_separate)
16905 warn (_("Section '%s' was not dumped because it does not exist\n"),
16906 cur->name);
aef1f6d0
DJ
16907 }
16908}
16909
015dc7e1 16910static bool
dda8d76d 16911process_section_contents (Filedata * filedata)
5b18a4bc 16912{
2cf0635d 16913 Elf_Internal_Shdr * section;
19e6b90e 16914 unsigned int i;
015dc7e1 16915 bool res = true;
103f02d3 16916
19e6b90e 16917 if (! do_dump)
015dc7e1 16918 return true;
103f02d3 16919
dda8d76d 16920 initialise_dumps_byname (filedata);
aef1f6d0 16921
dda8d76d 16922 for (i = 0, section = filedata->section_headers;
6431e409 16923 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16924 i++, section++)
16925 {
6431e409 16926 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16927
d6bfbc39
NC
16928 if (filedata->is_separate && ! process_links)
16929 dump &= DEBUG_DUMP;
047c3dbf 16930
19e6b90e 16931#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16932 if (dump & DISASS_DUMP)
16933 {
16934 if (! disassemble_section (section, filedata))
015dc7e1 16935 res = false;
dda8d76d 16936 }
19e6b90e 16937#endif
dda8d76d 16938 if (dump & HEX_DUMP)
32ec8896 16939 {
015dc7e1
AM
16940 if (! dump_section_as_bytes (section, filedata, false))
16941 res = false;
32ec8896 16942 }
103f02d3 16943
dda8d76d 16944 if (dump & RELOC_DUMP)
32ec8896 16945 {
015dc7e1
AM
16946 if (! dump_section_as_bytes (section, filedata, true))
16947 res = false;
32ec8896 16948 }
09c11c86 16949
dda8d76d 16950 if (dump & STRING_DUMP)
32ec8896 16951 {
dda8d76d 16952 if (! dump_section_as_strings (section, filedata))
015dc7e1 16953 res = false;
32ec8896 16954 }
cf13d699 16955
dda8d76d 16956 if (dump & DEBUG_DUMP)
32ec8896 16957 {
dda8d76d 16958 if (! display_debug_section (i, section, filedata))
015dc7e1 16959 res = false;
32ec8896 16960 }
7d9813f1 16961
094e34f2 16962#ifdef ENABLE_LIBCTF
7d9813f1
NA
16963 if (dump & CTF_DUMP)
16964 {
16965 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16966 res = false;
7d9813f1 16967 }
094e34f2 16968#endif
42b6953b
IB
16969 if (dump & SFRAME_DUMP)
16970 {
16971 if (! dump_section_as_sframe (section, filedata))
16972 res = false;
16973 }
5b18a4bc 16974 }
103f02d3 16975
835f2fae 16976 if (! filedata->is_separate)
0ee3043f 16977 {
835f2fae
NC
16978 /* Check to see if the user requested a
16979 dump of a section that does not exist. */
16980 for (; i < filedata->dump.num_dump_sects; i++)
16981 if (filedata->dump.dump_sects[i])
16982 {
ca0e11aa 16983 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16984 res = false;
835f2fae 16985 }
0ee3043f 16986 }
32ec8896
NC
16987
16988 return res;
5b18a4bc 16989}
103f02d3 16990
5b18a4bc 16991static void
19e6b90e 16992process_mips_fpe_exception (int mask)
5b18a4bc 16993{
19e6b90e
L
16994 if (mask)
16995 {
015dc7e1 16996 bool first = true;
32ec8896 16997
19e6b90e 16998 if (mask & OEX_FPU_INEX)
015dc7e1 16999 fputs ("INEX", stdout), first = false;
19e6b90e 17000 if (mask & OEX_FPU_UFLO)
015dc7e1 17001 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 17002 if (mask & OEX_FPU_OFLO)
015dc7e1 17003 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 17004 if (mask & OEX_FPU_DIV0)
015dc7e1 17005 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
17006 if (mask & OEX_FPU_INVAL)
17007 printf ("%sINVAL", first ? "" : "|");
17008 }
5b18a4bc 17009 else
19e6b90e 17010 fputs ("0", stdout);
5b18a4bc 17011}
103f02d3 17012
f6f0e17b
NC
17013/* Display's the value of TAG at location P. If TAG is
17014 greater than 0 it is assumed to be an unknown tag, and
17015 a message is printed to this effect. Otherwise it is
17016 assumed that a message has already been printed.
17017
17018 If the bottom bit of TAG is set it assumed to have a
17019 string value, otherwise it is assumed to have an integer
17020 value.
17021
17022 Returns an updated P pointing to the first unread byte
17023 beyond the end of TAG's value.
17024
17025 Reads at or beyond END will not be made. */
17026
17027static unsigned char *
60abdbed 17028display_tag_value (signed int tag,
f6f0e17b
NC
17029 unsigned char * p,
17030 const unsigned char * const end)
17031{
26c527e6 17032 uint64_t val;
f6f0e17b
NC
17033
17034 if (tag > 0)
17035 printf (" Tag_unknown_%d: ", tag);
17036
17037 if (p >= end)
17038 {
4082ef84 17039 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
17040 }
17041 else if (tag & 1)
17042 {
071436c6
NC
17043 /* PR 17531 file: 027-19978-0.004. */
17044 size_t maxlen = (end - p) - 1;
17045
17046 putchar ('"');
4082ef84
NC
17047 if (maxlen > 0)
17048 {
17049 print_symbol ((int) maxlen, (const char *) p);
17050 p += strnlen ((char *) p, maxlen) + 1;
17051 }
17052 else
17053 {
17054 printf (_("<corrupt string tag>"));
17055 p = (unsigned char *) end;
17056 }
071436c6 17057 printf ("\"\n");
f6f0e17b
NC
17058 }
17059 else
17060 {
cd30bcef 17061 READ_ULEB (val, p, end);
26c527e6 17062 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
17063 }
17064
4082ef84 17065 assert (p <= end);
f6f0e17b
NC
17066 return p;
17067}
17068
53a346d8
CZ
17069/* ARC ABI attributes section. */
17070
17071static unsigned char *
17072display_arc_attribute (unsigned char * p,
17073 const unsigned char * const end)
17074{
17075 unsigned int tag;
53a346d8
CZ
17076 unsigned int val;
17077
cd30bcef 17078 READ_ULEB (tag, p, end);
53a346d8
CZ
17079
17080 switch (tag)
17081 {
17082 case Tag_ARC_PCS_config:
cd30bcef 17083 READ_ULEB (val, p, end);
53a346d8
CZ
17084 printf (" Tag_ARC_PCS_config: ");
17085 switch (val)
17086 {
17087 case 0:
17088 printf (_("Absent/Non standard\n"));
17089 break;
17090 case 1:
17091 printf (_("Bare metal/mwdt\n"));
17092 break;
17093 case 2:
17094 printf (_("Bare metal/newlib\n"));
17095 break;
17096 case 3:
17097 printf (_("Linux/uclibc\n"));
17098 break;
17099 case 4:
17100 printf (_("Linux/glibc\n"));
17101 break;
17102 default:
17103 printf (_("Unknown\n"));
17104 break;
17105 }
17106 break;
17107
17108 case Tag_ARC_CPU_base:
cd30bcef 17109 READ_ULEB (val, p, end);
53a346d8
CZ
17110 printf (" Tag_ARC_CPU_base: ");
17111 switch (val)
17112 {
17113 default:
17114 case TAG_CPU_NONE:
17115 printf (_("Absent\n"));
17116 break;
17117 case TAG_CPU_ARC6xx:
17118 printf ("ARC6xx\n");
17119 break;
17120 case TAG_CPU_ARC7xx:
17121 printf ("ARC7xx\n");
17122 break;
17123 case TAG_CPU_ARCEM:
17124 printf ("ARCEM\n");
17125 break;
17126 case TAG_CPU_ARCHS:
17127 printf ("ARCHS\n");
17128 break;
17129 }
17130 break;
17131
17132 case Tag_ARC_CPU_variation:
cd30bcef 17133 READ_ULEB (val, p, end);
53a346d8
CZ
17134 printf (" Tag_ARC_CPU_variation: ");
17135 switch (val)
17136 {
17137 default:
17138 if (val > 0 && val < 16)
53a346d8 17139 printf ("Core%d\n", val);
d8cbc93b
JL
17140 else
17141 printf ("Unknown\n");
17142 break;
17143
53a346d8
CZ
17144 case 0:
17145 printf (_("Absent\n"));
17146 break;
17147 }
17148 break;
17149
17150 case Tag_ARC_CPU_name:
17151 printf (" Tag_ARC_CPU_name: ");
17152 p = display_tag_value (-1, p, end);
17153 break;
17154
17155 case Tag_ARC_ABI_rf16:
cd30bcef 17156 READ_ULEB (val, p, end);
53a346d8
CZ
17157 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
17158 break;
17159
17160 case Tag_ARC_ABI_osver:
cd30bcef 17161 READ_ULEB (val, p, end);
53a346d8
CZ
17162 printf (" Tag_ARC_ABI_osver: v%d\n", val);
17163 break;
17164
17165 case Tag_ARC_ABI_pic:
17166 case Tag_ARC_ABI_sda:
cd30bcef 17167 READ_ULEB (val, p, end);
53a346d8
CZ
17168 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
17169 : " Tag_ARC_ABI_pic: ");
17170 switch (val)
17171 {
17172 case 0:
17173 printf (_("Absent\n"));
17174 break;
17175 case 1:
17176 printf ("MWDT\n");
17177 break;
17178 case 2:
17179 printf ("GNU\n");
17180 break;
17181 default:
17182 printf (_("Unknown\n"));
17183 break;
17184 }
17185 break;
17186
17187 case Tag_ARC_ABI_tls:
cd30bcef 17188 READ_ULEB (val, p, end);
53a346d8
CZ
17189 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
17190 break;
17191
17192 case Tag_ARC_ABI_enumsize:
cd30bcef 17193 READ_ULEB (val, p, end);
53a346d8
CZ
17194 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
17195 _("smallest"));
17196 break;
17197
17198 case Tag_ARC_ABI_exceptions:
cd30bcef 17199 READ_ULEB (val, p, end);
53a346d8
CZ
17200 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
17201 : _("default"));
17202 break;
17203
17204 case Tag_ARC_ABI_double_size:
cd30bcef 17205 READ_ULEB (val, p, end);
53a346d8
CZ
17206 printf (" Tag_ARC_ABI_double_size: %d\n", val);
17207 break;
17208
17209 case Tag_ARC_ISA_config:
17210 printf (" Tag_ARC_ISA_config: ");
17211 p = display_tag_value (-1, p, end);
17212 break;
17213
17214 case Tag_ARC_ISA_apex:
17215 printf (" Tag_ARC_ISA_apex: ");
17216 p = display_tag_value (-1, p, end);
17217 break;
17218
17219 case Tag_ARC_ISA_mpy_option:
cd30bcef 17220 READ_ULEB (val, p, end);
53a346d8
CZ
17221 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
17222 break;
17223
db1e1b45 17224 case Tag_ARC_ATR_version:
cd30bcef 17225 READ_ULEB (val, p, end);
db1e1b45 17226 printf (" Tag_ARC_ATR_version: %d\n", val);
17227 break;
17228
53a346d8
CZ
17229 default:
17230 return display_tag_value (tag & 1, p, end);
17231 }
17232
17233 return p;
17234}
17235
11c1ff18
PB
17236/* ARM EABI attributes section. */
17237typedef struct
17238{
70e99720 17239 unsigned int tag;
2cf0635d 17240 const char * name;
11c1ff18 17241 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 17242 unsigned int type;
288f0ba2 17243 const char *const *table;
11c1ff18
PB
17244} arm_attr_public_tag;
17245
288f0ba2 17246static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 17247 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 17248 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
17249 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
17250 "v8.1-M.mainline", "v9"};
288f0ba2
AM
17251static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
17252static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 17253 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 17254static const char *const arm_attr_tag_FP_arch[] =
bca38921 17255 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 17256 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
17257static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
17258static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
17259 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
17260 "NEON for ARMv8.1"};
288f0ba2 17261static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
17262 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
17263 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 17264static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 17265 {"V6", "SB", "TLS", "Unused"};
288f0ba2 17266static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 17267 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 17268static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 17269 {"Absolute", "PC-relative", "None"};
288f0ba2 17270static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 17271 {"None", "direct", "GOT-indirect"};
288f0ba2 17272static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 17273 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
17274static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
17275static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 17276 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
17277static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
17278static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
17279static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 17280 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 17281static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 17282 {"Unused", "small", "int", "forced to int"};
288f0ba2 17283static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 17284 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 17285static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 17286 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 17287static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 17288 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 17289static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
17290 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17291 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 17292static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
17293 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17294 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
17295static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
17296static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 17297 {"Not Allowed", "Allowed"};
288f0ba2 17298static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 17299 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 17300static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 17301 {"Follow architecture", "Allowed"};
288f0ba2 17302static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 17303 {"Not Allowed", "Allowed"};
288f0ba2 17304static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 17305 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 17306 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
17307static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
17308static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 17309 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 17310 "TrustZone and Virtualization Extensions"};
288f0ba2 17311static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 17312 {"Not Allowed", "Allowed"};
11c1ff18 17313
288f0ba2 17314static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
17315 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
17316
99db83d0
AC
17317static const char * arm_attr_tag_PAC_extension[] =
17318 {"No PAC/AUT instructions",
17319 "PAC/AUT instructions permitted in the NOP space",
17320 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
17321
4b535030
AC
17322static const char * arm_attr_tag_BTI_extension[] =
17323 {"BTI instructions not permitted",
17324 "BTI instructions permitted in the NOP space",
17325 "BTI instructions permitted in the NOP and in the non-NOP space"};
17326
b81ee92f
AC
17327static const char * arm_attr_tag_BTI_use[] =
17328 {"Compiled without branch target enforcement",
17329 "Compiled with branch target enforcement"};
17330
c9fed665
AC
17331static const char * arm_attr_tag_PACRET_use[] =
17332 {"Compiled without return address signing and authentication",
17333 "Compiled with return address signing and authentication"};
17334
11c1ff18
PB
17335#define LOOKUP(id, name) \
17336 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 17337static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
17338{
17339 {4, "CPU_raw_name", 1, NULL},
17340 {5, "CPU_name", 1, NULL},
17341 LOOKUP(6, CPU_arch),
17342 {7, "CPU_arch_profile", 0, NULL},
17343 LOOKUP(8, ARM_ISA_use),
17344 LOOKUP(9, THUMB_ISA_use),
75375b3e 17345 LOOKUP(10, FP_arch),
11c1ff18 17346 LOOKUP(11, WMMX_arch),
f5f53991
AS
17347 LOOKUP(12, Advanced_SIMD_arch),
17348 LOOKUP(13, PCS_config),
11c1ff18
PB
17349 LOOKUP(14, ABI_PCS_R9_use),
17350 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 17351 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
17352 LOOKUP(17, ABI_PCS_GOT_use),
17353 LOOKUP(18, ABI_PCS_wchar_t),
17354 LOOKUP(19, ABI_FP_rounding),
17355 LOOKUP(20, ABI_FP_denormal),
17356 LOOKUP(21, ABI_FP_exceptions),
17357 LOOKUP(22, ABI_FP_user_exceptions),
17358 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
17359 {24, "ABI_align_needed", 0, NULL},
17360 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
17361 LOOKUP(26, ABI_enum_size),
17362 LOOKUP(27, ABI_HardFP_use),
17363 LOOKUP(28, ABI_VFP_args),
17364 LOOKUP(29, ABI_WMMX_args),
17365 LOOKUP(30, ABI_optimization_goals),
17366 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 17367 {32, "compatibility", 0, NULL},
f5f53991 17368 LOOKUP(34, CPU_unaligned_access),
75375b3e 17369 LOOKUP(36, FP_HP_extension),
8e79c3df 17370 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
17371 LOOKUP(42, MPextension_use),
17372 LOOKUP(44, DIV_use),
15afaa63 17373 LOOKUP(46, DSP_extension),
a7ad558c 17374 LOOKUP(48, MVE_arch),
99db83d0 17375 LOOKUP(50, PAC_extension),
4b535030 17376 LOOKUP(52, BTI_extension),
b81ee92f 17377 LOOKUP(74, BTI_use),
c9fed665 17378 LOOKUP(76, PACRET_use),
f5f53991
AS
17379 {64, "nodefaults", 0, NULL},
17380 {65, "also_compatible_with", 0, NULL},
17381 LOOKUP(66, T2EE_use),
17382 {67, "conformance", 1, NULL},
17383 LOOKUP(68, Virtualization_use),
cd21e546 17384 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
17385};
17386#undef LOOKUP
17387
11c1ff18 17388static unsigned char *
f6f0e17b
NC
17389display_arm_attribute (unsigned char * p,
17390 const unsigned char * const end)
11c1ff18 17391{
70e99720 17392 unsigned int tag;
70e99720 17393 unsigned int val;
2cf0635d 17394 arm_attr_public_tag * attr;
11c1ff18 17395 unsigned i;
70e99720 17396 unsigned int type;
11c1ff18 17397
cd30bcef 17398 READ_ULEB (tag, p, end);
11c1ff18 17399 attr = NULL;
2cf0635d 17400 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
17401 {
17402 if (arm_attr_public_tags[i].tag == tag)
17403 {
17404 attr = &arm_attr_public_tags[i];
17405 break;
17406 }
17407 }
17408
17409 if (attr)
17410 {
17411 printf (" Tag_%s: ", attr->name);
17412 switch (attr->type)
17413 {
17414 case 0:
17415 switch (tag)
17416 {
17417 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 17418 READ_ULEB (val, p, end);
11c1ff18
PB
17419 switch (val)
17420 {
2b692964
NC
17421 case 0: printf (_("None\n")); break;
17422 case 'A': printf (_("Application\n")); break;
17423 case 'R': printf (_("Realtime\n")); break;
17424 case 'M': printf (_("Microcontroller\n")); break;
17425 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
17426 default: printf ("??? (%d)\n", val); break;
17427 }
17428 break;
17429
75375b3e 17430 case 24: /* Tag_align_needed. */
cd30bcef 17431 READ_ULEB (val, p, end);
75375b3e
MGD
17432 switch (val)
17433 {
2b692964
NC
17434 case 0: printf (_("None\n")); break;
17435 case 1: printf (_("8-byte\n")); break;
17436 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
17437 case 3: printf ("??? 3\n"); break;
17438 default:
17439 if (val <= 12)
dd24e3da 17440 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17441 1 << val);
17442 else
17443 printf ("??? (%d)\n", val);
17444 break;
17445 }
17446 break;
17447
17448 case 25: /* Tag_align_preserved. */
cd30bcef 17449 READ_ULEB (val, p, end);
75375b3e
MGD
17450 switch (val)
17451 {
2b692964
NC
17452 case 0: printf (_("None\n")); break;
17453 case 1: printf (_("8-byte, except leaf SP\n")); break;
17454 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
17455 case 3: printf ("??? 3\n"); break;
17456 default:
17457 if (val <= 12)
dd24e3da 17458 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17459 1 << val);
17460 else
17461 printf ("??? (%d)\n", val);
17462 break;
17463 }
17464 break;
17465
11c1ff18 17466 case 32: /* Tag_compatibility. */
071436c6 17467 {
cd30bcef 17468 READ_ULEB (val, p, end);
071436c6 17469 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17470 if (p < end - 1)
17471 {
17472 size_t maxlen = (end - p) - 1;
17473
17474 print_symbol ((int) maxlen, (const char *) p);
17475 p += strnlen ((char *) p, maxlen) + 1;
17476 }
17477 else
17478 {
17479 printf (_("<corrupt>"));
17480 p = (unsigned char *) end;
17481 }
071436c6 17482 putchar ('\n');
071436c6 17483 }
11c1ff18
PB
17484 break;
17485
f5f53991 17486 case 64: /* Tag_nodefaults. */
541a3cbd
NC
17487 /* PR 17531: file: 001-505008-0.01. */
17488 if (p < end)
17489 p++;
2b692964 17490 printf (_("True\n"));
f5f53991
AS
17491 break;
17492
17493 case 65: /* Tag_also_compatible_with. */
cd30bcef 17494 READ_ULEB (val, p, end);
f5f53991
AS
17495 if (val == 6 /* Tag_CPU_arch. */)
17496 {
cd30bcef 17497 READ_ULEB (val, p, end);
071436c6 17498 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
17499 printf ("??? (%d)\n", val);
17500 else
17501 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17502 }
17503 else
17504 printf ("???\n");
071436c6
NC
17505 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17506 ;
f5f53991
AS
17507 break;
17508
11c1ff18 17509 default:
bee0ee85
NC
17510 printf (_("<unknown: %d>\n"), tag);
17511 break;
11c1ff18
PB
17512 }
17513 return p;
17514
17515 case 1:
f6f0e17b 17516 return display_tag_value (-1, p, end);
11c1ff18 17517 case 2:
f6f0e17b 17518 return display_tag_value (0, p, end);
11c1ff18
PB
17519
17520 default:
17521 assert (attr->type & 0x80);
cd30bcef 17522 READ_ULEB (val, p, end);
11c1ff18
PB
17523 type = attr->type & 0x7f;
17524 if (val >= type)
17525 printf ("??? (%d)\n", val);
17526 else
17527 printf ("%s\n", attr->table[val]);
17528 return p;
17529 }
17530 }
11c1ff18 17531
f6f0e17b 17532 return display_tag_value (tag, p, end);
11c1ff18
PB
17533}
17534
104d59d1 17535static unsigned char *
60bca95a 17536display_gnu_attribute (unsigned char * p,
60abdbed 17537 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 17538 const unsigned char * const end)
104d59d1 17539{
cd30bcef 17540 unsigned int tag;
60abdbed 17541 unsigned int val;
104d59d1 17542
cd30bcef 17543 READ_ULEB (tag, p, end);
104d59d1
JM
17544
17545 /* Tag_compatibility is the only generic GNU attribute defined at
17546 present. */
17547 if (tag == 32)
17548 {
cd30bcef 17549 READ_ULEB (val, p, end);
071436c6
NC
17550
17551 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
17552 if (p == end)
17553 {
071436c6 17554 printf (_("<corrupt>\n"));
f6f0e17b
NC
17555 warn (_("corrupt vendor attribute\n"));
17556 }
17557 else
17558 {
4082ef84
NC
17559 if (p < end - 1)
17560 {
17561 size_t maxlen = (end - p) - 1;
071436c6 17562
4082ef84
NC
17563 print_symbol ((int) maxlen, (const char *) p);
17564 p += strnlen ((char *) p, maxlen) + 1;
17565 }
17566 else
17567 {
17568 printf (_("<corrupt>"));
17569 p = (unsigned char *) end;
17570 }
071436c6 17571 putchar ('\n');
f6f0e17b 17572 }
104d59d1
JM
17573 return p;
17574 }
17575
17576 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 17577 return display_proc_gnu_attribute (p, tag, end);
104d59d1 17578
f6f0e17b 17579 return display_tag_value (tag, p, end);
104d59d1
JM
17580}
17581
85f7484a
PB
17582static unsigned char *
17583display_m68k_gnu_attribute (unsigned char * p,
17584 unsigned int tag,
17585 const unsigned char * const end)
17586{
17587 unsigned int val;
17588
17589 if (tag == Tag_GNU_M68K_ABI_FP)
17590 {
17591 printf (" Tag_GNU_M68K_ABI_FP: ");
17592 if (p == end)
17593 {
17594 printf (_("<corrupt>\n"));
17595 return p;
17596 }
17597 READ_ULEB (val, p, end);
17598
17599 if (val > 3)
17600 printf ("(%#x), ", val);
17601
17602 switch (val & 3)
17603 {
17604 case 0:
17605 printf (_("unspecified hard/soft float\n"));
17606 break;
17607 case 1:
17608 printf (_("hard float\n"));
17609 break;
17610 case 2:
17611 printf (_("soft float\n"));
17612 break;
17613 }
17614 return p;
17615 }
17616
17617 return display_tag_value (tag & 1, p, end);
17618}
17619
34c8bcba 17620static unsigned char *
f6f0e17b 17621display_power_gnu_attribute (unsigned char * p,
60abdbed 17622 unsigned int tag,
f6f0e17b 17623 const unsigned char * const end)
34c8bcba 17624{
005d79fd 17625 unsigned int val;
34c8bcba
JM
17626
17627 if (tag == Tag_GNU_Power_ABI_FP)
17628 {
34c8bcba 17629 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 17630 if (p == end)
005d79fd
AM
17631 {
17632 printf (_("<corrupt>\n"));
17633 return p;
17634 }
cd30bcef 17635 READ_ULEB (val, p, end);
60bca95a 17636
005d79fd
AM
17637 if (val > 15)
17638 printf ("(%#x), ", val);
17639
17640 switch (val & 3)
34c8bcba
JM
17641 {
17642 case 0:
005d79fd 17643 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17644 break;
17645 case 1:
005d79fd 17646 printf (_("hard float, "));
34c8bcba
JM
17647 break;
17648 case 2:
005d79fd 17649 printf (_("soft float, "));
34c8bcba 17650 break;
3c7b9897 17651 case 3:
005d79fd 17652 printf (_("single-precision hard float, "));
3c7b9897 17653 break;
005d79fd
AM
17654 }
17655
17656 switch (val & 0xC)
17657 {
17658 case 0:
17659 printf (_("unspecified long double\n"));
17660 break;
17661 case 4:
17662 printf (_("128-bit IBM long double\n"));
17663 break;
17664 case 8:
17665 printf (_("64-bit long double\n"));
17666 break;
17667 case 12:
17668 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17669 break;
17670 }
17671 return p;
005d79fd 17672 }
34c8bcba 17673
c6e65352
DJ
17674 if (tag == Tag_GNU_Power_ABI_Vector)
17675 {
c6e65352 17676 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17677 if (p == end)
005d79fd
AM
17678 {
17679 printf (_("<corrupt>\n"));
17680 return p;
17681 }
cd30bcef 17682 READ_ULEB (val, p, end);
005d79fd
AM
17683
17684 if (val > 3)
17685 printf ("(%#x), ", val);
17686
17687 switch (val & 3)
c6e65352
DJ
17688 {
17689 case 0:
005d79fd 17690 printf (_("unspecified\n"));
c6e65352
DJ
17691 break;
17692 case 1:
005d79fd 17693 printf (_("generic\n"));
c6e65352
DJ
17694 break;
17695 case 2:
17696 printf ("AltiVec\n");
17697 break;
17698 case 3:
17699 printf ("SPE\n");
17700 break;
c6e65352
DJ
17701 }
17702 return p;
005d79fd 17703 }
c6e65352 17704
f82e0623
NF
17705 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17706 {
005d79fd 17707 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17708 if (p == end)
f6f0e17b 17709 {
005d79fd 17710 printf (_("<corrupt>\n"));
f6f0e17b
NC
17711 return p;
17712 }
cd30bcef 17713 READ_ULEB (val, p, end);
0b4362b0 17714
005d79fd
AM
17715 if (val > 2)
17716 printf ("(%#x), ", val);
17717
17718 switch (val & 3)
17719 {
17720 case 0:
17721 printf (_("unspecified\n"));
17722 break;
17723 case 1:
17724 printf ("r3/r4\n");
17725 break;
17726 case 2:
17727 printf (_("memory\n"));
17728 break;
17729 case 3:
17730 printf ("???\n");
17731 break;
17732 }
f82e0623
NF
17733 return p;
17734 }
17735
f6f0e17b 17736 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17737}
17738
643f7afb
AK
17739static unsigned char *
17740display_s390_gnu_attribute (unsigned char * p,
60abdbed 17741 unsigned int tag,
643f7afb
AK
17742 const unsigned char * const end)
17743{
cd30bcef 17744 unsigned int val;
643f7afb
AK
17745
17746 if (tag == Tag_GNU_S390_ABI_Vector)
17747 {
643f7afb 17748 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17749 READ_ULEB (val, p, end);
643f7afb
AK
17750
17751 switch (val)
17752 {
17753 case 0:
17754 printf (_("any\n"));
17755 break;
17756 case 1:
17757 printf (_("software\n"));
17758 break;
17759 case 2:
17760 printf (_("hardware\n"));
17761 break;
17762 default:
17763 printf ("??? (%d)\n", val);
17764 break;
17765 }
17766 return p;
17767 }
17768
17769 return display_tag_value (tag & 1, p, end);
17770}
17771
9e8c70f9 17772static void
60abdbed 17773display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17774{
17775 if (mask)
17776 {
015dc7e1 17777 bool first = true;
071436c6 17778
9e8c70f9 17779 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17780 fputs ("mul32", stdout), first = false;
9e8c70f9 17781 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17782 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17783 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17784 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17785 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17786 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17787 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17788 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17789 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17790 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17791 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17792 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17793 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17794 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17795 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17796 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17797 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17798 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17799 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17800 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17801 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17802 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17803 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17804 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17805 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17806 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17807 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17808 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17809 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17810 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17811 }
17812 else
071436c6
NC
17813 fputc ('0', stdout);
17814 fputc ('\n', stdout);
9e8c70f9
DM
17815}
17816
3d68f91c 17817static void
60abdbed 17818display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17819{
17820 if (mask)
17821 {
015dc7e1 17822 bool first = true;
071436c6 17823
3d68f91c 17824 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17825 fputs ("fjathplus", stdout), first = false;
3d68f91c 17826 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17827 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17828 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17829 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17830 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17831 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17832 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17833 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17834 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17835 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17836 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17837 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17838 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17839 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17840 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17841 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17842 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17843 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17844 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17845 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17846 }
17847 else
071436c6
NC
17848 fputc ('0', stdout);
17849 fputc ('\n', stdout);
3d68f91c
JM
17850}
17851
9e8c70f9 17852static unsigned char *
f6f0e17b 17853display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17854 unsigned int tag,
f6f0e17b 17855 const unsigned char * const end)
9e8c70f9 17856{
cd30bcef 17857 unsigned int val;
3d68f91c 17858
9e8c70f9
DM
17859 if (tag == Tag_GNU_Sparc_HWCAPS)
17860 {
cd30bcef 17861 READ_ULEB (val, p, end);
9e8c70f9 17862 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17863 display_sparc_hwcaps (val);
17864 return p;
3d68f91c
JM
17865 }
17866 if (tag == Tag_GNU_Sparc_HWCAPS2)
17867 {
cd30bcef 17868 READ_ULEB (val, p, end);
3d68f91c
JM
17869 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17870 display_sparc_hwcaps2 (val);
17871 return p;
17872 }
9e8c70f9 17873
f6f0e17b 17874 return display_tag_value (tag, p, end);
9e8c70f9
DM
17875}
17876
351cdf24 17877static void
32ec8896 17878print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17879{
17880 switch (val)
17881 {
17882 case Val_GNU_MIPS_ABI_FP_ANY:
17883 printf (_("Hard or soft float\n"));
17884 break;
17885 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17886 printf (_("Hard float (double precision)\n"));
17887 break;
17888 case Val_GNU_MIPS_ABI_FP_SINGLE:
17889 printf (_("Hard float (single precision)\n"));
17890 break;
17891 case Val_GNU_MIPS_ABI_FP_SOFT:
17892 printf (_("Soft float\n"));
17893 break;
17894 case Val_GNU_MIPS_ABI_FP_OLD_64:
17895 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17896 break;
17897 case Val_GNU_MIPS_ABI_FP_XX:
17898 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17899 break;
17900 case Val_GNU_MIPS_ABI_FP_64:
17901 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17902 break;
17903 case Val_GNU_MIPS_ABI_FP_64A:
17904 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17905 break;
3350cc01
CM
17906 case Val_GNU_MIPS_ABI_FP_NAN2008:
17907 printf (_("NaN 2008 compatibility\n"));
17908 break;
351cdf24
MF
17909 default:
17910 printf ("??? (%d)\n", val);
17911 break;
17912 }
17913}
17914
2cf19d5c 17915static unsigned char *
f6f0e17b 17916display_mips_gnu_attribute (unsigned char * p,
60abdbed 17917 unsigned int tag,
f6f0e17b 17918 const unsigned char * const end)
2cf19d5c 17919{
2cf19d5c
JM
17920 if (tag == Tag_GNU_MIPS_ABI_FP)
17921 {
32ec8896 17922 unsigned int val;
f6f0e17b 17923
2cf19d5c 17924 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17925 READ_ULEB (val, p, end);
351cdf24 17926 print_mips_fp_abi_value (val);
2cf19d5c
JM
17927 return p;
17928 }
17929
a9f58168
CF
17930 if (tag == Tag_GNU_MIPS_ABI_MSA)
17931 {
32ec8896 17932 unsigned int val;
a9f58168 17933
a9f58168 17934 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17935 READ_ULEB (val, p, end);
a9f58168
CF
17936
17937 switch (val)
17938 {
17939 case Val_GNU_MIPS_ABI_MSA_ANY:
17940 printf (_("Any MSA or not\n"));
17941 break;
17942 case Val_GNU_MIPS_ABI_MSA_128:
17943 printf (_("128-bit MSA\n"));
17944 break;
17945 default:
17946 printf ("??? (%d)\n", val);
17947 break;
17948 }
17949 return p;
17950 }
17951
f6f0e17b 17952 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17953}
17954
59e6276b 17955static unsigned char *
f6f0e17b
NC
17956display_tic6x_attribute (unsigned char * p,
17957 const unsigned char * const end)
59e6276b 17958{
60abdbed 17959 unsigned int tag;
cd30bcef 17960 unsigned int val;
59e6276b 17961
cd30bcef 17962 READ_ULEB (tag, p, end);
59e6276b
JM
17963
17964 switch (tag)
17965 {
75fa6dc1 17966 case Tag_ISA:
75fa6dc1 17967 printf (" Tag_ISA: ");
cd30bcef 17968 READ_ULEB (val, p, end);
59e6276b
JM
17969
17970 switch (val)
17971 {
75fa6dc1 17972 case C6XABI_Tag_ISA_none:
59e6276b
JM
17973 printf (_("None\n"));
17974 break;
75fa6dc1 17975 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17976 printf ("C62x\n");
17977 break;
75fa6dc1 17978 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17979 printf ("C67x\n");
17980 break;
75fa6dc1 17981 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17982 printf ("C67x+\n");
17983 break;
75fa6dc1 17984 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17985 printf ("C64x\n");
17986 break;
75fa6dc1 17987 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17988 printf ("C64x+\n");
17989 break;
75fa6dc1 17990 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17991 printf ("C674x\n");
17992 break;
17993 default:
17994 printf ("??? (%d)\n", val);
17995 break;
17996 }
17997 return p;
17998
87779176 17999 case Tag_ABI_wchar_t:
87779176 18000 printf (" Tag_ABI_wchar_t: ");
cd30bcef 18001 READ_ULEB (val, p, end);
87779176
JM
18002 switch (val)
18003 {
18004 case 0:
18005 printf (_("Not used\n"));
18006 break;
18007 case 1:
18008 printf (_("2 bytes\n"));
18009 break;
18010 case 2:
18011 printf (_("4 bytes\n"));
18012 break;
18013 default:
18014 printf ("??? (%d)\n", val);
18015 break;
18016 }
18017 return p;
18018
18019 case Tag_ABI_stack_align_needed:
87779176 18020 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 18021 READ_ULEB (val, p, end);
87779176
JM
18022 switch (val)
18023 {
18024 case 0:
18025 printf (_("8-byte\n"));
18026 break;
18027 case 1:
18028 printf (_("16-byte\n"));
18029 break;
18030 default:
18031 printf ("??? (%d)\n", val);
18032 break;
18033 }
18034 return p;
18035
18036 case Tag_ABI_stack_align_preserved:
cd30bcef 18037 READ_ULEB (val, p, end);
87779176
JM
18038 printf (" Tag_ABI_stack_align_preserved: ");
18039 switch (val)
18040 {
18041 case 0:
18042 printf (_("8-byte\n"));
18043 break;
18044 case 1:
18045 printf (_("16-byte\n"));
18046 break;
18047 default:
18048 printf ("??? (%d)\n", val);
18049 break;
18050 }
18051 return p;
18052
b5593623 18053 case Tag_ABI_DSBT:
cd30bcef 18054 READ_ULEB (val, p, end);
b5593623
JM
18055 printf (" Tag_ABI_DSBT: ");
18056 switch (val)
18057 {
18058 case 0:
18059 printf (_("DSBT addressing not used\n"));
18060 break;
18061 case 1:
18062 printf (_("DSBT addressing used\n"));
18063 break;
18064 default:
18065 printf ("??? (%d)\n", val);
18066 break;
18067 }
18068 return p;
18069
87779176 18070 case Tag_ABI_PID:
cd30bcef 18071 READ_ULEB (val, p, end);
87779176
JM
18072 printf (" Tag_ABI_PID: ");
18073 switch (val)
18074 {
18075 case 0:
18076 printf (_("Data addressing position-dependent\n"));
18077 break;
18078 case 1:
18079 printf (_("Data addressing position-independent, GOT near DP\n"));
18080 break;
18081 case 2:
18082 printf (_("Data addressing position-independent, GOT far from DP\n"));
18083 break;
18084 default:
18085 printf ("??? (%d)\n", val);
18086 break;
18087 }
18088 return p;
18089
18090 case Tag_ABI_PIC:
cd30bcef 18091 READ_ULEB (val, p, end);
87779176
JM
18092 printf (" Tag_ABI_PIC: ");
18093 switch (val)
18094 {
18095 case 0:
18096 printf (_("Code addressing position-dependent\n"));
18097 break;
18098 case 1:
18099 printf (_("Code addressing position-independent\n"));
18100 break;
18101 default:
18102 printf ("??? (%d)\n", val);
18103 break;
18104 }
18105 return p;
18106
18107 case Tag_ABI_array_object_alignment:
cd30bcef 18108 READ_ULEB (val, p, end);
87779176
JM
18109 printf (" Tag_ABI_array_object_alignment: ");
18110 switch (val)
18111 {
18112 case 0:
18113 printf (_("8-byte\n"));
18114 break;
18115 case 1:
18116 printf (_("4-byte\n"));
18117 break;
18118 case 2:
18119 printf (_("16-byte\n"));
18120 break;
18121 default:
18122 printf ("??? (%d)\n", val);
18123 break;
18124 }
18125 return p;
18126
18127 case Tag_ABI_array_object_align_expected:
cd30bcef 18128 READ_ULEB (val, p, end);
87779176
JM
18129 printf (" Tag_ABI_array_object_align_expected: ");
18130 switch (val)
18131 {
18132 case 0:
18133 printf (_("8-byte\n"));
18134 break;
18135 case 1:
18136 printf (_("4-byte\n"));
18137 break;
18138 case 2:
18139 printf (_("16-byte\n"));
18140 break;
18141 default:
18142 printf ("??? (%d)\n", val);
18143 break;
18144 }
18145 return p;
18146
3cbd1c06 18147 case Tag_ABI_compatibility:
071436c6 18148 {
cd30bcef 18149 READ_ULEB (val, p, end);
071436c6 18150 printf (" Tag_ABI_compatibility: ");
071436c6 18151 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
18152 if (p < end - 1)
18153 {
18154 size_t maxlen = (end - p) - 1;
18155
18156 print_symbol ((int) maxlen, (const char *) p);
18157 p += strnlen ((char *) p, maxlen) + 1;
18158 }
18159 else
18160 {
18161 printf (_("<corrupt>"));
18162 p = (unsigned char *) end;
18163 }
071436c6 18164 putchar ('\n');
071436c6
NC
18165 return p;
18166 }
87779176
JM
18167
18168 case Tag_ABI_conformance:
071436c6 18169 {
4082ef84
NC
18170 printf (" Tag_ABI_conformance: \"");
18171 if (p < end - 1)
18172 {
18173 size_t maxlen = (end - p) - 1;
071436c6 18174
4082ef84
NC
18175 print_symbol ((int) maxlen, (const char *) p);
18176 p += strnlen ((char *) p, maxlen) + 1;
18177 }
18178 else
18179 {
18180 printf (_("<corrupt>"));
18181 p = (unsigned char *) end;
18182 }
071436c6 18183 printf ("\"\n");
071436c6
NC
18184 return p;
18185 }
59e6276b
JM
18186 }
18187
f6f0e17b
NC
18188 return display_tag_value (tag, p, end);
18189}
59e6276b 18190
f6f0e17b 18191static void
60abdbed 18192display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 18193{
26c527e6 18194 uint64_t addr = 0;
f6f0e17b
NC
18195 size_t bytes = end - p;
18196
feceaa59 18197 assert (end >= p);
f6f0e17b 18198 while (bytes)
87779176 18199 {
f6f0e17b
NC
18200 int j;
18201 int k;
18202 int lbytes = (bytes > 16 ? 16 : bytes);
18203
26c527e6 18204 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
18205
18206 for (j = 0; j < 16; j++)
18207 {
18208 if (j < lbytes)
18209 printf ("%2.2x", p[j]);
18210 else
18211 printf (" ");
18212
18213 if ((j & 3) == 3)
18214 printf (" ");
18215 }
18216
18217 for (j = 0; j < lbytes; j++)
18218 {
18219 k = p[j];
18220 if (k >= ' ' && k < 0x7f)
18221 printf ("%c", k);
18222 else
18223 printf (".");
18224 }
18225
18226 putchar ('\n');
18227
18228 p += lbytes;
18229 bytes -= lbytes;
18230 addr += lbytes;
87779176 18231 }
59e6276b 18232
f6f0e17b 18233 putchar ('\n');
59e6276b
JM
18234}
18235
13761a11 18236static unsigned char *
b0191216 18237display_msp430_attribute (unsigned char * p,
26c527e6 18238 const unsigned char * const end)
13761a11 18239{
26c527e6
AM
18240 uint64_t val;
18241 uint64_t tag;
13761a11 18242
cd30bcef 18243 READ_ULEB (tag, p, end);
0b4362b0 18244
13761a11
NC
18245 switch (tag)
18246 {
18247 case OFBA_MSPABI_Tag_ISA:
13761a11 18248 printf (" Tag_ISA: ");
cd30bcef 18249 READ_ULEB (val, p, end);
13761a11
NC
18250 switch (val)
18251 {
18252 case 0: printf (_("None\n")); break;
18253 case 1: printf (_("MSP430\n")); break;
18254 case 2: printf (_("MSP430X\n")); break;
26c527e6 18255 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18256 }
18257 break;
18258
18259 case OFBA_MSPABI_Tag_Code_Model:
13761a11 18260 printf (" Tag_Code_Model: ");
cd30bcef 18261 READ_ULEB (val, p, end);
13761a11
NC
18262 switch (val)
18263 {
18264 case 0: printf (_("None\n")); break;
18265 case 1: printf (_("Small\n")); break;
18266 case 2: printf (_("Large\n")); break;
26c527e6 18267 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18268 }
18269 break;
18270
18271 case OFBA_MSPABI_Tag_Data_Model:
13761a11 18272 printf (" Tag_Data_Model: ");
cd30bcef 18273 READ_ULEB (val, p, end);
13761a11
NC
18274 switch (val)
18275 {
18276 case 0: printf (_("None\n")); break;
18277 case 1: printf (_("Small\n")); break;
18278 case 2: printf (_("Large\n")); break;
18279 case 3: printf (_("Restricted Large\n")); break;
26c527e6 18280 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18281 }
18282 break;
18283
18284 default:
26c527e6 18285 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
18286
18287 if (tag & 1)
18288 {
071436c6 18289 putchar ('"');
4082ef84
NC
18290 if (p < end - 1)
18291 {
18292 size_t maxlen = (end - p) - 1;
18293
18294 print_symbol ((int) maxlen, (const char *) p);
18295 p += strnlen ((char *) p, maxlen) + 1;
18296 }
18297 else
18298 {
18299 printf (_("<corrupt>"));
18300 p = (unsigned char *) end;
18301 }
071436c6 18302 printf ("\"\n");
13761a11
NC
18303 }
18304 else
18305 {
cd30bcef 18306 READ_ULEB (val, p, end);
26c527e6 18307 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
18308 }
18309 break;
18310 }
18311
4082ef84 18312 assert (p <= end);
13761a11
NC
18313 return p;
18314}
18315
c0ea7c52
JL
18316static unsigned char *
18317display_msp430_gnu_attribute (unsigned char * p,
18318 unsigned int tag,
18319 const unsigned char * const end)
18320{
18321 if (tag == Tag_GNU_MSP430_Data_Region)
18322 {
26c527e6 18323 uint64_t val;
c0ea7c52 18324
c0ea7c52 18325 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 18326 READ_ULEB (val, p, end);
c0ea7c52
JL
18327
18328 switch (val)
18329 {
18330 case Val_GNU_MSP430_Data_Region_Any:
18331 printf (_("Any Region\n"));
18332 break;
18333 case Val_GNU_MSP430_Data_Region_Lower:
18334 printf (_("Lower Region Only\n"));
18335 break;
18336 default:
26c527e6 18337 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
18338 }
18339 return p;
18340 }
18341 return display_tag_value (tag & 1, p, end);
18342}
18343
2dc8dd17
JW
18344struct riscv_attr_tag_t {
18345 const char *name;
cd30bcef 18346 unsigned int tag;
2dc8dd17
JW
18347};
18348
18349static struct riscv_attr_tag_t riscv_attr_tag[] =
18350{
18351#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
18352 T(arch),
18353 T(priv_spec),
18354 T(priv_spec_minor),
18355 T(priv_spec_revision),
18356 T(unaligned_access),
18357 T(stack_align),
18358#undef T
18359};
18360
18361static unsigned char *
18362display_riscv_attribute (unsigned char *p,
18363 const unsigned char * const end)
18364{
26c527e6
AM
18365 uint64_t val;
18366 uint64_t tag;
2dc8dd17
JW
18367 struct riscv_attr_tag_t *attr = NULL;
18368 unsigned i;
18369
cd30bcef 18370 READ_ULEB (tag, p, end);
2dc8dd17
JW
18371
18372 /* Find the name of attribute. */
18373 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
18374 {
18375 if (riscv_attr_tag[i].tag == tag)
18376 {
18377 attr = &riscv_attr_tag[i];
18378 break;
18379 }
18380 }
18381
18382 if (attr)
18383 printf (" %s: ", attr->name);
18384 else
18385 return display_tag_value (tag, p, end);
18386
18387 switch (tag)
18388 {
18389 case Tag_RISCV_priv_spec:
18390 case Tag_RISCV_priv_spec_minor:
18391 case Tag_RISCV_priv_spec_revision:
cd30bcef 18392 READ_ULEB (val, p, end);
26c527e6 18393 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
18394 break;
18395 case Tag_RISCV_unaligned_access:
cd30bcef 18396 READ_ULEB (val, p, end);
2dc8dd17
JW
18397 switch (val)
18398 {
18399 case 0:
18400 printf (_("No unaligned access\n"));
18401 break;
18402 case 1:
18403 printf (_("Unaligned access\n"));
18404 break;
18405 }
18406 break;
18407 case Tag_RISCV_stack_align:
cd30bcef 18408 READ_ULEB (val, p, end);
26c527e6 18409 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
18410 break;
18411 case Tag_RISCV_arch:
18412 p = display_tag_value (-1, p, end);
18413 break;
18414 default:
18415 return display_tag_value (tag, p, end);
18416 }
18417
18418 return p;
18419}
18420
0861f561
CQ
18421static unsigned char *
18422display_csky_attribute (unsigned char * p,
18423 const unsigned char * const end)
18424{
26c527e6
AM
18425 uint64_t tag;
18426 uint64_t val;
0861f561
CQ
18427 READ_ULEB (tag, p, end);
18428
18429 if (tag >= Tag_CSKY_MAX)
18430 {
18431 return display_tag_value (-1, p, end);
18432 }
18433
18434 switch (tag)
18435 {
18436 case Tag_CSKY_ARCH_NAME:
18437 printf (" Tag_CSKY_ARCH_NAME:\t\t");
18438 return display_tag_value (-1, p, end);
18439 case Tag_CSKY_CPU_NAME:
18440 printf (" Tag_CSKY_CPU_NAME:\t\t");
18441 return display_tag_value (-1, p, end);
18442
18443 case Tag_CSKY_ISA_FLAGS:
18444 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
18445 return display_tag_value (0, p, end);
18446 case Tag_CSKY_ISA_EXT_FLAGS:
18447 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
18448 return display_tag_value (0, p, end);
18449
18450 case Tag_CSKY_DSP_VERSION:
18451 printf (" Tag_CSKY_DSP_VERSION:\t\t");
18452 READ_ULEB (val, p, end);
18453 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
18454 printf ("DSP Extension\n");
18455 else if (val == VAL_CSKY_DSP_VERSION_2)
18456 printf ("DSP 2.0\n");
18457 break;
18458
18459 case Tag_CSKY_VDSP_VERSION:
18460 printf (" Tag_CSKY_VDSP_VERSION:\t");
18461 READ_ULEB (val, p, end);
26c527e6 18462 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
18463 break;
18464
18465 case Tag_CSKY_FPU_VERSION:
18466 printf (" Tag_CSKY_FPU_VERSION:\t\t");
18467 READ_ULEB (val, p, end);
18468 if (val == VAL_CSKY_FPU_VERSION_1)
18469 printf ("ABIV1 FPU Version 1\n");
18470 else if (val == VAL_CSKY_FPU_VERSION_2)
18471 printf ("FPU Version 2\n");
18472 break;
18473
18474 case Tag_CSKY_FPU_ABI:
18475 printf (" Tag_CSKY_FPU_ABI:\t\t");
18476 READ_ULEB (val, p, end);
18477 if (val == VAL_CSKY_FPU_ABI_HARD)
18478 printf ("Hard\n");
18479 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18480 printf ("SoftFP\n");
18481 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18482 printf ("Soft\n");
18483 break;
18484 case Tag_CSKY_FPU_ROUNDING:
18485 READ_ULEB (val, p, end);
f253158f
NC
18486 if (val == 1)
18487 {
18488 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18489 printf ("Needed\n");
18490 }
0861f561
CQ
18491 break;
18492 case Tag_CSKY_FPU_DENORMAL:
18493 READ_ULEB (val, p, end);
f253158f
NC
18494 if (val == 1)
18495 {
18496 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18497 printf ("Needed\n");
18498 }
0861f561
CQ
18499 break;
18500 case Tag_CSKY_FPU_Exception:
18501 READ_ULEB (val, p, end);
f253158f
NC
18502 if (val == 1)
18503 {
18504 printf (" Tag_CSKY_FPU_Exception:\t");
18505 printf ("Needed\n");
18506 }
0861f561
CQ
18507 break;
18508 case Tag_CSKY_FPU_NUMBER_MODULE:
18509 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18510 return display_tag_value (-1, p, end);
18511 case Tag_CSKY_FPU_HARDFP:
18512 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18513 READ_ULEB (val, p, end);
18514 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18515 printf (" Half");
18516 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18517 printf (" Single");
18518 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18519 printf (" Double");
18520 printf ("\n");
18521 break;
18522 default:
18523 return display_tag_value (tag, p, end);
18524 }
18525 return p;
18526}
18527
015dc7e1 18528static bool
dda8d76d 18529process_attributes (Filedata * filedata,
60bca95a 18530 const char * public_name,
104d59d1 18531 unsigned int proc_type,
f6f0e17b 18532 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 18533 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 18534{
2cf0635d 18535 Elf_Internal_Shdr * sect;
11c1ff18 18536 unsigned i;
015dc7e1 18537 bool res = true;
11c1ff18
PB
18538
18539 /* Find the section header so that we get the size. */
dda8d76d
NC
18540 for (i = 0, sect = filedata->section_headers;
18541 i < filedata->file_header.e_shnum;
11c1ff18
PB
18542 i++, sect++)
18543 {
071436c6
NC
18544 unsigned char * contents;
18545 unsigned char * p;
18546
104d59d1 18547 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
18548 continue;
18549
dda8d76d 18550 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 18551 sect->sh_size, _("attributes"));
60bca95a 18552 if (contents == NULL)
32ec8896 18553 {
015dc7e1 18554 res = false;
32ec8896
NC
18555 continue;
18556 }
60bca95a 18557
11c1ff18 18558 p = contents;
60abdbed
NC
18559 /* The first character is the version of the attributes.
18560 Currently only version 1, (aka 'A') is recognised here. */
18561 if (*p != 'A')
32ec8896
NC
18562 {
18563 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 18564 res = false;
32ec8896 18565 }
60abdbed 18566 else
11c1ff18 18567 {
625d49fc 18568 uint64_t section_len;
071436c6
NC
18569
18570 section_len = sect->sh_size - 1;
11c1ff18 18571 p++;
60bca95a 18572
071436c6 18573 while (section_len > 0)
11c1ff18 18574 {
625d49fc 18575 uint64_t attr_len;
e9847026 18576 unsigned int namelen;
015dc7e1
AM
18577 bool public_section;
18578 bool gnu_section;
11c1ff18 18579
071436c6 18580 if (section_len <= 4)
e0a31db1
NC
18581 {
18582 error (_("Tag section ends prematurely\n"));
015dc7e1 18583 res = false;
e0a31db1
NC
18584 break;
18585 }
071436c6 18586 attr_len = byte_get (p, 4);
11c1ff18 18587 p += 4;
60bca95a 18588
071436c6 18589 if (attr_len > section_len)
11c1ff18 18590 {
071436c6
NC
18591 error (_("Bad attribute length (%u > %u)\n"),
18592 (unsigned) attr_len, (unsigned) section_len);
18593 attr_len = section_len;
015dc7e1 18594 res = false;
11c1ff18 18595 }
74e1a04b 18596 /* PR 17531: file: 001-101425-0.004 */
071436c6 18597 else if (attr_len < 5)
74e1a04b 18598 {
071436c6 18599 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 18600 res = false;
74e1a04b
NC
18601 break;
18602 }
e9847026 18603
071436c6
NC
18604 section_len -= attr_len;
18605 attr_len -= 4;
18606
18607 namelen = strnlen ((char *) p, attr_len) + 1;
18608 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
18609 {
18610 error (_("Corrupt attribute section name\n"));
015dc7e1 18611 res = false;
e9847026
NC
18612 break;
18613 }
18614
071436c6
NC
18615 printf (_("Attribute Section: "));
18616 print_symbol (INT_MAX, (const char *) p);
18617 putchar ('\n');
60bca95a
NC
18618
18619 if (public_name && streq ((char *) p, public_name))
015dc7e1 18620 public_section = true;
11c1ff18 18621 else
015dc7e1 18622 public_section = false;
60bca95a
NC
18623
18624 if (streq ((char *) p, "gnu"))
015dc7e1 18625 gnu_section = true;
104d59d1 18626 else
015dc7e1 18627 gnu_section = false;
60bca95a 18628
11c1ff18 18629 p += namelen;
071436c6 18630 attr_len -= namelen;
e0a31db1 18631
071436c6 18632 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18633 {
e0a31db1 18634 int tag;
cd30bcef 18635 unsigned int val;
625d49fc 18636 uint64_t size;
071436c6 18637 unsigned char * end;
60bca95a 18638
e0a31db1 18639 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18640 if (attr_len < 6)
e0a31db1
NC
18641 {
18642 error (_("Unused bytes at end of section\n"));
015dc7e1 18643 res = false;
e0a31db1
NC
18644 section_len = 0;
18645 break;
18646 }
18647
18648 tag = *(p++);
11c1ff18 18649 size = byte_get (p, 4);
071436c6 18650 if (size > attr_len)
11c1ff18 18651 {
e9847026 18652 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18653 (unsigned) size, (unsigned) attr_len);
015dc7e1 18654 res = false;
071436c6 18655 size = attr_len;
11c1ff18 18656 }
e0a31db1
NC
18657 /* PR binutils/17531: Safe handling of corrupt files. */
18658 if (size < 6)
18659 {
18660 error (_("Bad subsection length (%u < 6)\n"),
18661 (unsigned) size);
015dc7e1 18662 res = false;
e0a31db1
NC
18663 section_len = 0;
18664 break;
18665 }
60bca95a 18666
071436c6 18667 attr_len -= size;
11c1ff18 18668 end = p + size - 1;
071436c6 18669 assert (end <= contents + sect->sh_size);
11c1ff18 18670 p += 4;
60bca95a 18671
11c1ff18
PB
18672 switch (tag)
18673 {
18674 case 1:
2b692964 18675 printf (_("File Attributes\n"));
11c1ff18
PB
18676 break;
18677 case 2:
2b692964 18678 printf (_("Section Attributes:"));
11c1ff18
PB
18679 goto do_numlist;
18680 case 3:
2b692964 18681 printf (_("Symbol Attributes:"));
1a0670f3 18682 /* Fall through. */
11c1ff18
PB
18683 do_numlist:
18684 for (;;)
18685 {
cd30bcef 18686 READ_ULEB (val, p, end);
11c1ff18
PB
18687 if (val == 0)
18688 break;
18689 printf (" %d", val);
18690 }
18691 printf ("\n");
18692 break;
18693 default:
2b692964 18694 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18695 public_section = false;
11c1ff18
PB
18696 break;
18697 }
60bca95a 18698
071436c6 18699 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18700 {
18701 while (p < end)
f6f0e17b 18702 p = display_pub_attribute (p, end);
60abdbed 18703 assert (p == end);
104d59d1 18704 }
071436c6 18705 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18706 {
18707 while (p < end)
18708 p = display_gnu_attribute (p,
f6f0e17b
NC
18709 display_proc_gnu_attribute,
18710 end);
60abdbed 18711 assert (p == end);
11c1ff18 18712 }
071436c6 18713 else if (p < end)
11c1ff18 18714 {
071436c6 18715 printf (_(" Unknown attribute:\n"));
f6f0e17b 18716 display_raw_attribute (p, end);
11c1ff18
PB
18717 p = end;
18718 }
071436c6
NC
18719 else
18720 attr_len = 0;
11c1ff18
PB
18721 }
18722 }
18723 }
d70c5fc7 18724
60bca95a 18725 free (contents);
11c1ff18 18726 }
32ec8896
NC
18727
18728 return res;
11c1ff18
PB
18729}
18730
ccb4c951
RS
18731/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18732 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18733 and return the VMA of the next entry, or -1 if there was a problem.
18734 Does not read from DATA_END or beyond. */
ccb4c951 18735
625d49fc
AM
18736static uint64_t
18737print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18738 unsigned char * data_end)
ccb4c951
RS
18739{
18740 printf (" ");
18741 print_vma (addr, LONG_HEX);
18742 printf (" ");
18743 if (addr < pltgot + 0xfff0)
18744 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18745 else
18746 printf ("%10s", "");
18747 printf (" ");
18748 if (data == NULL)
2b692964 18749 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18750 else
18751 {
625d49fc 18752 uint64_t entry;
82b1b41b 18753 unsigned char * from = data + addr - pltgot;
ccb4c951 18754
82b1b41b
NC
18755 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18756 {
18757 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18758 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18759 return (uint64_t) -1;
82b1b41b
NC
18760 }
18761 else
18762 {
18763 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18764 print_vma (entry, LONG_HEX);
18765 }
ccb4c951
RS
18766 }
18767 return addr + (is_32bit_elf ? 4 : 8);
18768}
18769
861fb55a
DJ
18770/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18771 PLTGOT. Print the Address and Initial fields of an entry at VMA
18772 ADDR and return the VMA of the next entry. */
18773
625d49fc
AM
18774static uint64_t
18775print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18776{
18777 printf (" ");
18778 print_vma (addr, LONG_HEX);
18779 printf (" ");
18780 if (data == NULL)
2b692964 18781 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18782 else
18783 {
625d49fc 18784 uint64_t entry;
861fb55a
DJ
18785
18786 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18787 print_vma (entry, LONG_HEX);
18788 }
18789 return addr + (is_32bit_elf ? 4 : 8);
18790}
18791
351cdf24
MF
18792static void
18793print_mips_ases (unsigned int mask)
18794{
18795 if (mask & AFL_ASE_DSP)
18796 fputs ("\n\tDSP ASE", stdout);
18797 if (mask & AFL_ASE_DSPR2)
18798 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18799 if (mask & AFL_ASE_DSPR3)
18800 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18801 if (mask & AFL_ASE_EVA)
18802 fputs ("\n\tEnhanced VA Scheme", stdout);
18803 if (mask & AFL_ASE_MCU)
18804 fputs ("\n\tMCU (MicroController) ASE", stdout);
18805 if (mask & AFL_ASE_MDMX)
18806 fputs ("\n\tMDMX ASE", stdout);
18807 if (mask & AFL_ASE_MIPS3D)
18808 fputs ("\n\tMIPS-3D ASE", stdout);
18809 if (mask & AFL_ASE_MT)
18810 fputs ("\n\tMT ASE", stdout);
18811 if (mask & AFL_ASE_SMARTMIPS)
18812 fputs ("\n\tSmartMIPS ASE", stdout);
18813 if (mask & AFL_ASE_VIRT)
18814 fputs ("\n\tVZ ASE", stdout);
18815 if (mask & AFL_ASE_MSA)
18816 fputs ("\n\tMSA ASE", stdout);
18817 if (mask & AFL_ASE_MIPS16)
18818 fputs ("\n\tMIPS16 ASE", stdout);
18819 if (mask & AFL_ASE_MICROMIPS)
18820 fputs ("\n\tMICROMIPS ASE", stdout);
18821 if (mask & AFL_ASE_XPA)
18822 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18823 if (mask & AFL_ASE_MIPS16E2)
18824 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18825 if (mask & AFL_ASE_CRC)
18826 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18827 if (mask & AFL_ASE_GINV)
18828 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18829 if (mask & AFL_ASE_LOONGSON_MMI)
18830 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18831 if (mask & AFL_ASE_LOONGSON_CAM)
18832 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18833 if (mask & AFL_ASE_LOONGSON_EXT)
18834 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18835 if (mask & AFL_ASE_LOONGSON_EXT2)
18836 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18837 if (mask == 0)
18838 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18839 else if ((mask & ~AFL_ASE_MASK) != 0)
18840 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18841}
18842
18843static void
18844print_mips_isa_ext (unsigned int isa_ext)
18845{
18846 switch (isa_ext)
18847 {
18848 case 0:
18849 fputs (_("None"), stdout);
18850 break;
18851 case AFL_EXT_XLR:
18852 fputs ("RMI XLR", stdout);
18853 break;
2c629856
N
18854 case AFL_EXT_OCTEON3:
18855 fputs ("Cavium Networks Octeon3", stdout);
18856 break;
351cdf24
MF
18857 case AFL_EXT_OCTEON2:
18858 fputs ("Cavium Networks Octeon2", stdout);
18859 break;
18860 case AFL_EXT_OCTEONP:
18861 fputs ("Cavium Networks OcteonP", stdout);
18862 break;
351cdf24
MF
18863 case AFL_EXT_OCTEON:
18864 fputs ("Cavium Networks Octeon", stdout);
18865 break;
18866 case AFL_EXT_5900:
18867 fputs ("Toshiba R5900", stdout);
18868 break;
18869 case AFL_EXT_4650:
18870 fputs ("MIPS R4650", stdout);
18871 break;
18872 case AFL_EXT_4010:
18873 fputs ("LSI R4010", stdout);
18874 break;
18875 case AFL_EXT_4100:
18876 fputs ("NEC VR4100", stdout);
18877 break;
18878 case AFL_EXT_3900:
18879 fputs ("Toshiba R3900", stdout);
18880 break;
18881 case AFL_EXT_10000:
18882 fputs ("MIPS R10000", stdout);
18883 break;
18884 case AFL_EXT_SB1:
18885 fputs ("Broadcom SB-1", stdout);
18886 break;
18887 case AFL_EXT_4111:
18888 fputs ("NEC VR4111/VR4181", stdout);
18889 break;
18890 case AFL_EXT_4120:
18891 fputs ("NEC VR4120", stdout);
18892 break;
18893 case AFL_EXT_5400:
18894 fputs ("NEC VR5400", stdout);
18895 break;
18896 case AFL_EXT_5500:
18897 fputs ("NEC VR5500", stdout);
18898 break;
18899 case AFL_EXT_LOONGSON_2E:
18900 fputs ("ST Microelectronics Loongson 2E", stdout);
18901 break;
18902 case AFL_EXT_LOONGSON_2F:
18903 fputs ("ST Microelectronics Loongson 2F", stdout);
18904 break;
38bf472a
MR
18905 case AFL_EXT_INTERAPTIV_MR2:
18906 fputs ("Imagination interAptiv MR2", stdout);
18907 break;
351cdf24 18908 default:
00ac7aa0 18909 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18910 }
18911}
18912
32ec8896 18913static signed int
351cdf24
MF
18914get_mips_reg_size (int reg_size)
18915{
18916 return (reg_size == AFL_REG_NONE) ? 0
18917 : (reg_size == AFL_REG_32) ? 32
18918 : (reg_size == AFL_REG_64) ? 64
18919 : (reg_size == AFL_REG_128) ? 128
18920 : -1;
18921}
18922
015dc7e1 18923static bool
dda8d76d 18924process_mips_specific (Filedata * filedata)
5b18a4bc 18925{
2cf0635d 18926 Elf_Internal_Dyn * entry;
351cdf24 18927 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18928 size_t liblist_offset = 0;
18929 size_t liblistno = 0;
18930 size_t conflictsno = 0;
18931 size_t options_offset = 0;
18932 size_t conflicts_offset = 0;
861fb55a
DJ
18933 size_t pltrelsz = 0;
18934 size_t pltrel = 0;
625d49fc
AM
18935 uint64_t pltgot = 0;
18936 uint64_t mips_pltgot = 0;
18937 uint64_t jmprel = 0;
18938 uint64_t local_gotno = 0;
18939 uint64_t gotsym = 0;
18940 uint64_t symtabno = 0;
015dc7e1 18941 bool res = true;
103f02d3 18942
dda8d76d 18943 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18944 display_mips_gnu_attribute))
015dc7e1 18945 res = false;
2cf19d5c 18946
dda8d76d 18947 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18948
18949 if (sect != NULL)
18950 {
18951 Elf_External_ABIFlags_v0 *abiflags_ext;
18952 Elf_Internal_ABIFlags_v0 abiflags_in;
18953
18954 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18955 {
18956 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18957 res = false;
32ec8896 18958 }
351cdf24
MF
18959 else
18960 {
dda8d76d 18961 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18962 sect->sh_size, _("MIPS ABI Flags section"));
18963 if (abiflags_ext)
18964 {
18965 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18966 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18967 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18968 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18969 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18970 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18971 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18972 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18973 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18974 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18975 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18976
18977 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18978 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18979 if (abiflags_in.isa_rev > 1)
18980 printf ("r%d", abiflags_in.isa_rev);
18981 printf ("\nGPR size: %d",
18982 get_mips_reg_size (abiflags_in.gpr_size));
18983 printf ("\nCPR1 size: %d",
18984 get_mips_reg_size (abiflags_in.cpr1_size));
18985 printf ("\nCPR2 size: %d",
18986 get_mips_reg_size (abiflags_in.cpr2_size));
18987 fputs ("\nFP ABI: ", stdout);
18988 print_mips_fp_abi_value (abiflags_in.fp_abi);
18989 fputs ("ISA Extension: ", stdout);
18990 print_mips_isa_ext (abiflags_in.isa_ext);
18991 fputs ("\nASEs:", stdout);
18992 print_mips_ases (abiflags_in.ases);
18993 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18994 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18995 fputc ('\n', stdout);
18996 free (abiflags_ext);
18997 }
18998 }
18999 }
19000
19e6b90e 19001 /* We have a lot of special sections. Thanks SGI! */
978c4450 19002 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
19003 {
19004 /* No dynamic information available. See if there is static GOT. */
dda8d76d 19005 sect = find_section (filedata, ".got");
bbdd9a68
MR
19006 if (sect != NULL)
19007 {
19008 unsigned char *data_end;
19009 unsigned char *data;
625d49fc 19010 uint64_t ent, end;
bbdd9a68
MR
19011 int addr_size;
19012
19013 pltgot = sect->sh_addr;
19014
19015 ent = pltgot;
19016 addr_size = (is_32bit_elf ? 4 : 8);
19017 end = pltgot + sect->sh_size;
19018
dda8d76d 19019 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
19020 end - pltgot, 1,
19021 _("Global Offset Table data"));
19022 /* PR 12855: Null data is handled gracefully throughout. */
19023 data_end = data + (end - pltgot);
19024
19025 printf (_("\nStatic GOT:\n"));
19026 printf (_(" Canonical gp value: "));
19027 print_vma (ent + 0x7ff0, LONG_HEX);
19028 printf ("\n\n");
19029
19030 /* In a dynamic binary GOT[0] is reserved for the dynamic
19031 loader to store the lazy resolver pointer, however in
19032 a static binary it may well have been omitted and GOT
19033 reduced to a table of addresses.
19034 PR 21344: Check for the entry being fully available
19035 before fetching it. */
19036 if (data
19037 && data + ent - pltgot + addr_size <= data_end
19038 && byte_get (data + ent - pltgot, addr_size) == 0)
19039 {
19040 printf (_(" Reserved entries:\n"));
19041 printf (_(" %*s %10s %*s\n"),
19042 addr_size * 2, _("Address"), _("Access"),
19043 addr_size * 2, _("Value"));
19044 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19045 printf ("\n");
625d49fc 19046 if (ent == (uint64_t) -1)
bbdd9a68
MR
19047 goto sgot_print_fail;
19048
19049 /* Check for the MSB of GOT[1] being set, identifying a
19050 GNU object. This entry will be used by some runtime
19051 loaders, to store the module pointer. Otherwise this
19052 is an ordinary local entry.
19053 PR 21344: Check for the entry being fully available
19054 before fetching it. */
19055 if (data
19056 && data + ent - pltgot + addr_size <= data_end
19057 && (byte_get (data + ent - pltgot, addr_size)
19058 >> (addr_size * 8 - 1)) != 0)
19059 {
19060 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19061 printf ("\n");
625d49fc 19062 if (ent == (uint64_t) -1)
bbdd9a68
MR
19063 goto sgot_print_fail;
19064 }
19065 printf ("\n");
19066 }
19067
f17e9d8a 19068 if (data != NULL && ent < end)
bbdd9a68
MR
19069 {
19070 printf (_(" Local entries:\n"));
19071 printf (" %*s %10s %*s\n",
19072 addr_size * 2, _("Address"), _("Access"),
19073 addr_size * 2, _("Value"));
19074 while (ent < end)
19075 {
19076 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19077 printf ("\n");
625d49fc 19078 if (ent == (uint64_t) -1)
bbdd9a68
MR
19079 goto sgot_print_fail;
19080 }
19081 printf ("\n");
19082 }
19083
19084 sgot_print_fail:
9db70fc3 19085 free (data);
bbdd9a68
MR
19086 }
19087 return res;
19088 }
252b5132 19089
978c4450 19090 for (entry = filedata->dynamic_section;
071436c6 19091 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
19092 (entry < filedata->dynamic_section + filedata->dynamic_nent
19093 && entry->d_tag != DT_NULL);
071436c6 19094 ++entry)
252b5132
RH
19095 switch (entry->d_tag)
19096 {
19097 case DT_MIPS_LIBLIST:
d93f0186 19098 liblist_offset
dda8d76d 19099 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19100 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
19101 break;
19102 case DT_MIPS_LIBLISTNO:
19103 liblistno = entry->d_un.d_val;
19104 break;
19105 case DT_MIPS_OPTIONS:
dda8d76d 19106 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
19107 break;
19108 case DT_MIPS_CONFLICT:
d93f0186 19109 conflicts_offset
dda8d76d 19110 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19111 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
19112 break;
19113 case DT_MIPS_CONFLICTNO:
19114 conflictsno = entry->d_un.d_val;
19115 break;
ccb4c951 19116 case DT_PLTGOT:
861fb55a
DJ
19117 pltgot = entry->d_un.d_ptr;
19118 break;
ccb4c951
RS
19119 case DT_MIPS_LOCAL_GOTNO:
19120 local_gotno = entry->d_un.d_val;
19121 break;
19122 case DT_MIPS_GOTSYM:
19123 gotsym = entry->d_un.d_val;
19124 break;
19125 case DT_MIPS_SYMTABNO:
19126 symtabno = entry->d_un.d_val;
19127 break;
861fb55a
DJ
19128 case DT_MIPS_PLTGOT:
19129 mips_pltgot = entry->d_un.d_ptr;
19130 break;
19131 case DT_PLTREL:
19132 pltrel = entry->d_un.d_val;
19133 break;
19134 case DT_PLTRELSZ:
19135 pltrelsz = entry->d_un.d_val;
19136 break;
19137 case DT_JMPREL:
19138 jmprel = entry->d_un.d_ptr;
19139 break;
252b5132
RH
19140 default:
19141 break;
19142 }
19143
19144 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
19145 {
2cf0635d 19146 Elf32_External_Lib * elib;
252b5132
RH
19147 size_t cnt;
19148
dda8d76d 19149 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
19150 sizeof (Elf32_External_Lib),
19151 liblistno,
19152 _("liblist section data"));
a6e9f9df 19153 if (elib)
252b5132 19154 {
26c527e6
AM
19155 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
19156 "\nSection '.liblist' contains %zu entries:\n",
19157 liblistno),
19158 liblistno);
2b692964 19159 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
19160 stdout);
19161
19162 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 19163 {
a6e9f9df 19164 Elf32_Lib liblist;
91d6fa6a 19165 time_t atime;
d5b07ef4 19166 char timebuf[128];
2cf0635d 19167 struct tm * tmp;
a6e9f9df
AM
19168
19169 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19170 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
19171 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19172 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19173 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19174
91d6fa6a 19175 tmp = gmtime (&atime);
e9e44622
JJ
19176 snprintf (timebuf, sizeof (timebuf),
19177 "%04u-%02u-%02uT%02u:%02u:%02u",
19178 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19179 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 19180
26c527e6 19181 printf ("%3zu: ", cnt);
84714f86
AM
19182 if (valid_dynamic_name (filedata, liblist.l_name))
19183 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 19184 else
2b692964 19185 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
19186 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
19187 liblist.l_version);
a6e9f9df
AM
19188
19189 if (liblist.l_flags == 0)
2b692964 19190 puts (_(" NONE"));
a6e9f9df
AM
19191 else
19192 {
19193 static const struct
252b5132 19194 {
2cf0635d 19195 const char * name;
a6e9f9df 19196 int bit;
252b5132 19197 }
a6e9f9df
AM
19198 l_flags_vals[] =
19199 {
19200 { " EXACT_MATCH", LL_EXACT_MATCH },
19201 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
19202 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
19203 { " EXPORTS", LL_EXPORTS },
19204 { " DELAY_LOAD", LL_DELAY_LOAD },
19205 { " DELTA", LL_DELTA }
19206 };
19207 int flags = liblist.l_flags;
19208 size_t fcnt;
19209
60bca95a 19210 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
19211 if ((flags & l_flags_vals[fcnt].bit) != 0)
19212 {
19213 fputs (l_flags_vals[fcnt].name, stdout);
19214 flags ^= l_flags_vals[fcnt].bit;
19215 }
19216 if (flags != 0)
19217 printf (" %#x", (unsigned int) flags);
252b5132 19218
a6e9f9df
AM
19219 puts ("");
19220 }
252b5132 19221 }
252b5132 19222
a6e9f9df
AM
19223 free (elib);
19224 }
32ec8896 19225 else
015dc7e1 19226 res = false;
252b5132
RH
19227 }
19228
19229 if (options_offset != 0)
19230 {
2cf0635d 19231 Elf_External_Options * eopt;
252b5132
RH
19232 size_t offset;
19233 int cnt;
19234
19235 /* Find the section header so that we get the size. */
dda8d76d 19236 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 19237 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
19238 if (sect == NULL)
19239 {
19240 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 19241 return false;
071436c6 19242 }
7fc0c668
NC
19243 /* PR 24243 */
19244 if (sect->sh_size < sizeof (* eopt))
19245 {
19246 error (_("The MIPS options section is too small.\n"));
015dc7e1 19247 return false;
7fc0c668 19248 }
252b5132 19249
dda8d76d 19250 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 19251 sect->sh_size, _("options"));
a6e9f9df 19252 if (eopt)
252b5132 19253 {
fd17d1e6 19254 Elf_Internal_Options option;
76da6bbe 19255
a6e9f9df 19256 offset = cnt = 0;
82b1b41b 19257 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 19258 {
2cf0635d 19259 Elf_External_Options * eoption;
fd17d1e6 19260 unsigned int optsize;
252b5132 19261
a6e9f9df 19262 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 19263
fd17d1e6 19264 optsize = BYTE_GET (eoption->size);
76da6bbe 19265
82b1b41b 19266 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
19267 if (optsize < sizeof (* eopt)
19268 || optsize > sect->sh_size - offset)
82b1b41b 19269 {
645f43a8 19270 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 19271 optsize);
645f43a8 19272 free (eopt);
015dc7e1 19273 return false;
82b1b41b 19274 }
fd17d1e6 19275 offset += optsize;
a6e9f9df
AM
19276 ++cnt;
19277 }
252b5132 19278
d3a49aa8
AM
19279 printf (ngettext ("\nSection '%s' contains %d entry:\n",
19280 "\nSection '%s' contains %d entries:\n",
19281 cnt),
dda8d76d 19282 printable_section_name (filedata, sect), cnt);
76da6bbe 19283
82b1b41b 19284 offset = 0;
a6e9f9df 19285 while (cnt-- > 0)
252b5132 19286 {
a6e9f9df 19287 size_t len;
fd17d1e6
AM
19288 Elf_External_Options * eoption;
19289
19290 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19291
19292 option.kind = BYTE_GET (eoption->kind);
19293 option.size = BYTE_GET (eoption->size);
19294 option.section = BYTE_GET (eoption->section);
19295 option.info = BYTE_GET (eoption->info);
a6e9f9df 19296
fd17d1e6 19297 switch (option.kind)
252b5132 19298 {
a6e9f9df
AM
19299 case ODK_NULL:
19300 /* This shouldn't happen. */
d0c4e780 19301 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 19302 option.section, option.info);
a6e9f9df 19303 break;
2e6be59c 19304
a6e9f9df
AM
19305 case ODK_REGINFO:
19306 printf (" REGINFO ");
dda8d76d 19307 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 19308 {
2cf0635d 19309 Elf32_External_RegInfo * ereg;
b34976b6 19310 Elf32_RegInfo reginfo;
a6e9f9df 19311
2e6be59c 19312 /* 32bit form. */
fd17d1e6
AM
19313 if (option.size < (sizeof (Elf_External_Options)
19314 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
19315 {
19316 printf (_("<corrupt>\n"));
19317 error (_("Truncated MIPS REGINFO option\n"));
19318 cnt = 0;
19319 break;
19320 }
19321
fd17d1e6 19322 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 19323
a6e9f9df
AM
19324 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19325 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19326 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19327 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19328 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
19329 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
19330
d0c4e780
AM
19331 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
19332 reginfo.ri_gprmask, reginfo.ri_gp_value);
19333 printf (" "
19334 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19335 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19336 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19337 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19338 }
19339 else
19340 {
19341 /* 64 bit form. */
2cf0635d 19342 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
19343 Elf64_Internal_RegInfo reginfo;
19344
fd17d1e6
AM
19345 if (option.size < (sizeof (Elf_External_Options)
19346 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
19347 {
19348 printf (_("<corrupt>\n"));
19349 error (_("Truncated MIPS REGINFO option\n"));
19350 cnt = 0;
19351 break;
19352 }
19353
fd17d1e6 19354 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
19355 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19356 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19357 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19358 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19359 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 19360 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 19361
d0c4e780
AM
19362 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
19363 reginfo.ri_gprmask, reginfo.ri_gp_value);
19364 printf (" "
19365 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19366 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19367 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19368 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19369 }
fd17d1e6 19370 offset += option.size;
a6e9f9df 19371 continue;
2e6be59c 19372
a6e9f9df
AM
19373 case ODK_EXCEPTIONS:
19374 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 19375 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 19376 fputs (") fpe_max(", stdout);
fd17d1e6 19377 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
19378 fputs (")", stdout);
19379
fd17d1e6 19380 if (option.info & OEX_PAGE0)
a6e9f9df 19381 fputs (" PAGE0", stdout);
fd17d1e6 19382 if (option.info & OEX_SMM)
a6e9f9df 19383 fputs (" SMM", stdout);
fd17d1e6 19384 if (option.info & OEX_FPDBUG)
a6e9f9df 19385 fputs (" FPDBUG", stdout);
fd17d1e6 19386 if (option.info & OEX_DISMISS)
a6e9f9df
AM
19387 fputs (" DISMISS", stdout);
19388 break;
2e6be59c 19389
a6e9f9df
AM
19390 case ODK_PAD:
19391 fputs (" PAD ", stdout);
fd17d1e6 19392 if (option.info & OPAD_PREFIX)
a6e9f9df 19393 fputs (" PREFIX", stdout);
fd17d1e6 19394 if (option.info & OPAD_POSTFIX)
a6e9f9df 19395 fputs (" POSTFIX", stdout);
fd17d1e6 19396 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
19397 fputs (" SYMBOL", stdout);
19398 break;
2e6be59c 19399
a6e9f9df
AM
19400 case ODK_HWPATCH:
19401 fputs (" HWPATCH ", stdout);
fd17d1e6 19402 if (option.info & OHW_R4KEOP)
a6e9f9df 19403 fputs (" R4KEOP", stdout);
fd17d1e6 19404 if (option.info & OHW_R8KPFETCH)
a6e9f9df 19405 fputs (" R8KPFETCH", stdout);
fd17d1e6 19406 if (option.info & OHW_R5KEOP)
a6e9f9df 19407 fputs (" R5KEOP", stdout);
fd17d1e6 19408 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
19409 fputs (" R5KCVTL", stdout);
19410 break;
2e6be59c 19411
a6e9f9df
AM
19412 case ODK_FILL:
19413 fputs (" FILL ", stdout);
19414 /* XXX Print content of info word? */
19415 break;
2e6be59c 19416
a6e9f9df
AM
19417 case ODK_TAGS:
19418 fputs (" TAGS ", stdout);
19419 /* XXX Print content of info word? */
19420 break;
2e6be59c 19421
a6e9f9df
AM
19422 case ODK_HWAND:
19423 fputs (" HWAND ", stdout);
fd17d1e6 19424 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19425 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19426 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19427 fputs (" R4KEOP_CLEAN", stdout);
19428 break;
2e6be59c 19429
a6e9f9df
AM
19430 case ODK_HWOR:
19431 fputs (" HWOR ", stdout);
fd17d1e6 19432 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19433 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19434 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19435 fputs (" R4KEOP_CLEAN", stdout);
19436 break;
2e6be59c 19437
a6e9f9df 19438 case ODK_GP_GROUP:
d0c4e780 19439 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
19440 option.info & OGP_GROUP,
19441 (option.info & OGP_SELF) >> 16);
a6e9f9df 19442 break;
2e6be59c 19443
a6e9f9df 19444 case ODK_IDENT:
d0c4e780 19445 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
19446 option.info & OGP_GROUP,
19447 (option.info & OGP_SELF) >> 16);
a6e9f9df 19448 break;
2e6be59c 19449
a6e9f9df
AM
19450 default:
19451 /* This shouldn't happen. */
d0c4e780 19452 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 19453 option.kind, option.section, option.info);
a6e9f9df 19454 break;
252b5132 19455 }
a6e9f9df 19456
2cf0635d 19457 len = sizeof (* eopt);
fd17d1e6 19458 while (len < option.size)
82b1b41b 19459 {
fd17d1e6 19460 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 19461
82b1b41b
NC
19462 if (ISPRINT (datum))
19463 printf ("%c", datum);
19464 else
19465 printf ("\\%03o", datum);
19466 len ++;
19467 }
a6e9f9df 19468 fputs ("\n", stdout);
82b1b41b 19469
fd17d1e6 19470 offset += option.size;
252b5132 19471 }
a6e9f9df 19472 free (eopt);
252b5132 19473 }
32ec8896 19474 else
015dc7e1 19475 res = false;
252b5132
RH
19476 }
19477
19478 if (conflicts_offset != 0 && conflictsno != 0)
19479 {
2cf0635d 19480 Elf32_Conflict * iconf;
252b5132
RH
19481 size_t cnt;
19482
978c4450 19483 if (filedata->dynamic_symbols == NULL)
252b5132 19484 {
591a748a 19485 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 19486 return false;
252b5132
RH
19487 }
19488
7296a62a
NC
19489 /* PR 21345 - print a slightly more helpful error message
19490 if we are sure that the cmalloc will fail. */
645f43a8 19491 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 19492 {
26c527e6
AM
19493 error (_("Overlarge number of conflicts detected: %zx\n"),
19494 conflictsno);
015dc7e1 19495 return false;
7296a62a
NC
19496 }
19497
3f5e193b 19498 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
19499 if (iconf == NULL)
19500 {
8b73c356 19501 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 19502 return false;
252b5132
RH
19503 }
19504
9ea033b2 19505 if (is_32bit_elf)
252b5132 19506 {
2cf0635d 19507 Elf32_External_Conflict * econf32;
a6e9f9df 19508
3f5e193b 19509 econf32 = (Elf32_External_Conflict *)
95099889
AM
19510 get_data (NULL, filedata, conflicts_offset,
19511 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 19512 if (!econf32)
5a814d6d
AM
19513 {
19514 free (iconf);
015dc7e1 19515 return false;
5a814d6d 19516 }
252b5132
RH
19517
19518 for (cnt = 0; cnt < conflictsno; ++cnt)
19519 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
19520
19521 free (econf32);
252b5132
RH
19522 }
19523 else
19524 {
2cf0635d 19525 Elf64_External_Conflict * econf64;
a6e9f9df 19526
3f5e193b 19527 econf64 = (Elf64_External_Conflict *)
95099889
AM
19528 get_data (NULL, filedata, conflicts_offset,
19529 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 19530 if (!econf64)
5a814d6d
AM
19531 {
19532 free (iconf);
015dc7e1 19533 return false;
5a814d6d 19534 }
252b5132
RH
19535
19536 for (cnt = 0; cnt < conflictsno; ++cnt)
19537 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
19538
19539 free (econf64);
252b5132
RH
19540 }
19541
26c527e6
AM
19542 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19543 "\nSection '.conflict' contains %zu entries:\n",
19544 conflictsno),
19545 conflictsno);
252b5132
RH
19546 puts (_(" Num: Index Value Name"));
19547
19548 for (cnt = 0; cnt < conflictsno; ++cnt)
19549 {
26c527e6 19550 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 19551
978c4450 19552 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 19553 printf (_("<corrupt symbol index>"));
d79b3d50 19554 else
e0a31db1
NC
19555 {
19556 Elf_Internal_Sym * psym;
19557
978c4450 19558 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
19559 print_vma (psym->st_value, FULL_HEX);
19560 putchar (' ');
84714f86
AM
19561 if (valid_dynamic_name (filedata, psym->st_name))
19562 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19563 else
19564 printf (_("<corrupt: %14ld>"), psym->st_name);
19565 }
31104126 19566 putchar ('\n');
252b5132
RH
19567 }
19568
252b5132
RH
19569 free (iconf);
19570 }
19571
ccb4c951
RS
19572 if (pltgot != 0 && local_gotno != 0)
19573 {
625d49fc 19574 uint64_t ent, local_end, global_end;
bbeee7ea 19575 size_t i, offset;
2cf0635d 19576 unsigned char * data;
82b1b41b 19577 unsigned char * data_end;
bbeee7ea 19578 int addr_size;
ccb4c951 19579
91d6fa6a 19580 ent = pltgot;
ccb4c951
RS
19581 addr_size = (is_32bit_elf ? 4 : 8);
19582 local_end = pltgot + local_gotno * addr_size;
ccb4c951 19583
74e1a04b
NC
19584 /* PR binutils/17533 file: 012-111227-0.004 */
19585 if (symtabno < gotsym)
19586 {
26c527e6
AM
19587 error (_("The GOT symbol offset (%" PRIu64
19588 ") is greater than the symbol table size (%" PRIu64 ")\n"),
19589 gotsym, symtabno);
015dc7e1 19590 return false;
74e1a04b 19591 }
82b1b41b 19592
74e1a04b 19593 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
19594 /* PR 17531: file: 54c91a34. */
19595 if (global_end < local_end)
19596 {
26c527e6 19597 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 19598 return false;
82b1b41b 19599 }
948f632f 19600
dda8d76d
NC
19601 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
19602 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
19603 global_end - pltgot, 1,
19604 _("Global Offset Table data"));
919383ac 19605 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 19606 data_end = data + (global_end - pltgot);
59245841 19607
ccb4c951
RS
19608 printf (_("\nPrimary GOT:\n"));
19609 printf (_(" Canonical gp value: "));
19610 print_vma (pltgot + 0x7ff0, LONG_HEX);
19611 printf ("\n\n");
19612
19613 printf (_(" Reserved entries:\n"));
19614 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
19615 addr_size * 2, _("Address"), _("Access"),
19616 addr_size * 2, _("Initial"));
82b1b41b 19617 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 19618 printf (_(" Lazy resolver\n"));
625d49fc 19619 if (ent == (uint64_t) -1)
82b1b41b 19620 goto got_print_fail;
75ec1fdb 19621
c4ab9505
MR
19622 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19623 This entry will be used by some runtime loaders, to store the
19624 module pointer. Otherwise this is an ordinary local entry.
19625 PR 21344: Check for the entry being fully available before
19626 fetching it. */
19627 if (data
19628 && data + ent - pltgot + addr_size <= data_end
19629 && (byte_get (data + ent - pltgot, addr_size)
19630 >> (addr_size * 8 - 1)) != 0)
19631 {
19632 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19633 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 19634 if (ent == (uint64_t) -1)
c4ab9505 19635 goto got_print_fail;
ccb4c951
RS
19636 }
19637 printf ("\n");
19638
f17e9d8a 19639 if (data != NULL && ent < local_end)
ccb4c951
RS
19640 {
19641 printf (_(" Local entries:\n"));
cc5914eb 19642 printf (" %*s %10s %*s\n",
2b692964
NC
19643 addr_size * 2, _("Address"), _("Access"),
19644 addr_size * 2, _("Initial"));
91d6fa6a 19645 while (ent < local_end)
ccb4c951 19646 {
82b1b41b 19647 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19648 printf ("\n");
625d49fc 19649 if (ent == (uint64_t) -1)
82b1b41b 19650 goto got_print_fail;
ccb4c951
RS
19651 }
19652 printf ("\n");
19653 }
19654
f17e9d8a 19655 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19656 {
19657 int sym_width;
19658
19659 printf (_(" Global entries:\n"));
cc5914eb 19660 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19661 addr_size * 2, _("Address"),
19662 _("Access"),
2b692964 19663 addr_size * 2, _("Initial"),
9cf03b7e
NC
19664 addr_size * 2, _("Sym.Val."),
19665 _("Type"),
19666 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19667 _("Ndx"), _("Name"));
0b4362b0 19668
ccb4c951 19669 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19670
ccb4c951
RS
19671 for (i = gotsym; i < symtabno; i++)
19672 {
82b1b41b 19673 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19674 printf (" ");
e0a31db1 19675
978c4450 19676 if (filedata->dynamic_symbols == NULL)
e0a31db1 19677 printf (_("<no dynamic symbols>"));
978c4450 19678 else if (i < filedata->num_dynamic_syms)
e0a31db1 19679 {
978c4450 19680 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19681
19682 print_vma (psym->st_value, LONG_HEX);
19683 printf (" %-7s %3s ",
dda8d76d
NC
19684 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19685 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19686
84714f86 19687 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19688 print_symbol (sym_width,
84714f86 19689 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19690 else
19691 printf (_("<corrupt: %14ld>"), psym->st_name);
19692 }
ccb4c951 19693 else
26c527e6
AM
19694 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
19695 i);
e0a31db1 19696
ccb4c951 19697 printf ("\n");
625d49fc 19698 if (ent == (uint64_t) -1)
82b1b41b 19699 break;
ccb4c951
RS
19700 }
19701 printf ("\n");
19702 }
19703
82b1b41b 19704 got_print_fail:
9db70fc3 19705 free (data);
ccb4c951
RS
19706 }
19707
861fb55a
DJ
19708 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19709 {
625d49fc 19710 uint64_t ent, end;
26c527e6
AM
19711 uint64_t offset, rel_offset;
19712 uint64_t count, i;
2cf0635d 19713 unsigned char * data;
861fb55a 19714 int addr_size, sym_width;
2cf0635d 19715 Elf_Internal_Rela * rels;
861fb55a 19716
dda8d76d 19717 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19718 if (pltrel == DT_RELA)
19719 {
dda8d76d 19720 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19721 return false;
861fb55a
DJ
19722 }
19723 else
19724 {
dda8d76d 19725 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19726 return false;
861fb55a
DJ
19727 }
19728
91d6fa6a 19729 ent = mips_pltgot;
861fb55a
DJ
19730 addr_size = (is_32bit_elf ? 4 : 8);
19731 end = mips_pltgot + (2 + count) * addr_size;
19732
dda8d76d
NC
19733 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19734 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19735 1, _("Procedure Linkage Table data"));
59245841 19736 if (data == NULL)
288f0ba2
AM
19737 {
19738 free (rels);
015dc7e1 19739 return false;
288f0ba2 19740 }
59245841 19741
9cf03b7e 19742 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19743 printf (_(" Reserved entries:\n"));
19744 printf (_(" %*s %*s Purpose\n"),
2b692964 19745 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19746 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19747 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19748 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19749 printf (_(" Module pointer\n"));
861fb55a
DJ
19750 printf ("\n");
19751
19752 printf (_(" Entries:\n"));
cc5914eb 19753 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19754 addr_size * 2, _("Address"),
19755 addr_size * 2, _("Initial"),
19756 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19757 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19758 for (i = 0; i < count; i++)
19759 {
26c527e6 19760 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19761
91d6fa6a 19762 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19763 printf (" ");
e0a31db1 19764
978c4450 19765 if (idx >= filedata->num_dynamic_syms)
26c527e6 19766 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 19767 else
e0a31db1 19768 {
978c4450 19769 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19770
19771 print_vma (psym->st_value, LONG_HEX);
19772 printf (" %-7s %3s ",
dda8d76d
NC
19773 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19774 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19775 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19776 print_symbol (sym_width,
84714f86 19777 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19778 else
19779 printf (_("<corrupt: %14ld>"), psym->st_name);
19780 }
861fb55a
DJ
19781 printf ("\n");
19782 }
19783 printf ("\n");
19784
9db70fc3 19785 free (data);
861fb55a
DJ
19786 free (rels);
19787 }
19788
32ec8896 19789 return res;
252b5132
RH
19790}
19791
015dc7e1 19792static bool
dda8d76d 19793process_nds32_specific (Filedata * filedata)
35c08157
KLC
19794{
19795 Elf_Internal_Shdr *sect = NULL;
19796
dda8d76d 19797 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19798 if (sect != NULL && sect->sh_size >= 4)
35c08157 19799 {
9c7b8e9b
AM
19800 unsigned char *buf;
19801 unsigned int flag;
35c08157
KLC
19802
19803 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19804 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19805 _("NDS32 elf flags section"));
35c08157 19806
9c7b8e9b 19807 if (buf == NULL)
015dc7e1 19808 return false;
32ec8896 19809
9c7b8e9b
AM
19810 flag = byte_get (buf, 4);
19811 free (buf);
19812 switch (flag & 0x3)
35c08157
KLC
19813 {
19814 case 0:
19815 printf ("(VEC_SIZE):\tNo entry.\n");
19816 break;
19817 case 1:
19818 printf ("(VEC_SIZE):\t4 bytes\n");
19819 break;
19820 case 2:
19821 printf ("(VEC_SIZE):\t16 bytes\n");
19822 break;
19823 case 3:
19824 printf ("(VEC_SIZE):\treserved\n");
19825 break;
19826 }
19827 }
19828
015dc7e1 19829 return true;
35c08157
KLC
19830}
19831
015dc7e1 19832static bool
dda8d76d 19833process_gnu_liblist (Filedata * filedata)
047b2264 19834{
2cf0635d
NC
19835 Elf_Internal_Shdr * section;
19836 Elf_Internal_Shdr * string_sec;
19837 Elf32_External_Lib * elib;
19838 char * strtab;
c256ffe7 19839 size_t strtab_size;
047b2264 19840 size_t cnt;
26c527e6 19841 uint64_t num_liblist;
047b2264 19842 unsigned i;
015dc7e1 19843 bool res = true;
047b2264
JJ
19844
19845 if (! do_arch)
015dc7e1 19846 return true;
047b2264 19847
dda8d76d
NC
19848 for (i = 0, section = filedata->section_headers;
19849 i < filedata->file_header.e_shnum;
b34976b6 19850 i++, section++)
047b2264
JJ
19851 {
19852 switch (section->sh_type)
19853 {
19854 case SHT_GNU_LIBLIST:
dda8d76d 19855 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19856 break;
19857
3f5e193b 19858 elib = (Elf32_External_Lib *)
dda8d76d 19859 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19860 _("liblist section data"));
047b2264
JJ
19861
19862 if (elib == NULL)
32ec8896 19863 {
015dc7e1 19864 res = false;
32ec8896
NC
19865 break;
19866 }
047b2264 19867
dda8d76d
NC
19868 string_sec = filedata->section_headers + section->sh_link;
19869 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19870 string_sec->sh_size,
19871 _("liblist string table"));
047b2264
JJ
19872 if (strtab == NULL
19873 || section->sh_entsize != sizeof (Elf32_External_Lib))
19874 {
19875 free (elib);
2842702f 19876 free (strtab);
015dc7e1 19877 res = false;
047b2264
JJ
19878 break;
19879 }
59245841 19880 strtab_size = string_sec->sh_size;
047b2264 19881
d3a49aa8 19882 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
19883 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
19884 " entries:\n",
19885 "\nLibrary list section '%s' contains %" PRIu64
19886 " entries:\n",
d3a49aa8 19887 num_liblist),
dda8d76d 19888 printable_section_name (filedata, section),
d3a49aa8 19889 num_liblist);
047b2264 19890
2b692964 19891 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19892
19893 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19894 ++cnt)
19895 {
19896 Elf32_Lib liblist;
91d6fa6a 19897 time_t atime;
d5b07ef4 19898 char timebuf[128];
2cf0635d 19899 struct tm * tmp;
047b2264
JJ
19900
19901 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19902 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19903 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19904 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19905 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19906
91d6fa6a 19907 tmp = gmtime (&atime);
e9e44622
JJ
19908 snprintf (timebuf, sizeof (timebuf),
19909 "%04u-%02u-%02uT%02u:%02u:%02u",
19910 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19911 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 19912
26c527e6 19913 printf ("%3zu: ", cnt);
047b2264 19914 if (do_wide)
c256ffe7 19915 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19916 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19917 else
c256ffe7 19918 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19919 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19920 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19921 liblist.l_version, liblist.l_flags);
19922 }
19923
19924 free (elib);
2842702f 19925 free (strtab);
047b2264
JJ
19926 }
19927 }
19928
32ec8896 19929 return res;
047b2264
JJ
19930}
19931
9437c45b 19932static const char *
dda8d76d 19933get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19934{
19935 static char buff[64];
103f02d3 19936
dda8d76d 19937 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19938 switch (e_type)
19939 {
57346661 19940 case NT_AUXV:
1ec5cd37 19941 return _("NT_AUXV (auxiliary vector)");
57346661 19942 case NT_PRSTATUS:
1ec5cd37 19943 return _("NT_PRSTATUS (prstatus structure)");
57346661 19944 case NT_FPREGSET:
1ec5cd37 19945 return _("NT_FPREGSET (floating point registers)");
57346661 19946 case NT_PRPSINFO:
1ec5cd37 19947 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19948 case NT_TASKSTRUCT:
1ec5cd37 19949 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19950 case NT_GDB_TDESC:
19951 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19952 case NT_PRXFPREG:
1ec5cd37 19953 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19954 case NT_PPC_VMX:
19955 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19956 case NT_PPC_VSX:
19957 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19958 case NT_PPC_TAR:
19959 return _("NT_PPC_TAR (ppc TAR register)");
19960 case NT_PPC_PPR:
19961 return _("NT_PPC_PPR (ppc PPR register)");
19962 case NT_PPC_DSCR:
19963 return _("NT_PPC_DSCR (ppc DSCR register)");
19964 case NT_PPC_EBB:
19965 return _("NT_PPC_EBB (ppc EBB registers)");
19966 case NT_PPC_PMU:
19967 return _("NT_PPC_PMU (ppc PMU registers)");
19968 case NT_PPC_TM_CGPR:
19969 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19970 case NT_PPC_TM_CFPR:
19971 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19972 case NT_PPC_TM_CVMX:
19973 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19974 case NT_PPC_TM_CVSX:
3fd21718 19975 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19976 case NT_PPC_TM_SPR:
19977 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19978 case NT_PPC_TM_CTAR:
19979 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19980 case NT_PPC_TM_CPPR:
19981 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19982 case NT_PPC_TM_CDSCR:
19983 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19984 case NT_386_TLS:
19985 return _("NT_386_TLS (x86 TLS information)");
19986 case NT_386_IOPERM:
19987 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19988 case NT_X86_XSTATE:
19989 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19990 case NT_X86_CET:
19991 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19992 case NT_S390_HIGH_GPRS:
19993 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19994 case NT_S390_TIMER:
19995 return _("NT_S390_TIMER (s390 timer register)");
19996 case NT_S390_TODCMP:
19997 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19998 case NT_S390_TODPREG:
19999 return _("NT_S390_TODPREG (s390 TOD programmable register)");
20000 case NT_S390_CTRS:
20001 return _("NT_S390_CTRS (s390 control registers)");
20002 case NT_S390_PREFIX:
20003 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
20004 case NT_S390_LAST_BREAK:
20005 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
20006 case NT_S390_SYSTEM_CALL:
20007 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
20008 case NT_S390_TDB:
20009 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
20010 case NT_S390_VXRS_LOW:
20011 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
20012 case NT_S390_VXRS_HIGH:
20013 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
20014 case NT_S390_GS_CB:
20015 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
20016 case NT_S390_GS_BC:
20017 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
20018 case NT_ARM_VFP:
20019 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
20020 case NT_ARM_TLS:
20021 return _("NT_ARM_TLS (AArch TLS registers)");
20022 case NT_ARM_HW_BREAK:
20023 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
20024 case NT_ARM_HW_WATCH:
20025 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
20026 case NT_ARM_SYSTEM_CALL:
20027 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
20028 case NT_ARM_SVE:
20029 return _("NT_ARM_SVE (AArch SVE registers)");
20030 case NT_ARM_PAC_MASK:
20031 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
20032 case NT_ARM_PACA_KEYS:
20033 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
20034 case NT_ARM_PACG_KEYS:
20035 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
20036 case NT_ARM_TAGGED_ADDR_CTRL:
20037 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
a8f175d9
LM
20038 case NT_ARM_SSVE:
20039 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
20040 case NT_ARM_ZA:
20041 return _("NT_ARM_ZA (AArch64 SME ZA register)");
11e3488d
LM
20042 case NT_ARM_ZT:
20043 return _("NT_ARM_ZT (AArch64 SME2 ZT registers)");
3af2785c
LM
20044 case NT_ARM_PAC_ENABLED_KEYS:
20045 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
20046 case NT_ARC_V2:
20047 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
20048 case NT_RISCV_CSR:
20049 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 20050 case NT_PSTATUS:
1ec5cd37 20051 return _("NT_PSTATUS (pstatus structure)");
57346661 20052 case NT_FPREGS:
1ec5cd37 20053 return _("NT_FPREGS (floating point registers)");
57346661 20054 case NT_PSINFO:
1ec5cd37 20055 return _("NT_PSINFO (psinfo structure)");
57346661 20056 case NT_LWPSTATUS:
1ec5cd37 20057 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 20058 case NT_LWPSINFO:
1ec5cd37 20059 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 20060 case NT_WIN32PSTATUS:
1ec5cd37 20061 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
20062 case NT_SIGINFO:
20063 return _("NT_SIGINFO (siginfo_t data)");
20064 case NT_FILE:
20065 return _("NT_FILE (mapped files)");
1ec5cd37
NC
20066 default:
20067 break;
20068 }
20069 else
20070 switch (e_type)
20071 {
20072 case NT_VERSION:
20073 return _("NT_VERSION (version)");
20074 case NT_ARCH:
20075 return _("NT_ARCH (architecture)");
9ef920e9 20076 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 20077 return _("OPEN");
9ef920e9 20078 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 20079 return _("func");
c8795e1f
NC
20080 case NT_GO_BUILDID:
20081 return _("GO BUILDID");
3ac925fc
LB
20082 case FDO_PACKAGING_METADATA:
20083 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
20084 default:
20085 break;
20086 }
20087
e9e44622 20088 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 20089 return buff;
779fe533
NC
20090}
20091
015dc7e1 20092static bool
9ece1fa9
TT
20093print_core_note (Elf_Internal_Note *pnote)
20094{
20095 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 20096 uint64_t count, page_size;
9ece1fa9
TT
20097 unsigned char *descdata, *filenames, *descend;
20098
20099 if (pnote->type != NT_FILE)
04ac15ab
AS
20100 {
20101 if (do_wide)
20102 printf ("\n");
015dc7e1 20103 return true;
04ac15ab 20104 }
9ece1fa9 20105
9ece1fa9
TT
20106 if (!is_32bit_elf)
20107 {
20108 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
20109 /* Still "successful". */
015dc7e1 20110 return true;
9ece1fa9 20111 }
9ece1fa9
TT
20112
20113 if (pnote->descsz < 2 * addr_size)
20114 {
32ec8896 20115 error (_(" Malformed note - too short for header\n"));
015dc7e1 20116 return false;
9ece1fa9
TT
20117 }
20118
20119 descdata = (unsigned char *) pnote->descdata;
20120 descend = descdata + pnote->descsz;
20121
20122 if (descdata[pnote->descsz - 1] != '\0')
20123 {
32ec8896 20124 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 20125 return false;
9ece1fa9
TT
20126 }
20127
20128 count = byte_get (descdata, addr_size);
20129 descdata += addr_size;
20130
20131 page_size = byte_get (descdata, addr_size);
20132 descdata += addr_size;
20133
625d49fc 20134 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 20135 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 20136 {
32ec8896 20137 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 20138 return false;
9ece1fa9
TT
20139 }
20140
20141 printf (_(" Page size: "));
20142 print_vma (page_size, DEC);
20143 printf ("\n");
20144
20145 printf (_(" %*s%*s%*s\n"),
20146 (int) (2 + 2 * addr_size), _("Start"),
20147 (int) (4 + 2 * addr_size), _("End"),
20148 (int) (4 + 2 * addr_size), _("Page Offset"));
20149 filenames = descdata + count * 3 * addr_size;
595712bb 20150 while (count-- > 0)
9ece1fa9 20151 {
625d49fc 20152 uint64_t start, end, file_ofs;
9ece1fa9
TT
20153
20154 if (filenames == descend)
20155 {
32ec8896 20156 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 20157 return false;
9ece1fa9
TT
20158 }
20159
20160 start = byte_get (descdata, addr_size);
20161 descdata += addr_size;
20162 end = byte_get (descdata, addr_size);
20163 descdata += addr_size;
20164 file_ofs = byte_get (descdata, addr_size);
20165 descdata += addr_size;
20166
20167 printf (" ");
20168 print_vma (start, FULL_HEX);
20169 printf (" ");
20170 print_vma (end, FULL_HEX);
20171 printf (" ");
20172 print_vma (file_ofs, FULL_HEX);
20173 printf ("\n %s\n", filenames);
20174
20175 filenames += 1 + strlen ((char *) filenames);
20176 }
20177
015dc7e1 20178 return true;
9ece1fa9
TT
20179}
20180
1118d252
RM
20181static const char *
20182get_gnu_elf_note_type (unsigned e_type)
20183{
1449284b 20184 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
20185 switch (e_type)
20186 {
20187 case NT_GNU_ABI_TAG:
20188 return _("NT_GNU_ABI_TAG (ABI version tag)");
20189 case NT_GNU_HWCAP:
20190 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
20191 case NT_GNU_BUILD_ID:
20192 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
20193 case NT_GNU_GOLD_VERSION:
20194 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
20195 case NT_GNU_PROPERTY_TYPE_0:
20196 return _("NT_GNU_PROPERTY_TYPE_0");
20197 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20198 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
20199 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20200 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 20201 default:
1449284b
NC
20202 {
20203 static char buff[64];
1118d252 20204
1449284b
NC
20205 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20206 return buff;
20207 }
20208 }
1118d252
RM
20209}
20210
a9eafb08
L
20211static void
20212decode_x86_compat_isa (unsigned int bitmask)
20213{
20214 while (bitmask)
20215 {
20216 unsigned int bit = bitmask & (- bitmask);
20217
20218 bitmask &= ~ bit;
20219 switch (bit)
20220 {
20221 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
20222 printf ("i486");
20223 break;
20224 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
20225 printf ("586");
20226 break;
20227 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
20228 printf ("686");
20229 break;
20230 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
20231 printf ("SSE");
20232 break;
20233 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
20234 printf ("SSE2");
20235 break;
20236 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
20237 printf ("SSE3");
20238 break;
20239 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
20240 printf ("SSSE3");
20241 break;
20242 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
20243 printf ("SSE4_1");
20244 break;
20245 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
20246 printf ("SSE4_2");
20247 break;
20248 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
20249 printf ("AVX");
20250 break;
20251 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
20252 printf ("AVX2");
20253 break;
20254 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
20255 printf ("AVX512F");
20256 break;
20257 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
20258 printf ("AVX512CD");
20259 break;
20260 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
20261 printf ("AVX512ER");
20262 break;
20263 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
20264 printf ("AVX512PF");
20265 break;
20266 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
20267 printf ("AVX512VL");
20268 break;
20269 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
20270 printf ("AVX512DQ");
20271 break;
20272 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
20273 printf ("AVX512BW");
20274 break;
65b3d26e
L
20275 default:
20276 printf (_("<unknown: %x>"), bit);
20277 break;
a9eafb08
L
20278 }
20279 if (bitmask)
20280 printf (", ");
20281 }
20282}
20283
9ef920e9 20284static void
32930e4e 20285decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 20286{
0a59decb 20287 if (!bitmask)
90c745dc
L
20288 {
20289 printf (_("<None>"));
20290 return;
20291 }
90c745dc 20292
9ef920e9
NC
20293 while (bitmask)
20294 {
1fc87489 20295 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
20296
20297 bitmask &= ~ bit;
20298 switch (bit)
20299 {
32930e4e 20300 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
20301 printf ("CMOV");
20302 break;
32930e4e 20303 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
20304 printf ("SSE");
20305 break;
32930e4e 20306 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
20307 printf ("SSE2");
20308 break;
32930e4e 20309 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
20310 printf ("SSE3");
20311 break;
32930e4e 20312 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
20313 printf ("SSSE3");
20314 break;
32930e4e 20315 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
20316 printf ("SSE4_1");
20317 break;
32930e4e 20318 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
20319 printf ("SSE4_2");
20320 break;
32930e4e 20321 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
20322 printf ("AVX");
20323 break;
32930e4e 20324 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
20325 printf ("AVX2");
20326 break;
32930e4e 20327 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
20328 printf ("FMA");
20329 break;
32930e4e 20330 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
20331 printf ("AVX512F");
20332 break;
32930e4e 20333 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
20334 printf ("AVX512CD");
20335 break;
32930e4e 20336 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
20337 printf ("AVX512ER");
20338 break;
32930e4e 20339 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
20340 printf ("AVX512PF");
20341 break;
32930e4e 20342 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
20343 printf ("AVX512VL");
20344 break;
32930e4e 20345 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
20346 printf ("AVX512DQ");
20347 break;
32930e4e 20348 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
20349 printf ("AVX512BW");
20350 break;
32930e4e 20351 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
20352 printf ("AVX512_4FMAPS");
20353 break;
32930e4e 20354 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
20355 printf ("AVX512_4VNNIW");
20356 break;
32930e4e 20357 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
20358 printf ("AVX512_BITALG");
20359 break;
32930e4e 20360 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
20361 printf ("AVX512_IFMA");
20362 break;
32930e4e 20363 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
20364 printf ("AVX512_VBMI");
20365 break;
32930e4e 20366 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
20367 printf ("AVX512_VBMI2");
20368 break;
32930e4e 20369 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
20370 printf ("AVX512_VNNI");
20371 break;
32930e4e 20372 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
20373 printf ("AVX512_BF16");
20374 break;
65b3d26e
L
20375 default:
20376 printf (_("<unknown: %x>"), bit);
20377 break;
9ef920e9
NC
20378 }
20379 if (bitmask)
20380 printf (", ");
20381 }
20382}
20383
28cdbb18
SM
20384static const char *
20385get_amdgpu_elf_note_type (unsigned int e_type)
20386{
20387 switch (e_type)
20388 {
20389 case NT_AMDGPU_METADATA:
20390 return _("NT_AMDGPU_METADATA (code object metadata)");
20391 default:
20392 {
20393 static char buf[64];
20394 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
20395 return buf;
20396 }
20397 }
20398}
20399
32930e4e
L
20400static void
20401decode_x86_isa (unsigned int bitmask)
20402{
32930e4e
L
20403 while (bitmask)
20404 {
20405 unsigned int bit = bitmask & (- bitmask);
20406
20407 bitmask &= ~ bit;
20408 switch (bit)
20409 {
b0ab0693
L
20410 case GNU_PROPERTY_X86_ISA_1_BASELINE:
20411 printf ("x86-64-baseline");
20412 break;
32930e4e
L
20413 case GNU_PROPERTY_X86_ISA_1_V2:
20414 printf ("x86-64-v2");
20415 break;
20416 case GNU_PROPERTY_X86_ISA_1_V3:
20417 printf ("x86-64-v3");
20418 break;
20419 case GNU_PROPERTY_X86_ISA_1_V4:
20420 printf ("x86-64-v4");
20421 break;
20422 default:
20423 printf (_("<unknown: %x>"), bit);
20424 break;
20425 }
20426 if (bitmask)
20427 printf (", ");
20428 }
20429}
20430
ee2fdd6f 20431static void
a9eafb08 20432decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 20433{
0a59decb 20434 if (!bitmask)
90c745dc
L
20435 {
20436 printf (_("<None>"));
20437 return;
20438 }
90c745dc 20439
ee2fdd6f
L
20440 while (bitmask)
20441 {
20442 unsigned int bit = bitmask & (- bitmask);
20443
20444 bitmask &= ~ bit;
20445 switch (bit)
20446 {
20447 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 20448 printf ("IBT");
ee2fdd6f 20449 break;
48580982 20450 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 20451 printf ("SHSTK");
48580982 20452 break;
279d901e
L
20453 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
20454 printf ("LAM_U48");
20455 break;
20456 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
20457 printf ("LAM_U57");
20458 break;
ee2fdd6f
L
20459 default:
20460 printf (_("<unknown: %x>"), bit);
20461 break;
20462 }
20463 if (bitmask)
20464 printf (", ");
20465 }
20466}
20467
a9eafb08
L
20468static void
20469decode_x86_feature_2 (unsigned int bitmask)
20470{
0a59decb 20471 if (!bitmask)
90c745dc
L
20472 {
20473 printf (_("<None>"));
20474 return;
20475 }
90c745dc 20476
a9eafb08
L
20477 while (bitmask)
20478 {
20479 unsigned int bit = bitmask & (- bitmask);
20480
20481 bitmask &= ~ bit;
20482 switch (bit)
20483 {
20484 case GNU_PROPERTY_X86_FEATURE_2_X86:
20485 printf ("x86");
20486 break;
20487 case GNU_PROPERTY_X86_FEATURE_2_X87:
20488 printf ("x87");
20489 break;
20490 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20491 printf ("MMX");
20492 break;
20493 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20494 printf ("XMM");
20495 break;
20496 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20497 printf ("YMM");
20498 break;
20499 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20500 printf ("ZMM");
20501 break;
a308b89d
L
20502 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20503 printf ("TMM");
20504 break;
32930e4e
L
20505 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20506 printf ("MASK");
20507 break;
a9eafb08
L
20508 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20509 printf ("FXSR");
20510 break;
20511 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20512 printf ("XSAVE");
20513 break;
20514 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20515 printf ("XSAVEOPT");
20516 break;
20517 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20518 printf ("XSAVEC");
20519 break;
65b3d26e
L
20520 default:
20521 printf (_("<unknown: %x>"), bit);
20522 break;
a9eafb08
L
20523 }
20524 if (bitmask)
20525 printf (", ");
20526 }
20527}
20528
cd702818
SD
20529static void
20530decode_aarch64_feature_1_and (unsigned int bitmask)
20531{
20532 while (bitmask)
20533 {
20534 unsigned int bit = bitmask & (- bitmask);
20535
20536 bitmask &= ~ bit;
20537 switch (bit)
20538 {
20539 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20540 printf ("BTI");
20541 break;
20542
20543 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20544 printf ("PAC");
20545 break;
20546
20547 default:
20548 printf (_("<unknown: %x>"), bit);
20549 break;
20550 }
20551 if (bitmask)
20552 printf (", ");
20553 }
20554}
20555
6320fd00
L
20556static void
20557decode_1_needed (unsigned int bitmask)
20558{
20559 while (bitmask)
20560 {
20561 unsigned int bit = bitmask & (- bitmask);
20562
20563 bitmask &= ~ bit;
20564 switch (bit)
20565 {
20566 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20567 printf ("indirect external access");
20568 break;
20569 default:
20570 printf (_("<unknown: %x>"), bit);
20571 break;
20572 }
20573 if (bitmask)
20574 printf (", ");
20575 }
20576}
20577
9ef920e9 20578static void
dda8d76d 20579print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
20580{
20581 unsigned char * ptr = (unsigned char *) pnote->descdata;
20582 unsigned char * ptr_end = ptr + pnote->descsz;
20583 unsigned int size = is_32bit_elf ? 4 : 8;
20584
20585 printf (_(" Properties: "));
20586
1fc87489 20587 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
20588 {
20589 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
20590 return;
20591 }
20592
6ab2c4ed 20593 while (ptr < ptr_end)
9ef920e9 20594 {
1fc87489 20595 unsigned int j;
6ab2c4ed
MC
20596 unsigned int type;
20597 unsigned int datasz;
20598
20599 if ((size_t) (ptr_end - ptr) < 8)
20600 {
20601 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
20602 break;
20603 }
20604
20605 type = byte_get (ptr, 4);
20606 datasz = byte_get (ptr + 4, 4);
9ef920e9 20607
1fc87489 20608 ptr += 8;
9ef920e9 20609
6ab2c4ed 20610 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 20611 {
1fc87489
L
20612 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
20613 type, datasz);
9ef920e9 20614 break;
1fc87489 20615 }
9ef920e9 20616
1fc87489
L
20617 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20618 {
dda8d76d
NC
20619 if (filedata->file_header.e_machine == EM_X86_64
20620 || filedata->file_header.e_machine == EM_IAMCU
20621 || filedata->file_header.e_machine == EM_386)
1fc87489 20622 {
aa7bca9b
L
20623 unsigned int bitmask;
20624
20625 if (datasz == 4)
0a59decb 20626 bitmask = byte_get (ptr, 4);
aa7bca9b
L
20627 else
20628 bitmask = 0;
20629
1fc87489
L
20630 switch (type)
20631 {
20632 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 20633 if (datasz != 4)
aa7bca9b
L
20634 printf (_("x86 ISA used: <corrupt length: %#x> "),
20635 datasz);
1fc87489 20636 else
aa7bca9b
L
20637 {
20638 printf ("x86 ISA used: ");
20639 decode_x86_isa (bitmask);
20640 }
1fc87489 20641 goto next;
9ef920e9 20642
1fc87489 20643 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20644 if (datasz != 4)
aa7bca9b
L
20645 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20646 datasz);
1fc87489 20647 else
aa7bca9b
L
20648 {
20649 printf ("x86 ISA needed: ");
20650 decode_x86_isa (bitmask);
20651 }
1fc87489 20652 goto next;
9ef920e9 20653
ee2fdd6f 20654 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20655 if (datasz != 4)
aa7bca9b
L
20656 printf (_("x86 feature: <corrupt length: %#x> "),
20657 datasz);
ee2fdd6f 20658 else
aa7bca9b
L
20659 {
20660 printf ("x86 feature: ");
a9eafb08
L
20661 decode_x86_feature_1 (bitmask);
20662 }
20663 goto next;
20664
20665 case GNU_PROPERTY_X86_FEATURE_2_USED:
20666 if (datasz != 4)
20667 printf (_("x86 feature used: <corrupt length: %#x> "),
20668 datasz);
20669 else
20670 {
20671 printf ("x86 feature used: ");
20672 decode_x86_feature_2 (bitmask);
20673 }
20674 goto next;
20675
20676 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20677 if (datasz != 4)
20678 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20679 else
20680 {
20681 printf ("x86 feature needed: ");
20682 decode_x86_feature_2 (bitmask);
20683 }
20684 goto next;
20685
20686 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20687 if (datasz != 4)
20688 printf (_("x86 ISA used: <corrupt length: %#x> "),
20689 datasz);
20690 else
20691 {
20692 printf ("x86 ISA used: ");
20693 decode_x86_compat_isa (bitmask);
20694 }
20695 goto next;
20696
20697 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20698 if (datasz != 4)
20699 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20700 datasz);
20701 else
20702 {
20703 printf ("x86 ISA needed: ");
20704 decode_x86_compat_isa (bitmask);
aa7bca9b 20705 }
ee2fdd6f
L
20706 goto next;
20707
32930e4e
L
20708 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20709 if (datasz != 4)
20710 printf (_("x86 ISA used: <corrupt length: %#x> "),
20711 datasz);
20712 else
20713 {
20714 printf ("x86 ISA used: ");
20715 decode_x86_compat_2_isa (bitmask);
20716 }
20717 goto next;
20718
20719 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20720 if (datasz != 4)
20721 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20722 datasz);
20723 else
20724 {
20725 printf ("x86 ISA needed: ");
20726 decode_x86_compat_2_isa (bitmask);
20727 }
20728 goto next;
20729
1fc87489
L
20730 default:
20731 break;
20732 }
20733 }
cd702818
SD
20734 else if (filedata->file_header.e_machine == EM_AARCH64)
20735 {
20736 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20737 {
20738 printf ("AArch64 feature: ");
20739 if (datasz != 4)
20740 printf (_("<corrupt length: %#x> "), datasz);
20741 else
20742 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20743 goto next;
20744 }
20745 }
1fc87489
L
20746 }
20747 else
20748 {
20749 switch (type)
9ef920e9 20750 {
1fc87489
L
20751 case GNU_PROPERTY_STACK_SIZE:
20752 printf (_("stack size: "));
20753 if (datasz != size)
20754 printf (_("<corrupt length: %#x> "), datasz);
20755 else
26c527e6 20756 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
20757 goto next;
20758
20759 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20760 printf ("no copy on protected ");
20761 if (datasz)
20762 printf (_("<corrupt length: %#x> "), datasz);
20763 goto next;
20764
20765 default:
5a767724
L
20766 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20767 && type <= GNU_PROPERTY_UINT32_AND_HI)
20768 || (type >= GNU_PROPERTY_UINT32_OR_LO
20769 && type <= GNU_PROPERTY_UINT32_OR_HI))
20770 {
6320fd00
L
20771 switch (type)
20772 {
20773 case GNU_PROPERTY_1_NEEDED:
20774 if (datasz != 4)
20775 printf (_("1_needed: <corrupt length: %#x> "),
20776 datasz);
20777 else
20778 {
20779 unsigned int bitmask = byte_get (ptr, 4);
20780 printf ("1_needed: ");
20781 decode_1_needed (bitmask);
20782 }
20783 goto next;
20784
20785 default:
20786 break;
20787 }
5a767724
L
20788 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20789 printf (_("UINT32_AND (%#x): "), type);
20790 else
20791 printf (_("UINT32_OR (%#x): "), type);
20792 if (datasz != 4)
20793 printf (_("<corrupt length: %#x> "), datasz);
20794 else
20795 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20796 goto next;
20797 }
9ef920e9
NC
20798 break;
20799 }
9ef920e9
NC
20800 }
20801
1fc87489
L
20802 if (type < GNU_PROPERTY_LOPROC)
20803 printf (_("<unknown type %#x data: "), type);
20804 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20805 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20806 else
20807 printf (_("<application-specific type %#x data: "), type);
20808 for (j = 0; j < datasz; ++j)
20809 printf ("%02x ", ptr[j] & 0xff);
20810 printf (">");
20811
dc1e8a47 20812 next:
9ef920e9 20813 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20814 if (ptr == ptr_end)
20815 break;
1fc87489 20816
6ab2c4ed
MC
20817 if (do_wide)
20818 printf (", ");
20819 else
20820 printf ("\n\t");
9ef920e9
NC
20821 }
20822
20823 printf ("\n");
20824}
20825
015dc7e1 20826static bool
dda8d76d 20827print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20828{
1449284b 20829 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20830 switch (pnote->type)
20831 {
20832 case NT_GNU_BUILD_ID:
20833 {
26c527e6 20834 size_t i;
664f90a3
TT
20835
20836 printf (_(" Build ID: "));
20837 for (i = 0; i < pnote->descsz; ++i)
20838 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20839 printf ("\n");
664f90a3
TT
20840 }
20841 break;
20842
20843 case NT_GNU_ABI_TAG:
20844 {
26c527e6 20845 unsigned int os, major, minor, subminor;
664f90a3
TT
20846 const char *osname;
20847
3102e897
NC
20848 /* PR 17531: file: 030-599401-0.004. */
20849 if (pnote->descsz < 16)
20850 {
20851 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20852 break;
20853 }
20854
664f90a3
TT
20855 os = byte_get ((unsigned char *) pnote->descdata, 4);
20856 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20857 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20858 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20859
20860 switch (os)
20861 {
20862 case GNU_ABI_TAG_LINUX:
20863 osname = "Linux";
20864 break;
20865 case GNU_ABI_TAG_HURD:
20866 osname = "Hurd";
20867 break;
20868 case GNU_ABI_TAG_SOLARIS:
20869 osname = "Solaris";
20870 break;
20871 case GNU_ABI_TAG_FREEBSD:
20872 osname = "FreeBSD";
20873 break;
20874 case GNU_ABI_TAG_NETBSD:
20875 osname = "NetBSD";
20876 break;
14ae95f2
RM
20877 case GNU_ABI_TAG_SYLLABLE:
20878 osname = "Syllable";
20879 break;
20880 case GNU_ABI_TAG_NACL:
20881 osname = "NaCl";
20882 break;
664f90a3
TT
20883 default:
20884 osname = "Unknown";
20885 break;
20886 }
20887
26c527e6 20888 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
20889 major, minor, subminor);
20890 }
20891 break;
926c5385
CC
20892
20893 case NT_GNU_GOLD_VERSION:
20894 {
26c527e6 20895 size_t i;
926c5385
CC
20896
20897 printf (_(" Version: "));
20898 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20899 printf ("%c", pnote->descdata[i]);
20900 printf ("\n");
20901 }
20902 break;
1449284b
NC
20903
20904 case NT_GNU_HWCAP:
20905 {
26c527e6 20906 unsigned int num_entries, mask;
1449284b
NC
20907
20908 /* Hardware capabilities information. Word 0 is the number of entries.
20909 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20910 is a series of entries, where each entry is a single byte followed
20911 by a nul terminated string. The byte gives the bit number to test
20912 if enabled in the bitmask. */
20913 printf (_(" Hardware Capabilities: "));
20914 if (pnote->descsz < 8)
20915 {
32ec8896 20916 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20917 return false;
1449284b
NC
20918 }
20919 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20920 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 20921 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
20922 /* FIXME: Add code to display the entries... */
20923 }
20924 break;
20925
9ef920e9 20926 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20927 print_gnu_property_note (filedata, pnote);
9ef920e9 20928 break;
9abca702 20929
1449284b
NC
20930 default:
20931 /* Handle unrecognised types. An error message should have already been
20932 created by get_gnu_elf_note_type(), so all that we need to do is to
20933 display the data. */
20934 {
26c527e6 20935 size_t i;
1449284b
NC
20936
20937 printf (_(" Description data: "));
20938 for (i = 0; i < pnote->descsz; ++i)
20939 printf ("%02x ", pnote->descdata[i] & 0xff);
20940 printf ("\n");
20941 }
20942 break;
664f90a3
TT
20943 }
20944
015dc7e1 20945 return true;
664f90a3
TT
20946}
20947
685080f2
NC
20948static const char *
20949get_v850_elf_note_type (enum v850_notes n_type)
20950{
20951 static char buff[64];
20952
20953 switch (n_type)
20954 {
20955 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20956 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20957 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20958 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20959 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20960 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20961 default:
20962 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20963 return buff;
20964 }
20965}
20966
015dc7e1 20967static bool
685080f2
NC
20968print_v850_note (Elf_Internal_Note * pnote)
20969{
20970 unsigned int val;
20971
20972 if (pnote->descsz != 4)
015dc7e1 20973 return false;
32ec8896 20974
685080f2
NC
20975 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20976
20977 if (val == 0)
20978 {
20979 printf (_("not set\n"));
015dc7e1 20980 return true;
685080f2
NC
20981 }
20982
20983 switch (pnote->type)
20984 {
20985 case V850_NOTE_ALIGNMENT:
20986 switch (val)
20987 {
015dc7e1
AM
20988 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20989 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20990 }
20991 break;
14ae95f2 20992
685080f2
NC
20993 case V850_NOTE_DATA_SIZE:
20994 switch (val)
20995 {
015dc7e1
AM
20996 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20997 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20998 }
20999 break;
14ae95f2 21000
685080f2
NC
21001 case V850_NOTE_FPU_INFO:
21002 switch (val)
21003 {
015dc7e1
AM
21004 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
21005 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
21006 }
21007 break;
14ae95f2 21008
685080f2
NC
21009 case V850_NOTE_MMU_INFO:
21010 case V850_NOTE_CACHE_INFO:
21011 case V850_NOTE_SIMD_INFO:
21012 if (val == EF_RH850_SIMD)
21013 {
21014 printf (_("yes\n"));
015dc7e1 21015 return true;
685080f2
NC
21016 }
21017 break;
21018
21019 default:
21020 /* An 'unknown note type' message will already have been displayed. */
21021 break;
21022 }
21023
21024 printf (_("unknown value: %x\n"), val);
015dc7e1 21025 return false;
685080f2
NC
21026}
21027
015dc7e1 21028static bool
c6056a74
SF
21029process_netbsd_elf_note (Elf_Internal_Note * pnote)
21030{
21031 unsigned int version;
21032
21033 switch (pnote->type)
21034 {
21035 case NT_NETBSD_IDENT:
b966f55f
AM
21036 if (pnote->descsz < 1)
21037 break;
c6056a74
SF
21038 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21039 if ((version / 10000) % 100)
b966f55f 21040 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
21041 version, version / 100000000, (version / 1000000) % 100,
21042 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 21043 'A' + (version / 10000) % 26);
c6056a74
SF
21044 else
21045 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 21046 version, version / 100000000, (version / 1000000) % 100,
15f205b1 21047 (version / 100) % 100);
015dc7e1 21048 return true;
c6056a74
SF
21049
21050 case NT_NETBSD_MARCH:
9abca702 21051 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 21052 pnote->descdata);
015dc7e1 21053 return true;
c6056a74 21054
9abca702 21055 case NT_NETBSD_PAX:
b966f55f
AM
21056 if (pnote->descsz < 1)
21057 break;
9abca702
CZ
21058 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21059 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
21060 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
21061 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
21062 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
21063 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
21064 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
21065 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 21066 return true;
c6056a74 21067 }
b966f55f
AM
21068
21069 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
21070 pnote->descsz, pnote->type);
015dc7e1 21071 return false;
c6056a74
SF
21072}
21073
f4ddf30f 21074static const char *
dda8d76d 21075get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 21076{
f4ddf30f
JB
21077 switch (e_type)
21078 {
21079 case NT_FREEBSD_THRMISC:
21080 return _("NT_THRMISC (thrmisc structure)");
21081 case NT_FREEBSD_PROCSTAT_PROC:
21082 return _("NT_PROCSTAT_PROC (proc data)");
21083 case NT_FREEBSD_PROCSTAT_FILES:
21084 return _("NT_PROCSTAT_FILES (files data)");
21085 case NT_FREEBSD_PROCSTAT_VMMAP:
21086 return _("NT_PROCSTAT_VMMAP (vmmap data)");
21087 case NT_FREEBSD_PROCSTAT_GROUPS:
21088 return _("NT_PROCSTAT_GROUPS (groups data)");
21089 case NT_FREEBSD_PROCSTAT_UMASK:
21090 return _("NT_PROCSTAT_UMASK (umask data)");
21091 case NT_FREEBSD_PROCSTAT_RLIMIT:
21092 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
21093 case NT_FREEBSD_PROCSTAT_OSREL:
21094 return _("NT_PROCSTAT_OSREL (osreldate data)");
21095 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
21096 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
21097 case NT_FREEBSD_PROCSTAT_AUXV:
21098 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
21099 case NT_FREEBSD_PTLWPINFO:
21100 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
21101 case NT_FREEBSD_X86_SEGBASES:
21102 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 21103 }
dda8d76d 21104 return get_note_type (filedata, e_type);
f4ddf30f
JB
21105}
21106
9437c45b 21107static const char *
dda8d76d 21108get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
21109{
21110 static char buff[64];
21111
540e6170
CZ
21112 switch (e_type)
21113 {
21114 case NT_NETBSDCORE_PROCINFO:
21115 /* NetBSD core "procinfo" structure. */
21116 return _("NetBSD procinfo structure");
9437c45b 21117
540e6170
CZ
21118 case NT_NETBSDCORE_AUXV:
21119 return _("NetBSD ELF auxiliary vector data");
9437c45b 21120
06d949ec
KR
21121 case NT_NETBSDCORE_LWPSTATUS:
21122 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 21123
540e6170 21124 default:
06d949ec 21125 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
21126 defined for NetBSD core files. If the note type is less
21127 than the start of the machine-dependent note types, we don't
21128 understand it. */
21129
21130 if (e_type < NT_NETBSDCORE_FIRSTMACH)
21131 {
21132 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21133 return buff;
21134 }
21135 break;
9437c45b
JT
21136 }
21137
dda8d76d 21138 switch (filedata->file_header.e_machine)
9437c45b
JT
21139 {
21140 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
21141 and PT_GETFPREGS == mach+2. */
21142
21143 case EM_OLD_ALPHA:
21144 case EM_ALPHA:
21145 case EM_SPARC:
21146 case EM_SPARC32PLUS:
21147 case EM_SPARCV9:
21148 switch (e_type)
21149 {
2b692964 21150 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 21151 return _("PT_GETREGS (reg structure)");
2b692964 21152 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 21153 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21154 default:
21155 break;
21156 }
21157 break;
21158
c0d38b0e
CZ
21159 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
21160 There's also old PT___GETREGS40 == mach + 1 for old reg
21161 structure which lacks GBR. */
21162 case EM_SH:
21163 switch (e_type)
21164 {
21165 case NT_NETBSDCORE_FIRSTMACH + 1:
21166 return _("PT___GETREGS40 (old reg structure)");
21167 case NT_NETBSDCORE_FIRSTMACH + 3:
21168 return _("PT_GETREGS (reg structure)");
21169 case NT_NETBSDCORE_FIRSTMACH + 5:
21170 return _("PT_GETFPREGS (fpreg structure)");
21171 default:
21172 break;
21173 }
21174 break;
21175
9437c45b
JT
21176 /* On all other arch's, PT_GETREGS == mach+1 and
21177 PT_GETFPREGS == mach+3. */
21178 default:
21179 switch (e_type)
21180 {
2b692964 21181 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 21182 return _("PT_GETREGS (reg structure)");
2b692964 21183 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 21184 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21185 default:
21186 break;
21187 }
21188 }
21189
9cf03b7e 21190 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 21191 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
21192 return buff;
21193}
21194
98ca73af
FC
21195static const char *
21196get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21197{
21198 switch (e_type)
21199 {
21200 case NT_OPENBSD_PROCINFO:
21201 return _("OpenBSD procinfo structure");
21202 case NT_OPENBSD_AUXV:
21203 return _("OpenBSD ELF auxiliary vector data");
21204 case NT_OPENBSD_REGS:
21205 return _("OpenBSD regular registers");
21206 case NT_OPENBSD_FPREGS:
21207 return _("OpenBSD floating point registers");
21208 case NT_OPENBSD_WCOOKIE:
21209 return _("OpenBSD window cookie");
21210 }
21211
21212 return get_note_type (filedata, e_type);
21213}
21214
e263a66b
CC
21215static const char *
21216get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
21217{
21218 switch (e_type)
21219 {
21220 case QNT_DEBUG_FULLPATH:
21221 return _("QNX debug fullpath");
21222 case QNT_DEBUG_RELOC:
21223 return _("QNX debug relocation");
21224 case QNT_STACK:
21225 return _("QNX stack");
21226 case QNT_GENERATOR:
21227 return _("QNX generator");
21228 case QNT_DEFAULT_LIB:
21229 return _("QNX default library");
21230 case QNT_CORE_SYSINFO:
21231 return _("QNX core sysinfo");
21232 case QNT_CORE_INFO:
21233 return _("QNX core info");
21234 case QNT_CORE_STATUS:
21235 return _("QNX core status");
21236 case QNT_CORE_GREG:
21237 return _("QNX general registers");
21238 case QNT_CORE_FPREG:
21239 return _("QNX floating point registers");
21240 case QNT_LINK_MAP:
21241 return _("QNX link map");
21242 }
21243
21244 return get_note_type (filedata, e_type);
21245}
21246
70616151
TT
21247static const char *
21248get_stapsdt_note_type (unsigned e_type)
21249{
21250 static char buff[64];
21251
21252 switch (e_type)
21253 {
21254 case NT_STAPSDT:
21255 return _("NT_STAPSDT (SystemTap probe descriptors)");
21256
21257 default:
21258 break;
21259 }
21260
21261 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21262 return buff;
21263}
21264
015dc7e1 21265static bool
c6a9fc58
TT
21266print_stapsdt_note (Elf_Internal_Note *pnote)
21267{
3ca60c57 21268 size_t len, maxlen;
26c527e6 21269 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
21270 char *data = pnote->descdata;
21271 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 21272 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
21273 char *provider, *probe, *arg_fmt;
21274
3ca60c57
NC
21275 if (pnote->descsz < (addr_size * 3))
21276 goto stapdt_note_too_small;
21277
c6a9fc58
TT
21278 pc = byte_get ((unsigned char *) data, addr_size);
21279 data += addr_size;
3ca60c57 21280
c6a9fc58
TT
21281 base_addr = byte_get ((unsigned char *) data, addr_size);
21282 data += addr_size;
3ca60c57 21283
c6a9fc58
TT
21284 semaphore = byte_get ((unsigned char *) data, addr_size);
21285 data += addr_size;
21286
3ca60c57
NC
21287 if (data >= data_end)
21288 goto stapdt_note_too_small;
21289 maxlen = data_end - data;
21290 len = strnlen (data, maxlen);
21291 if (len < maxlen)
21292 {
21293 provider = data;
21294 data += len + 1;
21295 }
21296 else
21297 goto stapdt_note_too_small;
21298
21299 if (data >= data_end)
21300 goto stapdt_note_too_small;
21301 maxlen = data_end - data;
21302 len = strnlen (data, maxlen);
21303 if (len < maxlen)
21304 {
21305 probe = data;
21306 data += len + 1;
21307 }
21308 else
21309 goto stapdt_note_too_small;
9abca702 21310
3ca60c57
NC
21311 if (data >= data_end)
21312 goto stapdt_note_too_small;
21313 maxlen = data_end - data;
21314 len = strnlen (data, maxlen);
21315 if (len < maxlen)
21316 {
21317 arg_fmt = data;
21318 data += len + 1;
21319 }
21320 else
21321 goto stapdt_note_too_small;
c6a9fc58
TT
21322
21323 printf (_(" Provider: %s\n"), provider);
21324 printf (_(" Name: %s\n"), probe);
21325 printf (_(" Location: "));
21326 print_vma (pc, FULL_HEX);
21327 printf (_(", Base: "));
21328 print_vma (base_addr, FULL_HEX);
21329 printf (_(", Semaphore: "));
21330 print_vma (semaphore, FULL_HEX);
9cf03b7e 21331 printf ("\n");
c6a9fc58
TT
21332 printf (_(" Arguments: %s\n"), arg_fmt);
21333
21334 return data == data_end;
3ca60c57
NC
21335
21336 stapdt_note_too_small:
21337 printf (_(" <corrupt - note is too small>\n"));
21338 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 21339 return false;
c6a9fc58
TT
21340}
21341
e5382207
LB
21342static bool
21343print_fdo_note (Elf_Internal_Note * pnote)
21344{
21345 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
21346 {
21347 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
21348 return true;
21349 }
21350 return false;
21351}
21352
00e98fc7
TG
21353static const char *
21354get_ia64_vms_note_type (unsigned e_type)
21355{
21356 static char buff[64];
21357
21358 switch (e_type)
21359 {
21360 case NT_VMS_MHD:
21361 return _("NT_VMS_MHD (module header)");
21362 case NT_VMS_LNM:
21363 return _("NT_VMS_LNM (language name)");
21364 case NT_VMS_SRC:
21365 return _("NT_VMS_SRC (source files)");
21366 case NT_VMS_TITLE:
9cf03b7e 21367 return "NT_VMS_TITLE";
00e98fc7
TG
21368 case NT_VMS_EIDC:
21369 return _("NT_VMS_EIDC (consistency check)");
21370 case NT_VMS_FPMODE:
21371 return _("NT_VMS_FPMODE (FP mode)");
21372 case NT_VMS_LINKTIME:
9cf03b7e 21373 return "NT_VMS_LINKTIME";
00e98fc7
TG
21374 case NT_VMS_IMGNAM:
21375 return _("NT_VMS_IMGNAM (image name)");
21376 case NT_VMS_IMGID:
21377 return _("NT_VMS_IMGID (image id)");
21378 case NT_VMS_LINKID:
21379 return _("NT_VMS_LINKID (link id)");
21380 case NT_VMS_IMGBID:
21381 return _("NT_VMS_IMGBID (build id)");
21382 case NT_VMS_GSTNAM:
21383 return _("NT_VMS_GSTNAM (sym table name)");
21384 case NT_VMS_ORIG_DYN:
9cf03b7e 21385 return "NT_VMS_ORIG_DYN";
00e98fc7 21386 case NT_VMS_PATCHTIME:
9cf03b7e 21387 return "NT_VMS_PATCHTIME";
00e98fc7
TG
21388 default:
21389 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21390 return buff;
21391 }
21392}
21393
015dc7e1 21394static bool
00e98fc7
TG
21395print_ia64_vms_note (Elf_Internal_Note * pnote)
21396{
26c527e6 21397 unsigned int maxlen = pnote->descsz;
8d18bf79 21398
26c527e6 21399 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
21400 goto desc_size_fail;
21401
00e98fc7
TG
21402 switch (pnote->type)
21403 {
21404 case NT_VMS_MHD:
8d18bf79
NC
21405 if (maxlen <= 36)
21406 goto desc_size_fail;
21407
26c527e6 21408 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
21409
21410 printf (_(" Creation date : %.17s\n"), pnote->descdata);
21411 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
21412 if (l + 34 < maxlen)
21413 {
21414 printf (_(" Module name : %s\n"), pnote->descdata + 34);
21415 if (l + 35 < maxlen)
21416 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
21417 else
21418 printf (_(" Module version : <missing>\n"));
21419 }
00e98fc7 21420 else
8d18bf79
NC
21421 {
21422 printf (_(" Module name : <missing>\n"));
21423 printf (_(" Module version : <missing>\n"));
21424 }
00e98fc7 21425 break;
8d18bf79 21426
00e98fc7 21427 case NT_VMS_LNM:
8d18bf79 21428 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21429 break;
8d18bf79 21430
00e98fc7 21431 case NT_VMS_FPMODE:
9cf03b7e 21432 printf (_(" Floating Point mode: "));
8d18bf79
NC
21433 if (maxlen < 8)
21434 goto desc_size_fail;
21435 /* FIXME: Generate an error if descsz > 8 ? */
21436
b8281767 21437 printf ("0x%016" PRIx64 "\n",
625d49fc 21438 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 21439 break;
8d18bf79 21440
00e98fc7
TG
21441 case NT_VMS_LINKTIME:
21442 printf (_(" Link time: "));
8d18bf79
NC
21443 if (maxlen < 8)
21444 goto desc_size_fail;
21445 /* FIXME: Generate an error if descsz > 8 ? */
21446
0e3c1eeb 21447 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21448 printf ("\n");
21449 break;
8d18bf79 21450
00e98fc7
TG
21451 case NT_VMS_PATCHTIME:
21452 printf (_(" Patch time: "));
8d18bf79
NC
21453 if (maxlen < 8)
21454 goto desc_size_fail;
21455 /* FIXME: Generate an error if descsz > 8 ? */
21456
0e3c1eeb 21457 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21458 printf ("\n");
21459 break;
8d18bf79 21460
00e98fc7 21461 case NT_VMS_ORIG_DYN:
8d18bf79
NC
21462 if (maxlen < 34)
21463 goto desc_size_fail;
21464
00e98fc7 21465 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
21466 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
21467 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 21468 printf (_(" Last modified : "));
0e3c1eeb 21469 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 21470 printf (_("\n Link flags : "));
b8281767 21471 printf ("0x%016" PRIx64 "\n",
625d49fc 21472 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 21473 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 21474 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 21475 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 21476 break;
8d18bf79 21477
00e98fc7 21478 case NT_VMS_IMGNAM:
8d18bf79 21479 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21480 break;
8d18bf79 21481
00e98fc7 21482 case NT_VMS_GSTNAM:
8d18bf79 21483 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21484 break;
8d18bf79 21485
00e98fc7 21486 case NT_VMS_IMGID:
8d18bf79 21487 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21488 break;
8d18bf79 21489
00e98fc7 21490 case NT_VMS_LINKID:
8d18bf79 21491 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21492 break;
8d18bf79 21493
00e98fc7 21494 default:
015dc7e1 21495 return false;
00e98fc7 21496 }
8d18bf79 21497
015dc7e1 21498 return true;
8d18bf79
NC
21499
21500 desc_size_fail:
21501 printf (_(" <corrupt - data size is too small>\n"));
21502 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 21503 return false;
00e98fc7
TG
21504}
21505
fd486f32
AM
21506struct build_attr_cache {
21507 Filedata *filedata;
21508 char *strtab;
26c527e6 21509 uint64_t strtablen;
fd486f32 21510 Elf_Internal_Sym *symtab;
26c527e6 21511 uint64_t nsyms;
fd486f32
AM
21512} ba_cache;
21513
6f156d7a
NC
21514/* Find the symbol associated with a build attribute that is attached
21515 to address OFFSET. If PNAME is non-NULL then store the name of
21516 the symbol (if found) in the provided pointer, Returns NULL if a
21517 symbol could not be found. */
c799a79d 21518
6f156d7a 21519static Elf_Internal_Sym *
015dc7e1 21520get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 21521 uint64_t offset,
015dc7e1
AM
21522 bool is_open_attr,
21523 const char **pname)
9ef920e9 21524{
fd486f32
AM
21525 Elf_Internal_Sym *saved_sym = NULL;
21526 Elf_Internal_Sym *sym;
9ef920e9 21527
dda8d76d 21528 if (filedata->section_headers != NULL
fd486f32 21529 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 21530 {
c799a79d 21531 Elf_Internal_Shdr * symsec;
9ef920e9 21532
fd486f32
AM
21533 free (ba_cache.strtab);
21534 ba_cache.strtab = NULL;
21535 free (ba_cache.symtab);
21536 ba_cache.symtab = NULL;
21537
c799a79d 21538 /* Load the symbol and string sections. */
dda8d76d
NC
21539 for (symsec = filedata->section_headers;
21540 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 21541 symsec ++)
9ef920e9 21542 {
28d13567
AM
21543 if (symsec->sh_type == SHT_SYMTAB
21544 && get_symtab (filedata, symsec,
21545 &ba_cache.symtab, &ba_cache.nsyms,
21546 &ba_cache.strtab, &ba_cache.strtablen))
21547 break;
9ef920e9 21548 }
fd486f32 21549 ba_cache.filedata = filedata;
9ef920e9
NC
21550 }
21551
fd486f32 21552 if (ba_cache.symtab == NULL)
6f156d7a 21553 return NULL;
9ef920e9 21554
c799a79d 21555 /* Find a symbol whose value matches offset. */
fd486f32 21556 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
21557 if (sym->st_value == offset)
21558 {
fd486f32 21559 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
21560 /* Huh ? This should not happen. */
21561 continue;
9ef920e9 21562
fd486f32 21563 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 21564 continue;
9ef920e9 21565
9b9b1092 21566 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 21567 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
21568 if (ba_cache.strtab[sym->st_name] == '$'
21569 && ba_cache.strtab[sym->st_name + 1] != 0
21570 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
21571 continue;
21572
c799a79d
NC
21573 if (is_open_attr)
21574 {
21575 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
21576 and FILE or OBJECT symbols over NOTYPE symbols. We skip
21577 FUNC symbols entirely. */
21578 switch (ELF_ST_TYPE (sym->st_info))
21579 {
c799a79d 21580 case STT_OBJECT:
6f156d7a 21581 case STT_FILE:
c799a79d 21582 saved_sym = sym;
6f156d7a
NC
21583 if (sym->st_size)
21584 {
21585 /* If the symbol has a size associated
21586 with it then we can stop searching. */
fd486f32 21587 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 21588 }
c799a79d 21589 continue;
9ef920e9 21590
c799a79d
NC
21591 case STT_FUNC:
21592 /* Ignore function symbols. */
21593 continue;
21594
21595 default:
21596 break;
21597 }
21598
21599 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 21600 {
c799a79d
NC
21601 case STB_GLOBAL:
21602 if (saved_sym == NULL
21603 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
21604 saved_sym = sym;
21605 break;
c871dade 21606
c799a79d
NC
21607 case STB_LOCAL:
21608 if (saved_sym == NULL)
21609 saved_sym = sym;
21610 break;
21611
21612 default:
9ef920e9
NC
21613 break;
21614 }
21615 }
c799a79d
NC
21616 else
21617 {
21618 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
21619 continue;
21620
21621 saved_sym = sym;
21622 break;
21623 }
21624 }
21625
6f156d7a 21626 if (saved_sym && pname)
fd486f32 21627 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
21628
21629 return saved_sym;
c799a79d
NC
21630}
21631
d20e98ab
NC
21632/* Returns true iff addr1 and addr2 are in the same section. */
21633
015dc7e1 21634static bool
26c527e6 21635same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
21636{
21637 Elf_Internal_Shdr * a1;
21638 Elf_Internal_Shdr * a2;
21639
21640 a1 = find_section_by_address (filedata, addr1);
21641 a2 = find_section_by_address (filedata, addr2);
9abca702 21642
d20e98ab
NC
21643 return a1 == a2 && a1 != NULL;
21644}
21645
015dc7e1 21646static bool
dda8d76d
NC
21647print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21648 Filedata * filedata)
c799a79d 21649{
26c527e6
AM
21650 static uint64_t global_offset = 0;
21651 static uint64_t global_end = 0;
21652 static uint64_t func_offset = 0;
21653 static uint64_t func_end = 0;
c871dade 21654
015dc7e1
AM
21655 Elf_Internal_Sym *sym;
21656 const char *name;
26c527e6
AM
21657 uint64_t start;
21658 uint64_t end;
015dc7e1 21659 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
21660
21661 switch (pnote->descsz)
c799a79d 21662 {
6f156d7a
NC
21663 case 0:
21664 /* A zero-length description means that the range of
21665 the previous note of the same type should be used. */
c799a79d 21666 if (is_open_attr)
c871dade 21667 {
6f156d7a 21668 if (global_end > global_offset)
26c527e6
AM
21669 printf (_(" Applies to region from %#" PRIx64
21670 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 21671 else
26c527e6
AM
21672 printf (_(" Applies to region from %#" PRIx64
21673 "\n"), global_offset);
c799a79d
NC
21674 }
21675 else
21676 {
6f156d7a 21677 if (func_end > func_offset)
26c527e6
AM
21678 printf (_(" Applies to region from %#" PRIx64
21679 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 21680 else
26c527e6
AM
21681 printf (_(" Applies to region from %#" PRIx64
21682 "\n"), func_offset);
c871dade 21683 }
015dc7e1 21684 return true;
9ef920e9 21685
6f156d7a
NC
21686 case 4:
21687 start = byte_get ((unsigned char *) pnote->descdata, 4);
21688 end = 0;
21689 break;
21690
21691 case 8:
c74147bb
NC
21692 start = byte_get ((unsigned char *) pnote->descdata, 4);
21693 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21694 break;
21695
21696 case 16:
21697 start = byte_get ((unsigned char *) pnote->descdata, 8);
21698 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21699 break;
9abca702 21700
6f156d7a 21701 default:
c799a79d
NC
21702 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21703 printf (_(" <invalid descsz>"));
015dc7e1 21704 return false;
c799a79d
NC
21705 }
21706
6f156d7a
NC
21707 name = NULL;
21708 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21709 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21710 in order to avoid them being confused with the start address of the
21711 first function in the file... */
21712 if (sym == NULL && is_open_attr)
21713 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21714 & name);
6f156d7a
NC
21715
21716 if (end == 0 && sym != NULL && sym->st_size > 0)
21717 end = start + sym->st_size;
c799a79d
NC
21718
21719 if (is_open_attr)
21720 {
d20e98ab
NC
21721 /* FIXME: Need to properly allow for section alignment.
21722 16 is just the alignment used on x86_64. */
21723 if (global_end > 0
21724 && start > BFD_ALIGN (global_end, 16)
21725 /* Build notes are not guaranteed to be organised in order of
21726 increasing address, but we should find the all of the notes
21727 for one section in the same place. */
21728 && same_section (filedata, start, global_end))
26c527e6
AM
21729 warn (_("Gap in build notes detected from %#" PRIx64
21730 " to %#" PRIx64 "\n"),
6f156d7a
NC
21731 global_end + 1, start - 1);
21732
26c527e6 21733 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21734 global_offset = start;
21735
21736 if (end)
21737 {
26c527e6 21738 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21739 global_end = end;
21740 }
c799a79d
NC
21741 }
21742 else
21743 {
26c527e6 21744 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21745 func_offset = start;
21746
21747 if (end)
21748 {
26c527e6 21749 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21750 func_end = end;
21751 }
c799a79d
NC
21752 }
21753
6f156d7a
NC
21754 if (sym && name)
21755 printf (_(" (%s)"), name);
21756
21757 printf ("\n");
015dc7e1 21758 return true;
9ef920e9
NC
21759}
21760
015dc7e1 21761static bool
9ef920e9
NC
21762print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21763{
1d15e434
NC
21764 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21765 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21766 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21767 char name_type;
21768 char name_attribute;
1d15e434 21769 const char * expected_types;
9ef920e9
NC
21770 const char * name = pnote->namedata;
21771 const char * text;
88305e1b 21772 signed int left;
9ef920e9
NC
21773
21774 if (name == NULL || pnote->namesz < 2)
21775 {
21776 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21777 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21778 return false;
9ef920e9
NC
21779 }
21780
6f156d7a
NC
21781 if (do_wide)
21782 left = 28;
21783 else
21784 left = 20;
88305e1b
NC
21785
21786 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21787 if (name[0] == 'G' && name[1] == 'A')
21788 {
6f156d7a
NC
21789 if (pnote->namesz < 4)
21790 {
21791 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21792 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21793 return false;
6f156d7a
NC
21794 }
21795
88305e1b
NC
21796 printf ("GA");
21797 name += 2;
21798 left -= 2;
21799 }
21800
9ef920e9
NC
21801 switch ((name_type = * name))
21802 {
21803 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21804 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21805 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21806 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21807 printf ("%c", * name);
88305e1b 21808 left --;
9ef920e9
NC
21809 break;
21810 default:
21811 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21812 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21813 return false;
9ef920e9
NC
21814 }
21815
9ef920e9
NC
21816 ++ name;
21817 text = NULL;
21818
21819 switch ((name_attribute = * name))
21820 {
21821 case GNU_BUILD_ATTRIBUTE_VERSION:
21822 text = _("<version>");
1d15e434 21823 expected_types = string_expected;
9ef920e9
NC
21824 ++ name;
21825 break;
21826 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21827 text = _("<stack prot>");
75d7d298 21828 expected_types = "!+*";
9ef920e9
NC
21829 ++ name;
21830 break;
21831 case GNU_BUILD_ATTRIBUTE_RELRO:
21832 text = _("<relro>");
1d15e434 21833 expected_types = bool_expected;
9ef920e9
NC
21834 ++ name;
21835 break;
21836 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21837 text = _("<stack size>");
1d15e434 21838 expected_types = number_expected;
9ef920e9
NC
21839 ++ name;
21840 break;
21841 case GNU_BUILD_ATTRIBUTE_TOOL:
21842 text = _("<tool>");
1d15e434 21843 expected_types = string_expected;
9ef920e9
NC
21844 ++ name;
21845 break;
21846 case GNU_BUILD_ATTRIBUTE_ABI:
21847 text = _("<ABI>");
21848 expected_types = "$*";
21849 ++ name;
21850 break;
21851 case GNU_BUILD_ATTRIBUTE_PIC:
21852 text = _("<PIC>");
1d15e434 21853 expected_types = number_expected;
9ef920e9
NC
21854 ++ name;
21855 break;
a8be5506
NC
21856 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21857 text = _("<short enum>");
1d15e434 21858 expected_types = bool_expected;
a8be5506
NC
21859 ++ name;
21860 break;
9ef920e9
NC
21861 default:
21862 if (ISPRINT (* name))
21863 {
21864 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21865
21866 if (len > left && ! do_wide)
21867 len = left;
75d7d298 21868 printf ("%.*s:", len, name);
9ef920e9 21869 left -= len;
0dd6ae21 21870 name += len;
9ef920e9
NC
21871 }
21872 else
21873 {
3e6b6445 21874 static char tmpbuf [128];
88305e1b 21875
3e6b6445
NC
21876 error (_("unrecognised byte in name field: %d\n"), * name);
21877 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21878 text = tmpbuf;
21879 name ++;
9ef920e9
NC
21880 }
21881 expected_types = "*$!+";
21882 break;
21883 }
21884
21885 if (text)
88305e1b 21886 left -= printf ("%s", text);
9ef920e9
NC
21887
21888 if (strchr (expected_types, name_type) == NULL)
75d7d298 21889 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 21890
26c527e6 21891 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 21892 {
26c527e6
AM
21893 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
21894 pnote->namesz,
21895 name - pnote->namedata);
015dc7e1 21896 return false;
9ef920e9
NC
21897 }
21898
21899 if (left < 1 && ! do_wide)
015dc7e1 21900 return true;
9ef920e9
NC
21901
21902 switch (name_type)
21903 {
21904 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21905 {
26c527e6
AM
21906 unsigned int bytes;
21907 uint64_t val = 0;
21908 unsigned int shift = 0;
21909 char *decoded = NULL;
ddef72cd 21910
b06b2c92
NC
21911 bytes = pnote->namesz - (name - pnote->namedata);
21912 if (bytes > 0)
21913 /* The -1 is because the name field is always 0 terminated, and we
21914 want to be able to ensure that the shift in the while loop below
21915 will not overflow. */
21916 -- bytes;
21917
ddef72cd
NC
21918 if (bytes > sizeof (val))
21919 {
3e6b6445
NC
21920 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21921 bytes);
21922 bytes = sizeof (val);
ddef72cd 21923 }
3e6b6445
NC
21924 /* We do not bother to warn if bytes == 0 as this can
21925 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21926
21927 while (bytes --)
21928 {
26c527e6 21929 uint64_t byte = *name++ & 0xff;
79a964dc
NC
21930
21931 val |= byte << shift;
9ef920e9
NC
21932 shift += 8;
21933 }
21934
75d7d298 21935 switch (name_attribute)
9ef920e9 21936 {
75d7d298 21937 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21938 switch (val)
21939 {
75d7d298
NC
21940 case 0: decoded = "static"; break;
21941 case 1: decoded = "pic"; break;
21942 case 2: decoded = "PIC"; break;
21943 case 3: decoded = "pie"; break;
21944 case 4: decoded = "PIE"; break;
21945 default: break;
9ef920e9 21946 }
75d7d298
NC
21947 break;
21948 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21949 switch (val)
9ef920e9 21950 {
75d7d298
NC
21951 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21952 case 0: decoded = "off"; break;
21953 case 1: decoded = "on"; break;
21954 case 2: decoded = "all"; break;
21955 case 3: decoded = "strong"; break;
21956 case 4: decoded = "explicit"; break;
21957 default: break;
9ef920e9 21958 }
75d7d298
NC
21959 break;
21960 default:
21961 break;
9ef920e9
NC
21962 }
21963
75d7d298 21964 if (decoded != NULL)
3e6b6445
NC
21965 {
21966 print_symbol (-left, decoded);
21967 left = 0;
21968 }
21969 else if (val == 0)
21970 {
21971 printf ("0x0");
21972 left -= 3;
21973 }
9ef920e9 21974 else
75d7d298
NC
21975 {
21976 if (do_wide)
26c527e6 21977 left -= printf ("0x%" PRIx64, val);
75d7d298 21978 else
26c527e6 21979 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 21980 }
9ef920e9
NC
21981 }
21982 break;
21983 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21984 left -= print_symbol (- left, name);
21985 break;
21986 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21987 left -= print_symbol (- left, "true");
21988 break;
21989 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21990 left -= print_symbol (- left, "false");
21991 break;
21992 }
21993
21994 if (do_wide && left > 0)
21995 printf ("%-*s", left, " ");
9abca702 21996
015dc7e1 21997 return true;
9ef920e9
NC
21998}
21999
2952f10c
SM
22000/* Print the contents of PNOTE as hex. */
22001
22002static void
22003print_note_contents_hex (Elf_Internal_Note *pnote)
22004{
22005 if (pnote->descsz)
22006 {
26c527e6 22007 size_t i;
2952f10c
SM
22008
22009 printf (_(" description data: "));
22010 for (i = 0; i < pnote->descsz; i++)
22011 printf ("%02x ", pnote->descdata[i] & 0xff);
22012 if (!do_wide)
22013 printf ("\n");
22014 }
22015
22016 if (do_wide)
22017 printf ("\n");
22018}
22019
22020#if defined HAVE_MSGPACK
22021
22022static void
22023print_indents (int n)
22024{
22025 printf (" ");
22026
22027 for (int i = 0; i < n; i++)
22028 printf (" ");
22029}
22030
22031/* Print OBJ in human-readable form. */
22032
22033static void
22034dump_msgpack_obj (const msgpack_object *obj, int indent)
22035{
22036 switch (obj->type)
22037 {
22038 case MSGPACK_OBJECT_NIL:
22039 printf ("(nil)");
22040 break;
22041
22042 case MSGPACK_OBJECT_BOOLEAN:
22043 printf ("%s", obj->via.boolean ? "true" : "false");
22044 break;
22045
22046 case MSGPACK_OBJECT_POSITIVE_INTEGER:
22047 printf ("%" PRIu64, obj->via.u64);
22048 break;
22049
22050 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
22051 printf ("%" PRIi64, obj->via.i64);
22052 break;
22053
22054 case MSGPACK_OBJECT_FLOAT32:
22055 case MSGPACK_OBJECT_FLOAT64:
22056 printf ("%f", obj->via.f64);
22057 break;
22058
22059 case MSGPACK_OBJECT_STR:
22060 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
22061 break;
22062
22063 case MSGPACK_OBJECT_ARRAY:
22064 {
22065 const msgpack_object_array *array = &obj->via.array;
22066
22067 printf ("[\n");
22068 ++indent;
22069
22070 for (uint32_t i = 0; i < array->size; ++i)
22071 {
22072 const msgpack_object *item = &array->ptr[i];
22073
22074 print_indents (indent);
22075 dump_msgpack_obj (item, indent);
22076 printf (",\n");
22077 }
22078
22079 --indent;
22080 print_indents (indent);
22081 printf ("]");
22082 break;
22083 }
22084 break;
22085
22086 case MSGPACK_OBJECT_MAP:
22087 {
22088 const msgpack_object_map *map = &obj->via.map;
22089
22090 printf ("{\n");
22091 ++indent;
22092
22093 for (uint32_t i = 0; i < map->size; ++i)
22094 {
22095 const msgpack_object_kv *kv = &map->ptr[i];
22096 const msgpack_object *key = &kv->key;
22097 const msgpack_object *val = &kv->val;
22098
22099 print_indents (indent);
22100 dump_msgpack_obj (key, indent);
22101 printf (": ");
22102 dump_msgpack_obj (val, indent);
22103
22104 printf (",\n");
22105 }
22106
22107 --indent;
22108 print_indents (indent);
22109 printf ("}");
22110
22111 break;
22112 }
22113
22114 case MSGPACK_OBJECT_BIN:
22115 printf ("(bin)");
22116 break;
22117
22118 case MSGPACK_OBJECT_EXT:
22119 printf ("(ext)");
22120 break;
22121 }
22122}
22123
22124static void
22125dump_msgpack (const msgpack_unpacked *msg)
22126{
22127 print_indents (0);
22128 dump_msgpack_obj (&msg->data, 0);
22129 printf ("\n");
22130}
22131
22132#endif /* defined HAVE_MSGPACK */
22133
22134static bool
22135print_amdgpu_note (Elf_Internal_Note *pnote)
22136{
22137#if defined HAVE_MSGPACK
22138 /* If msgpack is available, decode and dump the note's content. */
22139 bool ret;
22140 msgpack_unpacked msg;
22141 msgpack_unpack_return msgpack_ret;
22142
22143 assert (pnote->type == NT_AMDGPU_METADATA);
22144
22145 msgpack_unpacked_init (&msg);
22146 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
22147 NULL);
22148
22149 switch (msgpack_ret)
22150 {
22151 case MSGPACK_UNPACK_SUCCESS:
22152 dump_msgpack (&msg);
22153 ret = true;
22154 break;
22155
22156 default:
22157 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
22158 ret = false;
22159 break;
22160 }
22161
22162 msgpack_unpacked_destroy (&msg);
22163 return ret;
22164#else
22165 /* msgpack is not available, dump contents as hex. */
22166 print_note_contents_hex (pnote);
22167 return true;
22168#endif
22169}
22170
e263a66b
CC
22171static bool
22172print_qnx_note (Elf_Internal_Note *pnote)
22173{
22174 switch (pnote->type)
22175 {
22176 case QNT_STACK:
22177 if (pnote->descsz != 12)
22178 goto desc_size_fail;
22179
22180 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
22181 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
22182 printf (_(" Stack allocated: %" PRIx32 "\n"),
22183 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22184 printf (_(" Executable: %s\n"),
22185 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
22186 break;
22187
22188 default:
22189 print_note_contents_hex(pnote);
22190 }
22191 return true;
22192
22193desc_size_fail:
22194 printf (_(" <corrupt - data size is too small>\n"));
22195 error (_("corrupt QNX note: data size is too small\n"));
22196 return false;
22197}
22198
22199
6d118b09
NC
22200/* Note that by the ELF standard, the name field is already null byte
22201 terminated, and namesz includes the terminating null byte.
22202 I.E. the value of namesz for the name "FSF" is 4.
22203
e3c8793a 22204 If the value of namesz is zero, there is no name present. */
9ef920e9 22205
015dc7e1 22206static bool
9ef920e9 22207process_note (Elf_Internal_Note * pnote,
dda8d76d 22208 Filedata * filedata)
779fe533 22209{
2cf0635d
NC
22210 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
22211 const char * nt;
9437c45b
JT
22212
22213 if (pnote->namesz == 0)
1ec5cd37
NC
22214 /* If there is no note name, then use the default set of
22215 note type strings. */
dda8d76d 22216 nt = get_note_type (filedata, pnote->type);
1ec5cd37 22217
24d127aa 22218 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
22219 /* GNU-specific object file notes. */
22220 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 22221
28cdbb18
SM
22222 else if (startswith (pnote->namedata, "AMDGPU"))
22223 /* AMDGPU-specific object file notes. */
22224 nt = get_amdgpu_elf_note_type (pnote->type);
22225
24d127aa 22226 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 22227 /* FreeBSD-specific core file notes. */
dda8d76d 22228 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 22229
24d127aa 22230 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 22231 /* NetBSD-specific core file notes. */
dda8d76d 22232 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 22233
24d127aa 22234 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
22235 /* NetBSD-specific core file notes. */
22236 return process_netbsd_elf_note (pnote);
22237
24d127aa 22238 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
22239 /* NetBSD-specific core file notes. */
22240 return process_netbsd_elf_note (pnote);
22241
98ca73af
FC
22242 else if (startswith (pnote->namedata, "OpenBSD"))
22243 /* OpenBSD-specific core file notes. */
22244 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
22245
e263a66b
CC
22246 else if (startswith (pnote->namedata, "QNX"))
22247 /* QNX-specific core file notes. */
22248 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
22249
e9b095a5 22250 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
22251 {
22252 /* SPU-specific core file notes. */
22253 nt = pnote->namedata + 4;
22254 name = "SPU";
22255 }
22256
24d127aa 22257 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
22258 /* VMS/ia64-specific file notes. */
22259 nt = get_ia64_vms_note_type (pnote->type);
22260
24d127aa 22261 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
22262 nt = get_stapsdt_note_type (pnote->type);
22263
9437c45b 22264 else
1ec5cd37
NC
22265 /* Don't recognize this note name; just use the default set of
22266 note type strings. */
dda8d76d 22267 nt = get_note_type (filedata, pnote->type);
9437c45b 22268
1449284b 22269 printf (" ");
9ef920e9 22270
24d127aa 22271 if (((startswith (pnote->namedata, "GA")
483767a3
AM
22272 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22273 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22274 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22275 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
22276 print_gnu_build_attribute_name (pnote);
22277 else
22278 print_symbol (-20, name);
22279
22280 if (do_wide)
22281 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
22282 else
22283 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 22284
24d127aa 22285 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 22286 return print_ia64_vms_note (pnote);
24d127aa 22287 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 22288 return print_gnu_note (filedata, pnote);
24d127aa 22289 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 22290 return print_stapsdt_note (pnote);
24d127aa 22291 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 22292 return print_core_note (pnote);
e5382207
LB
22293 else if (startswith (pnote->namedata, "FDO"))
22294 return print_fdo_note (pnote);
24d127aa 22295 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
22296 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22297 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22298 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22299 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 22300 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
22301 else if (startswith (pnote->namedata, "AMDGPU")
22302 && pnote->type == NT_AMDGPU_METADATA)
22303 return print_amdgpu_note (pnote);
e263a66b
CC
22304 else if (startswith (pnote->namedata, "QNX"))
22305 return print_qnx_note (pnote);
779fe533 22306
2952f10c 22307 print_note_contents_hex (pnote);
015dc7e1 22308 return true;
1449284b 22309}
6d118b09 22310
015dc7e1 22311static bool
dda8d76d
NC
22312process_notes_at (Filedata * filedata,
22313 Elf_Internal_Shdr * section,
625d49fc
AM
22314 uint64_t offset,
22315 uint64_t length,
22316 uint64_t align)
779fe533 22317{
015dc7e1
AM
22318 Elf_External_Note *pnotes;
22319 Elf_External_Note *external;
22320 char *end;
22321 bool res = true;
103f02d3 22322
779fe533 22323 if (length <= 0)
015dc7e1 22324 return false;
103f02d3 22325
1449284b
NC
22326 if (section)
22327 {
dda8d76d 22328 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 22329 if (pnotes)
32ec8896 22330 {
dda8d76d 22331 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
22332 {
22333 free (pnotes);
015dc7e1 22334 return false;
f761cb13 22335 }
32ec8896 22336 }
1449284b
NC
22337 }
22338 else
82ed9683 22339 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 22340 _("notes"));
4dff97b2 22341
dd24e3da 22342 if (pnotes == NULL)
015dc7e1 22343 return false;
779fe533 22344
103f02d3 22345 external = pnotes;
103f02d3 22346
ca0e11aa
NC
22347 if (filedata->is_separate)
22348 printf (_("In linked file '%s': "), filedata->file_name);
22349 else
22350 printf ("\n");
1449284b 22351 if (section)
ca0e11aa 22352 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 22353 else
26c527e6
AM
22354 printf (_("Displaying notes found at file offset 0x%08" PRIx64
22355 " with length 0x%08" PRIx64 ":\n"),
22356 offset, length);
1449284b 22357
82ed9683
L
22358 /* NB: Some note sections may have alignment value of 0 or 1. gABI
22359 specifies that notes should be aligned to 4 bytes in 32-bit
22360 objects and to 8 bytes in 64-bit objects. As a Linux extension,
22361 we also support 4 byte alignment in 64-bit objects. If section
22362 alignment is less than 4, we treate alignment as 4 bytes. */
22363 if (align < 4)
22364 align = 4;
22365 else if (align != 4 && align != 8)
22366 {
26c527e6
AM
22367 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
22368 align);
a788aedd 22369 free (pnotes);
015dc7e1 22370 return false;
82ed9683
L
22371 }
22372
dbe15e4e 22373 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 22374
c8071705
NC
22375 end = (char *) pnotes + length;
22376 while ((char *) external < end)
779fe533 22377 {
b34976b6 22378 Elf_Internal_Note inote;
15b42fb0 22379 size_t min_notesz;
4dff97b2 22380 char * next;
2cf0635d 22381 char * temp = NULL;
c8071705 22382 size_t data_remaining = end - (char *) external;
6d118b09 22383
dda8d76d 22384 if (!is_ia64_vms (filedata))
15b42fb0 22385 {
9dd3a467
NC
22386 /* PR binutils/15191
22387 Make sure that there is enough data to read. */
15b42fb0
AM
22388 min_notesz = offsetof (Elf_External_Note, name);
22389 if (data_remaining < min_notesz)
9dd3a467 22390 {
26c527e6 22391 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22392 "not enough for a full note\n",
26c527e6 22393 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22394 "not enough for a full note\n",
22395 data_remaining),
26c527e6 22396 data_remaining);
9dd3a467
NC
22397 break;
22398 }
5396a86e
AM
22399 data_remaining -= min_notesz;
22400
15b42fb0
AM
22401 inote.type = BYTE_GET (external->type);
22402 inote.namesz = BYTE_GET (external->namesz);
22403 inote.namedata = external->name;
22404 inote.descsz = BYTE_GET (external->descsz);
276da9b3 22405 inote.descdata = ((char *) external
4dff97b2 22406 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 22407 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 22408 next = ((char *) external
4dff97b2 22409 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 22410 }
00e98fc7 22411 else
15b42fb0
AM
22412 {
22413 Elf64_External_VMS_Note *vms_external;
00e98fc7 22414
9dd3a467
NC
22415 /* PR binutils/15191
22416 Make sure that there is enough data to read. */
15b42fb0
AM
22417 min_notesz = offsetof (Elf64_External_VMS_Note, name);
22418 if (data_remaining < min_notesz)
9dd3a467 22419 {
26c527e6 22420 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22421 "not enough for a full note\n",
26c527e6 22422 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22423 "not enough for a full note\n",
22424 data_remaining),
26c527e6 22425 data_remaining);
9dd3a467
NC
22426 break;
22427 }
5396a86e 22428 data_remaining -= min_notesz;
3e55a963 22429
15b42fb0
AM
22430 vms_external = (Elf64_External_VMS_Note *) external;
22431 inote.type = BYTE_GET (vms_external->type);
22432 inote.namesz = BYTE_GET (vms_external->namesz);
22433 inote.namedata = vms_external->name;
22434 inote.descsz = BYTE_GET (vms_external->descsz);
22435 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
22436 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22437 next = inote.descdata + align_power (inote.descsz, 3);
22438 }
22439
5396a86e
AM
22440 /* PR 17531: file: 3443835e. */
22441 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
22442 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
22443 || (size_t) (inote.descdata - inote.namedata) > data_remaining
22444 || (size_t) (next - inote.descdata) < inote.descsz
22445 || ((size_t) (next - inote.descdata)
22446 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 22447 {
26c527e6
AM
22448 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
22449 (char *) external - (char *) pnotes);
22450 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 22451 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
22452 break;
22453 }
22454
15b42fb0 22455 external = (Elf_External_Note *) next;
dd24e3da 22456
6d118b09
NC
22457 /* Verify that name is null terminated. It appears that at least
22458 one version of Linux (RedHat 6.0) generates corefiles that don't
22459 comply with the ELF spec by failing to include the null byte in
22460 namesz. */
18344509 22461 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 22462 {
5396a86e 22463 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 22464 {
5396a86e
AM
22465 temp = (char *) malloc (inote.namesz + 1);
22466 if (temp == NULL)
22467 {
22468 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 22469 res = false;
5396a86e
AM
22470 break;
22471 }
76da6bbe 22472
5396a86e
AM
22473 memcpy (temp, inote.namedata, inote.namesz);
22474 inote.namedata = temp;
22475 }
22476 inote.namedata[inote.namesz] = 0;
6d118b09
NC
22477 }
22478
dda8d76d 22479 if (! process_note (& inote, filedata))
015dc7e1 22480 res = false;
103f02d3 22481
9db70fc3
AM
22482 free (temp);
22483 temp = NULL;
779fe533
NC
22484 }
22485
22486 free (pnotes);
103f02d3 22487
779fe533
NC
22488 return res;
22489}
22490
015dc7e1 22491static bool
dda8d76d 22492process_corefile_note_segments (Filedata * filedata)
779fe533 22493{
015dc7e1 22494 Elf_Internal_Phdr *segment;
b34976b6 22495 unsigned int i;
015dc7e1 22496 bool res = true;
103f02d3 22497
dda8d76d 22498 if (! get_program_headers (filedata))
015dc7e1 22499 return true;
103f02d3 22500
dda8d76d
NC
22501 for (i = 0, segment = filedata->program_headers;
22502 i < filedata->file_header.e_phnum;
b34976b6 22503 i++, segment++)
779fe533
NC
22504 {
22505 if (segment->p_type == PT_NOTE)
625d49fc
AM
22506 if (! process_notes_at (filedata, NULL, segment->p_offset,
22507 segment->p_filesz, segment->p_align))
015dc7e1 22508 res = false;
779fe533 22509 }
103f02d3 22510
779fe533
NC
22511 return res;
22512}
22513
015dc7e1 22514static bool
625d49fc 22515process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
22516{
22517 Elf_External_Note * pnotes;
22518 Elf_External_Note * external;
c8071705 22519 char * end;
015dc7e1 22520 bool res = true;
685080f2
NC
22521
22522 if (length <= 0)
015dc7e1 22523 return false;
685080f2 22524
dda8d76d 22525 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
22526 _("v850 notes"));
22527 if (pnotes == NULL)
015dc7e1 22528 return false;
685080f2
NC
22529
22530 external = pnotes;
c8071705 22531 end = (char*) pnotes + length;
685080f2 22532
26c527e6
AM
22533 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22534 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22535 offset, length);
685080f2 22536
c8071705 22537 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
22538 {
22539 Elf_External_Note * next;
22540 Elf_Internal_Note inote;
22541
22542 inote.type = BYTE_GET (external->type);
22543 inote.namesz = BYTE_GET (external->namesz);
22544 inote.namedata = external->name;
22545 inote.descsz = BYTE_GET (external->descsz);
22546 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22547 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22548
c8071705
NC
22549 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22550 {
22551 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22552 inote.descdata = inote.namedata;
22553 inote.namesz = 0;
22554 }
22555
685080f2
NC
22556 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22557
c8071705 22558 if ( ((char *) next > end)
685080f2
NC
22559 || ((char *) next < (char *) pnotes))
22560 {
26c527e6
AM
22561 warn (_("corrupt descsz found in note at offset %#tx\n"),
22562 (char *) external - (char *) pnotes);
22563 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22564 inote.type, inote.namesz, inote.descsz);
22565 break;
22566 }
22567
22568 external = next;
22569
22570 /* Prevent out-of-bounds indexing. */
c8071705 22571 if ( inote.namedata + inote.namesz > end
685080f2
NC
22572 || inote.namedata + inote.namesz < inote.namedata)
22573 {
26c527e6
AM
22574 warn (_("corrupt namesz found in note at offset %#zx\n"),
22575 (char *) external - (char *) pnotes);
22576 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22577 inote.type, inote.namesz, inote.descsz);
22578 break;
22579 }
22580
22581 printf (" %s: ", get_v850_elf_note_type (inote.type));
22582
22583 if (! print_v850_note (& inote))
22584 {
015dc7e1 22585 res = false;
26c527e6 22586 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
22587 inote.namesz, inote.descsz);
22588 }
22589 }
22590
22591 free (pnotes);
22592
22593 return res;
22594}
22595
015dc7e1 22596static bool
dda8d76d 22597process_note_sections (Filedata * filedata)
1ec5cd37 22598{
015dc7e1 22599 Elf_Internal_Shdr *section;
26c527e6 22600 size_t i;
32ec8896 22601 unsigned int n = 0;
015dc7e1 22602 bool res = true;
1ec5cd37 22603
dda8d76d
NC
22604 for (i = 0, section = filedata->section_headers;
22605 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 22606 i++, section++)
685080f2
NC
22607 {
22608 if (section->sh_type == SHT_NOTE)
22609 {
625d49fc
AM
22610 if (! process_notes_at (filedata, section, section->sh_offset,
22611 section->sh_size, section->sh_addralign))
015dc7e1 22612 res = false;
685080f2
NC
22613 n++;
22614 }
22615
dda8d76d
NC
22616 if (( filedata->file_header.e_machine == EM_V800
22617 || filedata->file_header.e_machine == EM_V850
22618 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
22619 && section->sh_type == SHT_RENESAS_INFO)
22620 {
625d49fc
AM
22621 if (! process_v850_notes (filedata, section->sh_offset,
22622 section->sh_size))
015dc7e1 22623 res = false;
685080f2
NC
22624 n++;
22625 }
22626 }
df565f32
NC
22627
22628 if (n == 0)
22629 /* Try processing NOTE segments instead. */
dda8d76d 22630 return process_corefile_note_segments (filedata);
1ec5cd37
NC
22631
22632 return res;
22633}
22634
015dc7e1 22635static bool
dda8d76d 22636process_notes (Filedata * filedata)
779fe533
NC
22637{
22638 /* If we have not been asked to display the notes then do nothing. */
22639 if (! do_notes)
015dc7e1 22640 return true;
103f02d3 22641
dda8d76d
NC
22642 if (filedata->file_header.e_type != ET_CORE)
22643 return process_note_sections (filedata);
103f02d3 22644
779fe533 22645 /* No program headers means no NOTE segment. */
dda8d76d
NC
22646 if (filedata->file_header.e_phnum > 0)
22647 return process_corefile_note_segments (filedata);
779fe533 22648
ca0e11aa
NC
22649 if (filedata->is_separate)
22650 printf (_("No notes found in linked file '%s'.\n"),
22651 filedata->file_name);
22652 else
22653 printf (_("No notes found file.\n"));
22654
015dc7e1 22655 return true;
779fe533
NC
22656}
22657
60abdbed
NC
22658static unsigned char *
22659display_public_gnu_attributes (unsigned char * start,
22660 const unsigned char * const end)
22661{
22662 printf (_(" Unknown GNU attribute: %s\n"), start);
22663
22664 start += strnlen ((char *) start, end - start);
22665 display_raw_attribute (start, end);
22666
22667 return (unsigned char *) end;
22668}
22669
22670static unsigned char *
22671display_generic_attribute (unsigned char * start,
22672 unsigned int tag,
22673 const unsigned char * const end)
22674{
22675 if (tag == 0)
22676 return (unsigned char *) end;
22677
22678 return display_tag_value (tag, start, end);
22679}
22680
015dc7e1 22681static bool
dda8d76d 22682process_arch_specific (Filedata * filedata)
252b5132 22683{
a952a375 22684 if (! do_arch)
015dc7e1 22685 return true;
a952a375 22686
dda8d76d 22687 switch (filedata->file_header.e_machine)
252b5132 22688 {
53a346d8
CZ
22689 case EM_ARC:
22690 case EM_ARC_COMPACT:
22691 case EM_ARC_COMPACT2:
b5c37946
SJ
22692 case EM_ARC_COMPACT3:
22693 case EM_ARC_COMPACT3_64:
dda8d76d 22694 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
22695 display_arc_attribute,
22696 display_generic_attribute);
11c1ff18 22697 case EM_ARM:
dda8d76d 22698 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
22699 display_arm_attribute,
22700 display_generic_attribute);
22701
252b5132 22702 case EM_MIPS:
4fe85591 22703 case EM_MIPS_RS3_LE:
dda8d76d 22704 return process_mips_specific (filedata);
60abdbed
NC
22705
22706 case EM_MSP430:
dda8d76d 22707 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 22708 display_msp430_attribute,
c0ea7c52 22709 display_msp430_gnu_attribute);
60abdbed 22710
2dc8dd17
JW
22711 case EM_RISCV:
22712 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22713 display_riscv_attribute,
22714 display_generic_attribute);
22715
35c08157 22716 case EM_NDS32:
dda8d76d 22717 return process_nds32_specific (filedata);
60abdbed 22718
85f7484a
PB
22719 case EM_68K:
22720 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22721 display_m68k_gnu_attribute);
22722
34c8bcba 22723 case EM_PPC:
b82317dd 22724 case EM_PPC64:
dda8d76d 22725 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22726 display_power_gnu_attribute);
22727
643f7afb
AK
22728 case EM_S390:
22729 case EM_S390_OLD:
dda8d76d 22730 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22731 display_s390_gnu_attribute);
22732
9e8c70f9
DM
22733 case EM_SPARC:
22734 case EM_SPARC32PLUS:
22735 case EM_SPARCV9:
dda8d76d 22736 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22737 display_sparc_gnu_attribute);
22738
59e6276b 22739 case EM_TI_C6000:
dda8d76d 22740 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22741 display_tic6x_attribute,
22742 display_generic_attribute);
22743
0861f561
CQ
22744 case EM_CSKY:
22745 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22746 display_csky_attribute, NULL);
22747
252b5132 22748 default:
dda8d76d 22749 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22750 display_public_gnu_attributes,
22751 display_generic_attribute);
252b5132 22752 }
252b5132
RH
22753}
22754
015dc7e1 22755static bool
dda8d76d 22756get_file_header (Filedata * filedata)
252b5132 22757{
9ea033b2 22758 /* Read in the identity array. */
dda8d76d 22759 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22760 return false;
252b5132 22761
9ea033b2 22762 /* Determine how to read the rest of the header. */
dda8d76d 22763 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22764 {
1a0670f3
AM
22765 default:
22766 case ELFDATANONE:
adab8cdc
AO
22767 case ELFDATA2LSB:
22768 byte_get = byte_get_little_endian;
22769 byte_put = byte_put_little_endian;
22770 break;
22771 case ELFDATA2MSB:
22772 byte_get = byte_get_big_endian;
22773 byte_put = byte_put_big_endian;
22774 break;
9ea033b2
NC
22775 }
22776
22777 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22778 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22779
22780 /* Read in the rest of the header. */
22781 if (is_32bit_elf)
22782 {
22783 Elf32_External_Ehdr ehdr32;
252b5132 22784
dda8d76d 22785 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22786 return false;
103f02d3 22787
dda8d76d
NC
22788 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22789 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22790 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22791 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22792 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22793 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22794 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22795 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22796 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22797 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22798 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22799 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22800 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22801 }
252b5132 22802 else
9ea033b2
NC
22803 {
22804 Elf64_External_Ehdr ehdr64;
a952a375 22805
dda8d76d 22806 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22807 return false;
103f02d3 22808
dda8d76d
NC
22809 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22810 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22811 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22812 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22813 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22814 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22815 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22816 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22817 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22818 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22819 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22820 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22821 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22822 }
252b5132 22823
015dc7e1 22824 return true;
252b5132
RH
22825}
22826
13acb58d
AM
22827static void
22828free_filedata (Filedata *filedata)
22829{
22830 free (filedata->program_interpreter);
13acb58d 22831 free (filedata->program_headers);
13acb58d 22832 free (filedata->section_headers);
13acb58d 22833 free (filedata->string_table);
13acb58d 22834 free (filedata->dump.dump_sects);
13acb58d 22835 free (filedata->dynamic_strings);
13acb58d 22836 free (filedata->dynamic_symbols);
13acb58d 22837 free (filedata->dynamic_syminfo);
13acb58d 22838 free (filedata->dynamic_section);
13acb58d
AM
22839
22840 while (filedata->symtab_shndx_list != NULL)
22841 {
22842 elf_section_list *next = filedata->symtab_shndx_list->next;
22843 free (filedata->symtab_shndx_list);
22844 filedata->symtab_shndx_list = next;
22845 }
22846
22847 free (filedata->section_headers_groups);
13acb58d
AM
22848
22849 if (filedata->section_groups)
22850 {
22851 size_t i;
22852 struct group_list * g;
22853 struct group_list * next;
22854
22855 for (i = 0; i < filedata->group_count; i++)
22856 {
22857 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22858 {
22859 next = g->next;
22860 free (g);
22861 }
22862 }
22863
22864 free (filedata->section_groups);
13acb58d 22865 }
066f8fbe
AM
22866 memset (&filedata->section_headers, 0,
22867 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22868}
22869
dda8d76d
NC
22870static void
22871close_file (Filedata * filedata)
22872{
22873 if (filedata)
22874 {
22875 if (filedata->handle)
22876 fclose (filedata->handle);
22877 free (filedata);
22878 }
22879}
22880
22881void
22882close_debug_file (void * data)
22883{
13acb58d 22884 free_filedata ((Filedata *) data);
dda8d76d
NC
22885 close_file ((Filedata *) data);
22886}
22887
22888static Filedata *
015dc7e1 22889open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22890{
22891 struct stat statbuf;
22892 Filedata * filedata = NULL;
22893
22894 if (stat (pathname, & statbuf) < 0
22895 || ! S_ISREG (statbuf.st_mode))
22896 goto fail;
22897
22898 filedata = calloc (1, sizeof * filedata);
22899 if (filedata == NULL)
22900 goto fail;
22901
22902 filedata->handle = fopen (pathname, "rb");
22903 if (filedata->handle == NULL)
22904 goto fail;
22905
be7d229a 22906 filedata->file_size = statbuf.st_size;
dda8d76d 22907 filedata->file_name = pathname;
ca0e11aa 22908 filedata->is_separate = is_separate;
dda8d76d
NC
22909
22910 if (! get_file_header (filedata))
22911 goto fail;
22912
4de91c10
AM
22913 if (!get_section_headers (filedata, false))
22914 goto fail;
dda8d76d
NC
22915
22916 return filedata;
22917
22918 fail:
22919 if (filedata)
22920 {
22921 if (filedata->handle)
22922 fclose (filedata->handle);
22923 free (filedata);
22924 }
22925 return NULL;
22926}
22927
22928void *
22929open_debug_file (const char * pathname)
22930{
015dc7e1 22931 return open_file (pathname, true);
dda8d76d
NC
22932}
22933
835f2fae
NC
22934static void
22935initialise_dump_sects (Filedata * filedata)
22936{
22937 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22938 Note we do this even if cmdline_dump_sects is empty because we
22939 must make sure that the dump_sets array is zeroed out before each
22940 object file is processed. */
22941 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22942 memset (filedata->dump.dump_sects, 0,
22943 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22944
22945 if (cmdline.num_dump_sects > 0)
22946 {
22947 if (filedata->dump.num_dump_sects == 0)
22948 /* A sneaky way of allocating the dump_sects array. */
22949 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22950
22951 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22952 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22953 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22954 }
22955}
22956
94585d6d
NC
22957static bool
22958might_need_separate_debug_info (Filedata * filedata)
22959{
22960 /* Debuginfo files do not need further separate file loading. */
22961 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22962 return false;
22963
22964 /* Since do_follow_links might be enabled by default, only treat it as an
22965 indication that separate files should be loaded if setting it was a
22966 deliberate user action. */
22967 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22968 return true;
22969
22970 if (process_links || do_syms || do_unwind
22971 || dump_any_debugging || do_dump || do_debugging)
22972 return true;
22973
22974 return false;
22975}
22976
fb52b2f4
NC
22977/* Process one ELF object file according to the command line options.
22978 This file may actually be stored in an archive. The file is
32ec8896
NC
22979 positioned at the start of the ELF object. Returns TRUE if no
22980 problems were encountered, FALSE otherwise. */
fb52b2f4 22981
015dc7e1 22982static bool
dda8d76d 22983process_object (Filedata * filedata)
252b5132 22984{
015dc7e1 22985 bool have_separate_files;
252b5132 22986 unsigned int i;
015dc7e1 22987 bool res;
252b5132 22988
dda8d76d 22989 if (! get_file_header (filedata))
252b5132 22990 {
dda8d76d 22991 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22992 return false;
252b5132
RH
22993 }
22994
22995 /* Initialise per file variables. */
978c4450
AM
22996 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22997 filedata->version_info[i] = 0;
252b5132 22998
978c4450
AM
22999 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
23000 filedata->dynamic_info[i] = 0;
23001 filedata->dynamic_info_DT_GNU_HASH = 0;
23002 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
23003
23004 /* Process the file. */
23005 if (show_name)
dda8d76d 23006 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 23007
835f2fae 23008 initialise_dump_sects (filedata);
d70c5fc7 23009
4de91c10
AM
23010 /* There may be some extensions in the first section header. Don't
23011 bomb if we can't read it. */
23012 get_section_headers (filedata, true);
23013
dda8d76d 23014 if (! process_file_header (filedata))
4de91c10
AM
23015 {
23016 res = false;
23017 goto out;
23018 }
252b5132 23019
e331b18d
AM
23020 /* Throw away the single section header read above, so that we
23021 re-read the entire set. */
23022 free (filedata->section_headers);
23023 filedata->section_headers = NULL;
23024
dda8d76d 23025 if (! process_section_headers (filedata))
2f62977e 23026 {
32ec8896 23027 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 23028 do_unwind = do_version = do_dump = do_arch = false;
252b5132 23029
2f62977e 23030 if (! do_using_dynamic)
015dc7e1 23031 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 23032 }
252b5132 23033
dda8d76d 23034 if (! process_section_groups (filedata))
32ec8896 23035 /* Without loaded section groups we cannot process unwind. */
015dc7e1 23036 do_unwind = false;
d1f5c6e3 23037
93df3340
AM
23038 process_program_headers (filedata);
23039
23040 res = process_dynamic_section (filedata);
252b5132 23041
dda8d76d 23042 if (! process_relocs (filedata))
015dc7e1 23043 res = false;
252b5132 23044
dda8d76d 23045 if (! process_unwind (filedata))
015dc7e1 23046 res = false;
4d6ed7c8 23047
dda8d76d 23048 if (! process_symbol_table (filedata))
015dc7e1 23049 res = false;
252b5132 23050
0f03783c 23051 if (! process_lto_symbol_tables (filedata))
015dc7e1 23052 res = false;
b9e920ec 23053
dda8d76d 23054 if (! process_syminfo (filedata))
015dc7e1 23055 res = false;
252b5132 23056
dda8d76d 23057 if (! process_version_sections (filedata))
015dc7e1 23058 res = false;
252b5132 23059
94585d6d 23060 if (might_need_separate_debug_info (filedata))
24841daa 23061 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 23062 else
015dc7e1 23063 have_separate_files = false;
dda8d76d
NC
23064
23065 if (! process_section_contents (filedata))
015dc7e1 23066 res = false;
f5842774 23067
24841daa 23068 if (have_separate_files)
dda8d76d 23069 {
24841daa
NC
23070 separate_info * d;
23071
23072 for (d = first_separate_info; d != NULL; d = d->next)
23073 {
835f2fae
NC
23074 initialise_dump_sects (d->handle);
23075
ca0e11aa 23076 if (process_links && ! process_file_header (d->handle))
015dc7e1 23077 res = false;
ca0e11aa 23078 else if (! process_section_headers (d->handle))
015dc7e1 23079 res = false;
d6bfbc39 23080 else if (! process_section_contents (d->handle))
015dc7e1 23081 res = false;
ca0e11aa
NC
23082 else if (process_links)
23083 {
ca0e11aa 23084 if (! process_section_groups (d->handle))
015dc7e1 23085 res = false;
93df3340 23086 process_program_headers (d->handle);
ca0e11aa 23087 if (! process_dynamic_section (d->handle))
015dc7e1 23088 res = false;
ca0e11aa 23089 if (! process_relocs (d->handle))
015dc7e1 23090 res = false;
ca0e11aa 23091 if (! process_unwind (d->handle))
015dc7e1 23092 res = false;
ca0e11aa 23093 if (! process_symbol_table (d->handle))
015dc7e1 23094 res = false;
ca0e11aa 23095 if (! process_lto_symbol_tables (d->handle))
015dc7e1 23096 res = false;
ca0e11aa 23097 if (! process_syminfo (d->handle))
015dc7e1 23098 res = false;
ca0e11aa 23099 if (! process_version_sections (d->handle))
015dc7e1 23100 res = false;
ca0e11aa 23101 if (! process_notes (d->handle))
015dc7e1 23102 res = false;
ca0e11aa 23103 }
24841daa
NC
23104 }
23105
23106 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
23107 }
23108
23109 if (! process_notes (filedata))
015dc7e1 23110 res = false;
103f02d3 23111
dda8d76d 23112 if (! process_gnu_liblist (filedata))
015dc7e1 23113 res = false;
047b2264 23114
dda8d76d 23115 if (! process_arch_specific (filedata))
015dc7e1 23116 res = false;
252b5132 23117
4de91c10 23118 out:
13acb58d 23119 free_filedata (filedata);
e4b17d5c 23120
19e6b90e 23121 free_debug_memory ();
18bd398b 23122
32ec8896 23123 return res;
252b5132
RH
23124}
23125
2cf0635d 23126/* Process an ELF archive.
32ec8896
NC
23127 On entry the file is positioned just after the ARMAG string.
23128 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 23129
015dc7e1
AM
23130static bool
23131process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
23132{
23133 struct archive_info arch;
23134 struct archive_info nested_arch;
23135 size_t got;
015dc7e1 23136 bool ret = true;
2cf0635d 23137
015dc7e1 23138 show_name = true;
2cf0635d
NC
23139
23140 /* The ARCH structure is used to hold information about this archive. */
23141 arch.file_name = NULL;
23142 arch.file = NULL;
23143 arch.index_array = NULL;
23144 arch.sym_table = NULL;
23145 arch.longnames = NULL;
23146
23147 /* The NESTED_ARCH structure is used as a single-item cache of information
23148 about a nested archive (when members of a thin archive reside within
23149 another regular archive file). */
23150 nested_arch.file_name = NULL;
23151 nested_arch.file = NULL;
23152 nested_arch.index_array = NULL;
23153 nested_arch.sym_table = NULL;
23154 nested_arch.longnames = NULL;
23155
dda8d76d 23156 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
23157 filedata->file_size, is_thin_archive,
23158 do_archive_index) != 0)
2cf0635d 23159 {
015dc7e1 23160 ret = false;
2cf0635d 23161 goto out;
4145f1d5 23162 }
fb52b2f4 23163
4145f1d5
NC
23164 if (do_archive_index)
23165 {
2cf0635d 23166 if (arch.sym_table == NULL)
1cb7d8b1
AM
23167 error (_("%s: unable to dump the index as none was found\n"),
23168 filedata->file_name);
4145f1d5
NC
23169 else
23170 {
26c527e6
AM
23171 uint64_t i, l;
23172 uint64_t current_pos;
4145f1d5 23173
26c527e6
AM
23174 printf (_("Index of archive %s: (%" PRIu64 " entries,"
23175 " %#" PRIx64 " bytes in the symbol table)\n"),
23176 filedata->file_name, arch.index_num,
1cb7d8b1 23177 arch.sym_size);
dda8d76d
NC
23178
23179 current_pos = ftell (filedata->handle);
4145f1d5 23180
2cf0635d 23181 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 23182 {
1cb7d8b1
AM
23183 if (i == 0
23184 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
23185 {
23186 char * member_name
23187 = get_archive_member_name_at (&arch, arch.index_array[i],
23188 &nested_arch);
2cf0635d 23189
1cb7d8b1
AM
23190 if (member_name != NULL)
23191 {
23192 char * qualified_name
23193 = make_qualified_name (&arch, &nested_arch,
23194 member_name);
2cf0635d 23195
1cb7d8b1
AM
23196 if (qualified_name != NULL)
23197 {
23198 printf (_("Contents of binary %s at offset "),
23199 qualified_name);
c2a7d3f5
NC
23200 (void) print_vma (arch.index_array[i], PREFIX_HEX);
23201 putchar ('\n');
1cb7d8b1
AM
23202 free (qualified_name);
23203 }
fd486f32 23204 free (member_name);
4145f1d5
NC
23205 }
23206 }
2cf0635d
NC
23207
23208 if (l >= arch.sym_size)
4145f1d5 23209 {
1cb7d8b1
AM
23210 error (_("%s: end of the symbol table reached "
23211 "before the end of the index\n"),
dda8d76d 23212 filedata->file_name);
015dc7e1 23213 ret = false;
cb8f3167 23214 break;
4145f1d5 23215 }
591f7597 23216 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
23217 printf ("\t%.*s\n",
23218 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 23219 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
23220 }
23221
67ce483b 23222 if (arch.uses_64bit_indices)
c2a7d3f5
NC
23223 l = (l + 7) & ~ 7;
23224 else
23225 l += l & 1;
23226
2cf0635d 23227 if (l < arch.sym_size)
32ec8896 23228 {
26c527e6 23229 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
23230 "but without corresponding entries in "
23231 "the index table\n",
26c527e6 23232 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
23233 "but without corresponding entries in "
23234 "the index table\n",
23235 arch.sym_size - l),
dda8d76d 23236 filedata->file_name, arch.sym_size - l);
015dc7e1 23237 ret = false;
32ec8896 23238 }
4145f1d5 23239
63cf857e 23240 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 23241 {
1cb7d8b1
AM
23242 error (_("%s: failed to seek back to start of object files "
23243 "in the archive\n"),
dda8d76d 23244 filedata->file_name);
015dc7e1 23245 ret = false;
2cf0635d 23246 goto out;
4145f1d5 23247 }
fb52b2f4 23248 }
4145f1d5
NC
23249
23250 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
23251 && !do_segments && !do_header && !do_dump && !do_version
23252 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 23253 && !do_section_groups && !do_dyn_syms)
2cf0635d 23254 {
015dc7e1 23255 ret = true; /* Archive index only. */
2cf0635d
NC
23256 goto out;
23257 }
fb52b2f4
NC
23258 }
23259
fb52b2f4
NC
23260 while (1)
23261 {
2cf0635d
NC
23262 char * name;
23263 size_t namelen;
23264 char * qualified_name;
23265
23266 /* Read the next archive header. */
63cf857e 23267 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
23268 {
23269 error (_("%s: failed to seek to next archive header\n"),
23270 arch.file_name);
015dc7e1 23271 ret = false;
1cb7d8b1
AM
23272 break;
23273 }
dda8d76d 23274 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 23275 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
23276 {
23277 if (got == 0)
2cf0635d 23278 break;
28e817cc
NC
23279 /* PR 24049 - we cannot use filedata->file_name as this will
23280 have already been freed. */
23281 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 23282
015dc7e1 23283 ret = false;
1cb7d8b1
AM
23284 break;
23285 }
2cf0635d 23286 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
23287 {
23288 error (_("%s: did not find a valid archive header\n"),
23289 arch.file_name);
015dc7e1 23290 ret = false;
1cb7d8b1
AM
23291 break;
23292 }
2cf0635d
NC
23293
23294 arch.next_arhdr_offset += sizeof arch.arhdr;
23295
978c4450 23296 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
23297
23298 name = get_archive_member_name (&arch, &nested_arch);
23299 if (name == NULL)
fb52b2f4 23300 {
28e817cc 23301 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 23302 ret = false;
d989285c 23303 break;
fb52b2f4 23304 }
2cf0635d 23305 namelen = strlen (name);
fb52b2f4 23306
2cf0635d
NC
23307 qualified_name = make_qualified_name (&arch, &nested_arch, name);
23308 if (qualified_name == NULL)
fb52b2f4 23309 {
28e817cc 23310 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 23311 free (name);
015dc7e1 23312 ret = false;
d989285c 23313 break;
fb52b2f4
NC
23314 }
23315
2cf0635d 23316 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
23317 {
23318 /* This is a proxy for an external member of a thin archive. */
23319 Filedata * member_filedata;
23320 char * member_file_name = adjust_relative_path
dda8d76d 23321 (filedata->file_name, name, namelen);
32ec8896 23322
fd486f32 23323 free (name);
1cb7d8b1
AM
23324 if (member_file_name == NULL)
23325 {
fd486f32 23326 free (qualified_name);
015dc7e1 23327 ret = false;
1cb7d8b1
AM
23328 break;
23329 }
2cf0635d 23330
015dc7e1 23331 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
23332 if (member_filedata == NULL)
23333 {
23334 error (_("Input file '%s' is not readable.\n"), member_file_name);
23335 free (member_file_name);
fd486f32 23336 free (qualified_name);
015dc7e1 23337 ret = false;
1cb7d8b1
AM
23338 break;
23339 }
2cf0635d 23340
978c4450 23341 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 23342 member_filedata->file_name = qualified_name;
2cf0635d 23343
75a2da57
AH
23344 /* The call to process_object() expects the file to be at the beginning. */
23345 rewind (member_filedata->handle);
23346
1cb7d8b1 23347 if (! process_object (member_filedata))
015dc7e1 23348 ret = false;
2cf0635d 23349
1cb7d8b1
AM
23350 close_file (member_filedata);
23351 free (member_file_name);
1cb7d8b1 23352 }
2cf0635d 23353 else if (is_thin_archive)
1cb7d8b1
AM
23354 {
23355 Filedata thin_filedata;
eb02c04d 23356
1cb7d8b1 23357 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 23358
a043396b
NC
23359 /* PR 15140: Allow for corrupt thin archives. */
23360 if (nested_arch.file == NULL)
23361 {
23362 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 23363 qualified_name, name);
fd486f32
AM
23364 free (qualified_name);
23365 free (name);
015dc7e1 23366 ret = false;
a043396b
NC
23367 break;
23368 }
fd486f32 23369 free (name);
a043396b 23370
1cb7d8b1 23371 /* This is a proxy for a member of a nested archive. */
978c4450
AM
23372 filedata->archive_file_offset
23373 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 23374
1cb7d8b1
AM
23375 /* The nested archive file will have been opened and setup by
23376 get_archive_member_name. */
63cf857e
AM
23377 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
23378 SEEK_SET) != 0)
1cb7d8b1
AM
23379 {
23380 error (_("%s: failed to seek to archive member.\n"),
23381 nested_arch.file_name);
fd486f32 23382 free (qualified_name);
015dc7e1 23383 ret = false;
1cb7d8b1
AM
23384 break;
23385 }
2cf0635d 23386
dda8d76d
NC
23387 thin_filedata.handle = nested_arch.file;
23388 thin_filedata.file_name = qualified_name;
9abca702 23389
1cb7d8b1 23390 if (! process_object (& thin_filedata))
015dc7e1 23391 ret = false;
1cb7d8b1 23392 }
2cf0635d 23393 else
1cb7d8b1 23394 {
fd486f32 23395 free (name);
978c4450 23396 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 23397 filedata->file_name = qualified_name;
1cb7d8b1 23398 if (! process_object (filedata))
015dc7e1 23399 ret = false;
237877b8 23400 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 23401 /* Stop looping with "negative" archive_file_size. */
978c4450 23402 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 23403 arch.next_arhdr_offset = -1ul;
1cb7d8b1 23404 }
fb52b2f4 23405
2cf0635d 23406 free (qualified_name);
fb52b2f4
NC
23407 }
23408
4145f1d5 23409 out:
2cf0635d
NC
23410 if (nested_arch.file != NULL)
23411 fclose (nested_arch.file);
23412 release_archive (&nested_arch);
23413 release_archive (&arch);
fb52b2f4 23414
d989285c 23415 return ret;
fb52b2f4
NC
23416}
23417
015dc7e1 23418static bool
2cf0635d 23419process_file (char * file_name)
fb52b2f4 23420{
dda8d76d 23421 Filedata * filedata = NULL;
fb52b2f4
NC
23422 struct stat statbuf;
23423 char armag[SARMAG];
015dc7e1 23424 bool ret = true;
fb52b2f4
NC
23425
23426 if (stat (file_name, &statbuf) < 0)
23427 {
f24ddbdd
NC
23428 if (errno == ENOENT)
23429 error (_("'%s': No such file\n"), file_name);
23430 else
23431 error (_("Could not locate '%s'. System error message: %s\n"),
23432 file_name, strerror (errno));
015dc7e1 23433 return false;
f24ddbdd
NC
23434 }
23435
23436 if (! S_ISREG (statbuf.st_mode))
23437 {
23438 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 23439 return false;
fb52b2f4
NC
23440 }
23441
dda8d76d
NC
23442 filedata = calloc (1, sizeof * filedata);
23443 if (filedata == NULL)
23444 {
23445 error (_("Out of memory allocating file data structure\n"));
015dc7e1 23446 return false;
dda8d76d
NC
23447 }
23448
23449 filedata->file_name = file_name;
23450 filedata->handle = fopen (file_name, "rb");
23451 if (filedata->handle == NULL)
fb52b2f4 23452 {
f24ddbdd 23453 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 23454 free (filedata);
015dc7e1 23455 return false;
fb52b2f4
NC
23456 }
23457
dda8d76d 23458 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 23459 {
4145f1d5 23460 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
23461 fclose (filedata->handle);
23462 free (filedata);
015dc7e1 23463 return false;
fb52b2f4
NC
23464 }
23465
be7d229a 23466 filedata->file_size = statbuf.st_size;
015dc7e1 23467 filedata->is_separate = false;
f54498b4 23468
fb52b2f4 23469 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 23470 {
015dc7e1
AM
23471 if (! process_archive (filedata, false))
23472 ret = false;
32ec8896 23473 }
2cf0635d 23474 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 23475 {
015dc7e1
AM
23476 if ( ! process_archive (filedata, true))
23477 ret = false;
32ec8896 23478 }
fb52b2f4
NC
23479 else
23480 {
1b513401 23481 if (do_archive_index && !check_all)
4145f1d5
NC
23482 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23483 file_name);
23484
dda8d76d 23485 rewind (filedata->handle);
978c4450 23486 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 23487
dda8d76d 23488 if (! process_object (filedata))
015dc7e1 23489 ret = false;
fb52b2f4
NC
23490 }
23491
dda8d76d 23492 fclose (filedata->handle);
8fb879cd
AM
23493 free (filedata->section_headers);
23494 free (filedata->program_headers);
23495 free (filedata->string_table);
6431e409 23496 free (filedata->dump.dump_sects);
dda8d76d 23497 free (filedata);
32ec8896 23498
fd486f32 23499 free (ba_cache.strtab);
1bd6175a 23500 ba_cache.strtab = NULL;
fd486f32 23501 free (ba_cache.symtab);
1bd6175a 23502 ba_cache.symtab = NULL;
fd486f32
AM
23503 ba_cache.filedata = NULL;
23504
fb52b2f4
NC
23505 return ret;
23506}
23507
252b5132
RH
23508#ifdef SUPPORT_DISASSEMBLY
23509/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 23510 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 23511 symbols. */
252b5132
RH
23512
23513void
2cf0635d 23514print_address (unsigned int addr, FILE * outfile)
252b5132
RH
23515{
23516 fprintf (outfile,"0x%8.8x", addr);
23517}
23518
e3c8793a 23519/* Needed by the i386 disassembler. */
dda8d76d 23520
252b5132
RH
23521void
23522db_task_printsym (unsigned int addr)
23523{
23524 print_address (addr, stderr);
23525}
23526#endif
23527
23528int
2cf0635d 23529main (int argc, char ** argv)
252b5132 23530{
ff78d6d6
L
23531 int err;
23532
87b9f255 23533#ifdef HAVE_LC_MESSAGES
252b5132 23534 setlocale (LC_MESSAGES, "");
3882b010 23535#endif
3882b010 23536 setlocale (LC_CTYPE, "");
252b5132
RH
23537 bindtextdomain (PACKAGE, LOCALEDIR);
23538 textdomain (PACKAGE);
23539
869b9d07
MM
23540 expandargv (&argc, &argv);
23541
dda8d76d 23542 parse_args (& cmdline, argc, argv);
59f14fc0 23543
18bd398b 23544 if (optind < (argc - 1))
1b513401
NC
23545 /* When displaying information for more than one file,
23546 prefix the information with the file name. */
015dc7e1 23547 show_name = true;
5656ba2c
L
23548 else if (optind >= argc)
23549 {
1b513401 23550 /* Ensure that the warning is always displayed. */
015dc7e1 23551 do_checks = true;
1b513401 23552
5656ba2c
L
23553 warn (_("Nothing to do.\n"));
23554 usage (stderr);
23555 }
18bd398b 23556
015dc7e1 23557 err = false;
252b5132 23558 while (optind < argc)
32ec8896 23559 if (! process_file (argv[optind++]))
015dc7e1 23560 err = true;
252b5132 23561
9db70fc3 23562 free (cmdline.dump_sects);
252b5132 23563
7d9813f1
NA
23564 free (dump_ctf_symtab_name);
23565 free (dump_ctf_strtab_name);
23566 free (dump_ctf_parent_name);
23567
32ec8896 23568 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 23569}